From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53550) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZFlEm-0004Nc-CR for qemu-devel@nongnu.org; Thu, 16 Jul 2015 11:38:17 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZFlEj-0005wT-DT for qemu-devel@nongnu.org; Thu, 16 Jul 2015 11:38:16 -0400 Received: from mx1.redhat.com ([209.132.183.28]:44566) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZFlEj-0005wL-52 for qemu-devel@nongnu.org; Thu, 16 Jul 2015 11:38:13 -0400 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id BF1AB8E6E6 for ; Thu, 16 Jul 2015 15:38:12 +0000 (UTC) From: Gerd Hoffmann Date: Thu, 16 Jul 2015 17:38:05 +0200 Message-Id: <1437061085-9370-5-git-send-email-kraxel@redhat.com> In-Reply-To: <1437061085-9370-1-git-send-email-kraxel@redhat.com> References: <1437061085-9370-1-git-send-email-kraxel@redhat.com> Subject: [Qemu-devel] [PULL 4/4] hid: clarify hid_keyboard_process_keycode List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Gerd Hoffmann From: Paolo Bonzini Coverity thinks the fallthroughs are smelly. They are correct, but everything else in this function is like "wut?". Refer explicitly to bits 8 and 9 of hs->kbd.modifiers instead of shifting right first and using (1 << 7). Document what the scancode is when hid_code is 0xe0. And add plenty of comments. Signed-off-by: Paolo Bonzini Signed-off-by: Gerd Hoffmann --- hw/input/hid.c | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/hw/input/hid.c b/hw/input/hid.c index 6841cb8..21ebd9e 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)) { -- 1.8.3.1