summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--hw/usb-wacom.c38
1 files changed, 24 insertions, 14 deletions
diff --git a/hw/usb-wacom.c b/hw/usb-wacom.c
index 3ea72411a1..fa97db2345 100644
--- a/hw/usb-wacom.c
+++ b/hw/usb-wacom.c
@@ -50,6 +50,8 @@ typedef struct USBWacomState {
         WACOM_MODE_HID = 1,
         WACOM_MODE_WACOM = 2,
     } mode;
+    uint8_t idle;
+    int changed;
 } USBWacomState;
 
 static const uint8_t qemu_wacom_dev_descriptor[] = {
@@ -125,6 +127,7 @@ static void usb_mouse_event(void *opaque,
     s->dy += dy1;
     s->dz += dz1;
     s->buttons_state = buttons_state;
+    s->changed = 1;
 }
 
 static void usb_wacom_event(void *opaque,
@@ -132,10 +135,12 @@ static void usb_wacom_event(void *opaque,
 {
     USBWacomState *s = opaque;
 
-    s->x = x;
-    s->y = y;
+    /* 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)
@@ -199,26 +204,22 @@ static int usb_wacom_poll(USBWacomState *s, uint8_t *buf, int len)
     if (s->buttons_state & MOUSE_EVENT_LBUTTON)
         b |= 0x01;
     if (s->buttons_state & MOUSE_EVENT_RBUTTON)
-        b |= 0x02;
+        b |= 0x40;
     if (s->buttons_state & MOUSE_EVENT_MBUTTON)
-        b |= 0x04;
+        b |= 0x20; /* eraser */
 
     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[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[1] = 0;
-        buf[2] = 0;
-        buf[3] = 0;
-        buf[4] = 0;
         buf[6] = (unsigned char) -127;
     }
 
@@ -350,7 +351,12 @@ static int usb_wacom_handle_control(USBDevice *dev, int request, int value,
         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:
@@ -369,6 +375,9 @@ static int usb_wacom_handle_data(USBDevice *dev, USBPacket *p)
     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)
@@ -395,6 +404,7 @@ 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;
 }