mirror of
https://github.com/kanjitalk755/macemu.git
synced 2024-11-25 02:33:09 +00:00
Add optional ability to intercept Windows key
This allows you to use the Windows key as your option key, bypassing Windows' various uses of the key for the start menu and keyboard shortcuts. This is enabled with the "reservewindowskey" setting in the prefs file, and a checkbox has been added to the settings GUI.
This commit is contained in:
parent
a5064455cb
commit
f1502fb6bd
@ -98,11 +98,14 @@ uint8 *ScratchMem = NULL; // Scratch memory for Mac ROM writes
|
||||
static bool lm_area_mapped = false; // Flag: Low Memory area mmap()ped
|
||||
#endif
|
||||
|
||||
static HHOOK keyboard_hook; // Hook for intercepting windows key events
|
||||
|
||||
|
||||
// Prototypes
|
||||
static int xpram_func(void *arg);
|
||||
static int tick_func(void *arg);
|
||||
static void one_tick(...);
|
||||
static LRESULT CALLBACK low_level_keyboard_hook(int nCode, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
|
||||
/*
|
||||
@ -283,6 +286,12 @@ int main(int argc, char **argv)
|
||||
QuitEmulator();
|
||||
#endif
|
||||
|
||||
// Install keyboard hook to block Windows key if enabled in prefs
|
||||
if (PrefsFindBool("reservewindowskey"))
|
||||
{
|
||||
keyboard_hook = SetWindowsHookEx(WH_KEYBOARD_LL, low_level_keyboard_hook, GetModuleHandle(NULL), 0);
|
||||
}
|
||||
|
||||
// Initialize SDL system
|
||||
int sdl_flags = 0;
|
||||
#ifdef USE_SDL_VIDEO
|
||||
@ -711,3 +720,42 @@ bool ChoiceAlert(const char *text, const char *pos, const char *neg)
|
||||
printf(GetString(STR_SHELL_WARNING_PREFIX), text);
|
||||
return false; //!!
|
||||
}
|
||||
|
||||
/*
|
||||
* Low level keyboard hook allowing us to intercept events involving the Windows key
|
||||
*/
|
||||
static LRESULT CALLBACK low_level_keyboard_hook(int nCode, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
// Not a relevant event, immediately pass it on
|
||||
if (nCode != HC_ACTION)
|
||||
return CallNextHookEx(keyboard_hook, nCode, wParam, lParam);
|
||||
|
||||
KBDLLHOOKSTRUCT *p = (KBDLLHOOKSTRUCT *)lParam;
|
||||
switch (wParam) {
|
||||
case WM_KEYDOWN:
|
||||
case WM_KEYUP:
|
||||
// Intercept left/right windows keys when we have keyboard focus so Windows doesn't handle them
|
||||
if (p->vkCode == VK_LWIN || p->vkCode == VK_RWIN) {
|
||||
bool intercept_event = false;
|
||||
#ifdef USE_SDL_VIDEO
|
||||
if (sdl_window && (SDL_GetWindowFlags(sdl_window) & SDL_WINDOW_INPUT_FOCUS)) {
|
||||
intercept_event = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
// If we've determined we should intercept the event, intercept it. But pass the event onto SDL so Basilisk handles it.
|
||||
if (intercept_event) {
|
||||
SDL_Event e;
|
||||
memset(&e, 0, sizeof(e));
|
||||
e.type = (wParam == WM_KEYDOWN) ? SDL_KEYDOWN : SDL_KEYUP;
|
||||
e.key.keysym.sym = (p->vkCode == VK_LWIN) ? SDLK_LGUI : SDLK_RGUI;
|
||||
SDL_PushEvent(&e);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// If we fall here, we weren't supposed to intercept it.
|
||||
return CallNextHookEx(keyboard_hook, nCode, wParam, lParam);
|
||||
}
|
||||
|
@ -1298,6 +1298,12 @@ static void tb_keycodes(GtkWidget *widget)
|
||||
set_input_sensitive();
|
||||
}
|
||||
|
||||
// "Reserve Windows Key" button toggled
|
||||
static void tb_reservewindowskey(GtkWidget *widget)
|
||||
{
|
||||
PrefsReplaceBool("reservewindowskey", GTK_TOGGLE_BUTTON(widget)->active);
|
||||
}
|
||||
|
||||
// "Mouse Wheel Mode" selected
|
||||
static void mn_wheel_page(...) {PrefsReplaceInt32("mousewheelmode", 0); set_input_sensitive();}
|
||||
static void mn_wheel_cursor(...) {PrefsReplaceInt32("mousewheelmode", 1); set_input_sensitive();}
|
||||
@ -1345,6 +1351,8 @@ static void create_input_pane(GtkWidget *top)
|
||||
gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
|
||||
g_object_set_data(G_OBJECT(w_keycode_file), "chooser_button", button);
|
||||
|
||||
make_checkbox(box, STR_RESERVE_WINDOWS_KEY_CTRL, "reservewindowskey", GTK_SIGNAL_FUNC(tb_reservewindowskey));
|
||||
|
||||
make_separator(box);
|
||||
|
||||
static const opt_desc options[] = {
|
||||
|
@ -53,6 +53,8 @@ prefs_desc platform_prefs_items[] = {
|
||||
{"sdlrender", TYPE_STRING, false, "SDL_Renderer driver (\"auto\", \"software\" (may be faster), etc.)"},
|
||||
{"sdl_vsync", TYPE_BOOLEAN, false, "Make SDL_Renderer vertical sync frames to host (eg. with software renderer)"},
|
||||
#endif
|
||||
{"reservewindowskey", TYPE_BOOLEAN, false, "block Windows key from activating start menu"},
|
||||
|
||||
|
||||
{NULL, TYPE_END, false, NULL} // End of list
|
||||
};
|
||||
@ -136,4 +138,5 @@ void AddPlatformPrefsDefaults(void)
|
||||
PrefsReplaceString("sdlrender", "software");
|
||||
PrefsReplaceBool("sdl_vsync", false);
|
||||
#endif
|
||||
PrefsAddBool("reservewindowskey", false);
|
||||
}
|
||||
|
@ -56,6 +56,7 @@ user_string_def platform_strings[] = {
|
||||
{STR_INPUT_PANE_TITLE, "Keyboard/Mouse"},
|
||||
{STR_KEYCODES_CTRL, "Use Raw Keycodes"},
|
||||
{STR_KEYCODE_FILE_CTRL, "Keycode Translation File"},
|
||||
{STR_RESERVE_WINDOWS_KEY_CTRL, "Reserve Windows Key"},
|
||||
{STR_MOUSEWHEELMODE_CTRL, "Mouse Wheel Function"},
|
||||
{STR_MOUSEWHEELMODE_PAGE_LAB, "Page Up/Down"},
|
||||
{STR_MOUSEWHEELMODE_CURSOR_LAB, "Cursor Up/Down"},
|
||||
|
@ -58,6 +58,7 @@ enum {
|
||||
STR_INPUT_PANE_TITLE,
|
||||
STR_KEYCODES_CTRL,
|
||||
STR_KEYCODE_FILE_CTRL,
|
||||
STR_RESERVE_WINDOWS_KEY_CTRL,
|
||||
STR_MOUSEWHEELMODE_CTRL,
|
||||
STR_MOUSEWHEELMODE_PAGE_LAB,
|
||||
STR_MOUSEWHEELMODE_CURSOR_LAB,
|
||||
|
@ -105,6 +105,8 @@ uintptr SheepMem::base = 0x60000000; // Address of SheepShaver data
|
||||
uintptr SheepMem::proc; // Bottom address of SheepShave procedures
|
||||
uintptr SheepMem::data; // Top of SheepShaver data (stack like storage)
|
||||
|
||||
static HHOOK keyboard_hook; // Hook for intercepting windows key events
|
||||
|
||||
|
||||
// Prototypes
|
||||
static bool kernel_data_init(void);
|
||||
@ -118,6 +120,7 @@ extern void emul_ppc(uint32 start);
|
||||
extern void init_emul_ppc(void);
|
||||
extern void exit_emul_ppc(void);
|
||||
sigsegv_return_t sigsegv_handler(sigsegv_info_t *sip);
|
||||
static LRESULT CALLBACK low_level_keyboard_hook(int nCode, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
|
||||
/*
|
||||
@ -210,6 +213,12 @@ int main(int argc, char **argv)
|
||||
// // Load win32 libraries
|
||||
// KernelInit();
|
||||
|
||||
// Install keyboard hook to block Windows key if enabled in prefs
|
||||
if (PrefsFindBool("reservewindowskey"))
|
||||
{
|
||||
keyboard_hook = SetWindowsHookEx(WH_KEYBOARD_LL, low_level_keyboard_hook, GetModuleHandle(NULL), 0);
|
||||
}
|
||||
|
||||
// Initialize SDL system
|
||||
int sdl_flags = 0;
|
||||
#ifdef USE_SDL_VIDEO
|
||||
@ -839,3 +848,42 @@ bool ChoiceAlert(const char *text, const char *pos, const char *neg)
|
||||
printf(GetString(STR_SHELL_WARNING_PREFIX), text);
|
||||
return false; //!!
|
||||
}
|
||||
|
||||
/*
|
||||
* Low level keyboard hook allowing us to intercept events involving the Windows key
|
||||
*/
|
||||
static LRESULT CALLBACK low_level_keyboard_hook(int nCode, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
// Not a relevant event, immediately pass it on
|
||||
if (nCode != HC_ACTION)
|
||||
return CallNextHookEx(keyboard_hook, nCode, wParam, lParam);
|
||||
|
||||
KBDLLHOOKSTRUCT *p = (KBDLLHOOKSTRUCT *)lParam;
|
||||
switch (wParam) {
|
||||
case WM_KEYDOWN:
|
||||
case WM_KEYUP:
|
||||
// Intercept left/right windows keys when we have keyboard focus so Windows doesn't handle them
|
||||
if (p->vkCode == VK_LWIN || p->vkCode == VK_RWIN) {
|
||||
bool intercept_event = false;
|
||||
#ifdef USE_SDL_VIDEO
|
||||
if (sdl_window && (SDL_GetWindowFlags(sdl_window) & SDL_WINDOW_INPUT_FOCUS)) {
|
||||
intercept_event = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
// If we've determined we should intercept the event, intercept it. But pass the event onto SDL so SheepShaver handles it.
|
||||
if (intercept_event) {
|
||||
SDL_Event e;
|
||||
memset(&e, 0, sizeof(e));
|
||||
e.type = (wParam == WM_KEYDOWN) ? SDL_KEYDOWN : SDL_KEYUP;
|
||||
e.key.keysym.sym = (p->vkCode == VK_LWIN) ? SDLK_LGUI : SDLK_RGUI;
|
||||
SDL_PushEvent(&e);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// If we fall here, we weren't supposed to intercept it.
|
||||
return CallNextHookEx(keyboard_hook, nCode, wParam, lParam);
|
||||
}
|
||||
|
@ -58,6 +58,7 @@ prefs_desc platform_prefs_items[] = {
|
||||
{"sdlrender", TYPE_STRING, false, "SDL_Renderer driver (\"auto\", \"software\" (may be faster), etc.)"},
|
||||
{"sdl_vsync", TYPE_BOOLEAN, false, "Make SDL_Renderer vertical sync frames to host (eg. with software renderer)"},
|
||||
#endif
|
||||
{"reservewindowskey", TYPE_BOOLEAN, false, "block Windows key from activating start menu"},
|
||||
|
||||
{NULL, TYPE_END, false, NULL} // End of list
|
||||
};
|
||||
@ -145,4 +146,5 @@ void AddPlatformPrefsDefaults(void)
|
||||
PrefsReplaceString("sdlrender", "software");
|
||||
PrefsReplaceBool("sdl_vsync", false);
|
||||
#endif
|
||||
PrefsAddBool("reservewindowskey", false);
|
||||
}
|
||||
|
@ -63,6 +63,7 @@ user_string_def platform_strings[] = {
|
||||
{STR_INPUT_PANE_TITLE, "Keyboard/Mouse"},
|
||||
{STR_KEYCODES_CTRL, "Use Raw Keycodes"},
|
||||
{STR_KEYCODE_FILE_CTRL, "Keycode Translation File"},
|
||||
{STR_RESERVE_WINDOWS_KEY_CTRL, "Reserve Windows Key"},
|
||||
{STR_MOUSEWHEELMODE_CTRL, "Mouse Wheel Function"},
|
||||
{STR_MOUSEWHEELMODE_PAGE_LAB, "Page Up/Down"},
|
||||
{STR_MOUSEWHEELMODE_CURSOR_LAB, "Cursor Up/Down"},
|
||||
|
@ -57,6 +57,7 @@ enum {
|
||||
STR_INPUT_PANE_TITLE,
|
||||
STR_KEYCODES_CTRL,
|
||||
STR_KEYCODE_FILE_CTRL,
|
||||
STR_RESERVE_WINDOWS_KEY_CTRL,
|
||||
STR_MOUSEWHEELMODE_CTRL,
|
||||
STR_MOUSEWHEELMODE_PAGE_LAB,
|
||||
STR_MOUSEWHEELMODE_CURSOR_LAB,
|
||||
|
Loading…
Reference in New Issue
Block a user