1{ 2 ---------------------------------- 3 gtk2proc.pp - gtk 2 interface procs 4 ---------------------------------- 5 6 This unit contains procedures/functions needed for the gtk 2 <-> LCL interface 7} 8{ 9 ***************************************************************************** 10 This file is part of the Lazarus Component Library (LCL) 11 12 See the file COPYING.modifiedLGPL.txt, included in this distribution, 13 for details about the license. 14 ***************************************************************************** 15} 16unit Gtk2Proc; 17 18{$mode objfpc}{$H+} 19 20interface 21 22{$I gtk2defines.inc} 23 24uses 25 {$IFDEF windows} 26 // use windows unit first, 27 // if not, Rect and Point are taken from the windows unit instead of classes. 28 Windows, // needed for keyboard handling 29 {$endif} 30 {$IFDEF Unix} 31 unix, 32 {$ENDIF} 33 SysUtils, Classes, 34 {$IFDEF HasX} 35 XAtom, // clipboard 36 X, XLib, // Font retrieval and Keyboard handling 37 {$ENDIF} 38 InterfaceBase, 39 // gtk2 40 glib2, gdk2pixbuf, gdk2, gtk2, Pango, 41 {$ifdef HasGdk2X} 42 gdk2x, 43 {$endif} 44 // Other units 45 Math, // Math after gtk to get the correct Float type 46 Types, 47 // LCL 48 LMessages, LCLProc, LCLIntf, LCLType, Graphics, 49 LResources, Controls, Forms, Buttons, Menus, StdCtrls, ComCtrls, ExtCtrls, 50 Dialogs, ExtDlgs, ImgList, LCLMessageGlue, 51 // LazUtils 52 FileUtil, LazFileUtils, LazStringUtils, LazUtilities, LazLoggerBase, LazTracer, 53 GraphType, Masks, LazUTF8, DynHashArray, 54 // Gtk2 55 Gtk2FontCache, Gtk2Globals, Gtk2Def, Gtk2Extra, {%H-}Gtk2Debug; 56 57const 58 GtkListItemGtkListTag = 'GtkList'; 59 GtkListItemLCLListTag = 'LCLList'; 60 61 62type 63 PPWaitHandleEventHandler = ^PWaitHandleEventHandler; 64 PWaitHandleEventHandler = ^TWaitHandleEventHandler; 65 TWaitHandleEventHandler = record 66 Handle: THandle; 67 GIOChannel: pgiochannel; 68 GSourceID: guint; 69 UserData: PtrInt; 70 OnEvent: TWaitHandleEvent; 71 PrevHandler: PWaitHandleEventHandler; 72 NextHandler: PWaitHandleEventHandler; 73 end; 74 75{$ifdef UNIX} 76 PPChildSignalEventHandler = ^PChildSignalEventHandler; 77 PChildSignalEventHandler = ^TChildSignalEventHandler; 78 TChildSignalEventHandler = record 79 PID: TPid; 80 UserData: PtrInt; 81 OnEvent: TChildExitEvent; 82 PrevHandler: PChildSignalEventHandler; 83 NextHandler: PChildSignalEventHandler; 84 end; 85 86{$endif} 87 88var 89 GTKAPIWidget_Type: GType = 0; 90 91// GTKCallback.inc headers 92procedure EventTrace(const {%H-}TheMessage: string; {%H-}data: pointer); 93function gtkNoteBookCloseBtnClicked({%H-}Widget: PGtkWidget; 94 Data: Pointer): GBoolean; cdecl; 95function gtkRealizeCB(Widget: PGtkWidget; Data: Pointer): GBoolean; cdecl; 96function gtkRealizeAfterCB(Widget: PGtkWidget; Data: Pointer): GBoolean; cdecl; 97function gtkshowCB( {%H-}widget: PGtkWidget; data: gPointer): GBoolean; cdecl; 98function gtkHideCB( {%H-}widget: PGtkWidget; data: gPointer): GBoolean; cdecl; 99function gtkactivateCB(widget: PGtkWidget; data: gPointer): GBoolean; cdecl; 100function gtkchangedCB( widget: PGtkWidget; data: gPointer): GBoolean; cdecl; 101procedure gtkchanged_editbox_delete_text(Widget: PGtkWidget; 102 {%H-}AStartPos, {%H-}AEndPos: gint; {%H-}data: gPointer); cdecl; 103procedure gtkchanged_editbox_insert_text(Widget: PGtkWidget; {%H-}ANewText: PgChar; 104 {%H-}ANewTextLength: gint; {%H-}APosition: pgint; {%H-}data: gPointer); cdecl; 105function gtkchanged_editbox( widget: PGtkWidget; data: gPointer): GBoolean; cdecl; 106function gtkchanged_editbox_delete({%H-}widget: PGtkWidget; 107 {%H-}AType: TGtkDeleteType; {%H-}APos: gint; {%H-}data: gPointer): GBoolean; cdecl; 108function gtkdaychanged(Widget: PGtkWidget; data: gPointer): GBoolean; cdecl; 109function gtktoggledCB( widget: PGtkWidget; data: gPointer): GBoolean; cdecl; 110function gtkpaste_editbox(Widget: PGtkWidget; data: gPointer): GBoolean; cdecl; 111 112function gtkExposeEvent(Widget: PGtkWidget; Event: PGDKEventExpose; 113 Data: gPointer): GBoolean; cdecl; 114function gtkExposeEventAfter(Widget: PGtkWidget; Event: PGDKEventExpose; 115 Data: gPointer): GBoolean; cdecl; 116function gtkfrmactivateAfter( widget: PGtkWidget; {%H-}Event: PgdkEventFocus; 117 data: gPointer): GBoolean; cdecl; 118function gtkfrmdeactivateAfter( widget: PGtkWidget; {%H-}Event: PgdkEventFocus; 119 data: gPointer): GBoolean; cdecl; 120 121function GTKKeyPress(Widget: PGtkWidget; Event: pgdkeventkey; 122 Data: gPointer): GBoolean; cdecl; 123function GTKKeyPressAfter(Widget: PGtkWidget; Event: pgdkeventkey; 124 Data: gPointer): GBoolean; cdecl; 125function GTKKeyRelease(Widget: PGtkWidget; Event: pgdkeventkey; 126 Data: gPointer): GBoolean; cdecl; 127function GTKKeyReleaseAfter(Widget: PGtkWidget; Event: pgdkeventkey; 128 Data: gPointer): GBoolean; cdecl; 129 130function GTKFocusCB(widget: PGtkWidget; {%H-}event:PGdkEventFocus; 131 data: gPointer): GBoolean; cdecl; 132function GTKKillFocusCB({%H-}widget: PGtkWidget; {%H-}event:PGdkEventFocus; 133 {%H-}data: gPointer): GBoolean; cdecl; 134function GTKKillFocusCBAfter(widget: PGtkWidget; {%H-}event:PGdkEventFocus; 135 data: gPointer): GBoolean; cdecl; 136function gtkdestroyCB(widget: PGtkWidget; data: gPointer): GBoolean; cdecl; 137procedure DestroyWindowFromPointCB(Widget: PGtkWidget; {%H-}data: gPointer); cdecl; 138function gtkdeleteCB({%H-}widget: PGtkWidget; {%H-}event: PGdkEvent; 139 data: gPointer): GBoolean; cdecl; 140function gtkresizeCB({%H-}widget: PGtkWidget; {%H-}data: gPointer): GBoolean; cdecl; 141function gtkMonthChanged({%H-}Widget: PGtkWidget; data: gPointer): GBoolean; cdecl; 142procedure DeliverMouseMoveMessage({%H-}Widget:PGTKWidget; Event: PGDKEventMotion; 143 AWinControl: TWinControl); 144 145function gtkMotionNotify(Widget:PGTKWidget; Event: PGDKEventMotion; 146 Data: gPointer): GBoolean; cdecl; 147function GTKMotionNotifyAfter(widget:PGTKWidget; event: PGDKEventMotion; 148 data: gPointer): GBoolean; cdecl; 149 150function DeliverMouseDownMessage({%H-}widget: PGtkWidget; event: pgdkEventButton; 151 AWinControl: TWinControl): PtrInt; 152 153function gtk2ScrollBarMouseBtnPress({%H-}widget: PGtkWidget; {%H-}event: pgdkEventButton; 154 {%H-}data: gPointer): GBoolean; cdecl; 155 156function gtk2ScrollBarMouseBtnRelease({%H-}widget: PGtkWidget; {%H-}event: pgdkEventButton; 157 {%H-}data: gPointer): GBoolean; cdecl; 158 159 160function gtkMouseBtnPress(widget: PGtkWidget; event: pgdkEventButton; 161 data: gPointer): GBoolean; cdecl; 162function gtkMouseBtnPressAfter(widget: PGtkWidget; event: pgdkEventButton; 163 data: gPointer): GBoolean; cdecl; 164function ControlGetsMouseUpBefore({%H-}AControl: TControl): boolean; 165function DeliverMouseUpMessage(widget: PGtkWidget; event: pgdkEventButton; 166 AWinControl: TWinControl): boolean; 167function gtkMouseBtnRelease(widget: PGtkWidget; event: pgdkEventButton; 168 data: gPointer): GBoolean; cdecl; 169function gtkMouseBtnReleaseAfter(widget: PGtkWidget; event: pgdkEventButton; 170 data: gPointer): GBoolean; cdecl; 171function gtkclickedCB( widget: PGtkWidget; data: gPointer): GBoolean; cdecl; 172 173function gtkEnterCB(widget: PGtkWidget; data: gPointer): GBoolean; cdecl; 174function gtkLeaveCB(widget: PGtkWidget; data: gPointer): GBoolean; cdecl; 175function gtksize_allocateCB(widget: PGtkWidget; {%H-}size :pGtkAllocation; 176 data: gPointer): GBoolean; cdecl; 177function gtksize_allocate_client({%H-}widget: PGtkWidget; {%H-}size :pGtkAllocation; 178 data: gPointer): GBoolean; cdecl; 179function gtkconfigureevent( widget: PGtkWidget; event: PgdkEventConfigure; 180 data: gPointer): GBoolean; cdecl; 181function gtkInsertText(widget: PGtkWidget; char: pChar; NewTextLength: 182 Integer; Position: pgint; data: gPointer): GBoolean; cdecl; 183function gtkSetEditable( {%H-}widget: PGtkWidget; data: gPointer): GBoolean; cdecl; 184function gtkMoveWord( {%H-}widget: PGtkWidget; data: gPointer): GBoolean; cdecl; 185function gtkMovePage( {%H-}widget: PGtkWidget; data: gPointer): GBoolean; cdecl; 186function gtkMoveToRow( {%H-}widget: PGtkWidget; data: gPointer): GBoolean; cdecl; 187function gtkMoveToColumn( {%H-}widget: PGtkWidget; data: gPointer): GBoolean; cdecl; 188function gtkKillChar( {%H-}widget: PGtkWidget; data: gPointer): GBoolean; cdecl; 189function gtkKillWord( {%H-}widget: PGtkWidget; data: gPointer): GBoolean; cdecl; 190function gtkKillLine( {%H-}widget: PGtkWidget; data: gPointer): GBoolean; cdecl; 191function gtkCutToClip( {%H-}widget: PGtkWidget; data: gPointer): GBoolean; cdecl; 192function gtkCopyToClip( {%H-}widget: PGtkWidget; data: gPointer): GBoolean; cdecl; 193function gtkPasteFromClip( {%H-}widget: PGtkWidget; data: gPointer): GBoolean; cdecl; 194function gtkValueChanged({%H-}widget: PGtkWidget; data: gPointer): GBoolean; cdecl; 195function gtkTimerCB(Data: gPointer): gBoolean; cdecl; 196function gtkFocusInNotifyCB (widget: PGtkWidget; {%H-}event: PGdkEvent; 197 data: gpointer): GBoolean; cdecl; 198function gtkFocusOutNotifyCB (widget: PGtkWidget; {%H-}event: PGdkEvent; 199 data: gpointer): GBoolean; cdecl; 200 201// PGtkAdjustment cb 202function GTKHScrollCB(Adjustment: PGTKAdjustment; data: GPointer): GBoolean; cdecl; 203function GTKVScrollCB(Adjustment: PGTKAdjustment; 204 data: GPointer): GBoolean; cdecl; 205 206// PGtkRange cb 207function Gtk2RangeScrollCB(ARange: PGtkRange; AScrollType: TGtkScrollType; 208 AValue: gdouble; AWidgetInfo: PWidgetInfo): gboolean; cdecl; 209function Gtk2RangeScrollPressCB(Widget: PGtkWidget; 210 {%H-}Event: PGdkEventButton; {%H-}Data: gPointer): gboolean; cdecl; 211function Gtk2RangeScrollReleaseCB(Widget: PGtkWidget; 212 {%H-}Event: PGdkEventButton; {%H-}Data: gPointer): gboolean; cdecl; 213function Gtk2RangeUbuntuScrollCB(Adjustment: PGTKAdjustment; data: GPointer): GBoolean; cdecl; 214 215procedure Gtk2RangeValueChanged(ARange: PGTKRange; data: GPointer); cdecl; 216 217function Gtk2ScrolledWindowScrollCB(AScrollWindow: PGtkScrolledWindow; 218 AEvent: PGdkEventScroll; AWidgetInfo: PWidgetInfo): gboolean; cdecl; 219function GTKCheckMenuToggeledCB(AMenuItem: PGTKCheckMenuItem; 220 AData: gPointer): GBoolean; cdecl; 221function GTKKeySnooper({%H-}Widget: PGtkWidget; Event: PGdkEventKey; 222 FuncData: gPointer): gInt; cdecl; 223function gtkYearChanged({%H-}Widget: PGtkWidget; data: gPointer): GBoolean; cdecl; 224procedure GtkDragDataReceived({%H-}widget:PGtkWidget; context:PGdkDragContext; 225 {%H-}x:gint; {%H-}y:gint; selection_data:PGtkSelectionData; {%H-}info:guint; time:guint; Data: gPointer);cdecl; 226 227 228// clipboard 229procedure ClipboardSelectionReceivedHandler({%H-}TargetWidget: PGtkWidget; 230 SelectionData: PGtkSelectionData; TimeID: guint32; {%H-}Data: Pointer); cdecl; 231procedure ClipboardSelectionRequestHandler({%H-}TargetWidget: PGtkWidget; 232 SelectionData: PGtkSelectionData; {%H-}Info: cardinal; {%H-}TimeID: cardinal; 233 {%H-}Data: Pointer); cdecl; 234function ClipboardSelectionLostOwnershipHandler({%H-}TargetWidget: PGtkWidget; 235 EventSelection: PGdkEventSelection; {%H-}Data: Pointer): cardinal; cdecl; 236{$IFDEF EventTrace} 237procedure GTKStyleChanged(Widget: PGtkWidget; previous_style : 238 PGTKStyle; Data: Pointer); cdecl; 239procedure GTKStyleChangedAfter(Widget: PGtkWidget; previous_style : PGTKStyle; 240 Data: Pointer); cdecl; 241{$ENDIF} 242function gtkListBoxSelectionChangedAfter(widget: PGtkWidget; 243 data: gPointer): GBoolean; cdecl; 244 245// drag callbacks 246function edit_drag_data_received({%H-}widget: pgtkWidget; 247 Context: pGdkDragContext; 248 {%H-}X: Integer; 249 {%H-}Y: Integer; 250 seldata: pGtkSelectionData; 251 {%H-}info: Integer; 252 time: Integer; 253 data: pointer): GBoolean; cdecl; 254function edit_source_drag_data_get({%H-}widget: pgtkWidget; 255 {%H-}Context: pGdkDragContext; 256 Selection_data: pGtkSelectionData; 257 info: Integer; 258 {%H-}time: Integer; 259 data: pointer): GBoolean; cdecl; 260function Edit_source_drag_data_delete ({%H-}widget: pGtkWidget; 261 {%H-}context: pGdkDragContext; 262 {%H-}data: gpointer): gBoolean ; cdecl; 263 264// combobox callbacks 265function gtkComboBoxShowAfter({%H-}widget: PGtkWidget; data: gPointer): GBoolean; cdecl; 266function gtkComboBoxHideAfter({%H-}widget: PGtkWidget; data: gPointer): GBoolean; cdecl; 267 268// notebook callbacks 269function PageIconWidgetExposeAfter(Widget: PGtkWidget; Event: PGDKEventExpose; 270 Data: gPointer): GBoolean; cdecl; 271 272// callbacks for menu items 273procedure DrawMenuItemIcon(MenuItem: PGtkCheckMenuItem; Area: PGdkRectangle); cdecl; 274procedure MenuSizeRequest(widget:PGtkWidget; requisition:PGtkRequisition); cdecl; 275 276//============================================================================== 277type 278 TDestroyConnectedWidgetCB = procedure(Widget: PGtkWidget; 279 CheckIfDestroying: boolean) of object; 280var 281 DestroyConnectedWidgetCB: TDestroyConnectedWidgetCB; // set by the TGtkWidgetSet 282 283//============================================================================== 284// functions 285 286function RectFromGdkRect(const AGdkRect: TGdkRectangle): TRect; 287function GdkRectFromRect(const R: TRect): TGdkRectangle; 288function AlignToGtkAlign(Align: TAlignment): gfloat; 289function GtkScrollTypeToScrollCode(ScrollType: TGtkScrollType): LongWord; 290function Gtk2TranslateScrollStyle(const SS:TScrollStyle):TPoint; 291 292// debugging 293function GtkWidgetIsA(Widget: PGtkWidget; AType: TGtkType): boolean; 294function GetWidgetClassName(Widget: PGtkWidget): string; 295function GetWidgetDebugReport(Widget: PGtkWidget): string; 296function GetWindowDebugReport(AWindow: PGDKWindow): string; 297function GetStyleDebugReport(AStyle: PGTKStyle): string; 298function GetRCStyleDebugReport(AStyle: PGtkRcStyle): string; 299function GetPangoDescriptionReport(Desc: PPangoFontDescription): string; 300function WidgetFlagsToString(Widget: PGtkWidget): string; 301function GdkColorToStr(Color: PGDKColor): string; 302function GetWidgetStyleReport(Widget: PGtkWidget): string; 303procedure BeginGDKErrorTrap; 304procedure EndGDKErrorTrap; 305function dbgGRect(const ARect: PGDKRectangle): string; overload; 306 307 308// gtk resources 309procedure Set_RC_Name(Sender: TObject; AWidget: PGtkWidget); 310 311// messages 312function DeliverPostMessage(const Target: Pointer; var TheMessage): GBoolean; 313function DeliverMessage(const Target: Pointer; var AMessage): PtrInt; 314 315// PChar 316//function CreatePChar(const s: string): PChar; 317function FindChar(c: char; p:PChar; Max: integer): integer; 318function FindLineLen(p:PChar; Max: integer): integer; 319 320// flags 321function WidgetIsDestroyingHandle(Widget: PGtkWidget): boolean; 322procedure SetWidgetIsDestroyingHandle(Widget: PGtkWidget); 323function ComponentIsDestroyingHandle(AWinControl: TWinControl): boolean; 324function LockOnChange(GtkObject: PGtkObject; LockOffset: integer): integer; 325procedure InvalidateLastWFPResult(AControl: TWinControl; const ABounds: TRect); 326 327// glib 328procedure MoveGListLinkBehind(First, Item, After: PGList); 329procedure MoveGListLink(First: PGList; FromIndex, ToIndex: integer); 330 331// properties 332function ObjectToGTKObject(const AnObject: TObject): PGtkObject; 333function GetMainWidget(const Widget: Pointer): Pointer; 334procedure SetMainWidget(const ParentWidget, ChildWidget: Pointer); 335function GetFixedWidget(const Widget: Pointer): Pointer; 336procedure SetFixedWidget(const ParentWidget, FixedWidget: Pointer); 337function GetControlWindow(Widget: Pointer): PGDKWindow; 338 339function CreateWidgetInfo(const AWidget: Pointer): PWidgetInfo; 340function CreateWidgetInfo(const AWidget: Pointer; const AObject: TObject; 341 const AParams: TCreateParams): PWidgetInfo; 342function GetWidgetInfo(const AWidget: Pointer): PWidgetInfo; 343function GetOrCreateWidgetInfo(const AWidget: Pointer): PWidgetInfo; 344procedure FreeWidgetInfo(AWidget: Pointer); 345 346procedure DestroyWidget(Widget: PGtkWidget); 347procedure SetLCLObject(const Widget: Pointer; const AnObject: TObject); 348function GetLCLObject(const Widget: Pointer): TObject; 349function GetNearestLCLObject(Widget: PGtkWidget): TObject; 350function GetWinControlWidget(Child: PGtkWidget): PGtkWidget; 351function GetWinControlFixedWidget(Child: PGtkWidget): PGtkWidget; 352function FindFixedChildListItem(ParentFixed: PGtkFixed; Child: PGtkWidget): PGList; 353function FindFixedLastChildListItem(ParentFixed: PGtkFixed): PGList; 354function GetFixedChildListWidget(Item: PGList): PGtkWidget; 355 356// fixed widgets 357function CreateFixedClientWidget(WithWindow: Boolean = true): PGTKWidget; 358procedure FixedMoveControl(Parent, Child: PGTKWidget; Left, Top: Longint); 359procedure FixedPutControl(Parent, Child: PGTKWidget; Left, Top: Longint); 360 361// forms 362procedure SetFormShowInTaskbar(AForm: TCustomForm; const AValue: TShowInTaskbar); 363procedure SetGtkWindowShowInTaskbar(AGtkWindow: PGtkWindow; Value: boolean); 364procedure SetWindowFullScreen(AForm: TCustomForm; const AValue: Boolean); 365procedure GrabKeyBoardToForm(AForm: TCustomForm); 366procedure ReleaseKeyBoardFromForm({%H-}AForm: TCustomForm); 367procedure GrabMouseToForm(AForm: TCustomForm); 368procedure ReleaseMouseFromForm({%H-}AForm: TCustomForm); 369procedure GtkWindowShowModal(AForm: TCustomForm; GtkWindow: PGtkWindow); 370 371// label 372procedure SetLabelAlignment(LabelWidget: PGtkLabel; const NewAlignment: TAlignment); 373 374// paint messages 375function DoDeliverPaintMessage(const Target: TObject; var PaintMsg: TLMPaint): PtrInt; 376function GtkPaintMessageToPaintMessage(var GtkPaintMsg: TLMGtkPaint; 377 FreeGtkPaintMsg: boolean): TLMPaint; 378procedure FinalizePaintMessage(Msg: PLMessage); 379procedure FinalizePaintTagMsg(Msg: PMsg); 380 381// region 382function RegionType(RGN: PGDKRegion): Longint; 383function CreateRectGDKRegion(const ARect: TRect): PGDKRegion; 384function GDKRegionAsString(RGN: PGDKRegion): string; 385 386// color 387procedure FreeGDIColor(GDIColor: PGDIColor); 388procedure AllocGDIColor({%H-}DC: hDC; GDIColor: PGDIColor); 389procedure BuildColorRefFromGDKColor(var GDIColor: TGDIColor); 390procedure SetGDIColorRef(var GDIColor: TGDIColor; NewColorRef: TColorRef); 391procedure EnsureGCColor(DC: hDC; ColorType: TDevContextsColorType; 392 IsSolidBrush, AsBackground: Boolean); 393procedure CopyGDIColor(var SourceGDIColor, DestGDIColor: TGDIColor); 394function AllocGDKColor(const AColor: TColorRef): TGDKColor; 395function TGDKColorToTColor(const value: TGDKColor): TColor; 396function TColortoTGDKColor(const value: TColor): TGDKColor; 397procedure UpdateSysColorMap(Widget: PGtkWidget; Lgs: TLazGtkStyle); 398function IsBackgroundColor(Color: TColor): boolean; 399 400procedure RealizeGDKColor(ColorMap: PGdkColormap; Color: PGDKColor); 401procedure RealizeGtkStyleColor(Style: PGTKStyle; Color: PGDKColor); 402function GetSysGCValues(Color: TColorRef; {%H-}ThemeWidget: PGtkWidget): TGDKGCValues; 403 404function GDKPixel2GDIRGB(Pixel: Longint; Visual: PGDKVisual; 405 Colormap: PGDKColormap): TGDIRGB; 406 407function CompareGDIColor(const Color1, Color2: TGDIColor): boolean; 408function CompareGDIFill(const Fill1, Fill2: TGdkFill): boolean; 409function CompareGDIBrushes(Brush1, Brush2: PGdiObject): boolean; 410 411// palette 412function PaletteIndexExists(Pal: PGDIObject; I: longint): Boolean; 413function PaletteRGBExists(Pal: PGDIObject; RGB: longint): Boolean; 414function PaletteAddIndex(Pal: PGDIObject; I, RGB: Longint): Boolean; 415function PaletteDeleteIndex(Pal: PGDIObject; I: Longint): Boolean; 416function PaletteIndexToRGB(Pal: PGDIObject; I: longint): longint; 417function PaletteRGBToIndex(Pal: PGDIObject; RGB: longint): longint; 418procedure InitializePalette(const Pal: PGDIObject; const Entries: PPaletteEntry; 419 const RGBCount: Longint); 420function GetIndexAsKey(p: pointer): pointer; 421function GetRGBAsKey(p: pointer): pointer; 422 423 424// Keyboard functions 425type 426 TVKeyUTF8Char = array[0..7] of Char; 427 TVKeyInfo = record 428 KeyCode: array[Boolean] of Byte; // false is primary keycode, true the keycode of the other key when 2 keys exist (like CTRL or extended key) 429 KeySym: array[0..7] of Integer; 430 KeyChar: array[0..3] of TVKeyUTF8Char; 431 end; 432 433const 434 GdkKeymap: PGdkKeymap = nil; 435 GdkKeyMapChangedID: gulong = 0; 436procedure InitKeyboardTables; 437procedure DoneKeyboardTables; 438procedure DisconnectGdkKeymapChangedSignal; 439function GetVKeyInfo(const AVKey: Byte): TVKeyInfo; 440function GTKEventStateToShiftState(KeyState: LongWord): TShiftState; 441procedure gdk_event_key_get_string(Event: PGDKEventKey; var theString: Pointer); 442procedure gdk_event_key_set_string(Event: PGDKEventKey; const NewString: PChar); 443function gdk_event_get_type(Event: Pointer): TGdkEventType; 444 445function HandleGTKKeyUpDown(AWidget: PGtkWidget; AEvent: PGdkEventKey; 446 AData: gPointer; ABeforeEvent, AHandleDown: Boolean; const AEventName: PGChar 447 ) : GBoolean; 448 449// ---- 450 451// common dialogs 452procedure StoreCommonDialogSetup(ADialog: TCommonDialog); 453procedure DestroyCommonDialogAddOns(ADialog: TCommonDialog); 454procedure PopulateFileAndDirectoryLists(FileSelection: PGtkFileSelection; 455 const Mask: string); 456 457// notebook 458function IsTTabControl(AWidget: PGtkWidget): Boolean; 459procedure UpdateNoteBookClientWidget(ANoteBook: TObject); 460function GetGtkNoteBookPageCount(ANoteBookWidget: PGtkNoteBook): integer; 461procedure UpdateNotebookPageTab(ANoteBook, APage: TObject); 462procedure UpdateNotebookTabFont(APage: TWinControl; AFont: TFont); 463 464// coordinate transformation 465function GetWidgetOrigin(TheWidget: PGtkWidget): TPoint; 466function GetWidgetClientOrigin(TheWidget: PGtkWidget): TPoint; 467function GetWidgetClientRect(TheWidget: PGtkWidget): TRect; 468function TranslateGdkPointToClientArea(SourceWindow: PGdkWindow; 469 SourcePos: TPoint; DestinationWidget: PGtkWidget): TPoint; 470function SubtractScoll(AWidget: PGtkWidget; APosition: TPoint): TPoint; 471 472// mouse capturing 473function GetDefaultMouseCaptureWidget(Widget: PGtkWidget): PGtkWidget; 474procedure ReleaseMouseCapture; 475procedure ReleaseCaptureWidget(Widget : PGtkWidget); 476 477// window group 478function GetGtkWindowGroup(Widget: PGtkWidget): PGtkWindowGroup; 479 480const 481 // for now return the same value, in the future we may want to return an 482 // offset of -1 so we can use 0 as error (now crDefault = 0) 483 // In the current situation, a TCursor is passed as hCursor. Since both are 484 // ordinals, the compiler won't complain 485 PREDEFINED_CURSOR_OFFSET = 0; //-1; 486 487 488 489// designing 490type 491 TConnectSignalFlag = ( 492 csfAfter, // connect after signal 493 csfConnectRealize, // auto connect realize handler 494 csfUpdateSignalMask, // extend signal mask for gdkwindow 495 csfDesignOnly // mark signal as design only 496 ); 497 TConnectSignalFlags = set of TConnectSignalFlag; 498 499 TDesignSignalType = ( 500 dstUnknown, 501 dstMousePress, 502 dstMouseMotion, 503 dstMouseRelease, 504 dstExposeAfter 505 ); 506 TDesignSignalTypes = set of TDesignSignalType; 507 508 TDesignSignalMask = longint; 509 510const 511 DesignSignalBefore: array[TDesignSignalType] of boolean = ( 512 true, // dstUnknown 513 true, // dstMousePress 514 true, // dstMouseMotion 515 true, // dstMouseRelease 516 false // dstExposeAfter 517 ); 518 519 DesignSignalAfter: array[TDesignSignalType] of boolean = ( 520 false, // dstUnknown 521 false, // dstMousePress 522 false, // dstMouseMotion 523 false, // dstMouseRelease 524 false // dstExposeAfter 525 ); 526 527 DesignSignalNames: array[TDesignSignalType] of PChar = ( 528 '', 529 'button-press-event', 530 'motion-notify-event', 531 'button-release-event', 532 'expose-event' 533 ); 534 535 DesignSignalFuncs: array[TDesignSignalType] of Pointer = ( 536 nil, 537 @gtkMouseBtnPress, 538 @gtkMotionNotify, 539 @gtkMouseBtnRelease, 540 @gtkExposeEventAfter 541 ); 542 543var 544 DesignSignalMasks: array[TDesignSignalType] of TDesignSignalMask; 545 546procedure InitDesignSignalMasks; 547function DesignSignalNameToType(Name: PChar; After: boolean): TDesignSignalType; 548function GetDesignSignalMask(Widget: PGtkWidget): TDesignSignalMask; 549procedure SetDesignSignalMask(Widget: PGtkWidget; NewMask: TDesignSignalMask); 550function GetDesignOnlySignalFlag(Widget: PGtkWidget; 551 DesignSignalType: TDesignSignalType): boolean; 552 553// signals 554// new signal procs, these will obsolete the old ones 555// new signalshandlers are attached locally in the new WSxxx classes 556// they also have PWidgetInfo as data (and not the TControl) 557// signals are now also handled dedicated and locally, so no case statements 558// anymore in signal handlers 559procedure SignalConnect(const AWidget: PGTKWidget; const ASignal: PChar; 560 const AProc: Pointer; const AInfo: PWidgetInfo); 561procedure SignalConnectAfter(const AWidget: PGTKWidget; const ASignal: PChar; 562 const AProc: Pointer; const AInfo: PWidgetInfo); 563 564// old signal procs 565// since they are used in attachcallbacks, and they pass TControl as data 566// One day attachsignals gets removed. 567procedure ConnectSignal(const AnObject: PGTKObject; const ASignal: PChar; 568 const ACallBackProc: Pointer; const ALCLObject: TObject; 569 const AReqSignalMask: TGdkEventMask; const ASFlags: TConnectSignalFlags); 570procedure ConnectSignal(const AnObject: PGTKObject; const ASignal: PChar; 571 const ACallBackProc: Pointer; const ALCLObject: TObject; 572 const AReqSignalMask: TGdkEventMask); 573procedure ConnectSignalAfter(const AnObject:PGTKObject; const ASignal: PChar; 574 const ACallBackProc: Pointer; const ALCLObject: TObject; 575 const AReqSignalMask: TGdkEventMask); 576procedure ConnectSignal(const AnObject:PGTKObject; const ASignal: PChar; 577 const ACallBackProc: Pointer; const ALCLObject: TObject); 578procedure ConnectSignalAfter(const AnObject:PGTKObject; const ASignal: PChar; 579 const ACallBackProc: Pointer; const ALCLObject: TObject); 580 581procedure ConnectInternalWidgetsSignals(AWidget: PGtkWidget; 582 AWinControl: TWinControl); 583 584//-- 585 586// accelerators 587function Ampersands2Underscore(Src: PChar): PChar; 588function Ampersands2Underscore(const ASource: String): String; 589function EscapeUnderscores(const Str: String): String; inline; 590procedure LabelFromAmpersands(var AText, APattern: String; var AAccelChar: Char); 591 592function GetAccelGroup(const Widget: PGtkWidget; 593 CreateIfNotExists: boolean): PGTKAccelGroup; 594procedure SetAccelGroup(const Widget: PGtkWidget; 595 const AnAccelGroup: PGTKAccelGroup); 596procedure FreeAccelGroup(const Widget: PGtkWidget); 597procedure RegroupAccelerator(Widget: PGtkWidget); 598procedure ClearAccelKey(Widget: PGtkWidget); 599procedure Accelerate(Component: TComponent; const Widget: PGtkWidget; 600 const Key: guint; Mods: TGdkModifierType; const Signal: string); 601procedure Accelerate(Component: TComponent; const Widget: PGtkWidget; 602 const NewShortCut: TShortCut; const Signal: string); 603procedure ShareWindowAccelGroups(AWindow: PGtkWidget); 604procedure UnshareWindowAccelGroups(AWindow: PGtkWidget); 605 606// pixbuf 607procedure LoadPixbufFromLazResource(const ResourceName: string; 608 var Pixbuf: PGdkPixbuf); 609procedure LoadXPMFromLazResource(const ResourceName: string; 610 Window: PGdkWindow; var PixmapImg, PixmapMask: PGdkPixmap); 611 612function CreatePixbufFromDrawable(ASource: PGdkDrawable; AColorMap:PGdkColormap; AIncludeAplha: Boolean; ASrcX, ASrcY, ADstX, ADstY, AWidth, AHeight :longint): PGdkPixbuf; 613 614 615// pixmaps 616procedure SetGCRasterOperation(TheGC: PGDKGC; Rop: Cardinal); 617procedure MergeClipping(DestinationDC: TGtkDeviceContext; DestinationGC: PGDKGC; 618 X,Y,Width,Height: integer; ClipMergeMask: PGdkBitmap; 619 ClipMergeMaskX, ClipMergeMaskY: integer; 620 out NewClipMask: PGdkBitmap); 621function CreatePixbufFromImageAndMask(ASrc: PGdkDrawable; ASrcX, ASrcY, ASrcWidth, 622 ASrcHeight: integer; ASrcColorMap: PGdkColormap; ASrcMask: PGdkBitmap): PGdkPixbuf; 623function ScalePixmapAndMask({%H-}AScaleGC: PGDKGC; AScaleMethod: TGdkInterpType; 624 ASrc: PGdkPixmap; ASrcX, ASrcY, ASrcWidth, ASrcHeight: integer; 625 ASrcColorMap: PGdkColormap; ASrcMask: PGdkBitmap; 626 ADstWidth, ADstHeight: Integer; FlipHorz, FlipVert: Boolean; 627 out ADst, ADstMask: PGdkPixmap): Boolean; 628 629// obsolete: 630function GetGdkImageBitsPerPixel(Image: PGdkImage): cardinal; 631function CreateGdkMaskBitmap(AImage, AMask: HBITMAP): PGdkBitmap; 632function CreateGdkMaskBitmap(AImageMask, AMask: PGdkBitmap): PGdkBitmap; 633function ExtractGdkBitmap(Bitmap: PGdkBitmap; const SrcRect: TRect): PGdkBitmap; 634procedure CheckGdkImageBitOrder(AImage: PGdkImage; AData: PByte; ADataCount: Integer); 635 636 637// menus 638function MENU_ITEM_CLASS(widget: PGtkWidget): PGtkMenuItemClass; 639function CHECK_MENU_ITEM_CLASS(widget: PGtkWidget): PGtkCheckMenuItemClass; 640procedure LockRadioGroupOnChange(RadioGroup: PGSList; const ADelta: Integer); 641procedure UpdateRadioGroupChecks(RadioGroup: PGSList); 642procedure UpdateInnerMenuItem(LCLMenuItem: TMenuItem; MenuItemWidget: PGtkWidget); 643procedure UpdateInnerMenuItem(LCLMenuItem: TMenuItem; MenuItemWidget: PGtkWidget; 644 NewShortCut, ShortCutKey2: TShortCut); 645 646// statusbar 647function CreateStatusBarPanel({%H-}StatusBar: TObject; {%H-}Index: integer): PGtkWidget; 648procedure UpdateStatusBarPanels(StatusBar: TObject; 649 StatusBarWidget: PGtkWidget); 650procedure UpdateStatusBarPanel(StatusBar: TObject; Index: integer; 651 StatusPanelWidget: PGtkWidget); 652 653// list 654function gtkListGetSelectionMode(list: PGtkList): TGtkSelectionMode;cdecl; 655 656// sizing 657procedure SaveSizeNotification(Widget: PGtkWidget); 658procedure SaveClientSizeNotification(FixWidget: PGtkWidget); 659procedure SendSizeNotificationToLCL(aWidget: PGtkWidget); 660function CreateTopologicalSortedWidgets(HashArray: TDynHashArray): TFPList; 661procedure GetGTKDefaultWidgetSize(AWinControl: TWinControl; 662 var PreferredWidth, PreferredHeight: integer; {%H-}WithThemeSpace: Boolean); 663procedure SendCachedGtkResizeNotifications; 664procedure ResizeHandle(LCLControl: TWinControl); 665procedure SetWidgetSizeAndPosition(LCLControl: TWinControl);// for child controls 666procedure SetWindowSizeAndPosition(Window: PGtkWindow; AWinControl: TWinControl);// for top level control 667procedure GetWidgetRelativePosition(aWidget: PGtkWidget; out Left, Top: integer); 668procedure UnsetResizeRequest(Widget: PGtkWidget); 669procedure SetResizeRequest(Widget: PGtkWidget); 670function WidgetSizeIsEditable(Widget: PGtkWidget): boolean; 671 672// debug 673procedure ReportNotObsolete(const Texts: String); 674 675// screen 676function GetScreenWidthMM(GdkValue: boolean = false): integer; 677function GetScreenHeightMM(GdkValue: boolean = false): integer; 678 679// clipboard 680function WaitForClipboardAnswer(c: PClipboardEventData): boolean; 681function RequestSelectionData(ClipboardWidget: PGtkWidget; 682 ClipboardType: TClipboardType; FormatID: PtrUInt): TGtkSelectionData; 683procedure FreeClipboardTargetEntries(ClipboardType: TClipboardType); 684function GdkAtomToStr(const Atom: TGdkAtom): string; 685 686// forms 687function CreateFormContents({%H-}AForm: TCustomForm; 688 var FormWidget: Pointer; AWidgetInfo: PWidgetInfo = nil): Pointer; 689 690// styles 691type 692 PStyleObject = ^TStyleObject; 693 TStyleObject = Record 694 Style: PGTKStyle; 695 Owner: PGtkWidget; // The widget that we hold a reference to. 696 Widget: PGTKWidget; // This is the style widget. 697 FrameBordersValid: boolean; 698 FrameBorders: TRect; 699 end; 700 701var 702 StandardStyles: array[TLazGtkStyle] of PStyleObject; 703 704function IndexOfStyle(aStyle: TLazGtkStyle): integer; 705function IndexOfStyleWithName(const WName: String): integer; 706procedure ReleaseAllStyles; 707procedure ReleaseStyle(aStyle: TLazGtkStyle); 708procedure ReleaseStyleWithName(const WName: String); 709function GetStyle(aStyle: TLazGtkStyle): PGTKStyle; 710function GetStyleWithName(const WName: String): PGTKStyle; 711function GetStyleWidget(aStyle: TLazGtkStyle): PGTKWidget; 712function GetStyleWidgetWithName(const WName: String): PGTKWidget; 713function GetStyleGroupboxFrameBorders: TRect; 714function GetStyleNotebookFrameBorders: TRect; 715 716function GetStyleFormFrameBorders(WithMenu: boolean): TRect; 717 718procedure StyleFillRectangle(drawable: PGDKDrawable; GC: PGDKGC; 719 Color: TColorRef; x, y, width, height: gint; 720 AClipArea: PGdkRectangle); 721function StyleForegroundColor(Color: TColorRef; DefaultColor: PGDKColor): PGDKColor; 722procedure UpdateWidgetStyleOfControl(AWinControl: TWinControl); 723 724// fonts 725function LoadDefaultFont: TGtkIntfFont; 726function FontIsDoubleByteCharsFont(TheFont: TGtkIntfFont): boolean; 727function FontIsMonoSpaceFont(TheFont: TGtkIntfFont): boolean; 728 729function LoadDefaultFontDesc: PPangoFontDescription; 730 731procedure GetTextExtentIgnoringAmpersands(TheFont: TGtkIntfFont; 732 Str: PChar; StrLength: integer; 733 lbearing, rbearing, width, ascent, descent: Pgint); 734function GetDefaultFontName: string; 735{$IFDEF GTK2OLDENUMFONTFAMILIES} 736procedure FillScreenFonts(ScreenFonts: TStrings); 737{$ENDIF} 738function GetTextHeight(DCTextMetric: TDevContextTextMetric): integer; 739{$IFDEF HasX} 740function XGetWorkarea(out ax,ay,awidth,aheight:gint): gint; 741{$ENDIF} 742 743 744// decoration 745function GetWindowDecorations(AForm: TCustomForm): Longint; 746function GetWindowFunction(AForm: TCustomForm): Longint; 747 748// functions for easier GTK2<->GTK1 Compatibility/Consistency ----> 749function gtk_widget_get_xthickness(Style: PGTKStyle): gint; overload; 750function gtk_widget_get_ythickness(Style: PGTKStyle): gint; overload; 751 752function gtk_widget_get_xthickness(Widget: PGTKWidget): gint; overload; 753function gtk_widget_get_ythickness(Widget: PGTKWidget): gint; overload; 754function GetGtkContainerBorderWidth(Widget: PGtkContainer): gint; 755 756 757 function gtk_class_get_type(aclass: Pointer): TGtkType; 758 759 //we wrap our own versions to handle nil tests --> 760 function gtk_object_get_class(anobject: Pointer): Pointer; 761 function gtk_window_get_modal(window:PGtkWindow):gboolean; 762 763 //we wrap our own versions to do gtk1 style result = new region --> 764 function gdk_region_union_with_rect(region:PGdkRegion; 765 rect:PGdkRectangle): PGdkRegion; 766 function gdk_region_intersect(source1:PGdkRegion; 767 source2:PGdkRegion): PGdkRegion; 768 function gdk_region_union(source1:PGdkRegion; source2:PGdkRegion): PGdkRegion; 769 function gdk_region_subtract(source1:PGdkRegion; 770 source2:PGdkRegion): PGdkRegion; 771 function gdk_region_xor(source1:PGdkRegion; source2:PGdkRegion): PGdkRegion; 772 773 //mimic GDKFont Routines With Pango --> 774 procedure gdk_text_extents(TheFont: TGtkIntfFont; 775 Str: PChar; StrLength: integer; 776 lbearing, rbearing, width, ascent, descent: Pgint); 777 778 779{$ifdef HasX} 780// X functions 781function FormToX11Window(const AForm: TCustomForm): X.TWindow; 782{$endif} 783function FindFocusWidget(AWidget: PGtkWidget): PGtkWidget; 784 785const 786 gtkevent_window_state_event = 'window-state-event'; 787 788function GTKWindowStateEventCB(widget: PGtkWidget; 789 state: PGdkEventWindowState; 790 data: gpointer): gboolean; cdecl; 791 792function gtkMouseWheelCB({%H-}widget: PGtkWidget; event: PGdkEventScroll; 793 data: gPointer): GBoolean; cdecl; 794 795implementation 796 797uses 798 {$IFDEF StaticXinerama} Xinerama, {$ENDIF} 799 Gtk2WSPrivate, URIParser, Gtk2Int, Gtk2WinApiWindow; 800 801const 802 KCINFO_FLAG_SHIFT = $01; 803 //KCINFO_FLAG_CTRL = $02; 804 KCINFO_FLAG_ALTGR = $04; 805 //KCINFO_FLAG_KEY_MASK = $07; 806 KCINFO_FLAG_EXT = $10; // extended key 807 //KCINFO_FLAG_TOGGLE = $20; // toggle key 808 809 KCINFO_FLAG_SHIFT_XOR_NUM = $40; // second vkey should be used when numlock <>shift 810 //KCINFO_FLAG_MULTI_MASK = $C0; // key has more than one VK 811 812 813type 814 TKeyCodeInfo = record 815 VKey1: Byte; 816 VKey2: Byte; // second code to be used depending on the type of MULTI_VK flag 817 Flags: Byte; // indicates if Alt | Ctrl | Shift is needed 818 // extended state 819 end; 820 821var 822 MKeyCodeInfo: array[Byte] of TKeyCodeInfo; 823 MVKeyInfo: array[Byte] of TVKeyInfo; 824 825 // Modifier keys can be set by a modmap and don't have to be the same on all systems 826 // Some defaults are set here incase we didn't find them 827type 828 TModifier = record 829 Mask: TGdkModifierType; // if UseValue is set, the modifier is set when the masked state matches the value 830 Value: TGdkModifierType; // otherwise any nonzero value will match 831 UseValue: Boolean; 832 end; 833 834var 835 MModifiers: array[TShiftStateEnum] of TModifier; 836 837{$ifdef UseOwnShiftState} 838{$ifdef HasX} 839 // KeyStateMap is a quick index to scan the results of a XQueryKeymap 840 // which returns for the 256 possible keycodes a boolean bit array (32 bytes) 841 // Shift is set when the mask for the Keymapkeys_return[index] is set 842var 843 MKeyStateMap: array of record 844 Index: Byte; // KeyCode shr 3 845 Mask: Byte; // 1 shl (KeyCode and 7); 846 Enum: TShiftStateEnum; 847 end; 848{$endif} 849{$endif} 850 851type 852 // TLCLHandledKeyEvent is used to remember, if an gdk key event was already 853 // handled. 854 TLCLHandledKeyEvent = class 855 private 856 fRefCount: integer; 857 public 858 thetype: TGdkEventType; 859 window: PGdkWindow; 860 send_event: gint8; 861 time: guint32; 862 state : guint; 863 keyval: guint; 864 hardware_keycode : guint16; 865 constructor Create(Event: PGdkEventKey); 866 function IsEqual(Event: PGdkEventKey): boolean; 867 procedure AddRef; 868 procedure Release; 869 end; 870 871 TWinControlAccess = class(TWinControl) 872 end; 873 874{ TLCLHandledKeyEvent } 875 876constructor TLCLHandledKeyEvent.Create(Event: PGdkEventKey); 877begin 878 fRefCount:=1; 879 thetype:=gdk_event_get_type(Event); 880 window:=Event^.window; 881 send_event:=Event^.send_event; 882 time:=Event^.time; 883 state:=Event^.state; 884 keyval:=Event^.keyval; 885 // event^.length ? 886 // event^._string ? 887 hardware_keycode:=event^.hardware_keycode; 888end; 889 890function TLCLHandledKeyEvent.IsEqual(Event: PGdkEventKey): boolean; 891begin 892 Result:=(gdk_event_get_type(Event)=thetype) 893 and (window=Event^.window) 894 and (send_event=Event^.send_event) 895 and (time=Event^.time) 896 and (keyval=Event^.keyval) 897 ; 898end; 899 900procedure TLCLHandledKeyEvent.AddRef; 901begin 902 inc(fRefCount); 903end; 904 905procedure TLCLHandledKeyEvent.Release; 906begin 907 dec(fRefCount); 908 if fRefCount=0 then 909 Free; 910end; 911 912var 913 // LCLHandledKeyEvents stores the last handled key event (handled by the LCL) 914 // Reason: The gtk sends the same key event to several widgets. The gtk intf 915 // only wants to send them once to the LCL. 916 LCLHandledKeyEvents: TFPList; // list of TLCLHandledKeyEvent 917 LCLHandledKeyAfterEvents: TFPList; // list of TLCLHandledKeyEvent 918 919var 920 GdkTrapIsSet: Boolean; 921 GdkTrapCalls: Integer; 922 923procedure Set_RC_Name(Sender: TObject; AWidget: PGtkWidget); 924var RCName: string; 925 AComponent: TComponent; 926begin 927 {$IFDEF NoStyle} 928 exit; 929 {$ENDIF} 930 if (AWidget=nil) or (not (Sender is TComponent)) then exit; 931 932 // check if a unique name can be created 933 AComponent:=TComponent(Sender); 934 while (AComponent<>nil) and (AComponent.Name<>'') do begin 935 AComponent:=AComponent.Owner; 936 end; 937 if (AComponent=nil) or (AComponent=TComponent(Application)) then begin 938 // create unique name 939 AComponent:=TComponent(Sender); 940 RCName:=AComponent.Name; 941 while (AComponent<>nil) do begin 942 AComponent:=TComponent(AComponent.Owner); 943 if (AComponent<>nil) and (AComponent.Name<>'') then 944 RCName:=AComponent.Name+'_'+RCName; 945 end; 946 // do not set widget name issue #21661 947 // gtk_widget_set_name(AWidget,PChar(RCName)); 948 //debugln('Set_RC_Name ',GetWidgetDebugReport(AWidget),' RCName="',RCName,'"'); 949 gtk_widget_set_rc_style(AWidget); 950 end; 951end; 952 953procedure InitGTKProc; 954var 955 lgs: TLazGtkStyle; 956begin 957 //MKeySymToVKMap := TMap.Create(itu4, SizeOf(TVKeyRecord)); 958 // UTF8 is max 4 bytes, acombined makes it 8 959 //MSymCharToVKMap := TMap.Create(itu8, SizeOf(TVKeyRecord)); 960 961 // fill initial modifier list 962 FillByte(MModifiers, SizeOf(MModifiers), 0); 963 // keyboard 964 {$ifndef UseOwnShiftState} 965 MModifiers[ssCaps].Mask := GDK_LOCK_MASK; 966 MModifiers[ssNum].Mask := GDK_MOD3_MASK; //todo: check this I've 2 here,but 3 was the original code 967 MModifiers[ssScroll].Mask := GDK_MOD5_MASK; //todo: check this I've ssAltGr here, but ssScroll was the original code 968 MModifiers[ssShift].Mask := GDK_SHIFT_MASK; 969 MModifiers[ssCtrl].Mask := GDK_CONTROL_MASK; 970 MModifiers[ssAlt].Mask := GDK_MOD1_MASK; 971 MModifiers[ssSuper].Mask := GDK_MOD4_MASK; 972 MModifiers[ssAltGr].Mask := GDK_RELEASE_MASK; 973 {$endif} 974 // mouse 975 MModifiers[ssLeft].Mask := GDK_BUTTON1_MASK; 976 MModifiers[ssMiddle].Mask := GDK_BUTTON2_MASK; 977 MModifiers[ssRight].Mask := GDK_BUTTON3_MASK; 978 MModifiers[ssExtra1].Mask := GDK_BUTTON4_MASK; 979 MModifiers[ssExtra2].Mask := GDK_BUTTON5_MASK; 980 981 FillChar(MKeyCodeInfo, SizeOf(MKeyCodeInfo), $FF); 982 FillChar(MVKeyInfo, SizeOf(MVKeyInfo), 0); 983 984 985 GdkTrapIsSet := False; 986 GdkTrapCalls := 0; 987 LCLHandledKeyEvents:=nil; 988 LCLHandledKeyAfterEvents:=nil; 989 990 for lgs:=Low(TLazGtkStyle) to High(TLazGtkStyle) do 991 StandardStyles[lgs]:=nil; 992end; 993 994procedure DoneGTKProc; 995begin 996 DoneKeyboardTables; 997// FreeAndNil(MKeySymToVKMap); 998// FreeAndNil(MSymCharToVKMap); 999end; 1000 1001{ Callbacks for events } 1002 1003{$I gtk2proc.inc} 1004{$I gtk2callback.inc} 1005 1006initialization 1007 InitGTKProc; 1008 1009finalization 1010 DoneGTKProc; 1011 1012end. 1013 1014