qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Filip Navara <filip.navara@gmail.com>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH] Add support for multiple simultaneously used keyboard devices.
Date: Sat, 24 OCT 09 16:9:3 +0100	[thread overview]
Message-ID: <E1N1hIq-0004SO-Eo@lists.gnu.org> (raw)

The support for multiple keyboard devices is essential for emulating embedded boards where multiple input devices are present (eg. keypad and rotary encoder) which are implemented using separate QEMU devices.

Signed-off-by: Filip Navara <filip.navara@gmail.com>
---
 console.h  |   11 ++++++++++-
 hw/xenfb.c |    8 ++++++--
 vl.c       |   60 +++++++++++++++++++++++++++++++++++++++++++++++++++++-------
 3 files changed, 69 insertions(+), 10 deletions(-)

diff --git a/console.h b/console.h
index 9615f56..568d097 100644
--- a/console.h
+++ b/console.h
@@ -26,7 +26,16 @@ typedef struct QEMUPutMouseEntry {
     struct QEMUPutMouseEntry *next;
 } QEMUPutMouseEntry;
 
-void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque);
+typedef struct QEMUPutKeyboardEntry {
+    QEMUPutKBDEvent *qemu_put_kbd_event;
+    void *qemu_put_kbd_event_opaque;
+
+    /* used internally by qemu for handling mice */
+    struct QEMUPutKeyboardEntry *next;
+} QEMUPutKeyboardEntry;
+
+QEMUPutKeyboardEntry *qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque);
+void qemu_remove_kbd_event_handler(QEMUPutKeyboardEntry *entry);
 QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func,
                                                 void *opaque, int absolute,
                                                 const char *name);
diff --git a/hw/xenfb.c b/hw/xenfb.c
index 795a326..090f857 100644
--- a/hw/xenfb.c
+++ b/hw/xenfb.c
@@ -68,6 +68,7 @@ struct XenInput {
     int button_state;       /* Last seen pointer button state */
     int extended;
     QEMUPutMouseEntry *qmouse;
+    QEMUPutKeyboardEntry *qkeyboard;
 };
 
 #define UP_QUEUE 8
@@ -373,7 +374,7 @@ static int input_connect(struct XenDevice *xendev)
     if (rc != 0)
 	return rc;
 
-    qemu_add_kbd_event_handler(xenfb_key_event, in);
+    in->qkeyboard = qemu_add_kbd_event_handler(xenfb_key_event, in);
     in->qmouse = qemu_add_mouse_event_handler(xenfb_mouse_event, in,
 					      in->abs_pointer_wanted,
 					      "Xen PVFB Mouse");
@@ -388,7 +389,10 @@ static void input_disconnect(struct XenDevice *xendev)
 	qemu_remove_mouse_event_handler(in->qmouse);
 	in->qmouse = NULL;
     }
-    qemu_add_kbd_event_handler(NULL, NULL);
+    if (in->qkeyboard) {
+	qemu_remove_kbd_event_handler(in->qkeyboard);
+	in->qkeyboard = NULL;
+    }
     common_unbind(&in->c);
 }
 
diff --git a/vl.c b/vl.c
index eb2744e..1bb7d40 100644
--- a/vl.c
+++ b/vl.c
@@ -346,15 +346,57 @@ ram_addr_t qemu_balloon_status(void)
 /***********************************************************/
 /* keyboard/mouse */
 
-static QEMUPutKBDEvent *qemu_put_kbd_event;
-static void *qemu_put_kbd_event_opaque;
+static QEMUPutKeyboardEntry *qemu_put_kbd_event_head;
 static QEMUPutMouseEntry *qemu_put_mouse_event_head;
 static QEMUPutMouseEntry *qemu_put_mouse_event_current;
 
-void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque)
+QEMUPutKeyboardEntry *qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque)
 {
-    qemu_put_kbd_event_opaque = opaque;
-    qemu_put_kbd_event = func;
+    QEMUPutKeyboardEntry *s, *cursor;
+
+    s = qemu_mallocz(sizeof(QEMUPutKeyboardEntry));
+
+    s->qemu_put_kbd_event = func;
+    s->qemu_put_kbd_event_opaque = opaque;
+    s->next = NULL;
+
+    if (!qemu_put_kbd_event_head) {
+        qemu_put_kbd_event_head = s;
+        return s;
+    }
+
+    cursor = qemu_put_kbd_event_head;
+    while (cursor->next != NULL)
+        cursor = cursor->next;
+
+    cursor->next = s;
+
+    return s;
+}
+
+void qemu_remove_kbd_event_handler(QEMUPutKeyboardEntry *entry)
+{
+    QEMUPutKeyboardEntry *prev = NULL, *cursor;
+
+    if (!qemu_put_kbd_event_head || entry == NULL)
+        return;
+
+    cursor = qemu_put_kbd_event_head;
+    while (cursor != NULL && cursor != entry) {
+        prev = cursor;
+        cursor = cursor->next;
+    }
+
+    if (cursor == NULL) // does not exist or list empty
+        return;
+    else if (prev == NULL) { // entry is head
+        qemu_put_kbd_event_head = cursor->next;
+        qemu_free(entry);
+        return;
+    }
+
+    prev->next = entry->next;
+    qemu_free(entry);
 }
 
 QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func,
@@ -421,8 +463,12 @@ void qemu_remove_mouse_event_handler(QEMUPutMouseEntry *entry)
 
 void kbd_put_keycode(int keycode)
 {
-    if (qemu_put_kbd_event) {
-        qemu_put_kbd_event(qemu_put_kbd_event_opaque, keycode);
+    QEMUPutKeyboardEntry *cursor;
+
+    cursor = qemu_put_kbd_event_head;
+    while (cursor != NULL) {
+        cursor->qemu_put_kbd_event(cursor->qemu_put_kbd_event_opaque, keycode);
+        cursor = cursor->next;
     }
 }
 
-- 
1.6.3.2.1299.gee46c

             reply	other threads:[~2009-10-24 14:09 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-10-24 15:09 Filip Navara [this message]
2009-10-26  5:27 ` [Qemu-devel] [PATCH] Add support for multiple simultaneously used keyboard devices Juha.Riihimaki
2009-11-09 14:35 ` Anthony Liguori
2009-11-11 18:17   ` Filip Navara

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=E1N1hIq-0004SO-Eo@lists.gnu.org \
    --to=filip.navara@gmail.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).