/*
 * 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 "keymaps.h"
#include "sysemu/sysemu.h"

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_to_key_range(struct key_range **krp, int code) {
    struct key_range *kr;
    for (kr = *krp; kr; kr = kr->next) {
        if (code >= kr->start && code <= kr->end) {
            break;
        }
        if (code == kr->start - 1) {
            kr->start--;
            break;
        }
        if (code == kr->end + 1) {
            kr->end++;
            break;
        }
    }
    if (kr == NULL) {
        kr = g_malloc0(sizeof(*kr));
        kr->start = kr->end = code;
        kr->next = *krp;
        *krp = kr;
    }
}

static void add_keysym(char *line, int keysym, int keycode, kbd_layout_t *k) {
    if (keysym < MAX_NORMAL_KEYCODE) {
        /* fprintf(stderr,"Setting keysym %s (%d) to %d\n",
                   line, keysym, keycode); */
        k->keysym2keycode[keysym] = keycode;
    } else {
        if (k->extra_count >= MAX_EXTRA_COUNT) {
            fprintf(stderr, "Warning: Could not assign keysym %s (0x%x)"
                    " because of memory constraints.\n", line, keysym);
        } else {
#if 0
            fprintf(stderr, "Setting %d: %d,%d\n",
                    k->extra_count, keysym, keycode);
#endif
            k->keysym2keycode_extra[k->extra_count].
            keysym = keysym;
            k->keysym2keycode_extra[k->extra_count].
            keycode = keycode;
            k->extra_count++;
        }
    }
}

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

    filename = qemu_find_file(QEMU_FILE_TYPE_KEYMAP, language);
    f = filename ? fopen(filename, "r") : NULL;
    g_free(filename);
    if (!f) {
        fprintf(stderr, "Could not read keymap file: '%s'\n", language);
        return NULL;
    }

    if (!k) {
        k = g_malloc0(sizeof(kbd_layout_t));
    }

    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)) {
            parse_keyboard_layout(table, line + 8, k);
        } else {
            char *end_of_keysym = line;
            while (*end_of_keysym != 0 && *end_of_keysym != ' ') {
                end_of_keysym++;
            }
            if (*end_of_keysym) {
                int keysym;
                *end_of_keysym = 0;
                keysym = get_keysym(table, line);
                if (keysym == 0) {
                    /* fprintf(stderr, "Warning: unknown keysym %s\n", line);*/
                } else {
                    const char *rest = end_of_keysym + 1;
                    int keycode = strtol(rest, NULL, 0);

                    if (strstr(rest, "numlock")) {
                        add_to_key_range(&k->keypad_range, keycode);
                        add_to_key_range(&k->numlock_range, keysym);
                        /* fprintf(stderr, "keypad keysym %04x keycode %d\n",
                                   keysym, keycode); */
                    }

                    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 = line; *c; c++) {
                            *c = qemu_toupper(*c);
                        }
                        keysym = get_keysym(table, line);
                        if (keysym) {
                            add_keysym(line, keysym,
                                       keycode | SCANCODE_SHIFT, k);
                        }
                    }
                }
            }
        }
    }
    fclose(f);
    return k;
}


void *init_keyboard_layout(const name2keysym_t *table, const char *language)
{
    return parse_keyboard_layout(table, language, NULL);
}


int keysym2scancode(void *kbd_layout, int keysym)
{
    kbd_layout_t *k = kbd_layout;
    if (keysym < MAX_NORMAL_KEYCODE) {
        if (k->keysym2keycode[keysym] == 0) {
            fprintf(stderr, "Warning: no scancode found for keysym %d\n",
                    keysym);
        }
        return k->keysym2keycode[keysym];
    } else {
        int i;
#ifdef XK_ISO_Left_Tab
        if (keysym == XK_ISO_Left_Tab) {
            keysym = XK_Tab;
        }
#endif
        for (i = 0; i < k->extra_count; i++) {
            if (k->keysym2keycode_extra[i].keysym == keysym) {
                return k->keysym2keycode_extra[i].keycode;
            }
        }
    }
    return 0;
}

int keycode_is_keypad(void *kbd_layout, int keycode)
{
    kbd_layout_t *k = kbd_layout;
    struct key_range *kr;

    for (kr = k->keypad_range; kr; kr = kr->next) {
        if (keycode >= kr->start && keycode <= kr->end) {
            return 1;
        }
    }
    return 0;
}

int keysym_is_numlock(void *kbd_layout, int keysym)
{
    kbd_layout_t *k = kbd_layout;
    struct key_range *kr;

    for (kr = k->numlock_range; kr; kr = kr->next) {
        if (keysym >= kr->start && keysym <= kr->end) {
            return 1;
        }
    }
    return 0;
}
