Skip to contentSkip to conversation

Qemu support for multiple keyboard devices

PATCH Superseded Shahar Havivi 4 participants 16 messages Mar 31, 2010

v3 of 5 Superseded Latest is v5 →

lore
Share & tools
lore
#0 lore raw

v3 cover Qemu support for multiple keyboard devices

v3:
Changes by Markus comments,

Patch #1 Change keyboard list pointer to qemu tail queue Patch #2 Add static index to keyboard entry
Remove unused error messages

Qemu support for multiple keyboard devices:

Patch #1 adding keyboard is done to list instead of "last added keyboard
wins", when removing keyboard via device_del - next keyboard selected.

Patch #2 adding 2 new monitor command to handle keyboard list:
'info keyboard' - show all keyboards and mark the current one 'keyboard_set' - set active keyboard by index as display in
'info keyboard'

Shahar Havivi (2):
Support for multiple keyboard devices
Added monitor commands: 'keyboard_set' and 'info keybaord'

 console.h            |   18 ++++++-
 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           |    4 +-
 input.c              |  152 ++++++++++++++++++++++++++++++++++++++++++++++---
 monitor.c            |    8 +++
 qemu-monitor.hx      |   17 ++++++
 16 files changed, 207 insertions(+), 27 deletions(-)
#1 lore raw

PATCH v3 1/2 Support for multiple keyboard devices

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.

---
 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           |    4 +-
 input.c              |   51 ++++++++++++++++++++++++++++++++++++++++---------
 14 files changed, 77 insertions(+), 27 deletions(-)
console.h +13 -1
index 6def115..91b66ea 100644
@@ -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);
hw/adb.c +1 -1
index 4fb7a62..09afcf9 100644
@@ -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);
 }
hw/escc.c +2 -1
index 6d2fd36..2b21d98 100644
@@ -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;
hw/musicpal.c +1 -1
index ebd933e..e1a3b6a 100644
@@ -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;
 }
hw/nseries.c +2 -2
index 0273eee..abfcec3 100644
@@ -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.  */
hw/palm.c +1 -1
index 6d19167..1b405d4 100644
@@ -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);
 
hw/ps2.c +1 -1
index f0b206a..886da37 100644
@@ -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;
 }
hw/pxa2xx_keypad.c +2 -1
index 060df58..2b75351 100644
@@ -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");
 }
hw/spitz.c +2 -1
index 564519b..b1c0af0 100644
@@ -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);
hw/stellaris_input.c +1 -1
index 33395a4..775cb46 100644
@@ -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);
 }
hw/syborg_keyboard.c +1 -1
index 4a562f8..d1651b4 100644
@@ -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);
hw/usb-hid.c +7 -3
index 8e6c6e0..dbab5d3 100644
@@ -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)
hw/xenfb.c +2 -2
index 422cd53..2c700bd 100644
@@ -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);
 }
 
input.c +41 -10

76 lines not on this page · raw message

Signature · 1 line
1.6.3.3
#2 lore raw

[Qemu-devel] Re: [PATCH 1/2] Support for multiple keyboard devices

Quoted 21 lines · Shahar Havivi

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.

hw/xenfb.c +1 -1
index 422cd53..2c700bd 100644
@@ -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");

hw/xenfb.c static void input_disconnect(struct XenDevice *xendev) · line 394

Quoted 8 lines
hw/xenfb.c +1 -1
@@ -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.

#3 lore raw

[Qemu-devel] Re: [PATCH 1/2] Support for multiple keyboard devices

Quoted 40 lines · Juan Quintela

Date: Wed, 31 Mar 2010 12:12:15 +0200
From: Juan Quintela <[email protected]>
To: Shahar Havivi <[email protected]>
Cc: [email protected]
Subject: Re: [PATCH 1/2] Support for multiple keyboard devices

Quoted 21 lines · Shahar Havivi

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.

hw/xenfb.c +1 -1
index 422cd53..2c700bd 100644
@@ -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");

hw/xenfb.c static void input_disconnect(struct XenDevice *xendev) · line 394

Quoted 8 lines
hw/xenfb.c +1 -1
@@ -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?

Quoted 1 line

Later, Juan.

