diff options
author | Gerd Hoffmann <kraxel@redhat.com> | 2011-07-15 14:37:15 +0200 |
---|---|---|
committer | Gerd Hoffmann <kraxel@redhat.com> | 2011-08-04 15:51:51 +0200 |
commit | 8bde6805412a2808009a84f1ce5f47b88b0352d0 (patch) | |
tree | 5fef3d64780cd9426ba32e26fda1f31fe1de145f /hw/usb-hid.c | |
parent | 0d878eec1eddcf01f07c38c6040ea91184139299 (diff) | |
download | qemu-8bde6805412a2808009a84f1ce5f47b88b0352d0.zip qemu-8bde6805412a2808009a84f1ce5f47b88b0352d0.tar.gz qemu-8bde6805412a2808009a84f1ce5f47b88b0352d0.tar.bz2 |
usb-hid: add event callback
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>
Diffstat (limited to 'hw/usb-hid.c')
-rw-r--r-- | hw/usb-hid.c | 106 |
1 files changed, 63 insertions, 43 deletions
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, |