From patchwork Wed Mar 31 15:11:05 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shahar Havivi X-Patchwork-Id: 49157 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 DD10DB6ED0 for ; Thu, 1 Apr 2010 02:23:39 +1100 (EST) Received: from localhost ([127.0.0.1]:56602 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NwzlT-0004Ed-OX for incoming@patchwork.ozlabs.org; Wed, 31 Mar 2010 11:23:31 -0400 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1Nwzb7-0008HP-E4 for qemu-devel@nongnu.org; Wed, 31 Mar 2010 11:12:49 -0400 Received: from [140.186.70.92] (port=33059 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Nwzao-0008DY-IJ for qemu-devel@nongnu.org; Wed, 31 Mar 2010 11:12:48 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1Nwzae-0001VV-Od for qemu-devel@nongnu.org; Wed, 31 Mar 2010 11:12:25 -0400 Received: from mx1.redhat.com ([209.132.183.28]:30365) by eggs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1Nwzad-0001UP-Lb for qemu-devel@nongnu.org; Wed, 31 Mar 2010 11:12:20 -0400 Received: from int-mx03.intmail.prod.int.phx2.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o2VFCCdK008940 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Wed, 31 Mar 2010 11:12:13 -0400 Received: from localhost (dhcp-1-229.tlv.redhat.com [10.35.1.229]) by int-mx03.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o2VFCBRt032082; Wed, 31 Mar 2010 11:12:12 -0400 Date: Wed, 31 Mar 2010 18:11:05 +0300 From: Shahar Havivi To: Juan Quintela Message-ID: <20100331151104.GA13328@redhat.com> References: <9535ae3ce401266d194f05c122a93f8e627f5b6f.1270022701.git.shaharh@redhat.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.20 (2009-08-17) X-Scanned-By: MIMEDefang 2.67 on 10.5.11.16 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. Cc: qemu-devel@nongnu.org Subject: [Qemu-devel] Re: [PATCH 1/2] Support for multiple 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 On Wed, Mar 31, 2010 at 12:12:15PM +0200, Juan Quintela wrote: > Date: Wed, 31 Mar 2010 12:12:15 +0200 > From: Juan Quintela > To: Shahar Havivi > Cc: qemu-devel@nongnu.org > Subject: Re: [PATCH 1/2] Support for multiple keyboard devices > > Shahar Havivi wrote: > > Currently you get segfault when trying to remove keyboard (device_del > > monitor command) because no keyboard handling is done. > > > > This patch add QEMUPutKbdEntry structure, handling each keyboard entry. > > Adding a keyboard add to the list, removing keyboard select the previous > > keyboard in list. > > > diff --git a/hw/xenfb.c b/hw/xenfb.c > > index 422cd53..2c700bd 100644 > > --- a/hw/xenfb.c > > +++ b/hw/xenfb.c > > @@ -373,7 +373,7 @@ static int input_connect(struct XenDevice *xendev) > > if (rc != 0) > > return rc; > > > > - qemu_add_kbd_event_handler(xenfb_key_event, in); > > + qemu_add_kbd_event_handler(xenfb_key_event, in, "Xen Keyboard"); > > in->qmouse = qemu_add_mouse_event_handler(xenfb_mouse_event, in, > > in->abs_pointer_wanted, > > "Xen PVFB Mouse"); > > @@ -388,7 +388,7 @@ static void input_disconnect(struct XenDevice *xendev) > > qemu_remove_mouse_event_handler(in->qmouse); > > in->qmouse = NULL; > > } > > - qemu_add_kbd_event_handler(NULL, NULL); > > + qemu_add_kbd_event_handler(NULL, NULL, NULL); > > common_unbind(&in->c); > > } > > > > xen code changes with this patch. You need to store the event handler > somewhere to be able to remove it later, no? > > Later, Juan. Right about the Xen, Added proper remove handling Signed-off-by: Shahar Havivi --- console.h | 14 ++++++++++++- hw/adb.c | 2 +- hw/escc.c | 3 +- hw/musicpal.c | 2 +- hw/nseries.c | 4 +- hw/palm.c | 2 +- hw/ps2.c | 2 +- hw/pxa2xx_keypad.c | 3 +- hw/spitz.c | 3 +- hw/stellaris_input.c | 2 +- hw/syborg_keyboard.c | 2 +- hw/usb-hid.c | 10 ++++++-- hw/xenfb.c | 5 ++- input.c | 51 ++++++++++++++++++++++++++++++++++++++++--------- 14 files changed, 78 insertions(+), 27 deletions(-) diff --git a/console.h b/console.h index 6def115..91b66ea 100644 --- a/console.h +++ b/console.h @@ -41,7 +41,19 @@ typedef struct QEMUPutLEDEntry { QTAILQ_ENTRY(QEMUPutLEDEntry) next; } QEMUPutLEDEntry; -void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque); +typedef struct QEMUPutKbdEntry { + char *qemu_put_kbd_name; + QEMUPutKBDEvent *qemu_put_kbd_event; + void *qemu_put_kbd_event_opaque; + int index; + + QTAILQ_ENTRY(QEMUPutKbdEntry) node; +} QEMUPutKbdEntry; + +QEMUPutKbdEntry *qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, + void *opaque, + const char *name); +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/hw/adb.c b/hw/adb.c index 4fb7a62..09afcf9 100644 --- a/hw/adb.c +++ b/hw/adb.c @@ -304,7 +304,7 @@ void adb_kbd_init(ADBBusState *bus) s = qemu_mallocz(sizeof(KBDState)); d = adb_register_device(bus, ADB_KEYBOARD, adb_kbd_request, adb_kbd_reset, s); - qemu_add_kbd_event_handler(adb_kbd_put_keycode, d); + qemu_add_kbd_event_handler(adb_kbd_put_keycode, d, "adb"); register_savevm("adb_kbd", -1, 1, adb_kbd_save, adb_kbd_load, s); } diff --git a/hw/escc.c b/hw/escc.c index 6d2fd36..2b21d98 100644 --- a/hw/escc.c +++ b/hw/escc.c @@ -919,7 +919,8 @@ static int escc_init1(SysBusDevice *dev) "QEMU Sun Mouse"); } if (s->chn[1].type == kbd) { - qemu_add_kbd_event_handler(sunkbd_event, &s->chn[1]); + qemu_add_kbd_event_handler(sunkbd_event, &s->chn[1], + "QEMU Sun Keyboard"); } return 0; diff --git a/hw/musicpal.c b/hw/musicpal.c index ebd933e..e1a3b6a 100644 --- a/hw/musicpal.c +++ b/hw/musicpal.c @@ -1447,7 +1447,7 @@ static int musicpal_key_init(SysBusDevice *dev) qdev_init_gpio_out(&dev->qdev, s->out, ARRAY_SIZE(s->out)); - qemu_add_kbd_event_handler(musicpal_key_event, s); + qemu_add_kbd_event_handler(musicpal_key_event, s, "Musicpal"); return 0; } diff --git a/hw/nseries.c b/hw/nseries.c index 0273eee..abfcec3 100644 --- a/hw/nseries.c +++ b/hw/nseries.c @@ -262,7 +262,7 @@ static void n800_tsc_kbd_setup(struct n800_s *s) if (n800_keys[i] >= 0) s->keymap[n800_keys[i]] = i; - qemu_add_kbd_event_handler(n800_key_event, s); + qemu_add_kbd_event_handler(n800_key_event, s, "Nokia n800"); tsc210x_set_transform(s->ts.chip, &n800_pointercal); } @@ -371,7 +371,7 @@ static void n810_kbd_setup(struct n800_s *s) if (n810_keys[i] > 0) s->keymap[n810_keys[i]] = i; - qemu_add_kbd_event_handler(n810_key_event, s); + qemu_add_kbd_event_handler(n810_key_event, s, "Nokia n810"); /* Attach the LM8322 keyboard to the I2C bus, * should happen in n8x0_i2c_setup and s->kbd be initialised here. */ diff --git a/hw/palm.c b/hw/palm.c index 6d19167..1b405d4 100644 --- a/hw/palm.c +++ b/hw/palm.c @@ -228,7 +228,7 @@ static void palmte_init(ram_addr_t ram_size, palmte_microwire_setup(cpu); - qemu_add_kbd_event_handler(palmte_button_event, cpu); + qemu_add_kbd_event_handler(palmte_button_event, cpu, "Palm Keyboard"); palmte_gpio_setup(cpu); diff --git a/hw/ps2.c b/hw/ps2.c index f0b206a..886da37 100644 --- a/hw/ps2.c +++ b/hw/ps2.c @@ -596,7 +596,7 @@ void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg) s->common.update_arg = update_arg; s->scancode_set = 2; vmstate_register(0, &vmstate_ps2_keyboard, s); - qemu_add_kbd_event_handler(ps2_put_keycode, s); + qemu_add_kbd_event_handler(ps2_put_keycode, s, "QEMU PS/2 Keyboard"); qemu_register_reset(ps2_kbd_reset, s); return s; } diff --git a/hw/pxa2xx_keypad.c b/hw/pxa2xx_keypad.c index 060df58..2b75351 100644 --- a/hw/pxa2xx_keypad.c +++ b/hw/pxa2xx_keypad.c @@ -332,5 +332,6 @@ void pxa27x_register_keypad(PXA2xxKeyPadState *kp, struct keymap *map, } kp->map = map; - qemu_add_kbd_event_handler((QEMUPutKBDEvent *) pxa27x_keyboard_event, kp); + qemu_add_kbd_event_handler((QEMUPutKBDEvent *) pxa27x_keyboard_event, kp, + "PXA keypad"); } diff --git a/hw/spitz.c b/hw/spitz.c index 564519b..b1c0af0 100644 --- a/hw/spitz.c +++ b/hw/spitz.c @@ -506,7 +506,8 @@ static void spitz_keyboard_register(PXA2xxState *cpu) pxa2xx_gpio_out_set(cpu->gpio, spitz_gpio_key_strobe[i], s->strobe[i]); spitz_keyboard_pre_map(s); - qemu_add_kbd_event_handler((QEMUPutKBDEvent *) spitz_keyboard_handler, s); + qemu_add_kbd_event_handler((QEMUPutKBDEvent *) spitz_keyboard_handler, s, + "Spitz keyboard"); register_savevm("spitz_keyboard", 0, 0, spitz_keyboard_save, spitz_keyboard_load, s); diff --git a/hw/stellaris_input.c b/hw/stellaris_input.c index 33395a4..775cb46 100644 --- a/hw/stellaris_input.c +++ b/hw/stellaris_input.c @@ -85,7 +85,7 @@ void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode) s->buttons[i].keycode = keycode[i]; } s->num_buttons = n; - qemu_add_kbd_event_handler(stellaris_gamepad_put_key, s); + qemu_add_kbd_event_handler(stellaris_gamepad_put_key, s, "Stellaris Gamepad"); register_savevm("stellaris_gamepad", -1, 1, stellaris_gamepad_save, stellaris_gamepad_load, s); } diff --git a/hw/syborg_keyboard.c b/hw/syborg_keyboard.c index 4a562f8..d1651b4 100644 --- a/hw/syborg_keyboard.c +++ b/hw/syborg_keyboard.c @@ -218,7 +218,7 @@ static int syborg_keyboard_init(SysBusDevice *dev) } s->key_fifo = qemu_mallocz(s->fifo_size * sizeof(s->key_fifo[0])); - qemu_add_kbd_event_handler(syborg_keyboard_event, s); + qemu_add_kbd_event_handler(syborg_keyboard_event, s, "Syborg Keyboard"); register_savevm("syborg_keyboard", -1, 1, syborg_keyboard_save, syborg_keyboard_load, s); diff --git a/hw/usb-hid.c b/hw/usb-hid.c index 8e6c6e0..dbab5d3 100644 --- a/hw/usb-hid.c +++ b/hw/usb-hid.c @@ -55,6 +55,7 @@ typedef struct USBKeyboardState { uint8_t leds; uint8_t key[16]; int keys; + QEMUPutKbdEntry *eh_entry; } USBKeyboardState; typedef struct USBHIDState { @@ -633,7 +634,8 @@ static void usb_keyboard_handle_reset(USBDevice *dev) { USBHIDState *s = (USBHIDState *)dev; - qemu_add_kbd_event_handler(usb_keyboard_event, s); + s->kbd.eh_entry = qemu_add_kbd_event_handler(usb_keyboard_event, s, + dev->product_desc); s->protocol = 1; } @@ -854,9 +856,11 @@ static void usb_hid_handle_destroy(USBDevice *dev) { USBHIDState *s = (USBHIDState *)dev; - if (s->kind != USB_KEYBOARD) + if (s->kind != USB_KEYBOARD) { qemu_remove_mouse_event_handler(s->ptr.eh_entry); - /* TODO: else */ + } else { + qemu_remove_kbd_event_handler(s->kbd.eh_entry); + } } static int usb_hid_initfn(USBDevice *dev, int kind) diff --git a/hw/xenfb.c b/hw/xenfb.c index 422cd53..0c1d1ec 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; + QEMUPutKbdEntry *qkbd; }; #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->qkbd = qemu_add_kbd_event_handler(xenfb_key_event, in, "Xen Keyboard"); in->qmouse = qemu_add_mouse_event_handler(xenfb_mouse_event, in, in->abs_pointer_wanted, "Xen PVFB Mouse"); @@ -388,7 +389,7 @@ static void input_disconnect(struct XenDevice *xendev) qemu_remove_mouse_event_handler(in->qmouse); in->qmouse = NULL; } - qemu_add_kbd_event_handler(NULL, NULL); + qemu_remove_kbd_event_handler(in->qkbd); common_unbind(&in->c); } diff --git a/input.c b/input.c index 8f0941e..e6dda25 100644 --- a/input.c +++ b/input.c @@ -28,20 +28,14 @@ #include "console.h" #include "qjson.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); static NotifierList mouse_mode_notifiers = NOTIFIER_LIST_INITIALIZER(mouse_mode_notifiers); -void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque) -{ - qemu_put_kbd_event_opaque = opaque; - qemu_put_kbd_event = func; -} - static void check_mode_change(void) { static int current_is_absolute, current_has_absolute; @@ -60,6 +54,38 @@ static void check_mode_change(void) current_has_absolute = has_absolute; } +QEMUPutKbdEntry *qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, + void *opaque, + const char *name) +{ + static int mouse_index = 0; + QEMUPutKbdEntry *s, *cursor; + + QTAILQ_FOREACH(cursor, &kbd_handlers, node) { + if (cursor->qemu_put_kbd_event == func && + cursor->qemu_put_kbd_event_opaque == opaque) { + return cursor; + } + } + + s = qemu_mallocz(sizeof(QEMUPutKbdEntry)); + + s->qemu_put_kbd_event_opaque = opaque; + s->qemu_put_kbd_event = func; + s->qemu_put_kbd_name = qemu_strdup(name); + s->index = mouse_index++; + + QTAILQ_INSERT_TAIL(&kbd_handlers, s, node); + + return s; +} + +void qemu_remove_kbd_event_handler(QEMUPutKbdEntry *entry) +{ + QTAILQ_REMOVE(&kbd_handlers, entry, node); + qemu_free(entry); +} + QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func, void *opaque, int absolute, const char *name) @@ -123,9 +149,14 @@ void qemu_remove_led_event_handler(QEMUPutLEDEntry *entry) void kbd_put_keycode(int keycode) { - if (qemu_put_kbd_event) { - qemu_put_kbd_event(qemu_put_kbd_event_opaque, keycode); + QEMUPutKbdEntry *entry; + + if (QTAILQ_EMPTY(&kbd_handlers)) { + return; } + + entry = QTAILQ_FIRST(&kbd_handlers); + entry->qemu_put_kbd_event(entry->qemu_put_kbd_event_opaque, keycode); } void kbd_put_ledstate(int ledstate)