All of lore.kernel.org
 help / color / mirror / Atom feed
From: Shahar Havivi <shaharh@redhat.com>
To: Anthony Liguori <anthony@codemonkey.ws>
Cc: qemu-devel@nongnu.org, Juan Quintela <quintela@redhat.com>
Subject: Re: [Qemu-devel] Re: [PATCH 2/2] Added monitor commands: 'keyboard_set' and 'info keybaord'
Date: Wed, 31 Mar 2010 23:55:44 +0300	[thread overview]
Message-ID: <20100331205543.GB18849@redhat.com> (raw)
In-Reply-To: <4BB380BB.8000600@codemonkey.ws>

> >>+
> >>+    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

  reply	other threads:[~2010-03-31 20:57 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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 [this message]
  -- strict thread matches above, loose matches on Subject: below --
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 2/2] Added monitor commands: 'keyboard_set' and 'info keybaord' Shahar Havivi
2010-03-26  9:57   ` Markus Armbruster
2010-03-26 18:40     ` Shahar Havivi
2010-03-31 15:10       ` Markus Armbruster
2010-03-31 15:19         ` [Qemu-devel] " Juan Quintela

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20100331205543.GB18849@redhat.com \
    --to=shaharh@redhat.com \
    --cc=anthony@codemonkey.ws \
    --cc=qemu-devel@nongnu.org \
    --cc=quintela@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.