Switched from raw input to low-level keyboard hook, with -W/--raw to optionally re-enable raw input (needed to debug, so the hook doesn't cause GDB to make system input unusably slow), fixes #4399.
This commit is contained in:
@@ -206,6 +206,7 @@ int video_fullscreen_scale_maximized = 0; /* (C) Whether
|
|||||||
also apply when maximized. */
|
also apply when maximized. */
|
||||||
int do_auto_pause = 0; /* (C) Auto-pause the emulator on focus
|
int do_auto_pause = 0; /* (C) Auto-pause the emulator on focus
|
||||||
loss */
|
loss */
|
||||||
|
int raw_input = 0; /* (C) Use raw input */
|
||||||
char uuid[MAX_UUID_LEN] = { '\0' }; /* (C) UUID or machine identifier */
|
char uuid[MAX_UUID_LEN] = { '\0' }; /* (C) UUID or machine identifier */
|
||||||
|
|
||||||
int other_ide_present = 0; /* IDE controllers from non-IDE cards are
|
int other_ide_present = 0; /* IDE controllers from non-IDE cards are
|
||||||
@@ -561,6 +562,7 @@ usage:
|
|||||||
printf("-S or --settings - show only the settings dialog\n");
|
printf("-S or --settings - show only the settings dialog\n");
|
||||||
#endif
|
#endif
|
||||||
printf("-V or --vmname name - overrides the name of the running VM\n");
|
printf("-V or --vmname name - overrides the name of the running VM\n");
|
||||||
|
printf("-W or --raw - uses raw input (compatibility-only outside Windows)\n");
|
||||||
printf("-X or --clear what - clears the 'what' (cmos/flash/both)\n");
|
printf("-X or --clear what - clears the 'what' (cmos/flash/both)\n");
|
||||||
printf("-Y or --donothing - do not show any UI or run the emulation\n");
|
printf("-Y or --donothing - do not show any UI or run the emulation\n");
|
||||||
printf("-Z or --lastvmpath - the last parameter is VM path rather than config\n");
|
printf("-Z or --lastvmpath - the last parameter is VM path rather than config\n");
|
||||||
@@ -636,6 +638,8 @@ usage:
|
|||||||
dump_missing = 1;
|
dump_missing = 1;
|
||||||
} else if (!strcasecmp(argv[c], "--donothing") || !strcasecmp(argv[c], "-Y")) {
|
} else if (!strcasecmp(argv[c], "--donothing") || !strcasecmp(argv[c], "-Y")) {
|
||||||
do_nothing = 1;
|
do_nothing = 1;
|
||||||
|
} else if (!strcasecmp(argv[c], "--raw") || !strcasecmp(argv[c], "-W")) {
|
||||||
|
raw_input = 1;
|
||||||
} else if (!strcasecmp(argv[c], "--keycodes") || !strcasecmp(argv[c], "-K")) {
|
} else if (!strcasecmp(argv[c], "--keycodes") || !strcasecmp(argv[c], "-K")) {
|
||||||
if ((c + 1) == argc)
|
if ((c + 1) == argc)
|
||||||
goto usage;
|
goto usage;
|
||||||
|
|||||||
@@ -29,7 +29,9 @@
|
|||||||
|
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
|
|
||||||
int keyboard_scan;
|
uint16_t scancode_map[768] = { 0 };
|
||||||
|
|
||||||
|
int keyboard_scan;
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
/* Windows: F8+F12 */
|
/* Windows: F8+F12 */
|
||||||
@@ -386,3 +388,22 @@ keyboard_ismsexit(void)
|
|||||||
return ((recv_key_ui[key_prefix_1_1] || recv_key_ui[key_prefix_1_2]) &&
|
return ((recv_key_ui[key_prefix_1_1] || recv_key_ui[key_prefix_1_2]) &&
|
||||||
(recv_key_ui[key_uncapture_1] || recv_key_ui[key_uncapture_2]));
|
(recv_key_ui[key_uncapture_1] || recv_key_ui[key_uncapture_2]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This is so we can disambiguate scan codes that would otherwise conflict and get
|
||||||
|
passed on incorrectly. */
|
||||||
|
uint16_t
|
||||||
|
convert_scan_code(uint16_t scan_code)
|
||||||
|
{
|
||||||
|
if ((scan_code & 0xff00) == 0xe000)
|
||||||
|
scan_code = (scan_code & 0xff) | 0x0100;
|
||||||
|
|
||||||
|
if (scan_code == 0xE11D)
|
||||||
|
scan_code = 0x0100;
|
||||||
|
/* E0 00 is sent by some USB keyboards for their special keys, as it is an
|
||||||
|
invalid scan code (it has no untranslated set 2 equivalent), we mark it
|
||||||
|
appropriately so it does not get passed through. */
|
||||||
|
else if ((scan_code > 0x01FF) || (scan_code == 0x0100))
|
||||||
|
scan_code = 0xFFFF;
|
||||||
|
|
||||||
|
return scan_code;
|
||||||
|
}
|
||||||
|
|||||||
@@ -165,6 +165,7 @@ extern _Atomic double mouse_y_error; /* Mouse error accumulator - Y */
|
|||||||
#endif
|
#endif
|
||||||
extern int pit_mode; /* (C) force setting PIT mode */
|
extern int pit_mode; /* (C) force setting PIT mode */
|
||||||
extern int fm_driver; /* (C) select FM sound driver */
|
extern int fm_driver; /* (C) select FM sound driver */
|
||||||
|
extern int raw_input; /* (C) Use raw input */
|
||||||
|
|
||||||
/* Keyboard variables for future key combination redefinition. */
|
/* Keyboard variables for future key combination redefinition. */
|
||||||
extern uint16_t key_prefix_1_1;
|
extern uint16_t key_prefix_1_1;
|
||||||
|
|||||||
@@ -194,8 +194,10 @@ typedef struct scancode {
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern uint8_t keyboard_mode;
|
extern uint8_t keyboard_mode;
|
||||||
extern int keyboard_scan;
|
extern int keyboard_scan;
|
||||||
|
|
||||||
|
extern uint16_t scancode_map[768];
|
||||||
|
|
||||||
extern void (*keyboard_send)(uint16_t val);
|
extern void (*keyboard_send)(uint16_t val);
|
||||||
extern void kbd_adddata_process(uint16_t val, void (*adddata)(uint16_t val));
|
extern void kbd_adddata_process(uint16_t val, void (*adddata)(uint16_t val));
|
||||||
@@ -288,6 +290,9 @@ extern uint8_t kbc_at_dev_queue_pos(atkbc_dev_t *dev, uint8_t main);
|
|||||||
extern void kbc_at_dev_queue_add(atkbc_dev_t *dev, uint8_t val, uint8_t main);
|
extern void kbc_at_dev_queue_add(atkbc_dev_t *dev, uint8_t val, uint8_t main);
|
||||||
extern void kbc_at_dev_reset(atkbc_dev_t *dev, int do_fa);
|
extern void kbc_at_dev_reset(atkbc_dev_t *dev, int do_fa);
|
||||||
extern atkbc_dev_t *kbc_at_dev_init(uint8_t inst);
|
extern atkbc_dev_t *kbc_at_dev_init(uint8_t inst);
|
||||||
|
/* This is so we can disambiguate scan codes that would otherwise conflict and get
|
||||||
|
passed on incorrectly. */
|
||||||
|
extern uint16_t convert_scan_code(uint16_t scan_code);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ Q_IMPORT_PLUGIN(QWindowsVistaStylePlugin)
|
|||||||
# include "qt_winmanagerfilter.hpp"
|
# include "qt_winmanagerfilter.hpp"
|
||||||
# include <86box/win.h>
|
# include <86box/win.h>
|
||||||
# include <shobjidl.h>
|
# include <shobjidl.h>
|
||||||
|
# include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -81,6 +82,7 @@ extern QElapsedTimer elapsed_timer;
|
|||||||
extern MainWindow *main_window;
|
extern MainWindow *main_window;
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
#include <86box/keyboard.h>
|
||||||
#include <86box/timer.h>
|
#include <86box/timer.h>
|
||||||
#include <86box/nvr.h>
|
#include <86box/nvr.h>
|
||||||
extern int qt_nvr_save(void);
|
extern int qt_nvr_save(void);
|
||||||
@@ -88,6 +90,122 @@ extern int qt_nvr_save(void);
|
|||||||
|
|
||||||
void qt_set_sequence_auto_mnemonic(bool b);
|
void qt_set_sequence_auto_mnemonic(bool b);
|
||||||
|
|
||||||
|
#ifdef Q_OS_WINDOWS
|
||||||
|
static void
|
||||||
|
keyboard_getkeymap()
|
||||||
|
{
|
||||||
|
const LPCSTR keyName = "SYSTEM\\CurrentControlSet\\Control\\Keyboard Layout";
|
||||||
|
const LPCSTR valueName = "Scancode Map";
|
||||||
|
unsigned char buf[32768];
|
||||||
|
DWORD bufSize;
|
||||||
|
HKEY hKey;
|
||||||
|
int j;
|
||||||
|
UINT32 *bufEx2;
|
||||||
|
int scMapCount;
|
||||||
|
UINT16 *bufEx;
|
||||||
|
int scancode_unmapped;
|
||||||
|
int scancode_mapped;
|
||||||
|
|
||||||
|
/* First, prepare the default scan code map list which is 1:1.
|
||||||
|
* Remappings will be inserted directly into it.
|
||||||
|
* 512 bytes so this takes less memory, bit 9 set means E0
|
||||||
|
* prefix.
|
||||||
|
*/
|
||||||
|
for (j = 0; j < 512; j++)
|
||||||
|
scancode_map[j] = j;
|
||||||
|
|
||||||
|
/* Get the scan code remappings from:
|
||||||
|
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout */
|
||||||
|
bufSize = 32768;
|
||||||
|
if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, keyName, 0, 1, &hKey) == ERROR_SUCCESS) {
|
||||||
|
if (RegQueryValueExA(hKey, valueName, NULL, NULL, buf, &bufSize) == ERROR_SUCCESS) {
|
||||||
|
bufEx2 = (UINT32 *) buf;
|
||||||
|
scMapCount = bufEx2[2];
|
||||||
|
if ((bufSize != 0) && (scMapCount != 0)) {
|
||||||
|
bufEx = (UINT16 *) (buf + 12);
|
||||||
|
for (j = 0; j < scMapCount * 2; j += 2) {
|
||||||
|
/* Each scan code is 32-bit: 16 bits of remapped scan code,
|
||||||
|
and 16 bits of original scan code. */
|
||||||
|
scancode_unmapped = bufEx[j + 1];
|
||||||
|
scancode_mapped = bufEx[j];
|
||||||
|
|
||||||
|
scancode_unmapped = convert_scan_code(scancode_unmapped);
|
||||||
|
scancode_mapped = convert_scan_code(scancode_mapped);
|
||||||
|
|
||||||
|
/* Ignore source scan codes with prefixes other than E1
|
||||||
|
that are not E1 1D. */
|
||||||
|
if (scancode_unmapped != 0xFFFF)
|
||||||
|
scancode_map[scancode_unmapped] = scancode_mapped;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RegCloseKey(hKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static LRESULT CALLBACK
|
||||||
|
emu_LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
|
||||||
|
{
|
||||||
|
LPKBDLLHOOKSTRUCT lpKdhs = (LPKBDLLHOOKSTRUCT) lParam;
|
||||||
|
/* Checks if CTRL was pressed. */
|
||||||
|
BOOL bCtrlDown = GetAsyncKeyState (VK_CONTROL) >> ((sizeof(SHORT) * 8) - 1);
|
||||||
|
uint16_t scancode = lpKdhs->scanCode & 0x00ff;
|
||||||
|
|
||||||
|
if (lpKdhs->flags & LLKHF_EXTENDED)
|
||||||
|
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(!(lpKdhs->flags & LLKHF_UP), scancode);
|
||||||
|
|
||||||
|
main_window->checkFullscreenHotkey();
|
||||||
|
|
||||||
|
if ((lpKdhs->scanCode == 0x01) && (lpKdhs->flags & LLKHF_ALTDOWN) &&
|
||||||
|
!(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED)))
|
||||||
|
return TRUE;
|
||||||
|
else if ((lpKdhs->scanCode == 0x01) && bCtrlDown && !(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED)))
|
||||||
|
return TRUE;
|
||||||
|
else if ((lpKdhs->scanCode == 0x0f) && (lpKdhs->flags & LLKHF_ALTDOWN) &&
|
||||||
|
!(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED)))
|
||||||
|
return TRUE;
|
||||||
|
else if ((lpKdhs->scanCode == 0x0f) && bCtrlDown && !(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED)))
|
||||||
|
return TRUE;
|
||||||
|
else if ((lpKdhs->scanCode == 0x39) && (lpKdhs->flags & LLKHF_ALTDOWN) &&
|
||||||
|
!(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED)))
|
||||||
|
return TRUE;
|
||||||
|
else if ((lpKdhs->scanCode == 0x3e) && (lpKdhs->flags & LLKHF_ALTDOWN) &&
|
||||||
|
!(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED)))
|
||||||
|
return TRUE;
|
||||||
|
else if ((lpKdhs->scanCode == 0x51) && bCtrlDown && !(lpKdhs->flags & LLKHF_UP))
|
||||||
|
return TRUE;
|
||||||
|
else if ((lpKdhs->scanCode >= 0x5b) && (lpKdhs->scanCode <= 0x5d) && (lpKdhs->flags & LLKHF_EXTENDED))
|
||||||
|
return TRUE;
|
||||||
|
else
|
||||||
|
return CallNextHookEx(NULL, nCode, wParam, lParam);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
main_thread_fn()
|
main_thread_fn()
|
||||||
{
|
{
|
||||||
@@ -165,6 +283,10 @@ main_thread_fn()
|
|||||||
|
|
||||||
static std::thread *main_thread;
|
static std::thread *main_thread;
|
||||||
|
|
||||||
|
#ifdef Q_OS_WINDOWS
|
||||||
|
static HHOOK llhook = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
@@ -176,6 +298,7 @@ main(int argc, char *argv[])
|
|||||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
|
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
|
||||||
QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
|
QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
QApplication app(argc, argv);
|
QApplication app(argc, argv);
|
||||||
QLocale::setDefault(QLocale::C);
|
QLocale::setDefault(QLocale::C);
|
||||||
|
|
||||||
@@ -193,6 +316,13 @@ main(int argc, char *argv[])
|
|||||||
#endif
|
#endif
|
||||||
elapsed_timer.start();
|
elapsed_timer.start();
|
||||||
|
|
||||||
|
for (size_t i = 0; i < sizeof(scancode_map) / sizeof(scancode_map[0]); i++)
|
||||||
|
scancode_map[i] = i;
|
||||||
|
|
||||||
|
#ifdef Q_OS_WINDOWS
|
||||||
|
keyboard_getkeymap();
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!pc_init(argc, argv)) {
|
if (!pc_init(argc, argv)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -340,6 +470,13 @@ main(int argc, char *argv[])
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef Q_OS_WINDOWS
|
||||||
|
if (!raw_input) {
|
||||||
|
llhook = SetWindowsHookEx(WH_KEYBOARD_LL, emu_LowLevelKeyboardProc, NULL, 0);
|
||||||
|
atexit([] () -> void { if (llhook) UnhookWindowsHookEx(llhook); });
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Setup raw input */
|
/* Setup raw input */
|
||||||
auto rawInputFilter = WindowsRawInputFilter::Register(main_window);
|
auto rawInputFilter = WindowsRawInputFilter::Register(main_window);
|
||||||
if (rawInputFilter) {
|
if (rawInputFilter) {
|
||||||
|
|||||||
@@ -64,8 +64,10 @@ WindowsRawInputFilter::Register(MainWindow *window)
|
|||||||
.hwndTarget = nullptr}
|
.hwndTarget = nullptr}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (RegisterRawInputDevices(rid, 2, sizeof(rid[0])) == FALSE)
|
if (raw_input && (RegisterRawInputDevices(rid, 2, sizeof(rid[0])) == FALSE))
|
||||||
return std::unique_ptr<WindowsRawInputFilter>(nullptr);
|
return std::unique_ptr<WindowsRawInputFilter>(nullptr);
|
||||||
|
else if (!raw_input && RegisterRawInputDevices(&(rid[1]), 1, sizeof(rid[0])) == FALSE)
|
||||||
|
return std::unique_ptr<WindowsRawInputFilter>(nullptr);
|
||||||
|
|
||||||
std::unique_ptr<WindowsRawInputFilter> inputfilter(new WindowsRawInputFilter(window));
|
std::unique_ptr<WindowsRawInputFilter> inputfilter(new WindowsRawInputFilter(window));
|
||||||
|
|
||||||
@@ -80,11 +82,6 @@ WindowsRawInputFilter::WindowsRawInputFilter(MainWindow *window)
|
|||||||
connect(menu, &QMenu::aboutToShow, this, [=]() { menus_open++; });
|
connect(menu, &QMenu::aboutToShow, this, [=]() { menus_open++; });
|
||||||
connect(menu, &QMenu::aboutToHide, this, [=]() { menus_open--; });
|
connect(menu, &QMenu::aboutToHide, this, [=]() { menus_open--; });
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < sizeof(scancode_map) / sizeof(scancode_map[0]); i++)
|
|
||||||
scancode_map[i] = i;
|
|
||||||
|
|
||||||
keyboard_getkeymap();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WindowsRawInputFilter::~WindowsRawInputFilter()
|
WindowsRawInputFilter::~WindowsRawInputFilter()
|
||||||
@@ -100,7 +97,10 @@ WindowsRawInputFilter::~WindowsRawInputFilter()
|
|||||||
.hwndTarget = NULL}
|
.hwndTarget = NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
RegisterRawInputDevices(rid, 2, sizeof(rid[0]));
|
if (raw_input)
|
||||||
|
RegisterRawInputDevices(rid, 2, sizeof(rid[0]));
|
||||||
|
else
|
||||||
|
RegisterRawInputDevices(&(rid[1]), 1, sizeof(rid[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@@ -197,7 +197,7 @@ WindowsRawInputFilter::keyboard_handle(PRAWINPUT raw)
|
|||||||
|
|
||||||
/* Remap it according to the list from the Registry */
|
/* Remap it according to the list from the Registry */
|
||||||
if ((scancode < (sizeof(scancode_map) / sizeof(scancode_map[0]))) && (scancode != scancode_map[scancode])) {
|
if ((scancode < (sizeof(scancode_map) / sizeof(scancode_map[0]))) && (scancode != scancode_map[scancode])) {
|
||||||
pclog("Scan code remap: %03X -> %03X\n", scancode, scancode_map[scancode]);
|
// pclog("Scan code remap: %03X -> %03X\n", scancode, scancode_map[scancode]);
|
||||||
scancode = scancode_map[scancode];
|
scancode = scancode_map[scancode];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -221,77 +221,6 @@ WindowsRawInputFilter::keyboard_handle(PRAWINPUT raw)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is so we can disambiguate scan codes that would otherwise conflict and get
|
|
||||||
passed on incorrectly. */
|
|
||||||
UINT16
|
|
||||||
WindowsRawInputFilter::convert_scan_code(UINT16 scan_code)
|
|
||||||
{
|
|
||||||
if ((scan_code & 0xff00) == 0xe000)
|
|
||||||
scan_code = (scan_code & 0xff) | 0x0100;
|
|
||||||
|
|
||||||
if (scan_code == 0xE11D)
|
|
||||||
scan_code = 0x0100;
|
|
||||||
/* E0 00 is sent by some USB keyboards for their special keys, as it is an
|
|
||||||
invalid scan code (it has no untranslated set 2 equivalent), we mark it
|
|
||||||
appropriately so it does not get passed through. */
|
|
||||||
else if ((scan_code > 0x01FF) || (scan_code == 0x0100))
|
|
||||||
scan_code = 0xFFFF;
|
|
||||||
|
|
||||||
return scan_code;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
WindowsRawInputFilter::keyboard_getkeymap()
|
|
||||||
{
|
|
||||||
const LPCSTR keyName = "SYSTEM\\CurrentControlSet\\Control\\Keyboard Layout";
|
|
||||||
const LPCSTR valueName = "Scancode Map";
|
|
||||||
unsigned char buf[32768];
|
|
||||||
DWORD bufSize;
|
|
||||||
HKEY hKey;
|
|
||||||
int j;
|
|
||||||
UINT32 *bufEx2;
|
|
||||||
int scMapCount;
|
|
||||||
UINT16 *bufEx;
|
|
||||||
int scancode_unmapped;
|
|
||||||
int scancode_mapped;
|
|
||||||
|
|
||||||
/* First, prepare the default scan code map list which is 1:1.
|
|
||||||
* Remappings will be inserted directly into it.
|
|
||||||
* 512 bytes so this takes less memory, bit 9 set means E0
|
|
||||||
* prefix.
|
|
||||||
*/
|
|
||||||
for (j = 0; j < 512; j++)
|
|
||||||
scancode_map[j] = j;
|
|
||||||
|
|
||||||
/* Get the scan code remappings from:
|
|
||||||
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout */
|
|
||||||
bufSize = 32768;
|
|
||||||
if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, keyName, 0, 1, &hKey) == ERROR_SUCCESS) {
|
|
||||||
if (RegQueryValueExA(hKey, valueName, NULL, NULL, buf, &bufSize) == ERROR_SUCCESS) {
|
|
||||||
bufEx2 = (UINT32 *) buf;
|
|
||||||
scMapCount = bufEx2[2];
|
|
||||||
if ((bufSize != 0) && (scMapCount != 0)) {
|
|
||||||
bufEx = (UINT16 *) (buf + 12);
|
|
||||||
for (j = 0; j < scMapCount * 2; j += 2) {
|
|
||||||
/* Each scan code is 32-bit: 16 bits of remapped scan code,
|
|
||||||
and 16 bits of original scan code. */
|
|
||||||
scancode_unmapped = bufEx[j + 1];
|
|
||||||
scancode_mapped = bufEx[j];
|
|
||||||
|
|
||||||
scancode_unmapped = convert_scan_code(scancode_unmapped);
|
|
||||||
scancode_mapped = convert_scan_code(scancode_mapped);
|
|
||||||
|
|
||||||
/* Ignore source scan codes with prefixes other than E1
|
|
||||||
that are not E1 1D. */
|
|
||||||
if (scancode_unmapped != 0xFFFF)
|
|
||||||
scancode_map[scancode_unmapped] = scancode_mapped;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
RegCloseKey(hKey);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
WindowsRawInputFilter::mouse_handle(PRAWINPUT raw)
|
WindowsRawInputFilter::mouse_handle(PRAWINPUT raw)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -61,7 +61,6 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
MainWindow *window;
|
MainWindow *window;
|
||||||
uint16_t scancode_map[768];
|
|
||||||
int buttons = 0;
|
int buttons = 0;
|
||||||
int dx = 0;
|
int dx = 0;
|
||||||
int dy = 0;
|
int dy = 0;
|
||||||
@@ -73,8 +72,6 @@ private:
|
|||||||
void handle_input(HRAWINPUT input);
|
void handle_input(HRAWINPUT input);
|
||||||
void keyboard_handle(PRAWINPUT raw);
|
void keyboard_handle(PRAWINPUT raw);
|
||||||
void mouse_handle(PRAWINPUT raw);
|
void mouse_handle(PRAWINPUT raw);
|
||||||
static UINT16 convert_scan_code(UINT16 scan_code);
|
|
||||||
void keyboard_getkeymap();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user