/*
  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"

#include "SDL_evdev_kbd.h"
#include "SDL_hints.h"

#ifdef SDL_INPUT_LINUXKD

/* This logic is adapted from drivers/tty/vt/keyboard.c in the Linux kernel source */

#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/kd.h>
#include <linux/keyboard.h>
#include <linux/vt.h>
#include <linux/tiocl.h> /* for TIOCL_GETSHIFTSTATE */

#include <signal.h>

#include "../../events/SDL_events_c.h"
#include "SDL_evdev_kbd_default_accents.h"
#include "SDL_evdev_kbd_default_keymap.h"

/* These are not defined in older Linux kernel headers */
#ifndef K_UNICODE
#define K_UNICODE 0x03
#endif
#ifndef K_OFF
#define K_OFF 0x04
#endif

/*
 * Handler Tables.
 */

#define K_HANDLERS\
    k_self,     k_fn,       k_spec,       k_pad,\
    k_dead,     k_cons,     k_cur,        k_shift,\
    k_meta,     k_ascii,    k_lock,       k_lowercase,\
    k_slock,    k_dead2,    k_brl,        k_ignore

typedef void (k_handler_fn)(SDL_EVDEV_keyboard_state *kbd, unsigned char value, char up_flag);
static k_handler_fn K_HANDLERS;
static k_handler_fn *k_handler[16] = { K_HANDLERS };

typedef void (fn_handler_fn)(SDL_EVDEV_keyboard_state *kbd);
static void fn_enter(SDL_EVDEV_keyboard_state *kbd);
static void fn_caps_toggle(SDL_EVDEV_keyboard_state *kbd);
static void fn_caps_on(SDL_EVDEV_keyboard_state *kbd);
static void fn_num(SDL_EVDEV_keyboard_state *kbd);
static void fn_compose(SDL_EVDEV_keyboard_state *kbd);

static fn_handler_fn *fn_handler[] =
{
    NULL,       fn_enter,   NULL,       NULL,
    NULL,       NULL,       NULL,       fn_caps_toggle,
    fn_num,     NULL,       NULL,       NULL,
    NULL,       fn_caps_on, fn_compose, NULL,
    NULL,       NULL,       NULL,       fn_num
};


/*
 * Keyboard State
 */

struct SDL_EVDEV_keyboard_state
{
    int console_fd;
    int old_kbd_mode;
    unsigned short **key_maps;
    unsigned char shift_down[NR_SHIFT];        /* shift state counters.. */
    SDL_bool dead_key_next;
    int npadch;                    /* -1 or number assembled on pad */
    struct kbdiacrs *accents;
    unsigned int diacr;
    SDL_bool rep;                    /* flag telling character repeat */
    unsigned char lockstate;
    unsigned char slockstate;
    unsigned char ledflagstate;
    char shift_state;
    char text[128];
    unsigned int text_len;
};

#ifdef DUMP_ACCENTS
static void SDL_EVDEV_dump_accents(SDL_EVDEV_keyboard_state *kbd)
{
    unsigned int i;

    printf("static struct kbdiacrs default_accents = {\n");
    printf("    %d,\n", kbd->accents->kb_cnt);
    printf("    {\n");
    for (i = 0; i < kbd->accents->kb_cnt; ++i) {
        struct kbdiacr *diacr = &kbd->accents->kbdiacr[i];
        printf("        { 0x%.2x, 0x%.2x, 0x%.2x },\n",
            diacr->diacr, diacr->base, diacr->result);
    }
    while (i < 256) {
        printf("        { 0x00, 0x00, 0x00 },\n");
        ++i;
    }
    printf("    }\n");
    printf("};\n");
}
#endif /* DUMP_ACCENTS */

#ifdef DUMP_KEYMAP
static void SDL_EVDEV_dump_keymap(SDL_EVDEV_keyboard_state *kbd)
{
    int i, j;

    for (i = 0; i < MAX_NR_KEYMAPS; ++i) {
        if (kbd->key_maps[i]) {
            printf("static unsigned short default_key_map_%d[NR_KEYS] = {", i);
            for (j = 0; j < NR_KEYS; ++j) {
                if ((j%8) == 0) {
                    printf("\n    ");
                }
                printf("0x%.4x, ", kbd->key_maps[i][j]);
            }
            printf("\n};\n");
        }
    }
    printf("\n");
    printf("static unsigned short *default_key_maps[MAX_NR_KEYMAPS] = {\n");
    for (i = 0; i < MAX_NR_KEYMAPS; ++i) {
        if (kbd->key_maps[i]) {
            printf("    default_key_map_%d,\n", i);
        } else {
            printf("    NULL,\n");
        }
    }
    printf("};\n");
}
#endif /* DUMP_KEYMAP */

