Advances keyboard events in Android and X11. Simple key down/up can already be received in both

git-svn-id: trunk@34207 -
This commit is contained in:
sekelsenmat 2011-12-15 13:19:01 +00:00
parent fb0efe6763
commit 05cd46835f
16 changed files with 2128 additions and 69 deletions

1
.gitattributes vendored
View File

@ -3357,6 +3357,7 @@ examples/anchordocking/minide/unit1.lfm svneol=native#text/plain
examples/anchordocking/minide/unit1.pas svneol=native#text/plain
examples/androidlcl/android/AndroidManifest.xml svneol=native#text/plain
examples/androidlcl/android/build.properties svneol=native#text/plain
examples/androidlcl/android/build.sh svneol=native#text/plain
examples/androidlcl/android/build.xml svneol=native#text/plain
examples/androidlcl/android/default.properties svneol=native#text/plain
examples/androidlcl/android/local.properties svneol=native#text/plain

View File

@ -0,0 +1,4 @@
ant debug
~/Programas/android-sdk-linux/platform-tools/adb uninstall com.pascal.lcltest
~/Programas/android-sdk-linux/platform-tools/adb install bin/LCLExample-debug.apk
~/Programas/android-sdk-linux/platform-tools/adb logcat

View File

@ -8,6 +8,7 @@ object Form1: TForm1
ClientWidth = 220
OnClick = FormClick
OnCreate = FormCreate
OnKeyDown = Button1KeyDown
OnMouseMove = FormMouseMove
OnPaint = FormPaint
LCLVersion = '0.9.31'
@ -28,6 +29,7 @@ object Form1: TForm1
Width = 116
Caption = 'Move Progress'
OnClick = Button1Click
OnKeyDown = Button1KeyDown
TabOrder = 1
end
object ProgressBar1: TProgressBar

View File

@ -30,6 +30,8 @@ type
procedure Arrow1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure Button1Click(Sender: TObject);
procedure Button1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState
);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure FormClick(Sender: TObject);
@ -140,6 +142,13 @@ begin
ProgressBar1.Position := ProgressBar1.Position + 10;
end;
procedure TForm1.Button1KeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
DebugLn('[TForm1.Button1KeyDown] '+ LCLProc.DbgsVKCode(Key));
Caption := LCLProc.DbgsVKCode(Key);
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
Application.OnMessageDialogFinished := @HandleMessageDialogFinished;

View File

@ -49,9 +49,6 @@
</CompilerOptions>
</Item2>
<Item3 Name="NotCustomDrawn">
<MacroValues Count="1">
<Macro1 Name="LCLWidgetType" Value="carbon"/>
</MacroValues>
<CompilerOptions>
<Version Value="11"/>
<Target>

File diff suppressed because it is too large Load Diff

View File

@ -6,7 +6,7 @@ interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
ComCtrls;
ComCtrls, ExtCtrls;
type
@ -15,6 +15,7 @@ type
TForm2 = class(TForm)
Button1: TButton;
Edit1: TEdit;
Image1: TImage;
procedure Button1Click(Sender: TObject);
private
{ private declarations }

View File

@ -134,6 +134,13 @@ type
FWMDeleteWindow: TAtom; // Atom for "WM_DELETE_WINDOW"
FWMHints: TAtom; // Atom for "_MOTIF_WM_HINTS"
// For composing character events
ComposeBuffer: string;
ComposeStatus: TStatus;
InputMethod: xlib.PXIM;
InputContext: PXIC;
LastKeySym: TKeySym; // Used for KeyRelease event
function FindWindowByXID(XWindowID: X.TWindow; out AWindowInfo: TX11WindowInfo): TWinControl;
{$endif}
{$ifdef CD_Android}
@ -146,13 +153,14 @@ type
AccumulatedStr: string;
// The currently focused control
FocusedControl: TWinControl;
FocusedIntfControl: TWinControl;
// Default Fonts
DefaultFont: TFPCustomFont;
DefaultFontAndroidSize: Integer;
// For unusual implementations of DebugLn/DebugOut
procedure AccumulatingDebugOut(AStr: string);
//
procedure CDSetFocusToControl(ALCLControl: TWinControl);
procedure CDSetFocusToControl(ALCLControl, AIntfControl: TWinControl);
//
protected
{function CreateThemeServices: TThemeServices; override;}
@ -161,6 +169,7 @@ type
//
procedure BackendCreate;
procedure BackendDestroy;
procedure BackendInit;
public
// ScreenDC and Image for doing Canvas operations outside the Paint event
// and also for text drawing operations

