/*
 * 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/datadir.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)
{
    g_autofree char *filename = NULL;
    int ret;
    FILE *f;
    char line[1024];
    char keyname[64];
    int len;

    filename = qemu_find_file(QEMU_FILE_TYPE_KEYMAP, language);
    if (!filename) {
        error_setg(errp, "could not find keymap file for language '%s'",
                   language);
        return -1;
    }

    trace_keymap_parse(filename);

    f = fopen(filename, "r");
    if (!f) {
        error_setg_file_open(errp, errno, filename);
        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;
}
