summaryrefslogtreecommitdiff
path: root/source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_events.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_events.c')
-rw-r--r--source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_events.c748
1 files changed, 748 insertions, 0 deletions
diff --git a/source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_events.c b/source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_events.c
new file mode 100644
index 0000000..27cf19f
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/directfb/SDL_DirectFB_events.c
@@ -0,0 +1,748 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 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); */
+}
+
+#endif /* SDL_VIDEO_DRIVER_DIRECTFB */