static int SDL_EVDEV_kbd_load_keymaps(SDL_EVDEV_keyboard_state *kbd)
{
    int i, j;

    kbd->key_maps = (unsigned short **)SDL_calloc(MAX_NR_KEYMAPS, sizeof(unsigned short *));
    if (!kbd->key_maps) {
        return -1;
    }

    for (i = 0; i < MAX_NR_KEYMAPS; ++i) {
        struct kbentry kbe;

        kbe.kb_table = i;
        kbe.kb_index = 0;
        if (ioctl(kbd->console_fd, KDGKBENT, &kbe) < 0) {
            return -1;
        }

        if (kbe.kb_value == K_NOSUCHMAP) {
            continue;
        }

        kbd->key_maps[i] = (unsigned short *)SDL_malloc(NR_KEYS * sizeof(unsigned short));
        if (!kbd->key_maps[i]) {
            return -1;
        }

        for (j = 0; j < NR_KEYS; ++j) {
            kbe.kb_table = i;
            kbe.kb_index = j;
            if (ioctl(kbd->console_fd, KDGKBENT, &kbe) < 0) {
                return -1;
            }
            kbd->key_maps[i][j] = (kbe.kb_value ^ 0xf000);
        }
    }
    return 0;
}

static SDL_EVDEV_keyboard_state * kbd_cleanup_state = NULL;
static int kbd_cleanup_sigactions_installed = 0;
static int kbd_cleanup_atexit_installed = 0;

static struct sigaction old_sigaction[NSIG];

static int fatal_signals[] =
{
    /* Handlers for SIGTERM and SIGINT are installed in SDL_QuitInit. */
    SIGHUP,  SIGQUIT, SIGILL,  SIGABRT,
    SIGFPE,  SIGSEGV, SIGPIPE, SIGBUS,
    SIGSYS
};

static void kbd_cleanup(void)
{
    SDL_EVDEV_keyboard_state* kbd = kbd_cleanup_state;
    if (kbd == NULL) {
        return;
    }
    kbd_cleanup_state = NULL;

    fprintf(stderr, "(SDL restoring keyboard) ");
    ioctl(kbd->console_fd, KDSKBMODE, kbd->old_kbd_mode);
}

void
SDL_EVDEV_kbd_reraise_signal(int sig)
{
    raise(sig);
}

siginfo_t* SDL_EVDEV_kdb_cleanup_siginfo = NULL;
void*      SDL_EVDEV_kdb_cleanup_ucontext = NULL;

static void kbd_cleanup_signal_action(int signum, siginfo_t* info, void* ucontext)
{
    struct sigaction* old_action_p = &(old_sigaction[signum]);
    sigset_t sigset;

    /* Restore original signal handler before going any further. */
    sigaction(signum, old_action_p, NULL);

    /* Unmask current signal. */
    sigemptyset(&sigset);
    sigaddset(&sigset, signum);
    sigprocmask(SIG_UNBLOCK, &sigset, NULL);

    /* Save original signal info and context for archeologists. */
    SDL_EVDEV_kdb_cleanup_siginfo = info;
    SDL_EVDEV_kdb_cleanup_ucontext = ucontext;

    /* Restore keyboard. */
    kbd_cleanup();

    /* Reraise signal. */
    SDL_EVDEV_kbd_reraise_signal(signum);
}

static void kbd_unregister_emerg_cleanup()
{
    int tabidx, signum;

    kbd_cleanup_state = NULL;

    if (!kbd_cleanup_sigactions_installed) {
        return;
    }
    kbd_cleanup_sigactions_installed = 0;

    for (tabidx = 0; tabidx < sizeof(fatal_signals) / sizeof(fatal_signals[0]); ++tabidx) {
        struct sigaction* old_action_p;
        struct sigaction cur_action;
        signum = fatal_signals[tabidx];
        old_action_p = &(old_sigaction[signum]);

        /* Examine current signal action */
        if (sigaction(signum, NULL, &cur_action))
            continue;

        /* Check if action installed and not modifed */
        if (!(cur_action.sa_flags & SA_SIGINFO)
                || cur_action.sa_sigaction != &kbd_cleanup_signal_action)
            continue;

        /* Restore original action */
        sigaction(signum, old_action_p, NULL);
    }
}

