Expose the keymap separately from the event keycode

This adds functions to query the keymap:
* SDL_GetCurrentKeymap()
* SDL_GetKeymapKeycode()
* SDL_GetKeymapScancode()
* SDL_ReleaseKeymap()

and these are distinct from the function to query the event keycode associated with a scancode, which might be affected by SDL_HINT_KEYCODE_OPTIONS.

Also added an SDL_bool parameter to SDL_GetKeyName() and SDL_GetKeyFromName() to enable upper case handling of the name.
This commit is contained in:
Sam Lantinga
2024-08-05 16:37:24 -07:00
parent d68d32e12c
commit c298a3749b
15 changed files with 241 additions and 191 deletions

View File

@@ -189,12 +189,13 @@ static void PrintKeymap(void)
(SDL_KMOD_MODE | SDL_KMOD_SHIFT | SDL_KMOD_CAPS)
};
int i, m;
SDL_Keymap *keymap = SDL_GetCurrentKeymap();
SDL_Log("Differences from the default keymap:\n");
for (m = 0; m < SDL_arraysize(mods); ++m) {
for (i = 0; i < SDL_NUM_SCANCODES; ++i) {
SDL_Keycode key = SDL_GetKeyFromScancode((SDL_Scancode)i, mods[m]);
SDL_Keycode default_key = SDL_GetDefaultKeyFromScancode((SDL_Scancode)i, mods[m]);
SDL_Keycode key = SDL_GetKeymapKeycode(keymap, (SDL_Scancode)i, mods[m]);
SDL_Keycode default_key = SDL_GetKeymapKeycode(NULL, (SDL_Scancode)i, mods[m]);
if (key != default_key) {
char message[512];
char *spot;
@@ -203,13 +204,14 @@ static void PrintKeymap(void)
spot = message;
left = sizeof(message);
print_string(&spot, &left, "Scancode %s", SDL_GetScancodeName((SDL_Scancode)i));
print_string(&spot, &left, "Scancode %s (%d)", SDL_GetScancodeName((SDL_Scancode)i), i);
print_modifiers(&spot, &left, mods[m]);
print_string(&spot, &left, ": %s 0x%x (default: %s 0x%x)", SDL_GetKeyName(key), key, SDL_GetKeyName(default_key), default_key);
print_string(&spot, &left, ": %s 0x%x (default: %s 0x%x)", SDL_GetKeyName(key, SDL_FALSE), key, SDL_GetKeyName(default_key, SDL_FALSE), default_key);
SDL_Log("%s", message);
}
}
}
SDL_ReleaseKeymap(keymap);
}
static void PrintModifierState(void)
@@ -242,7 +244,7 @@ static void PrintKey(SDL_KeyboardEvent *event)
event->raw,
event->scancode,
event->scancode == SDL_SCANCODE_UNKNOWN ? "UNKNOWN" : SDL_GetScancodeName(event->scancode),
event->key, SDL_GetKeyName(event->key));
event->key, SDL_GetKeyName(event->key, SDL_TRUE));
} else {
print_string(&spot, &left,
"Unknown Key (raw 0x%.2x, scancode %d = %s) %s ",

View File

@@ -59,39 +59,43 @@ static int keyboard_getKeyFromName(void *arg)
SDL_Keycode result;
/* Case where Key is known, 1 character input */
result = SDL_GetKeyFromName("A");
SDLTest_AssertPass("Call to SDL_GetKeyFromName(known/single)");
SDLTest_AssertCheck(result == SDLK_A, "Verify result from call, expected: %d, got: %" SDL_PRIs32, SDLK_A, result);
result = SDL_GetKeyFromName("A", SDL_TRUE);
SDLTest_AssertPass("Call to SDL_GetKeyFromName('A', SDL_TRUE)");
SDLTest_AssertCheck(result == SDLK_A, "Verify result from call, expected: %d, got: %" SDL_PRIu32, SDLK_A, result);
result = SDL_GetKeyFromName("A", SDL_FALSE);
SDLTest_AssertPass("Call to SDL_GetKeyFromName('A', SDL_FALSE)");
SDLTest_AssertCheck(result == 'A', "Verify result from call, expected: %d, got: %" SDL_PRIu32, 'A', result);
/* Case where Key is known, 2 character input */
result = SDL_GetKeyFromName("F1");
result = SDL_GetKeyFromName("F1", SDL_TRUE);
SDLTest_AssertPass("Call to SDL_GetKeyFromName(known/double)");
SDLTest_AssertCheck(result == SDLK_F1, "Verify result from call, expected: %d, got: %" SDL_PRIs32, SDLK_F1, result);
SDLTest_AssertCheck(result == SDLK_F1, "Verify result from call, expected: %d, got: %" SDL_PRIu32, SDLK_F1, result);
/* Case where Key is known, 3 character input */
result = SDL_GetKeyFromName("End");
result = SDL_GetKeyFromName("End", SDL_TRUE);
SDLTest_AssertPass("Call to SDL_GetKeyFromName(known/triple)");
SDLTest_AssertCheck(result == SDLK_END, "Verify result from call, expected: %d, got: %" SDL_PRIs32, SDLK_END, result);
SDLTest_AssertCheck(result == SDLK_END, "Verify result from call, expected: %d, got: %" SDL_PRIu32, SDLK_END, result);
/* Case where Key is known, 4 character input */
result = SDL_GetKeyFromName("Find");
result = SDL_GetKeyFromName("Find", SDL_TRUE);
SDLTest_AssertPass("Call to SDL_GetKeyFromName(known/quad)");
SDLTest_AssertCheck(result == SDLK_FIND, "Verify result from call, expected: %d, got: %" SDL_PRIs32, SDLK_FIND, result);
SDLTest_AssertCheck(result == SDLK_FIND, "Verify result from call, expected: %d, got: %" SDL_PRIu32, SDLK_FIND, result);
/* Case where Key is known, multiple character input */
result = SDL_GetKeyFromName("MediaStop");
result = SDL_GetKeyFromName("MediaStop", SDL_TRUE);
SDLTest_AssertPass("Call to SDL_GetKeyFromName(known/multi)");
SDLTest_AssertCheck(result == SDLK_MEDIA_STOP, "Verify result from call, expected: %d, got: %" SDL_PRIs32, SDLK_MEDIA_STOP, result);
SDLTest_AssertCheck(result == SDLK_MEDIA_STOP, "Verify result from call, expected: %d, got: %" SDL_PRIu32, SDLK_MEDIA_STOP, result);
/* Case where Key is unknown */
result = SDL_GetKeyFromName("NotThere");
result = SDL_GetKeyFromName("NotThere", SDL_TRUE);
SDLTest_AssertPass("Call to SDL_GetKeyFromName(unknown)");
SDLTest_AssertCheck(result == SDLK_UNKNOWN, "Verify result from call is UNKNOWN, expected: %d, got: %" SDL_PRIs32, SDLK_UNKNOWN, result);
SDLTest_AssertCheck(result == SDLK_UNKNOWN, "Verify result from call is UNKNOWN, expected: %d, got: %" SDL_PRIu32, SDLK_UNKNOWN, result);
/* Case where input is NULL/invalid */
result = SDL_GetKeyFromName(NULL);
result = SDL_GetKeyFromName(NULL, SDL_TRUE);
SDLTest_AssertPass("Call to SDL_GetKeyFromName(NULL)");
SDLTest_AssertCheck(result == SDLK_UNKNOWN, "Verify result from call is UNKNOWN, expected: %d, got: %" SDL_PRIs32, SDLK_UNKNOWN, result);
SDLTest_AssertCheck(result == SDLK_UNKNOWN, "Verify result from call is UNKNOWN, expected: %d, got: %" SDL_PRIu32, SDLK_UNKNOWN, result);
return TEST_COMPLETED;
}
@@ -126,12 +130,12 @@ static int keyboard_getKeyFromScancode(void *arg)
/* Case where input is valid */
result = SDL_GetKeyFromScancode(SDL_SCANCODE_A, SDL_KMOD_NONE);
SDLTest_AssertPass("Call to SDL_GetKeyFromScancode(valid)");
SDLTest_AssertCheck(result == SDLK_A, "Verify result from call, expected: %d, got: %" SDL_PRIs32, SDLK_A, result);
SDLTest_AssertCheck(result == SDLK_A, "Verify result from call, expected: %d, got: %" SDL_PRIu32, SDLK_A, result);
/* Case where input is zero */
result = SDL_GetKeyFromScancode(SDL_SCANCODE_UNKNOWN, SDL_KMOD_NONE);
SDLTest_AssertPass("Call to SDL_GetKeyFromScancode(0)");
SDLTest_AssertCheck(result == SDLK_UNKNOWN, "Verify result from call is UNKNOWN, expected: %d, got: %" SDL_PRIs32, SDLK_UNKNOWN, result);
SDLTest_AssertCheck(result == SDLK_UNKNOWN, "Verify result from call is UNKNOWN, expected: %d, got: %" SDL_PRIu32, SDLK_UNKNOWN, result);
/* Clear error message */
SDL_ClearError();
@@ -140,13 +144,13 @@ static int keyboard_getKeyFromScancode(void *arg)
/* Case where input is invalid (too small) */
result = SDL_GetKeyFromScancode((SDL_Scancode)-999, SDL_KMOD_NONE);
SDLTest_AssertPass("Call to SDL_GetKeyFromScancode(-999)");
SDLTest_AssertCheck(result == SDLK_UNKNOWN, "Verify result from call is UNKNOWN, expected: %d, got: %" SDL_PRIs32, SDLK_UNKNOWN, result);
SDLTest_AssertCheck(result == SDLK_UNKNOWN, "Verify result from call is UNKNOWN, expected: %d, got: %" SDL_PRIu32, SDLK_UNKNOWN, result);
checkInvalidScancodeError();
/* Case where input is invalid (too big) */
result = SDL_GetKeyFromScancode((SDL_Scancode)999, SDL_KMOD_NONE);
SDLTest_AssertPass("Call to SDL_GetKeyFromScancode(999)");
SDLTest_AssertCheck(result == SDLK_UNKNOWN, "Verify result from call is UNKNOWN, expected: %d, got: %" SDL_PRIs32, SDLK_UNKNOWN, result);
SDLTest_AssertCheck(result == SDLK_UNKNOWN, "Verify result from call is UNKNOWN, expected: %d, got: %" SDL_PRIu32, SDLK_UNKNOWN, result);
checkInvalidScancodeError();
return TEST_COMPLETED;
@@ -164,42 +168,42 @@ static int keyboard_getKeyName(void *arg)
/* Case where key has a 1 character name */
expected = "3";
result = SDL_GetKeyName(SDLK_3);
result = SDL_GetKeyName(SDLK_3, SDL_TRUE);
SDLTest_AssertPass("Call to SDL_GetKeyName()");
SDLTest_AssertCheck(result != NULL, "Verify result from call is not NULL");
SDLTest_AssertCheck(SDL_strcmp(result, expected) == 0, "Verify result from call is valid, expected: %s, got: %s", expected, result);
/* Case where key has a 2 character name */
expected = "F1";
result = SDL_GetKeyName(SDLK_F1);
result = SDL_GetKeyName(SDLK_F1, SDL_TRUE);
SDLTest_AssertPass("Call to SDL_GetKeyName()");
SDLTest_AssertCheck(result != NULL, "Verify result from call is not NULL");
SDLTest_AssertCheck(SDL_strcmp(result, expected) == 0, "Verify result from call is valid, expected: %s, got: %s", expected, result);
/* Case where key has a 3 character name */
expected = "Cut";
result = SDL_GetKeyName(SDLK_CUT);
result = SDL_GetKeyName(SDLK_CUT, SDL_TRUE);
SDLTest_AssertPass("Call to SDL_GetKeyName()");
SDLTest_AssertCheck(result != NULL, "Verify result from call is not NULL");
SDLTest_AssertCheck(SDL_strcmp(result, expected) == 0, "Verify result from call is valid, expected: %s, got: %s", expected, result);
/* Case where key has a 4 character name */
expected = "Down";
result = SDL_GetKeyName(SDLK_DOWN);
result = SDL_GetKeyName(SDLK_DOWN, SDL_TRUE);
SDLTest_AssertPass("Call to SDL_GetKeyName()");
SDLTest_AssertCheck(result != NULL, "Verify result from call is not NULL");
SDLTest_AssertCheck(SDL_strcmp(result, expected) == 0, "Verify result from call is valid, expected: %s, got: %s", expected, result);
/* Case where key has a N character name */
expected = "MediaPlay";
result = SDL_GetKeyName(SDLK_MEDIA_PLAY);
result = SDL_GetKeyName(SDLK_MEDIA_PLAY, SDL_TRUE);
SDLTest_AssertPass("Call to SDL_GetKeyName()");
SDLTest_AssertCheck(result != NULL, "Verify result from call is not NULL");
SDLTest_AssertCheck(SDL_strcmp(result, expected) == 0, "Verify result from call is valid, expected: %s, got: %s", expected, result);
/* Case where key has a N character name with space */
expected = "Keypad MemStore";
result = SDL_GetKeyName(SDLK_KP_MEMSTORE);
result = SDL_GetKeyName(SDLK_KP_MEMSTORE, SDL_TRUE);
SDLTest_AssertPass("Call to SDL_GetKeyName()");
SDLTest_AssertCheck(result != NULL, "Verify result from call is not NULL");
SDLTest_AssertCheck(SDL_strcmp(result, expected) == 0, "Verify result from call is valid, expected: %s, got: %s", expected, result);
@@ -246,8 +250,8 @@ static int keyboard_getKeyNameNegative(void *arg)
/* Unknown keycode */
keycode = SDLK_UNKNOWN;
result = SDL_GetKeyName(keycode);
SDLTest_AssertPass("Call to SDL_GetKeyName(%" SDL_PRIs32 "/unknown)", keycode);
result = SDL_GetKeyName(keycode, SDL_TRUE);
SDLTest_AssertPass("Call to SDL_GetKeyName(%" SDL_PRIu32 "/unknown)", keycode);
SDLTest_AssertCheck(result != NULL, "Verify result from call is not NULL");
SDLTest_AssertCheck(SDL_strcmp(result, expected) == 0, "Verify result from call is valid, expected: '%s', got: '%s'", expected, result);
@@ -257,8 +261,8 @@ static int keyboard_getKeyNameNegative(void *arg)
/* Negative keycode */
keycode = (SDL_Keycode)SDLTest_RandomIntegerInRange(-255, -1);
result = SDL_GetKeyName(keycode);
SDLTest_AssertPass("Call to SDL_GetKeyName(%" SDL_PRIs32 "/negative)", keycode);
result = SDL_GetKeyName(keycode, SDL_TRUE);
SDLTest_AssertPass("Call to SDL_GetKeyName(%" SDL_PRIu32 "/negative)", keycode);
SDLTest_AssertCheck(result != NULL, "Verify result from call is not NULL");
SDLTest_AssertCheck(SDL_strcmp(result, expected) == 0, "Verify result from call is valid, expected: '%s', got: '%s'", expected, result);
checkInvalidScancodeError();
@@ -494,25 +498,25 @@ static int keyboard_setTextInputAreaNegative(void *arg)
}
/**
* Check call to SDL_GetScancodeFromKey
* Check call to SDL_getKeymapScancode
*
* \sa SDL_GetScancodeFromKey
* \sa SDL_getKeymapScancode
* \sa SDL_Keycode
*/
static int keyboard_getScancodeFromKey(void *arg)
static int keyboard_getKeymapScancode(void *arg)
{
SDL_Scancode scancode;
SDL_Keymod modstate;
/* Regular key */
scancode = SDL_GetDefaultScancodeFromKey(SDLK_4, &modstate);
SDLTest_AssertPass("Call to SDL_GetScancodeFromKey(SDLK_4)");
scancode = SDL_GetKeymapScancode(NULL, SDLK_4, &modstate);
SDLTest_AssertPass("Call to SDL_GetKeymapScancode(SDLK_4)");
SDLTest_AssertCheck(scancode == SDL_SCANCODE_4, "Validate return value from SDL_GetDefaultScancodeFromKey, expected: %d, got: %d", SDL_SCANCODE_4, scancode);
SDLTest_AssertCheck(modstate == SDL_KMOD_NONE, "Validate modstate from SDL_GetDefaultScancodeFromKey, expected: %d, got: %d", SDL_KMOD_NONE, modstate);
/* Virtual key */
scancode = SDL_GetDefaultScancodeFromKey(SDLK_PLUS, &modstate);
SDLTest_AssertPass("Call to SDL_GetScancodeFromKey(SDLK_PLUS)");
scancode = SDL_GetKeymapScancode(NULL, SDLK_PLUS, &modstate);
SDLTest_AssertPass("Call to SDL_GetKeymapScancode(SDLK_PLUS)");
SDLTest_AssertCheck(scancode == SDL_SCANCODE_EQUALS, "Validate return value from SDL_GetDefaultScancodeFromKey, expected: %d, got: %d", SDL_SCANCODE_EQUALS, scancode);
SDLTest_AssertCheck(modstate == SDL_KMOD_SHIFT, "Validate modstate from SDL_GetDefaultScancodeFromKey, expected: %d, got: %d", SDL_KMOD_SHIFT, modstate);
@@ -674,7 +678,7 @@ static const SDLTest_TestCaseReference keyboardTest9 = {
};
static const SDLTest_TestCaseReference keyboardTest10 = {
(SDLTest_TestCaseFp)keyboard_getScancodeFromKey, "keyboard_getScancodeFromKey", "Check call to SDL_GetScancodeFromKey", TEST_ENABLED
(SDLTest_TestCaseFp)keyboard_getKeymapScancode, "keyboard_getKeymapScancode", "Check call to SDL_getKeymapScancode", TEST_ENABLED
};
static const SDLTest_TestCaseReference keyboardTest11 = {

View File

@@ -1209,7 +1209,7 @@ int main(int argc, char *argv[])
event.key.scancode,
SDL_GetScancodeName(event.key.scancode),
SDL_static_cast(Uint32, event.key.key),
SDL_GetKeyName(event.key.key));
SDL_GetKeyName(event.key.key, SDL_TRUE));
break;
}
case SDL_EVENT_TEXT_INPUT: {