Expose separate keyboard and mouse grab support

This adds SDL_SetWindowKeyboardGrab(), SDL_GetWindowKeyboardGrab(),
SDL_SetWindowMouseGrab(), SDL_GetWindowMouseGrab(), and new
SDL_WINDOW_KEYBOARD_GRABBED flag. It also updates the test harness to exercise
this functionality and makes a minor fix to X11 that I missed in
https://hg.libsdl.org/SDL/rev/02a2d609369b

To fit in with this new support, SDL_WINDOW_INPUT_CAPTURE has been renamed to
SDL_WINDOW_MOUSE_CAPTURE with the old name remaining as an alias for backwards
compatibility with older code.
This commit is contained in:
Cameron Gutman
2021-01-26 19:16:17 -06:00
parent ff827fc767
commit 6b057c6783
12 changed files with 367 additions and 84 deletions

View File

@@ -265,7 +265,7 @@ video_createWindowVariousFlags(void *arg)
w = SDLTest_RandomIntegerInRange(320, 1024);
h = SDLTest_RandomIntegerInRange(320, 768);
for (fVariation = 0; fVariation < 13; fVariation++) {
for (fVariation = 0; fVariation < 14; fVariation++) {
switch(fVariation) {
case 0:
flags = SDL_WINDOW_FULLSCREEN;
@@ -299,7 +299,7 @@ video_createWindowVariousFlags(void *arg)
flags = SDL_WINDOW_MAXIMIZED;
break;
case 9:
flags = SDL_WINDOW_INPUT_GRABBED;
flags = SDL_WINDOW_MOUSE_GRABBED;
break;
case 10:
flags = SDL_WINDOW_INPUT_FOCUS;
@@ -310,6 +310,9 @@ video_createWindowVariousFlags(void *arg)
case 12:
flags = SDL_WINDOW_FOREIGN;
break;
case 13:
flags = SDL_WINDOW_KEYBOARD_GRABBED;
break;
}
window = SDL_CreateWindow(title, x, y, w, h, flags);
@@ -744,87 +747,213 @@ video_getWindowGammaRampNegative(void *arg)
return TEST_COMPLETED;
}
/* Helper for setting and checking the window grab state */
/* Helper for setting and checking the window mouse grab state */
void
_setAndCheckWindowGrabState(SDL_Window* window, SDL_bool desiredState)
_setAndCheckWindowMouseGrabState(SDL_Window* window, SDL_bool desiredState)
{
SDL_bool currentState;
/* Set state */
SDL_SetWindowGrab(window, desiredState);
SDLTest_AssertPass("Call to SDL_SetWindowGrab(%s)", (desiredState == SDL_FALSE) ? "SDL_FALSE" : "SDL_TRUE");
SDL_SetWindowMouseGrab(window, desiredState);
SDLTest_AssertPass("Call to SDL_SetWindowMouseGrab(%s)", (desiredState == SDL_FALSE) ? "SDL_FALSE" : "SDL_TRUE");
/* Get and check state */
currentState = SDL_GetWindowGrab(window);
SDLTest_AssertPass("Call to SDL_GetWindowGrab()");
currentState = SDL_GetWindowMouseGrab(window);
SDLTest_AssertPass("Call to SDL_GetWindowMouseGrab()");
SDLTest_AssertCheck(
currentState == desiredState,
"Validate returned state; expected: %s, got: %s",
(desiredState == SDL_FALSE) ? "SDL_FALSE" : "SDL_TRUE",
(currentState == SDL_FALSE) ? "SDL_FALSE" : "SDL_TRUE");
if (desiredState) {
SDLTest_AssertCheck(
SDL_GetGrabbedWindow() == window,
"Grabbed window should be to our window");
SDLTest_AssertCheck(
SDL_GetWindowGrab(window),
"SDL_GetWindowGrab() should return SDL_TRUE");
SDLTest_AssertCheck(
SDL_GetWindowFlags(window) & SDL_WINDOW_MOUSE_GRABBED,
"SDL_WINDOW_MOUSE_GRABBED should be set");
} else {
SDLTest_AssertCheck(
!(SDL_GetWindowFlags(window) & SDL_WINDOW_MOUSE_GRABBED),
"SDL_WINDOW_MOUSE_GRABBED should be unset");
}
}
/* Helper for setting and checking the window keyboard grab state */
void
_setAndCheckWindowKeyboardGrabState(SDL_Window* window, SDL_bool desiredState)
{
SDL_bool currentState;
/* Set state */
SDL_SetWindowKeyboardGrab(window, desiredState);
SDLTest_AssertPass("Call to SDL_SetWindowKeyboardGrab(%s)", (desiredState == SDL_FALSE) ? "SDL_FALSE" : "SDL_TRUE");
/* Get and check state */
currentState = SDL_GetWindowKeyboardGrab(window);
SDLTest_AssertPass("Call to SDL_GetWindowKeyboardGrab()");
SDLTest_AssertCheck(
currentState == desiredState,
"Validate returned state; expected: %s, got: %s",
(desiredState == SDL_FALSE) ? "SDL_FALSE" : "SDL_TRUE",
(currentState == SDL_FALSE) ? "SDL_FALSE" : "SDL_TRUE");
if (desiredState) {
SDLTest_AssertCheck(
SDL_GetGrabbedWindow() == window,
"Grabbed window should be set to our window");
SDLTest_AssertCheck(
SDL_GetWindowGrab(window),
"SDL_GetWindowGrab() should return SDL_TRUE");
SDLTest_AssertCheck(
SDL_GetWindowFlags(window) & SDL_WINDOW_KEYBOARD_GRABBED,
"SDL_WINDOW_KEYBOARD_GRABBED should be set");
} else {
SDLTest_AssertCheck(
!(SDL_GetWindowFlags(window) & SDL_WINDOW_KEYBOARD_GRABBED),
"SDL_WINDOW_KEYBOARD_GRABBED should be unset");
}
}
/**
* @brief Tests call to SDL_GetWindowGrab and SDL_SetWindowGrab
* @brief Tests keyboard and mouse grab support
*
* @sa http://wiki.libsdl.org/moin.fcg/SDL_GetWindowGrab
* @sa http://wiki.libsdl.org/moin.fcg/SDL_SetWindowGrab
* @sa http://wiki.libsdl.org/SDL_GetWindowGrab
* @sa http://wiki.libsdl.org/SDL_SetWindowGrab
*/
int
video_getSetWindowGrab(void *arg)
{
const char* title = "video_getSetWindowGrab Test Window";
SDL_Window* window;
SDL_bool originalState, dummyState, currentState, desiredState;
SDL_bool originalMouseState, originalKeyboardState, dummyState;
/* Call against new test window */
window = _createVideoSuiteTestWindow(title);
if (window == NULL) return TEST_ABORTED;
/* Get state */
originalState = SDL_GetWindowGrab(window);
SDLTest_AssertPass("Call to SDL_GetWindowGrab()");
originalMouseState = SDL_GetWindowMouseGrab(window);
SDLTest_AssertPass("Call to SDL_GetWindowMouseGrab()");
originalKeyboardState = SDL_GetWindowKeyboardGrab(window);
SDLTest_AssertPass("Call to SDL_GetWindowKeyboardGrab()");
/* F */
_setAndCheckWindowGrabState(window, SDL_FALSE);
_setAndCheckWindowKeyboardGrabState(window, SDL_FALSE);
_setAndCheckWindowMouseGrabState(window, SDL_FALSE);
SDLTest_AssertCheck(!SDL_GetWindowGrab(window),
"SDL_GetWindowGrab should return SDL_FALSE");
SDLTest_AssertCheck(SDL_GetGrabbedWindow() == NULL,
"Expected NULL grabbed window");
/* F --> F */
_setAndCheckWindowGrabState(window, SDL_FALSE);
_setAndCheckWindowMouseGrabState(window, SDL_FALSE);
_setAndCheckWindowKeyboardGrabState(window, SDL_FALSE);
SDLTest_AssertCheck(SDL_GetGrabbedWindow() == NULL,
"Expected NULL grabbed window");
/* F --> T */
_setAndCheckWindowGrabState(window, SDL_TRUE);
_setAndCheckWindowMouseGrabState(window, SDL_TRUE);
_setAndCheckWindowKeyboardGrabState(window, SDL_TRUE);
SDLTest_AssertCheck(SDL_GetWindowGrab(window),
"SDL_GetWindowGrab() should return SDL_TRUE");
/* T --> T */
_setAndCheckWindowGrabState(window, SDL_TRUE);
_setAndCheckWindowKeyboardGrabState(window, SDL_TRUE);
_setAndCheckWindowMouseGrabState(window, SDL_TRUE);
SDLTest_AssertCheck(SDL_GetWindowGrab(window),
"SDL_GetWindowGrab() should return SDL_TRUE");
/* T --> F */
_setAndCheckWindowGrabState(window, SDL_FALSE);
/* M: T --> F */
/* K: T --> T */
_setAndCheckWindowKeyboardGrabState(window, SDL_TRUE);
_setAndCheckWindowMouseGrabState(window, SDL_FALSE);
SDLTest_AssertCheck(SDL_GetWindowGrab(window),
"SDL_GetWindowGrab() should return SDL_TRUE");
/* M: F --> T */
/* K: T --> F */
_setAndCheckWindowMouseGrabState(window, SDL_TRUE);
_setAndCheckWindowKeyboardGrabState(window, SDL_FALSE);
SDLTest_AssertCheck(SDL_GetWindowGrab(window),
"SDL_GetWindowGrab() should return SDL_TRUE");
/* M: T --> F */
/* K: F --> F */
_setAndCheckWindowMouseGrabState(window, SDL_FALSE);
_setAndCheckWindowKeyboardGrabState(window, SDL_FALSE);
SDLTest_AssertCheck(!SDL_GetWindowGrab(window),
"SDL_GetWindowGrab() should return SDL_FALSE");
SDLTest_AssertCheck(SDL_GetGrabbedWindow() == NULL,
"Expected NULL grabbed window");
/* Using the older SDL_SetWindowGrab API should only grab mouse by default */
SDL_SetWindowGrab(window, SDL_TRUE);
SDLTest_AssertPass("Call to SDL_SetWindowGrab(SDL_TRUE)");
SDLTest_AssertCheck(SDL_GetWindowGrab(window),
"SDL_GetWindowGrab() should return SDL_TRUE");
SDLTest_AssertCheck(SDL_GetWindowMouseGrab(window),
"SDL_GetWindowMouseGrab() should return SDL_TRUE");
SDLTest_AssertCheck(!SDL_GetWindowKeyboardGrab(window),
"SDL_GetWindowKeyboardGrab() should return SDL_FALSE");
SDL_SetWindowGrab(window, SDL_FALSE);
SDLTest_AssertCheck(!SDL_GetWindowGrab(window),
"SDL_GetWindowGrab() should return SDL_FALSE");
SDLTest_AssertCheck(!SDL_GetWindowMouseGrab(window),
"SDL_GetWindowMouseGrab() should return SDL_FALSE");
SDLTest_AssertCheck(!SDL_GetWindowKeyboardGrab(window),
"SDL_GetWindowKeyboardGrab() should return SDL_FALSE");
/* Now test with SDL_HINT_GRAB_KEYBOARD set. We should get keyboard grab now. */
SDL_SetHint(SDL_HINT_GRAB_KEYBOARD, "1");
SDL_SetWindowGrab(window, SDL_TRUE);
SDLTest_AssertPass("Call to SDL_SetWindowGrab(SDL_TRUE)");
SDLTest_AssertCheck(SDL_GetWindowGrab(window),
"SDL_GetWindowGrab() should return SDL_TRUE");
SDLTest_AssertCheck(SDL_GetWindowMouseGrab(window),
"SDL_GetWindowMouseGrab() should return SDL_TRUE");
SDLTest_AssertCheck(SDL_GetWindowKeyboardGrab(window),
"SDL_GetWindowKeyboardGrab() should return SDL_TRUE");
SDL_SetWindowGrab(window, SDL_FALSE);
SDLTest_AssertCheck(!SDL_GetWindowGrab(window),
"SDL_GetWindowGrab() should return SDL_FALSE");
SDLTest_AssertCheck(!SDL_GetWindowMouseGrab(window),
"SDL_GetWindowMouseGrab() should return SDL_FALSE");
SDLTest_AssertCheck(!SDL_GetWindowKeyboardGrab(window),
"SDL_GetWindowKeyboardGrab() should return SDL_FALSE");
/* Negative tests */
dummyState = SDL_GetWindowGrab(NULL);
SDLTest_AssertPass("Call to SDL_GetWindowGrab(window=NULL)");
_checkInvalidWindowError();
dummyState = SDL_GetWindowKeyboardGrab(NULL);
SDLTest_AssertPass("Call to SDL_GetWindowKeyboardGrab(window=NULL)");
_checkInvalidWindowError();
SDL_SetWindowGrab(NULL, SDL_FALSE);
SDLTest_AssertPass("Call to SDL_SetWindowGrab(window=NULL,SDL_FALSE)");
_checkInvalidWindowError();
SDL_SetWindowGrab(NULL, SDL_TRUE);
SDLTest_AssertPass("Call to SDL_SetWindowGrab(window=NULL,SDL_FALSE)");
SDL_SetWindowKeyboardGrab(NULL, SDL_FALSE);
SDLTest_AssertPass("Call to SDL_SetWindowKeyboardGrab(window=NULL,SDL_FALSE)");
_checkInvalidWindowError();
/* State should still be F */
desiredState = SDL_FALSE;
currentState = SDL_GetWindowGrab(window);
SDLTest_AssertPass("Call to SDL_GetWindowGrab()");
SDLTest_AssertCheck(
currentState == desiredState,
"Validate returned state; expected: %s, got: %s",
(desiredState == SDL_FALSE) ? "SDL_FALSE" : "SDL_TRUE",
(currentState == SDL_FALSE) ? "SDL_FALSE" : "SDL_TRUE");
SDL_SetWindowGrab(NULL, SDL_TRUE);
SDLTest_AssertPass("Call to SDL_SetWindowGrab(window=NULL,SDL_TRUE)");
_checkInvalidWindowError();
SDL_SetWindowKeyboardGrab(NULL, SDL_TRUE);
SDLTest_AssertPass("Call to SDL_SetWindowKeyboardGrab(window=NULL,SDL_TRUE)");
_checkInvalidWindowError();
/* Restore state */
_setAndCheckWindowGrabState(window, originalState);
_setAndCheckWindowMouseGrabState(window, originalMouseState);
_setAndCheckWindowKeyboardGrabState(window, originalKeyboardState);
/* Clean up */
_destroyVideoSuiteTestWindow(window);