34
34
Windows, // needed for keyboard handling
39
SysUtils, Classes, FPCAdds,
41
XAtom, X, XLib, XUtil, //Font retrieval and Keyboard handling
42
X, XLib, // Font retrieval and Keyboard handling
50
51
Math, // Math after gtk to get the correct Float type
51
LMessages, LCLProc, LCLStrConsts, LCLIntf, LCLType, DynHashArray, Maps, Masks,
52
GraphType, GraphMath, Graphics, LResources, Controls, Forms,
52
LMessages, LCLProc, LCLIntf, LCLType, DynHashArray, Masks,
53
GraphType, Graphics, LResources, Controls, Forms,
53
54
Buttons, Menus, StdCtrls, ComCtrls, ExtCtrls, Dialogs, ExtDlgs,
54
FileUtil, ImgList, Gtk2FontCache, Gtk2Globals, Gtk2Def, Gtk2Extra, Gtk2Debug,
55
FileUtil, ImgList, Gtk2FontCache, Gtk2Globals, Gtk2Def, Gtk2Extra, {%H-}Gtk2Debug,
89
90
GTKAPIWidget_Type: GType = 0;
91
92
// GTKCallback.inc headers
92
procedure EventTrace(const TheMessage: string; data: pointer);
93
procedure EventTrace(const {%H-}TheMessage: string; {%H-}data: pointer);
93
94
function gtkNoteBookCloseBtnClicked(Widget: PGtkWidget;
94
95
Data: Pointer): GBoolean; cdecl;
95
96
function gtkRealizeCB(Widget: PGtkWidget; Data: Pointer): GBoolean; cdecl;
101
102
function gtkchanged_editbox( widget: PGtkWidget; data: gPointer): GBoolean; cdecl;
102
103
function gtkchanged_spinbox(widget: PGtkWidget; data: gPointer): GBoolean; cdecl;
103
104
function gtkchanged_editbox_backspace( widget: PGtkWidget;
104
data: gPointer): GBoolean; cdecl;
105
{%H-}data: gPointer): GBoolean; cdecl;
105
106
function gtkchanged_editbox_delete(widget: PGtkWidget;
106
AType: TGtkDeleteType; APos: gint; data: gPointer): GBoolean; cdecl;
107
{%H-}AType: TGtkDeleteType; {%H-}APos: gint; {%H-}data: gPointer): GBoolean; cdecl;
107
108
function gtkdaychanged(Widget: PGtkWidget; data: gPointer): GBoolean; cdecl;
108
109
function gtktoggledCB( widget: PGtkWidget; data: gPointer): GBoolean; cdecl;
129
130
function GTKFocusCB(widget: PGtkWidget; event:PGdkEventFocus;
130
131
data: gPointer): GBoolean; cdecl;
131
132
function GTKKillFocusCB(widget: PGtkWidget; event:PGdkEventFocus;
132
data: gPointer): GBoolean; cdecl;
133
{%H-}data: gPointer): GBoolean; cdecl;
133
134
function GTKKillFocusCBAfter(widget: PGtkWidget; event:PGdkEventFocus;
134
135
data: gPointer): GBoolean; cdecl;
135
136
function gtkdestroyCB(widget: PGtkWidget; data: gPointer): GBoolean; cdecl;
136
procedure DestroyWindowFromPointCB(Widget: PGtkWidget; data: gPointer); cdecl;
137
procedure DestroyWindowFromPointCB(Widget: PGtkWidget; {%H-}data: gPointer); cdecl;
137
138
function gtkdeleteCB(widget: PGtkWidget; event: PGdkEvent;
138
139
data: gPointer): GBoolean; cdecl;
139
function gtkresizeCB(widget: PGtkWidget; data: gPointer): GBoolean; cdecl;
140
function gtkresizeCB(widget: PGtkWidget; {%H-}data: gPointer): GBoolean; cdecl;
140
141
function gtkMonthChanged(Widget: PGtkWidget; data: gPointer): GBoolean; cdecl;
141
procedure DeliverMouseMoveMessage(Widget:PGTKWidget; Event: PGDKEventMotion;
142
procedure DeliverMouseMoveMessage({%H-}Widget:PGTKWidget; Event: PGDKEventMotion;
142
143
AWinControl: TWinControl);
143
function ControlGetsMouseMoveBefore(AControl: TControl): boolean;
144
145
function gtkMotionNotify(Widget:PGTKWidget; Event: PGDKEventMotion;
145
146
Data: gPointer): GBoolean; cdecl;
146
147
function GTKMotionNotifyAfter(widget:PGTKWidget; event: PGDKEventMotion;
147
148
data: gPointer): GBoolean; cdecl;
148
function ControlGetsMouseDownBefore(AControl: TControl;
149
AWidget: PGtkWidget): boolean;
150
procedure DeliverMouseDownMessage(widget: PGtkWidget; event: pgdkEventButton;
151
AWinControl: TWinControl);
153
function gtk2ScrollBarMouseBtnPress(widget: PGtkWidget; event: pgdkEventButton;
154
data: gPointer): GBoolean; cdecl;
156
function gtk2ScrollBarMouseBtnRelease(widget: PGtkWidget; event: pgdkEventButton;
157
data: gPointer): GBoolean; cdecl;
150
function DeliverMouseDownMessage({%H-}widget: PGtkWidget; event: pgdkEventButton;
151
AWinControl: TWinControl): PtrInt;
153
function gtk2ScrollBarMouseBtnPress({%H-}widget: PGtkWidget; {%H-}event: pgdkEventButton;
154
{%H-}data: gPointer): GBoolean; cdecl;
156
function gtk2ScrollBarMouseBtnRelease({%H-}widget: PGtkWidget; {%H-}event: pgdkEventButton;
157
{%H-}data: gPointer): GBoolean; cdecl;
160
160
function gtkMouseBtnPress(widget: PGtkWidget; event: pgdkEventButton;
173
173
function gtkEnterCB(widget: PGtkWidget; data: gPointer): GBoolean; cdecl;
174
174
function gtkLeaveCB(widget: PGtkWidget; data: gPointer): GBoolean; cdecl;
175
function gtksize_allocateCB(widget: PGtkWidget; size :pGtkAllocation;
175
function gtksize_allocateCB(widget: PGtkWidget; {%H-}size :pGtkAllocation;
176
176
data: gPointer): GBoolean; cdecl;
177
177
function gtksize_allocate_client(widget: PGtkWidget; size :pGtkAllocation;
178
178
data: gPointer): GBoolean; cdecl;
191
191
function gtkCutToClip( widget: PGtkWidget; data: gPointer): GBoolean; cdecl;
192
192
function gtkCopyToClip( widget: PGtkWidget; data: gPointer): GBoolean; cdecl;
193
193
function gtkPasteFromClip( widget: PGtkWidget; data: gPointer): GBoolean; cdecl;
194
function gtkValueChanged(widget: PGtkWidget; data: gPointer): GBoolean; cdecl;
194
function gtkValueChanged({%H-}widget: PGtkWidget; data: gPointer): GBoolean; cdecl;
195
195
function gtkTimerCB(Data: gPointer): gBoolean; cdecl;
196
196
function gtkFocusInNotifyCB (widget: PGtkWidget; event: PGdkEvent;
197
197
data: gpointer): GBoolean; cdecl;
207
207
function Gtk2RangeScrollCB(ARange: PGtkRange; AScrollType: TGtkScrollType;
208
208
AValue: gdouble; AWidgetInfo: PWidgetInfo): gboolean; cdecl;
209
function Gtk2RangeScrollPressCB(Widget: PGtkWidget;
210
{%H-}Event: PGdkEventButton; {%H-}Data: gPointer): gboolean; cdecl;
211
function Gtk2RangeScrollReleaseCB(Widget: PGtkWidget;
212
{%H-}Event: PGdkEventButton; {%H-}Data: gPointer): gboolean; cdecl;
213
function Gtk2RangeUbuntuScrollCB(Adjustment: PGTKAdjustment; data: GPointer): GBoolean; cdecl;
215
function Gtk2ScrolledWindowScrollCB(AScrollWindow: PGtkScrolledWindow;
216
AEvent: PGdkEventScroll; AWidgetInfo: PWidgetInfo): gboolean; cdecl;
210
217
function GTKCheckMenuToggeledCB(AMenuItem: PGTKCheckMenuItem;
211
218
AData: gPointer): GBoolean; cdecl;
212
function GTKKeySnooper(Widget: PGtkWidget; Event: PGdkEventKey;
219
function GTKKeySnooper({%H-}Widget: PGtkWidget; Event: PGdkEventKey;
213
220
FuncData: gPointer): gInt; cdecl;
214
221
function gtkYearChanged(Widget: PGtkWidget; data: gPointer): GBoolean; cdecl;
215
procedure GtkDragDataReceived(widget:PGtkWidget; context:PGdkDragContext;
216
x:gint; y:gint; selection_data:PGtkSelectionData; info:guint; time:guint; Data: gPointer);cdecl;
222
procedure GtkDragDataReceived({%H-}widget:PGtkWidget; context:PGdkDragContext;
223
{%H-}x:gint; {%H-}y:gint; selection_data:PGtkSelectionData; {%H-}info:guint; time:guint; Data: gPointer);cdecl;
230
237
function gtkListBoxSelectionChangedAfter(widget: PGtkWidget;
231
238
data: gPointer): GBoolean; cdecl;
233
// gtkDragCallback.inc headers
234
241
function edit_drag_data_received(widget: pgtkWidget;
235
242
Context: pGdkDragContext;
249
256
context: pGdkDragContext;
250
257
data: gpointer): gBoolean ; cdecl;
252
// gtkcomboboxcallbacks.inc headers
259
// combobox callbacks
253
260
function gtkComboBoxShowAfter(widget: PGtkWidget; data: gPointer): GBoolean; cdecl;
254
261
function gtkComboBoxHideAfter(widget: PGtkWidget; data: gPointer): GBoolean; cdecl;
256
// gtkpagecallbacks.inc headers
263
// notebook callbacks
257
264
function PageIconWidgetExposeAfter(Widget: PGtkWidget; Event: PGDKEventExpose;
258
265
Data: gPointer): GBoolean; cdecl;
275
282
function GdkRectFromRect(R: TRect): TGdkRectangle;
276
283
function AlignToGtkAlign(Align: TAlignment): gfloat;
277
284
function GtkScrollTypeToScrollCode(ScrollType: TGtkScrollType): LongWord;
285
function Gtk2TranslateScrollStyle(const SS:TScrollStyle):TPoint;
280
288
function GtkWidgetIsA(Widget: PGtkWidget; AType: TGtkType): boolean;
335
343
procedure SetLCLObject(const Widget: Pointer; const AnObject: TObject);
336
344
function GetLCLObject(const Widget: Pointer): TObject;
337
345
function GetNearestLCLObject(Widget: PGtkWidget): TObject;
338
procedure SetHiddenLCLObject(const Widget: Pointer; const AnObject: TObject);
339
function GetHiddenLCLObject(const Widget: Pointer): TObject;
340
346
function GetWinControlWidget(Child: PGtkWidget): PGtkWidget;
341
347
function GetWinControlFixedWidget(Child: PGtkWidget): PGtkWidget;
342
348
function FindFixedChildListItem(ParentFixed: PGtkFixed; Child: PGtkWidget): PGList;
354
360
procedure SetGtkWindowShowInTaskbar(AGtkWindow: PGtkWindow; Value: boolean);
355
361
procedure SetWindowFullScreen(AForm: TCustomForm; const AValue: Boolean);
356
362
procedure GrabKeyBoardToForm(AForm: TCustomForm);
357
procedure ReleaseKeyBoardFromForm(AForm: TCustomForm);
363
procedure ReleaseKeyBoardFromForm({%H-}AForm: TCustomForm);
358
364
procedure GrabMouseToForm(AForm: TCustomForm);
359
procedure ReleaseMouseFromForm(AForm: TCustomForm);
365
procedure ReleaseMouseFromForm({%H-}AForm: TCustomForm);
360
366
procedure GtkWindowShowModal(AForm: TCustomForm; GtkWindow: PGtkWindow);
379
385
procedure FreeGDIColor(GDIColor: PGDIColor);
380
procedure AllocGDIColor(DC: hDC; GDIColor: PGDIColor);
386
procedure AllocGDIColor({%H-}DC: hDC; GDIColor: PGDIColor);
381
387
procedure BuildColorRefFromGDKColor(var GDIColor: TGDIColor);
382
388
procedure SetGDIColorRef(var GDIColor: TGDIColor; NewColorRef: TColorRef);
383
389
procedure EnsureGCColor(DC: hDC; ColorType: TDevContextsColorType;
384
390
IsSolidBrush, AsBackground: Boolean);
385
391
procedure CopyGDIColor(var SourceGDIColor, DestGDIColor: TGDIColor);
386
function AllocGDKColor(const AColor: LongInt): TGDKColor;
392
function AllocGDKColor(const AColor: TColorRef): TGDKColor;
387
393
function TGDKColorToTColor(const value: TGDKColor): TColor;
388
394
function TColortoTGDKColor(const value: TColor): TGDKColor;
389
395
procedure UpdateSysColorMap(Widget: PGtkWidget; Lgs: TLazGtkStyle);
392
398
procedure RealizeGDKColor(ColorMap: PGdkColormap; Color: PGDKColor);
393
399
procedure RealizeGtkStyleColor(Style: PGTKStyle; Color: PGDKColor);
394
function GetSysGCValues(Color: TColorRef; ThemeWidget: PGtkWidget): TGDKGCValues;
400
function GetSysGCValues(Color: TColorRef; {%H-}ThemeWidget: PGtkWidget): TGDKGCValues;
396
402
function GDKPixel2GDIRGB(Pixel: Longint; Visual: PGDKVisual;
397
403
Colormap: PGDKColormap): TGDIRGB;
453
460
function GetGtkNoteBookPageCount(ANoteBookWidget: PGtkNoteBook): integer;
454
461
procedure RemoveDummyNoteBookPage(NoteBookWidget: PGtkNotebook);
455
462
procedure UpdateNotebookPageTab(ANoteBook, APage: TObject);
463
procedure UpdateNotebookTabFont(APage: TWinControl; AFont: TFont);
457
465
// coordinate transformation
458
466
function GetWidgetOrigin(TheWidget: PGtkWidget): TPoint;
459
467
function GetWidgetClientOrigin(TheWidget: PGtkWidget): TPoint;
468
function GetWidgetClientRect(TheWidget: PGtkWidget): TRect;
460
469
function TranslateGdkPointToClientArea(SourceWindow: PGdkWindow;
461
470
SourcePos: TPoint; DestinationWidget: PGtkWidget): TPoint;
462
471
function SubtractScoll(AWidget: PGtkWidget; APosition: TPoint): TPoint;
464
473
// mouse capturing
465
{$IFDEF GTK2_USE_OLD_CAPTURE}
466
procedure CaptureMouseForWidget(Widget: PGtkWidget; Owner: TMouseCaptureType);
468
474
function GetDefaultMouseCaptureWidget(Widget: PGtkWidget): PGtkWidget;
469
475
procedure ReleaseMouseCapture;
470
476
procedure ReleaseCaptureWidget(Widget : PGtkWidget);
471
procedure UpdateMouseCaptureControl;
613
618
procedure MergeClipping(DestinationDC: TGtkDeviceContext; DestinationGC: PGDKGC;
614
619
X,Y,Width,Height: integer; ClipMergeMask: PGdkBitmap;
615
620
ClipMergeMaskX, ClipMergeMaskY: integer;
616
var NewClipMask: PGdkBitmap);
621
out NewClipMask: PGdkBitmap);
617
622
function CreatePixbufFromImageAndMask(ASrc: PGdkDrawable; ASrcX, ASrcY, ASrcWidth,
618
623
ASrcHeight: integer; ASrcColorMap: PGdkColormap; ASrcMask: PGdkBitmap): PGdkPixbuf;
619
function ScalePixmapAndMask(AScaleGC: PGDKGC; AScaleMethod: TGdkInterpType;
624
function ScalePixmapAndMask({%H-}AScaleGC: PGDKGC; AScaleMethod: TGdkInterpType;
620
625
ASrc: PGdkPixmap; ASrcX, ASrcY, ASrcWidth, ASrcHeight: integer;
621
626
ASrcColorMap: PGdkColormap; ASrcMask: PGdkBitmap;
622
627
ADstWidth, ADstHeight: Integer; FlipHorz, FlipVert: Boolean;
635
640
function CHECK_MENU_ITEM_CLASS(widget: PGtkWidget): PGtkCheckMenuItemClass;
636
641
procedure LockRadioGroupOnChange(RadioGroup: PGSList; const ADelta: Integer);
637
642
procedure UpdateRadioGroupChecks(RadioGroup: PGSList);
638
procedure UpdateInnerMenuItem(LCLMenuItem: TMenuItem;
639
MenuItemWidget: PGtkWidget);
640
procedure UpdateInnerMenuItem(LCLMenuItem: TMenuItem;
641
MenuItemWidget: PGtkWidget; NewShortCut: TShortCut);
643
procedure UpdateInnerMenuItem(LCLMenuItem: TMenuItem; MenuItemWidget: PGtkWidget);
644
procedure UpdateInnerMenuItem(LCLMenuItem: TMenuItem; MenuItemWidget: PGtkWidget;
645
NewShortCut, ShortCutKey2: TShortCut);
644
function CreateStatusBarPanel(StatusBar: TObject; Index: integer): PGtkWidget;
648
function CreateStatusBarPanel({%H-}StatusBar: TObject; {%H-}Index: integer): PGtkWidget;
645
649
procedure UpdateStatusBarPanels(StatusBar: TObject;
646
650
StatusBarWidget: PGtkWidget);
647
651
procedure UpdateStatusBarPanel(StatusBar: TObject; Index: integer;
656
660
procedure SendSizeNotificationToLCL(aWidget: PGtkWidget);
657
661
function CreateTopologicalSortedWidgets(HashArray: TDynHashArray): TFPList;
658
662
procedure GetGTKDefaultWidgetSize(AWinControl: TWinControl;
659
var PreferredWidth, PreferredHeight: integer; WithThemeSpace: Boolean);
663
var PreferredWidth, PreferredHeight: integer; {%H-}WithThemeSpace: Boolean);
660
664
procedure SendCachedGtkResizeNotifications;
661
665
procedure ResizeHandle(LCLControl: TWinControl);
662
666
procedure SetWidgetSizeAndPosition(LCLControl: TWinControl);// for child controls
663
667
procedure SetWindowSizeAndPosition(Window: PGtkWindow; AWinControl: TWinControl);// for top level control
664
procedure GetWidgetRelativePosition(aWidget: PGtkWidget; var Left, Top: integer);
668
procedure GetWidgetRelativePosition(aWidget: PGtkWidget; out Left, Top: integer);
665
669
procedure UnsetResizeRequest(Widget: PGtkWidget);
666
670
procedure SetResizeRequest(Widget: PGtkWidget);
667
671
function WidgetSizeIsEditable(Widget: PGtkWidget): boolean;
681
685
function GdkAtomToStr(const Atom: TGdkAtom): string;
684
function CreateFormContents(AForm: TCustomForm;
688
function CreateFormContents({%H-}AForm: TCustomForm;
685
689
var FormWidget: Pointer; AWidgetInfo: PWidgetInfo = nil): Pointer;
689
693
PStyleObject = ^TStyleObject;
690
694
TStyleObject = Record
692
695
Style: PGTKStyle;
696
Owner: PGtkWidget; // The widget that we hold a reference to.
697
Widget: PGTKWidget; // This is the style widget.
694
698
FrameBordersValid: boolean;
695
699
FrameBorders: TRect;
713
717
function GetStyleFormFrameBorders(WithMenu: boolean): TRect;
715
719
procedure StyleFillRectangle(drawable: PGDKDrawable; GC: PGDKGC;
716
Color: TColorRef; x, y, width, height: gint);
720
Color: TColorRef; x, y, width, height: gint;
721
AClipArea: PGdkRectangle);
717
722
function StyleForegroundColor(Color: TColorRef; DefaultColor: PGDKColor): PGDKColor;
718
723
procedure UpdateWidgetStyleOfControl(AWinControl: TWinControl);
728
733
Str: PChar; StrLength: integer;
729
734
lbearing, rbearing, width, ascent, descent: Pgint);
730
735
function GetDefaultFontName: string;
736
{$IFDEF GTK2OLDENUMFONTFAMILIES}
731
737
procedure FillScreenFonts(ScreenFonts: TStrings);
732
739
function GetTextHeight(DCTextMetric: TDevContextTextMetric): integer;
734
function XGetWorkarea(var ax,ay,awidth,aheight:gint): gint;
741
function XGetWorkarea(out ax,ay,awidth,aheight:gint): gint;
783
790
state: PGdkEventWindowState;
784
791
data: gpointer): gboolean; cdecl;
786
function gtkMouseWheelCB(widget: PGtkWidget; event: PGdkEventScroll;
793
function gtkMouseWheelCB({%H-}widget: PGtkWidget; event: PGdkEventScroll;
787
794
data: gPointer): GBoolean; cdecl;
788
795
procedure GTKStyleChangedAfter(Widget: PGtkWidget; previous_style : PGTKStyle;
789
796
Data: Pointer); cdecl;
791
{ Miscelaneus Widget functions }
793
function WidgetGetSelStart(const Widget: PGtkWidget): integer;
794
procedure WidgetSetSelLength(const Widget: PGtkWidget; NewLength: integer);
799
801
{$IFDEF StaticXinerama} Xinerama, {$ENDIF}
800
dynlibs, Gtk2WSPrivate, URIParser, Gtk2Int, Gtk2WinApiWindow;
802
Gtk2WSPrivate, URIParser, Gtk2Int, Gtk2WinApiWindow;
803
805
KCINFO_FLAG_SHIFT = $01;
804
KCINFO_FLAG_CTRL = $02;
806
//KCINFO_FLAG_CTRL = $02;
805
807
KCINFO_FLAG_ALTGR = $04;
806
KCINFO_FLAG_KEY_MASK = $07;
808
//KCINFO_FLAG_KEY_MASK = $07;
807
809
KCINFO_FLAG_EXT = $10; // extended key
808
KCINFO_FLAG_TOGGLE = $20; // toggle key
810
//KCINFO_FLAG_TOGGLE = $20; // toggle key
810
812
KCINFO_FLAG_SHIFT_XOR_NUM = $40; // second vkey should be used when numlock <>shift
811
KCINFO_FLAG_MULTI_MASK = $C0; // key has more than one VK
813
//KCINFO_FLAG_MULTI_MASK = $C0; // key has more than one VK
815
PKeyCodeInfo = ^TKeyCodeInfo;
816
817
TKeyCodeInfo = record
818
819
VKey2: Byte; // second code to be used depending on the type of MULTI_VK flag
917
918
if (AComponent<>nil) and (AComponent.Name<>'') then
918
919
RCName:=AComponent.Name+'_'+RCName;
920
gtk_widget_set_name(AWidget,PChar(RCName));
921
// do not set widget name issue #21661
922
// gtk_widget_set_name(AWidget,PChar(RCName));
921
923
//debugln('Set_RC_Name ',GetWidgetDebugReport(AWidget),' RCName="',RCName,'"');
922
924
gtk_widget_set_rc_style(AWidget);
934
936
// fill initial modifier list
935
937
FillByte(MModifiers, SizeOf(MModifiers), 0);
939
{$ifndef UseOwnShiftState}
937
940
MModifiers[ssCaps].Mask := GDK_LOCK_MASK;
938
941
MModifiers[ssNum].Mask := GDK_MOD3_MASK; //todo: check this I've 2 here,but 3 was the original code
939
942
MModifiers[ssScroll].Mask := GDK_MOD5_MASK; //todo: check this I've ssAltGr here, but ssScroll was the original code
940
{$ifndef UseOwnShiftState}
941
943
MModifiers[ssShift].Mask := GDK_SHIFT_MASK;
942
944
MModifiers[ssCtrl].Mask := GDK_CONTROL_MASK;
943
945
MModifiers[ssAlt].Mask := GDK_MOD1_MASK;
976
978
{$I gtk2proc.inc}
977
979
{$I gtk2callback.inc}
979
{ Miscelaneus Widget functions }
981
function WidgetGetSelStart(const Widget: PGtkWidget): integer;
983
if Widget <> nil then
985
if PGtkOldEditable(Widget)^.selection_start_pos
986
< PGtkOldEditable(Widget)^.selection_end_pos
988
Result:= PGtkOldEditable(Widget)^.selection_start_pos
990
Result:= PGtkOldEditable(Widget)^.current_pos;// selection_end_pos
995
procedure WidgetSetSelLength(const Widget: PGtkWidget; NewLength: integer);
999
gtk_editable_select_region(PGtkOldEditable(Widget),
1000
gtk_editable_get_position(PGtkOldEditable(Widget)),
1001
gtk_editable_get_position(PGtkOldEditable(Widget)) + NewLength);