|
@@ -738,11 +738,58 @@ WIN_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp)
|
|
|
return succeeded ? 0 : -1;
|
|
|
}
|
|
|
|
|
|
+static void WIN_GrabKeyboard(SDL_Window *window)
|
|
|
+{
|
|
|
+ SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
|
|
|
+ HMODULE module;
|
|
|
+
|
|
|
+ if (data->keyboard_hook) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* SetWindowsHookEx() needs to know which module contains the hook we
|
|
|
+ want to install. This is complicated by the fact that SDL can be
|
|
|
+ linked statically or dynamically. Fortunately XP and later provide
|
|
|
+ this nice API that will go through the loaded modules and find the
|
|
|
+ one containing our code.
|
|
|
+ */
|
|
|
+ if (!GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT | GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
|
|
|
+ (LPTSTR)WIN_KeyboardHookProc,
|
|
|
+ &module)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* To grab the keyboard, we have to install a low-level keyboard hook to
|
|
|
+ intercept keys that would normally be captured by the OS. Intercepting
|
|
|
+ all key events on the system is rather invasive, but it's what Microsoft
|
|
|
+ actually documents that you do to capture these.
|
|
|
+ */
|
|
|
+ data->keyboard_hook = SetWindowsHookEx(WH_KEYBOARD_LL, WIN_KeyboardHookProc, module, 0);
|
|
|
+}
|
|
|
+
|
|
|
+void WIN_UngrabKeyboard(SDL_Window *window)
|
|
|
+{
|
|
|
+ SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
|
|
|
+
|
|
|
+ if (data->keyboard_hook) {
|
|
|
+ UnhookWindowsHookEx(data->keyboard_hook);
|
|
|
+ data->keyboard_hook = NULL;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
void
|
|
|
WIN_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed)
|
|
|
{
|
|
|
WIN_UpdateClipCursor(window);
|
|
|
|
|
|
+ if (grabbed) {
|
|
|
+ if (SDL_GetHintBoolean(SDL_HINT_GRAB_KEYBOARD, SDL_FALSE)) {
|
|
|
+ WIN_GrabKeyboard(window);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ WIN_UngrabKeyboard(window);
|
|
|
+ }
|
|
|
+
|
|
|
if (window->flags & SDL_WINDOW_FULLSCREEN) {
|
|
|
UINT flags = SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOSIZE;
|
|
|
|
|
@@ -759,6 +806,9 @@ WIN_DestroyWindow(_THIS, SDL_Window * window)
|
|
|
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
|
|
|
|
|
|
if (data) {
|
|
|
+ if (data->keyboard_hook) {
|
|
|
+ UnhookWindowsHookEx(data->keyboard_hook);
|
|
|
+ }
|
|
|
ReleaseDC(data->hwnd, data->hdc);
|
|
|
RemoveProp(data->hwnd, TEXT("SDL_WindowData"));
|
|
|
if (data->created) {
|