From patchwork Sat Oct 24 15:09:03 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Filip Navara X-Patchwork-Id: 36842 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 7E382B7BD1 for ; Sun, 25 Oct 2009 01:10:02 +1100 (EST) Received: from localhost ([127.0.0.1]:40938 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1N1hJf-0004TW-KU for incoming@patchwork.ozlabs.org; Sat, 24 Oct 2009 10:09:59 -0400 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1N1hIr-0004Sc-0o for qemu-devel@nongnu.org; Sat, 24 Oct 2009 10:09:09 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1N1hIq-0004SO-Eo for qemu-devel@nongnu.org; Sat, 24 Oct 2009 10:09:08 -0400 Received: from [199.232.76.173] (port=40630 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1N1hIq-0004SL-BK for qemu-devel@nongnu.org; Sat, 24 Oct 2009 10:09:08 -0400 Received: from [94.142.236.94] (port=52234 helo=FilipNavara-PC) by monty-python.gnu.org with smtp (Exim 4.60) (envelope-from ) id 1N1hIp-0003SA-J9 for qemu-devel@nongnu.org; Sat, 24 Oct 2009 10:09:08 -0400 Date: Sat, 24 OCT 09 16:9:3 +0100 From: Filip Navara CC: To: qemu-devel@nongnu.org X-Mailer: TortoiseGit MIME-Version: 1.0 X-detected-operating-system: by monty-python.gnu.org: Windows XP/2000 (RFC1323+, w+, tstamp-) Message-Id: Subject: [Qemu-devel] [PATCH] Add support for multiple simultaneously used keyboard devices. X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org 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 --- 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; } }