qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v2 0/4] input: add support for kbd delays
@ 2014-06-02 11:28 Gerd Hoffmann
  2014-06-02 11:28 ` [Qemu-devel] [PATCH 1/4] " Gerd Hoffmann
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Gerd Hoffmann @ 2014-06-02 11:28 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann, dave

  Hi,

Little series of four input patches.  First patch adds support for
submitting keyboard delays, which will make the input layer setup a
timer, buffer the following keyboard events, send them to the guest
once the delay is over.  This should be used anywhere where we send
synthetic key events to the guest as injecting key events to the
guest without delays may cause problems with guests which are not
prepared to receive events faster than with human typing speed.

Second patch makes the send_key monitor command use the new service
instead of using its own timer.  Third patch inserts delays in
the curses ui.  Last patch adds kbd delays to the vnc press_key
function.

please review & test,
  Gerd

Gerd Hoffmann (4):
  input: add support for kbd delays
  input: use kbd delays for send_key monitor command
  input/curses: add kbd delay between keydown and keyup events
  input/vnc: use kbd delays in press_key

 include/ui/input.h |   1 +
 ui/curses.c        |  10 +++++
 ui/input-legacy.c  |  45 +++--------------------
 ui/input.c         | 106 +++++++++++++++++++++++++++++++++++++++++++++++++++--
 ui/vnc.c           |   2 +
 5 files changed, 122 insertions(+), 42 deletions(-)

-- 
1.8.3.1

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Qemu-devel] [PATCH 1/4] input: add support for kbd delays
  2014-06-02 11:28 [Qemu-devel] [PATCH v2 0/4] input: add support for kbd delays Gerd Hoffmann
@ 2014-06-02 11:28 ` Gerd Hoffmann
  2014-06-02 11:28 ` [Qemu-devel] [PATCH 2/4] input: use kbd delays for send_key monitor command Gerd Hoffmann
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Gerd Hoffmann @ 2014-06-02 11:28 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann, Anthony Liguori, dave

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 include/ui/input.h |   1 +
 ui/input.c         | 106 +++++++++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 104 insertions(+), 3 deletions(-)

diff --git a/include/ui/input.h b/include/ui/input.h
index aa99b0c..5d5ac00 100644
--- a/include/ui/input.h
+++ b/include/ui/input.h
@@ -39,6 +39,7 @@ InputEvent *qemu_input_event_new_key(KeyValue *key, bool down);
 void qemu_input_event_send_key(QemuConsole *src, KeyValue *key, bool down);
 void qemu_input_event_send_key_number(QemuConsole *src, int num, bool down);
 void qemu_input_event_send_key_qcode(QemuConsole *src, QKeyCode q, bool down);
+void qemu_input_event_send_key_delay(uint32_t delay_ms);
 int qemu_input_key_number_to_qcode(uint8_t nr);
 int qemu_input_key_value_to_number(const KeyValue *value);
 int qemu_input_key_value_to_qcode(const KeyValue *value);
diff --git a/ui/input.c b/ui/input.c
index 14c9434..b450ce0 100644
--- a/ui/input.c
+++ b/ui/input.c
@@ -14,11 +14,30 @@ struct QemuInputHandlerState {
     QemuConsole       *con;
     QTAILQ_ENTRY(QemuInputHandlerState) node;
 };
+
+typedef struct QemuInputEventQueue QemuInputEventQueue;
+struct QemuInputEventQueue {
+    enum {
+        QEMU_INPUT_QUEUE_DELAY = 1,
+        QEMU_INPUT_QUEUE_EVENT,
+        QEMU_INPUT_QUEUE_SYNC,
+    } type;
+    QEMUTimer *timer;
+    uint32_t delay_ms;
+    QemuConsole *src;
+    InputEvent *evt;
+    QTAILQ_ENTRY(QemuInputEventQueue) node;
+};
+
 static QTAILQ_HEAD(, QemuInputHandlerState) handlers =
     QTAILQ_HEAD_INITIALIZER(handlers);
 static NotifierList mouse_mode_notifiers =
     NOTIFIER_LIST_INITIALIZER(mouse_mode_notifiers);
 
+static QTAILQ_HEAD(QemuInputEventQueueHead, QemuInputEventQueue) kbd_queue =
+    QTAILQ_HEAD_INITIALIZER(kbd_queue);
+static QEMUTimer *kbd_timer;
+
 QemuInputHandlerState *qemu_input_handler_register(DeviceState *dev,
                                                    QemuInputHandler *handler)
 {
@@ -171,6 +190,73 @@ static void qemu_input_event_trace(QemuConsole *src, InputEvent *evt)
     }
 }
 
+static void qemu_input_queue_process(void *opaque)
+{
+    struct QemuInputEventQueueHead *queue = opaque;
+    QemuInputEventQueue *item;
+
+    g_assert(!QTAILQ_EMPTY(queue));
+    item = QTAILQ_FIRST(queue);
+    g_assert(item->type == QEMU_INPUT_QUEUE_DELAY);
+    QTAILQ_REMOVE(queue, item, node);
+    g_free(item);
+
+    while (!QTAILQ_EMPTY(queue)) {
+        item = QTAILQ_FIRST(queue);
+        switch (item->type) {
+        case QEMU_INPUT_QUEUE_DELAY:
+            timer_mod(item->timer, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL)
+                      + item->delay_ms);
+            return;
+        case QEMU_INPUT_QUEUE_EVENT:
+            qemu_input_event_send(item->src, item->evt);
+            qapi_free_InputEvent(item->evt);
+            break;
+        case QEMU_INPUT_QUEUE_SYNC:
+            qemu_input_event_sync();
+            break;
+        }
+        QTAILQ_REMOVE(queue, item, node);
+        g_free(item);
+    }
+}
+
+static void qemu_input_queue_delay(struct QemuInputEventQueueHead *queue,
+                                   QEMUTimer *timer, uint32_t delay_ms)
+{
+    QemuInputEventQueue *item = g_new0(QemuInputEventQueue, 1);
+    bool start_timer = QTAILQ_EMPTY(queue);
+
+    item->type = QEMU_INPUT_QUEUE_DELAY;
+    item->delay_ms = delay_ms;
+    item->timer = timer;
+    QTAILQ_INSERT_TAIL(queue, item, node);
+
+    if (start_timer) {
+        timer_mod(item->timer, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL)
+                  + item->delay_ms);
+    }
+}
+
+static void qemu_input_queue_event(struct QemuInputEventQueueHead *queue,
+                                   QemuConsole *src, InputEvent *evt)
+{
+    QemuInputEventQueue *item = g_new0(QemuInputEventQueue, 1);
+
+    item->type = QEMU_INPUT_QUEUE_EVENT;
+    item->src = src;
+    item->evt = evt;
+    QTAILQ_INSERT_TAIL(queue, item, node);
+}
+
+static void qemu_input_queue_sync(struct QemuInputEventQueueHead *queue)
+{
+    QemuInputEventQueue *item = g_new0(QemuInputEventQueue, 1);
+
+    item->type = QEMU_INPUT_QUEUE_SYNC;
+    QTAILQ_INSERT_TAIL(queue, item, node);
+}
+
 void qemu_input_event_send(QemuConsole *src, InputEvent *evt)
 {
     QemuInputHandlerState *s;
@@ -230,9 +316,14 @@ void qemu_input_event_send_key(QemuConsole *src, KeyValue *key, bool down)
 {
     InputEvent *evt;
     evt = qemu_input_event_new_key(key, down);
-    qemu_input_event_send(src, evt);
-    qemu_input_event_sync();
-    qapi_free_InputEvent(evt);
+    if (QTAILQ_EMPTY(&kbd_queue)) {
+        qemu_input_event_send(src, evt);
+        qemu_input_event_sync();
+        qapi_free_InputEvent(evt);
+    } else {
+        qemu_input_queue_event(&kbd_queue, src, evt);
+        qemu_input_queue_sync(&kbd_queue);
+    }
 }
 
 void qemu_input_event_send_key_number(QemuConsole *src, int num, bool down)
@@ -251,6 +342,15 @@ void qemu_input_event_send_key_qcode(QemuConsole *src, QKeyCode q, bool down)
     qemu_input_event_send_key(src, key, down);
 }
 
+void qemu_input_event_send_key_delay(uint32_t delay_ms)
+{
+    if (!kbd_timer) {
+        kbd_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, qemu_input_queue_process,
+                                 &kbd_queue);
+    }
+    qemu_input_queue_delay(&kbd_queue, kbd_timer, delay_ms);
+}
+
 InputEvent *qemu_input_event_new_btn(InputButton btn, bool down)
 {
     InputEvent *evt = g_new0(InputEvent, 1);
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [Qemu-devel] [PATCH 2/4] input: use kbd delays for send_key monitor command
  2014-06-02 11:28 [Qemu-devel] [PATCH v2 0/4] input: add support for kbd delays Gerd Hoffmann
  2014-06-02 11:28 ` [Qemu-devel] [PATCH 1/4] " Gerd Hoffmann