static void kbd_cleanup_atexit(void)
{
    /* Restore keyboard. */
    kbd_cleanup();

    /* Try to restore signal handlers in case shared library is being unloaded */
    kbd_unregister_emerg_cleanup();
}

static void kbd_register_emerg_cleanup(SDL_EVDEV_keyboard_state * kbd)
{
    int tabidx, signum;

    if (kbd_cleanup_state != NULL) {
        return;
    }
    kbd_cleanup_state = kbd;

    if (!kbd_cleanup_atexit_installed) {
        /* Since glibc 2.2.3, atexit() (and on_exit(3)) can be used within a shared library to establish
         * functions that are called when the shared library is unloaded.
         * -- man atexit(3)
         */
        atexit(kbd_cleanup_atexit);
        kbd_cleanup_atexit_installed = 1;
    }

    if (kbd_cleanup_sigactions_installed) {
        return;
    }
    kbd_cleanup_sigactions_installed = 1;

    for (tabidx = 0; tabidx < sizeof(fatal_signals) / sizeof(fatal_signals[0]); ++tabidx) {
        struct sigaction* old_action_p;
        struct sigaction new_action;
        signum = fatal_signals[tabidx];   
        old_action_p = &(old_sigaction[signum]);
        if (sigaction(signum, NULL, old_action_p))
            continue;

        /* Skip SIGHUP and SIGPIPE if handler is already installed
         * - assume the handler will do the cleanup
         */
        if ((signum == SIGHUP || signum == SIGPIPE)
                && (old_action_p->sa_handler != SIG_DFL 
                    || (void (*)(int))old_action_p->sa_sigaction != SIG_DFL))
            continue;

        new_action = *old_action_p;
        new_action.sa_flags |= SA_SIGINFO;
        new_action.sa_sigaction = &kbd_cleanup_signal_action;
        sigaction(signum, &new_action, NULL);
    }
}

SDL_EVDEV_keyboard_state *
SDL_EVDEV_kbd_init(void)
{
    SDL_EVDEV_keyboard_state *kbd;
    int i;
    char flag_state;
    char shift_state[ sizeof (long) ] = {TIOCL_GETSHIFTSTATE, 0};

    kbd = (SDL_EVDEV_keyboard_state *)SDL_calloc(1, sizeof(*kbd));
    if (!kbd) {
        return NULL;
    }

    kbd->npadch = -1;

    /* This might fail if we're not connected to a tty (e.g. on the Steam Link) */
    kbd->console_fd = open("/dev/tty", O_RDONLY);

    if (ioctl(kbd->console_fd, TIOCLINUX, shift_state) == 0) {
        kbd->shift_state = *shift_state;
    }

    if (ioctl(kbd->console_fd, KDGKBLED, &flag_state) == 0) {
        kbd->ledflagstate = flag_state;
    }

    kbd->accents = &default_accents;
    if (ioctl(kbd->console_fd, KDGKBDIACR, kbd->accents) < 0) {
        /* No worries, we'll use the default accent table */
    }

    kbd->key_maps = default_key_maps;
    if (ioctl(kbd->console_fd, KDGKBMODE, &kbd->old_kbd_mode) == 0) {
        /* Set the keyboard in UNICODE mode and load the keymaps */
        ioctl(kbd->console_fd, KDSKBMODE, K_UNICODE);

        if (SDL_EVDEV_kbd_load_keymaps(kbd) < 0) {
            for (i = 0; i < MAX_NR_KEYMAPS; ++i) {
                if (kbd->key_maps[i]) {
                    SDL_free(kbd->key_maps[i]);
                }
            }
            SDL_free(kbd->key_maps);

            kbd->key_maps = default_key_maps;
        }

        /* Allow inhibiting keyboard mute with env. variable for debugging etc. */
        if (getenv("SDL_INPUT_LINUX_KEEP_KBD") == NULL) {
            /* Mute the keyboard so keystrokes only generate evdev events
             * and do not leak through to the console
             */
            ioctl(kbd->console_fd, KDSKBMODE, K_OFF);

            /* Make sure to restore keyboard if application fails to call
             * SDL_Quit before exit or fatal signal is raised.
             */
            if (!SDL_GetHintBoolean(SDL_HINT_NO_SIGNAL_HANDLERS, SDL_FALSE)) {
                kbd_register_emerg_cleanup(kbd);
            }
        }
    }

#ifdef DUMP_ACCENTS
    SDL_EVDEV_dump_accents(kbd);
#endif
#ifdef DUMP_KEYMAP
    SDL_EVDEV_dump_keymap(kbd);
#endif
    return kbd;
}