Right about the Xen,
Added proper remove handling

---
 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(-)
console.h +13 -1
index 6def115..91b66ea 100644
@@ -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);
hw/adb.c +1 -1
index 4fb7a62..09afcf9 100644
@@ -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);
 }
hw/escc.c +2 -1
index 6d2fd36..2b21d98 100644
@@ -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;
hw/musicpal.c +1 -1
index ebd933e..e1a3b6a 100644
@@ -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;
 }
hw/nseries.c +2 -2
index 0273eee..abfcec3 100644
@@ -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.  */
hw/palm.c +1 -1
index 6d19167..1b405d4 100644
@@ -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);
 
hw/ps2.c +1 -1
index f0b206a..886da37 100644
@@ -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;
 }
hw/pxa2xx_keypad.c +2 -1
index 060df58..2b75351 100644
@@ -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");
 }
hw/spitz.c +2 -1
index 564519b..b1c0af0 100644
@@ -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);
hw/stellaris_input.c +1 -1
index 33395a4..775cb46 100644
@@ -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);
 }
hw/syborg_keyboard.c +1 -1
index 4a562f8..d1651b4 100644
@@ -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);
hw/usb-hid.c +7 -3
index 8e6c6e0..dbab5d3 100644
@@ -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)
hw/xenfb.c +3 -2
index 422cd53..0c1d1ec 100644
@@ -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);
 }
 
input.c +41 -10

76 lines not on this page · raw message

Signature · 1 line
1.6.3.3
#4 lore raw

Re: [Qemu-devel] [PATCH 1/2] Support for multiple keyboard devices

In reply to Shahar Havivi
Quoted 9 lines · Shahar Havivi

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.

---

[...]

Quoted 4 lines
input.c +0 -0
index 8f0941e..e6dda25 100644

[...]

input.c static void check_mode_change(void) · line 61

Quoted 9 lines
input.c +5 -0
@@ -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;

"mouse_index" is an unorthodox name for counting keyboards ;)

Quoted 20 lines
input.c +20 -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;
+}

[...]

#5 lore raw

Re: [Qemu-devel] [PATCH 1/2] Support for multiple keyboard devices

Quoted 27 lines · Markus Armbruster

Date: Wed, 31 Mar 2010 17:23:46 +0200
From: Markus Armbruster <[email protected]>
To: Shahar Havivi <[email protected]>
Cc: [email protected]
Subject: Re: [Qemu-devel] [PATCH 1/2] Support for multiple keyboard devices

Quoted 9 lines · Shahar Havivi

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.

---

[...]

Quoted 4 lines
input.c +0 -0
index 8f0941e..e6dda25 100644

[...]

Quoted 4 lines
input.c +0 -0
@@ -60,6 +54,38 @@ static void check_mode_change(void)
     current_has_absolute = has_absolute;
 }
 
Quoted 8 lines

input.c static void check_mode_change(void) · line 61

Quoted 5 lines
input.c +5 -0
+QEMUPutKbdEntry *qemu_add_kbd_event_handler(QEMUPutKBDEvent *func,
+                                            void *opaque,
+                                            const char *name)
+{
+    static int mouse_index = 0;

"mouse_index" is an unorthodox name for counting keyboards ;) [...]

Right :)

---
 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(-)
console.h +13 -1
index 6def115..91b66ea 100644
@@ -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);
hw/adb.c +1 -1
index 4fb7a62..09afcf9 100644
@@ -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);
 }
hw/escc.c +2 -1
index 6d2fd36..2b21d98 100644
@@ -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;
hw/musicpal.c +1 -1
index ebd933e..e1a3b6a 100644
@@ -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;
 }
hw/nseries.c +2 -2
index 0273eee..abfcec3 100644
@@ -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.  */
hw/palm.c +1 -1
index 6d19167..1b405d4 100644
@@ -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);
 
hw/ps2.c +1 -1
index f0b206a..886da37 100644
@@ -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;
 }
hw/pxa2xx_keypad.c +2 -1
index 060df58..2b75351 100644
@@ -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");
 }
hw/spitz.c +2 -1
index 564519b..b1c0af0 100644
@@ -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);
hw/stellaris_input.c +1 -1
index 33395a4..775cb46 100644
@@ -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);
 }
