sdl12-compat: Convert SDL2 Scancodes into SDLKey, not SDL2 Keycodes

From b9226b07be15bba33d656f8f4082895f82cd5bcb Mon Sep 17 00:00:00 2001
From: David Gow <[EMAIL REDACTED]>
Date: Thu, 10 Jun 2021 15:08:20 +0800
Subject: [PATCH] Convert SDL2 Scancodes into SDLKey, not SDL2 Keycodes
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

SDL 1.2's keysym appears to be entirely layout-indpendent: it always
acts as though there is a US keyboard layout. i.e., the values represent
the positions on the keyboard, not the "meaning" of the key. This
matches what SDL 2.0 scancodes do, but not SDL 2.0 keycodes, which are
translated according to the current keyboard layout.

This means that many SDL 1.2 applications would suddenly start using the
user's keyboard layout, rather than the US one, which -- while quite
convenient in some cases -- is a change in behaviour and could break
things.

Instead of converting SDL_Keycode→SDLKey, this patch converts from
SDL_Scancode→SDLKey, preserving the original behaviour. SDL 1.2
applications will still get translated values in the 'unicode' Keysym
variable if enabled, so text input in many applications will still work
as expected.
---
 src/SDL12_compat.c | 212 ++++++++++++++++++++++++++++-----------------
 1 file changed, 131 insertions(+), 81 deletions(-)

diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c
index fdc57f0..c05a60e 100644
--- a/src/SDL12_compat.c
+++ b/src/SDL12_compat.c
@@ -2294,88 +2294,138 @@ SDL_GetKeyName(SDL12Key key)
 }
 
 static SDL12Key
