SDL_DirectFB_events.c (28797B)
1/* 2 Simple DirectMedia Layer 3 Copyright (C) 1997-2014 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 54typedef struct _cb_data cb_data; 55struct _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 */ 63static SDL_Scancode oskeymap[256]; 64 65 66static SDL_Keysym *DirectFB_TranslateKey(_THIS, DFBWindowEvent * evt, 67 SDL_Keysym * keysym, Uint32 *unicode); 68static SDL_Keysym *DirectFB_TranslateKeyInputEvent(_THIS, DFBInputEvent * evt, 69 SDL_Keysym * keysym, Uint32 *unicode); 70 71static void DirectFB_InitOSKeymap(_THIS, SDL_Scancode * keypmap, int numkeys); 72static int DirectFB_TranslateButton(DFBInputDeviceButtonIdentifier button); 73 74static 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 95static void 96FocusAllMice(_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 110static void 111FocusAllKeyboards(_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 124static void 125MotionAllMice(_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 140static int 141KbdIndex(_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 153static int 154ClientXY(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 173static void 174ProcessWindowEvent(_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 307static void 308ProcessInputEvent(_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 409void 410DirectFB_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 451void 452DirectFB_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 579static SDL_Keysym * 580DirectFB_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 609static SDL_Keysym * 610DirectFB_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 639static int 640DirectFB_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 654static DFBEnumerationResult 655EnumKeyboards(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 712void 713DirectFB_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 742void 743DirectFB_QuitKeyboard(_THIS) 744{ 745 /* SDL_DFB_DEVICEDATA(_this); */ 746 747 SDL_KeyboardQuit(); 748 749} 750 751#endif /* SDL_VIDEO_DRIVER_DIRECTFB */