comparison src/video/x11/SDL_x11keyboard.c @ 2305:fbe8ff44c519

First pass of new SDL scancode concept for X11.
author Sam Lantinga <slouken@libsdl.org>
date Thu, 07 Feb 2008 15:31:09 +0000
parents a7cbc25071b6
children 1a8bab15a45d
comparison
equal deleted inserted replaced
2304:50f58ce12497 2305:fbe8ff44c519
22 #include "SDL_config.h" 22 #include "SDL_config.h"
23 23
24 #include "SDL_x11video.h" 24 #include "SDL_x11video.h"
25 25
26 #include "../../events/SDL_keyboard_c.h" 26 #include "../../events/SDL_keyboard_c.h"
27 #include "../../events/scancodes_darwin.h"
28 #include "../../events/scancodes_xfree86.h"
27 29
28 #include <X11/keysym.h> 30 #include <X11/keysym.h>
29 31
30 #include "imKStoUCS.h" 32 #include "imKStoUCS.h"
31 33
32 /* 34 static KeySym XKeySymTable[SDL_NUM_SCANCODES] = {
33 KeyCode-to-SDLKey translation tables for various X servers. Which 35 0, 0, 0, 0,
34 one to use is decided in X11_InitKeyboard(). 36 XK_a,
35 */ 37 XK_b,
36 38 XK_c,
37 static SDLKey macKeyCodeToSDLK[]; 39 XK_d,
38 static SDLKey xorgLinuxKeyCodeToSDLK[]; 40 XK_e,
39 41 XK_f,
40 static SDLKey *keyCodeToSDLKeyTables[] = { 42 XK_g,
41 xorgLinuxKeyCodeToSDLK, 43 XK_h,
42 macKeyCodeToSDLK, 44 XK_i,
43 NULL 45 XK_j,
46 XK_k,
47 XK_l,
48 XK_m,
49 XK_n,
50 XK_o,
51 XK_p,
52 XK_q,
53 XK_r,
54 XK_s,
55 XK_t,
56 XK_u,
57 XK_v,
58 XK_w,
59 XK_x,
60 XK_y,
61 XK_z,
62 XK_1,
63 XK_2,
64 XK_3,
65 XK_4,
66 XK_5,
67 XK_6,
68 XK_7,
69 XK_8,
70 XK_9,
71 XK_0,
72 XK_Return,
73 XK_Escape,
74 XK_BackSpace,
75 XK_Tab,
76 XK_space,
77 XK_minus,
78 XK_equal,
79 XK_bracketleft,
80 XK_bracketright,
81 XK_backslash,
82 0, /* SDL_SCANCODE_NONUSHASH ? */
83 XK_semicolon,
84 XK_apostrophe,
85 XK_grave,
86 XK_comma,
87 XK_period,
88 XK_slash,
89 XK_Caps_Lock,
90 XK_F1,
91 XK_F2,
92 XK_F3,
93 XK_F4,
94 XK_F5,
95 XK_F6,
96 XK_F7,
97 XK_F8,
98 XK_F9,
99 XK_F10,
100 XK_F11,
101 XK_F12,
102 XK_Print,
103 XK_Scroll_Lock,
104 XK_Pause,
105 XK_Insert,
106 XK_Home,
107 XK_Prior,
108 XK_Delete,
109 XK_End,
110 XK_Next,
111 XK_Right,
112 XK_Left,
113 XK_Down,
114 XK_Up,
115 XK_Num_Lock,
116 XK_KP_Divide,
117 XK_KP_Multiply,
118 XK_KP_Subtract,
119 XK_KP_Add,
120 XK_KP_Enter,
121 XK_KP_1,
122 XK_KP_2,
123 XK_KP_3,
124 XK_KP_4,
125 XK_KP_5,
126 XK_KP_6,
127 XK_KP_7,
128 XK_KP_8,
129 XK_KP_9,
130 XK_KP_0,
131 XK_KP_Decimal,
132 0, /* SDL_SCANCODE_NONUSBACKSLASH ? */
133 XK_Hyper_R,
134 0, /* SDL_SCANCODE_POWER ? */
135 XK_KP_Equal,
136 XK_F13,
137 XK_F14,
138 XK_F15,
139 XK_F16,
140 XK_F17,
141 XK_F18,
142 XK_F19,
143 XK_F20,
144 XK_F21,
145 XK_F22,
146 XK_F23,
147 XK_F24,
148 XK_Execute,
149 XK_Help,
150 XK_Menu,
151 XK_Select,
152 XK_Cancel,
153 XK_Redo,
154 XK_Undo,
155 0, /* SDL_SCANCODE_CUT ? */
156 0, /* SDL_SCANCODE_COPY ? */
157 0, /* SDL_SCANCODE_PASTE ? */
158 XK_Find,
159 0, /* SDL_SCANCODE_MUTE ? */
160 0, /* SDL_SCANCODE_VOLUMEUP ? */
161 0, /* SDL_SCANCODE_VOLUMEDOWN ? */
162 0, 0, 0,
163 XK_KP_Separator,
164 0, /* SDL_SCANCODE_KP_EQUALSAS400 ? */
165 0, /* SDL_SCANCODE_INTERNATIONAL1 ? */
166 0, /* SDL_SCANCODE_INTERNATIONAL2 ? */
167 0, /* SDL_SCANCODE_INTERNATIONAL3 ? */
168 0, /* SDL_SCANCODE_INTERNATIONAL4 ? */
169 0, /* SDL_SCANCODE_INTERNATIONAL5 ? */
170 0, /* SDL_SCANCODE_INTERNATIONAL6 ? */
171 0, /* SDL_SCANCODE_INTERNATIONAL7 ? */
172 0, /* SDL_SCANCODE_INTERNATIONAL8 ? */
173 0, /* SDL_SCANCODE_INTERNATIONAL9 ? */
174 0, /* SDL_SCANCODE_LANG1 ? */
175 0, /* SDL_SCANCODE_LANG2 ? */
176 0, /* SDL_SCANCODE_LANG3 ? */
177 0, /* SDL_SCANCODE_LANG4 ? */
178 0, /* SDL_SCANCODE_LANG5 ? */
179 0, /* SDL_SCANCODE_LANG6 ? */
180 0, /* SDL_SCANCODE_LANG7 ? */
181 0, /* SDL_SCANCODE_LANG8 ? */
182 0, /* SDL_SCANCODE_LANG9 ? */
183 0, /* SDL_SCANCODE_ALTERASE ? */
184 XK_Sys_Req,
185 0, /* SDL_SCANCODE_CANCEL ? - XK_Cancel was used above... */
186 0, /* SDL_SCANCODE_CLEAR ? */
187 0, /* SDL_SCANCODE_PRIOR ? - XK_Prior was used above... */
188 0, /* SDL_SCANCODE_RETURN2 ? */
189 0, /* SDL_SCANCODE_SEPARATOR ? */
190 0, /* SDL_SCANCODE_OUT ? */
191 0, /* SDL_SCANCODE_OPER ? */
192 0, /* SDL_SCANCODE_CLEARAGAIN ? */
193 0, /* SDL_SCANCODE_CRSEL ? */
194 0, /* SDL_SCANCODE_EXSEL ? */
195 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
196 0, /* SDL_SCANCODE_KP_00 ? */
197 0, /* SDL_SCANCODE_KP_000 ? */
198 0, /* SDL_SCANCODE_THOUSANDSSEPARATOR ? */
199 0, /* SDL_SCANCODE_DECIMALSEPARATOR ? */
200 0, /* SDL_SCANCODE_CURRENCYUNIT ? */
201 0, /* SDL_SCANCODE_CURRENCYSUBUNIT ? */
202 0, /* SDL_SCANCODE_KP_LEFTPAREN ? */
203 0, /* SDL_SCANCODE_KP_RIGHTPAREN ? */
204 0, /* SDL_SCANCODE_KP_LEFTBRACE ? */
205 0, /* SDL_SCANCODE_KP_RIGHTBRACE ? */
206 0, /* SDL_SCANCODE_KP_TAB ? */
207 0, /* SDL_SCANCODE_KP_BACKSPACE ? */
208 0, /* SDL_SCANCODE_KP_A ? */
209 0, /* SDL_SCANCODE_KP_B ? */
210 0, /* SDL_SCANCODE_KP_C ? */
211 0, /* SDL_SCANCODE_KP_D ? */
212 0, /* SDL_SCANCODE_KP_E ? */
213 0, /* SDL_SCANCODE_KP_F ? */
214 0, /* SDL_SCANCODE_KP_XOR ? */
215 0, /* SDL_SCANCODE_KP_POWER ? */
216 0, /* SDL_SCANCODE_KP_PERCENT ? */
217 0, /* SDL_SCANCODE_KP_LESS ? */
218 0, /* SDL_SCANCODE_KP_GREATER ? */
219 0, /* SDL_SCANCODE_KP_AMPERSAND ? */
220 0, /* SDL_SCANCODE_KP_DBLAMPERSAND ? */
221 0, /* SDL_SCANCODE_KP_VERTICALBAR ? */
222 0, /* SDL_SCANCODE_KP_DBLVERTICALBAR ? */
223 0, /* SDL_SCANCODE_KP_COLON ? */
224 0, /* SDL_SCANCODE_KP_HASH ? */
225 0, /* SDL_SCANCODE_KP_SPACE ? */
226 0, /* SDL_SCANCODE_KP_AT ? */
227 0, /* SDL_SCANCODE_KP_EXCLAM ? */
228 0, /* SDL_SCANCODE_KP_MEMSTORE ? */
229 0, /* SDL_SCANCODE_KP_MEMRECALL ? */
230 0, /* SDL_SCANCODE_KP_MEMCLEAR ? */
231 0, /* SDL_SCANCODE_KP_MEMADD ? */
232 0, /* SDL_SCANCODE_KP_MEMSUBTRACT ? */
233 0, /* SDL_SCANCODE_KP_MEMMULTIPLY ? */
234 0, /* SDL_SCANCODE_KP_MEMDIVIDE ? */
235 0, /* SDL_SCANCODE_KP_PLUSMINUS ? */
236 0, /* SDL_SCANCODE_KP_CLEAR ? */
237 0, /* SDL_SCANCODE_KP_CLEARENTRY ? */
238 0, /* SDL_SCANCODE_KP_BINARY ? */
239 0, /* SDL_SCANCODE_KP_OCTAL ? */
240 0, /* SDL_SCANCODE_KP_DECIMAL ? */
241 0, /* SDL_SCANCODE_KP_HEXADECIMAL ? */
242 0, 0,
243 XK_Control_L,
244 XK_Shift_L,
245 XK_Alt_L,
246 XK_Meta_L,
247 XK_Control_R,
248 XK_Shift_R,
249 XK_Alt_R,
250 XK_Meta_R,
251 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
252 XK_Mode_switch /*XK_ISO_Level3_Shift */ ,
253 0, /* SDL_SCANCODE_AUDIONEXT ? */
254 0, /* SDL_SCANCODE_AUDIOPREV ? */
255 0, /* SDL_SCANCODE_AUDIOSTOP ? */
256 0, /* SDL_SCANCODE_AUDIOPLAY ? */
257 0, /* SDL_SCANCODE_AUDIOMUTE ? */
258 0, /* SDL_SCANCODE_MEDIASELECT ? */
259 0, /* SDL_SCANCODE_WWW ? */
260 0, /* SDL_SCANCODE_MAIL ? */
261 0, /* SDL_SCANCODE_CALCULATOR ? */
262 0, /* SDL_SCANCODE_COMPUTER ? */
263 0, /* SDL_SCANCODE_AC_SEARCH ? */
264 0, /* SDL_SCANCODE_AC_HOME ? */
265 0, /* SDL_SCANCODE_AC_BACK ? */
266 0, /* SDL_SCANCODE_AC_FORWARD ? */
267 0, /* SDL_SCANCODE_AC_STOP ? */
268 0, /* SDL_SCANCODE_AC_REFRESH ? */
269 0, /* SDL_SCANCODE_AC_BOOKMARKS ? */
270 0, /* SDL_SCANCODE_BRIGHTNESSDOWN ? */
271 0, /* SDL_SCANCODE_BRIGHTNESSUP ? */
272 0, /* SDL_SCANCODE_DISPLAYSWITCH ? */
273 0, /* SDL_SCANCODE_KBDILLUMTOGGLE ? */
274 0, /* SDL_SCANCODE_KBDILLUMDOWN ? */
275 0, /* SDL_SCANCODE_KBDILLUMUP ? */
276 0, /* SDL_SCANCODE_EJECT ? */
277 0, /* SDL_SCANCODE_SLEEP ? */
44 }; 278 };
45 279
46 /* *INDENT-OFF* */
47
48 /* These are just Mac virtual key codes + 8 (see SDL/src/video/cocoa/
49 SDL_cocoakeys.h for more info). Observed to work with Apple X11 on
50 Mac OS X 10.4. May also work on older Linux distributions on Mac
51 hardware.
52 */
53
54 #define KeyCodeTableSize (256)
55 static SDLKey macKeyCodeToSDLK[KeyCodeTableSize] =
56 {
57 /* 0 */ SDLK_UNKNOWN,
58 /* 1 */ SDLK_UNKNOWN,
59 /* 2 */ SDLK_UNKNOWN,
60 /* 3 */ SDLK_UNKNOWN,
61 /* 4 */ SDLK_UNKNOWN,
62 /* 5 */ SDLK_UNKNOWN,
63 /* 6 */ SDLK_UNKNOWN,
64 /* 7 */ SDLK_UNKNOWN,
65 /* 8 */ SDLK_A,
66 /* 9 */ SDLK_S,
67 /* 10 */ SDLK_D,
68 /* 11 */ SDLK_F,
69 /* 12 */ SDLK_H,
70 /* 13 */ SDLK_G,
71 /* 14 */ SDLK_Z,
72 /* 15 */ SDLK_X,
73 /* 16 */ SDLK_C,
74 /* 17 */ SDLK_V,
75 /* 18 */ SDLK_GRAVE,
76 /* 19 */ SDLK_B,
77 /* 20 */ SDLK_Q,
78 /* 21 */ SDLK_W,
79 /* 22 */ SDLK_E,
80 /* 23 */ SDLK_R,
81 /* 24 */ SDLK_Y,
82 /* 25 */ SDLK_T,
83 /* 26 */ SDLK_1,
84 /* 27 */ SDLK_2,
85 /* 28 */ SDLK_3,
86 /* 29 */ SDLK_4,
87 /* 30 */ SDLK_6,
88 /* 31 */ SDLK_5,
89 /* 32 */ SDLK_EQUALS,
90 /* 33 */ SDLK_9,
91 /* 34 */ SDLK_7,
92 /* 35 */ SDLK_HYPHENMINUS,
93 /* 36 */ SDLK_8,
94 /* 37 */ SDLK_0,
95 /* 38 */ SDLK_RIGHTBRACKET,
96 /* 39 */ SDLK_O,
97 /* 40 */ SDLK_U,
98 /* 41 */ SDLK_LEFTBRACKET,
99 /* 42 */ SDLK_I,
100 /* 43 */ SDLK_P,
101 /* 44 */ SDLK_RETURN,
102 /* 45 */ SDLK_L,
103 /* 46 */ SDLK_J,
104 /* 47 */ SDLK_APOSTROPHE,
105 /* 48 */ SDLK_K,
106 /* 49 */ SDLK_SEMICOLON,
107 /* 50 */ SDLK_BACKSLASH,
108 /* 51 */ SDLK_COMMA,
109 /* 52 */ SDLK_SLASH,
110 /* 53 */ SDLK_N,
111 /* 54 */ SDLK_M,
112 /* 55 */ SDLK_PERIOD,
113 /* 56 */ SDLK_TAB,
114 /* 57 */ SDLK_SPACE,
115 /* 58 */ SDLK_NONUSBACKSLASH,
116 /* 59 */ SDLK_BACKSPACE,
117 /* 60 */ SDLK_KP_ENTER,
118 /* 61 */ SDLK_ESCAPE,
119 /* 62 */ SDLK_RMETA,
120 /* 63 */ SDLK_LMETA,
121 /* 64 */ SDLK_LSHIFT,
122 /* 65 */ SDLK_CAPSLOCK,
123 /* 66 */ SDLK_LALT,
124 /* 67 */ SDLK_LCTRL,
125 /* 68 */ SDLK_RSHIFT,
126 /* 69 */ SDLK_RALT,
127 /* 70 */ SDLK_RCTRL,
128 /* 71 */ SDLK_NONE,
129 /* 72 */ SDLK_UNKNOWN,
130 /* 73 */ SDLK_KP_PERIOD,
131 /* 74 */ SDLK_UNKNOWN,
132 /* 75 */ SDLK_KP_MULTIPLY,
133 /* 76 */ SDLK_UNKNOWN,
134 /* 77 */ SDLK_KP_PLUS,
135 /* 78 */ SDLK_UNKNOWN,
136 /* 79 */ SDLK_KP_NUMLOCKCLEAR,
137 /* 80 */ SDLK_VOLUMEUP,
138 /* 81 */ SDLK_VOLUMEDOWN,
139 /* 82 */ SDLK_MUTE,
140 /* 83 */ SDLK_KP_DIVIDE,
141 /* 84 */ SDLK_KP_ENTER,
142 /* 85 */ SDLK_UNKNOWN,
143 /* 86 */ SDLK_KP_MINUS,
144 /* 87 */ SDLK_UNKNOWN,
145 /* 88 */ SDLK_UNKNOWN,
146 /* 89 */ SDLK_KP_EQUALS,
147 /* 90 */ SDLK_KP_0,
148 /* 91 */ SDLK_KP_1,
149 /* 92 */ SDLK_KP_2,
150 /* 93 */ SDLK_KP_3,
151 /* 94 */ SDLK_KP_4,
152 /* 95 */ SDLK_KP_5,
153 /* 96 */ SDLK_KP_6,
154 /* 97 */ SDLK_KP_7,
155 /* 98 */ SDLK_UNKNOWN,
156 /* 99 */ SDLK_KP_8,
157 /* 100 */ SDLK_KP_9,
158 /* 101 */ SDLK_INTERNATIONAL3,
159 /* 102 */ SDLK_INTERNATIONAL1,
160 /* 103 */ SDLK_KP_COMMA,
161 /* 104 */ SDLK_F5,
162 /* 105 */ SDLK_F6,
163 /* 106 */ SDLK_F7,
164 /* 107 */ SDLK_F3,
165 /* 108 */ SDLK_F8,
166 /* 109 */ SDLK_F9,
167 /* 110 */ SDLK_LANG2,
168 /* 111 */ SDLK_F11,
169 /* 112 */ SDLK_LANG1,
170 /* 113 */ SDLK_PRINTSCREEN,
171 /* 114 */ SDLK_F16,
172 /* 115 */ SDLK_SCROLLLOCK,
173 /* 116 */ SDLK_UNKNOWN,
174 /* 117 */ SDLK_F10,
175 /* 118 */ SDLK_APPLICATION,
176 /* 119 */ SDLK_F12,
177 /* 120 */ SDLK_UNKNOWN,
178 /* 121 */ SDLK_PAUSE,
179 /* 122 */ SDLK_INSERT,
180 /* 123 */ SDLK_HOME,
181 /* 124 */ SDLK_PAGEUP,
182 /* 125 */ SDLK_DELETE,
183 /* 126 */ SDLK_F4,
184 /* 127 */ SDLK_END,
185 /* 128 */ SDLK_F2,
186 /* 129 */ SDLK_PAGEDOWN,
187 /* 130 */ SDLK_F1,
188 /* 131 */ SDLK_LEFT,
189 /* 132 */ SDLK_RIGHT,
190 /* 133 */ SDLK_DOWN,
191 /* 134 */ SDLK_UP,
192 /* 135 */ SDLK_POWER,
193 /* 136 */ SDLK_UNKNOWN, /* codes higher than 135 shouldn't occur as Mac virtual keycodes only go to 127 */
194 /* 137 */ SDLK_UNKNOWN,
195 /* 138 */ SDLK_UNKNOWN,
196 /* 139 */ SDLK_UNKNOWN,
197 /* 140 */ SDLK_UNKNOWN,
198 /* 141 */ SDLK_UNKNOWN,
199 /* 142 */ SDLK_UNKNOWN,
200 /* 143 */ SDLK_UNKNOWN,
201 /* 144 */ SDLK_UNKNOWN,
202 /* 145 */ SDLK_UNKNOWN,
203 /* 146 */ SDLK_UNKNOWN,
204 /* 147 */ SDLK_UNKNOWN,
205 /* 148 */ SDLK_UNKNOWN,
206 /* 149 */ SDLK_UNKNOWN,
207 /* 150 */ SDLK_UNKNOWN,
208 /* 151 */ SDLK_UNKNOWN,
209 /* 152 */ SDLK_UNKNOWN,
210 /* 153 */ SDLK_UNKNOWN,
211 /* 154 */ SDLK_UNKNOWN,
212 /* 155 */ SDLK_UNKNOWN,
213 /* 156 */ SDLK_UNKNOWN,
214 /* 157 */ SDLK_UNKNOWN,
215 /* 158 */ SDLK_UNKNOWN,
216 /* 159 */ SDLK_UNKNOWN,
217 /* 160 */ SDLK_UNKNOWN,
218 /* 161 */ SDLK_UNKNOWN,
219 /* 162 */ SDLK_UNKNOWN,
220 /* 163 */ SDLK_UNKNOWN,
221 /* 164 */ SDLK_UNKNOWN,
222 /* 165 */ SDLK_UNKNOWN,
223 /* 166 */ SDLK_UNKNOWN,
224 /* 167 */ SDLK_UNKNOWN,
225 /* 168 */ SDLK_UNKNOWN,
226 /* 169 */ SDLK_UNKNOWN,
227 /* 170 */ SDLK_UNKNOWN,
228 /* 171 */ SDLK_UNKNOWN,
229 /* 172 */ SDLK_UNKNOWN,
230 /* 173 */ SDLK_UNKNOWN,
231 /* 174 */ SDLK_UNKNOWN,
232 /* 175 */ SDLK_UNKNOWN,
233 /* 176 */ SDLK_UNKNOWN,
234 /* 177 */ SDLK_UNKNOWN,
235 /* 178 */ SDLK_UNKNOWN,
236 /* 179 */ SDLK_UNKNOWN,
237 /* 180 */ SDLK_UNKNOWN,
238 /* 181 */ SDLK_UNKNOWN,
239 /* 182 */ SDLK_UNKNOWN,
240 /* 183 */ SDLK_UNKNOWN,
241 /* 184 */ SDLK_UNKNOWN,
242 /* 185 */ SDLK_UNKNOWN,
243 /* 186 */ SDLK_UNKNOWN,
244 /* 187 */ SDLK_UNKNOWN,
245 /* 188 */ SDLK_UNKNOWN,
246 /* 189 */ SDLK_UNKNOWN,
247 /* 190 */ SDLK_UNKNOWN,
248 /* 191 */ SDLK_UNKNOWN,
249 /* 192 */ SDLK_UNKNOWN,
250 /* 193 */ SDLK_UNKNOWN,
251 /* 194 */ SDLK_UNKNOWN,
252 /* 195 */ SDLK_UNKNOWN,
253 /* 196 */ SDLK_UNKNOWN,
254 /* 197 */ SDLK_UNKNOWN,
255 /* 198 */ SDLK_UNKNOWN,
256 /* 199 */ SDLK_UNKNOWN,
257 /* 200 */ SDLK_UNKNOWN,
258 /* 201 */ SDLK_UNKNOWN,
259 /* 202 */ SDLK_UNKNOWN,
260 /* 203 */ SDLK_UNKNOWN,
261 /* 204 */ SDLK_UNKNOWN,
262 /* 205 */ SDLK_UNKNOWN,
263 /* 206 */ SDLK_UNKNOWN,
264 /* 207 */ SDLK_UNKNOWN,
265 /* 208 */ SDLK_UNKNOWN,
266 /* 209 */ SDLK_UNKNOWN,
267 /* 210 */ SDLK_UNKNOWN,
268 /* 211 */ SDLK_UNKNOWN,
269 /* 212 */ SDLK_UNKNOWN,
270 /* 213 */ SDLK_UNKNOWN,
271 /* 214 */ SDLK_UNKNOWN,
272 /* 215 */ SDLK_UNKNOWN,
273 /* 216 */ SDLK_UNKNOWN,
274 /* 217 */ SDLK_UNKNOWN,
275 /* 218 */ SDLK_UNKNOWN,
276 /* 219 */ SDLK_UNKNOWN,
277 /* 220 */ SDLK_UNKNOWN,
278 /* 221 */ SDLK_UNKNOWN,
279 /* 222 */ SDLK_UNKNOWN,
280 /* 223 */ SDLK_UNKNOWN,
281 /* 224 */ SDLK_UNKNOWN,
282 /* 225 */ SDLK_UNKNOWN,
283 /* 226 */ SDLK_UNKNOWN,
284 /* 227 */ SDLK_UNKNOWN,
285 /* 228 */ SDLK_UNKNOWN,
286 /* 229 */ SDLK_UNKNOWN,
287 /* 230 */ SDLK_UNKNOWN,
288 /* 231 */ SDLK_UNKNOWN,
289 /* 232 */ SDLK_UNKNOWN,
290 /* 233 */ SDLK_UNKNOWN,
291 /* 234 */ SDLK_UNKNOWN,
292 /* 235 */ SDLK_UNKNOWN,
293 /* 236 */ SDLK_UNKNOWN,
294 /* 237 */ SDLK_UNKNOWN,
295 /* 238 */ SDLK_UNKNOWN,
296 /* 239 */ SDLK_UNKNOWN,
297 /* 240 */ SDLK_UNKNOWN,
298 /* 241 */ SDLK_UNKNOWN,
299 /* 242 */ SDLK_UNKNOWN,
300 /* 243 */ SDLK_UNKNOWN,
301 /* 244 */ SDLK_UNKNOWN,
302 /* 245 */ SDLK_UNKNOWN,
303 /* 246 */ SDLK_UNKNOWN,
304 /* 247 */ SDLK_UNKNOWN,
305 /* 248 */ SDLK_UNKNOWN,
306 /* 249 */ SDLK_UNKNOWN,
307 /* 250 */ SDLK_UNKNOWN,
308 /* 251 */ SDLK_UNKNOWN,
309 /* 252 */ SDLK_UNKNOWN,
310 /* 253 */ SDLK_UNKNOWN,
311 /* 254 */ SDLK_UNKNOWN,
312 /* 255 */ SDLK_UNKNOWN
313 };
314
315 /* Found mostly by experimentation with X.org on Linux (Fedora Core 4 and
316 Ubuntu Dapper) on PC and PPC Mac hardware, some parts (especially about
317 the "multimedia"/"internet" keys) from various sources on the web.
318 */
319 static SDLKey xorgLinuxKeyCodeToSDLK[KeyCodeTableSize] =
320 {
321 /* 0 */ SDLK_UNKNOWN,
322 /* 1 */ SDLK_UNKNOWN,
323 /* 2 */ SDLK_UNKNOWN,
324 /* 3 */ SDLK_UNKNOWN,
325 /* 4 */ SDLK_UNKNOWN,
326 /* 5 */ SDLK_UNKNOWN,
327 /* 6 */ SDLK_UNKNOWN,
328 /* 7 */ SDLK_UNKNOWN,
329 /* 8 */ SDLK_UNKNOWN,
330 /* 9 */ SDLK_ESCAPE,
331 /* 10 */ SDLK_1,
332 /* 11 */ SDLK_2,
333 /* 12 */ SDLK_3,
334 /* 13 */ SDLK_4,
335 /* 14 */ SDLK_5,
336 /* 15 */ SDLK_6,
337 /* 16 */ SDLK_7,
338 /* 17 */ SDLK_8,
339 /* 18 */ SDLK_9,
340 /* 19 */ SDLK_0,
341 /* 20 */ SDLK_HYPHENMINUS,
342 /* 21 */ SDLK_EQUALS,
343 /* 22 */ SDLK_BACKSPACE,
344 /* 23 */ SDLK_TAB,
345 /* 24 */ SDLK_Q,
346 /* 25 */ SDLK_W,
347 /* 26 */ SDLK_E,
348 /* 27 */ SDLK_R,
349 /* 28 */ SDLK_T,
350 /* 29 */ SDLK_Y,
351 /* 30 */ SDLK_U,
352 /* 31 */ SDLK_I,
353 /* 32 */ SDLK_O,
354 /* 33 */ SDLK_P,
355 /* 34 */ SDLK_LEFTBRACKET,
356 /* 35 */ SDLK_RIGHTBRACKET,
357 /* 36 */ SDLK_RETURN,
358 /* 37 */ SDLK_LCTRL,
359 /* 38 */ SDLK_A,
360 /* 39 */ SDLK_S,
361 /* 40 */ SDLK_D,
362 /* 41 */ SDLK_F,
363 /* 42 */ SDLK_G,
364 /* 43 */ SDLK_H,
365 /* 44 */ SDLK_J,
366 /* 45 */ SDLK_K,
367 /* 46 */ SDLK_L,
368 /* 47 */ SDLK_SEMICOLON,
369 /* 48 */ SDLK_APOSTROPHE,
370 /* 49 */ SDLK_GRAVE,
371 /* 50 */ SDLK_LSHIFT,
372 /* 51 */ SDLK_BACKSLASH,
373 /* 52 */ SDLK_Z,
374 /* 53 */ SDLK_X,
375 /* 54 */ SDLK_C,
376 /* 55 */ SDLK_V,
377 /* 56 */ SDLK_B,
378 /* 57 */ SDLK_N,
379 /* 58 */ SDLK_M,
380 /* 59 */ SDLK_COMMA,
381 /* 60 */ SDLK_PERIOD,
382 /* 61 */ SDLK_SLASH,
383 /* 62 */ SDLK_RSHIFT,
384 /* 63 */ SDLK_KP_MULTIPLY,
385 /* 64 */ SDLK_LALT,
386 /* 65 */ SDLK_SPACE,
387 /* 66 */ SDLK_CAPSLOCK,
388 /* 67 */ SDLK_F1,
389 /* 68 */ SDLK_F2,
390 /* 69 */ SDLK_F3,
391 /* 70 */ SDLK_F4,
392 /* 71 */ SDLK_F5,
393 /* 72 */ SDLK_F6,
394 /* 73 */ SDLK_F7,
395 /* 74 */ SDLK_F8,
396 /* 75 */ SDLK_F9,
397 /* 76 */ SDLK_F10,
398 /* 77 */ SDLK_KP_NUMLOCKCLEAR,
399 /* 78 */ SDLK_SCROLLLOCK,
400 /* 79 */ SDLK_KP_7,
401 /* 80 */ SDLK_KP_8,
402 /* 81 */ SDLK_KP_9,
403 /* 82 */ SDLK_KP_MINUS,
404 /* 83 */ SDLK_KP_4,
405 /* 84 */ SDLK_KP_5,
406 /* 85 */ SDLK_KP_6,
407 /* 86 */ SDLK_KP_PLUS,
408 /* 87 */ SDLK_KP_1,
409 /* 88 */ SDLK_KP_2,
410 /* 89 */ SDLK_KP_3,
411 /* 90 */ SDLK_KP_0,
412 /* 91 */ SDLK_KP_PERIOD,
413 /* 92 */ SDLK_SYSREQ,
414 /* 93 */ SDLK_MODE, /* is translated to XK_Mode_switch by my X server, but I have no keyboard that generates this code, so I'm not sure if this is correct */
415 /* 94 */ SDLK_NONUSBACKSLASH,
416 /* 95 */ SDLK_F11,
417 /* 96 */ SDLK_F12,
418 /* 97 */ SDLK_HOME,
419 /* 98 */ SDLK_UP,
420 /* 99 */ SDLK_PAGEUP,
421 /* 100 */ SDLK_LEFT,
422 /* 101 */ SDLK_BRIGHTNESSDOWN, /* on PowerBook G4 */
423 /* 102 */ SDLK_RIGHT,
424 /* 103 */ SDLK_END,
425 /* 104 */ SDLK_DOWN,
426 /* 105 */ SDLK_PAGEDOWN,
427 /* 106 */ SDLK_INSERT,
428 /* 107 */ SDLK_DELETE,
429 /* 108 */ SDLK_KP_ENTER,
430 /* 109 */ SDLK_RCTRL,
431 /* 110 */ SDLK_PAUSE,
432 /* 111 */ SDLK_PRINTSCREEN,
433 /* 112 */ SDLK_KP_DIVIDE,
434 /* 113 */ SDLK_RALT,
435 /* 114 */ SDLK_UNKNOWN,
436 /* 115 */ SDLK_LMETA,
437 /* 116 */ SDLK_RMETA,
438 /* 117 */ SDLK_APPLICATION,
439 /* 118 */ SDLK_F13,
440 /* 119 */ SDLK_F14,
441 /* 120 */ SDLK_F15,
442 /* 121 */ SDLK_F16,
443 /* 122 */ SDLK_F17,
444 /* 123 */ SDLK_UNKNOWN,
445 /* 124 */ SDLK_UNKNOWN, /* is translated to XK_ISO_Level3_Shift by my X server, but I have no keyboard that generates this code, so I don't know what the correct SDLK_* for it is */
446 /* 125 */ SDLK_UNKNOWN,
447 /* 126 */ SDLK_KP_EQUALS,
448 /* 127 */ SDLK_UNKNOWN,
449 /* 128 */ SDLK_UNKNOWN,
450 /* 129 */ SDLK_UNKNOWN,
451 /* 130 */ SDLK_UNKNOWN,
452 /* 131 */ SDLK_UNKNOWN,
453 /* 132 */ SDLK_UNKNOWN,
454 /* 133 */ SDLK_INTERNATIONAL3, /* Yen */
455 /* 134 */ SDLK_UNKNOWN,
456 /* 135 */ SDLK_AGAIN,
457 /* 136 */ SDLK_UNDO,
458 /* 137 */ SDLK_UNKNOWN,
459 /* 138 */ SDLK_UNKNOWN,
460 /* 139 */ SDLK_UNKNOWN,
461 /* 140 */ SDLK_UNKNOWN,
462 /* 141 */ SDLK_UNKNOWN,
463 /* 142 */ SDLK_UNKNOWN,
464 /* 143 */ SDLK_UNKNOWN,
465 /* 144 */ SDLK_AUDIOPREV,
466 /* 145 */ SDLK_UNKNOWN,
467 /* 146 */ SDLK_UNKNOWN,
468 /* 147 */ SDLK_UNKNOWN,
469 /* 148 */ SDLK_UNKNOWN,
470 /* 149 */ SDLK_UNKNOWN,
471 /* 150 */ SDLK_UNKNOWN,
472 /* 151 */ SDLK_UNKNOWN,
473 /* 152 */ SDLK_UNKNOWN,
474 /* 153 */ SDLK_AUDIONEXT,
475 /* 154 */ SDLK_UNKNOWN,
476 /* 155 */ SDLK_UNKNOWN,
477 /* 156 */ SDLK_UNKNOWN,
478 /* 157 */ SDLK_KP_EQUALS, /* on PowerBook G4 */
479 /* 158 */ SDLK_UNKNOWN,
480 /* 159 */ SDLK_UNKNOWN,
481 /* 160 */ SDLK_MUTE,
482 /* 161 */ SDLK_CALC,
483 /* 162 */ SDLK_AUDIOPLAY,
484 /* 163 */ SDLK_UNKNOWN,
485 /* 164 */ SDLK_AUDIOSTOP,
486 /* 165 */ SDLK_UNKNOWN,
487 /* 166 */ SDLK_UNKNOWN,
488 /* 167 */ SDLK_UNKNOWN,
489 /* 168 */ SDLK_UNKNOWN,
490 /* 169 */ SDLK_UNKNOWN,
491 /* 170 */ SDLK_UNKNOWN,
492 /* 171 */ SDLK_UNKNOWN,
493 /* 172 */ SDLK_UNKNOWN,
494 /* 173 */ SDLK_UNKNOWN,
495 /* 174 */ SDLK_VOLUMEDOWN,
496 /* 175 */ SDLK_UNKNOWN,
497 /* 176 */ SDLK_VOLUMEUP,
498 /* 177 */ SDLK_UNKNOWN,
499 /* 178 */ SDLK_WWW,
500 /* 179 */ SDLK_UNKNOWN,
501 /* 180 */ SDLK_UNKNOWN,
502 /* 181 */ SDLK_UNKNOWN,
503 /* 182 */ SDLK_UNKNOWN,
504 /* 183 */ SDLK_UNKNOWN,
505 /* 184 */ SDLK_UNKNOWN,
506 /* 185 */ SDLK_UNKNOWN,
507 /* 186 */ SDLK_UNKNOWN,
508 /* 187 */ SDLK_HELP,
509 /* 188 */ SDLK_UNKNOWN,
510 /* 189 */ SDLK_UNKNOWN,
511 /* 190 */ SDLK_UNKNOWN,
512 /* 191 */ SDLK_UNKNOWN,
513 /* 192 */ SDLK_UNKNOWN,
514 /* 193 */ SDLK_UNKNOWN,
515 /* 194 */ SDLK_UNKNOWN,
516 /* 195 */ SDLK_UNKNOWN,
517 /* 196 */ SDLK_UNKNOWN,
518 /* 197 */ SDLK_UNKNOWN,
519 /* 198 */ SDLK_UNKNOWN,
520 /* 199 */ SDLK_UNKNOWN,
521 /* 200 */ SDLK_UNKNOWN,
522 /* 201 */ SDLK_UNKNOWN,
523 /* 202 */ SDLK_UNKNOWN,
524 /* 203 */ SDLK_UNKNOWN,
525 /* 204 */ SDLK_EJECT, /* on PowerBook G4 */
526 /* 205 */ SDLK_UNKNOWN,
527 /* 206 */ SDLK_UNKNOWN,
528 /* 207 */ SDLK_UNKNOWN,
529 /* 208 */ SDLK_UNKNOWN,
530 /* 209 */ SDLK_UNKNOWN,
531 /* 210 */ SDLK_UNKNOWN,
532 /* 211 */ SDLK_UNKNOWN,
533 /* 212 */ SDLK_BRIGHTNESSUP, /* on PowerBook G4 */
534 /* 213 */ SDLK_UNKNOWN,
535 /* 214 */ SDLK_DISPLAYSWITCH, /* on PowerBook G4 */
536 /* 215 */ SDLK_KBDILLUMTOGGLE,
537 /* 216 */ SDLK_KBDILLUMDOWN,
538 /* 217 */ SDLK_KBDILLUMUP,
539 /* 218 */ SDLK_UNKNOWN,
540 /* 219 */ SDLK_UNKNOWN,
541 /* 220 */ SDLK_UNKNOWN,
542 /* 221 */ SDLK_UNKNOWN,
543 /* 222 */ SDLK_POWER,
544 /* 223 */ SDLK_SLEEP,
545 /* 224 */ SDLK_UNKNOWN,
546 /* 225 */ SDLK_UNKNOWN,
547 /* 226 */ SDLK_UNKNOWN,
548 /* 227 */ SDLK_UNKNOWN,
549 /* 228 */ SDLK_UNKNOWN,
550 /* 229 */ SDLK_SEARCH,
551 /* 230 */ SDLK_BOOKMARKS,
552 /* 231 */ SDLK_BROWSERRELOAD,
553 /* 232 */ SDLK_BROWSERSTOP,
554 /* 233 */ SDLK_BROWSERFORWARD,
555 /* 234 */ SDLK_BROWSERBACK,
556 /* 235 */ SDLK_COMPUTER,
557 /* 236 */ SDLK_EMAIL,
558 /* 237 */ SDLK_MEDIA,
559 /* 238 */ SDLK_UNKNOWN,
560 /* 239 */ SDLK_UNKNOWN,
561 /* 240 */ SDLK_UNKNOWN,
562 /* 241 */ SDLK_UNKNOWN,
563 /* 242 */ SDLK_UNKNOWN,
564 /* 243 */ SDLK_UNKNOWN,
565 /* 244 */ SDLK_UNKNOWN,
566 /* 245 */ SDLK_UNKNOWN,
567 /* 246 */ SDLK_UNKNOWN,
568 /* 247 */ SDLK_UNKNOWN,
569 /* 248 */ SDLK_UNKNOWN,
570 /* 249 */ SDLK_UNKNOWN,
571 /* 250 */ SDLK_UNKNOWN,
572 /* 251 */ SDLK_UNKNOWN,
573 /* 252 */ SDLK_UNKNOWN,
574 /* 253 */ SDLK_UNKNOWN,
575 /* 254 */ SDLK_UNKNOWN,
576 /* 255 */ SDLK_UNKNOWN
577 };
578
579 /*---------------------------------------------------------------------------*/
580
581 /* Used by X11_KeySymToSDLKey(). This is a hybrid of a KeySym-to-layout-key
582 mapping (needed in X11_GetLayoutKey()) and a fallback KeySym-to-physical-key
583 mapping under the assumption of a US keyboard layout (needed in
584 X11_InitKeyboard()). If for a given KeySym...
585 - the layout and physical codes are the same (must be an SDLK_ constant):
586 there is one entry,
587 - the layout and physical codes differ: there are two entries, with the
588 layout one first,
589 - there is only a physical code in the table (must be an SDLK_ constant):
590 it's marked by X11_KEY_PHYSICAL_ONLY_BIT (this is the case when the layout
591 key code is handled by KeySymToUcs4()),
592 - there is only a layout code in the table (can't be an SDLK_ constant):
593 recognizable by the absence of SDL_KEY_CAN_BE_PHYSICAL_BIT.
594 This list is sorted by KeySym to allow a binary search.
595 */
596 #define X11_KEY_PHYSICAL_ONLY_BIT SDL_KEY_LAYOUT_SPECIAL_BIT
597 /* SDL_KEY_LAYOUT_SPECIAL_BIT cannot possibly occur in an SDLK_ constant, so we may repurpose that bit for our own use. */
598 static struct 280 static struct
599 { 281 {
600 KeySym sym; 282 SDL_scancode *table;
601 SDLKey key; 283 int table_size;
602 } keySymToSDLKey[KeyCodeTableSize] = 284 } scancode_set[] = {
603 { 285 {
604 /* 0x00xx */ 286 darwin_scancode_table, SDL_arraysize(darwin_scancode_table)}, {
605 {XK_space, SDLK_SPACE}, 287 xfree86_scancode_table, SDL_arraysize(xfree86_scancode_table)},};
606 {XK_apostrophe, SDLK_APOSTROPHE | X11_KEY_PHYSICAL_ONLY_BIT},
607 {XK_comma, SDLK_COMMA | X11_KEY_PHYSICAL_ONLY_BIT},
608 {XK_minus, SDLK_HYPHENMINUS | X11_KEY_PHYSICAL_ONLY_BIT},
609 {XK_period, SDLK_PERIOD | X11_KEY_PHYSICAL_ONLY_BIT},
610 {XK_slash, SDLK_SLASH | X11_KEY_PHYSICAL_ONLY_BIT},
611 {XK_0, SDLK_0 | X11_KEY_PHYSICAL_ONLY_BIT},
612 {XK_1, SDLK_1 | X11_KEY_PHYSICAL_ONLY_BIT},
613 {XK_2, SDLK_2 | X11_KEY_PHYSICAL_ONLY_BIT},
614 {XK_3, SDLK_3 | X11_KEY_PHYSICAL_ONLY_BIT},
615 {XK_4, SDLK_4 | X11_KEY_PHYSICAL_ONLY_BIT},
616 {XK_5, SDLK_5 | X11_KEY_PHYSICAL_ONLY_BIT},
617 {XK_6, SDLK_6 | X11_KEY_PHYSICAL_ONLY_BIT},
618 {XK_7, SDLK_7 | X11_KEY_PHYSICAL_ONLY_BIT},
619 {XK_8, SDLK_8 | X11_KEY_PHYSICAL_ONLY_BIT},
620 {XK_9, SDLK_9 | X11_KEY_PHYSICAL_ONLY_BIT},
621 {XK_semicolon, SDLK_SEMICOLON | X11_KEY_PHYSICAL_ONLY_BIT},
622 {XK_less, SDLK_NONUSBACKSLASH | X11_KEY_PHYSICAL_ONLY_BIT},
623 {XK_equal, SDLK_EQUALS | X11_KEY_PHYSICAL_ONLY_BIT},
624 {XK_bracketleft, SDLK_LEFTBRACKET | X11_KEY_PHYSICAL_ONLY_BIT},
625 {XK_backslash, SDLK_BACKSLASH | X11_KEY_PHYSICAL_ONLY_BIT},
626 {XK_bracketright, SDLK_RIGHTBRACKET | X11_KEY_PHYSICAL_ONLY_BIT},
627 {XK_grave, SDLK_GRAVE | X11_KEY_PHYSICAL_ONLY_BIT},
628 {XK_a, SDLK_A | X11_KEY_PHYSICAL_ONLY_BIT},
629 {XK_b, SDLK_B | X11_KEY_PHYSICAL_ONLY_BIT},
630 {XK_c, SDLK_C | X11_KEY_PHYSICAL_ONLY_BIT},
631 {XK_d, SDLK_D | X11_KEY_PHYSICAL_ONLY_BIT},
632 {XK_e, SDLK_E | X11_KEY_PHYSICAL_ONLY_BIT},
633 {XK_f, SDLK_F | X11_KEY_PHYSICAL_ONLY_BIT},
634 {XK_g, SDLK_G | X11_KEY_PHYSICAL_ONLY_BIT},
635 {XK_h, SDLK_H | X11_KEY_PHYSICAL_ONLY_BIT},
636 {XK_i, SDLK_I | X11_KEY_PHYSICAL_ONLY_BIT},
637 {XK_j, SDLK_J | X11_KEY_PHYSICAL_ONLY_BIT},
638 {XK_k, SDLK_K | X11_KEY_PHYSICAL_ONLY_BIT},
639 {XK_l, SDLK_L | X11_KEY_PHYSICAL_ONLY_BIT},
640 {XK_m, SDLK_M | X11_KEY_PHYSICAL_ONLY_BIT},
641 {XK_n, SDLK_N | X11_KEY_PHYSICAL_ONLY_BIT},
642 {XK_o, SDLK_O | X11_KEY_PHYSICAL_ONLY_BIT},
643 {XK_p, SDLK_P | X11_KEY_PHYSICAL_ONLY_BIT},
644 {XK_q, SDLK_Q | X11_KEY_PHYSICAL_ONLY_BIT},
645 {XK_r, SDLK_R | X11_KEY_PHYSICAL_ONLY_BIT},
646 {XK_s, SDLK_S | X11_KEY_PHYSICAL_ONLY_BIT},
647 {XK_t, SDLK_T | X11_KEY_PHYSICAL_ONLY_BIT},
648 {XK_u, SDLK_U | X11_KEY_PHYSICAL_ONLY_BIT},
649 {XK_v, SDLK_V | X11_KEY_PHYSICAL_ONLY_BIT},
650 {XK_w, SDLK_W | X11_KEY_PHYSICAL_ONLY_BIT},
651 {XK_x, SDLK_X | X11_KEY_PHYSICAL_ONLY_BIT},
652 {XK_y, SDLK_Y | X11_KEY_PHYSICAL_ONLY_BIT},
653 {XK_z, SDLK_Z | X11_KEY_PHYSICAL_ONLY_BIT},
654 {XK_section, SDLK_NONUSBACKSLASH | X11_KEY_PHYSICAL_ONLY_BIT},
655 /* 0xFExx */
656 {XK_ISO_Level3_Shift, SDLK_RALT},
657 {XK_dead_grave, '`'},
658 {XK_dead_acute, 0xB4},
659 {XK_dead_circumflex, '^'},
660 {XK_dead_tilde, '~'},
661 {XK_dead_macron, 0xAF},
662 {XK_dead_breve, 0x2D8},
663 {XK_dead_abovedot, 0x2D9},
664 {XK_dead_diaeresis, 0xA8},
665 {XK_dead_abovering, 0x2DA},
666 {XK_dead_doubleacute, 0x2DD},
667 {XK_dead_caron, 0x2C7},
668 {XK_dead_cedilla, 0xB8},
669 {XK_dead_ogonek, 0x2DB},
670 {XK_dead_iota, 0x3B9},
671 {XK_dead_voiced_sound, 0x309B},
672 {XK_dead_semivoiced_sound, 0x309C},
673 {XK_dead_belowdot, 0xB7}, /* that's actually MIDDLE DOT,
674 but I haven't found a
675 non-combining DOT BELOW
676 XK_dead_hook, XK_dead_horn: I
677 haven't found non-combining
678 HOOK and HORN characters */
679 /* 0xFFxx */
680 {XK_BackSpace, SDLK_BACKSPACE},
681 {XK_Tab, SDLK_TAB},
682 {XK_Return, SDLK_RETURN},
683 {XK_Pause, SDLK_PAUSE},
684 {XK_Scroll_Lock, SDLK_SCROLLLOCK},
685 {XK_Escape, SDLK_ESCAPE},
686 {XK_Home, SDLK_HOME},
687 {XK_Left, SDLK_LEFT},
688 {XK_Up, SDLK_UP},
689 {XK_Right, SDLK_RIGHT},
690 {XK_Down, SDLK_DOWN},
691 {XK_Page_Up, SDLK_PAGEUP},
692 {XK_Page_Down, SDLK_PAGEDOWN},
693 {XK_End, SDLK_END},
694 {XK_Print, SDLK_PRINTSCREEN},
695 {XK_Insert, SDLK_INSERT},
696 {XK_Menu, SDLK_APPLICATION},
697 {XK_Break, SDLK_PAUSE},
698 {XK_Mode_switch, SDLK_MODE},
699 {XK_Num_Lock, SDLK_KP_NUMLOCKCLEAR},
700 {XK_KP_Enter, SDLK_KP_ENTER},
701 {XK_KP_Home, SDLK_KP_7 | X11_KEY_PHYSICAL_ONLY_BIT},
702 {XK_KP_Left, SDLK_KP_4 | X11_KEY_PHYSICAL_ONLY_BIT},
703 {XK_KP_Up, SDLK_KP_8 | X11_KEY_PHYSICAL_ONLY_BIT},
704 {XK_KP_Right, SDLK_KP_6 | X11_KEY_PHYSICAL_ONLY_BIT},
705 {XK_KP_Down, SDLK_KP_2 | X11_KEY_PHYSICAL_ONLY_BIT},
706 {XK_KP_Page_Up, SDLK_KP_9 | X11_KEY_PHYSICAL_ONLY_BIT},
707 {XK_KP_Page_Down, SDLK_KP_3 | X11_KEY_PHYSICAL_ONLY_BIT},
708 {XK_KP_End, SDLK_KP_1 | X11_KEY_PHYSICAL_ONLY_BIT},
709 {XK_KP_Begin, SDLK_KP_5 | X11_KEY_PHYSICAL_ONLY_BIT},
710 {XK_KP_Insert, SDLK_KP_0 | X11_KEY_PHYSICAL_ONLY_BIT},
711 {XK_KP_Delete, SDLK_KP_PERIOD | X11_KEY_PHYSICAL_ONLY_BIT},
712 {XK_KP_Multiply, '*'},
713 {XK_KP_Multiply, SDLK_KP_MULTIPLY},
714 {XK_KP_Add, '+'},
715 {XK_KP_Add, SDLK_KP_PLUS},
716 {XK_KP_Separator, '.'},
717 {XK_KP_Separator, SDLK_KP_PERIOD},
718 {XK_KP_Subtract, '-'},
719 {XK_KP_Subtract, SDLK_KP_MINUS},
720 {XK_KP_Decimal, '.'},
721 {XK_KP_Decimal, SDLK_KP_PERIOD},
722 {XK_KP_Divide, '/'},
723 {XK_KP_Divide, SDLK_KP_DIVIDE},
724 {XK_KP_0, '0'},
725 {XK_KP_0, SDLK_KP_0},
726 {XK_KP_1, '1'},
727 {XK_KP_1, SDLK_KP_1},
728 {XK_KP_2, '2'},
729 {XK_KP_2, SDLK_KP_2},
730 {XK_KP_3, '3'},
731 {XK_KP_3, SDLK_KP_3},
732 {XK_KP_4, '4'},
733 {XK_KP_4, SDLK_KP_4},
734 {XK_KP_5, '5'},
735 {XK_KP_5, SDLK_KP_5},
736 {XK_KP_6, '6'},
737 {XK_KP_6, SDLK_KP_6},
738 {XK_KP_7, '7'},
739 {XK_KP_7, SDLK_KP_7},
740 {XK_KP_8, '8'},
741 {XK_KP_8, SDLK_KP_8},
742 {XK_KP_9, '9'},
743 {XK_KP_9, SDLK_KP_9},
744 {XK_KP_Equal, '='},
745 {XK_KP_Equal, SDLK_KP_EQUALS},
746 {XK_F1, SDLK_F1},
747 {XK_F2, SDLK_F2},
748 {XK_F3, SDLK_F3},
749 {XK_F4, SDLK_F4},
750 {XK_F5, SDLK_F5},
751 {XK_F6, SDLK_F6},
752 {XK_F7, SDLK_F7},
753 {XK_F8, SDLK_F8},
754 {XK_F9, SDLK_F9},
755 {XK_F10, SDLK_F10},
756 {XK_F11, SDLK_F11},
757 {XK_F12, SDLK_F12},
758 {XK_F13, SDLK_F13},
759 {XK_F14, SDLK_F14},
760 {XK_F15, SDLK_F15},
761 {XK_F16, SDLK_F16},
762 {XK_F17, SDLK_F17},
763 {XK_F18, SDLK_F18},
764 {XK_F19, SDLK_F19},
765 {XK_F20, SDLK_F20},
766 {XK_F21, SDLK_F21},
767 {XK_F22, SDLK_F22},
768 {XK_F23, SDLK_F23},
769 {XK_F24, SDLK_F24},
770 {XK_Shift_L, SDLK_LSHIFT},
771 {XK_Shift_R, SDLK_RSHIFT},
772 {XK_Control_L, SDLK_LCTRL},
773 {XK_Control_R, SDLK_RCTRL},
774 {XK_Caps_Lock, SDLK_CAPSLOCK},
775 {XK_Shift_Lock, SDLK_CAPSLOCK},
776 {XK_Meta_L, SDLK_LMETA},
777 {XK_Meta_R, SDLK_RMETA},
778 {XK_Alt_L, SDLK_LALT},
779 {XK_Alt_R, SDLK_RALT},
780 {XK_Super_L, SDLK_LMETA},
781 {XK_Super_R, SDLK_RMETA},
782 {XK_Hyper_L, SDLK_LMETA},
783 {XK_Hyper_R, SDLK_RMETA},
784 {XK_Delete, SDLK_DELETE},
785 {0x1000003, SDLK_KP_ENTER} /* keyboard enter on Mac OS X */
786 };
787
788 /* *INDENT-ON* */
789
790 /*
791 Used for two purposes: - by X11_GetLayoutKey(), with physical =
792 false, to convert a KeySym to the corresponding layout key code
793 (SDLK_ ones and some character ones - most character KeySyms are
794 handled by X11_KeySymToUcs4() after this function returns
795 SDLK_UNKNOWN for them). - by X11_InitKeyboard(), with physical =
796 true, to build a makeshift translation table based on the KeySyms
797 when none of the predefined KeyCode- to-SDLKey tables fits. This
798 is *not* correct anywhere but on a US layout, since the
799 translation table deals with physical key codes, while the X11
800 KeySym corresponds to our concept of a layout key code, but it's
801 better than nothing.
802 */
803
804 static SDLKey
805 X11_KeySymToSDLKey(KeySym sym, SDL_bool physical)
806 {
807 /* Do a binary search for sym in the keySymToSDLKey table */
808 SDLKey key = SDLK_UNKNOWN;
809 int start = -1;
810 int end = SDL_arraysize(keySymToSDLKey);
811 int i;
812 /* Invariant: keySymToSDLKey[start].sym < sym <
813 keySymToSDLKey[end].sym (imagine ...[-1] = -inf and
814 ...[arraysize] = inf, these entries needn't be there in reality
815 because they're never accessed) */
816 while (end > start + 1) {
817 i = (start + end) / 2;
818 if (keySymToSDLKey[i].sym == sym) {
819 /* found an entry, if it's the second of two back up to the first */
820 if (keySymToSDLKey[i - 1].sym == sym)
821 i--;
822 /* if there are two, the physical one is the second */
823 if (physical && keySymToSDLKey[i + 1].sym == sym)
824 i++;
825 key = keySymToSDLKey[i].key;
826 break;
827 } else if (keySymToSDLKey[i].sym < sym)
828 start = i;
829 else
830 end = i;
831 }
832
833 /* if we're being asked for a layout key code, but the table only
834 has a physical one, or vice versa, return SDLK_UNKNOWN) */
835
836 if (!physical && ((key & X11_KEY_PHYSICAL_ONLY_BIT) != 0)
837 || physical && ((key & SDL_KEY_CAN_BE_PHYSICAL_BIT) == 0))
838 key = SDLK_UNKNOWN;
839 key &= ~X11_KEY_PHYSICAL_ONLY_BIT;
840 return key;
841 }
842 288
843 int 289 int
844 X11_InitKeyboard(_THIS) 290 X11_InitKeyboard(_THIS)
845 { 291 {
846 SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; 292 SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
847 SDL_Keyboard keyboard; 293 SDL_Keyboard keyboard;
848 SDLKey **table; 294 int i, j;
849 SDLKey *foundTable; 295 int min_keycode, max_keycode;
850 int i; 296 SDL_scancode fingerprint_scancodes[] = {
851 int code; 297 SDL_SCANCODE_HOME,
852 SDLKey sdlkey; 298 SDL_SCANCODE_PAGEUP,
299 SDL_SCANCODE_PAGEDOWN
300 };
301 int fingerprint[3];
302 SDL_bool fingerprint_detected;
853 303
854 XAutoRepeatOn(data->display); 304 XAutoRepeatOn(data->display);
855 305
856 /* A random collection of KeySym/SDLKey pairs that should be valid 306 /* Try to determine which scancodes are being used based on fingerprint */
857 in any keyboard layout (if this isn't the case on yours, 307 fingerprint_detected = SDL_FALSE;
858 please adjust). Using XKeysymToKeycode on these KeySyms 308 XDisplayKeycodes(data->display, &min_keycode, &max_keycode);
859 creates a "fingerprint" of the X server's key-to-KeyCode 309 for (i = 0; i < SDL_arraysize(fingerprint_scancodes); ++i) {
860 mapping which is then matched against all our predefined 310 fingerprint[i] =
861 KeyCodeToSDLK tables to find the right one (if any). 311 XKeysymToKeycode(data->display,
862 */ 312 XKeySymTable[fingerprint_scancodes[i]]) -
863 313 min_keycode;
864 /* *INDENT-OFF* */ 314 }
865 struct 315 for (i = 0; i < SDL_arraysize(scancode_set); ++i) {
866 { 316 /* Make sure the scancode set isn't too big */
867 KeySym sym; 317 if ((max_keycode - min_keycode + 1) <= scancode_set[i].table_size) {
868 SDLKey key; 318 continue;
869 } fingerprint[] = 319 }
870 { 320 for (j = 0; j < SDL_arraysize(fingerprint); ++j) {
871 {XK_Tab, SDLK_TAB}, 321 if (fingerprint[j] < 0
872 {XK_Return, SDLK_RETURN}, 322 || fingerprint[j] >= scancode_set[i].table_size) {
873 {XK_Escape, SDLK_ESCAPE}, 323 break;
874 {XK_space, SDLK_SPACE} 324 }
875 }; 325 if (scancode_set[i].table[fingerprint[j]] !=
876 /* *INDENT-ON* */ 326 fingerprint_scancodes[j]) {
877
878 SDL_zero(keyboard);
879 data->keyboard = SDL_AddKeyboard(&keyboard, -1);
880
881 /* Determine which X11 KeyCode to SDL physical key code table to use */
882
883 foundTable = NULL;
884 table = keyCodeToSDLKeyTables;
885 while ((NULL == foundTable) && (NULL != (*table))) {
886 foundTable = *table;
887 for (i = 0; i < SDL_arraysize(fingerprint); i++) {
888 code = XKeysymToKeycode(data->display, fingerprint[i].sym);
889 if ((code != 0) && ((*table)[code] != fingerprint[i].key)) {
890 foundTable = NULL;
891 break; 327 break;
892 } 328 }
893 } 329 }
894 table++; 330 if (j == SDL_arraysize(fingerprint)) {
895 } 331 printf("Using scancode set %d\n", i);
896 332 SDL_memcpy(&data->key_layout[min_keycode], scancode_set[i].table,
897 if (NULL != foundTable) { 333 sizeof(SDL_scancode) * scancode_set[i].table_size);
898 /* Found a suitable one among the predefined tables */ 334 fingerprint_detected = SDL_TRUE;
899 data->keyCodeToSDLKTable = foundTable;
900 } else {
901 /* No suitable table found - build a makeshift table based on
902 the KeySyms, assuming a US keyboard layout */
903
904 #if 1
905 fprintf(stderr,
906 "The key codes of your X server are unknown to SDL. Keys may not be recognized properly. To help get this fixed, report this to the SDL mailing list <sdl@libsdl.org> or to Christian Walther <cwalther@gmx.ch>.\n");
907 #endif
908 data->keyCodeToSDLKTable =
909 SDL_malloc(KeyCodeTableSize * sizeof(SDLKey));
910 if (data->keyCodeToSDLKTable == NULL) {
911 SDL_OutOfMemory();
912 return -1;
913 }
914 for (code = KeyCodeTableSize; code >= 0; code--) {
915 data->keyCodeToSDLKTable[code] =
916 X11_KeySymToSDLKey(XKeycodeToKeysym(data->display, code, 0),
917 SDL_TRUE);
918 }
919 }
920
921 /* Set some non-default key names */
922
923 for (code = 0; code < KeyCodeTableSize; code++) {
924 sdlkey = data->keyCodeToSDLKTable[code];
925 switch (sdlkey) {
926 /* The SDLK_*META keys are used as XK_Meta_* by some X
927 servers, as XK_Super_* by others */
928 case SDLK_LMETA:
929 case SDLK_RMETA:
930 switch (XKeycodeToKeysym(data->display, code, 0)) {
931 /* nothing to do for XK_Meta_* because that's already the default name */
932 case XK_Super_L:
933 SDL_SetKeyName(sdlkey, "left super");
934 break;
935 case XK_Super_R:
936 SDL_SetKeyName(sdlkey, "right super");
937 break;
938 }
939 break; 335 break;
940 } 336 }
941 } 337 }
942 SDL_SetKeyName(SDLK_APPLICATION, "menu"); 338
339 if (!fingerprint_detected) {
340 printf
341 ("Keyboard layout unknown, please send the following to the SDL mailing list (sdl@libsdl.org):\n");
342
343 /* Determine key_layout - only works on US QWERTY layout */
344 for (i = min_keycode; i <= max_keycode; ++i) {
345 KeySym sym;
346 sym = XKeycodeToKeysym(data->display, i, 0);
347 if (sym) {
348 printf("code = %d, sym = 0x%X (%s) ", i - min_keycode, sym,
349 XKeysymToString(sym));
350 for (j = 0; j < SDL_arraysize(XKeySymTable); ++j) {
351 if (XKeySymTable[j] == sym) {
352 data->key_layout[i] = (SDL_scancode) j;
353 break;
354 }
355 }
356 if (j == SDL_arraysize(XKeySymTable)) {
357 printf("scancode not found\n");
358 } else {
359 printf("scancode = %d (%s)\n", j, SDL_GetScancodeName(j));
360 }
361 }
362 }
363 }
364
365 SDL_zero(keyboard);
366 data->keyboard = SDL_AddKeyboard(&keyboard, -1);
367 X11_UpdateKeymap(this);
368
369 SDL_SetScancodeName(SDL_SCANCODE_APPLICATION, "Menu");
943 370
944 return 0; 371 return 0;
945 } 372 }
946 373
947 SDLKey 374 void
948 X11_GetLayoutKey(_THIS, SDLKey physicalKey) 375 X11_UpdateKeymap(_THIS)
949 { 376 {
950 SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; 377 SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
951 int code = 0; 378 int i;
952 KeySym sym; 379 SDL_scancode scancode;
953 SDLKey layoutKey; 380 SDLKey keymap[SDL_NUM_SCANCODES];
954 381
955 switch (physicalKey) { 382 SDL_GetDefaultKeymap(keymap);
956 case SDLK_UNKNOWN: 383
957 return physicalKey; 384 for (i = 0; i < SDL_arraysize(data->key_layout); i++) {
958 385
959 /* Shortcut handling of keypad numbers because on my PC their 386 /* Make sure this scancode is a valid character scancode */
960 primary KeySyms are not the numbers that I want but 387 scancode = data->key_layout[i];
961 XK_KP_Home, XK_KP_Up etc. The downside is that this gets us 388 if (scancode == SDL_SCANCODE_UNKNOWN ||
962 latin numerals even on e.g. an Arabic layout. */ 389 (keymap[scancode] & SDLK_SCANCODE_MASK)) {
963 case SDLK_KP_1: 390 continue;
964 return '1'; 391 }
965 case SDLK_KP_2: 392
966 return '2'; 393 keymap[scancode] =
967 case SDLK_KP_3: 394 (SDLKey) X11_KeySymToUcs4(XKeycodeToKeysym(data->display, i, 0));
968 return '3';
969 case SDLK_KP_4:
970 return '4';
971 case SDLK_KP_5:
972 return '5';
973 case SDLK_KP_6:
974 return '6';
975 case SDLK_KP_7:
976 return '7';
977 case SDLK_KP_8:
978 return '8';
979 case SDLK_KP_9:
980 return '9';
981 case SDLK_KP_0:
982 return '0';
983 case SDLK_KP_PERIOD:
984 return '.';
985 default:
986 break; /* just to avoid a compiler warning */
987 } 395 }
988 396 SDL_SetKeymap(data->keyboard, 0, keymap, SDL_NUM_SCANCODES);
989 /* Look up physicalKey to get an X11 KeyCode - linear search isn't
990 terribly efficient, this might have to be optimized. */
991 while ((code < KeyCodeTableSize) &&
992 (physicalKey != data->keyCodeToSDLKTable[code])) {
993 code++;
994 }
995
996 if (code == KeyCodeTableSize) {
997 return physicalKey;
998 }
999 /* Get the corresponding KeySym - this is where the keyboard
1000 layout comes into play */
1001 sym = XKeycodeToKeysym(data->display, code, 0);
1002
1003 /* Try our own KeySym-to-layout-key-code table: it handles all
1004 keys whose layout code is an SDLK_ one, including a few where
1005 X11_KeySymToUcs4() would yield a character, but not a suitable
1006 one as a key name (e.g. space), and some that are character
1007 keys for our purposes, but aren't handled by X11_KeySymToUcs4()
1008 (dead keys, keypad operations). */
1009
1010 layoutKey = X11_KeySymToSDLKey(sym, SDL_FALSE);
1011
1012 /* If it wasn't handled by X11_KeySymToSDLKey(), it's most
1013 probably a plain character KeySym that X11_KeySymToUcs4()
1014 (ripped from X.org) knows. */
1015
1016 if (layoutKey == SDLK_UNKNOWN) {
1017 unsigned int ucs = X11_KeySymToUcs4(sym);
1018 if (ucs != 0)
1019 layoutKey = (SDLKey) ucs;
1020 }
1021
1022 /* Still no success? Give up. */
1023 if (layoutKey == SDLK_UNKNOWN) {
1024 return physicalKey;
1025 }
1026
1027 return layoutKey;
1028 } 397 }
1029 398
1030 void 399 void
1031 X11_QuitKeyboard(_THIS) 400 X11_QuitKeyboard(_THIS)
1032 { 401 {
1033 SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; 402 SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
1034 403
1035 if (data->keyCodeToSDLKTable != NULL) {
1036 /* If it's not one of the predefined tables, it was malloced
1037 and must be freed */
1038 SDLKey **table = keyCodeToSDLKeyTables;
1039 while (*table != NULL && *table != data->keyCodeToSDLKTable) {
1040 table++;
1041 }
1042 if (*table == NULL)
1043 SDL_free(data->keyCodeToSDLKTable);
1044 data->keyCodeToSDLKTable = NULL;
1045 }
1046
1047 SDL_DelKeyboard(data->keyboard); 404 SDL_DelKeyboard(data->keyboard);
1048 } 405 }
1049 406
1050 /* vi: set ts=4 sw=4 expandtab: */ 407 /* vi: set ts=4 sw=4 expandtab: */