This repository has been archived by the owner on Feb 11, 2021. It is now read-only.
/
SDL_x11keyboard.c
293 lines (262 loc) · 8.68 KB
1
/*
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Simple DirectMedia Layer
Copyright (C) 1997-2011 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
20
21
22
*/
#include "SDL_config.h"
23
24
#if SDL_VIDEO_DRIVER_X11
25
26
27
#include "SDL_x11video.h"
#include "../../events/SDL_keyboard_c.h"
28
29
#include "../../events/scancodes_darwin.h"
#include "../../events/scancodes_xfree86.h"
30
31
32
33
34
#include <X11/keysym.h>
#include "imKStoUCS.h"
35
/* *INDENT-OFF* */
36
static const struct {
37
KeySym keysym;
38
SDL_Keycode sdlkey;
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
} KeySymToSDLKey[] = {
{ XK_Return, SDLK_RETURN },
{ XK_Escape, SDLK_ESCAPE },
{ XK_BackSpace, SDLK_BACKSPACE },
{ XK_Tab, SDLK_TAB },
{ XK_Caps_Lock, SDLK_CAPSLOCK },
{ XK_F1, SDLK_F1 },
{ XK_F2, SDLK_F2 },
{ XK_F3, SDLK_F3 },
{ XK_F4, SDLK_F4 },
{ XK_F5, SDLK_F5 },
{ XK_F6, SDLK_F6 },
{ XK_F7, SDLK_F7 },
{ XK_F8, SDLK_F8 },
{ XK_F9, SDLK_F9 },
{ XK_F10, SDLK_F10 },
{ XK_F11, SDLK_F11 },
{ XK_F12, SDLK_F12 },
{ XK_Print, SDLK_PRINTSCREEN },
{ XK_Scroll_Lock, SDLK_SCROLLLOCK },
{ XK_Pause, SDLK_PAUSE },
{ XK_Insert, SDLK_INSERT },
{ XK_Home, SDLK_HOME },
{ XK_Prior, SDLK_PAGEUP },
{ XK_Delete, SDLK_DELETE },
{ XK_End, SDLK_END },
{ XK_Next, SDLK_PAGEDOWN },
{ XK_Right, SDLK_RIGHT },
{ XK_Left, SDLK_LEFT },
{ XK_Down, SDLK_DOWN },
{ XK_Up, SDLK_UP },
{ XK_Num_Lock, SDLK_NUMLOCKCLEAR },
{ XK_KP_Divide, SDLK_KP_DIVIDE },
{ XK_KP_Multiply, SDLK_KP_MULTIPLY },
{ XK_KP_Subtract, SDLK_KP_MINUS },
{ XK_KP_Add, SDLK_KP_PLUS },
{ XK_KP_Enter, SDLK_KP_ENTER },
{ XK_KP_Delete, SDLK_KP_PERIOD },
{ XK_KP_End, SDLK_KP_1 },
{ XK_KP_Down, SDLK_KP_2 },
{ XK_KP_Next, SDLK_KP_3 },
{ XK_KP_Left, SDLK_KP_4 },
{ XK_KP_Begin, SDLK_KP_5 },
{ XK_KP_Right, SDLK_KP_6 },
{ XK_KP_Home, SDLK_KP_7 },
{ XK_KP_Up, SDLK_KP_8 },
{ XK_KP_Prior, SDLK_KP_9 },
{ XK_KP_Insert, SDLK_KP_0 },
{ XK_KP_Decimal, SDLK_KP_PERIOD },
{ XK_KP_1, SDLK_KP_1 },
{ XK_KP_2, SDLK_KP_2 },
{ XK_KP_3, SDLK_KP_3 },
{ XK_KP_4, SDLK_KP_4 },
{ XK_KP_5, SDLK_KP_5 },
{ XK_KP_6, SDLK_KP_6 },
{ XK_KP_7, SDLK_KP_7 },
{ XK_KP_8, SDLK_KP_8 },
{ XK_KP_9, SDLK_KP_9 },
{ XK_KP_0, SDLK_KP_0 },
{ XK_KP_Decimal, SDLK_KP_PERIOD },
{ XK_Hyper_R, SDLK_APPLICATION },
{ XK_KP_Equal, SDLK_KP_EQUALS },
{ XK_F13, SDLK_F13 },
{ XK_F14, SDLK_F14 },
{ XK_F15, SDLK_F15 },
{ XK_F16, SDLK_F16 },
{ XK_F17, SDLK_F17 },
{ XK_F18, SDLK_F18 },
{ XK_F19, SDLK_F19 },
{ XK_F20, SDLK_F20 },
{ XK_F21, SDLK_F21 },
{ XK_F22, SDLK_F22 },
{ XK_F23, SDLK_F23 },
{ XK_F24, SDLK_F24 },
{ XK_Execute, SDLK_EXECUTE },
{ XK_Help, SDLK_HELP },
{ XK_Menu, SDLK_MENU },
{ XK_Select, SDLK_SELECT },
{ XK_Cancel, SDLK_STOP },
{ XK_Redo, SDLK_AGAIN },
{ XK_Undo, SDLK_UNDO },
{ XK_Find, SDLK_FIND },
{ XK_KP_Separator, SDLK_KP_COMMA },
{ XK_Sys_Req, SDLK_SYSREQ },
{ XK_Control_L, SDLK_LCTRL },
{ XK_Shift_L, SDLK_LSHIFT },
{ XK_Alt_L, SDLK_LALT },
{ XK_Meta_L, SDLK_LGUI },
{ XK_Super_L, SDLK_LGUI },
{ XK_Control_R, SDLK_RCTRL },
{ XK_Shift_R, SDLK_RSHIFT },
{ XK_Alt_R, SDLK_RALT },
{ XK_Meta_R, SDLK_RGUI },
{ XK_Super_R, SDLK_RGUI },
{ XK_Mode_switch, SDLK_MODE },
134
135
};
136
static const struct
137
{
138
const SDL_Scancode const *table;
139
140
int table_size;
} scancode_set[] = {
141
142
{ darwin_scancode_table, SDL_arraysize(darwin_scancode_table) },
{ xfree86_scancode_table, SDL_arraysize(xfree86_scancode_table) },
143
{ xfree86_scancode_table2, SDL_arraysize(xfree86_scancode_table2) },
144
145
};
/* *INDENT-OFF* */
146
147
static SDL_Keycode
148
149
150
151
152
153
154
155
156
157
158
159
160
X11_KeyCodeToSDLKey(Display *display, KeyCode keycode)
{
KeySym keysym;
unsigned int ucs4;
int i;
keysym = XKeycodeToKeysym(display, keycode, 0);
if (keysym == NoSymbol) {
return SDLK_UNKNOWN;
}
ucs4 = X11_KeySymToUcs4(keysym);
if (ucs4) {
161
return (SDL_Keycode) ucs4;
162
163
164
165
166
167
168
169
170
171
}
for (i = 0; i < SDL_arraysize(KeySymToSDLKey); ++i) {
if (keysym == KeySymToSDLKey[i].keysym) {
return KeySymToSDLKey[i].sdlkey;
}
}
return SDLK_UNKNOWN;
}
172
int
173
174
175
X11_InitKeyboard(_THIS)
{
SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
176
177
int i, j;
int min_keycode, max_keycode;
178
struct {
179
SDL_Scancode scancode;
180
181
182
183
184
185
KeySym keysym;
int value;
} fingerprint[] = {
{ SDL_SCANCODE_HOME, XK_Home, 0 },
{ SDL_SCANCODE_PAGEUP, XK_Prior, 0 },
{ SDL_SCANCODE_PAGEDOWN, XK_Next, 0 },
186
};
187
SDL_bool fingerprint_detected;
188
189
XAutoRepeatOn(data->display);
190
191
192
193
/* Try to determine which scancodes are being used based on fingerprint */
fingerprint_detected = SDL_FALSE;
XDisplayKeycodes(data->display, &min_keycode, &max_keycode);
194
195
196
for (i = 0; i < SDL_arraysize(fingerprint); ++i) {
fingerprint[i].value =
XKeysymToKeycode(data->display, fingerprint[i].keysym) -
197
198
199
200
201
202
203
204
min_keycode;
}
for (i = 0; i < SDL_arraysize(scancode_set); ++i) {
/* Make sure the scancode set isn't too big */
if ((max_keycode - min_keycode + 1) <= scancode_set[i].table_size) {
continue;
}
for (j = 0; j < SDL_arraysize(fingerprint); ++j) {
205
206
if (fingerprint[j].value < 0
|| fingerprint[j].value >= scancode_set[i].table_size) {
207
208
break;
}
209
210
if (scancode_set[i].table[fingerprint[j].value] !=
fingerprint[j].scancode) {
211
212
213
break;
}
}
214
if (j == SDL_arraysize(fingerprint)) {
215
216
217
#ifdef DEBUG_KEYBOARD
printf("Using scancode set %d, min_keycode = %d, max_keycode = %d, table_size = %d\n", i, min_keycode, max_keycode, scancode_set[i].table_size);
#endif
218
SDL_memcpy(&data->key_layout[min_keycode], scancode_set[i].table,
219
sizeof(SDL_Scancode) * scancode_set[i].table_size);
220
221
fingerprint_detected = SDL_TRUE;
break;
222
223
224
}
}
225
if (!fingerprint_detected) {
226
SDL_Keycode keymap[SDL_NUM_SCANCODES];
227
228
229
230
231
printf
("Keyboard layout unknown, please send the following to the SDL mailing list (sdl@libsdl.org):\n");
/* Determine key_layout - only works on US QWERTY layout */
232
SDL_GetDefaultKeymap(keymap);
233
234
235
for (i = min_keycode; i <= max_keycode; ++i) {
KeySym sym;
sym = XKeycodeToKeysym(data->display, i, 0);
236
if (sym != NoSymbol) {
237
SDL_Keycode key;
238
239
printf("code = %d, sym = 0x%X (%s) ", i - min_keycode,
(unsigned int) sym, XKeysymToString(sym));
240
241
242
key = X11_KeyCodeToSDLKey(data->display, i);
for (j = 0; j < SDL_arraysize(keymap); ++j) {
if (keymap[j] == key) {
243
data->key_layout[i] = (SDL_Scancode) j;
244
245
246
break;
}
}
247
if (j == SDL_arraysize(keymap)) {
248
249
250
251
printf("scancode not found\n");
} else {
printf("scancode = %d (%s)\n", j, SDL_GetScancodeName(j));
}
252
253
254
}
}
}
255
256
X11_UpdateKeymap(_this);
257
258
SDL_SetScancodeName(SDL_SCANCODE_APPLICATION, "Menu");
259
260
261
262
return 0;
}
263
264
void
X11_UpdateKeymap(_THIS)
265
266
{
SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
267
int i;
268
SDL_Scancode scancode;
269
SDL_Keycode keymap[SDL_NUM_SCANCODES];
270
271
SDL_zero(keymap);
272
273
for (i = 0; i < SDL_arraysize(data->key_layout); i++) {
274
275
/* Make sure this is a valid scancode */
276
scancode = data->key_layout[i];
277
if (scancode == SDL_SCANCODE_UNKNOWN) {
278
279
continue;
}
280
281
keymap[scancode] = X11_KeyCodeToSDLKey(data->display, (KeyCode)i);
282
}
283
SDL_SetKeymap(0, keymap, SDL_NUM_SCANCODES);
284
285
286
287
288
289
290
}
void
X11_QuitKeyboard(_THIS)
{
}
291
292
#endif /* SDL_VIDEO_DRIVER_X11 */
293
/* vi: set ts=4 sw=4 expandtab: */