This repository has been archived by the owner on Feb 11, 2021. It is now read-only.
/
SDL_x11keyboard.c
290 lines (260 loc) · 8.55 KB
1
2
/*
SDL - Simple DirectMedia Layer
3
Copyright (C) 1997-2010 Sam Lantinga
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
*/
#include "SDL_config.h"
#include "SDL_x11video.h"
#include "../../events/SDL_keyboard_c.h"
27
28
#include "../../events/scancodes_darwin.h"
#include "../../events/scancodes_xfree86.h"
29
30
31
32
33
#include <X11/keysym.h>
#include "imKStoUCS.h"
34
/* *INDENT-OFF* */
35
static const struct {
36
KeySym keysym;
37
SDL_Keycode sdlkey;
38
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
} 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 },
133
134
};
135
static const struct
136
{
137
const SDL_Scancode const *table;
138
139
int table_size;
} scancode_set[] = {
140
141
{ darwin_scancode_table, SDL_arraysize(darwin_scancode_table) },
{ xfree86_scancode_table, SDL_arraysize(xfree86_scancode_table) },
142
{ xfree86_scancode_table2, SDL_arraysize(xfree86_scancode_table2) },
143
144
};
/* *INDENT-OFF* */
145
146
static SDL_Keycode
147
148
149
150
151
152
153
154
155
156
157
158
159
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) {
160
return (SDL_Keycode) ucs4;
161
162
163
164
165
166
167
168
169
170
}
for (i = 0; i < SDL_arraysize(KeySymToSDLKey); ++i) {
if (keysym == KeySymToSDLKey[i].keysym) {
return KeySymToSDLKey[i].sdlkey;
}
}
return SDLK_UNKNOWN;
}
171
int
172
173
174
X11_InitKeyboard(_THIS)
{
SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
175
176
int i, j;
int min_keycode, max_keycode;
177
struct {
178
SDL_Scancode scancode;
179
180
181
182
183
184
KeySym keysym;
int value;
} fingerprint[] = {
{ SDL_SCANCODE_HOME, XK_Home, 0 },
{ SDL_SCANCODE_PAGEUP, XK_Prior, 0 },
{ SDL_SCANCODE_PAGEDOWN, XK_Next, 0 },
185
};
186
SDL_bool fingerprint_detected;
187
188
XAutoRepeatOn(data->display);
189
190
191
192
/* Try to determine which scancodes are being used based on fingerprint */
fingerprint_detected = SDL_FALSE;
XDisplayKeycodes(data->display, &min_keycode, &max_keycode);
193
194
195
for (i = 0; i < SDL_arraysize(fingerprint); ++i) {
fingerprint[i].value =
XKeysymToKeycode(data->display, fingerprint[i].keysym) -
196
197
198
199
200
201
202
203
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) {
204
205
if (fingerprint[j].value < 0
|| fingerprint[j].value >= scancode_set[i].table_size) {
206
207
break;
}
208
209
if (scancode_set[i].table[fingerprint[j].value] !=
fingerprint[j].scancode) {
210
211
212
break;
}
}
213
if (j == SDL_arraysize(fingerprint)) {
214
215
216
#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
217
SDL_memcpy(&data->key_layout[min_keycode], scancode_set[i].table,
218
sizeof(SDL_Scancode) * scancode_set[i].table_size);
219
220
fingerprint_detected = SDL_TRUE;
break;
221
222
223
}
}
224
if (!fingerprint_detected) {
225
SDL_Keycode keymap[SDL_NUM_SCANCODES];
226
227
228
229
230
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 */
231
SDL_GetDefaultKeymap(keymap);
232
233
234
for (i = min_keycode; i <= max_keycode; ++i) {
KeySym sym;
sym = XKeycodeToKeysym(data->display, i, 0);
235
if (sym != NoSymbol) {
236
SDL_Keycode key;
237
238
printf("code = %d, sym = 0x%X (%s) ", i - min_keycode,
(unsigned int) sym, XKeysymToString(sym));
239
240
241
key = X11_KeyCodeToSDLKey(data->display, i);
for (j = 0; j < SDL_arraysize(keymap); ++j) {
if (keymap[j] == key) {
242
data->key_layout[i] = (SDL_Scancode) j;
243
244
245
break;
}
}
246
if (j == SDL_arraysize(keymap)) {
247
248
249
250
printf("scancode not found\n");
} else {
printf("scancode = %d (%s)\n", j, SDL_GetScancodeName(j));
}
251
252
253
}
}
}
254
255
X11_UpdateKeymap(_this);
256
257
SDL_SetScancodeName(SDL_SCANCODE_APPLICATION, "Menu");
258
259
260
261
return 0;
}
262
263
void
X11_UpdateKeymap(_THIS)
264
265
{
SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
266
int i;
267
SDL_Scancode scancode;
268
SDL_Keycode keymap[SDL_NUM_SCANCODES];
269
270
SDL_zero(keymap);
271
272
for (i = 0; i < SDL_arraysize(data->key_layout); i++) {
273
274
/* Make sure this is a valid scancode */
275
scancode = data->key_layout[i];
276
if (scancode == SDL_SCANCODE_UNKNOWN) {
277
278
continue;
}
279
280
keymap[scancode] = X11_KeyCodeToSDLKey(data->display, (KeyCode)i);
281
}
282
SDL_SetKeymap(0, keymap, SDL_NUM_SCANCODES);
283
284
285
286
287
288
289
290
}
void
X11_QuitKeyboard(_THIS)
{
}
/* vi: set ts=4 sw=4 expandtab: */