hw/syborg_keyboard.c +1 -1
index 4a562f8..d1651b4 100644
@@ -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);
hw/usb-hid.c +7 -3
index 8e6c6e0..dbab5d3 100644
@@ -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)
hw/xenfb.c +3 -2
index 422cd53..0c1d1ec 100644
@@ -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);
 }
 
input.c +41 -10

76 lines not on this page · raw message

Signature · 1 line
1.6.3.3
#6 lore raw

PATCH v3 2/2 Added monitor commands: 'keyboard_set' and 'info keybaord'

In reply to Shahar Havivi

Two new monitor commands: adding ability to handle which keyboard qemu will use and to see which keyboard are currently available.

$ info keyboard
$ keyboard_set <index>
---
 console.h       |    4 ++
 input.c         |  101 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 monitor.c       |    8 ++++
 qemu-monitor.hx |   17 +++++++++
 4 files changed, 130 insertions(+), 0 deletions(-)
console.h +4 -0
index 91b66ea..889f5d5 100644
@@ -87,6 +87,10 @@ void do_info_mice_print(Monitor *mon, const QObject *data);
 void do_info_mice(Monitor *mon, QObject **ret_data);
 void do_mouse_set(Monitor *mon, const QDict *qdict);
 
+void do_info_keyboard_print(Monitor *mon, const QObject *data);
+void do_info_keyboard(Monitor *mon, QObject **ret_data);
+int do_keyboard_set(Monitor *mon, const QDict *qdict, QObject **ret_data);
+
 /* keysym is a unicode code except for special keys (see QEMU_KEY_xxx
    constants) */
 #define QEMU_KEY_ESC1(c) ((c) | 0xe100)
input.c +101 -0

104 lines not on this page · raw message

monitor.c +8 -0
index 822dc27..f5474b1 100644
@@ -2781,6 +2781,14 @@ static const mon_cmd_t info_cmds[] = {
         .mhandler.info_new = do_info_mice,
     },
     {
+        .name       = "keyboard",
+        .args_type  = "",
+        .params     = "",
+        .help       = "show which guest keyboard is receiving events",
+        .user_print = do_info_keyboard_print,
+        .mhandler.info_new = do_info_keyboard,
+    },
+    {
         .name       = "vnc",
         .args_type  = "",
         .params     = "",
qemu-monitor.hx +17 -0
index 5308f36..e9beb12 100644
@@ -659,6 +659,23 @@ info mice
 @end example
 ETEXI
 
+    {
+        .name       = "keyboard_set",
+        .args_type  = "index:i",
+        .params     = "index",
+        .help       = "set which keyboard device receives events",
+        .mhandler.cmd_new = do_keyboard_set,
+    },
+
+STEXI
+@item keyboard_set @var{index}
+@findex keyboard_set
+Set which keyboard device receives events at given @var{index}, index
+can be obtained with
+@example
+info keyboard
+@end example
+ETEXI
 #ifdef HAS_AUDIO
     {
         .name       = "wavcapture",
Signature · 1 line
1.6.3.3
#7 lore raw

[Qemu-devel] Re: [PATCH 2/2] Added monitor commands: 'keyboard_set' and 'info keybaord'

input.c void qemu_remove_mouse_mode_change_notifier(Notifier *notify) · line 415

Quoted 8 lines · Shahar Havivi

Two new monitor commands: adding ability to handle which keyboard qemu will use and to see which keyboard are currently available.

input.c +5 -0
+int do_keyboard_set(Monitor *mon, const QDict *qdict, QObject **ret_data)
+{
+    QEMUPutKbdEntry *cursor;
+    int index = qdict_get_int(qdict, "index");
+    int found = 0;

found variable is not used.

input.c void qemu_remove_mouse_mode_change_notifier(Notifier *notify) · line 426

Quoted 11 lines
input.c +11 -0
+
+    if (QTAILQ_EMPTY(&kbd_handlers)) {
+        qerror_report(QERR_DEVICE_NOT_FOUND, "keyboard");
+        return -1;
+    }
+
+    QTAILQ_FOREACH(cursor, &kbd_handlers, node) {
+        if (cursor->index == index) {
+            QTAILQ_REMOVE(&kbd_handlers, cursor, node);
+            QTAILQ_INSERT_HEAD(&kbd_handlers, cursor, node);
+            found = 1;

well it is set :)

input.c void qemu_remove_mouse_mode_change_notifier(Notifier *notify) · line 431

Quoted 5 lines
input.c +5 -0
+            break;
+        }
+    }
+
+    return 0;

I guess you want to return one error if the index don't exist.

Quoted 1 line

+}

I still think that adding an "id" property as in markus proposal would be neat. Otherwise I don't know how you are going to distinguish between two keyboards with the same name.

Later, Juan.

#8 lore raw

Re: [Qemu-devel] Re: [PATCH 2/2] Added monitor commands: 'keyboard_set' and 'info keybaord'

Quoted 32 lines · Juan Quintela

input.c void qemu_remove_mouse_mode_change_notifier(Notifier *notify) · line 415

Quoted 8 lines · Shahar Havivi

Two new monitor commands: adding ability to handle which keyboard qemu will use and to see which keyboard are currently available.

input.c +5 -0
+int do_keyboard_set(Monitor *mon, const QDict *qdict, QObject **ret_data)
+{
+    QEMUPutKbdEntry *cursor;
+    int index = qdict_get_int(qdict, "index");
+    int found = 0;

found variable is not used.

input.c void qemu_remove_mouse_mode_change_notifier(Notifier *notify) · line 426

Quoted 11 lines
input.c +11 -0
+
+    if (QTAILQ_EMPTY(&kbd_handlers)) {
+        qerror_report(QERR_DEVICE_NOT_FOUND, "keyboard");
+        return -1;
+    }
+
+    QTAILQ_FOREACH(cursor, &kbd_handlers, node) {
+        if (cursor->index == index) {
+            QTAILQ_REMOVE(&kbd_handlers, cursor, node);
+            QTAILQ_INSERT_HEAD(&kbd_handlers, cursor, node);
+            found = 1;

well it is set :)

input.c void qemu_remove_mouse_mode_change_notifier(Notifier *notify) · line 431

Quoted 5 lines
input.c +5 -0
+            break;
+        }
+    }
+
+    return 0;
Quoted 7 lines

I guess you want to return one error if the index don't exist.

Quoted 1 line

+}

