/*
 * This work is licensed under the terms of the GNU GPL, version 2 or
 * (at your option) any later version.  See the COPYING file in the
 * top-level directory.
 */

#include "qemu/osdep.h"
#include "qemu/iov.h"
#include "qemu/module.h"

#include "hw/virtio/virtio.h"
#include "hw/qdev-properties.h"
#include "hw/virtio/virtio-input.h"

#undef CONFIG_CURSES
#include "ui/console.h"

#include "standard-headers/linux/input.h"

#define VIRTIO_ID_NAME_KEYBOARD "QEMU Virtio Keyboard"
#define VIRTIO_ID_NAME_MOUSE    "QEMU Virtio Mouse"
#define VIRTIO_ID_NAME_TABLET   "QEMU Virtio Tablet"

/* ----------------------------------------------------------------- */

static const unsigned short keymap_button[INPUT_BUTTON__MAX] = {
    [INPUT_BUTTON_LEFT]              = BTN_LEFT,
    [INPUT_BUTTON_RIGHT]             = BTN_RIGHT,
    [INPUT_BUTTON_MIDDLE]            = BTN_MIDDLE,
    [INPUT_BUTTON_WHEEL_UP]          = BTN_GEAR_UP,
    [INPUT_BUTTON_WHEEL_DOWN]        = BTN_GEAR_DOWN,
    [INPUT_BUTTON_SIDE]              = BTN_SIDE,
    [INPUT_BUTTON_EXTRA]             = BTN_EXTRA,
};

static const unsigned short axismap_rel[INPUT_AXIS__MAX] = {
    [INPUT_AXIS_X]                   = REL_X,
    [INPUT_AXIS_Y]                   = REL_Y,
};

static const unsigned short axismap_abs[INPUT_AXIS__MAX] = {
    [INPUT_AXIS_X]                   = ABS_X,
    [INPUT_AXIS_Y]                   = ABS_Y,
};

/* ----------------------------------------------------------------- */

static void virtio_input_key_config(VirtIOInput *vinput,
                                    const unsigned short *keymap,
                                    size_t mapsize)
{
    virtio_input_config keys;
    int i, bit, byte, bmax = 0;

    memset(&keys, 0, sizeof(keys));
    for (i = 0; i < mapsize; i++) {
        bit = keymap[i];
        if (!bit) {
            continue;
        }
        byte = bit / 8;
        bit  = bit % 8;
        keys.u.bitmap[byte] |= (1 << bit);
        if (bmax < byte+1) {
            bmax = byte+1;
        }
    }
    keys.select = VIRTIO_INPUT_CFG_EV_BITS;
    keys.subsel = EV_KEY;
    keys.size   = bmax;
    virtio_input_add_config(vinput, &keys);
}

