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??
diff --git a/input.c b/input.c
index 6b5c2c3..8a281d6 100644
--- a/input.c
+++ b/input.c
@@ -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 @@
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 kbd_put_keycode(int keycode)
{
+ QEMUPutKBDEntry *cursor;
if (!runstate_is_running()) {
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);
}
}