diff options
author | Gerd Hoffmann <kraxel@redhat.com> | 2013-04-24 12:08:38 +0200 |
---|---|---|
committer | Anthony Liguori <aliguori@us.ibm.com> | 2013-04-24 11:50:18 -0500 |
commit | 5a37532d0897de488c35ab2db6d86647bd2a1b6f (patch) | |
tree | 13c6185efc40487fef39999ba0055120ac739aac /ui/input.c | |
parent | 72711efb58c13e28c89813490120b32947a2d719 (diff) |
input: introduce keyboard handler list
Add a linked list of keyboard handlers. Added handlers will go
to the head of the list. Removed handlers will be zapped from
the list. The head of the list will be used for events.
This fixes the keyboard-dead-after-usb-kbd-unplug issue, key events
will be re-routed to the ps/2 kbd instead of being discarded.
[ v2: fix cut+paste bug found my Markus ]
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Message-id: 1366798118-3248-3-git-send-email-kraxel@redhat.com
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Diffstat (limited to 'ui/input.c')
-rw-r--r-- | ui/input.c | 37 |
1 files changed, 25 insertions, 12 deletions
diff --git a/ui/input.c b/ui/input.c index d8793e7798..8ca1a03e12 100644 --- a/ui/input.c +++ b/ui/input.c @@ -41,18 +41,25 @@ struct QEMUPutMouseEntry { QTAILQ_ENTRY(QEMUPutMouseEntry) node; }; +struct QEMUPutKbdEntry { + QEMUPutKBDEvent *put_kbd; + void *opaque; + QTAILQ_ENTRY(QEMUPutKbdEntry) next; +}; + struct QEMUPutLEDEntry { QEMUPutLEDEvent *put_led; void *opaque; QTAILQ_ENTRY(QEMUPutLEDEntry) next; }; -static QEMUPutKBDEvent *qemu_put_kbd_event; -static void *qemu_put_kbd_event_opaque; -static QTAILQ_HEAD(, QEMUPutLEDEntry) led_handlers = QTAILQ_HEAD_INITIALIZER(led_handlers); +static QTAILQ_HEAD(, QEMUPutLEDEntry) led_handlers = + QTAILQ_HEAD_INITIALIZER(led_handlers); +static QTAILQ_HEAD(, QEMUPutKbdEntry) kbd_handlers = + QTAILQ_HEAD_INITIALIZER(kbd_handlers); static QTAILQ_HEAD(, QEMUPutMouseEntry) mouse_handlers = QTAILQ_HEAD_INITIALIZER(mouse_handlers); -static NotifierList mouse_mode_notifiers = +static NotifierList mouse_mode_notifiers = NOTIFIER_LIST_INITIALIZER(mouse_mode_notifiers); static const int key_defs[] = { @@ -304,16 +311,20 @@ void qmp_send_key(KeyValueList *keys, bool has_hold_time, int64_t hold_time, muldiv64(get_ticks_per_sec(), hold_time, 1000)); } -void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque) +QEMUPutKbdEntry *qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque) { - qemu_put_kbd_event_opaque = opaque; - qemu_put_kbd_event = func; + QEMUPutKbdEntry *entry; + + entry = g_malloc0(sizeof(QEMUPutKbdEntry)); + entry->put_kbd = func; + entry->opaque = opaque; + QTAILQ_INSERT_HEAD(&kbd_handlers, entry, next); + return entry; } -void qemu_remove_kbd_event_handler(void) +void qemu_remove_kbd_event_handler(QEMUPutKbdEntry *entry) { - qemu_put_kbd_event_opaque = NULL; - qemu_put_kbd_event = NULL; + QTAILQ_REMOVE(&kbd_handlers, entry, next); } static void check_mode_change(void) @@ -397,11 +408,13 @@ void qemu_remove_led_event_handler(QEMUPutLEDEntry *entry) void kbd_put_keycode(int keycode) { + QEMUPutKbdEntry *entry = QTAILQ_FIRST(&kbd_handlers); + 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); + if (entry) { + entry->put_kbd(entry->opaque, keycode); } } |