static void virtio_input_handle_event(DeviceState *dev, QemuConsole *src,
                                      InputEvent *evt)
{
    VirtIOInputHID *vhid = VIRTIO_INPUT_HID(dev);
    VirtIOInput *vinput = VIRTIO_INPUT(dev);
    virtio_input_event event;
    int qcode;
    InputKeyEvent *key;
    InputMoveEvent *move;
    InputBtnEvent *btn;

    switch (evt->type) {
    case INPUT_EVENT_KIND_KEY:
        key = evt->u.key.data;
        qcode = qemu_input_key_value_to_qcode(key->key);
        if (qcode < qemu_input_map_qcode_to_linux_len &&
            qemu_input_map_qcode_to_linux[qcode]) {
            event.type  = cpu_to_le16(EV_KEY);
            event.code  = cpu_to_le16(qemu_input_map_qcode_to_linux[qcode]);
            event.value = cpu_to_le32(key->down ? 1 : 0);
            virtio_input_send(vinput, &event);
        } else {
            if (key->down) {
                fprintf(stderr, "%s: unmapped key: %d [%s]\n", __func__,
                        qcode, QKeyCode_str(qcode));
            }
        }
        break;
    case INPUT_EVENT_KIND_BTN:
        btn = evt->u.btn.data;
        if (vhid->wheel_axis &&
            (btn->button == INPUT_BUTTON_WHEEL_UP ||
             btn->button == INPUT_BUTTON_WHEEL_DOWN) &&
            btn->down) {
            event.type  = cpu_to_le16(EV_REL);
            event.code  = cpu_to_le16(REL_WHEEL);
            event.value = cpu_to_le32(btn->button == INPUT_BUTTON_WHEEL_UP
                                      ? 1 : -1);
            virtio_input_send(vinput, &event);
        } else if (keymap_button[btn->button]) {
            event.type  = cpu_to_le16(EV_KEY);
            event.code  = cpu_to_le16(keymap_button[btn->button]);
            event.value = cpu_to_le32(btn->down ? 1 : 0);
            virtio_input_send(vinput, &event);
        } else {
            if (btn->down) {
                fprintf(stderr, "%s: unmapped button: %d [%s]\n", __func__,
                        btn->button,
                        InputButton_str(btn->button));
            }
        }
        break;
    case INPUT_EVENT_KIND_REL:
        move = evt->u.rel.data;
        event.type  = cpu_to_le16(EV_REL);
        event.code  = cpu_to_le16(axismap_rel[move->axis]);
        event.value = cpu_to_le32(move->value);
        virtio_input_send(vinput, &event);
        break;
    case INPUT_EVENT_KIND_ABS:
        move = evt->u.abs.data;
        event.type  = cpu_to_le16(EV_ABS);
        event.code  = cpu_to_le16(axismap_abs[move->axis]);
        event.value = cpu_to_le32(move->value);
        virtio_input_send(vinput, &event);
        break;
    default:
        /* keep gcc happy */
        break;
    }
}

static void virtio_input_handle_sync(DeviceState *dev)
{
    VirtIOInput *vinput = VIRTIO_INPUT(dev);
    virtio_input_event event = {
        .type  = cpu_to_le16(EV_SYN),
        .code  = cpu_to_le16(SYN_REPORT),
        .value = 0,
    };

    virtio_input_send(vinput, &event);
}

static void virtio_input_hid_realize(DeviceState *dev, Error **errp)
{
    VirtIOInputHID *vhid = VIRTIO_INPUT_HID(dev);

    vhid->hs = qemu_input_handler_register(dev, vhid->handler);
    if (vhid->display && vhid->hs) {
        qemu_input_handler_bind(vhid->hs, vhid->display, vhid->head, NULL);
    }
}

static void virtio_input_hid_unrealize(DeviceState *dev, Error **errp)
{
    VirtIOInputHID *vhid = VIRTIO_INPUT_HID(dev);
    qemu_input_handler_unregister(vhid->hs);
}

static void virtio_input_hid_change_active(VirtIOInput *vinput)
{
    VirtIOInputHID *vhid = VIRTIO_INPUT_HID(vinput);

    if (vinput->active) {
        qemu_input_handler_activate(vhid->hs);
    } else {
        qemu_input_handler_deactivate(vhid->hs);
    }
}

static void virtio_input_hid_handle_status(VirtIOInput *vinput,
                                           virtio_input_event *event)
{
    VirtIOInputHID *vhid = VIRTIO_INPUT_HID(vinput);
    int ledbit = 0;

    switch (le16_to_cpu(event->type)) {
    case EV_LED:
        if (event->code == LED_NUML) {
            ledbit = QEMU_NUM_LOCK_LED;
        } else if (event->code == LED_CAPSL) {
            ledbit = QEMU_CAPS_LOCK_LED;
        } else if (event->code == LED_SCROLLL) {
            ledbit = QEMU_SCROLL_LOCK_LED;
        }
        if (event->value) {
            vhid->ledstate |= ledbit;
        } else {
            vhid->ledstate &= ~ledbit;
        }
        kbd_put_ledstate(vhid->ledstate);
        break;
    default:
        fprintf(stderr, "%s: unknown type %d\n", __func__,
                le16_to_cpu(event->type));
        break;
    }
}

