Skip to contentSkip to conversation

Qemu support for multiple keyboard devices

PATCH Applied Shahar Havivi 4 participants 7 messages Apr 18, 2010 – Apr 29, 2011

v4 of 5 Applied Latest is v5 →

lore
Share & tools
lore
#0 lore raw

v4 cover Qemu support for multiple keyboard devices

v4:
Patch #1 Xen keyboard, added QEMUPutKbdEntry to XenInput in order to properly
remove when disconnected (Juan Quintela comment).
Rename mouse_index to index (Markus Armbruster comment).

Patch #2 Remove un-used variable (Juan Quintela comment).
Split do_keyboard_set() to qemu_activate_keyboard_event_handler(), for polling via usb_keyboard_poll() will set the current keyboard (Anthony Liguori comment).

Open issue:
Set user define id property instead of index based keyboard (mice as well).

Qemu support for multiple keyboard devices:
Patch #1 adding keyboard is done to qemu tail queue instead of
"last added keyboard wins",
when removing keyboard via device_del - prev 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
Two new monitor commands: 'info keyboard', 'keyboard_set'

 console.h            |   19 ++++++-
 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         |   16 ++++-
 hw/xenfb.c           |    5 +-
 input.c              |  162 ++++++++++++++++++++++++++++++++++++++++++++++---
 monitor.c            |    8 +++
 qemu-monitor.hx      |   17 +++++
 16 files changed, 225 insertions(+), 27 deletions(-)
#1 lore raw

PATCH v4 1/2 Support for multiple keyboard devices

Patch add QEMUPutKbdEntry structure - handling each keyboard entry, the structure handled by qemu tail queue.
Adding a new keyboard add to the list and select it, 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           |    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
#2 lore raw

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

Quoted 7 lines · Shahar Havivi

Patch add QEMUPutKbdEntry structure - handling each keyboard entry, the structure handled by qemu tail queue.
Adding a new keyboard add to the list and select it, removing keyboard select the previous keyboard in list.

Applied all. Thanks.

Regards,

Anthony Liguori

Quoted 332 lines
---
  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
index 8f0941e..18875a9 100644
@@ -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 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 = 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)
#3 lore raw

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

Quoted 13 lines · Anthony Liguori

Date: Mon, 10 May 2010 15:18:29 -0500
From: Anthony Liguori <[email protected]>
To: Shahar Havivi <[email protected]>
CC: [email protected]
Subject: Re: [Qemu-devel] [PATCH 1/2 v4] Support for multiple keyboard
devices

Quoted 5 lines · Shahar Havivi

Patch add QEMUPutKbdEntry structure - handling each keyboard entry, the structure handled by qemu tail queue.
Adding a new keyboard add to the list and select it, removing keyboard select the previous keyboard in list.

Quoted 8 lines
Quoted 1 line

Applied all. Thanks.

Regards,

Anthony Liguori

Anthony, I don't think that you applied this changes, Thanks
Shahar Havivi.

Quoted 332 lines
Quoted 331 lines
---
 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
index 8f0941e..18875a9 100644
@@ -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 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 = 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)
#4 lore raw

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

In reply to Anthony Liguori
Quoted 9 lines · Anthony Liguori
Quoted 6 lines · Shahar Havivi

Patch add QEMUPutKbdEntry structure - handling each keyboard entry, the structure handled by qemu tail queue.
Adding a new keyboard add to the list and select it, removing keyboard select the previous keyboard in list.

Applied all. Thanks.

Hello. What happened to this patchset? Seems like it didn't make to the trunk. Were there any objections not discussed on the list? If there are no objections I'll update these patches and resend them. Is it OK?

Regards,
Dmitry

Quoted 345 lines

Regards,

Anthony Liguori

Quoted 337 lines
---
  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 +2 -8
index 8f0941e..18875a9 100644
@@ -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;
input.c +39 -2
@@ -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 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 = 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)
#5 lore raw

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

Fine with me

Quoted 355 lines · Dmitry Zhurikhin
Quoted 9 lines · Anthony Liguori
Quoted 6 lines · Shahar Havivi

Patch add QEMUPutKbdEntry structure - handling each keyboard entry, the structure handled by qemu tail queue.
Adding a new keyboard add to the list and select it, removing keyboard select the previous keyboard in list.

Applied all. Thanks.

Hello. What happened to this patchset? Seems like it didn't make to the trunk. Were there any objections not discussed on the list? If there are no objections I'll update these patches and resend them. Is it OK?

Regards,
Dmitry

Quoted 339 lines

Regards,

Anthony Liguori

Quoted 331 lines
---
 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
index 8f0941e..18875a9 100644
@@ -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 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 = 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)
#6 lore raw

PATCH v4 2/2 Two new monitor commands: 'info keyboard', 'keyboard_set'

In reply to Shahar Havivi

Adding ability to handle which keyboard qemu will use and to see which keyboard are currently available.

$ info keyboard
$ keyboard_set <index>
---
 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 5659991..35885f4 100644
@@ -2696,6 +2696,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