1
0
mirror of https://github.com/salvadordf/CEF4Delphi.git synced 2025-09-30 21:28:55 +02:00
Files
CEF4Delphi/source/uCEFLinuxFunctions.pas
2025-09-18 19:31:58 +02:00

887 lines
26 KiB
ObjectPascal

unit uCEFLinuxFunctions;
{$IFDEF FPC}
{$MODE OBJFPC}{$H+}
{$ENDIF}
{$I cef.inc}
{$IFNDEF TARGET_64BITS}{$ALIGN ON}{$ENDIF}
{$MINENUMSIZE 4}
interface
uses
{$IFDEF LINUX}
{$IFDEF FPC}
ctypes, keysym, xf86keysym, x, xlib, LCLVersion,
{$IFDEF LCLGTK2}gtk2, glib2, gdk2, gtk2proc, gtk2int, Gtk2Def, gdk2x, Gtk2Extra,{$ENDIF}
{$IFDEF LCLGTK3}LazGdk3, LazGtk3, LazGObject2, LazGLib2, gtk3objects, gtk3procs,{$ENDIF}
{$IFDEF LCLQT}qt4,{$ENDIF}
{$IFDEF LCLQT5}qt5,{$ENDIF}
{$IFDEF LCLQT6}qt6,{$ENDIF}
{$ENDIF}
{$ENDIF}
uCEFLinuxTypes, uCEFTypes;
{$IFNDEF FPC}
const
// We define this constant only to avoid warnings in Delphi
LCL_FULLVERSION = 3000001;
{$ENDIF}
{$IFDEF LINUX}
function KeyboardCodeFromXKeysym(keysym : uint32) : integer;
{$IF DEFINED(LINUXFMX) or DEFINED(LCLGTK2) or (DEFINED(LCLGTK3) and (LCL_FULLVERSION<3000000))}
function GetCefStateModifiers(state : uint32) : integer;
{$IFEND}
{$IF DEFINED(LCLGTK3) and (LCL_FULLVERSION>3000000)}
function GetCefStateModifiers(state : TGdkModifierType) : integer;
{$IFEND}
function GetWindowsKeyCodeWithoutLocation(key_code : integer) : integer;
function GetControlCharacter(windows_key_code : integer; shift : boolean) : integer;
{$IF DEFINED(LINUXFMX) or DEFINED(LCLGTK2) or DEFINED(LCLGTK3)}
procedure GdkEventKeyToCEFKeyEvent(GdkEvent: PGdkEventKey; var aCEFKeyEvent : TCEFKeyEvent);
function GdkEventToWindowsKeyCode(Event: PGdkEventKey) : integer;
{$IFEND}
{$IF DEFINED(LCLQT) OR DEFINED(LCLQT5) OR DEFINED(LCLQT6)}
function GetCefStateModifiers(KeyboardModifiers : QtKeyboardModifiers; NativeModifiers : LongWord) : TCefEventFlags;
function GetCefWindowsKeyCode(key : QtKey) : integer;
procedure QTKeyEventToCEFKeyEvent(Event_ : QKeyEventH; var aCEFKeyEvent : TCEFKeyEvent);
{$IFEND}
{$IFDEF FMX}
type
TXErrorHandler = function (para1:PDisplay; para2:PXErrorEvent):longint; cdecl;
TXIOErrorHandler = function (para1:PDisplay):longint; cdecl;
function XSetErrorHandler(para1:TXErrorHandler):TXErrorHandler; cdecl; external 'libX11.so';
function XSetIOErrorHandler(para1:TXIOErrorHandler):TXIOErrorHandler; cdecl; external 'libX11.so';
function gdk_keyval_to_unicode(keyval: guint): guint32; cdecl; external 'libgdk-3.so';
function g_signal_connect_data(instance: gpointer; detailed_signal: Pgchar; c_handler: TGCallback; data: gpointer; destroy_data: TGClosureNotify; connect_flags: TGConnectFlags): gulong; cdecl; external 'libgobject-2.0.so';
function g_signal_connect(instance: gpointer; detailed_signal: Pgchar; c_handler: TGCallback; data: gpointer): gulong; overload;
function g_signal_connect(instance: gpointer; const detailed_signal: AnsiString; c_handler: TGCallback; data: gpointer): gulong; overload;
function gdk_screen_width:gint; cdecl; external 'libgdk-3.so';
function gdk_screen_width_mm:gint; cdecl; external 'libgdk-3.so';
function gdk_screen_get_default:PGdkScreen; cdecl; external 'libgdk-3.so';
function gdk_screen_get_resolution(screen:PGdkScreen):gdouble; cdecl; external 'libgdk-3.so';
{$ENDIF}
{$IFDEF FPC}
{$IFDEF LCLGTK3}
function gdk_x11_window_get_xid(window: PGdkWindow): TXID; cdecl; external 'libgdk-3.so.0';
function gdk_x11_get_default_xdisplay: PDisplay; cdecl; external 'libgdk-3.so.0';
procedure gdk_set_allowed_backends(const backends: PGchar); cdecl; external 'libgdk-3.so.0';
function gdk_x11_display_get_xdisplay(display: PGdkDisplay): PDisplay; cdecl; external 'libgdk-3.so.0';
function gdk_x11_screen_get_screen_number(screen: PGdkScreen): longint; cdecl; external 'libgdk-3.so.0';
function gdk_x11_visual_get_xvisual(visual: PGdkVisual): PVisual; cdecl; external 'libgdk-3.so.0';
procedure UseDefaultX11VisualForGtk(widget : PGtkWidget);
procedure FlushDisplay(widget : PGtkWidget);
{$ENDIF}
procedure ShowX11Message(const aMessage : string);
{$ENDIF}{$ENDIF}
implementation
uses
{$IFDEF DELPHI16_UP}
System.SysUtils,
{$ELSE}
SysUtils,
{$ENDIF}
{$IFDEF LCLGTK3}gtk3widgets,{$ENDIF}
uCEFLinuxConstants, uCEFConstants;
{$IFDEF LINUX}
function KeyboardCodeFromXKeysym(keysym : uint32) : integer;
begin
case keysym of
XK_BackSpace:
Result := VKEY_BACK;
XK_Delete,
XK_KP_Delete:
Result := VKEY_DELETE;
XK_Tab,
XK_KP_Tab,
XK_ISO_Left_Tab,
XK_3270_BackTab:
Result := VKEY_TAB;
XK_Linefeed,
XK_Return,
XK_KP_Enter,
XK_ISO_Enter:
Result := VKEY_Return;
XK_Clear,
XK_KP_Begin:
Result := VKEY_CLEAR;
XK_KP_Space,
XK_space:
Result := VKEY_SPACE;
XK_Home,
XK_KP_Home:
Result := VKEY_HOME;
XK_End,
XK_KP_End:
Result := VKEY_END;
XK_Page_Up,
XK_KP_Page_Up:
Result := VKEY_PRIOR;
XK_Page_Down,
XK_KP_Page_Down:
Result := VKEY_NEXT;
XK_Left,
XK_KP_Left:
Result := VKEY_LEFT;
XK_Right,
XK_KP_Right:
Result := VKEY_RIGHT;
XK_Down,
XK_KP_Down:
Result := VKEY_DOWN;
XK_Up,
XK_KP_Up:
Result := VKEY_UP;
XK_Escape:
Result := VKEY_ESCAPE;
XK_Kana_Lock,
XK_Kana_Shift:
Result := VKEY_KANA;
XK_Hangul:
Result := VKEY_HANGUL;
XK_Hangul_Hanja:
Result := VKEY_HANJA;
XK_Kanji:
Result := VKEY_KANJI;
XK_Henkan:
Result := VKEY_CONVERT;
XK_Muhenkan:
Result := VKEY_NONCONVERT;
XK_Zenkaku_Hankaku:
Result := VKEY_DBE_DBCSCHAR;
XKc_A,
XK_a:
Result := VKEY_A;
XKc_B,
XK_b:
Result := VKEY_B;
XKc_C,
XK_c:
Result := VKEY_C;
XKc_D,
XK_d:
Result := VKEY_D;
XKc_E,
XK_e:
Result := VKEY_E;
XKc_F,
XK_f:
Result := VKEY_F;
XKc_G,
XK_g:
Result := VKEY_G;
XKc_H,
XK_h:
Result := VKEY_H;
XKc_I,
XK_i:
Result := VKEY_I;
XKc_J,
XK_j:
Result := VKEY_J;
XKc_K,
XK_k:
Result := VKEY_K;
XKc_L,
XK_l:
Result := VKEY_L;
XKc_M,
XK_m:
Result := VKEY_M;
XKc_N,
XK_n:
Result := VKEY_N;
XKc_O,
XK_o:
Result := VKEY_O;
XKc_P,
XK_p:
Result := VKEY_P;
XKc_Q,
XK_q:
Result := VKEY_Q;
XKc_R,
XK_r:
Result := VKEY_R;
XKc_S,
XK_s:
Result := VKEY_S;
XKc_T,
XK_t:
Result := VKEY_T;
XKc_U,
XK_u:
Result := VKEY_U;
XKc_V,
XK_v:
Result := VKEY_V;
XKc_W,
XK_w:
Result := VKEY_W;
XKc_X,
XK_x:
Result := VKEY_X;
XKc_Y,
XK_y:
Result := VKEY_Y;
XKc_Z,
XK_z:
Result := VKEY_Z;
XK_0,
XK_1,
XK_2,
XK_3,
XK_4,
XK_5,
XK_6,
XK_7,
XK_8,
XK_9:
Result := VKEY_0 + (keysym - XK_0);
XK_parenright:
Result := VKEY_0;
XK_exclam:
Result := VKEY_1;
XK_at:
Result := VKEY_2;
XK_numbersign:
Result := VKEY_3;
XK_dollar:
Result := VKEY_4;
XK_percent:
Result := VKEY_5;
XK_asciicircum:
Result := VKEY_6;
XK_ampersand:
Result := VKEY_7;
XK_asterisk:
Result := VKEY_8;
XK_parenleft:
Result := VKEY_9;
XK_KP_0,
XK_KP_1,
XK_KP_2,
XK_KP_3,
XK_KP_4,
XK_KP_5,
XK_KP_6,
XK_KP_7,
XK_KP_8,
XK_KP_9:
Result := VKEY_NUMPAD0 + (keysym - XK_KP_0);
XK_multiply,
XK_KP_Multiply:
Result := VKEY_MULTIPLY;
XK_KP_Add:
Result := VKEY_ADD;
XK_KP_Separator:
Result := VKEY_SEPARATOR;
XK_KP_Subtract:
Result := VKEY_SUBTRACT;
XK_KP_Decimal:
Result := VKEY_DECIMAL;
XK_KP_Divide:
Result := VKEY_DIVIDE;
XK_KP_Equal,
XK_equal,
XK_plus:
Result := VKEY_OEM_PLUS;
XK_comma,
XK_less:
Result := VKEY_OEM_COMMA;
XK_minus,
XK_underscore:
Result := VKEY_OEM_MINUS;
XK_greater,
XK_period:
Result := VKEY_OEM_PERIOD;
XK_colon,
XK_semicolon:
Result := VKEY_OEM_1;
XK_question,
XK_slash:
Result := VKEY_OEM_2;
XK_asciitilde,
XK_quoteleft:
Result := VKEY_OEM_3;
XK_bracketleft,
XK_braceleft:
Result := VKEY_OEM_4;
XK_backslash,
XK_bar:
Result := VKEY_OEM_5;
XK_bracketright,
XK_braceright:
Result := VKEY_OEM_6;
XK_quoteright,
XK_quotedbl:
Result := VKEY_OEM_7;
XK_ISO_Level5_Shift:
Result := VKEY_OEM_8;
XK_Shift_L,
XK_Shift_R:
Result := VKEY_SHIFT;
XK_Control_L,
XK_Control_R:
Result := VKEY_CONTROL;
XK_Meta_L,
XK_Meta_R,
XK_Alt_L,
XK_Alt_R:
Result := VKEY_MENU;
XK_ISO_Level3_Shift:
Result := VKEY_ALTGR;
XK_Multi_key:
Result := VKEY_COMPOSE;
XK_Pause:
Result := VKEY_PAUSE;
XK_Caps_Lock:
Result := VKEY_CAPITAL;
XK_Num_Lock:
Result := VKEY_NUMLOCK;
XK_Scroll_Lock:
Result := VKEY_SCROLL;
XK_Select:
Result := VKEY_SELECT;
XK_Print:
Result := VKEY_PRINT;
XK_Execute:
Result := VKEY_EXECUTE;
XK_Insert,
XK_KP_Insert:
Result := VKEY_INSERT;
XK_Help:
Result := VKEY_HELP;
XK_Super_L:
Result := VKEY_LWIN;
XK_Super_R:
Result := VKEY_RWIN;
XK_Menu:
Result := VKEY_APPS;
XK_F1,
XK_F2,
XK_F3,
XK_F4,
XK_F5,
XK_F6,
XK_F7,
XK_F8,
XK_F9,
XK_F10,
XK_F11,
XK_F12,
XK_F13,
XK_F14,
XK_F15,
XK_F16,
XK_F17,
XK_F18,
XK_F19,
XK_F20,
XK_F21,
XK_F22,
XK_F23,
XK_F24:
Result := VKEY_F1 + (keysym - XK_F1);
XK_KP_F1,
XK_KP_F2,
XK_KP_F3,
XK_KP_F4:
Result := VKEY_F1 + (keysym - XK_KP_F1);
XK_guillemotleft,
XK_guillemotright,
XK_degree,
XK_ugrave,
XKc_Ugrave,
XK_brokenbar:
Result := VKEY_OEM_102;
XF86XK_Tools:
Result := VKEY_F13;
XF86XK_Launch5:
Result := VKEY_F14;
XF86XK_Launch6:
Result := VKEY_F15;
XF86XK_Launch7:
Result := VKEY_F16;
XF86XK_Launch8:
Result := VKEY_F17;
XF86XK_Launch9:
Result := VKEY_F18;
XF86XK_Refresh,
XF86XK_History,
XF86XK_OpenURL,
XF86XK_AddFavorite,
XF86XK_Go,
XF86XK_ZoomIn,
XF86XK_ZoomOut:
Result := VKEY_UNKNOWN;
XF86XK_Back:
Result := VKEY_BROWSER_BACK;
XF86XK_Forward:
Result := VKEY_BROWSER_FORWARD;
XF86XK_Reload:
Result := VKEY_BROWSER_REFRESH;
XF86XK_Stop:
Result := VKEY_BROWSER_STOP;
XF86XK_Search:
Result := VKEY_BROWSER_SEARCH;
XF86XK_Favorites:
Result := VKEY_BROWSER_FAVORITES;
XF86XK_HomePage:
Result := VKEY_BROWSER_HOME;
XF86XK_AudioMute:
Result := VKEY_VOLUME_MUTE;
XF86XK_AudioLowerVolume:
Result := VKEY_VOLUME_DOWN;
XF86XK_AudioRaiseVolume:
Result := VKEY_VOLUME_UP;
XF86XK_AudioNext:
Result := VKEY_MEDIA_NEXT_TRACK;
XF86XK_AudioPrev:
Result := VKEY_MEDIA_PREV_TRACK;
XF86XK_AudioStop:
Result := VKEY_MEDIA_STOP;
XF86XK_AudioPlay:
Result := VKEY_MEDIA_PLAY_PAUSE;
XF86XK_Mail:
Result := VKEY_MEDIA_LAUNCH_MAIL;
XF86XK_LaunchA:
Result := VKEY_MEDIA_LAUNCH_APP1;
XF86XK_LaunchB,
XF86XK_Calculator:
Result := VKEY_MEDIA_LAUNCH_APP2;
XF86XK_WLAN:
Result := VKEY_WLAN;
XF86XK_PowerOff:
Result := VKEY_POWER;
XF86XK_MonBrightnessDown:
Result := VKEY_BRIGHTNESS_DOWN;
XF86XK_MonBrightnessUp:
Result := VKEY_BRIGHTNESS_UP;
XF86XK_KbdBrightnessDown:
Result := VKEY_KBD_BRIGHTNESS_DOWN;
XF86XK_KbdBrightnessUp:
Result := VKEY_KBD_BRIGHTNESS_UP;
else Result := VKEY_UNKNOWN;
end;
end;
{$IF DEFINED(LINUXFMX) or DEFINED(LCLGTK2) or (DEFINED(LCLGTK3) and (LCL_FULLVERSION<3000000))}
function GetCefStateModifiers(state : uint32) : integer;
begin
Result := EVENTFLAG_NONE;
if ((state and GDK_SHIFT_MASK) <> 0) then
Result := Result or EVENTFLAG_SHIFT_DOWN;
if ((state and GDK_LOCK_MASK) <> 0) then
Result := Result or EVENTFLAG_CAPS_LOCK_ON;
if ((state and GDK_CONTROL_MASK) <> 0) then
Result := Result or EVENTFLAG_CONTROL_DOWN;
if ((state and GDK_MOD1_MASK) <> 0) then
Result := Result or EVENTFLAG_ALT_DOWN;
if ((state and GDK_BUTTON1_MASK) <> 0) then
Result := Result or EVENTFLAG_LEFT_MOUSE_BUTTON;
if ((state and GDK_BUTTON2_MASK) <> 0) then
Result := Result or EVENTFLAG_MIDDLE_MOUSE_BUTTON;
if ((state and GDK_BUTTON3_MASK) <> 0) then
Result := Result or EVENTFLAG_RIGHT_MOUSE_BUTTON;
end;
{$IFEND}
{$IF DEFINED(LCLGTK3) and (LCL_FULLVERSION>3000000)}
function GetCefStateModifiers(state : TGdkModifierType) : integer;
begin
Result := EVENTFLAG_NONE;
if (GDK_SHIFT_MASK in state) then
Result := Result or EVENTFLAG_SHIFT_DOWN;
if (GDK_LOCK_MASK in state) then
Result := Result or EVENTFLAG_CAPS_LOCK_ON;
if (GDK_CONTROL_MASK in state) then
Result := Result or EVENTFLAG_CONTROL_DOWN;
if (GDK_MOD1_MASK in state) then
Result := Result or EVENTFLAG_ALT_DOWN;
if (GDK_BUTTON1_MASK in state) then
Result := Result or EVENTFLAG_LEFT_MOUSE_BUTTON;
if (GDK_BUTTON2_MASK in state) then
Result := Result or EVENTFLAG_MIDDLE_MOUSE_BUTTON;
if (GDK_BUTTON3_MASK in state) then
Result := Result or EVENTFLAG_RIGHT_MOUSE_BUTTON;
end;
{$IFEND}
function GetWindowsKeyCodeWithoutLocation(key_code : integer) : integer;
begin
case key_code of
VKEY_LCONTROL, VKEY_RCONTROL : Result := VKEY_CONTROL;
VKEY_LSHIFT, VKEY_RSHIFT : Result := VKEY_SHIFT;
VKEY_LMENU, VKEY_RMENU : Result := VKEY_MENU;
else Result := key_code;
end;
end;
function GetControlCharacter(windows_key_code : integer; shift : boolean) : integer;
begin
if (windows_key_code >= VKEY_A) and (windows_key_code <= VKEY_Z) then
Result := windows_key_code - VKEY_A + 1
else
if shift then
case windows_key_code of
VKEY_2 : Result := 0;
VKEY_6 : Result := $1E;
VKEY_OEM_MINUS : Result := $1F;
else Result := 0;
end
else
case windows_key_code of
VKEY_OEM_4 : Result := $1B;
VKEY_OEM_5 : Result := $1C;
VKEY_OEM_6 : Result := $1D;
VKEY_RETURN : Result := $0A;
else Result := 0;
end;
end;
{$IF DEFINED(LINUXFMX) or DEFINED(LCLGTK2) or DEFINED(LCLGTK3)}
procedure GdkEventKeyToCEFKeyEvent(GdkEvent: PGdkEventKey; var aCEFKeyEvent : TCEFKeyEvent);
var
windows_key_code : integer;
begin
windows_key_code := GdkEventToWindowsKeyCode(GdkEvent);
aCEFKeyEvent.size := SizeOf(TCEFKeyEvent);
aCEFKeyEvent.windows_key_code := GetWindowsKeyCodeWithoutLocation(windows_key_code);
aCEFKeyEvent.native_key_code := GdkEvent^.hardware_keycode;
aCEFKeyEvent.modifiers := GetCefStateModifiers(GdkEvent^.state);
aCEFKeyEvent.focus_on_editable_field := 0;
if (GdkEvent^.keyval >= GDK_KP_Space) and (GdkEvent^.keyval <= GDK_KP_9) then
aCEFKeyEvent.modifiers := aCEFKeyEvent.modifiers or EVENTFLAG_IS_KEY_PAD;
aCEFKeyEvent.is_system_key := ord((aCEFKeyEvent.modifiers and EVENTFLAG_ALT_DOWN) <> 0);
if (windows_key_code = VKEY_RETURN) then
aCEFKeyEvent.unmodified_character := #13
else
aCEFKeyEvent.unmodified_character := WideChar(gdk_keyval_to_unicode(GdkEvent^.keyval));
if ((aCEFKeyEvent.modifiers and EVENTFLAG_CONTROL_DOWN) <> 0) then
aCEFKeyEvent.character := WideChar(GetControlCharacter(windows_key_code, ((aCEFKeyEvent.modifiers and EVENTFLAG_SHIFT_DOWN) <> 0)))
else
aCEFKeyEvent.character := aCEFKeyEvent.unmodified_character;
end;
function GdkEventToWindowsKeyCode(event: PGdkEventKey) : integer;
var
windows_key_code, keyval : integer;
begin
windows_key_code := KeyboardCodeFromXKeysym(event^.keyval);
if (windows_key_code <> 0) then
begin
Result := windows_key_code;
exit;
end;
if (event^.hardware_keycode < length(kHardwareCodeToGDKKeyval)) then
begin
keyval := kHardwareCodeToGDKKeyval[event^.hardware_keycode];
if (keyval <> 0) then
begin
Result := KeyboardCodeFromXKeysym(keyval);
exit;
end;
end;
Result := KeyboardCodeFromXKeysym(event^.keyval);
end;
{$IFEND}
{$IF DEFINED(LCLQT) OR DEFINED(LCLQT5) OR DEFINED(LCLQT6)}
function GetCefStateModifiers(KeyboardModifiers : QtKeyboardModifiers; NativeModifiers : LongWord) : TCefEventFlags;
Const
GDK_SHIFT_MASK = 1 shl 0;
GDK_LOCK_MASK = 1 shl 1;
GDK_CONTROL_MASK = 1 shl 2;
GDK_MOD1_MASK = 1 shl 3;
GDK_BUTTON1_MASK = 1 shl 8;
GDK_BUTTON2_MASK = 1 shl 9;
GDK_BUTTON3_MASK = 1 shl 10;
begin
Result := EVENTFLAG_NONE;
if (KeyboardModifiers and QtShiftModifier) <> 0 then Result := Result or EVENTFLAG_SHIFT_DOWN;
if (KeyboardModifiers and QtControlModifier) <> 0 then Result := Result or EVENTFLAG_CONTROL_DOWN;
if (KeyboardModifiers and QtAltModifier) <> 0 then Result := Result or EVENTFLAG_ALT_DOWN;
if (KeyboardModifiers and QtKeypadModifier) <> 0 then Result := Result or EVENTFLAG_IS_KEY_PAD;
if (NativeModifiers and GDK_SHIFT_MASK) <> 0 then Result := Result or EVENTFLAG_SHIFT_DOWN;
if (NativeModifiers and GDK_LOCK_MASK) <> 0 then Result := Result or EVENTFLAG_CAPS_LOCK_ON;
if (NativeModifiers and GDK_CONTROL_MASK) <> 0 then Result := Result or EVENTFLAG_CONTROL_DOWN;
if (NativeModifiers and GDK_MOD1_MASK) <> 0 then Result := Result or EVENTFLAG_ALT_DOWN;
if (NativeModifiers and GDK_BUTTON1_MASK) <> 0 then Result := Result or EVENTFLAG_LEFT_MOUSE_BUTTON;
if (NativeModifiers and GDK_BUTTON2_MASK) <> 0 then Result := Result or EVENTFLAG_MIDDLE_MOUSE_BUTTON;
if (NativeModifiers and GDK_BUTTON3_MASK) <> 0 then Result := Result or EVENTFLAG_RIGHT_MOUSE_BUTTON;
end;
function GetCefWindowsKeyCode(key : QtKey): integer;
begin
case key of
QtKey_Escape : Result := VKEY_ESCAPE;
QtKey_Tab,
QtKey_Backtab : Result := VKEY_TAB;
QtKey_Backspace : Result := VKEY_BACK;
QtKey_Return,
QtKey_Enter : Result := VKEY_RETURN;
QtKey_Insert : Result := VKEY_INSERT;
QtKey_Delete : Result := VKEY_DELETE;
QtKey_Pause : Result := VKEY_PAUSE;
QtKey_Print : Result := VKEY_PRINT;
QtKey_Clear : Result := VKEY_CLEAR;
QtKey_Home : Result := VKEY_HOME;
QtKey_End : Result := VKEY_END;
QtKey_Left : Result := VKEY_LEFT;
QtKey_Up : Result := VKEY_UP;
QtKey_Right : Result := VKEY_RIGHT;
QtKey_Down : Result := VKEY_DOWN;
QtKey_PageUp : Result := VKEY_PRIOR;
QtKey_PageDown : Result := VKEY_NEXT;
QtKey_Shift : Result := VKEY_SHIFT;
QtKey_Control : Result := VKEY_CONTROL;
QtKey_Alt : Result := VKEY_MENU;
QtKey_CapsLock : Result := VKEY_CAPITAL;
QtKey_NumLock : Result := VKEY_NUMLOCK;
QtKey_ScrollLock : Result := VKEY_SCROLL;
QtKey_F1..QtKey_F24 : Result := key - QtKey_F1 + VKEY_F1;
QtKey_Help : Result := VKEY_HELP;
QtKey_Space : Result := VKEY_SPACE;
QtKey_Exclam : Result := VKEY_1;
QtKey_QuoteDbl : Result := VKEY_OEM_7;
QtKey_NumberSign : Result := VKEY_3;
QtKey_Dollar : Result := VKEY_4;
QtKey_Percent : Result := VKEY_5;
QtKey_Ampersand : Result := VKEY_7;
QtKey_Apostrophe : Result := VKEY_OEM_7;
QtKey_ParenLeft : Result := VKEY_9;
QtKey_ParenRight : Result := VKEY_0;
QtKey_Asterisk : Result := VKEY_8;
QtKey_Plus : Result := VKEY_OEM_PLUS;
QtKey_Comma : Result := VKEY_OEM_COMMA;
QtKey_Minus : Result := VKEY_OEM_MINUS;
QtKey_Period : Result := VKEY_OEM_PERIOD;
QtKey_Slash : Result := VKEY_OEM_2;
QtKey_0..QtKey_9 : Result := key;
QtKey_Colon,
QtKey_Semicolon : Result := VKEY_OEM_1;
QtKey_Less : Result := VKEY_OEM_COMMA;
QtKey_Equal : Result := VKEY_OEM_PLUS;
QtKey_Greater : Result := VKEY_OEM_PERIOD;
QtKey_Question : Result := VKEY_OEM_2;
QtKey_At : Result := VKEY_2;
QtKey_A..QtKey_Z : Result := key;
QtKey_BracketLeft : Result := VKEY_OEM_4;
QtKey_Backslash : Result := VKEY_OEM_5;
QtKey_BracketRight : Result := VKEY_OEM_6;
QtKey_AsciiCircum : Result := VKEY_6;
QtKey_Underscore : Result := VKEY_OEM_MINUS;
QtKey_QuoteLeft : Result := VKEY_OEM_3;
QtKey_BraceLeft : Result := VKEY_OEM_4;
QtKey_Bar : Result := VKEY_OEM_5;
QtKey_BraceRight : Result := VKEY_OEM_6;
QtKey_AsciiTilde : Result := VKEY_OEM_3;
QtKey_multiply : Result := VKEY_MULTIPLY;
QtKey_VolumeDown : Result := VKEY_VOLUME_DOWN;
QtKey_VolumeMute : Result := VKEY_VOLUME_MUTE;
QtKey_VolumeUp : Result := VKEY_VOLUME_UP;
QtKey_MediaPlay : Result := VKEY_MEDIA_PLAY_PAUSE;
QtKey_MediaStop : Result := VKEY_MEDIA_STOP;
QtKey_Select : Result := VKEY_SELECT;
QtKey_Printer : Result := VKEY_SNAPSHOT;
QtKey_Execute : Result := VKEY_EXECUTE;
else Result := 0;
end;
end;
procedure QTKeyEventToCEFKeyEvent(Event_: QKeyEventH; var aCEFKeyEvent : TCEFKeyEvent);
var
windows_key_code : integer;
begin
windows_key_code := GetCefWindowsKeyCode(QKeyEvent_key(Event_));
aCEFKeyEvent.size := SizeOf(TCEFKeyEvent);
aCEFKeyEvent.modifiers := GetCefStateModifiers(QKeyEvent_modifiers(Event_), QKeyEvent_nativeModifiers(Event_));
aCEFKeyEvent.windows_key_code := GetWindowsKeyCodeWithoutLocation(windows_key_code);
aCEFKeyEvent.native_key_code := QKeyEvent_nativeScanCode(Event_);
aCEFKeyEvent.is_system_key := ord((aCEFKeyEvent.modifiers and EVENTFLAG_ALT_DOWN) <> 0);
aCEFKeyEvent.unmodified_character := WideChar(QKeyEvent_nativeVirtualKey(Event_));
aCEFKeyEvent.focus_on_editable_field := ord(False);
if ((aCEFKeyEvent.modifiers and EVENTFLAG_CONTROL_DOWN) <> 0) then
aCEFKeyEvent.character := WideChar(GetControlCharacter(windows_key_code, ((aCEFKeyEvent.modifiers and EVENTFLAG_SHIFT_DOWN) <> 0)))
else
aCEFKeyEvent.character := aCEFKeyEvent.unmodified_character;
end;
{$IFEND}
{$IFDEF FMX}
function g_signal_connect(instance: gpointer; detailed_signal: Pgchar; c_handler: TGCallback; data: gpointer): gulong;
begin
Result := g_signal_connect_data(instance, detailed_signal, c_handler, data, nil, TGConnectFlags(0));
end;
function g_signal_connect(instance: gpointer; const detailed_signal: AnsiString; c_handler: TGCallback; data: gpointer): gulong;
begin
Result := g_signal_connect(instance, @detailed_signal[1], c_handler, data);
end;
{$ENDIF}
{$IFDEF FPC}
// This function is almost an identical copy of "ModalShowX11Window" available
// at https://wiki.lazarus.freepascal.org/X11
procedure ShowX11Message(const aMessage : string);
var
TempDisplay : PDisplay;
TempWindow : TWindow;
TempEvent : TXEvent;
TempMessage : PChar;
TempScreen : cint;
begin
TempMessage := PChar(trim(copy(aMessage, 1, pred(pos(#13, aMessage)))));
TempDisplay := XOpenDisplay(nil);
if (TempDisplay = nil) then
begin
WriteLn(aMessage);
exit;
end;
TempScreen := DefaultScreen(TempDisplay);
TempWindow := XCreateSimpleWindow(TempDisplay,
RootWindow(TempDisplay, TempScreen),
10, 10, 200, 100, 1,
BlackPixel(TempDisplay, TempScreen),
WhitePixel(TempDisplay, TempScreen));
XSelectInput(TempDisplay, TempWindow, ExposureMask or KeyPressMask);
XMapWindow(TempDisplay, TempWindow);
while (True) do
begin
XNextEvent(TempDisplay, @TempEvent);
if (TempEvent._type = Expose) then
XDrawString(TempDisplay,
TempWindow,
DefaultGC(TempDisplay, TempScreen),
40, 50,
TempMessage,
strlen(TempMessage));
if (TempEvent._type = KeyPress) then Break;
end;
XCloseDisplay(TempDisplay);
end;
{$ENDIF}
{$IFDEF LCLGTK3}
procedure UseDefaultX11VisualForGtk(widget : PGtkWidget);
type
PGdkX11Screen = type PGdkScreen;
var
screen : PGdkScreen;
visuals, cursor : PGList;
x11_screen : PGdkX11Screen;
default_xvisual : PVisual;
visual : PGdkVisual;
function GDK_X11_VISUAL(obj : pointer) : PGdkVisual;
begin
Result := PGdkVisual(obj);
end;
function GDK_SCREEN_X11(obj : pointer) : PGdkX11Screen;
begin
GDK_SCREEN_X11 := PGdkX11Screen(obj);
end;
function GDK_SCREEN_XDISPLAY(screen : PGdkScreen) : PDisplay;
begin
GDK_SCREEN_XDISPLAY := gdk_x11_display_get_xdisplay(gdk_screen_get_display(screen));
end;
function GDK_SCREEN_XNUMBER(screen : PGdkScreen) : longint;
begin
GDK_SCREEN_XNUMBER := gdk_x11_screen_get_screen_number(screen);
end;
begin
// GTK+ > 3.15.1 uses an X11 visual optimized for GTK+'s OpenGL stuff
// since revid dae447728d: https://github.com/GNOME/gtk/commit/dae447728d
// However, it breaks CEF: https://github.com/cztomczak/cefcapi/issues/9
// Let's use the default X11 visual instead of the GTK's blessed one.
// Copied from: https://github.com/cztomczak/cefcapi.
screen := gdk_screen_get_default();
visuals := gdk_screen_list_visuals(screen);
x11_screen := GDK_SCREEN_X11(screen);
if (x11_screen <> nil) then
begin
default_xvisual := DefaultVisual(GDK_SCREEN_XDISPLAY(x11_screen),
GDK_SCREEN_XNUMBER(x11_screen));
if (default_xvisual <> nil) then
begin
cursor := visuals;
while (cursor <> nil) do
begin
visual := GDK_X11_VISUAL(cursor^.data);
if (default_xvisual^.visualid = gdk_x11_visual_get_xvisual(visual)^.visualid) then
begin
gtk_widget_set_visual(widget, visual);
break;
end;
cursor := cursor^.next;
end;
end;
end;
g_list_free(visuals);
end;
procedure FlushDisplay(widget : PGtkWidget);
var
gdk_window : PGdkWindow;
display : PGdkDisplay;
begin
gdk_window := gtk_widget_get_window(widget);
display := gdk_window_get_display(gdk_window);
gdk_display_flush(display);
end;
{$ENDIF}
{$ENDIF}
end.