static Property virtio_input_hid_properties[] = {
    DEFINE_PROP_STRING("display", VirtIOInputHID, display),
    DEFINE_PROP_UINT32("head", VirtIOInputHID, head, 0),
    DEFINE_PROP_END_OF_LIST(),
};

static void virtio_input_hid_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    VirtIOInputClass *vic = VIRTIO_INPUT_CLASS(klass);

    device_class_set_props(dc, virtio_input_hid_properties);
    vic->realize       = virtio_input_hid_realize;
    vic->unrealize     = virtio_input_hid_unrealize;
    vic->change_active = virtio_input_hid_change_active;
    vic->handle_status = virtio_input_hid_handle_status;
}

static const TypeInfo virtio_input_hid_info = {
    .name          = TYPE_VIRTIO_INPUT_HID,
    .parent        = TYPE_VIRTIO_INPUT,
    .instance_size = sizeof(VirtIOInputHID),
    .class_init    = virtio_input_hid_class_init,
    .abstract      = true,
};

/* ----------------------------------------------------------------- */

static QemuInputHandler virtio_keyboard_handler = {
    .name  = VIRTIO_ID_NAME_KEYBOARD,
    .mask  = INPUT_EVENT_MASK_KEY,
    .event = virtio_input_handle_event,
    .sync  = virtio_input_handle_sync,
};

static struct virtio_input_config virtio_keyboard_config[] = {
    {
        .select    = VIRTIO_INPUT_CFG_ID_NAME,
        .size      = sizeof(VIRTIO_ID_NAME_KEYBOARD),
        .u.string  = VIRTIO_ID_NAME_KEYBOARD,
    },{
        .select    = VIRTIO_INPUT_CFG_ID_DEVIDS,
        .size      = sizeof(struct virtio_input_devids),
        .u.ids     = {
            .bustype = const_le16(BUS_VIRTUAL),
            .vendor  = const_le16(0x0627), /* same we use for usb hid devices */
            .product = const_le16(0x0001),
            .version = const_le16(0x0001),
        },
    },{
        .select    = VIRTIO_INPUT_CFG_EV_BITS,
        .subsel    = EV_REP,
        .size      = 1,
    },{
        .select    = VIRTIO_INPUT_CFG_EV_BITS,
        .subsel    = EV_LED,
        .size      = 1,
        .u.bitmap  = {
            (1 << LED_NUML) | (1 << LED_CAPSL) | (1 << LED_SCROLLL),
        },
    },
    { /* end of list */ },
};

static void virtio_keyboard_init(Object *obj)
{
    VirtIOInputHID *vhid = VIRTIO_INPUT_HID(obj);
    VirtIOInput *vinput = VIRTIO_INPUT(obj);

    vhid->handler = &virtio_keyboard_handler;
    virtio_input_init_config(vinput, virtio_keyboard_config);
    virtio_input_key_config(vinput, qemu_input_map_qcode_to_linux,
                            qemu_input_map_qcode_to_linux_len);
}

static const TypeInfo virtio_keyboard_info = {
    .name          = TYPE_VIRTIO_KEYBOARD,
    .parent        = TYPE_VIRTIO_INPUT_HID,
    .instance_size = sizeof(VirtIOInputHID),
    .instance_init = virtio_keyboard_init,
};

/* ----------------------------------------------------------------- */

static QemuInputHandler virtio_mouse_handler = {
    .name  = VIRTIO_ID_NAME_MOUSE,
    .mask  = INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_REL,
    .event = virtio_input_handle_event,
    .sync  = virtio_input_handle_sync,
};

