qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

ui/win32-kbd-hook: handle AltGr in a hook procedure

Import win32 keyboard hooking code from project spice-gtk. This
patch removes the extra left control key up/down input events
inserted by Windows for the right alt key up/down input events
with international keyboard layouts. Additionally there's some
code to grab the keyboard.

The next patches will use this code.

Only Windows needs this.

Signed-off-by: Volker Rümelin <vr_qemu@t-online.de>
Message-id: 20200516072014.7766-1-vr_qemu@t-online.de
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>

authored by

Volker Rümelin and committed by
Gerd Hoffmann
2df9f571 debe78ce

+138
+14
include/ui/win32-kbd-hook.h
··· 1 + /* 2 + * SPDX-License-Identifier: GPL-2.0-or-later 3 + * 4 + * This work is licensed under the terms of the GNU GPL, version 2 or later. 5 + * See the COPYING file in the top-level directory. 6 + */ 7 + 8 + #ifndef UI_WIN32_KBD_HOOK_H 9 + #define UI_WIN32_KBD_HOOK_H 10 + 11 + void win32_kbd_set_window(void *hwnd); 12 + void win32_kbd_set_grab(bool grab); 13 + 14 + #endif
+1
stubs/Makefile.objs
··· 32 32 stub-obj-y += uuid.o 33 33 stub-obj-y += vm-stop.o 34 34 stub-obj-y += vmstate.o 35 + stub-obj-y += win32-kbd-hook.o 35 36 stub-obj-y += fd-register.o 36 37 stub-obj-y += qmp_memory_device.o 37 38 stub-obj-y += target-monitor-defs.o
+18
stubs/win32-kbd-hook.c
··· 1 + /* 2 + * Win32 keyboard hook stubs 3 + * 4 + * This work is licensed under the terms of the GNU GPL, version 2 or 5 + * (at your option) any later version. See the COPYING file in the 6 + * top-level directory. 7 + */ 8 + 9 + #include "qemu/osdep.h" 10 + #include "ui/win32-kbd-hook.h" 11 + 12 + void win32_kbd_set_window(void *hwnd) 13 + { 14 + } 15 + 16 + void win32_kbd_set_grab(bool grab) 17 + { 18 + }
+3
ui/Makefile.objs
··· 15 15 common-obj-$(CONFIG_COCOA) += cocoa.o 16 16 common-obj-$(CONFIG_VNC) += $(vnc-obj-y) 17 17 common-obj-$(call lnot,$(CONFIG_VNC)) += vnc-stubs.o 18 + ifneq (,$(findstring m,$(CONFIG_SDL)$(CONFIG_GTK))) 19 + common-obj-$(CONFIG_WIN32) += win32-kbd-hook.o 20 + endif 18 21 19 22 # ui-sdl module 20 23 common-obj-$(CONFIG_SDL) += sdl.mo
+102
ui/win32-kbd-hook.c
··· 1 + /* 2 + * This work is licensed under the terms of the GNU GPL, version 2 or 3 + * (at your option) any later version. See the COPYING file in the 4 + * top-level directory. 5 + * 6 + * The win32 keyboard hooking code was imported from project spice-gtk. 7 + */ 8 + 9 + #include "qemu/osdep.h" 10 + #include "sysemu/sysemu.h" 11 + #include "ui/win32-kbd-hook.h" 12 + 13 + static Notifier win32_unhook_notifier; 14 + static HHOOK win32_keyboard_hook; 15 + static HWND win32_window; 16 + static DWORD win32_grab; 17 + 18 + static LRESULT CALLBACK keyboard_hook_cb(int code, WPARAM wparam, LPARAM lparam) 19 + { 20 + if (win32_window && code == HC_ACTION && win32_window == GetFocus()) { 21 + KBDLLHOOKSTRUCT *hooked = (KBDLLHOOKSTRUCT *)lparam; 22 + 23 + if (wparam != WM_KEYUP) { 24 + DWORD dwmsg = (hooked->flags << 24) | 25 + ((hooked->scanCode & 0xff) << 16) | 1; 26 + 27 + switch (hooked->vkCode) { 28 + case VK_CAPITAL: 29 + /* fall through */ 30 + case VK_SCROLL: 31 + /* fall through */ 32 + case VK_NUMLOCK: 33 + /* fall through */ 34 + case VK_LSHIFT: 35 + /* fall through */ 36 + case VK_RSHIFT: 37 + /* fall through */ 38 + case VK_RCONTROL: 39 + /* fall through */ 40 + case VK_LMENU: 41 + /* fall through */ 42 + case VK_RMENU: 43 + break; 44 + 45 + case VK_LCONTROL: 46 + /* 47 + * When pressing AltGr, an extra VK_LCONTROL with a special 48 + * scancode with bit 9 set is sent. Let's ignore the extra 49 + * VK_LCONTROL, as that will make AltGr misbehave. 50 + */ 51 + if (hooked->scanCode & 0x200) { 52 + return 1; 53 + } 54 + break; 55 + 56 + default: 57 + if (win32_grab) { 58 + SendMessage(win32_window, wparam, hooked->vkCode, dwmsg); 59 + return 1; 60 + } 61 + break; 62 + } 63 + 64 + } else { 65 + switch (hooked->vkCode) { 66 + case VK_LCONTROL: 67 + if (hooked->scanCode & 0x200) { 68 + return 1; 69 + } 70 + break; 71 + } 72 + } 73 + } 74 + 75 + return CallNextHookEx(NULL, code, wparam, lparam); 76 + } 77 + 78 + static void keyboard_hook_unhook(Notifier *n, void *data) 79 + { 80 + UnhookWindowsHookEx(win32_keyboard_hook); 81 + win32_keyboard_hook = NULL; 82 + } 83 + 84 + void win32_kbd_set_window(void *hwnd) 85 + { 86 + if (hwnd && !win32_keyboard_hook) { 87 + /* note: the installing thread must have a message loop */ 88 + win32_keyboard_hook = SetWindowsHookEx(WH_KEYBOARD_LL, keyboard_hook_cb, 89 + GetModuleHandle(NULL), 0); 90 + if (win32_keyboard_hook) { 91 + win32_unhook_notifier.notify = keyboard_hook_unhook; 92 + qemu_add_exit_notifier(&win32_unhook_notifier); 93 + } 94 + } 95 + 96 + win32_window = hwnd; 97 + } 98 + 99 + void win32_kbd_set_grab(bool grab) 100 + { 101 + win32_grab = grab; 102 + }