/*
 * 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;
} 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;
}

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

    s->x = x;
    s->y = y;
    s->dz += dz;
    s->buttons_state = buttons_state;
}

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 |= 0x02;
    if (s->buttons_state & MOUSE_EVENT_MBUTTON)
        b |= 0x04;

    if (len < 7)
        return 0;

    buf[0] = s->mode;
    buf[5] = 0x00;
    if (b) {
        buf[1] = s->x & 0xff;
        buf[2] = s->x >> 8;
        buf[3] = s->y & 0xff;
        buf[4] = s->y >> 8;
        buf[6] = 0;
    } else {
        buf[1] = 0;
        buf[2] = 0;
        buf[3] = 0;
        buf[4] = 0;
        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_SET_IDLE:
        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->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);
    qemu_free(s);
}

USBDevice *usb_wacom_init(void)
{
    USBWacomState *s;

    s = qemu_mallocz(sizeof(USBWacomState));
    s->dev.speed = USB_SPEED_FULL;
    s->dev.handle_packet = usb_generic_handle_packet;

    s->dev.handle_reset = usb_wacom_handle_reset;
    s->dev.handle_control = usb_wacom_handle_control;
    s->dev.handle_data = usb_wacom_handle_data;
    s->dev.handle_destroy = usb_wacom_handle_destroy;

    pstrcpy(s->dev.devname, sizeof(s->dev.devname),
            "QEMU PenPartner Tablet");

    return (USBDevice *) s;
}
