summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGerd Hoffmann2016-10-12 15:03:04 +0200
committerGerd Hoffmann2016-10-13 09:25:24 +0200
commit2a57c55f26f7ba6dcea6d01ef74bae7069150f6f (patch)
treebf702f53ae78c5d648da27edfaa10d914b8eb565
parentui: rename vnc_init_state to vnc_start_protocol (diff)
downloadqemu-2a57c55f26f7ba6dcea6d01ef74bae7069150f6f.tar.gz
qemu-2a57c55f26f7ba6dcea6d01ef74bae7069150f6f.tar.xz
qemu-2a57c55f26f7ba6dcea6d01ef74bae7069150f6f.zip
input-linux: initialize key state
Query input device keys, initialize state accordingly, so the correct state is reflected in case any key is pressed at initialization time. There is a high chance for this to actually happen for the 'enter' key in case you start qemu with a terminal command (directly or virsh). When finding any pressed keys the input grab is delayed until all keys are lifted, to avoid confusing guest and host with appearently stuck keys. Reported-by: Muted Bytes <mutedbytes@gmail.com> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> Message-id: 1476277384-30365-1-git-send-email-kraxel@redhat.com
-rw-r--r--ui/input-linux.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/ui/input-linux.c b/ui/input-linux.c
index 0e230ce699..f345317794 100644
--- a/ui/input-linux.c
+++ b/ui/input-linux.c
@@ -347,7 +347,8 @@ static void input_linux_event(void *opaque)
static void input_linux_complete(UserCreatable *uc, Error **errp)
{
InputLinux *il = INPUT_LINUX(uc);
- uint8_t evtmap, relmap, absmap, keymap[KEY_CNT / 8];
+ uint8_t evtmap, relmap, absmap;
+ uint8_t keymap[KEY_CNT / 8], keystate[KEY_CNT / 8];
unsigned int i;
int rc, ver;
@@ -394,6 +395,7 @@ static void input_linux_complete(UserCreatable *uc, Error **errp)
if (evtmap & (1 << EV_KEY)) {
memset(keymap, 0, sizeof(keymap));
rc = ioctl(il->fd, EVIOCGBIT(EV_KEY, sizeof(keymap)), keymap);
+ rc = ioctl(il->fd, EVIOCGKEY(sizeof(keystate)), keystate);
for (i = 0; i < KEY_CNT; i++) {
if (keymap[i / 8] & (1 << (i % 8))) {
if (linux_is_button(i)) {
@@ -401,12 +403,21 @@ static void input_linux_complete(UserCreatable *uc, Error **errp)
} else {
il->num_keys++;
}
+ if (keystate[i / 8] & (1 << (i % 8))) {
+ il->keydown[i] = true;
+ il->keycount++;
+ }
}
}
}
qemu_set_fd_handler(il->fd, input_linux_event, NULL, il);
- input_linux_toggle_grab(il);
+ if (il->keycount) {
+ /* delay grab until all keys are released */
+ il->grab_request = true;
+ } else {
+ input_linux_toggle_grab(il);
+ }
QTAILQ_INSERT_TAIL(&inputs, il, next);
il->initialized = true;
return;