static struct virtio_input_config virtio_mouse_config_v1[] = {
    {
        .select    = VIRTIO_INPUT_CFG_ID_NAME,
        .size      = sizeof(VIRTIO_ID_NAME_MOUSE),
        .u.string  = VIRTIO_ID_NAME_MOUSE,
    },{
        .select    = VIRTIO_INPUT_CFG_ID_DEVIDS,
        .size      = sizeof(struct virtio_input_devids),
        .u.ids     = {
            .bustype = const_le16(BUS_VIRTUAL),
            .vendor  = const_le16(0x0627), /* same we use for usb hid devices */
            .product = const_le16(0x0002),
            .version = const_le16(0x0001),
        },
    },{
        .select    = VIRTIO_INPUT_CFG_EV_BITS,
        .subsel    = EV_REL,
        .size      = 1,
        .u.bitmap  = {
            (1 << REL_X) | (1 << REL_Y),
        },
    },
    { /* end of list */ },
};

static struct virtio_input_config virtio_mouse_config_v2[] = {
    {
        .select    = VIRTIO_INPUT_CFG_ID_NAME,
        .size      = sizeof(VIRTIO_ID_NAME_MOUSE),
        .u.string  = VIRTIO_ID_NAME_MOUSE,
    },{
        .select    = VIRTIO_INPUT_CFG_ID_DEVIDS,
        .size      = sizeof(struct virtio_input_devids),
        .u.ids     = {
            .bustype = const_le16(BUS_VIRTUAL),
            .vendor  = const_le16(0x0627), /* same we use for usb hid devices */
            .product = const_le16(0x0002),
            .version = const_le16(0x0002),
        },
    },{
        .select    = VIRTIO_INPUT_CFG_EV_BITS,
        .subsel    = EV_REL,
        .size      = 2,
        .u.bitmap  = {
            (1 << REL_X) | (1 << REL_Y),
            (1 << (REL_WHEEL - 8))
        },
    },
    { /* end of list */ },
};

static Property virtio_mouse_properties[] = {
    DEFINE_PROP_BOOL("wheel-axis", VirtIOInputHID, wheel_axis, true),
    DEFINE_PROP_END_OF_LIST(),
};

static void virtio_mouse_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);

    device_class_set_props(dc, virtio_mouse_properties);
}

static void virtio_mouse_init(Object *obj)
{
    VirtIOInputHID *vhid = VIRTIO_INPUT_HID(obj);
    VirtIOInput *vinput = VIRTIO_INPUT(obj);

    vhid->handler = &virtio_mouse_handler;
    virtio_input_init_config(vinput, vhid->wheel_axis
                             ? virtio_mouse_config_v2
                             : virtio_mouse_config_v1);
    virtio_input_key_config(vinput, keymap_button,
                            ARRAY_SIZE(keymap_button));
}

static const TypeInfo virtio_mouse_info = {
    .name          = TYPE_VIRTIO_MOUSE,
    .parent        = TYPE_VIRTIO_INPUT_HID,
    .instance_size = sizeof(VirtIOInputHID),
    .instance_init = virtio_mouse_init,
    .class_init    = virtio_mouse_class_init,
};

/* ----------------------------------------------------------------- */

static QemuInputHandler virtio_tablet_handler = {
    .name  = VIRTIO_ID_NAME_TABLET,
    .mask  = INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_ABS,
    .event = virtio_input_handle_event,
    .sync  = virtio_input_handle_sync,
};

static struct virtio_input_config virtio_tablet_config_v1[] = {
    {
        .select    = VIRTIO_INPUT_CFG_ID_NAME,
        .size      = sizeof(VIRTIO_ID_NAME_TABLET),
        .u.string  = VIRTIO_ID_NAME_TABLET,
    },{
        .select    = VIRTIO_INPUT_CFG_ID_DEVIDS,
        .size      = sizeof(struct virtio_input_devids),
        .u.ids     = {
            .bustype = const_le16(BUS_VIRTUAL),
            .vendor  = const_le16(0x0627), /* same we use for usb hid devices */
            .product = const_le16(0x0003),
            .version = const_le16(0x0001),
        },
    },{
        .select    = VIRTIO_INPUT_CFG_EV_BITS,
        .subsel    = EV_ABS,
        .size      = 1,
        .u.bitmap  = {
            (1 << ABS_X) | (1 << ABS_Y),
        },
    },{
        .select    = VIRTIO_INPUT_CFG_ABS_INFO,
        .subsel    = ABS_X,
        .size      = sizeof(virtio_input_absinfo),
        .u.abs.min = const_le32(INPUT_EVENT_ABS_MIN),
        .u.abs.max = const_le32(INPUT_EVENT_ABS_MAX),
    },{
        .select    = VIRTIO_INPUT_CFG_ABS_INFO,
        .subsel    = ABS_Y,
        .size      = sizeof(virtio_input_absinfo),
        .u.abs.min = const_le32(INPUT_EVENT_ABS_MIN),
        .u.abs.max = const_le32(INPUT_EVENT_ABS_MAX),
    },
    { /* end of list */ },
};

