/*
 * QEMU keysym to keycode conversion using rdesktop keymaps
 *
 * Copyright (c) 2004 Johannes Schindelin
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include "qemu/osdep.h"
#include "qemu-common.h"
#include "keymaps.h"
#include "trace.h"
#include "qemu/ctype.h"
#include "qemu/error-report.h"
#include "qapi/error.h"
#include "ui/input.h"

struct keysym2code {
    uint32_t count;
    uint16_t keycodes[4];
};

struct kbd_layout_t {
    GHashTable *hash;
};

static int get_keysym(const name2keysym_t *table,
                      const char *name)
{
    const name2keysym_t *p;
    for(p = table; p->name != NULL; p++) {
        if (!strcmp(p->name, name)) {
            return p->keysym;
        }
    }
    if (name[0] == 'U' && strlen(name) == 5) { /* try unicode Uxxxx */
        char *end;
        int ret = (int)strtoul(name + 1, &end, 16);
        if (*end == '\0' && ret > 0) {
            return ret;
        }
    }
    return 0;
}


static void add_keysym(char *line, int keysym, int keycode, kbd_layout_t *k)
{
    struct keysym2code *keysym2code;

    keysym2code = g_hash_table_lookup(k->hash, GINT_TO_POINTER(keysym));
    if (keysym2code) {
        if (keysym2code->count < ARRAY_SIZE(keysym2code->keycodes)) {
            keysym2code->keycodes[keysym2code->count++] = keycode;
        } else {
            warn_report("more than %zd keycodes for keysym %d",
                        ARRAY_SIZE(keysym2code->keycodes), keysym);
        }
        return;
    }

    keysym2code = g_new0(struct keysym2code, 1);
    keysym2code->keycodes[0] = keycode;
    keysym2code->count = 1;
    g_hash_table_replace(k->hash, GINT_TO_POINTER(keysym), keysym2code);
    trace_keymap_add(keysym, keycode, line);
}

static int parse_keyboard_layout(kbd_layout_t *k,
                                 const name2keysym_t *table,
                                 const char *language, Error **errp)
{
    int ret;
    FILE *f;
    char * filename;
    char line[1024];
    char keyname[64];
    int len;

    filename = qemu_find_file(QEMU_FILE_TYPE_KEYMAP, language);
    trace_keymap_parse(filename);
    f = filename ? fopen(filename, "r") : NULL;
    g_free(filename);
    if (!f) {
        error_setg(errp, "could not read keymap file: '%s'", language);
        return -1;
    }

    for(;;) {
        if (fgets(line, 1024, f) == NULL) {
            break;
        }
        len = strlen(line);
        if (len > 0 && line[len - 1] == '\n') {
            line[len - 1] = '\0';
        }
        if (line[0] == '#') {
            continue;
        }
        if (!strncmp(line, "map ", 4)) {
            continue;
        }
        if (!strncmp(line, "include ", 8)) {
            error_setg(errp, "keymap include files are not supported any more");
            ret = -1;
            goto out;
        } else {
            int offset = 0;
            while (line[offset] != 0 &&
                   line[offset] != ' ' &&
                   offset < sizeof(keyname) - 1) {
                keyname[offset] = line[offset];
                offset++;
            }
            keyname[offset] = 0;
            if (strlen(keyname)) {
                int keysym;
                keysym = get_keysym(table, keyname);
                if (keysym == 0) {
                    /* warn_report("unknown keysym %s", line);*/
                } else {
                    const char *rest = line + offset + 1;
                    int keycode = strtol(rest, NULL, 0);

                    if (strstr(rest, "shift")) {
                        keycode |= SCANCODE_SHIFT;
                    }
                    if (strstr(rest, "altgr")) {
                        keycode |= SCANCODE_ALTGR;
                    }
                    if (strstr(rest, "ctrl")) {
                        keycode |= SCANCODE_CTRL;
                    }

                    add_keysym(line, keysym, keycode, k);

                    if (strstr(rest, "addupper")) {
                        char *c;
                        for (c = keyname; *c; c++) {
                            *c = qemu_toupper(*c);
                        }
                        keysym = get_keysym(table, keyname);
                        if (keysym) {
                            add_keysym(line, keysym,
                                       keycode | SCANCODE_SHIFT, k);
                        }
                    }
                }
            }
        }
    }

    ret = 0;
out:
    fclose(f);
    return ret;
}


kbd_layout_t *init_keyboard_layout(const name2keysym_t *table,
                                   const char *language, Error **errp)
{
    kbd_layout_t *k;

    k = g_new0(kbd_layout_t, 1);
    k->hash = g_hash_table_new(NULL, NULL);
    if (parse_keyboard_layout(k, table, language, errp) < 0) {
        g_hash_table_unref(k->hash);
        g_free(k);
        return NULL;
    }
    return k;
}


int keysym2scancode(kbd_layout_t *k, int keysym,
                    QKbdState *kbd, bool down)
{
    static const uint32_t mask =
        SCANCODE_SHIFT | SCANCODE_ALTGR | SCANCODE_CTRL;
    uint32_t mods, i;
    struct keysym2code *keysym2code;

#ifdef XK_ISO_Left_Tab
    if (keysym == XK_ISO_Left_Tab) {
        keysym = XK_Tab;
    }
#endif

    keysym2code = g_hash_table_lookup(k->hash, GINT_TO_POINTER(keysym));
    if (!keysym2code) {
        trace_keymap_unmapped(keysym);
        warn_report("no scancode found for keysym %d", keysym);
        return 0;
    }

    if (keysym2code->count == 1) {
        return keysym2code->keycodes[0];
    }

    /* We have multiple keysym -> keycode mappings. */
    if (down) {
        /*
         * On keydown: Check whenever we find one mapping where the
         * modifier state of the mapping matches the current user
         * interface modifier state.  If so, prefer that one.
         */
        mods = 0;
        if (kbd && qkbd_state_modifier_get(kbd, QKBD_MOD_SHIFT)) {
            mods |= SCANCODE_SHIFT;
        }
        if (kbd && qkbd_state_modifier_get(kbd, QKBD_MOD_ALTGR)) {
            mods |= SCANCODE_ALTGR;
        }
        if (kbd && qkbd_state_modifier_get(kbd, QKBD_MOD_CTRL)) {
            mods |= SCANCODE_CTRL;
        }

        for (i = 0; i < keysym2code->count; i++) {
            if ((keysym2code->keycodes[i] & mask) == mods) {
                return keysym2code->keycodes[i];
            }
        }
    } else {
        /*
         * On keyup: Try find a key which is actually down.
         */
        for (i = 0; i < keysym2code->count; i++) {
            QKeyCode qcode = qemu_input_key_number_to_qcode
                (keysym2code->keycodes[i]);
            if (kbd && qkbd_state_key_get(kbd, qcode)) {
                return keysym2code->keycodes[i];
            }
        }
    }
    return keysym2code->keycodes[0];
}

int keycode_is_keypad(kbd_layout_t *k, int keycode)
{
    if (keycode >= 0x47 && keycode <= 0x53) {
        return true;
    }
    return false;
}

int keysym_is_numlock(kbd_layout_t *k, int keysym)
{
    switch (keysym) {
    case 0xffb0 ... 0xffb9:  /* KP_0 .. KP_9 */
    case 0xffac:             /* KP_Separator */
    case 0xffae:             /* KP_Decimal   */
        return true;
    }
    return false;
}
