diff options
author | Juha Riihimäki <juha.riihimaki@nokia.com> | 2012-07-04 11:18:33 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2012-07-25 13:31:41 +0100 |
commit | c746737e13befb20b621ab1e820431a5ea3836de (patch) | |
tree | 2dbe7a6be55b170fb978669a1d5fcdbc42b1bf6f | |
parent | 155210f5c5f20871a04f28b1738404a68f8d9022 (diff) |
Support multiple simultaneous keyboard event handlers
On some systems (such as n900), multiple physical devices can create
keyboard events (gpio, lis302dl, twl4030, ..). Add hooks to make it
possible to recieve keyboard input from multiple devices.
merge our version with upstream multikb support
multitouch, multi-keyboard and window close hook support
TODO: make this look more like mouse version, ie return a handle
which is passed to remove. Also who calls add_kbd_event_handler
with a NULL function?? & if we send keycode to all kbd handlers
this is ok for n900 but what about eg pc + usb kbd??
-rw-r--r-- | console.h | 8 | ||||
-rw-r--r-- | hw/hid.c | 2 | ||||
-rw-r--r-- | input.c | 33 |
3 files changed, 32 insertions, 11 deletions
@@ -37,6 +37,12 @@ typedef struct QEMUPutMouseEntry { QTAILQ_ENTRY(QEMUPutMouseEntry) node; } QEMUPutMouseEntry; +typedef struct QEMUPutKBDEntry { + QEMUPutKBDEvent *put_kbd_event; + void *opaque; + QTAILQ_ENTRY(QEMUPutKBDEntry) next; +} QEMUPutKBDEntry; + typedef struct QEMUPutLEDEntry { QEMUPutLEDEvent *put_led; void *opaque; @@ -44,7 +50,7 @@ typedef struct QEMUPutLEDEntry { } QEMUPutLEDEntry; void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque); -void qemu_remove_kbd_event_handler(void); +void qemu_remove_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque); QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func, void *opaque, int absolute, const char *name); @@ -383,7 +383,7 @@ void hid_free(HIDState *hs) { switch (hs->kind) { case HID_KEYBOARD: - qemu_remove_kbd_event_handler(); + qemu_remove_kbd_event_handler(hid_keyboard_event, hs); break; case HID_MOUSE: case HID_TABLET: @@ -29,8 +29,8 @@ #include "error.h" #include "qmp-commands.h" -static QEMUPutKBDEvent *qemu_put_kbd_event; -static void *qemu_put_kbd_event_opaque; +static QTAILQ_HEAD(, QEMUPutKBDEntry) kbd_handlers = + QTAILQ_HEAD_INITIALIZER(kbd_handlers); static QTAILQ_HEAD(, QEMUPutLEDEntry) led_handlers = QTAILQ_HEAD_INITIALIZER(led_handlers); static QTAILQ_HEAD(, QEMUPutMouseEntry) mouse_handlers = QTAILQ_HEAD_INITIALIZER(mouse_handlers); @@ -39,14 +39,28 @@ static NotifierList mouse_mode_notifiers = void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque) { - qemu_put_kbd_event_opaque = opaque; - qemu_put_kbd_event = func; + QEMUPutKBDEntry *s; + + if (func != NULL) { + s = g_malloc0(sizeof(QEMUPutKBDEntry)); + + s->put_kbd_event = func; + s->opaque = opaque; + + QTAILQ_INSERT_TAIL(&kbd_handlers, s, next); + } } -void qemu_remove_kbd_event_handler(void) +void qemu_remove_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque) { - qemu_put_kbd_event_opaque = NULL; - qemu_put_kbd_event = NULL; + QEMUPutKBDEntry *cursor, *cursor_next; + if (func != NULL) { + QTAILQ_FOREACH_SAFE(cursor, &kbd_handlers, next, cursor_next) { + if (cursor->put_kbd_event == func && cursor->opaque == opaque) { + QTAILQ_REMOVE(&kbd_handlers, cursor, next); + } + } + } } static void check_mode_change(void) @@ -130,11 +144,12 @@ void qemu_remove_led_event_handler(QEMUPutLEDEntry *entry) void kbd_put_keycode(int keycode) { + QEMUPutKBDEntry *cursor; if (!runstate_is_running() && !runstate_check(RUN_STATE_SUSPENDED)) { return; } - if (qemu_put_kbd_event) { - qemu_put_kbd_event(qemu_put_kbd_event_opaque, keycode); + QTAILQ_FOREACH(cursor, &kbd_handlers, next) { + cursor->put_kbd_event(cursor->opaque, keycode); } } |