/*
 * Wacom PenPartner USB tablet emulation.
 *
 * Copyright (c) 2006 Openedhand Ltd.
 * Author: Andrzej Zaborowski <balrog@zabor.org>
 *
 * Based on hw/usb-hid.c:
 * Copyright (c) 2005 Fabrice Bellard
 *
 * 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 "hw.h"
#include "console.h"
#include "usb.h"

/* Interface requests */
#define WACOM_GET_REPORT	0x2101
#define WACOM_SET_REPORT	0x2109

/* HID interface requests */
#define HID_GET_REPORT		0xa101
#define HID_GET_IDLE		0xa102
#define HID_GET_PROTOCOL	0xa103
#define HID_SET_IDLE		0x210a
#define HID_SET_PROTOCOL	0x210b

typedef struct USBWacomState {
    USBDevice dev;
    QEMUPutMouseEntry *eh_entry;
    int dx, dy, dz, buttons_state;
    int x, y;
    int mouse_grabbed;
    enum {
        WACOM_MODE_HID = 1,
        WACOM_MODE_WACOM = 2,
    } mode;
    uint8_t idle;
    int changed;
} USBWacomState;

static const uint8_t qemu_wacom_dev_descriptor[] = {
    0x12,	/*  u8 bLength; */
    0x01,	/*  u8 bDescriptorType; Device */
    0x10, 0x10,	/*  u16 bcdUSB; v1.10 */

    0x00,	/*  u8  bDeviceClass; */
    0x00,	/*  u8  bDeviceSubClass; */
    0x00,	/*  u8  bDeviceProtocol; [ low/full speeds only ] */
    0x08,	/*  u8  bMaxPacketSize0; 8 Bytes */

    0x6a, 0x05,	/*  u16 idVendor; */
    0x00, 0x00,	/*  u16 idProduct; */
    0x10, 0x42,	/*  u16 bcdDevice */

    0x01,	/*  u8  iManufacturer; */
    0x02,	/*  u8  iProduct; */
    0x00,	/*  u8  iSerialNumber; */
    0x01,	/*  u8  bNumConfigurations; */
};

static const uint8_t qemu_wacom_config_descriptor[] = {
    /* one configuration */
    0x09,	/*  u8  bLength; */
    0x02,	/*  u8  bDescriptorType; Configuration */
    0x22, 0x00,	/*  u16 wTotalLength; */
    0x01,	/*  u8  bNumInterfaces; (1) */
    0x01,	/*  u8  bConfigurationValue; */
    0x00,	/*  u8  iConfiguration; */
    0x80,	/*  u8  bmAttributes;
				 Bit 7: must be set,
				     6: Self-powered,
				     5: Remote wakeup,
				     4..0: resvd */
    40,		/*  u8  MaxPower; */

    /* one interface */
    0x09,	/*  u8  if_bLength; */
    0x04,	/*  u8  if_bDescriptorType; Interface */
    0x00,	/*  u8  if_bInterfaceNumber; */
    0x00,	/*  u8  if_bAlternateSetting; */
    0x01,	/*  u8  if_bNumEndpoints; */
    0x03,	/*  u8  if_bInterfaceClass; HID */
    0x01,	/*  u8  if_bInterfaceSubClass; Boot */
    0x02,	/*  u8  if_bInterfaceProtocol; [usb1.1 or single tt] */
    0x00,	/*  u8  if_iInterface; */

    /* HID descriptor */
    0x09,	/*  u8  bLength; */
    0x21,	/*  u8  bDescriptorType; */
    0x01, 0x10,	/*  u16 HID_class */
    0x00,	/*  u8  country_code */
    0x01,	/*  u8  num_descriptors */
    0x22,	/*  u8  type; Report */
    0x6e, 0x00,	/*  u16 len */

    /* one endpoint (status change endpoint) */
    0x07,	/*  u8  ep_bLength; */
    0x05,	/*  u8  ep_bDescriptorType; Endpoint */
    0x81,	/*  u8  ep_bEndpointAddress; IN Endpoint 1 */
    0x03,	/*  u8  ep_bmAttributes; Interrupt */
    0x08, 0x00,	/*  u16 ep_wMaxPacketSize; */
    0x0a,	/*  u8  ep_bInterval; */
};

static void usb_mouse_event(void *opaque,
                            int dx1, int dy1, int dz1, int buttons_state)
{
    USBWacomState *s = opaque;

    s->dx += dx1;
    s->dy += dy1;
    s->dz += dz1;
    s->buttons_state = buttons_state;
    s->changed = 1;
}

