qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH][RFC] USB Wacom fixes


From: François Revol
Subject: [Qemu-devel] [PATCH][RFC] USB Wacom fixes
Date: Fri, 27 Mar 2009 18:43:44 +0100 CET

Following my previous mail about usb-wacom which didn't received many
comments...

I added code to handle IDLE mode instead of always accepting polling
requests from the guest, with some help from Paul Brook on IRC.
I mostly just copied the missing part from the hid code.
As Paul said, usb-wacom.c mostly copies usb-hid.c appart from the wacom
specific mode and should probably be merged later on.

But at least with this fix I get correct coordinates and buttons, and
guest cpu usage dropped from 50% to unnoticeable when not moving the
mouse.

Btw, about the scaling:
<hpoussin> mmu_man: instead of doing some scale work for x and y,
correct solution is to change the hid descriptor
<mmu_man> hpoussin nope
<mmu_man> - the Haiku driver disregards the HID desc
<mmu_man> - the linux one too IIRC
<mmu_man> - the HID desc for some wacom tablets, including the
penpartner is known to be buggy


François.

Index: hw/usb-wacom.c
===================================================================
--- hw/usb-wacom.c      (révision 6883)
+++ hw/usb-wacom.c      (copie de travail)
@@ -50,6 +50,8 @@
         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 @@
     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 @@
 {
     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 @@
     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 @@
         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 @@
     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)
@@ -404,6 +413,7 @@
     s->dev.handle_control = usb_wacom_handle_control;
     s->dev.handle_data = usb_wacom_handle_data;
     s->dev.handle_destroy = usb_wacom_handle_destroy;
+    s->changed = 1;
 
     pstrcpy(s->dev.devname, sizeof(s->dev.devname),
             "QEMU PenPartner Tablet");

reply via email to

[Prev in Thread] Current Thread [Next in Thread]