I still think that adding an "id" property as in markus proposal would be neat. Otherwise I don't know how you are going to distinguish between two keyboards with the same name.

If I understand the patch correctly (only time for a quick skim today), the keyboard receives a numeric ID when it is created, and keyboard_set identifies it by that ID. Yes, a user-defined ID would be nicer, and consistent with how similar things work. But the numeric ID isn't *wrong*, as far as I can see.

#9 lore raw

Re: [Qemu-devel] Re: [PATCH 2/2] Added monitor commands: 'keyboard_set' and 'info keybaord'

Quoted 7 lines · Markus Armbruster

Date: Wed, 31 Mar 2010 17:31:49 +0200
From: Markus Armbruster <[email protected]>
To: Juan Quintela <[email protected]>
Cc: Shahar Havivi <[email protected]>, [email protected]
Subject: Re: [Qemu-devel] Re: [PATCH 2/2] Added monitor commands:
'keyboard_set' and 'info keybaord'

Quoted 35 lines
Quoted 33 lines · Juan Quintela

Review

Quoted 8 lines · Shahar Havivi

Two new monitor commands: adding ability to handle which keyboard qemu will use and to see which keyboard are currently available.

(quoted diff) +5 -0
+int do_keyboard_set(Monitor *mon, const QDict *qdict, QObject **ret_data)
+{
+    QEMUPutKbdEntry *cursor;
+    int index = qdict_get_int(qdict, "index");
+    int found = 0;

found variable is not used.

Review

Quoted 11 lines
(quoted diff) +11 -0
+
+    if (QTAILQ_EMPTY(&kbd_handlers)) {
+        qerror_report(QERR_DEVICE_NOT_FOUND, "keyboard");
+        return -1;
+    }
+
+    QTAILQ_FOREACH(cursor, &kbd_handlers, node) {
+        if (cursor->index == index) {
+            QTAILQ_REMOVE(&kbd_handlers, cursor, node);
+            QTAILQ_INSERT_HEAD(&kbd_handlers, cursor, node);
+            found = 1;

well it is set :)

Review

Quoted 5 lines
(quoted diff) +5 -0
+            break;
+        }
+    }
+
+    return 0;