View File

@ -20,7 +20,7 @@ begin
AccumulatedStr := AccumulatedStr + AStr;
end;
procedure TCDWidgetSet.CDSetFocusToControl(ALCLControl: TWinControl);
procedure TCDWidgetSet.CDSetFocusToControl(ALCLControl, AIntfControl: TWinControl);
begin
if (CDWidgetset.FocusedControl <> ALCLControl) then
begin
@ -29,6 +29,12 @@ begin
LCLSendKillFocusMsg(CDWidgetset.FocusedControl);
CDWidgetset.FocusedControl := ALCLControl;
LCLSendSetFocusMsg(ALCLControl);
// The same for intf controls
if CDWidgetset.FocusedIntfControl <> nil then
LCLSendKillFocusMsg(CDWidgetset.FocusedIntfControl);
CDWidgetset.FocusedIntfControl := AIntfControl;
if AIntfControl <> nil then LCLSendSetFocusMsg(AIntfControl);
end;
end;

View File

@ -42,25 +42,17 @@ begin
eventResult := 0;
lCurForm := GetCurrentForm();
lTarget := FindControlWhichReceivedEvent(lCurForm.LCLForm, lCurForm.Children, Round(X), Round(Y));
lEventPos := FormPosToControlPos(lTarget, Round(X), Round(Y));
case action of
ACTION_DOWN:
begin
lCurForm.LastMouseDownControl := lTarget;
LCLSendMouseDownMsg(lTarget, lEventPos.X, lEventPos.Y, mbLeft, []);
CallbackMouseDown(lCurForm, Round(X), Round(Y), mbLeft, []);
end;
ACTION_UP:
begin
if lCurForm.LastMouseDownControl <> nil then lTarget := lCurForm.LastMouseDownControl;
LCLSendMouseUpMsg(lTarget, lEventPos.X, lEventPos.Y, mbLeft, []);
LCLSendClickedMsg(lTarget);
// If the target is focusable, a mouse up will give it focus
CDWidgetset.CDSetFocusToControl(lTarget);
CallbackMouseUp(lCurForm, Round(X), Round(Y), mbLeft, []);
end;
ACTION_MOVE: LCLSendMouseMoveMsg(lTarget, lEventPos.X, lEventPos.Y, []);
ACTION_MOVE: CallbackMouseMove(lCurForm, Round(X), Round(Y), []);
end;
// This sends messages like Invalidate requests
@ -156,36 +148,33 @@ begin
eventResult := 0;
lCurForm := GetCurrentForm();
lTarget := lCurForm.GetFocusedControl();
lKey := CDWidgetset.AndroidKeyCodeToLCLKeyCode(AKeyCode);
case AKind of
ACTION_DOWN:
begin
LCLSendKeyDownEvent(lTarget, lKey, 0, False, False);
end;
ACTION_DOWN: CallbackKeyDown(lCurForm, lKey);
ACTION_UP:
begin
LCLSendKeyUpEvent(lTarget, lKey, 0, False, False);
CallbackKeyUp(lCurForm, lKey);
if AChar <> 0 then
begin
LCLSendCharEvent(lTarget, lKey, 0, False, False, True);
SetLength(AWideText, 1);
AWideText[1] := WideChar(AChar);
AUTF8Text := UTF16ToUTF8(AWideText);
AUTF8Char := AUTF8Text;
LCLSendUTF8KeyPress(lTarget, AUTF8Char, False);
CallbackKeyChar(lCurForm, lKey, AUTF8Char);
end;
// Handle the Back hardware key
if AKeyCode = AKEYCODE_BACK then
begin
// The back hardware key hides the current form and shows the one bellow it
lForm := GetCurrentForm();
HideForm(lForm);
// If all forms got hidden, exit the application
lForm := GetCurrentForm();
if lForm = nil then eventResult := eventResult or 2;
lForm := lCurForm;
//DebugLn(Format('CallbackKeyUp D lForm=%x', [PtrInt(lForm)]));
// If this is the main form, then go back to desktop
if (Application.MainForm <> nil) and (lForm = TCDForm(Application.MainForm.Handle)) then
eventResult := eventResult or 2
// for other forms, hide them
else HideForm(lForm);
end;
end;
//ACTION_MULTIPLE:
@ -405,9 +394,9 @@ begin
AKEYCODE_NUM = 78;
AKEYCODE_HEADSETHOOK = 79;
AKEYCODE_FOCUS = 80; // *Camera* focus
AKEYCODE_PLUS = 81;
AKEYCODE_MENU = 82;
AKEYCODE_NOTIFICATION = 83;
AKEYCODE_PLUS = 81;}
AKEYCODE_MENU: Result := VK_MENU;
{ AKEYCODE_NOTIFICATION = 83;
AKEYCODE_SEARCH = 84;
AKEYCODE_MEDIA_PLAY_PAUSE = 85;
AKEYCODE_MEDIA_STOP = 86;
@ -506,6 +495,11 @@ begin
{$endif}
end;
procedure TCDWidgetSet.BackendInit;
begin
end;
{------------------------------------------------------------------------------
Method: TWinCEWidgetSet.AppInit
Params: None

View File

@ -18,7 +18,12 @@
*****************************************************************************
}
function TCDWidgetSet.FindWindowByXID(XWindowID: X.TWindow; out AWindowInfo: TX11WindowInfo): TWinControl;
// redefines:
function XOpenIM(para1: PDisplay; para2: PXrmHashBucketRec; para3: Pchar; para4: Pchar): PXIM; cdecl; external;
function XCreateIC(para1: PXIM; para2: array of const): PXIC; cdecl; external;function TCDWidgetSet.FindWindowByXID(XWindowID: X.TWindow; out AWindowInfo: TX11WindowInfo): TWinControl;
var
i: Integer;
EndSubSearch: Boolean; { Necessary to quit the recursion }
@ -70,6 +75,15 @@ procedure TCDWidgetSet.BackendDestroy;
begin
end;
procedure TCDWidgetSet.BackendInit;
begin
InputMethod := XOpenIM(FDisplay, nil, nil, nil);
if InputMethod <> nil then
InputContext := XCreateIC(InputMethod, [XNInputStyle, XIMPreeditNothing or XIMStatusNothing, nil]);
if InputContext = nil then DebugLn('[TCDWidgetSet.BackendInit] Failed to initialize the Keyboard handling!');
end;
{------------------------------------------------------------------------------
Method: TWinCEWidgetSet.AppInit
Params: None
@ -94,6 +108,8 @@ begin
if not Assigned(FDisplay) then
raise Exception.Create('[TCDWidgetSet.AppInit] XOpenDisplay failed');
BackendInit();
//if (not (woX11SkipWMHints in WindowOptions)) and (woWindow in WindowOptions) then
//begin
LeaderWindow := XCreateSimpleWindow(FDisplay, XDefaultRootWindow(FDisplay), 0, 0, 1, 1, 0, 0, 0);

View File

@ -9,7 +9,7 @@ uses
Types, Classes, SysUtils,
// LCL
Controls, Graphics, stdctrls, extctrls, comctrls,
customdrawnproc, customdrawncontrols;
customdrawnproc, customdrawncontrols, lcltype, lclproc;
type
{ TCDIntfButton }
@ -17,8 +17,6 @@ type
TCDIntfButton = class(TCDButton)
public
LCLControl: TButton;
constructor Create(AOwner: TComponent); override;
procedure HandleOnClick(Sender: TObject);
end;
// These are default message handlers which backends might use to simplify their code
@ -26,6 +24,10 @@ type
procedure CallbackMouseUp(AWindowHandle: TCDForm; x, y: Integer; Button: TMouseButton; ShiftState: TShiftState = []);
procedure CallbackMouseDown(AWindowHandle: TCDForm; x, y: Integer; Button: TMouseButton; ShiftState: TShiftState = []);
procedure CallbackMouseMove(AWindowHandle: TCDForm; x, y: Integer; ShiftState: TShiftState = []);
procedure CallbackKeyDown(AWindowHandle: TCDForm; AKey: Word);
procedure CallbackKeyUp(AWindowHandle: TCDForm; AKey: Word);
procedure CallbackKeyChar(AWindowHandle: TCDForm; AKey: Word; AChar: TUTF8Char);
function IsIntfControl(AControl: TWinControl): Boolean;
implementation
@ -43,21 +45,40 @@ begin
lEventPos := FormPosToControlPos(lTarget, x, y);
LCLSendMouseUpMsg(lTarget, lEventPos.x, lEventPos.y, Button, ShiftState);
LCLSendClickedMsg(lTarget);
// If this is a interface control, send the message to the main LCL control too
if IsIntfControl(lTarget) then
begin
lTarget := lTarget.Parent;
LCLSendMouseUpMsg(lTarget, lEventPos.x, lEventPos.y, Button, ShiftState);
LCLSendClickedMsg(lTarget);
end;
end;
procedure CallbackMouseDown(AWindowHandle: TCDForm; x, y: Integer; Button: TMouseButton; ShiftState: TShiftState = []);
var
lTarget: TWinControl;
lIntfTarget: TWinControl = nil;
lEventPos: TPoint;
begin
lTarget := FindControlWhichReceivedEvent(AWindowHandle.LCLForm, AWindowHandle.Children, x, y);
AWindowHandle.LastMouseDownControl := lTarget;
AWindowHandle.FocusedControl := lTarget;
lEventPos := FormPosToControlPos(lTarget, x, y);
// If the target is focusable, a mouse down will give it focus
CDWidgetset.CDSetFocusToControl(lTarget);
LCLSendMouseDownMsg(lTarget, lEventPos.x, lEventPos.y, Button, ShiftState);
// If this is a interface control, send the message to the main LCL control too
if IsIntfControl(lTarget) then
begin
lIntfTarget := lTarget;
lTarget := lTarget.Parent;
LCLSendMouseDownMsg(lTarget, lEventPos.x, lEventPos.y, Button, ShiftState);
end;
// If the target is focusable, a mouse down will give it focus
CDWidgetset.CDSetFocusToControl(lTarget, lIntfTarget);
end;
procedure CallbackMouseMove(AWindowHandle: TCDForm; x, y: Integer; ShiftState: TShiftState = []);
@ -72,20 +93,82 @@ begin
lEventPos := FormPosToControlPos(lTarget, x, y);
LCLSendMouseMoveMsg(lTarget, lEventPos.x, lEventPos.y, ShiftState);
// If this is a interface control, send the message to the main LCL control too
if IsIntfControl(lTarget) then
begin
lTarget := lTarget.Parent;
LCLSendMouseMoveMsg(lTarget, lEventPos.x, lEventPos.y, ShiftState);
end;
end;
{ TCDIntfButton }
constructor TCDIntfButton.Create(AOwner: TComponent);
procedure CallbackKeyDown(AWindowHandle: TCDForm; AKey: Word);
var
lTarget: TWinControl;
begin
inherited Create(AOwner);
OnClick := @HandleOnClick;
lTarget := AWindowHandle.GetFocusedControl();
{$ifdef VerboseCDEvents}
DebugLn(Format('CallbackKeyDown FocusedControl=%s:%s AKey=%x', [lTarget.Name, lTarget.ClassName, AKey]));
{$endif}
LCLSendKeyDownEvent(lTarget, AKey, 0, True, False);
// If this is a interface control, send the message to the main LCL control too
if IsIntfControl(lTarget) then
begin
lTarget := lTarget.Parent;
{$ifdef VerboseCDEvents}
DebugLn(Format('CallbackKeyDown IsIntfControl, sending msg to Parent=%s:%s', [lTarget.Name, lTarget.ClassName]));
{$endif}
LCLSendKeyDownEvent(lTarget, AKey, 0, True, False);
end;
end;
procedure TCDIntfButton.HandleOnClick(Sender: TObject);
procedure CallbackKeyUp(AWindowHandle: TCDForm; AKey: Word);
var
lTarget: TWinControl;
begin
if Assigned(LCLControl.OnClick) then
LCLControl.OnClick(LCLControl);
lTarget := AWindowHandle.GetFocusedControl();
{$ifdef VerboseCDEvents}
DebugLn(Format('CallbackKeyUp FocusedControl=%s:%s', [lTarget.Name, lTarget.ClassName]));
{$endif}
LCLSendKeyUpEvent(lTarget, AKey, 0, True, False);
// If this is a interface control, send the message to the main LCL control too
if IsIntfControl(lTarget) then
begin
lTarget := lTarget.Parent;
LCLSendKeyUpEvent(lTarget, AKey, 0, True, False);
end;
end;
procedure CallbackKeyChar(AWindowHandle: TCDForm; AKey: Word; AChar: TUTF8Char);
var
lTarget: TWinControl;
begin
lTarget := AWindowHandle.GetFocusedControl();
{$ifdef VerboseCDEvents}
DebugLn(Format('CallbackKeyChar FocusedControl=%s:%s', [lTarget.Name, lTarget.ClassName]));
{$endif}
LCLSendCharEvent(lTarget, AKey, 0, True, False, True);
LCLSendUTF8KeyPress(lTarget, AChar, False);
// If this is a interface control, send the message to the main LCL control too
if IsIntfControl(lTarget) then
begin
lTarget := lTarget.Parent;
LCLSendCharEvent(lTarget, AKey, 0, True, False, True);
LCLSendUTF8KeyPress(lTarget, AChar, False);
end;
end;
function IsIntfControl(AControl: TWinControl): Boolean;
begin
Result := (AControl <> nil) and (AControl.Parent <> nil) and
((AControl is TCDIntfButton) {or ...});
end;
end.

View File

@ -50,6 +50,7 @@ type
NativeHandle: HWND;
//
LastMouseDownControl: TWinControl; // Stores the control which should receive the next MouseUp
FocusedControl: TWinControl; // The control focused in the form
// Counter to keep track of when we requested Invalidate
// Some systems like X11 and Win32 will keep sending unnecessary paint messages
// so for them we just throw the previously painted image
@ -225,7 +226,7 @@ begin
if lCurrentForm = ACDForm then
begin
lCurrentForm := FindTopMostVisibleForm();
LCLIntf.InvalidateRect(lCurrentForm.NativeHandle, nil, True);
LCLIntf.InvalidateRect(HWND(lCurrentForm), nil, True);
end;
end;
@ -648,7 +649,7 @@ end;
function TCDForm.GetFocusedControl: TWinControl;
begin
if LastMouseDownControl <> nil then Result := LastMouseDownControl
if FocusedControl <> nil then Result := FocusedControl
else Result := LCLForm;
end;

View File

@ -2884,8 +2884,9 @@ end;*)
------------------------------------------------------------------------------}
function TCDWidgetSet.GetFocus: HWND;
begin
if FocusedControl = nil then Result := 0
else Result := FocusedControl.Handle;
Result := 0;
if FocusedIntfControl <> nil then Result := FocusedIntfControl.Handle
else if FocusedControl <> nil then Result := FocusedControl.Handle;
end;
(*function TQtWidgetSet.GetKeyState(nVirtKey: Integer): Smallint;
@ -4632,7 +4633,7 @@ var
lControl: TWinControl;
begin
{$ifdef VerboseCDDrawing}
WriteLn('[WinAPI InvalidateRect]');
DebugLn('[WinAPI InvalidateRect]');
{$endif}
if AHandle = 0 then exit(False);

View File

@ -44,7 +44,7 @@ uses
customdrawncontrols,
// Widgetset
InterfaceBase, WSForms, WSProc, WSLCLClasses, LCLMessageGlue,
customdrawnwscontrols, customdrawnint, customdrawnproc;
customdrawnwscontrols, customdrawnint, customdrawnproc, customdrawnprivate;
type
{ TCDWSScrollingWinControl }
@ -128,6 +128,9 @@ type
var Event: TXConfigureEvent);
class procedure EvClientMessage(const AWinControl: TWinControl;
AWindowInfo: TX11WindowInfo; var Event: TXClientMessageEvent);
// Key routines
class function StartComposing(const Event: TXKeyEvent): TKeySym;
class function X11KeyToLCLKey(AX11Key: TKeySym): Word;
{$endif}
published
class function CreateHandle(const AWinControl: TWinControl; const AParams: TCreateParams): TLCLIntfHandle; override;

