1 {
2  /***************************************************************************
3                 CustomDrawnInt.pas -  CustomDrawn Interface Object
4                              -------------------
5 
6  ***************************************************************************/
7 
8  *****************************************************************************
9   This file is part of the Lazarus Component Library (LCL)
10 
11   See the file COPYING.modifiedLGPL.txt, included in this distribution,
12   for details about the license.
13  *****************************************************************************
14 }
15 
16 unit CustomDrawnInt;
17 
18 {$mode objfpc}{$H+}
19 
20 {$I customdrawndefines.inc}
21 
22 interface
23 
24 uses
25   // RTL
26   // for CD_Cocoa Types needs to be after the platform-specif units or else Mac
27   // will catch MacOSAll.Rect/Size/Point
28   {$ifndef CD_Cocoa}Types,{$endif}Classes, SysUtils, Math,
29   fpimage, fpcanvas, fpimgcanv, ctypes, dateutils,
30   // XML
31   XMLRead, Dom,
32   // Platform specific
33   {$ifdef CD_Windows}Windows, customdrawn_WinProc, customdrawn_winextra,{$endif}
34   {$ifdef CD_Cocoa}MacOSAll, CocoaAll, customdrawn_cocoaproc, CocoaGDIObjects,Types,{$endif}
35   {$ifdef CD_X11}X, XLib, XUtil, BaseUnix, customdrawn_x11proc,{$ifdef CD_UseNativeText}xft, fontconfig,{$endif}{$endif}
36   {$ifdef CD_Android}
37   customdrawn_androidproc, jni, bitmap, log, keycodes,
38   {$endif}
39   {$ifdef WinCE}aygshell,{$endif}
40   // LazUtils
41   LazFileUtils, lazutf8,
42   {$ifndef CD_UseNativeText}
43   // LazFreeType
44   LazFreeTypeIntfDrawer, LazFreeType, EasyLazFreeType, IniFiles,
45   {$endif}
46   // Widgetset
47   customdrawnproc, customdrawnthemes,
48   // LCL
49   customdrawn_common, customdrawncontrols, customdrawndrawers,
50   lazcanvas, lazregions, lazdeviceapis,
51   LCLPlatformDef, InterfaceBase, Themes, Dialogs, Buttons,
52   Controls,  Forms, lclproc, IntfGraphics, GraphType,
53   LCLType, LMessages, Graphics, LCLStrConsts, Menus, LazLoggerBase;
54 
55 type
56   {$ifdef CD_Windows}
57   TWinCETitlePolicy = (tpAlwaysUseOKButton, tpOKButtonOnlyOnDialogs, tpControlWithBorderIcons);
58 
59   PPPipeEventInfo = ^PPipeEventInfo;
60   PPipeEventInfo = ^TPipeEventInfo;
61   TPipeEventInfo = record
62     Handle: THandle;
63     UserData: PtrInt;
64     OnEvent: TPipeEvent;
65     Prev: PPipeEventInfo;
66     Next: PPipeEventInfo;
67   end;
68 
69   TWaitHandler = record
70     ListIndex: pdword;
71     UserData: PtrInt;
72     OnEvent: TWaitHandleEvent;
73   end;
74 
Socketnull75   TSocketEvent = function(ASocket: THandle; Flags: dword): Integer of object;
76   {$endif}
77   {$ifdef CD_Cocoa}
78 
79   TCDTimerObject=objcclass(NSObject)
80     func : TWSTimerProc;
81     procedure timerEvent; message 'timerEvent';
initWithFuncnull82     class function initWithFunc(afunc: TWSTimerProc): TCDTimerObject; message 'initWithFunc:';
83   end;
84 
85   TCDAppDelegate = objcclass(NSObject, NSApplicationDelegateProtocol)
applicationShouldTerminatenull86     function applicationShouldTerminate(sender: NSApplication): NSApplicationTerminateReply; message 'applicationShouldTerminate:';
87   end;
88   {$endif}
89   {$ifdef CD_X11}
90   // Just in case...
91   {$endif}
92 
93   // Return true to disable the form background drawing
94   TDisableFormBackgroundDrawingProc = function (AForm: TCustomForm): Boolean of object;
95 
96   { TLazCDCustomFont }
97 
98   TLazCDCustomFont = class(TFPCustomFont)
99   public
100     {$ifndef CD_UseNativeText}
101     FTFont: TFreeTypeFont;
102     {$endif}
103     constructor Create; override;
104     destructor Destroy; override;
105   end;
106 
107   { TCDWidgetSet }
108 
109   TCDWidgetSet = class(TWidgetSet)
110   private
111     FTerminating: Boolean;
112 
113     // Clipboard support
114     FClipBoardFormats: TStringList;
115 
116     {$ifdef CD_WINDOWS}
117     // In win32 it is: The parent of all windows, represents the button of the taskbar
118     // In wince it is just an invisible window, but retains the following functions:
119     // * This window is also the owner of the clipboard.
120     // * Assoc. windowproc also acts as handler for popup menus
121     // * It is indispensable for popupmenus and thread synchronization
122     FAppHandle: THandle;
123 
124     FMetrics: TNonClientMetrics;
125     FMetricsFailed: Boolean;
126 
127     FStatusFont: HFONT;
128     FMessageFont: HFONT;
129 
130     FWaitHandleCount: dword;
131     FWaitHandles: array of HANDLE;
132     FWaitHandlers: array of TWaitHandler;
133     FWaitPipeHandlers: PPipeEventInfo;
134 
135     FOnAsyncSocketMsg: TSocketEvent;
136 
WinRegisternull137     function WinRegister: Boolean;
138     procedure CreateAppHandle;
139     {$endif}
140   public
141     {$ifdef CD_X11}
142     FDisplayName: string;
143     FDisplay: PDisplay;
144     FScreen: longint;
145     FVisual: TVisual; // Visual from X11
146 
147     LeaderWindow: X.TWindow;
148     ClientLeaderAtom: TAtom;
149 
150     FWMProtocols: TAtom;	  // Atom for "WM_PROTOCOLS"
151     FWMDeleteWindow: TAtom;	  // Atom for "WM_DELETE_WINDOW"
152     FWMHints: TAtom;		  // Atom for "_MOTIF_WM_HINTS"
153     FWMPaint: TAtom;		  // Atom for "WM_PAINT"
154 
155     // For composing character events
156     ComposeBuffer: string;
157     ComposeStatus: TStatus;
158     InputMethod: xlib.PXIM;
159     InputContext: PXIC;
160     LastKeySym: TKeySym; // Used for KeyRelease event
161     LastKey: Word;       // Used for KeyRelease event
162 
163     ShiftState: TShiftState; // Keeps ShiftState from X
164 
165     // XConnections list
166     XConnections: TFPList;
167     // Windows Info List
168     XWindowList: TStringList;
169     // Timer queue head
170     {$ifdef CD_X11_UseNewTimer}
171     XTimerListHead: customdrawn_x11proc.TCDX11Timer;
172     {$endif}
173 
174     // Functions to keep track of windows needing repaint
CheckInvalidateWindowForXnull175     function CheckInvalidateWindowForX(XWIndowID: X.TWindow): Boolean;
176     procedure WindowUpdated(XWIndowID: X.TWindow);
177 
FindWindowByXIDnull178     function FindWindowByXID(XWindowID: X.TWindow; out AWindowInfo: TX11WindowInfo): TWinControl;
179     procedure AppProcessMessage;
180     procedure AppProcessInvalidates;
XStateToLCLStatenull181     function XStateToLCLState(XKeyState: cuint): TShiftState;
182     {$endif}
183     {$ifdef CD_Android}
184     CombiningAccent: Cardinal;
185     {$IFnDEF WithOldDebugln}
186     procedure AndroidDebugLn(ASender: TObject; AStr: string; var AHandled: Boolean;
187       Target: TLazLoggerWriteTarget; Data: Pointer);
188     {$ELSE}
189     procedure AndroidDebugLn(AStr: string);
190     {$ENDIF}
AndroidKeyCodeToLCLKeyCodenull191     function AndroidKeyCodeToLCLKeyCode(AAndroidKeyCode: Integer): Word;
DoOpenURLWidgetsetImplementationnull192     function DoOpenURLWidgetsetImplementation(AURL: string): Boolean;
DoOpenDocumentWidgetsetImplementationnull193     function DoOpenDocumentWidgetsetImplementation(APath: string): Boolean;
DoOpenAndroidURInull194     function DoOpenAndroidURI(AURI: JObject; AMimeType: string): Boolean;
GetMimeTypeFromFileNamenull195     function GetMimeTypeFromFileName(AFileName: string): string;
196     procedure ShowListViewDialog(ATitle: string; ATitles,
197       ADescriptions: array of string;
198       AColorOddRow: jint = $ff292C29; AColorEvenRow: jint = $ff424542);
199     {$endif}
200     {$ifdef CD_Cocoa}
201     pool      : NSAutoreleasePool;
202     NSApp     : NSApplication;
203     delegate  : TCDAppDelegate;
204     ScreenBitmapContext: CGContextRef;
205     {$endif}
206   // For generic methods added in customdrawn
207   // They are used internally in LCL-CustomDrawn, LCL app should not use them
208   public
209     {$ifndef CD_UseNativeText}
210     // Font Path List
211     FFontPaths: TstringList;
212     FFontList: THashedStringList;
213     // default fonts availability
214     LiberationFont: Boolean;
215     LuxiFont: Boolean;
216     {$endif}
217     // Stock objects
218     FStockBlackBrush: TFPCustomBrush;
219     FStockDKGrayBrush: TFPCustomBrush;
220     FStockGrayBrush: TFPCustomBrush;
221     FStockLtGrayBrush: TFPCustomBrush;
222     FStockNullBrush: TFPCustomBrush;
223     FStockWhiteBrush: TFPCustomBrush;
224 
225     FStockBlackPen: TFPCustomPen;
226     FStockNullPen: TFPCustomPen;
227     FStockWhitePen: TFPCustomPen;
228 
229     DefaultFontSize: Integer;
230     FDefaultGUIFont: TFPCustomFont;
231     //
232     AccumulatedStr: string;
233     // The currently focused control
234     FocusedControl: TWinControl;
235     FocusedIntfControl: TWinControl;
236     // Default Fonts
237     DefaultFont: TFPCustomFont;
238     DefaultFontAndroidSize: Integer;
239     // Mobile emulator and mobile mode
240     MobileMainForm: TLCLIntfHandle;
241     // For unusual implementations of DebugLn/DebugOut
242     {$IFnDEF WithOldDebugln}
243     procedure AccumulatingDebugOut(ASender: TObject; AStr: string; var AHandled: Boolean;
244       Target: TLazLoggerWriteTarget; Data: Pointer);
245     {$ELSE}
246     procedure AccumulatingDebugOut(AStr: string);
247     {$ENDIF}
248     //
249     procedure CDSetFocusToControl(ALCLControl, AIntfControl: TWinControl);
250   //
251   protected
CreateThemeServicesnull252     function CreateThemeServices: TThemeServices; override;
GetAppHandlenull253     function GetAppHandle: THandle; override; //BackendSpecific
254     //procedure SetAppHandle(const AValue: THandle); override;
255     //
256     procedure BackendCreate;
257     procedure BackendDestroy;
258     //
259     procedure GenericAppInit;
260   public
261     // ScreenDC and Image for doing Canvas operations outside the Paint event
262     // and also for text drawing operations
263     ScreenDC: TLazCanvas;
264     ScreenBitmapRawImage: TRawImage;
265     ScreenBitmapHeight: Integer;
266     ScreenBitmapWidth: Integer;
267     ScreenImage: TLazIntfImage;
268     ScreenFormat: TLazCanvasImageFormat;
269 
270     // Android Activity callbacks
271     ActivityOnCreate: TProcedure;
272     ActivityClassName: string;
273 
274     constructor Create; override;
275     destructor Destroy; override;
276 
LCLPlatformnull277     function LCLPlatform: TLCLPlatform; override;
GetLCLCapabilitynull278     function GetLCLCapability(ACapability: TLCLCapability): PtrUInt; override;
279 
280     { Initialize the API }
281     procedure AppInit(var ScreenInfo: TScreenInfo); override;
282     procedure AppRun(const ALoop: TApplicationMainLoop); override;
283     procedure AppWaitMessage; override;
284     procedure AppProcessMessages; override;
285     procedure AppTerminate; override;
286     procedure AppMinimize; override;
287     procedure AppRestore; override;
288     procedure AppBringToFront; override;
289     procedure AppSetIcon(const Small, Big: HICON); override;
290     procedure AppSetTitle(const ATitle: string); override;
291     procedure AppSetVisible(const AVisible: Boolean); override;
AppRemoveStayOnTopFlagsnull292     function AppRemoveStayOnTopFlags(const ASystemTopAlso: Boolean = False): Boolean; override;
AppRestoreStayOnTopFlagsnull293     function AppRestoreStayOnTopFlags(const ASystemTopAlso: Boolean = False): Boolean; override;
294     procedure AppSetMainFormOnTaskBar(const DoSet: Boolean); override;
295 
InitStockFontnull296     //function  InitStockFont(AFont: TObject; AStockFont: TStockFont): Boolean; override;
297 
298     procedure DCSetPixel(CanvasHandle: HDC; X, Y: integer; AColor: TGraphicsColor); override;
DCGetPixelnull299     function  DCGetPixel(CanvasHandle: HDC; X, Y: integer): TGraphicsColor; override;
300     procedure DCRedraw(CanvasHandle: HDC); override;
301     procedure DCSetAntialiasing(CanvasHandle: HDC; AEnabled: Boolean); override;
302     procedure SetDesigning(AComponent: TComponent); override;
303 
304     // create and destroy
CreateTimernull305     function CreateTimer(Interval: integer; TimerFunc: TWSTimerProc): THandle; override;
DestroyTimernull306     function DestroyTimer(TimerHandle: THandle): boolean; override;
307 
308     {$I customdrawnwinapih.inc}
309     {$I customdrawnlclintfh.inc}
310   public
311     { Variables to be set by the user }
312     {$ifdef WinCE}
313     WinCETitlePolicy: TWinCETitlePolicy;
314     {$endif}
315 
316     // This callback might be set to provide a routine which will select for
317     // which forms the drawing of the background should be disabled
318     // This is provided for speeding up the drawing
319     //
320     // Only use it if you are 100% sure that you are filling the entire buffer
321     // in the form paint event. Note that the form might sometimes be smaller
322     // then the buffer in Android so fill the entire Canvas area, not only the form size
323     DisableFormBackgroundDrawingProc: TDisableFormBackgroundDrawingProc;
324   end;
325 
326 var
327   CDWidgetSet: TCDWidgetSet absolute WidgetSet;
328 
CDMessageBoxFunctionnull329 function CDMessageBoxFunction(Text, Caption : PChar; Flags : Longint) : Integer;
330 
331 {$ifdef CD_WINDOWS}
WindowProcnull332 function WindowProc(Window: HWnd; Msg: UInt; WParam: Windows.WParam;
333   LParam: Windows.LParam): LResult; {$ifdef WinCE}cdecl;{$else}stdcall;{$endif}
334 {$endif}
335 {$ifdef CD_X11}
336 procedure MyXConnectionWatchProc(display: PDisplay; client_data: TXPointer;
337   fd: cint; opening: XLib.TBool; watch_data: PXPointer); cdecl;
338 {$endif}
339 {$ifdef CD_Android}
Java_com_pascal_lclproject_LCLActivity_LCLOnTouchnull340 function Java_com_pascal_lclproject_LCLActivity_LCLOnTouch(env:PJNIEnv;this:jobject; x, y: single; action: jint): jint; cdecl;
Java_com_pascal_lclproject_LCLActivity_LCLDrawToBitmapnull341 function Java_com_pascal_lclproject_LCLActivity_LCLDrawToBitmap(
342     env:PJNIEnv;this:jobject; width, height: jint; abitmap: jobject): jint; cdecl;
Java_com_pascal_lclproject_LCLActivity_LCLOnCreatenull343 function Java_com_pascal_lclproject_LCLActivity_LCLOnCreate(
344     env:PJNIEnv; this:jobject; alclactivity: jobject): jint; cdecl;
Java_com_pascal_lclproject_LCLActivity_LCLOnMessageBoxFinishednull345 function Java_com_pascal_lclproject_LCLActivity_LCLOnMessageBoxFinished(
346     env:PJNIEnv; this:jobject; AResult, ADialogType: jint): jint; cdecl;
Java_com_pascal_lclproject_LCLActivity_LCLOnKeynull347 function Java_com_pascal_lclproject_LCLActivity_LCLOnKey(
348     env:PJNIEnv; this:jobject; AKind: jint; AKeyCode: jint;
349     AEvent: jobject; AChar: jint): jint; cdecl;
Java_com_pascal_lclproject_LCLActivity_LCLOnTimernull350 function Java_com_pascal_lclproject_LCLActivity_LCLOnTimer(
351     env:PJNIEnv; this:jobject; ATimer: jobject; ATimerIDIndex: jint): jint; cdecl;
Java_com_pascal_lclproject_LCLActivity_LCLOnConfigurationChangednull352 function Java_com_pascal_lclproject_LCLActivity_LCLOnConfigurationChanged(
353     env:PJNIEnv; this:jobject; ANewDPI, ANewWidth: jint): jint; cdecl;
Java_com_pascal_lclproject_LCLActivity_LCLOnSensorChangednull354 function Java_com_pascal_lclproject_LCLActivity_LCLOnSensorChanged(
355     env:PJNIEnv; this:jobject; ASensorKind: jint; AValues: JDoubleArray): jint; cdecl;
Java_com_pascal_lclproject_LCLActivity_LCLOnMenuActionnull356 function Java_com_pascal_lclproject_LCLActivity_LCLOnMenuAction(
357   env:PJNIEnv; this:jobject; kind, itemIndex: jint): jint; cdecl;
JNI_OnLoadnull358 function JNI_OnLoad(vm:PJavaVM;reserved:pointer):jint; cdecl;
359 procedure JNI_OnUnload(vm:PJavaVM;reserved:pointer); cdecl;
360 
361 var
362   javaVMRef: PJavaVM=nil;
363   javaEnvRef: PJNIEnv=nil;
364   javaActivityClass: JClass = nil;
365   javaActivityObject: jobject = nil;
366 
367   // The SDK Version
368   android_os_Build_VERSION_SDK_INT: jint;
369 
370   // Other classes and objects
371   javaAndroidAppActivityClass: JClass = nil;
372   javaJavaLangSystemClass: JClass = nil;
373   javaAndroidOSBuildClass: JClass = nil;
374   javaAndroidOSVibratorClass: JClass = nil;
375   javaAndroidContentContextClass: JClass = nil;
376   javaJavaLangStringClass: JClass = nil;
377   javaAndroidOSBuildVERSIONClass: JClass = nil;
378 
379   // Other fields
380   javaField_VERSION_SDK_INT: JFieldID = nil;
381   // Fields of our Activity
382   // Strings
383   javaField_lcltext: JfieldID=nil;
384   javaField_lcltitle: JfieldID=nil;
385   javaField_lclbutton1str: JfieldID=nil;
386   javaField_lclbutton2str: JfieldID=nil;
387   javaField_lclbutton3str: JfieldID=nil;
388   // Integers
389   javaField_lclwidth: JfieldID=nil;
390   javaField_lclheight: JfieldID=nil;
391   javaField_lclbutton1: JfieldID=nil;
392   javaField_lclbutton2: JfieldID=nil;
393   javaField_lclbutton3: JfieldID=nil;
394   javaField_lclbitmap: JfieldID=nil;
395   javaField_lcltextsize: JfieldID=nil;
396   // Text metrics
397   javaField_lcltextascent: JfieldID=nil;
398   javaField_lcltextbottom: JfieldID=nil;
399   javaField_lcltextdescent: JfieldID=nil;
400   javaField_lcltextleading: JfieldID=nil;
401   javaField_lcltexttop: JfieldID=nil;
402   javaField_lclmaxwidth: JfieldID=nil;
403   javaField_lclmaxcount: JfieldID=nil;
404   javaField_lclpartialwidths: JfieldID=nil;
405   // Timer
406   javaField_lcltimerinterval: JfieldID=nil;
407   javaField_lcltimerid: JfieldID=nil;
408   // Screen Metrics
409   javaField_lclxdpi: JfieldID=nil;
410   javaField_lclydpi: JfieldID=nil;
411   javaField_lclformwidth: JfieldID=nil;
412   javaField_lclformheight: JfieldID=nil;
413   javaField_lclscreenwidth: JfieldID=nil;
414   javaField_lclscreenheight: JfieldID=nil;
415   // For LazDeviceAPIs
416   javaField_lcldestination: JfieldID=nil;
417   javaField_lclkind: JfieldID=nil;
418 
419   // Methods of our Activity
420   javaMethod_LCLDoGetTextBounds: jmethodid = nil;
421   javaMethod_LCLDoGetTextPartialWidths: jmethodid = nil;
422   javaMethod_LCLDoDrawText: jmethodid = nil;
423   javaMethod_LCLDoShowMessageBox: jmethodid = nil;
424   javaMethod_LCLDoCreateTimer: jmethodid = nil;
425   javaMethod_LCLDoDestroyTimer: jmethodid = nil;
426   javaMethod_LCLDoHideVirtualKeyboard: jmethodid = nil;
427   javaMethod_LCLDoShowVirtualKeyboard: jmethodid = nil;
428   javaMethod_LCLDoStartReadingAccelerometer: jmethodid = nil;
429   javaMethod_LCLDoStopReadingAccelerometer: jmethodid = nil;
430   javaMethod_LCLDoSendMessage: jmethodid = nil;
431   javaMethod_LCLDoRequestPositionInfo: jmethodid = nil;
432   // Methods from android.app.Activity
433   javaMethod_Activity_finish: jmethodid = nil;
434   // Methods from java.lang.System
435   javaMethod_System_exit: jmethodid = nil;
436   // Generic methods from Context
437   javaMethod_getSystemService: jmethodid = nil;
438 
439   // This is utilized to store the information such as invalidate requests in events
440   eventResult: jint;
441 {$endif}
442 
443 implementation
444 
445 uses
446   WsControls, lclintf,
447   CustomDrawnWSFactory,
448   CustomDrawnWSForms,
449 {  Win32WSButtons,
450   Win32WSMenus,
451   Win32WSStdCtrls,
452   Win32WSDialogs,
453   Win32Themes,
454 ////////////////////////////////////////////////////
455   Win32Extra,}
456   customdrawnprivate,
457   LCLMessageGlue;
458 
459   {$ifdef CD_Windows}
460 const
461   CDBackendNativeHandle = nhtWindowsHWND;
462   {$define CD_HasNativeFormHandle}
463   {$endif}
464   {$ifdef CD_X11}
465 const
466   CDBackendNativeHandle = nhtX11TWindow;
467   {$define CD_HasNativeFormHandle}
468   {$endif}
469   {$ifdef CD_Cocoa}
470 const
471   CDBackendNativeHandle = nhtCocoaNSWindow;
472   {$define CD_HasNativeFormHandle}
473   {$endif}
474 
475 { TLazCDCustomFont }
476 
477 constructor TLazCDCustomFont.Create;
478 begin
479   inherited Create;
480   {$ifndef CD_UseNativeText}
481   FTFont := TFreeTypeFont.Create;
482   {$endif}
483 end;
484 
485 destructor TLazCDCustomFont.Destroy;
486 begin
487   {$ifndef CD_UseNativeText}
488   FTFont.Free;
489   {$endif}
490   inherited Destroy;
491 end;
492 
493 {$I customdrawnobject.inc}
494 
495 {$I customdrawnwinapi.inc}
496 {$I customdrawnlclintf.inc}
497 
498 {$ifdef CD_Windows}
499   {$include wincallback.inc}
500   {$I customdrawnobject_win.inc}
501   {$I customdrawnwinapi_win.inc}
502   {$I customdrawnlclintf_win.inc}
503 {$endif}
504 {$ifdef CD_Cocoa}
505   {$I customdrawnobject_cocoa.inc}
506   {$I customdrawnwinapi_cocoa.inc}
507   {$I customdrawnlclintf_cocoa.inc}
508 {$endif}
509 {$ifdef CD_X11}
510   {$I customdrawnobject_x11.inc}
511   {$I customdrawnwinapi_x11.inc}
512   {$I customdrawnlclintf_x11.inc}
513 {$endif}
514 {$ifdef CD_Android}
515   {$I customdrawnobject_android.inc}
516   {$I customdrawnwinapi_android.inc}
517   {$I customdrawnlclintf_android.inc}
518 {$endif}
519 
520 end.
521