Another attempt to fix the hook.
This commit is contained in:
@@ -144,6 +144,54 @@ keyboard_getkeymap()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
win_keyboard_handle(uint32_t scancode, int up, int e0, int e1)
|
||||||
|
{
|
||||||
|
/* If it's not a scan code that starts with 0xE1 */
|
||||||
|
if (e1) {
|
||||||
|
if (scancode == 0x1D) {
|
||||||
|
scancode = scancode_map[0x100]; /* Translate E1 1D to 0x100 (which would
|
||||||
|
otherwise be E0 00 but that is invalid
|
||||||
|
anyway).
|
||||||
|
Also, take a potential mapping into
|
||||||
|
account. */
|
||||||
|
} else
|
||||||
|
scancode = 0xFFFF;
|
||||||
|
if (scancode != 0xFFFF)
|
||||||
|
keyboard_input(!up, scancode);
|
||||||
|
} else {
|
||||||
|
if (e0)
|
||||||
|
scancode |= 0x100;
|
||||||
|
|
||||||
|
/* Translate the scan code to 9-bit */
|
||||||
|
scancode = convert_scan_code(scancode);
|
||||||
|
|
||||||
|
/* Remap it according to the list from the Registry */
|
||||||
|
if ((scancode < (sizeof(scancode_map) / sizeof(scancode_map[0]))) && (scancode != scancode_map[scancode])) {
|
||||||
|
// pclog("Scan code remap: %03X -> %03X\n", scancode, scancode_map[scancode]);
|
||||||
|
scancode = scancode_map[scancode];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If it's not 0xFFFF, send it to the emulated
|
||||||
|
keyboard.
|
||||||
|
We use scan code 0xFFFF to mean a mapping that
|
||||||
|
has a prefix other than E0 and that is not E1 1D,
|
||||||
|
which is, for our purposes, invalid. */
|
||||||
|
|
||||||
|
/* Translate right CTRL to left ALT if the user has so
|
||||||
|
chosen. */
|
||||||
|
if ((scancode == 0x11d) && rctrl_is_lalt)
|
||||||
|
scancode = 0x038;
|
||||||
|
|
||||||
|
/* Normal scan code pass through, pass it through as is if
|
||||||
|
it's not an invalid scan code. */
|
||||||
|
if (scancode != 0xFFFF)
|
||||||
|
keyboard_input(!up, scancode);
|
||||||
|
|
||||||
|
main_window->checkFullscreenHotkey();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static LRESULT CALLBACK
|
static LRESULT CALLBACK
|
||||||
emu_LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
|
emu_LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
@@ -151,6 +199,23 @@ emu_LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
|
|||||||
/* Checks if CTRL was pressed. */
|
/* Checks if CTRL was pressed. */
|
||||||
BOOL bCtrlDown = GetAsyncKeyState (VK_CONTROL) >> ((sizeof(SHORT) * 8) - 1);
|
BOOL bCtrlDown = GetAsyncKeyState (VK_CONTROL) >> ((sizeof(SHORT) * 8) - 1);
|
||||||
BOOL is_over_window = (GetForegroundWindow() == ((HWND) main_window->winId()));
|
BOOL is_over_window = (GetForegroundWindow() == ((HWND) main_window->winId()));
|
||||||
|
BOOL ret = TRUE;
|
||||||
|
/* Leave this in, in case we have to still bring hook input back. */
|
||||||
|
#ifdef HOOK_INPUT_TESTS
|
||||||
|
static int last = 0;
|
||||||
|
|
||||||
|
pclog("Old: %08X, %08X, %08X, %i\n", lpKdhs->scanCode, lpKdhs->flags, lpKdhs->vkCode, last);
|
||||||
|
|
||||||
|
if (!last && (lpKdhs->scanCode == 0x00000036))
|
||||||
|
lpKdhs->flags &= ~LLKHF_EXTENDED;
|
||||||
|
|
||||||
|
if (lpKdhs->scanCode == 0x00000236)
|
||||||
|
last = 1;
|
||||||
|
else if (last && (lpKdhs->scanCode == 0x00000036))
|
||||||
|
last = 0;
|
||||||
|
|
||||||
|
pclog("New: %08X, %08X, %08X, %i\n", lpKdhs->scanCode, lpKdhs->flags, lpKdhs->vkCode, last);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (show_second_monitors) for (int monitor_index = 1; monitor_index < MONITORS_NUM; monitor_index++) {
|
if (show_second_monitors) for (int monitor_index = 1; monitor_index < MONITORS_NUM; monitor_index++) {
|
||||||
const auto &secondaryRenderer = main_window->renderers[monitor_index];
|
const auto &secondaryRenderer = main_window->renderers[monitor_index];
|
||||||
@@ -158,30 +223,34 @@ emu_LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
|
|||||||
(GetForegroundWindow() == ((HWND) secondaryRenderer->winId())));
|
(GetForegroundWindow() == ((HWND) secondaryRenderer->winId())));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((nCode < 0) || (nCode != HC_ACTION)/* || (!mouse_capture && !video_fullscreen)*/ || !is_over_window)
|
if ((nCode < 0) || (nCode != HC_ACTION) || !is_over_window)
|
||||||
return CallNextHookEx(NULL, nCode, wParam, lParam);
|
return CallNextHookEx(NULL, nCode, wParam, lParam);
|
||||||
else if ((lpKdhs->scanCode == 0x01) && (lpKdhs->flags & LLKHF_ALTDOWN) &&
|
else if ((lpKdhs->scanCode == 0x01) && (lpKdhs->flags & LLKHF_ALTDOWN) &&
|
||||||
!(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED)))
|
!(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED)))
|
||||||
return TRUE;
|
ret = TRUE;
|
||||||
else if ((lpKdhs->scanCode == 0x01) && bCtrlDown && !(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED)))
|
else if ((lpKdhs->scanCode == 0x01) && bCtrlDown && !(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED)))
|
||||||
return TRUE;
|
ret = TRUE;
|
||||||
else if ((lpKdhs->scanCode == 0x0f) && (lpKdhs->flags & LLKHF_ALTDOWN) &&
|
else if ((lpKdhs->scanCode == 0x0f) && (lpKdhs->flags & LLKHF_ALTDOWN) &&
|
||||||
!(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED)))
|
!(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED)))
|
||||||
return TRUE;
|
ret = TRUE;
|
||||||
else if ((lpKdhs->scanCode == 0x0f) && bCtrlDown && !(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED)))
|
else if ((lpKdhs->scanCode == 0x0f) && bCtrlDown && !(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED)))
|
||||||
return TRUE;
|
ret = TRUE;
|
||||||
else if ((lpKdhs->scanCode == 0x39) && (lpKdhs->flags & LLKHF_ALTDOWN) &&
|
else if ((lpKdhs->scanCode == 0x39) && (lpKdhs->flags & LLKHF_ALTDOWN) &&
|
||||||
!(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED)))
|
!(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED)))
|
||||||
return TRUE;
|
ret = TRUE;
|
||||||
else if ((lpKdhs->scanCode == 0x3e) && (lpKdhs->flags & LLKHF_ALTDOWN) &&
|
else if ((lpKdhs->scanCode == 0x3e) && (lpKdhs->flags & LLKHF_ALTDOWN) &&
|
||||||
!(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED)))
|
!(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED)))
|
||||||
return TRUE;
|
ret = TRUE;
|
||||||
else if ((lpKdhs->scanCode == 0x49) && bCtrlDown && !(lpKdhs->flags & LLKHF_UP))
|
else if ((lpKdhs->scanCode == 0x49) && bCtrlDown && !(lpKdhs->flags & LLKHF_UP))
|
||||||
return TRUE;
|
ret = TRUE;
|
||||||
else if ((lpKdhs->scanCode >= 0x5b) && (lpKdhs->scanCode <= 0x5d) && (lpKdhs->flags & LLKHF_EXTENDED))
|
else if ((lpKdhs->scanCode >= 0x5b) && (lpKdhs->scanCode <= 0x5d) && (lpKdhs->flags & LLKHF_EXTENDED))
|
||||||
return TRUE;
|
ret = TRUE;
|
||||||
else
|
else
|
||||||
return CallNextHookEx(NULL, nCode, wParam, lParam);
|
return CallNextHookEx(NULL, nCode, wParam, lParam);
|
||||||
|
|
||||||
|
win_keyboard_handle(lpKdhs->scanCode, lpKdhs->flags & LLKHF_UP, lpKdhs->flags & LLKHF_EXTENDED, 0);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -455,6 +524,15 @@ main(int argc, char *argv[])
|
|||||||
hook_enabled = 0;
|
hook_enabled = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hook_enabled) {
|
||||||
|
/* Yes, low-level hooks *DO* work with raw input, at least global ones. */
|
||||||
|
llhook = SetWindowsHookEx(WH_KEYBOARD_LL, emu_LowLevelKeyboardProc, NULL, 0);
|
||||||
|
atexit([] () -> void {
|
||||||
|
if (llhook)
|
||||||
|
UnhookWindowsHookEx(llhook);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/* Setup raw input */
|
/* Setup raw input */
|
||||||
auto rawInputFilter = WindowsRawInputFilter::Register(main_window);
|
auto rawInputFilter = WindowsRawInputFilter::Register(main_window);
|
||||||
if (rawInputFilter) {
|
if (rawInputFilter) {
|
||||||
@@ -507,7 +585,6 @@ main(int argc, char *argv[])
|
|||||||
/* Initialize the rendering window, or fullscreen. */
|
/* Initialize the rendering window, or fullscreen. */
|
||||||
QTimer::singleShot(0, &app, [] {
|
QTimer::singleShot(0, &app, [] {
|
||||||
pc_reset_hard_init();
|
pc_reset_hard_init();
|
||||||
main_thread = new std::thread(main_thread_fn);
|
|
||||||
|
|
||||||
/* Set the PAUSE mode depending on the renderer. */
|
/* Set the PAUSE mode depending on the renderer. */
|
||||||
#ifdef USE_VNC
|
#ifdef USE_VNC
|
||||||
@@ -516,18 +593,9 @@ main(int argc, char *argv[])
|
|||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
plat_pause(0);
|
plat_pause(0);
|
||||||
});
|
|
||||||
|
|
||||||
#ifdef Q_OS_WINDOWS
|
main_thread = new std::thread(main_thread_fn);
|
||||||
if (hook_enabled) {
|
|
||||||
/* Yes, low-level hooks *DO* work with raw input, at least global ones. */
|
|
||||||
llhook = SetWindowsHookEx(WH_KEYBOARD_LL, emu_LowLevelKeyboardProc, NULL, 0);
|
|
||||||
atexit([] () -> void {
|
|
||||||
if (llhook)
|
|
||||||
UnhookWindowsHookEx(llhook);
|
|
||||||
});
|
});
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
const auto ret = app.exec();
|
const auto ret = app.exec();
|
||||||
cpu_thread_run = 0;
|
cpu_thread_run = 0;
|
||||||
|
|||||||
@@ -44,6 +44,8 @@
|
|||||||
#include <86box/plat.h>
|
#include <86box/plat.h>
|
||||||
#include <86box/86box.h>
|
#include <86box/86box.h>
|
||||||
|
|
||||||
|
extern void win_keyboard_handle(uint32_t scancode, int up, int e0, int e1);
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
@@ -166,54 +168,10 @@ WindowsRawInputFilter::handle_input(HRAWINPUT input)
|
|||||||
void
|
void
|
||||||
WindowsRawInputFilter::keyboard_handle(PRAWINPUT raw)
|
WindowsRawInputFilter::keyboard_handle(PRAWINPUT raw)
|
||||||
{
|
{
|
||||||
USHORT scancode;
|
|
||||||
|
|
||||||
RAWKEYBOARD rawKB = raw->data.keyboard;
|
RAWKEYBOARD rawKB = raw->data.keyboard;
|
||||||
scancode = rawKB.MakeCode;
|
|
||||||
|
|
||||||
/* If it's not a scan code that starts with 0xE1 */
|
win_keyboard_handle(rawKB.MakeCode, (rawKB.Flags & RI_KEY_BREAK),
|
||||||
if ((rawKB.Flags & RI_KEY_E1)) {
|
(rawKB.Flags & RI_KEY_E0), (rawKB.Flags & RI_KEY_E1));
|
||||||
if (rawKB.MakeCode == 0x1D) {
|
|
||||||
scancode = scancode_map[0x100]; /* Translate E1 1D to 0x100 (which would
|
|
||||||
otherwise be E0 00 but that is invalid
|
|
||||||
anyway).
|
|
||||||
Also, take a potential mapping into
|
|
||||||
account. */
|
|
||||||
} else
|
|
||||||
scancode = 0xFFFF;
|
|
||||||
if (scancode != 0xFFFF)
|
|
||||||
keyboard_input(!(rawKB.Flags & RI_KEY_BREAK), scancode);
|
|
||||||
} else {
|
|
||||||
if (rawKB.Flags & RI_KEY_E0)
|
|
||||||
scancode |= 0x100;
|
|
||||||
|
|
||||||
/* Translate the scan code to 9-bit */
|
|
||||||
scancode = convert_scan_code(scancode);
|
|
||||||
|
|
||||||
/* Remap it according to the list from the Registry */
|
|
||||||
if ((scancode < (sizeof(scancode_map) / sizeof(scancode_map[0]))) && (scancode != scancode_map[scancode])) {
|
|
||||||
// pclog("Scan code remap: %03X -> %03X\n", scancode, scancode_map[scancode]);
|
|
||||||
scancode = scancode_map[scancode];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If it's not 0xFFFF, send it to the emulated
|
|
||||||
keyboard.
|
|
||||||
We use scan code 0xFFFF to mean a mapping that
|
|
||||||
has a prefix other than E0 and that is not E1 1D,
|
|
||||||
which is, for our purposes, invalid. */
|
|
||||||
|
|
||||||
/* Translate right CTRL to left ALT if the user has so
|
|
||||||
chosen. */
|
|
||||||
if ((scancode == 0x11d) && rctrl_is_lalt)
|
|
||||||
scancode = 0x038;
|
|
||||||
|
|
||||||
/* Normal scan code pass through, pass it through as is if
|
|
||||||
it's not an invalid scan code. */
|
|
||||||
if (scancode != 0xFFFF)
|
|
||||||
keyboard_input(!(rawKB.Flags & RI_KEY_BREAK), scancode);
|
|
||||||
|
|
||||||
window->checkFullscreenHotkey();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
Reference in New Issue
Block a user