diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 19c392d9..e9278352 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -94,6 +94,7 @@ set(SOURCES src/lg-renderer.c src/ll.c src/utils.c + src/wm.c ) add_subdirectory("${PROJECT_TOP}/common" "${CMAKE_BINARY_DIR}/common" ) diff --git a/client/src/main.c b/client/src/main.c index 8ebbfccb..a7a2a7fb 100644 --- a/client/src/main.c +++ b/client/src/main.c @@ -54,6 +54,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA #include "utils.h" #include "kb.h" #include "ll.h" +#include "wm.h" #define RESIZE_TIMEOUT (10 * 1000) // 10ms @@ -964,17 +965,7 @@ static void handleMouseNormal(double ex, double ey) g_cursor.redraw = true; g_cursor.warpState = WARP_STATE_ON; - - XGrabPointer( - g_state.wminfo.info.x11.display, - g_state.wminfo.info.x11.window, - true, - None, - GrabModeAsync, - GrabModeAsync, - g_state.wminfo.info.x11.window, - None, - CurrentTime); + wmGrabPointer(); } struct DoublePoint guest = @@ -1040,7 +1031,7 @@ static void handleMouseNormal(double ex, double ey) g_cursor.inWindow = false; /* ungrab the pointer and move the local cursor to the exit point */ - XUngrabPointer(g_state.wminfo.info.x11.display, CurrentTime); + wmUngrabPointer(); warpMouse(tx, ty, true); return; } @@ -1140,14 +1131,7 @@ static void keyboardGrab() return; // grab the keyboard so we can intercept WM keys - XGrabKeyboard( - g_state.wminfo.info.x11.display, - g_state.wminfo.info.x11.window, - true, - GrabModeAsync, - GrabModeAsync, - CurrentTime - ); + wmGrabKeyboard(); } // only called for X11 @@ -1157,10 +1141,7 @@ static void keyboardUngrab() return; // ungrab the keyboard - XUngrabKeyboard( - g_state.wminfo.info.x11.display, - CurrentTime - ); + wmUngrabKeyboard(); } static void setGrab(bool enable) @@ -1184,42 +1165,22 @@ static void setGrabQuiet(bool enable) g_cursor.grab = enable; - if (g_state.wminfo.subsystem != SDL_SYSWM_X11) - SDL_SetWindowGrab(g_state.window, enable); + if (enable) + { + wmGrabPointer(); + + if (params.grabKeyboard) + wmGrabKeyboard(); + } else { - if (enable) + if (params.grabKeyboard) { - XGrabPointer( - g_state.wminfo.info.x11.display, - g_state.wminfo.info.x11.window, - true, - None, - GrabModeAsync, - GrabModeAsync, - g_state.wminfo.info.x11.window, - None, - CurrentTime); - - if (params.grabKeyboard) - XGrabKeyboard( - g_state.wminfo.info.x11.display, - g_state.wminfo.info.x11.window, - true, - GrabModeAsync, - GrabModeAsync, - CurrentTime); + if (!g_state.focused || !params.grabKeyboardOnFocus) + wmUngrabKeyboard(); } - else - { - if (params.grabKeyboard) - { - if (!g_state.focused || !params.grabKeyboardOnFocus) - XUngrabKeyboard(g_state.wminfo.info.x11.display, CurrentTime); - } - XUngrabPointer(g_state.wminfo.info.x11.display, CurrentTime); - } + wmUngrabPointer(); } // if exiting capture when input on capture only, we want to show the cursor diff --git a/client/src/wm.c b/client/src/wm.c new file mode 100644 index 00000000..0f665eff --- /dev/null +++ b/client/src/wm.c @@ -0,0 +1,137 @@ +/* +Looking Glass - KVM FrameRelay (KVMFR) Client +Copyright (C) 2017-2021 Geoffrey McRae +https://looking-glass.hostfission.com + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; either version 2 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 59 Temple +Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "wm.h" +#include "main.h" + +#include +#include + +#include "common/debug.h" + +struct WMState +{ + bool pointerGrabbed; + bool keyboardGrabbed; +}; + +static struct WMState g_wmState; + +void wmGrabPointer() +{ + switch(g_state.wminfo.subsystem) + { + case SDL_SYSWM_X11: + XGrabPointer( + g_state.wminfo.info.x11.display, + g_state.wminfo.info.x11.window, + true, + None, + GrabModeAsync, + GrabModeAsync, + g_state.wminfo.info.x11.window, + None, + CurrentTime); + break; + + default: + SDL_SetWindowGrab(g_state.window, SDL_TRUE); + break; + } + + g_wmState.pointerGrabbed = true; +} + +void wmUngrabPointer() +{ + switch(g_state.wminfo.subsystem) + { + case SDL_SYSWM_X11: + XUngrabPointer(g_state.wminfo.info.x11.display, CurrentTime); + break; + + default: + SDL_SetWindowGrab(g_state.window, SDL_TRUE); + break; + } + + g_wmState.pointerGrabbed = false; +} + +void wmGrabKeyboard() +{ + switch(g_state.wminfo.subsystem) + { + case SDL_SYSWM_X11: + XGrabKeyboard( + g_state.wminfo.info.x11.display, + g_state.wminfo.info.x11.window, + true, + GrabModeAsync, + GrabModeAsync, + CurrentTime); + break; + + default: + if (g_wmState.pointerGrabbed) + SDL_SetWindowGrab(g_state.window, SDL_FALSE); + else + { + DEBUG_WARN("SDL does not support grabbing only the keyboard, grabbing all"); + g_wmState.pointerGrabbed = true; + } + + SDL_SetHint(SDL_HINT_GRAB_KEYBOARD, "1"); + SDL_SetWindowGrab(g_state.window, SDL_TRUE); + break; + } + + g_wmState.keyboardGrabbed = true; +} + +void wmUngrabKeyboard() +{ + switch(g_state.wminfo.subsystem) + { + case SDL_SYSWM_X11: + XUngrabKeyboard(g_state.wminfo.info.x11.display, CurrentTime); + break; + + default: + SDL_SetHint(SDL_HINT_GRAB_KEYBOARD, "0"); + SDL_SetWindowGrab(g_state.window, SDL_FALSE); + if (g_wmState.pointerGrabbed) + SDL_SetWindowGrab(g_state.window, SDL_TRUE); + break; + } + + g_wmState.keyboardGrabbed = false; +} + +void wmGrabAll() +{ + wmGrabPointer(); + wmGrabKeyboard(); +} + +void wmUngrabAll() +{ + wmUngrabPointer(); + wmUngrabKeyboard(); +} diff --git a/client/src/wm.h b/client/src/wm.h new file mode 100644 index 00000000..455d033d --- /dev/null +++ b/client/src/wm.h @@ -0,0 +1,25 @@ +/* +Looking Glass - KVM FrameRelay (KVMFR) Client +Copyright (C) 2017-2021 Geoffrey McRae +https://looking-glass.hostfission.com + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; either version 2 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 59 Temple +Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +void wmGrabPointer(); +void wmUngrabPointer(); +void wmGrabKeyboard(); +void wmUngrabKeyboard(); +void wmGrabAll(); +void wmUngrabAll();