void
SDL_EVDEV_kbd_quit(SDL_EVDEV_keyboard_state *kbd)
{
    if (!kbd) {
        return;
    }

    kbd_unregister_emerg_cleanup();

    if (kbd->console_fd >= 0) {
        /* Restore the original keyboard mode */
        ioctl(kbd->console_fd, KDSKBMODE, kbd->old_kbd_mode);

        close(kbd->console_fd);
        kbd->console_fd = -1;
    }

    if (kbd->key_maps && kbd->key_maps != default_key_maps) {
        int i;
        for (i = 0; i < MAX_NR_KEYMAPS; ++i) {
            if (kbd->key_maps[i]) {
                SDL_free(kbd->key_maps[i]);
            }
        }
        SDL_free(kbd->key_maps);
    }

    SDL_free(kbd);
}

/*
 * Helper Functions.
 */
static void put_queue(SDL_EVDEV_keyboard_state *kbd, uint c)
{
    /* c is already part of a UTF-8 sequence and safe to add as a character */
    if (kbd->text_len < (sizeof(kbd->text)-1)) {
        kbd->text[kbd->text_len++] = (char)c;
    }
}

static void put_utf8(SDL_EVDEV_keyboard_state *kbd, uint c)
{
    if (c < 0x80)
        /*  0******* */
        put_queue(kbd, c);
    else if (c < 0x800) {
        /* 110***** 10****** */
        put_queue(kbd, 0xc0 | (c >> 6));
        put_queue(kbd, 0x80 | (c & 0x3f));
    } else if (c < 0x10000) {
        if (c >= 0xD800 && c < 0xE000)
            return;
        if (c == 0xFFFF)
            return;
        /* 1110**** 10****** 10****** */
        put_queue(kbd, 0xe0 | (c >> 12));
        put_queue(kbd, 0x80 | ((c >> 6) & 0x3f));
        put_queue(kbd, 0x80 | (c & 0x3f));
    } else if (c < 0x110000) {
        /* 11110*** 10****** 10****** 10****** */
        put_queue(kbd, 0xf0 | (c >> 18));
        put_queue(kbd, 0x80 | ((c >> 12) & 0x3f));
        put_queue(kbd, 0x80 | ((c >> 6) & 0x3f));
        put_queue(kbd, 0x80 | (c & 0x3f));
    }
}

/*
 * We have a combining character DIACR here, followed by the character CH.
 * If the combination occurs in the table, return the corresponding value.
 * Otherwise, if CH is a space or equals DIACR, return DIACR.
 * Otherwise, conclude that DIACR was not combining after all,
 * queue it and return CH.
 */
static unsigned int handle_diacr(SDL_EVDEV_keyboard_state *kbd, unsigned int ch)
{
    unsigned int d = kbd->diacr;
    unsigned int i;

    kbd->diacr = 0;

    for (i = 0; i < kbd->accents->kb_cnt; i++) {
        if (kbd->accents->kbdiacr[i].diacr == d &&
            kbd->accents->kbdiacr[i].base == ch) {
            return kbd->accents->kbdiacr[i].result;
        }
    }

    if (ch == ' ' || ch == d)
        return d;

    put_utf8(kbd, d);

    return ch;
}

static int vc_kbd_led(SDL_EVDEV_keyboard_state *kbd, int flag)
{
    return (kbd->ledflagstate & flag) != 0;
}

static void set_vc_kbd_led(SDL_EVDEV_keyboard_state *kbd, int flag)
{
    kbd->ledflagstate |= flag;
    ioctl(kbd->console_fd, KDSETLED, (unsigned long)(kbd->ledflagstate));
}

static void clr_vc_kbd_led(SDL_EVDEV_keyboard_state *kbd, int flag)
{
    kbd->ledflagstate &= ~flag;
    ioctl(kbd->console_fd, KDSETLED, (unsigned long)(kbd->ledflagstate));
}

static void chg_vc_kbd_lock(SDL_EVDEV_keyboard_state *kbd, int flag)
{
    kbd->lockstate ^= 1 << flag;
}

