123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 |
- /*
- * This work is licensed under the terms of the GNU GPL, version 2 or
- * (at your option) any later version. See the COPYING file in the
- * top-level directory.
- *
- * The win32 keyboard hooking code was imported from project spice-gtk.
- */
- #include "qemu/osdep.h"
- #include "system/system.h"
- #include "ui/win32-kbd-hook.h"
- static Notifier win32_unhook_notifier;
- static HHOOK win32_keyboard_hook;
- static HWND win32_window;
- static DWORD win32_grab;
- static LRESULT CALLBACK keyboard_hook_cb(int code, WPARAM wparam, LPARAM lparam)
- {
- if (win32_window && code == HC_ACTION && win32_window == GetFocus()) {
- KBDLLHOOKSTRUCT *hooked = (KBDLLHOOKSTRUCT *)lparam;
- if (wparam != WM_KEYUP) {
- DWORD dwmsg = (hooked->flags << 24) |
- ((hooked->scanCode & 0xff) << 16) | 1;
- switch (hooked->vkCode) {
- case VK_CAPITAL:
- /* fall through */
- case VK_SCROLL:
- /* fall through */
- case VK_NUMLOCK:
- /* fall through */
- case VK_LSHIFT:
- /* fall through */
- case VK_RSHIFT:
- /* fall through */
- case VK_RCONTROL:
- /* fall through */
- case VK_LMENU:
- /* fall through */
- case VK_RMENU:
- break;
- case VK_LCONTROL:
- /*
- * When pressing AltGr, an extra VK_LCONTROL with a special
- * scancode with bit 9 set is sent. Let's ignore the extra
- * VK_LCONTROL, as that will make AltGr misbehave.
- */
- if (hooked->scanCode & 0x200) {
- return 1;
- }
- break;
- default:
- if (win32_grab) {
- SendMessage(win32_window, wparam, hooked->vkCode, dwmsg);
- return 1;
- }
- break;
- }
- } else {
- switch (hooked->vkCode) {
- case VK_LCONTROL:
- if (hooked->scanCode & 0x200) {
- return 1;
- }
- break;
- }
- }
- }
- return CallNextHookEx(NULL, code, wparam, lparam);
- }
- static void keyboard_hook_unhook(Notifier *n, void *data)
- {
- UnhookWindowsHookEx(win32_keyboard_hook);
- win32_keyboard_hook = NULL;
- }
- void win32_kbd_set_window(void *hwnd)
- {
- if (hwnd && !win32_keyboard_hook) {
- /* note: the installing thread must have a message loop */
- win32_keyboard_hook = SetWindowsHookEx(WH_KEYBOARD_LL, keyboard_hook_cb,
- GetModuleHandle(NULL), 0);
- if (win32_keyboard_hook) {
- win32_unhook_notifier.notify = keyboard_hook_unhook;
- qemu_add_exit_notifier(&win32_unhook_notifier);
- }
- }
- win32_window = hwnd;
- }
- void win32_kbd_set_grab(bool grab)
- {
- win32_grab = grab;
- }
|