* [Qemu-devel] [PATCH 1/2] Support for multiple keyboard devices
2010-03-19 10:57 [Qemu-devel] [PATCH 0/2] Qemu support " Shahar Havivi
@ 2010-03-19 10:57 ` Shahar Havivi
0 siblings, 0 replies; 22+ messages in thread
From: Shahar Havivi @ 2010-03-19 10:57 UTC (permalink / raw)
To: qemu-devel; +Cc: Dor Laor
Currently you get segfault when trying to remove keyboard because no
keyboard handling is done.
This patch add keyboard list similar to the mouse device handlers.
Adding a keyboard add to the list, removing keyboard select the next
keyboard in list, and not leaving the keyboard handlers un-handled.
Signed-off-by: Shahar Havivi <shaharh@redhat.com>
---
console.h | 16 +++++++++-
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 | 2 +-
hw/spitz.c | 2 +-
hw/stellaris_input.c | 2 +-
hw/syborg_keyboard.c | 2 +-
hw/usb-hid.c | 10 ++++--
hw/xenfb.c | 4 +-
input.c | 84 +++++++++++++++++++++++++++++++++++++++++++++----
14 files changed, 113 insertions(+), 24 deletions(-)
diff --git a/console.h b/console.h
index 71e8ff2..56d0bbc 100644
--- a/console.h
+++ b/console.h
@@ -38,7 +38,17 @@ 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;
+ struct QEMUPutKbdEntry *next;
+} 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);
@@ -63,6 +73,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);
+void do_keyboard_set(Monitor *mon, const QDict *qdict);
+
/* keysym is a unicode code except for special keys (see QEMU_KEY_xxx
constants) */
#define QEMU_KEY_ESC1(c) ((c) | 0xe100)
diff --git a/hw/adb.c b/hw/adb.c
index 4fb7a62..09afcf9 100644
--- a/hw/adb.c
+++ b/hw/adb.c
@@ -304,7 +304,7 @@ void adb_kbd_init(ADBBusState *bus)
s = qemu_mallocz(sizeof(KBDState));
d = adb_register_device(bus, ADB_KEYBOARD, adb_kbd_request,
adb_kbd_reset, s);
- qemu_add_kbd_event_handler(adb_kbd_put_keycode, d);
+ qemu_add_kbd_event_handler(adb_kbd_put_keycode, d, "adb");
register_savevm("adb_kbd", -1, 1, adb_kbd_save,
adb_kbd_load, s);
}
diff --git a/hw/escc.c b/hw/escc.c
index 6d2fd36..2b21d98 100644
--- a/hw/escc.c
+++ b/hw/escc.c
@@ -919,7 +919,8 @@ static int escc_init1(SysBusDevice *dev)
"QEMU Sun Mouse");
}
if (s->chn[1].type == kbd) {
- qemu_add_kbd_event_handler(sunkbd_event, &s->chn[1]);
+ qemu_add_kbd_event_handler(sunkbd_event, &s->chn[1],
+ "QEMU Sun Keyboard");
}
return 0;
diff --git a/hw/musicpal.c b/hw/musicpal.c
index b8af15e..166d1b0 100644
--- a/hw/musicpal.c
+++ b/hw/musicpal.c
@@ -1447,7 +1447,7 @@ static int musicpal_key_init(SysBusDevice *dev)
qdev_init_gpio_out(&dev->qdev, s->out, ARRAY_SIZE(s->out));
- qemu_add_kbd_event_handler(musicpal_key_event, s);
+ qemu_add_kbd_event_handler(musicpal_key_event, s, "Musicpal");
return 0;
}
diff --git a/hw/nseries.c b/hw/nseries.c
index 0273eee..abfcec3 100644
--- a/hw/nseries.c
+++ b/hw/nseries.c
@@ -262,7 +262,7 @@ static void n800_tsc_kbd_setup(struct n800_s *s)
if (n800_keys[i] >= 0)
s->keymap[n800_keys[i]] = i;
- qemu_add_kbd_event_handler(n800_key_event, s);
+ qemu_add_kbd_event_handler(n800_key_event, s, "Nokia n800");
tsc210x_set_transform(s->ts.chip, &n800_pointercal);
}
@@ -371,7 +371,7 @@ static void n810_kbd_setup(struct n800_s *s)
if (n810_keys[i] > 0)
s->keymap[n810_keys[i]] = i;
- qemu_add_kbd_event_handler(n810_key_event, s);
+ qemu_add_kbd_event_handler(n810_key_event, s, "Nokia n810");
/* Attach the LM8322 keyboard to the I2C bus,
* should happen in n8x0_i2c_setup and s->kbd be initialised here. */
diff --git a/hw/palm.c b/hw/palm.c
index 6d19167..1b405d4 100644
--- a/hw/palm.c
+++ b/hw/palm.c
@@ -228,7 +228,7 @@ static void palmte_init(ram_addr_t ram_size,
palmte_microwire_setup(cpu);
- qemu_add_kbd_event_handler(palmte_button_event, cpu);
+ qemu_add_kbd_event_handler(palmte_button_event, cpu, "Palm Keyboard");
palmte_gpio_setup(cpu);
diff --git a/hw/ps2.c b/hw/ps2.c
index f0b206a..886da37 100644
--- a/hw/ps2.c
+++ b/hw/ps2.c
@@ -596,7 +596,7 @@ void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg)
s->common.update_arg = update_arg;
s->scancode_set = 2;
vmstate_register(0, &vmstate_ps2_keyboard, s);
- qemu_add_kbd_event_handler(ps2_put_keycode, s);
+ qemu_add_kbd_event_handler(ps2_put_keycode, s, "QEMU PS/2 Keyboard");
qemu_register_reset(ps2_kbd_reset, s);
return s;
}
diff --git a/hw/pxa2xx_keypad.c b/hw/pxa2xx_keypad.c
index 060df58..7fa5af9 100644
--- a/hw/pxa2xx_keypad.c
+++ b/hw/pxa2xx_keypad.c
@@ -332,5 +332,5 @@ void pxa27x_register_keypad(PXA2xxKeyPadState *kp, struct keymap *map,
}
kp->map = map;
- qemu_add_kbd_event_handler((QEMUPutKBDEvent *) pxa27x_keyboard_event, kp);
+ qemu_add_kbd_event_handler((QEMUPutKBDEvent *) pxa27x_keyboard_event, kp, "PXA keypad");
}
diff --git a/hw/spitz.c b/hw/spitz.c
index 564519b..64e8a6e 100644
--- a/hw/spitz.c
+++ b/hw/spitz.c
@@ -506,7 +506,7 @@ static void spitz_keyboard_register(PXA2xxState *cpu)
pxa2xx_gpio_out_set(cpu->gpio, spitz_gpio_key_strobe[i], s->strobe[i]);
spitz_keyboard_pre_map(s);
- qemu_add_kbd_event_handler((QEMUPutKBDEvent *) spitz_keyboard_handler, s);
+ qemu_add_kbd_event_handler((QEMUPutKBDEvent *) spitz_keyboard_handler, s, "Spitz keyboard");
register_savevm("spitz_keyboard", 0, 0,
spitz_keyboard_save, spitz_keyboard_load, s);
diff --git a/hw/stellaris_input.c b/hw/stellaris_input.c
index 33395a4..775cb46 100644
--- a/hw/stellaris_input.c
+++ b/hw/stellaris_input.c
@@ -85,7 +85,7 @@ void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode)
s->buttons[i].keycode = keycode[i];
}
s->num_buttons = n;
- qemu_add_kbd_event_handler(stellaris_gamepad_put_key, s);
+ qemu_add_kbd_event_handler(stellaris_gamepad_put_key, s, "Stellaris Gamepad");
register_savevm("stellaris_gamepad", -1, 1,
stellaris_gamepad_save, stellaris_gamepad_load, s);
}
diff --git a/hw/syborg_keyboard.c b/hw/syborg_keyboard.c
index 4a562f8..d1651b4 100644
--- a/hw/syborg_keyboard.c
+++ b/hw/syborg_keyboard.c
@@ -218,7 +218,7 @@ static int syborg_keyboard_init(SysBusDevice *dev)
}
s->key_fifo = qemu_mallocz(s->fifo_size * sizeof(s->key_fifo[0]));
- qemu_add_kbd_event_handler(syborg_keyboard_event, s);
+ qemu_add_kbd_event_handler(syborg_keyboard_event, s, "Syborg Keyboard");
register_savevm("syborg_keyboard", -1, 1,
syborg_keyboard_save, syborg_keyboard_load, s);
diff --git a/hw/usb-hid.c b/hw/usb-hid.c
index 2e4e647..078a536 100644
--- a/hw/usb-hid.c
+++ b/hw/usb-hid.c
@@ -55,6 +55,7 @@ typedef struct USBKeyboardState {
uint8_t leds;
uint8_t key[16];
int keys;
+ QEMUPutKbdEntry *eh_entry;
} USBKeyboardState;
typedef struct USBHIDState {
@@ -635,7 +636,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;
}
@@ -856,9 +858,11 @@ static void usb_hid_handle_destroy(USBDevice *dev)
{
USBHIDState *s = (USBHIDState *)dev;
- if (s->kind != USB_KEYBOARD)
+ if (s->kind != USB_KEYBOARD) {
qemu_remove_mouse_event_handler(s->ptr.eh_entry);
- /* TODO: else */
+ } else {
+ qemu_remove_kbd_event_handler(s->kbd.eh_entry);
+ }
}
static int usb_hid_initfn(USBDevice *dev, int kind)
diff --git a/hw/xenfb.c b/hw/xenfb.c
index 422cd53..2c700bd 100644
--- a/hw/xenfb.c
+++ b/hw/xenfb.c
@@ -373,7 +373,7 @@ static int input_connect(struct XenDevice *xendev)
if (rc != 0)
return rc;
- qemu_add_kbd_event_handler(xenfb_key_event, in);
+ qemu_add_kbd_event_handler(xenfb_key_event, in, "Xen Keyboard");
in->qmouse = qemu_add_mouse_event_handler(xenfb_mouse_event, in,
in->abs_pointer_wanted,
"Xen PVFB Mouse");
@@ -388,7 +388,7 @@ static void input_disconnect(struct XenDevice *xendev)
qemu_remove_mouse_event_handler(in->qmouse);
in->qmouse = NULL;
}
- qemu_add_kbd_event_handler(NULL, NULL);
+ qemu_add_kbd_event_handler(NULL, NULL, NULL);
common_unbind(&in->c);
}
diff --git a/input.c b/input.c
index baaa4c6..4b86f48 100644
--- a/input.c
+++ b/input.c
@@ -29,16 +29,85 @@
#include "qjson.h"
-static QEMUPutKBDEvent *qemu_put_kbd_event;
-static void *qemu_put_kbd_event_opaque;
+static QEMUPutKbdEntry *qemu_put_kbd_event_head;
+static QEMUPutKbdEntry *qemu_put_kbd_event_current;
static QEMUPutMouseEntry *qemu_put_mouse_event_head;
static QEMUPutMouseEntry *qemu_put_mouse_event_current;
static QTAILQ_HEAD(, QEMUPutLEDEntry) led_handlers = QTAILQ_HEAD_INITIALIZER(led_handlers);
-void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque)
+QEMUPutKbdEntry *qemu_add_kbd_event_handler(QEMUPutKBDEvent *func,
+ void *opaque,
+ const char *name)
{
- qemu_put_kbd_event_opaque = opaque;
- qemu_put_kbd_event = func;
+ QEMUPutKbdEntry *s, *cursor;
+
+ cursor = qemu_put_kbd_event_head;
+ while (cursor) {
+ if (cursor->qemu_put_kbd_event == func &&
+ cursor->qemu_put_kbd_event_opaque == opaque) {
+
+ qemu_put_kbd_event_current = cursor;
+ return cursor;
+ }
+ cursor = cursor->next;
+ }
+
+ 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->next = NULL;
+
+ if (!qemu_put_kbd_event_head) {
+ qemu_put_kbd_event_head = s;
+ qemu_put_kbd_event_current = s;
+ return s;
+ }
+
+ cursor = qemu_put_kbd_event_head;
+ while (cursor->next) {
+ cursor = cursor->next;
+ }
+
+ cursor->next = s;
+ qemu_put_kbd_event_current = s;
+
+ return s;
+}
+
+void qemu_remove_kbd_event_handler(QEMUPutKbdEntry *entry)
+{
+ QEMUPutKbdEntry *prev = NULL, *cursor;
+
+ if (!qemu_put_kbd_event_head || !entry) {
+ return;
+ }
+
+ cursor = qemu_put_kbd_event_head;
+ while (cursor && cursor != entry) {
+ prev = cursor;
+ cursor = cursor->next;
+ }
+
+ if (cursor == NULL) {
+ return;
+ } else if (prev == NULL) {
+ qemu_put_kbd_event_head = cursor->next;
+ if (qemu_put_kbd_event_current == entry) {
+ qemu_put_kbd_event_current = cursor->next;
+ }
+ qemu_free(entry);
+ return;
+ }
+
+ prev->next = entry->next;
+
+ if (qemu_put_kbd_event_current == entry) {
+ qemu_put_kbd_event_current = prev;
+ }
+
+ qemu_free(entry);
}
QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func,
@@ -126,8 +195,9 @@ 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);
+ if (qemu_put_kbd_event_current) {
+ qemu_put_kbd_event_current->qemu_put_kbd_event(
+ qemu_put_kbd_event_current->qemu_put_kbd_event_opaque, keycode);
}
}
--
1.6.3.3
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [Qemu-devel] [PATCH 1/2] Support for multiple keyboard devices
2010-03-23 19:57 [Qemu-devel] [PATCH 0/2] Qemu support for multiple keyboard devices - v2 Shahar Havivi
@ 2010-03-23 19:58 ` Shahar Havivi
2010-03-26 9:46 ` Markus Armbruster
0 siblings, 1 reply; 22+ messages in thread
From: Shahar Havivi @ 2010-03-23 19:58 UTC (permalink / raw)
To: qemu-devel
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.
Signed-off-by: Shahar Havivi <shaharh@redhat.com>
---
console.h | 12 ++++++-
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 | 2 +-
hw/spitz.c | 2 +-
hw/stellaris_input.c | 2 +-
hw/syborg_keyboard.c | 2 +-
hw/usb-hid.c | 10 ++++--
hw/xenfb.c | 4 +-
input.c | 90 ++++++++++++++++++++++++++++++++++++++++++++-----
14 files changed, 112 insertions(+), 27 deletions(-)
diff --git a/console.h b/console.h
index 6def115..16c9c3d 100644
--- a/console.h
+++ b/console.h
@@ -41,7 +41,17 @@ 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;
+ struct QEMUPutKbdEntry *next;
+} QEMUPutKbdEntry;
+
+QEMUPutKbdEntry *qemu_add_kbd_event_handler(QEMUPutKBDEvent *func,
+ void *opaque,
+ const char *name);
+void qemu_remove_kbd_event_handler(QEMUPutKbdEntry *entry);
QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func,
void *opaque, int absolute,
const char *name);
diff --git a/hw/adb.c b/hw/adb.c
index 4fb7a62..09afcf9 100644
--- a/hw/adb.c
+++ b/hw/adb.c
@@ -304,7 +304,7 @@ void adb_kbd_init(ADBBusState *bus)
s = qemu_mallocz(sizeof(KBDState));
d = adb_register_device(bus, ADB_KEYBOARD, adb_kbd_request,
adb_kbd_reset, s);
- qemu_add_kbd_event_handler(adb_kbd_put_keycode, d);
+ qemu_add_kbd_event_handler(adb_kbd_put_keycode, d, "adb");
register_savevm("adb_kbd", -1, 1, adb_kbd_save,
adb_kbd_load, s);
}
diff --git a/hw/escc.c b/hw/escc.c
index 6d2fd36..2b21d98 100644
--- a/hw/escc.c
+++ b/hw/escc.c
@@ -919,7 +919,8 @@ static int escc_init1(SysBusDevice *dev)
"QEMU Sun Mouse");
}
if (s->chn[1].type == kbd) {
- qemu_add_kbd_event_handler(sunkbd_event, &s->chn[1]);
+ qemu_add_kbd_event_handler(sunkbd_event, &s->chn[1],
+ "QEMU Sun Keyboard");
}
return 0;
diff --git a/hw/musicpal.c b/hw/musicpal.c
index 7fc9fb3..aca8a88 100644
--- a/hw/musicpal.c
+++ b/hw/musicpal.c
@@ -1447,7 +1447,7 @@ static int musicpal_key_init(SysBusDevice *dev)
qdev_init_gpio_out(&dev->qdev, s->out, ARRAY_SIZE(s->out));
- qemu_add_kbd_event_handler(musicpal_key_event, s);
+ qemu_add_kbd_event_handler(musicpal_key_event, s, "Musicpal");
return 0;
}
diff --git a/hw/nseries.c b/hw/nseries.c
index 0273eee..abfcec3 100644
--- a/hw/nseries.c
+++ b/hw/nseries.c
@@ -262,7 +262,7 @@ static void n800_tsc_kbd_setup(struct n800_s *s)
if (n800_keys[i] >= 0)
s->keymap[n800_keys[i]] = i;
- qemu_add_kbd_event_handler(n800_key_event, s);
+ qemu_add_kbd_event_handler(n800_key_event, s, "Nokia n800");
tsc210x_set_transform(s->ts.chip, &n800_pointercal);
}
@@ -371,7 +371,7 @@ static void n810_kbd_setup(struct n800_s *s)
if (n810_keys[i] > 0)
s->keymap[n810_keys[i]] = i;
- qemu_add_kbd_event_handler(n810_key_event, s);
+ qemu_add_kbd_event_handler(n810_key_event, s, "Nokia n810");
/* Attach the LM8322 keyboard to the I2C bus,
* should happen in n8x0_i2c_setup and s->kbd be initialised here. */
diff --git a/hw/palm.c b/hw/palm.c
index 6d19167..1b405d4 100644
--- a/hw/palm.c
+++ b/hw/palm.c
@@ -228,7 +228,7 @@ static void palmte_init(ram_addr_t ram_size,
palmte_microwire_setup(cpu);
- qemu_add_kbd_event_handler(palmte_button_event, cpu);
+ qemu_add_kbd_event_handler(palmte_button_event, cpu, "Palm Keyboard");
palmte_gpio_setup(cpu);
diff --git a/hw/ps2.c b/hw/ps2.c
index f0b206a..886da37 100644
--- a/hw/ps2.c
+++ b/hw/ps2.c
@@ -596,7 +596,7 @@ void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg)
s->common.update_arg = update_arg;
s->scancode_set = 2;
vmstate_register(0, &vmstate_ps2_keyboard, s);
- qemu_add_kbd_event_handler(ps2_put_keycode, s);
+ qemu_add_kbd_event_handler(ps2_put_keycode, s, "QEMU PS/2 Keyboard");
qemu_register_reset(ps2_kbd_reset, s);
return s;
}
diff --git a/hw/pxa2xx_keypad.c b/hw/pxa2xx_keypad.c
index 060df58..7fa5af9 100644
--- a/hw/pxa2xx_keypad.c
+++ b/hw/pxa2xx_keypad.c
@@ -332,5 +332,5 @@ void pxa27x_register_keypad(PXA2xxKeyPadState *kp, struct keymap *map,
}
kp->map = map;
- qemu_add_kbd_event_handler((QEMUPutKBDEvent *) pxa27x_keyboard_event, kp);
+ qemu_add_kbd_event_handler((QEMUPutKBDEvent *) pxa27x_keyboard_event, kp, "PXA keypad");
}
diff --git a/hw/spitz.c b/hw/spitz.c
index 564519b..64e8a6e 100644
--- a/hw/spitz.c
+++ b/hw/spitz.c
@@ -506,7 +506,7 @@ static void spitz_keyboard_register(PXA2xxState *cpu)
pxa2xx_gpio_out_set(cpu->gpio, spitz_gpio_key_strobe[i], s->strobe[i]);
spitz_keyboard_pre_map(s);
- qemu_add_kbd_event_handler((QEMUPutKBDEvent *) spitz_keyboard_handler, s);
+ qemu_add_kbd_event_handler((QEMUPutKBDEvent *) spitz_keyboard_handler, s, "Spitz keyboard");
register_savevm("spitz_keyboard", 0, 0,
spitz_keyboard_save, spitz_keyboard_load, s);
diff --git a/hw/stellaris_input.c b/hw/stellaris_input.c
index 33395a4..775cb46 100644
--- a/hw/stellaris_input.c
+++ b/hw/stellaris_input.c
@@ -85,7 +85,7 @@ void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode)
s->buttons[i].keycode = keycode[i];
}
s->num_buttons = n;
- qemu_add_kbd_event_handler(stellaris_gamepad_put_key, s);
+ qemu_add_kbd_event_handler(stellaris_gamepad_put_key, s, "Stellaris Gamepad");
register_savevm("stellaris_gamepad", -1, 1,
stellaris_gamepad_save, stellaris_gamepad_load, s);
}
diff --git a/hw/syborg_keyboard.c b/hw/syborg_keyboard.c
index 4a562f8..d1651b4 100644
--- a/hw/syborg_keyboard.c
+++ b/hw/syborg_keyboard.c
@@ -218,7 +218,7 @@ static int syborg_keyboard_init(SysBusDevice *dev)
}
s->key_fifo = qemu_mallocz(s->fifo_size * sizeof(s->key_fifo[0]));
- qemu_add_kbd_event_handler(syborg_keyboard_event, s);
+ qemu_add_kbd_event_handler(syborg_keyboard_event, s, "Syborg Keyboard");
register_savevm("syborg_keyboard", -1, 1,
syborg_keyboard_save, syborg_keyboard_load, s);
diff --git a/hw/usb-hid.c b/hw/usb-hid.c
index 8e6c6e0..dbab5d3 100644
--- a/hw/usb-hid.c
+++ b/hw/usb-hid.c
@@ -55,6 +55,7 @@ typedef struct USBKeyboardState {
uint8_t leds;
uint8_t key[16];
int keys;
+ QEMUPutKbdEntry *eh_entry;
} USBKeyboardState;
typedef struct USBHIDState {
@@ -633,7 +634,8 @@ static void usb_keyboard_handle_reset(USBDevice *dev)
{
USBHIDState *s = (USBHIDState *)dev;
- qemu_add_kbd_event_handler(usb_keyboard_event, s);
+ s->kbd.eh_entry = qemu_add_kbd_event_handler(usb_keyboard_event, s,
+ dev->product_desc);
s->protocol = 1;
}
@@ -854,9 +856,11 @@ static void usb_hid_handle_destroy(USBDevice *dev)
{
USBHIDState *s = (USBHIDState *)dev;
- if (s->kind != USB_KEYBOARD)
+ if (s->kind != USB_KEYBOARD) {
qemu_remove_mouse_event_handler(s->ptr.eh_entry);
- /* TODO: else */
+ } else {
+ qemu_remove_kbd_event_handler(s->kbd.eh_entry);
+ }
}
static int usb_hid_initfn(USBDevice *dev, int kind)
diff --git a/hw/xenfb.c b/hw/xenfb.c
index 422cd53..2c700bd 100644
--- a/hw/xenfb.c
+++ b/hw/xenfb.c
@@ -373,7 +373,7 @@ static int input_connect(struct XenDevice *xendev)
if (rc != 0)
return rc;
- qemu_add_kbd_event_handler(xenfb_key_event, in);
+ qemu_add_kbd_event_handler(xenfb_key_event, in, "Xen Keyboard");
in->qmouse = qemu_add_mouse_event_handler(xenfb_mouse_event, in,
in->abs_pointer_wanted,
"Xen PVFB Mouse");
@@ -388,7 +388,7 @@ static void input_disconnect(struct XenDevice *xendev)
qemu_remove_mouse_event_handler(in->qmouse);
in->qmouse = NULL;
}
- qemu_add_kbd_event_handler(NULL, NULL);
+ qemu_add_kbd_event_handler(NULL, NULL, NULL);
common_unbind(&in->c);
}
diff --git a/input.c b/input.c
index 8f0941e..563ecad 100644
--- a/input.c
+++ b/input.c
@@ -28,20 +28,14 @@
#include "console.h"
#include "qjson.h"
-static QEMUPutKBDEvent *qemu_put_kbd_event;
-static void *qemu_put_kbd_event_opaque;
+static QEMUPutKbdEntry *qemu_put_kbd_event_head;
+static QEMUPutKbdEntry *qemu_put_kbd_event_current;
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,81 @@ static void check_mode_change(void)
current_has_absolute = has_absolute;
}
+QEMUPutKbdEntry *qemu_add_kbd_event_handler(QEMUPutKBDEvent *func,
+ void *opaque,
+ const char *name)
+{
+ QEMUPutKbdEntry *s, *cursor;
+
+ cursor = qemu_put_kbd_event_head;
+ while (cursor) {
+ if (cursor->qemu_put_kbd_event == func &&
+ cursor->qemu_put_kbd_event_opaque == opaque) {
+
+ qemu_put_kbd_event_current = cursor;
+ return cursor;
+ }
+ cursor = cursor->next;
+ }
+
+ 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->next = NULL;
+
+ if (!qemu_put_kbd_event_head) {
+ qemu_put_kbd_event_head = s;
+ qemu_put_kbd_event_current = s;
+ return s;
+ }
+
+ cursor = qemu_put_kbd_event_head;
+ while (cursor->next) {
+ cursor = cursor->next;
+ }
+
+ cursor->next = s;
+ qemu_put_kbd_event_current = s;
+
+ return s;
+}
+
+void qemu_remove_kbd_event_handler(QEMUPutKbdEntry *entry)
+{
+ QEMUPutKbdEntry *prev = NULL, *cursor;
+
+ if (!qemu_put_kbd_event_head || !entry) {
+ return;
+ }
+
+ cursor = qemu_put_kbd_event_head;
+ while (cursor && cursor != entry) {
+ prev = cursor;
+ cursor = cursor->next;
+ }
+
+ if (cursor == NULL) {
+ return;
+ } else if (prev == NULL) {
+ qemu_put_kbd_event_head = cursor->next;
+ if (qemu_put_kbd_event_current == entry) {
+ qemu_put_kbd_event_current = cursor->next;
+ }
+ qemu_free(entry);
+ return;
+ }
+
+ prev->next = entry->next;
+
+ if (qemu_put_kbd_event_current == entry) {
+ qemu_put_kbd_event_current = prev;
+ }
+
+ qemu_free(entry);
+}
+
QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func,
void *opaque, int absolute,
const char *name)
@@ -123,8 +192,9 @@ 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);
+ if (qemu_put_kbd_event_current) {
+ qemu_put_kbd_event_current->qemu_put_kbd_event(
+ qemu_put_kbd_event_current->qemu_put_kbd_event_opaque, keycode);
}
}
--
1.6.3.3
^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [Qemu-devel] [PATCH 1/2] Support for multiple keyboard devices
2010-03-23 19:58 ` [Qemu-devel] [PATCH 1/2] Support for multiple keyboard devices Shahar Havivi
@ 2010-03-26 9:46 ` Markus Armbruster
2010-03-27 15:56 ` Shahar Havivi
0 siblings, 1 reply; 22+ messages in thread
From: Markus Armbruster @ 2010-03-26 9:46 UTC (permalink / raw)
To: Shahar Havivi; +Cc: qemu-devel
Shahar Havivi <shaharh@redhat.com> writes:
> 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.
>
> Signed-off-by: Shahar Havivi <shaharh@redhat.com>
> ---
> console.h | 12 ++++++-
> 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 | 2 +-
> hw/spitz.c | 2 +-
> hw/stellaris_input.c | 2 +-
> hw/syborg_keyboard.c | 2 +-
> hw/usb-hid.c | 10 ++++--
> hw/xenfb.c | 4 +-
> input.c | 90 ++++++++++++++++++++++++++++++++++++++++++++-----
> 14 files changed, 112 insertions(+), 27 deletions(-)
>
> diff --git a/console.h b/console.h
> index 6def115..16c9c3d 100644
> --- a/console.h
> +++ b/console.h
> @@ -41,7 +41,17 @@ 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;
> + struct QEMUPutKbdEntry *next;
> +} QEMUPutKbdEntry;
> +
> +QEMUPutKbdEntry *qemu_add_kbd_event_handler(QEMUPutKBDEvent *func,
> + void *opaque,
> + const char *name);
> +void qemu_remove_kbd_event_handler(QEMUPutKbdEntry *entry);
> QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func,
> void *opaque, int absolute,
> const char *name);
[...]
> diff --git a/input.c b/input.c
> index 8f0941e..563ecad 100644
> --- a/input.c
> +++ b/input.c
> @@ -28,20 +28,14 @@
> #include "console.h"
> #include "qjson.h"
>
> -static QEMUPutKBDEvent *qemu_put_kbd_event;
> -static void *qemu_put_kbd_event_opaque;
> +static QEMUPutKbdEntry *qemu_put_kbd_event_head;
> +static QEMUPutKbdEntry *qemu_put_kbd_event_current;
> 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,81 @@ static void check_mode_change(void)
> current_has_absolute = has_absolute;
> }
>
> +QEMUPutKbdEntry *qemu_add_kbd_event_handler(QEMUPutKBDEvent *func,
> + void *opaque,
> + const char *name)
> +{
> + QEMUPutKbdEntry *s, *cursor;
> +
> + cursor = qemu_put_kbd_event_head;
> + while (cursor) {
> + if (cursor->qemu_put_kbd_event == func &&
> + cursor->qemu_put_kbd_event_opaque == opaque) {
> +
> + qemu_put_kbd_event_current = cursor;
> + return cursor;
> + }
> + cursor = cursor->next;
> + }
You're chasing list pointers. Why not use a suitable list type from
qemu-queue.h?
> +
> + 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->next = NULL;
> +
> + if (!qemu_put_kbd_event_head) {
> + qemu_put_kbd_event_head = s;
> + qemu_put_kbd_event_current = s;
> + return s;
> + }
> +
> + cursor = qemu_put_kbd_event_head;
> + while (cursor->next) {
> + cursor = cursor->next;
> + }
> +
> + cursor->next = s;
> + qemu_put_kbd_event_current = s;
> +
> + return s;
> +}
> +
> +void qemu_remove_kbd_event_handler(QEMUPutKbdEntry *entry)
> +{
> + QEMUPutKbdEntry *prev = NULL, *cursor;
> +
> + if (!qemu_put_kbd_event_head || !entry) {
> + return;
> + }
> +
> + cursor = qemu_put_kbd_event_head;
> + while (cursor && cursor != entry) {
> + prev = cursor;
> + cursor = cursor->next;
> + }
> +
> + if (cursor == NULL) {
> + return;
> + } else if (prev == NULL) {
> + qemu_put_kbd_event_head = cursor->next;
> + if (qemu_put_kbd_event_current == entry) {
> + qemu_put_kbd_event_current = cursor->next;
> + }
> + qemu_free(entry);
> + return;
> + }
> +
> + prev->next = entry->next;
> +
> + if (qemu_put_kbd_event_current == entry) {
> + qemu_put_kbd_event_current = prev;
> + }
> +
> + qemu_free(entry);
More list pointer chasing.
> +}
> +
> QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func,
> void *opaque, int absolute,
> const char *name)
> @@ -123,8 +192,9 @@ 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);
> + if (qemu_put_kbd_event_current) {
> + qemu_put_kbd_event_current->qemu_put_kbd_event(
> + qemu_put_kbd_event_current->qemu_put_kbd_event_opaque, keycode);
> }
> }
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [Qemu-devel] [PATCH 1/2] Support for multiple keyboard devices
2010-03-26 9:46 ` Markus Armbruster
@ 2010-03-27 15:56 ` Shahar Havivi
0 siblings, 0 replies; 22+ messages in thread
From: Shahar Havivi @ 2010-03-27 15:56 UTC (permalink / raw)
To: Markus Armbruster; +Cc: qemu-devel
On Fri, Mar 26, 2010 at 10:46:14AM +0100, Markus Armbruster wrote:
> > +QEMUPutKbdEntry *qemu_add_kbd_event_handler(QEMUPutKBDEvent *func,
> > + void *opaque,
> > + const char *name)
> > +{
> > + QEMUPutKbdEntry *s, *cursor;
> > +
> > + cursor = qemu_put_kbd_event_head;
> > + while (cursor) {
> > + if (cursor->qemu_put_kbd_event == func &&
> > + cursor->qemu_put_kbd_event_opaque == opaque) {
> > +
> > + qemu_put_kbd_event_current = cursor;
> > + return cursor;
> > + }
> > + cursor = cursor->next;
> > + }
>
> You're chasing list pointers. Why not use a suitable list type from
> qemu-queue.h?
>
Change keyboard list to qemu tail queue.
---
console.h | 12 ++++++++++-
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 | 2 +-
hw/spitz.c | 2 +-
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, 73 insertions(+), 27 deletions(-)
diff --git a/console.h b/console.h
index 6def115..7d19407 100644
--- a/console.h
+++ b/console.h
@@ -41,7 +41,17 @@ 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;
+ QTAILQ_ENTRY(QEMUPutKbdEntry) entry;
+} QEMUPutKbdEntry;
+
+QEMUPutKbdEntry *qemu_add_kbd_event_handler(QEMUPutKBDEvent *func,
+ void *opaque,
+ const char *name);
+void qemu_remove_kbd_event_handler(QEMUPutKbdEntry *entry);
QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func,
void *opaque, int absolute,
const char *name);
diff --git a/hw/adb.c b/hw/adb.c
index 4fb7a62..09afcf9 100644
--- a/hw/adb.c
+++ b/hw/adb.c
@@ -304,7 +304,7 @@ void adb_kbd_init(ADBBusState *bus)
s = qemu_mallocz(sizeof(KBDState));
d = adb_register_device(bus, ADB_KEYBOARD, adb_kbd_request,
adb_kbd_reset, s);
- qemu_add_kbd_event_handler(adb_kbd_put_keycode, d);
+ qemu_add_kbd_event_handler(adb_kbd_put_keycode, d, "adb");
register_savevm("adb_kbd", -1, 1, adb_kbd_save,
adb_kbd_load, s);
}
diff --git a/hw/escc.c b/hw/escc.c
index 6d2fd36..2b21d98 100644
--- a/hw/escc.c
+++ b/hw/escc.c
@@ -919,7 +919,8 @@ static int escc_init1(SysBusDevice *dev)
"QEMU Sun Mouse");
}
if (s->chn[1].type == kbd) {
- qemu_add_kbd_event_handler(sunkbd_event, &s->chn[1]);
+ qemu_add_kbd_event_handler(sunkbd_event, &s->chn[1],
+ "QEMU Sun Keyboard");
}
return 0;
diff --git a/hw/musicpal.c b/hw/musicpal.c
index 7fc9fb3..aca8a88 100644
--- a/hw/musicpal.c
+++ b/hw/musicpal.c
@@ -1447,7 +1447,7 @@ static int musicpal_key_init(SysBusDevice *dev)
qdev_init_gpio_out(&dev->qdev, s->out, ARRAY_SIZE(s->out));
- qemu_add_kbd_event_handler(musicpal_key_event, s);
+ qemu_add_kbd_event_handler(musicpal_key_event, s, "Musicpal");
return 0;
}
diff --git a/hw/nseries.c b/hw/nseries.c
index 0273eee..abfcec3 100644
--- a/hw/nseries.c
+++ b/hw/nseries.c
@@ -262,7 +262,7 @@ static void n800_tsc_kbd_setup(struct n800_s *s)
if (n800_keys[i] >= 0)
s->keymap[n800_keys[i]] = i;
- qemu_add_kbd_event_handler(n800_key_event, s);
+ qemu_add_kbd_event_handler(n800_key_event, s, "Nokia n800");
tsc210x_set_transform(s->ts.chip, &n800_pointercal);
}
@@ -371,7 +371,7 @@ static void n810_kbd_setup(struct n800_s *s)
if (n810_keys[i] > 0)
s->keymap[n810_keys[i]] = i;
- qemu_add_kbd_event_handler(n810_key_event, s);
+ qemu_add_kbd_event_handler(n810_key_event, s, "Nokia n810");
/* Attach the LM8322 keyboard to the I2C bus,
* should happen in n8x0_i2c_setup and s->kbd be initialised here. */
diff --git a/hw/palm.c b/hw/palm.c
index 6d19167..1b405d4 100644
--- a/hw/palm.c
+++ b/hw/palm.c
@@ -228,7 +228,7 @@ static void palmte_init(ram_addr_t ram_size,
palmte_microwire_setup(cpu);
- qemu_add_kbd_event_handler(palmte_button_event, cpu);
+ qemu_add_kbd_event_handler(palmte_button_event, cpu, "Palm Keyboard");
palmte_gpio_setup(cpu);
diff --git a/hw/ps2.c b/hw/ps2.c
index f0b206a..886da37 100644
--- a/hw/ps2.c
+++ b/hw/ps2.c
@@ -596,7 +596,7 @@ void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg)
s->common.update_arg = update_arg;
s->scancode_set = 2;
vmstate_register(0, &vmstate_ps2_keyboard, s);
- qemu_add_kbd_event_handler(ps2_put_keycode, s);
+ qemu_add_kbd_event_handler(ps2_put_keycode, s, "QEMU PS/2 Keyboard");
qemu_register_reset(ps2_kbd_reset, s);
return s;
}
diff --git a/hw/pxa2xx_keypad.c b/hw/pxa2xx_keypad.c
index 060df58..7fa5af9 100644
--- a/hw/pxa2xx_keypad.c
+++ b/hw/pxa2xx_keypad.c
@@ -332,5 +332,5 @@ void pxa27x_register_keypad(PXA2xxKeyPadState *kp, struct keymap *map,
}
kp->map = map;
- qemu_add_kbd_event_handler((QEMUPutKBDEvent *) pxa27x_keyboard_event, kp);
+ qemu_add_kbd_event_handler((QEMUPutKBDEvent *) pxa27x_keyboard_event, kp, "PXA keypad");
}
diff --git a/hw/spitz.c b/hw/spitz.c
index 564519b..64e8a6e 100644
--- a/hw/spitz.c
+++ b/hw/spitz.c
@@ -506,7 +506,7 @@ static void spitz_keyboard_register(PXA2xxState *cpu)
pxa2xx_gpio_out_set(cpu->gpio, spitz_gpio_key_strobe[i], s->strobe[i]);
spitz_keyboard_pre_map(s);
- qemu_add_kbd_event_handler((QEMUPutKBDEvent *) spitz_keyboard_handler, s);
+ qemu_add_kbd_event_handler((QEMUPutKBDEvent *) spitz_keyboard_handler, s, "Spitz keyboard");
register_savevm("spitz_keyboard", 0, 0,
spitz_keyboard_save, spitz_keyboard_load, s);
diff --git a/hw/stellaris_input.c b/hw/stellaris_input.c
index 33395a4..775cb46 100644
--- a/hw/stellaris_input.c
+++ b/hw/stellaris_input.c
@@ -85,7 +85,7 @@ void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode)
s->buttons[i].keycode = keycode[i];
}
s->num_buttons = n;
- qemu_add_kbd_event_handler(stellaris_gamepad_put_key, s);
+ qemu_add_kbd_event_handler(stellaris_gamepad_put_key, s, "Stellaris Gamepad");
register_savevm("stellaris_gamepad", -1, 1,
stellaris_gamepad_save, stellaris_gamepad_load, s);
}
diff --git a/hw/syborg_keyboard.c b/hw/syborg_keyboard.c
index 4a562f8..d1651b4 100644
--- a/hw/syborg_keyboard.c
+++ b/hw/syborg_keyboard.c
@@ -218,7 +218,7 @@ static int syborg_keyboard_init(SysBusDevice *dev)
}
s->key_fifo = qemu_mallocz(s->fifo_size * sizeof(s->key_fifo[0]));
- qemu_add_kbd_event_handler(syborg_keyboard_event, s);
+ qemu_add_kbd_event_handler(syborg_keyboard_event, s, "Syborg Keyboard");
register_savevm("syborg_keyboard", -1, 1,
syborg_keyboard_save, syborg_keyboard_load, s);
diff --git a/hw/usb-hid.c b/hw/usb-hid.c
index 8e6c6e0..dbab5d3 100644
--- a/hw/usb-hid.c
+++ b/hw/usb-hid.c
@@ -55,6 +55,7 @@ typedef struct USBKeyboardState {
uint8_t leds;
uint8_t key[16];
int keys;
+ QEMUPutKbdEntry *eh_entry;
} USBKeyboardState;
typedef struct USBHIDState {
@@ -633,7 +634,8 @@ static void usb_keyboard_handle_reset(USBDevice *dev)
{
USBHIDState *s = (USBHIDState *)dev;
- qemu_add_kbd_event_handler(usb_keyboard_event, s);
+ s->kbd.eh_entry = qemu_add_kbd_event_handler(usb_keyboard_event, s,
+ dev->product_desc);
s->protocol = 1;
}
@@ -854,9 +856,11 @@ static void usb_hid_handle_destroy(USBDevice *dev)
{
USBHIDState *s = (USBHIDState *)dev;
- if (s->kind != USB_KEYBOARD)
+ if (s->kind != USB_KEYBOARD) {
qemu_remove_mouse_event_handler(s->ptr.eh_entry);
- /* TODO: else */
+ } else {
+ qemu_remove_kbd_event_handler(s->kbd.eh_entry);
+ }
}
static int usb_hid_initfn(USBDevice *dev, int kind)
diff --git a/hw/xenfb.c b/hw/xenfb.c
index 422cd53..2c700bd 100644
--- a/hw/xenfb.c
+++ b/hw/xenfb.c
@@ -373,7 +373,7 @@ static int input_connect(struct XenDevice *xendev)
if (rc != 0)
return rc;
- qemu_add_kbd_event_handler(xenfb_key_event, in);
+ qemu_add_kbd_event_handler(xenfb_key_event, in, "Xen Keyboard");
in->qmouse = qemu_add_mouse_event_handler(xenfb_mouse_event, in,
in->abs_pointer_wanted,
"Xen PVFB Mouse");
@@ -388,7 +388,7 @@ static void input_disconnect(struct XenDevice *xendev)
qemu_remove_mouse_event_handler(in->qmouse);
in->qmouse = NULL;
}
- qemu_add_kbd_event_handler(NULL, NULL);
+ qemu_add_kbd_event_handler(NULL, NULL, NULL);
common_unbind(&in->c);
}
diff --git a/input.c b/input.c
index 8f0941e..c27a600 100644
--- a/input.c
+++ b/input.c
@@ -28,20 +28,15 @@
#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 QEMUPutKbdEntry *kbd_current;
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 +55,41 @@ static void check_mode_change(void)
current_has_absolute = has_absolute;
}
+QEMUPutKbdEntry *qemu_add_kbd_event_handler(QEMUPutKBDEvent *func,
+ void *opaque,
+ const char *name)
+{
+ QEMUPutKbdEntry *s, *cursor;
+
+ QTAILQ_FOREACH(cursor, &kbd_handlers, entry) {
+ if (cursor->qemu_put_kbd_event == func &&
+ cursor->qemu_put_kbd_event_opaque == opaque) {
+ kbd_current = cursor;
+ 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);
+
+ QTAILQ_INSERT_TAIL(&kbd_handlers, s, entry);
+ kbd_current = s;
+
+ return s;
+}
+
+void qemu_remove_kbd_event_handler(QEMUPutKbdEntry *entry)
+{
+ QTAILQ_REMOVE(&kbd_handlers, entry, entry);
+ if (kbd_current == entry) {
+ kbd_current = QTAILQ_FIRST(&kbd_handlers);
+ }
+ qemu_free(entry);
+}
+
QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func,
void *opaque, int absolute,
const char *name)
@@ -123,8 +153,9 @@ 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);
+ if (kbd_current) {
+ kbd_current->qemu_put_kbd_event(
+ kbd_current->qemu_put_kbd_event_opaque, keycode);
}
}
--
1.6.3.3
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [Qemu-devel] [PATCH 0/2 v3] Qemu support for multiple keyboard devices
@ 2010-03-31 8:15 Shahar Havivi
2010-03-31 8:16 ` [Qemu-devel] [PATCH 1/2] Support " Shahar Havivi
2010-03-31 8:16 ` [Qemu-devel] [PATCH 2/2] Added monitor commands: 'keyboard_set' and 'info keybaord' Shahar Havivi
0 siblings, 2 replies; 22+ messages in thread
From: Shahar Havivi @ 2010-03-31 8:15 UTC (permalink / raw)
To: qemu-devel
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(-)
^ permalink raw reply [flat|nested] 22+ messages in thread
* [Qemu-devel] [PATCH 1/2] Support for multiple keyboard devices
2010-03-31 8:15 [Qemu-devel] [PATCH 0/2 v3] Qemu support for multiple keyboard devices Shahar Havivi
@ 2010-03-31 8:16 ` Shahar Havivi
2010-03-31 10:12 ` [Qemu-devel] " Juan Quintela
2010-03-31 15:23 ` [Qemu-devel] " Markus Armbruster
2010-03-31 8:16 ` [Qemu-devel] [PATCH 2/2] Added monitor commands: 'keyboard_set' and 'info keybaord' Shahar Havivi
1 sibling, 2 replies; 22+ messages in thread
From: Shahar Havivi @ 2010-03-31 8:16 UTC (permalink / raw)
To: qemu-devel
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.
Signed-off-by: Shahar Havivi <shaharh@redhat.com>
---
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(-)
diff --git a/console.h b/console.h
index 6def115..91b66ea 100644
--- a/console.h
+++ b/console.h
@@ -41,7 +41,19 @@ typedef struct QEMUPutLEDEntry {
QTAILQ_ENTRY(QEMUPutLEDEntry) next;
} QEMUPutLEDEntry;
-void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque);
+typedef struct QEMUPutKbdEntry {
+ char *qemu_put_kbd_name;
+ QEMUPutKBDEvent *qemu_put_kbd_event;
+ void *qemu_put_kbd_event_opaque;
+ int index;
+
+ QTAILQ_ENTRY(QEMUPutKbdEntry) node;
+} QEMUPutKbdEntry;
+
+QEMUPutKbdEntry *qemu_add_kbd_event_handler(QEMUPutKBDEvent *func,
+ void *opaque,
+ const char *name);
+void qemu_remove_kbd_event_handler(QEMUPutKbdEntry *entry);
QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func,
void *opaque, int absolute,
const char *name);
diff --git a/hw/adb.c b/hw/adb.c
index 4fb7a62..09afcf9 100644
--- a/hw/adb.c
+++ b/hw/adb.c
@@ -304,7 +304,7 @@ void adb_kbd_init(ADBBusState *bus)
s = qemu_mallocz(sizeof(KBDState));
d = adb_register_device(bus, ADB_KEYBOARD, adb_kbd_request,
adb_kbd_reset, s);
- qemu_add_kbd_event_handler(adb_kbd_put_keycode, d);
+ qemu_add_kbd_event_handler(adb_kbd_put_keycode, d, "adb");
register_savevm("adb_kbd", -1, 1, adb_kbd_save,
adb_kbd_load, s);
}
diff --git a/hw/escc.c b/hw/escc.c
index 6d2fd36..2b21d98 100644
--- a/hw/escc.c
+++ b/hw/escc.c
@@ -919,7 +919,8 @@ static int escc_init1(SysBusDevice *dev)
"QEMU Sun Mouse");
}
if (s->chn[1].type == kbd) {
- qemu_add_kbd_event_handler(sunkbd_event, &s->chn[1]);
+ qemu_add_kbd_event_handler(sunkbd_event, &s->chn[1],
+ "QEMU Sun Keyboard");
}
return 0;
diff --git a/hw/musicpal.c b/hw/musicpal.c
index ebd933e..e1a3b6a 100644
--- a/hw/musicpal.c
+++ b/hw/musicpal.c
@@ -1447,7 +1447,7 @@ static int musicpal_key_init(SysBusDevice *dev)
qdev_init_gpio_out(&dev->qdev, s->out, ARRAY_SIZE(s->out));
- qemu_add_kbd_event_handler(musicpal_key_event, s);
+ qemu_add_kbd_event_handler(musicpal_key_event, s, "Musicpal");
return 0;
}
diff --git a/hw/nseries.c b/hw/nseries.c
index 0273eee..abfcec3 100644
--- a/hw/nseries.c
+++ b/hw/nseries.c
@@ -262,7 +262,7 @@ static void n800_tsc_kbd_setup(struct n800_s *s)
if (n800_keys[i] >= 0)
s->keymap[n800_keys[i]] = i;
- qemu_add_kbd_event_handler(n800_key_event, s);
+ qemu_add_kbd_event_handler(n800_key_event, s, "Nokia n800");
tsc210x_set_transform(s->ts.chip, &n800_pointercal);
}
@@ -371,7 +371,7 @@ static void n810_kbd_setup(struct n800_s *s)
if (n810_keys[i] > 0)
s->keymap[n810_keys[i]] = i;
- qemu_add_kbd_event_handler(n810_key_event, s);
+ qemu_add_kbd_event_handler(n810_key_event, s, "Nokia n810");
/* Attach the LM8322 keyboard to the I2C bus,
* should happen in n8x0_i2c_setup and s->kbd be initialised here. */
diff --git a/hw/palm.c b/hw/palm.c
index 6d19167..1b405d4 100644
--- a/hw/palm.c
+++ b/hw/palm.c
@@ -228,7 +228,7 @@ static void palmte_init(ram_addr_t ram_size,
palmte_microwire_setup(cpu);
- qemu_add_kbd_event_handler(palmte_button_event, cpu);
+ qemu_add_kbd_event_handler(palmte_button_event, cpu, "Palm Keyboard");
palmte_gpio_setup(cpu);
diff --git a/hw/ps2.c b/hw/ps2.c
index f0b206a..886da37 100644
--- a/hw/ps2.c
+++ b/hw/ps2.c
@@ -596,7 +596,7 @@ void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg)
s->common.update_arg = update_arg;
s->scancode_set = 2;
vmstate_register(0, &vmstate_ps2_keyboard, s);
- qemu_add_kbd_event_handler(ps2_put_keycode, s);
+ qemu_add_kbd_event_handler(ps2_put_keycode, s, "QEMU PS/2 Keyboard");
qemu_register_reset(ps2_kbd_reset, s);
return s;
}
diff --git a/hw/pxa2xx_keypad.c b/hw/pxa2xx_keypad.c
index 060df58..2b75351 100644
--- a/hw/pxa2xx_keypad.c
+++ b/hw/pxa2xx_keypad.c
@@ -332,5 +332,6 @@ void pxa27x_register_keypad(PXA2xxKeyPadState *kp, struct keymap *map,
}
kp->map = map;
- qemu_add_kbd_event_handler((QEMUPutKBDEvent *) pxa27x_keyboard_event, kp);
+ qemu_add_kbd_event_handler((QEMUPutKBDEvent *) pxa27x_keyboard_event, kp,
+ "PXA keypad");
}
diff --git a/hw/spitz.c b/hw/spitz.c
index 564519b..b1c0af0 100644
--- a/hw/spitz.c
+++ b/hw/spitz.c
@@ -506,7 +506,8 @@ static void spitz_keyboard_register(PXA2xxState *cpu)
pxa2xx_gpio_out_set(cpu->gpio, spitz_gpio_key_strobe[i], s->strobe[i]);
spitz_keyboard_pre_map(s);
- qemu_add_kbd_event_handler((QEMUPutKBDEvent *) spitz_keyboard_handler, s);
+ qemu_add_kbd_event_handler((QEMUPutKBDEvent *) spitz_keyboard_handler, s,
+ "Spitz keyboard");
register_savevm("spitz_keyboard", 0, 0,
spitz_keyboard_save, spitz_keyboard_load, s);
diff --git a/hw/stellaris_input.c b/hw/stellaris_input.c
index 33395a4..775cb46 100644
--- a/hw/stellaris_input.c
+++ b/hw/stellaris_input.c
@@ -85,7 +85,7 @@ void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode)
s->buttons[i].keycode = keycode[i];
}
s->num_buttons = n;
- qemu_add_kbd_event_handler(stellaris_gamepad_put_key, s);
+ qemu_add_kbd_event_handler(stellaris_gamepad_put_key, s, "Stellaris Gamepad");
register_savevm("stellaris_gamepad", -1, 1,
stellaris_gamepad_save, stellaris_gamepad_load, s);
}
diff --git a/hw/syborg_keyboard.c b/hw/syborg_keyboard.c
index 4a562f8..d1651b4 100644
--- a/hw/syborg_keyboard.c
+++ b/hw/syborg_keyboard.c
@@ -218,7 +218,7 @@ static int syborg_keyboard_init(SysBusDevice *dev)
}
s->key_fifo = qemu_mallocz(s->fifo_size * sizeof(s->key_fifo[0]));
- qemu_add_kbd_event_handler(syborg_keyboard_event, s);
+ qemu_add_kbd_event_handler(syborg_keyboard_event, s, "Syborg Keyboard");
register_savevm("syborg_keyboard", -1, 1,
syborg_keyboard_save, syborg_keyboard_load, s);
diff --git a/hw/usb-hid.c b/hw/usb-hid.c
index 8e6c6e0..dbab5d3 100644
--- a/hw/usb-hid.c
+++ b/hw/usb-hid.c
@@ -55,6 +55,7 @@ typedef struct USBKeyboardState {
uint8_t leds;
uint8_t key[16];
int keys;
+ QEMUPutKbdEntry *eh_entry;
} USBKeyboardState;
typedef struct USBHIDState {
@@ -633,7 +634,8 @@ static void usb_keyboard_handle_reset(USBDevice *dev)
{
USBHIDState *s = (USBHIDState *)dev;
- qemu_add_kbd_event_handler(usb_keyboard_event, s);
+ s->kbd.eh_entry = qemu_add_kbd_event_handler(usb_keyboard_event, s,
+ dev->product_desc);
s->protocol = 1;
}
@@ -854,9 +856,11 @@ static void usb_hid_handle_destroy(USBDevice *dev)
{
USBHIDState *s = (USBHIDState *)dev;
- if (s->kind != USB_KEYBOARD)
+ if (s->kind != USB_KEYBOARD) {
qemu_remove_mouse_event_handler(s->ptr.eh_entry);
- /* TODO: else */
+ } else {
+ qemu_remove_kbd_event_handler(s->kbd.eh_entry);
+ }
}
static int usb_hid_initfn(USBDevice *dev, int kind)
diff --git a/hw/xenfb.c b/hw/xenfb.c
index 422cd53..2c700bd 100644
--- a/hw/xenfb.c
+++ b/hw/xenfb.c
@@ -373,7 +373,7 @@ static int input_connect(struct XenDevice *xendev)
if (rc != 0)
return rc;
- qemu_add_kbd_event_handler(xenfb_key_event, in);
+ qemu_add_kbd_event_handler(xenfb_key_event, in, "Xen Keyboard");
in->qmouse = qemu_add_mouse_event_handler(xenfb_mouse_event, in,
in->abs_pointer_wanted,
"Xen PVFB Mouse");
@@ -388,7 +388,7 @@ static void input_disconnect(struct XenDevice *xendev)
qemu_remove_mouse_event_handler(in->qmouse);
in->qmouse = NULL;
}
- qemu_add_kbd_event_handler(NULL, NULL);
+ qemu_add_kbd_event_handler(NULL, NULL, NULL);
common_unbind(&in->c);
}
diff --git a/input.c b/input.c
index 8f0941e..e6dda25 100644
--- a/input.c
+++ b/input.c
@@ -28,20 +28,14 @@
#include "console.h"
#include "qjson.h"
-static QEMUPutKBDEvent *qemu_put_kbd_event;
-static void *qemu_put_kbd_event_opaque;
+static QTAILQ_HEAD(, QEMUPutKbdEntry) kbd_handlers =
+ QTAILQ_HEAD_INITIALIZER(kbd_handlers);
static QTAILQ_HEAD(, QEMUPutLEDEntry) led_handlers = QTAILQ_HEAD_INITIALIZER(led_handlers);
static QTAILQ_HEAD(, QEMUPutMouseEntry) mouse_handlers =
QTAILQ_HEAD_INITIALIZER(mouse_handlers);
static NotifierList mouse_mode_notifiers =
NOTIFIER_LIST_INITIALIZER(mouse_mode_notifiers);
-void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque)
-{
- qemu_put_kbd_event_opaque = opaque;
- qemu_put_kbd_event = func;
-}
-
static void check_mode_change(void)
{
static int current_is_absolute, current_has_absolute;
@@ -60,6 +54,38 @@ static void check_mode_change(void)
current_has_absolute = has_absolute;
}
+QEMUPutKbdEntry *qemu_add_kbd_event_handler(QEMUPutKBDEvent *func,
+ void *opaque,
+ const char *name)
+{
+ static int mouse_index = 0;
+ QEMUPutKbdEntry *s, *cursor;
+
+ QTAILQ_FOREACH(cursor, &kbd_handlers, node) {
+ if (cursor->qemu_put_kbd_event == func &&
+ cursor->qemu_put_kbd_event_opaque == opaque) {
+ return cursor;
+ }
+ }
+
+ s = qemu_mallocz(sizeof(QEMUPutKbdEntry));
+
+ s->qemu_put_kbd_event_opaque = opaque;
+ s->qemu_put_kbd_event = func;
+ s->qemu_put_kbd_name = qemu_strdup(name);
+ s->index = mouse_index++;
+
+ QTAILQ_INSERT_TAIL(&kbd_handlers, s, node);
+
+ return s;
+}
+
+void qemu_remove_kbd_event_handler(QEMUPutKbdEntry *entry)
+{
+ QTAILQ_REMOVE(&kbd_handlers, entry, node);
+ qemu_free(entry);
+}
+
QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func,
void *opaque, int absolute,
const char *name)
@@ -123,9 +149,14 @@ void qemu_remove_led_event_handler(QEMUPutLEDEntry *entry)
void kbd_put_keycode(int keycode)
{
- if (qemu_put_kbd_event) {
- qemu_put_kbd_event(qemu_put_kbd_event_opaque, keycode);
+ QEMUPutKbdEntry *entry;
+
+ if (QTAILQ_EMPTY(&kbd_handlers)) {
+ return;
}
+
+ entry = QTAILQ_FIRST(&kbd_handlers);
+ entry->qemu_put_kbd_event(entry->qemu_put_kbd_event_opaque, keycode);
}
void kbd_put_ledstate(int ledstate)
--
1.6.3.3
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [Qemu-devel] [PATCH 2/2] Added monitor commands: 'keyboard_set' and 'info keybaord'
2010-03-31 8:15 [Qemu-devel] [PATCH 0/2 v3] Qemu support for multiple keyboard devices Shahar Havivi
2010-03-31 8:16 ` [Qemu-devel] [PATCH 1/2] Support " Shahar Havivi
@ 2010-03-31 8:16 ` Shahar Havivi
2010-03-31 10:20 ` [Qemu-devel] " Juan Quintela
1 sibling, 1 reply; 22+ messages in thread
From: Shahar Havivi @ 2010-03-31 8:16 UTC (permalink / raw)
To: qemu-devel
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>
Signed-off-by: Shahar Havivi <shaharh@redhat.com>
---
console.h | 4 ++
input.c | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
monitor.c | 8 ++++
qemu-monitor.hx | 17 +++++++++
4 files changed, 130 insertions(+), 0 deletions(-)
diff --git a/console.h b/console.h
index 91b66ea..889f5d5 100644
--- a/console.h
+++ b/console.h
@@ -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)
diff --git a/input.c b/input.c
index e6dda25..3cc33f0 100644
--- a/input.c
+++ b/input.c
@@ -329,3 +329,104 @@ void qemu_remove_mouse_mode_change_notifier(Notifier *notify)
{
notifier_list_remove(&mouse_mode_notifiers, notify);
}
+
+static void info_keyboard_iter(QObject *data, void *opaque)
+{
+ QDict *kbd;
+ Monitor *mon = opaque;
+
+ kbd = qobject_to_qdict(data);
+ monitor_printf(mon, "%c Keyboard #%" PRId64 ": %s\n",
+ (qdict_get_bool(kbd, "current") ? '*' : ' '),
+ qdict_get_int(kbd, "index"), qdict_get_str(kbd, "name"));
+}
+
+void do_info_keyboard_print(Monitor *mon, const QObject *data)
+{
+ QList *kbd_list;
+
+ kbd_list = qobject_to_qlist(data);
+ if (qlist_empty(kbd_list)) {
+ monitor_printf(mon, "No keyboard devices connected\n");
+ return;
+ }
+
+ qlist_iter(kbd_list, info_keyboard_iter, mon);
+}
+
+/*
+ * do_info_keyboard(): Show VM keyboard information
+ *
+ * Each keyboard is represented by a QDict, the returned QObject is
+ * a QList of all keyboards.
+ *
+ * The keyboard QDict contains the following:
+ *
+ * - "name": keyboard's name
+ * - "index": keyboard's index
+ * - "current": true if this keyboard is receiving events, false otherwise
+ *
+ * Example:
+ *
+ * [ { "name": "QEMU USB Keyboard", "index": 0, "current": false },
+ * { "name": "QEMU PS/2 Keyboard", "index": 1, "current": true } ]
+ */
+void do_info_keyboard(Monitor *mon, QObject **ret_data)
+{
+ QEMUPutKbdEntry *cursor;
+ QList *kbd_list;
+ int current;
+
+ kbd_list = qlist_new();
+
+ if (QTAILQ_EMPTY(&kbd_handlers)) {
+ goto out;
+ }
+
+ current = QTAILQ_FIRST(&kbd_handlers)->index;
+ QTAILQ_FOREACH(cursor, &kbd_handlers, node) {
+ QObject *obj;
+ obj = qobject_from_jsonf("{ 'name': %s,"
+ " 'index': %d,"
+ " 'current': %i }",
+ cursor->qemu_put_kbd_name,
+ cursor->index,
+ current == cursor->index);
+ qlist_append_obj(kbd_list, obj);
+ }
+out:
+ *ret_data = QOBJECT(kbd_list);
+}
+
+/*
+ * do_keyboard_set(): Set active keyboard
+ *
+ * Argument qdict contains
+ * - "index": the keyboard index to set
+ *
+ * Example:
+ *
+ * { "index": "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;
+
+ 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;
+ break;
+ }
+ }
+
+ return 0;
+}
diff --git a/monitor.c b/monitor.c
index 822dc27..f5474b1 100644
--- a/monitor.c
+++ b/monitor.c
@@ -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 = "",
diff --git a/qemu-monitor.hx b/qemu-monitor.hx
index 5308f36..e9beb12 100644
--- a/qemu-monitor.hx
+++ b/qemu-monitor.hx
@@ -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",
--
1.6.3.3
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [Qemu-devel] Re: [PATCH 1/2] Support for multiple keyboard devices
2010-03-31 8:16 ` [Qemu-devel] [PATCH 1/2] Support " Shahar Havivi
@ 2010-03-31 10:12 ` Juan Quintela
2010-03-31 15:11 ` Shahar Havivi
2010-03-31 15:23 ` [Qemu-devel] " Markus Armbruster
1 sibling, 1 reply; 22+ messages in thread
From: Juan Quintela @ 2010-03-31 10:12 UTC (permalink / raw)
To: Shahar Havivi; +Cc: qemu-devel
Shahar Havivi <shaharh@redhat.com> wrote:
> Currently you get segfault when trying to remove keyboard (device_del
> monitor command) because no keyboard handling is done.
>
> This patch add QEMUPutKbdEntry structure, handling each keyboard entry.
> Adding a keyboard add to the list, removing keyboard select the previous
> keyboard in list.
> diff --git a/hw/xenfb.c b/hw/xenfb.c
> index 422cd53..2c700bd 100644
> --- a/hw/xenfb.c
> +++ b/hw/xenfb.c
> @@ -373,7 +373,7 @@ static int input_connect(struct XenDevice *xendev)
> if (rc != 0)
> return rc;
>
> - qemu_add_kbd_event_handler(xenfb_key_event, in);
> + qemu_add_kbd_event_handler(xenfb_key_event, in, "Xen Keyboard");
> in->qmouse = qemu_add_mouse_event_handler(xenfb_mouse_event, in,
> in->abs_pointer_wanted,
> "Xen PVFB Mouse");
> @@ -388,7 +388,7 @@ static void input_disconnect(struct XenDevice *xendev)
> qemu_remove_mouse_event_handler(in->qmouse);
> in->qmouse = NULL;
> }
> - qemu_add_kbd_event_handler(NULL, NULL);
> + qemu_add_kbd_event_handler(NULL, NULL, NULL);
> common_unbind(&in->c);
> }
>
xen code changes with this patch. You need to store the event handler
somewhere to be able to remove it later, no?
Later, Juan.
^ permalink raw reply [flat|nested] 22+ messages in thread
* [Qemu-devel] Re: [PATCH 2/2] Added monitor commands: 'keyboard_set' and 'info keybaord'
2010-03-31 8:16 ` [Qemu-devel] [PATCH 2/2] Added monitor commands: 'keyboard_set' and 'info keybaord' Shahar Havivi
@ 2010-03-31 10:20 ` Juan Quintela
2010-03-31 15:31 ` Markus Armbruster
2010-03-31 17:04 ` Anthony Liguori
0 siblings, 2 replies; 22+ messages in thread
From: Juan Quintela @ 2010-03-31 10:20 UTC (permalink / raw)
To: Shahar Havivi; +Cc: qemu-devel
Shahar Havivi <shaharh@redhat.com> wrote:
> Two new monitor commands: adding ability to handle which keyboard qemu will
> use and to see which keyboard are currently available.
> +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.
> +
> + 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 :)
> + break;
> + }
> + }
> +
> + return 0;
I guess you want to return one error if the index don't exist.
> +}
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.
^ permalink raw reply [flat|nested] 22+ messages in thread
* [Qemu-devel] Re: [PATCH 1/2] Support for multiple keyboard devices
2010-03-31 10:12 ` [Qemu-devel] " Juan Quintela
@ 2010-03-31 15:11 ` Shahar Havivi
0 siblings, 0 replies; 22+ messages in thread
From: Shahar Havivi @ 2010-03-31 15:11 UTC (permalink / raw)
To: Juan Quintela; +Cc: qemu-devel
On Wed, Mar 31, 2010 at 12:12:15PM +0200, Juan Quintela wrote:
> Date: Wed, 31 Mar 2010 12:12:15 +0200
> From: Juan Quintela <quintela@redhat.com>
> To: Shahar Havivi <shaharh@redhat.com>
> Cc: qemu-devel@nongnu.org
> Subject: Re: [PATCH 1/2] Support for multiple keyboard devices
>
> Shahar Havivi <shaharh@redhat.com> wrote:
> > Currently you get segfault when trying to remove keyboard (device_del
> > monitor command) because no keyboard handling is done.
> >
> > This patch add QEMUPutKbdEntry structure, handling each keyboard entry.
> > Adding a keyboard add to the list, removing keyboard select the previous
> > keyboard in list.
>
> > diff --git a/hw/xenfb.c b/hw/xenfb.c
> > index 422cd53..2c700bd 100644
> > --- a/hw/xenfb.c
> > +++ b/hw/xenfb.c
> > @@ -373,7 +373,7 @@ static int input_connect(struct XenDevice *xendev)
> > if (rc != 0)
> > return rc;
> >
> > - qemu_add_kbd_event_handler(xenfb_key_event, in);
> > + qemu_add_kbd_event_handler(xenfb_key_event, in, "Xen Keyboard");
> > in->qmouse = qemu_add_mouse_event_handler(xenfb_mouse_event, in,
> > in->abs_pointer_wanted,
> > "Xen PVFB Mouse");
> > @@ -388,7 +388,7 @@ static void input_disconnect(struct XenDevice *xendev)
> > qemu_remove_mouse_event_handler(in->qmouse);
> > in->qmouse = NULL;
> > }
> > - qemu_add_kbd_event_handler(NULL, NULL);
> > + qemu_add_kbd_event_handler(NULL, NULL, NULL);
> > common_unbind(&in->c);
> > }
> >
>
> xen code changes with this patch. You need to store the event handler
> somewhere to be able to remove it later, no?
>
> Later, Juan.
Right about the Xen,
Added proper remove handling
Signed-off-by: Shahar Havivi <shaharh@redhat.com>
---
console.h | 14 ++++++++++++-
hw/adb.c | 2 +-
hw/escc.c | 3 +-
hw/musicpal.c | 2 +-
hw/nseries.c | 4 +-
hw/palm.c | 2 +-
hw/ps2.c | 2 +-
hw/pxa2xx_keypad.c | 3 +-
hw/spitz.c | 3 +-
hw/stellaris_input.c | 2 +-
hw/syborg_keyboard.c | 2 +-
hw/usb-hid.c | 10 ++++++--
hw/xenfb.c | 5 ++-
input.c | 51 ++++++++++++++++++++++++++++++++++++++++---------
14 files changed, 78 insertions(+), 27 deletions(-)
diff --git a/console.h b/console.h
index 6def115..91b66ea 100644
--- a/console.h
+++ b/console.h
@@ -41,7 +41,19 @@ typedef struct QEMUPutLEDEntry {
QTAILQ_ENTRY(QEMUPutLEDEntry) next;
} QEMUPutLEDEntry;
-void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque);
+typedef struct QEMUPutKbdEntry {
+ char *qemu_put_kbd_name;
+ QEMUPutKBDEvent *qemu_put_kbd_event;
+ void *qemu_put_kbd_event_opaque;
+ int index;
+
+ QTAILQ_ENTRY(QEMUPutKbdEntry) node;
+} QEMUPutKbdEntry;
+
+QEMUPutKbdEntry *qemu_add_kbd_event_handler(QEMUPutKBDEvent *func,
+ void *opaque,
+ const char *name);
+void qemu_remove_kbd_event_handler(QEMUPutKbdEntry *entry);
QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func,
void *opaque, int absolute,
const char *name);
diff --git a/hw/adb.c b/hw/adb.c
index 4fb7a62..09afcf9 100644
--- a/hw/adb.c
+++ b/hw/adb.c
@@ -304,7 +304,7 @@ void adb_kbd_init(ADBBusState *bus)
s = qemu_mallocz(sizeof(KBDState));
d = adb_register_device(bus, ADB_KEYBOARD, adb_kbd_request,
adb_kbd_reset, s);
- qemu_add_kbd_event_handler(adb_kbd_put_keycode, d);
+ qemu_add_kbd_event_handler(adb_kbd_put_keycode, d, "adb");
register_savevm("adb_kbd", -1, 1, adb_kbd_save,
adb_kbd_load, s);
}
diff --git a/hw/escc.c b/hw/escc.c
index 6d2fd36..2b21d98 100644
--- a/hw/escc.c
+++ b/hw/escc.c
@@ -919,7 +919,8 @@ static int escc_init1(SysBusDevice *dev)
"QEMU Sun Mouse");
}
if (s->chn[1].type == kbd) {
- qemu_add_kbd_event_handler(sunkbd_event, &s->chn[1]);
+ qemu_add_kbd_event_handler(sunkbd_event, &s->chn[1],
+ "QEMU Sun Keyboard");
}
return 0;
diff --git a/hw/musicpal.c b/hw/musicpal.c
index ebd933e..e1a3b6a 100644
--- a/hw/musicpal.c
+++ b/hw/musicpal.c
@@ -1447,7 +1447,7 @@ static int musicpal_key_init(SysBusDevice *dev)
qdev_init_gpio_out(&dev->qdev, s->out, ARRAY_SIZE(s->out));
- qemu_add_kbd_event_handler(musicpal_key_event, s);
+ qemu_add_kbd_event_handler(musicpal_key_event, s, "Musicpal");
return 0;
}
diff --git a/hw/nseries.c b/hw/nseries.c
index 0273eee..abfcec3 100644
--- a/hw/nseries.c
+++ b/hw/nseries.c
@@ -262,7 +262,7 @@ static void n800_tsc_kbd_setup(struct n800_s *s)
if (n800_keys[i] >= 0)
s->keymap[n800_keys[i]] = i;
- qemu_add_kbd_event_handler(n800_key_event, s);
+ qemu_add_kbd_event_handler(n800_key_event, s, "Nokia n800");
tsc210x_set_transform(s->ts.chip, &n800_pointercal);
}
@@ -371,7 +371,7 @@ static void n810_kbd_setup(struct n800_s *s)
if (n810_keys[i] > 0)
s->keymap[n810_keys[i]] = i;
- qemu_add_kbd_event_handler(n810_key_event, s);
+ qemu_add_kbd_event_handler(n810_key_event, s, "Nokia n810");
/* Attach the LM8322 keyboard to the I2C bus,
* should happen in n8x0_i2c_setup and s->kbd be initialised here. */
diff --git a/hw/palm.c b/hw/palm.c
index 6d19167..1b405d4 100644
--- a/hw/palm.c
+++ b/hw/palm.c
@@ -228,7 +228,7 @@ static void palmte_init(ram_addr_t ram_size,
palmte_microwire_setup(cpu);
- qemu_add_kbd_event_handler(palmte_button_event, cpu);
+ qemu_add_kbd_event_handler(palmte_button_event, cpu, "Palm Keyboard");
palmte_gpio_setup(cpu);
diff --git a/hw/ps2.c b/hw/ps2.c
index f0b206a..886da37 100644
--- a/hw/ps2.c
+++ b/hw/ps2.c
@@ -596,7 +596,7 @@ void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg)
s->common.update_arg = update_arg;
s->scancode_set = 2;
vmstate_register(0, &vmstate_ps2_keyboard, s);
- qemu_add_kbd_event_handler(ps2_put_keycode, s);
+ qemu_add_kbd_event_handler(ps2_put_keycode, s, "QEMU PS/2 Keyboard");
qemu_register_reset(ps2_kbd_reset, s);
return s;
}
diff --git a/hw/pxa2xx_keypad.c b/hw/pxa2xx_keypad.c
index 060df58..2b75351 100644
--- a/hw/pxa2xx_keypad.c
+++ b/hw/pxa2xx_keypad.c
@@ -332,5 +332,6 @@ void pxa27x_register_keypad(PXA2xxKeyPadState *kp, struct keymap *map,
}
kp->map = map;
- qemu_add_kbd_event_handler((QEMUPutKBDEvent *) pxa27x_keyboard_event, kp);
+ qemu_add_kbd_event_handler((QEMUPutKBDEvent *) pxa27x_keyboard_event, kp,
+ "PXA keypad");
}
diff --git a/hw/spitz.c b/hw/spitz.c
index 564519b..b1c0af0 100644
--- a/hw/spitz.c
+++ b/hw/spitz.c
@@ -506,7 +506,8 @@ static void spitz_keyboard_register(PXA2xxState *cpu)
pxa2xx_gpio_out_set(cpu->gpio, spitz_gpio_key_strobe[i], s->strobe[i]);
spitz_keyboard_pre_map(s);
- qemu_add_kbd_event_handler((QEMUPutKBDEvent *) spitz_keyboard_handler, s);
+ qemu_add_kbd_event_handler((QEMUPutKBDEvent *) spitz_keyboard_handler, s,
+ "Spitz keyboard");
register_savevm("spitz_keyboard", 0, 0,
spitz_keyboard_save, spitz_keyboard_load, s);
diff --git a/hw/stellaris_input.c b/hw/stellaris_input.c
index 33395a4..775cb46 100644
--- a/hw/stellaris_input.c
+++ b/hw/stellaris_input.c
@@ -85,7 +85,7 @@ void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode)
s->buttons[i].keycode = keycode[i];
}
s->num_buttons = n;
- qemu_add_kbd_event_handler(stellaris_gamepad_put_key, s);
+ qemu_add_kbd_event_handler(stellaris_gamepad_put_key, s, "Stellaris Gamepad");
register_savevm("stellaris_gamepad", -1, 1,
stellaris_gamepad_save, stellaris_gamepad_load, s);
}
diff --git a/hw/syborg_keyboard.c b/hw/syborg_keyboard.c
index 4a562f8..d1651b4 100644
--- a/hw/syborg_keyboard.c
+++ b/hw/syborg_keyboard.c
@@ -218,7 +218,7 @@ static int syborg_keyboard_init(SysBusDevice *dev)
}
s->key_fifo = qemu_mallocz(s->fifo_size * sizeof(s->key_fifo[0]));
- qemu_add_kbd_event_handler(syborg_keyboard_event, s);
+ qemu_add_kbd_event_handler(syborg_keyboard_event, s, "Syborg Keyboard");
register_savevm("syborg_keyboard", -1, 1,
syborg_keyboard_save, syborg_keyboard_load, s);
diff --git a/hw/usb-hid.c b/hw/usb-hid.c
index 8e6c6e0..dbab5d3 100644
--- a/hw/usb-hid.c
+++ b/hw/usb-hid.c
@@ -55,6 +55,7 @@ typedef struct USBKeyboardState {
uint8_t leds;
uint8_t key[16];
int keys;
+ QEMUPutKbdEntry *eh_entry;
} USBKeyboardState;
typedef struct USBHIDState {
@@ -633,7 +634,8 @@ static void usb_keyboard_handle_reset(USBDevice *dev)
{
USBHIDState *s = (USBHIDState *)dev;
- qemu_add_kbd_event_handler(usb_keyboard_event, s);
+ s->kbd.eh_entry = qemu_add_kbd_event_handler(usb_keyboard_event, s,
+ dev->product_desc);
s->protocol = 1;
}
@@ -854,9 +856,11 @@ static void usb_hid_handle_destroy(USBDevice *dev)
{
USBHIDState *s = (USBHIDState *)dev;
- if (s->kind != USB_KEYBOARD)
+ if (s->kind != USB_KEYBOARD) {
qemu_remove_mouse_event_handler(s->ptr.eh_entry);
- /* TODO: else */
+ } else {
+ qemu_remove_kbd_event_handler(s->kbd.eh_entry);
+ }
}
static int usb_hid_initfn(USBDevice *dev, int kind)
diff --git a/hw/xenfb.c b/hw/xenfb.c
index 422cd53..0c1d1ec 100644
--- a/hw/xenfb.c
+++ b/hw/xenfb.c
@@ -68,6 +68,7 @@ struct XenInput {
int button_state; /* Last seen pointer button state */
int extended;
QEMUPutMouseEntry *qmouse;
+ QEMUPutKbdEntry *qkbd;
};
#define UP_QUEUE 8
@@ -373,7 +374,7 @@ static int input_connect(struct XenDevice *xendev)
if (rc != 0)
return rc;
- qemu_add_kbd_event_handler(xenfb_key_event, in);
+ in->qkbd = qemu_add_kbd_event_handler(xenfb_key_event, in, "Xen Keyboard");
in->qmouse = qemu_add_mouse_event_handler(xenfb_mouse_event, in,
in->abs_pointer_wanted,
"Xen PVFB Mouse");
@@ -388,7 +389,7 @@ static void input_disconnect(struct XenDevice *xendev)
qemu_remove_mouse_event_handler(in->qmouse);
in->qmouse = NULL;
}
- qemu_add_kbd_event_handler(NULL, NULL);
+ qemu_remove_kbd_event_handler(in->qkbd);
common_unbind(&in->c);
}
diff --git a/input.c b/input.c
index 8f0941e..e6dda25 100644
--- a/input.c
+++ b/input.c
@@ -28,20 +28,14 @@
#include "console.h"
#include "qjson.h"
-static QEMUPutKBDEvent *qemu_put_kbd_event;
-static void *qemu_put_kbd_event_opaque;
+static QTAILQ_HEAD(, QEMUPutKbdEntry) kbd_handlers =
+ QTAILQ_HEAD_INITIALIZER(kbd_handlers);
static QTAILQ_HEAD(, QEMUPutLEDEntry) led_handlers = QTAILQ_HEAD_INITIALIZER(led_handlers);
static QTAILQ_HEAD(, QEMUPutMouseEntry) mouse_handlers =
QTAILQ_HEAD_INITIALIZER(mouse_handlers);
static NotifierList mouse_mode_notifiers =
NOTIFIER_LIST_INITIALIZER(mouse_mode_notifiers);
-void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque)
-{
- qemu_put_kbd_event_opaque = opaque;
- qemu_put_kbd_event = func;
-}
-
static void check_mode_change(void)
{
static int current_is_absolute, current_has_absolute;
@@ -60,6 +54,38 @@ static void check_mode_change(void)
current_has_absolute = has_absolute;
}
+QEMUPutKbdEntry *qemu_add_kbd_event_handler(QEMUPutKBDEvent *func,
+ void *opaque,
+ const char *name)
+{
+ static int mouse_index = 0;
+ QEMUPutKbdEntry *s, *cursor;
+
+ QTAILQ_FOREACH(cursor, &kbd_handlers, node) {
+ if (cursor->qemu_put_kbd_event == func &&
+ cursor->qemu_put_kbd_event_opaque == opaque) {
+ return cursor;
+ }
+ }
+
+ s = qemu_mallocz(sizeof(QEMUPutKbdEntry));
+
+ s->qemu_put_kbd_event_opaque = opaque;
+ s->qemu_put_kbd_event = func;
+ s->qemu_put_kbd_name = qemu_strdup(name);
+ s->index = mouse_index++;
+
+ QTAILQ_INSERT_TAIL(&kbd_handlers, s, node);
+
+ return s;
+}
+
+void qemu_remove_kbd_event_handler(QEMUPutKbdEntry *entry)
+{
+ QTAILQ_REMOVE(&kbd_handlers, entry, node);
+ qemu_free(entry);
+}
+
QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func,
void *opaque, int absolute,
const char *name)
@@ -123,9 +149,14 @@ void qemu_remove_led_event_handler(QEMUPutLEDEntry *entry)
void kbd_put_keycode(int keycode)
{
- if (qemu_put_kbd_event) {
- qemu_put_kbd_event(qemu_put_kbd_event_opaque, keycode);
+ QEMUPutKbdEntry *entry;
+
+ if (QTAILQ_EMPTY(&kbd_handlers)) {
+ return;
}
+
+ entry = QTAILQ_FIRST(&kbd_handlers);
+ entry->qemu_put_kbd_event(entry->qemu_put_kbd_event_opaque, keycode);
}
void kbd_put_ledstate(int ledstate)
--
1.6.3.3
^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [Qemu-devel] [PATCH 1/2] Support for multiple keyboard devices
2010-03-31 8:16 ` [Qemu-devel] [PATCH 1/2] Support " Shahar Havivi
2010-03-31 10:12 ` [Qemu-devel] " Juan Quintela
@ 2010-03-31 15:23 ` Markus Armbruster
2010-03-31 15:36 ` Shahar Havivi
1 sibling, 1 reply; 22+ messages in thread
From: Markus Armbruster @ 2010-03-31 15:23 UTC (permalink / raw)
To: Shahar Havivi; +Cc: qemu-devel
Shahar Havivi <shaharh@redhat.com> writes:
> 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.
>
> Signed-off-by: Shahar Havivi <shaharh@redhat.com>
> ---
[...]
> diff --git a/input.c b/input.c
> index 8f0941e..e6dda25 100644
> --- a/input.c
> +++ b/input.c
[...]
> @@ -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 ;)
> + 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;
> +}
[...]
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [Qemu-devel] Re: [PATCH 2/2] Added monitor commands: 'keyboard_set' and 'info keybaord'
2010-03-31 10:20 ` [Qemu-devel] " Juan Quintela
@ 2010-03-31 15:31 ` Markus Armbruster
2010-03-31 15:42 ` Shahar Havivi
2010-03-31 16:58 ` Juan Quintela
2010-03-31 17:04 ` Anthony Liguori
1 sibling, 2 replies; 22+ messages in thread
From: Markus Armbruster @ 2010-03-31 15:31 UTC (permalink / raw)
To: Juan Quintela; +Cc: Shahar Havivi, qemu-devel
Juan Quintela <quintela@redhat.com> writes:
> Shahar Havivi <shaharh@redhat.com> wrote:
>> Two new monitor commands: adding ability to handle which keyboard qemu will
>> use and to see which keyboard are currently available.
>
>> +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.
>
>> +
>> + 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 :)
>
>> + break;
>> + }
>> + }
>> +
>> + return 0;
>
> I guess you want to return one error if the index don't exist.
>
>> +}
>
> 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.
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [Qemu-devel] [PATCH 1/2] Support for multiple keyboard devices
2010-03-31 15:23 ` [Qemu-devel] " Markus Armbruster
@ 2010-03-31 15:36 ` Shahar Havivi
0 siblings, 0 replies; 22+ messages in thread
From: Shahar Havivi @ 2010-03-31 15:36 UTC (permalink / raw)
To: Markus Armbruster; +Cc: qemu-devel
On Wed, Mar 31, 2010 at 05:23:46PM +0200, Markus Armbruster wrote:
> Date: Wed, 31 Mar 2010 17:23:46 +0200
> From: Markus Armbruster <armbru@redhat.com>
> To: Shahar Havivi <shaharh@redhat.com>
> Cc: qemu-devel@nongnu.org
> Subject: Re: [Qemu-devel] [PATCH 1/2] Support for multiple keyboard devices
>
> Shahar Havivi <shaharh@redhat.com> writes:
>
> > 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.
> >
> > Signed-off-by: Shahar Havivi <shaharh@redhat.com>
> > ---
> [...]
> > diff --git a/input.c b/input.c
> > index 8f0941e..e6dda25 100644
> > --- a/input.c
> > +++ b/input.c
> [...]
> > @@ -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 ;)
> [...]
Right :)
Signed-off-by: Shahar Havivi <shaharh@redhat.com>
---
console.h | 14 ++++++++++++-
hw/adb.c | 2 +-
hw/escc.c | 3 +-
hw/musicpal.c | 2 +-
hw/nseries.c | 4 +-
hw/palm.c | 2 +-
hw/ps2.c | 2 +-
hw/pxa2xx_keypad.c | 3 +-
hw/spitz.c | 3 +-
hw/stellaris_input.c | 2 +-
hw/syborg_keyboard.c | 2 +-
hw/usb-hid.c | 10 ++++++--
hw/xenfb.c | 5 ++-
input.c | 51 ++++++++++++++++++++++++++++++++++++++++---------
14 files changed, 78 insertions(+), 27 deletions(-)
diff --git a/console.h b/console.h
index 6def115..91b66ea 100644
--- a/console.h
+++ b/console.h
@@ -41,7 +41,19 @@ typedef struct QEMUPutLEDEntry {
QTAILQ_ENTRY(QEMUPutLEDEntry) next;
} QEMUPutLEDEntry;
-void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque);
+typedef struct QEMUPutKbdEntry {
+ char *qemu_put_kbd_name;
+ QEMUPutKBDEvent *qemu_put_kbd_event;
+ void *qemu_put_kbd_event_opaque;
+ int index;
+
+ QTAILQ_ENTRY(QEMUPutKbdEntry) node;
+} QEMUPutKbdEntry;
+
+QEMUPutKbdEntry *qemu_add_kbd_event_handler(QEMUPutKBDEvent *func,
+ void *opaque,
+ const char *name);
+void qemu_remove_kbd_event_handler(QEMUPutKbdEntry *entry);
QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func,
void *opaque, int absolute,
const char *name);
diff --git a/hw/adb.c b/hw/adb.c
index 4fb7a62..09afcf9 100644
--- a/hw/adb.c
+++ b/hw/adb.c
@@ -304,7 +304,7 @@ void adb_kbd_init(ADBBusState *bus)
s = qemu_mallocz(sizeof(KBDState));
d = adb_register_device(bus, ADB_KEYBOARD, adb_kbd_request,
adb_kbd_reset, s);
- qemu_add_kbd_event_handler(adb_kbd_put_keycode, d);
+ qemu_add_kbd_event_handler(adb_kbd_put_keycode, d, "adb");
register_savevm("adb_kbd", -1, 1, adb_kbd_save,
adb_kbd_load, s);
}
diff --git a/hw/escc.c b/hw/escc.c
index 6d2fd36..2b21d98 100644
--- a/hw/escc.c
+++ b/hw/escc.c
@@ -919,7 +919,8 @@ static int escc_init1(SysBusDevice *dev)
"QEMU Sun Mouse");
}
if (s->chn[1].type == kbd) {
- qemu_add_kbd_event_handler(sunkbd_event, &s->chn[1]);
+ qemu_add_kbd_event_handler(sunkbd_event, &s->chn[1],
+ "QEMU Sun Keyboard");
}
return 0;
diff --git a/hw/musicpal.c b/hw/musicpal.c
index ebd933e..e1a3b6a 100644
--- a/hw/musicpal.c
+++ b/hw/musicpal.c
@@ -1447,7 +1447,7 @@ static int musicpal_key_init(SysBusDevice *dev)
qdev_init_gpio_out(&dev->qdev, s->out, ARRAY_SIZE(s->out));
- qemu_add_kbd_event_handler(musicpal_key_event, s);
+ qemu_add_kbd_event_handler(musicpal_key_event, s, "Musicpal");
return 0;
}
diff --git a/hw/nseries.c b/hw/nseries.c
index 0273eee..abfcec3 100644
--- a/hw/nseries.c
+++ b/hw/nseries.c
@@ -262,7 +262,7 @@ static void n800_tsc_kbd_setup(struct n800_s *s)
if (n800_keys[i] >= 0)
s->keymap[n800_keys[i]] = i;
- qemu_add_kbd_event_handler(n800_key_event, s);
+ qemu_add_kbd_event_handler(n800_key_event, s, "Nokia n800");
tsc210x_set_transform(s->ts.chip, &n800_pointercal);
}
@@ -371,7 +371,7 @@ static void n810_kbd_setup(struct n800_s *s)
if (n810_keys[i] > 0)
s->keymap[n810_keys[i]] = i;
- qemu_add_kbd_event_handler(n810_key_event, s);
+ qemu_add_kbd_event_handler(n810_key_event, s, "Nokia n810");
/* Attach the LM8322 keyboard to the I2C bus,
* should happen in n8x0_i2c_setup and s->kbd be initialised here. */
diff --git a/hw/palm.c b/hw/palm.c
index 6d19167..1b405d4 100644
--- a/hw/palm.c
+++ b/hw/palm.c
@@ -228,7 +228,7 @@ static void palmte_init(ram_addr_t ram_size,
palmte_microwire_setup(cpu);
- qemu_add_kbd_event_handler(palmte_button_event, cpu);
+ qemu_add_kbd_event_handler(palmte_button_event, cpu, "Palm Keyboard");
palmte_gpio_setup(cpu);
diff --git a/hw/ps2.c b/hw/ps2.c
index f0b206a..886da37 100644
--- a/hw/ps2.c
+++ b/hw/ps2.c
@@ -596,7 +596,7 @@ void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg)
s->common.update_arg = update_arg;
s->scancode_set = 2;
vmstate_register(0, &vmstate_ps2_keyboard, s);
- qemu_add_kbd_event_handler(ps2_put_keycode, s);
+ qemu_add_kbd_event_handler(ps2_put_keycode, s, "QEMU PS/2 Keyboard");
qemu_register_reset(ps2_kbd_reset, s);
return s;
}
diff --git a/hw/pxa2xx_keypad.c b/hw/pxa2xx_keypad.c
index 060df58..2b75351 100644
--- a/hw/pxa2xx_keypad.c
+++ b/hw/pxa2xx_keypad.c
@@ -332,5 +332,6 @@ void pxa27x_register_keypad(PXA2xxKeyPadState *kp, struct keymap *map,
}
kp->map = map;
- qemu_add_kbd_event_handler((QEMUPutKBDEvent *) pxa27x_keyboard_event, kp);
+ qemu_add_kbd_event_handler((QEMUPutKBDEvent *) pxa27x_keyboard_event, kp,
+ "PXA keypad");
}
diff --git a/hw/spitz.c b/hw/spitz.c
index 564519b..b1c0af0 100644
--- a/hw/spitz.c
+++ b/hw/spitz.c
@@ -506,7 +506,8 @@ static void spitz_keyboard_register(PXA2xxState *cpu)
pxa2xx_gpio_out_set(cpu->gpio, spitz_gpio_key_strobe[i], s->strobe[i]);
spitz_keyboard_pre_map(s);
- qemu_add_kbd_event_handler((QEMUPutKBDEvent *) spitz_keyboard_handler, s);
+ qemu_add_kbd_event_handler((QEMUPutKBDEvent *) spitz_keyboard_handler, s,
+ "Spitz keyboard");
register_savevm("spitz_keyboard", 0, 0,
spitz_keyboard_save, spitz_keyboard_load, s);
diff --git a/hw/stellaris_input.c b/hw/stellaris_input.c
index 33395a4..775cb46 100644
--- a/hw/stellaris_input.c
+++ b/hw/stellaris_input.c
@@ -85,7 +85,7 @@ void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode)
s->buttons[i].keycode = keycode[i];
}
s->num_buttons = n;
- qemu_add_kbd_event_handler(stellaris_gamepad_put_key, s);
+ qemu_add_kbd_event_handler(stellaris_gamepad_put_key, s, "Stellaris Gamepad");
register_savevm("stellaris_gamepad", -1, 1,
stellaris_gamepad_save, stellaris_gamepad_load, s);
}
diff --git a/hw/syborg_keyboard.c b/hw/syborg_keyboard.c
index 4a562f8..d1651b4 100644
--- a/hw/syborg_keyboard.c
+++ b/hw/syborg_keyboard.c
@@ -218,7 +218,7 @@ static int syborg_keyboard_init(SysBusDevice *dev)
}
s->key_fifo = qemu_mallocz(s->fifo_size * sizeof(s->key_fifo[0]));
- qemu_add_kbd_event_handler(syborg_keyboard_event, s);
+ qemu_add_kbd_event_handler(syborg_keyboard_event, s, "Syborg Keyboard");
register_savevm("syborg_keyboard", -1, 1,
syborg_keyboard_save, syborg_keyboard_load, s);
diff --git a/hw/usb-hid.c b/hw/usb-hid.c
index 8e6c6e0..dbab5d3 100644
--- a/hw/usb-hid.c
+++ b/hw/usb-hid.c
@@ -55,6 +55,7 @@ typedef struct USBKeyboardState {
uint8_t leds;
uint8_t key[16];
int keys;
+ QEMUPutKbdEntry *eh_entry;
} USBKeyboardState;
typedef struct USBHIDState {
@@ -633,7 +634,8 @@ static void usb_keyboard_handle_reset(USBDevice *dev)
{
USBHIDState *s = (USBHIDState *)dev;
- qemu_add_kbd_event_handler(usb_keyboard_event, s);
+ s->kbd.eh_entry = qemu_add_kbd_event_handler(usb_keyboard_event, s,
+ dev->product_desc);
s->protocol = 1;
}
@@ -854,9 +856,11 @@ static void usb_hid_handle_destroy(USBDevice *dev)
{
USBHIDState *s = (USBHIDState *)dev;
- if (s->kind != USB_KEYBOARD)
+ if (s->kind != USB_KEYBOARD) {
qemu_remove_mouse_event_handler(s->ptr.eh_entry);
- /* TODO: else */
+ } else {
+ qemu_remove_kbd_event_handler(s->kbd.eh_entry);
+ }
}
static int usb_hid_initfn(USBDevice *dev, int kind)
diff --git a/hw/xenfb.c b/hw/xenfb.c
index 422cd53..0c1d1ec 100644
--- a/hw/xenfb.c
+++ b/hw/xenfb.c
@@ -68,6 +68,7 @@ struct XenInput {
int button_state; /* Last seen pointer button state */
int extended;
QEMUPutMouseEntry *qmouse;
+ QEMUPutKbdEntry *qkbd;
};
#define UP_QUEUE 8
@@ -373,7 +374,7 @@ static int input_connect(struct XenDevice *xendev)
if (rc != 0)
return rc;
- qemu_add_kbd_event_handler(xenfb_key_event, in);
+ in->qkbd = qemu_add_kbd_event_handler(xenfb_key_event, in, "Xen Keyboard");
in->qmouse = qemu_add_mouse_event_handler(xenfb_mouse_event, in,
in->abs_pointer_wanted,
"Xen PVFB Mouse");
@@ -388,7 +389,7 @@ static void input_disconnect(struct XenDevice *xendev)
qemu_remove_mouse_event_handler(in->qmouse);
in->qmouse = NULL;
}
- qemu_add_kbd_event_handler(NULL, NULL);
+ qemu_remove_kbd_event_handler(in->qkbd);
common_unbind(&in->c);
}
diff --git a/input.c b/input.c
index 8f0941e..18875a9 100644
--- a/input.c
+++ b/input.c
@@ -28,20 +28,14 @@
#include "console.h"
#include "qjson.h"
-static QEMUPutKBDEvent *qemu_put_kbd_event;
-static void *qemu_put_kbd_event_opaque;
+static QTAILQ_HEAD(, QEMUPutKbdEntry) kbd_handlers =
+ QTAILQ_HEAD_INITIALIZER(kbd_handlers);
static QTAILQ_HEAD(, QEMUPutLEDEntry) led_handlers = QTAILQ_HEAD_INITIALIZER(led_handlers);
static QTAILQ_HEAD(, QEMUPutMouseEntry) mouse_handlers =
QTAILQ_HEAD_INITIALIZER(mouse_handlers);
static NotifierList mouse_mode_notifiers =
NOTIFIER_LIST_INITIALIZER(mouse_mode_notifiers);
-void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque)
-{
- qemu_put_kbd_event_opaque = opaque;
- qemu_put_kbd_event = func;
-}
-
static void check_mode_change(void)
{
static int current_is_absolute, current_has_absolute;
@@ -60,6 +54,38 @@ static void check_mode_change(void)
current_has_absolute = has_absolute;
}
+QEMUPutKbdEntry *qemu_add_kbd_event_handler(QEMUPutKBDEvent *func,
+ void *opaque,
+ const char *name)
+{
+ static int 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)
--
1.6.3.3
^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [Qemu-devel] Re: [PATCH 2/2] Added monitor commands: 'keyboard_set' and 'info keybaord'
2010-03-31 15:31 ` Markus Armbruster
@ 2010-03-31 15:42 ` Shahar Havivi
2010-03-31 16:58 ` Juan Quintela
1 sibling, 0 replies; 22+ messages in thread
From: Shahar Havivi @ 2010-03-31 15:42 UTC (permalink / raw)
To: Markus Armbruster; +Cc: qemu-devel, Juan Quintela
On Wed, Mar 31, 2010 at 05:31:49PM +0200, Markus Armbruster wrote:
> Date: Wed, 31 Mar 2010 17:31:49 +0200
> From: Markus Armbruster <armbru@redhat.com>
> To: Juan Quintela <quintela@redhat.com>
> Cc: Shahar Havivi <shaharh@redhat.com>, qemu-devel@nongnu.org
> Subject: Re: [Qemu-devel] Re: [PATCH 2/2] Added monitor commands:
> 'keyboard_set' and 'info keybaord'
>
> Juan Quintela <quintela@redhat.com> writes:
>
> > Shahar Havivi <shaharh@redhat.com> wrote:
> >> Two new monitor commands: adding ability to handle which keyboard qemu will
> >> use and to see which keyboard are currently available.
> >
> >> +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.
> >
> >> +
> >> + 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 :)
> >
> >> + break;
> >> + }
> >> + }
> >> +
> >> + return 0;
> >
> > I guess you want to return one error if the index don't exist.
Right about that, Thanks.
> >> +}
> >
> > 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 ...')
Signed-off-by: Shahar Havivi <shaharh@redhat.com>
---
console.h | 4 ++
input.c | 106 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
monitor.c | 8 ++++
qemu-monitor.hx | 17 +++++++++
4 files changed, 135 insertions(+), 0 deletions(-)
diff --git a/console.h b/console.h
index 91b66ea..889f5d5 100644
--- a/console.h
+++ b/console.h
@@ -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)
diff --git a/input.c b/input.c
index 18875a9..27ef8f9 100644
--- a/input.c
+++ b/input.c
@@ -329,3 +329,109 @@ void qemu_remove_mouse_mode_change_notifier(Notifier *notify)
{
notifier_list_remove(&mouse_mode_notifiers, notify);
}
+
+static void info_keyboard_iter(QObject *data, void *opaque)
+{
+ QDict *kbd;
+ Monitor *mon = opaque;
+
+ kbd = qobject_to_qdict(data);
+ monitor_printf(mon, "%c Keyboard #%" PRId64 ": %s\n",
+ (qdict_get_bool(kbd, "current") ? '*' : ' '),
+ qdict_get_int(kbd, "index"), qdict_get_str(kbd, "name"));
+}
+
+void do_info_keyboard_print(Monitor *mon, const QObject *data)
+{
+ QList *kbd_list;
+
+ kbd_list = qobject_to_qlist(data);
+ if (qlist_empty(kbd_list)) {
+ monitor_printf(mon, "No keyboard devices connected\n");
+ return;
+ }
+
+ qlist_iter(kbd_list, info_keyboard_iter, mon);
+}
+
+/*
+ * do_info_keyboard(): Show VM keyboard information
+ *
+ * Each keyboard is represented by a QDict, the returned QObject is
+ * a QList of all keyboards.
+ *
+ * The keyboard QDict contains the following:
+ *
+ * - "name": keyboard's name
+ * - "index": keyboard's index
+ * - "current": true if this keyboard is receiving events, false otherwise
+ *
+ * Example:
+ *
+ * [ { "name": "QEMU USB Keyboard", "index": 0, "current": false },
+ * { "name": "QEMU PS/2 Keyboard", "index": 1, "current": true } ]
+ */
+void do_info_keyboard(Monitor *mon, QObject **ret_data)
+{
+ QEMUPutKbdEntry *cursor;
+ QList *kbd_list;
+ int current;
+
+ kbd_list = qlist_new();
+
+ if (QTAILQ_EMPTY(&kbd_handlers)) {
+ goto out;
+ }
+
+ current = QTAILQ_FIRST(&kbd_handlers)->index;
+ QTAILQ_FOREACH(cursor, &kbd_handlers, node) {
+ QObject *obj;
+ obj = qobject_from_jsonf("{ 'name': %s,"
+ " 'index': %d,"
+ " 'current': %i }",
+ cursor->qemu_put_kbd_name,
+ cursor->index,
+ current == cursor->index);
+ qlist_append_obj(kbd_list, obj);
+ }
+out:
+ *ret_data = QOBJECT(kbd_list);
+}
+
+/*
+ * do_keyboard_set(): Set active keyboard
+ *
+ * Argument qdict contains
+ * - "index": the keyboard index to set
+ *
+ * Example:
+ *
+ * { "index": "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;
+
+ 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;
+ break;
+ }
+ }
+
+ if (!found) {
+ qerror_report(QERR_INVALID_PARAMETER, "index");
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/monitor.c b/monitor.c
index 822dc27..f5474b1 100644
--- a/monitor.c
+++ b/monitor.c
@@ -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 = "",
diff --git a/qemu-monitor.hx b/qemu-monitor.hx
index 5308f36..e9beb12 100644
--- a/qemu-monitor.hx
+++ b/qemu-monitor.hx
@@ -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",
--
1.6.3.3
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [Qemu-devel] Re: [PATCH 2/2] Added monitor commands: 'keyboard_set' and 'info keybaord'
2010-03-31 15:31 ` Markus Armbruster
2010-03-31 15:42 ` Shahar Havivi
@ 2010-03-31 16:58 ` Juan Quintela
2010-03-31 19:37 ` Shahar Havivi
1 sibling, 1 reply; 22+ messages in thread
From: Juan Quintela @ 2010-03-31 16:58 UTC (permalink / raw)
To: Markus Armbruster; +Cc: Shahar Havivi, qemu-devel
Markus Armbruster <armbru@redhat.com> wrote:
> Juan Quintela <quintela@redhat.com> writes:
>> 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.
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [Qemu-devel] Re: [PATCH 2/2] Added monitor commands: 'keyboard_set' and 'info keybaord'
2010-03-31 10:20 ` [Qemu-devel] " Juan Quintela
2010-03-31 15:31 ` Markus Armbruster
@ 2010-03-31 17:04 ` Anthony Liguori
2010-03-31 20:55 ` Shahar Havivi
1 sibling, 1 reply; 22+ messages in thread
From: Anthony Liguori @ 2010-03-31 17:04 UTC (permalink / raw)
To: Juan Quintela; +Cc: Shahar Havivi, qemu-devel
On 03/31/2010 05:20 AM, Juan Quintela wrote:
> Shahar Havivi<shaharh@redhat.com> wrote:
>
>> Two new monitor commands: adding ability to handle which keyboard qemu will
>> use and to see which keyboard are currently available.
>>
>
>> +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.
>
>
>> +
>> + 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
>> + break;
>> + }
>> + }
>> +
>> + return 0;
>>
> I guess you want to return one error if the index don't exist.
>
>
>> +}
>>
> 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.
>
>
>
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [Qemu-devel] Re: [PATCH 2/2] Added monitor commands: 'keyboard_set' and 'info keybaord'
2010-03-31 16:58 ` Juan Quintela
@ 2010-03-31 19:37 ` Shahar Havivi
2010-03-31 19:52 ` Anthony Liguori
0 siblings, 1 reply; 22+ messages in thread
From: Shahar Havivi @ 2010-03-31 19:37 UTC (permalink / raw)
To: Juan Quintela; +Cc: Markus Armbruster, qemu-devel
On Wed, Mar 31, 2010 at 06:58:14PM +0200, Juan Quintela wrote:
> Date: Wed, 31 Mar 2010 18:58:14 +0200
> From: Juan Quintela <quintela@redhat.com>
> To: Markus Armbruster <armbru@redhat.com>
> Cc: Shahar Havivi <shaharh@redhat.com>, qemu-devel@nongnu.org
> Subject: [Qemu-devel] Re: [PATCH 2/2] Added monitor commands: 'keyboard_set'
> and 'info keybaord'
>
> Markus Armbruster <armbru@redhat.com> wrote:
> > Juan Quintela <quintela@redhat.com> writes:
> >> 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.
You right, this is a problem.
As I see it id cannot be force to receive by the user right?
Thanks, Shahar.
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [Qemu-devel] Re: [PATCH 2/2] Added monitor commands: 'keyboard_set' and 'info keybaord'
2010-03-31 19:37 ` Shahar Havivi
@ 2010-03-31 19:52 ` Anthony Liguori
2010-03-31 20:16 ` Juan Quintela
0 siblings, 1 reply; 22+ messages in thread
From: Anthony Liguori @ 2010-03-31 19:52 UTC (permalink / raw)
To: Shahar Havivi; +Cc: qemu-devel, Markus Armbruster, Juan Quintela
On 03/31/2010 02:37 PM, Shahar Havivi wrote:
> On Wed, Mar 31, 2010 at 06:58:14PM +0200, Juan Quintela wrote:
>
>> Date: Wed, 31 Mar 2010 18:58:14 +0200
>> From: Juan Quintela<quintela@redhat.com>
>> To: Markus Armbruster<armbru@redhat.com>
>> Cc: Shahar Havivi<shaharh@redhat.com>, qemu-devel@nongnu.org
>> Subject: [Qemu-devel] Re: [PATCH 2/2] Added monitor commands: 'keyboard_set'
>> and 'info keybaord'
>>
>> Markus Armbruster<armbru@redhat.com> wrote:
>>
>>> Juan Quintela<quintela@redhat.com> writes:
>>>
>>>> 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.
>>
> 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
> Thanks, Shahar.
>
>
>
^ permalink raw reply [flat|nested] 22+ messages in thread
* [Qemu-devel] Re: [PATCH 2/2] Added monitor commands: 'keyboard_set' and 'info keybaord'
2010-03-31 19:52 ` Anthony Liguori
@ 2010-03-31 20:16 ` Juan Quintela
0 siblings, 0 replies; 22+ messages in thread
From: Juan Quintela @ 2010-03-31 20:16 UTC (permalink / raw)
To: Anthony Liguori; +Cc: Shahar Havivi, Markus Armbruster, qemu-devel
Anthony Liguori <anthony@codemonkey.ws> wrote:
> On 03/31/2010 02:37 PM, Shahar Havivi wrote:
>> On Wed, Mar 31, 2010 at 06:58:14PM +0200, Juan Quintela wrote:
>>
>>> Date: Wed, 31 Mar 2010 18:58:14 +0200
>>> From: Juan Quintela<quintela@redhat.com>
>>> To: Markus Armbruster<armbru@redhat.com>
>>> Cc: Shahar Havivi<shaharh@redhat.com>, qemu-devel@nongnu.org
>>> Subject: [Qemu-devel] Re: [PATCH 2/2] Added monitor commands: 'keyboard_set'
>>> and 'info keybaord'
>>>
>>> Markus Armbruster<armbru@redhat.com> wrote:
>>>
>>>> Juan Quintela<quintela@redhat.com> writes:
>>>>
>>>>> 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.
>>>
>> 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.
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [Qemu-devel] Re: [PATCH 2/2] Added monitor commands: 'keyboard_set' and 'info keybaord'
2010-03-31 17:04 ` Anthony Liguori
@ 2010-03-31 20:55 ` Shahar Havivi
0 siblings, 0 replies; 22+ messages in thread
From: Shahar Havivi @ 2010-03-31 20:55 UTC (permalink / raw)
To: Anthony Liguori; +Cc: qemu-devel, Juan Quintela
> >>+
> >>+ 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
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.
Signed-off-by: Shahar Havivi <shaharh@redhat.com>
---
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(-)
diff --git a/console.h b/console.h
index 91b66ea..5d68cff 100644
--- a/console.h
+++ b/console.h
@@ -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)
diff --git a/hw/usb-hid.c b/hw/usb-hid.c
index dbab5d3..88ef36c 100644
--- a/hw/usb-hid.c
+++ b/hw/usb-hid.c
@@ -55,6 +55,7 @@ typedef struct USBKeyboardState {
uint8_t leds;
uint8_t key[16];
int keys;
+ 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)
diff --git a/input.c b/input.c
index 18875a9..da43ee5 100644
--- a/input.c
+++ b/input.c
@@ -329,3 +329,114 @@ void qemu_remove_mouse_mode_change_notifier(Notifier *notify)
{
notifier_list_remove(&mouse_mode_notifiers, notify);
}
+
+static void info_keyboard_iter(QObject *data, void *opaque)
+{
+ QDict *kbd;
+ Monitor *mon = opaque;
+
+ kbd = qobject_to_qdict(data);
+ monitor_printf(mon, "%c Keyboard #%" PRId64 ": %s\n",
+ (qdict_get_bool(kbd, "current") ? '*' : ' '),
+ qdict_get_int(kbd, "index"), qdict_get_str(kbd, "name"));
+}
+
+void do_info_keyboard_print(Monitor *mon, const QObject *data)
+{
+ QList *kbd_list;
+
+ kbd_list = qobject_to_qlist(data);
+ if (qlist_empty(kbd_list)) {
+ monitor_printf(mon, "No keyboard devices connected\n");
+ return;
+ }
+
+ qlist_iter(kbd_list, info_keyboard_iter, mon);
+}
+
+void qemu_activate_keyboard_event_handler(QEMUPutKbdEntry *entry)
+{
+ QTAILQ_REMOVE(&kbd_handlers, entry, node);
+ QTAILQ_INSERT_HEAD(&kbd_handlers, entry, node);
+}
+
+/*
+ * do_info_keyboard(): Show VM keyboard information
+ *
+ * Each keyboard is represented by a QDict, the returned QObject is
+ * a QList of all keyboards.
+ *
+ * The keyboard QDict contains the following:
+ *
+ * - "name": keyboard's name
+ * - "index": keyboard's index
+ * - "current": true if this keyboard is receiving events, false otherwise
+ *
+ * Example:
+ *
+ * [ { "name": "QEMU USB Keyboard", "index": 0, "current": false },
+ * { "name": "QEMU PS/2 Keyboard", "index": 1, "current": true } ]
+ */
+void do_info_keyboard(Monitor *mon, QObject **ret_data)
+{
+ QEMUPutKbdEntry *cursor;
+ QList *kbd_list;
+ int current;
+
+ kbd_list = qlist_new();
+
+ if (QTAILQ_EMPTY(&kbd_handlers)) {
+ goto out;
+ }
+
+ current = QTAILQ_FIRST(&kbd_handlers)->index;
+ QTAILQ_FOREACH(cursor, &kbd_handlers, node) {
+ QObject *obj;
+ obj = qobject_from_jsonf("{ 'name': %s,"
+ " 'index': %d,"
+ " 'current': %i }",
+ cursor->qemu_put_kbd_name,
+ cursor->index,
+ current == cursor->index);
+ qlist_append_obj(kbd_list, obj);
+ }
+out:
+ *ret_data = QOBJECT(kbd_list);
+}
+
+/*
+ * do_keyboard_set(): Set active keyboard
+ *
+ * Argument qdict contains
+ * - "index": the keyboard index to set
+ *
+ * Example:
+ *
+ * { "index": "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;
+
+ if (QTAILQ_EMPTY(&kbd_handlers)) {
+ qerror_report(QERR_DEVICE_NOT_FOUND, "keyboard");
+ return -1;
+ }
+
+ QTAILQ_FOREACH(cursor, &kbd_handlers, node) {
+ if (cursor->index == index) {
+ qemu_activate_keyboard_event_handler(cursor);
+ found = 1;
+ break;
+ }
+ }
+
+ if (!found) {
+ qerror_report(QERR_INVALID_PARAMETER, "index");
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/monitor.c b/monitor.c
index 822dc27..f5474b1 100644
--- a/monitor.c
+++ b/monitor.c
@@ -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 = "",
diff --git a/qemu-monitor.hx b/qemu-monitor.hx
index 5308f36..e9beb12 100644
--- a/qemu-monitor.hx
+++ b/qemu-monitor.hx
@@ -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",
--
1.6.3.3
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [Qemu-devel] [PATCH 1/2] Support for multiple keyboard devices
2010-06-19 20:27 [Qemu-devel] [PATCH 0/2 v5] Qemu support " Shahar Havivi
@ 2010-06-19 20:28 ` Shahar Havivi
0 siblings, 0 replies; 22+ messages in thread
From: Shahar Havivi @ 2010-06-19 20:28 UTC (permalink / raw)
To: qemu-devel, Anthony Liguori
Signed-off-by: Shahar Havivi <shaharh@redhat.com>
---
console.h | 15 +++++++++++-
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 | 6 +++-
hw/xenfb.c | 5 ++-
input.c | 57 ++++++++++++++++++++++++++++++++++++--------------
14 files changed, 75 insertions(+), 33 deletions(-)
diff --git a/console.h b/console.h
index aafb031..0157d30 100644
--- a/console.h
+++ b/console.h
@@ -41,8 +41,19 @@ typedef struct QEMUPutLEDEntry {
QTAILQ_ENTRY(QEMUPutLEDEntry) next;
} QEMUPutLEDEntry;
-void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque);
-void qemu_remove_kbd_event_handler(void);
+typedef struct QEMUPutKbdEntry {
+ char *qemu_put_kbd_name;
+ QEMUPutKBDEvent *qemu_put_kbd_event;
+ void *qemu_put_kbd_event_opaque;
+ int index;
+
+ QTAILQ_ENTRY(QEMUPutKbdEntry) node;
+} QEMUPutKbdEntry;
+
+QEMUPutKbdEntry *qemu_add_kbd_event_handler(QEMUPutKBDEvent *func,
+ void *opaque,
+ const char *name);
+void qemu_remove_kbd_event_handler(QEMUPutKbdEntry *entry);
QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func,
void *opaque, int absolute,
const char *name);
diff --git a/hw/adb.c b/hw/adb.c
index 4fb7a62..09afcf9 100644
--- a/hw/adb.c
+++ b/hw/adb.c
@@ -304,7 +304,7 @@ void adb_kbd_init(ADBBusState *bus)
s = qemu_mallocz(sizeof(KBDState));
d = adb_register_device(bus, ADB_KEYBOARD, adb_kbd_request,
adb_kbd_reset, s);
- qemu_add_kbd_event_handler(adb_kbd_put_keycode, d);
+ qemu_add_kbd_event_handler(adb_kbd_put_keycode, d, "adb");
register_savevm("adb_kbd", -1, 1, adb_kbd_save,
adb_kbd_load, s);
}
diff --git a/hw/escc.c b/hw/escc.c
index 6d2fd36..2bf765c 100644
--- a/hw/escc.c
+++ b/hw/escc.c
@@ -919,7 +919,8 @@ static int escc_init1(SysBusDevice *dev)
"QEMU Sun Mouse");
}
if (s->chn[1].type == kbd) {
- qemu_add_kbd_event_handler(sunkbd_event, &s->chn[1]);
+ qemu_add_kbd_event_handler(sunkbd_event, &s->chn[1],
+ "QEMU Sun Keyboard");
}
return 0;
diff --git a/hw/musicpal.c b/hw/musicpal.c
index d44c5a0..3f2ead7 100644
--- a/hw/musicpal.c
+++ b/hw/musicpal.c
@@ -1445,7 +1445,7 @@ static int musicpal_key_init(SysBusDevice *dev)
qdev_init_gpio_out(&dev->qdev, s->out, ARRAY_SIZE(s->out));
- qemu_add_kbd_event_handler(musicpal_key_event, s);
+ qemu_add_kbd_event_handler(musicpal_key_event, s, "Musicpal");
return 0;
}
diff --git a/hw/nseries.c b/hw/nseries.c
index 04a028d..b529504 100644
--- a/hw/nseries.c
+++ b/hw/nseries.c
@@ -262,7 +262,7 @@ static void n800_tsc_kbd_setup(struct n800_s *s)
if (n800_keys[i] >= 0)
s->keymap[n800_keys[i]] = i;
- qemu_add_kbd_event_handler(n800_key_event, s);
+ qemu_add_kbd_event_handler(n800_key_event, s, "Nokia n800");
tsc210x_set_transform(s->ts.chip, &n800_pointercal);
}
@@ -371,7 +371,7 @@ static void n810_kbd_setup(struct n800_s *s)
if (n810_keys[i] > 0)
s->keymap[n810_keys[i]] = i;
- qemu_add_kbd_event_handler(n810_key_event, s);
+ qemu_add_kbd_event_handler(n810_key_event, s, "Nokia n810");
/* Attach the LM8322 keyboard to the I2C bus,
* should happen in n8x0_i2c_setup and s->kbd be initialised here. */
diff --git a/hw/palm.c b/hw/palm.c
index 8db133d..ace19f9 100644
--- a/hw/palm.c
+++ b/hw/palm.c
@@ -227,7 +227,7 @@ static void palmte_init(ram_addr_t ram_size,
palmte_microwire_setup(cpu);
- qemu_add_kbd_event_handler(palmte_button_event, cpu);
+ qemu_add_kbd_event_handler(palmte_button_event, cpu, "Palm Keyboard");
palmte_gpio_setup(cpu);
diff --git a/hw/ps2.c b/hw/ps2.c
index f0b206a..886da37 100644
--- a/hw/ps2.c
+++ b/hw/ps2.c
@@ -596,7 +596,7 @@ void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg)
s->common.update_arg = update_arg;
s->scancode_set = 2;
vmstate_register(0, &vmstate_ps2_keyboard, s);
- qemu_add_kbd_event_handler(ps2_put_keycode, s);
+ qemu_add_kbd_event_handler(ps2_put_keycode, s, "QEMU PS/2 Keyboard");
qemu_register_reset(ps2_kbd_reset, s);
return s;
}
diff --git a/hw/pxa2xx_keypad.c b/hw/pxa2xx_keypad.c
index 060df58..2b75351 100644
--- a/hw/pxa2xx_keypad.c
+++ b/hw/pxa2xx_keypad.c
@@ -332,5 +332,6 @@ void pxa27x_register_keypad(PXA2xxKeyPadState *kp, struct keymap *map,
}
kp->map = map;
- qemu_add_kbd_event_handler((QEMUPutKBDEvent *) pxa27x_keyboard_event, kp);
+ qemu_add_kbd_event_handler((QEMUPutKBDEvent *) pxa27x_keyboard_event, kp,
+ "PXA keypad");
}
diff --git a/hw/spitz.c b/hw/spitz.c
index 4f82e24..f1e0a2a 100644
--- a/hw/spitz.c
+++ b/hw/spitz.c
@@ -506,7 +506,8 @@ static void spitz_keyboard_register(PXA2xxState *cpu)
pxa2xx_gpio_out_set(cpu->gpio, spitz_gpio_key_strobe[i], s->strobe[i]);
spitz_keyboard_pre_map(s);
- qemu_add_kbd_event_handler((QEMUPutKBDEvent *) spitz_keyboard_handler, s);
+ qemu_add_kbd_event_handler((QEMUPutKBDEvent *) spitz_keyboard_handler, s,
+ "Spitz keyboard");
register_savevm("spitz_keyboard", 0, 0,
spitz_keyboard_save, spitz_keyboard_load, s);
diff --git a/hw/stellaris_input.c b/hw/stellaris_input.c
index 33395a4..775cb46 100644
--- a/hw/stellaris_input.c
+++ b/hw/stellaris_input.c
@@ -85,7 +85,7 @@ void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode)
s->buttons[i].keycode = keycode[i];
}
s->num_buttons = n;
- qemu_add_kbd_event_handler(stellaris_gamepad_put_key, s);
+ qemu_add_kbd_event_handler(stellaris_gamepad_put_key, s, "Stellaris Gamepad");
register_savevm("stellaris_gamepad", -1, 1,
stellaris_gamepad_save, stellaris_gamepad_load, s);
}
diff --git a/hw/syborg_keyboard.c b/hw/syborg_keyboard.c
index 4a562f8..d1651b4 100644
--- a/hw/syborg_keyboard.c
+++ b/hw/syborg_keyboard.c
@@ -218,7 +218,7 @@ static int syborg_keyboard_init(SysBusDevice *dev)
}
s->key_fifo = qemu_mallocz(s->fifo_size * sizeof(s->key_fifo[0]));
- qemu_add_kbd_event_handler(syborg_keyboard_event, s);
+ qemu_add_kbd_event_handler(syborg_keyboard_event, s, "Syborg Keyboard");
register_savevm("syborg_keyboard", -1, 1,
syborg_keyboard_save, syborg_keyboard_load, s);
diff --git a/hw/usb-hid.c b/hw/usb-hid.c
index 882d933..0a09457 100644
--- a/hw/usb-hid.c
+++ b/hw/usb-hid.c
@@ -56,6 +56,7 @@ typedef struct USBKeyboardState {
uint8_t leds;
uint8_t key[16];
int keys;
+ QEMUPutKbdEntry *eh_entry;
} USBKeyboardState;
typedef struct USBHIDState {
@@ -634,7 +635,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;
}
@@ -857,7 +859,7 @@ static void usb_hid_handle_destroy(USBDevice *dev)
switch(s->kind) {
case USB_KEYBOARD:
- qemu_remove_kbd_event_handler();
+ qemu_remove_kbd_event_handler(s->kbd.eh_entry);
break;
default:
qemu_remove_mouse_event_handler(s->ptr.eh_entry);
diff --git a/hw/xenfb.c b/hw/xenfb.c
index da5297b..d5f1543 100644
--- a/hw/xenfb.c
+++ b/hw/xenfb.c
@@ -67,6 +67,7 @@ struct XenInput {
int button_state; /* Last seen pointer button state */
int extended;
QEMUPutMouseEntry *qmouse;
+ QEMUPutKbdEntry *qkbd;
};
#define UP_QUEUE 8
@@ -372,7 +373,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");
@@ -387,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_remove_kbd_event_handler(in->qkbd);
common_unbind(&in->c);
}
diff --git a/input.c b/input.c
index ec05548..9da4a56 100644
--- a/input.c
+++ b/input.c
@@ -28,26 +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;
-}
-
-void qemu_remove_kbd_event_handler(void)
-{
- qemu_put_kbd_event_opaque = NULL;
- qemu_put_kbd_event = NULL;
-}
-
static void check_mode_change(void)
{
static int current_is_absolute, current_has_absolute;
@@ -66,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)
@@ -129,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)
--
1.7.0.4
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [Qemu-devel] [PATCH 1/2] Support for multiple keyboard devices
2011-05-04 12:35 [Qemu-devel] [PATCH 0/2 v6] Qemu support for multiple keyboard devices Dmitry Zhurikhin
@ 2011-05-04 12:35 ` Dmitry Zhurikhin
0 siblings, 0 replies; 22+ messages in thread
From: Dmitry Zhurikhin @ 2011-05-04 12:35 UTC (permalink / raw)
To: QEMU-devel Developers; +Cc: Shahar Havivi
From: Shahar Havivi <shaharh@redhat.com>
Adding keyboard is done to the queue instead of "last added keyboard wins",
when removing keyboard via device_del - previous keyboard is selected.
Signed-off-by: Shahar Havivi <shaharh@redhat.com>
---
console.h | 16 +++++++++++-
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 | 3 +-
hw/syborg_keyboard.c | 3 +-
hw/usb-hid.c | 12 ++++++++-
hw/xenfb.c | 5 ++-
input.c | 63 +++++++++++++++++++++++++++++++++++++------------
14 files changed, 90 insertions(+), 33 deletions(-)
diff --git a/console.h b/console.h
index 64d1f09..671390c 100644
--- a/console.h
+++ b/console.h
@@ -43,8 +43,20 @@ typedef struct QEMUPutLEDEntry {
QTAILQ_ENTRY(QEMUPutLEDEntry) next;
} QEMUPutLEDEntry;
-void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque);
-void qemu_remove_kbd_event_handler(void);
+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);
+void qemu_activate_keyboard_event_handler(QEMUPutKbdEntry *entry);
QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func,
void *opaque, int absolute,
const char *name);
diff --git a/hw/adb.c b/hw/adb.c
index 7499cdc..7af5a0e 100644
--- a/hw/adb.c
+++ b/hw/adb.c
@@ -293,7 +293,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, "QEMU ADB Keyboard");
vmstate_register(NULL, -1, &vmstate_adb_kbd, s);
}
diff --git a/hw/escc.c b/hw/escc.c
index f6fd919..d5d3297 100644
--- a/hw/escc.c
+++ b/hw/escc.c
@@ -928,7 +928,8 @@ static int escc_init1(SysBusDevice *dev)
"QEMU Sun Mouse");
}
if (s->chn[1].type == kbd) {
- qemu_add_kbd_event_handler(sunkbd_event, &s->chn[1]);
+ qemu_add_kbd_event_handler(sunkbd_event, &s->chn[1],
+ "QEMU Sun Keyboard");
}
return 0;
diff --git a/hw/musicpal.c b/hw/musicpal.c
index 52b2931..723f94b 100644
--- a/hw/musicpal.c
+++ b/hw/musicpal.c
@@ -1454,7 +1454,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, "QEMU Musicpal Keyboard");
return 0;
}
diff --git a/hw/nseries.c b/hw/nseries.c
index 2f6f473..5a4e0e8 100644
--- a/hw/nseries.c
+++ b/hw/nseries.c
@@ -262,7 +262,7 @@ static void n800_tsc_kbd_setup(struct n800_s *s)
if (n800_keys[i] >= 0)
s->keymap[n800_keys[i]] = i;
- qemu_add_kbd_event_handler(n800_key_event, s);
+ qemu_add_kbd_event_handler(n800_key_event, s, "QEMU Nokia N800 Keyboard");
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, "QEMU Nokia N810 Keyboard");
/* Attach the LM8322 keyboard to the I2C bus,
* should happen in n8x0_i2c_setup and s->kbd be initialised here. */
diff --git a/hw/palm.c b/hw/palm.c
index f22d777..ab60452 100644
--- a/hw/palm.c
+++ b/hw/palm.c
@@ -232,7 +232,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, "QEMU Palm Keyboard");
palmte_gpio_setup(cpu);
diff --git a/hw/ps2.c b/hw/ps2.c
index 91b73e0..b12a76f 100644
--- a/hw/ps2.c
+++ b/hw/ps2.c
@@ -610,7 +610,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(NULL, 0, &vmstate_ps2_keyboard, s);
- qemu_add_kbd_event_handler(ps2_put_keycode, s);
+ qemu_add_kbd_event_handler(ps2_put_keycode, s, "QEMU PS/2 Keyboard");
qemu_register_reset(ps2_kbd_reset, s);
return s;
}
diff --git a/hw/pxa2xx_keypad.c b/hw/pxa2xx_keypad.c
index 10ef154..e032dfd 100644
--- a/hw/pxa2xx_keypad.c
+++ b/hw/pxa2xx_keypad.c
@@ -333,5 +333,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,
+ "QEMU PXA Keypad");
}
diff --git a/hw/spitz.c b/hw/spitz.c
index 006f7a9..5e9761d 100644
--- a/hw/spitz.c
+++ b/hw/spitz.c
@@ -487,7 +487,8 @@ static void spitz_keyboard_register(PXA2xxState *cpu)
qemu_mod_timer(s->kbdtimer, qemu_get_clock_ns(vm_clock));
- qemu_add_kbd_event_handler(spitz_keyboard_handler, s);
+ qemu_add_kbd_event_handler(spitz_keyboard_handler, s,
+ "QEMU Spitz Keyboard");
}
static int spitz_keyboard_init(SysBusDevice *dev)
diff --git a/hw/stellaris_input.c b/hw/stellaris_input.c
index 06c5f9d..64b9047 100644
--- a/hw/stellaris_input.c
+++ b/hw/stellaris_input.c
@@ -84,6 +84,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,
+ "QEMU Stellaris Gamepad");
vmstate_register(NULL, -1, &vmstate_stellaris_gamepad, s);
}
diff --git a/hw/syborg_keyboard.c b/hw/syborg_keyboard.c
index 706a039..a83d588 100644
--- a/hw/syborg_keyboard.c
+++ b/hw/syborg_keyboard.c
@@ -197,7 +197,8 @@ 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,
+ "QEMU Syborg Keyboard");
vmstate_register(&dev->qdev, -1, &vmstate_syborg_keyboard, s);
return 0;
diff --git a/hw/usb-hid.c b/hw/usb-hid.c
index 89c293c..21c4b56 100644
--- a/hw/usb-hid.c
+++ b/hw/usb-hid.c
@@ -66,6 +66,8 @@ typedef struct USBKeyboardState {
uint8_t leds;
uint8_t key[16];
int32_t keys;
+ int keyboard_grabbed;
+ QEMUPutKbdEntry *eh_entry;
} USBKeyboardState;
typedef struct USBHIDState {
@@ -663,6 +665,11 @@ static int usb_keyboard_poll(USBHIDState *hs, 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;
+ }
+
usb_keyboard_process_keycode(hs);
buf[0] = s->modifiers & 0xff;
@@ -710,7 +717,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);
memset(s->kbd.keycodes, 0, sizeof (s->kbd.keycodes));
s->head = 0;
s->n = 0;
@@ -845,7 +853,7 @@ static void usb_hid_handle_destroy(USBDevice *dev)
switch(s->kind) {
case USB_KEYBOARD:
- qemu_remove_kbd_event_handler();
+ qemu_remove_kbd_event_handler(s->kbd.eh_entry);
break;
default:
qemu_remove_mouse_event_handler(s->ptr.eh_entry);
diff --git a/hw/xenfb.c b/hw/xenfb.c
index 1db75fb..80760e8 100644
--- a/hw/xenfb.c
+++ b/hw/xenfb.c
@@ -66,6 +66,7 @@ struct XenInput {
int button_state; /* Last seen pointer button state */
int extended;
QEMUPutMouseEntry *qmouse;
+ QEMUPutKbdEntry *qkbd;
};
#define UP_QUEUE 8
@@ -371,7 +372,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");
@@ -386,7 +387,7 @@ static void input_disconnect(struct XenDevice *xendev)
qemu_remove_mouse_event_handler(in->qmouse);
in->qmouse = NULL;
}
- qemu_add_kbd_event_handler(NULL, NULL);
+ qemu_remove_kbd_event_handler(in->qkbd);
common_unbind(&in->c);
}
diff --git a/input.c b/input.c
index 5664d3a..efec56e 100644
--- a/input.c
+++ b/input.c
@@ -28,26 +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;
-}
-
-void qemu_remove_kbd_event_handler(void)
-{
- qemu_put_kbd_event_opaque = NULL;
- qemu_put_kbd_event = NULL;
-}
-
static void check_mode_change(void)
{
static int current_is_absolute, current_has_absolute;
@@ -66,6 +54,44 @@ 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;
+ 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_activate_keyboard_event_handler(QEMUPutKbdEntry *entry)
+{
+ QTAILQ_REMOVE(&kbd_handlers, entry, node);
+ QTAILQ_INSERT_HEAD(&kbd_handlers, entry, node);
+}
+
+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)
@@ -129,9 +155,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)
--
1.7.1
^ permalink raw reply related [flat|nested] 22+ messages in thread
end of thread, other threads:[~2011-05-04 12:35 UTC | newest]
Thread overview: 22+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-03-31 8:15 [Qemu-devel] [PATCH 0/2 v3] Qemu support for multiple keyboard devices Shahar Havivi
2010-03-31 8:16 ` [Qemu-devel] [PATCH 1/2] Support " Shahar Havivi
2010-03-31 10:12 ` [Qemu-devel] " Juan Quintela
2010-03-31 15:11 ` Shahar Havivi
2010-03-31 15:23 ` [Qemu-devel] " Markus Armbruster
2010-03-31 15:36 ` Shahar Havivi
2010-03-31 8:16 ` [Qemu-devel] [PATCH 2/2] Added monitor commands: 'keyboard_set' and 'info keybaord' Shahar Havivi
2010-03-31 10:20 ` [Qemu-devel] " Juan Quintela
2010-03-31 15:31 ` Markus Armbruster
2010-03-31 15:42 ` Shahar Havivi
2010-03-31 16:58 ` Juan Quintela
2010-03-31 19:37 ` Shahar Havivi
2010-03-31 19:52 ` Anthony Liguori
2010-03-31 20:16 ` Juan Quintela
2010-03-31 17:04 ` Anthony Liguori
2010-03-31 20:55 ` Shahar Havivi
-- strict thread matches above, loose matches on Subject: below --
2011-05-04 12:35 [Qemu-devel] [PATCH 0/2 v6] Qemu support for multiple keyboard devices Dmitry Zhurikhin
2011-05-04 12:35 ` [Qemu-devel] [PATCH 1/2] Support " Dmitry Zhurikhin
2010-06-19 20:27 [Qemu-devel] [PATCH 0/2 v5] Qemu support " Shahar Havivi
2010-06-19 20:28 ` [Qemu-devel] [PATCH 1/2] Support " Shahar Havivi
2010-03-23 19:57 [Qemu-devel] [PATCH 0/2] Qemu support for multiple keyboard devices - v2 Shahar Havivi
2010-03-23 19:58 ` [Qemu-devel] [PATCH 1/2] Support for multiple keyboard devices Shahar Havivi
2010-03-26 9:46 ` Markus Armbruster
2010-03-27 15:56 ` Shahar Havivi
2010-03-19 10:57 [Qemu-devel] [PATCH 0/2] Qemu support " Shahar Havivi
2010-03-19 10:57 ` [Qemu-devel] [PATCH 1/2] Support " Shahar Havivi
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).