| /* |
| Simple DirectMedia Layer |
| Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org> |
| |
| This software is provided 'as-is', without any express or implied |
| warranty. In no event will the authors be held liable for any damages |
| arising from the use of this software. |
| |
| Permission is granted to anyone to use this software for any purpose, |
| including commercial applications, and to alter it and redistribute it |
| freely, subject to the following restrictions: |
| |
| 1. The origin of this software must not be misrepresented; you must not |
| claim that you wrote the original software. If you use this software |
| in a product, an acknowledgment in the product documentation would be |
| appreciated but is not required. |
| 2. Altered source versions must be plainly marked as such, and must not be |
| misrepresented as being the original software. |
| 3. This notice may not be removed or altered from any source distribution. |
| */ |
| #include "../../SDL_internal.h" |
| |
| #if SDL_VIDEO_DRIVER_DIRECTFB |
| |
| /* Handle the event stream, converting DirectFB input events into SDL events */ |
| |
| #include "SDL_DirectFB_video.h" |
| #include "SDL_DirectFB_window.h" |
| #include "SDL_DirectFB_modes.h" |
| |
| #include "SDL_syswm.h" |
| |
| #include "../../events/SDL_mouse_c.h" |
| #include "../../events/SDL_keyboard_c.h" |
| #include "../../events/SDL_windowevents_c.h" |
| #include "../../events/SDL_events_c.h" |
| #include "../../events/scancodes_linux.h" |
| #include "../../events/scancodes_xfree86.h" |
| |
| #include "SDL_DirectFB_events.h" |
| |
| #if USE_MULTI_API |
| #define SDL_SendMouseMotion_ex(w, id, relative, x, y, p) SDL_SendMouseMotion(w, id, relative, x, y, p) |
| #define SDL_SendMouseButton_ex(w, id, state, button) SDL_SendMouseButton(w, id, state, button) |
| #define SDL_SendKeyboardKey_ex(id, state, scancode) SDL_SendKeyboardKey(id, state, scancode) |
| #define SDL_SendKeyboardText_ex(id, text) SDL_SendKeyboardText(id, text) |
| #else |
| #define SDL_SendMouseMotion_ex(w, id, relative, x, y, p) SDL_SendMouseMotion(w, id, relative, x, y) |
| #define SDL_SendMouseButton_ex(w, id, state, button) SDL_SendMouseButton(w, id, state, button) |
| #define SDL_SendKeyboardKey_ex(id, state, scancode) SDL_SendKeyboardKey(state, scancode) |
| #define SDL_SendKeyboardText_ex(id, text) SDL_SendKeyboardText(text) |
| #endif |
| |
| typedef struct _cb_data cb_data; |
| struct _cb_data |
| { |
| DFB_DeviceData *devdata; |
| int sys_ids; |
| int sys_kbd; |
| }; |
| |
| /* The translation tables from a DirectFB keycode to a SDL keysym */ |
| static SDL_Scancode oskeymap[256]; |
| |
| |
| static SDL_Keysym *DirectFB_TranslateKey(_THIS, DFBWindowEvent * evt, |
| SDL_Keysym * keysym, Uint32 *unicode); |
| static SDL_Keysym *DirectFB_TranslateKeyInputEvent(_THIS, DFBInputEvent * evt, |
| SDL_Keysym * keysym, Uint32 *unicode); |
| |
| static void DirectFB_InitOSKeymap(_THIS, SDL_Scancode * keypmap, int numkeys); |
| static int DirectFB_TranslateButton(DFBInputDeviceButtonIdentifier button); |
| |
| static void UnicodeToUtf8( Uint16 w , char *utf8buf) |
| { |
| unsigned char *utf8s = (unsigned char *) utf8buf; |
| |
| if ( w < 0x0080 ) { |
| utf8s[0] = ( unsigned char ) w; |
| utf8s[1] = 0; |
| } |
| else if ( w < 0x0800 ) { |
| utf8s[0] = 0xc0 | (( w ) >> 6 ); |
| utf8s[1] = 0x80 | (( w ) & 0x3f ); |
| utf8s[2] = 0; |
| } |
| else { |
| utf8s[0] = 0xe0 | (( w ) >> 12 ); |
| utf8s[1] = 0x80 | (( ( w ) >> 6 ) & 0x3f ); |
| utf8s[2] = 0x80 | (( w ) & 0x3f ); |
| utf8s[3] = 0; |
| } |
| } |
| |
| static void |
| FocusAllMice(_THIS, SDL_Window *window) |
| { |
| #if USE_MULTI_API |
| SDL_DFB_DEVICEDATA(_this); |
| int index; |
| |
| for (index = 0; index < devdata->num_mice; index++) |
| SDL_SetMouseFocus(devdata->mouse_id[index], id); |
| #else |
| SDL_SetMouseFocus(window); |
| #endif |
| } |
| |
| |
| static void |
| FocusAllKeyboards(_THIS, SDL_Window *window) |
| { |
| #if USE_MULTI_API |
| SDL_DFB_DEVICEDATA(_this); |
| int index; |
| |
| for (index = 0; index < devdata->num_keyboard; index++) |
| SDL_SetKeyboardFocus(index, id); |
| #else |
| SDL_SetKeyboardFocus(window); |
| #endif |
| } |
| |
| static void |
| MotionAllMice(_THIS, int x, int y) |
| { |
| #if USE_MULTI_API |
| SDL_DFB_DEVICEDATA(_this); |
| int index; |
| |
| for (index = 0; index < devdata->num_mice; index++) { |
| SDL_Mouse *mouse = SDL_GetMouse(index); |
| mouse->x = mouse->last_x = x; |
| mouse->y = mouse->last_y = y; |
| /* SDL_SendMouseMotion(devdata->mouse_id[index], 0, x, y, 0); */ |
| } |
| #endif |
| } |
| |
| static int |
| KbdIndex(_THIS, int id) |
| { |
| SDL_DFB_DEVICEDATA(_this); |
| int index; |
| |
| for (index = 0; index < devdata->num_keyboard; index++) { |
| if (devdata->keyboard[index].id == id) |
| return index; |
| } |
| return -1; |
| } |
| |
| static int |
| ClientXY(DFB_WindowData * p, int *x, int *y) |
| { |
| int cx, cy; |
| |
| cx = *x; |
| cy = *y; |
| |
| cx -= p->client.x; |
| cy -= p->client.y; |
| |
| if (cx < 0 || cy < 0) |
| return 0; |
| if (cx >= p->client.w || cy >= p->client.h) |
| return 0; |
| *x = cx; |
| *y = cy; |
| return 1; |
| } |
| |
| static void |
| ProcessWindowEvent(_THIS, SDL_Window *sdlwin, DFBWindowEvent * evt) |
| { |
| SDL_DFB_DEVICEDATA(_this); |
| SDL_DFB_WINDOWDATA(sdlwin); |
| SDL_Keysym keysym; |
| Uint32 unicode; |
| char text[SDL_TEXTINPUTEVENT_TEXT_SIZE]; |
| |
| if (evt->clazz == DFEC_WINDOW) { |
| switch (evt->type) { |
| case DWET_BUTTONDOWN: |
| if (ClientXY(windata, &evt->x, &evt->y)) { |
| if (!devdata->use_linux_input) { |
| SDL_SendMouseMotion_ex(sdlwin, devdata->mouse_id[0], 0, evt->x, |
| evt->y, 0); |
| SDL_SendMouseButton_ex(sdlwin, devdata->mouse_id[0], |
| SDL_PRESSED, |
| DirectFB_TranslateButton |
| (evt->button)); |
| } else { |
| MotionAllMice(_this, evt->x, evt->y); |
| } |
| } |
| break; |
| case DWET_BUTTONUP: |
| if (ClientXY(windata, &evt->x, &evt->y)) { |
| if (!devdata->use_linux_input) { |
| SDL_SendMouseMotion_ex(sdlwin, devdata->mouse_id[0], 0, evt->x, |
| evt->y, 0); |
| SDL_SendMouseButton_ex(sdlwin, devdata->mouse_id[0], |
| SDL_RELEASED, |
| DirectFB_TranslateButton |
| (evt->button)); |
| } else { |
| MotionAllMice(_this, evt->x, evt->y); |
| } |
| } |
| break; |
| case DWET_MOTION: |
| if (ClientXY(windata, &evt->x, &evt->y)) { |
| if (!devdata->use_linux_input) { |
| if (!(sdlwin->flags & SDL_WINDOW_INPUT_GRABBED)) |
| SDL_SendMouseMotion_ex(sdlwin, devdata->mouse_id[0], 0, |
| evt->x, evt->y, 0); |
| } else { |
| /* relative movements are not exact! |
| * This code should limit the number of events sent. |
| * However it kills MAME axis recognition ... */ |
| static int cnt = 0; |
| if (1 && ++cnt > 20) { |
| MotionAllMice(_this, evt->x, evt->y); |
| cnt = 0; |
| } |
| } |
| if (!(sdlwin->flags & SDL_WINDOW_MOUSE_FOCUS)) |
| SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_ENTER, 0, |
| 0); |
| } |
| break; |
| case DWET_KEYDOWN: |
| if (!devdata->use_linux_input) { |
| DirectFB_TranslateKey(_this, evt, &keysym, &unicode); |
| /* printf("Scancode %d %d %d\n", keysym.scancode, evt->key_code, evt->key_id); */ |
| SDL_SendKeyboardKey_ex(0, SDL_PRESSED, keysym.scancode); |
| if (SDL_EventState(SDL_TEXTINPUT, SDL_QUERY)) { |
| SDL_zero(text); |
| UnicodeToUtf8(unicode, text); |
| if (*text) { |
| SDL_SendKeyboardText_ex(0, text); |
| } |
| } |
| } |
| break; |
| case DWET_KEYUP: |
| if (!devdata->use_linux_input) { |
| DirectFB_TranslateKey(_this, evt, &keysym, &unicode); |
| SDL_SendKeyboardKey_ex(0, SDL_RELEASED, keysym.scancode); |
| } |
| break; |
| case DWET_POSITION: |
| if (ClientXY(windata, &evt->x, &evt->y)) { |
| SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_MOVED, |
| evt->x, evt->y); |
| } |
| break; |
| case DWET_POSITION_SIZE: |
| if (ClientXY(windata, &evt->x, &evt->y)) { |
| SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_MOVED, |
| evt->x, evt->y); |
| } |
| /* fall throught */ |
| case DWET_SIZE: |
| /* FIXME: what about < 0 */ |
| evt->w -= (windata->theme.right_size + windata->theme.left_size); |
| evt->h -= |
| (windata->theme.top_size + windata->theme.bottom_size + |
| windata->theme.caption_size); |
| SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_RESIZED, |
| evt->w, evt->h); |
| break; |
| case DWET_CLOSE: |
| SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_CLOSE, 0, 0); |
| break; |
| case DWET_GOTFOCUS: |
| DirectFB_SetContext(_this, sdlwin); |
| FocusAllKeyboards(_this, sdlwin); |
| SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_FOCUS_GAINED, |
| 0, 0); |
| break; |
| case DWET_LOSTFOCUS: |
| SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_FOCUS_LOST, 0, 0); |
| FocusAllKeyboards(_this, 0); |
| break; |
| case DWET_ENTER: |
| /* SDL_DirectFB_ReshowCursor(_this, 0); */ |
| FocusAllMice(_this, sdlwin); |
| /* FIXME: when do we really enter ? */ |
| if (ClientXY(windata, &evt->x, &evt->y)) |
| MotionAllMice(_this, evt->x, evt->y); |
| SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_ENTER, 0, 0); |
| break; |
| case DWET_LEAVE: |
| SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_LEAVE, 0, 0); |
| FocusAllMice(_this, 0); |
| /* SDL_DirectFB_ReshowCursor(_this, 1); */ |
| break; |
| default: |
| ; |
| } |
| } else |
| printf("Event Clazz %d\n", evt->clazz); |
| } |
| |
| static void |
| ProcessInputEvent(_THIS, DFBInputEvent * ievt) |
| { |
| SDL_DFB_DEVICEDATA(_this); |
| SDL_Keysym keysym; |
| int kbd_idx; |
| Uint32 unicode; |
| char text[SDL_TEXTINPUTEVENT_TEXT_SIZE]; |
| |
| if (!devdata->use_linux_input) { |
| if (ievt->type == DIET_AXISMOTION) { |
| if ((devdata->grabbed_window != NULL) && (ievt->flags & DIEF_AXISREL)) { |
| if (ievt->axis == DIAI_X) |
| SDL_SendMouseMotion_ex(devdata->grabbed_window, ievt->device_id, 1, |
| ievt->axisrel, 0, 0); |
| else if (ievt->axis == DIAI_Y) |
| SDL_SendMouseMotion_ex(devdata->grabbed_window, ievt->device_id, 1, 0, |
| ievt->axisrel, 0); |
| } |
| } |
| } else { |
| static int last_x, last_y; |
| |
| switch (ievt->type) { |
| case DIET_AXISMOTION: |
| if (ievt->flags & DIEF_AXISABS) { |
| if (ievt->axis == DIAI_X) |
| last_x = ievt->axisabs; |
| else if (ievt->axis == DIAI_Y) |
| last_y = ievt->axisabs; |
| if (!(ievt->flags & DIEF_FOLLOW)) { |
| #if USE_MULTI_API |
| SDL_Mouse *mouse = SDL_GetMouse(ievt->device_id); |
| SDL_Window *window = SDL_GetWindowFromID(mouse->focus); |
| #else |
| SDL_Window *window = devdata->grabbed_window; |
| #endif |
| if (window) { |
| DFB_WindowData *windata = |
| (DFB_WindowData *) window->driverdata; |
| int x, y; |
| |
| windata->dfbwin->GetPosition(windata->dfbwin, &x, &y); |
| SDL_SendMouseMotion_ex(window, ievt->device_id, 0, |
| last_x - (x + |
| windata->client.x), |
| last_y - (y + |
| windata->client.y), 0); |
| } else { |
| SDL_SendMouseMotion_ex(window, ievt->device_id, 0, last_x, |
| last_y, 0); |
| } |
| } |
| } else if (ievt->flags & DIEF_AXISREL) { |
| if (ievt->axis == DIAI_X) |
| SDL_SendMouseMotion_ex(devdata->grabbed_window, ievt->device_id, 1, |
| ievt->axisrel, 0, 0); |
| else if (ievt->axis == DIAI_Y) |
| SDL_SendMouseMotion_ex(devdata->grabbed_window, ievt->device_id, 1, 0, |
| ievt->axisrel, 0); |
| } |
| break; |
| case DIET_KEYPRESS: |
| kbd_idx = KbdIndex(_this, ievt->device_id); |
| DirectFB_TranslateKeyInputEvent(_this, ievt, &keysym, &unicode); |
| /* printf("Scancode %d %d %d\n", keysym.scancode, evt->key_code, evt->key_id); */ |
| SDL_SendKeyboardKey_ex(kbd_idx, SDL_PRESSED, keysym.scancode); |
| if (SDL_EventState(SDL_TEXTINPUT, SDL_QUERY)) { |
| SDL_zero(text); |
| UnicodeToUtf8(unicode, text); |
| if (*text) { |
| SDL_SendKeyboardText_ex(kbd_idx, text); |
| } |
| } |
| break; |
| case DIET_KEYRELEASE: |
| kbd_idx = KbdIndex(_this, ievt->device_id); |
| DirectFB_TranslateKeyInputEvent(_this, ievt, &keysym, &unicode); |
| SDL_SendKeyboardKey_ex(kbd_idx, SDL_RELEASED, keysym.scancode); |
| break; |
| case DIET_BUTTONPRESS: |
| if (ievt->buttons & DIBM_LEFT) |
| SDL_SendMouseButton_ex(devdata->grabbed_window, ievt->device_id, SDL_PRESSED, 1); |
| if (ievt->buttons & DIBM_MIDDLE) |
| SDL_SendMouseButton_ex(devdata->grabbed_window, ievt->device_id, SDL_PRESSED, 2); |
| if (ievt->buttons & DIBM_RIGHT) |
| SDL_SendMouseButton_ex(devdata->grabbed_window, ievt->device_id, SDL_PRESSED, 3); |
| break; |
| case DIET_BUTTONRELEASE: |
| if (!(ievt->buttons & DIBM_LEFT)) |
| SDL_SendMouseButton_ex(devdata->grabbed_window, ievt->device_id, SDL_RELEASED, 1); |
| if (!(ievt->buttons & DIBM_MIDDLE)) |
| SDL_SendMouseButton_ex(devdata->grabbed_window, ievt->device_id, SDL_RELEASED, 2); |
| if (!(ievt->buttons & DIBM_RIGHT)) |
| SDL_SendMouseButton_ex(devdata->grabbed_window, ievt->device_id, SDL_RELEASED, 3); |
| break; |
| default: |
| break; /* please gcc */ |
| } |
| } |
| } |
| |
| void |
| DirectFB_PumpEventsWindow(_THIS) |
| { |
| SDL_DFB_DEVICEDATA(_this); |
| DFBInputEvent ievt; |
| SDL_Window *w; |
| |
| for (w = devdata->firstwin; w != NULL; w = w->next) { |
| SDL_DFB_WINDOWDATA(w); |
| DFBWindowEvent evt; |
| |
| while (windata->eventbuffer->GetEvent(windata->eventbuffer, |
| DFB_EVENT(&evt)) == DFB_OK) { |
| if (!DirectFB_WM_ProcessEvent(_this, w, &evt)) { |
| /* Send a SDL_SYSWMEVENT if the application wants them */ |
| if (SDL_GetEventState(SDL_SYSWMEVENT) == SDL_ENABLE) { |
| SDL_SysWMmsg wmmsg; |
| SDL_VERSION(&wmmsg.version); |
| wmmsg.subsystem = SDL_SYSWM_DIRECTFB; |
| wmmsg.msg.dfb.event.window = evt; |
| SDL_SendSysWMEvent(&wmmsg); |
| } |
| ProcessWindowEvent(_this, w, &evt); |
| } |
| } |
| } |
| |
| /* Now get relative events in case we need them */ |
| while (devdata->events->GetEvent(devdata->events, |
| DFB_EVENT(&ievt)) == DFB_OK) { |
| |
| if (SDL_GetEventState(SDL_SYSWMEVENT) == SDL_ENABLE) { |
| SDL_SysWMmsg wmmsg; |
| SDL_VERSION(&wmmsg.version); |
| wmmsg.subsystem = SDL_SYSWM_DIRECTFB; |
| wmmsg.msg.dfb.event.input = ievt; |
| SDL_SendSysWMEvent(&wmmsg); |
| } |
| ProcessInputEvent(_this, &ievt); |
| } |
| } |
| |
| void |
| DirectFB_InitOSKeymap(_THIS, SDL_Scancode * keymap, int numkeys) |
| { |
| int i; |
| |
| /* Initialize the DirectFB key translation table */ |
| for (i = 0; i < numkeys; ++i) |
| keymap[i] = SDL_SCANCODE_UNKNOWN; |
| |
| keymap[DIKI_A - DIKI_UNKNOWN] = SDL_SCANCODE_A; |
| keymap[DIKI_B - DIKI_UNKNOWN] = SDL_SCANCODE_B; |
| keymap[DIKI_C - DIKI_UNKNOWN] = SDL_SCANCODE_C; |
| keymap[DIKI_D - DIKI_UNKNOWN] = SDL_SCANCODE_D; |
| keymap[DIKI_E - DIKI_UNKNOWN] = SDL_SCANCODE_E; |
| keymap[DIKI_F - DIKI_UNKNOWN] = SDL_SCANCODE_F; |
| keymap[DIKI_G - DIKI_UNKNOWN] = SDL_SCANCODE_G; |
| keymap[DIKI_H - DIKI_UNKNOWN] = SDL_SCANCODE_H; |
| keymap[DIKI_I - DIKI_UNKNOWN] = SDL_SCANCODE_I; |
| keymap[DIKI_J - DIKI_UNKNOWN] = SDL_SCANCODE_J; |
| keymap[DIKI_K - DIKI_UNKNOWN] = SDL_SCANCODE_K; |
| keymap[DIKI_L - DIKI_UNKNOWN] = SDL_SCANCODE_L; |
| keymap[DIKI_M - DIKI_UNKNOWN] = SDL_SCANCODE_M; |
| keymap[DIKI_N - DIKI_UNKNOWN] = SDL_SCANCODE_N; |
| keymap[DIKI_O - DIKI_UNKNOWN] = SDL_SCANCODE_O; |
| keymap[DIKI_P - DIKI_UNKNOWN] = SDL_SCANCODE_P; |
| keymap[DIKI_Q - DIKI_UNKNOWN] = SDL_SCANCODE_Q; |
| keymap[DIKI_R - DIKI_UNKNOWN] = SDL_SCANCODE_R; |
| keymap[DIKI_S - DIKI_UNKNOWN] = SDL_SCANCODE_S; |
| keymap[DIKI_T - DIKI_UNKNOWN] = SDL_SCANCODE_T; |
| keymap[DIKI_U - DIKI_UNKNOWN] = SDL_SCANCODE_U; |
| keymap[DIKI_V - DIKI_UNKNOWN] = SDL_SCANCODE_V; |
| keymap[DIKI_W - DIKI_UNKNOWN] = SDL_SCANCODE_W; |
| keymap[DIKI_X - DIKI_UNKNOWN] = SDL_SCANCODE_X; |
| keymap[DIKI_Y - DIKI_UNKNOWN] = SDL_SCANCODE_Y; |
| keymap[DIKI_Z - DIKI_UNKNOWN] = SDL_SCANCODE_Z; |
| |
| keymap[DIKI_0 - DIKI_UNKNOWN] = SDL_SCANCODE_0; |
| keymap[DIKI_1 - DIKI_UNKNOWN] = SDL_SCANCODE_1; |
| keymap[DIKI_2 - DIKI_UNKNOWN] = SDL_SCANCODE_2; |
| keymap[DIKI_3 - DIKI_UNKNOWN] = SDL_SCANCODE_3; |
| keymap[DIKI_4 - DIKI_UNKNOWN] = SDL_SCANCODE_4; |
| keymap[DIKI_5 - DIKI_UNKNOWN] = SDL_SCANCODE_5; |
| keymap[DIKI_6 - DIKI_UNKNOWN] = SDL_SCANCODE_6; |
| keymap[DIKI_7 - DIKI_UNKNOWN] = SDL_SCANCODE_7; |
| keymap[DIKI_8 - DIKI_UNKNOWN] = SDL_SCANCODE_8; |
| keymap[DIKI_9 - DIKI_UNKNOWN] = SDL_SCANCODE_9; |
| |
| keymap[DIKI_F1 - DIKI_UNKNOWN] = SDL_SCANCODE_F1; |
| keymap[DIKI_F2 - DIKI_UNKNOWN] = SDL_SCANCODE_F2; |
| keymap[DIKI_F3 - DIKI_UNKNOWN] = SDL_SCANCODE_F3; |
| keymap[DIKI_F4 - DIKI_UNKNOWN] = SDL_SCANCODE_F4; |
| keymap[DIKI_F5 - DIKI_UNKNOWN] = SDL_SCANCODE_F5; |
| keymap[DIKI_F6 - DIKI_UNKNOWN] = SDL_SCANCODE_F6; |
| keymap[DIKI_F7 - DIKI_UNKNOWN] = SDL_SCANCODE_F7; |
| keymap[DIKI_F8 - DIKI_UNKNOWN] = SDL_SCANCODE_F8; |
| keymap[DIKI_F9 - DIKI_UNKNOWN] = SDL_SCANCODE_F9; |
| keymap[DIKI_F10 - DIKI_UNKNOWN] = SDL_SCANCODE_F10; |
| keymap[DIKI_F11 - DIKI_UNKNOWN] = SDL_SCANCODE_F11; |
| keymap[DIKI_F12 - DIKI_UNKNOWN] = SDL_SCANCODE_F12; |
| |
| keymap[DIKI_ESCAPE - DIKI_UNKNOWN] = SDL_SCANCODE_ESCAPE; |
| keymap[DIKI_LEFT - DIKI_UNKNOWN] = SDL_SCANCODE_LEFT; |
| keymap[DIKI_RIGHT - DIKI_UNKNOWN] = SDL_SCANCODE_RIGHT; |
| keymap[DIKI_UP - DIKI_UNKNOWN] = SDL_SCANCODE_UP; |
| keymap[DIKI_DOWN - DIKI_UNKNOWN] = SDL_SCANCODE_DOWN; |
| keymap[DIKI_CONTROL_L - DIKI_UNKNOWN] = SDL_SCANCODE_LCTRL; |
| keymap[DIKI_CONTROL_R - DIKI_UNKNOWN] = SDL_SCANCODE_RCTRL; |
| keymap[DIKI_SHIFT_L - DIKI_UNKNOWN] = SDL_SCANCODE_LSHIFT; |
| keymap[DIKI_SHIFT_R - DIKI_UNKNOWN] = SDL_SCANCODE_RSHIFT; |
| keymap[DIKI_ALT_L - DIKI_UNKNOWN] = SDL_SCANCODE_LALT; |
| keymap[DIKI_ALT_R - DIKI_UNKNOWN] = SDL_SCANCODE_RALT; |
| keymap[DIKI_META_L - DIKI_UNKNOWN] = SDL_SCANCODE_LGUI; |
| keymap[DIKI_META_R - DIKI_UNKNOWN] = SDL_SCANCODE_RGUI; |
| keymap[DIKI_SUPER_L - DIKI_UNKNOWN] = SDL_SCANCODE_APPLICATION; |
| keymap[DIKI_SUPER_R - DIKI_UNKNOWN] = SDL_SCANCODE_APPLICATION; |
| /* FIXME:Do we read hyper keys ? |
| * keymap[DIKI_HYPER_L - DIKI_UNKNOWN] = SDL_SCANCODE_APPLICATION; |
| * keymap[DIKI_HYPER_R - DIKI_UNKNOWN] = SDL_SCANCODE_APPLICATION; |
| */ |
| keymap[DIKI_TAB - DIKI_UNKNOWN] = SDL_SCANCODE_TAB; |
| keymap[DIKI_ENTER - DIKI_UNKNOWN] = SDL_SCANCODE_RETURN; |
| keymap[DIKI_SPACE - DIKI_UNKNOWN] = SDL_SCANCODE_SPACE; |
| keymap[DIKI_BACKSPACE - DIKI_UNKNOWN] = SDL_SCANCODE_BACKSPACE; |
| keymap[DIKI_INSERT - DIKI_UNKNOWN] = SDL_SCANCODE_INSERT; |
| keymap[DIKI_DELETE - DIKI_UNKNOWN] = SDL_SCANCODE_DELETE; |
| keymap[DIKI_HOME - DIKI_UNKNOWN] = SDL_SCANCODE_HOME; |
| keymap[DIKI_END - DIKI_UNKNOWN] = SDL_SCANCODE_END; |
| keymap[DIKI_PAGE_UP - DIKI_UNKNOWN] = SDL_SCANCODE_PAGEUP; |
| keymap[DIKI_PAGE_DOWN - DIKI_UNKNOWN] = SDL_SCANCODE_PAGEDOWN; |
| keymap[DIKI_CAPS_LOCK - DIKI_UNKNOWN] = SDL_SCANCODE_CAPSLOCK; |
| keymap[DIKI_NUM_LOCK - DIKI_UNKNOWN] = SDL_SCANCODE_NUMLOCKCLEAR; |
| keymap[DIKI_SCROLL_LOCK - DIKI_UNKNOWN] = SDL_SCANCODE_SCROLLLOCK; |
| keymap[DIKI_PRINT - DIKI_UNKNOWN] = SDL_SCANCODE_PRINTSCREEN; |
| keymap[DIKI_PAUSE - DIKI_UNKNOWN] = SDL_SCANCODE_PAUSE; |
| |
| keymap[DIKI_KP_EQUAL - DIKI_UNKNOWN] = SDL_SCANCODE_KP_EQUALS; |
| keymap[DIKI_KP_DECIMAL - DIKI_UNKNOWN] = SDL_SCANCODE_KP_PERIOD; |
| keymap[DIKI_KP_0 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_0; |
| keymap[DIKI_KP_1 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_1; |
| keymap[DIKI_KP_2 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_2; |
| keymap[DIKI_KP_3 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_3; |
| keymap[DIKI_KP_4 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_4; |
| keymap[DIKI_KP_5 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_5; |
| keymap[DIKI_KP_6 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_6; |
| keymap[DIKI_KP_7 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_7; |
| keymap[DIKI_KP_8 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_8; |
| keymap[DIKI_KP_9 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_9; |
| keymap[DIKI_KP_DIV - DIKI_UNKNOWN] = SDL_SCANCODE_KP_DIVIDE; |
| keymap[DIKI_KP_MULT - DIKI_UNKNOWN] = SDL_SCANCODE_KP_MULTIPLY; |
| keymap[DIKI_KP_MINUS - DIKI_UNKNOWN] = SDL_SCANCODE_KP_MINUS; |
| keymap[DIKI_KP_PLUS - DIKI_UNKNOWN] = SDL_SCANCODE_KP_PLUS; |
| keymap[DIKI_KP_ENTER - DIKI_UNKNOWN] = SDL_SCANCODE_KP_ENTER; |
| |
| keymap[DIKI_QUOTE_LEFT - DIKI_UNKNOWN] = SDL_SCANCODE_GRAVE; /* TLDE */ |
| keymap[DIKI_MINUS_SIGN - DIKI_UNKNOWN] = SDL_SCANCODE_MINUS; /* AE11 */ |
| keymap[DIKI_EQUALS_SIGN - DIKI_UNKNOWN] = SDL_SCANCODE_EQUALS; /* AE12 */ |
| keymap[DIKI_BRACKET_LEFT - DIKI_UNKNOWN] = SDL_SCANCODE_RIGHTBRACKET; /* AD11 */ |
| keymap[DIKI_BRACKET_RIGHT - DIKI_UNKNOWN] = SDL_SCANCODE_LEFTBRACKET; /* AD12 */ |
| keymap[DIKI_BACKSLASH - DIKI_UNKNOWN] = SDL_SCANCODE_BACKSLASH; /* BKSL */ |
| keymap[DIKI_SEMICOLON - DIKI_UNKNOWN] = SDL_SCANCODE_SEMICOLON; /* AC10 */ |
| keymap[DIKI_QUOTE_RIGHT - DIKI_UNKNOWN] = SDL_SCANCODE_APOSTROPHE; /* AC11 */ |
| keymap[DIKI_COMMA - DIKI_UNKNOWN] = SDL_SCANCODE_COMMA; /* AB08 */ |
| keymap[DIKI_PERIOD - DIKI_UNKNOWN] = SDL_SCANCODE_PERIOD; /* AB09 */ |
| keymap[DIKI_SLASH - DIKI_UNKNOWN] = SDL_SCANCODE_SLASH; /* AB10 */ |
| keymap[DIKI_LESS_SIGN - DIKI_UNKNOWN] = SDL_SCANCODE_NONUSBACKSLASH; /* 103rd */ |
| |
| } |
| |
| static SDL_Keysym * |
| DirectFB_TranslateKey(_THIS, DFBWindowEvent * evt, SDL_Keysym * keysym, Uint32 *unicode) |
| { |
| SDL_DFB_DEVICEDATA(_this); |
| int kbd_idx = 0; /* Window events lag the device source KbdIndex(_this, evt->device_id); */ |
| DFB_KeyboardData *kbd = &devdata->keyboard[kbd_idx]; |
| |
| keysym->scancode = SDL_SCANCODE_UNKNOWN; |
| |
| if (kbd->map && evt->key_code >= kbd->map_adjust && |
| evt->key_code < kbd->map_size + kbd->map_adjust) |
| keysym->scancode = kbd->map[evt->key_code - kbd->map_adjust]; |
| |
| if (keysym->scancode == SDL_SCANCODE_UNKNOWN || |
| devdata->keyboard[kbd_idx].is_generic) { |
| if (evt->key_id - DIKI_UNKNOWN < SDL_arraysize(oskeymap)) |
| keysym->scancode = oskeymap[evt->key_id - DIKI_UNKNOWN]; |
| else |
| keysym->scancode = SDL_SCANCODE_UNKNOWN; |
| } |
| |
| *unicode = |
| (DFB_KEY_TYPE(evt->key_symbol) == DIKT_UNICODE) ? evt->key_symbol : 0; |
| if (*unicode == 0 && |
| (evt->key_symbol > 0 && evt->key_symbol < 255)) |
| *unicode = evt->key_symbol; |
| |
| return keysym; |
| } |
| |
| static SDL_Keysym * |
| DirectFB_TranslateKeyInputEvent(_THIS, DFBInputEvent * evt, |
| SDL_Keysym * keysym, Uint32 *unicode) |
| { |
| SDL_DFB_DEVICEDATA(_this); |
| int kbd_idx = KbdIndex(_this, evt->device_id); |
| DFB_KeyboardData *kbd = &devdata->keyboard[kbd_idx]; |
| |
| keysym->scancode = SDL_SCANCODE_UNKNOWN; |
| |
| if (kbd->map && evt->key_code >= kbd->map_adjust && |
| evt->key_code < kbd->map_size + kbd->map_adjust) |
| keysym->scancode = kbd->map[evt->key_code - kbd->map_adjust]; |
| |
| if (keysym->scancode == SDL_SCANCODE_UNKNOWN || devdata->keyboard[kbd_idx].is_generic) { |
| if (evt->key_id - DIKI_UNKNOWN < SDL_arraysize(oskeymap)) |
| keysym->scancode = oskeymap[evt->key_id - DIKI_UNKNOWN]; |
| else |
| keysym->scancode = SDL_SCANCODE_UNKNOWN; |
| } |
| |
| *unicode = |
| (DFB_KEY_TYPE(evt->key_symbol) == DIKT_UNICODE) ? evt->key_symbol : 0; |
| if (*unicode == 0 && |
| (evt->key_symbol > 0 && evt->key_symbol < 255)) |
| *unicode = evt->key_symbol; |
| |
| return keysym; |
| } |
| |
| static int |
| DirectFB_TranslateButton(DFBInputDeviceButtonIdentifier button) |
| { |
| switch (button) { |
| case DIBI_LEFT: |
| return 1; |
| case DIBI_MIDDLE: |
| return 2; |
| case DIBI_RIGHT: |
| return 3; |
| default: |
| return 0; |
| } |
| } |
| |
| static DFBEnumerationResult |
| EnumKeyboards(DFBInputDeviceID device_id, |
| DFBInputDeviceDescription desc, void *callbackdata) |
| { |
| cb_data *cb = callbackdata; |
| DFB_DeviceData *devdata = cb->devdata; |
| #if USE_MULTI_API |
| SDL_Keyboard keyboard; |
| #endif |
| SDL_Keycode keymap[SDL_NUM_SCANCODES]; |
| |
| if (!cb->sys_kbd) { |
| if (cb->sys_ids) { |
| if (device_id >= 0x10) |
| return DFENUM_OK; |
| } else { |
| if (device_id < 0x10) |
| return DFENUM_OK; |
| } |
| } else { |
| if (device_id != DIDID_KEYBOARD) |
| return DFENUM_OK; |
| } |
| |
| if ((desc.caps & DIDTF_KEYBOARD)) { |
| #if USE_MULTI_API |
| SDL_zero(keyboard); |
| SDL_AddKeyboard(&keyboard, devdata->num_keyboard); |
| #endif |
| devdata->keyboard[devdata->num_keyboard].id = device_id; |
| devdata->keyboard[devdata->num_keyboard].is_generic = 0; |
| if (!strncmp("X11", desc.name, 3)) |
| { |
| devdata->keyboard[devdata->num_keyboard].map = xfree86_scancode_table2; |
| devdata->keyboard[devdata->num_keyboard].map_size = SDL_arraysize(xfree86_scancode_table2); |
| devdata->keyboard[devdata->num_keyboard].map_adjust = 8; |
| } else { |
| devdata->keyboard[devdata->num_keyboard].map = linux_scancode_table; |
| devdata->keyboard[devdata->num_keyboard].map_size = SDL_arraysize(linux_scancode_table); |
| devdata->keyboard[devdata->num_keyboard].map_adjust = 0; |
| } |
| |
| SDL_DFB_LOG("Keyboard %d - %s\n", device_id, desc.name); |
| |
| SDL_GetDefaultKeymap(keymap); |
| #if USE_MULTI_API |
| SDL_SetKeymap(devdata->num_keyboard, 0, keymap, SDL_NUM_SCANCODES); |
| #else |
| SDL_SetKeymap(0, keymap, SDL_NUM_SCANCODES); |
| #endif |
| devdata->num_keyboard++; |
| |
| if (cb->sys_kbd) |
| return DFENUM_CANCEL; |
| } |
| return DFENUM_OK; |
| } |
| |
| void |
| DirectFB_InitKeyboard(_THIS) |
| { |
| SDL_DFB_DEVICEDATA(_this); |
| cb_data cb; |
| |
| DirectFB_InitOSKeymap(_this, &oskeymap[0], SDL_arraysize(oskeymap)); |
| |
| devdata->num_keyboard = 0; |
| cb.devdata = devdata; |
| |
| if (devdata->use_linux_input) { |
| cb.sys_kbd = 0; |
| cb.sys_ids = 0; |
| SDL_DFB_CHECK(devdata->dfb-> |
| EnumInputDevices(devdata->dfb, EnumKeyboards, &cb)); |
| if (devdata->num_keyboard == 0) { |
| cb.sys_ids = 1; |
| SDL_DFB_CHECK(devdata->dfb->EnumInputDevices(devdata->dfb, |
| EnumKeyboards, |
| &cb)); |
| } |
| } else { |
| cb.sys_kbd = 1; |
| SDL_DFB_CHECK(devdata->dfb->EnumInputDevices(devdata->dfb, |
| EnumKeyboards, |
| &cb)); |
| } |
| } |
| |
| void |
| DirectFB_QuitKeyboard(_THIS) |
| { |
| /* SDL_DFB_DEVICEDATA(_this); */ |
| |
| SDL_KeyboardQuit(); |
| |
| } |
| |
| #endif /* SDL_VIDEO_DRIVER_DIRECTFB */ |