I guess you want to return one error if the index don't exist.

Right about that, Thanks.

Quoted 11 lines
Quoted 5 lines
Quoted 1 line

+}

I still think that adding an "id" property as in markus proposal would be neat. Otherwise I don't know how you are going to distinguish between two keyboards with the same name.

If I understand the patch correctly (only time for a quick skim today), the keyboard receives a numeric ID when it is created, and keyboard_set identifies it by that ID. Yes, a user-defined ID would be nicer, and consistent with how similar things work. But the numeric ID isn't *wrong*, as far as I can see.

The index Id that I use is the same as I saw that the mouse devices do, I will try to get it from the user as well (I guess you mean by command
line: 'qemu -device usb-kbd,id=kbd ...')

---
 console.h       |    4 ++
 input.c         |  106 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 monitor.c       |    8 ++++
 qemu-monitor.hx |   17 +++++++++
 4 files changed, 135 insertions(+), 0 deletions(-)
console.h +4 -0
index 91b66ea..889f5d5 100644
@@ -87,6 +87,10 @@ void do_info_mice_print(Monitor *mon, const QObject *data);
 void do_info_mice(Monitor *mon, QObject **ret_data);
 void do_mouse_set(Monitor *mon, const QDict *qdict);
 
+void do_info_keyboard_print(Monitor *mon, const QObject *data);
+void do_info_keyboard(Monitor *mon, QObject **ret_data);
+int do_keyboard_set(Monitor *mon, const QDict *qdict, QObject **ret_data);
+
 /* keysym is a unicode code except for special keys (see QEMU_KEY_xxx
    constants) */
 #define QEMU_KEY_ESC1(c) ((c) | 0xe100)
input.c +106 -0

109 lines not on this page · raw message

