lazarus/lcl/interfaces/gtk/gtkwinapi.inc
mattias 9628a2b23e implemented TMouse.SetCursorPos from Andrew
git-svn-id: trunk@7268 -
2005-06-22 17:37:06 +00:00

10828 lines
345 KiB
PHP

{%MainUnit gtkint.pp}
{ $Id$ }
{******************************************************************************
All GTK Winapi implementations.
Initial Revision : Sat Nov 13 12:53:53 1999
!! Keep alphabetical !!
Support routines go to gtkproc.pp
******************************************************************************
Implementation
******************************************************************************
*****************************************************************************
* *
* This file is part of the Lazarus Component Library (LCL) *
* *
* See the file COPYING.LCL, included in this distribution, *
* for details about the copyright. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* *
*****************************************************************************
}
{$IFOPT C-}
// Uncomment for local trace
// {$C+}
// {$DEFINE ASSERT_IS_ON}
{$EndIf}
const
BOOL_TEXT: array[Boolean] of string = ('False', 'True');
//##apiwiz##sps## // Do not remove
{------------------------------------------------------------------------------
Method: Arc
Params: x,y,width,height,angle1,angle2
Returns: Nothing
Use Arc to draw an elliptically curved line with the current Pen.
The angles angle1 and angle2 are 1/16th of a degree. For example, a full
circle equals 5760 (16*360). Positive values of Angle and AngleLength mean
counter-clockwise while negative values mean clockwise direction.
Zero degrees is at the 3'o clock position.
------------------------------------------------------------------------------}
function TGtkWidgetSet.Arc(DC: HDC;
Left,Top,width,height,angle1,angle2 : Integer): Boolean;
var
DCOrigin: TPoint;
begin
Result := IsValidDC(DC);
if Result
then with TDeviceContext(DC) do
begin
if GC = nil
then begin
DebugLn('WARNING: [TGtkWidgetSet.Arc] Uninitialized GC');
Result := False;
end
else begin
// Draw outline
SelectGDKPenProps(DC);
If (dcfPenSelected in DCFlags) then begin
Result := True;
if (CurrentPen^.IsNullPen) then exit;
DCOrigin:=GetDCOffset(TDeviceContext(DC));
inc(Left,DCOrigin.X);
inc(Top,DCOrigin.Y);
{$IFDEF DebugGDKTraps}BeginGDKErrorTrap;{$ENDIF}
gdk_draw_arc(Drawable, GC, 0, Left,Top,Width,Height,
Angle1 shl 2, Angle2 shl 2);
{$IFDEF DebugGDKTraps}EndGDKErrorTrap;{$ENDIF}
end else
Result:=false;
end;
end;
end;
{------------------------------------------------------------------------------
Method: AngleChord
Params: DC,x,y,width,height,angle1,angle2
Returns: Nothing
Use AngleChord to draw a filled Chord-shape on the canvas. The angles angle1
and angle2 are 1/16th of a degree. For example, a full circle equals 5760
16*360). Positive values of Angle and AngleLength mean counter-clockwise while
negative values mean clockwise direction. Zero degrees is at the 3'o clock
position.
------------------------------------------------------------------------------}
function TGtkWidgetSet.AngleChord(DC: HDC;
x,y,width,height,angle1,angle2 : Integer): Boolean;
begin
Result := IsValidDC(DC);
if Result
then with TDeviceContext(DC) do
begin
if GC = nil
then begin
DebugLn('WARNING: [TGtkWidgetSet.AngleChord] Uninitialized GC');
Result := False;
end
else
Result := Inherited AngleChord(DC, x, y, width, height, angle1, angle2);
end;
end;
{------------------------------------------------------------------------------
Function: BeginPaint
Params:
Returns:
------------------------------------------------------------------------------}
function TGtkWidgetSet.BeginPaint(Handle: hWnd; Var PS : TPaintStruct) : hdc;
var
{$IFDEF Gtk1}
Widget: PGtkWidget;
TargetObject: TObject;
PaintWidget: Pointer;
{$ENDIF}
IsDoubleBuffered: Boolean;
begin
{$IFDEF Gtk1}
Widget:=PGtkWidget(Handle);
TargetObject:=GetNearestLCLObject(Widget);
IsDoubleBuffered:=(TargetObject is TWinControl)
and TWinControl(TargetObject).DoubleBuffered;
// check if Handle is the paint widget of the LCL component
if IsDoubleBuffered then begin
PaintWidget:=GetFixedWidget(PGtkWidget(TWinControl(TargetObject).Handle));
IsDoubleBuffered:=(PaintWidget=Widget);
//if not IsDoubleBuffered then begin
// DebugLn('TGtkWidgetSet.BeginPaint Not the paint widget: ',
// TWinControl(TargetObject).Name,':',TWinControl(TargetObject).ClassName,
// ' PaintWidget=',GetWidgetClassName(PaintWidget),
// ' Widget=',GetWidgetClassName(Widget));
//end;
end;
{$IFNDEF UseGTKDoubleBuf}
IsDoubleBuffered:=false;
{$ENDIF}
{$ELSE}
IsDoubleBuffered:=false;
{$ENDIF}
if IsDoubleBuffered then
PS.hDC:=GetDoubleBufferedDC(Handle)
else
PS.hDC:=GetDC(Handle);
Result := PS.hDC;
end;
{------------------------------------------------------------------------------
Function: BitBlt
Params: DestDC: The destination devicecontext
X, Y: The left/top corner of the destination rectangle
Width, Height: The size of the destination rectangle
SrcDC: The source devicecontext
XSrc, YSrc: The left/top corner of the source rectangle
Rop: The raster operation to be performed
Returns: True if succesful
The BitBlt function copies a bitmap from a source context into a destination
context using the specified raster operation.
------------------------------------------------------------------------------}
function TGtkWidgetSet.BitBlt(DestDC: HDC; X, Y, Width, Height: Integer;
SrcDC: HDC; XSrc, YSrc: Integer; Rop: DWORD): Boolean;
begin
Result := StretchBlt(DestDC, X, Y, Width, Height, SrcDC, XSrc, YSrc, Width,
Height, ROP);
end;
{------------------------------------------------------------------------------
Function: BringWindowToTop
Params: hWnd:
Returns:
------------------------------------------------------------------------------}
Function TGtkWidgetSet.BringWindowToTop(hWnd : HWND): Boolean;
var
{$IFDEF VerboseFocus}
LCLObject: TControl;
{$ENDIF}
GdkWindow: PGdkWindow;
AForm: TCustomForm;
{$IFDEF GTK1}
FormWidget: PGtkWidget;
FormWindow: PGdkWindowPrivate;
WindowDesktop: Integer;
{$ENDIF}
begin
{$IFDEF VerboseFocus}
DbgOut('TGtkWidgetSet.BringWindowToTop hWnd=',DbgS(hWnd));
LCLObject:=TControl(GetLCLObject(Pointer(hWnd)));
if LCLObject<>nil then
DebugLn(' LCLObject=',LCLObject.Name,':',LCLObject.ClassName)
else
DebugLn(' LCLObject=nil');
{$ENDIF}
Result := GtkWidgetIsA(PGtkWidget(hWnd),GTK_TYPE_WINDOW);
if Result then begin
GdkWindow:=GetControlWindow(PgtkWidget(hwnd));
if GdkWindow<>nil then begin
AForm:=TCustomForm(GetLCLObject(PgtkWidget(hwnd)));
if (AForm<>nil) and (AForm is TCustomForm) and (AForm.Parent=nil) then
begin
if Screen.CustomFormZIndex(AForm)<Screen.GetCurrentModalFormZIndex then
begin
debugln('TGtkWidgetSet.BringWindowToTop Form=',DbgSName(AForm),
' can not be raised, because ',
DbgSName(Screen.GetCurrentModalForm),
' is modal and above.');
Result:=false;
exit;
end;
Screen.MoveFormToZFront(AForm);
end;
{$IFDEF DebugGDKTraps}
BeginGDKErrorTrap;
{$ENDIF}
gdk_window_show(GdkWindow);
gdk_window_raise(GdkWindow);
{$IFDEF DebugGDKTraps}
EndGDKErrorTrap;
{$ENDIF}
{$IFDEF GTK1}
FormWidget:=PGtkWidget(AForm.Handle);
FormWindow:=PGdkWindowPrivate(FormWidget^.window);
if FormWindow<>nil then begin
WindowDesktop := GDK_WINDOW_GET_DESKTOP(FormWindow);
// this prevents the window from appearing on a different desktop
// which could be undesirable.
// check if the window is on all desktops or is on the current desktop
if (WindowDesktop < 0) or (WindowDesktop = GDK_GET_CURRENT_DESKTOP) then
begin
GDK_WINDOW_ACTIVATE(FormWindow);
end
else begin
// TODO: Figure out how to set the focus on an inactive desktop without
// bringing the window to the current desktop
end;
end;
{$ENDIF}
{$ifdef gtk2}
// this currently will bring the window to the current desktop and focus it
gtk_window_present(PGtkWindow(hWnd));
{$endif gtk2}
end;
end;
end;
{------------------------------------------------------------------------------
Function: CallNextHookEx
Params: none
Returns: Nothing
------------------------------------------------------------------------------}
function TGtkWidgetSet.CallNextHookEx(hhk : HHOOK; ncode : Integer; wParam: WParam; lParam : LParam) : Integer;
begin
Result := 0;
//TODO: Does anything need to be done here?
Assert(False, 'Trace:!!!!!!!!!!!!!!!!!!');
Assert(False, 'Trace:!!!!!!!!!!!!!!!!!!');
Assert(False, 'Trace:TODO: CALLNEXTHOOKEX in gtkwinapi.inc');
Assert(False, 'Trace:!!!!!!!!!!!!!!!!!!');
Assert(False, 'Trace:!!!!!!!!!!!!!!!!!!');
end;
{------------------------------------------------------------------------------
Function: CallWindowProc
Params: lpPrevWndFunc:
Handle:
Msg:
wParam:
lParam:
Returns:
------------------------------------------------------------------------------}
Function TGtkWidgetSet.CallWindowProc(lpPrevWndFunc : TFarProc; Handle : HWND;
Msg : UINT; wParam: WParam; lParam : LParam) : Integer;
var
Proc : TWndMethod;
Mess : TLMessage;
P : Pointer;
begin
Result := -1;
if Handle = 0 then Exit;
Result := -1;
P := nil;
P := gtk_object_get_data(pgtkobject(Handle),'WNDPROC');
if P <> nil then
Proc := TWndMethod(P^)
else
Exit;
Mess.msg := msg;
Mess.LParam := LParam;
Mess.WParam := WParam;
Proc(Mess);
Result := Mess.Result;
end;
{------------------------------------------------------------------------------
Function: ClientToScreen
Params: Handle : HWND; var P : TPoint
Returns: true on success
Converts the client-area coordinates of P to screen coordinates.
------------------------------------------------------------------------------}
Function TGtkWidgetSet.ClientToScreen(Handle : HWND; var P : TPoint) : Boolean;
var
Position: TPoint;
Begin
if Handle = 0
then begin
Position.X := 0;
Position.Y := 0;
end
else begin
Position:=GetWidgetClientOrigin(PGtkWidget(Handle));
end;
// Todo: calculate offset, since platform specific
Inc(P.X, Position.X);
Inc(P.Y, Position.Y);
Assert(False, Format('Trace: [GTKObject.ClientToScreen] Handle: 0x%x --> (%d, %d)', [Integer(Handle), P.X, P.y]));
Result := True;
end;
{------------------------------------------------------------------------------
Function: ClipboardFormatToMimeType
Params: FormatID - a registered format identifier (0 is invalid)
Returns: the corresponding mime type as string
------------------------------------------------------------------------------}
function TGtkWidgetSet.ClipboardFormatToMimeType(
FormatID: TClipboardFormat): string;
var p: PChar;
begin
if FormatID<>0 then begin
p:=gdk_atom_name(FormatID);
Result:=StrPas(p);
g_free(p);
end else
Result:='';
end;
{------------------------------------------------------------------------------
Function: ClipboardGetData
Params: ClipboardType
FormatID - a registered format identifier (0 is invalid)
Stream - If format is available, it will be appended to this stream
Returns: true on success
------------------------------------------------------------------------------}
function TGtkWidgetSet.ClipboardGetData(ClipboardType: TClipboardType;
FormatID: TClipboardFormat; Stream: TStream): boolean;
type
PGdkAtom = ^TGdkAtom;
var FormatAtom, FormatTry: Cardinal;
SupportedCnt, i: integer;
SupportedFormats: PGdkAtom;
SelData: TGtkSelectionData;
CompoundTextList: PPGChar;
CompoundTextCount: integer;
function IsFormatSupported(Format: cardinal): boolean;
var a: integer;
AllID: cardinal;
begin
if Format=0 then begin
Result:=false;
exit;
end;
if SupportedCnt<0 then begin
Result:=false;
AllID:=gdk_atom_intern('TARGETS',GdkFalse);
SelData:=RequestSelectionData(ClipboardWidget,ClipboardType,AllID);
{DebugLn('IsFormatSupported A ',Dbgs(SelData.Selection),
' ',HexStr(Cardinal(ClipboardTypeAtoms[ClipboardType]),8),
' SelData.Target='+dbgs(SelData.Target),' AllID='+dbgs(AllID),
' SelData.TheType='+dbgs(SelData.TheType),' '+dbgs(gdk_atom_intern('ATOM',0)),
' SelData.Length='+dbgs(SelData.Length),
' SelData.Format='+dbgs(SelData.Format)
);}
if (SelData.Selection<>ClipboardTypeAtoms[ClipboardType])
or (SelData.Target<>AllID)
or (SelData.{$IfDef GTK2}_Type{$Else}theType{$EndIf}<>gdk_atom_intern('ATOM',GdkFalse)) then begin
SupportedCnt:=0;
exit;
end;
SupportedCnt:=SelData.Length div (SelData.Format shr 3);
SupportedFormats:=PGdkAtom(SelData.Data);
{a:=SupportedCnt-1;
while (a>=0) do begin
debugln(' ',dbgs(a),' ',GdkAtomToStr(SupportedFormats[a]),' "',p,'"');
dec(a);
end;}
end;
a:=SupportedCnt-1;
while (a>=0) and (SupportedFormats[a]<>Format) do dec(a);
Result:=(a>=0);
end;
begin
{$IfDef DEBUG_CLIPBOARD}
DebugLn('[TGtkWidgetSet.ClipboardGetData] A ClipboardWidget=',Dbgs(ClipboardWidget),' FormatID=',ClipboardFormatToMimeType(FormatID),' Now=',dbgs(Now));
{$EndIf}
Result:=false;
if (FormatID=0) or (Stream=nil) then exit;
if not (ClipboardType in [ctPrimarySelection,ctSecondarySelection,ctClipboard])
then exit;
// request the data from the selection owner
SupportedCnt:=-1;
SupportedFormats:=nil;
FillChar(SelData,SizeOf(TGtkSelectionData),0);
try
FormatAtom:=FormatID;
if (FormatAtom=gdk_atom_intern('text/plain',GdkTrue)) then begin
FormatAtom:=0;
// text/plain is supported in various formats in gtk
FormatTry:=gdk_atom_intern('COMPOUND_TEXT',GdkFalse);
if IsFormatSupported(FormatTry) then
FormatAtom:=FormatTry;
// The COMPOUND_TEXT format can be converted and is therefore
// used as default for 'text/plain'
if (SupportedCnt=0) then
FormatAtom:=gdk_atom_intern('COMPOUND_TEXT',GdkFalse);
// then check for UTF8 text format 'UTF8_STRING'
FormatTry:=gdk_atom_intern('UTF8_STRING',GdkFalse);
if IsFormatSupported(FormatTry) then
FormatAtom:=FormatTry;
// then check for simple text format 'text/plain'
FormatTry:=gdk_atom_intern('text/plain',GdkFalse);
if (FormatAtom=0) and IsFormatSupported(FormatTry) then
FormatAtom:=FormatTry;
// then check for simple text format STRING
FormatTry:=gdk_atom_intern('STRING',GdkFalse);
if (FormatAtom=0) and IsFormatSupported(FormatTry) then
FormatAtom:=FormatTry;
// check for some other formats that can be interpreted as text
FormatTry:=gdk_atom_intern('FILE_NAME',GdkTrue);
if (FormatAtom=0) and IsFormatSupported(FormatTry) then
FormatAtom:=FormatTry;
FormatTry:=gdk_atom_intern('HOST_NAME',GdkTrue);
if (FormatAtom=0) and IsFormatSupported(FormatTry) then
FormatAtom:=FormatTry;
FormatTry:=gdk_atom_intern('USER',GdkTrue);
if (FormatAtom=0) and IsFormatSupported(FormatTry) then
FormatAtom:=FormatTry;
// the TEXT format is not reliable, but it should be supported
FormatTry:=gdk_atom_intern('TEXT',GdkFalse);
if (FormatAtom=0) and IsFormatSupported(FormatTry) then
FormatAtom:=FormatTry;
end;
{$IfDef DEBUG_CLIPBOARD}
DebugLn('[TGtkWidgetSet.ClipboardGetData] B Format=',ClipboardFormatToMimeType(FormatAtom),' FormatAtom=',dbgs(FormatAtom),' Now=',dbgs(Now));
{$EndIf}
if FormatAtom=0 then exit;
// request data from owner
SelData:=RequestSelectionData(ClipboardWidget,ClipboardType,FormatAtom);
{$IfDef DEBUG_CLIPBOARD}
DebugLn('[TGtkWidgetSet.ClipboardGetData] C Length=',dbgs(SelData.Length),' Now=',dbgs(Now),' ',
' SelData.Selection=',dbgs(SelData.Selection),' SelData.Length=',dbgs(SelData.Length));
{$EndIf}
if (SelData.Selection<>ClipboardTypeAtoms[ClipboardType])
or (SelData.Target<>FormatAtom) then begin
{$IfDef DEBUG_CLIPBOARD}
DebugLn('[TGtkWidgetSet.ClipboardGetData] REQUESTED FORMAT NOT SUPPORTED Length=',dbgs(SelData.Length));
{$ENDIF}
exit;
end;
// write data to stream
if (SelData.Data<>nil) and (SelData.Length>0) then begin
if (FormatID=gdk_atom_intern('text/plain',GdkTrue)) then begin
// the lcl expects the return format as simple text
// transform if necessary
if FormatAtom=gdk_atom_intern('COMPOUND_TEXT',GdkTrue) then begin
CompoundTextCount:=gdk_text_property_to_text_list(SelData.{$IfDef GTK2}_Type{$Else}theType{$EndIf},
SelData.Format,SelData.Data,SelData.Length,{$IfDef GTK1}@{$EndIf}CompoundTextList);
{$IfDef DEBUG_CLIPBOARD}
DebugLn('[TGtkWidgetSet.ClipboardGetData] D CompoundTextCount=',dbgs(CompoundTextCount),' Now=',dbgs(Now));
{$EndIf}
for i:=0 to CompoundTextCount-1 do
if (CompoundTextList[i]<>nil) then
Stream.Write(CompoundTextList[i]^,StrLen(CompoundTextList[i]));
gdk_free_text_list(CompoundTextList);
end else
Stream.Write(SelData.Data^,SelData.Length);
end else begin
Stream.Write(SelData.Data^,SelData.Length);
end;
end;
{$IfDef DEBUG_CLIPBOARD}
DebugLn('[TGtkWidgetSet.ClipboardGetData] END ',' Now=',dbgs(Now));
{$EndIf}
Result:=true;
finally
if SupportedFormats<>nil then FreeMem(SupportedFormats);
if SelData.Data<>nil then FreeMem(SelData.Data);
end;
end;
{------------------------------------------------------------------------------
Function: ClipboardGetFormats
Params: ClipboardType
Returns: true on success
Count contains the number of supported formats
List is an array of TClipboardType
! List will be created. You must free it yourself with FreeMem(List) !
------------------------------------------------------------------------------}
function TGtkWidgetSet.ClipboardGetFormats(ClipboardType: TClipboardType;
var Count: integer; var List: PClipboardFormat): boolean;
type
PGdkAtom = ^TGdkAtom;
var AllID: cardinal;
FormatAtoms: PGdkAtom;
Cnt, i: integer;
AddTextPlain: boolean;
SelData: TGtkSelectionData;
function IsFormatSupported(Format: cardinal): boolean;
var a: integer;
begin
if Format<>0 then begin
for a:=0 to Cnt-1 do begin
{$IfDef DEBUG_CLIPBOARD}
DebugLn(' IsFormatSupported ',dbgs(Format),' ',dbgs(FormatAtoms[a]));
{$EndIf}
if FormatAtoms[a]=Format then begin
Result:=true;
exit;
end;
end;
end;
Result:=false;
end;
function IsFormatSupported(Formats: TGtkClipboardFormats): boolean;
var Format: TGtkClipboardFormat;
begin
for Format:=Low(TGtkClipboardFormat) to High(TGtkClipboardFormat) do
if (Format in Formats)
and (IsFormatSupported(
gdk_atom_intern(PGChar(GtkClipboardFormatName[Format]),GdkTrue)))
then begin
Result:=true;
exit;
end;
Result:=false;
end;
begin
{$IfDef DEBUG_CLIPBOARD}
DebugLn('[TGtkWidgetSet.ClipboardGetFormats] A ClipboardWidget=',Dbgs(ClipboardWidget),' Now=',dbgs(Now));
{$EndIf}
Result:=false;
Count:=0;
List:=nil;
if not (ClipboardType in [ctPrimarySelection,ctSecondarySelection,ctClipboard])
then exit;
// request the list of supported formats from the selection owner
AllID:=gdk_atom_intern('TARGETS',GdkFalse);
SelData:=RequestSelectionData(ClipboardWidget,ClipboardType,AllID);
try
{$IfDef DEBUG_CLIPBOARD}
DebugLn('[TGtkWidgetSet.ClipboardGetFormats] Checking TARGETS answer ',
' selection: '+dbgs(SelData.Selection)+'='+dbgs(ClipboardTypeAtoms[ClipboardType])+
' "'+gdk_atom_name(SelData.Selection)+'"',
' target: '+dbgs(SelData.Target),'=',dbgs(AllID),
' "'+gdk_atom_name(SelData.Target),'"',
' theType: '+dbgs(SelData.TheType)+'='+dbgs(gdk_atom_intern('ATOM',GdkFalse))+
' "'+gdk_atom_name(SelData.theType)+'"',
' Length='+dbgs(SelData.Length),
' Format='+dbgs(SelData.Format),
' Data='+Dbgs(SelData.Data),
' Now='+dbgs(Now)
);
{$EndIf}
if (SelData.Selection<>ClipboardTypeAtoms[ClipboardType])
or (SelData.Target<>AllID)
or (SelData.Format<=0)
or ((SelData.{$IfDef GTK2}_Type{$Else}TheType{$EndIf}<>gdk_atom_intern('ATOM',GdkFalse))
and (SelData.{$IfDef GTK2}_Type{$Else}TheType{$EndIf}<>AllID))
then
exit;
Cnt:=SelData.Length div (SelData.Format shr 3);
if (SelData.Data<>nil) and (Cnt>0) then begin
Count:=Cnt;
FormatAtoms:=PGdkAtom(SelData.Data);
// add transformable lcl formats
// for example: the lcl expects text as 'text/plain', but gtk applications
// also know 'TEXT' and 'STRING'. These formats can automagically
// transformed into the lcl format, so the lcl format is also supported
// and will be added to the list
AddTextPlain:=false;
if (not IsFormatSupported(gdk_atom_intern('text/plain',GdkTrue)))
and (IsFormatSupported([gfCOMPOUND_TEXT,gfTEXT,gfSTRING,gfFILE_NAME,
gfHOST_NAME,gfUSER]))
then begin
AddTextPlain:=true;
inc(Count);
end;
// copy normal supported formats
GetMem(List,SizeOf(TClipboardFormat)*Count);
i:=0;
while (i<Cnt) do begin
{$IfDef DEBUG_CLIPBOARD}
DebugLn('[TGtkWidgetSet.ClipboardGetFormats] Supported formats: ',
dbgs(i)+'/'+dbgs(Cnt),': ',dbgs(FormatAtoms[i]));
DebugLn(' MimeType="',ClipboardFormatToMimeType(FormatAtoms[i]),'"');
{$EndIf}
List[i]:=FormatAtoms[i];
inc(i);
end;
// add all lcl formats that the gtk-interface can transform from the
// supported formats
if AddTextPlain then begin
List[i]:=gdk_atom_intern('text/plain',GdkFalse);
inc(i);
end;
end;
finally
if SelData.Data<>nil then FreeMem(SelData.Data);
end;
Result:=true;
end;
{------------------------------------------------------------------------------
Function: ClipboardGetOwnerShip
Params: ClipboardType
OnRequestProc - TClipboardRequestEvent is defined in LCLIntf.pp
If OnRequestProc is nil the onwership will end.
FormatCount - number of formats
Formats - array of TClipboardFormat. The supported formats the owner
provides.
Returns: true on success
Sets the supported formats and requests ownership for the clipboard.
Each time the clipboard is read the OnRequestProc will be executed.
If someone else requests the ownership, the OnRequestProc will be executed
with the invalid FormatID 0 to notify the old owner of the lost of ownership.
------------------------------------------------------------------------------}
function TGtkWidgetSet.ClipboardGetOwnerShip(ClipboardType: TClipboardType;
OnRequestProc: TClipboardRequestEvent; FormatCount: integer;
Formats: PClipboardFormat): boolean;
var TargetEntries: PGtkTargetEntry;
function IsFormatSupported(FormatID: cardinal): boolean;
var i: integer;
begin
if FormatID=0 then begin
Result:=false;
exit;
end;
i:=FormatCount-1;
while (i>=0) and (Formats[i]<>FormatID) do dec(i);
Result:=(i>=0);
end;
procedure AddTargetEntry(var Index: integer; const FormatName: string);
begin
{$IfDef DEBUG_CLIPBOARD}
DebugLn(' AddTargetEntry ',FormatName);
{$EndIf}
TargetEntries[Index].Target := StrAlloc(Length(FormatName) + 1);
StrPCopy(TargetEntries[Index].Target, FormatName);
TargetEntries[Index].Info:=Index;
inc(Index);
end;
{function TGtkWidgetSet.ClipboardGetOwnerShip(ClipboardType: TClipboardType;
OnRequestProc: TClipboardRequestEvent; FormatCount: integer;
Formats: PClipboardFormat): boolean;}
var
TargetEntriesSize, i: integer;
gtkFormat: TGtkClipboardFormat;
ExpFormatCnt: integer;
OldClipboardWidget: PGtkWidget;
begin
if ClipboardType in [ctPrimarySelection, ctSecondarySelection, ctClipboard] then
begin
{$IfDef DEBUG_CLIPBOARD}
DebugLn('[TGtkWidgetSet.ClipboardGetOwnerShip] A');
{$EndIf}
ClipboardHandler[ClipboardType]:=nil;
Result:=false;
if (ClipboardWidget=nil) or (FormatCount=0) or (Formats=nil) then
begin
// end ownership
if (ClipBoardWidget <> nil)
and (GetControlWindow(ClipboardWidget)<>nil)
and (gdk_selection_owner_get(ClipboardTypeAtoms[ClipboardType]) =
GetControlWindow(ClipboardWidget))
then begin
gtk_selection_owner_set(nil,ClipboardTypeAtoms[ClipboardType],0);
end;
Result:=true;
exit;
end;
// registering targets
FreeClipboardTargetEntries(ClipboardType);
// the gtk-interface adds automatically some gtk formats the lcl does not
// know
ExpFormatCnt:=FormatCount;
for gtkFormat:=Low(TGtkClipboardFormat) to High(TGtkClipboardFormat) do
ClipboardExtraGtkFormats[ClipboardType][gtkFormat]:=false;
{$IfDef DEBUG_CLIPBOARD}
DebugLn('[TGtkWidgetSet.ClipboardGetOwnerShip] B');
{$EndIf}
if IsFormatSupported(gdk_atom_intern('text/plain',GdkTrue)) then
begin
// lcl provides 'text/plain' and the gtk-interface will automatically
// provide some more text formats
ClipboardExtraGtkFormats[ClipboardType][gfCOMPOUND_TEXT]:=
not IsFormatSupported(
gdk_atom_intern(PGChar(GtkClipboardFormatName[gfCOMPOUND_TEXT]),GdkFalse));
ClipboardExtraGtkFormats[ClipboardType][gfSTRING]:=not IsFormatSupported(
gdk_atom_intern(PGChar(GtkClipboardFormatName[gfSTRING]),GdkFalse));
ClipboardExtraGtkFormats[ClipboardType][gfTEXT]:=not IsFormatSupported(
gdk_atom_intern(PGChar(GtkClipboardFormatName[gfTEXT]),GdkFalse));
end;
for gtkFormat:=Low(TGtkClipboardFormat) to High(TGtkClipboardFormat) do
if ClipboardExtraGtkFormats[ClipboardType][gtkFormat] then
inc(ExpFormatCnt);
// build TargetEntries
TargetEntriesSize:=SizeOf(TGtkTargetEntry) * ExpFormatCnt;
GetMem(TargetEntries,TargetEntriesSize);
FillChar(TargetEntries^,TargetEntriesSize,0);
i:=0;
while i<FormatCount do
AddTargetEntry(i,ClipboardFormatToMimeType(Formats[i]));
for gtkFormat:=Low(TGtkClipboardFormat) to High(TGtkClipboardFormat) do
if ClipboardExtraGtkFormats[ClipboardType][gtkFormat] then
AddTargetEntry(i,GtkClipboardFormatName[gtkFormat]);
// set the supported formats
ClipboardTargetEntries[ClipboardType]:=TargetEntries;
ClipboardTargetEntryCnt[ClipboardType]:=ExpFormatCnt;
// reset the clipboard widget (this will set the new target list)
OldClipboardWidget:=ClipboardWidget;
SetClipboardWidget(nil);
SetClipboardWidget(OldClipboardWidget);
// taking the ownership
{$IfDef DEBUG_CLIPBOARD}
DebugLn('[TGtkWidgetSet.ClipboardGetOwnerShip] C');
{$EndIf}
if gtk_selection_owner_set(ClipboardWidget,
ClipboardTypeAtoms[ClipboardType],0)=GdkFalse
then begin
{$IfDef DEBUG_CLIPBOARD}
DebugLn('[TGtkWidgetSet.ClipboardGetOwnerShip] D FAILED');
{$EndIf}
exit;
end;
{$IfDef DEBUG_CLIPBOARD}
DebugLn('[TGtkWidgetSet.ClipboardGetOwnerShip] YEAH, got it!');
{$EndIf}
ClipboardHandler[ClipboardType]:=OnRequestProc;
Result:=true;
end else
{ the gtk does not support this kind of clipboard, so the application can
have the ownership at any time. The TClipboard in clipbrd.pp has an
internal cache system, so that an application can use all types of
clipboards even if the underlying platform does not support it.
Of course this will only be a local clipboard, invisible to other
applications. }
Result:=true;
end;
{------------------------------------------------------------------------------
Function: ClipboardRegisterFormat
Params: AMimeType
Returns: the registered Format identifier (TClipboardFormat)
------------------------------------------------------------------------------}
function TGtkWidgetSet.ClipboardRegisterFormat(
const AMimeType:String): TClipboardFormat;
var AtomName: PChar;
begin
if Assigned(Application) then begin
AtomName:=PChar(AMimeType);
Result:=gdk_atom_intern(AtomName,GdkFalse);
end else
RaiseException(
'ERROR: TGtkWidgetSet.ClipboardRegisterFormat gdk not initialized');
end;
{------------------------------------------------------------------------------
Function: CreateBitmap
Params: none
Returns: Nothing
------------------------------------------------------------------------------}
function TGtkWidgetSet.CreateBitmap(Width, Height: Integer;
Planes, BitCount: Longint; BitmapBits: Pointer): HBITMAP;
var
GdiObject: PGdiObject;
DefGdkWindow: PGdkWindow;
begin
Assert(False, Format('Trace:> [TGtkWidgetSet.CreateBitmap] Width: %d, Height: %d, Planes: %d, BitCount: %d, BitmapBits: 0x%x', [Width, Height, Planes, BitCount, Longint(BitmapBits)]));
if (BitCount < 1) or (Bitcount > 32)
then begin
Result := 0;
DebugLn(Format('ERROR: [TGtkWidgetSet.CreateBitmap] Illegal depth %d', [BitCount]));
Exit;
end;
//write('TGtkWidgetSet.CreateBitmap->');
GdiObject := NewGDIObject(gdiBitmap);
{$IFDEF DebugGDKTraps}
BeginGDKErrorTrap;
{$ENDIF}
// if the bitcount is 1 then create a gdkbitmap
// else create a gdkpixmap
{if BitCount > 1
then begin
Assert(False, Format('Trace: [TGtkWidgetSet.CreateBitmap] gbPixmap', [])); }
DefGdkWindow := nil;
If BitCount = 1 then begin
GdiObject^.GDIBitmapType := gbBitmap;
GdiObject^.GDIBitmapObject := CreateGdkBitmap(DefGdkWindow,Width,Height);
GdiObject^.Visual := gdk_window_get_visual(GdiObject^.GDIBitmapObject);
end
else begin
GdiObject^.GDIBitmapType := gbPixmap;
GdiObject^.GDIPixmapObject :=
gdk_pixmap_new(DefGdkWindow, Width, Height, BitCount);
GdiObject^.Visual := gdk_window_get_visual(GdiObject^.GDIPixmapObject);
end;
gdk_visual_ref(GdiObject^.Visual);
GdiObject^.SystemVisual := False;
// the visual is created only when needed
{If GdiObject^.Visual <> nil then
gdk_visual_ref(GdiObject^.Visual)
else begin
GdiObject^.Visual := gdk_visual_get_best_with_depth(BitCount);
if GdiObject^.Visual=nil then begin
DebugLn('Warning: [TGtkWidgetSet.CreateBitmap] No visual for depth ',
BitCount,'. Using default.');
GdiObject^.Visual := gdk_visual_get_system;
end;
end;}
// the colormap is only created if needed
//GdiObject^.Colormap := gdk_colormap_new(GdiObject^.Visual, GdkTrue);
{$IFDEF DebugGDKTraps}
EndGDKErrorTrap;
{$ENDIF}
If BitmapBits <> nil then
LoadFromPixbufData(hBitmap(GdiObject), BitmapBits);
{end
else if Bitcount = 1
then begin
Assert(False, Format('Trace: [TGtkWidgetSet.CreateBitmap] gbBitmap', []));
GdiObject^.GDIBitmapType := gbBitmap;
GdiObject^.GDIBitmapObject := gdk_pixmap_new(nil, Width, Height, BitCount);
GdiObject^.Visual := gdk_window_get_visual(GdiObject^.GDIBitmapObject);
If GdiObject^.Visual = nil then
GdiObject^.Visual := gdk_visual_get_best_with_depth(BitCount)
else
gdk_visual_ref(GdiObject^.Visual);
GdiObject^.Colormap := gdk_colormap_new(GdiObject^.Visual, 1)
end;
else begin
Assert(False, Format('Trace: [TGtkWidgetSet.CreateBitmap] gbImage', []));
GdiObject^.GDIBitmapType := gbImage;
GdiObject^.GDI_RGBImageObject := NewGDI_RGBImage(Width, Height, BitCount);
GdiObject^.Visual := gdk_visual_get_best_with_depth(BitCount);
GdiObject^.Colormap := gdk_colormap_new(GdiObject^.Visual, 1);
end;}
Result := HBITMAP(GdiObject);
//DebugLn('[TGtkWidgetSet.CreateBitmap] ',DbgS(Result,8));
Assert(False, Format('Trace:< [TGtkWidgetSet.CreateBitmap] --> 0x%x', [Integer(Result)]));
end;
{------------------------------------------------------------------------------
function TGtkWidgetSet.CreateBitmapFromRawImage(const RawImage: TRawImage;
var Bitmap, MaskBitmap: HBitmap; AlwaysCreateMask: boolean): Boolean;
------------------------------------------------------------------------------}
function TGtkWidgetSet.CreateBitmapFromRawImage(const RawImage: TRawImage;
var Bitmap, MaskBitmap: HBitmap; AlwaysCreateMask: boolean): boolean;
var
GdiObject: PGDIObject;
DefGDkWindow: PGdkWindow;
GDkWindow: PGdkWindow;
GC: PGdkGC;
ImgData: Pointer;
ImgWidth: Cardinal;
ImgHeight: Cardinal;
ImgDepth: Cardinal;
Visual: PGdkVisual;
GdkImage: PGdkImage;
ImgDataSize: Cardinal;
begin
Result:=false;
Bitmap:=0;
MaskBitmap:=0;
if (RawImage.Description.Width=0) or (RawImage.Description.Height=0) then
exit;
try
{$IFDEF VerboseRawImage}
DebugLn('TGtkWidgetSet.CreateBitmapFromRawImage A ',
' AlwaysCreateMask='+dbgs(AlwaysCreateMask),
' Depth='+dbgs(RawImage.Description.Depth),
' Width='+dbgs(RawImage.Description.Width),
' Height='+dbgs(RawImage.Description.Height),
' Data='+DbgS(RawImage.Data),
' DataSize='+dbgs(RawImage.DataSize)+
' Mask='+DbgS(RawImage.Mask)+
' MaskSize='+dbgs(RawImage.MaskSize)+
' Palette='+DbgS(RawImage.Palette)+
' PaletteSize='+dbgs(RawImage.PaletteSize)+
' BitsPerPixel='+dbgs(RawImage.Description.BitsPerPixel)+
'');
{$ENDIF}
// ToDo: check description
DefGdkWindow := nil;
GdiObject := NewGDIObject(gdiBitmap);
GdiObject^.GDIBitmapType := gbPixmap;
// create Pixmap from data
ImgWidth:=RawImage.Description.Width;
ImgHeight:=RawImage.Description.Height;
ImgDepth:=RawImage.Description.Depth;
ImgData:=RawImage.Data;
ImgDataSize:=RawImage.DataSize;
if ImgDepth=1 then begin
// create a GdkBitmap
if RawImage.Data<>nil then begin
GDkWindow:=gdk_bitmap_create_from_data(DefGdkWindow,ImgData,
ImgWidth,ImgHeight);
end else begin
GDkWindow := CreateGdkBitmap(DefGdkWindow,ImgWidth,ImgHeight);
end;
GdiObject^.GDIBitmapObject := GDkWindow;
GdiObject^.GDIBitmapType := gbBitmap;
end else begin
// create a GdkPixmap
if RawImage.Data<>nil then begin
{ The gdk_pixmap_create_from_data seems to be buggy.
It only creates pixmaps of Depth 1
gdk_pixmap_create_from_data(DefGdkWindow,PGChar(RawImage.Data),
RawImage.Description.Width, RawImage.Description.Height,
RawImage.Description.Depth, @fg,@bg);}
GdkWindow:=gdk_pixmap_new(DefGdkWindow,ImgWidth,ImgHeight,ImgDepth);
// Create a GdkImage, copy our data into it and create a pixmap from it
Visual:=gdk_visual_get_best_with_depth(ImgDepth);
GdkImage:=gdk_image_new(GDK_IMAGE_FASTEST,Visual,ImgWidth,ImgHeight);
{$IFDEF VerboseRawImage}
DebugLn('TGtkWidgetSet.CreateBitmapFromRawImage GdkImage: ',
' BytesPerLine=',dbgs(GdkImage^.bpl),
' BytesPerPixel=',dbgs(GdkImage^.bpp),
' ByteOrder=',dbgs(GdkImage^.byte_order),
'');
{$ENDIF}
if (RawImage.Description.BitsPerPixel<>(cardinal(GdkImage^.bpp) shl 3))
then begin
RaiseGDBException('TGtkWidgetSet.CreateBitmapFromRawImage Incompatible BitsPerPixel');
end;
if (ImgDataSize<>GdkImage^.bpl*ImgHeight) then begin
RaiseGDBException('TGtkWidgetSet.CreateBitmapFromRawImage Incompatible DataSize');
end;
System.Move(ImgData^,GdkImage^.mem^,ImgDataSize);
GC:=gdk_gc_new(GDkWindow);
gdk_draw_image(PGDKDrawable(GdkWindow),GC,
GdkImage,0,0,0,0,ImgWidth,ImgHeight);
gdk_gc_unref(GC);
gdk_image_destroy(GdkImage);
end else begin
GDkWindow := gdk_pixmap_new(DefGdkWindow,
RawImage.Description.Width,RawImage.Description.Height,
RawImage.Description.Depth);
end;
GdiObject^.GDIPixmapObject := GDkWindow;
GdiObject^.Visual := gdk_window_get_visual(GdiObject^.GDIPixmapObject);
gdk_visual_ref(GdiObject^.Visual);
GdiObject^.SystemVisual := False;
end;
// if we are here the bitmap was created successfully
Bitmap:=HBITMAP(GdiObject);
// create mask
if (AlwaysCreateMask or (not RawImageMaskIsEmpty(@RawImage,true)))
and (RawImage.Mask<>nil) then begin
{$IFDEF VerboseRawImage}
DebugLn('TGtkWidgetSet.CreateBitmapFromRawImage creating mask .. ');
{$ENDIF}
GdiObject^.GDIBitmapMaskObject :=
gdk_bitmap_create_from_data(DefGdkWindow,PGChar(RawImage.Mask),
RawImage.Description.Width, RawImage.Description.Height);
end;
except
if Bitmap<>0 then DeleteObject(Bitmap);
Bitmap:=0;
if MaskBitmap<>0 then DeleteObject(MaskBitmap);
MaskBitmap:=0;
exit;
end;
Result:=true;
end;
{------------------------------------------------------------------------------
Function: CreateBrushIndirect
Params: none
Returns: Nothing
------------------------------------------------------------------------------}
function TGtkWidgetSet.CreateBrushIndirect(const LogBrush: TLogBrush): HBRUSH;
const
//HATCH_NULL : array[0..7] of Byte = ($00, $00, $00, $00, $00, $00, $00, $00);
HATCH_BDIAGONAL : array[0..7] of Byte = ($80, $40, $20, $10, $08, $04, $02, $01);
HATCH_CROSS : array[0..7] of Byte = ($08, $08, $08, $FF, $08, $08, $08, $08);
{This is too fine for a Cross Hatch ($22, $22, $FF, $22, $22, $22, $FF, $22);}
HATCH_DIAGCROSS : array[0..7] of Byte = ($81, $42, $24, $18, $18, $24, $42, $81);
HATCH_FDIAGONAL : array[0..7] of Byte = ($01, $02, $04, $08, $10, $20, $40, $80);
HATCH_HORIZONTAL: array[0..7] of Byte = ($00, $00, $00, $FF, $00, $00, $00, $00);
HATCH_VERTICAL : array[0..7] of Byte = ($08, $08, $08, $08, $08, $08, $08, $08);
var
GObject: PGdiObject;
begin
Assert(False, Format('Trace:> [TGtkWidgetSet.CreateBrushIndirect] Style: %d, Color: %8x', [LogBrush.lbStyle, LogBrush.lbColor]));
{$IFDEF DebugGDKTraps}
BeginGDKErrorTrap;
{$ENDIF}
//write('CreateBrushIndirect->');
GObject := NewGDIObject(gdiBrush);
try
{$IFDEF DebugGDIBrush}
DebugLn('[TGtkWidgetSet.CreateBrushIndirect] ',DbgS(GObject));
{$ENDIF}
GObject^.IsNullBrush := False;
with LogBrush do
begin
case lbStyle of
// BS_HOLLOW, // Hollow brush.
BS_NULL: // Same as BS_HOLLOW.
begin
//GObject^.GDIBrushFill := GDK_STIPPLED;
//GObject^.GDIBrushPixmap :=
// gdk_bitmap_create_from_data(nil, @HATCH_NULL, 8, 8);
GObject^.IsNullBrush := True;
end;
BS_SOLID: // Solid brush.
begin
GObject^.GDIBrushFill := GDK_SOLID;
end;
BS_HATCHED: // Hatched brush.
begin
GObject^.GDIBrushFill := GDK_STIPPLED;
case lbHatch of
HS_BDIAGONAL:
GObject^.GDIBrushPixmap := gdk_bitmap_create_from_data(
nil, @HATCH_BDIAGONAL, 8, 8);
HS_CROSS:
GObject^.GDIBrushPixmap := gdk_bitmap_create_from_data(
nil, @HATCH_CROSS, 8, 8);
HS_DIAGCROSS:
GObject^.GDIBrushPixmap := gdk_bitmap_create_from_data(
nil, @HATCH_DIAGCROSS, 8, 8);
HS_FDIAGONAL:
GObject^.GDIBrushPixmap := gdk_bitmap_create_from_data(
nil, @HATCH_FDIAGONAL, 8, 8);
HS_HORIZONTAL:
GObject^.GDIBrushPixmap := gdk_bitmap_create_from_data(
nil, @HATCH_HORIZONTAL, 8, 8);
HS_VERTICAL:
GObject^.GDIBrushPixmap := gdk_bitmap_create_from_data(
nil, @HATCH_VERTICAL, 8, 8);
else
RaiseGDBException('invalid lbHatch');
end;
end;
BS_DIBPATTERN, // A pattern brush defined by a device-independent
// bitmap (DIB) specification. If lbStyle is BS_DIBPATTERN, the
// lbHatch member contains a handle to a packed DIB.Windows 95:
// Creating brushes from bitmaps or DIBs larger than 8x8 pixels
// is not supported. If a larger bitmap is given, only a portion
// of the bitmap is used.
BS_DIBPATTERN8X8, // Same as BS_DIBPATTERN.
BS_DIBPATTERNPT, // A pattern brush defined by a device-independent
// bitmap (DIB) specification. If lbStyle is BS_DIBPATTERNPT, the
// lbHatch member contains a pointer to a packed DIB.
BS_PATTERN, // Pattern brush defined by a memory bitmap.
BS_PATTERN8X8: // Same as BS_PATTERN.
begin
GObject^.GDIBrushFill := GDK_TILED;
if IsValidGDIObject(lbHatch)
and (PGdiObject(lbHatch)^.GDIType = gdiBitmap)
then
GObject^.GDIBrushPixmap := PGdiObject(lbHatch)^.GDIBitmapObject
else
RaiseGDBException('unsupported bitmap');
end;
else
RaiseGDBException(Format('unsupported Style %d',[lbStyle]));
end;
{$IFDEF DebugGDKTraps}
EndGDKErrorTrap;
{$ENDIF}
If not GObject^.IsNullBrush then
SetGDIColorRef(GObject^.GDIBrushColor,lbColor);
end;
Result := HBRUSH(GObject);
except
Result:=0;
DisposeGDIObject(GObject);
DebugLn('TGtkWidgetSet.CreateBrushIndirect failed');
end;
Assert(False, Format('Trace:< [TGtkWidgetSet.CreateBrushIndirect] Got --> %x', [Result]));
end;
{------------------------------------------------------------------------------
Function: CreateCaret
Params: none
Returns: Nothing
------------------------------------------------------------------------------}
function TGtkWidgetSet.CreateCaret(Handle: HWND; Bitmap: hBitmap;
Width, Height: Integer): Boolean;
var
GTKObject: PGTKObject;
BMP: PGDKPixmap;
begin
Assert(False, 'Trace:TODO: [TGtkWidgetSet.CreateCaret] Finish');
GTKObject := PGTKObject(Handle);
Result := GTKObject <> nil;
if Result then begin
if gtk_type_is_a(gtk_object_type(GTKObject), GTKAPIWidget_GetType)
then begin
if IsValidGDIObjectType(Bitmap, gdiBitmap) then
BMP := PGdiObject(Bitmap)^.GDIBitmapObject
else
BMP := nil;
GTKAPIWidget_CreateCaret(PGTKAPIWidget(GTKObject), Width, Height, BMP);
end
// else if // TODO: other widgettypes
else begin
Result := False;
end;
end
else Assert(False, 'Trace:WARNING: [TGtkWidgetSet.CreateCaret] Got null HWND');
end;
{------------------------------------------------------------------------------
Function: CreateCompatibleBitmap
Params: DC:
Width:
Height:
Returns:
Creates a bitmap compatible with the specified device context.
------------------------------------------------------------------------------}
function TGtkWidgetSet.CreateCompatibleBitmap(DC: HDC;
Width, Height: Integer): HBITMAP;
var
Depth : Longint;
GDIObject: PGdiObject;
DefGdkWindow: PGDkWindow;
begin
Assert(False, Format('Trace:> [TGtkWidgetSet.CreateCompatibleBitmap] DC: 0x%x, W: %d, H: %d', [DC, Width, Height]));
Depth := -1;
{$IFDEF DebugGDKTraps}
BeginGDKErrorTrap;
{$ENDIF}
if (IsValidDC(DC) and (TDeviceContext(DC).Drawable <> nil)) then begin
DefGdkWindow := TDeviceContext(DC).Drawable;
Depth := gdk_drawable_get_depth(TDeviceContext(DC).Drawable);
end else
DefGdkWindow:=nil;
If Depth = -1 then
Depth := gdk_visual_get_system^.Depth;
if Depth <> -1 then begin
if (Depth < 1) or (Depth > 32)
then begin
Result := 0;
DebugLn(Format('ERROR: [TGtkWidgetSet.CreateCompatibleBitmap] Illegal depth %d', [Depth]));
{$IFDEF DebugGDKTraps}
EndGDKErrorTrap;
{$ENDIF}
Exit;
end;
GdiObject := NewGDIObject(gdiBitmap);
If Depth = 1 then begin
GdiObject^.GDIBitmapType := gbBitmap;
GdiObject^.GDIBitmapObject :=
gdk_pixmap_new(DefGdkWindow, Width, Height, Depth);
GdiObject^.Visual := gdk_window_get_visual(GdiObject^.GDIPixmapObject);
end
else begin
GdiObject^.GDIBitmapType := gbPixmap;
GdiObject^.GDIPixmapObject :=
gdk_pixmap_new(DefGdkWindow, Width, Height, Depth);
GdiObject^.Visual := gdk_window_get_visual(GdiObject^.GDIPixmapObject);
end;
If GdiObject^.Visual = nil then begin
GdiObject^.Visual := gdk_visual_get_best_with_depth(Depth);
If GdiObject^.Visual = nil then
GdiObject^.Visual := gdk_visual_get_system;
GdiObject^.SystemVisual := True;
end
else begin
gdk_visual_ref(GdiObject^.Visual);
GdiObject^.SystemVisual := False;
end;
GdiObject^.Colormap := gdk_colormap_new(GdiObject^.Visual, GdkTrue);
{$IFDEF DebugGDKTraps}
EndGDKErrorTrap;
{$ENDIF}
Result := HBITMAP(GdiObject);
end else
Result := 0;
Assert(False, Format('Trace:< [TGtkWidgetSet.CreateCompatibleBitmap] DC: 0x%x --> 0x%x', [DC, Result]));
end;
{------------------------------------------------------------------------------
Function: CreateCompatibleDC
Params: none
Returns: Nothing
------------------------------------------------------------------------------}
function TGtkWidgetSet.CreateCompatibleDC(DC: HDC): HDC;
var
pNewDC: TDeviceContext;
begin
Result := 0;
pNewDC := NewDC;
// dont copy
// In a compatible DC you have to select a bitmap into it
(*
if IsValidDC(DC) then
with TDeviceContext(DC)^ do
begin
pNewDC^.hWnd := hWnd;
pNewDC^.Drawable := Drawable;
pNewDC^.GC := gdk_gc_new(Drawable);
end
else begin
// We can't do anything yet
// Wait till a bitmap get selected
end;
*)
pNewDC.CurrentFont := CreateDefaultFont;
pNewDC.CurrentBrush := CreateDefaultBrush;
pNewDC.CurrentPen := CreateDefaultPen;
Result := HDC(pNewDC);
Assert(False,Format('trace: [TGtkWidgetSet.CreateCompatibleDC] DC: 0x%x --> 0x%x', [Integer(DC), Integer(Result)]));
end;
{------------------------------------------------------------------------------
Function: CreateFontIndirect
Params: const LogFont: TLogFont
Returns: HFONT
Creates a font GDIObject.
------------------------------------------------------------------------------}
function TGtkWidgetSet.CreateFontIndirect(const LogFont: TLogFont): HFONT;
begin
Result:=CreateFontIndirectEx(LogFont,'');
end;
{------------------------------------------------------------------------------
Function: CreateFontIndirectEx
Params: const LogFont: TLogFont; const LongFontName: string
Returns: HFONT
Creates a font GDIObject.
------------------------------------------------------------------------------}
function TGtkWidgetSet.CreateFontIndirectEx(const LogFont: TLogFont;
const LongFontName: string): HFONT;
{$IfDef GTK2}
begin
DebugLn('ToDo: TGtkWidgetSet.CreateFontIndirectEx');
Result:=0;
end;
{$Else}
var
GdiObject: PGdiObject;
FontNameRegistry, Foundry, FamilyName, WeightName,
Slant, SetwidthName, AddStyleName, PixelSize,
PointSize, ResolutionX, ResolutionY, Spacing, AverageWidth,
CharSetRegistry, CharSetCoding: string;
n: Integer;
sn, cs: Float;
CachedFont: TGdkFontCacheDescriptor;
function LoadFont: boolean;
var
S: string;
Desc: TGdkFontCacheDescriptor;
begin
S:=FontNameRegistry+'-'+Foundry+'-'+FamilyName+'-'+WeightName
+'-'+Slant+'-'+SetwidthName+'-'+AddStyleName+'-'+PixelSize
+'-'+PointSize+'-'+ResolutionX+'-'+ResolutionY+'-'+Spacing+'-'+AverageWidth
+'-'+CharSetRegistry+'-'+CharSetCoding;
{ MG: heaptrc gets corrupted heap using the construction below:
S := Format('%s-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s',
[FontNameRegistry, Foundry, FamilyName, WeightName,
Slant, SetwidthName, AddStyleName, PixelSize,
PointSize, ResolutionX, ResolutionY, Spacing, AverageWidth,
CharSetRegistry, CharSetCoding
]);}
//DebugLn(' Trying "',S,'"');
{S:=FontNameRegistry+','+Foundry+','+FamilyName+','+WeightName
+','+Slant+','+SetwidthName+','+AddStyleName+','+PixelSize
+','+PointSize+','+ResolutionX+','+ResolutionY+','+Spacing+','+AverageWidth
+','+CharSetRegistry+','+CharSetCoding;
DebugLn(' Trying B "',S,'"');}
GdiObject^.GDIFontObject := gdk_font_load(PChar(s));
Result:=GdiObject^.GDIFontObject<>nil;
if Result then begin
Desc:=FontCache.Add(GdiObject^.GDIFontObject,LogFont,LongFontName);
if Desc<>nil then
Desc.xlfd:=s;
end;
{$IFDEF VerboseFonts}
//if GdiObject^.GDIFontObject<>nil then
DebugLn(' Tried "',S,'" Success=',dbgs(GdiObject^.GDIFontObject<>nil));
{$ENDIF}
end;
procedure LoadDefaultFont;
begin
DisposeGDIObject(GdiObject);
GdiObject:=CreateDefaultFont;
{$IFDEF VerboseFonts}
DebugLn('TGtkWidgetSet.CreateFontIndirectEx.LoadDefaultFont');
{$ENDIF}
end;
function GetDefaultFontFamilyName: string;
begin
Result:=GetDefaultFontName;
if IsFontNameXLogicalFontDesc(Result) then
Result := ExtractXLFDItem(LongFontName,2);
if Result='' then Result:='*';
end;
function ExtractXLFDItemMask(const ALongFontName: string;
Index: Integer): string;
begin
Result:=ExtractXLFDItem(ALongFontName,Index);
if Result='' then Result:='*';
end;
function FamilyNameExists: boolean;
var
AFont: PGdkFont;
S: String;
begin
S := '*-*-'+FamilyName+'*-*-*-*-*-*-*-*-*-*-*-*-*';
AFont:=gdk_font_load(PChar(s));
Result:=AFont<>nil;
if Result then gdk_font_unref(AFont);
end;
function CheckFontNameIsMangledXLogicalFontDesc(const ALongFontName: string
): boolean;
var
c: Integer;
i: Integer;
begin
c:=0;
for i:=1 to length(ALongFontName) do
if ALongFontName[i]='-' then inc(c);
Result:=(c>5) and (c<>14);
if Result then
debugln('WARNING: Fontnamt "',ALongFontName,'" seems to be a XLFD fontname, but has 14<>',dbgs(c),' minus signs');
end;
begin
// For info about xlfd see:
// http://wwwinfo.cern.ch/umtf/working-groups/X11/fonts/hp_xlfd.html
// Lets fill in all the xlfd parts. Assume we have scalable fonts.
{$IFDEF VerboseFonts}
DebugLn('TGtkWidgetSet.CreateFontIndirectEx A Name=',LogFont.lfFaceName,' Height=',dbgs(LogFont.lfHeight),' LongName=',LongFontName);
{$ENDIF}
Result := 0;
GDIObject := NewGDIObject(gdiFont);
try
GdiObject^.LogFont := LogFont;
CachedFont:=FontCache.FindGDKFontDesc(LogFont,LongFontName);
if CachedFont<>nil then begin
CachedFont.Item.IncreaseRefCount;
GdiObject^.GDIFontObject := TGdkFontCacheItem(CachedFont.Item).GdkFont;
exit;
end;
// set default values
FontNameRegistry := '*';
Foundry := '*';
FamilyName := '*';
WeightName := '*';
Slant := '*';
SetwidthName := '*';
AddStyleName := '*';
PixelSize := '*';
PointSize := '*';
ResolutionX := '*';
ResolutionY := '*';
Spacing := '*';
AverageWidth := '*';
CharSetRegistry := '*';
CharSetCoding := '*';
// check if LongFontName is in XLFD format and get nicer defaults
// This way, the user can set X fonts that are not supported by TFont.
{$IFDEF VerboseFonts}
DebugLn('TGtkWidgetSet.CreateFontIndirectEx Name="',LogFont.lfFaceName,'"',
' Long="',LongFontName,'" IsXLFD=',dbgs(IsFontNameXLogicalFontDesc(LongFontName))
,' ',dbgs(ord(LogFont.lfFaceName[0])));
{$ENDIF}
if IsFontNameXLogicalFontDesc(LongFontName) then begin
FontNameRegistry := ExtractXLFDItemMask(LongFontName,0);
Foundry := ExtractXLFDItemMask(LongFontName,1);
FamilyName := ExtractXLFDItemMask(LongFontName,2);
WeightName := ExtractXLFDItemMask(LongFontName,3);
Slant := ExtractXLFDItemMask(LongFontName,4);
SetWidthName := ExtractXLFDItemMask(LongFontName,5);
AddStyleName := ExtractXLFDItemMask(LongFontName,6);
PixelSize := ExtractXLFDItemMask(LongFontName,7);
PointSize := ExtractXLFDItemMask(LongFontName,8);
ResolutionX := ExtractXLFDItemMask(LongFontName,9);
ResolutionY := ExtractXLFDItemMask(LongFontName,10);
Spacing := ExtractXLFDItemMask(LongFontName,11);
AverageWidth := ExtractXLFDItemMask(LongFontName,12);
CharSetRegistry := ExtractXLFDItemMask(LongFontName,13);
CharSetCoding := ExtractXLFDItemMask(LongFontName,14);
end else if CheckFontNameIsMangledXLogicalFontDesc(LongFontName) then begin
end;
with LogFont do
begin
if lfFaceName[0] = #0
then begin
Assert(false,'ERROR: [TGtkWidgetSet.CreateFontIndirectEx] No fontname');
Exit;
end;
FamilyName := StrPas(lfFaceName); //StringReplace(FaceName, ' ', '*');
if (CompareText(FamilyName,'default')<>0)
and (not FamilyNameExists) then begin
FamilyName:='default';
end;
if CompareText(FamilyName,'default')=0 then begin
{$IFDEF VerboseFonts}
DebugLn('TGtkWidgetSet.CreateFontIndirectEx FamilyName="',FamilyName,'" PixelSize=',PixelSize,' LogFont.lfHeight=',LogFont.lfHeight);
{$ENDIF}
if (LogFont.lfHeight=0) then begin
LoadDefaultFont;
exit;
end else begin
FamilyName:=GetDefaultFontFamilyName;
Foundry:='*';
end;
end;
Assert(False, Format('trace: [TGtkWidgetSet.CreateFontIndirectEx] Name: %s, Height: %d', [FamilyName, lfHeight]));
// calculate weight offset.
// API XLFD
// --------------------- --------------
// Weight=400 --> normal normal
// Weight=700 --> bold normal+4000 (or bold in non scalable fonts)
//
// So in API the offset for normal = 400 and an increase of 300 equals to
// an offset of 4000
if WeightName='*' then begin
case lfWeight of
FW_DONTCARE : WeightName := '*';
FW_LIGHT : WeightName := 'light';
FW_NORMAL : WeightName := 'normal';
FW_MEDIUM : WeightName := 'medium';
FW_SEMIBOLD : WeightName := 'demi bold';
FW_BOLD : WeightName := 'bold';
else begin
n := ((lfWeight - FW_NORMAL) * 4000) div (FW_BOLD - FW_NORMAL);
if n = 0
then WeightName := 'normal'
else if n > 0
then WeightName := Format('normal+%d', [n])
else WeightName := Format('normal%d', [n]);
end;
end;
end;
if Slant='*' then begin
// TODO: find out if escapement has something to do with slant
if lfItalic = 0 then Slant := 'r' else Slant := 'i';
end;
// SetWidthName := '*';
{$IFDEF OLD_ROTATION}
if AddStyleName='*' then begin
// calculate Style name extentions (=rotation)
// API XLFD
// --------------------- --------------
// Orientation 1/10 deg 1/64 deg
if lfOrientation = 0
then AddStyleName := '*'
else begin
n := (lfOrientation * 64) div 10;
if n >= 0
then AddStyleName := Format('+%d', [n])
else AddStyleName := Format('+%d', [n]);
end;
end;
{$ENDIF}
if (PixelSize='*') and (PointSize='*') then begin
// TODO: make more accurate (implement the meaning of
// positive and negative height values.
PixelSize := IntToStr(Abs(lfHeight));
{$IFNDEF OLD_ROTATION}
if lfOrientation <> 0 then begin
SinCos(lfOrientation/1800.*Pi, sn, cs);
cs := cs*Abs(lfHeight);
sn := sn*Abs(lfHeight);
PixelSize := Format('[%.3f %.3f %.3f %.3f]', [cs, sn, -sn, cs]);
repeat
n := Pos('-', PixelSize);
if n > 0 then
PixelSize[n] := '~';
until n <= 0;
end;
{$ENDIF}
// Since we use pixelsize, it isn't allowed to give a value here
PointSize := '*';
// Use the default
ResolutionX := '*';
ResolutionY := '*';
end;
if Spacing='*' then begin
// spacing
if (FIXED_PITCH and lfPitchAndFamily)>0 then
Spacing := 'm' // mono spaced
else if (VARIABLE_PITCH and lfPitchAndFamily)>0 then
Spacing := 'p' // proportional spaced
else
Spacing := '*';
end;
if AverageWidth='*' then begin
// calculate AverageWidth
// API XLFD
// --------------------- --------------
// Width pixel 1/10 pixel
if lfWidth = 0
then AverageWidth := '*'
else AverageWidth := InttoStr(lfWidth * 10);
end;
if CharSetCoding = '*' then begin
case lfCharset of
FCS_ISO_10646_1: begin
CharSetRegistry:='iso10646';
CharSetCoding:='1';
end;
fcs_ISO_8859_1: begin
CharSetRegistry:='iso8859';
CharSetCoding:='1';
end;
fcs_ISO_8859_2: begin
CharSetRegistry:='iso8859';
CharSetCoding:='2';
end;
fcs_ISO_8859_3: begin
CharSetRegistry:='iso8859';
CharSetCoding:='3';
end;
fcs_ISO_8859_4: begin
CharSetRegistry:='iso8859';
CharSetCoding:='4';
end;
fcs_ISO_8859_5: begin
CharSetRegistry:='iso8859';
CharSetCoding:='5';
end;
fcs_ISO_8859_6: begin
CharSetRegistry:='iso8859';
CharSetCoding:='6';
end;
fcs_ISO_8859_7: begin
CharSetRegistry:='iso8859';
CharSetCoding:='7';
end;
fcs_ISO_8859_8: begin
CharSetRegistry:='iso8859';
CharSetCoding:='8';
end;
fcs_ISO_8859_9: begin
CharSetRegistry:='iso8859';
CharSetCoding:='9';
end;
fcs_ISO_8859_10: begin
CharSetRegistry:='iso8859';
CharSetCoding:='10';
end;
fcs_ISO_8859_15: begin
CharSetRegistry:='iso8859';
CharSetCoding:='15';
end;
end;
end;
end;
{$IFDEF VerboseFonts}
write('CreateFontIndirect->');
{$ENDIF}
if LoadFont then exit;
if (WeightName='normal') then begin
WeightName:='medium';
if LoadFont then exit;
end else if (WeightName='bold') then begin
WeightName:='black';
if LoadFont then exit;
end;
if (WeightName='medium') then begin
WeightName:='regular';
if LoadFont then exit;
end else if (WeightName='black') then begin
WeightName:='demi bold';
if LoadFont then exit;
end;
// try all weights
WeightName := '*';
if LoadFont then exit;
// try one height lower
PixelSize := IntToStr(Abs(LogFont.lfHeight)-1);
if LoadFont then exit;
// try one height higher
PixelSize := IntToStr(Abs(LogFont.lfHeight)+1);
if LoadFont then exit;
PixelSize := IntToStr(Abs(LogFont.lfHeight));
// try instead of mono spaced -> character cell spaced
if (Spacing='m') then begin
Spacing:='c';
if LoadFont then exit;
end;
// try instead of italic -> oblique
if (Slant='i') then begin
Slant := 'o';
if LoadFont then exit;
end;
// try all slants
Slant := '*';
if LoadFont then exit;
// try all spacings
if spacing<>'*' then begin
Spacing := '*';
if LoadFont then exit;
end;
if charSetCoding<>'*' then begin
charsetCoding := '*';
charSetRegistry:= '*';
if LoadFont then exit;
end;
if (Foundry<>'*') then begin
// try all Families
PixelSize := IntToStr(Abs(LogFont.lfHeight));
FamilyName := '*';
if LoadFont then exit;
end;
// nothing exists -> use default
LoadDefaultFont;
finally
if GdiObject^.GDIFontObject = nil
then begin
{$IFDEF VerboseFonts}
DebugLn('[TGtkWidgetSet.CreateFontIndirect] ',DbgS(GdiObject),' ',FGDIObjects.Count);
{$ENDIF}
DisposeGDIObject(GdiObject);
Result := 0;
end
else begin
Result := HFONT(GdiObject);
end;
if Result = 0
then DebugLn('WARNING: [TGtkWidgetSet.CreateFontIndirectEx] NOT found XLFD: <'+LongFontName+'> Fontname="'+LogFont.lfFaceName+'"')
else Assert(False, Format('Trace: [TGtkWidgetSet.CreateFontIndirectEx] found XLFD: <%s>', [LongFontName]));
end;
end;
{$EndIf}
{------------------------------------------------------------------------------
Function: CreatePalette
Params: LogPalette
Returns: a handle to the Palette created
------------------------------------------------------------------------------}
function TGtkWidgetSet.CreatePalette(const LogPalette: TLogPalette): HPALETTE;
var
GObject: PGdiObject;
begin
Assert(False, 'trace:[TGtkWidgetSet.CreatePalette]');
GObject := NewGDIObject(gdiPalette);
GObject^.SystemPalette := False;
GObject^.PaletteRealized := False;
GObject^.VisualType := GDK_VISUAL_PSEUDO_COLOR;
GObject^.PaletteVisual := nil;
{$IFDEF DebugGDKTraps}
BeginGDKErrorTrap;
{$ENDIF}
GObject^.PaletteVisual := gdk_visual_get_best_with_type(GObject^.VisualType);
if GObject^.PaletteVisual = nil
then begin
GObject^.PaletteVisual := GDK_Visual_Get_System;
GDK_Visual_Ref(GObject^.PaletteVisual);
end;
GObject^.PaletteColormap := GDK_Colormap_new(GObject^.PaletteVisual, GdkTrue);
{$IFDEF DebugGDKTraps}
EndGDKErrorTrap;
{$ENDIF}
GObject^.RGBTable := TDynHashArray.Create(-1);
GObject^.RGBTable.OnGetKeyForHashItem:=@GetRGBAsKey;
GObject^.IndexTable := TDynHashArray.Create(-1);
GObject^.IndexTable.OnGetKeyForHashItem:=@GetIndexAsKey;
InitializePalette(GObject, LogPalette.palPalEntry, LogPalette.palNumEntries);
Result := HPALETTE(GObject);
end;
{------------------------------------------------------------------------------
Function: CreatePenIndirect
Params: none
Returns: Nothing
------------------------------------------------------------------------------}
function TGtkWidgetSet.CreatePenIndirect(const LogPen: TLogPen): HPEN;
var
GObject: PGdiObject;
begin
Assert(False, 'trace:[TGtkWidgetSet.CreatePenIndirect]');
//write('CreatePenIndirect->');
GObject := NewGDIObject(gdiPen);
with LogPen do
begin
GObject^.GDIPenStyle := lopnStyle;
GObject^.GDIPenWidth := lopnWidth.X;
SetGDIColorRef(GObject^.GDIPenColor,lopnColor);
end;
Result := HPEN(GObject);
end;
{------------------------------------------------------------------------------
Function: CreatePixmapIndirect
Params: Data: Raw pixmap data (PPGChar of xpm file,
You can use graphics.XPMToPPChar to create this)
Returns: Handle to LCL bitmap
Creates a bitmap from raw pixmap data.
If TransColor < 0 the transparency mask will be automatically gnerated.
------------------------------------------------------------------------------}
function TGtkWidgetSet.CreatePixmapIndirect(const Data: Pointer;
const TransColor: Longint): HBITMAP;
var
GdiObject: PGdiObject;
GDKColor: TGDKColor;
Window: PGdkWindow;
ColorMap: PGdkColormap;
P: Pointer;
Depth : Longint;
begin
GdiObject := NewGDIObject(gdiBitmap);
if TransColor >= 0 then begin
GDKColor := AllocGDKColor(TransColor);
p := @GDKColor;
end else
p:=nil; // automatically create transparency mask
Window:=nil; // use the X root window for colormap
{$IFDEF DebugGDKTraps}
BeginGDKErrorTrap;
{$ENDIF}
if Window<>nil then
ColorMap:=gdk_window_get_colormap(Window)
else
ColorMap:=gdk_colormap_get_system;
try
GdiObject^.GDIPixmapObject :=
gdk_pixmap_colormap_create_from_xpm_d(Window,Colormap,
GdiObject^.GDIBitmapMaskObject, p, Data);
Depth := gdk_drawable_get_depth(GdiObject^.GDIPixmapObject);
If GdiObject^.Visual <> nil then
GDK_Visual_UnRef(GdiObject^.Visual);
GdiObject^.Visual := gdk_window_get_visual(GdiObject^.GDIPixmapObject);
If GdiObject^.Visual = nil then begin
GdiObject^.Visual := gdk_visual_get_best_with_depth(Depth);
If GdiObject^.Visual = nil then
GdiObject^.Visual := gdk_visual_get_system;
GdiObject^.SystemVisual := True;
end
else begin
gdk_visual_ref(GdiObject^.Visual);
GdiObject^.SystemVisual := False;
end;
If GdiObject^.Colormap <> nil then
GDK_Colormap_UnRef(GdiObject^.Colormap);
GdiObject^.Colormap := gdk_colormap_new(GdiObject^.Visual, GdkFalse);
GdiObject^.GDIBitmapType:=gbPixmap;
except
DisposeGDIObject(GdiObject);
GdiObject:=nil;
end;
{$IFDEF DebugGDKTraps}
EndGDKErrorTrap;
{$ENDIF}
Result := HBITMAP(GdiObject);
end;
{------------------------------------------------------------------------------
Method: CreatePolygonRgn
Params: Points, NumPts, FillMode
Returns: the handle to the region
Creates a Polygon, a closed many-sided shaped region. The Points parameter is
an array of points that give the vertices of the polygon. FillMode=Winding
determines what points are going to be included in the region. When Winding
is True, points are selected by using the Winding fill algorithm. When Winding
is False, points are selected by using using the even-odd (alternative) fill
algorithm. NumPts indicates the number of points to use.
The first point is always connected to the last point.
------------------------------------------------------------------------------}
Function TGtkWidgetSet.CreatePolygonRgn(Points: PPoint; NumPts: Integer;
FillMode: integer): HRGN;
var
i: integer;
PointArray: PGDKPoint;
GObject: PGdiObject;
fr : TGDKFillRule;
begin
Result := 0;
if NumPts<=0 then exit;
GObject := NewGDIObject(gdiRegion);
GetMem(PointArray,SizeOf(TGdkPoint)*NumPts);
for i:=0 to NumPts-1 do begin
PointArray[i].x:=Points[i].x;
PointArray[i].y:=Points[i].y;
end;
If FillMode=Winding then
fr := GDK_WINDING_RULE
else
fr := GDK_EVEN_ODD_RULE;
GObject^.GDIRegionObject := gdk_region_polygon(PointArray, NumPts, fr);
FreeMem(PointArray);
Result := HRGN(GObject);
end;
{------------------------------------------------------------------------------
Function: CreateRectRgn
Params: none
Returns: Nothing
------------------------------------------------------------------------------}
function TGtkWidgetSet.CreateRectRgn(X1,Y1,X2,Y2 : Integer): HRGN;
var
R: TGDKRectangle;
RRGN: PGDKRegion;
GObject: PGdiObject;
RegionObj: PGdkRegion;
begin
GObject := NewGDIObject(gdiRegion);
if X1<=X2 then begin
R.X := gint16(X1);
R.Width := X2 - X1;
end else begin
R.X := gint16(X2);
R.Width := X1 - X2;
end;
if Y1<=Y2 then begin
R.Y := gint16(Y1);
R.Height := Y2 - Y1;
end else begin
R.Y := gint16(Y2);
R.Height := Y1 - Y1;
end;
RRGN := gdk_region_new;
RegionObj:=PGdkRegion(gdk_region_union_with_rect(RRGN,@R));
GObject^.GDIRegionObject := RegionObj;
gdk_region_destroy(RRGN);
Result := HRGN(GObject);
//DebugLn('TGtkWidgetSet.CreateRectRgn A ',GDKRegionAsString(RegionObj));
end;
{------------------------------------------------------------------------------
Function: CombineRgn
Params: Dest, Src1, Src2, fnCombineMode
Returns: longint
Combine the 2 Source Regions into the Destination Region using the specified
Combine Mode. The Destination must already be initialized. The Return value
is the Destination's Region type, or ERROR.
The Combine Mode can be one of the following:
RGN_AND : Gets a region of all points which are in both source regions
RGN_COPY : Gets an exact copy of the first source region
RGN_DIFF : Gets a region of all points which are in the first source
region but not in the second.(Source1 - Source2)
RGN_OR : Gets a region of all points which are in either the first
source region or in the second.(Source1 + Source2)
RGN_XOR : Gets all points which are in either the first Source Region
or in the second, but not in both.
The result can be one of the following constants
Error
NullRegion
SimpleRegion
ComplexRegion
------------------------------------------------------------------------------}
Function TGtkWidgetSet.CombineRgn(Dest, Src1, Src2 : HRGN;
fnCombineMode : Longint) : Longint;
var
Continue : Boolean;
D, S1, S2 : PGDKRegion;
DObj, S1Obj, S2Obj : PGDIObject;
begin
Result := SIMPLEREGION;
DObj := PGdiObject(Dest);
S1Obj := PGdiObject(Src1);
S2Obj := PGdiObject(Src2);
Continue := IsValidGDIObject(Dest) and IsValidGDIObject(Src1)
and IsValidGDIObject(Src2);
If Not Continue then begin
DebugLn('WARNING: [TGtkWidgetSet.CombineRgn] Invalid HRGN');
Result := Error;
end
else begin
If DObj^.GDIRegionObject <> nil then begin
gdk_region_destroy(DObj^.GDIRegionObject);
DObj^.GDIRegionObject:=nil;
end;
S1 := S1Obj^.GDIRegionObject;
S2 := S2Obj^.GDIRegionObject;
//DebugLn('TGtkWidgetSet.CombineRgn A fnCombineMode=',fnCombineMode);
Case fnCombineMode of
RGN_AND :
D := PGDKRegion(gdk_region_intersect(S1, S2));
RGN_COPY :
D := gdk_region_copy(S1);
RGN_DIFF :
D := PGDKRegion(gdk_region_subtract(S1, S2));
RGN_OR :
D := PGDKRegion(gdk_region_union(S1, S2));
RGN_XOR :
D := PGDKRegion(gdk_region_xor(S1, S2));
else begin
Result:= ERROR;
D := nil;
end;
end;
DObj^.GDIRegionObject := D;
Result := RegionType(D);
//DebugLn('TGtkWidgetSet.CombineRgn B Mode=',fnCombineMode,
// ' S1=',GDKRegionAsString(S1),' S2=',GDKRegionAsString(S2),' D=',GDKRegionAsString(D),'');
end;
end;
{------------------------------------------------------------------------------
function TGtkWidgetSet.ComboBoxDropDown(Handle: HWND;
DropDown: boolean): boolean; override;
------------------------------------------------------------------------------}
function TGtkWidgetSet.ComboBoxDropDown(Handle: HWND; DropDown: boolean): boolean;
procedure gtk_combo_get_pos(combo : PGtkCombo; var x : gint; var y : gint;
var height : gint; var width : gint);
var
popwin : PGtkbin;
widget : PGtkWidget;
popup : PGtkScrolledwindow;
real_height : gint;
list_requisition : PGtkRequisition;
show_hscroll : gboolean;
show_vscroll : gboolean;
avail_height : gint;
min_height : gint;
alloc_width : gint;
work_height : gint;
old_height : gint;
old_width : gint;
okay_to_exit : boolean;
const
EMPTY_LIST_HEIGHT = 15;
begin
show_hscroll := False;
show_vscroll := False;
widget := GTK_WIDGET(combo);
popup := GTK_SCROLLED_WINDOW (combo^.popup);
popwin := GTK_BIN (combo^.popwin);
gdk_window_get_origin (combo^.entry^.window, @x, @y);
real_height := MIN (combo^.entry^.requisition.height,
combo^.entry^.allocation.height);
y := y + real_height;
avail_height := gdk_screen_height () - y;
New(list_requisition);
gtk_widget_size_request (combo^.list, list_requisition);
min_height := MIN (list_requisition^.height,popup^.vscrollbar^.requisition.height);
if GTK_LIST (combo^.list)^.children = nil then
list_requisition^.height := list_requisition^.height + EMPTY_LIST_HEIGHT;
alloc_width := (cardinal(widget^.allocation.width) -
2 * cardinal(gtk_widget_get_xthickness(gtk_bin_get_child(popwin))) -
2 * border_width(GTK_CONTAINER (gtk_bin_get_child(popwin))^) -
2 * border_width(GTK_CONTAINER (combo^.popup)^) -
2 * border_width(GTK_CONTAINER (gtk_bin_get_child(PGTKBin(popup)))^) -
2 * cardinal(gtk_widget_get_xthickness(gtk_bin_get_child(PGTKBin(popup)))));
work_height := (2 * cardinal(gtk_widget_get_ythickness(gtk_bin_get_child(popwin))) +
2 * border_width(GTK_CONTAINER (gtk_bin_get_child(popwin))^) +
2 * border_width(GTK_CONTAINER (combo^.popup)^) +
2 * border_width(GTK_CONTAINER (gtk_bin_get_child(PGTKBin(popup)))^) +
2 * cardinal(gtk_widget_get_xthickness(gtk_bin_get_child(PGTKBin(popup)))));
repeat
okay_to_exit := True;
old_width := alloc_width;
old_height := work_height;
if ((not show_hscroll) and (alloc_width < list_requisition^.width)) then
begin
work_height := work_height + popup^.hscrollbar^.requisition.height +
GTK_SCROLLED_WINDOW_CLASS(gtk_object_get_class(combo^.popup))^.scrollbar_spacing;
show_hscroll := TRUE;
okay_to_exit := False;
end;
if ((not show_vscroll) and (work_height + list_requisition^.height > avail_height)) then
begin
if ((work_height + min_height > avail_height) and (y - real_height > avail_height)) then
begin
y := y - (work_height + list_requisition^.height + real_height);
break;
end;
alloc_width := alloc_width -
popup^.vscrollbar^.requisition.width +
GTK_SCROLLED_WINDOW_CLASS(gtk_object_get_class(combo^.popup))^.scrollbar_spacing;
show_vscroll := TRUE;
okay_to_exit := False;
end;
until ((old_width <> alloc_width) or (old_height <> work_height) or okay_to_exit);
width := widget^.allocation.width;
if (show_vscroll) then
height := avail_height
else
height := work_height + list_requisition^.height;
if (x < 0) then
x := 0;
Dispose(list_requisition);
end;
var
ComboWidget: PGtkCombo;
height, width, x, y : gint;
old_width, old_height : gint;
begin
Result:=false;
if Handle=0 then exit;
ComboWidget:=PGtkCombo(Handle);
if DropDown<>GTK_WIDGET_VISIBLE(ComboWidget^.popwin) then begin
if DropDown then begin
old_width := ComboWidget^.popwin^.allocation.width;
old_height := ComboWidget^.popwin^.allocation.height;
gtk_combo_get_pos(ComboWidget,x,y,height,width);
if ((old_width <> width) or (old_height <> height)) then
begin
gtk_widget_hide (GTK_SCROLLED_WINDOW(ComboWidget^.popup)^.hscrollbar);
gtk_widget_hide (GTK_SCROLLED_WINDOW(ComboWidget^.popup)^.vscrollbar);
end;
gtk_widget_set_uposition (comboWidget^.popwin,x, y);
gtk_widget_set_usize(ComboWidget^.popwin,width ,height);
gtk_widget_realize(ComboWidget^.popwin);
{$IFDEF DebugGDKTraps}
BeginGDKErrorTrap;
{$ENDIF}
gdk_window_resize(ComboWidget^.popwin^.window,width,height);
{$IFDEF DebugGDKTraps}
EndGDKErrorTrap;
{$ENDIF}
gtk_widget_show (ComboWidget^.popwin);
gtk_widget_grab_focus(ComboWidget^.popwin);
end else
gtk_widget_hide (ComboWidget^.popwin);
end;
Result:=true;
end;
{------------------------------------------------------------------------------
Function: DeleteDC
Params: none
Returns: Nothing
------------------------------------------------------------------------------}
function TGtkWidgetSet.DeleteDC(hDC: HDC): Boolean;
begin
// TODO:
// for now it's just the same, however CreateDC/FreeDC
// and GetDC/ReleaseDC are couples
// we should use gdk_new_gc for create and gtk_new_gc for Get
Result:= (ReleaseDC(0, hDC) = 1);
end;
{------------------------------------------------------------------------------
Function: DeleteObject
Params: none
Returns: Nothing
------------------------------------------------------------------------------}
function TGtkWidgetSet.DeleteObject(GDIObject: HGDIOBJ): Boolean;
procedure RaiseInvalidGDIObject;
begin
RaiseGDBException('TGtkWidgetSet.DeleteObject invalid GdiObject='+DbgS(GdiObject));
end;
var
GDIObjectExists: boolean;
begin
if GDIObject=0 then begin
Result:=true;
exit;
end;
// Find out if we want to release internal GDI object
GDIObjectExists:=FGDIObjects.Contains(PGDIObject(GDIObject));
Result:=GDIObjectExists;
if not GDIObjectExists then begin
RaiseInvalidGDIObject;
end;
with PGdiObject(GDIObject)^ do
begin
case GDIType of
gdiFont:
begin
if GDIFontObject<>nil then begin
{$Ifdef GTK2}
pango_font_description_free(GDIFontObject);
{$Else}
FontCache.Unreference(GDIFontObject);
{$EndIf}
end;
end;
gdiBrush:
begin
{$IFDEF DebugGDKTraps}
BeginGDKErrorTrap;
{$ENDIF}
{$IFDEF DebugGDIBrush}
debugln('TGtkWidgetSet.DeleteObject gdiBrush: ',DbgS(GdiObject));
//if Cardinal(GdiObject)=$404826F4 then RaiseGDBException('');
{$ENDIF}
if (GDIBrushPixmap <> nil)
then gdk_bitmap_unref(GDIBrushPixmap);
{$IFDEF DebugGDKTraps}
EndGDKErrorTrap;
{$ENDIF}
FreeGDIColor(@GDIBrushColor);
end;
gdiBitmap:
begin
{$IFDEF DebugGDKTraps}
BeginGDKErrorTrap;
{$ENDIF}
if GDIBitmapObject <> nil then
gdk_bitmap_unref(GDIBitmapObject);
If (Visual <> nil) and (not SystemVisual) then
gdk_visual_unref(Visual);
If Colormap <> nil then
gdk_colormap_unref(Colormap);
{$IFDEF DebugGDKTraps}
EndGDKErrorTrap;
{$ENDIF}
end;
gdiPen:
begin
FreeGDIColor(@GDIPenColor);
end;
gdiRegion:
begin
if (GDIRegionObject <> nil) then
gdk_region_destroy(GDIRegionObject);
end;
gdiPalette:
begin
{$IFDEF DebugGDKTraps}
BeginGDKErrorTrap;
{$ENDIF}
If PaletteVisual <> nil then
gdk_visual_unref(PaletteVisual);
If PaletteColormap <> nil then
gdk_colormap_unref(PaletteColormap);
{$IFDEF DebugGDKTraps}
EndGDKErrorTrap;
{$ENDIF}
RGBTable.Free;
IndexTable.Free;
end;
else begin
Result:= false;
DebugLn('[TGtkWidgetSet.DeleteObject] TODO : Unimplemented GDI type');
Assert(False, 'Trace:TODO : Unimplemented GDI object in delete object');
end;
end;
end;
{ Dispose of the GDI object }
//DebugLn('[TGtkWidgetSet.DeleteObject] ',Result,' ',DbgS(GDIObject,8),' ',FGDIObjects.Count);
DisposeGDIObject(PGDIObject(GDIObject));
end;
{------------------------------------------------------------------------------
Function: DestroyCaret
Params: none
Returns: Nothing
------------------------------------------------------------------------------}
function TGtkWidgetSet.DestroyCaret(Handle: HWND): Boolean;
var
GTKObject: PGTKObject;
begin
GTKObject := PGTKObject(Handle);
Result := true;
if GTKObject<>nil then begin
if gtk_type_is_a(gtk_object_type(GTKObject), GTKAPIWidget_GetType)
then begin
GTKAPIWidget_DestroyCaret(PGTKAPIWidget(GTKObject));
end
// else if // TODO: other widgettypes
else begin
Result := False;
end;
end
else Assert(False, 'Trace:WARNING: [TGtkWidgetSet.DestroyCaret] Got null HWND');
end;
{------------------------------------------------------------------------------
Function: DrawFrameControl
Params:
Returns:
------------------------------------------------------------------------------}
function TGtkWidgetSet.DrawFrameControl(DC: HDC; var Rect : TRect;
uType, uState : Cardinal) : Boolean;
{const
ADJUST_FLAG: array[Boolean] of Integer = (0, BF_ADJUST);
PUSH_EDGE_FLAG: array[Boolean] of Integer = (EDGE_RAISED, EDGE_SUNKEN);
PUSH_EDGE_FLAG2: array[Boolean] of Integer = (0, BF_FLAT);}
var
Widget: PGtkWidget;
procedure DrawButtonPush;
var
State: TGtkStateType;
Shadow: TGtkShadowType;
aStyle : PGTKStyle;
aDC: TDeviceContext;
DCOrigin: TPoint;
begin
//if Widget<>nil then begin
// use the gtk paint functions to draw a widget style dependent button
//writeln('DrawButtonPush ',
// ' DFCS_BUTTONPUSH=',uState and DFCS_BUTTONPUSH,
// ' DFCS_PUSHED=',uState and DFCS_PUSHED,
// ' DFCS_INACTIVE=',uState and DFCS_INACTIVE,
// ' DFCS_FLAT=',uState and DFCS_FLAT,
// '');
// set State (the interior filling style)
if (DFCS_INACTIVE and uState)<>0 then begin
// button disabled
State:=GTK_STATE_INSENSITIVE;
end else begin
if (DFCS_PUSHED and uState)<>0 then begin
// button enabled, down
if (DFCS_CHECKED and uState)<>0 then begin
// button enabled, down, special (e.g. mouse over)
State:=GTK_STATE_ACTIVE;
end else begin
// button enabled, down, normal
State:=GTK_STATE_SELECTED;
end;
end else begin
// button enabled, up
if (DFCS_CHECKED and uState)<>0 then begin
// button enabled, up, special (e.g. mouse over)
State:=GTK_STATE_PRELIGHT;
end else begin
// button enabled, up, normal
State:=GTK_STATE_NORMAL;
end;
end;
end;
// set Shadow (the border style)
if (DFCS_PUSHED and uState)<>0 then begin
// button down
Shadow:=GTK_SHADOW_IN;
end else begin
if (((DFCS_FLAT+DFCS_CHECKED) and uState)=DFCS_FLAT) then begin
// button up, flat, no special
Shadow:=GTK_SHADOW_ETCHED_OUT;
//Shadow:=GTK_SHADOW_NONE;
end else begin
// button up
Shadow:=GTK_SHADOW_OUT;
end;
end;
aDC:=TDeviceContext(DC);
DCOrigin:=GetDCOffset(aDC);
aStyle := GetStyle(lgsButton);
If aStyle = nil then
aStyle := gtk_widget_get_style(Widget)
else begin
If State = GTK_STATE_SELECTED then
State := GTK_STATE_ACTIVE;
// MG: You can't assign a style to any window. Why it is needed anyway?
//aStyle := gtk_style_attach(gtk_style_ref(aStyle),aDC.Drawable);
end;
if aStyle<>nil then begin
If (Shadow=GTK_SHADOW_NONE) then
gtk_paint_flat_box(aStyle,aDC.Drawable,
State,
Shadow,
nil,
Widget,
'button',
Rect.Left+DCOrigin.X,Rect.Top+DCOrigin.Y,
Rect.Right-Rect.Left,Rect.Bottom-Rect.Top)
else
gtk_paint_box(aStyle,aDC.Drawable,
State,
Shadow,
nil,
Widget,
'button',
Rect.Left+DCOrigin.X,Rect.Top+DCOrigin.Y,
Rect.Right-Rect.Left,Rect.Bottom-Rect.Top);
end;
Result := True;
end;
procedure DrawCheck;
var
State: TGtkStateType;
Shadow: TGtkShadowType;
aDC: TDeviceContext;
DCOrigin: TPoint;
Style : PGTKStyle;
Widget : PGTKWidget;
begin
// use the gtk paint functions to draw a widget style dependent check(box)
if (DFCS_PUSHED and uState)<>0 then begin
STATE := GTK_STATE_ACTIVE;//button checked(GTK ignores disabled)
Shadow := GTK_SHADOW_IN;//checked style
end
else begin
Shadow := GTK_SHADOW_OUT; //unchecked style
if (DFCS_INACTIVE and uState)<>0 then begin
State:=GTK_STATE_INSENSITIVE;//button disabled
end else
if (DFCS_CHECKED and uState)<>0 then begin
// button enabled, special (e.g. mouse over)
State:=GTK_STATE_PRELIGHT;
end else begin
// button enabled, normal
State:=GTK_STATE_NORMAL;
end;
end;
aDC:=TDeviceContext(DC);
DCOrigin:=GetDCOffset(aDC);
Style := GetStyle(lgsCheckbox);
If Style = nil then
Style := GetStyle(lgsGTK_Default);
If Style <> nil then
Style := gtk_style_attach(gtk_style_ref(Style),aDC.Drawable);
Widget := GetStyleWidget(lgsCheckbox);
If Widget = nil then
Widget := GetStyleWidget(lgsDefault);
If (Widget <> nil) and (Style <> nil) then begin
Widget^.Window := aDC.Drawable;
if Style<>nil then
gtk_paint_check(Style,aDC.Drawable, State,
Shadow, nil, Widget, 'checkbutton',
Rect.Left+DCOrigin.X,Rect.Top+DCOrigin.Y,
Rect.Right-Rect.Left, Rect.Bottom-Rect.Top);
Result := True;
end
else begin
{$IfNDef Win32}
if Style<>nil then
gtk_draw_check(Style,aDC.Drawable, State,
Shadow, Rect.Left+DCOrigin.X,Rect.Top+DCOrigin.Y,
Rect.Right-Rect.Left, Rect.Bottom-Rect.Top);
{$EndIf}
Result := True;
end;
end;
var ClientWidget: PGtkWidget;
begin
Result := False;
if IsValidDC(DC) then begin
Widget:=PGtkWidget(TDeviceContext(DC).Wnd);
ClientWidget:=GetFixedWidget(Widget);
if ClientWidget<>nil then
Widget:=ClientWidget;
end else
Widget:=nil;
case uType of
DFC_CAPTION:
begin //all draw CAPTION commands here
end;
DFC_MENU:
begin
end;
DFC_SCROLL:
begin
end;
DFC_BUTTON:
begin
Assert(False, Format('Trace: [TGtkWidgetSet.DrawFrameControl] DFC_BUTTON --> draw rect = %d,%d,%d,%d',[Rect.Left,Rect.Top,REct.Right,REct.Bottom]));
//figure out the style first
case uState and $1F of
DFCS_BUTTONRADIOIMAGE:
begin
Assert(False, 'Trace:State ButtonRadioImage');
end;
DFCS_BUTTONRADIOMASK:
begin
Assert(False, 'Trace:State ButtonRadioMask');
end;
DFCS_BUTTONRADIO:
begin
Assert(False, 'Trace:State ButtonRadio');
end;
DFCS_BUTTON3STATE:
begin
Assert(False, 'Trace:State Button3State');
end;
DFCS_BUTTONPUSH:
begin
Assert(False, 'Trace:DFCS_BUTTONPUSH in uState');
DrawButtonPush;
end;
DFCS_BUTTONCHECK:
begin
Assert(False, 'Trace:State ButtonCheck');
DrawCheck;
end;
else
DebugLn(Format('ERROR: [TGtkWidgetSet.DrawFrameControl] Unknown State 0x%x', [uState]));
end;
end;
else
DebugLn(Format('ERROR: [TGtkWidgetSet.DrawFrameControl] Unknown type %d', [uType]));
end;
end;
{------------------------------------------------------------------------------
Function: DrawEdge
Params: DC: HDC; var Rect: TRect; edge: Cardinal; grfFlags: Cardinal
Returns: Boolean
Draws one or more edges of a rectangle. The rectangle is the area
Left to Right-1 and Top to Bottom-1.
------------------------------------------------------------------------------}
function TGtkWidgetSet.DrawEdge(DC: HDC; var ARect: TRect; Edge: Cardinal;
grfFlags: Cardinal): Boolean;
procedure DrawEdges(var R: TRect; GC: pgdkGC; Drawable:PGdkDrawable;
const TopLeftColor, BottomRightColor: TGDKColor);
begin
gdk_gc_set_foreground(GC, @TopLeftColor);
if (grfFlags and BF_TOP) = BF_TOP then begin
gdk_draw_line(Drawable, GC, R.Left, R.Top, R.Right, R.Top);
inc(R.Top);
end;
if (grfFlags and BF_LEFT) = BF_LEFT then begin
gdk_draw_line(Drawable, GC, R.Left, R.Top, R.Left, R.Bottom);
inc(R.Left);
end;
gdk_gc_set_foreground(GC, @BottomRightColor);
if (grfFlags and BF_BOTTOM) = BF_BOTTOM then begin
gdk_draw_line(Drawable, GC, R.Left, R.Bottom-1, R.Right, R.Bottom-1);
dec(R.Bottom);
end;
if (grfFlags and BF_RIGHT) = BF_RIGHT then begin
gdk_draw_line(Drawable, GC, R.Right-1, R.Top, R.Right-1, R.Bottom);
dec(R.Right);
end;
end;
Var
InnerTL, OuterTL,
InnerBR, OuterBR: TGDKColor;
BInner, BOuter: Boolean;
Width, Height: Integer;
R: TRect;
DCOrigin: TPoint;
begin
//DebugLn('TGtkWidgetSet.DrawEdge Edge=',DbgS(Edge),8),' grfFlags=',DbgS(Cardinal(grfFlags));
Result := IsValidDC(DC);
if Result
then with TDeviceContext(DC) do
begin
if GC = nil
then begin
Assert(False, 'Trace:[TGtkWidgetSet.DrawEdge] Uninitialized GC');
Result := False;
end
else begin
R := ARect;
DCOrigin:=GetDCOffset(TDeviceContext(DC));
OffsetRect(R,DCOrigin.X,DCOrigin.Y);
// try to use the gdk functions, so that the current theme is used
BInner := False;
BOuter := False;
// TODO: change this to real colors
if (edge and BDR_RAISEDINNER) = BDR_RAISEDINNER
then begin
InnerTL := AllocGDKColor(GetSysColor(COLOR_BTNHIGHLIGHT));
InnerBR := AllocGDKColor(GetSysColor(COLOR_BTNSHADOW));
BInner := True;
end;
if (edge and BDR_SUNKENINNER) = BDR_SUNKENINNER
then begin
InnerTL := AllocGDKColor(GetSysColor(COLOR_BTNSHADOW));
InnerBR := AllocGDKColor(GetSysColor(COLOR_BTNHIGHLIGHT));
BInner := True;
end;
if (edge and BDR_RAISEDOUTER) = BDR_RAISEDOUTER
then begin
OuterTL := AllocGDKColor(GetSysColor(COLOR_BTNHIGHLIGHT));
OuterBR := AllocGDKColor(GetSysColor(COLOR_BTNSHADOW));
BOuter := True;
end;
if (edge and BDR_SUNKENOUTER) = BDR_SUNKENOUTER
then begin
OuterTL := AllocGDKColor(GetSysColor(COLOR_BTNSHADOW));
OuterBR := AllocGDKColor(GetSysColor(COLOR_BTNHIGHLIGHT));
BOuter := True;
end;
gdk_gc_set_fill(GC, GDK_SOLID);
SelectedColors := dcscCustom;
// Draw outer rect
if Bouter then
DrawEdges(R,GC,Drawable,OuterTL,OuterBR);
// Draw inner rect
if BInner then
DrawEdges(R,GC,Drawable,InnerTL,InnerBR);
// gdk_colormap_free_colors(gdk_colormap_get_system, @OuterTL, 1);
// gdk_colormap_free_colors(gdk_colormap_get_system, @OuterBR, 1);
// gdk_colormap_free_colors(gdk_colormap_get_system, @InnerTL, 1);
// gdk_colormap_free_colors(gdk_colormap_get_system, @InnerBR, 1);
//Draw interiour
if ((grfFlags and BF_MIDDLE) = BF_MIDDLE) and
not CurrentBrush^.IsNullBrush
then begin
Width := R.Right - R.Left + 1;
Height := R.Bottom - R.Top + 1;
SelectGDKBrushProps(DC);
If not CurrentBrush^.IsNullBrush then
if (CurrentBrush^.GDIBrushFill = GDK_SOLID)
and (IsBackgroundColor(TColor(CurrentBrush^.GDIBrushColor.ColorRef)))
then
StyleFillRectangle(Drawable, GC, CurrentBrush^.GDIBrushColor.ColorRef,
R.Left, R.Top, Width, Height)
else
gdk_draw_rectangle(Drawable, GC, 1, R.Left, R.Top, Width, Height);
end;
// adjust rect if needed
if (grfFlags and BF_ADJUST) = BF_ADJUST
then ARect := R;
Result := True;
end;
end;
end;
{------------------------------------------------------------------------------
Method: DrawText
Params: DC, Str, Count, Rect, Flags
Returns: If the string was drawn, or CalcRect run
------------------------------------------------------------------------------}
function TGtkWidgetSet.DrawText(DC: HDC; Str: PChar; Count: Integer;
var Rect: TRect; Flags: Cardinal): Integer;
var
TM : TTextmetric;
theRect : TRect;
Lines : PPChar;
I, NumLines : Longint;
TempDC,
TempPen,
TempBrush : Longint;
Function LeftOffset : Longint;
begin
If (Flags and DT_Right) = DT_Right then
Result := DT_Right
else
If (Flags and DT_CENTER) = DT_CENTER then
Result := DT_CENTER
else
Result := DT_LEFT;
end;
Function TopOffset : Longint;
begin
If (Flags and DT_BOTTOM) = DT_BOTTOM then
Result := DT_BOTTOM
else
If (Flags and DT_VCENTER) = DT_VCENTER then
Result := DT_VCENTER
else
Result := DT_Top;
end;
Function CalcRect : Boolean;
begin
Result := (Flags and DT_CalcRect) = DT_CalcRect;
end;
Procedure DoCalcRect;
var
AP : TSize;
J, MaxLength,
LineWidth : Integer;
begin
theRect := Rect;
MaxLength := theRect.Right - theRect.Left;
If (Flags and DT_SingleLine) = DT_SingleLine then begin
// ignore word and line breaks
GetTextExtentPoint(DC, Str, Count, AP);
theRect.Right := theRect.Left + Min(MaxLength, AP.cX);
theRect.Bottom := theRect.Top + TM.tmHeight;
If not CalcRect then
Case TopOffset of
DT_VCENTER :
OffsetRect(theRect, 0, (Rect.Bottom - theRect.Bottom) div 2);
DT_Bottom :
OffsetRect(theRect, 0, Rect.Bottom - theRect.Bottom);
end;
end
else begin
// consider line breaks
If (Flags and DT_WordBreak) <> DT_WordBreak then begin
// do not break at word boundaries
GetTextExtentPoint(DC, Str, Count, AP);
MaxLength := AP.cX;
end;
Self.WordWrap(DC, Str, MaxLength, Lines, NumLines);
LineWidth := 0;
If (Lines <> nil) then begin
For J := 0 to NumLines - 1 do begin
GetTextExtentPoint(DC, Lines[J], StrLen(Lines[J]), AP);
LineWidth := Max(LineWidth, AP.cX);
end;
end;
LineWidth := Min(MaxLength, LineWidth);
theRect.Right := theRect.Left + LineWidth;
theRect.Bottom := theRect.Top + NumLines*TM.tmHeight;
if NumLines>1 then
Inc(theRect.Bottom, (NumLines-1)*TM.tmDescent);// space between lines
//debugln('TGtkWidgetSet.DrawText A ',dbgs(theRect),' TM.tmHeight=',dbgs(TM.tmHeight),' LineWidth=',dbgs(LineWidth),' NumLines=',dbgs(NumLines));
end;
If not CalcRect then
Case LeftOffset of
DT_CENTER :
OffsetRect(theRect, (Rect.Right - theRect.Right) div 2, 0);
DT_Right :
OffsetRect(theRect, Rect.Right - theRect.Right, 0);
end;
end;
Procedure DrawLine(theLine : PChar; LineLength, TopPos : Longint);
var
Points : Array[0..1] of TSize;
LogP : TLogPen;
pIndex : Longint;
AStr : String;
LeftPos : Longint;
begin
AStr := Copy(String(theLine), 1, LineLength);
If (Flags and DT_NoPrefix) <> DT_NoPrefix then
pIndex := DeleteAmpersands(aStr)
else
pIndex := -1;
If TempBrush = -1 then
TempBrush := SelectObject(DC, GetStockObject(NULL_BRUSH));
If LeftOffset <> DT_Left then
GetTextExtentPoint(DC, PChar(aStr), Length(aStr), Points[0]);
Case LeftOffset of
DT_Left:
LeftPos := theRect.Left;
DT_Center:
LeftPos := theRect.Left + (theRect.Right - theRect.Left) div 2
- Points[0].cX div 2;
DT_Right:
LeftPos := theRect.Right - Points[0].cX;
end;
{Draw line of Text}
TextOut(DC, LeftPos, TopPos, PChar(aStr), Length(aStr));
{Draw Prefix}
If pIndex > 0 then begin
{Create & select pen of font color}
If TempPen = -1 then begin
LogP.lopnStyle := PS_SOLID;
LogP.lopnWidth.X := 1;
LogP.lopnColor := GetTextColor(DC);
TempPen := SelectObject(DC, CreatePenIndirect(LogP));
end;
{Get prefix line position}
GetTextExtentPoint(DC, PChar(aStr), pIndex - 1, Points[0]);
Points[0].cX := LeftPos + Points[0].cX;
Points[0].cY := TopPos + tm.tmHeight - TM.tmDescent + 1;
GetTextExtentPoint(DC, @aStr[pIndex], 1, Points[1]);
Points[1].cX := Points[0].cX + Points[1].cX;
Points[1].cY := Points[0].cY;
{Draw prefix line}
Polyline(DC, @Points[0], 2);
end;
end;
begin
if (Str=nil) or (Str[0]=#0) then exit;
Assert(False, Format('trace:> [TGtkWidgetSet.DrawText] DC:0x%x, Str:''%s'', Count: %d, Rect = %d,%d,%d,%d, Flags:%d',
[DC, Str, Count, Rect.Left, Rect.Top, Rect.Right, Rect.Bottom, Flags]));
Result := Longint(IsValidDC(DC));
if Boolean(Result)
then with TDeviceContext(DC) do
begin
if GC = nil
then begin
DebugLn('WARNING: [TGtkWidgetSet.DrawText] Uninitialized GC');
Result := 0;
end
else begin
Result := 0;
Lines := nil;
NumLines := 0;
TempDC := -1;
TempPen := -1;
TempBrush := -1;
try
Count := Min(StrLen(Str), Count);
GetTextMetrics(DC, TM);
DoCalcRect;
If (Flags and DT_CalcRect) = DT_CalcRect then begin
CopyRect(Rect, theRect);
Result := 1;
exit;
end else begin
TempDC := SaveDC(DC);
end;
If (Flags and DT_NOCLIP) <> DT_NOCLIP then begin
If theRect.Right > Rect.Right then
theRect.Right := Rect.Right;
If theRect.Bottom > Rect.Bottom then
theRect.Bottom := Rect.Bottom;
IntersectClipRect(DC, theRect.Left, theRect.Top,
theRect.Right, theRect.Bottom);
end;
If (Flags and DT_SingleLine) = DT_SingleLine then begin
DrawLine(Str, Count, theRect.Top);
Result := 1;
end
else If (Lines <> nil) and (NumLines <> 0) then begin
For I := 0 to NumLines - 1 do begin
if I>0 then
Inc(theRect.Top, TM.tmDescent);// space between lines
If (((Flags and DT_EditControl) = DT_EditControl) and
(tm.tmHeight > (theRect.Bottom - theRect.Top))) or
(theRect.Top > theRect.Bottom)
then
break;
If Lines[I] <> nil then
DrawLine(Lines[I], StrLen(Lines[I]), theRect.Top);
Inc(theRect.Top, TM.tmHeight);
end;
Result := 1;
end;
finally
Reallocmem(Lines, 0);
If TempBrush <> -1 then
SelectObject(DC, TempBrush);
If TempPen <> -1 then
DeleteObject(SelectObject(DC, TempPen));
If TempDC <> -1 then
RestoreDC(DC, TempDC);
end;
end;
end;
Assert(False, Format('trace:> [TGtkWidgetSet.DrawText] DC:0x%x, Str:''%s'', Count: %d, Rect = %d,%d,%d,%d, Flags:%d',
[DC, Str, Count, Rect.Left, Rect.Top, Rect.Right, Rect.Bottom, Flags]));
end;
{------------------------------------------------------------------------------
Function: EnableScrollBar
Params: Wnd, wSBflags, wArrows
Returns: Nothing
------------------------------------------------------------------------------}
function TGtkWidgetSet.EnableScrollBar(Wnd: HWND; wSBflags, wArrows: Cardinal): Boolean;
begin
Assert(False, 'Trace:TODO: [TGtkWidgetSet.EnableScrollBar]');
//TODO: Implement this;
Result := False;
end;
{------------------------------------------------------------------------------
Function: EnableWindow
Params: hWnd:
bEnable:
Returns:
------------------------------------------------------------------------------}
function TGtkWidgetSet.EnableWindow(hWnd: HWND; bEnable: Boolean): Boolean;
begin
Assert(False, Format('Trace: [TGtkWidgetSet.EnableWindow] hWnd: 0x%x, Enable: %s', [hwnd, BOOL_TEXT[bEnable]]));
if hWnd <> 0 then
gtk_widget_set_sensitive(pgtkwidget(hWnd), bEnable);
Result:=true;
end;
{------------------------------------------------------------------------------
Function: EndPaint
Params:
Returns:
------------------------------------------------------------------------------}
function TGtkWidgetSet.EndPaint(Handle: hwnd; var PS: TPaintStruct): Integer;
{$IFDEF Gtk1}
var
Widget: PGtkWidget;
IsDoubleBuffer: Boolean;
DCDrawable: PGdkDrawable;
Width, Height: integer;
DevContext: TDeviceContext;
CaretWasVisible: Boolean;
MainWidget: PGtkWidget;
//LCLObject: TObject;
//x, y: integer;
{$ENDIF}
begin
Result:=1;
if PS.HDC <> 0 then begin
{$IFDEF Gtk1}
Widget:=PGtkWidget(Handle);
DevContext:=TDeviceContext(PS.HDC);
if Widget<>PGtkWidget(DevContext.Wnd) then
RaiseException('');
DCDrawable:=DevContext.Drawable;
IsDoubleBuffer:=dcfDoubleBuffer in DevContext.DCFlags;
if IsDoubleBuffer then begin
// copy
gdk_window_get_size(DCDrawable,@Width,@Height);
{$IFDEF VerboseDoubleBuffer}
DebugLn('TGtkWidgetSet.EndPaint Copying from buffer to window: ',Width,' ',Height);
{$ENDIF}
gdk_gc_set_clip_region(DevContext.GC, nil);
gdk_gc_set_clip_rectangle(DevContext.GC, nil);
// hide caret
HideCaretOfWidgetGroup(Widget,MainWidget,CaretWasVisible);
// draw
gdk_window_copy_area(Widget^.Window, DevContext.GC, 0,0,
DCDrawable, 0, 0, Width, Height);
{LCLObject:=GetParentLCLObject(Widget);
if (LCLObject is TPanel)
and (csDesigning in TPanel(LCLObject).ComponentState) then begin
gdk_window_get_origin(Widget^.Window,@x,@y);
DebugLn('TGtkWidgetSet.EndPaint ',TPanel(LCLObject).Name,':',TPanel(LCLObject).ClassName,
' Widget=',GetWidgetClassName(Widget),
' Origin=',x,',',y,
' ',Widget^.allocation.x,',',Widget^.allocation.y);
end;}
// restore caret
if CaretWasVisible then
GTKAPIWidget_ShowCaret(PGTKAPIWidget(MainWidget));
end;
{$ENDIF}
ReleaseDC(Handle, PS.HDC);
end;
end;
{------------------------------------------------------------------------------
Method: Ellipse
Params: X1, Y1, X2, Y2
Returns: Nothing
Use Ellipse to draw a filled circle or ellipse.
------------------------------------------------------------------------------}
function TGtkWidgetSet.Ellipse(DC: HDC;
x1,y1,x2,y2: Integer): Boolean;
var
x,y,width,height: integer;
DCOrigin: TPoint;
begin
Result := IsValidDC(DC);
if Result
then with TDeviceContext(DC) do
begin
if GC = nil
then begin
DebugLn('WARNING: [TGtkWidgetSet.Ellipse] Uninitialized GC');
Result := False;
end
else begin
if x1<x2 then begin
x:=x1;
width:=x2-x1;
end else begin
x:=x2;
width:=x1-x2;
end;
if y1<y2 then begin
y:=y1;
height:=y2-y1;
end else begin
y:=y2;
height:=y1-y2;
end;
// first draw interior in brush color
SelectGDKBrushProps(DC);
DCOrigin:=GetDCOffset(TDeviceContext(DC));
{$IFDEF DebugGDKTraps}
BeginGDKErrorTrap;
{$ENDIF}
If not CurrentBrush^.IsNullBrush then
gdk_draw_arc(Drawable, GC, 1, x+DCOrigin.X, y+DCOrigin.Y, Width, Height,
0, 360 shl 6);
// Draw outline
SelectGDKPenProps(DC);
If (dcfPenSelected in DCFlags) then begin
Result := True;
if (CurrentPen^.IsNullPen) then exit;
gdk_draw_arc(Drawable, GC, 0, x+DCOrigin.X, y+DCOrigin.Y, Width, Height,
0, 360 shl 6);
end else
Result := False;
{$IFDEF DebugGDKTraps}
EndGDKErrorTrap;
{$ENDIF}
end;
end;
end;
{------------------------------------------------------------------------------
Function: ExcludeClipRect
Params: dc: hdc; Left, Top, Right, Bottom : Integer
Returns: integer
Subtracts all intersecting points of the passed bounding rectangle
(Left, Top, Right, Bottom) from the Current clipping region in the
device context (dc).
The result can be one of the following constants
Error
NullRegion
SimpleRegion
ComplexRegion
------------------------------------------------------------------------------}
function TGtkWidgetSet.ExcludeClipRect(dc: hdc;
Left, Top, Right, Bottom : Integer) : Integer;
begin
Result := Inherited ExcludeClipRect(DC, Left, Top, Right, Bottom);
end;
{------------------------------------------------------------------------------
Function: ExtSelectClipRGN
Params: dc, RGN, Mode
Returns: integer
Combines the passed Region with the current clipping region in the device
context (dc), using the specified mode.
The Combine Mode can be one of the following:
RGN_AND : all points which are in both regions
RGN_COPY : an exact copy of the source region, same as SelectClipRGN
RGN_DIFF : all points which are in the Clipping Region but
not in the Source.(Clip - RGN)
RGN_OR : all points which are in either the Clip Region or
in the Source.(Clip + RGN)
RGN_XOR : all points which are in either the Clip Region
or in the Source, but not in both.
The result can be one of the following constants
Error
NullRegion
SimpleRegion
ComplexRegion
------------------------------------------------------------------------------}
function TGtkWidgetSet.ExtSelectClipRGN(dc: hdc; rgn : hrgn;
Mode : Longint) : Integer;
var
Clip,
Tmp : hRGN;
X, Y : Longint;
DCOrigin: TPoint;
begin
Result := SIMPLEREGION;
If not IsValidDC(DC) then
Result := ERROR
else with TDeviceContext(DC) do
begin
if GC = nil
then begin
DebugLn('WARNING: [TGtkWidgetSet.ExtSelectClipRGN] Uninitialized GC');
Result := ERROR;
end
else begin
//DebugLn('TGtkWidgetSet.ExtSelectClipRGN A ClipRegValid=',dbgs(DCClipRegionValid(DC)),
// ' Mode=',dbgs(Mode),' RGN=',GDKRegionAsString(PGdiObject(RGN)^.GDIRegionObject));
If ClipRegion=0 then begin
// there is no clipping region in the DC
Case Mode of
RGN_COPY:
begin
Result := RegionType(PGdiObject(RGN)^.GDIRegionObject);
If Result <> ERROR then
Result := SelectClipRGN(DC, RGN);
end;
RGN_OR,
RGN_XOR,
RGN_AND,
RGN_DIFF:
begin
// get existing clip
GDK_Window_Get_Size(Drawable, @X, @Y);
DCOrigin:=GetDCOffset(TDeviceContext(DC));
Clip := CreateRectRGN(-DCOrigin.X,-DCOrigin.Y,X-DCOrigin.X,Y-DCOrigin.Y);
// create target clip
Tmp := CreateEmptyRegion;
// combine
Result := CombineRGN(Tmp, Clip, RGN, Mode);
// commit
//DebugLn('TGtkWidgetSet.ExtSelectClipRGN B ClipRegValid=',dbgs(ClipRegion),' TmpRGN=',GDKRegionAsString(PGdiObject(Tmp)^.GDIRegionObject));
SelectClipRGN(DC, Tmp);
// clean up
DeleteObject(Clip);
DeleteObject(Tmp);
end;
end;
end
else
Result := Inherited ExtSelectClipRGN(dc, rgn, mode);
end;
end;
end;
{------------------------------------------------------------------------------
Function: ExtTextOut
Params: none
Returns: Nothing
------------------------------------------------------------------------------}
function TGtkWidgetSet.ExtTextOut(DC: HDC; X, Y: Integer; Options: Longint;
Rect: PRect; Str: PChar; Count: Longint; Dx: PInteger): Boolean;
{$Ifdef GTK2}
begin
DebugLn('ToDo: TGtkWidgetSet.ExtTextOut');
Result:=false;
end;
{$Else}
var
LineStart, LineEnd, StrEnd: PChar;
Left, Top, Width, Height: Integer;
TopY, LineLen, LineHeight : Integer;
TxtPt : TPoint;
UseFont : PGDKFont;
UnRef : Boolean;
DCOrigin: TPoint;
UnderLine: boolean;
buffer: PGdkDrawable;
buffered: Boolean;
procedure DrawTextLine;
var
UnderLineLen, Y: integer;
CurDistX: PInteger;
CharsWritten, CurX, i: integer;
LinePos: PChar;
CharLen: LongInt;
begin
{$IFDEF DebugGDKTraps}
BeginGDKErrorTrap;
{$ENDIF}
with TDeviceContext(DC) do begin
if (Dx=nil) then begin
// no dist array -> write as one block
//debugln('TGtkWidgetSet.ExtTextOut.DrawTextLine Dx=nil ',dbgs(LineLen),' DCTextMetric.IsDoubleByteChar=',dbgs(DCTextMetric.IsDoubleByteChar));
gdk_draw_text(Buffer, UseFont, GC, TxtPt.X, TxtPt.Y,
LineStart, LineLen);
end else begin
// dist array -> write each char separately
CharsWritten:=integer(LineStart-Str);
if DCTextMetric.IsDoubleByteChar then begin
CharLen:=2;
CharsWritten:=CharsWritten div 2;
end else
CharLen:=1;
CurDistX:=Dx+CharsWritten*SizeOf(Integer);
CurX:=TxtPt.X;
LinePos:=LineStart;
//debugln('TGtkWidgetSet.ExtTextOut.DrawTextLine ',dbgs(dx),' DCTextMetric.IsDoubleByteChar=',dbgs(DCTextMetric.IsDoubleByteChar));
i:=1;
while (i<=LineLen) do begin
//debugln('TGtkWidgetSet.ExtTextOut.DrawTextLine ',dbgs(CharLen),' ',dbgs(ord(LinePos^)));
gdk_draw_text(Buffer, UseFont, GC, CurX, TxtPt.Y, LinePos, CharLen);
inc(LinePos,CharLen);
inc(CurX,CurDistX^);
inc(CurDistX);
inc(i,CharLen);
end;
end;
if UnderLine then begin
if Rect<>nil then
UnderLineLen := Rect^.Right-Rect^.Left
else
UnderLineLen := gdk_text_width(UseFont,LineStart, LineLen);
Y := TxtPt.Y + 1;
gdk_draw_line(Buffer, GC, TxtPt.X, Y, TxtPt.X+UnderLineLen, Y);
end;
end;
{$IFDEF DebugGDKTraps}
EndGDKErrorTrap;
{$ENDIF}
end;
begin
Assert(False, Format('trace:> [TGtkWidgetSet.ExtTextOut] DC:0x%x, X:%d, Y:%d, Options:%d, Str:''%s'', Count: %d', [DC, X, Y, Options, Str, Count]));
Result := IsValidDC(DC);
if Result
then with TDeviceContext(DC) do
begin
if GC = nil
then begin
DebugLn('WARNING: [TGtkWidgetSet.ExtTextOut] Uninitialized GC');
Result := False;
exit;
end;
if ((Options and (ETO_OPAQUE+ETO_CLIPPED)) <> 0)
and (Rect=nil) then begin
DebugLn('WARNING: [TGtkWidgetSet.ExtTextOut] Rect=nil');
Result := False;
exit;
end;
// TODO: implement other parameters.
// to reduce flickering calculate first and then paint
DCOrigin:=GetDCOffset(TDeviceContext(DC));
buffered := false;
UseFont:=nil;
buffer := Drawable;
UnRef := false;
UnderLine := false;
if (Str<>nil) and (Count>0) then begin
if (CurrentFont = nil) or (CurrentFont^.GDIFontObject = nil) then begin
UseFont := GetDefaultFont(false);
end else begin
UseFont := CurrentFont^.GDIFontObject;
UnderLine := (CurrentFont^.LogFont.lfUnderline<>0);
end;
if UseFont <> nil then begin
if (Options and ETO_CLIPPED) <> 0 then
begin
X := Rect^.Left;
Y := Rect^.Top;
IntersectClipRect(DC, Rect^.Left, Rect^.Top,
Rect^.Right, Rect^.Bottom);
end;
end else begin
DebugLn('WARNING: [TGtkWidgetSet.ExtTextOut] Missing Font');
Result := False;
end;
end;
if ((Options and ETO_OPAQUE) <> 0) then
begin
Width := Rect^.Right - Rect^.Left;
Height := Rect^.Bottom - Rect^.Top;
SelectedColors := dcscCustom;
EnsureGCColor(DC, dccCurrentBackColor, True, False);
if buffered then begin
Left:=0;
Top:=0;
end else begin
Left:=Rect^.Left+DCOrigin.X;
Top:=Rect^.Top+DCOrigin.Y;
end;
{$IFDEF DebugGDKTraps}
BeginGDKErrorTrap;
{$ENDIF}
if IsBackgroundColor(TColor(CurrentBackColor.ColorRef)) then
StyleFillRectangle(buffer, GC, CurrentBackColor.ColorRef,
Left, Top, Width, Height)
else
gdk_draw_rectangle(buffer, GC, 1, Left, Top, Width, Height);
{$IFDEF DebugGDKTraps}
EndGDKErrorTrap;
{$ENDIF}
end;
if UseFont<>nil then begin
LineLen := FindChar(#10,Str,Count);
UpdateDCTextMetric(TDeviceContext(DC));
LineHeight:=GetTextHeight(DCTextMetric);
if Buffered then begin
TxtPt.X := 0;
TxtPt.Y := LineHeight;
end
else begin
TopY := Y;
TxtPt.X := X + DCOrigin.X;
TxtPt.Y := TopY + LineHeight + DCOrigin.Y;
end;
SelectGDKTextProps(DC);
LineStart:=Str;
if LineLen < 0 then begin
LineLen:=Count;
if Count> 0 then DrawTextLine;
end else
Begin //write multiple lines
StrEnd:=Str+Count;
while LineStart < StrEnd do begin
LineEnd:=LineStart+LineLen;
if LineLen>0 then DrawTextLine;
inc(TxtPt.Y,LineHeight);
LineStart:=LineEnd+1; // skip #10
if (LineStart<StrEnd) and (LineStart^=#13) then
inc(LineStart); // skip #10
Count:=StrEnd-LineStart;
LineLen:=FindChar(#10,LineStart,Count);
if LineLen<0 then
LineLen:=Count;
end;
end;
If UnRef then begin
{$IFDEF DebugGDKTraps}
BeginGDKErrorTrap;
{$ENDIF}
FontCache.Unreference(UseFont);
{$IFDEF DebugGDKTraps}
EndGDKErrorTrap;
{$ENDIF}
end;
end;
end;
Assert(False, Format('trace:< [TGtkWidgetSet.ExtTextOut] DC:0x%x, X:%d, Y:%d, Options:%d, Str:''%s'', Count: %d', [DC, X, Y, Options, Str, Count]));
end;
{$EndIf}
{------------------------------------------------------------------------------
Function: FillRect
Params: none
Returns: Nothing
The FillRect function fills a rectangle by using the specified brush.
This function includes the left and top borders, but excludes the right and
bottom borders of the rectangle.
------------------------------------------------------------------------------}
function TGtkWidgetSet.FillRect(DC: HDC; const Rect: TRect; Brush: HBRUSH): Boolean;
var
Width, Height: Integer;
OldCurrentBrush: PGdiObject;
DCOrigin: TPoint;
BrushChanged: Boolean;
begin
BrushChanged :=false;
Result := IsValidDC(DC) and IsValidGDIObject(Brush);
if not Result then exit;
with TDeviceContext(DC) do
begin
if GC = nil
then begin
DebugLn('WARNING: [TGtkWidgetSet.FillRect] Uninitialized GC');
Result := False;
exit;
end;
if not PGdiObject(Brush)^.IsNullBrush then begin
Width := Rect.Right - Rect.Left;
Height := Rect.Bottom - Rect.Top;
// Temporary hold the old brush to
// replace it with the given brush
OldCurrentBrush := CurrentBrush;
if not CompareGDIBrushes(PGdiObject(Brush),OldCurrentBrush) then begin
BrushChanged:=true;
CurrentBrush := PGdiObject(Brush);
SelectedColors:=dcscCustom;
end;
//DebugLn('TGtkWidgetSet.FillRect Color=',DbgS(CurrentBrush^.GDIBrushColor.ColorRef));
SelectGDKBrushProps(DC);
DCOrigin:=GetDCOffset(TDeviceContext(DC));
if (CurrentBrush^.GDIBrushFill = GDK_SOLID)
and (IsBackgroundColor(TColor(CurrentBrush^.GDIBrushColor.ColorRef)))
then begin
StyleFillRectangle(drawable, GC,
CurrentBrush^.GDIBrushColor.ColorRef,
Rect.Left+DCOrigin.X, Rect.Top+DCOrigin.Y,
Width, Height)
end else begin
gdk_draw_rectangle(Drawable, GC, 1,
Rect.Left+DCOrigin.X, Rect.Top+DCOrigin.Y,
Width, Height);
end;
// Restore current brush
if BrushChanged then begin
SelectedColors:=dcscCustom;
CurrentBrush := OldCurrentBrush;
end;
end;
Result := True;
end;
Assert(False, Format('trace:< [TGtkWidgetSet.FillRect] DC:0x%x; Rect: ((%d,%d)(%d,%d)); brush: %x', [Integer(DC), Rect.left, rect.top, rect.right, rect.bottom, brush]));
end;
{------------------------------------------------------------------------------
function Frame(DC: HDC; const ARect: TRect): Integer; override;
Draws the border of a rectangle.
------------------------------------------------------------------------------}
function TGtkWidgetSet.Frame(DC: HDC; const ARect: TRect): Integer;
var
DCOrigin: TPoint;
begin
Result:=0;
if IsValidDC(DC) and (TDeviceContext(DC).GC<>nil) then begin
with TDeviceContext(DC) do
begin
// Draw outline
SelectGDKPenProps(DC);
If (dcfPenSelected in DCFlags) then begin
Result := 1;
if (not CurrentPen^.IsNullPen) then begin
DCOrigin:=GetDCOffset(TDeviceContext(DC));
gdk_draw_rectangle(Drawable, GC, 0,
ARect.Left+DCOrigin.X, ARect.Top+DCOrigin.Y,
ARect.Right-ARect.Left, ARect.Bottom-ARect.Top);
end;
end;
end;
end;
end;
{------------------------------------------------------------------------------
Function: Frame3d
Params: -
Returns: Nothing
Draws a 3d border in GTK native style.
------------------------------------------------------------------------------}
function TGtkWidgetSet.Frame3d(DC : HDC; var ARect : TRect;
const FrameWidth : integer; const Style : TBevelCut) : boolean;
const GTKThinShadowType: array[TBevelCut] of integer =
(GTK_SHADOW_NONE, GTK_SHADOW_IN, GTK_SHADOW_OUT, GTK_SHADOW_NONE);
const GTKStrongShadowType: array[TBevelCut] of integer =
(GTK_SHADOW_NONE, GTK_SHADOW_ETCHED_IN, GTK_SHADOW_ETCHED_OUT, GTK_SHADOW_NONE);
var
Widget, ClientWidget: PGtkWidget;
i : integer;
DCOrigin: TPoint;
TheStyle: PGtkStyle;
Area: TGdkRectangle;
ShadowType: Integer;
AWindow: PGdkWindow;
begin
Result := IsValidDC(DC);
if not Result then exit;
if FrameWidth=0 then exit;
TheStyle:=GetStyle(lgsButton);
//DebugLn('TGtkWidgetSet.Frame3d A ',DbgS(TheStyle));
if TheStyle=nil then exit;
with TDeviceContext(DC) do
begin
if GC = nil then begin
Result:= False;
exit;
end;
Widget:=PGtkWidget(TDeviceContext(DC).Wnd);
ClientWidget:=Widget;
if Widget<>nil then begin
ClientWidget:=GetFixedWidget(Widget);
if ClientWidget=nil then
ClientWidget:=Widget;
end;
AWindow:=Drawable;
DCOrigin:=GetDCOffset(TDeviceContext(DC));
Area.X:=ARect.Left+DCOrigin.X;
Area.Y:=ARect.Top+DCOrigin.Y;
Area.Width:=ARect.Right-ARect.Left;
Area.Height:=ARect.Bottom-ARect.Top;
if FrameWidth=1 then
ShadowType:=GTKThinShadowType[Style]
else
ShadowType:=GTKStrongShadowType[Style];
//DebugLn('ShadowType ',ShadowType,
//' dark_gc=',DbgS(TheStyle^.dark_gc[GTK_STATE_NORMAL]),
//' light_gc=',DbgS(TheStyle^.light_gc[GTK_STATE_NORMAL]),
//'');
for i:= 1 to FrameWidth do begin
gtk_paint_shadow(TheStyle,
AWindow, GTK_STATE_NORMAL,
ShadowType,
@Area,
ClientWidget,
'button',
ARect.Left+DCOrigin.X, ARect.Top+DCOrigin.Y,
ARect.Right-ARect.Left, ARect.Bottom-ARect.Top);
// inflate the rectangle (! ARect will be returned to the user with this)
InflateRect(ARect, -1, -1);
end;
end;
end;
{------------------------------------------------------------------------------
function TGtkWidgetSet.FrameRect(DC: HDC; const ARect: TRect;
hBr: HBRUSH): Integer;
------------------------------------------------------------------------------}
function TGtkWidgetSet.FrameRect(DC: HDC; const ARect: TRect;
hBr: HBRUSH): Integer;
var
DCOrigin: TPoint;
begin
Result:=0;
if IsValidDC(DC) and (TDeviceContext(DC).GC<>nil)
and IsValidGDIObject(hBr) then begin
// Draw outline
Result := 1;
if (not PGdiObject(hBr)^.IsNullBrush) then begin
with TDeviceContext(DC) do
begin
SelectedColors:=dcscCustom;
EnsureGCColor(DC, dccGDIBrushColor, True, False);//Brush Color
DCOrigin:=GetDCOffset(TDeviceContext(DC));
gdk_draw_rectangle(Drawable, GC, 0,
ARect.Left+DCOrigin.X, ARect.Top+DCOrigin.Y,
ARect.Right-ARect.Left, ARect.Bottom-ARect.Top);
end;
end;
end;
end;
{------------------------------------------------------------------------------
Function: GetActiveWindow
Params: none
Returns:
------------------------------------------------------------------------------}
Function TGtkWidgetSet.GetActiveWindow : HWND;
var
TopList, List: PGList;
Widget: PGTKWidget;
Window: PGTKWindow;
begin
// Default to 0
Result := 0;
TopList := gdk_window_get_toplevels;
List := TopList;
while List <> nil do
begin
if (List^.Data <> nil)
then begin
gdk_window_get_user_data(PGDKWindow(List^.Data), @Window);
if gtk_is_window(Window)
then begin
Widget := Window^.focus_widget;
if (Widget <> nil) and gtk_widget_has_focus(Widget)
then begin
Result := HWND(GetMainWidget(PGtkWidget(Window)));
Break;
end;
end;
end;
list := g_list_next(list);
end;
if TopList <> nil
then g_list_free(TopList);
end;
{------------------------------------------------------------------------------
Function: GetDIBits
Params:
Returns:
------------------------------------------------------------------------------}
function TGtkWidgetSet.GetDIBits(DC: HDC; Bitmap: HBitmap; StartScan, NumScans: UINT;
Bits: Pointer; var BitInfo: BitmapInfo; Usage: UINT): Integer;
begin
Assert(False, 'trace:[TGtkWidgetSet.GetDIBits]');
Result := 0;
if IsValidGDIObject(Bitmap)
then begin
case PGDIObject(Bitmap)^.GDIType of
gdiBitmap:
Result := InternalGetDIBits(DC, Bitmap, StartScan, NumScans, -1, Bits,
BitInfo, Usage, True);
else
DebugLn('WARNING: [TGtkWidgetSet.GetDIBits] not a Bitmap!');
end;
end
else
DebugLn('WARNING: [TGtkWidgetSet.GetDIBits] invalid Bitmap!');
end;
{------------------------------------------------------------------------------
Function: GetBitmapBits
Params:
Returns:
------------------------------------------------------------------------------}
function TGtkWidgetSet.GetBitmapBits(Bitmap: HBITMAP; Count: Longint; Bits: Pointer): Longint;
var
BitInfo : tagBitmapInfo;
begin
Assert(False, 'trace:[TGtkWidgetSet.GetBitmapBits]');
Result := 0;
if IsValidGDIObject(Bitmap)
then begin
case PGDIObject(Bitmap)^.GDIType of
gdiBitmap:
Result := InternalGetDIBits(0, Bitmap, 0, 0, Count, Bits, BitInfo, 0, False);
else
DebugLn('WARNING: [TGtkWidgetSet.GetBitmapBits] not a Bitmap!');
end;
end
else
DebugLn('WARNING: [TGtkWidgetSet.GetBitmapBits] invalid Bitmap!');
end;
{------------------------------------------------------------------------------
Function: GetBitmapRawImageDescription
Params: Bitmap: HBITMAP;
Desc: PRawImageDescription
Returns: boolean;
------------------------------------------------------------------------------}
function TGtkWidgetSet.GetBitmapRawImageDescription(Bitmap: HBITMAP;
Desc: PRawImageDescription): boolean;
var
GDIObject: PGDIObject;
GdkPixmap: PGdkPixmap;
begin
Result:=false;
if not IsValidGDIObject(Bitmap) then begin
DebugLn('WARNING: [TGtkWidgetSet.GetBitmapRawImageDescription] invalid Bitmap!');
exit;
end;
GDIObject:=PGDIObject(Bitmap);
case GDIObject^.GDIBitmapType of
gbBitmap: GdkPixmap:=PGdkPixmap(PGdiObject(Bitmap)^.GDIBitmapObject);
gbPixmap: GdkPixmap:=PGdkPixmap(PGdiObject(Bitmap)^.GDIPixmapObject);
else
GdkPixmap:=nil;
DebugLn('WARNING: [TGtkWidgetSet.GetBitmapRawImageDescription] GDI_RGBImage not implemented');
exit;
end;
Result:=GetWindowRawImageDescription(PGdkWindow(GdkPixmap),Desc);
end;
{------------------------------------------------------------------------------
Function: GetCapture
Params: none
Returns: Nothing
------------------------------------------------------------------------------}
function TGtkWidgetSet.GetCapture: HWND;
var
Widget: PGtkWidget;
AWindow: PGtkWindow;
IsModal: gboolean;
begin
Widget:=gtk_grab_get_current;
// for the LCL a modal window is not capturing
if Widget<>nil then begin
if GtkWidgetIsA(Widget,GTK_TYPE_WINDOW) then begin
AWindow:=PGtkWindow(Widget);
IsModal:=gtk_window_get_modal(AWindow);
if IsModal then
Widget:=nil;
end;
end;
Result := HWnd(Widget);
end;
{------------------------------------------------------------------------------
Function: GetCaretPos
Params: lpPoint: The caretposition
Returns: True if succesful
------------------------------------------------------------------------------}
function TGtkWidgetSet.GetCaretPos(var lpPoint: TPoint): Boolean;
var
//FocusObject: PGTKObject;
modmask : TGDKModifierType;
begin
{ Assert(False, 'Trace:TODO: [TGtkWidgetSet.GetCaretPos] finish');
FocusObject := PGTKObject(GetFocus);
Result := FocusObject <> nil;
if Result
then begin
// Assert(False, Format('Trace:[TGtkWidgetSet.GetCaretPos] Got focusObject 0x%x --> %s', [Integer(FocusObject), gtk_type_name(FocusObject^.Klass^.theType)]));
if gtk_type_is_a(gtk_object_type(FocusObject), GTKAPIWidget_GetType)
then begin
GTKAPIWidget_GetCaretPos(PGTKAPIWidget(FocusObject), lpPoint.X, lpPoint.Y);
end
// else if // TODO: other widgettypes
else begin
Result := False;
end;
end
else DebugLn('[TGtkWidgetSet.GetCaretPos] got focusObject nil');
}
{$IFDEF DebugGDKTraps}
BeginGDKErrorTrap;
{$ENDIF}
gdk_window_get_pointer(nil,@lpPoint.X,@lpPoint.y,@modmask);
{$IFDEF DebugGDKTraps}
EndGDKErrorTrap;
{$ENDIF}
Result := True;
end;
{------------------------------------------------------------------------------
function TGtkWidgetSet.GetCaretRespondToFocus(handle: HWND;
var ShowHideOnFocus: boolean): Boolean;
------------------------------------------------------------------------------}
function TGtkWidgetSet.GetCaretRespondToFocus(handle: HWND;
var ShowHideOnFocus: boolean): Boolean;
begin
if handle<>0 then begin
if gtk_type_is_a(gtk_object_type(PGTKObject(handle)), GTKAPIWidget_GetType)
then begin
GTKAPIWidget_GetCaretRespondToFocus(PGTKAPIWidget(handle),
ShowHideOnFocus);
Result:=true;
end
else begin
Result := False;
end;
end else
Result:=false;
end;
{------------------------------------------------------------------------------
Function: GetCharABCWidths pbd
Params: Don't care yet
Returns: False so that the font cache in the newest mwEdit will use
TextMetrics info which is working already
------------------------------------------------------------------------------}
function TGtkWidgetSet.GetCharABCWidths(DC: HDC; p2, p3: UINT;
const ABCStructs): Boolean;
begin
Result := False;
end;
{------------------------------------------------------------------------------
Function: GetClientBounds
Params: handle:
Result:
Returns: true on success
Returns the client bounds of a control. The client bounds is the rectangle of
the inner area of a control, where the child controls are visible. The
coordinates are relative to the control's left and top.
------------------------------------------------------------------------------}
Function TGtkWidgetSet.GetClientBounds(handle : HWND; var ARect : TRect) : Boolean;
var
Widget, ClientWidget: PGtkWidget;
MainOrigin, ClientOrigin: TPoint;
ClientWindow, MainWindow: PGdkWindow;
begin
Result := False;
if Handle = 0 then Exit;
Widget := pgtkwidget(Handle);
ClientWidget := GetFixedWidget(Widget);
if (ClientWidget <> Widget) then begin
ClientWindow:=GetControlWindow(ClientWidget);
MainWindow:=GetControlWindow(Widget);
if MainWindow<>ClientWindow then begin
if MainWindow<>nil then begin
gdk_window_get_origin(MainWindow,@MainOrigin.X,@MainOrigin.Y);
end else begin
// widget not realized
MainOrigin.X:=0;
MainOrigin.Y:=0;
end;
// check if the main gdkwindow is the clientwindow of the parent
if (Widget^.Parent<>nil)
and (MainWindow=gtk_widget_get_parent_window(Widget)) then begin
// the widget is using its parent window
// -> adjust the coordinates
inc(MainOrigin.X,Widget^.Allocation.X);
inc(MainOrigin.Y,Widget^.Allocation.Y);
end;
if ClientWindow<>nil then begin
{$Ifdef GTK2}
if GTK_WIDGET_NO_WINDOW(ClientWidget)
then begin
ClientOrigin.X := ClientWidget^.Allocation.X;
ClientOrigin.Y := ClientWidget^.Allocation.Y;
end else
{$EndIf}
gdk_window_get_origin(ClientWindow,@ClientOrigin.X,@ClientOrigin.Y);
end else begin
// client widget not realized
{$Ifdef GTK2}
if GTK_WIDGET_NO_WINDOW(ClientWidget)
then begin
ClientOrigin.X := ClientWidget^.Allocation.X;
ClientOrigin.Y := ClientWidget^.Allocation.Y;
end else
{$EndIf}
ClientOrigin:=MainOrigin;
end;
ARect.Left:=ClientOrigin.X-MainOrigin.X;
ARect.Top:=ClientOrigin.Y-MainOrigin.Y;
ARect.Right:=ARect.Left+ClientWidget^.Allocation.Width;
ARect.Bottom:=ARect.Top+ClientWidget^.Allocation.Height;
Result:=true;
end;
end;
if not Result then begin
with Widget^.Allocation do
ARect := Rect(0,0,Width,Height);
end;
Result:=true;
end;
{------------------------------------------------------------------------------
Function: GetClientRect
Params: handle:
Result:
Returns: true on success
Returns the client rectangle of a control. Left and Top are always 0.
The client rectangle is the size of the inner area of a control, where the
child controls are visible.
------------------------------------------------------------------------------}
Function TGtkWidgetSet.GetClientRect(handle : HWND; var ARect : TRect) : Boolean;
var
Widget, ClientWidget: PGtkWidget;
begin
Result := false;
if Handle = 0 then Exit;
ARect.Left := 0;
ARect.Top := 0;
Widget := pgtkwidget(Handle);
ClientWidget := GetFixedWidget(Widget);
if (ClientWidget <> nil) then
Widget := ClientWidget;
if (Widget <> nil) then begin
ARect.Right:=Widget^.Allocation.Width;
ARect.Bottom:=Widget^.Allocation.Height;
end else begin
ARect.Right:=0;
ARect.Bottom:=0;
end;
{$IfDef VerboseGetClientRect}
if ClientWidget<>nil then begin
DebugLn('GetClientRect Widget=',DbgS(handle),
' Client=',DbgS(ClientWidget),
' WindowSize=',ARect.Right,',',ARect.Bottom,
' Allocation=',ClientWidget^.Allocation.Width,',',ClientWidget^.Allocation.Height
);
end else begin
DebugLn('GetClientRect Widget=',DbgS(handle),
' Client=',DbgS(ClientWidget),
' WindowSize=',ARect.Right,',',ARect.Bottom,
' Allocation=',Widget^.Allocation.Width,',',Widget^.Allocation.Height
);
end;
{$EndIf}
Result:=true;
end;
{------------------------------------------------------------------------------
Function: GetClipBox
Params: dc, lprect
Returns: Integer
Returns the smallest rectangle which includes the entire current
Clipping Region, or if no Clipping Region is set, the current
dimensions of the Drawable.
The result can be one of the following constants
Error
NullRegion
SimpleRegion
ComplexRegion
------------------------------------------------------------------------------}
Function TGtkWidgetSet.GetClipBox(DC : hDC; lpRect : PRect) : Longint;
var
CRect : TGDKRectangle;
X, Y : Longint;
DCOrigin: Tpoint;
begin
// set default values
Result := SIMPLEREGION;
If lpRect <> nil then
lpRect^ := Rect(0,0,0,0);
If not IsValidDC(DC) then
Result := ERROR;
if Result <> ERROR
then with TDeviceContext(DC) do
begin
DCOrigin:=GetDCOffset(TDeviceContext(DC));
If Not IsValidGDIObject(ClipRegion) then begin
{$IFDEF DebugGDKTraps}
BeginGDKErrorTrap;
{$ENDIF}
gdk_window_get_size(Drawable, @X, @Y);
{$IFDEF DebugGDKTraps}
EndGDKErrorTrap;
{$ENDIF}
lpRect^ := Rect(-DCOrigin.X, -DCOrigin.Y, X-DCOrigin.X, Y-DCOrigin.Y);
Result := SIMPLEREGION;
end
else begin
Result := RegionType(PGDIObject(ClipRegion)^.GDIRegionObject);
gdk_region_get_clipbox(PGDIObject(ClipRegion)^.GDIRegionObject,
@CRect);
lpRect^.Left := CRect.X-DCOrigin.X;
lpRect^.Top := CRect.Y-DCOrigin.Y;
lpRect^.Right := lpRect^.Left + CRect.Width;
lpRect^.Bottom := lpRect^.Top + CRect.Height;
end;
end;
end;
{------------------------------------------------------------------------------
Function: GetRGNBox
Params: rgn, lprect
Returns: Integer
Returns the smallest rectangle which includes the entire passed
Region, if lprect is null then just returns RegionType.
The result can be one of the following constants
Error
NullRegion
SimpleRegion
ComplexRegion
------------------------------------------------------------------------------}
Function TGtkWidgetSet.GetRgnBox(RGN : HRGN; lpRect : PRect) : Longint;
var
CRect : TGDKRectangle;
begin
Result := SIMPLEREGION;
If lpRect <> nil then
lpRect^ := Rect(0,0,0,0);
If Not IsValidGDIObject(RGN) then
Result := ERROR
else begin
Result := RegionType(PGDIObject(RGN)^.GDIRegionObject);
If lpRect <> nil then begin
gdk_region_get_clipbox(PGDIObject(RGN)^.GDIRegionObject,
@CRect);
With lpRect^,CRect do begin
Left := X;
Top := Y;
Right := X + Width;
Bottom := Y + Height;
end;
end;
end;
end;
Function TGtkWidgetSet.GetROP2(DC: HDC): Integer;
var
Values: TGdkGCValues;
begin
if not IsValidDC(DC) then begin
Assert(False, 'Trace:[TGtkWidgetSet.GetROP2] Invalid GC');
result := 0
end else
with TDeviceContext(DC) do begin
if GC = nil then begin
Assert(False, 'Trace:[TGtkWidgetSet.GetROP2] Uninitialized GC');
Result := 0;
end else begin
gdk_gc_get_values(GC, @Values);
result := GdkFunctionToROP2Mode( Values.{$ifdef gtk1}thefunction{$else}_function{$endif} )
end;
end;
end;
{------------------------------------------------------------------------------
Function: GetClipRGN
Params: dc, rgn
Returns: Integer
Returns a copy of the current Clipping Region.
The result can be one of the following constants
0 = no clipping set
1 = ok
-1 = error
------------------------------------------------------------------------------}
Function TGtkWidgetSet.GetClipRGN(DC : hDC; RGN : hRGN) : longint;
var
DCOrigin: TPoint;
ClipRegionWithDCOffset: PGdkRegion;
CurRegionObject: PGdkRegion;
ARect: TRect;
begin
Result := SIMPLEREGION;
If (not IsValidDC(DC)) then
Result := ERROR
else If Not IsValidGDIObject(RGN) then begin
Result := ERROR;
DebugLn('WARNING: [TGtkWidgetSet.GetClipRGN] Invalid HRGN');
end
else if (TDeviceContext(DC).ClipRegion<>0)
and (not IsValidGDIObject(TDeviceContext(DC).ClipRegion)) then
Result := ERROR
else with TDeviceContext(DC) do
begin
CurRegionObject:=nil;
if ClipRegion<>0 then
CurRegionObject:=PGdiObject(ClipRegion)^.GDIRegionObject;
ARect:=Rect(0,0,0,0);
if CurRegionObject<>nil then begin
// create a copy of the current clipregion
ClipRegionWithDCOffset:=gdk_region_copy(CurRegionObject);
// move it to the DC offset
// Example: if the ClipRegion is at 10,10 and the DCOrigin is at 10,10,
// then the ClipRegion must be moved to 0,0
DCOrigin:=GetDCOffset(TDeviceContext(DC));
//debugln('TGtkWidgetSet.GetClipRGN DCOrigin=',dbgs(DCOrigin),' CurRegionObject=',dbgs(CurRegionObject),' ',dbgs(ARect));
gdk_region_offset(ClipRegionWithDCOffset,-DCOrigin.x,-DCOrigin.Y);
end else begin
// create a default clipregion
GetClipBox(DC,@ARect);
ClipRegionWithDCOffset:=CreateRectGDKRegion(ARect);
end;
// free the old region in RGN
if PGdiObject(RGN)^.GDIRegionObject<>nil then
gdk_region_destroy(PGdiObject(RGN)^.GDIRegionObject);
// set the new region in RGN
PGdiObject(RGN)^.GDIRegionObject := ClipRegionWithDCOffset;
Result := RegionType(ClipRegionWithDCOffset);
//DebugLn('TGtkWidgetSet.GetClipRGN B DC=',DbgS(DC),
// ' DCOrigin=',dbgs(DCOrigin),' RGN=',GDKRegionAsString(ClipRegionWithDCOffset),' Result=',dbgs(Result));
If Result = NULLREGION then
Result := 0
else If Result <> ERROR then
Result := 1;
end;
If Result = ERROR then
Result := -1;
end;
{------------------------------------------------------------------------------
Function: GetCmdLineParamDescForInterface
Params: none
Returns: ansistring
Returns a description of the command line parameters, that are understood by
the interface.
------------------------------------------------------------------------------}
Function TGtkWidgetSet.GetCmdLineParamDescForInterface: string;
function b(const s: string): string;
begin
Result:=BreakString(s,75,22)+LineEnding+LineEnding;
end;
begin
Result:=
b(rsgtkOptionNoTransient)
+b(rsgtkOptionModule)
+b(rsgOptionFatalWarnings)
+b(rsgtkOptionDebug)
+b(rsgtkOptionNoDebug)
+b(rsgdkOptionDebug)
+b(rsgdkOptionNoDebug)
+b(rsgtkOptionDisplay)
+b(rsgtkOptionSync)
+b(rsgtkOptionNoXshm)
+b(rsgtkOptionName)
+b(rsgtkOptionClass);
end;
{------------------------------------------------------------------------------
Function: GetCursorPos
Params: lpPoint: The cursorposition
Returns: True if succesful
------------------------------------------------------------------------------}
function TGtkWidgetSet.GetCursorPos(var lpPoint: TPoint ): Boolean;
{$IFDEF GTK2}
begin
// TODO: GTK2 GetCursorPos
DebugLn('TGtkWidgetSet.GetCursorPos ToDo');
Result:=false;
end;
{$ELSE}
{$IFDEF UNIX}
var
root, child: pointer;
winx, winy: Integer;
xmask: Cardinal;
TopList, List: PGList;
begin
Result := False;
{$IFDEF DebugGDKTraps}
BeginGDKErrorTrap;
{$ENDIF}
try
TopList := gdk_window_get_toplevels;
List := TopList;
while List <> nil do
begin
if (List^.Data <> nil)
and gdk_window_is_visible(List^.Data)
then begin
XQueryPointer(gdk_window_xdisplay(List^.Data),
gdk_window_xwindow(List^.Data),
@root,@child,@lpPoint.X,@lpPoint.Y,@winx,@winy,@xmask);
Result := True;
Break;
end;
List := g_list_next(List);
end;
if TopList <> nil
then g_list_free(TopList);
finally
{$IFDEF DebugGDKTraps}EndGDKErrorTrap;{$ENDIF}
end;
end;
{$ELSE}
begin
// TODO: GTK1-win32 GetCursorPos
Result := False;
end;
{$ENDIF unix}
{$ENDIF gkt2}
{------------------------------------------------------------------------------
Function: GetDC
Params: none
Returns: Nothing
hWnd is any widget.
The DC will be created for the client area and without the child areas
(they are clipped away). Child areas are all child gdkwindows
(e.g. not TControls).
------------------------------------------------------------------------------}
function TGtkWidgetSet.GetDC(hWnd: HWND): HDC;
begin
Result:=CreateDCForWidget(PGtkWidget(hWnd),nil,false);
end;
{------------------------------------------------------------------------------
function TGtkWidgetSet.GetDeviceCaps(DC: HDC; Index: Integer): Integer;
------------------------------------------------------------------------------}
function TGtkWidgetSet.GetDeviceCaps(DC: HDC; Index: Integer): Integer;
var
Visual: PGdkVisual;
function GetVisual: boolean;
begin
Visual:=nil;
with TDeviceContext(DC) do begin
If Drawable <> nil then
Visual:=gdk_window_get_visual(PGdkWindow(Drawable));
if Visual = nil then
Visual := GDK_Visual_Get_System;
end;
Result:=Visual<>nil;
end;
begin
Result := -1;
If DC = 0 then begin
DC := GetDC(0);
If DC = 0 then
exit;
Result := GetDeviceCaps(DC, Index);
ReleaseDC(0, DC);
end;
if not IsValidDC(DC) then exit;
with TDeviceContext(DC) do
Case Index of
HORZRES : { Horizontal width in pixels }
If Drawable = nil then
Result := GetSystemMetrics(SM_CXSCREEN)
else
gdk_drawable_get_size(Drawable, @Result, nil);
VERTRES : { Vertical height in pixels }
If Drawable = nil then
Result := GetSystemMetrics(SM_CYSCREEN)
else
gdk_drawable_get_size(Drawable, nil, @Result);
BITSPIXEL : { Number of used bits per pixel = depth }
If Drawable = nil then
Result := GDK_Visual_Get_System^.Depth
else
//gdk_window_get_geometry(Drawable, nil, nil, nil, nil, @Result);
Result := gdk_drawable_get_depth(Drawable);
PLANES : { Number of planes }
// ToDo
Result := 1;
//For Size in MM, MM = (Pixels*100)/(PPI*25.4)
HORZSIZE : { Horizontal size in millimeters }
Result := RoundToInt((GetDeviceCaps(DC, HORZRES) * 100) /
(GetDeviceCaps(DC, LOGPIXELSX) * 25.4));
VERTSIZE : { Vertical size in millimeters }
Result := RoundToInt((GetDeviceCaps(DC, VERTRES) * 100) /
(GetDeviceCaps(DC, LOGPIXELSY) * 25.4));
//So long as gdk_screen_width_mm is acurate, these should be
//acurate for Screen GDKDrawables. Once we get Metafiles
//we will also have to add internal support for Papersizes etc..
LOGPIXELSX : { Logical pixels per inch in X }
Result := RoundToInt(gdk_screen_width / (gdk_screen_width_mm / 25.4));
LOGPIXELSY : { Logical pixels per inch in Y }
Result := RoundToInt(gdk_screen_height / (gdk_screen_height_mm / 25.4));
SIZEPALETTE: { number of entries in color palette }
if GetVisual then
Result:=Visual^.colormap_size
else
Result:=0;
NUMRESERVED: { number of reserverd colors in color palette }
Result:=0;
else
DebugLn('TGtkWidgetSet.GetDeviceCaps not supported: Type=',dbgs(Index));
end;
end;
{------------------------------------------------------------------------------
function GetDeviceRawImageDescription(DC: HDC;
Desc: PRawImageDescription): boolean;
Retrieves the information about the structure of the supported image data.
------------------------------------------------------------------------------}
function TGtkWidgetSet.GetDeviceRawImageDescription(DC: HDC;
Desc: PRawImageDescription): boolean;
var
GDKWindow: PGdkWindow;
begin
GdkWindow:=nil;
If IsValidDC(DC) then
GDKWindow:=PGdkWindow(TDeviceContext(DC).Drawable);
Result:=GetWindowRawImageDescription(GDKWindow,Desc);
end;
{------------------------------------------------------------------------------
function GetDeviceSize(DC: HDC; var p: TPoint): boolean;
Retrieves the width and height of the device context in pixels.
------------------------------------------------------------------------------}
function TGtkWidgetSet.GetDeviceSize(DC: HDC; var p: TPoint): boolean;
begin
Result := false;
P := Point(0,0);
If IsValidDC(DC) then
with TDeviceContext(DC) do begin
if Drawable<>nil then begin
gdk_window_get_size(PGdkWindow(Drawable), @P.X, @P.Y);
Result := true;
end else begin
{$IFDEF RaiseExceptionOnNilPointers}
RaiseException('TGtkWidgetSet.GetDeviceSize Window=nil');
{$ENDIF}
DebugLn('TGtkWidgetSet.GetDeviceSize:',
' WARNING: DC ',DbgS(DC),' without gdkwindow.',
' Widget=',DbgS(wnd));
end;
end;
end;
{------------------------------------------------------------------------------
function TGtkWidgetSet.GetDCOriginRelativeToWindow(PaintDC: HDC;
WindowHandle: HWND; var OriginDiff: TPoint): boolean;
Returns the origin of PaintDC relative to the window handle.
Example:
A PaintDC of a TButton at 20,10 with a DC Offset of 0,0 on a form and the
WindowHandle is the form.
Then OriginDiff will be the the difference between the Forms client origin
and the PaintDC will be 20,10.
------------------------------------------------------------------------------}
function TGtkWidgetSet.GetDCOriginRelativeToWindow(PaintDC: HDC;
WindowHandle: HWND; var OriginDiff: TPoint): boolean;
procedure InvalidDrawable;
begin
{$IFDEF RaiseExceptionOnNilPointers}
RaiseException('TGtkWidgetSet.GetDCOriginRelativeToWindow Window=nil');
{$ENDIF}
DebugLn('TGtkWidgetSet.GetDCOriginRelativeToWindow:',
' WARNING: PaintDC ',DbgS(PaintDC),' without gdkwindow.',
' Widget=',DbgS(TDeviceContext(PaintDC).wnd));
end;
var
DCOrigin: TPoint;
DCScreenOrigin: TPoint;
WindowScreenOrigin: TPoint;
Widget: PGtkWidget;
ScreenDrawable: PGdkDrawable;
begin
Result := false;
OriginDiff := Point(0,0);
If not IsValidDC(PaintDC) then exit;
with TDeviceContext(PaintDC) do begin
DCOrigin:=GetDCOffset(TDeviceContext(PaintDC));
ScreenDrawable:=Drawable;
if (dcfDoubleBuffer in DCFlags) then
ScreenDrawable:=OriginalDrawable;
if ScreenDrawable=nil then
InvalidDrawable;
gdk_window_get_origin(PGdkWindow(Drawable),
@(DCScreenOrigin.X), @(DCScreenOrigin.Y));
inc(DCScreenOrigin.X,DCOrigin.X);
inc(DCScreenOrigin.Y,DCOrigin.Y);
Widget:=GetFixedWidget(PGtkWidget(WindowHandle));
if Widget=nil then Widget:=PGtkWidget(WindowHandle);
gdk_window_get_origin(PGdkWindow(Widget^.window),
@(WindowScreenOrigin.X), @(WindowScreenOrigin.Y));
OriginDiff.X:=DCScreenOrigin.X-WindowScreenOrigin.X;
OriginDiff.Y:=DCScreenOrigin.Y-WindowScreenOrigin.Y;
Result := true;
end;
end;
{------------------------------------------------------------------------------
Function: GetDesignerDC
Params: none
Returns: Nothing
WindowHandle is any widget.
The DC will be created for the client area including the child areas.
------------------------------------------------------------------------------}
function TGtkWidgetSet.GetDesignerDC(WindowHandle: HWND): HDC;
begin
//DebugLn('TGtkWidgetSet.GetDesignerDC A');
Result:=CreateDCForWidget(PGtkWidget(WindowHandle),nil,true);
end;
{------------------------------------------------------------------------------
Function: GetFocus
Params: none
Returns: The handle of the window with focus
The GetFocus function retrieves the handle of the window that has the focus.
------------------------------------------------------------------------------}
function TGtkWidgetSet.GetFocus: HWND;
var
TopList, List: PGList;
Widget: PGTKWidget;
Window: PGTKWindow;
begin
// Default to 0
Result := 0;
{$IFDEF DebugGDKTraps}
BeginGDKErrorTrap;
{$ENDIF}
TopList := gdk_window_get_toplevels;
List := TopList;
while List <> nil do
begin
if (List^.Data <> nil)
then begin
gdk_window_get_user_data(PGDKWindow(List^.Data), @Window);
if gtk_is_window(Window)
then begin
Widget := Window^.focus_widget;
if (Widget <> nil) and gtk_widget_has_focus(Widget)
then begin
Result := HWND(GetMainWidget(Widget));
Break;
end;
end;
end;
list := g_list_next(list);
end;
if TopList <> nil
then g_list_free(TopList);
{$IFDEF DebugGDKTraps}EndGDKErrorTrap;{$ENDIF}
end;
{------------------------------------------------------------------------------
function GetFontLanguageInfo(DC: HDC): DWord; override;
------------------------------------------------------------------------------}
function TGtkWidgetSet.GetFontLanguageInfo(DC: HDC): DWord;
begin
Result := 0;
If IsValidDC(DC) then
with TDeviceContext(DC) do begin
UpdateDCTextMetric(TDeviceContext(DC));
if TDeviceContext(DC).DCTextMetric.IsDoubleByteChar then
inc(Result,GCP_DBCS);
end;
end;
{------------------------------------------------------------------------------
Function: GetKeyState
Params: nVirtKey: The requested key
Returns: If the function succeeds, the return value specifies the status of
the given virtual key. If the high-order bit is 1, the key is down;
otherwise, it is up. If the low-order bit is 1, the key is toggled.
The GetKeyState function retrieves the status of the specified virtual key.
------------------------------------------------------------------------------}
function TGtkWidgetSet.GetKeyState(nVirtKey: Integer): Smallint;
const
KEYSTATE: array[Boolean] of Smallint = (0, -32768 { $8000});
TOGGLESTATE: array[Boolean] of Smallint = (0, 1);
begin
case nVirtKey of
VK_LSHIFT: nVirtKey := VK_SHIFT;
VK_LCONTROL: nVirtKey := VK_CONTROL;
VK_LMENU: nVirtKey := VK_MENU;
end;
{$IFDEF Use_KeyStateList}
Result := KEYSTATE[FKeyStateList_.IndexOf(Pointer(PtrInt(nVirtKey))) >=0];
{$ELSE}
Implement this
{$ENDIF}
// try extended keys
if Result = 0
then begin
nVirtKey := nVirtKey or KEYMAP_EXTENDED;
{$IFDEF Use_KeyStateList}
Result := KEYSTATE[FKeyStateList_.IndexOf(Pointer(PtrInt(nVirtKey))) >=0];
{$ELSE}
Implement this
{$ENDIF}
end;
{$IFDEF Use_KeyStateList}
// add toggle
if Result <> 0 then
Result := Result or TOGGLESTATE[FKeyStateList_.IndexOf(Pointer(
PtrInt(nVirtKey or KEYMAP_TOGGLE))) >=0];
{$ENDIF}
//Assert(False, Format('Trace:[TGtkWidgetSet.GetKeyState] %d -> 0x%x', [nVirtKey, Result]));
end;
{------------------------------------------------------------------------------
Function: GetObject
Params: none
Returns: Nothing
------------------------------------------------------------------------------}
function TGtkWidgetSet.GetObject(GDIObj: HGDIOBJ; BufSize: Integer;
Buf: Pointer): Integer;
var
NumColors : Longint;
BitmapSection : TDIBSECTION;
begin
Assert(False, 'trace:[TGtkWidgetSet.GetObject]');
Result := 0;
if IsValidGDIObject(GDIObj)
then begin
case PGDIObject(GDIObj)^.GDIType of
gdiBitmap:
begin
Assert(False, 'Trace:FINISH: [TGtkWidgetSet.GetObject] gdiBitmap');
if Buf = nil then
Result := SizeOf(TDIBSECTION)
else begin
FillChar(BitmapSection,SizeOf(TDIBSECTION),0);
With PGDIObject(GDIObj)^, BitmapSection,
BitmapSection.dsBm, BitmapSection.dsBmih
do begin
{dsBM - BITMAP}
bmType := $4D42;
bmWidth := 0 ;
bmHeight := 0;
{bmWidthBytes: Longint;}
bmPlanes := 1;//Does Bitmap Format support more?
bmBitsPixel := 1;
bmBits := nil;
{dsBmih - BITMAPINFOHEADER}
biSize := 40;
biWidth := 0;
biHeight := 0;
biPlanes := bmPlanes;
biBitCount := 1;
biCompression := 0;
biSizeImage := 0;
biXPelsPerMeter := 0;
biYPelsPerMeter := 0;
biClrUsed := 0;
biClrImportant := 0;
{dsBitfields: array[0..2] of DWORD;
dshSection: THandle;
dsOffset: DWORD;}
{$IFDEF DebugGDKTraps}
BeginGDKErrorTrap;
{$ENDIF}
case GDIBitmapType of
gbBitmap:
If GDIBitmapObject <> nil then begin
GDK_WINDOW_GET_SIZE(GDIBitmapObject, @biWidth, @biHeight);
NumColors := 2;
biBitCount := 1;
end;
gbPixmap:
If GDIPixmapObject <> nil then begin
biBitCount := word(gdk_drawable_get_depth(GDIPixmapObject));
gdk_drawable_get_size(GDIPixmapObject,@biWidth, @biHeight);
end;
{obsolete: gbImage :
If GDI_RGBImageObject <> nil then
With GDI_RGBImageObject^ do begin
biHeight := Height;
biWidth := Width;
biBitCount := Depth;
end;}
end;
If Visual = nil then begin
Visual := gdk_visual_get_best_with_depth(biBitCount);
If Visual = nil then { Depth not supported }
Visual := gdk_visual_get_system;
SystemVisual := True; { This visual should not be referenced }
If Colormap <> nil then
gdk_colormap_unref(Colormap);
ColorMap := gdk_colormap_new(Visual, GdkTrue);
end else
biBitCount := Visual^.Depth;
{$IFDEF DebugGDKTraps}EndGDKErrorTrap;{$ENDIF}
If biBitCount < 16 then
NumColors := Colormap^.Size;
biSizeImage := (((biBitCount*biWidth+31) shr 5) shl 2)*biHeight;
If GetSystemMetrics(SM_CXSCREEN) >= biWidth then
biXPelsPerMeter := GetDeviceCaps(0, LOGPIXELSX)
else
biXPelsPerMeter :=
RoundToInt((single(biWidth) / GetSystemMetrics(SM_CXSCREEN)) *
GetDeviceCaps(0, LOGPIXELSX));
If GetSystemMetrics(SM_CYSCREEN) >= biHeight then
biYPelsPerMeter := GetDeviceCaps(0, LOGPIXELSY)
else
biYPelsPerMeter :=
RoundToInt((Single(biHeight) / GetSystemMetrics(SM_CYSCREEN))*
GetDeviceCaps(0, LOGPIXELSY));
bmWidth := biWidth;
bmHeight := biHeight;
bmBitsPixel := biBitCount;
//Need to retrieve actual Number of Colors if Indexed Image
if (bmBitsPixel < 16) then begin
biClrUsed := NumColors;
biClrImportant := biClrUsed;
end;
end;
if BufSize >= SizeOf(BitmapSection)
then begin
PDIBSECTION(Buf)^ := BitmapSection;
Result:= SizeOf(TDIBSECTION);
end else
if BufSize>0 then begin
Move(BitmapSection,Buf^,BufSize);
Result:=BufSize;
end;
end;
end;
gdiBrush:
begin
Assert(False, 'Trace:TODO: [TGtkWidgetSet.GetObject] gdiBrush');
end;
gdiFont:
begin
{$IfDef GTK2}
Assert(False, 'Trace:TODO: [TGtkWidgetSet.GetObject] gdiFont(PANGO)');
{$Else}
if Buf = nil then
Result := SizeOf(PGDIObject(GDIObj)^.LogFont)
else begin
if BufSize >= SizeOf(PGDIObject(GDIObj)^.LogFont)
then begin
PLogfont(Buf)^ := PGDIObject(GDIObj)^.LogFont;
Result:= SizeOf(TLogFont);
end else if BufSize>0 then begin
Move(PGDIObject(GDIObj)^.LogFont,Buf^,BufSize);
Result:=BufSize;
end;
end;
{$EndIf}
end;
gdiPen:
begin
Assert(False, 'Trace:TODO: [TGtkWidgetSet.GetObject] gdiPen');
end;
gdiRegion:
begin
Assert(False, 'Trace:TODO: [TGtkWidgetSet.GetObject] gdiRegion');
end;
else
DebugLn(Format('WARNING: [TGtkWidgetSet.GetObject] Unknown type %d', [Integer(PGDIObject(GDIObj)^.GDIType)]));
end;
end;
end;
{------------------------------------------------------------------------------
Function: GetParent
Params: Handle:
Returns:
------------------------------------------------------------------------------}
Function TGtkWidgetSet.GetParent(Handle : HWND): HWND;
begin
//DebugLn('TGtkWidgetSet.GetParent ',DbgS(Handle));
Result:=0;
if Handle<>0 then
Result:=HWnd(PGtkWidget(Handle)^.Parent);
end;
{------------------------------------------------------------------------------
Function: GetProp
Params: Handle: Str
Returns: Pointer
------------------------------------------------------------------------------}
Function TGtkWidgetSet.GetProp(Handle : hwnd; Str : PChar): Pointer;
Begin
Result := gtk_object_get_data(pgtkobject(Handle),Str);
end;
{------------------------------------------------------------------------------
function TGtkWidgetSet.GetRawImageFromDevice(SrcDC: HDC; const SrcRect: TRect;
var NewRawImage: TRawImage): boolean;
------------------------------------------------------------------------------}
function TGtkWidgetSet.GetRawImageFromDevice(SrcDC: HDC; const SrcRect: TRect;
var NewRawImage: TRawImage): boolean;
var
DCOrigin: TPoint;
ARect: TRect;
GDKWindow: PGdkWindow;
begin
Result:=false;
if not IsValidDC(SrcDC) then begin
DebugLn('WARNING: TGtkWidgetSet.GetRawImageFromDevice invalid SrcDC');
exit;
end;
DCOrigin:=GetDCOffset(TDeviceContext(SrcDC));
{$IFDEF VerboseRawImage}
DebugLn('TGtkWidgetSet.GetRawImageFromDevice A DCOrigin=',dbgs(DCOrigin.X),',',dbgs(DCOrigin.Y),' SrcRect=',dbgs(SrcRect.Left),',',dbgs(SrcRect.Top),',',dbgs(SrcRect.Right),',',dbgs(SrcRect.Bottom));
{$ENDIF}
ARect:=SrcRect;
OffSetRect(ARect,DCOrigin.x,DCOrigin.y);
GDKWindow:=PGdkWindow(TDeviceContext(SrcDC).Drawable);
Result:=GetRawImageFromGdkWindow(GDKWindow,nil,ARect,NewRawImage);
end;
{------------------------------------------------------------------------------
function TGtkWidgetSet.GetRawImageFromBitmap(SrcBitmap, SrcMaskBitmap: HBITMAP;
const SrcRect: TRect; var NewRawImage: TRawImage): boolean; override;
------------------------------------------------------------------------------}
function TGtkWidgetSet.GetRawImageFromBitmap(SrcBitmap, SrcMaskBitmap: HBITMAP;
const SrcRect: TRect; var NewRawImage: TRawImage): boolean;
var
GDIImg: PGDIObject;
GdkPixmap: PGdkPixmap;
GDIMaskImg: PGDIObject;
GdkMaskBitmap: PGdkBitmap;
begin
Result:=false;
{$IFDEF VerboseRawImage}
DebugLn('TGtkWidgetSet.GetRawImageFromBitmap A');
{$ENDIF}
FillChar(NewRawImage,SizeOf(NewRawImage),0);
if (not IsValidGDIObject(SrcBitmap)) then begin
DebugLn('WARNING: [TGtkWidgetSet.GetRawImageFromBitmap] invalid SrcBitmap!');
exit;
end;
if ((SrcMaskBitmap<>0) and not IsValidGDIObject(SrcMaskBitmap)) then begin
DebugLn('WARNING: [TGtkWidgetSet.GetRawImageFromBitmap] invalid MaskBitmap!');
exit;
end;
try
// get rawimage for Bitmap
GDIImg:=PGDIObject(SrcBitmap);
GdkPixmap:=nil;
case GDIImg^.GDIBitmapType of
gbBitmap: GdkPixmap:=PGdkPixmap(GDIImg^.GDIBitmapObject);
gbPixmap: GdkPixmap:=PGdkPixmap(GDIImg^.GDIPixmapObject);
else
DebugLn('WARNING: [TGtkWidgetSet.GetRawImageFromBitmap] GDI_RGBImage not implemented');
exit;
end;
{$IFDEF VerboseRawImage}
DebugLn('TGtkWidgetSet.GetRawImageFromBitmap A GdkPixmap=',DbgS(GdkPixmap),8),' SrcMaskBitmap=',DbgS(Cardinal(SrcMaskBitmap));
{$ENDIF}
GDIMaskImg:=nil;
GdkMaskBitmap:=nil;
if SrcMaskBitmap<>0 then begin
// use special mask SrcMaskBitmap
GDIMaskImg:=PGDIObject(SrcMaskBitmap);
case GDIMaskImg^.GDIBitmapType of
gbBitmap: GdkMaskBitmap:=GDIMaskImg^.GDIBitmapObject;
else
DebugLn('WARNING: [TGtkWidgetSet.GetRawImageFromBitmap] invalid MaskBitmap');
exit;
end;
end else if GDIImg^.GDIBitmapMaskObject<>nil then begin
// use mask in SrcBitmap
GdkMaskBitmap:=GDIImg^.GDIBitmapMaskObject;
end else begin
// no mask available
end;
if not GetRawImageFromGdkWindow(PGdkWindow(GdkPixmap),GdkMaskBitmap,SrcRect,
NewRawImage)
then begin
DebugLn('WARNING: [TGtkWidgetSet.GetRawImageFromBitmap] unable to GetRawImageFromGdkWindow Image');
exit;
end;
except
FreeRawImageData(@NewRawImage);
end;
Result:=true;
end;
{------------------------------------------------------------------------------
function TGtkWidgetSet.GetScrollBarSize(Handle: HWND; BarKind: Integer): integer;
Returns the current width of the scrollbar of the widget.
------------------------------------------------------------------------------}
function TGtkWidgetSet.GetScrollBarSize(Handle: HWND; BarKind: Integer): integer;
var
Widget, ScrollWidget, BarWidget: PGtkWidget;
begin
Result:=0;
Widget:=PGtkWidget(Handle);
if GtkWidgetIsA(Widget,GTK_TYPE_SCROLLED_WINDOW) then begin
ScrollWidget:=Widget;
end else begin
ScrollWidget:=PGtkWidget(gtk_object_get_data(
PGtkObject(Widget),odnScrollArea));
end;
if ScrollWidget=nil then exit;
if BarKind=SM_CYVSCROLL then begin
BarWidget:=PGtkScrolledWindow(ScrollWidget)^.vscrollbar;
if BarWidget<>nil then
Result:=BarWidget^.Requisition.Width;
end else begin
BarWidget:=PGtkScrolledWindow(ScrollWidget)^.hscrollbar;
if BarWidget<>nil then
Result:=BarWidget^.Requisition.Height;
end;
end;
{------------------------------------------------------------------------------
function TGtkWidgetSet.GetScrollbarVisible(Handle: HWND;
SBStyle: Integer): boolean;
------------------------------------------------------------------------------}
function TGtkWidgetSet.GetScrollbarVisible(Handle: HWND; SBStyle: Integer): boolean;
var
Widget, ScrollWidget, BarWidget: PGtkWidget;
begin
Result:=false;
if Handle=0 then exit;
Widget:=PGtkWidget(Handle);
if GtkWidgetIsA(Widget,GTK_TYPE_SCROLLED_WINDOW) then begin
ScrollWidget:=Widget;
end else begin
ScrollWidget:=PGtkWidget(gtk_object_get_data(
PGtkObject(Widget),odnScrollArea));
end;
if ScrollWidget=nil then exit;
if SBStyle=SB_VERT then begin
BarWidget:=PGtkScrolledWindow(ScrollWidget)^.vscrollbar;
end else begin
BarWidget:=PGtkScrolledWindow(ScrollWidget)^.hscrollbar;
end;
if BarWidget<>nil then
Result:=GTK_WIDGET_VISIBLE(BarWidget);
end;
{------------------------------------------------------------------------------
Function: GetScrollInfo
Params: Handle, BarFlag, ScrollInfo
Returns: Nothing
------------------------------------------------------------------------------}
function TGtkWidgetSet.GetScrollInfo(Handle: HWND; SBStyle: Integer;
var ScrollInfo: TScrollInfo): Boolean;
var
Adjustment: PGtkAdjustment;
Scroll : PGTKWidget;
begin
Result := false;
if (Handle = 0) then exit;
Adjustment := nil;
Scroll := GTK_Object_Get_Data(PGTKObject(Handle), odnScrollArea);
If not GtkWidgetIsA(PGtkWidget(Scroll),gtk_scrolled_window_get_type) then
Scroll := PGTKWidget(Handle);
case SBStyle of
SB_HORZ:
If GtkWidgetIsA(PGtkWidget(Scroll),gtk_scrolled_window_get_type) then
Adjustment := gtk_scrolled_window_get_hadjustment(
PGTKScrolledWindow(Scroll))
else
if GtkWidgetIsA(PGtkWidget(Scroll),gtk_hscrollbar_get_type) then
Adjustment := PgtkhScrollBar(Scroll)^.Scrollbar.Range.Adjustment
else //clist
if GtkWidgetIsA(PGtkWidget(Scroll),gtk_clist_get_type) then
Adjustment := gtk_clist_get_hadjustment(PgtkCList(Scroll));
SB_VERT:
If GtkWidgetIsA(PGtkWidget(Scroll),gtk_scrolled_window_get_type) then
Adjustment := gtk_scrolled_window_get_vadjustment(
PGTKScrolledWindow(Scroll))
else
if GtkWidgetIsA(PGtkWidget(Scroll),gtk_vscrollbar_get_type) then
Adjustment := PgtkvScrollBar(Scroll)^.Scrollbar.Range.Adjustment
else //clist
if GtkWidgetIsA(PGtkWidget(Scroll), gtk_clist_get_type) then
Adjustment := gtk_clist_get_vadjustment(PgtkCList(Scroll));
SB_CTL:
if GtkWidgetIsA(PGtkWidget(Scroll), gtk_range_get_type) then
Adjustment := gtk_range_get_adjustment(PGTKRange(Scroll));
end;
if Adjustment<>nil then begin
with ScrollInfo, Adjustment^ do begin
// POS
if (fMask and SIF_POS) <> 0 then
nPos := RoundToInt(Value);
// RANGE
if (fMask and SIF_RANGE) <> 0
then begin
nMin:= RoundToInt(Lower);
nMax:= RoundToInt(Upper);
end;
// PAGE
if (fMask and SIF_PAGE) <> 0 then
nPage := RoundToCardinal(Page_Size);
// TRACKPOS
if (fMask and SIF_TRACKPOS)<>0 then
nTrackPos := RoundToInt(Value);
end;
Result := true;
end else begin
with ScrollInfo, Adjustment^ do begin
// POS
if (fMask and SIF_POS) <> 0 then
nPos := 0;
// RANGE
if (fMask and SIF_RANGE) <> 0
then begin
nMin:= 0;
nMax:= 0;
end;
// PAGE
if (fMask and SIF_PAGE) <> 0 then
nPage := 0;
// TRACKPOS
if (fMask and SIF_TRACKPOS)<>0 then
nTrackPos := 0;
end;
Result := false;
end;
end;
{------------------------------------------------------------------------------
Function TGtkWidgetSet.CreateSystemFont : hFont;
------------------------------------------------------------------------------}
Function TGtkWidgetSet.CreateSystemFont: hFont;
var
GDIObj : PGDIObject;
begin
GDIObj := NewGDIObject(gdiFont);
{$IfDef GTK2}
GDIObj^.GDIFontObject:= GetDefaultFontDesc(true);
{$Else}
GDIObj^.GDIFontObject:= GetDefaultFont(true);
{$EndIf}
Result := hFont(GDIObj);
;
end;
{------------------------------------------------------------------------------
Function: GetStockObject
Params:
Returns: Nothing
------------------------------------------------------------------------------}
function TGtkWidgetSet.GetStockObject(Value: Integer): LongInt;
begin
Assert(False, Format('Trace:> [TGtkWidgetSet.GetStockObject] %d', [Value]));
Result := 0;
case Value of
BLACK_BRUSH: // Black brush.
Result := FStockBlackBrush;
DKGRAY_BRUSH: // Dark gray brush.
Result := FStockDKGrayBrush;
GRAY_BRUSH: // Gray brush.
Result := FStockGrayBrush;
LTGRAY_BRUSH: // Light gray brush.
Result := FStockLtGrayBrush;
NULL_BRUSH: // Null brush (equivalent to HOLLOW_BRUSH).
Result := FStockNullBrush;
WHITE_BRUSH: // White brush.
Result := FStockWhiteBrush;
BLACK_PEN: // Black pen.
Result := FStockBlackPen;
NULL_PEN: // Null pen.
Result := FStockNullPen;
WHITE_PEN: // White pen.
Result := FStockWhitePen;
(* ANSI_FIXED_FONT: // Fixed-pitch (monospace) system font.
begin
{If FStockFixedFont = 0 then
FStockFixedFont := GetStockFixedFont;
Result := FStockFixedFont;}
end;
ANSI_VAR_FONT: // Variable-pitch (proportional space) system font.
begin
end;
DEVICE_DEFAULT_FONT: // Device-dependent font.
begin
end; *)
(* OEM_FIXED_FONT: // Original equipment manufacturer (OEM) dependent fixed-pitch (monospace) font.
begin
end;
*)
DEFAULT_GUI_FONT, SYSTEM_FONT: // System font. By default, Windows uses the system font to draw menus, dialog box controls, and text. In Windows versions 3.0 and later, the system font is a proportionally spaced font; earlier versions of Windows used a monospace system font.
begin
If FStockSystemFont <> 0 then begin //This is a Temporary Hack!!! This
DeleteObject(FStockSystemFont); //should really only be done on
FStockSystemFont := 0; //theme change.
end;
If FStockSystemFont = 0 then
FStockSystemFont := CreateSystemFont;
Result := FStockSystemFont;
end;
(* SYSTEM_FIXED_FONT: // Fixed-pitch (monospace) system font used in Windows versions earlier than 3.0. This stock object is provided for compatibility with earlier versions of Windows.
begin
Result := GetStockObject(ANSI_FIXED_FONT);
end;
DEFAULT_PALETTE: // Default palette. This palette consists of the static colors in the system palette.
begin
end;
*) else
Assert(False, Format('Trace:TODO: [TGtkWidgetSet.GetStockObject] Implement value: %d', [Value]));
end;
Assert(False, Format('Trace:< [TGtkWidgetSet.GetStockObject] %d --> 0x%x', [Value, Result]));
end;
{------------------------------------------------------------------------------
Function: GetSysColor
Params: index to the syscolors array
Returns: RGB value
------------------------------------------------------------------------------}
function TGtkWidgetSet.GetSysColor(nIndex: Integer): DWORD;
begin
if (nIndex < 0) or (nIndex > MAX_SYS_COLORS)
then begin
Result := 0;
//RaiseException('');
DebugLn(Format('ERROR: [TGtkWidgetSet.GetSysColor] Bad Value: %8x Valid Range between 0 and %d', [nIndex, MAX_SYS_COLORS]));
end
else Result := SysColorMap[nIndex];
//Assert(False, Format('Trace:[TGtkWidgetSet.GetSysColor] Index %d --> %8x', [nIndex, Result]));
end;
{------------------------------------------------------------------------------
Function: GetSystemMetrics
Params:
Returns: Nothing
------------------------------------------------------------------------------}
function TGtkWidgetSet.GetSystemMetrics(nIndex: Integer): Integer;
var
P : Pointer;
begin
Assert(False, Format('Trace:> [TGtkWidgetSet.GetSystemMetrics] %d', [nIndex]));
case nIndex of
SM_ARRANGE:
begin
Assert(False, 'Trace:TODO: [TGtkWidgetSet.GetSystemMetrics] --> SM_ARRANGE ');
end;
SM_CLEANBOOT:
begin
Assert(False, 'Trace:TODO: [TGtkWidgetSet.GetSystemMetrics] --> SM_CLEANBOOT ');
end;
SM_CMOUSEBUTTONS:
begin
Assert(False, 'Trace:TODO: [TGtkWidgetSet.GetSystemMetrics] --> SM_CMOUSEBUTTONS ');
end;
SM_CXBORDER:
begin
Assert(False, 'Trace:TODO: [TGtkWidgetSet.GetSystemMetrics] --> SM_CXBORDER ');
end;
SM_CYBORDER:
begin
Assert(False, 'Trace:TODO: [TGtkWidgetSet.GetSystemMetrics] --> SM_CYBORDER ');
end;
SM_CXCURSOR:
begin
Assert(False, 'Trace:TODO: [TGtkWidgetSet.GetSystemMetrics] --> SM_CXCURSOR ');
end;
SM_CYCURSOR:
begin
Assert(False, 'Trace:TODO: [TGtkWidgetSet.GetSystemMetrics] --> SM_CYCURSOR ');
end;
SM_CXDOUBLECLK:
begin
Assert(False, 'Trace:TODO: [TGtkWidgetSet.GetSystemMetrics] --> SM_CXDOUBLECLK ');
end;
SM_CYDOUBLECLK:
begin
Assert(False, 'Trace:TODO: [TGtkWidgetSet.GetSystemMetrics] --> SM_CYDOUBLECLK ');
end;
SM_CXDRAG:
begin
Result := 2;
end;
SM_CYDRAG:
begin
Result := 2;
end;
SM_CXEDGE:
begin
Assert(False, 'Trace:TODO: [TGtkWidgetSet.GetSystemMetrics] --> SM_CXEDGE ');
end;
SM_CYEDGE:
begin
Assert(False, 'Trace:TODO: [TGtkWidgetSet.GetSystemMetrics] --> SM_CYEDGE ');
end;
SM_CXFIXEDFRAME:
begin
Assert(False, 'Trace:TODO: [TGtkWidgetSet.GetSystemMetrics] --> SM_CXFIXEDFRAME ');
end;
SM_CYFIXEDFRAME:
begin
Assert(False, 'Trace:TODO: [TGtkWidgetSet.GetSystemMetrics] --> SM_CYFIXEDFRAME ');
end;
SM_CXFULLSCREEN:
begin
Assert(False, 'Trace:TODO: [TGtkWidgetSet.GetSystemMetrics] --> SM_CXFULLSCREEN ');
end;
SM_CYFULLSCREEN:
begin
Assert(False, 'Trace:TODO: [TGtkWidgetSet.GetSystemMetrics] --> SM_CYFULLSCREEN ');
end;
SM_CXHSCROLL:
begin
P:=GetStyleWidget(lgsVerticalScrollbar);
Result := GTK_Widget(P)^.requisition.Width;
end;
SM_CYHSCROLL:
begin
P:=GetStyleWidget(lgsHorizontalScrollbar);
Result := GTK_Widget(P)^.requisition.Height;
end;
SM_CXHTHUMB:
begin
Assert(False, 'Trace:TODO: [TGtkWidgetSet.GetSystemMetrics] --> SM_CXHTHUMB ');
end;
SM_CXICON:
begin
Assert(False, 'Trace:TODO: [TGtkWidgetSet.GetSystemMetrics] --> SM_CXICON ');
end;
SM_CYICON:
begin
Assert(False, 'Trace:TODO: [TGtkWidgetSet.GetSystemMetrics] --> SM_CYICON ');
end;
SM_CXICONSPACING:
begin
Assert(False, 'Trace:TODO: [TGtkWidgetSet.GetSystemMetrics] --> SM_CXICONSPACING ');
end;
SM_CYICONSPACING:
begin
Assert(False, 'Trace:TODO: [TGtkWidgetSet.GetSystemMetrics] --> SM_CYICONSPACING ');
end;
SM_CXMAXIMIZED:
begin
Assert(False, 'Trace:TODO: [TGtkWidgetSet.GetSystemMetrics] --> SM_CXMAXIMIZED ');
end;
SM_CYMAXIMIZED:
begin
Assert(False, 'Trace:TODO: [TGtkWidgetSet.GetSystemMetrics] --> SM_CYMAXIMIZED ');
end;
SM_CXMAXTRACK:
begin
Assert(False, 'Trace:TODO: [TGtkWidgetSet.GetSystemMetrics] --> SM_CXMAXTRACK ');
end;
SM_CYMAXTRACK:
begin
Assert(False, 'Trace:TODO: [TGtkWidgetSet.GetSystemMetrics] --> SM_CYMAXTRACK ');
end;
SM_CXMENUCHECK:
begin
Assert(False, 'Trace:TODO: [TGtkWidgetSet.GetSystemMetrics] --> SM_CXMENUCHECK ');
end;
SM_CYMENUCHECK:
begin
Assert(False, 'Trace:TODO: [TGtkWidgetSet.GetSystemMetrics] --> SM_CYMENUCHECK ');
end;
SM_CXMENUSIZE:
begin
Assert(False, 'Trace:TODO: [TGtkWidgetSet.GetSystemMetrics] --> SM_CXMENUSIZE ');
end;
SM_CYMENUSIZE:
begin
Assert(False, 'Trace:TODO: [TGtkWidgetSet.GetSystemMetrics] --> SM_CYMENUSIZE ');
end;
SM_CXMIN:
begin
Assert(False, 'Trace:TODO: [TGtkWidgetSet.GetSystemMetrics] --> SM_CXMIN ');
end;
SM_CYMIN:
begin
Assert(False, 'Trace:TODO: [TGtkWidgetSet.GetSystemMetrics] --> SM_CYMIN ');
end;
SM_CXMINIMIZED:
begin
Assert(False, 'Trace:TODO: [TGtkWidgetSet.GetSystemMetrics] --> SM_CXMINIMIZED ');
end;
SM_CYMINIMIZED:
begin
Assert(False, 'Trace:TODO: [TGtkWidgetSet.GetSystemMetrics] --> SM_CYMINIMIZED ');
end;
SM_CXMINSPACING:
begin
Assert(False, 'Trace:TODO: [TGtkWidgetSet.GetSystemMetrics] --> SM_CXMINSPACING ');
end;
SM_CYMINSPACING:
begin
Assert(False, 'Trace:TODO: [TGtkWidgetSet.GetSystemMetrics] --> SM_CYMINSPACING ');
end;
SM_CXMINTRACK:
begin
Assert(False, 'Trace:TODO: [TGtkWidgetSet.GetSystemMetrics] --> SM_CXMINTRACK ');
end;
SM_CYMINTRACK:
begin
Assert(False, 'Trace:TODO: [TGtkWidgetSet.GetSystemMetrics] --> SM_CYMINTRACK ');
end;
SM_CXSCREEN:
begin
{$IFDEF GTK1} { Partial fix for multi monitor systems - force use of first one }
{$IFDEF UseXinerama}
if GetFirstScreen then
result := FirstScreen.x
else
{$ENDIF}
{$ENDIF}
result := gdk_Screen_Width;
end;
SM_CYSCREEN:
begin
{$IFDEF GTK1}
{$IFDEF UseXinerama}
if GetFirstScreen then
result := FirstScreen.y
else
{$ENDIF}
{$ENDIF}
result := gdk_Screen_Height;
end;
SM_CXSIZE:
begin
Assert(False, 'Trace:TODO: [TGtkWidgetSet.GetSystemMetrics] --> SM_CXSIZE ');
end;
SM_CYSIZE:
begin
Assert(False, 'Trace:TODO: [TGtkWidgetSet.GetSystemMetrics] --> SM_CYSIZE ');
end;
SM_CXSIZEFRAME:
begin
Assert(False, 'Trace:TODO: [TGtkWidgetSet.GetSystemMetrics] --> SM_CXSIZEFRAME ');
end;
SM_CYSIZEFRAME:
begin
Assert(False, 'Trace:TODO: [TGtkWidgetSet.GetSystemMetrics] --> SM_CYSIZEFRAME ');
end;
SM_CXSMICON:
begin
Assert(False, 'Trace:TODO: [TGtkWidgetSet.GetSystemMetrics] --> SM_CXSMICON ');
end;
SM_CYSMICON:
begin
Assert(False, 'Trace:TODO: [TGtkWidgetSet.GetSystemMetrics] --> SM_CYSMICON ');
end;
SM_CXSMSIZE:
begin
Assert(False, 'Trace:TODO: [TGtkWidgetSet.GetSystemMetrics] --> SM_CXSMSIZE ');
end;
SM_CYSMSIZE:
begin
Assert(False, 'Trace:TODO: [TGtkWidgetSet.GetSystemMetrics] --> SM_CYSMSIZE ');
end;
SM_CXVSCROLL:
begin
P:=GetStyleWidget(lgsVerticalScrollbar);
Result := GTK_Widget(P)^.requisition.Width;
end;
SM_CYVSCROLL:
begin
P:=GetStyleWidget(lgsHorizontalScrollbar);
Result := GTK_Widget(P)^.requisition.Height;
end;
SM_CYCAPTION:
begin
Assert(False, 'Trace:TODO: [TGtkWidgetSet.GetSystemMetrics] --> SM_CYCAPTION ');
end;
SM_CYKANJIWINDOW:
begin
Assert(False, 'Trace:TODO: [TGtkWidgetSet.GetSystemMetrics] --> SM_CYKANJIWINDOW ');
end;
SM_CYMENU:
begin
Assert(False, 'Trace:TODO: [TGtkWidgetSet.GetSystemMetrics] --> SM_CYMENU ');
end;
SM_CYSMCAPTION:
begin
Assert(False, 'Trace:TODO: [TGtkWidgetSet.GetSystemMetrics] --> SM_CYSMCAPTION ');
end;
SM_CYVTHUMB:
begin
Assert(False, 'Trace:TODO: [TGtkWidgetSet.GetSystemMetrics] --> SM_CYVTHUMB ');
end;
SM_DBCSENABLED:
begin
Assert(False, 'Trace:TODO: [TGtkWidgetSet.GetSystemMetrics] --> SM_DBCSENABLED ');
end;
SM_DEBUG:
begin
Assert(False, 'Trace:TODO: [TGtkWidgetSet.GetSystemMetrics] --> SM_DEBUG ');
end;
SM_MENUDROPALIGNMENT:
begin
Assert(False, 'Trace:TODO: [TGtkWidgetSet.GetSystemMetrics] --> SM_MENUDROPALIGNMENT');
end;
SM_MIDEASTENABLED:
begin
Assert(False, 'Trace:TODO: [TGtkWidgetSet.GetSystemMetrics] --> SM_MIDEASTENABLED ');
end;
SM_MOUSEPRESENT:
begin
Assert(False, 'Trace:TODO: [TGtkWidgetSet.GetSystemMetrics] --> SM_MOUSEPRESENT ');
end;
SM_MOUSEWHEELPRESENT:
begin
Assert(False, 'Trace:TODO: [TGtkWidgetSet.GetSystemMetrics] --> SM_MOUSEWHEELPRESENT');
end;
SM_NETWORK:
begin
Assert(False, 'Trace:TODO: [TGtkWidgetSet.GetSystemMetrics] --> SM_NETWORK ');
end;
SM_PENWINDOWS:
begin
Assert(False, 'Trace:TODO: [TGtkWidgetSet.GetSystemMetrics] --> SM_PENWINDOWS ');
end;
SM_SECURE:
begin
Assert(False, 'Trace:TODO: [TGtkWidgetSet.GetSystemMetrics] --> SM_SECURE ');
end;
SM_SHOWSOUNDS:
begin
Assert(False, 'Trace:TODO: [TGtkWidgetSet.GetSystemMetrics] --> SM_SHOWSOUNDS ');
end;
SM_SLOWMACHINE:
begin
Assert(False, 'Trace:TODO: [TGtkWidgetSet.GetSystemMetrics] --> SM_SLOWMACHINE ');
end;
SM_SWAPBUTTON:
begin
Assert(False, 'Trace:TODO: [TGtkWidgetSet.GetSystemMetrics] --> SM_SWAPBUTTON ');
end;
else Result := 0;
end;
Assert(False, Format('Trace:< [TGtkWidgetSet.GetSystemMetrics] %d --> 0x%x (%d)', [nIndex, Result, Result]));
end;
{------------------------------------------------------------------------------
Function: GetTextColor
Params: DC
Returns: TColorRef
Gets the Font Color currently assigned to the Device Context
------------------------------------------------------------------------------}
function TGtkWidgetSet.GetTextColor(DC: HDC) : TColorRef;
begin
Result := 0;
if IsValidDC(DC) then
with TDeviceContext(DC) do
begin
Result := CurrentTextColor.ColorRef;
end;
end;
{------------------------------------------------------------------------------
Function: GetTextExtentPoint
Params: none
Returns: Nothing
------------------------------------------------------------------------------}
function TGtkWidgetSet.GetTextExtentPoint(DC: HDC; Str: PChar; Count: Integer;
var Size: TSize): Boolean;
{$IfDef GTK2}
begin
DebugLn('TGtkWidgetSet.GetTextExtentPoint ToDo');
Result:=false;
end;
{$Else}
var
lbearing, rbearing, width, ascent,descent: LongInt;
UseFont : PGDKFont;
UnRef : Boolean;
IsDBCSFont: Boolean;
NewCount: Integer;
begin
Result := IsValidDC(DC);
if Result
then with TDeviceContext(DC) do
begin
if (CurrentFont = nil) or (CurrentFont^.GDIFontObject = nil)
then begin
UseFont := GetDefaultFont(true);
UnRef := True;
end
else begin
UseFont := CurrentFont^.GDIFontObject;
UnRef := False;
end;
If UseFont = nil then
DebugLn('WARNING: [TGtkWidgetSet.GetTextExtentPoint] Missing font')
else begin
descent:=0;
UpdateDCTextMetric(TDeviceContext(DC));
IsDBCSFont:=TDeviceContext(DC).DCTextMetric.IsDoubleByteChar;
if IsDBCSFont then begin
NewCount:=Count*2;
if FExtUTF8OutCacheSize<NewCount then begin
ReAllocMem(FExtUTF8OutCache,NewCount);
FExtUTF8OutCacheSize:=NewCount;
end;
NewCount:=UTF8ToDoubleByte(Str,Count,FExtUTF8OutCache)*2;
gdk_text_extents(UseFont, FExtUTF8OutCache, NewCount,
@lbearing, @rBearing, @width, @ascent, @descent);
end else begin
gdk_text_extents(UseFont, Str, Count,
@lbearing, @rBearing, @width, @ascent, @descent);
end;
Size.cX := Width;
// I THINK this is accurate...
Size.cY :={$IFDEF Win32}
GDK_String_Height(UseFont, Str)
{$ELSE}
ascent+descent;
{$ENDIF}
//debugln('TGtkWidgetSet.GetTextExtentPoint END Str="'+DbgStr(Str)+'" Size=',dbgs(Size.cX),'x',dbgs(Size.cY),' ascent=',dbgs(ascent),' descent=',dbgs(descent),' tmDescent=',dbgs(TDeviceContext(DC).DCTextMetric.TextMetric.tmDescent));
If UnRef then
FontCache.Unreference(UseFont);
end;
end;
Assert(False, 'trace:< [TGtkWidgetSet.GetTextExtentPoint]');
end;
{$EndIf}
{------------------------------------------------------------------------------
Function: GetTextMetrics
Params: none
Returns: Nothing
------------------------------------------------------------------------------}
function TGtkWidgetSet.GetTextMetrics(DC: HDC; var TM: TTextMetric): Boolean;
begin
Assert(False, Format('Trace:> TODO FINISH[TGtkWidgetSet.GetTextMetrics] DC: 0x%x', [DC]));
Result := IsValidDC(DC);
if Result then begin
UpdateDCTextMetric(TDeviceContext(DC));
TM:=TDeviceContext(DC).DCTextMetric.TextMetric;
end;
Assert(False, Format('Trace:< TODO FINISH[TGtkWidgetSet.GetTextMetrics] DC: 0x%x', [DC]));
end;
{------------------------------------------------------------------------------
Function: GetWindowLong
Params: none
Returns: Nothing
------------------------------------------------------------------------------}
Function TGtkWidgetSet.GetWindowLong(Handle : hwnd; int : Integer): Longint;
var
//Data : Tobject;
P : Pointer;
begin
//TODO:Started but not finished
Assert(False, Format('Trace:> [TGtkWidgetSet.GETWINDOWLONG] HWND: 0x%x, int: 0x%x (%d)', [Handle, int, int]));
case int of
GWL_WNDPROC :
begin
Result := Longint(gtk_object_get_data(pgtkobject(Handle),'WNDPROC'));
end;
GWL_HINSTANCE :
begin
Result := Longint(gtk_object_get_data(pgtkobject(Handle),'HINSTANCE'));
end;
GWL_HWNDPARENT :
begin
P := gtk_object_get_data(pgtkobject(Handle),'HWNDPARENT');
if P = nil then Result := 0 else Result := LongInt(p);
end;
{ GWL_WNDPROC :
begin
Data := GetLCLObject(Pointer(Handle));
if Data is TControl
then Result := Longint(@(TControl(Data).WindowProc));
// TODO fix this, a method pointer (2 pointers) cant be casted to a longint
end;
}
{ GWL_HWNDPARENT :
begin
Data := GetLCLObject(Pointer(Handle));
if (Data is TWinControl)
then Result := Longint(TWincontrol(Data).Handle)
else Result := 0;
end;
}
GWL_STYLE :
begin
Result := Longint(gtk_object_get_data(pgtkobject(Handle),'Style'));
end;
GWL_EXSTYLE :
begin
Result := Longint(gtk_object_get_data(pgtkobject(Handle),'ExStyle'));
end;
GWL_USERDATA :
begin
Result := Longint(gtk_object_get_data(pgtkobject(Handle),'Userdata'));
end;
GWL_ID :
begin
Result := Longint(gtk_object_get_data(pgtkobject(Handle),'ID'));
end;
else Result := 0;
end; //case
Assert(False, Format('Trace:< [TGtkWidgetSet.GETWINDOWLONG] HWND: 0x%x, int: 0x%x (%d) --> 0x%x (%d)', [Handle, int, int, Result, Result]));
end;
{------------------------------------------------------------------------------
Function: GetWindowOrgEx
Params: none
Returns: Nothing
Returns the current offset of the DC.
------------------------------------------------------------------------------}
function TGtkWidgetSet.GetWindowOrgEx(dc : hdc; P : PPoint): Integer;
begin
Result := 0;
if P=nil then exit;
P^ := Point(0,0);
If not IsValidDC(DC) then exit;
with TDeviceContext(DC) do begin
P^:=GetDCOffset(TDeviceContext(DC));
Result:=1;
end;
end;
{------------------------------------------------------------------------------
Function: GetWindowRect
Params: none
Returns: 0
After the call, ARect will be the control area in screen coordinates.
That means, Left and Top will be the screen coordinate of the TopLeft pixel
of the Handle object and Right and Bottom will be the screen coordinate of
the BottomRight pixel.
------------------------------------------------------------------------------}
function TGtkWidgetSet.GetWindowRect(Handle: hwnd; var ARect: TRect): Integer;
var
X, Y, W, H: Integer;
Widget: PGTKWidget;
Window: PGdkWindow;
begin
//DebugLn('GetWindowRect');
Result := 0; //default
if Handle <> 0 then
begin
Widget := pgtkwidget(Handle);
Window:=GetControlWindow(Widget);
if Window <> nil then Begin
gdk_window_get_origin(Window, @X, @Y);
gdk_window_get_size(Window, @W, @H);
end
else
Begin
X := 0;
Y := 0;
W := 100;
Y := 200;
end;
ARect:=Rect(X,Y,X+W,Y+H);
end;
end;
{------------------------------------------------------------------------------
Function: GetWindowRelativePosition
Params: Handle : hwnd;
Returns: true on success
Returns the Left, Top, relative to the client origin of its parent
------------------------------------------------------------------------------}
function TGtkWidgetSet.GetWindowRelativePosition(Handle : hwnd;
var Left, Top: integer): boolean;
begin
if GtkWidgetIsA(PGtkWidget(Handle),GTK_TYPE_WIDGET) then begin
Result:=true;
Left:=PGtkWidget(Handle)^.Allocation.X;
Top:=PGtkWidget(Handle)^.Allocation.Y;
end else
Result:=false;
end;
{------------------------------------------------------------------------------
Function: GetWindowSize
Params: Handle : hwnd;
Returns: true on success
Returns the current widget Width and Height
------------------------------------------------------------------------------}
Function TGtkWidgetSet.GetWindowSize(Handle : hwnd;
var Width, Height: integer): boolean;
begin
if GtkWidgetIsA(PGtkWidget(Handle),GTK_TYPE_WIDGET) then begin
Result:=true;
Width:=PGtkWidget(Handle)^.Allocation.Width;
Height:=PGtkWidget(Handle)^.Allocation.Height;
end else
Result:=false;
end;
{------------------------------------------------------------------------------
Function: GradientFill
Params: DC - DeviceContext to perform on
Vertices - array of Points W/Color & Alpha
NumVertices - Number of Vertices
Meshes - array of Triangle or Rectangle Meshes,
each mesh representing one Gradient Fill
NumMeshes - Number of Meshes
Mode - Gradient Type, either Triangle,
Vertical Rect, Horizontal Rect
Returns: true on success
Performs multiple Gradient Fills, either a Three way Triangle Gradient,
or a two way Rectangle Gradient, each Vertex point also supports optional
Alpha/Transparency for more advanced Gradients.
------------------------------------------------------------------------------}
function TGtkWidgetSet.GradientFill(DC: HDC; Vertices: PTriVertex;
NumVertices : Longint;
Meshes: Pointer; NumMeshes : Longint; Mode : Longint): Boolean;
Function DoFillTriangle : Boolean;
begin
Result := (Mode and GRADIENT_FILL_TRIANGLE) = GRADIENT_FILL_TRIANGLE;
end;
Function DoFillVRect : Boolean;
begin
Result := (Mode and GRADIENT_FILL_RECT_V) = GRADIENT_FILL_RECT_V;
end;
Procedure GetGradientBrush(BeginColor, EndColor : TColorRef; Position,
TotalSteps : Longint; var GradientBrush : hBrush);
var
R1, G1, B1 : Integer;
R2, G2, B2 : Integer;
NewBrush : TLogBrush;
begin
GetRGBIntValues(BeginColor,R1,G1,B1);
GetRGBIntValues(EndColor,R2,G2,B2);
R1 := R1 + (Position*(R2 - R1) div TotalSteps);
G1 := G1 + (Position*(G2 - G1) div TotalSteps);
B1 := B1 + (Position*(B2 - B1) div TotalSteps);
With NewBrush do begin
lbStyle := BS_SOLID;
lbColor := RGB(R1,G1,B1);
end;
If GradientBrush <> 0 then
LCLIntf.DeleteObject(GradientBrush);
GradientBrush := LCLIntf.CreateBrushIndirect(NewBrush);
end;
Function FillTriMesh(Mesh : tagGradientTriangle) : Boolean;
{var
V1, V2, V3 : tagTRIVERTEX;
C1, C2, C3 : TColorRef;
begin
With Mesh do begin
Result := (Vertex1 < NumVertices) and (Vertex2 >= 0) and
(Vertex2 < NumVertices) and (Vertex2 >= 0) and
(Vertex3 < NumVertices) and (Vertex3 >= 0);
If (Vertex1 = Vertex2) or (Vertex1 = Vertex3) or
(Vertex2 = Vertex3) or not Result
then
exit;
V1 := Vertices[Vertex1];
V2 := Vertices[Vertex2];
V3 := Vertices[Vertex3];
//Check to make sure they are in reasonable positions..
//then what??
end;}
begin
Result := False;
end;
Function FillRectMesh(Mesh : tagGradientRect) : Boolean;
var
TL,BR : tagTRIVERTEX;
StartColor, EndColor : TColorRef;
I, Swap : Longint;
SwapColors : Boolean;
UseBrush : hBrush;
Steps, MaxSteps : Longint;
begin
With Mesh do begin
Result := (UpperLeft < NumVertices) and (UpperLeft >= 0) and
(LowerRight < NumVertices) and (LowerRight >= 0);
If (LowerRight = UpperLeft) or not Result then
exit;
TL := Vertices[UpperLeft];
BR := Vertices[LowerRight];
SwapColors := (BR.Y < TL.Y) and (BR.X < TL.X);
If BR.X < TL.X then begin
Swap := BR.X;
BR.X := TL.X;
TL.X := Swap;
end;
If BR.Y < TL.Y then begin
Swap := BR.Y;
BR.Y := TL.Y;
TL.Y := Swap;
end;
StartColor := RGB(TL.Red, TL.Green, TL.Blue);
EndColor := RGB(BR.Red, BR.Green, BR.Blue);
If SwapColors then begin
Swap := StartColor;
StartColor := EndColor;
EndColor := Swap;
end;
UseBrush := 0;
MaxSteps := GetDeviceCaps(DC, BITSPIXEL);
If MaxSteps >= 4 then
MaxSteps := Floor(Power(2, MaxSteps))
else
MaxSteps := 256;
If DoFillVRect then begin
Steps := Min(BR.Y - TL.Y, MaxSteps);
for I := 0 to Steps - 1 do begin
GetGradientBrush(StartColor, EndColor, I, Steps, UseBrush);
LCLIntf.FillRect(DC, Rect(TL.X, TL.Y + I, BR.X, TL.Y + I + 1),
UseBrush)
end
end
else begin
Steps := Min(BR.X - TL.X, MaxSteps);
for I := 0 to Steps - 1 do begin
GetGradientBrush(StartColor, EndColor, I, Steps, UseBrush);
LCLIntf.FillRect(DC, Rect(TL.X + I, TL.Y, TL.X + I + 1, BR.Y),
UseBrush);
end;
end;
If UseBrush <> 0 then
LCLIntf.DeleteObject(UseBrush);
end;
end;
const
MeshSize: Array[Boolean] of Integer = (
SizeOf(tagGradientRect), SizeOf(tagGradientTriangle));
var
I : Integer;
begin
//Currently Alpha blending is ignored... Ideas anyone?
Result := (Meshes <> nil) and (NumMeshes >= 1) and (NumVertices >= 2)
and (Vertices <> nil);
If Result and DoFillTriangle then
Result := NumVertices >= 3;
If Result then begin
Result := False;
//Sanity Checks For Vertices Size vs. Count
If MemSize(Vertices) < SizeOf(tagTRIVERTEX)*NumVertices then
exit;
//Sanity Checks For Meshes Size vs. Count
If MemSize(Meshes) < MeshSize[DoFillTriangle]*NumMeshes then
exit;
For I := 0 to NumMeshes - 1 do begin
If DoFillTriangle then begin
If Not FillTriMesh(PGradientTriangle(Meshes)[I]) then
exit;
end
else begin
If not FillRectMesh(PGradientRect(Meshes)[I]) then
exit;
end;
end;
Result := True;
end;
end;
{------------------------------------------------------------------------------
Function: HideCaret
Params: none
Returns: Nothing
------------------------------------------------------------------------------}
function TGtkWidgetSet.HideCaret(hWnd: HWND): Boolean;
var
GTKObject: PGTKObject;
WasVisible: boolean;
begin
//DebugLn('[TGtkWidgetSet.HideCaret] A');
Assert(False, Format('Trace: [TGtkWidgetSet.HideCaret] HWND: 0x%x', [hWnd]));
//TODO: [TGtkWidgetSet.HideCaret] Finish (in gtkwinapi.inc)
GTKObject := PGTKObject(HWND);
Result := GTKObject <> nil;
if Result
then begin
if gtk_type_is_a(gtk_object_type(GTKObject), GTKAPIWidget_GetType)
then begin
GTKAPIWidget_HideCaret(PGTKAPIWidget(GTKObject),WasVisible);
end
// else if // TODO: other widgettypes
else begin
Result := False;
end;
end
else DebugLn('WARNING: [TGtkWidgetSet.HideCaret] Got null HWND');
end;
{------------------------------------------------------------------------------
Function: IntersectClipRect
Params: dc: hdc; Left, Top, Right, Bottom: Integer
Returns: Integer
Shrinks the clipping region in the device context dc to a region of all
intersecting points between the boundary defined by Left, Top, Right,
Bottom , and the Current clipping region.
The result can be one of the following constants
Error
NullRegion
SimpleRegion
ComplexRegion
------------------------------------------------------------------------------}
function TGtkWidgetSet.IntersectClipRect(dc: hdc;
Left, Top, Right, Bottom: Integer): Integer;
begin
Result := Inherited IntersectClipRect(DC, Left, Top, Right, Bottom);
end;
{------------------------------------------------------------------------------
Function: InvalidateRect
Params: aHandle:
Rect:
bErase:
Returns:
------------------------------------------------------------------------------}
function TGtkWidgetSet.InvalidateRect(aHandle : HWND; Rect : pRect;
bErase : Boolean) : Boolean;
var
gdkRect : TGDKRectangle;
Widget, PaintWidget: PGtkWidget;
LCLObject: TObject;
begin
// DebugLn(format('Rect = %d,%d,%d,%d',[rect^.left,rect^.top,rect^.Right,rect^.Bottom]));
Widget:=PGtkWidget(aHandle);
LCLObject:=GetLCLObject(Widget);
if (LCLObject<>nil) then begin
if (LCLObject=CurrentSentPaintMessageTarget) then begin
DebugLn('NOTE: TGtkWidgetSet.InvalidateRect during paint message: ',
LCLObject.ClassName);
//RaiseException('Double paint');
end;
{$IFDEF VerboseDsgnPaintMsg}
if (LCLObject is TComponent)
and (csDesigning in TComponent(LCLObject).ComponentState) then begin
write('TGtkWidgetSet.InvalidateRect A ');
write(TComponent(LCLObject).Name,':');
write(LCLObject.ClassName);
with Rect^ do
write(' Rect=',Left,',',Top,',',Right,',',Bottom);
DebugLn(' Erase=',bErase);
end;
{$ENDIF}
end;
Result := True;
gdkRect.X := Rect^.Left;
gdkRect.Y := Rect^.Top;
gdkRect.Width := (Rect^.Right - Rect^.Left);
gdkRect.Height := (Rect^.Bottom - Rect^.Top);
PaintWidget:=GetFixedWidget(Widget);
if PaintWidget=nil then PaintWidget:=Widget;
{$IfDef GTK2}
if (PaintWidget<>nil) and GTK_WIDGET_NO_WINDOW(PaintWidget)
and (not GtkWidgetIsA(PGTKWidget(PaintWidget),GTKAPIWidget_GetType))
then begin
Inc(gdkRect.X, PaintWidget^.Allocation.x);
Inc(gdkRect.Y, PaintWidget^.Allocation.y);
end;
{$EndIf}
if bErase then
gtk_widget_queue_clear_area(PaintWidget,
gdkRect.X,gdkRect.Y,gdkRect.Width,gdkRect.Height);
gtk_widget_queue_draw_area(PaintWidget,
gdkRect.X,gdkRect.Y,gdkRect.Width,gdkRect.Height);
end;
{------------------------------------------------------------------------------
function TGtkWidgetSet.IsWindowEnabled(handle: HWND): boolean;
------------------------------------------------------------------------------}
function TGtkWidgetSet.IsWindowEnabled(handle: HWND): boolean;
var
LCLObject: TObject;
Widget: PGtkWidget;
AForm: TCustomForm;
//i: Integer;
begin
Widget:=PGtkWidget(handle);
Result:=(Widget<>nil) and GTK_WIDGET_SENSITIVE(Widget)
and GTK_WIDGET_PARENT_SENSITIVE(Widget);
LCLObject:=GetLCLObject(PGtkWidget(Handle));
//debugln('TGtkWidgetSet.IsWindowEnabled A ',DbgSName(LCLObject),' Result=',dbgs(Result),
// ' SENSITIVE=',dbgs(GTK_WIDGET_SENSITIVE(Widget)),
// ' PARENT_SENSITIVE=',dbgs(GTK_WIDGET_PARENT_SENSITIVE(Widget)),
// ' TOPLEVEL=',dbgs(GTK_WIDGET_TOPLEVEL(Widget)),
// '');
if Result and GtkWidgetIsA(Widget,GTK_TYPE_WINDOW) then begin
LCLObject:=GetLCLObject(Widget);
if (LCLObject is TCustomForm) then begin
AForm:=TCustomForm(LCLObject);
if not Screen.CustomFormBelongsToActiveGroup(AForm) then
Result:=false;
//debugln('TGtkWidgetSet.IsWindowEnabled B ',dbgs(Screen.CustomFormBelongsToActiveGroup(AForm)));
//for i:=0 to Screen.CustomFormCount-1 do begin
// debugln(' ',dbgs(i),' ',DbgSName(Screen.CustomFormsZOrdered[i]));
//end;
end;
end;
end;
{------------------------------------------------------------------------------
function TGtkWidgetSet.IsWindowVisible(handle: HWND): boolean;
------------------------------------------------------------------------------}
function TGtkWidgetSet.IsWindowVisible(handle: HWND): boolean;
begin
Result:=(handle<>0) and GTK_WIDGET_VISIBLE(PGtkWidget(handle));
end;
{------------------------------------------------------------------------------
Function: LineTo
Params: none
Returns: Nothing
------------------------------------------------------------------------------}
function TGtkWidgetSet.LineTo(DC: HDC; X, Y: Integer): Boolean;
var
DCOrigin: TPoint;
begin
Assert(False, Format('trace:> [TGtkWidgetSet.LineTo] DC:0x%x, X:%d, Y:%d', [DC, X, Y]));
Result := IsValidDC(DC);
if Result
then with TDeviceContext(DC) do
begin
if GC <> nil then begin
SelectGDKPenProps(DC);
If (dcfPenSelected in DCFlags) then begin
Result := True;
if (CurrentPen^.IsNullPen) then exit;
DCOrigin:=GetDCOffset(TDeviceContext(DC));
{$IFDEF DebugGDK}BeginGDKErrorTrap;{$ENDIF}
gdk_draw_line(Drawable, GC, PenPos.X+DCOrigin.X, PenPos.Y+DCOrigin.Y,
X+DCOrigin.X, Y+DCOrigin.Y);
{$IFDEF DebugGDK}EndGDKErrorTrap;{$ENDIF}
PenPos:= Point(X, Y);
end else
Result := False;
end else begin
DebugLn('WARNING: [TGtkWidgetSet.LineTo] Uninitialized GC');
Result := False;
end;
end;
Assert(False, Format('trace:< [TGtkWidgetSet.LineTo] DC:0x%x, X:%d, Y:%d', [DC, X, Y]));
end;
{------------------------------------------------------------------------------
Function: MessageBox
Params: hWnd: The handle of parent window
Returns: 0 if not successful (out of memory), otherwise one of the defined value :
IDABORT, IDCANCEL, IDIGNORE, IDNO, IDOK, IDRETRY, IDYES
The MessageBox function displays a modal dialog, with text and caption defined,
and includes buttons.
------------------------------------------------------------------------------}
function MessageButtonClicked(Widget : PGtkWidget; data: gPointer) : GBoolean; cdecl;
begin
//DebugLn('[MessageButtonClicked] ',dbgs(data),' ',dbgs(gtk_object_get_data(PGtkObject(Widget), 'modal_result')));
if Integer(data^) = 0 then
Integer(data^):=
Integer(gtk_object_get_data(PGtkObject(Widget), 'modal_result'));
Result:=false;
end;
function MessageBoxClosed(Widget : PGtkWidget; Event : PGdkEvent;
data: gPointer) : GBoolean; cdecl;
var ModalResult : integer;
begin
{ We were requested by window manager to close }
if Integer(data^) = 0 then begin
ModalResult:= Integer(gtk_object_get_data(PGtkObject(Widget), 'modal_result'));
{ Don't allow to close if we don't have a default return value }
Result:= (ModalResult = 0);
if not Result then Integer(data^):= ModalResult
else DebugLn('Do not close !!!');
end else Result:= false;
end;
function TGtkWidgetSet.MessageBox(hWnd: HWND; lpText, lpCaption: PChar;
uType : Cardinal): integer;
var Dialog, ALabel : PGtkWidget;
ButtonCount, DefButton, ADialogResult : Integer;
DialogType : Cardinal;
procedure CreateButton(const ALabel : PChar; const RetValue : integer);
var AButton : PGtkWidget;
begin
AButton:= gtk_button_new_with_label(ALabel);
Inc(ButtonCount);
if ButtonCount = DefButton then begin
gtk_window_set_focus(PGtkWindow(Dialog), AButton);
end;
{ If there is the Cancel button, allow the dialog to close }
if RetValue = IDCANCEL then begin
gtk_object_set_data(PGtkObject(Dialog), 'modal_result', Pointer(IDCANCEL));
end;
gtk_object_set_data(PGtkObject(AButton), 'modal_result',
Pointer(PtrInt(RetValue)));
g_signal_connect(PGtkObject(AButton), 'clicked',
TGtkSignalFunc(@MessageButtonClicked), @ADialogResult);
gtk_container_add (PGtkContainer(PGtkDialog(Dialog)^.action_area), AButton);
end;
begin
ButtonCount:= 0;
{ Determine which is the default button }
DefButton:= ((uType and $00000300) shr 8) + 1;
Assert(False, 'Trace:Default button is ' + IntToStr(DefButton));
ADialogResult:= 0;
Dialog:= gtk_dialog_new;
g_signal_connect(PGtkObject(Dialog), 'delete-event', TGtkSignalFunc(@MessageBoxClosed), @ADialogResult);
gtk_window_set_default_size(PGtkWindow(Dialog), 100, 100);
ALabel:= gtk_label_new(lpText);
gtk_container_add (PGtkContainer(PGtkDialog(Dialog)^.vbox), ALabel);
DialogType:= (uType and $0000000F);
if DialogType = MB_OKCANCEL
then begin
CreateButton(PChar(rsMbOK), IDOK);
CreateButton(PChar(rsMbCancel), IDCANCEL);
end
else begin
if DialogType = MB_ABORTRETRYIGNORE
then begin
CreateButton(PChar(rsMbAbort), IDABORT);
CreateButton(PChar(rsMbRetry), IDRETRY);
CreateButton(PChar(rsMbIgnore), IDIGNORE);
end
else begin
if DialogType = MB_YESNOCANCEL
then begin
CreateButton(PChar(rsMbYes), IDYES);
CreateButton(PChar(rsMbNo), IDNO);
CreateButton(PChar(rsMbCancel), IDCANCEL);
end
else begin
if DialogType = MB_YESNO
then begin
CreateButton(PChar(rsMbYes), IDYES);
CreateButton(PChar(rsMbNo), IDNO);
end
else begin
if DialogType = MB_RETRYCANCEL
then begin
CreateButton(PChar(rsMbRetry), IDRETRY);
CreateButton(PChar(rsMbCancel), IDCANCEL);
end
else begin
{ We have no buttons to show. Create the default of OK button }
CreateButton(PChar(rsMbOK), IDOK);
end;
end;
end;
end;
end;
gtk_window_set_title(PGtkWindow(Dialog), lpCaption);
gtk_window_set_position(PGtkWindow(Dialog), GTK_WIN_POS_CENTER);
gtk_window_set_modal(PGtkWindow(Dialog), true);
gtk_widget_show_all(Dialog);
while ADialogResult = 0 do begin
Application.HandleMessage;
end;
DestroyConnectedWidget(Dialog,true);
Result:= ADialogResult;
end;
{------------------------------------------------------------------------------
Function: MoveToEx
Params: none
Returns: Nothing
------------------------------------------------------------------------------}
function TGtkWidgetSet.MoveToEx(DC: HDC; X, Y: Integer;
OldPoint: PPoint): Boolean;
begin
Assert(False, Format('trace:> [TGtkWidgetSet.MoveToEx] DC:0x%x, X:%d, Y:%d', [DC, X, Y]));
Result := IsValidDC(DC);
if Result
then with TDeviceContext(DC) do
begin
if OldPoint <> nil then OldPoint^ := PenPos;
PenPos := Point(X, Y);
end;
Assert(False, Format('trace:< [TGtkWidgetSet.MoveToEx] DC:0x%x, X:%d, Y:%d', [DC, X, Y]));
end;
{------------------------------------------------------------------------------
function MoveWindowOrgEx(DC: HDC; dX, dY: Integer): Boolean; override;
Move the origin of all operations of a DeviceContext.
For example:
Moving the Origin to 10,20 and drawing a point to 50,50, results in
drawing a point to 60,70.
------------------------------------------------------------------------------}
function TGtkWidgetSet.MoveWindowOrgEx(DC: HDC; dX, dY: Integer): Boolean;
begin
Result:=IsValidDC(DC);
if Result then
with TDeviceContext(DC) do begin
//DebugLn('[TGtkWidgetSet.MoveWindowOrgEx] B DC=',DbgS(DC),
// ' Old=',Origin.X,',',Origin.Y,' d=',dX,',',dY,' ');
inc(Origin.X,dX);
inc(Origin.Y,dY);
end;
end;
{------------------------------------------------------------------------------
function TGtkWidgetSet.PairSplitterAddSide(SplitterHandle, SideHandle: hWnd;
Side: integer): Boolean;
------------------------------------------------------------------------------}
function TGtkWidgetSet.PairSplitterAddSide(SplitterHandle, SideHandle: hWnd;
Side: integer): Boolean;
begin
Result:=false;
if (SplitterHandle=0) or (SideHandle=0) or (Side<0) or (Side>1) then exit;
if Side=0 then
gtk_paned_add1(PGtkPaned(SplitterHandle),PGtkWidget(SideHandle))
else
gtk_paned_add2(PGtkPaned(SplitterHandle),PGtkWidget(SideHandle));
Result:=true;
end;
{------------------------------------------------------------------------------
function TGtkWidgetSet.PairSplitterGetInterfaceInfo: Boolean;
------------------------------------------------------------------------------}
function TGtkWidgetSet.PairSplitterGetInterfaceInfo: Boolean;
begin
Result:=true;
end;
{------------------------------------------------------------------------------
function TGtkWidgetSet.PairSplitterRemoveSide(SplitterHandle, SideHandle: hWnd;
Side: integer): Boolean;
------------------------------------------------------------------------------}
function TGtkWidgetSet.PairSplitterRemoveSide(SplitterHandle, SideHandle: hWnd;
Side: integer): Boolean;
begin
Result:=false;
DebugLn('WARNING: TGtkWidgetSet.PairSplitterRemoveSide not implemented');
end;
{------------------------------------------------------------------------------
function TGtkWidgetSet.PairSplitterSetPosition(SplitterHandle: hWnd;
var NewPosition: integer): Boolean;
Negative values for NewPosition will only read the value
------------------------------------------------------------------------------}
function TGtkWidgetSet.PairSplitterSetPosition(SplitterHandle: hWnd;
var NewPosition: integer): Boolean;
begin
Result:=false;
if (SplitterHandle=0) then exit;
if NewPosition>=0 then
gtk_paned_set_position(PGtkPaned(SplitterHandle),NewPosition);
NewPosition:=PGtkPaned(SplitterHandle)^.child1_size;
Result:=true;
end;
{------------------------------------------------------------------------------
Function: PeekMessage
Params: lpMsg - Where it should put the message
Handle - Handle of the window (thread)
wMsgFilterMin- Lowest MSG to grab
wMsgFilterMax- Highest MSG to grab
wRemoveMsg - Should message be pulled out of the queue
Returns: Boolean if an event was there
------------------------------------------------------------------------------}
function TGtkWidgetSet.PeekMessage(var lpMsg: TMsg; Handle : HWND;
wMsgFilterMin, wMsgFilterMax, wRemoveMsg: UINT): Boolean;
var
vlItem : TGtkMessageQueueItem;
begin
//TODO Filtering
DebugLn('Peek !!!' );
vlItem := fMessageQueue.FirstMessageItem;
Result := vlItem <> nil;
if Result then begin
lpMsg := vlItem.Msg^;
if (wRemoveMsg and PM_REMOVE) = PM_REMOVE then
fMessageQueue.RemoveMessage(vlItem,FPMF_Internal,true);
end;
end;
{------------------------------------------------------------------------------
Method: PolyBezier
Params: DC, Points, NumPts, Filled, Continous
Returns: Boolean
Use Polybezier to draw cubic Bézier curves. The first curve is drawn from the
first point to the fourth point with the second and third points being the
control points. If the Continuous flag is TRUE then each subsequent curve
requires three more points, using the end-point of the previous Curve as its
starting point, the first and second points being used as its control points,
and the third point its end-point. If the continous flag is set to FALSE,
then each subsequent Curve requires 4 additional points, which are used
excatly as in the first curve. Any additonal points which do not add up to
a full bezier(4 for Continuous, 3 otherwise) are ingored. There must be at
least 4 points for an drawing to occur. If the Filled Flag is set to TRUE
then the resulting Poly-Bézier will be drawn as a Polygon.
------------------------------------------------------------------------------}
Function TGtkWidgetSet.PolyBezier(DC: HDC; Points: PPoint; NumPts: Integer;
Filled, Continuous: Boolean): Boolean;
Begin
Result := IsValidDC(DC);
if Result
then with TDeviceContext(DC) do
begin
if GC = nil
then begin
DebugLn('WARNING: [TGtkWidgetSet.PolyBezier] Uninitialized GC');
Result := False;
end
else
Result := Inherited PolyBezier(DC, Points, NumPts, Filled, Continuous);
end;
End;
{------------------------------------------------------------------------------
Method: TGtkWidgetSet.Polygon
Params: DC: HDC; Points: ^TPoint; NumPts: integer; Winding: Boolean;
Returns: Nothing
Use Polygon to draw a closed, many-sided shape on the canvas, using the value
of Pen. After drawing the complete shape, Polygon fills the shape using the
value of Brush.
The Points parameter is an array of points that give the vertices of the
polygon.
Winding determines how the polygon is filled. When Winding is True, Polygon
fills the shape using the Winding fill algorithm. When Winding is False,
Polygon uses the even-odd (alternative) fill algorithm.
NumPts indicates the number of points to use.
The first point is always connected to the last point.
To draw a polygon on the canvas, without filling it, use the Polyline method,
specifying the first point a second time at the end.
}
function TGtkWidgetSet.Polygon(DC: HDC; Points: PPoint; NumPts: Integer;
Winding: Boolean): boolean;
var
i: integer;
PointArray: PGDKPoint;
Tmp, RGN : hRGN;
ClipRect : TRect;
DCOrigin: TPoint;
OldNumPts: integer;
begin
Result := IsValidDC(DC);
if Result
then with TDeviceContext(DC) do
begin
if NumPts<=0 then exit;
if GC = nil
then begin
DebugLn('WARNING: [TGtkWidgetSet.Polygon] Uninitialized GC');
Result := False;
end
else begin
DCOrigin:=GetDCOffset(TDeviceContext(DC));
// create the PointsArray, which is a copy of Points moved by the DCOrigin
GetMem(PointArray,SizeOf(TGdkPoint)*(NumPts+1)); // +1 for return line
for i:=0 to NumPts-1 do begin
PointArray[i].x:=Points[i].x;
PointArray[i].y:=Points[i].y;
Inc(PointArray[i].x, DCOrigin.X);
Inc(PointArray[i].y, DCOrigin.Y);
end;
OldNumPts:=NumPts;
If (Points[NumPts-1].X <> Points[0].X) or
(Points[NumPts-1].Y <> Points[0].Y)
then begin
// add last point to return to first
PointArray[NumPts].x:=PointArray[0].x;
PointArray[NumPts].y:=PointArray[0].y;
Inc(NumPts);
end;
// first draw interior in brush color
SelectGDKBrushProps(DC);
{$IFDEF DebugGDK}BeginGDKErrorTrap;{$ENDIF}
If not CurrentBrush^.IsNullBrush then
if Winding then begin
// store old clipping
Tmp := CreateEmptyRegion;
GetClipRGN(DC, Tmp);
// apply new clipping
RGN := CreatePolygonRgn(Points, OldNumPts, LCLType.Winding);
ExtSelectClipRGN(DC, RGN, RGN_AND);
DeleteObject(RGN);
GetClipBox(DC, @ClipRect);
// draw polygon area
FillRect(DC, ClipRect, HBrush(CurrentBrush));
// restore old clipping
SelectClipRGN(DC, Tmp);
DeleteObject(Tmp);
end else
gdk_draw_polygon(Drawable, GC, 1, PointArray, NumPts);
// draw outline
SelectGDKPenProps(DC);
If (dcfPenSelected in DCFlags) then begin
Result := True;
if (not CurrentPen^.IsNullPen) then begin
gdk_draw_polygon(Drawable, GC, 0, PointArray, NumPts);
end;
end else
Result:=false;
{$IFDEF DebugGDKTraps}EndGDKErrorTrap;{$ENDIF}
FreeMem(PointArray);
Result := True;
end;
end;
end;
function TGtkWidgetSet.Polyline(DC: HDC; Points: PPoint; NumPts: Integer): boolean;
var i: integer;
PointArray: PGDKPoint;
DCOrigin: TPoint;
begin
Result := IsValidDC(DC);
if Result
then with TDeviceContext(DC) do
begin
if GC = nil
then begin
DebugLn('WARNING: [TGtkWidgetSet.Polyline] Uninitialized GC');
Result := False;
end
else begin
if NumPts<=0 then exit;
DCOrigin:=GetDCOffset(TDeviceContext(DC));
GetMem(PointArray,SizeOf(TGdkPoint)*NumPts);
for i:=0 to NumPts-1 do begin
PointArray[i].x:=Points[i].x+DCOrigin.X;
PointArray[i].y:=Points[i].y+DCOrigin.Y;
end;
// draw outline
SelectGDKPenProps(DC);
If (dcfPenSelected in DCFlags) then begin
Result := True;
if (not CurrentPen^.IsNullPen) then begin
{$IFDEF DebugGDK}BeginGDKErrorTrap;{$ENDIF}
gdk_draw_lines(Drawable, GC, PointArray, NumPts);
{$IFDEF DebugGDKTraps}EndGDKErrorTrap;{$ENDIF}
end;
end else
Result:=false;
FreeMem(PointArray);
end;
end;
end;
{------------------------------------------------------------------------------
Function: PostMessage
Params: Handle:
Msg:
wParam:
lParam:
Returns: True if succesful
The PostMessage function places (posts) a message in the message queue and
then returns without waiting.
------------------------------------------------------------------------------}
function TGtkWidgetSet.PostMessage(Handle: HWND; Msg: Cardinal; wParam: WParam;
lParam: LParam): Boolean;
function ParentPaintMessageInQueue: boolean;
var
Target: TControl;
Parent: TWinControl;
ParentHandle: hWnd;
begin
Result:=false;
Target:=TControl(GetLCLObject(Pointer(Handle)));
if not (Target is TControl) then exit;
Parent:=Target.Parent;
if (Target is TControl) then begin
Parent:=Target.Parent;
while Parent<>nil do begin
ParentHandle:=Parent.Handle;
if fMessageQueue.FindPaintMessage(ParentHandle)<>nil then begin
Result:=true;
end;
Parent:=Parent.Parent;
end;
end;
end;
procedure CombinePaintMessages(NewMsg:PMsg);
// combine NewMsg and OldMsg paint message into NewMsg and free OldMsg
var
vlItem : TGtkMessageQueueItem;
NewData: TLMGtkPaintData;
OldData: TLMGtkPaintData;
OldMsg : PMsg;
begin
vlItem := fMessageQueue.FindPaintMessage(NewMsg^.Hwnd);
if vlItem = nil then exit;
OldMsg := vlItem.Msg;
if OldMsg=nil then exit;
if (NewMsg^.Message=LM_PAINT) or (OldMsg^.Message=LM_PAINT) then begin
// LM_PAINT means: repaint all
// convert NewMsg into a LM_PAINT if not already done
if NewMsg^.Message<>LM_PAINT then begin
FinalizePaintTagMsg(NewMsg);
NewMsg^.Message:=LM_PAINT;
end;
end else if (NewMsg^.Message<>LM_GtkPAINT) then begin
RaiseException('CombinePaintMessages A unknown paint message');
end else if (OldMsg^.Message<>LM_GtkPAINT) then begin
RaiseException('CombinePaintMessages B unknown paint message');
end else begin
// combine the two LM_GtkPAINT messages
NewData:=TLMGtkPaintData(NewMsg^.WParam);
OldData:=TLMGtkPaintData(OldMsg^.WParam);
NewData.RepaintAll:=NewData.RepaintAll or OldData.RepaintAll;
if not NewData.RepaintAll then begin
NewData.Rect.Left:=Min(NewData.Rect.Left,OldData.Rect.Left);
NewData.Rect.Top:=Min(NewData.Rect.Top,OldData.Rect.Top);
NewData.Rect.Right:=Max(NewData.Rect.Right,OldData.Rect.Right);
NewData.Rect.Bottom:=Max(NewData.Rect.Bottom,OldData.Rect.Bottom);
end;
end;
fMessageQueue.RemoveMessage(vlItem,FPMF_All,true);
end;
var
AMessage: PMsg;
begin
Result := True;
New(AMessage);
AMessage^.HWnd := Handle; // this is normally the main gtk widget
AMessage^.Message := Msg;
AMessage^.WParam := WParam;
AMessage^.LParam := LParam;
// Message^.Time :=
if (AMessage^.Message=LM_PAINT) or (AMessage^.Message=LM_GtkPAINT) then begin
{ Obsolete, because InvalidateRectangle now works.
// paint messages are the most expensive messages in the LCL
// A paint message to a control will also repaint all child controls.
// -> check if there is already a paint message for one of its parents
// if yes, then skip this message
if ParentPaintMessageInQueue then begin
FinalizePaintTagMsg(AMessage^);
exit;
end;}
// delete old paint message to this widget,
// so that the widget repaints only once
CombinePaintMessages(AMessage);
end ;
FMessageQueue.AddMessage(AMessage);
end;
{------------------------------------------------------------------------------
Method: RadialArc
Params: DC,x,y,width,height,sx,sy,ex,ey
Returns: Nothing
Use RadialArc to draw an elliptically curved line with the current Pen. The
values sx,sy, and ex,ey represent the starting and ending radial-points
between which the Arc is drawn.
------------------------------------------------------------------------------}
function TGtkWidgetSet.RadialArc(DC: HDC; x,y,width,height,sx,sy,ex,ey : Integer): Boolean;
Begin
Result := IsValidDC(DC);
if Result
then with TDeviceContext(DC) do
begin
if GC = nil
then begin
DebugLn('WARNING: [TGtkWidgetSet.RadialArc] Uninitialized GC');
Result := False;
end
else
Result := Inherited RadialArc(DC, x, y, width, height, sx,sy,ex,ey);
end;
End;
{------------------------------------------------------------------------------
Method: RadialChord
Params: DC,x,y,width,height,sx,sy,ex,ey
Returns: Nothing
Use RadialChord to draw a filled Chord-shape on the canvas. The values sx,sy,
and ex,ey represent the starting and ending radial-points between which
the bounding-Arc is drawn.
------------------------------------------------------------------------------}
function TGtkWidgetSet.RadialChord(DC: HDC; x,y,width,height,sx,sy,ex,ey : Integer): Boolean;
begin
Result := IsValidDC(DC);
if Result
then with TDeviceContext(DC) do
begin
if GC = nil
then begin
DebugLn('WARNING: [TGtkWidgetSet.RadialChord] Uninitialized GC');
Result := False;
end
else
Result := Inherited RadialChord(DC, x, y, width, height, sx,sy,ex,ey);
end;
End;
{------------------------------------------------------------------------------
Method: RadialPie
Params: DC,x,y,width,height,sx,sy,ex,ey
Returns: Nothing
Use RadialPie to draw a filled Pie-shaped Wedge on the canvas. The values
sx,sy, and ex,ey represent the starting and ending radial-points between which
the bounding-Arc is drawn.
------------------------------------------------------------------------------}
function TGtkWidgetSet.RadialPie(DC: HDC; x,y,width,height,sx,sy,ex,ey : Integer): Boolean;
begin
Result := IsValidDC(DC);
if Result
then with TDeviceContext(DC) do
begin
if GC = nil
then begin
DebugLn('WARNING: [TGtkWidgetSet.RadialPie] Uninitialized GC');
Result := False;
end
else
Result := Inherited RadialPie(DC, x, y, width, height, sx,sy,ex,ey);
end;
end;
{------------------------------------------------------------------------------
Function: RadioMenuItemGroup
Params: hndMenu: HMENU; bRadio: Boolean
Returns: Nothing
Change the group of menuitems to 'radio' or to 'checked'.
------------------------------------------------------------------------------}
function TGtkWidgetSet.RadioMenuItemGroup(hndMenu: HMENU; bRadio: Boolean): Boolean;
var
LCLMenuItem: TMenuItem;
begin
LCLMenuItem:=TMenuItem(GetLCLObject(Pointer(hndMenu)));
if LCLMenuItem<>nil then begin
LCLMenuItem.RecreateHandle;
Result:=true;
end else
Result := false;
end;
{------------------------------------------------------------------------------
Function: RealizePalette
Params: DC: HDC
Returns: Nothing
------------------------------------------------------------------------------}
function TGtkWidgetSet.RealizePalette(DC: HDC): Cardinal;
begin
Assert(False, 'Trace:FINISH: [TGtkWidgetSet.RealizePalette]');
Result := 0;
if IsValidDC(DC)
then with TDeviceContext(DC) do
begin
end;
end;
{------------------------------------------------------------------------------
Function: Rectangle
Params: DC: HDC; X1, Y1, X2, Y2: Integer
Returns: Nothing
The Rectangle function draws a rectangle. The rectangle is outlined by using
the current pen and filled by using the current brush.
------------------------------------------------------------------------------}
function TGtkWidgetSet.Rectangle(DC: HDC; X1, Y1, X2, Y2: Integer): Boolean;
var
Left, Top, Width, Height: Integer;
DCOrigin: TPoint;
begin
Assert(False, Format('trace:> [TGtkWidgetSet.Rectangle] DC:0x%x, X1:%d, Y1:%d, X2:%d, Y2:%d', [DC, X1, Y1, X2, Y2]));
Result := IsValidDC(DC);
if Result
then with TDeviceContext(DC) do
begin
if GC = nil
then begin
DebugLn('WARNING: [TGtkWidgetSet.Rectangle] Uninitialized GC');
Result := False;
end
else begin
CalculateLeftTopWidthHeight(X1,Y1,X2,Y2,Left,Top,Width,Height);
// first draw interior in brush color
SelectGDKBrushProps(DC);
DCOrigin:=GetDCOffset(TDeviceContext(DC));
{$IFDEF DebugGDK}BeginGDKErrorTrap;{$ENDIF}
If not CurrentBrush^.IsNullBrush then
if (CurrentBrush^.GDIBrushFill = GDK_SOLID)
and (IsBackgroundColor(TColor(CurrentBrush^.GDIBrushColor.ColorRef))) then
StyleFillRectangle(Drawable, GC, CurrentBrush^.GDIBrushColor.ColorRef, Left+DCOrigin.X, Top+DCOrigin.Y, Width, Height)
else
gdk_draw_rectangle(Drawable, GC, 1, Left+DCOrigin.X, Top+DCOrigin.Y,
Width, Height);
// Draw outline
SelectGDKPenProps(DC);
If (dcfPenSelected in DCFlags) then begin
Result := True;
if (not CurrentPen^.IsNullPen) then
gdk_draw_rectangle(Drawable, GC, 0, Left+DCOrigin.X, Top+DCOrigin.Y,
Width, Height);
end else
Result:=false;
{$IFDEF DebugGDKTraps}EndGDKErrorTrap;{$ENDIF}
end;
end;
Assert(False, Format('trace:< [TGtkWidgetSet.Rectangle] DC:0x%x, X1:%d, Y1:%d, X2:%d, Y2:%d', [DC, X1, Y1, X2, Y2]));
end;
{------------------------------------------------------------------------------
Function: RectVisible
Params: dc : hdc; ARect: TRect
Returns: True if ARect is not completely clipped away.
------------------------------------------------------------------------------}
function TGtkWidgetSet.RectVisible(dc : hdc; const ARect: TRect) : Boolean;
begin
Result := inherited RectVisible(dc,ARect);
end;
{------------------------------------------------------------------------------
Function: RegroupMenuItem
Params: hndMenu: HMENU; GroupIndex: integer
Returns: Nothing
Move a menuitem into its group
This function is called by the LCL, after some menuitems were regrouped to
GroupIndex. The hndMenu is one of them.
Update all radio groups.
------------------------------------------------------------------------------}
function TGtkWidgetSet.RegroupMenuItem(hndMenu: HMENU;
GroupIndex: Integer): Boolean;
const
GROUPIDX_DATANAME = 'GroupIndex';
function GetGroup: PGSList;
{$IfDef GTK1}
var
Item: PGList;
Arg: TGTKArg;
begin
Result := nil;
Arg.theType := GTK_TYPE_OBJECT;
Arg.Name := 'parent';
gtk_widget_get(Pointer(hndMenu), @Arg);
if Arg.d.object_data = nil then Exit;
Item := gtk_container_children(PGTKContainer(Arg.d.object_data));
while Item <> nil do
begin
if (Item^.Data <> Pointer(hndMenu)) // exclude ourself
and gtk_is_radio_menu_item(Item^.Data)
and (GroupIndex = Integer(gtk_object_get_data(Item^.Data, GROUPIDX_DATANAME)))
then begin
Result := gtk_radio_menu_item_group(PGtkRadioMenuItem(Item^.Data));
Exit;
end;
Item := Item^.Next;
end;
{$Else}
var
Item: PGList;
parent : PGTKWidget;
begin
Result := nil;
parent := gtk_widget_get_parent(Pointer(hndMenu));
if parent = nil then Exit;
Item := gtk_container_children(PGTKContainer(parent));
while Item <> nil do
begin
if (Item^.Data <> Pointer(hndMenu)) // exclude ourself
and gtk_is_radio_menu_item(Item^.Data)
and (GroupIndex = Integer(gtk_object_get_data(Item^.Data, GROUPIDX_DATANAME)))
then begin
Result := gtk_radio_menu_item_get_group (PGtkRadioMenuItem(Item^.Data));
Exit;
end;
Item := Item^.Next;
end;
{$EndIf}
end;
var
RadioGroup: PGSList;
CurrentGroupIndex: Integer;
begin
Result := False;
if not gtk_is_radio_menu_item(Pointer(hndMenu))
then begin
DebugLn('WARNING: TGtkWidgetSet.RegroupMenuItem: handle is not a GTK_RADIO_MENU_ITEM');
Exit;
end;
CurrentGroupIndex := Integer(gtk_object_get_data(Pointer(hndMenu), GROUPIDX_DATANAME));
// Update needed ?
if GroupIndex = CurrentGroupIndex
then begin
Result := True;
Exit;
end;
// Remove current group
gtk_radio_menu_item_set_group(PGtkRadioMenuItem(hndMenu), nil);
gtk_object_set_data(Pointer(hndMenu), GROUPIDX_DATANAME, nil);
// Check remove only
if GroupIndex = 0
then begin
Result := True;
Exit;
end;
// Try to find new group
RadioGroup := GetGroup;
// Set new group
gtk_object_set_data(Pointer(hndMenu), GROUPIDX_DATANAME, Pointer(PtrInt(GroupIndex)));
if RadioGroup = nil
then begin
// We're the only member, get a group
RadioGroup := gtk_radio_menu_item_group(PGtkRadioMenuItem(hndMenu))
end
else begin
gtk_radio_menu_item_set_group(PGtkRadioMenuItem(hndMenu), RadioGroup);
end;
//radiogroup^.data
//radiogroup^.next
// Refetch newgroup list
RadioGroup := gtk_radio_menu_item_group(PGtkRadioMenuItem(hndMenu));
// Update checks
UpdateRadioGroupChecks(RadioGroup);
Result := True;
end;
// MWE: Reimplemented to get rid of unneeded group order constraint
// (which doesn't work if the menu isn't created in order)
(*
function GetGroup(ParentMenuItem: TMenuItem;
GrpIndex, LastRadioItem: integer): PGSList;
var
i: Integer;
begin
for i:=LastRadioItem downto 0 do begin
if ParentMenuItem[i].RadioItem
and (ParentMenuItem[i].GroupIndex=GrpIndex)
and ParentMenuItem[i].HandleAllocated
and GtkWidgetIsA(Pointer(ParentMenuItem[i].Handle),
GTK_RADIO_MENU_ITEM_TYPE)
then begin
Result:=gtk_radio_menu_item_group(
GTK_RADIO_MENU_ITEM(ParentMenuItem[i].Handle));
//DebugLn('TGtkWidgetSet.RegroupMenuItem.GetGroup A i=',i,' ',ParentMenuItem[i].Name,' GrpIndex=',ParentMenuItem[i].GroupIndex,' LastRadioItem=',LastRadioItem,' Result=',DbgS(Result));
exit;
end;
end;
Result:=nil;
end;
var
RadioGroup: PGSList;
AMenuItem: TMenuItem;
ParentMenuItem: TMenuItem;
LastRadioGroupStart: integer;
i: Integer;
begin
if GTK_IS_RADIO_MENU_ITEM(Pointer(hndMenu)) then begin
AMenuItem:=TMenuItem(GetLCLObject(Pointer(hndMenu)));
if AMenuItem=nil then exit;
ParentMenuItem:=AMenuItem.Parent;
if ParentMenuItem=nil then exit;
//DebugLn('TGtkWidgetSet.RegroupMenuItem A ',AMenuItem.Name,' ',ParentMenuItem.Name,' GroupIndex=',AMenuItem.GroupIndex);
LastRadioGroupStart:=-1;
for i:=0 to ParentMenuItem.Count-1 do begin
if ParentMenuItem[i].RadioItem
and ParentMenuItem[i].HandleAllocated
and GtkWidgetIsA(Pointer(ParentMenuItem[i].Handle),
GTK_RADIO_MENU_ITEM_TYPE)
then begin
//DebugLn('TGtkWidgetSet.RegroupMenuItem B i=',i,' ',ParentMenuItem[i].Name,
//' GrpIndex=',ParentMenuItem[i].GroupIndex,
//' LastRadioGroupStart=',LastRadioGroupStart,
//' LastGroup=',DbgS(Cardinal(gtk_radio_menu_item_group(
// GTK_RADIO_MENU_ITEM(ParentMenuItem[i].Handle))),8)
//);
if (ParentMenuItem[i].GroupIndex<>0) then begin
// item has a group -> bind to group
RadioGroup:=GetGroup(ParentMenuItem,ParentMenuItem[i].GroupIndex,
LastRadioGroupStart);
gtk_radio_menu_item_set_group(
PGtkRadioMenuItem(ParentMenuItem[i].Handle),RadioGroup);
if (LastRadioGroupStart<0)
or (ParentMenuItem[LastRadioGroupStart].GroupIndex
<>ParentMenuItem[i].GroupIndex)
then
LastRadioGroupStart:=i;
end else begin
// item has no group -> unbind
if gtk_radio_menu_item_group(
GTK_RADIO_MENU_ITEM(ParentMenuItem[i].Handle))
<>nil
then
gtk_radio_menu_item_set_group(
PGtkRadioMenuItem(ParentMenuItem[i].Handle),nil);
end;
end;
end;
// update checks
RadioGroup:=gtk_radio_menu_item_group(PGtkRadioMenuItem(hndMenu));
UpdateRadioGroupChecks(RadioGroup);
Result:=true;
end else begin
DebugLn('WARNING: TGtkWidgetSet.RegroupMenuItem: handle is not a GTK_RADIO_MENU_ITEM');
Result:=false;
end;
end;
*)
{------------------------------------------------------------------------------
Function: ReleaseCapture
Params: none
Returns: True if succesful
The ReleaseCapture function releases the mouse capture from a window
and restores normal mouse input processing.
------------------------------------------------------------------------------}
function TGtkWidgetSet.ReleaseCapture: Boolean;
begin
SetCapture(0);
Result := True;
end;
{------------------------------------------------------------------------------
Function: ReleaseDC
Params: none
Returns: Nothing
------------------------------------------------------------------------------}
function TGtkWidgetSet.ReleaseDC(hWnd: HWND; DC: HDC): Integer;
var
aDC, pSavedDC: TDeviceContext;
begin
//DebugLn('[TGtkWidgetSet.ReleaseDC] ',DbgS(DC,8),' ',FDeviceContexts.Count);
Assert(False, Format('trace:> [TGtkWidgetSet.ReleaseDC] DC:0x%x', [DC]));
Result := 0;
if {(hWnd <> 0) and} (DC <> 0)
then begin
if FDeviceContexts.Contains(Pointer(DC))
then begin
aDC := TDeviceContext(DC);
{ Release all saved device contexts }
pSavedDC:=aDC.SavedContext;
if pSavedDC<>nil then begin
if pSavedDC.CurrentBitmap = aDC.CurrentBitmap
then
aDC.CurrentBitmap := nil;
if pSavedDC.CurrentFont = aDC.CurrentFont
then
aDC.CurrentFont := nil;
if (pSavedDC.CurrentPen = aDC.CurrentPen)
and (aDC.CurrentPen<>nil)
then
aDC.CurrentPen := nil;
if pSavedDC.CurrentBrush = aDC.CurrentBrush
then
aDC.CurrentBrush := nil;
{if pSavedDC.CurrentPalette = aDC.CurrentPalette
then aDC.CurrentPalette := nil;}
if pSavedDC.ClipRegion = aDC.ClipRegion
then
pSavedDC.ClipRegion := 0;
ReleaseDC(0,HDC(pSavedDC));
aDC.SavedContext:=nil;
end;
// Release all graphic objects
DeleteObject(HGDIObj(aDC.CurrentBrush));
DeleteObject(HGDIObj(aDC.CurrentPen));
DeleteObject(HGDIObj(aDC.CurrentFont));
// bitmaps are not auto created, they are set via SelectObject
// -> user must free it
// ... DeleteObject(HGDIObj(aDC.CurrentBitmap));
//DeleteObject(HGDIObj(aDC.CurrentPalette));
DeleteObject(HGDIObj(aDC.ClipRegion));
{FreeGDIColor(aDC.CurrentTextColor);
FreeGDIColor(aDC.CurrentBackColor);}
try
{ On root window, we don't allocate a graphics context and so we dont free}
if aDC.GC <> nil then begin
gdk_gc_unref(aDC.GC);
aDC.GC:=nil;
end;
except
on E:Exception do begin
//Nothing, just try to unref it
//(it segfaults if the window doesnt exist anymore :-)
DebugLn('TGtkWidgetSet.ReleaseDC: ',E.Message);
end;
end;
DisposeDC(aDC);
Result := 1;
end;
end;
Assert(False, Format('trace:< [TGtkWidgetSet.ReleaseDC] FDeviceContexts DC:0x%x', [DC]));
end;
{------------------------------------------------------------------------------
Function: RemoveProp
Params: Handle: Handle of the object
Str: Name of the property to remove
Returns: The handle of the property (0=failure)
------------------------------------------------------------------------------}
function TGtkWidgetSet.RemoveProp(Handle: hwnd; Str: PChar): THandle;
begin
gtk_object_remove_data(pGTKObject(handle), Str);
Result := 1;
end;
{------------------------------------------------------------------------------
Function: RestoreDC
Params: none
Returns: Nothing
-------------------------------------------------------------------------------}
function TGtkWidgetSet.RestoreDC(DC: HDC; SavedDC: Integer): Boolean;
var
aDC, pSavedDC: TDeviceContext;
Count: Integer;
ClipRegionChanged: Boolean;
begin
Assert(False, Format('Trace:> [TGtkWidgetSet.RestoreDC] DC:0x%x, SavedDC: %d', [DC, SavedDC]));
Result := IsValidDC(DC) and (SavedDC <> 0);
if Result
then begin
pSavedDC := TDeviceContext(DC);
Count:=Abs(SavedDC);
while (Count>0) and (pSavedDC<>nil) do begin
aDC:=pSavedDC;
pSavedDC:=aDC.SavedContext;
dec(Count);
end;
// TODO copy bitmap also
ClipRegionChanged:=false;
if (aDC.ClipRegion<>0) and (pSavedDC.ClipRegion <> aDC.ClipRegion) then
begin
// clipping region has changed
DeleteObject(aDC.ClipRegion);
ClipRegionChanged:=true;
aDC.ClipRegion := 0;
end;
if aDC.GC<>nil then begin
gdk_gc_unref(aDC.GC);
aDC.GC:=nil;
end;
Result := CopyDCData(aDC, pSavedDC);
aDC.SavedContext := pSavedDC.SavedContext;
pSavedDC.SavedContext := nil;
if ClipRegionChanged then
SelectGDIRegion(HDC(aDC));
//DebugLn('TGtkWidgetSet.RestoreDC A ',GDKRegionAsString(PGdiObject(aDC.ClipRegion)^.GDIRegionObject));
// free saved DC
//prevent deleting of copied objects:
if pSavedDC.CurrentBitmap = aDC.CurrentBitmap
then
pSavedDC.CurrentBitmap := nil;
if pSavedDC.CurrentFont = aDC.CurrentFont
then
pSavedDC.CurrentFont := nil;
if (pSavedDC.CurrentPen = aDC.CurrentPen)
and (pSavedDC.CurrentPen<>nil) then
pSavedDC.CurrentPen := nil;
if pSavedDC.CurrentBrush = aDC.CurrentBrush
then
pSavedDC.CurrentBrush := nil;
if pSavedDC.CurrentBrush = aDC.CurrentBrush
then
pSavedDC.CurrentBrush := nil;
{if pSavedDC.CurrentPalette = aDC.CurrentPalette
then pSavedDC.CurrentPalette := nil;}
if pSavedDC.ClipRegion = aDC.ClipRegion
then
pSavedDC.ClipRegion := 0;
DeleteDC(HGDIOBJ(pSavedDC));
end;
Assert(False, Format('Trace:< [TGtkWidgetSet.RestoreDC] DC:0x%x, Saved: %d --> %s', [Integer(DC), SavedDC, BOOL_TEXT[Result]]));
end;
{------------------------------------------------------------------------------
Method: RoundRect
Params: X1, Y1, X2, Y2, RX, RY
Returns: If succesfull
Draws a Rectangle with optional rounded corners. RY is the radial height
of the corner arcs, RX is the radial width. If either is less than or equal to
0, the routine simly calls to standard Rectangle.
------------------------------------------------------------------------------}
Function TGtkWidgetSet.RoundRect(DC : hDC; X1, Y1, X2, Y2: Integer; RX,RY : Integer): Boolean;
begin
Assert(False, Format('trace:> [TGtkWidgetSet.RoundRect] DC:0x%x, X1:%d, Y1:%d, X2:%d, Y2:%d, RX:%d, RY:%d', [DC, X1, Y1, X2, Y2, RX, RY]));
Result := IsValidDC(DC);
if Result
then with TDeviceContext(DC) do
begin
if GC = nil
then begin
DebugLn('WARNING: [TGtkWidgetSet.RoundRect] Uninitialized GC');
Result := False;
end
else
Result := Inherited RoundRect(DC, X1, Y1, X2, Y2, RX, RY);
end;
Assert(False, Format('trace:< [TGtkWidgetSet.RoundRect] DC:0x%x, X1:%d, Y1:%d, X2:%d, Y2:%d, RX:%d, RY:%d', [DC, X1, Y1, X2, Y2, RX, RY]));
end;
{------------------------------------------------------------------------------
Function: SaveDc
Params: DC: a DC to save
Returns: 0 if the functions fails otherwise a positive integer identifing
the saved DC
The SaveDC function saves the current state of the specified device
context (DC) by copying its elements to a context stack.
-------------------------------------------------------------------------------}
function TGtkWidgetSet.SaveDC(DC: HDC): Integer;
var
aDC, aSavedDC: TDeviceContext;
begin
Assert(False, Format('Trace:> [TGtkWidgetSet.SaveDC] 0x%x', [Integer(DC)]));
Result := 0;
if IsValidDC(DC)
then begin
aDC := TDeviceContext(DC);
aSavedDC := NewDC;
CopyDCData(aSavedDC, aDC);
aSavedDC.SavedContext:=aDC.SavedContext;
aDC.SavedContext:= aSavedDC;
Result:=1;
end;
Assert(False, Format('Trace:< [TGtkWidgetSet.SaveDC] 0x%x --> %d', [Integer(DC), Result]));
end;
{------------------------------------------------------------------------------
Function: ScreenToClient
Params: Handle:
P:
Returns:
------------------------------------------------------------------------------}
Function TGtkWidgetSet.ScreenToClient(Handle : HWND; var P : TPoint) : Integer;
var
X, Y: Integer;
Widget: PGTKWidget;
Window: PgdkWindow;
Begin
if Handle = 0
then begin
X := 0;
Y := 0;
end
else
begin
Widget := GetFixedWidget(pgtkwidget(Handle));
if Widget = nil then
Widget := pgtkwidget(Handle);
if Widget = nil then
begin
X := 0;
Y := 0;
end
else begin
Window:=GetControlWindow(Widget);
{$IFDEF DebugGDK}BeginGDKErrorTrap;{$ENDIF}
if Window<>nil then
gdk_window_get_origin(Window, @X, @Y)
else begin
X:=0;
Y:=0;
end;
{$IFDEF DebugGDKTraps}EndGDKErrorTrap;{$ENDIF}
end;
end;
//DebugLn('[TGtkWidgetSet.ScreenToClient] ',x,',',y,' P=',P.X,',',P.Y);
dec(P.X, X);
dec(P.Y, Y);
Result := -1;
end;
{------------------------------------------------------------------------------
Function: ScrollWindowEx
Params: hWnd: handle of window to scroll
dx: horizontal amount to scroll
dy: vertical amount to scroll
prcScroll: pointer to scroll rectangle
prcClip: pointer to clip rectangle
hrgnUpdate: handle of update region
prcUpdate: pointer to update rectangle
flags: scrolling flags
Returns: True if succesfull;
The ScrollWindowEx function scrolls the content of the specified window's
client area
------------------------------------------------------------------------------}
function TGtkWidgetSet.ScrollWindowEx(hWnd: HWND; dx, dy: Integer; prcScroll, prcClip: PRect; hrgnUpdate: HRGN; prcUpdate: PRect; flags: UINT): Boolean;
begin
Result := False;
end;
{------------------------------------------------------------------------------
Function: SelectClipRGN
Params: DC, RGN
Returns: longint
Sets the DeviceContext's ClipRegion. The Return value
is the new clip regions type, or ERROR.
The result can be one of the following constants
Error
NullRegion
SimpleRegion
ComplexRegion
------------------------------------------------------------------------------}
Function TGtkWidgetSet.SelectClipRGN(DC : hDC; RGN : HRGN) : Longint;
var
RegObj: PGdkRegion;
DCOrigin: TPoint;
begin
If not IsValidDC(DC) then begin
Result := ERROR;
exit;
end;
Result := SIMPLEREGION;
with TDeviceContext(DC) do
begin
if (GC = nil) and (RGN <> 0)
then begin
DebugLn('WARNING: [TGtkWidgetSet.SelectClipRGN] Uninitialized GC');
Result := ERROR;
end
else begin
// clear old clipregion
if (ClipRegion<>0)
and ((SavedContext=nil) or (SavedContext.ClipRegion<>ClipRegion)) then
DeleteObject(ClipRegion);
ClipRegion := 0;
If (GC = nil) or (RGN = 0) then begin
if GC<>nil then
SelectGDIRegion(DC);
end
else
If IsValidGDIObject(RGN) then begin
ClipRegion := CreateRegionCopy(RGN);
RegObj:=PGdiObject(ClipRegion)^.GDIRegionObject;
DCOrigin:=GetDCOffset(TDeviceContext(DC));
//DebugLn('TGtkWidgetSet.SelectClipRGN A RegObj=',GDKRegionAsString(RegObj),' DCOrigin=',dbgs(DCOrigin),' RGN=',GDKRegionAsString(PGdiObject(RGN)^.GDIRegionObject));
gdk_region_offset(RegObj,DCOrigin.x,DCOrigin.Y);
Result := RegionType(RegObj);
//DebugLn('TGtkWidgetSet.SelectClipRGN B RegObj=',GDKRegionAsString(RegObj),' DCOrigin=',dbgs(DCOrigin));
SelectGDIRegion(DC);
end
else begin
Result := ERROR;
DebugLn('WARNING: [TGtkWidgetSet.SelectClipRGN] Invalid RGN');
end;
end;
end;
end;
{------------------------------------------------------------------------------
Function: SelectObject
Params: none
Returns: Nothing
------------------------------------------------------------------------------}
function TGtkWidgetSet.SelectObject(DC: HDC; GDIObj: HGDIOBJ): HGDIOBJ;
procedure RaiseInvalidGDIType;
begin
RaiseException('TGtkWidgetSet.SelectObject Invalid GDIType '+IntToStr(ord(PGdiObject(GDIObj)^.GDIType)));
end;
begin
Result := 0;
{if not IsValidDC(DC) then begin
DebugLn('TGtkWidgetSet.SelectObject invalid DC ',DbgS(DC));
end;
if not IsValidGDIObject(GDIObj) then begin
DebugLn('TGtkWidgetSet.SelectObject invalid GDIObj ',DbgS(GDIObj));
end;}
if IsValidDC(DC) and IsValidGDIObject(GDIObj)
then begin
//DebugLn('TGtkWidgetSet.SelectObject DC=',DbgS(DC),8),' GDIObj=',DbgS(Cardinal(GDIObj),' GDIType=',ord(PGdiObject(GDIObj)^.GDIType),' ',ord(gdiBitmap),' ',ord(gdiRegion));
case PGdiObject(GDIObj)^.GDIType of
gdiBitmap:
with TDeviceContext(DC) do
begin
Assert(False, Format('trace: [TGtkWidgetSet.SelectObject] DC: 0x%x, Type: Bitmap', [DC]));
Result := HBITMAP(CurrentBitmap);
CurrentBitmap := PGDIObject(GDIObj);
if GC <> nil then begin
gdk_gc_unref(GC);
GC:=nil;
end;
with CurrentBitmap^ do
case GDIBitmapType of
gbPixmap: Drawable := GDIPixmapObject;
gbBitmap: Drawable := GDIBitmapObject;
{obsolete: gbImage: Drawable := nil;//GDI_RGBImageObject;}
else
Drawable := nil;
end;
//DebugLn('TGtkWidgetSet.SelectObject DC=',DbgS(DC),8),' GDIBitmap=',DbgS(Cardinal(CurrentBitmap),
//' GDIBitmapType=',ord(CurrentBitmap^.GDIBitmapType),' Drawable=',DbgS(Drawable));
GC := gdk_gc_new(Drawable);
gdk_gc_set_function(GC, GDK_COPY);
SelectedColors := dcscCustom;
end;
gdiBrush:
with TDeviceContext(DC), PGdiObject(GDIObj)^ do
begin
Assert(False, Format('trace: [TGtkWidgetSet.SelectObject] DC: 0x%x, Type: Brush', [DC]));
Result := HBRUSH(CurrentBrush);
CurrentBrush := PGDIObject(GDIObj);
if GC <> nil
then begin
gdk_gc_set_fill(GC, GDIBrushFill);
case GDIBrushFill of
GDK_STIPPLED: gdk_gc_set_stipple(GC, GDIBrushPixMap);
GDK_TILED: gdk_gc_set_tile(GC, GDIBrushPixMap);
end;
end;
SelectedColors := dcscCustom;
end;
gdiFont:
with TDeviceContext(DC) do
begin
Assert(False, Format('trace: [TGtkWidgetSet.SelectObject] DC: 0x%x, Type: Font', [DC]));
Result := HFONT(CurrentFont);
CurrentFont := PGDIObject(GDIObj);
{$IfDef GTK1}
if GC <> nil then begin
gdk_gc_set_font(GC, PGdiObject(GDIObj)^.GDIFontObject);
end;
{$ENDIF}
Exclude(DCFlags,dcfTextMetricsValid);
SelectedColors := dcscCustom;
end;
gdiPen:
with TDeviceContext(DC) do
begin
Result := HPEN(CurrentPen);
CurrentPen := PGDIObject(GDIObj);
DCFlags:=DCFlags-[dcfPenSelected];
if GC <> nil then SelectGDKPenProps(DC);
SelectedColors := dcscCustom;
end;
gdiRegion:
begin
with TDeviceContext(DC) do
begin
Result := ClipRegion;
if GC <> nil then
SelectClipRGN(DC, GDIObj)
else
ClipRegion:=0;
end;
end;
else
RaiseInvalidGDIType;
end;
end;
//DebugLn('[TGtkWidgetSet.SelectObject] GDI=',DbgS(GDIObj)
// ,' Old=',DbgS(Result));
end;
{------------------------------------------------------------------------------
Function: SelectPalette
Params: none
Returns: Nothing
------------------------------------------------------------------------------}
function TGtkWidgetSet.SelectPalette(DC: HDC; Palette: HPALETTE; ForceBackground: Boolean): HPALETTE;
begin
Assert(False, 'Trace:TODO: [TGtkWidgetSet.SelectPalette]');
//TODO: Implement this;
Result := 0;
end;
{------------------------------------------------------------------------------
Function: SendMessage
Params: hWnd:
Msg:
wParam:
lParam:
Returns:
The SendMessage function sends the specified message to a window or windows.
The function calls the window procedure for the specified window and does
not return until the window procedure has processed the message.
------------------------------------------------------------------------------}
function TGtkWidgetSet.SendMessage(HandleWnd: HWND; Msg: Cardinal; wParam: WParam;
lParam: LParam): LResult;
var
OldMsg: Cardinal;
procedure PreparePaintMessage(TargetObject: TObject; var AMessage: TLMessage);
var
GtkPaintData: TLMGtkPaintData;
OldGtkPaintMsg: TLMGtkPaint;
{$IFNDEF Gtk2}
PaintDC: HDC;
DCOrigin: TPoint;
{$ENDIF}
begin
(* MG: old trick. Not used anymore, but it might be, that someday there
will be component, that works better with this, so it is kept.
{ The LCL repaints controls in a top-down hierachy. But the gtk sends
gtkdraw events bottom-up. So, controls at the bottom are repainted
many times. To avoid this the queue is checked for LM_PAINT messages
for the parent control. If there is a parent LM_PAINT, this message
is ignored.}
if (Target is TControl) then begin
ParentControl:=TControl(Target).Parent;
while ParentControl<>nil do begin
ParentHandle:=TWinControl(ParentControl).Handle;
if FindPaintMessage(ParentHandle)<>nil then begin
{$IFDEF VerboseDsgnPaintMsg}
if (csDesigning in TComponent(Target).ComponentState) then begin
DebugLn('TGtkWidgetSet.SendMessage A ',
TComponent(Target).Name,':',Target.ClassName,
' Parent Message found: ',ParentControl.Name,':',ParentControl.ClassName
);
end;
{$ENDIF}
if Msg=LM_PAINT then
ReleaseDC(0,AMessage.WParam);
//exit;
end;
ParentControl:=ParentControl.Parent;
end;
end; *)
{$IFDEF VerboseDsgnPaintMsg}
if (csDesigning in TComponent(TargetObject).ComponentState) then begin
write('TGtkWidgetSet.SendMessage B ',
TComponent(TargetObject).Name,':',TargetObject.ClassName,
' GtkPaint=',AMessage.Msg=LM_GtkPAINT);
if AMessage.Msg=LM_GtkPAINT then begin
if AMessage.wParam<>0 then begin
with TLMGtkPaintData(AMessage.wParam) do begin
write(' GtkPaintData(',
' Widget=',DbgS(Widget),'=',GetWidgetClassName(Widget),
' State=',State,
' Rect=',Rect.Left,',',Rect.Top,',',Rect.Right,',',Rect.Bottom,
' RepaintAll=',RepaintAll,
')');
end;
end else begin
write(' GtkPaintData=nil');
end;
end;
DebugLn('');
end;
{$ENDIF}
if AMessage.Msg=LM_GtkPAINT then begin
OldGtkPaintMsg:=TLMGtkPaint(AMessage);
GtkPaintData:=OldGtkPaintMsg.Data;
// convert LM_GtkPAINT to LM_PAINT
AMessage := TLMessage(GtkPaintMessageToPaintMessage(
TLMGtkPaint(AMessage), False));
{$IfNDef GTK2}
if (GtkPaintData<>nil) and (not GtkPaintData.RepaintAll) then begin
PaintDC:=TLMPaint(AMessage).DC;
DCOrigin:=GetDCOffset(TDeviceContext(PaintDC));
with GtkPaintData.Rect do
IntersectClipRect(PaintDC,Left-DCOrigin.X,Top-DCOrigin.Y,
Right-DCOrigin.X,Bottom-DCOrigin.Y);
end;
{$EndIf}
GtkPaintData.Free;
end;
end;
procedure DisposePaintMessage(TargetObject: TObject; var AMessage: TLMessage);
begin
if OldMsg=LM_GtkPAINT then begin
FinalizePaintMessage(@AMessage);
//if (csDesigning in TComponent(TargetObject).ComponentState)
//and (TargetObject is TWinControl) then
// SendPaintMessagesForInternalWidgets(TWinControl(TargetObject));
end else
if ((AMessage.Msg=LM_PAINT) or (AMessage.Msg=LM_INTERNALPAINT))
and (AMessage.WParam<>0) then begin
// free DC
ReleaseDC(0,AMessage.WParam);
AMessage.WParam:=0;
//if (csDesigning in TComponent(TargetObject).ComponentState)
//and (TargetObject is TWinControl) then
// SendPaintMessagesForInternalWidgets(TWinControl(TargetObject));
end;
end;
var
AMessage: TLMessage;
Target: TObject;
begin
OldMsg:=Msg;
AMessage.Msg := Msg;
AMessage.WParam := WParam;
AMessage.LParam := LParam;
AMessage.Result := 0;
Target := GetLCLObject(Pointer(HandleWnd));
if Target<>nil then begin
if (Msg=LM_PAINT) or (Msg=LM_GtkPaint) then begin
PreparePaintMessage(Target,AMessage);
end;
// deliver it
Result := DeliverMessage(Target, AMessage);
if (Msg=LM_PAINT) or (Msg=LM_INTERNALPAINT) or (Msg=LM_GtkPaint) then begin
DisposePaintMessage(Target,AMessage);
end;
end;
end;
{------------------------------------------------------------------------------
function SetActiveWindow(Handle: HWND): HWND;
------------------------------------------------------------------------------}
function TGtkWidgetSet.SetActiveWindow(Handle: HWND): HWND;
begin
// ToDo
Result:=GetActiveWindow;
end;
{------------------------------------------------------------------------------
Function: SetBkColor pbd
Params: DC: Device context to change the text background color
Color: RGB Tuple
Returns: Old Background color
------------------------------------------------------------------------------}
function TGtkWidgetSet.SetBKColor(DC: HDC; Color: TColorRef): TColorRef;
begin
Assert(False, Format('trace:> [TGtkWidgetSet.SetBKColor] DC: 0x%x Color: %8x', [Integer(DC), Color]));
Result := CLR_INVALID;
if IsValidDC(DC)
then begin
with TDeviceContext(DC) do
begin
Result := CurrentBackColor.ColorRef;
SetGDIColorRef(CurrentBackColor,Color);
end;
end;
Assert(False, Format('trace:< [TGtkWidgetSet.SetBKColor] DC: 0x%x Color: %8x --> %8x', [Integer(DC), Color, Result]));
end;
{------------------------------------------------------------------------------
Function: SetBkMode
Params: DC:
bkMode:
Returns:
------------------------------------------------------------------------------}
Function TGtkWidgetSet.SetBkMode(DC: HDC; bkMode : Integer) : Integer;
begin
// Your code here
Result:=0;
end;
{------------------------------------------------------------------------------
Function TGtkWidgetSet.SetComboMinDropDownSize(Handle: HWND;
MinItemsWidth, MinItemsHeight: integer): boolean;
------------------------------------------------------------------------------}
Function TGtkWidgetSet.SetComboMinDropDownSize(Handle: HWND;
MinItemsWidth, MinItemsHeight, MinItemCount: integer): boolean;
var
ComboWidget: PGtkCombo;
DropDownWidget, ListWidget, FirstChildWidget: PGtkWidget;
FirstChild: PGList;
CurX, CurY, CurWidth, CurHeight, CurItemHeight, BorderX, BorderY,
NewWidth, NewHeight: integer;
ComboPopup: PGtkScrolledWindow;
item_requisition: TGtkRequisition;
begin
Result:=true;
if not (GtkWidgetIsA(PgtkWidget(Handle),GTK_TYPE_COMBO)) then
RaiseException('TGtkWidgetSet.SetComboMinDropDownSize invalid handle');
// get current items width and height
ComboWidget:=PGtkCombo(Handle);
ListWidget:=ComboWidget^.List;
if ListWidget=nil then exit;
CurWidth:=ListWidget^.Allocation.Width;
CurHeight:=ListWidget^.Allocation.Height;
if MinItemCount>0 then begin
FirstChild:=PGTkList(ListWidget)^.children;
if FirstChild<>nil then begin
FirstChildWidget:=PGtkWidget(FirstChild^.Data);
gtk_widget_size_request(FirstChildWidget,@item_requisition);
CurItemHeight:=Max(FirstChildWidget^.Allocation.Height,
item_requisition.Height);
if MinItemsHeight<CurItemHeight*MinItemCount then
MinItemsHeight:=CurItemHeight*MinItemCount;
end;
end;
// calculate new width and height
DropDownWidget:=ComboWidget^.popwin;
if DropDownWidget=nil then exit;
CurX:=DropDownWidget^.Allocation.x;
CurY:=DropDownWidget^.Allocation.y;
ComboPopup:=PGtkScrolledWindow(ComboWidget^.popup);
if ComboPopup=nil then exit;
// ToDo: add scrollbars only if needed
BorderX:=DropDownWidget^.Allocation.Width-CurWidth;
if BorderX<0 then BorderX:=0;
inc(BorderX,
ComboPopup^.hscrollbar^.requisition.height
{+GTK_SCROLLED_WINDOW_GET_CLASS(ComboWidget^.popup)^.scrollbar_spacing});
BorderY:=DropDownWidget^.Allocation.Height-CurHeight;
if BorderY<0 then BorderY:=0;
inc(BorderX,
ComboPopup^.vscrollbar^.requisition.width
{+GTK_SCROLLED_WINDOW_GET_CLASS(ComboWidget^.popup)^.scrollbar_spacing});
NewWidth := MinItemsWidth+BorderX;
NewHeight := MinItemsHeight+BorderY;
if NewWidth<CurWidth then NewWidth:=CurWidth;
if NewHeight<CurHeight then NewHeight:=CurHeight;
//DebugLn('NewWidth=',NewWidth,' NewHeight=',NewHeight,' CurWidth=',CurWidth,' CurHeight=',CurHeight);
if (NewWidth=CurWidth) and (NewHeight=CurHeight) then exit;
//gtk_widget_set_uposition(DropDownWidget,NewX,NewY);
NewWidth:=Min(NewWidth, Screen.Width - CurX);
NewHeight:=Min(NewHeight, Screen.Height - CurY);
gtk_widget_set_usize(DropDownWidget,NewWidth,NewHeight);
end;
{------------------------------------------------------------------------------
Function: SetCapture
Params: Value: Handle of window to capture
Returns: Nothing
------------------------------------------------------------------------------}
function TGtkWidgetSet.SetCapture(AHandle: HWND): HWND;
var
Widget: PGtkWidget;
begin
Assert(False, Format('Trace:> [TGtkWidgetSet.SetCapture] 0x%x', [AHandle]));
Widget := PGtkWidget(AHandle);
{$IfDef VerboseMouseCapture}
DebugLn('TGtkWidgetSet.SetCapture NewValue=[',GetWidgetDebugReport(Widget),']');
{$EndIf}
// return old capture handle
Result := GetCapture;
// capture
CaptureMouseForWidget(Widget, mctLCL);
end;
{------------------------------------------------------------------------------
Function: SetCaretPos
Params: new position x, y
Returns: true on success
------------------------------------------------------------------------------}
function TGtkWidgetSet.SetCaretPos(X, Y: Integer): Boolean;
var
FocusObject: PGTKObject;
begin
FocusObject := PGTKObject(GetFocus);
Result:=SetCaretPosEx(LongInt(FocusObject),X,Y);
end;
{------------------------------------------------------------------------------
Function: SetCaretPos
Params: new position x, y
Returns: true on success
------------------------------------------------------------------------------}
function TGtkWidgetSet.SetCaretPosEx(Handle: HWNd; X, Y: Integer): Boolean;
var
GtkObject: PGTKObject;
begin
GtkObject := PGTKObject(Handle);
Result := GtkObject <> nil;
if Result then begin
if gtk_type_is_a(gtk_object_type(GtkObject), GTKAPIWidget_GetType)
then begin
GTKAPIWidget_SetCaretPos(PGTKAPIWidget(GtkObject), X, Y);
end
// else if // TODO: other widgettypes
else begin
Result := False;
end;
end;
end;
{------------------------------------------------------------------------------
Function: SetCaretRespondToFocus
Params: handle : Handle of a TWinControl
ShowHideOnFocus: true = caret is hidden on focus lost
Returns: true on success
------------------------------------------------------------------------------}
function TGtkWidgetSet.SetCaretRespondToFocus(handle: HWND;
ShowHideOnFocus: boolean): Boolean;
begin
if handle<>0 then begin
if gtk_type_is_a(gtk_object_type(PGTKObject(handle)), GTKAPIWidget_GetType)
then begin
GTKAPIWidget_SetCaretRespondToFocus(PGTKAPIWidget(handle),
ShowHideOnFocus);
Result:=true;
end
else begin
Result := False;
end;
end else
Result:=false;
end;
{------------------------------------------------------------------------------
Function: SetCursorPos
Params: X:
Y:
Returns:
------------------------------------------------------------------------------}
function TGtkWidgetSet.SetCursorPos(X, Y: Integer): Boolean;
{$IFDEF UNIX}
var
dpy: PDisplay;
TopList, List: PGList;
begin
Result := False;
{$IFDEF DebugGDKTraps}
BeginGDKErrorTrap;
{$ENDIF}
try
TopList := gdk_window_get_toplevels;
List := TopList;
while List <> nil do
begin
if (List^.Data <> nil)
and gdk_window_is_visible(List^.Data)
then begin
{$IFDEF GTK2}
//the pascal Gtk2 bindings don't seem to have gdk_window_xdisplay
dpy := XOpenDisplay(nil);
if dpy <> nil then begin
{$ELSE GTK2}
dpy := gdk_window_xdisplay(List^.Data);
{$ENDIF GTK2}
XWarpPointer(dpy,
0,
RootWindow(dpy, DefaultScreen(dpy)),
0, 0, 0, 0,
X,
Y);
{$IFDEF GTK2}
XCloseDisplay(dpy);
end;
{$ENDIF GTK2}
Result := True;
Break;
end;
List := g_list_next(List);
end;
if TopList <> nil
then g_list_free(TopList);
finally
{$IFDEF DebugGDKTraps}EndGDKErrorTrap;{$ENDIF}
end;
end;
{$ELSE UNIX}
begin
DebugLn('TGtkWidgetSet.SetCursorPos not implemented for this platform');
// Can this call TWin32WidgetSet.SetCursorPos?
end;
{$ENDIF UNIX}
{------------------------------------------------------------------------------
Function: SetFocus
Params: hWnd: Handle of new focus window
Returns: The old focus window
The SetFocus function sets the keyboard focus to the specified window
------------------------------------------------------------------------------}
function TGtkWidgetSet.SetFocus(hWnd: HWND): HWND;
{off $DEFINE VerboseFocus}
var
Widget, TopLevel, ImplWidget, NewFocusWidget: PGtkWidget;
WinWidgetInfo: PWinWidgetInfo;
{$IfDef VerboseFocus}
LCLObject, AWinControl: TWinControl;
NewTopLevel: PGtkWidget;
{$EndIf}
NewTopLevelWidget: PGtkWidget;
NewTopLevelObject: TObject;
NewForm: TCustomForm;
begin
if hWnd=0 then exit;
Widget:=PGtkWidget(hWnd);
{$IfDef VerboseFocus}
DebugLn('');
writeln('[TGtkWidgetSet.SetFocus] A hWnd=',GetWidgetDebugReport(Widget));
LCLObject:=TWinControl(GetLCLObject(Widget));
{$EndIf}
if hwnd = 0 then begin
Result:=0;
exit;
end;
// return the old focus handle
Result := GetFocus;
NewFocusWidget:=nil;
TopLevel := gtk_widget_get_toplevel(Widget);
{$IfDef VerboseFocus}
Debugln('[TGtkWidgetSet.SetFocus] B');
DbgOut(' TopLevel=',DbgS(TopLevel));
DbgOut(' OldFocus=',GetWidgetDebugReport(PGtkWidget(Result)));
DebugLn('');
if not GTK_WIDGET_VISIBLE(Widget) then
RaiseException('TGtkWidgetSet.SetFocus: Widget is not visible');
{$EndIf}
if Result=hWnd then exit;
if GtkWidgetIsA(TopLevel, gtk_window_get_type)
then begin
// TopLevel is a gtkwindow
{$IfDef VerboseFocus}
AWinControl:=TWinControl(GetNearestLCLObject(PGtkWindow(TopLevel)^.focus_widget));
write(' C TopLevel is a gtkwindow ');
write(' focus_widget=',DbgS(PGtkWindow(TopLevel)^.focus_widget));
if AWinControl<>nil then
write(' LCLParent=',AWinControl.Name,':',AWinControl.ClassName)
else
write(' LCLParent=nil');
DebugLn('');
{$EndIf}
NewTopLevelObject:=GetNearestLCLObject(TopLevel);
if (NewTopLevelObject is TCustomForm) then begin
NewForm:=TCustomForm(NewTopLevelObject);
if Screen.GetCurrentModalFormZIndex>Screen.CustomFormZIndex(NewForm) then
begin
// there is a modal form above -> focus forbidden
{$IfDef VerboseFocus}
DebugLn(' there is a modal form above -> focus forbidden');
{$EndIf}
exit;
end;
end;
if (NewFocusWidget=nil)
and GtkWidgetIsA(Widget, gtk_combo_get_type) then begin
// handle is a gtk combo
{$IfDef VerboseFocus}
DebugLn(' D taking gtkcombo entry');
{$EndIf}
NewFocusWidget:=PgtkWidget(PGtkCombo(Widget)^.entry);
end;
if NewFocusWidget=nil then begin
// check if widget has a WinWidgetInfo record
WinWidgetInfo:=GetWidgetInfo(Widget, false);
if (WinWidgetInfo<>nil) then begin
ImplWidget:= WinWidgetInfo^.CoreWidget;
if ImplWidget <> nil then begin
// handle has an ImplementationWidget
if GtkWidgetIsA(ImplWidget, gtk_list_get_type) then begin
{$IfDef VerboseFocus}
DebugLn(' E using list');
{$EndIf}
if selection_mode(PGtkList(ImplWidget)^) > GTK_SELECTION_BROWSE then
NewFocusWidget:=PGtkList(ImplWidget)^.last_focus_child;
if (NewFocusWidget = nil) and (PGtkList(ImplWidget)^.selection <> nil) then
NewFocusWidget := (PGtkList(ImplWidget)^.selection)^.data;
if (NewFocusWidget = nil) and (gtk_container_children(PGtkContainer(ImplWidget)) <> nil) then
NewFocusWidget := g_list_first(gtk_container_children(PGtkContainer(ImplWidget)))^.data;
end else begin
{$IfDef VerboseFocus}
DebugLn(' E taking ImplementationWidget');
{$EndIf}
NewFocusWidget:=ImplWidget;
end;
end;
end;
end;
if (NewFocusWidget=nil) then begin
NewFocusWidget:=Widget;
{$IfDef VerboseFocus}
DebugLn(' F taking default ');
{$EndIf}
end;
{$IfDef VerboseFocus}
write(' G NewFocusWidget=',DbgS(NewFocusWidget),' ',DbgSName(GetNearestLCLObject(NewFocusWidget)));
write(' WidVisible=',GTK_WIDGET_VISIBLE(PGtkWidget(NewFocusWidget)));
write(' WidRealized=',GTK_WIDGET_REALIZED(PGtkWidget(NewFocusWidget)));
write(' WidMapped=',GTK_WIDGET_MAPPED(PGtkWidget(NewFocusWidget)));
write(' WidCanfocus=',GTK_WIDGET_CAN_FOCUS(PGtkWidget(NewFocusWidget)));
write(' TopLvlVisible=',GTK_WIDGET_VISIBLE(PGtkWidget(TopLevel)));
DebugLn('');
{$EndIf}
if (NewFocusWidget<>nil) and GTK_WIDGET_CAN_FOCUS(NewFocusWidget) then begin
if (PGtkWindow(TopLevel)^.Focus_Widget<>NewFocusWidget)
then begin
{$IfDef VerboseFocus}
DebugLn(' H SETTING NewFocusWidget=',dbgs(NewFocusWidget),' ',DbgSName(GetNearestLCLObject(NewFocusWidget)));
{$EndIf}
gtk_window_set_focus(PGtkWindow(TopLevel),NewFocusWidget);
{$IfDef VerboseFocus}
DebugLn(' I NewTopLevel FocusWidget=',DbgS(PGtkWindow(TopLevel)^.Focus_Widget),' Success=',dbgs(PGtkWindow(TopLevel)^.Focus_Widget=NewFocusWidget));
{$EndIf}
end;
end;
end
else begin
NewFocusWidget:=Widget;
end;
if (NewFocusWidget <> nil) and not gtk_widget_has_focus(NewFocusWidget) then
begin
// grab the focus to the parent window
NewTopLevelWidget := gtk_widget_get_toplevel(NewFocusWidget);
if (Screen<>nil)
and (GetNearestLCLObject(NewTopLevelWidget)<>Screen.GetCurrentModalForm)
then begin
{$IFDEF VerboseFocus}
DebugLn('[TGtkWidgetSet.SetFocus] there is a modal form -> not grabbing');
{$ENDIF}
end else begin
{$IfDef VerboseFocus}
DebugLn(' J Grabbing focus ',GetWidgetDebugReport(NewFocusWidget));
{$EndIf}
gtk_widget_grab_focus(NewFocusWidget);
end;
end;
{$IfDef VerboseFocus}
write('[TGtkWidgetSet.SetFocus] END hWnd=',DbgS(hWnd));
NewFocusWidget:=PGtkWidget(GetFocus);
write(' NewFocus=',DbgS(NewFocusWidget));
AWinControl:=TWinControl(GetNearestLCLObject(NewFocusWidget));
if AWinControl<>nil then
write(' NewLCLParent=',AWinControl.Name,':',AWinControl.ClassName)
else
write(' NewLCLParent=nil');
DebugLn('');
{$EndIf}
end;
{------------------------------------------------------------------------------
Function TGtkWidgetSet.SetProp(Handle: hwnd; Str : PChar;
Data : Pointer) : Boolean;
------------------------------------------------------------------------------}
function TGtkWidgetSet.SetProp(Handle: hwnd; Str : PChar; Data : Pointer) : Boolean;
begin
gtk_object_set_data(pGTKObject(handle),Str,data);
Result:=true;
end;
{------------------------------------------------------------------------------
Function TGtkWidgetSet.SetROPMode(Handle: hwnd; Str : PChar;
Data : Pointer) : Boolean;
------------------------------------------------------------------------------}
Function TGtkWidgetSet.SetROP2(DC: HDC; Mode: Integer) : Integer;
Begin
if IsValidDC(DC) then with TDeviceContext(DC) do begin
if GC=nil then begin
Assert(False, 'Trace:[TGtkWidgetSet.SetROP2] Uninitialized GC');
result := 0
end else begin
Result := GetROP2(DC);
gdk_gc_set_function(GC, ROP2ModeToGdkFunction(Mode));
end;
end else begin
Assert(False, 'Trace:[TGtkWidgetSet.SetROP2] Invalid GC');
Result := 0;
end;
end;
{------------------------------------------------------------------------------
Function: SetScrollInfo
Params: none
Returns: The old position value
------------------------------------------------------------------------------}
function TGtkWidgetSet.SetScrollInfo(Handle : HWND; SBStyle : Integer;
ScrollInfo: TScrollInfo; bRedraw : Boolean): Integer;
procedure SetRangeUpdatePolicy(Range: PGtkRange);
var
UpdPolicy: TGTKUpdateType;
begin
case ScrollInfo.nTrackPos of
SB_POLICY_DISCONTINUOUS: UpdPolicy := GTK_UPDATE_DISCONTINUOUS;
SB_POLICY_DELAYED: UpdPolicy := GTK_UPDATE_DELAYED;
else UpdPolicy := GTK_UPDATE_CONTINUOUS;
end;
gtk_range_set_update_policy(Range, UpdPolicy);
end;
procedure SetScrolledWindowUpdatePolicy(ScrolledWindow:PGTKScrolledWindow);
var
Range: PGtkRange;
begin
case SBStyle of
SB_VERT: Range := PGtkRange(ScrolledWindow^.vscrollbar);
SB_HORZ: Range := PGtkRange(ScrolledWindow^.hscrollbar);
else exit;
end;
SetRangeUpdatePolicy(Range);
end;
const
POLICY: array[BOOLEAN] of TGTKPolicyType = (GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
var
Adjustment: PGtkAdjustment;
Scroll: PGTKWidget;
NewPolicy: Integer;
i: Integer;
begin
Result := 0;
if (Handle = 0) then exit;
//DebugLn('TGtkWidgetSet.SetScrollInfo A Widget=',GetWidgetClassName(PGtkWidget(Handle)));
Adjustment := nil;
Scroll := GTK_Object_Get_Data(PGTKObject(Handle), odnScrollArea);
If not GtkWidgetIsA(PGtkWidget(Scroll),gtk_scrolled_window_get_type) then
Scroll := PGTKWidget(Handle);
// scrollbar update policy
if (Scrollinfo.fmask and SIF_UPDATEPOLICY <> 0) then begin
if GtkWidgetIsA(PGtkWidget(Scroll),gtk_scrolled_window_get_type) then
SetScrolledWindowUpdatePolicy(PGTKScrolledWindow(Scroll))
else if GtkWidgetIsA(PgtkWidget(Scroll), gtk_clist_get_type) then
SetScrolledWindowUpdatePolicy(PGTKScrolledWindow(@PgtkCList(Scroll)^.container))
else if GtkWidgetIsA(PGtkWidget(Scroll),gtk_hscrollbar_get_type) then
SetRangeUpdatePolicy(PgtkRange(Scroll))
else if GtkWidgetIsA(PGtkWidget(Scroll),gtk_vscrollbar_get_type) then
SetRangeUpdatePolicy(PgtkRange(Scroll))
else if GtkWidgetIsA(PGtkWidget(Scroll), gtk_range_get_type) then
SetRangeUpdatePolicy(PGTKRange(Scroll));
end;
Adjustment:=nil;
case SBStyle of
SB_HORZ:
If GtkWidgetIsA(PGtkWidget(Scroll),gtk_scrolled_window_get_type) then
Adjustment := gtk_scrolled_window_get_hadjustment(
PGTKScrolledWindow(Scroll))
else
if GtkWidgetIsA(PGtkWidget(Scroll),gtk_hscrollbar_get_type) then
Adjustment := PgtkhScrollBar(Scroll)^.Scrollbar.Range.Adjustment
else //clist
if GtkWidgetIsA(PGtkWidget(Scroll),gtk_clist_get_type) then
Adjustment := gtk_clist_get_hadjustment(PgtkCList(Scroll));
SB_VERT:
If GtkWidgetIsA(PGtkWidget(Scroll),gtk_scrolled_window_get_type) then
Adjustment := gtk_scrolled_window_get_vadjustment(
PGTKScrolledWindow(Scroll))
else
if GtkWidgetIsA(PGtkWidget(Scroll),gtk_vscrollbar_get_type) then
Adjustment := PgtkvScrollBar(Scroll)^.Scrollbar.Range.Adjustment
else //clist
if GtkWidgetIsA(PGtkWidget(Scroll), gtk_clist_get_type) then
Adjustment := gtk_clist_get_vadjustment(PgtkCList(Scroll));
SB_CTL:
if GtkWidgetIsA(PGtkWidget(Scroll), gtk_range_get_type) then
Adjustment := gtk_range_get_adjustment(PGTKRange(Scroll));
end;
if Adjustment = nil then exit;
with ScrollInfo, Adjustment^ do begin
//DebugLn('SetScrollInfo Value=',Value);
// workaround for strange floating point bug
for i:=0 to 2 do begin
try
Result := RoundToInt(Value);
break;
except
on e: Exception do begin
DebugLn('TGtkWidgetSet.SetScrollInfo Workaround for ',E.Message,' try: ',dbgs(i));
Result:=0;
end;
end;
end;
//DebugLn('SetScrollInfo Result=',Result);
if (fMask and SIF_POS) <> 0
then Value := nPos;
if (fMask and SIF_RANGE) <> 0
then begin
Lower := nMin;
Upper := nMax;
end;
if (fMask and SIF_PAGE) <> 0
then begin
Page_Size := nPage;
Page_Increment := nPage;
end;
{DebugLn('');
DebugLn('[TGtkWidgetSet.SetScrollInfo] Result=',Result,
' Lower=',RoundToInt(Lower),
' Upper=',RoundToInt(Upper),
' Page_Size=',RoundToInt(Page_Size),
' Page_Increment=',RoundToInt(Page_Increment),
' bRedraw=',bRedraw,
' Handle=',DbgS(Handle));}
// do we have to set this always ?
if bRedraw then
begin
if GtkWidgetIsA(PGtkWidget(Scroll),gtk_scrolled_window_get_type) then
begin
if SBStyle in [SB_BOTH, SB_HORZ] then begin
NewPolicy:=POLICY[bRedraw];
gtk_object_set(PGTKObject(Scroll),'hscrollbar_policy',[NewPolicy,nil]);
end;
if SBStyle in [SB_BOTH, SB_VERT] then begin
NewPolicy:=POLICY[bRedraw];
gtk_object_set(PGTKObject(Scroll),'vscrollbar_policy',[NewPolicy,nil]);
end;
end
else
begin
if (SBSTYLE = SB_CTL)
and GtkWidgetIsA(PGtkWidget(Scroll),gtk_widget_get_type) then
gtk_widget_show(PGTKWidget(Scroll))
else
gtk_widget_hide(PGTKWidget(Scroll))
end;
{DebugLn('');
DebugLn('TGtkWidgetSet.SetScrollInfo: ',
' lower=',RoundToInt(lower),'/',nMin,
' upper=',RoundToInt(upper),'/',nMax,
' value=',RoundToInt(value),'/',nPos,
' step_increment=',RoundToInt(step_increment),'/',1,
' page_increment=',RoundToInt(page_increment),'/',nPage,
' page_size=',RoundToInt(page_size),'/',nPage,
'');}
gtk_adjustment_changed(Adjustment);
end;
end;
end;
{------------------------------------------------------------------------------
Function: SetSysColors
Params: cElements: the number of elements
lpaElements: array with element numbers
lpaRgbValues: array with colors
Returns: 0 if unsuccesful
The SetSysColors function sets the colors for one or more display elements.
------------------------------------------------------------------------------}
function TGtkWidgetSet.SetSysColors(cElements: Integer; const lpaElements;
const lpaRgbValues): Boolean;
type
TLongArray = array[0..0] of Longint;
PLongArray = ^TLongArray;
var
n: Integer;
Element: LongInt;
begin
Result := False;
if cElements > MAX_SYS_COLORS then Exit;
for n := 0 to cElements - 1 do
begin
Element := PLongArray(lpaElements)^[n];
if (Element > MAX_SYS_COLORS)
or (Element < 0)
then Exit;
SysColorMap[PLongArray(lpaElements)^[n]] := PLongArray(lpaRgbValues)^[n];
//Assert(False, Format('Trace:[TGtkWidgetSet.SetSysColor] Index %d (%8x) --> %8x', [PLongArray(lpaElements)^[n], SysColorMap[PLongArray(lpaElements)^[n]], PLongArray(lpaRgbValues)^[n]]));
end;
//TODO send WM_SYSCOLORCHANGE
Result := True;
end;
{------------------------------------------------------------------------------
Function: SetTextCharacterExtra
Params: _hdc:
nCharExtra:
Returns:
------------------------------------------------------------------------------}
Function TGtkWidgetSet.SetTextCharacterExtra(_hdc : hdc; nCharExtra : Integer):Integer;
begin
// Your code here
Result:=0;
end;
{------------------------------------------------------------------------------
Function: SetTextColor
Params: hdc: Identifies the device context.
Color: Specifies the color of the text.
Returns: The previous color if succesful, CLR_INVALID otherwise
The SetTextColor function sets the text color for the specified device
context to the specified color.
------------------------------------------------------------------------------}
function TGtkWidgetSet.SetTextColor(DC: HDC; Color: TColorRef): TColorRef;
begin
Assert(False, Format('trace:> [TGtkWidgetSet.SetTextColor] DC: 0x%x Color: %8x', [Integer(DC), Color]));
Result := CLR_INVALID;
if IsValidDC(DC)
then begin
with TDeviceContext(DC) do
begin
Result := CurrentTextColor.ColorRef;
SetGDIColorRef(CurrentTextColor,Color);
end;
end;
Assert(False, Format('trace:< [TGtkWidgetSet.SetTextColor] DC: 0x%x Color: %8x --> %8x', [Integer(DC), Color, Result]));
end;
{------------------------------------------------------------------------------
Procedure: SetWindowLong
Params: none
Returns: Nothing
------------------------------------------------------------------------------}
function TGtkWidgetSet.SetWindowLong(Handle: HWND; Idx: Integer;
NewLong: Longint): LongInt;
var
Data: Pointer;
begin
//TODO: Finish this;
Assert(False, Format('Trace:> [TGtkWidgetSet.SETWINDOWLONG] HWND: 0x%x, idx: 0x%x(%d), Value: 0x%x(%d)', [Handle, idx, idx, newlong, newlong]));
Result:=0;
Data := Pointer(PtrInt(NewLong));
case idx of
GWL_WNDPROC :
begin
gtk_object_set_data(pgtkobject(Handle),'WNDPROC',Data);
end;
GWL_HINSTANCE :
begin
gtk_object_set_data(pgtkobject(Handle),'HINSTANCE',Data);
end;
GWL_HWNDPARENT :
begin
gtk_object_set_data(pgtkobject(Handle),'HWNDPARENT',Data);
end;
GWL_STYLE :
begin
gtk_object_set_data(pgtkobject(Handle),'Style',Data);
end;
GWL_EXSTYLE :
begin
gtk_object_set_data(pgtkobject(Handle),'ExStyle',Data);
end;
GWL_USERDATA :
begin
gtk_object_set_data(pgtkobject(Handle),'Userdata',Data);
end;
GWL_ID :
begin
gtk_object_set_data(pgtkobject(Handle),'ID',Data);
end;
end; //case
Assert(False, Format('Trace:< [TGtkWidgetSet.SETWINDOWLONG] HWND: 0x%x, idx: 0x%x(%d), Value: 0x%x(%d) --> 0x%x(%d)', [Handle, idx, idx, newlong, newlong, Result, Result]));
end;
{------------------------------------------------------------------------------
Function TGtkWidgetSet.SetWindowOrgEx(DC : HDC; NewX, NewY : Integer;
OldPoint: PPoint) : Boolean;
Sets the DC offset for the specified device context.
------------------------------------------------------------------------------}
Function TGtkWidgetSet.SetWindowOrgEx(DC : HDC; NewX, NewY : Integer;
OldPoint: PPoint) : Boolean;
var
OldP: TPoint;
begin
//DebugLn('[TGtkWidgetSet.SetWindowOrgEx] ',NewX,' ',NewY);
GetWindowOrgEx(DC,@OldP);
Result := MoveWindowOrgEx(DC,NewX-OldP.X,NewY-OldP.Y);
if OldPoint<>nil then
OldPoint^:=OldP;
end;
{------------------------------------------------------------------------------
function TGtkWidgetSet.SetWindowPos(hWnd: HWND; hWndInsertAfter: HWND;
X, Y, cx, cy: Integer; uFlags: UINT): Boolean;
hWnd: Widget to move
hWndInsertAfter:
HWND_BOTTOM to move bottommost
HWND_TOP to move topmost
the Widget, that should lie just on top of hWnd
uFlags:
SWP_NOMOVE: ignore X, Y
SWP_NOSIZE: ignore cx, cy
SWP_NOZORDER: ignore hWndInsertAfter
SWP_NOREDRAW: skip instant redraw
SWP_NOACTIVATE: skip switching focus
------------------------------------------------------------------------------}
function TGtkWidgetSet.SetWindowPos(hWnd: HWND; hWndInsertAfter: HWND;
X, Y, cx, cy: Integer; uFlags: UINT): Boolean;
procedure SetZOrderOnFixedWidget(Widget, FixedWidget: PGtkWidget);
var
OldListItem: PGList;
AfterWidget: PGtkWidget;
AfterListItem: PGList;
begin
OldListItem:=FindFixedChildListItem(PGtkFixed(FixedWidget),Widget);
if OldListItem=nil then begin
DebugLn('TGtkWidgetSet.SetWindowPos.SetZOrderOnFixedWidget WARNING: Widget not on parents fixed widget');
exit;
end;
AfterWidget:=nil;
AfterListItem:=nil;
if hWndInsertAfter=HWND_BOTTOM then begin
//debugln('HWND_BOTTOM');
// HWND_BOTTOM
end else if hWndInsertAfter=HWND_TOP then begin
//debugln('HWND_TOP');
// HWND_TOP
AfterListItem:=FindFixedLastChildListItem(PGtkFixed(FixedWidget));
end else if hWndInsertAfter=0 then begin
DebugLn('TGtkWidgetSet.SetWindowPos.SetZOrderOnFixedWidget WARNING: hWndInsertAfter=0');
exit;
end else begin
// hWndInsertAfter
AfterWidget:=PGtkWidget(hWndInsertAfter);
AfterListItem:=FindFixedChildListItem(PGtkFixed(FixedWidget),AfterWidget);
//debugln('AfterWidget=',GetWidgetDebugReport(AfterWidget));
end;
if (AfterListItem=nil) and (AfterWidget<>nil) then begin
DebugLn('TGtkWidgetSet.SetWindowPos.SetZOrderOnFixedWidget WARNING: AfterWidget not on parents fixed widget');
exit;
end;
if (OldListItem=AfterListItem) or (OldListItem^.next=AfterListItem) then
begin
{$IFDEF EnableGtkZReordering}
DebugLn('TGtkWidgetSet.SetWindowPos.SetZOrderOnFixedWidget Hint: Already there');
{$ENDIF}
exit;
end;
//DebugLn('TGtkWidgetSet.SetWindowPos Moving GList entry');
// reorder
{$IFDEF EnableGtkZReordering}
// MG: This trick does not work properly
debugln('SetZOrderOnFixedWidget FixedWidget=['+GetWidgetDebugReport(FixedWidget)+']',
' Widget=['+GetWidgetDebugReport(Widget)+']',
' AfterWidget=['+GetWidgetDebugReport(AfterWidget)+']');
MoveGListLinkBehind(PGtkFixed(FixedWidget)^.children,
OldListItem,AfterListItem);
if GTK_WIDGET_VISIBLE(FixedWidget) and GTK_WIDGET_VISIBLE(Widget)
and GTK_WIDGET_MAPPED(Widget) then begin
DebugLn('TGtkWidgetSet.SetWindowPos.SetZOrderOnFixedWidget resize ..');
gtk_widget_queue_resize(FixedWidget);
AfterListItem:=PGtkFixed(FixedWidget)^.children;
while AfterListItem<>nil do begin
AfterWidget:=GetFixedChildListWidget(AfterListItem);
DebugLn('TGtkWidgetSet.SetWindowPos.SetZOrderOnFixedWidget A ',GetWidgetDebugReport(AfterWidget));
AfterListItem:=AfterListItem^.next;
end;
end;
{$ENDIF}
end;
procedure SetZOrderOnLayoutWidget(Widget, LayoutWidget: PGtkWidget);
begin
//DebugLn('TGtkWidgetSet.SetWindowPos.SetZOrderOnLayoutWidget Not implemented: ZOrdering .. on ',GetWidgetDebugReport(LayoutWidget));
end;
var
Widget: PGTKWidget;
FixedWidget: PGtkWidget;
begin
Result:=false;
Widget:=PGtkWidget(hWnd);
{DebugLn('[TGtkWidgetSet.SetWindowPos] ',GetWidgetDebugReport(Widget),
' Top=',hWndInsertAfter=HWND_TOP,
' SWP_NOZORDER=',(SWP_NOZORDER and uFlags)<>0,
' SWP_NOSIZE=',(SWP_NOSIZE and uFlags)<>0,
' SWP_NOMOVE=',(SWP_NOMOVE and uFlags)<>0,
'');}
if GtkWidgetIsA(Widget,GTK_TYPE_WINDOW) then begin
{ case hWndInsertAfter of
HWND_BOTTOM: ; //gdk_window_lower(Widget^.Window);
HWND_TOP: gtk_window_set_position(PGtkWindow(hWnd),GTK_WIN_POS_CENTER);
//gdk_window_raise(Widget^.Window);
end;
}
end else if (SWP_NOZORDER and uFlags)=0 then begin
FixedWidget:=Widget^.Parent;
if FixedWidget=nil then exit;
//DebugLn('TGtkWidgetSet.SetWindowPos ZOrdering .. on ',GetWidgetDebugReport(FixedWidget));
if GtkWidgetIsA(FixedWidget,GTK_Fixed_Get_Type) then begin
// parent's client area is a gtk_fixed widget
SetZOrderOnFixedWidget(Widget,FixedWidget);
end else if GtkWidgetIsA(FixedWidget,GTK_Layout_Get_Type) then begin
// parent's client area is a gtk_layout widget
SetZOrderOnLayoutWidget(Widget,FixedWidget);
end else begin
//DebugLn('TGtkWidgetSet.SetWindowPos Not implemented: ZOrdering .. on ',GetWidgetDebugReport(FixedWidget));
exit;
end;
end;
Result:=true;
end;
{------------------------------------------------------------------------------
Function: ShowCaret
Params: none
Returns: Nothing
------------------------------------------------------------------------------}
function TGtkWidgetSet.ShowCaret(hWnd: HWND): Boolean;
var
GTKObject: PGTKObject;
begin
Assert(False, Format('Trace:> [TGtkWidgetSet.ShowCaret] HWND: 0x%x', [hWnd]));
GTKObject := PGTKObject(HWND);
Result := GTKObject <> nil;
if Result
then begin
if gtk_type_is_a(gtk_object_type(GTKObject), GTKAPIWidget_GetType)
then begin
GTKAPIWidget_ShowCaret(PGTKAPIWidget(GTKObject));
end
else begin
Result := False;
end;
end
else DebugLn('WARNING: [TGtkWidgetSet.ShowCaret] Got null HWND');
Assert(False, Format('Trace:< [TGtkWidgetSet.ShowCaret] HWND: 0x%x --> %s', [hWnd, BOOL_TEXT[Result]]));
end;
{------------------------------------------------------------------------------
Function: ShowScrollBar
Params: Wnd, wBar, bShow
Returns: Nothing
------------------------------------------------------------------------------}
function TGtkWidgetSet.ShowScrollBar(Handle: HWND; wBar: Integer;
bShow: Boolean): Boolean;
const
POLICY: array[BOOLEAN] of TGTKPolicyType = (GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
var
Widget: PGtkWidget;
NewPolicy: Integer;
begin
Assert(False, 'trace:[TGtkWidgetSet.ShowScrollBar]');
Result:=false;
Result := (Handle <> 0);
if Result then begin
Widget:=PGtkWidget(Handle);
if GtkWidgetIsA(Widget,gtk_scrolled_window_get_type) then begin
if wBar in [SB_BOTH, SB_HORZ] then begin
if bShow then
NewPolicy:=POLICY[bShow]
else
NewPolicy:=GTK_POLICY_NEVER;
gtk_object_set(PGTKObject(Widget), 'hscrollbar_policy', [NewPolicy,nil]);
end;
if wBar in [SB_BOTH, SB_VERT] then begin
if bShow then
NewPolicy:=POLICY[bShow]
else
NewPolicy:=GTK_POLICY_NEVER;
gtk_object_set(PGTKObject(Widget), 'vscrollbar_policy', [NewPolicy,nil]);
end;
end
else begin
if (wBar = SB_CTL)
and gtk_type_is_a(gtk_object_type(PGTKObject(Handle)),gtk_widget_get_type)
then begin
if bShow
then gtk_widget_show(Widget)
else gtk_widget_hide(Widget);
end;
end;
end;
end;
{------------------------------------------------------------------------------
function ShowWindow(hWnd: HWND; nCmdShow: Integer): Boolean;
nCmdShow:
SW_SHOWNORMAL, SW_MINIMIZE, SW_SHOWMAXIMIZED
------------------------------------------------------------------------------}
function TGtkWidgetSet.ShowWindow(hWnd: HWND; nCmdShow: Integer): Boolean;
var
GtkWindow: PGtkWindow;
begin
Result:=false;
GtkWindow:=PGtkWindow(hWnd);
if GtkWindow=nil then
RaiseException('TGtkWidgetSet.ShowWindow hWnd is nil');
{$IFDEF Gtk2}
//debugln('TGtkWidgetSet.ShowWindow A ',GetWidgetDebugReport(PGtkWidget(GtkWindow)),' nCmdShow=',dbgs(nCmdShow),' SW_MINIMIZE=',dbgs(SW_MINIMIZE=nCmdShow));
case nCmdShow of
SW_SHOWNORMAL:
begin
gtk_window_deiconify(GtkWindow);
gtk_window_unmaximize(GtkWindow);
end;
SW_MINIMIZE:
gtk_window_iconify(GtkWindow);
SW_SHOWMAXIMIZED:
gtk_window_maximize(GtkWindow);
end;
{$ELSE}
case nCmdShow of
SW_SHOWNORMAL:
begin
{$IFDEF DebugGDK}BeginGDKErrorTrap;{$ENDIF}
gdk_window_show(PgtkWidget(GtkWindow)^.Window);
{$IFDEF DebugGDKTraps}EndGDKErrorTrap;{$ENDIF}
end;
SW_MINIMIZE:
begin
GDK_WINDOW_MINIMIZE(PGdkWindowPrivate(PgtkWidget(GtkWindow)^.Window));
end;
SW_SHOWMAXIMIZED:
begin
GDK_WINDOW_MAXIMIZE(PGdkWindowPrivate(PgtkWidget(GtkWindow)^.Window));
end;
end;
Result:=true;
{$ENDIF}
end;
{------------------------------------------------------------------------------
Function: StretchBlt
Params: DestDC: The destination devicecontext
X, Y: The left/top corner of the destination rectangle
Width, Height: The size of the destination rectangle
SrcDC: The source devicecontext
XSrc, YSrc: The left/top corner of the source rectangle
SrcWidth, SrcHeight: The size of the source rectangle
ROp: The raster operation to be performed
Returns: True if succesful
The StretchBlt function copies a bitmap from a source rectangle into a
destination rectangle using the specified raster operation. If needed it
resizes the bitmap to fit the dimensions of the destination rectangle.
Sizing is done according to the stretching mode currently set in the
destination device context.
If SrcDC contains a mask the pixmap will be copied with this transparency.
ToDo: Mirroring, extended NonDrawable support (Image, Bitmap, etc)
------------------------------------------------------------------------------}
function TGtkWidgetSet.StretchBlt(DestDC: HDC; X, Y, Width, Height: Integer;
SrcDC: HDC; XSrc, YSrc, SrcWidth, SrcHeight: Integer; ROp: Cardinal): Boolean;
begin
Result:=StretchCopyArea(DestDC,X,Y,Width,Height,
SrcDC,XSrc,YSrc,SrcWidth,SrcHeight,
0,0,0,
ROp);
end;
{------------------------------------------------------------------------------
Function: StretchMaskBlt
Params: DestDC: The destination devicecontext
X, Y: The left/top corner of the destination rectangle
Width, Height: The size of the destination rectangle
SrcDC: The source devicecontext
XSrc, YSrc: The left/top corner of the source rectangle
SrcWidth, SrcHeight: The size of the source rectangle
Mask: The handle of a monochrome bitmap
XMask, YMask: The left/top corner of the mask rectangle
ROp: The raster operation to be performed
Returns: True if succesful
The StretchMaskBlt function copies a bitmap from a source rectangle into a
destination rectangle using the specified mask and raster operation. If needed
it resizes the bitmap to fit the dimensions of the destination rectangle.
Sizing is done according to the stretching mode currently set in the
destination device context.
------------------------------------------------------------------------------}
function TGtkWidgetSet.StretchMaskBlt(DestDC: HDC; X, Y, Width, Height: Integer;
SrcDC: HDC; XSrc, YSrc, SrcWidth, SrcHeight: Integer; Mask: HBITMAP;
XMask, YMask: Integer; Rop: DWORD): Boolean;
begin
Result:=StretchCopyArea(DestDC,X,Y,Width,Height,
SrcDC,XSrc,YSrc,SrcWidth,SrcHeight,
Mask,XMask,YMask,
ROp);
end;
{------------------------------------------------------------------------------
Function: TextOut
Params: DC:
X:
Y:
Str:
Count:
Returns:
------------------------------------------------------------------------------}
Function TGtkWidgetSet.TextOut(DC: HDC; X,Y : Integer; Str : Pchar;
Count: Integer) : Boolean;
{$IfDef GTK2}
begin
DebugLn('TGtkWidgetSet.TextOut ToDo');
Result:=false;
end;
{$ELSE}
var
aRect : TRect;
txtpt : TPoint;
sz : TSize;
UseFont : PGDKFont;
UnRef,
Underline,
StrikeOut : Boolean;
DCOrigin: TPoint;
TempPen : hPen;
LogP : TLogPen;
Points : array[0..1] of TSize;
begin
Result := IsValidDC(DC);
if Result and (Count>0)
then with TDeviceContext(DC) do
begin
if GC = nil
then begin
DebugLn('WARNING: [TGtkWidgetSet.TextOut] Uninitialized GC');
end
else begin
if (CurrentFont = nil) or (CurrentFont^.GDIFontObject = nil)
then begin
UseFont := GetDefaultFont(true);
UnRef := True;
Underline := False;
StrikeOut := False;
end
else begin
UseFont := CurrentFont^.GDIFontObject;
UnRef := False;
Underline := LongBool(CurrentFont^.LogFont.lfUnderline);
StrikeOut := LongBool(CurrentFont^.LogFont.lfStrikeOut);
end;
If UseFont = nil then
DebugLn('WARNING: [TGtkWidgetSet.TextOut] Missing Font')
else begin
DCOrigin:=GetDCOffset(TDeviceContext(DC));
GetTextExtentPoint(DC, Str, Count, Sz);
aRect := Rect(X+DCOrigin.X,Y+DCOrigin.Y,X + Sz.CX, Sz.CY);
//DebugLn('TGtkWidgetSet.TextOut ',ARect.Left,',',ARect.Top,',',ARect.RIght,',',ARect.Bottom);
FillRect(DC,aRect,hBrush(CurrentBrush));
UpdateDCTextMetric(TDeviceContext(DC));
TxtPt.X := X;
{$IfDef Win32}
TxtPt.Y := Y + DCTextMetric.TextMetric.tmHeight div 2;
{$Else}
TxtPt.Y := Y + DCTextMetric.TextMetric.tmAscent;
{$EndIf}
SelectGDKTextProps(DC);
{$IFDEF DebugGDK}BeginGDKErrorTrap;{$ENDIF}
gdk_draw_text(Drawable, UseFont,
GC, TxtPt.X+DCOrigin.X, TxtPt.Y+DCOrigin.Y, Str, Count);
{$IFDEF DebugGDKTraps}EndGDKErrorTrap;{$ENDIF}
If Underline or StrikeOut then begin
{Create & select pen of font color}
LogP.lopnStyle := PS_SOLID;
LogP.lopnWidth.X := 1;
LogP.lopnColor := GetTextColor(DC);
TempPen := SelectObject(DC, CreatePenIndirect(LogP));
{Get line(s) horizontal position(s)}
Points[0].cX := X;
Points[1].cX := X + sz.cX;
{Draw line(s)}
If Underline then begin
Points[0].cY := Y + 2 + DCTextMetric.TextMetric.tmHeight -
DCTextMetric.TextMetric.tmDescent;
Points[1].cY := Points[0].cY;
Polyline(DC, @Points[0], 2);
end;
If StrikeOut then begin
Points[0].cY := Y + 2 + (TxtPt.Y - Y) div 2;
Points[1].cY := Points[0].cY;
Polyline(DC, @Points[0], 2);
end;
DeleteObject(SelectObject(DC, TempPen));
end;
Result := True;
If UnRef then
FontCache.Unreference(UseFont);
end;
end;
end;
end;
{$EndIf}
{------------------------------------------------------------------------------
Function: VkKeyScan
Params: AChar: Character to translate
Returns: LoByte: VK-code
HiByte: ALT | CTRL | SHIFT pressed -> bit2 | bit1 | bit0
------------------------------------------------------------------------------}
function TGtkWidgetSet.VkKeyScan(AChar: Char): Short;
begin
Result := CharToVkAndFlags(AChar);
end;
{------------------------------------------------------------------------------
Function: WindowFromPoint
Params: Point: Specifies the x and y Coords
Returns: The handle of the gtkwidget. If none exist, then NULL is returned.
------------------------------------------------------------------------------}
Function TGtkWidgetSet.WindowFromPoint(Point : TPoint) : HWND;
var
ev : TgdkEvent;
Window : PgdkWindow;
Widget : PgtkWidget;
p: TPoint;
begin
Result := 0;
// !!!gdk_window_at_pointer changes the coordinates!!!
// -> using local variable p
p:=Point;
Window := gdk_window_at_pointer(@p.x,@p.Y);
if window <> nil then
begin
FillChar(ev,SizeOf(ev),0);
ev.any.window := Window;
Widget := gtk_get_event_widget(@ev);
Result := Longint(widget);
end;
end;
//##apiwiz##eps## // Do not remove
// Placed CriticalSectionSupport outside the API wizard bounds
// so it won't affect sorting etc.
{$IfDef Critical_Sections_Support}
{$IfNDef Win32}
{$Define pthread}
Type
_pthread_fastlock = packed record
__status: Longint;
__spinlock: Integer;
end;
pthread_mutex_t = packed record
__m_reserved: Integer;
__m_count: Integer;
__m_owner: Pointer;
__m_kind: Integer;
__m_lock: _pthread_fastlock;
end;
ppthread_mutex_t = ^pthread_mutex_t;
pthread_mutexattr_t = packed record
__mutexkind: Integer;
end;
{$linklib pthread}
function pthread_mutex_init(var Mutex: pthread_mutex_t;
var Attr: pthread_mutexattr_t): Integer; cdecl;external;
function pthread_mutexattr_settype(var Attr: pthread_mutexattr_t;
Kind: Integer): Integer; cdecl;external;
function pthread_mutex_lock(var Mutex: pthread_mutex_t):
Integer; cdecl; external;
function pthread_mutex_unlock(var Mutex: pthread_mutex_t):
Integer; cdecl; external;
function pthread_mutex_destroy(var Mutex: pthread_mutex_t):
Integer; cdecl; external;
{$EndIf}
{$EndIf}
Procedure TGtkWidgetSet.InitializeCriticalSection(var CritSection: TCriticalSection);
{$IfDef pthread}
var
Crit : ppthread_mutex_t;
Attribute: pthread_mutexattr_t;
begin
if pthread_mutexattr_settype(Attribute, 1) <> 0 then
Exit;
If CritSection <> 0 then
Try
Crit := ppthread_mutex_t(CritSection);
Dispose(Crit);
except
CritSection := 0;
end;
New(Crit);
pthread_mutex_init(Crit^, Attribute);
CritSection := Longint(Crit);
end;
{$Else}
begin
end;
{$EndIf}
Procedure TGtkWidgetSet.EnterCriticalSection(var CritSection: TCriticalSection);
{$IfDef pthread}
var
Crit,
tmp : ppthread_mutex_t;
begin
New(Crit);
If CritSection <> 0 then
Try
Crit^ := ppthread_mutex_t(CritSection)^;
except
begin
CritSection := Longint(Crit);
exit;
end;
end;
pthread_mutex_lock(Crit^);
tmp := ppthread_mutex_t(CritSection);
CritSection := Longint(Crit);
Dispose(Tmp);
end;
{$Else}
begin
end;
{$EndIf}
Procedure TGtkWidgetSet.LeaveCriticalSection(var CritSection: TCriticalSection);
{$IfDef pthread}
var
Crit,
tmp : ppthread_mutex_t;
begin
New(Crit);
If CritSection <> 0 then
Try
Crit^ := ppthread_mutex_t(CritSection)^;
except
begin
CritSection := Longint(Crit);
exit;
end;
end;
pthread_mutex_unlock(Crit^);
tmp := ppthread_mutex_t(CritSection);
CritSection := Longint(Crit);
Dispose(Tmp);
end;
{$Else}
begin
end;
{$EndIf}
Procedure TGtkWidgetSet.DeleteCriticalSection(var CritSection: TCriticalSection);
{$IfDef pthread}
var
Crit,
tmp : ppthread_mutex_t;
begin
New(Crit);
If CritSection <> 0 then
Try
Crit^ := ppthread_mutex_t(CritSection)^;
except
begin
CritSection := Longint(Crit);
exit;
end;
end;
pthread_mutex_destroy(Crit^);
Dispose(Crit);
tmp := ppthread_mutex_t(CritSection);
CritSection := 0;
Dispose(Tmp);
end;
{$Else}
begin
end;
{$EndIf}
{$IfDef ASSERT_IS_ON}
{$UNDEF ASSERT_IS_ON}
{$C-}
{$EndIf}
{ =============================================================================
$Log$
Revision 1.422 2005/06/22 17:37:06 mattias
implemented TMouse.SetCursorPos from Andrew
Revision 1.421 2005/06/03 20:58:23 mattias
fixed focussing modal forms on gtk intf
Revision 1.420 2005/05/21 15:58:44 mattias
implemented right justification for menuitems for winapi intf from Martin Smat
Revision 1.419 2005/05/18 09:12:21 mattias
fixed retrieving TCanvas.Width/Height
Revision 1.418 2005/03/21 18:59:50 mattias
gtk1 intf no longer moves a focused window to another desktop from Andrew Haines
Revision 1.417 2005/03/21 08:12:10 mattias
fixed removing focus of a gtk listbox on delete item from Collin Western
Revision 1.416 2005/03/20 09:45:05 mattias
disabled gtk1 focussing a window, enable it with -dEnableGtkWindowFocus
Revision 1.415 2005/03/20 09:35:47 mattias
next try to fix the gtk1 crashing on focussing a window from Andrew Haines
Revision 1.414 2005/03/19 09:17:20 mattias
gtk1: minimizing windows, missing: window state events from Andrew Haines
Revision 1.413 2005/03/18 15:32:13 mattias
next try to fix the crashing when switching focus from Andrew Haines
Revision 1.412 2005/03/17 10:10:51 mattias
added gtk1 check for current desktop on focussing windows from Andrew Haines
Revision 1.411 2005/03/16 17:45:28 mattias
published TStringGrid.OnResize/OnChangeBounds and fixed gtk1 intf check in focussing
Revision 1.410 2005/03/16 12:30:15 mattias
added some checks to avoid crashes
Revision 1.409 2005/03/16 11:36:21 mattias
improved gtk1 intf switching focus to another form from Andrew Haines
Revision 1.408 2005/03/13 22:35:17 mattias
fixed deleting selected TListBox item under gtk1 from Collin
Revision 1.407 2005/03/08 00:28:03 mattias
implemented gtk2 AppMinimize
Revision 1.406 2005/03/07 21:59:45 vincents
changed hexstr(cardinal()) for pointers to dbgs() and other 64-bits fixes from Peter Vreman
Revision 1.405 2005/03/05 14:44:01 mattias
fixed gtk1 font rotating from C Western
Revision 1.404 2005/03/04 13:50:09 mattias
fixed Arc and changed x,y to Left,Top to make meaning more clear
Revision 1.403 2005/03/04 12:21:56 mattias
fixed TShape FPCanvas issue
Revision 1.402 2005/03/02 16:47:20 mattias
fixed loading forms under fpc 1.9.9
Revision 1.401 2005/02/23 01:21:54 marc
- Removed double commit (?)
Revision 1.400 2005/02/23 01:12:47 marc
+ Added RemoveProp winapi call
* Some maintenace on winapi/lclintf files
Revision 1.399 2005/02/19 20:36:56 mattias
xinerama hack is now only enabled when compiled with -dUseXinerama
Revision 1.398 2005/02/19 16:30:47 mattias
fixed 1.0.10 compilation
Revision 1.397 2005/02/19 16:19:19 mattias
added xinerama recognition fro gtk1/fpc1_9+ from C Western
Revision 1.396 2005/02/17 00:05:25 mattias
fixed some gtk2 intf warnings
Revision 1.395 2005/02/05 22:48:51 mattias
clean up
Revision 1.394 2005/02/05 16:09:52 marc
* first 64bit changes
Revision 1.393 2005/02/05 13:33:05 mattias
implemented gtkwidgetset.IsWindowEnabled
Revision 1.392 2005/02/05 09:05:50 micha
add platform independent winapi function IsWindowEnabled
Revision 1.391 2005/02/04 01:04:41 mattias
fixed gtk intf Arc
Revision 1.390 2005/01/28 17:55:48 mattias
fixed mem leak
Revision 1.389 2005/01/27 19:03:51 mattias
added QuestionDlg - a MessageDlg with custom buttons
Revision 1.388 2005/01/22 23:53:43 mattias
fixed gtk2 intf from Peter Vreman
Revision 1.387 2005/01/17 16:42:35 mattias
improved TLabel autosizing
Revision 1.386 2005/01/17 15:36:31 mattias
improved gtk intf to calculate TextHeight
Revision 1.385 2005/01/16 11:40:11 mattias
fixed TGtkWidgetSet.ExtSelectClipRGN for DCOrigin
Revision 1.384 2005/01/08 11:03:18 mattias
implemented TPen.Mode=pmXor from Jesus
Revision 1.383 2005/01/07 18:40:10 mattias
clean up, added GetRGBValues
Revision 1.382 2005/01/01 20:17:32 mattias
implemented gtk GetTextExtentPoint for UTF8
Revision 1.381 2005/01/01 16:04:13 mattias
implemented CodeExplorer auto update on switching source editor page
Revision 1.380 2004/12/22 19:56:44 mattias
started TFont mirgration to fpCanvas font
Revision 1.379 2004/12/21 22:49:29 mattias
implemented scrollbar codes for gtk intf from Jesus
Revision 1.378 2004/12/16 19:03:57 mattias
applied patch for smooth scrolling parameters from Jesus
Revision 1.377 2004/12/11 01:28:58 mattias
implemented bvSpace of TBevelCut
Revision 1.376 2004/12/01 16:17:18 mattias
updated fpdoc sceletons for lcl and gtk intf
Revision 1.375 2004/11/27 13:57:49 mattias
added more gtk ISO character sets
Revision 1.374 2004/11/20 11:49:15 mattias
implemented stopping project on close project
Revision 1.373 2004/11/20 11:20:06 mattias
implemented creating classes at run time from any TComponent descendant
Revision 1.372 2004/11/10 18:23:56 mattias
impementing changing a TLabel.Font properties Size, Height, Name, Style - set only at Handle creation time
Revision 1.371 2004/11/08 19:11:55 mattias
disabled hardly used gtk FillScreenFont, this should be only done on demand, improved getting default font family for gtk
Revision 1.370 2004/10/15 13:28:22 mattias
codeexplorer: using lower recursive depth
Revision 1.369 2004/10/01 13:16:44 mattias
fixed unselecting TCanvas objects
Revision 1.368 2004/09/29 15:18:27 mattias
fixed TBitmap.Canvas.Frame3d
Revision 1.367 2004/09/17 20:30:13 vincents
replaced write by DbgOut
Revision 1.366 2004/09/10 16:28:51 mattias
implemented very rudimentary TTabControl
Revision 1.365 2004/09/06 22:24:52 mattias
started the carbon LCL interface
Revision 1.364 2004/09/02 09:17:00 mattias
improved double byte char fonts for gtk1, started synedit UTF8 support
Revision 1.363 2004/08/30 10:49:20 mattias
fixed focus catch for combobox csDropDownList
Revision 1.362 2004/08/19 18:50:53 mattias
splitted IDE component owner hierachy to reduce notification time
Revision 1.361 2004/08/18 20:49:03 mattias
simple forms can now be child controls
Revision 1.360 2004/08/13 20:40:27 mattias
fixed DebugLn for VerboseRawImage
Revision 1.359 2004/08/11 12:57:03 mattias
improved gtk1 FontCache to handle several descriptors per gdkfont
Revision 1.358 2004/08/10 17:34:13 mattias
implemented font cache for gtk, which accelerates switching fonts
Revision 1.357 2004/07/01 10:23:27 mattias
fixed uninitialsed vars from Jeroen
Revision 1.356 2004/06/28 23:16:24 mattias
added TListView.AddItems from Andrew Haines
Revision 1.355 2004/06/28 20:03:33 mattias
fixed TGtkWidgetSet.DrawFrameControl
Revision 1.354 2004/06/28 17:03:37 mattias
clean up
Revision 1.353 2004/06/28 15:45:48 mattias
fixed a mem violation in gtk intf paint msg conversion
Revision 1.352 2004/06/09 20:51:45 vincents
implemented basic clipboard support for win32
Revision 1.351 2004/05/22 14:35:33 mattias
fixed button return key
Revision 1.350 2004/05/11 11:42:27 mattias
replaced writeln by debugln
Revision 1.349 2004/05/07 08:07:57 mattias
ifdefd UseSimpleJpeg
Revision 1.348 2004/04/18 23:55:39 marc
* Applied patch from Ladislav Michl
* Changed the way TControl.Text is resolved
* Added setting of text to TWSWinControl
Revision 1.347 2004/04/15 21:27:40 marc
* Applied patch from Ladislav Michl
Revision 1.346 2004/04/12 22:36:29 mattias
made TIcon more independent of TBitmap from Colin
Revision 1.345 2004/04/03 16:47:46 mattias
implemented converting gdkbitmap to RawImage mask
Revision 1.344 2004/04/02 14:28:44 vincents
Fixed compilation with -dVerboseFocus
Revision 1.343 2004/03/30 20:38:14 mattias
fixed interface constraints, fixed syncompletion colors
Revision 1.342 2004/03/28 12:49:23 mattias
implemented mask merge and extraction for raw images
Revision 1.341 2004/03/24 01:21:41 marc
* Simplified signals for gtkwsbutton
Revision 1.340 2004/03/22 19:10:04 mattias
implemented icons for TPage in gtk, mask for TCustomImageList
Revision 1.339 2004/03/09 15:30:15 peter
* fixed gtk2 compilation
Revision 1.338 2004/03/06 17:12:19 mattias
fixed CreateBrushIndirect
Revision 1.337 2004/03/06 15:37:43 mattias
fixed FreeDC
Revision 1.336 2004/03/05 00:31:52 marc
* Renamed TGtkObject to TGtkWidgetSet
Revision 1.335 2004/02/28 00:34:36 mattias
fixed CreateComponent for buttons, implemented basic Drag And Drop
Revision 1.334 2004/02/23 23:15:14 mattias
improved FindDragTarget
Revision 1.333 2004/02/23 18:24:38 mattias
completed new TToolBar
Revision 1.332 2004/02/21 01:01:03 mattias
added uninstall popupmenuitem to package graph explorer
Revision 1.331 2004/02/19 05:07:17 mattias
CreateBitmapFromRawImage now creates mask only if needed
Revision 1.330 2004/02/17 00:32:25 mattias
fixed TCustomImage.DoAutoSize fixing uninitialized vars
Revision 1.329 2004/02/13 15:49:54 mattias
started advanced LCL auto sizing
Revision 1.328 2004/02/10 00:05:03 mattias
TSpeedButton now uses MaskBlt
Revision 1.327 2004/02/04 22:17:09 mattias
removed workaround VirtualCreate
Revision 1.326 2004/02/04 12:48:17 mattias
added CLX colors
Revision 1.325 2004/02/03 08:54:09 mattias
Frame3D rect now var again
Revision 1.324 2004/02/02 15:46:19 mattias
implemented basic TSplitter, still many ToDos
Revision 1.323 2004/02/02 12:44:45 mattias
implemented interface constraints
Revision 1.322 2004/01/26 11:55:35 mattias
fixed resizing synedit
Revision 1.321 2004/01/23 13:55:30 mattias
style widgets are now realized, so all values are initialized
Revision 1.320 2004/01/22 11:23:36 mattias
started MaskBlt for gtkIF and applied patch for dir dlg in env opts from Vincent
Revision 1.319 2004/01/18 11:03:01 mattias
added finnish translation
Revision 1.318 2004/01/17 13:29:04 mattias
using now fpc constant LineEnding from Vincent
Revision 1.317 2004/01/15 22:36:24 mattias
workaround for fpc fpu bug and added calendar debugging msg
Revision 1.316 2004/01/13 10:41:40 mattias
fixed statusbar updating all panels
Revision 1.315 2004/01/12 23:56:10 mattias
improved double buffering, only one issue left: parent gdkwindow paint messages
Revision 1.314 2004/01/10 22:34:20 mattias
started double buffering for gtk intf
Revision 1.313 2004/01/10 18:00:42 mattias
fixed GetWindowOrgEx, added GetDCOriginRelativeToWindow
Revision 1.312 2004/01/10 00:46:46 mattias
fixed DestroyComponent
Revision 1.311 2004/01/09 20:03:13 mattias
implemented new statusbar methods in gtk intf
Revision 1.310 2004/01/05 01:18:16 mattias
implemented Double Buffering for synedit and deactivated multi buffering in TGTKObject.ExtTextOut
Revision 1.309 2004/01/03 23:15:00 mattias
default font can now change height and fixed gtk crash
Revision 1.308 2004/01/03 20:31:02 mattias
fixed CreateRectRgn for negative widths/heights
Revision 1.307 2003/12/30 21:05:13 micha
fix gtk interface due to lcl interface change (from vincent
Revision 1.306 2003/12/25 14:17:07 mattias
fixed many range check warnings
Revision 1.305 2003/12/23 11:16:41 mattias
started key combinations, fixed some range check errors
Revision 1.304 2003/11/29 15:23:23 mattias
ct parser now understands interconst:const
Revision 1.303 2003/11/29 13:17:38 mattias
made gtklayout using window theme at start
Revision 1.302 2003/11/24 11:03:07 marc
* Splitted winapi*.inc into a winapi and a lcl interface communication part
Revision 1.301 2003/11/23 13:13:35 mattias
added clWindow for gtklistitem
Revision 1.300 2003/11/23 10:58:47 mattias
fixed de-associating TUpDown
Revision 1.299 2003/11/10 16:15:32 micha
cleanups; win32 fpimage support
Revision 1.298 2003/11/08 22:53:11 mattias
workaround for gtk1 invalidate bug
Revision 1.297 2003/11/03 22:37:41 mattias
fixed vert scrollbar, implemented GetDesignerDC
Revision 1.296 2003/11/01 10:27:41 mattias
fpc 1.1 fixes, started scrollbar hiding, started polymorphing client areas
Revision 1.295 2003/10/31 14:54:10 mattias
added the possibility to disbale double buffering
Revision 1.294 2003/10/30 21:26:23 mattias
removed some hints
Revision 1.293 2003/10/22 17:50:16 mattias
updated rpm scripts
Revision 1.292 2003/10/16 23:54:27 marc
Implemented new gtk keyevent handling
Revision 1.291 2003/10/15 20:33:37 ajgenius
add csForm, start fixing Style matching for syscolors and fonts
Revision 1.290 2003/10/06 16:13:52 ajgenius
partly fixed gtk2 mouse offsets;
added new includes to gtk2 lpk
Revision 1.289 2003/10/02 18:18:32 ajgenius
buffer cs_opaque ExtTextOut blocks to help prevent extensive flickering
Revision 1.288 2003/09/25 16:02:16 ajgenius
try to catch GDK/X drawable errors and raise an AV to stop killing App
Revision 1.287 2003/09/19 00:41:52 ajgenius
remove USE_PANGO define since pango now apears to work properly.
Revision 1.286 2003/09/18 14:06:30 ajgenius
fixed Tgtkobject.drawtext for Pango till the native pango one works better
Revision 1.285 2003/09/18 12:15:01 mattias
fixed is checks for TCustomXXX controls
Revision 1.284 2003/09/18 09:21:03 mattias
renamed LCLLinux to LCLIntf
Revision 1.283 2003/09/17 19:40:46 ajgenius
Initial DoubleBuffering Support for GTK2
Revision 1.282 2003/09/16 11:35:14 mattias
started TDBCheckBox
Revision 1.281 2003/09/15 15:43:04 mattias
fixed gtk2interface package
Revision 1.280 2003/09/11 21:33:11 ajgenius
partly fixed TWinControl(csFixed)
Revision 1.279 2003/09/10 18:03:46 ajgenius
more changes for pango -
partly fixed ref counting,
added Pango versions of TextOut, CreateFontIndirectEx, and GetTextExtentPoint to the GTK2 interface
Revision 1.278 2003/09/09 20:46:38 ajgenius
more implementation toward pango for gtk2
Revision 1.277 2003/09/09 17:16:24 ajgenius
start implementing pango routines for GTK2
Revision 1.276 2003/09/09 04:15:08 ajgenius
more updates for GTK2, more GTK1 wrappers, removal of more ifdef's, partly fixed signals
Revision 1.275 2003/09/06 20:23:53 ajgenius
fixes for gtk2
added more wrappers for gtk1/gtk2 converstion and sanity
removed pointless version $Ifdef GTK2 etc
IDE now "runs" Tcontrol drawing/using problems
renders it unuseable however
Revision 1.274 2003/09/06 17:24:52 ajgenius
gtk2 changes for pixmap, getcursorpos, mouse events workaround
Revision 1.273 2003/09/05 19:29:38 mattias
Success: The first gtk2 application ran without error
Revision 1.272 2003/09/05 18:19:54 ajgenius
Make GTK2 "compile". linking fails still
(Makefile.fpc needs pkgconfig libs/GTK2 linking rules,
but not sure how not sure how) and when linked via a make script
(like gtk2 examples do) apps still won't work(yet). I think we
need to do a lot of work to make sure incompatible(also to get rid
of deprecated) things are done in GTK2 interface itself, and just
use more $Ifdef GTK1 in the gtk interface itself.
Revision 1.271 2003/08/27 08:14:37 mattias
fixed system fonts for win32 intf
Revision 1.270 2003/08/26 08:12:33 mattias
applied listbox/combobox patch from Karl
Revision 1.269 2003/08/18 19:24:18 mattias
fixed TCanvas.Pie
Revision 1.268 2003/08/18 13:21:23 mattias
renamed lazqueue to lazlinkedlist, patch from Jeroen
Revision 1.267 2003/08/16 15:29:56 mattias
fixed TBitmap.GetHandle
Revision 1.266 2003/08/15 14:01:20 mattias
combined lazconf things for unix
Revision 1.265 2003/07/29 00:28:43 marc
+ Implemented GetCursorPos
Revision 1.264 2003/07/21 23:43:32 marc
* Fixed radiogroup menuitems
Revision 1.263 2003/07/20 06:39:03 mattias
added comments
Revision 1.262 2003/07/08 20:09:40 mattias
updated build fpc rpm script
Revision 1.261 2003/07/07 07:59:34 mattias
made Size_SourceIsInterface a flag
Revision 1.260 2003/07/06 20:40:34 mattias
TWinControl.WmSize/Move now updates interface messages smarter
Revision 1.259 2003/07/04 22:06:49 mattias
implemented interface graphics
Revision 1.258 2003/07/04 08:54:53 mattias
implemented 16bit rawimages for gtk
Revision 1.257 2003/07/03 18:10:55 mattias
added fontdialog options to win32 intf from Wojciech Malinowski
Revision 1.256 2003/07/02 15:56:15 mattias
fixed win32 painting and started creating bitmaps from rawimages
Revision 1.255 2003/07/02 10:02:51 mattias
fixed TPaintStruct
Revision 1.254 2003/07/01 13:49:36 mattias
clean up
Revision 1.253 2003/07/01 09:29:51 mattias
attaching menuitems topdown
Revision 1.252 2003/06/30 10:09:46 mattias
fixed Get/SetPixel for DC without widget
Revision 1.251 2003/06/23 09:42:09 mattias
fixes for debugging lazarus
Revision 1.250 2002/08/19 15:15:24 mattias
implemented TPairSplitter
Revision 1.249 2002/08/18 16:50:09 mattias
fixes for debugging
Revision 1.248 2002/08/18 04:57:01 mattias
fixed csDashDot
Revision 1.247 2002/08/17 23:41:35 mattias
many clipping fixes
Revision 1.246 2003/06/20 12:56:53 mattias
reduced paint messages on destroy
Revision 1.245 2003/06/19 09:26:58 mattias
fixed changing unitname during update
Revision 1.244 2003/06/18 11:21:07 mattias
fixed taborder=0, implemented TabOrder Editor
Revision 1.243 2003/06/13 21:08:53 mattias
moved TColorButton to dialogs.pp
Revision 1.242 2003/06/13 10:37:20 mattias
fixed AV on StretchDraw 0x0
Revision 1.241 2003/06/07 13:04:03 mattias
ComboBoxDropDown from Yoyong
Revision 1.240 2003/06/07 09:34:21 mattias
added ambigius compiled unit test for packages
Revision 1.239 2003/06/03 08:02:33 mattias
implemented showing source lines in breakpoints dialog
Revision 1.238 2003/05/20 21:41:07 mattias
started loading/saving breakpoints
Revision 1.237 2003/05/19 08:16:33 mattias
fixed allocation of dc backcolor
Revision 1.236 2003/04/26 10:45:34 mattias
fixed right control release
Revision 1.235 2003/04/16 22:11:35 mattias
fixed codetools Makefile, fixed default prop not found error
Revision 1.234 2003/04/16 17:20:24 mattias
implemented package check broken dependency on compile
Revision 1.233 2003/04/11 21:21:34 mattias
implemented closing unneeded package
Revision 1.232 2003/04/11 17:10:20 mattias
added but not implemented ComboBoxDropDown
Revision 1.231 2003/04/11 09:05:41 mattias
fixed adding items on TComboBox.DropDown
Revision 1.230 2003/04/03 17:42:13 mattias
added exception handling for createpixmapindirect
Revision 1.229 2003/04/02 13:23:24 mattias
fixed default font
Revision 1.228 2003/03/31 20:25:19 mattias
fixed scrollbars of TIpHtmlPanel
Revision 1.227 2003/03/29 23:52:25 mattias
IpHtmlPanel can show simple HTML pages, but there are mem bugs
Revision 1.226 2003/03/29 17:20:05 mattias
added TMemoScrollBar
Revision 1.225 2003/03/28 19:39:54 mattias
started typeinfo for double extended
Revision 1.224 2003/03/26 19:25:27 mattias
added transient deactivation option and updated localization
Revision 1.223 2003/03/26 00:21:25 mattias
implemented build lazarus extra options -d
Revision 1.222 2003/03/25 10:45:41 mattias
reduced focus handling and improved focus setting
Revision 1.221 2003/03/18 13:04:25 mattias
improved focus debugging output
Revision 1.220 2003/03/17 20:53:16 mattias
removed SetRadioButtonGroupMode
Revision 1.219 2003/03/17 20:50:30 mattias
fixed TRadioGroup.ItemIndex=-1
Revision 1.218 2003/03/17 08:51:09 mattias
added IsWindowVisible
Revision 1.217 2003/03/16 09:41:06 mattias
fixed checking menuitems
Revision 1.216 2003/03/12 14:39:29 mattias
fixed clipping origin in stretchblt
Revision 1.215 2003/03/11 08:14:22 mattias
implemented ShowWindow for gtk2
Revision 1.214 2003/03/10 20:10:28 ajgenius
initial changes to fix mask vs. region clipping
Revision 1.213 2003/03/09 21:13:32 mattias
localized gtk interface
Revision 1.212 2003/02/28 19:54:05 mattias
added ShowWindow
Revision 1.211 2003/02/23 10:42:06 mattias
implemented changing TMenuItem.GroupIndex at runtime
Revision 1.210 2003/02/16 01:40:43 mattias
fixed uninitialized style
Revision 1.209 2003/02/04 14:36:19 mattias
fixed set method in OI
Revision 1.208 2003/01/27 13:49:16 mattias
reduced speedbutton invalidates, added TCanvas.Frame
Revision 1.207 2003/01/24 11:58:01 mattias
fixed clipboard waiting and kwrite targets
Revision 1.206 2003/01/06 14:41:24 mattias
fixed synedit mouse pos to logical column
Revision 1.205 2003/01/06 13:59:45 mattias
fixed synedit ensure cursor pos visible with tab chars
Revision 1.204 2003/01/01 12:38:53 mattias
clean ups
Revision 1.203 2003/01/01 10:46:59 mattias
fixes for win32 listbox/combobox from Karl Brandt
Revision 1.202 2002/12/30 17:24:08 mattias
added history to identifier completion
Revision 1.201 2002/12/28 12:42:38 mattias
focus fixes, reduced lpi size
Revision 1.200 2002/12/28 11:29:47 mattias
xmlcfg deletion, focus fixes
Revision 1.199 2002/12/27 17:58:47 mattias
cleanup
Revision 1.198 2002/12/27 17:12:38 mattias
added more Delphi win32 compatibility functions
Revision 1.197 2002/12/27 08:46:32 mattias
changes for fpc 1.1
Revision 1.196 2002/12/26 11:00:15 mattias
added included by to unitinfo and a few win32 functions
Revision 1.195 2002/12/25 13:30:37 mattias
added more windows funcs and fixed jump to compiler error end of file
Revision 1.194 2002/12/22 22:42:55 mattias
custom controls now support child wincontrols
Revision 1.193 2002/12/07 08:42:09 mattias
improved ExtTxtOut: support for char dist array
Revision 1.192 2002/12/05 22:16:33 mattias
double byte char font started
Revision 1.191 2002/12/05 17:26:02 mattias
implemented fsUnderLine for ExtTextOut for gtk
Revision 1.190 2002/11/23 13:48:46 mattias
added Timer patch from Vincent Snijders
Revision 1.189 2002/11/12 10:16:20 lazarus
MG: fixed TMainMenu creation
Revision 1.188 2002/11/09 18:13:36 lazarus
MG: fixed gdkwindow checks
Revision 1.187 2002/11/09 15:02:08 lazarus
MG: fixed LM_LVChangedItem, OnShowHint, small bugs
Revision 1.186 2002/11/03 22:14:44 lazarus
MG: fixed Polygon and not winding
Revision 1.185 2002/11/01 17:55:35 lazarus
AJ: ignore offset in Polygon Winding, Region/FillRect should take care of it
Revision 1.184 2002/11/01 17:26:45 lazarus
MG: fixed GetClipBox
Revision 1.183 2002/11/01 14:40:31 lazarus
MG: fixed mouse coords on scrolling wincontrols
Revision 1.182 2002/10/31 22:14:16 lazarus
MG: fixed GetClipBox when clipping region invalid
Revision 1.181 2002/10/31 21:29:47 lazarus
MG: implemented TControlScrollBar.Size
Revision 1.180 2002/10/31 18:37:30 lazarus
MG: fixed GetClipBox
Revision 1.179 2002/10/31 17:31:11 lazarus
MG: fixed return polygon point
Revision 1.178 2002/10/31 04:27:59 lazarus
AJ: added TShape
Revision 1.177 2002/10/30 17:43:37 lazarus
AJ: added IsNullBrush checks to reduce pointless color allocations & GDK function calls
Revision 1.176 2002/10/29 23:14:28 lazarus
MG: removed interfaces
Revision 1.175 2002/10/29 19:33:42 lazarus
MG: removed interfaces
Revision 1.174 2002/10/29 12:30:45 lazarus
AJ: fixed initial result in clipping/region routines
Revision 1.173 2002/10/28 23:25:36 lazarus
AJ: initialize SelectClipRgn Result
Revision 1.172 2002/10/28 18:17:04 lazarus
MG: impoved focussing, unfocussing on destroy and fixed unit search
Revision 1.171 2002/10/26 12:32:29 lazarus
AJ:Minor fixes for Win32 GTK compiling
Revision 1.170 2002/10/24 20:59:35 lazarus
AJ: fixed typo causing gdk cmap error
Revision 1.169 2002/10/23 20:47:27 lazarus
AJ: Started Form Scrolling
Started StaticText FocusControl
Fixed Misc Dialog Problems
Added TApplication.Title
Revision 1.168 2002/10/21 22:12:49 lazarus
MG: fixed frmactivate
Revision 1.167 2002/10/21 18:21:39 lazarus
AJ:minor styles improvement; fixed drawing checks under all(?) themes
Revision 1.166 2002/10/21 14:40:53 lazarus
MG: fixes for 1.1
Revision 1.165 2002/10/20 21:54:04 lazarus
MG: fixes for 1.1
Revision 1.164 2002/10/20 21:49:11 lazarus
MG: fixes for fpc1.1
Revision 1.163 2002/10/20 19:03:57 lazarus
AJ: minor fixes for FPC 1.1
Revision 1.162 2002/10/18 16:08:10 lazarus
AJ: Partial HintWindow Fix; Added Screen.Font & Font.Name PropEditor; Started to fix ComboBox DropDown size/pos
Revision 1.161 2002/10/17 21:00:18 lazarus
MG: fixed uncapturing of mouse
Revision 1.160 2002/10/17 15:09:33 lazarus
MG: made mouse capturing more strict
Revision 1.159 2002/10/15 22:28:06 lazarus
AJ: added forcelinebreaks
Revision 1.158 2002/10/15 17:09:54 lazarus
AJ: fixed GTK DrawText to use WordWrap, and add DT_EditControl
Revision 1.157 2002/10/15 16:01:38 lazarus
MG: fixed timers
Revision 1.156 2002/10/15 07:01:31 lazarus
MG: fixed timer checking
Revision 1.155 2002/10/14 19:00:50 lazarus
MG: fixed zombie timers
Revision 1.154 2002/10/10 19:43:17 lazarus
MG: accelerated GetTextMetrics
Revision 1.153 2002/10/10 08:51:15 lazarus
MG: added paint messages for some gtk internal widgets
Revision 1.152 2002/10/09 20:08:41 lazarus
Cleanups
Revision 1.151 2002/10/09 10:22:55 lazarus
MG: fixed client origin coordinates
Revision 1.150 2002/10/08 21:51:12 lazarus
MG: fixed Ellipse
Revision 1.149 2002/10/08 14:28:14 lazarus
MG: accelerated FillRect
Revision 1.148 2002/10/08 14:10:03 lazarus
MG: added TDeviceContext.SelectedColors
Revision 1.147 2002/10/08 13:42:26 lazarus
MG: added TDevContextColorType
Revision 1.146 2002/10/08 10:08:47 lazarus
MG: accelerated GDIColor allocating
Revision 1.145 2002/10/07 20:50:59 lazarus
MG: accelerated SelectGDKPenProps
Revision 1.144 2002/10/07 10:55:18 lazarus
MG: accelerated TDynHashArray
Revision 1.143 2002/10/04 22:59:14 lazarus
MG: added OnDrawItem to OI
Revision 1.142 2002/10/04 14:24:17 lazarus
MG: added DrawItem to TComboBox/TListBox
Revision 1.141 2002/10/03 14:47:32 lazarus
MG: added TComboBox.OnPopup+OnCloseUp+ItemWidth
Revision 1.140 2002/10/01 10:05:50 lazarus
MG: changed PDeviceContext into class TDeviceContext
Revision 1.139 2002/09/30 20:19:14 lazarus
MG: fixed flickering of modal forms
Revision 1.138 2002/09/27 20:52:25 lazarus
MWE: Applied patch from "Andrew Johnson" <aj_genius@hotmail.com>
Here is the run down of what it includes -
-Vasily Volchenko's Updated Russian Localizations
-improvements to GTK Styles/SysColors
-initial GTK Palette code - (untested, and for now useless)
-Hint Windows and Modal dialogs now try to stay transient to
the main program form, aka they stay on top of the main form
and usually minimize/maximize with it.
-fixes to Form BorderStyle code(tool windows needed a border)
-fixes DrawFrameControl DFCS_BUTTONPUSH to match Win32 better
when flat
-fixes DrawFrameControl DFCS_BUTTONCHECK to match Win32 better
and to match GTK theme better. It works most of the time now,
but some themes, noteably Default, don't work.
-fixes bug in Bitmap code which broke compiling in NoGDKPixbuf
mode.
-misc other cleanups/ fixes in gtk interface
-speedbutton's should now draw correctly when flat in Win32
-I have included an experimental new CheckBox(disabled by
default) which has initial support for cbGrayed(Tri-State),
and WordWrap, and misc other improvements. It is not done, it
is mostly a quick hack to test DrawFrameControl
DFCS_BUTTONCHECK, however it offers many improvements which
can be seen in cbsCheck/cbsCrissCross (aka non-themed) state.
-fixes Message Dialogs to more accurately determine
button Spacing/Size, and Label Spacing/Size based on current
System font.
-fixes MessageDlgPos, & ShowMessagePos in Dialogs
-adds InputQuery & InputBox to Dialogs
-re-arranges & somewhat re-designs Control Tabbing, it now
partially works - wrapping around doesn't work, and
subcontrols(Panels & Children, etc) don't work. TabOrder now
works to an extent. I am not sure what is wrong with my code,
based on my other tests at least wrapping and TabOrder SHOULD
work properly, but.. Anyone want to try and fix?
-SynEdit(Code Editor) now changes mouse cursor to match
position(aka over scrollbar/gutter vs over text edit)
-adds a TRegion property to Graphics.pp, and Canvas. Once I
figure out how to handle complex regions(aka polygons) data
properly I will add Region functions to the canvas itself
(SetClipRect, intersectClipRect etc.)
-BitBtn now has a Stored flag on Glyph so it doesn't store to
lfm/lrs if Glyph is Empty, or if Glyph is not bkCustom(aka
bkOk, bkCancel, etc.) This should fix most crashes with older
GDKPixbuf libs.
Revision 1.137 2002/09/20 13:11:13 lazarus
MG: fixed TPanel and Frame3D
Revision 1.136 2002/09/19 19:56:17 lazarus
MG: accelerated designer drawings
Revision 1.135 2002/09/19 16:45:54 lazarus
MG: fixed Menu.Free and gdkwindow=nil bug
Revision 1.134 2002/09/18 17:07:29 lazarus
MG: added patch from Andrew
Revision 1.133 2002/09/13 16:58:28 lazarus
MG: removed the 1x1 bitmap from TBitBtn
Revision 1.132 2002/09/13 11:49:48 lazarus
Cleanups, extended TStatusBar, graphic control cleanups.
Revision 1.131 2002/09/12 15:35:57 lazarus
MG: small bugfixes
Revision 1.130 2002/09/12 05:56:17 lazarus
MG: gradient fill, minor issues from Andrew
Revision 1.129 2002/09/12 05:32:14 lazarus
MG: fixed DeleteObject
Revision 1.128 2002/09/10 15:23:22 lazarus
MG: fixed calculation of bitmap size
Revision 1.127 2002/09/10 06:49:22 lazarus
MG: scrollingwincontrol from Andrew
Revision 1.126 2002/09/09 14:01:06 lazarus
MG: improved TScreen and ShowModal
Revision 1.125 2002/09/06 19:45:11 lazarus
Cleanups plus a fix to TPanel parent/drawing problem.
Revision 1.124 2002/09/06 19:11:48 lazarus
MG: fixed scrollbars of TTreeView
Revision 1.123 2002/09/06 16:41:31 lazarus
MG: set SpecialOrigin
Revision 1.122 2002/09/06 16:38:25 lazarus
MG: added GetDCOffset
Revision 1.121 2002/09/06 15:57:36 lazarus
MG: fixed notebook client area, send messages and minor bugs
Revision 1.120 2002/09/06 11:33:36 lazarus
MG: added jitform error messagedlg
Revision 1.119 2002/09/03 08:07:22 lazarus
MG: image support, TScrollBox, and many other things from Andrew
Revision 1.118 2002/09/02 08:13:17 lazarus
MG: fixed GraphicClass.Create
Revision 1.117 2002/08/30 13:43:38 lazarus
MG: fixed drawing of non visual components in designer
Revision 1.116 2002/08/30 12:32:24 lazarus
MG: MoveWindowOrgEx, Splitted FWinControls/FControls, TControl drawing, Better DesignerDrawing, ...
Revision 1.115 2002/08/29 00:07:03 lazarus
MG: fixed TComboBox and InvalidateControl
Revision 1.114 2002/08/28 09:40:50 lazarus
MG: reduced paint messages and DC getting/releasing
Revision 1.113 2002/08/27 18:45:15 lazarus
MG: propedits text improvements from Andrew, uncapturing, improved comobobox
Revision 1.112 2002/08/27 06:40:51 lazarus
MG: ShortCut support for buttons from Andrew
Revision 1.111 2002/08/24 12:55:00 lazarus
MG: fixed mouse capturing, OI edit focus
Revision 1.110 2002/08/24 06:51:24 lazarus
MG: from Andrew: style list fixes, autosize for radio/checkbtns
Revision 1.109 2002/08/22 16:43:36 lazarus
MG: improved theme support from Andrew
Revision 1.108 2002/08/22 16:22:39 lazarus
MG: started debugging of mouse capturing
Revision 1.107 2002/08/22 13:45:58 lazarus
MG: fixed non AutoCheck menuitems and editor bookmark popupmenu
Revision 1.106 2002/08/22 12:25:00 lazarus
MG: fixed mouse events
Revision 1.105 2002/08/22 07:30:16 lazarus
MG: freeing more unused GCs
Revision 1.104 2002/08/21 15:46:08 lazarus
MG: fixed a mem leak in RestoreDC
Revision 1.103 2002/08/21 14:44:18 lazarus
MG: accelerated synedit
Revision 1.102 2002/08/21 14:06:41 lazarus
MG: added TDeviceContextMemManager
Revision 1.101 2002/08/21 13:51:31 lazarus
MG: removed SaveDC and RestoreDC in ExtTextOut
Revision 1.100 2002/08/21 13:35:25 lazarus
MG: accelerations for synedit
Revision 1.99 2002/08/21 11:29:36 lazarus
MG: fixed mem some leaks in ide and gtk
Revision 1.98 2002/08/21 10:46:37 lazarus
MG: fixed unreleased gdiRegions
Revision 1.97 2002/08/21 08:13:38 lazarus
MG: accelerated new/dispose of gdiobjects
Revision 1.96 2002/08/21 07:16:59 lazarus
MG: reduced mem leak of clipping stuff, still not fixed
Revision 1.95 2002/08/19 20:34:48 lazarus
MG: improved Clipping, TextOut, Polygon functions
Revision 1.94 2002/08/17 15:45:34 lazarus
MG: removed ClientRectBugfix defines
Revision 1.93 2002/08/15 15:46:50 lazarus
MG: added changes from Andrew (Clipping)
Revision 1.92 2002/08/15 13:37:58 lazarus
MG: started menuitem icon, checked, radio and groupindex
Revision 1.91 2002/08/13 07:08:24 lazarus
MG: added gdkpixbuf.pp and changes from Andrew Johnson
Revision 1.90 2002/08/08 18:05:47 lazarus
MG: added graphics extensions from Andrew Johnson
Revision 1.89 2002/08/08 17:26:39 lazarus
MG: added property TMenuItems.RightJustify
Revision 1.88 2002/08/08 09:07:07 lazarus
MG: TMenuItem can now be created/destroyed/moved at any time
Revision 1.87 2002/08/07 09:55:30 lazarus
MG: codecompletion now checks for filebreaks, savefile now checks for filedate
Revision 1.86 2002/08/05 10:45:06 lazarus
MG: TMenuItem.Caption can now be set after creation
Revision 1.85 2002/08/05 08:56:57 lazarus
MG: TMenuItems can now be enabled and disabled
Revision 1.84 2002/08/05 07:43:29 lazarus
MG: fixed BadCursor bug and Circle Reference of FixedWidget of csPanel
Revision 1.83 2002/07/23 07:40:52 lazarus
MG: fixed get widget position for inherited gdkwindows
Revision 1.82 2002/07/20 13:47:04 lazarus
MG: fixed eventmask for realized windows
Revision 1.81 2002/07/09 17:18:23 lazarus
MG: fixed parser for external vars
Revision 1.80 2002/06/21 15:41:56 lazarus
MG: moved RectVisible, ExcludeClipRect and IntersectClipRect to interface dependent functions
Revision 1.79 2002/06/19 19:46:10 lazarus
MG: Form Editing: snapping, guidelines, modified on move/resize, creating components in csDesigning, ...
Revision 1.78 2002/06/12 12:35:44 lazarus
MG: fixed apiwidget warnings/criticals
Revision 1.77 2002/06/11 13:41:11 lazarus
MG: fixed mouse coords and fixed mouse clicked thru bug
Revision 1.76 2002/06/05 12:33:58 lazarus
MG: fixed fonts in XLFD format and styles
Revision 1.75 2002/06/04 19:28:17 lazarus
MG: cursor is now inverted and can be used with twilight color scheme
Revision 1.74 2002/06/04 15:17:24 lazarus
MG: improved TFont for XLFD font names
Revision 1.73 2002/06/01 08:41:28 lazarus
MG: DrawFramControl now uses gtk style, transparent STrechBlt
Revision 1.72 2002/05/27 17:58:42 lazarus
MG: added command line help
Revision 1.71 2002/05/24 07:16:34 lazarus
MG: started mouse bugfix and completed Makefile.fpc
Revision 1.70 2002/05/17 10:45:23 lazarus
MG: finddeclaration for stupid things like var a:a;
Revision 1.69 2002/05/16 18:26:08 lazarus
MG: fixed selection painting of non highlighter
Revision 1.68 2002/05/10 06:05:57 lazarus
MG: changed license to LGPL
Revision 1.67 2002/05/09 12:41:30 lazarus
MG: further clientrect bugfixes
Revision 1.66 2002/05/06 08:50:37 lazarus
MG: replaced logo, increased version to 0.8.3a and some clientrectbugfix
Revision 1.65 2002/04/22 13:07:45 lazarus
MG: fixed AdjustClientRect of TGroupBox
Revision 1.64 2002/04/04 12:25:02 lazarus
MG: changed except statements to more verbosity
Revision 1.63 2002/03/31 22:01:38 lazarus
MG: fixed unreleased/unpressed Ctrl/Alt/Shift
Revision 1.62 2002/03/14 20:28:49 lazarus
Bug fix for Mattias.
Fixed spinedit so you can now get the value and set the value.
Shane
Revision 1.61 2002/02/25 16:48:13 lazarus
MG: new IDE window layout system
Revision 1.60 2002/02/03 00:24:01 lazarus
TPanel implemented.
Basic graphic primitives split into GraphType package, so that we can
reference it from interface (GTK, Win32) units.
New Frame3d canvas method that uses native (themed) drawing (GTK only).
New overloaded Canvas.TextRect method.
LCLIntf and Graphics was split, so a bunch of files had to be modified.
Revision 1.59 2002/01/24 15:40:59 lazarus
MG: deactivated clipboard setting target list for win32
Revision 1.58 2002/01/21 14:17:47 lazarus
MG: added find-block-start and renamed find-block-other-end
Revision 1.57 2002/01/08 16:02:45 lazarus
Minor changes to TListView.
Added TImageList to the IDE
Shane
Revision 1.56 2002/01/04 21:07:49 lazarus
MG: added TTreeView
Revision 1.55 2002/01/02 15:24:58 lazarus
MG: added TCanvas.Polygon and TCanvas.Polyline
Revision 1.54 2001/12/28 11:41:51 lazarus
MG: added TCanvas.Ellipse, TCanvas.Pie
Revision 1.53 2001/12/27 16:31:28 lazarus
MG: implemented TCanvas.Arc
Revision 1.52 2001/12/20 14:41:20 lazarus
Fixed setfocus for TComboBox and TMemo
Shane
Revision 1.51 2001/12/12 14:23:18 lazarus
MG: implemented DestroyCaret
Revision 1.50 2001/12/11 16:51:37 lazarus
Modified the Watches dialog
Shane
Revision 1.49 2001/11/14 17:46:59 lazarus
Changes to make toggling between form and unit work.
Added BringWindowToTop
Shane
Revision 1.48 2001/11/12 16:56:08 lazarus
MG: CLIPBOARD
Revision 1.47 2001/11/09 19:14:25 lazarus
HintWindow changes
Shane
Revision 1.46 2001/10/31 16:29:23 lazarus
Fixed the gtk mousemove bug where the control gets the coord's based on it's parent instead of itself.
Shane
Revision 1.45 2001/10/24 00:35:55 lazarus
MG: fixes for fpc 1.1: range check errors
Revision 1.44 2001/10/16 14:19:13 lazarus
MG: added nvidia opengl support and a new opengl example from satan
Revision 1.41 2001/09/30 08:34:52 lazarus
MG: fixed mem leaks and fixed range check errors
Revision 1.40 2001/07/01 23:33:13 lazarus
MG: added WaitMessage and HandleEvents is now non blocking
Revision 1.39 2001/06/26 21:44:32 lazarus
MG: reduced paint messages
Revision 1.37 2001/06/14 23:13:30 lazarus
MWE:
* Fixed some syntax errors for the latest 1.0.5 compiler
Revision 1.36 2001/06/14 14:57:59 lazarus
MG: small bugfixes and less notes
Revision 1.33 2001/04/13 13:22:23 lazarus
Made fix to buttonglyph to use the correct size of single glyph
Made fix to StretchBlt to use the correct height and width
Both of these corrected the Win32 Speedbutton problem MAH
Revision 1.32 2001/04/06 22:25:14 lazarus
* TTimer uses winapi-interface now instead of sendmessage-interface, stoppok
Revision 1.31 2001/03/26 14:58:31 lazarus
MG: setwindowpos + bugfixes
Revision 1.26 2001/03/19 18:51:57 lazarus
MG: added dynhasharray and renamed tsynautocompletion
Revision 1.25 2001/03/19 14:44:22 lazarus
MG: fixed many unreleased DC and GDIObj bugs
Revision 1.22 2001/03/12 12:17:02 lazarus
MG: fixed random function results
Revision 1.21 2001/02/20 16:53:27 lazarus
Changes for wordcompletion and many other things from Mattias.
Shane
Revision 1.20 2001/02/16 19:13:31 lazarus
Added some functions
Shane
Revision 1.19 2001/02/06 18:19:38 lazarus
Shane
Revision 1.18 2001/02/04 04:18:12 lazarus
Code cleanup and JITFOrms bug fix.
Shane
Revision 1.17 2001/02/01 19:34:50 lazarus
TScrollbar created and a lot of code added.
It's cose to working.
Shane
Revision 1.16 2001/01/23 23:33:55 lazarus
MWE:
- Removed old LM_InvalidateRect
- did some cleanup in old code
+ added some comments on gtkobject data (gtkproc)
Revision 1.15 2001/01/23 19:01:10 lazarus
Fixxed bug in RestoreDC
Shane
Revision 1.12 2001/01/12 18:46:50 lazarus
Named the speedbuttons in MAINIDE and took out some writelns.
Shane
Revision 1.11 2001/01/04 16:12:54 lazarus
Removed some writelns and changed the property editor for TStrings a bit.
Shane
Revision 1.10 2001/01/03 18:44:54 lazarus
The Speedbutton now has a numglyphs setting.
I started the TStringPropertyEditor
Revision 1.9 2000/10/09 22:50:33 lazarus
MWE:
* fixed some selection code
+ Added selection sample
Revision 1.8 2000/09/10 23:08:31 lazarus
MWE:
+ Added CreateCompatibeleBitamp function
+ Updated TWinControl.WMPaint
+ Added some checks to avoid gtk/gdk errors
- Removed no fixed warning from GetDC
- Removed some output
Revision 1.7 2000/08/14 12:31:12 lazarus
Minor modifications for SynEdit .
Shane
Revision 1.6 2000/08/11 14:59:09 lazarus
Adding all the Synedit files.
Changed the GDK_KEY_PRESS and GDK_KEY_RELEASE stuff to fix the problem in the editor with the shift key being ignored.
Shane
Revision 1.5 2000/08/10 18:56:24 lazarus
Added some winapi calls.
Most don't have code yet.
SetTextCharacterExtra
CharLowerBuff
IsCharAlphaNumeric
Shane
Revision 1.4 2000/08/07 17:06:39 lazarus
Slight modification to CreateFontIndirect.
I check to see if the GdiObject^.GDIFontObject is nil. If so After the code to retry the weight and slant I added code to retry the Family and Foundry.
Shane
Revision 1.3 2000/07/30 21:48:34 lazarus
MWE:
= Moved ObjectToGTKObject to GTKProc unit
* Fixed array checking in LoadPixmap
= Moved LM_SETENABLED to API func EnableWindow and EnableMenuItem
~ Some cleanup
Revision 1.2 2000/07/23 10:53:41 lazarus
workaround for possible compiler bug (KEYSTATE), stoppok
Revision 1.1 2000/07/13 10:28:30 michael
+ Initial import
Revision 1.17 2000/07/09 20:18:56 lazarus
MWE:
+ added new controlselection
+ some fixes
~ some cleanup
Revision 1.16 2000/06/04 10:00:33 lazarus
MWE:
* Fixed bug #6.
Revision 1.15 2000/05/30 22:28:41 lazarus
MWE:
Applied patches from Vincent Snijders:
+ Added GetWindowRect
* Fixed horz label alignment
+ Added vert label alignment
Revision 1.14 2000/05/14 21:56:12 lazarus
MWE:
+ added local messageloop
+ added PostMessage
* fixed Peekmessage
* fixed ClientToScreen
* fixed Flat style of Speedutton (TODO: Draw)
+ Added TApplicatio.OnIdle
Revision 1.13 2000/05/11 22:04:16 lazarus
MWE:
+ Added messagequeue
* Recoded SendMessage and Peekmessage
+ Added postmessage
+ added DeliverPostMessage
Revision 1.12 2000/05/10 22:52:59 lazarus
MWE:
= Moved some global api stuf to gtkobject
Revision 1.11 2000/05/10 02:32:34 lazarus
Put ERRORs and WARNINGs back to writelns. CAW
Revision 1.10 2000/05/10 01:45:12 lazarus
Replaced writelns with Asserts.
Put ERROR and WARNING messages back to writelns. CAW
Revision 1.9 2000/05/09 18:37:02 lazarus
*** empty log message ***
Revision 1.8 2000/05/08 16:07:32 lazarus
fixed screentoclient and clienttoscreen
Shane
Revision 1.7 2000/05/08 15:56:59 lazarus
MWE:
+ Added support for mwedit92 in Makefiles
* Fixed bug # and #5 (Fillrect)
* Fixed labelsize in ApiWizz
+ Added a call to the resize event in WMWindowPosChanged
Revision 1.6 2000/05/08 12:54:20 lazarus
Removed some writeln's
Added alignment for the TLabel. Isn't working quite right.
Added the shell code for WindowFromPoint and GetParent.
Added FindLCLWindow
Shane
Revision 1.5 2000/05/03 00:27:05 lazarus
MWE:
+ First rollout of the API wizzard.
Revision 1.4 2000/04/10 14:03:07 lazarus
Added SetProp and GetProp winapi calls.
Added ONChange to the TEdit's published property list.
Shane
Revision 1.3 2000/04/07 16:59:55 lazarus
Implemented GETCAPTURE and SETCAPTURE along with RELEASECAPTURE.
Shane
Revision 1.2 2000/03/31 18:41:03 lazarus
Implemented MessageBox / Application.MessageBox calls. No icons yet, though...
Revision 1.1 2000/03/30 22:51:43 lazarus
MWE:
Moved from ../../lcl
Revision 1.62 2000/03/30 21:57:44 lazarus
MWE:
+ Added some general functions to Get/Set the Main/Fixed/CoreChild
widget
+ Started with graphic scalig/depth stuff. This is way from finished
Hans-Joachim Ott <hjott@compuserve.com>:
+ Added some improvements for TMEMO
Revision 1.61 2000/03/30 18:07:54 lazarus
Added some drag and drop code
Added code to change the unit name when it's saved as a different name. Not perfect yet because if you are in a comment it fails.
Shane
Revision 1.60 2000/03/28 22:47:49 lazarus
MWE:
Started with the blt function family
Revision 1.59 2000/03/22 18:49:51 lazarus
Initial work for getting transparent speedbutton glyphs
Shane
Revision 1.58 2000/03/22 17:09:30 lazarus
*** empty log message ***
Revision 1.57 2000/03/19 23:01:43 lazarus
MWE:
= Changed splashscreen loading/colordepth
= Chenged Save/RestoreDC to platform dependent, since they are
relative to a DC
Revision 1.56 2000/03/17 19:19:58 lazarus
Added Hans Ott's code for TMemo
Shane
Revision 1.55 2000/03/17 17:07:00 lazarus
Added images to speedbuttons
Shane
Revision 1.54 2000/03/16 23:58:46 lazarus
MWE:
Added TPixmap for XPM support
Revision 1.53 2000/03/15 20:15:32 lazarus
MOdified TBitmap but couldn't get it to work
Shane
Revision 1.52 2000/03/15 01:09:59 lazarus
MWE:
+ Removed comment on LM_IMAGECHANGED in TgtkObject.IntSendMessage3
it does compile (compiler hickup ?)
Revision 1.51 2000/03/15 00:51:58 lazarus
MWE:
+ Added LM_Paint on expose
+ Added forced creation of gdkwindow if needed
~ Modified DrawFrameControl
+ Added BF_ADJUST support on DrawEdge
- Commented out LM_IMAGECHANGED in TgtkObject.IntSendMessage3
(It did not compile)
Revision 1.50 2000/03/14 21:18:23 lazarus
Added the ability to click on the speedbuttons
Shane
Revision 1.48 2000/03/10 18:31:10 lazarus
Added TSpeedbutton code
Shane
Revision 1.47 2000/03/09 23:47:58 lazarus
MWE:
* Fixed colorcache
* Fixed black window in new editor
~ Did some cosmetic stuff
From Peter Dyson <peter@skel.demon.co.uk>:
+ Added Rect api support functions
+ Added the start of ScrollWindowEx
Revision 1.46 2000/03/08 23:57:38 lazarus
MWE:
Added SetSysColors
Fixed TEdit text bug (thanks to hans-joachim ott <hjott@compuserve.com>)
Finished GetKeyState
Added changes from Peter Dyson <peter@skel.demon.co.uk>
- a new GetSysColor
- some improvements on ExTextOut
Revision 1.45 2000/03/07 16:52:58 lazarus
Fixxed a problem with the main.pp unit determining a new files FORM name.
Shane
Revision 1.44 2000/03/06 00:05:05 lazarus
MWE: Added changes from Peter Dyson <peter@skel.demon.co.uk> for a new
release of mwEdit (0.92)
Revision 1.43 2000/03/03 22:58:26 lazarus
MWE:
Fixed focussing problem.
LM-FOCUS was bound to the wrong signal
Added GetKeyState api func.
Now LCL knows if shift/trl/alt is pressed (might be handy for keyboard
selections ;-)
Revision 1.42 2000/02/26 23:31:50 lazarus
MWE:
Fixed notebook crash on insert
Fixed loadfont problem for win32 (tleast now a fontname is required)
Revision 1.41 2000/02/22 23:26:13 lazarus
MWE: Fixed cursor movement in editor
Started on focus problem
Revision 1.40 2000/02/22 21:51:40 lazarus
MWE: Removed some double (or triple) event declarations.
The latest compiler doesn't like it
Revision 1.39 2000/02/18 19:38:53 lazarus
Implemented TCustomForm.Position
Better implemented border styles. Still needs some tweaks.
Changed TComboBox and TListBox to work again, at least partially.
Minor cleanups.
Revision 1.38 2000/01/31 20:00:21 lazarus
Added code for Application.ProcessMessages. Needs work.
Added TScreen.Width and TScreen.Height. Added the code into
GetSystemMetrics for these two properties.
Shane
Revision 1.37 2000/01/26 19:16:24 lazarus
Implemented TPen.Style properly for GTK. Done SelectObject for pen objects.
Misc bug fixes.
Corrected GDK declaration for gdk_gc_set_slashes.
Revision 1.36 2000/01/25 23:51:14 lazarus
MWE:
Added more Caret functionality.
Removed old ifdef stuff from the editor
Revision 1.35 2000/01/25 22:04:27 lazarus
MWE:
The first primitive Caret functions are getting visible
Revision 1.34 2000/01/25 00:38:25 lazarus
MWE:
Added GetFocus
Revision 1.33 2000/01/22 20:07:47 lazarus
Some cleanups. It needs much more cleanup than this.
Worked around a compiler bug (?) in mwCustomEdit.
Reverted some changes to font generation and increased font size.
Revision 1.32 2000/01/18 22:18:35 lazarus
Moved bitmap creation into appropriate place. Cleaned up a bit.
Finished DeleteObject procedure.
Revision 1.31 2000/01/18 21:47:00 lazarus
Added OffSetRec
Revision 1.30 2000/01/17 23:33:08 lazarus
MWE:
fixed: nil pointer reference in DeleteObject
fixed: some trace info didn't start with 'trace:'
Revision 1.29 2000/01/17 20:36:25 lazarus
Fixed Makefile again.
Made implementation of TScreen and screen info saner.
Began to implemented DeleteObject in GTKWinAPI.
Fixed a bug in GDI allocation which in turn fixed A LOT of other bugs :-)
Revision 1.28 2000/01/16 23:23:07 lazarus
MWE:
Added/completed scrollbar API funcs
Revision 1.27 2000/01/14 21:47:04 lazarus
Commented out SHOWCARET. Not sure how to implement yet. Seems like I may need to draw it myself and therefore will need to create a timer and draw a line, then copy the pixmap over the line to erase it.......not sure yet.
Shane
Revision 1.26 2000/01/13 22:44:05 lazarus
MWE:
Created/updated net gtkwidget for TWinControl decendants
also improved foccusing on such a control
Revision 1.25 2000/01/12 22:13:07 lazarus
Modified ShowCaret. Still not working.
Shane
Revision 1.24 2000/01/11 20:50:32 lazarus
Added some code for SETCURSOR. Doesn't work perfect yet but getting there.
Shane
Revision 1.22 2000/01/10 21:24:12 lazarus
Minor cleanup and changes.
Revision 1.21 2000/01/07 21:14:13 lazarus
Added code for getwindowlong and setwindowlong.
Shane
Revision 1.20 1999/12/21 21:35:54 lazarus
committed the latest toolbar code. Currently it doesn't appear anywhere and I have to get it to add buttons correctly through (I think) setstyle. I think I'll implement the LM_TOOLBARINSERTBUTTON call there.
Shane
Revision 1.19 1999/12/21 00:37:19 lazarus
MWE:
Fixed SetTextColor
Revision 1.18 1999/12/21 00:07:06 lazarus
MWE:
Some fixes
Completed a bit of DraWEdge
Revision 1.17 1999/12/20 21:01:13 lazarus
Added a few things for compatability with Delphi and TToolbar
Shane
Revision 1.16 1999/12/18 18:27:32 lazarus
MWE:
Rearranged some events to get a LM_SIZE, LM_MOVE and LM_WINDOWPOSCHANGED
Initialized the TextMetricstruct to zeros to clear unset values
Get mwEdit to show more than one line
Fixed some errors in earlier commits
Revision 1.15 1999/12/14 21:07:12 lazarus
Added more stuff for TToolbar
Shane
Revision 1.14 1999/12/14 01:08:56 lazarus
MWE:
Started GetTextMetrics
Revision 1.13 1999/12/14 00:16:43 lazarus
MWE:
Renamed LM... message handlers to WM... to be compatible and to
get more edit parts to compile
Started to implement GetSystemMetrics
Removed some Lazarus specific parts from mwEdit
Revision 1.12 1999/12/06 20:41:14 lazarus
Miinor debugging changes.
Shane
Revision 1.11 1999/12/03 00:26:47 lazarus
MWE:
fixed control location
added gdiobject reference counter
Revision 1.10 1999/12/02 19:00:59 lazarus
MWE:
Added (GDI)Pen
Changed (GDI)Brush
Changed (GDI)Font (color)
Changed Canvas to use/create pen/brush/font
Hacked mwedit to allow setting the number of chars (till it get a WM/LM_SIZE event)
The editor shows a line !
Revision 1.9 1999/11/29 00:46:47 lazarus
MWE:
Added TBrush as gdiobject
commented out some more mwedit MWE_FPC ifdefs
Revision 1.8 1999/11/25 23:45:08 lazarus
MWE:
Added font as GDIobject
Added some API testcode to testform
Commented out some more IFDEFs in mwCustomEdit
Revision 1.7 1999/11/19 01:09:43 lazarus
MWE:
implemented TCanvas.CopyRect
Added StretchBlt
Enabled creation of TCustomControl.Canvas
Added a temp hack in TWinControl.Repaint to get a LM_PAINT
Revision 1.6 1999/11/18 00:13:08 lazarus
MWE:
Partly Implemented SelectObject
Added ExTextOut
Added GetTextExtentPoint
Added TCanvas.TextExtent/TextWidth/TextHeight
Added TSize and HPEN
Revision 1.5 1999/11/17 01:16:40 lazarus
MWE:
Added some more API stuff
Added an initial TBitmapCanvas
Added some DC stuff
Changed and commented out, original gtk linedraw/rectangle code. This
is now called through the winapi wrapper.
Revision 1.4 1999/11/16 01:32:22 lazarus
MWE:
Added some more DC functionality
}