From: Gerd Hoffmann <kraxel@redhat.com>
To: qemu-devel@nongnu.org
Cc: Gerd Hoffmann <kraxel@redhat.com>
Subject: [Qemu-devel] [PATCH 2/8] usb keyboard: add event event queue
Date: Mon, 24 Jan 2011 17:30:49 +0100 [thread overview]
Message-ID: <1295886655-32312-3-git-send-email-kraxel@redhat.com> (raw)
In-Reply-To: <1295886655-32312-1-git-send-email-kraxel@redhat.com>
This patch adds a event queue to the usb keyboard. This makes sure the
guest will see all key events even if they come in bursts. With this
patch applied sending Ctrl-Alt-Del using vncviewer's F8 menu works.
Also with autosuspend enabled the first keypress on a suspended keyboard
takes a little longer to be delivered to the guest because the usb bus
must be resumed first. Without event queue this easily gets lost.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/usb-hid.c | 38 ++++++++++++++++++++++++++++++++------
1 files changed, 32 insertions(+), 6 deletions(-)
diff --git a/hw/usb-hid.c b/hw/usb-hid.c
index ea49543..5f1451b 100644
--- a/hw/usb-hid.c
+++ b/hw/usb-hid.c
@@ -63,6 +63,9 @@ typedef struct USBMouseState {
} USBMouseState;
typedef struct USBKeyboardState {
+ uint32_t keycodes[QUEUE_LENGTH];
+ uint32_t head; /* index into circular queue */
+ uint32_t n;
uint16_t modifiers;
uint8_t leds;
uint8_t key[16];
@@ -494,8 +497,27 @@ static void usb_keyboard_event(void *opaque, int keycode)
{
USBHIDState *hs = opaque;
USBKeyboardState *s = &hs->kbd;
+ int slot;
+
+ if (s->n == QUEUE_LENGTH) {
+ fprintf(stderr, "usb-kbd: warning: key event queue full\n");
+ return;
+ }
+ slot = (s->head + s->n) & QUEUE_MASK; s->n++;
+ s->keycodes[slot] = keycode;
+ usb_hid_changed(hs);
+}
+
+static void usb_keyboard_process_keycode(USBKeyboardState *s)
+{
uint8_t hid_code, key;
- int i;
+ int i, keycode, slot;
+
+ if (s->n == 0) {
+ return;
+ }
+ slot = s->head & QUEUE_MASK; QUEUE_INCR(s->head); s->n--;
+ keycode = s->keycodes[slot];
key = keycode & 0x7f;
hid_code = usb_hid_usage_keys[key | ((s->modifiers >> 1) & (1 << 7))];
@@ -528,7 +550,6 @@ static void usb_keyboard_event(void *opaque, int keycode)
if (s->key[i] == hid_code) {
s->key[i] = s->key[-- s->keys];
s->key[s->keys] = 0x00;
- usb_hid_changed(hs);
break;
}
if (i < 0)
@@ -543,8 +564,6 @@ static void usb_keyboard_event(void *opaque, int keycode)
} else
return;
}
-
- usb_hid_changed(hs);
}
static inline int int_clamp(int val, int vmin, int vmax)
@@ -645,6 +664,8 @@ static int usb_keyboard_poll(USBHIDState *hs, uint8_t *buf, int len)
if (len < 2)
return 0;
+ usb_keyboard_process_keycode(s);
+
buf[0] = s->modifiers & 0xff;
buf[1] = 0;
if (s->keys > 6)
@@ -680,7 +701,7 @@ static void usb_mouse_handle_reset(USBDevice *dev)
{
USBHIDState *s = (USBHIDState *)dev;
- memset (s->ptr.queue, 0, sizeof (s->ptr.queue));
+ memset(s->ptr.queue, 0, sizeof (s->ptr.queue));
s->ptr.head = 0;
s->ptr.n = 0;
s->protocol = 1;
@@ -691,6 +712,11 @@ static void usb_keyboard_handle_reset(USBDevice *dev)
USBHIDState *s = (USBHIDState *)dev;
qemu_add_kbd_event_handler(usb_keyboard_event, s);
+ memset(s->kbd.keycodes, 0, sizeof (s->kbd.keycodes));
+ s->kbd.head = 0;
+ s->kbd.n = 0;
+ memset(s->kbd.key, 0, sizeof (s->kbd.key));
+ s->kbd.keys = 0;
s->protocol = 1;
}
@@ -800,7 +826,7 @@ static int usb_hid_handle_data(USBDevice *dev, USBPacket *p)
}
else if (s->kind == USB_KEYBOARD) {
ret = usb_keyboard_poll(s, p->data, p->len);
- s->changed = 0;
+ s->changed = s->kbd.n > 0;
}
} else {
goto fail;
--
1.7.1
next prev parent reply other threads:[~2011-01-24 16:31 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-01-24 16:30 [Qemu-devel] [PULL 0/8] usb patch queue Gerd Hoffmann
2011-01-24 16:30 ` [Qemu-devel] [PATCH 1/8] add event queueing to USB HID Gerd Hoffmann
2011-01-24 16:30 ` Gerd Hoffmann [this message]
2011-01-24 16:30 ` [Qemu-devel] [PATCH 3/8] usb hid: move head+n to common struct Gerd Hoffmann
2011-01-24 16:30 ` [Qemu-devel] [PATCH 4/8] vnc: fix numlock+capslock tracking Gerd Hoffmann
2011-01-28 13:36 ` [Qemu-devel] " Paolo Bonzini
2011-01-28 19:58 ` Gerd Hoffmann
2011-01-28 20:11 ` Anthony Liguori
2011-01-24 16:30 ` [Qemu-devel] [PATCH 5/8] usb core: add migration support Gerd Hoffmann
2011-01-24 16:30 ` [Qemu-devel] [PATCH 6/8] usb hub: " Gerd Hoffmann
2011-01-24 16:30 ` [Qemu-devel] [PATCH 7/8] usb hid: " Gerd Hoffmann
2011-01-24 16:30 ` [Qemu-devel] [PATCH 8/8] usb-bus: use snprintf Gerd Hoffmann
2011-02-17 20:00 ` [Qemu-devel] [PULL 0/8] usb patch queue Anthony Liguori
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=1295886655-32312-3-git-send-email-kraxel@redhat.com \
--to=kraxel@redhat.com \
--cc=qemu-devel@nongnu.org \
/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 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).