static void usb_wacom_event(void *opaque,
                            int x, int y, int dz, int buttons_state)
{
    USBWacomState *s = opaque;

    /* scale to Penpartner resolution */
    s->x = (x * 5040 / 0x7FFF);
    s->y = (y * 3780 / 0x7FFF);
    s->dz += dz;
    s->buttons_state = buttons_state;
    s->changed = 1;
}

static inline int int_clamp(int val, int vmin, int vmax)
{
    if (val < vmin)
        return vmin;
    else if (val > vmax)
        return vmax;
    else
        return val;
}

static int usb_mouse_poll(USBWacomState *s, uint8_t *buf, int len)
{
    int dx, dy, dz, b, l;

    if (!s->mouse_grabbed) {
        s->eh_entry = qemu_add_mouse_event_handler(usb_mouse_event, s, 0,
                        "QEMU PenPartner tablet");
        s->mouse_grabbed = 1;
    }

    dx = int_clamp(s->dx, -128, 127);
    dy = int_clamp(s->dy, -128, 127);
    dz = int_clamp(s->dz, -128, 127);

    s->dx -= dx;
    s->dy -= dy;
    s->dz -= dz;

    b = 0;
    if (s->buttons_state & MOUSE_EVENT_LBUTTON)
        b |= 0x01;
    if (s->buttons_state & MOUSE_EVENT_RBUTTON)
        b |= 0x02;
    if (s->buttons_state & MOUSE_EVENT_MBUTTON)
        b |= 0x04;

    buf[0] = b;
    buf[1] = dx;
    buf[2] = dy;
    l = 3;
    if (len >= 4) {
        buf[3] = dz;
        l = 4;
    }
    return l;
}

static int usb_wacom_poll(USBWacomState *s, uint8_t *buf, int len)
{
    int b;

    if (!s->mouse_grabbed) {
        s->eh_entry = qemu_add_mouse_event_handler(usb_wacom_event, s, 1,
                        "QEMU PenPartner tablet");
        s->mouse_grabbed = 1;
    }

    b = 0;
    if (s->buttons_state & MOUSE_EVENT_LBUTTON)
        b |= 0x01;
    if (s->buttons_state & MOUSE_EVENT_RBUTTON)
        b |= 0x40;
    if (s->buttons_state & MOUSE_EVENT_MBUTTON)
        b |= 0x20; /* eraser */

    if (len < 7)
        return 0;

    buf[0] = s->mode;
    buf[5] = 0x00 | (b & 0xf0);
    buf[1] = s->x & 0xff;
    buf[2] = s->x >> 8;
    buf[3] = s->y & 0xff;
    buf[4] = s->y >> 8;
    if (b & 0x3f) {
        buf[6] = 0;
    } else {
        buf[6] = (unsigned char) -127;
    }

    return 7;
}

static void usb_wacom_handle_reset(USBDevice *dev)
{
    USBWacomState *s = (USBWacomState *) dev;

    s->dx = 0;
    s->dy = 0;
    s->dz = 0;
    s->x = 0;
    s->y = 0;
    s->buttons_state = 0;
    s->mode = WACOM_MODE_HID;
}

