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

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