static void chg_vc_kbd_slock(SDL_EVDEV_keyboard_state *kbd, int flag)
{
    kbd->slockstate ^= 1 << flag;
}

static void chg_vc_kbd_led(SDL_EVDEV_keyboard_state *kbd, int flag)
{
    kbd->ledflagstate ^= flag;
    ioctl(kbd->console_fd, KDSETLED, (unsigned long)(kbd->ledflagstate));
}

/*
 * Special function handlers
 */

static void fn_enter(SDL_EVDEV_keyboard_state *kbd)
{
    if (kbd->diacr) {
        put_utf8(kbd, kbd->diacr);
        kbd->diacr = 0;
    }
}

static void fn_caps_toggle(SDL_EVDEV_keyboard_state *kbd)
{
    if (kbd->rep)
        return;

    chg_vc_kbd_led(kbd, K_CAPSLOCK);
}

static void fn_caps_on(SDL_EVDEV_keyboard_state *kbd)
{
    if (kbd->rep)
        return;

    set_vc_kbd_led(kbd, K_CAPSLOCK);
}

static void fn_num(SDL_EVDEV_keyboard_state *kbd)
{
    if (!kbd->rep)
        chg_vc_kbd_led(kbd, K_NUMLOCK);
}

static void fn_compose(SDL_EVDEV_keyboard_state *kbd)
{
    kbd->dead_key_next = SDL_TRUE;
}

/*
 * Special key handlers
 */

static void k_ignore(SDL_EVDEV_keyboard_state *kbd, unsigned char value, char up_flag)
{
}

static void k_spec(SDL_EVDEV_keyboard_state *kbd, unsigned char value, char up_flag)
{
    if (up_flag)
        return;
    if (value >= SDL_arraysize(fn_handler))
        return;
    if (fn_handler[value])
        fn_handler[value](kbd);
}

static void k_lowercase(SDL_EVDEV_keyboard_state *kbd, unsigned char value, char up_flag)
{
}

static void k_self(SDL_EVDEV_keyboard_state *kbd, unsigned char value, char up_flag)
{
    if (up_flag)
        return;        /* no action, if this is a key release */

    if (kbd->diacr)
        value = handle_diacr(kbd, value);

    if (kbd->dead_key_next) {
        kbd->dead_key_next = SDL_FALSE;
        kbd->diacr = value;
        return;
    }
    put_utf8(kbd, value);
}

static void k_deadunicode(SDL_EVDEV_keyboard_state *kbd, unsigned int value, char up_flag)
{
    if (up_flag)
        return;

    kbd->diacr = (kbd->diacr ? handle_diacr(kbd, value) : value);
}

static void k_dead(SDL_EVDEV_keyboard_state *kbd, unsigned char value, char up_flag)
{
    const unsigned char ret_diacr[NR_DEAD] = {'`', '\'', '^', '~', '"', ',' };

    k_deadunicode(kbd, ret_diacr[value], up_flag);
}

static void k_dead2(SDL_EVDEV_keyboard_state *kbd, unsigned char value, char up_flag)
{
    k_deadunicode(kbd, value, up_flag);
}

static void k_cons(SDL_EVDEV_keyboard_state *kbd, unsigned char value, char up_flag)
{
}

static void k_fn(SDL_EVDEV_keyboard_state *kbd, unsigned char value, char up_flag)
{
}

static void k_cur(SDL_EVDEV_keyboard_state *kbd, unsigned char value, char up_flag)
{
}

static void k_pad(SDL_EVDEV_keyboard_state *kbd, unsigned char value, char up_flag)
{
    static const char pad_chars[] = "0123456789+-*/\015,.?()#";

    if (up_flag)
        return;        /* no action, if this is a key release */

    if (!vc_kbd_led(kbd, K_NUMLOCK)) {
        /* unprintable action */
        return;
    }

    put_queue(kbd, pad_chars[value]);
}