monitor.c +8 -0
index 822dc27..f5474b1 100644
@@ -2781,6 +2781,14 @@ static const mon_cmd_t info_cmds[] = {
         .mhandler.info_new = do_info_mice,
     },
     {
+        .name       = "keyboard",
+        .args_type  = "",
+        .params     = "",
+        .help       = "show which guest keyboard is receiving events",
+        .user_print = do_info_keyboard_print,
+        .mhandler.info_new = do_info_keyboard,
+    },
+    {
         .name       = "vnc",
         .args_type  = "",
         .params     = "",
qemu-monitor.hx +17 -0
index 5308f36..e9beb12 100644
@@ -659,6 +659,23 @@ info mice
 @end example
 ETEXI
 
+    {
+        .name       = "keyboard_set",
+        .args_type  = "index:i",
+        .params     = "index",
+        .help       = "set which keyboard device receives events",
+        .mhandler.cmd_new = do_keyboard_set,
+    },
+
+STEXI
+@item keyboard_set @var{index}
+@findex keyboard_set
+Set which keyboard device receives events at given @var{index}, index
+can be obtained with
+@example
+info keyboard
+@end example
+ETEXI
 #ifdef HAS_AUDIO
     {
         .name       = "wavcapture",
Signature · 1 line
1.6.3.3
#10 lore raw

[Qemu-devel] Re: [PATCH 2/2] Added monitor commands: 'keyboard_set' and 'info keybaord'

In reply to Markus Armbruster
Quoted 10 lines · Markus Armbruster
Quoted 3 lines · Juan Quintela

I still think that adding an "id" property as in markus proposal would be neat. Otherwise I don't know how you are going to distinguish between two keyboards with the same name.

If I understand the patch correctly (only time for a quick skim today), the keyboard receives a numeric ID when it is created, and keyboard_set identifies it by that ID. Yes, a user-defined ID would be nicer, and consistent with how similar things work. But the numeric ID isn't *wrong*, as far as I can see.

my problem is that if you add two keyboards of the same type, they will receive random index (different ones), now you do info keyboard, and you see two keyboard with the same names and different numbers, how do you know which of the two given you want to choose?

And no, I don't have magic bullet to make multimonitor/keyboard/mouse behave as expected out of given them right id's.

Later, Juan.

#11 lore raw

Re: [Qemu-devel] Re: [PATCH 2/2] Added monitor commands: 'keyboard_set' and 'info keybaord'

Quoted 24 lines · Juan Quintela

Date: Wed, 31 Mar 2010 18:58:14 +0200
From: Juan Quintela <[email protected]>
To: Markus Armbruster <[email protected]>
Cc: Shahar Havivi <[email protected]>, [email protected]
Subject: [Qemu-devel] Re: [PATCH 2/2] Added monitor commands: 'keyboard_set'
and 'info keybaord'

Quoted 10 lines · Markus Armbruster
Quoted 3 lines · Juan Quintela

I still think that adding an "id" property as in markus proposal would be neat. Otherwise I don't know how you are going to distinguish between two keyboards with the same name.

If I understand the patch correctly (only time for a quick skim today), the keyboard receives a numeric ID when it is created, and keyboard_set identifies it by that ID. Yes, a user-defined ID would be nicer, and consistent with how similar things work. But the numeric ID isn't *wrong*, as far as I can see.

my problem is that if you add two keyboards of the same type, they will receive random index (different ones), now you do info keyboard, and you see two keyboard with the same names and different numbers, how do you know which of the two given you want to choose?

Quoted 4 lines

And no, I don't have magic bullet to make multimonitor/keyboard/mouse behave as expected out of given them right id's.

Later, Juan.

You right, this is a problem.
As I see it id cannot be force to receive by the user right?

Thanks, Shahar.

#12 lore raw

Re: [Qemu-devel] Re: [PATCH 2/2] Added monitor commands: 'keyboard_set' and 'info keybaord'

Quoted 28 lines · Shahar Havivi
Quoted 26 lines · Juan Quintela

Date: Wed, 31 Mar 2010 18:58:14 +0200
From: Juan Quintela<[email protected]>
To: Markus Armbruster<[email protected]>
Cc: Shahar Havivi<[email protected]>, [email protected]
Subject: [Qemu-devel] Re: [PATCH 2/2] Added monitor commands: 'keyboard_set'
and 'info keybaord'

Quoted 6 lines · Markus Armbruster
Quoted 4 lines · Juan Quintela

I still think that adding an "id" property as in markus proposal would be neat. Otherwise I don't know how you are going to distinguish between two keyboards with the same name.

Quoted 6 lines

If I understand the patch correctly (only time for a quick skim today), the keyboard receives a numeric ID when it is created, and keyboard_set identifies it by that ID. Yes, a user-defined ID would be nicer, and consistent with how similar things work. But the numeric ID isn't *wrong*, as far as I can see.

my problem is that if you add two keyboards of the same type, they will receive random index (different ones), now you do info keyboard, and you see two keyboard with the same names and different numbers, how do you know which of the two given you want to choose?

Quoted 8 lines
Quoted 5 lines

And no, I don't have magic bullet to make multimonitor/keyboard/mouse behave as expected out of given them right id's.

Later, Juan.

You right, this is a problem.
As I see it id cannot be force to receive by the user right?

This is already the case with the mouse.

Ultimately, I don't think it's a useful problem to attempt to solve. Why would there every be two keyboards of the same type (or two mice)?

Regards,

Anthony Liguori

Quoted 4 lines

Thanks, Shahar.

#13 lore raw

[Qemu-devel] Re: [PATCH 2/2] Added monitor commands: 'keyboard_set' and 'info keybaord'

Quoted 34 lines · Anthony Liguori
Quoted 33 lines · Shahar Havivi
Quoted 31 lines · Juan Quintela

Date: Wed, 31 Mar 2010 18:58:14 +0200
From: Juan Quintela<[email protected]>
To: Markus Armbruster<[email protected]>
Cc: Shahar Havivi<[email protected]>, [email protected]
Subject: [Qemu-devel] Re: [PATCH 2/2] Added monitor commands: 'keyboard_set'
and 'info keybaord'

Quoted 6 lines · Markus Armbruster
Quoted 4 lines · Juan Quintela

I still think that adding an "id" property as in markus proposal would be neat. Otherwise I don't know how you are going to distinguish between two keyboards with the same name.

Quoted 6 lines

If I understand the patch correctly (only time for a quick skim today), the keyboard receives a numeric ID when it is created, and keyboard_set identifies it by that ID. Yes, a user-defined ID would be nicer, and consistent with how similar things work. But the numeric ID isn't *wrong*, as far as I can see.

my problem is that if you add two keyboards of the same type, they will receive random index (different ones), now you do info keyboard, and you see two keyboard with the same names and different numbers, how do you know which of the two given you want to choose?

And no, I don't have magic bullet to make multimonitor/keyboard/mouse behave as expected out of given them right id's.

Later, Juan.

Quoted 8 lines
Quoted 3 lines

You right, this is a problem.
As I see it id cannot be force to receive by the user right?

This is already the case with the mouse.

Ultimately, I don't think it's a useful problem to attempt to solve. Why would there every be two keyboards of the same type (or two mice)?

I don't understand why somebody will want multiscreen+mouse+keyboard.

Once told that, if having more than one of any of them, then it is better that keyboard_set

/*
* do_keyboard_set(): Set active keyboard
*
* Argument qdict contains
* - "index": the keyboard index to set

should take as a keyboard the string identifier and be done with that? Instead of all this bussines of numbering/renumbering during hot [un]plug?

Later, Juan.

#14 lore raw

Re: [Qemu-devel] Re: [PATCH 2/2] Added monitor commands: 'keyboard_set' and 'info keybaord'

In reply to Juan Quintela
Quoted 15 lines · Juan Quintela

input.c void qemu_remove_mouse_mode_change_notifier(Notifier *notify) · line 415

Quoted 10 lines · Shahar Havivi

Two new monitor commands: adding ability to handle which keyboard qemu will use and to see which keyboard are currently available.

input.c +5 -0
+int do_keyboard_set(Monitor *mon, const QDict *qdict, QObject **ret_data)
+{
+    QEMUPutKbdEntry *cursor;
+    int index = qdict_get_int(qdict, "index");
+    int found = 0;

found variable is not used.

Quoted 14 lines

input.c void qemu_remove_mouse_mode_change_notifier(Notifier *notify) · line 426

Quoted 12 lines
input.c +11 -0
+
+    if (QTAILQ_EMPTY(&kbd_handlers)) {
+        qerror_report(QERR_DEVICE_NOT_FOUND, "keyboard");
+        return -1;
+    }
+
+    QTAILQ_FOREACH(cursor,&kbd_handlers, node) {
+        if (cursor->index == index) {
+            QTAILQ_REMOVE(&kbd_handlers, cursor, node);
+            QTAILQ_INSERT_HEAD(&kbd_handlers, cursor, node);
+            found = 1;

well it is set :)

Please split out this bit into a qemu_activate_keyboard_handler() and plumb it with the usb device such that it's only used when a guest loads a driver for it.

It should be very symmetric to how the mouse driver works.

Regards,

Anthony Liguori

Quoted 19 lines

input.c void qemu_remove_mouse_mode_change_notifier(Notifier *notify) · line 431

Quoted 6 lines
input.c +5 -0
+            break;
+        }
+    }
+
+    return 0;

I guess you want to return one error if the index don't exist.

Quoted 2 lines

+}

I still think that adding an "id" property as in markus proposal would be neat. Otherwise I don't know how you are going to distinguish between two keyboards with the same name.

Later, Juan.

#15 lore raw

Re: [Qemu-devel] Re: [PATCH 2/2] Added monitor commands: 'keyboard_set' and 'info keybaord'

Quoted 17 lines
Quoted 4 lines
Quoted 4 lines
(quoted diff) +4 -0
+
+    if (QTAILQ_EMPTY(&kbd_handlers)) {
+        qerror_report(QERR_DEVICE_NOT_FOUND, "keyboard");
+        return -1;
Quoted 8 lines

Review

Quoted 7 lines
(quoted diff) +7 -0
+    }
+
+    QTAILQ_FOREACH(cursor,&kbd_handlers, node) {
+        if (cursor->index == index) {
+            QTAILQ_REMOVE(&kbd_handlers, cursor, node);
+            QTAILQ_INSERT_HEAD(&kbd_handlers, cursor, node);
+            found = 1;

well it is set :)

Please split out this bit into a qemu_activate_keyboard_handler() and plumb it with the usb device such that it's only used when a guest loads a driver for it.

Quoted 5 lines

It should be very symmetric to how the mouse driver works.

Regards,

Anthony Liguori

Anthony,

Added qemu_activate_keyboard_event_handler, and use it with usb_keyboard_poll. I test it with two usb keyboard devices, the last connected one is active.

Shahar.

---
 console.h       |    5 ++
 hw/usb-hid.c    |    6 +++
 input.c         |  111 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 monitor.c       |    8 ++++
 qemu-monitor.hx |   17 ++++++++
 5 files changed, 147 insertions(+), 0 deletions(-)
console.h +5 -0
index 91b66ea..5d68cff 100644
@@ -54,6 +54,7 @@ QEMUPutKbdEntry *qemu_add_kbd_event_handler(QEMUPutKBDEvent *func,
                                             void *opaque,
                                             const char *name);
 void qemu_remove_kbd_event_handler(QEMUPutKbdEntry *entry);
+void qemu_activate_keyboard_event_handler(QEMUPutKbdEntry *entry);
 QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func,
                                                 void *opaque, int absolute,
                                                 const char *name);
@@ -87,6 +88,10 @@ void do_info_mice_print(Monitor *mon, const QObject *data);
 void do_info_mice(Monitor *mon, QObject **ret_data);
 void do_mouse_set(Monitor *mon, const QDict *qdict);
 
+void do_info_keyboard_print(Monitor *mon, const QObject *data);
+void do_info_keyboard(Monitor *mon, QObject **ret_data);
+int do_keyboard_set(Monitor *mon, const QDict *qdict, QObject **ret_data);
+
 /* keysym is a unicode code except for special keys (see QEMU_KEY_xxx
    constants) */
 #define QEMU_KEY_ESC1(c) ((c) | 0xe100)
hw/usb-hid.c +6 -0
index dbab5d3..88ef36c 100644
@@ -55,6 +55,7 @@ typedef struct USBKeyboardState {
     uint8_t leds;
     uint8_t key[16];
     int keys;
+    int keyboard_grabbed;
     QEMUPutKbdEntry *eh_entry;
 } USBKeyboardState;
 
@@ -586,6 +587,11 @@ static int usb_keyboard_poll(USBKeyboardState *s, uint8_t *buf, int len)
     if (len < 2)
         return 0;
 
+    if (!s->keyboard_grabbed) {
+        qemu_activate_keyboard_event_handler(s->eh_entry);
+        s->keyboard_grabbed = 1;
+    }
+
     buf[0] = s->modifiers & 0xff;
     buf[1] = 0;
     if (s->keys > 6)
input.c +111 -0

114 lines not on this page · raw message

monitor.c +8 -0
index 822dc27..f5474b1 100644
@@ -2781,6 +2781,14 @@ static const mon_cmd_t info_cmds[] = {
         .mhandler.info_new = do_info_mice,
     },
     {
+        .name       = "keyboard",
+        .args_type  = "",
+        .params     = "",
+        .help       = "show which guest keyboard is receiving events",
+        .user_print = do_info_keyboard_print,
+        .mhandler.info_new = do_info_keyboard,
+    },
+    {
         .name       = "vnc",
         .args_type  = "",
         .params     = "",
qemu-monitor.hx +17 -0
index 5308f36..e9beb12 100644
@@ -659,6 +659,23 @@ info mice
 @end example
 ETEXI
 
+    {
+        .name       = "keyboard_set",
+        .args_type  = "index:i",
+        .params     = "index",
+        .help       = "set which keyboard device receives events",
+        .mhandler.cmd_new = do_keyboard_set,
+    },
+
+STEXI
+@item keyboard_set @var{index}
+@findex keyboard_set
+Set which keyboard device receives events at given @var{index}, index
+can be obtained with
+@example
+info keyboard
+@end example
+ETEXI
 #ifdef HAS_AUDIO
     {
         .name       = "wavcapture",
Signature · 1 line
1.6.3.3