From patchwork Fri Mar 8 14:22:51 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gerd Hoffmann X-Patchwork-Id: 226132 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 27BA62C0374 for ; Sat, 9 Mar 2013 01:23:25 +1100 (EST) Received: from localhost ([::1]:60448 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UDyCh-00046G-Bh for incoming@patchwork.ozlabs.org; Fri, 08 Mar 2013 09:23:23 -0500 Received: from eggs.gnu.org ([208.118.235.92]:37138) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UDyCK-0003zx-7I for qemu-devel@nongnu.org; Fri, 08 Mar 2013 09:23:03 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UDyCE-0003Oh-JA for qemu-devel@nongnu.org; Fri, 08 Mar 2013 09:23:00 -0500 Received: from mx1.redhat.com ([209.132.183.28]:24084) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UDyCE-0003O9-9O for qemu-devel@nongnu.org; Fri, 08 Mar 2013 09:22:54 -0500 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id r28EMrku021676 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 8 Mar 2013 09:22:53 -0500 Received: from rincewind.home.kraxel.org (ovpn-116-26.ams2.redhat.com [10.36.116.26]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id r28EMqqh004204; Fri, 8 Mar 2013 09:22:52 -0500 Received: by rincewind.home.kraxel.org (Postfix, from userid 500) id A6A0C42086; Fri, 8 Mar 2013 15:22:51 +0100 (CET) From: Gerd Hoffmann To: qemu-devel@nongnu.org Date: Fri, 8 Mar 2013 15:22:51 +0100 Message-Id: <1362752571-2056-3-git-send-email-kraxel@redhat.com> In-Reply-To: <1362752571-2056-1-git-send-email-kraxel@redhat.com> References: <1362752571-2056-1-git-send-email-kraxel@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 209.132.183.28 Cc: Anthony Liguori , armbru@redhat.com, Gerd Hoffmann Subject: [Qemu-devel] [PATCH v2 2/2] input: introduce keyboard handler list X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org 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 --- hw/hid.c | 4 ++-- hw/hid.h | 1 + include/ui/console.h | 6 ++++-- ui/input.c | 37 +++++++++++++++++++++++++------------ 4 files changed, 32 insertions(+), 16 deletions(-) diff --git a/hw/hid.c b/hw/hid.c index 89b5415..6be00ec 100644 --- a/hw/hid.c +++ b/hw/hid.c @@ -415,7 +415,7 @@ void hid_free(HIDState *hs) { switch (hs->kind) { case HID_KEYBOARD: - qemu_remove_kbd_event_handler(); + qemu_remove_kbd_event_handler(hs->kbd.eh_entry); break; case HID_MOUSE: case HID_TABLET: @@ -431,7 +431,7 @@ void hid_init(HIDState *hs, int kind, HIDEventFunc event) hs->event = event; if (hs->kind == HID_KEYBOARD) { - qemu_add_kbd_event_handler(hid_keyboard_event, hs); + hs->kbd.eh_entry = qemu_add_kbd_event_handler(hid_keyboard_event, hs); } else if (hs->kind == HID_MOUSE) { hs->ptr.eh_entry = qemu_add_mouse_event_handler(hid_pointer_event, hs, 0, "QEMU HID Mouse"); diff --git a/hw/hid.h b/hw/hid.h index 56c71ed..2567879 100644 --- a/hw/hid.h +++ b/hw/hid.h @@ -31,6 +31,7 @@ typedef struct HIDKeyboardState { uint8_t leds; uint8_t key[16]; int32_t keys; + QEMUPutKbdEntry *eh_entry; } HIDKeyboardState; struct HIDState { diff --git a/include/ui/console.h b/include/ui/console.h index ce5a550..fd39d94 100644 --- a/include/ui/console.h +++ b/include/ui/console.h @@ -28,10 +28,12 @@ typedef void QEMUPutLEDEvent(void *opaque, int ledstate); typedef void QEMUPutMouseEvent(void *opaque, int dx, int dy, int dz, int buttons_state); typedef struct QEMUPutMouseEntry QEMUPutMouseEntry; +typedef struct QEMUPutKbdEntry QEMUPutKbdEntry; typedef struct QEMUPutLEDEntry QEMUPutLEDEntry; -void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque); -void qemu_remove_kbd_event_handler(void); +QEMUPutKbdEntry *qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, + void *opaque); +void qemu_remove_kbd_event_handler(QEMUPutKbdEntry *entry); QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func, void *opaque, int absolute, const char *name); diff --git a/ui/input.c b/ui/input.c index 87a23df..57e963b 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[] = { @@ -306,16 +313,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) @@ -399,11 +410,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); } }