@ 2014-06-02 11:28 ` Gerd Hoffmann
  2014-06-02 11:28 ` [Qemu-devel] [PATCH 3/4] input/curses: add kbd delay between keydown and keyup events Gerd Hoffmann
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Gerd Hoffmann @ 2014-06-02 11:28 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann, Anthony Liguori, dave

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 ui/input-legacy.c | 45 ++++++---------------------------------------
 1 file changed, 6 insertions(+), 39 deletions(-)

diff --git a/ui/input-legacy.c b/ui/input-legacy.c
index 2a53860..018a1fa 100644
--- a/ui/input-legacy.c
+++ b/ui/input-legacy.c
@@ -74,27 +74,6 @@ int index_from_key(const char *key)
     return i;
 }
 
-static KeyValue **keyvalues;
-static int keyvalues_size;
-static QEMUTimer *key_timer;
-
-static void free_keyvalues(void)
-{
-    g_free(keyvalues);
-    keyvalues = NULL;
-    keyvalues_size = 0;
-}
-
-static void release_keys(void *opaque)
-{
-    while (keyvalues_size > 0) {
-        qemu_input_event_send_key(NULL, keyvalues[--keyvalues_size],
-                                  false);
-    }
-
-    free_keyvalues();
-}
-
 static KeyValue *copy_key_value(KeyValue *src)
 {
     KeyValue *dst = g_new(KeyValue, 1);
@@ -107,30 +86,18 @@ void qmp_send_key(KeyValueList *keys, bool has_hold_time, int64_t hold_time,
 {
     KeyValueList *p;
 
-    if (!key_timer) {
-        key_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, release_keys, NULL);
-    }
-
-    if (keyvalues != NULL) {
-        timer_del(key_timer);
-        release_keys(NULL);
-    }
-
     if (!has_hold_time) {
-        hold_time = 100;
+        hold_time = 10;
     }
 
     for (p = keys; p != NULL; p = p->next) {
         qemu_input_event_send_key(NULL, copy_key_value(p->value), true);
-
-        keyvalues = g_realloc(keyvalues, sizeof(KeyValue *) *
-                              (keyvalues_size + 1));
-        keyvalues[keyvalues_size++] = copy_key_value(p->value);
+        qemu_input_event_send_key_delay(hold_time);
+    }
+    for (p = keys; p != NULL; p = p->next) {
+        qemu_input_event_send_key(NULL, copy_key_value(p->value), false);
+        qemu_input_event_send_key_delay(hold_time);
     }
-
-    /* delayed key up events */
-    timer_mod(key_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
-              muldiv64(get_ticks_per_sec(), hold_time, 1000));
 }
 
 static void legacy_kbd_event(DeviceState *dev, QemuConsole *src,
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [Qemu-devel] [PATCH 3/4] input/curses: add kbd delay between keydown and keyup events
  2014-06-02 11:28 [Qemu-devel] [PATCH v2 0/4] input: add support for kbd delays Gerd Hoffmann
  2014-06-02 11:28 ` [Qemu-devel] [PATCH 1/4] " Gerd Hoffmann
  2014-06-02 11:28 ` [Qemu-devel] [PATCH 2/4] input: use kbd delays for send_key monitor command Gerd Hoffmann
@ 2014-06-02 11:28 ` Gerd Hoffmann
  2014-06-02 11:28 ` [Qemu-devel] [PATCH 4/4] input/vnc: use kbd delays in press_key Gerd Hoffmann
  2014-06-02 12:59 ` [Qemu-devel] [PATCH v2 0/4] input: add support for kbd delays Dave Mielke
  4 siblings, 0 replies; 6+ messages in thread
From: Gerd Hoffmann @ 2014-06-02 11:28 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann, Anthony Liguori, dave

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 ui/curses.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/ui/curses.c b/ui/curses.c
index de85f76..c96b861 100644
--- a/ui/curses.c
+++ b/ui/curses.c
@@ -277,31 +277,41 @@ static void curses_refresh(DisplayChangeListener *dcl)
              * events, we need to emit both for each key received */
             if (keycode & SHIFT) {
                 qemu_input_event_send_key_number(NULL, SHIFT_CODE, true);
+                qemu_input_event_send_key_delay(10);
             }
             if (keycode & CNTRL) {
                 qemu_input_event_send_key_number(NULL, CNTRL_CODE, true);
+                qemu_input_event_send_key_delay(10);
             }
             if (keycode & ALT) {
                 qemu_input_event_send_key_number(NULL, ALT_CODE, true);
+                qemu_input_event_send_key_delay(10);
             }
             if (keycode & ALTGR) {
                 qemu_input_event_send_key_number(NULL, GREY | ALT_CODE, true);
+                qemu_input_event_send_key_delay(10);
             }
 
             qemu_input_event_send_key_number(NULL, keycode & KEY_MASK, true);
+            qemu_input_event_send_key_delay(10);
             qemu_input_event_send_key_number(NULL, keycode & KEY_MASK, false);
+            qemu_input_event_send_key_delay(10);
 
             if (keycode & ALTGR) {
                 qemu_input_event_send_key_number(NULL, GREY | ALT_CODE, false);
+                qemu_input_event_send_key_delay(10);
             }
             if (keycode & ALT) {
                 qemu_input_event_send_key_number(NULL, ALT_CODE, false);
+                qemu_input_event_send_key_delay(10);
             }
             if (keycode & CNTRL) {
                 qemu_input_event_send_key_number(NULL, CNTRL_CODE, false);
+                qemu_input_event_send_key_delay(10);
             }
             if (keycode & SHIFT) {
                 qemu_input_event_send_key_number(NULL, SHIFT_CODE, false);
+                qemu_input_event_send_key_delay(10);
             }
         } else {
             keysym = curses2qemu[chr];
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [Qemu-devel] [PATCH 4/4] input/vnc: use kbd delays in press_key
  2014-06-02 11:28 [Qemu-devel] [PATCH v2 0/4] input: add support for kbd delays Gerd Hoffmann
                   ` (2 preceding siblings ...)
  2014-06-02 11:28 ` [Qemu-devel] [PATCH 3/4] input/curses: add kbd delay between keydown and keyup events Gerd Hoffmann
@ 2014-06-02 11:28 ` Gerd Hoffmann
  2014-06-02 12:59 ` [Qemu-devel] [PATCH v2 0/4] input: add support for kbd delays Dave Mielke
  4 siblings, 0 replies; 6+ messages in thread
From: Gerd Hoffmann @ 2014-06-02 11:28 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann, Anthony Liguori, dave

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 ui/vnc.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/ui/vnc.c b/ui/vnc.c
index 2d7def9..5521abb 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -1552,7 +1552,9 @@ static void press_key(VncState *vs, int keysym)
 {
     int keycode = keysym2scancode(vs->vd->kbd_layout, keysym) & SCANCODE_KEYMASK;
     qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, true);
+    qemu_input_event_send_key_delay(10);
     qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, false);
+    qemu_input_event_send_key_delay(10);
 }
 
 static int current_led_state(VncState *vs)
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [Qemu-devel] [PATCH v2 0/4] input: add support for kbd delays
  2014-06-02 11:28 [Qemu-devel] [PATCH v2 0/4] input: add support for kbd delays Gerd Hoffmann
                   ` (3 preceding siblings ...)
  2014-06-02 11:28 ` [Qemu-devel] [PATCH 4/4] input/vnc: use kbd delays in press_key Gerd Hoffmann
@ 2014-06-02 12:59 ` Dave Mielke
  4 siblings, 0 replies; 6+ messages in thread
From: Dave Mielke @ 2014-06-02 12:59 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: qemu-devel

[quoted lines by Gerd Hoffmann on 2014/06/02 at 13:28 +0200]

Hi:

>Little series of four input patches.  

Yes, it all seems to work correctly, now, with these four patches applied.

Perhaps there should be a common constant that all the delay calls use. Maybe 
even a variable which defaults to 10 and is set by something like the -k delay= 
in my patch. That'd allow users to modify it if it isn't quite right in some 
other circumstance, as well as to reduce it to 0 if they perceive a need to do 
so.

It might be a good idea to introduce an intermediate call which doesn't have a 
"length of delay" argument, which then calls the current function with the 
desired value.

These are, of course, cosmetic suggestions. The code as it now stands dodes 
work.

-- 
Dave Mielke           | 2213 Fox Crescent | The Bible is the very Word of God.
Phone: 1-613-726-0014 | Ottawa, Ontario   | http://Mielke.cc/bible/
EMail: dave@mielke.cc | Canada  K2A 1H7   | http://FamilyRadio.com/

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2014-06-02 12:59 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-06-02 11:28 [Qemu-devel] [PATCH v2 0/4] input: add support for kbd delays Gerd Hoffmann
2014-06-02 11:28 ` [Qemu-devel] [PATCH 1/4] " Gerd Hoffmann
2014-06-02 11:28 ` [Qemu-devel] [PATCH 2/4] input: use kbd delays for send_key monitor command Gerd Hoffmann
2014-06-02 11:28 ` [Qemu-devel] [PATCH 3/4] input/curses: add kbd delay between keydown and keyup events Gerd Hoffmann
2014-06-02 11:28 ` [Qemu-devel] [PATCH 4/4] input/vnc: use kbd delays in press_key Gerd Hoffmann
2014-06-02 12:59 ` [Qemu-devel] [PATCH v2 0/4] input: add support for kbd delays Dave Mielke

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).