Skip to content

Commit 8a72eae

Browse files
committed
Filter out extended key codes
SDL2 has no mapping for extended keycodes, so SDL2 apps/games are not expecting them. If an extended key code is encountered, the key code will instead be derived from the scancode, and the standard scancode will be returned for commonly remapped keys if no mapping is found, which matches the existing mapping and behavior of the real SDL2.
1 parent b13e861 commit 8a72eae

File tree

1 file changed

+53
-5
lines changed

1 file changed

+53
-5
lines changed

src/sdl2_compat.c

Lines changed: 53 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1281,6 +1281,24 @@ static SDL2_Scancode SDL3ScancodeToSDL2Scancode(SDL_Scancode scancode)
12811281
}
12821282
}
12831283

1284+
static SDL_Keycode SDL3KeycodeToSDL2Keycode(SDL_Scancode scancode, SDL_Keycode keycode)
1285+
{
1286+
/* Keys without the extended mask are passed through. */
1287+
if (!(keycode & SDLK_EXTENDED_MASK)) {
1288+
return keycode;
1289+
}
1290+
1291+
/* SDLK_TAB is an ASCII value and can't be converted directly from a scancode. */
1292+
if (keycode == SDLK_LEFT_TAB) {
1293+
return SDLK_TAB;
1294+
}
1295+
1296+
/* Convert the scancode directly to the keycode. This matches the mapping behavior
1297+
* of SDL2 backends unless some very esoteric key remapping is being used.
1298+
*/
1299+
return SDL_SCANCODE_TO_KEYCODE(scancode);
1300+
}
1301+
12841302
/* (current) strategy for SDL_Events:
12851303
in sdl12-compat, we built our own event queue, so when the SDL2 queue is pumped, we
12861304
took the events we cared about and added them to the sdl12-compat queue, and otherwise
@@ -1322,7 +1340,7 @@ Event3to2(const SDL_Event *event3, SDL2_Event *event2)
13221340
case SDL_EVENT_KEY_DOWN:
13231341
case SDL_EVENT_KEY_UP:
13241342
event2->key.keysym.scancode = SDL3ScancodeToSDL2Scancode(event3->key.scancode);
1325-
event2->key.keysym.sym = event3->key.key;
1343+
event2->key.keysym.sym = SDL3KeycodeToSDL2Keycode(event3->key.scancode, event3->key.key);
13261344
event2->key.keysym.mod = event3->key.mod;
13271345
event2->key.state = event3->key.down;
13281346
event2->key.repeat = event3->key.repeat;
@@ -1902,18 +1920,48 @@ SDL_GetKeyFromScancode(SDL2_Scancode scancode)
19021920
}
19031921

19041922
if (scancode <= SDL2_SCANCODE_MODE) {
1905-
// They're the same
1906-
return SDL3_GetKeyFromScancode(SDL2ScancodeToSDL3Scancode(scancode), SDL_KMOD_NONE, true);
1907-
} else {
1908-
return SDL_SCANCODE_TO_KEYCODE(scancode);
1923+
/* Filter out extended keycodes. This matches the key mapping behavior of SDL2 backends. */
1924+
const SDL_Keycode keycode = SDL3_GetKeyFromScancode(SDL2ScancodeToSDL3Scancode(scancode), SDL_KMOD_NONE, true);
1925+
if (!(keycode & SDLK_EXTENDED_MASK)) {
1926+
return keycode;
1927+
}
19091928
}
1929+
1930+
return SDL_SCANCODE_TO_KEYCODE(scancode);
19101931
}
19111932

19121933
SDL_DECLSPEC SDL2_Scancode SDLCALL
19131934
SDL_GetScancodeFromKey(SDL_Keycode key)
19141935
{
19151936
SDL_Keymod modstate = SDL_KMOD_NONE;
19161937
SDL_Scancode scancode = SDL3_GetScancodeFromKey(key, &modstate);
1938+
1939+
if (scancode == SDL_SCANCODE_UNKNOWN) {
1940+
/* Keys commonly remapped to extended keycodes in SDL3.
1941+
* If the keymap returns no mapping, convert the key to a scancode directly.
1942+
*/
1943+
switch (key) {
1944+
case SDLK_LCTRL:
1945+
case SDLK_RCTRL:
1946+
case SDLK_LALT:
1947+
case SDLK_RALT:
1948+
case SDLK_LGUI:
1949+
case SDLK_RGUI:
1950+
case SDLK_CAPSLOCK:
1951+
case SDLK_SCROLLLOCK:
1952+
case SDLK_PRINTSCREEN:
1953+
case SDLK_INSERT:
1954+
scancode = (SDL_Scancode)(key & ~SDLK_SCANCODE_MASK);
1955+
break;
1956+
case SDLK_TAB:
1957+
/* ASCII value that can't be directly converted to a scancode. */
1958+
scancode = SDL_SCANCODE_TAB;
1959+
break;
1960+
default:
1961+
break;
1962+
}
1963+
}
1964+
19171965
if (modstate != SDL_KMOD_NONE) {
19181966
return SDL2_SCANCODE_UNKNOWN;
19191967
}

0 commit comments

Comments
 (0)