{ /*************************************************************************** GTKINT.pp - GTKInterface Object ------------------- Initial Revision : Thu July 1st CST 1999 ***************************************************************************/ ***************************************************************************** This file is part of the Lazarus Component Library (LCL) See the file COPYING.modifiedLGPL.txt, included in this distribution, for details about the license. ***************************************************************************** } unit GtkInt; {$mode objfpc} {$LONGSTRINGS ON} interface {$ifdef Trace} {$ASSERTIONS ON} {$endif} {$I gtkdefines.inc} uses {$IFDEF WIN32} // use windows unit first, // if not, Rect and Point are taken from the windows unit instead of classes. Windows, {$ENDIF} {$IFDEF UNIX} // use unix units first, // if not, TSize is taken from the unix unit instead of types. ctypes, baseunix, unix, {$ENDIF} {$IFDEF TraceGdiCalls} LineInfo, {$ENDIF} // rtl+fcl Types, Classes, SysUtils, // LazUtils FPCAdds, LazUTF8, // gtk {$IFDEF gtk2} glib2, gdk2pixbuf, gdk2, gtk2, Pango, gtk2proc, {$ifdef HasGdk2X} gdk2x, {$endif} {$ELSE} glib, gdk, gtk, gdkpixbuf, {$ENDIF} // Target OS specific {$ifdef HasX} x, xlib, {$endif} Math, // after gtk to get the correct Float type // LCL LCLPlatformDef, InterfaceBase, FileUtil, Translations, ExtDlgs, Dialogs, Controls, Forms, LCLStrConsts, LMessages, LCLProc, LCLIntf, LCLType, DynHashArray, GraphType, GraphMath, Graphics, Menus, Maps, LazLoggerBase, LazFileUtils, LazStringUtils, Themes, // widgetset GtkDebug, GtkFontCache, gtkDef, GtkProc, gtkMsgQueue, GtkExtra, WSLCLClasses; type { TGTKWidgetSet } TGTKWidgetSet = class(TWidgetSet) private FMultiThreadingEnabled: boolean; FocusTimer: cardinal; FAppActive: Boolean; FLastFocusIn: PGtkWidget; FLastFocusOut: PGtkWidget; function GetAppActive: Boolean; procedure SetAppActive(const AValue: Boolean); protected FKeyStateList_: TFPList; // Keeps track of which keys are pressed FDeviceContexts: TDynHashArray;// hasharray of HDC FGDIObjects: TDynHashArray; // hasharray of PGdiObject FMessageQueue: TGtkMessageQueue; // queue of PMsg (must be thread safe!) WaitingForMessages: boolean; MovedPaintMessageCount: integer;// how many paint messages moved to he end of the queue FRCFilename: string; FRCFileParsed: boolean; FRCFileAge: integer; FGTKToolTips: PGtkToolTips; FLogHandlerID: guint; // ID returend by set_handler FStockNullBrush: HBRUSH; FStockBlackBrush: HBRUSH; FStockLtGrayBrush: HBRUSH; FStockGrayBrush: HBRUSH; FStockDkGrayBrush: HBRUSH; FStockWhiteBrush: HBRUSH; FStockNullPen: HPEN; FStockBlackPen: HPEN; FStockWhitePen: HPEN; FSysColorBrushes: array[0..MAX_SYS_COLORS] of HBrush; FWaitHandles: PWaitHandleEventHandler; {$ifdef unix} FChildSignalHandlers: PChildSignalEventHandler; {$else} {$IFDEF VerboseGtkToDos}{$warning no declaration of FChildSignalHandlers for this OS}{$ENDIF} {$endif} {$Ifdef GTK2} FDefaultFontDesc: PPangoFontDescription; {$Endif} FDefaultFont: TGtkIntfFont; FStockSystemFont: HFONT; FExtUTF8OutCache: Pointer; FExtUTF8OutCacheSize: integer; FGlobalCursor: HCursor; FDCManager: TDeviceContextMemManager; FDockImage: PGtkWidget; FDragImageList: PGtkWidget; FDragImageListIcon: PGtkWidget; FDragHotStop: TPoint; function CreateThemeServices: TThemeServices; override; function GetDeviceContextClass: TGtkDeviceContextClass; virtual; abstract; public procedure InitStockItems; virtual; procedure FreeStockItems; virtual; procedure InitSystemColors; procedure InitSystemBrushes; virtual; procedure FreeSystemBrushes; virtual; procedure PassCmdLineOptions; override; {$ifdef Unix} procedure InitSynchronizeSupport; procedure ProcessChildSignal; procedure PrepareSynchronize(AObject: TObject); {$endif} procedure HandlePipeEvent(AData: PtrInt; AFlags: dword); // styles procedure FreeAllStyles; virtual; function GetCompStyle(Sender : TObject) : Longint; virtual; // create and destroy function CreateAPIWidget(AWinControl: TWinControl): PGtkWidget; function OldCreateStatusBarPanel(StatusBar: TObject; Index: integer): PGtkWidget; function CreateSimpleClientAreaWidget(Sender: TObject; NotOnParentsClientArea: boolean): PGtkWidget; procedure DestroyEmptySubmenu(Sender: TObject);virtual; procedure DestroyConnectedWidget(Widget: PGtkWidget; CheckIfDestroying: boolean);virtual; function RecreateWnd(Sender: TObject): Integer; virtual; // clipboard procedure SetClipboardWidget(TargetWidget: PGtkWidget);virtual; // device contexts function IsValidDC(const DC: HDC): Boolean;virtual; function NewDC: TGtkDeviceContext;virtual; function FindDCWithGDIObject(GDIObject: PGdiObject): TGtkDeviceContext;virtual; procedure DisposeDC(aDC: TGtkDeviceContext);virtual; function CreateDCForWidget(AWidget: PGtkWidget; AWindow: PGdkWindow; AWithChildWindows: Boolean; ADoubleBuffer: PgdkDrawable = nil): HDC; function GetDoubleBufferedDC(Handle: HWND): HDC; // GDIObjects function IsValidGDIObject(const AGDIObj: HGDIOBJ): Boolean; virtual; function IsValidGDIObjectType(const GDIObject: HGDIOBJ; const GDIType: TGDIType): Boolean;virtual; function NewGDIObject(const GDIType: TGDIType): PGdiObject;virtual; procedure DisposeGDIObject(GdiObject: PGdiObject);virtual; function ReleaseGDIObject(GdiObject: PGdiObject): boolean;virtual; procedure ReferenceGDIObject(GdiObject: PGdiObject);virtual; function CreateDefaultBrush: PGdiObject;virtual; function CreateDefaultFont: PGdiObject;virtual; function CreateDefaultPen: PGdiObject;virtual; function CreateDefaultGDIBitmap: PGdiObject;virtual; procedure UpdateDCTextMetric(DC: TGtkDeviceContext); virtual; {$Ifdef GTK2} function GetDefaultFontDesc(IncreaseReferenceCount: boolean): PPangoFontDescription; {$Endif} function GetDefaultGtkFont(IncreaseReferenceCount: boolean): TGtkIntfFont; function GetGtkFont(DC: TGtkDeviceContext): TGtkIntfFont; function CreateRegionCopy(SrcRGN: hRGN): hRGN; override; function DCClipRegionValid(DC: HDC): boolean; override; function CreateEmptyRegion: hRGN; override; // images procedure LoadPixbufFromLazResource(const ResourceName: string; var Pixbuf: PGdkPixbuf); function InternalGetDIBits(DC: HDC; Bitmap: HBitmap; StartScan, NumScans: UINT; BitSize : Longint; Bits: Pointer; var BitInfo: BitmapInfo; Usage: UINT; DIB : Boolean): Integer;virtual; function RawImage_DescriptionFromDrawable(out ADesc: TRawImageDescription; ADrawable: PGdkDrawable; ACustomAlpha: Boolean): boolean; function RawImage_DescriptionFromPixbuf(out ADesc: TRawImageDescription; APixbuf: PGdkPixbuf): boolean; function RawImage_FromDrawable(out ARawImage: TRawImage; ADrawable, AAlpha: PGdkDrawable; ARect: PRect = nil): boolean; function RawImage_FromPixbuf(out ARawImage: TRawImage; APixbuf: PGdkPixbuf; ARect: PRect = nil): boolean; function RawImage_SetAlpha(var ARawImage: TRawImage; AAlpha: PGdkPixmap; ARect: PRect = nil): boolean; function RawImage_AddMask(var ARawImage: TRawImage; AMask: PGdkBitmap; ARect: PRect = nil): boolean; function StretchCopyArea(DestDC: HDC; X, Y, Width, Height: Integer; SrcDC: HDC; XSrc, YSrc, SrcWidth, SrcHeight: Integer; Mask: HBITMAP; XMask, YMask: Integer; Rop: Cardinal): Boolean; // RC file procedure SetRCFilename(const AValue: string);virtual; procedure CheckRCFilename;virtual; procedure ParseRCFile;virtual; // forms and dialogs procedure BringFormToFront(Sender: TObject); procedure UntransientWindow(GtkWindow: PGtkWindow); // misc function GetCaption(Sender : TObject) : String; virtual; procedure WordWrap(DC: HDC; AText: PChar; MaxWidthInPixel: integer; var Lines: PPChar; var LineCount: integer); procedure ResizeChild(Sender : TObject; Left,Top,Width,Height : Integer);virtual; procedure RemoveCallbacks(Widget: PGtkWidget); virtual; // for gtk specific components: procedure SetLabelCaption(const ALabel: PGtkLabel; const ACaption: String {$IFDEF Gtk1} ; const AComponent: TComponent = nil; const ASignalWidget: PGTKWidget = nil; const ASignal: PChar = nil{$ENDIF}); virtual; abstract; procedure SetWidgetColor(const AWidget: PGtkWidget; const FGColor, BGColor: TColor; const Mask: tGtkStateEnum); procedure SetWidgetFont(const AWidget : PGtkWidget;const AFONT : tFont); virtual; abstract; procedure SetCallbackEx(const AMsg: LongInt; const AGTKObject: PGTKObject; const ALCLObject: TObject; Direct: boolean); virtual; procedure SetCallbackDirect(const AMsg: LongInt; const AGTKObject: PGTKObject; const ALCLObject: TObject); procedure SetCallback(const AMsg: LongInt; const AGTKObject: PGTKObject; const ALCLObject: TObject); procedure SetCommonCallbacks(const AGTKObject: PGTKObject; const ALCLObject: TObject); virtual; function LCLtoGtkMessagePending: boolean;virtual; procedure SendCachedGtkMessages;virtual; // show, hide and invalidate procedure SetVisible(Sender: TObject; const AVisible: Boolean); virtual; // Drag ImageLsit function DragImageList_BeginDrag(APixmap: PGdkPixmap; AMask: PGdkBitmap; AHotSpot: TPoint): Boolean; procedure DragImageList_EndDrag; function DragImageList_DragMove(X, Y: Integer): Boolean; function DragImageList_SetVisible(NewVisible: Boolean): Boolean; public function LCLPlatform: TLCLPlatform; override; // Application procedure AppInit(var ScreenInfo: TScreenInfo); override; procedure AppProcessMessages; override; procedure AppWaitMessage; override; procedure AppTerminate; override; procedure AppMinimize; override; procedure AppRestore; override; procedure AppBringToFront; override; procedure AppSetTitle(const ATitle: string); override; // notebook procedure AddDummyNoteBookPage(NoteBookWidget: PGtkNoteBook);virtual; public constructor Create; override; destructor Destroy; override; procedure SendCachedLCLMessages; override; function DCGetPixel(CanvasHandle: HDC; X, Y: integer): TGraphicsColor; override; procedure DCSetPixel(CanvasHandle: HDC; X, Y: integer; AColor: TGraphicsColor); override; procedure DCRedraw(CanvasHandle: HDC); override; procedure SetDesigning(AComponent: TComponent); override; // helper routines needed by interface methods // |-forms procedure UpdateTransientWindows; virtual; // |-listbox procedure SetSelectionMode(Sender: TObject; Widget: PGtkWidget; MultiSelect, ExtendedSelect: boolean); virtual; function ForceLineBreaks(DC : hDC; Src: PChar; MaxWidthInPixels : Longint; ConvertAmpersandsToUnderScores: Boolean) : PChar; // create and destroy function CreateTimer(Interval: integer; TimerProc: TWSTimerProc) : TLCLHandle; override; function DestroyTimer(TimerHandle: TLCLHandle) : boolean; override; procedure DestroyLCLComponent(Sender: TObject);virtual; // for gtk controls not part of the LCL: procedure FinishCreateHandle(const AWinControl: TWinControl; Widget: PGtkWidget; const AParams: TCreateParams); {$I gtkwinapih.inc} {$I gtklclintfh.inc} public // special methods and properties to track app activation / deactivation procedure StartFocusTimer; property AppActive: Boolean read GetAppActive write SetAppActive; property LastFocusIn: PGtkWidget read FLastFocusIn write FLastFocusIn; property LastFocusOut: PGtkWidget read FLastFocusOut write FLastFocusOut; property RCFilename: string read FRCFilename write SetRCFilename; property MultiThreadingEnabled: boolean read FMultiThreadingEnabled; end; {$I gtklistslh.inc} {$I gtkfiledialogutilsh.inc} var GTKWidgetSet: TGTKWidgetSet; implementation uses //////////////////////////////////////////////////// // I M P O R T A N T //////////////////////////////////////////////////// // To get as little as possible circles, // uncomment only those units with implementation //////////////////////////////////////////////////// // GtkWSActnList, GtkWSButtons, GtkWSCalendar, GtkWSCheckLst, GtkWSComCtrls, GtkWSControls, // GtkWSDbCtrls, // GtkWSDBGrids, GtkWSDialogs, // GtkWSEditBtn, GtkWSExtCtrls, GtkWSExtDlgs, // GtkWSFileCtrl, GtkWSForms, GtkWSGrids, // GtkWSImgList, // GtkWSMaskEdit, GtkWSMenus, GtkWSPairSplitter, GtkWSSpin, GtkWSStdCtrls, // GtkWSToolwin, //////////////////////////////////////////////////// GtkWSPrivate, GtkThemes, Buttons, StdCtrls, PairSplitter, GTKWinApiWindow, ComCtrls, Calendar, Spin, ExtCtrls, FileCtrl, LResources, gtkglobals, LazUtilities; {$I gtklistsl.inc} {$I gtkfiledialogutils.inc} {$I gtkwidgetset.inc} {$I gtkwinapi.inc} {$I gtklclintf.inc} procedure InternalInit; var c: TClipboardType; begin gtk_handler_quark := g_quark_from_static_string('gtk-signal-handlers'); MouseCaptureWidget := nil; MouseCaptureType := mctGTK; LastLeft:=EmptyLastMouseClick; LastMiddle:=EmptyLastMouseClick; LastRight:=EmptyLastMouseClick; // clipboard ClipboardSelectionData:=TFPList.Create; for c:=Low(TClipboardType) to High(TClipboardType) do begin ClipboardTypeAtoms[c]:=0; ClipboardHandler[c]:=nil; //ClipboardIgnoreLossCount[c]:=0; ClipboardTargetEntries[c]:=nil; ClipboardTargetEntryCnt[c]:=0; end; // charset encodings {$IFDEF Gtk1} SystemCharSetIsUTF8:=not NeedRTLAnsi; {$ENDIF} CharSetEncodingList := TList.Create; CreateDefaultCharsetEncodings; InitDesignSignalMasks; end; procedure InternalFinal; var i: integer; ced: PClipboardEventData; c: TClipboardType; begin // clipboard for i:=0 to ClipboardSelectionData.Count-1 do begin ced:=PClipboardEventData(ClipboardSelectionData[i]); if ced^.Data.Data<>nil then FreeMem(ced^.Data.Data); Dispose(ced); end; for c:=Low(TClipboardType) to High(TClipboardType) do FreeClipboardTargetEntries(c); ClipboardSelectionData.Free; ClipboardSelectionData:=nil; // charset encodings if CharSetEncodingList<>nil then begin ClearCharSetEncodings; CharSetEncodingList.Free; CharSetEncodingList:=nil; end; end; initialization {$IFDEF GTK1} {$I gtkimages.lrs} {$ENDIF} InternalInit; finalization InternalFinal; end.