static struct virtio_input_config virtio_tablet_config_v2[] = {
    {
        .select    = VIRTIO_INPUT_CFG_ID_NAME,
        .size      = sizeof(VIRTIO_ID_NAME_TABLET),
        .u.string  = VIRTIO_ID_NAME_TABLET,
    },{
        .select    = VIRTIO_INPUT_CFG_ID_DEVIDS,
        .size      = sizeof(struct virtio_input_devids),
        .u.ids     = {
            .bustype = const_le16(BUS_VIRTUAL),
            .vendor  = const_le16(0x0627), /* same we use for usb hid devices */
            .product = const_le16(0x0003),
            .version = const_le16(0x0002),
        },
    },{
        .select    = VIRTIO_INPUT_CFG_EV_BITS,
        .subsel    = EV_ABS,
        .size      = 1,
        .u.bitmap  = {
            (1 << ABS_X) | (1 << ABS_Y),
        },
    },{
        .select    = VIRTIO_INPUT_CFG_EV_BITS,
        .subsel    = EV_REL,
        .size      = 2,
        .u.bitmap  = {
            0,
            (1 << (REL_WHEEL - 8))
        },
    },{
        .select    = VIRTIO_INPUT_CFG_ABS_INFO,
        .subsel    = ABS_X,
        .size      = sizeof(virtio_input_absinfo),
        .u.abs.min = const_le32(INPUT_EVENT_ABS_MIN),
        .u.abs.max = const_le32(INPUT_EVENT_ABS_MAX),
    },{
        .select    = VIRTIO_INPUT_CFG_ABS_INFO,
        .subsel    = ABS_Y,
        .size      = sizeof(virtio_input_absinfo),
        .u.abs.min = const_le32(INPUT_EVENT_ABS_MIN),
        .u.abs.max = const_le32(INPUT_EVENT_ABS_MAX),
    },
    { /* end of list */ },
};

static Property virtio_tablet_properties[] = {
    DEFINE_PROP_BOOL("wheel-axis", VirtIOInputHID, wheel_axis, true),
    DEFINE_PROP_END_OF_LIST(),
};

static void virtio_tablet_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);

    device_class_set_props(dc, virtio_tablet_properties);
}

static void virtio_tablet_init(Object *obj)
{
    VirtIOInputHID *vhid = VIRTIO_INPUT_HID(obj);
    VirtIOInput *vinput = VIRTIO_INPUT(obj);

    vhid->handler = &virtio_tablet_handler;
    virtio_input_init_config(vinput, vhid->wheel_axis
                             ? virtio_tablet_config_v2
                             : virtio_tablet_config_v1);
    virtio_input_key_config(vinput, keymap_button,
                            ARRAY_SIZE(keymap_button));
}

static const TypeInfo virtio_tablet_info = {
    .name          = TYPE_VIRTIO_TABLET,
    .parent        = TYPE_VIRTIO_INPUT_HID,
    .instance_size = sizeof(VirtIOInputHID),
    .instance_init = virtio_tablet_init,
    .class_init    = virtio_tablet_class_init,
};

/* ----------------------------------------------------------------- */

static void virtio_register_types(void)
{
    type_register_static(&virtio_input_hid_info);
    type_register_static(&virtio_keyboard_info);
    type_register_static(&virtio_mouse_info);
    type_register_static(&virtio_tablet_info);
}

type_init(virtio_register_types)
