1 /*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20 */
21 #include "../../SDL_internal.h"
22
23 #if SDL_VIDEO_DRIVER_DIRECTFB
24
25 /* Handle the event stream, converting DirectFB input events into SDL events */
26
27 #include "SDL_DirectFB_video.h"
28 #include "SDL_DirectFB_window.h"
29 #include "SDL_DirectFB_modes.h"
30
31 #include "SDL_syswm.h"
32
33 #include "../../events/SDL_mouse_c.h"
34 #include "../../events/SDL_keyboard_c.h"
35 #include "../../events/SDL_windowevents_c.h"
36 #include "../../events/SDL_events_c.h"
37 #include "../../events/scancodes_linux.h"
38 #include "../../events/scancodes_xfree86.h"
39
40 #include "SDL_DirectFB_events.h"
41
42 #if USE_MULTI_API
43 #define SDL_SendMouseMotion_ex(w, id, relative, x, y, p) SDL_SendMouseMotion(w, id, relative, x, y, p)
44 #define SDL_SendMouseButton_ex(w, id, state, button) SDL_SendMouseButton(w, id, state, button)
45 #define SDL_SendKeyboardKey_ex(id, state, scancode) SDL_SendKeyboardKey(id, state, scancode)
46 #define SDL_SendKeyboardText_ex(id, text) SDL_SendKeyboardText(id, text)
47 #else
48 #define SDL_SendMouseMotion_ex(w, id, relative, x, y, p) SDL_SendMouseMotion(w, id, relative, x, y)
49 #define SDL_SendMouseButton_ex(w, id, state, button) SDL_SendMouseButton(w, id, state, button)
50 #define SDL_SendKeyboardKey_ex(id, state, scancode) SDL_SendKeyboardKey(state, scancode)
51 #define SDL_SendKeyboardText_ex(id, text) SDL_SendKeyboardText(text)
52 #endif
53
54 typedef struct _cb_data cb_data;
55 struct _cb_data
56 {
57 DFB_DeviceData *devdata;
58 int sys_ids;
59 int sys_kbd;
60 };
61
62 /* The translation tables from a DirectFB keycode to a SDL keysym */
63 static SDL_Scancode oskeymap[256];
64
65
66 static SDL_Keysym *DirectFB_TranslateKey(_THIS, DFBWindowEvent * evt,
67 SDL_Keysym * keysym, Uint32 *unicode);
68 static SDL_Keysym *DirectFB_TranslateKeyInputEvent(_THIS, DFBInputEvent * evt,
69 SDL_Keysym * keysym, Uint32 *unicode);
70
71 static void DirectFB_InitOSKeymap(_THIS, SDL_Scancode * keypmap, int numkeys);
72 static int DirectFB_TranslateButton(DFBInputDeviceButtonIdentifier button);
73
UnicodeToUtf8(Uint16 w,char * utf8buf)74 static void UnicodeToUtf8( Uint16 w , char *utf8buf)
75 {
76 unsigned char *utf8s = (unsigned char *) utf8buf;
77
78 if ( w < 0x0080 ) {
79 utf8s[0] = ( unsigned char ) w;
80 utf8s[1] = 0;
81 }
82 else if ( w < 0x0800 ) {
83 utf8s[0] = 0xc0 | (( w ) >> 6 );
84 utf8s[1] = 0x80 | (( w ) & 0x3f );
85 utf8s[2] = 0;
86 }
87 else {
88 utf8s[0] = 0xe0 | (( w ) >> 12 );
89 utf8s[1] = 0x80 | (( ( w ) >> 6 ) & 0x3f );
90 utf8s[2] = 0x80 | (( w ) & 0x3f );
91 utf8s[3] = 0;
92 }
93 }
94
95 static void
FocusAllMice(_THIS,SDL_Window * window)96 FocusAllMice(_THIS, SDL_Window *window)
97 {
98 #if USE_MULTI_API
99 SDL_DFB_DEVICEDATA(_this);
100 int index;
101
102 for (index = 0; index < devdata->num_mice; index++)
103 SDL_SetMouseFocus(devdata->mouse_id[index], id);
104 #else
105 SDL_SetMouseFocus(window);
106 #endif
107 }
108
109
110 static void
FocusAllKeyboards(_THIS,SDL_Window * window)111 FocusAllKeyboards(_THIS, SDL_Window *window)
112 {
113 #if USE_MULTI_API
114 SDL_DFB_DEVICEDATA(_this);
115 int index;
116
117 for (index = 0; index < devdata->num_keyboard; index++)
118 SDL_SetKeyboardFocus(index, id);
119 #else
120 SDL_SetKeyboardFocus(window);
121 #endif
122 }
123
124 static void
MotionAllMice(_THIS,int x,int y)125 MotionAllMice(_THIS, int x, int y)
126 {
127 #if USE_MULTI_API
128 SDL_DFB_DEVICEDATA(_this);
129 int index;
130
131 for (index = 0; index < devdata->num_mice; index++) {
132 SDL_Mouse *mouse = SDL_GetMouse(index);
133 mouse->x = mouse->last_x = x;
134 mouse->y = mouse->last_y = y;
135 /* SDL_SendMouseMotion(devdata->mouse_id[index], 0, x, y, 0); */
136 }
137 #endif
138 }
139
140 static int
KbdIndex(_THIS,int id)141 KbdIndex(_THIS, int id)
142 {
143 SDL_DFB_DEVICEDATA(_this);
144 int index;
145
146 for (index = 0; index < devdata->num_keyboard; index++) {
147 if (devdata->keyboard[index].id == id)
148 return index;
149 }
150 return -1;
151 }
152
153 static int
ClientXY(DFB_WindowData * p,int * x,int * y)154 ClientXY(DFB_WindowData * p, int *x, int *y)
155 {
156 int cx, cy;
157
158 cx = *x;
159 cy = *y;
160
161 cx -= p->client.x;
162 cy -= p->client.y;
163
164 if (cx < 0 || cy < 0)
165 return 0;
166 if (cx >= p->client.w || cy >= p->client.h)
167 return 0;
168 *x = cx;
169 *y = cy;
170 return 1;
171 }
172
173 static void
ProcessWindowEvent(_THIS,SDL_Window * sdlwin,DFBWindowEvent * evt)174 ProcessWindowEvent(_THIS, SDL_Window *sdlwin, DFBWindowEvent * evt)
175 {
176 SDL_DFB_DEVICEDATA(_this);
177 SDL_DFB_WINDOWDATA(sdlwin);
178 SDL_Keysym keysym;
179 Uint32 unicode;
180 char text[SDL_TEXTINPUTEVENT_TEXT_SIZE];
181
182 if (evt->clazz == DFEC_WINDOW) {
183 switch (evt->type) {
184 case DWET_BUTTONDOWN:
185 if (ClientXY(windata, &evt->x, &evt->y)) {
186 if (!devdata->use_linux_input) {
187 SDL_SendMouseMotion_ex(sdlwin, devdata->mouse_id[0], 0, evt->x,
188 evt->y, 0);
189 SDL_SendMouseButton_ex(sdlwin, devdata->mouse_id[0],
190 SDL_PRESSED,
191 DirectFB_TranslateButton
192 (evt->button));
193 } else {
194 MotionAllMice(_this, evt->x, evt->y);
195 }
196 }
197 break;
198 case DWET_BUTTONUP:
199 if (ClientXY(windata, &evt->x, &evt->y)) {
200 if (!devdata->use_linux_input) {
201 SDL_SendMouseMotion_ex(sdlwin, devdata->mouse_id[0], 0, evt->x,
202 evt->y, 0);
203 SDL_SendMouseButton_ex(sdlwin, devdata->mouse_id[0],
204 SDL_RELEASED,
205 DirectFB_TranslateButton
206 (evt->button));
207 } else {
208 MotionAllMice(_this, evt->x, evt->y);
209 }
210 }
211 break;
212 case DWET_MOTION:
213 if (ClientXY(windata, &evt->x, &evt->y)) {
214 if (!devdata->use_linux_input) {
215 if (!(sdlwin->flags & SDL_WINDOW_INPUT_GRABBED))
216 SDL_SendMouseMotion_ex(sdlwin, devdata->mouse_id[0], 0,
217 evt->x, evt->y, 0);
218 } else {
219 /* relative movements are not exact!
220 * This code should limit the number of events sent.
221 * However it kills MAME axis recognition ... */
222 static int cnt = 0;
223 if (1 && ++cnt > 20) {
224 MotionAllMice(_this, evt->x, evt->y);
225 cnt = 0;
226 }
227 }
228 if (!(sdlwin->flags & SDL_WINDOW_MOUSE_FOCUS))
229 SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_ENTER, 0,
230 0);
231 }
232 break;
233 case DWET_KEYDOWN:
234 if (!devdata->use_linux_input) {
235 DirectFB_TranslateKey(_this, evt, &keysym, &unicode);
236 /* printf("Scancode %d %d %d\n", keysym.scancode, evt->key_code, evt->key_id); */
237 SDL_SendKeyboardKey_ex(0, SDL_PRESSED, keysym.scancode);
238 if (SDL_EventState(SDL_TEXTINPUT, SDL_QUERY)) {
239 SDL_zero(text);
240 UnicodeToUtf8(unicode, text);
241 if (*text) {
242 SDL_SendKeyboardText_ex(0, text);
243 }
244 }
245 }
246 break;
247 case DWET_KEYUP:
248 if (!devdata->use_linux_input) {
249 DirectFB_TranslateKey(_this, evt, &keysym, &unicode);
250 SDL_SendKeyboardKey_ex(0, SDL_RELEASED, keysym.scancode);
251 }
252 break;
253 case DWET_POSITION:
254 if (ClientXY(windata, &evt->x, &evt->y)) {
255 SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_MOVED,
256 evt->x, evt->y);
257 }
258 break;
259 case DWET_POSITION_SIZE:
260 if (ClientXY(windata, &evt->x, &evt->y)) {
261 SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_MOVED,
262 evt->x, evt->y);
263 }
264 /* fall throught */
265 case DWET_SIZE:
266 /* FIXME: what about < 0 */
267 evt->w -= (windata->theme.right_size + windata->theme.left_size);
268 evt->h -=
269 (windata->theme.top_size + windata->theme.bottom_size +
270 windata->theme.caption_size);
271 SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_RESIZED,
272 evt->w, evt->h);
273 break;
274 case DWET_CLOSE:
275 SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_CLOSE, 0, 0);
276 break;
277 case DWET_GOTFOCUS:
278 DirectFB_SetContext(_this, sdlwin);
279 FocusAllKeyboards(_this, sdlwin);
280 SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_FOCUS_GAINED,
281 0, 0);
282 break;
283 case DWET_LOSTFOCUS:
284 SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_FOCUS_LOST, 0, 0);
285 FocusAllKeyboards(_this, 0);
286 break;
287 case DWET_ENTER:
288 /* SDL_DirectFB_ReshowCursor(_this, 0); */
289 FocusAllMice(_this, sdlwin);
290 /* FIXME: when do we really enter ? */
291 if (ClientXY(windata, &evt->x, &evt->y))
292 MotionAllMice(_this, evt->x, evt->y);
293 SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_ENTER, 0, 0);
294 break;
295 case DWET_LEAVE:
296 SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_LEAVE, 0, 0);
297 FocusAllMice(_this, 0);
298 /* SDL_DirectFB_ReshowCursor(_this, 1); */
299 break;
300 default:
301 ;
302 }
303 } else
304 printf("Event Clazz %d\n", evt->clazz);
305 }
306
307 static void
ProcessInputEvent(_THIS,DFBInputEvent * ievt)308 ProcessInputEvent(_THIS, DFBInputEvent * ievt)
309 {
310 SDL_DFB_DEVICEDATA(_this);
311 SDL_Keysym keysym;
312 int kbd_idx;
313 Uint32 unicode;
314 char text[SDL_TEXTINPUTEVENT_TEXT_SIZE];
315
316 if (!devdata->use_linux_input) {
317 if (ievt->type == DIET_AXISMOTION) {
318 if ((devdata->grabbed_window != NULL) && (ievt->flags & DIEF_AXISREL)) {
319 if (ievt->axis == DIAI_X)
320 SDL_SendMouseMotion_ex(devdata->grabbed_window, ievt->device_id, 1,
321 ievt->axisrel, 0, 0);
322 else if (ievt->axis == DIAI_Y)
323 SDL_SendMouseMotion_ex(devdata->grabbed_window, ievt->device_id, 1, 0,
324 ievt->axisrel, 0);
325 }
326 }
327 } else {
328 static int last_x, last_y;
329
330 switch (ievt->type) {
331 case DIET_AXISMOTION:
332 if (ievt->flags & DIEF_AXISABS) {
333 if (ievt->axis == DIAI_X)
334 last_x = ievt->axisabs;
335 else if (ievt->axis == DIAI_Y)
336 last_y = ievt->axisabs;
337 if (!(ievt->flags & DIEF_FOLLOW)) {
338 #if USE_MULTI_API
339 SDL_Mouse *mouse = SDL_GetMouse(ievt->device_id);
340 SDL_Window *window = SDL_GetWindowFromID(mouse->focus);
341 #else
342 SDL_Window *window = devdata->grabbed_window;
343 #endif
344 if (window) {
345 DFB_WindowData *windata =
346 (DFB_WindowData *) window->driverdata;
347 int x, y;
348
349 windata->dfbwin->GetPosition(windata->dfbwin, &x, &y);
350 SDL_SendMouseMotion_ex(window, ievt->device_id, 0,
351 last_x - (x +
352 windata->client.x),
353 last_y - (y +
354 windata->client.y), 0);
355 } else {
356 SDL_SendMouseMotion_ex(window, ievt->device_id, 0, last_x,
357 last_y, 0);
358 }
359 }
360 } else if (ievt->flags & DIEF_AXISREL) {
361 if (ievt->axis == DIAI_X)
362 SDL_SendMouseMotion_ex(devdata->grabbed_window, ievt->device_id, 1,
363 ievt->axisrel, 0, 0);
364 else if (ievt->axis == DIAI_Y)
365 SDL_SendMouseMotion_ex(devdata->grabbed_window, ievt->device_id, 1, 0,
366 ievt->axisrel, 0);
367 }
368 break;
369 case DIET_KEYPRESS:
370 kbd_idx = KbdIndex(_this, ievt->device_id);
371 DirectFB_TranslateKeyInputEvent(_this, ievt, &keysym, &unicode);
372 /* printf("Scancode %d %d %d\n", keysym.scancode, evt->key_code, evt->key_id); */
373 SDL_SendKeyboardKey_ex(kbd_idx, SDL_PRESSED, keysym.scancode);
374 if (SDL_EventState(SDL_TEXTINPUT, SDL_QUERY)) {
375 SDL_zero(text);
376 UnicodeToUtf8(unicode, text);
377 if (*text) {
378 SDL_SendKeyboardText_ex(kbd_idx, text);
379 }
380 }
381 break;
382 case DIET_KEYRELEASE:
383 kbd_idx = KbdIndex(_this, ievt->device_id);
384 DirectFB_TranslateKeyInputEvent(_this, ievt, &keysym, &unicode);
385 SDL_SendKeyboardKey_ex(kbd_idx, SDL_RELEASED, keysym.scancode);
386 break;
387 case DIET_BUTTONPRESS:
388 if (ievt->buttons & DIBM_LEFT)
389 SDL_SendMouseButton_ex(devdata->grabbed_window, ievt->device_id, SDL_PRESSED, 1);
390 if (ievt->buttons & DIBM_MIDDLE)
391 SDL_SendMouseButton_ex(devdata->grabbed_window, ievt->device_id, SDL_PRESSED, 2);
392 if (ievt->buttons & DIBM_RIGHT)
393 SDL_SendMouseButton_ex(devdata->grabbed_window, ievt->device_id, SDL_PRESSED, 3);
394 break;
395 case DIET_BUTTONRELEASE:
396 if (!(ievt->buttons & DIBM_LEFT))
397 SDL_SendMouseButton_ex(devdata->grabbed_window, ievt->device_id, SDL_RELEASED, 1);
398 if (!(ievt->buttons & DIBM_MIDDLE))
399 SDL_SendMouseButton_ex(devdata->grabbed_window, ievt->device_id, SDL_RELEASED, 2);
400 if (!(ievt->buttons & DIBM_RIGHT))
401 SDL_SendMouseButton_ex(devdata->grabbed_window, ievt->device_id, SDL_RELEASED, 3);
402 break;
403 default:
404 break; /* please gcc */
405 }
406 }
407 }
408
409 void
DirectFB_PumpEventsWindow(_THIS)410 DirectFB_PumpEventsWindow(_THIS)
411 {
412 SDL_DFB_DEVICEDATA(_this);
413 DFBInputEvent ievt;
414 SDL_Window *w;
415
416 for (w = devdata->firstwin; w != NULL; w = w->next) {
417 SDL_DFB_WINDOWDATA(w);
418 DFBWindowEvent evt;
419
420 while (windata->eventbuffer->GetEvent(windata->eventbuffer,
421 DFB_EVENT(&evt)) == DFB_OK) {
422 if (!DirectFB_WM_ProcessEvent(_this, w, &evt)) {
423 /* Send a SDL_SYSWMEVENT if the application wants them */
424 if (SDL_GetEventState(SDL_SYSWMEVENT) == SDL_ENABLE) {
425 SDL_SysWMmsg wmmsg;
426 SDL_VERSION(&wmmsg.version);
427 wmmsg.subsystem = SDL_SYSWM_DIRECTFB;
428 wmmsg.msg.dfb.event.window = evt;
429 SDL_SendSysWMEvent(&wmmsg);
430 }
431 ProcessWindowEvent(_this, w, &evt);
432 }
433 }
434 }
435
436 /* Now get relative events in case we need them */
437 while (devdata->events->GetEvent(devdata->events,
438 DFB_EVENT(&ievt)) == DFB_OK) {
439
440 if (SDL_GetEventState(SDL_SYSWMEVENT) == SDL_ENABLE) {
441 SDL_SysWMmsg wmmsg;
442 SDL_VERSION(&wmmsg.version);
443 wmmsg.subsystem = SDL_SYSWM_DIRECTFB;
444 wmmsg.msg.dfb.event.input = ievt;
445 SDL_SendSysWMEvent(&wmmsg);
446 }
447 ProcessInputEvent(_this, &ievt);
448 }
449 }
450
451 void
DirectFB_InitOSKeymap(_THIS,SDL_Scancode * keymap,int numkeys)452 DirectFB_InitOSKeymap(_THIS, SDL_Scancode * keymap, int numkeys)
453 {
454 int i;
455
456 /* Initialize the DirectFB key translation table */
457 for (i = 0; i < numkeys; ++i)
458 keymap[i] = SDL_SCANCODE_UNKNOWN;
459
460 keymap[DIKI_A - DIKI_UNKNOWN] = SDL_SCANCODE_A;
461 keymap[DIKI_B - DIKI_UNKNOWN] = SDL_SCANCODE_B;
462 keymap[DIKI_C - DIKI_UNKNOWN] = SDL_SCANCODE_C;
463 keymap[DIKI_D - DIKI_UNKNOWN] = SDL_SCANCODE_D;
464 keymap[DIKI_E - DIKI_UNKNOWN] = SDL_SCANCODE_E;
465 keymap[DIKI_F - DIKI_UNKNOWN] = SDL_SCANCODE_F;
466 keymap[DIKI_G - DIKI_UNKNOWN] = SDL_SCANCODE_G;
467 keymap[DIKI_H - DIKI_UNKNOWN] = SDL_SCANCODE_H;
468 keymap[DIKI_I - DIKI_UNKNOWN] = SDL_SCANCODE_I;
469 keymap[DIKI_J - DIKI_UNKNOWN] = SDL_SCANCODE_J;
470 keymap[DIKI_K - DIKI_UNKNOWN] = SDL_SCANCODE_K;
471 keymap[DIKI_L - DIKI_UNKNOWN] = SDL_SCANCODE_L;
472 keymap[DIKI_M - DIKI_UNKNOWN] = SDL_SCANCODE_M;
473 keymap[DIKI_N - DIKI_UNKNOWN] = SDL_SCANCODE_N;
474 keymap[DIKI_O - DIKI_UNKNOWN] = SDL_SCANCODE_O;
475 keymap[DIKI_P - DIKI_UNKNOWN] = SDL_SCANCODE_P;
476 keymap[DIKI_Q - DIKI_UNKNOWN] = SDL_SCANCODE_Q;
477 keymap[DIKI_R - DIKI_UNKNOWN] = SDL_SCANCODE_R;
478 keymap[DIKI_S - DIKI_UNKNOWN] = SDL_SCANCODE_S;
479 keymap[DIKI_T - DIKI_UNKNOWN] = SDL_SCANCODE_T;
480 keymap[DIKI_U - DIKI_UNKNOWN] = SDL_SCANCODE_U;
481 keymap[DIKI_V - DIKI_UNKNOWN] = SDL_SCANCODE_V;
482 keymap[DIKI_W - DIKI_UNKNOWN] = SDL_SCANCODE_W;
483 keymap[DIKI_X - DIKI_UNKNOWN] = SDL_SCANCODE_X;
484 keymap[DIKI_Y - DIKI_UNKNOWN] = SDL_SCANCODE_Y;
485 keymap[DIKI_Z - DIKI_UNKNOWN] = SDL_SCANCODE_Z;
486
487 keymap[DIKI_0 - DIKI_UNKNOWN] = SDL_SCANCODE_0;
488 keymap[DIKI_1 - DIKI_UNKNOWN] = SDL_SCANCODE_1;
489 keymap[DIKI_2 - DIKI_UNKNOWN] = SDL_SCANCODE_2;
490 keymap[DIKI_3 - DIKI_UNKNOWN] = SDL_SCANCODE_3;
491 keymap[DIKI_4 - DIKI_UNKNOWN] = SDL_SCANCODE_4;
492 keymap[DIKI_5 - DIKI_UNKNOWN] = SDL_SCANCODE_5;
493 keymap[DIKI_6 - DIKI_UNKNOWN] = SDL_SCANCODE_6;
494 keymap[DIKI_7 - DIKI_UNKNOWN] = SDL_SCANCODE_7;
495 keymap[DIKI_8 - DIKI_UNKNOWN] = SDL_SCANCODE_8;
496 keymap[DIKI_9 - DIKI_UNKNOWN] = SDL_SCANCODE_9;
497
498 keymap[DIKI_F1 - DIKI_UNKNOWN] = SDL_SCANCODE_F1;
499 keymap[DIKI_F2 - DIKI_UNKNOWN] = SDL_SCANCODE_F2;
500 keymap[DIKI_F3 - DIKI_UNKNOWN] = SDL_SCANCODE_F3;
501 keymap[DIKI_F4 - DIKI_UNKNOWN] = SDL_SCANCODE_F4;
502 keymap[DIKI_F5 - DIKI_UNKNOWN] = SDL_SCANCODE_F5;
503 keymap[DIKI_F6 - DIKI_UNKNOWN] = SDL_SCANCODE_F6;
504 keymap[DIKI_F7 - DIKI_UNKNOWN] = SDL_SCANCODE_F7;
505 keymap[DIKI_F8 - DIKI_UNKNOWN] = SDL_SCANCODE_F8;
506 keymap[DIKI_F9 - DIKI_UNKNOWN] = SDL_SCANCODE_F9;
507 keymap[DIKI_F10 - DIKI_UNKNOWN] = SDL_SCANCODE_F10;
508 keymap[DIKI_F11 - DIKI_UNKNOWN] = SDL_SCANCODE_F11;
509 keymap[DIKI_F12 - DIKI_UNKNOWN] = SDL_SCANCODE_F12;
510
511 keymap[DIKI_ESCAPE - DIKI_UNKNOWN] = SDL_SCANCODE_ESCAPE;
512 keymap[DIKI_LEFT - DIKI_UNKNOWN] = SDL_SCANCODE_LEFT;
513 keymap[DIKI_RIGHT - DIKI_UNKNOWN] = SDL_SCANCODE_RIGHT;
514 keymap[DIKI_UP - DIKI_UNKNOWN] = SDL_SCANCODE_UP;
515 keymap[DIKI_DOWN - DIKI_UNKNOWN] = SDL_SCANCODE_DOWN;
516 keymap[DIKI_CONTROL_L - DIKI_UNKNOWN] = SDL_SCANCODE_LCTRL;
517 keymap[DIKI_CONTROL_R - DIKI_UNKNOWN] = SDL_SCANCODE_RCTRL;
518 keymap[DIKI_SHIFT_L - DIKI_UNKNOWN] = SDL_SCANCODE_LSHIFT;
519 keymap[DIKI_SHIFT_R - DIKI_UNKNOWN] = SDL_SCANCODE_RSHIFT;
520 keymap[DIKI_ALT_L - DIKI_UNKNOWN] = SDL_SCANCODE_LALT;
521 keymap[DIKI_ALT_R - DIKI_UNKNOWN] = SDL_SCANCODE_RALT;
522 keymap[DIKI_META_L - DIKI_UNKNOWN] = SDL_SCANCODE_LGUI;
523 keymap[DIKI_META_R - DIKI_UNKNOWN] = SDL_SCANCODE_RGUI;
524 keymap[DIKI_SUPER_L - DIKI_UNKNOWN] = SDL_SCANCODE_APPLICATION;
525 keymap[DIKI_SUPER_R - DIKI_UNKNOWN] = SDL_SCANCODE_APPLICATION;
526 /* FIXME:Do we read hyper keys ?
527 * keymap[DIKI_HYPER_L - DIKI_UNKNOWN] = SDL_SCANCODE_APPLICATION;
528 * keymap[DIKI_HYPER_R - DIKI_UNKNOWN] = SDL_SCANCODE_APPLICATION;
529 */
530 keymap[DIKI_TAB - DIKI_UNKNOWN] = SDL_SCANCODE_TAB;
531 keymap[DIKI_ENTER - DIKI_UNKNOWN] = SDL_SCANCODE_RETURN;
532 keymap[DIKI_SPACE - DIKI_UNKNOWN] = SDL_SCANCODE_SPACE;
533 keymap[DIKI_BACKSPACE - DIKI_UNKNOWN] = SDL_SCANCODE_BACKSPACE;
534 keymap[DIKI_INSERT - DIKI_UNKNOWN] = SDL_SCANCODE_INSERT;
535 keymap[DIKI_DELETE - DIKI_UNKNOWN] = SDL_SCANCODE_DELETE;
536 keymap[DIKI_HOME - DIKI_UNKNOWN] = SDL_SCANCODE_HOME;
537 keymap[DIKI_END - DIKI_UNKNOWN] = SDL_SCANCODE_END;
538 keymap[DIKI_PAGE_UP - DIKI_UNKNOWN] = SDL_SCANCODE_PAGEUP;
539 keymap[DIKI_PAGE_DOWN - DIKI_UNKNOWN] = SDL_SCANCODE_PAGEDOWN;
540 keymap[DIKI_CAPS_LOCK - DIKI_UNKNOWN] = SDL_SCANCODE_CAPSLOCK;
541 keymap[DIKI_NUM_LOCK - DIKI_UNKNOWN] = SDL_SCANCODE_NUMLOCKCLEAR;
542 keymap[DIKI_SCROLL_LOCK - DIKI_UNKNOWN] = SDL_SCANCODE_SCROLLLOCK;
543 keymap[DIKI_PRINT - DIKI_UNKNOWN] = SDL_SCANCODE_PRINTSCREEN;
544 keymap[DIKI_PAUSE - DIKI_UNKNOWN] = SDL_SCANCODE_PAUSE;
545
546 keymap[DIKI_KP_EQUAL - DIKI_UNKNOWN] = SDL_SCANCODE_KP_EQUALS;
547 keymap[DIKI_KP_DECIMAL - DIKI_UNKNOWN] = SDL_SCANCODE_KP_PERIOD;
548 keymap[DIKI_KP_0 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_0;
549 keymap[DIKI_KP_1 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_1;
550 keymap[DIKI_KP_2 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_2;
551 keymap[DIKI_KP_3 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_3;
552 keymap[DIKI_KP_4 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_4;
553 keymap[DIKI_KP_5 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_5;
554 keymap[DIKI_KP_6 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_6;
555 keymap[DIKI_KP_7 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_7;
556 keymap[DIKI_KP_8 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_8;
557 keymap[DIKI_KP_9 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_9;
558 keymap[DIKI_KP_DIV - DIKI_UNKNOWN] = SDL_SCANCODE_KP_DIVIDE;
559 keymap[DIKI_KP_MULT - DIKI_UNKNOWN] = SDL_SCANCODE_KP_MULTIPLY;
560 keymap[DIKI_KP_MINUS - DIKI_UNKNOWN] = SDL_SCANCODE_KP_MINUS;
561 keymap[DIKI_KP_PLUS - DIKI_UNKNOWN] = SDL_SCANCODE_KP_PLUS;
562 keymap[DIKI_KP_ENTER - DIKI_UNKNOWN] = SDL_SCANCODE_KP_ENTER;
563
564 keymap[DIKI_QUOTE_LEFT - DIKI_UNKNOWN] = SDL_SCANCODE_GRAVE; /* TLDE */
565 keymap[DIKI_MINUS_SIGN - DIKI_UNKNOWN] = SDL_SCANCODE_MINUS; /* AE11 */
566 keymap[DIKI_EQUALS_SIGN - DIKI_UNKNOWN] = SDL_SCANCODE_EQUALS; /* AE12 */
567 keymap[DIKI_BRACKET_LEFT - DIKI_UNKNOWN] = SDL_SCANCODE_RIGHTBRACKET; /* AD11 */
568 keymap[DIKI_BRACKET_RIGHT - DIKI_UNKNOWN] = SDL_SCANCODE_LEFTBRACKET; /* AD12 */
569 keymap[DIKI_BACKSLASH - DIKI_UNKNOWN] = SDL_SCANCODE_BACKSLASH; /* BKSL */
570 keymap[DIKI_SEMICOLON - DIKI_UNKNOWN] = SDL_SCANCODE_SEMICOLON; /* AC10 */
571 keymap[DIKI_QUOTE_RIGHT - DIKI_UNKNOWN] = SDL_SCANCODE_APOSTROPHE; /* AC11 */
572 keymap[DIKI_COMMA - DIKI_UNKNOWN] = SDL_SCANCODE_COMMA; /* AB08 */
573 keymap[DIKI_PERIOD - DIKI_UNKNOWN] = SDL_SCANCODE_PERIOD; /* AB09 */
574 keymap[DIKI_SLASH - DIKI_UNKNOWN] = SDL_SCANCODE_SLASH; /* AB10 */
575 keymap[DIKI_LESS_SIGN - DIKI_UNKNOWN] = SDL_SCANCODE_NONUSBACKSLASH; /* 103rd */
576
577 }
578
579 static SDL_Keysym *
DirectFB_TranslateKey(_THIS,DFBWindowEvent * evt,SDL_Keysym * keysym,Uint32 * unicode)580 DirectFB_TranslateKey(_THIS, DFBWindowEvent * evt, SDL_Keysym * keysym, Uint32 *unicode)
581 {
582 SDL_DFB_DEVICEDATA(_this);
583 int kbd_idx = 0; /* Window events lag the device source KbdIndex(_this, evt->device_id); */
584 DFB_KeyboardData *kbd = &devdata->keyboard[kbd_idx];
585
586 keysym->scancode = SDL_SCANCODE_UNKNOWN;
587
588 if (kbd->map && evt->key_code >= kbd->map_adjust &&
589 evt->key_code < kbd->map_size + kbd->map_adjust)
590 keysym->scancode = kbd->map[evt->key_code - kbd->map_adjust];
591
592 if (keysym->scancode == SDL_SCANCODE_UNKNOWN ||
593 devdata->keyboard[kbd_idx].is_generic) {
594 if (evt->key_id - DIKI_UNKNOWN < SDL_arraysize(oskeymap))
595 keysym->scancode = oskeymap[evt->key_id - DIKI_UNKNOWN];
596 else
597 keysym->scancode = SDL_SCANCODE_UNKNOWN;
598 }
599
600 *unicode =
601 (DFB_KEY_TYPE(evt->key_symbol) == DIKT_UNICODE) ? evt->key_symbol : 0;
602 if (*unicode == 0 &&
603 (evt->key_symbol > 0 && evt->key_symbol < 255))
604 *unicode = evt->key_symbol;
605
606 return keysym;
607 }
608
609 static SDL_Keysym *
DirectFB_TranslateKeyInputEvent(_THIS,DFBInputEvent * evt,SDL_Keysym * keysym,Uint32 * unicode)610 DirectFB_TranslateKeyInputEvent(_THIS, DFBInputEvent * evt,
611 SDL_Keysym * keysym, Uint32 *unicode)
612 {
613 SDL_DFB_DEVICEDATA(_this);
614 int kbd_idx = KbdIndex(_this, evt->device_id);
615 DFB_KeyboardData *kbd = &devdata->keyboard[kbd_idx];
616
617 keysym->scancode = SDL_SCANCODE_UNKNOWN;
618
619 if (kbd->map && evt->key_code >= kbd->map_adjust &&
620 evt->key_code < kbd->map_size + kbd->map_adjust)
621 keysym->scancode = kbd->map[evt->key_code - kbd->map_adjust];
622
623 if (keysym->scancode == SDL_SCANCODE_UNKNOWN || devdata->keyboard[kbd_idx].is_generic) {
624 if (evt->key_id - DIKI_UNKNOWN < SDL_arraysize(oskeymap))
625 keysym->scancode = oskeymap[evt->key_id - DIKI_UNKNOWN];
626 else
627 keysym->scancode = SDL_SCANCODE_UNKNOWN;
628 }
629
630 *unicode =
631 (DFB_KEY_TYPE(evt->key_symbol) == DIKT_UNICODE) ? evt->key_symbol : 0;
632 if (*unicode == 0 &&
633 (evt->key_symbol > 0 && evt->key_symbol < 255))
634 *unicode = evt->key_symbol;
635
636 return keysym;
637 }
638
639 static int
DirectFB_TranslateButton(DFBInputDeviceButtonIdentifier button)640 DirectFB_TranslateButton(DFBInputDeviceButtonIdentifier button)
641 {
642 switch (button) {
643 case DIBI_LEFT:
644 return 1;
645 case DIBI_MIDDLE:
646 return 2;
647 case DIBI_RIGHT:
648 return 3;
649 default:
650 return 0;
651 }
652 }
653
654 static DFBEnumerationResult
EnumKeyboards(DFBInputDeviceID device_id,DFBInputDeviceDescription desc,void * callbackdata)655 EnumKeyboards(DFBInputDeviceID device_id,
656 DFBInputDeviceDescription desc, void *callbackdata)
657 {
658 cb_data *cb = callbackdata;
659 DFB_DeviceData *devdata = cb->devdata;
660 #if USE_MULTI_API
661 SDL_Keyboard keyboard;
662 #endif
663 SDL_Keycode keymap[SDL_NUM_SCANCODES];
664
665 if (!cb->sys_kbd) {
666 if (cb->sys_ids) {
667 if (device_id >= 0x10)
668 return DFENUM_OK;
669 } else {
670 if (device_id < 0x10)
671 return DFENUM_OK;
672 }
673 } else {
674 if (device_id != DIDID_KEYBOARD)
675 return DFENUM_OK;
676 }
677
678 if ((desc.caps & DIDTF_KEYBOARD)) {
679 #if USE_MULTI_API
680 SDL_zero(keyboard);
681 SDL_AddKeyboard(&keyboard, devdata->num_keyboard);
682 #endif
683 devdata->keyboard[devdata->num_keyboard].id = device_id;
684 devdata->keyboard[devdata->num_keyboard].is_generic = 0;
685 if (!strncmp("X11", desc.name, 3))
686 {
687 devdata->keyboard[devdata->num_keyboard].map = xfree86_scancode_table2;
688 devdata->keyboard[devdata->num_keyboard].map_size = SDL_arraysize(xfree86_scancode_table2);
689 devdata->keyboard[devdata->num_keyboard].map_adjust = 8;
690 } else {
691 devdata->keyboard[devdata->num_keyboard].map = linux_scancode_table;
692 devdata->keyboard[devdata->num_keyboard].map_size = SDL_arraysize(linux_scancode_table);
693 devdata->keyboard[devdata->num_keyboard].map_adjust = 0;
694 }
695
696 SDL_DFB_LOG("Keyboard %d - %s\n", device_id, desc.name);
697
698 SDL_GetDefaultKeymap(keymap);
699 #if USE_MULTI_API
700 SDL_SetKeymap(devdata->num_keyboard, 0, keymap, SDL_NUM_SCANCODES);
701 #else
702 SDL_SetKeymap(0, keymap, SDL_NUM_SCANCODES);
703 #endif
704 devdata->num_keyboard++;
705
706 if (cb->sys_kbd)
707 return DFENUM_CANCEL;
708 }
709 return DFENUM_OK;
710 }
711
712 void
DirectFB_InitKeyboard(_THIS)713 DirectFB_InitKeyboard(_THIS)
714 {
715 SDL_DFB_DEVICEDATA(_this);
716 cb_data cb;
717
718 DirectFB_InitOSKeymap(_this, &oskeymap[0], SDL_arraysize(oskeymap));
719
720 devdata->num_keyboard = 0;
721 cb.devdata = devdata;
722
723 if (devdata->use_linux_input) {
724 cb.sys_kbd = 0;
725 cb.sys_ids = 0;
726 SDL_DFB_CHECK(devdata->dfb->
727 EnumInputDevices(devdata->dfb, EnumKeyboards, &cb));
728 if (devdata->num_keyboard == 0) {
729 cb.sys_ids = 1;
730 SDL_DFB_CHECK(devdata->dfb->EnumInputDevices(devdata->dfb,
731 EnumKeyboards,
732 &cb));
733 }
734 } else {
735 cb.sys_kbd = 1;
736 SDL_DFB_CHECK(devdata->dfb->EnumInputDevices(devdata->dfb,
737 EnumKeyboards,
738 &cb));
739 }
740 }
741
742 void
DirectFB_QuitKeyboard(_THIS)743 DirectFB_QuitKeyboard(_THIS)
744 {
745 /* SDL_DFB_DEVICEDATA(_this); */
746
747 SDL_KeyboardQuit();
748
749 }
750
751 #endif /* SDL_VIDEO_DRIVER_DIRECTFB */
752