View File

@ -1,5 +1,9 @@
{$MainForm customdrawnwsforms.pp}
// redefines:
function XmbLookupString(p1: PXIC; ev: PXKeyPressedEvent; str: PChar; len: longword; ks: PKeySym; stat: PStatus): longint; cdecl; external;
function Xutf8LookupString(p1: PXIC; ev: PXKeyPressedEvent; str: PChar; len: longword; ks: PKeySym; stat: PStatus): longint; cdecl; external;
{ TCDWSCustomForm }
class procedure TCDWSCustomForm.UpdateMotifWMHints(const AWinControl: TWinControl; CanMaximize: Boolean);
@ -480,14 +484,18 @@ end;
class procedure TCDWSCustomForm.EvKeyPressed(const AWinControl: TWinControl;
AWindowInfo: TX11WindowInfo; var Event: TXKeyEvent);
{var
KeySym: TKeySym;}
var
lKey: Word;
lForm: TCDForm;
KeySym: TKeySym;
begin
{ KeySym := StartComposing(FXEvent^);
lForm := TCDForm(AWinControl.Handle);
KeySym := StartComposing(Event);
inherited EvKeyPressed(AKey);
lKey := X11KeyToLCLKey(KeySym);
CallbackKeyDown(lForm, lKey);
if (FXEvent^.xkey.state and (ControlMask or Mod1Mask)) = 0 then EndComposing;}
//if (FXEvent^.xkey.state and (ControlMask or Mod1Mask)) = 0 then EndComposing;
end;
class procedure TCDWSCustomForm.EvKeyReleased(const AWinControl: TWinControl;
@ -506,19 +514,10 @@ class procedure TCDWSCustomForm.EvMousePressed(const AWinControl: TWinControl; A
var Event: TXButtonEvent);
var
MouseButton: TMouseButton;
lTarget: TWinControl;
lEventPos: TPoint;
begin
lTarget := FindControlWhichReceivedEvent(TCustomForm(AWinControl), AWindowInfo.Children, Event.x, Event.y);
AWindowInfo.LastMouseDownControl := lTarget;
lEventPos := FormPosToControlPos(lTarget, Event.x, Event.y);
// If the target is focusable, a mouse down will give it focus
CDWidgetset.CDSetFocusToControl(lTarget);
if XButtonToMouseButton(Event.button, MouseButton) then
begin
LCLSendMouseDownMsg(lTarget, lEventPos.x, lEventPos.y, MouseButton, [])
CallbackMouseDown(TCDForm(AWinControl.Handle), Event.x, Event.y, MouseButton, []);
end
else
begin
@ -704,6 +703,184 @@ begin
DebugLn(Format('LCL-CustomDrawn-X11: Unknown client message: %d', [Event.message_type]));
end;
class function TCDWSCustomForm.StartComposing(const Event: TXKeyEvent): TKeySym;
var
len: integer;
begin
SetLength(CDWidgetset.ComposeBuffer, 20);
// Xutf8LookupString returns the size of FComposeBuffer in bytes.
len := Xutf8LookupString(CDWidgetset.InputContext, @Event, @CDWidgetset.ComposeBuffer[1],
Length(CDWidgetset.ComposeBuffer), @Result, @CDWidgetset.ComposeStatus);
SetLength(CDWidgetset.ComposeBuffer, len);
// if overflow occured, then previous SetLength() would have fixed the buffer
// size, so run Xutf8LookupString again to read correct value.
if CDWidgetset.ComposeStatus = XBufferOverflow then
Xutf8LookupString(CDWidgetset.InputContext, @Event, @CDWidgetset.ComposeBuffer[1],
Length(CDWidgetset.ComposeBuffer), @Result, @CDWidgetset.ComposeStatus);
end;
class function TCDWSCustomForm.X11KeyToLCLKey(AX11Key: TKeySym): Word;
{const
Table_20aX: array[$20a0..$20ac] of Word = (keyEcuSign, keyColonSign,
keyCruzeiroSign, keyFFrancSign, keyLiraSign, keyMillSign, keyNairaSign,
keyPesetaSign, keyRupeeSign, keyWonSign, keyNewSheqelSign, keyDongSign,
keyEuroSign);
Table_feXX: array[$fe50..$fe60] of Word = (keyDeadGrave, keyDeadAcute,
keyDeadCircumflex, keyDeadTilde, keyDeadMacron,keyDeadBreve,
keyDeadAbovedot, keyDeadDiaeresis, keyDeadRing, keyDeadDoubleacute,
keyDeadCaron, keyDeadCedilla, keyDeadOgonek, keyDeadIota,
keyDeadVoicedSound, keyDeadSemivoicedSound, keyDeadBelowdot);
Table_ff5X: array[$ff50..$ff58] of Word = (keyHome, keyLeft, keyUp, keyRight,
keyDown, keyPrior, keyNext, keyEnd, keyBegin);
Table_ff6X: array[$ff60..$ff6b] of Word = (keySelect, keyPrintScreen,
keyExecute, keyInsert, keyNIL, keyUndo, keyRedo, keyMenu, keyFind,
keyCancel, keyHelp, keyBreak);
Table_ff9X: array[$ff91..$ff9f] of Word = (keyPF1, keyPF2, keyPF3, keyPF4,
keyP7, keyP4, keyP8, keyP6, keyP2, keyP9, keyP3, keyP1, keyP5, keyP0,
keyPDecimal);
Table_ffeX: array[$ffe1..$ffee] of Word = (keyShiftL, keyShiftR, keyCtrlL,
keyCtrlR, keyCapsLock, keyShiftLock, keyMetaL, keyMetaR, keyAltL, keyAltR,
keySuperL, keySuperR, keyHyperL, keyHyperR); }
begin
case AX11Key of
$20: Result := VK_SPACE;
{ 0x0021 U0021 . # exclam
0x0022 U0022 . # quotedbl
0x0023 U0023 . # numbersign
0x0024 U0024 . # dollar
0x0025 U0025 . # percent
0x0026 U0026 . # ampersand
0x0027 U0027 . # apostrophe
0x0027 U0027 . # quoteright /* deprecated */
0x0028 U0028 . # parenleft
0x0029 U0029 . # parenright
0x002a U002a . # asterisk
0x002b U002b . # plus
0x002c U002c . # comma
0x002d U002d . # minus
0x002e U002e . # period
0x002f U002f . # slash
0x0030 U0030 . # 0
0x0031 U0031 . # 1
0x0032 U0032 . # 2
0x0033 U0033 . # 3
0x0034 U0034 . # 4
0x0035 U0035 . # 5
0x0036 U0036 . # 6
0x0037 U0037 . # 7
0x0038 U0038 . # 8
0x0039 U0039 . # 9
0x003a U003a . # colon
0x003b U003b . # semicolon
0x003c U003c . # less
0x003d U003d . # equal
0x003e U003e . # greater
0x003f U003f . # question
0x0040 U0040 . # at }
$41: Result := VK_A;
{ 0x0042 U0042 . # B
0x0043 U0043 . # C
0x0044 U0044 . # D
0x0045 U0045 . # E
0x0046 U0046 . # F
0x0047 U0047 . # G
0x0048 U0048 . # H
0x0049 U0049 . # I
0x004a U004a . # J
0x004b U004b . # K
0x004c U004c . # L
0x004d U004d . # M
0x004e U004e . # N
0x004f U004f . # O
0x0050 U0050 . # P
0x0051 U0051 . # Q
0x0052 U0052 . # R
0x0053 U0053 . # S
0x0054 U0054 . # T
0x0055 U0055 . # U
0x0056 U0056 . # V
0x0057 U0057 . # W
0x0058 U0058 . # X
0x0059 U0059 . # Y
0x005a U005a . # Z }
{ 0x005b U005b . # bracketleft
0x005c U005c . # backslash
0x005d U005d . # bracketright
0x005e U005e . # asciicircum
0x005f U005f . # underscore
0x0060 U0060 . # grave
0x0060 U0060 . # quoteleft /* deprecated */ }
$61: Result := VK_A;
{ 0x0062 U0062 . # b
0x0063 U0063 . # c
0x0064 U0064 . # d
0x0065 U0065 . # e
0x0066 U0066 . # f
0x0067 U0067 . # g
0x0068 U0068 . # h
0x0069 U0069 . # i
0x006a U006a . # j
0x006b U006b . # k
0x006c U006c . # l
0x006d U006d . # m
0x006e U006e . # n
0x006f U006f . # o
0x0070 U0070 . # p
0x0071 U0071 . # q
0x0072 U0072 . # r
0x0073 U0073 . # s
0x0074 U0074 . # t
0x0075 U0075 . # u
0x0076 U0076 . # v
0x0077 U0077 . # w
0x0078 U0078 . # x
0x0079 U0079 . # y
0x007a U007a . # z }
{ 0..Ord('a')-1, Ord('z')+1..$bf, $f7:
826 Result := KeySym;
827 Ord('a')..Ord('z'), $c0..$f6, $f8..$ff:
828 Result := KeySym - 32; // ignore case: convert lowercase a-z to A-Z keysyms;
829 $20a0..$20ac: Result := Table_20aX[KeySym];
830 $fe20: Result := keyTab;
831 $fe50..$fe60: Result := Table_feXX[KeySym];
832 XK_BackSpace: Result := keyBackspace;
833 XK_Tab: Result := keyTab;
834 XK_Linefeed: Result := keyLinefeed;
835 $ff0b: Result := keyClear;
836 $ff0d: Result := keyReturn;
837 $ff13: Result := keyPause;
838 $ff14: Result := keyScrollLock;
839 $ff15: Result := keySysRq;
840 $ff1b: Result := keyEscape;
841 $ff50..$ff58: Result := Table_ff5X[KeySym];
842 $ff60..$ff6b: Result := Table_ff6X[KeySym];
843 $ff7e: Result := keyModeSwitch;
844 $ff7f: Result := keyNumLock;
845 $ff80: Result := keyPSpace;
846 $ff89: Result := keyPTab;
847 $ff8d: Result := keyPEnter;
848 $ff91..$ff9f: Result := Table_ff9X[KeySym];
849 $ffaa: Result := keyPAsterisk;
850 $ffab: Result := keyPPlus;
851 $ffac: Result := keyPSeparator;
852 $ffad: Result := keyPMinus;
853 $ffae: Result := keyPDecimal;
854 $ffaf: Result := keyPSlash;
855 $ffb0..$ffb9: Result := keyP0 + KeySym - $ffb0;
856 $ffbd: Result := keyPEqual;
857 $ffbe..$ffe0: Result := keyF1 + KeySym - $ffbe;
858 $ffe1..$ffee: Result := Table_ffeX[KeySym];
859 $ffff: Result := keyDelete; }
else
Result := 0;
end;
(*864 {$IFDEF Debug}
865 if Result = keyNIL then
866 WriteLn('fpGFX/X11: Unknown KeySym: $', IntToHex(KeySym, 4));
867 {$ENDIF}*)
end;
{------------------------------------------------------------------------------
Method: TCDWSCustomForm.CreateHandle
Params: None