static void k_shift(SDL_EVDEV_keyboard_state *kbd, unsigned char value, char up_flag)
{
    int old_state = kbd->shift_state;

    if (kbd->rep)
        return;
    /*
     * Mimic typewriter:
     * a CapsShift key acts like Shift but undoes CapsLock
     */
    if (value == KVAL(K_CAPSSHIFT)) {
        value = KVAL(K_SHIFT);
        if (!up_flag)
            clr_vc_kbd_led(kbd, K_CAPSLOCK);
    }

    if (up_flag) {
        /*
         * handle the case that two shift or control
         * keys are depressed simultaneously
         */
        if (kbd->shift_down[value])
            kbd->shift_down[value]--;
    } else
        kbd->shift_down[value]++;

    if (kbd->shift_down[value])
        kbd->shift_state |= (1 << value);
    else
        kbd->shift_state &= ~(1 << value);

    /* kludge */
    if (up_flag && kbd->shift_state != old_state && kbd->npadch != -1) {
        put_utf8(kbd, kbd->npadch);
        kbd->npadch = -1;
    }
}

static void k_meta(SDL_EVDEV_keyboard_state *kbd, unsigned char value, char up_flag)
{
}

static void k_ascii(SDL_EVDEV_keyboard_state *kbd, unsigned char value, char up_flag)
{
    int base;

    if (up_flag)
        return;

    if (value < 10) {
        /* decimal input of code, while Alt depressed */
        base = 10;
    } else {
        /* hexadecimal input of code, while AltGr depressed */
        value -= 10;
        base = 16;
    }

    if (kbd->npadch == -1)
        kbd->npadch = value;
    else
        kbd->npadch = kbd->npadch * base + value;
}

static void k_lock(SDL_EVDEV_keyboard_state *kbd, unsigned char value, char up_flag)
{
    if (up_flag || kbd->rep)
        return;

    chg_vc_kbd_lock(kbd, value);
}

static void k_slock(SDL_EVDEV_keyboard_state *kbd, unsigned char value, char up_flag)
{
    k_shift(kbd, value, up_flag);
    if (up_flag || kbd->rep)
        return;

    chg_vc_kbd_slock(kbd, value);
    /* try to make Alt, oops, AltGr and such work */
    if (!kbd->key_maps[kbd->lockstate ^ kbd->slockstate]) {
        kbd->slockstate = 0;
        chg_vc_kbd_slock(kbd, value);
    }
}

static void k_brl(SDL_EVDEV_keyboard_state *kbd, unsigned char value, char up_flag)
{
}

void
SDL_EVDEV_kbd_keycode(SDL_EVDEV_keyboard_state *kbd, unsigned int keycode, int down)
{
    unsigned char shift_final;
    unsigned char type;
    unsigned short *key_map;
    unsigned short keysym;

    if (!kbd) {
        return;
    }

    kbd->rep = (down == 2);

    shift_final = (kbd->shift_state | kbd->slockstate) ^ kbd->lockstate;
    key_map = kbd->key_maps[shift_final];
    if (!key_map) {
        /* Unsupported shift state (e.g. ctrl = 4, alt = 8), just reset to the default state */
        kbd->shift_state = 0;
        kbd->slockstate = 0;
        kbd->lockstate = 0;
        return;
    }

    if (keycode < NR_KEYS) {
        keysym = key_map[keycode];
    } else {
        return;
    }

    type = KTYP(keysym);

    if (type < 0xf0) {
        if (down) {
            put_utf8(kbd, keysym);
        }
    } else {
        type -= 0xf0;

        /* if type is KT_LETTER then it can be affected by Caps Lock */
        if (type == KT_LETTER) {
            type = KT_LATIN;

            if (vc_kbd_led(kbd, K_CAPSLOCK)) {
                key_map = kbd->key_maps[shift_final ^ (1 << KG_SHIFT)];
                if (key_map) {
                    keysym = key_map[keycode];
                }
            }
        }

        (*k_handler[type])(kbd, keysym & 0xff, !down);

        if (type != KT_SLOCK) {
            kbd->slockstate = 0;
        }
    }

    if (kbd->text_len > 0) {
        kbd->text[kbd->text_len] = '\0';
        SDL_SendKeyboardText(kbd->text);
        kbd->text_len = 0;
    }
}

#else /* !SDL_INPUT_LINUXKD */

SDL_EVDEV_keyboard_state *
SDL_EVDEV_kbd_init(void)
{
    return NULL;
}

void
SDL_EVDEV_kbd_keycode(SDL_EVDEV_keyboard_state *state, unsigned int keycode, int down)
{
}

void
SDL_EVDEV_kbd_quit(SDL_EVDEV_keyboard_state *state)
{
}

#endif /* SDL_INPUT_LINUXKD */

/* vi: set ts=4 sw=4 expandtab: */
