/*
  Simple DirectMedia Layer
  Copyright (C) 1997-2019 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 */