-Keysym20to12(const SDL_Keycode keysym20)
-{
-    if (((int) keysym20) < 127) {  /* (most of) low-ASCII maps directly */
-        if (keysym20 == SDLK_PAUSE) {
-            return SDLK12_PAUSE;
-        } else if (keysym20 == SDLK_CLEAR) {
-            return SDLK12_CLEAR;
-        }
-        return (SDL12Key) keysym20;
-    }
-
-    switch (keysym20) {
-    #define CASEKEYSYM20TO12(k20, k12) case SDLK_##k20: return SDLK12_##k12
-    CASEKEYSYM20TO12(KP_0, KP0);
-    CASEKEYSYM20TO12(KP_1, KP1);
-    CASEKEYSYM20TO12(KP_2, KP2);
-    CASEKEYSYM20TO12(KP_3, KP3);
-    CASEKEYSYM20TO12(KP_4, KP4);
-    CASEKEYSYM20TO12(KP_5, KP5);
-    CASEKEYSYM20TO12(KP_6, KP6);
-    CASEKEYSYM20TO12(KP_7, KP7);
-    CASEKEYSYM20TO12(KP_8, KP8);
-    CASEKEYSYM20TO12(KP_9, KP9);
-    CASEKEYSYM20TO12(NUMLOCKCLEAR, NUMLOCK);
-    CASEKEYSYM20TO12(SCROLLLOCK, SCROLLOCK);
-    CASEKEYSYM20TO12(RGUI, RMETA);
-    CASEKEYSYM20TO12(LGUI, LMETA);
-    CASEKEYSYM20TO12(PRINTSCREEN, PRINT);
-    #undef CASEKEYSYM20TO12
-
-    #define CASEKEYSYM20TO12(k) case SDLK_##k: return SDLK12_##k
-    CASEKEYSYM20TO12(CLEAR);
-    CASEKEYSYM20TO12(PAUSE);
-    CASEKEYSYM20TO12(KP_PERIOD);
-    CASEKEYSYM20TO12(KP_DIVIDE);
-    CASEKEYSYM20TO12(KP_MULTIPLY);
-    CASEKEYSYM20TO12(KP_MINUS);
-    CASEKEYSYM20TO12(KP_PLUS);
-    CASEKEYSYM20TO12(KP_ENTER);
-    CASEKEYSYM20TO12(KP_EQUALS);
-    CASEKEYSYM20TO12(UP);
-    CASEKEYSYM20TO12(DOWN);
-    CASEKEYSYM20TO12(RIGHT);
-    CASEKEYSYM20TO12(LEFT);
-    CASEKEYSYM20TO12(INSERT);
-    CASEKEYSYM20TO12(HOME);
-    CASEKEYSYM20TO12(END);
-    CASEKEYSYM20TO12(PAGEUP);
-    CASEKEYSYM20TO12(PAGEDOWN);
-    CASEKEYSYM20TO12(F1);
-    CASEKEYSYM20TO12(F2);
-    CASEKEYSYM20TO12(F3);
-    CASEKEYSYM20TO12(F4);
-    CASEKEYSYM20TO12(F5);
-    CASEKEYSYM20TO12(F6);
-    CASEKEYSYM20TO12(F7);
-    CASEKEYSYM20TO12(F8);
-    CASEKEYSYM20TO12(F9);
-    CASEKEYSYM20TO12(F10);
-    CASEKEYSYM20TO12(F11);
-    CASEKEYSYM20TO12(F12);
-    CASEKEYSYM20TO12(F13);
-    CASEKEYSYM20TO12(F14);
-    CASEKEYSYM20TO12(F15);
-    CASEKEYSYM20TO12(CAPSLOCK);
-    CASEKEYSYM20TO12(RSHIFT);
-    CASEKEYSYM20TO12(LSHIFT);
-    CASEKEYSYM20TO12(RCTRL);
-    CASEKEYSYM20TO12(LCTRL);
-    CASEKEYSYM20TO12(RALT);
-    CASEKEYSYM20TO12(LALT);
-    CASEKEYSYM20TO12(MODE);
-    CASEKEYSYM20TO12(HELP);
-    CASEKEYSYM20TO12(SYSREQ);;
-    CASEKEYSYM20TO12(MENU);
-    CASEKEYSYM20TO12(POWER);
-    CASEKEYSYM20TO12(UNDO);
-    #undef CASEKEYSYM20TO12
+Scancode20toKeysym12(const SDL_Scancode scancode20)
+{
+    switch (scancode20) {
+    #define CASESCANCODE20TOKEY12(s20, k12) case SDL_SCANCODE_##s20: return SDLK12_##k12
+    CASESCANCODE20TOKEY12(A,a);
+    CASESCANCODE20TOKEY12(B,b);
+    CASESCANCODE20TOKEY12(C,c);
+    CASESCANCODE20TOKEY12(D,d);
+    CASESCANCODE20TOKEY12(E,e);
+    CASESCANCODE20TOKEY12(F,f);
+    CASESCANCODE20TOKEY12(G,g);
+    CASESCANCODE20TOKEY12(H,h);
+    CASESCANCODE20TOKEY12(I,i);
+    CASESCANCODE20TOKEY12(J,j);
+    CASESCANCODE20TOKEY12(K,k);
+    CASESCANCODE20TOKEY12(L,l);
+    CASESCANCODE20TOKEY12(M,m);
+    CASESCANCODE20TOKEY12(N,n);
+    CASESCANCODE20TOKEY12(O,o);
+    CASESCANCODE20TOKEY12(P,p);
+    CASESCANCODE20TOKEY12(Q,q);
+    CASESCANCODE20TOKEY12(R,r);
+    CASESCANCODE20TOKEY12(S,s);
+    CASESCANCODE20TOKEY12(T,t);
+    CASESCANCODE20TOKEY12(U,u);
+    CASESCANCODE20TOKEY12(V,v);
+    CASESCANCODE20TOKEY12(W,w);
+    CASESCANCODE20TOKEY12(X,x);
+    CASESCANCODE20TOKEY12(Y,y);
+    CASESCANCODE20TOKEY12(Z,z);
+    CASESCANCODE20TOKEY12(1,1);
+    CASESCANCODE20TOKEY12(2,2);
+    CASESCANCODE20TOKEY12(3,3);
+    CASESCANCODE20TOKEY12(4,4);
+    CASESCANCODE20TOKEY12(5,5);
+    CASESCANCODE20TOKEY12(6,6);
+    CASESCANCODE20TOKEY12(7,7);
+    CASESCANCODE20TOKEY12(8,8);
+    CASESCANCODE20TOKEY12(9,9);
+    CASESCANCODE20TOKEY12(0,0);
+    CASESCANCODE20TOKEY12(RETURN,RETURN);
+    CASESCANCODE20TOKEY12(ESCAPE,ESCAPE);
+    CASESCANCODE20TOKEY12(BACKSPACE,BACKSPACE);
+    CASESCANCODE20TOKEY12(TAB,TAB);
+    CASESCANCODE20TOKEY12(SPACE,SPACE);
+    CASESCANCODE20TOKEY12(MINUS,MINUS);
+    CASESCANCODE20TOKEY12(EQUALS,EQUALS);
+    CASESCANCODE20TOKEY12(LEFTBRACKET,LEFTBRACKET);
+    CASESCANCODE20TOKEY12(RIGHTBRACKET,RIGHTBRACKET);
+    CASESCANCODE20TOKEY12(BACKSLASH,BACKSLASH);
+    CASESCANCODE20TOKEY12(NONUSHASH,HASH);
+    CASESCANCODE20TOKEY12(SEMICOLON,SEMICOLON);
+    CASESCANCODE20TOKEY12(APOSTROPHE,QUOTE);
+    CASESCANCODE20TOKEY12(GRAVE,BACKQUOTE);
+    CASESCANCODE20TOKEY12(COMMA,COMMA);
+    CASESCANCODE20TOKEY12(PERIOD,PERIOD);
+    CASESCANCODE20TOKEY12(SLASH,SLASH);
+    CASESCANCODE20TOKEY12(CAPSLOCK,CAPSLOCK);
+    CASESCANCODE20TOKEY12(F1,F1);
+    CASESCANCODE20TOKEY12(F2,F2);
+    CASESCANCODE20TOKEY12(F3,F3);
+    CASESCANCODE20TOKEY12(F4,F4);
+    CASESCANCODE20TOKEY12(F5,F5);
+    CASESCANCODE20TOKEY12(F6,F6);
+    CASESCANCODE20TOKEY12(F7,F7);
+    CASESCANCODE20TOKEY12(F8,F8);
+    CASESCANCODE20TOKEY12(F9,F9);
+    CASESCANCODE20TOKEY12(F10,F10);
+    CASESCANCODE20TOKEY12(F11,F11);
+    CASESCANCODE20TOKEY12(F12,F12);
+    CASESCANCODE20TOKEY12(PRINTSCREEN,PRINT);
+    CASESCANCODE20TOKEY12(SCROLLLOCK,SCROLLOCK);
+    CASESCANCODE20TOKEY12(PAUSE,PAUSE);
+    CASESCANCODE20TOKEY12(INSERT,INSERT);
+    CASESCANCODE20TOKEY12(HOME,HOME);
+    CASESCANCODE20TOKEY12(PAGEUP,PAGEUP);
+    CASESCANCODE20TOKEY12(DELETE,DELETE);
+    CASESCANCODE20TOKEY12(END,END);
+    CASESCANCODE20TOKEY12(PAGEDOWN,PAGEDOWN);
+    CASESCANCODE20TOKEY12(RIGHT,RIGHT);
+    CASESCANCODE20TOKEY12(LEFT,LEFT);
+    CASESCANCODE20TOKEY12(DOWN,DOWN);
+    CASESCANCODE20TOKEY12(UP,UP);
+    CASESCANCODE20TOKEY12(NUMLOCKCLEAR,NUMLOCK);
+
+    CASESCANCODE20TOKEY12(KP_DIVIDE,KP_DIVIDE);
+    CASESCANCODE20TOKEY12(KP_MULTIPLY,KP_MULTIPLY);
+    CASESCANCODE20TOKEY12(KP_MINUS,KP_MINUS);
+    CASESCANCODE20TOKEY12(KP_PLUS,KP_PLUS);
+    CASESCANCODE20TOKEY12(KP_ENTER,KP_ENTER);
+    CASESCANCODE20TOKEY12(KP_1,KP1);
+    CASESCANCODE20TOKEY12(KP_2,KP2);
+    CASESCANCODE20TOKEY12(KP_3,KP3);
+    CASESCANCODE20TOKEY12(KP_4,KP4);
+    CASESCANCODE20TOKEY12(KP_5,KP5);
+    CASESCANCODE20TOKEY12(KP_6,KP6);
+    CASESCANCODE20TOKEY12(KP_7,KP7);
+    CASESCANCODE20TOKEY12(KP_8,KP8);
+    CASESCANCODE20TOKEY12(KP_9,KP9);
+    CASESCANCODE20TOKEY12(KP_0,KP0);
+
+    CASESCANCODE20TOKEY12(NONUSBACKSLASH,BACKSLASH);
+    /* The description of this could be MENU, or COMPOSE, or neither. */
+    CASESCANCODE20TOKEY12(APPLICATION,COMPOSE);
+    CASESCANCODE20TOKEY12(POWER,POWER);
+    CASESCANCODE20TOKEY12(F13,F13);
+    CASESCANCODE20TOKEY12(F14,F14);
+    CASESCANCODE20TOKEY12(F15,F15);
+    CASESCANCODE20TOKEY12(KP_EQUALS,KP_EQUALS);
+    /* SDL 1.2 doesn't support F16..F21 */
+    /* Nor SDL_SCANCODE_EXECUTE */
+    CASESCANCODE20TOKEY12(HELP,HELP);
+    CASESCANCODE20TOKEY12(MENU,MENU);
+    /* The next several scancodes don't have equivalents, until... */
+    CASESCANCODE20TOKEY12(SYSREQ,SYSREQ);
+    CASESCANCODE20TOKEY12(CLEAR,CLEAR);
+    /* Skip some more... */
+    CASESCANCODE20TOKEY12(LCTRL,LCTRL);
+    CASESCANCODE20TOKEY12(LSHIFT,LSHIFT);
+    CASESCANCODE20TOKEY12(LALT,LALT);
+    CASESCANCODE20TOKEY12(LGUI,LSUPER);
+    CASESCANCODE20TOKEY12(RCTRL,RCTRL);
+    CASESCANCODE20TOKEY12(RSHIFT,RSHIFT);
+    CASESCANCODE20TOKEY12(RALT,RALT);
+    CASESCANCODE20TOKEY12(RGUI,RSUPER);
+
+    CASESCANCODE20TOKEY12(MODE,MODE);
+    #undef CASESCANCODE20TOKEY12
     default: break;
     }
 
-    FIXME("nothing maps to SDLK12_COMPOSE, SDLK12_BREAK, or SDLK12_EURO ...?");
+    FIXME("nothing maps to SDLK12_BREAK, or SDLK12_EURO ...?");
     FIXME("map some of the SDLK12_WORLD keys");
     return SDLK12_UNKNOWN;
 }
@@ -2646,7 +2696,7 @@ EventFilter20to12(void *data, SDL_Event *event20)
             if (event20->key.repeat) {
                 return 1;  /* ignore 2.0-style key repeat events */
             }
-            event12.key.keysym.sym = Keysym20to12(event20->key.keysym.sym);
+            event12.key.keysym.sym = Scancode20toKeysym12(event20->key.keysym.scancode);
 
             KeyState[event12.key.keysym.sym] = event20->key.state;
 
@@ -2668,7 +2718,7 @@ EventFilter20to12(void *data, SDL_Event *event20)
                 return 1;  /* ignore 2.0-style key repeat events */
             }
 
-            PendingKeydownEvent.key.keysym.sym = Keysym20to12(event20->key.keysym.sym);
+            PendingKeydownEvent.key.keysym.sym = Scancode20toKeysym12(event20->key.keysym.scancode);
 
             KeyState[PendingKeydownEvent.key.keysym.sym] = event20->key.state;