aboutsummaryrefslogtreecommitdiffstats
path: root/hw/usb-hid.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/usb-hid.c')
-rw-r--r--hw/usb-hid.c52
1 files changed, 36 insertions, 16 deletions
diff --git a/hw/usb-hid.c b/hw/usb-hid.c
index 406c9ab..c850a91 100644
--- a/hw/usb-hid.c
+++ b/hw/usb-hid.c
@@ -65,8 +65,10 @@ typedef struct USBHIDState {
};
int kind;
int protocol;
- int idle;
+ uint8_t idle;
int changed;
+ void *datain_opaque;
+ void (*datain)(void *);
} USBHIDState;
/* mostly the same values as the Bochs USB Mouse device */
@@ -402,6 +404,14 @@ static const uint8_t usb_hid_usage_keys[0x100] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
+static void usb_hid_changed(USBHIDState *hs)
+{
+ hs->changed = 1;
+
+ if (hs->datain)
+ hs->datain(hs->datain_opaque);
+}
+
static void usb_mouse_event(void *opaque,
int dx1, int dy1, int dz1, int buttons_state)
{
@@ -412,7 +422,8 @@ static void usb_mouse_event(void *opaque,
s->dy += dy1;
s->dz += dz1;
s->buttons_state = buttons_state;
- hs->changed = 1;
+
+ usb_hid_changed(hs);
}
static void usb_tablet_event(void *opaque,
@@ -425,7 +436,8 @@ static void usb_tablet_event(void *opaque,
s->y = y;
s->dz += dz;
s->buttons_state = buttons_state;
- hs->changed = 1;
+
+ usb_hid_changed(hs);
}
static void usb_keyboard_event(void *opaque, int keycode)
@@ -439,8 +451,6 @@ static void usb_keyboard_event(void *opaque, int keycode)
hid_code = usb_hid_usage_keys[key | ((s->modifiers >> 1) & (1 << 7))];
s->modifiers &= ~(1 << 8);
- hs->changed = 1;
-
switch (hid_code) {
case 0x00:
return;
@@ -465,15 +475,23 @@ static void usb_keyboard_event(void *opaque, int keycode)
if (s->key[i] == hid_code) {
s->key[i] = s->key[-- s->keys];
s->key[s->keys] = 0x00;
- return;
+ usb_hid_changed(hs);
+ break;
}
+ if (i < 0)
+ return;
} else {
for (i = s->keys - 1; i >= 0; i --)
if (s->key[i] == hid_code)
- return;
- if (s->keys < sizeof(s->key))
- s->key[s->keys ++] = hid_code;
+ break;
+ if (i < 0) {
+ if (s->keys < sizeof(s->key))
+ s->key[s->keys ++] = hid_code;
+ } else
+ return;
}
+
+ usb_hid_changed(hs);
}
static inline int int_clamp(int val, int vmin, int vmax)
@@ -776,7 +794,7 @@ static int usb_hid_handle_control(USBDevice *dev, int request, int value,
data[0] = s->idle;
break;
case SET_IDLE:
- s->idle = value;
+ s->idle = (uint8_t) (value >> 8);
ret = 0;
break;
default:
@@ -833,8 +851,6 @@ USBDevice *usb_tablet_init(void)
USBHIDState *s;
s = qemu_mallocz(sizeof(USBHIDState));
- if (!s)
- return NULL;
s->dev.speed = USB_SPEED_FULL;
s->dev.handle_packet = usb_generic_handle_packet;
@@ -856,8 +872,6 @@ USBDevice *usb_mouse_init(void)
USBHIDState *s;
s = qemu_mallocz(sizeof(USBHIDState));
- if (!s)
- return NULL;
s->dev.speed = USB_SPEED_FULL;
s->dev.handle_packet = usb_generic_handle_packet;
@@ -879,8 +893,6 @@ USBDevice *usb_keyboard_init(void)
USBHIDState *s;
s = qemu_mallocz(sizeof(USBHIDState));
- if (!s)
- return NULL;
s->dev.speed = USB_SPEED_FULL;
s->dev.handle_packet = usb_generic_handle_packet;
@@ -894,3 +906,11 @@ USBDevice *usb_keyboard_init(void)
return (USBDevice *) s;
}
+
+void usb_hid_datain_cb(USBDevice *dev, void *opaque, void (*datain)(void *))
+{
+ USBHIDState *s = (USBHIDState *)dev;
+
+ s->datain_opaque = opaque;
+ s->datain = datain;
+}