/*
 * 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 "hw/qdev.h"
#include "hw/virtio/virtio.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);

    dc->props          = 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);

    dc->props  = 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);

    dc->props  = 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)
