Patchwork [12/16] usb-hid: add event callback

login
register
mail settings
Submitter Gerd Hoffmann
Date Aug. 4, 2011, 3:10 p.m.
Message ID <1312470626-25872-13-git-send-email-kraxel@redhat.com>
Download mbox | patch
Permalink /patch/108513/
State New
Headers show

Comments

Gerd Hoffmann - Aug. 4, 2011, 3:10 p.m.
Add callback for event notification, which allows to un-usbify more
functions.  Also split separate hid_* functions for reset and release.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/usb-hid.c |  106 ++++++++++++++++++++++++++++++++++-----------------------
 1 files changed, 63 insertions(+), 43 deletions(-)

Patch

diff --git a/hw/usb-hid.c b/hw/usb-hid.c
index f5d6c61..870cc66 100644
--- a/hw/usb-hid.c
+++ b/hw/usb-hid.c
@@ -54,6 +54,9 @@  typedef struct HIDPointerEvent {
 #define QUEUE_MASK      (QUEUE_LENGTH-1u)
 #define QUEUE_INCR(v)   ((v)++, (v) &= QUEUE_MASK)
 
+typedef struct HIDState HIDState;
+typedef void (*HIDEventFunc)(HIDState *s);
+
 typedef struct HIDMouseState {
     HIDPointerEvent queue[QUEUE_LENGTH];
     int mouse_grabbed;
@@ -68,7 +71,7 @@  typedef struct HIDKeyboardState {
     int32_t keys;
 } HIDKeyboardState;
 
-typedef struct HIDState {
+struct HIDState {
     union {
         HIDMouseState ptr;
         HIDKeyboardState kbd;
@@ -76,7 +79,8 @@  typedef struct HIDState {
     uint32_t head; /* index into circular queue */
     uint32_t n;
     int kind;
-} HIDState;
+    HIDEventFunc event;
+};
 
 typedef struct USBHIDState {
     USBDevice dev;
@@ -440,14 +444,17 @@  static const uint8_t usb_hid_usage_keys[0x100] = {
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 };
 
-static void usb_hid_changed(USBHIDState *hs)
+static void usb_hid_changed(HIDState *hs)
 {
-    hs->changed = 1;
+    USBHIDState *us = container_of(hs, USBHIDState, hid);
 
-    if (hs->datain)
-        hs->datain(hs->datain_opaque);
+    us->changed = 1;
+
+    if (us->datain) {
+        us->datain(us->datain_opaque);
+    }
 
-    usb_wakeup(&hs->dev);
+    usb_wakeup(&us->dev);
 }
 
 static void hid_pointer_event_clear(HIDPointerEvent *e, int buttons)
@@ -473,11 +480,10 @@  static void hid_pointer_event_combine(HIDPointerEvent *e, int xyrel,
     e->dz += z1;
 }
 
-static void usb_pointer_event(void *opaque,
+static void hid_pointer_event(void *opaque,
                               int x1, int y1, int z1, int buttons_state)
 {
-    USBHIDState *us = opaque;
-    HIDState *hs = &us->hid;
+    HIDState *hs = opaque;
     unsigned use_slot = (hs->head + hs->n - 1) & QUEUE_MASK;
     unsigned previous_slot = (use_slot - 1) & QUEUE_MASK;
 
@@ -501,13 +507,12 @@  static void usb_pointer_event(void *opaque,
     hid_pointer_event_combine(&hs->ptr.queue[use_slot],
                               hs->kind == HID_MOUSE,
                               x1, y1, z1);
-    usb_hid_changed(us);
+    hs->event(hs);
 }
 
-static void usb_keyboard_event(void *opaque, int keycode)
+static void hid_keyboard_event(void *opaque, int keycode)
 {
-    USBHIDState *us = opaque;
-    HIDState *hs = &us->hid;
+    HIDState *hs = opaque;
     int slot;
 
     if (hs->n == QUEUE_LENGTH) {
@@ -516,7 +521,7 @@  static void usb_keyboard_event(void *opaque, int keycode)
     }
     slot = (hs->head + hs->n) & QUEUE_MASK; hs->n++;
     hs->kbd.keycodes[slot] = keycode;
-    usb_hid_changed(us);
+    hs->event(hs);
 }
 
 static void hid_keyboard_process_keycode(HIDState *hs)
@@ -713,26 +718,29 @@  static int hid_keyboard_write(HIDState *hs, uint8_t *buf, int len)
     return 0;
 }
 
-static void usb_mouse_handle_reset(USBDevice *dev)
+static void hid_handle_reset(HIDState *hs)
 {
-    USBHIDState *us = DO_UPCAST(USBHIDState, dev, dev);
-
-    memset(us->hid.ptr.queue, 0, sizeof(us->hid.ptr.queue));
-    us->hid.head = 0;
-    us->hid.n = 0;
-    us->protocol = 1;
+    switch (hs->kind) {
+    case HID_KEYBOARD:
+        qemu_add_kbd_event_handler(hid_keyboard_event, hs);
+        memset(hs->kbd.keycodes, 0, sizeof(hs->kbd.keycodes));
+        memset(hs->kbd.key, 0, sizeof(hs->kbd.key));
+        hs->kbd.keys = 0;
+        break;
+    case HID_MOUSE:
+    case HID_TABLET:
+        memset(hs->ptr.queue, 0, sizeof(hs->ptr.queue));
+        break;
+    }
+    hs->head = 0;
+    hs->n = 0;
 }
 
-static void usb_keyboard_handle_reset(USBDevice *dev)
+static void usb_hid_handle_reset(USBDevice *dev)
 {
     USBHIDState *us = DO_UPCAST(USBHIDState, dev, dev);
 
-    qemu_add_kbd_event_handler(usb_keyboard_event, us);
-    memset(us->hid.kbd.keycodes, 0, sizeof(us->hid.kbd.keycodes));
-    us->hid.head = 0;
-    us->hid.n = 0;
-    memset(us->hid.kbd.key, 0, sizeof(us->hid.kbd.key));
-    us->hid.kbd.keys = 0;
+    hid_handle_reset(&us->hid);
     us->protocol = 1;
 }
 
@@ -866,34 +874,46 @@  static int usb_hid_handle_data(USBDevice *dev, USBPacket *p)
     return ret;
 }
 
-static void usb_hid_handle_destroy(USBDevice *dev)
+static void hid_free(HIDState *hs)
 {
-    USBHIDState *us = DO_UPCAST(USBHIDState, dev, dev);
-
-    switch (us->hid.kind) {
+    switch (hs->kind) {
     case HID_KEYBOARD:
         qemu_remove_kbd_event_handler();
         break;
-    default:
-        qemu_remove_mouse_event_handler(us->hid.ptr.eh_entry);
+    case HID_MOUSE:
+    case HID_TABLET:
+        qemu_remove_mouse_event_handler(hs->ptr.eh_entry);
+        break;
     }
 }
 
-static int usb_hid_initfn(USBDevice *dev, int kind)
+static void usb_hid_handle_destroy(USBDevice *dev)
 {
     USBHIDState *us = DO_UPCAST(USBHIDState, dev, dev);
-    HIDState *hs = &us->hid;
 
-    usb_desc_init(dev);
+    hid_free(&us->hid);
+}
+
+static void hid_init(HIDState *hs, int kind, HIDEventFunc event)
+{
     hs->kind = kind;
+    hs->event = event;
 
     if (hs->kind == HID_MOUSE) {
-        hs->ptr.eh_entry = qemu_add_mouse_event_handler(usb_pointer_event, us,
+        hs->ptr.eh_entry = qemu_add_mouse_event_handler(hid_pointer_event, hs,
                                                         0, "QEMU HID Mouse");
     } else if (hs->kind == HID_TABLET) {
-        hs->ptr.eh_entry = qemu_add_mouse_event_handler(usb_pointer_event, us,
+        hs->ptr.eh_entry = qemu_add_mouse_event_handler(hid_pointer_event, hs,
                                                         1, "QEMU HID Tablet");
     }
+}
+
+static int usb_hid_initfn(USBDevice *dev, int kind)
+{
+    USBHIDState *us = DO_UPCAST(USBHIDState, dev, dev);
+
+    usb_desc_init(dev);
+    hid_init(&us->hid, kind, usb_hid_changed);
 
     /* Force poll routine to be run and grab input the first time.  */
     us->changed = 1;
@@ -992,7 +1012,7 @@  static struct USBDeviceInfo hid_info[] = {
         .usb_desc       = &desc_tablet,
         .init           = usb_tablet_initfn,
         .handle_packet  = usb_generic_handle_packet,
-        .handle_reset   = usb_mouse_handle_reset,
+        .handle_reset   = usb_hid_handle_reset,
         .handle_control = usb_hid_handle_control,
         .handle_data    = usb_hid_handle_data,
         .handle_destroy = usb_hid_handle_destroy,
@@ -1005,7 +1025,7 @@  static struct USBDeviceInfo hid_info[] = {
         .usb_desc       = &desc_mouse,
         .init           = usb_mouse_initfn,
         .handle_packet  = usb_generic_handle_packet,
-        .handle_reset   = usb_mouse_handle_reset,
+        .handle_reset   = usb_hid_handle_reset,
         .handle_control = usb_hid_handle_control,
         .handle_data    = usb_hid_handle_data,
         .handle_destroy = usb_hid_handle_destroy,
@@ -1018,7 +1038,7 @@  static struct USBDeviceInfo hid_info[] = {
         .usb_desc       = &desc_keyboard,
         .init           = usb_keyboard_initfn,
         .handle_packet  = usb_generic_handle_packet,
-        .handle_reset   = usb_keyboard_handle_reset,
+        .handle_reset   = usb_hid_handle_reset,
         .handle_control = usb_hid_handle_control,
         .handle_data    = usb_hid_handle_data,
         .handle_destroy = usb_hid_handle_destroy,