Re: [Qemu-devel] patch: add -kbddelay option

2014-05-27 Thread Markus Armbruster
Dave Mielke d...@mielke.cc writes:

 [quoted lines by Dave Mielke on 2014/05/26 at 08:59 -0400]

 I'm sorry for quoting myself, but I'm doing it for context since I have a
 question:

This patch, attached as qemu-kbddelay-1.patch, is a rework of the former 
curses
UI patch so that the delay applies to key events in general. A new option,
-kbddelay [duration=]msecs, controls it. As before, the default is 0, meaning
no delay, in which case the timer and queue aren't used thus retaining the
original behaviour.

 I've currently coded it so that there's a new option - -kbddelay. So, we have
 the following two options:

   (old) -k language
   (new) -kbddelay [duration=]msecs

 My question is if this is the best way to do it, or if the two options should
 be merged. For example:

-k [language=]language,delay=msecs

 What do you think?

*If* the feature is deemed useful: better extend -k.  We generally
prefer extensible options based on QemuOpts to proliferating ad hoc
single-purpose options.



Re: [Qemu-devel] patch: add -kbddelay option

2014-05-26 Thread Dave Mielke
[quoted lines by Peter Maydell on 2014/05/25 at 10:11 +0100]

Ah, I see. Still, I think it makes more sense for the queue and delay
to be in the common key handling code, not in the curses frontend
specifically.

This patch, attached as qemu-kbddelay-1.patch, is a rework of the former curses 
UI patch so that the delay applies to key events in general. A new option, 
-kbddelay [duration=]msecs, controls it. As before, the default is 0, meaning 
no delay, in which case the timer and queue aren't used thus retaining the 
original behaviour.

-- 
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: d...@mielke.cc | Canada  K2A 1H7   | http://FamilyRadio.com/
diff --git a/include/ui/input.h b/include/ui/input.h
index 3d3d487..17c77c8 100644
--- a/include/ui/input.h
+++ b/include/ui/input.h
@@ -35,6 +35,7 @@ void qemu_input_event_sync(void);
 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_set_keyboard_delay(uint64_t duration);
 void qemu_input_event_send_key_qcode(QemuConsole *src, QKeyCode q, bool down);
 int qemu_input_key_value_to_number(const KeyValue *value);
 int qemu_input_key_value_to_qcode(const KeyValue *value);
diff --git a/qemu-options.hx b/qemu-options.hx
index c2c0823..5d0a8b1 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -262,6 +262,24 @@ de  en-us  fi  fr-be  hr it  lv  nl-be  pt  sl tr
 The default is @code{en-us}.
 ETEXI
 
+DEF(kbddelay, HAS_ARG, QEMU_OPTION_kbddelay,
+-kbddelay [duration=]msecs\n
+ensure a minimum delay between keyboard events\n
+duration: the minimum delay between keyboard events 
(default: 0)\n,
+QEMU_ARCH_ALL)
+STEXI
+@item -kbddelay [duration=]@var{msecs}
+@findex -kbddelay
+Set the minimum delay between keyboard events to @var{msecs} milliseconds.
+The default is 0 (no minimum delay).
+This option exists in order to deal with problematic applications which run 
+into trouble when keys are typed too quickly. Certain UIs, like curses, 
+aggravate the problem because they must turn a single user keyboard action 
into 
+several keyboard events being delivered to the virtual machine. Only try this 
+option if you encounter an unexpected keyboard input issue, for example the 
+input not being recognized at all. A duration of 20 seems to be reasonable.
+ETEXI
+
 
 DEF(audio-help, 0, QEMU_OPTION_audio_help,
 -audio-help print list of audio drivers and their options\n,
diff --git a/ui/input.c b/ui/input.c
index fc91fba..eb6c1dd 100644
--- a/ui/input.c
+++ b/ui/input.c
@@ -188,7 +188,9 @@ InputEvent *qemu_input_event_new_key(KeyValue *key, bool 
down)
 return evt;
 }
 
-void qemu_input_event_send_key(QemuConsole *src, KeyValue *key, bool down)
+static void qemu_input_event_send_key_immediate(QemuConsole *src,
+KeyValue *key,
+bool down)
 {
 InputEvent *evt;
 evt = qemu_input_event_new_key(key, down);
@@ -197,6 +199,82 @@ void qemu_input_event_send_key(QemuConsole *src, KeyValue 
*key, bool down)
 qapi_free_InputEvent(evt);
 }
 
+struct PendingKeyEvent {
+struct PendingKeyEvent *next;
+QemuConsole *src;
+KeyValue *key;
+bool down;
+};
+
+static struct PendingKeyEvent *firstPendingKeyEvent = NULL;
+static struct PendingKeyEvent *lastPendingKeyEvent = NULL;
+
+static unsigned long long pendingKeyEventDelay = 0;
+static QEMUTimer *pendingKeyEventTimer = NULL;
+
+static void qemu_input_begin_pending_key_event(void)
+{
+struct PendingKeyEvent *event = firstPendingKeyEvent;
+
+qemu_input_event_send_key_immediate(event-src, event-key, event-down);
+timer_mod(pendingKeyEventTimer, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + 
pendingKeyEventDelay);
+}
+
+static void qemu_input_end_pending_key_event(void *opaque)
+{
+struct PendingKeyEvent *event = firstPendingKeyEvent;
+
+if ((firstPendingKeyEvent = event-next))
+{
+qemu_input_begin_pending_key_event();
+}
+else
+{
+lastPendingKeyEvent = NULL;
+}
+
+g_free(event);
+}
+
+void qemu_input_event_send_key(QemuConsole *src, KeyValue *key, bool down)
+{
+if (pendingKeyEventDelay)
+{
+struct PendingKeyEvent *event;
+
+event = g_malloc(sizeof(*event));
+event-next = NULL;
+event-src = src;
+event-key = key;
+event-down = down;
+
+if (lastPendingKeyEvent)
+{
+lastPendingKeyEvent-next = event;
+lastPendingKeyEvent = event;
+}
+else
+{
+if (!pendingKeyEventTimer)
+{
+pendingKeyEventTimer = timer_new_ms(QEMU_CLOCK_VIRTUAL, 

Re: [Qemu-devel] patch: add -kbddelay option

2014-05-26 Thread Dave Mielke
[quoted lines by Dave Mielke on 2014/05/26 at 08:59 -0400]

I'm sorry for quoting myself, but I'm doing it for context since I have a
question:

This patch, attached as qemu-kbddelay-1.patch, is a rework of the former curses
UI patch so that the delay applies to key events in general. A new option,
-kbddelay [duration=]msecs, controls it. As before, the default is 0, meaning
no delay, in which case the timer and queue aren't used thus retaining the
original behaviour.

I've currently coded it so that there's a new option - -kbddelay. So, we have
the following two options:

  (old) -k language
  (new) -kbddelay [duration=]msecs

My question is if this is the best way to do it, or if the two options should
be merged. For example:

   -k [language=]language,delay=msecs

What do you think?

-- 
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: d...@mielke.cc | Canada  K2A 1H7   | http://FamilyRadio.com/