1 { XKeyInput
2 
3   Copyright (C) 2008 Tom Gregorovic
4 
5   This source is free software; you can redistribute it and/or modify it under the terms of the
6   GNU General Public License as published by the Free Software Foundation; either version 2 of the
7   License, or (at your option) any later version.
8 
9   This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
10   even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11   General Public License for more details.
12 
13   A copy of the GNU General Public License is available on the World Wide Web at
14   <http://www.gnu.org/copyleft/gpl.html>. You can also obtain it by writing to the Free Software
15   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16 }
17 unit XKeyInput;
18 
19 {$mode objfpc}{$H+}
20 {$linklib Xtst}
21 
22 interface
23 
24 uses
25   Classes, SysUtils, Controls, Forms,
26   X, XLib, KeySym,
27   KeyInputIntf;
28 
29 type
30 
31   { TXKeyInput }
32 
33   TXKeyInput = class(TKeyInput)
34   protected
35     procedure DoDown(Key: Word); override;
36     procedure DoUp(Key: Word); override;
37   end;
38 
InitializeKeyInputnull39 function InitializeKeyInput: TKeyInput;
40 
XTestFakeKeyEventnull41 function XTestFakeKeyEvent(dpy: PDisplay; keycode: dword; is_press: Boolean32;
42   delay: dword): longint; cdecl; external;
43 
44 implementation
45 
46 uses LCLType;
47 
InitializeKeyInputnull48 function InitializeKeyInput: TKeyInput;
49 begin
50   Result := TXKeyInput.Create;
51 end;
52 
VirtualKeyToXKeySymnull53 function VirtualKeyToXKeySym(Key: Word): TKeySym;
54 begin
55   case Key of
56     VK_BACK: Result := XK_BackSpace;
57     VK_TAB: Result := XK_Tab;
58     VK_CLEAR: Result := XK_Clear;
59     VK_RETURN: Result := XK_Return;
60     VK_SHIFT: Result := XK_Shift_L;
61     VK_CONTROL: Result := XK_Control_L;
62     VK_MENU: Result := XK_VoidSymbol; // alt key crashes app, XK_Alt_R;
63     VK_CAPITAL: Result := XK_Caps_Lock;
64 
65     VK_ESCAPE: Result := XK_Escape;
66     VK_SPACE: Result := XK_space;
67     VK_PRIOR: Result := XK_Prior;
68     VK_NEXT: Result := XK_Next;
69     VK_END: Result := XK_End;
70     VK_HOME: Result := XK_Home;
71     VK_LEFT: Result := XK_Left;
72     VK_UP: Result := XK_Up;
73     VK_RIGHT: Result := XK_Right;
74     VK_DOWN: Result := XK_Down;
75     VK_SELECT: Result := XK_Select;
76     VK_PRINT: Result := XK_Print;
77     VK_EXECUTE: Result := XK_Execute;
78 
79     VK_INSERT: Result := XK_Insert;
80     VK_DELETE: Result := XK_Delete;
81     VK_HELP: Result := XK_Help;
82     VK_0: Result := XK_0;
83     VK_1: Result := XK_1;
84     VK_2: Result := XK_2;
85     VK_3: Result := XK_3;
86     VK_4: Result := XK_4;
87     VK_5: Result := XK_5;
88     VK_6: Result := XK_6;
89     VK_7: Result := XK_7;
90     VK_8: Result := XK_8;
91     VK_9: Result := XK_9;
92 
93     VK_A: Result := XK_a;
94     VK_B: Result := XK_b;
95     VK_C: Result := XK_c;
96     VK_D: Result := XK_d;
97     VK_E: Result := XK_e;
98     VK_F: Result := XK_f;
99     VK_G: Result := XK_g;
100     VK_H: Result := XK_h;
101     VK_I: Result := XK_i;
102     VK_J: Result := XK_j;
103     VK_K: Result := XK_k;
104     VK_L: Result := XK_l;
105     VK_M: Result := XK_m;
106     VK_N: Result := XK_n;
107     VK_O: Result := XK_o;
108     VK_P: Result := XK_p;
109     VK_Q: Result := XK_q;
110     VK_R: Result := XK_r;
111     VK_S: Result := XK_s;
112     VK_T: Result := XK_t;
113     VK_U: Result := XK_u;
114     VK_V: Result := XK_v;
115     VK_W: Result := XK_w;
116     VK_X: Result := XK_x;
117     VK_Y: Result := XK_y;
118     VK_Z: Result := XK_z;
119 
120     VK_NUMPAD0: Result := XK_KP_0;
121     VK_NUMPAD1: Result := XK_KP_1;
122     VK_NUMPAD2: Result := XK_KP_2;
123     VK_NUMPAD3: Result := XK_KP_3;
124     VK_NUMPAD4: Result := XK_KP_4;
125     VK_NUMPAD5: Result := XK_KP_5;
126     VK_NUMPAD6: Result := XK_KP_6;
127     VK_NUMPAD7: Result := XK_KP_7;
128     VK_NUMPAD8: Result := XK_KP_8;
129     VK_NUMPAD9: Result := XK_KP_9;
130     VK_MULTIPLY: Result := XK_KP_Multiply;
131     VK_ADD: Result := XK_KP_Add;
132     VK_SEPARATOR: Result := XK_KP_Separator;
133     VK_SUBTRACT: Result := XK_KP_Subtract;
134     VK_DECIMAL: Result := XK_KP_Decimal;
135     VK_DIVIDE: Result := XK_KP_Divide;
136     VK_F1: Result := XK_F1;
137     VK_F2: Result := XK_F2;
138     VK_F3: Result := XK_F3;
139     VK_F4: Result := XK_F4;
140     VK_F5: Result := XK_F5;
141     VK_F6: Result := XK_F6;
142     VK_F7: Result := XK_F7;
143     VK_F8: Result := XK_F8;
144     VK_F9: Result := XK_F9;
145     VK_F10: Result := XK_F10;
146     VK_F11: Result := XK_F11;
147     VK_F12: Result := XK_F12;
148     VK_F13: Result := XK_F13;
149     VK_F14: Result := XK_F14;
150     VK_F15: Result := XK_F15;
151     VK_F16: Result := XK_F16;
152     VK_F17: Result := XK_F17;
153     VK_F18: Result := XK_F18;
154     VK_F19: Result := XK_F19;
155     VK_F20: Result := XK_F20;
156     VK_F21: Result := XK_F21;
157     VK_F22: Result := XK_F22;
158     VK_F23: Result := XK_F23;
159     VK_F24: Result := XK_F24;
160     VK_NUMLOCK: Result := XK_Num_Lock;
161     VK_SCROLL: Result := XK_Scroll_Lock;
162   else
163     Result := XK_VoidSymbol;
164   end;
165 end;
166 
167 { TXKeyInput }
168 
169 procedure TXKeyInput.DoDown(Key: Word);
170 var
171   Display: PDisplay;
172   KeySym: TKeySym;
173 begin
174   KeySym := VirtualKeyToXKeySym(Key);
175   if KeySym = XK_VoidSymbol then Exit;
176 
177   Display := XOpenDisplay(nil);
178   XTestFakeKeyEvent(Display, XKeysymToKeycode(Display, KeySym), True, 0);
179   XFlush(Display);
180   XCloseDisplay(Display);
181 end;
182 
183 procedure TXKeyInput.DoUp(Key: Word);
184 var
185   Display: PDisplay;
186   KeySym: TKeySym;
187 begin
188   KeySym := VirtualKeyToXKeySym(Key);
189   if KeySym = XK_VoidSymbol then Exit;
190 
191   Display := XOpenDisplay(nil);
192   XTestFakeKeyEvent(Display, XKeysymToKeycode(Display, KeySym), False, 0);
193   XFlush(Display);
194   XCloseDisplay(Display);
195 end;
196 
197 end.
198 
199