static int usb_wacom_handle_control(USBDevice *dev, int request, int value,
                                    int index, int length, uint8_t *data)
{
    USBWacomState *s = (USBWacomState *) dev;
    int ret = 0;

    switch (request) {
    case DeviceRequest | USB_REQ_GET_STATUS:
        data[0] = (1 << USB_DEVICE_SELF_POWERED) |
            (dev->remote_wakeup << USB_DEVICE_REMOTE_WAKEUP);
        data[1] = 0x00;
        ret = 2;
        break;
    case DeviceOutRequest | USB_REQ_CLEAR_FEATURE:
        if (value == USB_DEVICE_REMOTE_WAKEUP) {
            dev->remote_wakeup = 0;
        } else {
            goto fail;
        }
        ret = 0;
        break;
    case DeviceOutRequest | USB_REQ_SET_FEATURE:
        if (value == USB_DEVICE_REMOTE_WAKEUP) {
            dev->remote_wakeup = 1;
        } else {
            goto fail;
        }
        ret = 0;
        break;
    case DeviceOutRequest | USB_REQ_SET_ADDRESS:
        dev->addr = value;
        ret = 0;
        break;
    case DeviceRequest | USB_REQ_GET_DESCRIPTOR:
        switch (value >> 8) {
        case USB_DT_DEVICE:
            memcpy(data, qemu_wacom_dev_descriptor,
                   sizeof(qemu_wacom_dev_descriptor));
            ret = sizeof(qemu_wacom_dev_descriptor);
            break;
        case USB_DT_CONFIG:
       	    memcpy(data, qemu_wacom_config_descriptor,
                   sizeof(qemu_wacom_config_descriptor));
            ret = sizeof(qemu_wacom_config_descriptor);
            break;
        case USB_DT_STRING:
            switch (value & 0xff) {
            case 0:
                /* language ids */
                data[0] = 4;
                data[1] = 3;
                data[2] = 0x09;
                data[3] = 0x04;
                ret = 4;
                break;
            case 1:
                /* serial number */
                ret = set_usb_string(data, "1");
                break;
            case 2:
		ret = set_usb_string(data, "Wacom PenPartner");
                break;
            case 3:
                /* vendor description */
                ret = set_usb_string(data, "QEMU " QEMU_VERSION);
                break;
            case 4:
                ret = set_usb_string(data, "Wacom Tablet");
                break;
            case 5:
                ret = set_usb_string(data, "Endpoint1 Interrupt Pipe");
                break;
            default:
                goto fail;
            }
            break;
        default:
            goto fail;
        }
        break;
    case DeviceRequest | USB_REQ_GET_CONFIGURATION:
        data[0] = 1;
        ret = 1;
        break;
    case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
        ret = 0;
        break;
    case DeviceRequest | USB_REQ_GET_INTERFACE:
        data[0] = 0;
        ret = 1;
        break;
    case DeviceOutRequest | USB_REQ_SET_INTERFACE:
        ret = 0;
        break;
    case WACOM_SET_REPORT:
        qemu_remove_mouse_event_handler(s->eh_entry);
        s->mouse_grabbed = 0;
        s->mode = data[0];
        ret = 0;
        break;
    case WACOM_GET_REPORT:
        data[0] = 0;
        data[1] = s->mode;
        ret = 2;
        break;
    /* USB HID requests */
    case HID_GET_REPORT:
        if (s->mode == WACOM_MODE_HID)
            ret = usb_mouse_poll(s, data, length);
        else if (s->mode == WACOM_MODE_WACOM)
            ret = usb_wacom_poll(s, data, length);
        break;
    case HID_GET_IDLE:
        ret = 1;
        data[0] = s->idle;
        break;
    case HID_SET_IDLE:
        s->idle = (uint8_t) (value >> 8);
        ret = 0;
        break;
    default:
    fail:
        ret = USB_RET_STALL;
        break;
    }
    return ret;
}

static int usb_wacom_handle_data(USBDevice *dev, USBPacket *p)
{
    USBWacomState *s = (USBWacomState *) dev;
    int ret = 0;

    switch (p->pid) {
    case USB_TOKEN_IN:
        if (p->devep == 1) {
            if (!(s->changed || s->idle))
                return USB_RET_NAK;
            s->changed = 0;
            if (s->mode == WACOM_MODE_HID)
                ret = usb_mouse_poll(s, p->data, p->len);
            else if (s->mode == WACOM_MODE_WACOM)
                ret = usb_wacom_poll(s, p->data, p->len);
            break;
        }
        /* Fall through.  */
    case USB_TOKEN_OUT:
    default:
        ret = USB_RET_STALL;
        break;
    }
    return ret;
}

static void usb_wacom_handle_destroy(USBDevice *dev)
{
    USBWacomState *s = (USBWacomState *) dev;

    qemu_remove_mouse_event_handler(s->eh_entry);
}

static int usb_wacom_initfn(USBDevice *dev)
{
    USBWacomState *s = DO_UPCAST(USBWacomState, dev, dev);
    s->dev.speed = USB_SPEED_FULL;
    s->changed = 1;
    return 0;
}

static struct USBDeviceInfo wacom_info = {
    .qdev.name      = "QEMU PenPartner Tablet",
    .qdev.alias     = "wacom-tablet",
    .usbdevice_name = "wacom-tablet",
    .qdev.size      = sizeof(USBWacomState),
    .init           = usb_wacom_initfn,
    .handle_packet  = usb_generic_handle_packet,
    .handle_reset   = usb_wacom_handle_reset,
    .handle_control = usb_wacom_handle_control,
    .handle_data    = usb_wacom_handle_data,
    .handle_destroy = usb_wacom_handle_destroy,
};

static void usb_wacom_register_devices(void)
{
    usb_qdev_register(&wacom_info);
}
device_init(usb_wacom_register_devices)
