summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2015-07-17 10:52:12 +0100
committerPeter Maydell <peter.maydell@linaro.org>2015-07-17 10:52:12 +0100
commitfd1a9ef9c2493b5bc98e8e041333a57b635c5d71 (patch)
tree3ea0e8eebf0953e6f7bf5102c082da63fbe0f8bc
parentb4329bf41c86bac8b56cadb097081960cc4839a0 (diff)
parent562f93754b95fd6dc65ad9a2aa15a90b2da7e8a4 (diff)
downloadfocaccia-qemu-fd1a9ef9c2493b5bc98e8e041333a57b635c5d71.tar.gz
focaccia-qemu-fd1a9ef9c2493b5bc98e8e041333a57b635c5d71.zip
Merge remote-tracking branch 'remotes/kraxel/tags/pull-input-20150717-1' into staging
input: fixes for 2.4

# gpg: Signature made Fri Jul 17 07:45:17 2015 BST using RSA key ID D3E87138
# gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>"
# gpg:                 aka "Gerd Hoffmann <gerd@kraxel.org>"
# gpg:                 aka "Gerd Hoffmann (private) <kraxel@gmail.com>"

* remotes/kraxel/tags/pull-input-20150717-1:
  hid: clarify hid_keyboard_process_keycode
  virtio-input: move sys/ioctl.h include
  virtio-input: fix segfault in virtio_input_hid_properties

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--hw/input/hid.c32
-rw-r--r--hw/input/virtio-input-hid.c1
-rw-r--r--hw/input/virtio-input-host.c1
-rw-r--r--include/standard-headers/linux/input.h1
-rwxr-xr-xscripts/update-linux-headers.sh1
5 files changed, 31 insertions, 5 deletions
diff --git a/hw/input/hid.c b/hw/input/hid.c
index 6841cb8649..21ebd9e718 100644
--- a/hw/input/hid.c
+++ b/hw/input/hid.c
@@ -239,7 +239,7 @@ static void hid_keyboard_event(DeviceState *dev, QemuConsole *src,
 
 static void hid_keyboard_process_keycode(HIDState *hs)
 {
-    uint8_t hid_code, key;
+    uint8_t hid_code, index, key;
     int i, keycode, slot;
 
     if (hs->n == 0) {
@@ -249,7 +249,8 @@ static void hid_keyboard_process_keycode(HIDState *hs)
     keycode = hs->kbd.keycodes[slot];
 
     key = keycode & 0x7f;
-    hid_code = hid_usage_keys[key | ((hs->kbd.modifiers >> 1) & (1 << 7))];
+    index = key | ((hs->kbd.modifiers & (1 << 8)) >> 1);
+    hid_code = hid_usage_keys[index];
     hs->kbd.modifiers &= ~(1 << 8);
 
     switch (hid_code) {
@@ -257,18 +258,41 @@ static void hid_keyboard_process_keycode(HIDState *hs)
         return;
 
     case 0xe0:
+        assert(key == 0x1d);
         if (hs->kbd.modifiers & (1 << 9)) {
-            hs->kbd.modifiers ^= 3 << 8;
+            /* The hid_codes for the 0xe1/0x1d scancode sequence are 0xe9/0xe0.
+             * Here we're processing the second hid_code.  By dropping bit 9
+             * and setting bit 8, the scancode after 0x1d will access the
+             * second half of the table.
+             */
+            hs->kbd.modifiers ^= (1 << 8) | (1 << 9);
             return;
         }
+        /* fall through to process Ctrl_L */
     case 0xe1 ... 0xe7:
+        /* Ctrl_L/Ctrl_R, Shift_L/Shift_R, Alt_L/Alt_R, Win_L/Win_R.
+         * Handle releases here, or fall through to process presses.
+         */
         if (keycode & (1 << 7)) {
             hs->kbd.modifiers &= ~(1 << (hid_code & 0x0f));
             return;
         }
-    case 0xe8 ... 0xef:
+        /* fall through */
+    case 0xe8 ... 0xe9:
+        /* USB modifiers are just 1 byte long.  Bits 8 and 9 of
+         * hs->kbd.modifiers implement a state machine that detects the
+         * 0xe0 and 0xe1/0x1d sequences.  These bits do not follow the
+         * usual rules where bit 7 marks released keys; they are cleared
+         * elsewhere in the function as the state machine dictates.
+         */
         hs->kbd.modifiers |= 1 << (hid_code & 0x0f);
         return;
+
+    case 0xea ... 0xef:
+        abort();
+
+    default:
+        break;
     }
 
     if (keycode & (1 << 7)) {
diff --git a/hw/input/virtio-input-hid.c b/hw/input/virtio-input-hid.c
index 616a815ed4..4d85dad4d1 100644
--- a/hw/input/virtio-input-hid.c
+++ b/hw/input/virtio-input-hid.c
@@ -308,6 +308,7 @@ static void virtio_input_hid_handle_status(VirtIOInput *vinput,
 static Property virtio_input_hid_properties[] = {
     DEFINE_PROP_STRING("display", VirtIOInputHID, display),
     DEFINE_PROP_UINT32("head", VirtIOInputHID, head, 0),
+    DEFINE_PROP_END_OF_LIST(),
 };
 
 static void virtio_input_hid_class_init(ObjectClass *klass, void *data)
diff --git a/hw/input/virtio-input-host.c b/hw/input/virtio-input-host.c
index f7e3d844e6..8978f16bae 100644
--- a/hw/input/virtio-input-host.c
+++ b/hw/input/virtio-input-host.c
@@ -11,6 +11,7 @@
 #include "hw/virtio/virtio.h"
 #include "hw/virtio/virtio-input.h"
 
+#include <sys/ioctl.h>
 #include "standard-headers/linux/input.h"
 
 /* ----------------------------------------------------------------- */
diff --git a/include/standard-headers/linux/input.h b/include/standard-headers/linux/input.h
index a459dd25da..b003c67059 100644
--- a/include/standard-headers/linux/input.h
+++ b/include/standard-headers/linux/input.h
@@ -10,7 +10,6 @@
 
 
 #include <sys/time.h>
-#include <sys/ioctl.h>
 #include <sys/types.h>
 #include "standard-headers/linux/types.h"
 
diff --git a/scripts/update-linux-headers.sh b/scripts/update-linux-headers.sh
index 47378d93d4..f0e830c2d6 100755
--- a/scripts/update-linux-headers.sh
+++ b/scripts/update-linux-headers.sh
@@ -56,6 +56,7 @@ cp_virtio() {
                 -e 's/__bitwise__//' \
                 -e 's/__attribute__((packed))/QEMU_PACKED/' \
                 -e 's/__inline__/inline/' \
+                -e '/sys\/ioctl.h/d' \
                 "$f" > "$to/$header";
         done
     fi