sdl12-compat: Merge pull request #97 from sulix/scancodeseverywhere

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 1/3] 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;
 

From acd719c5aade255fc1dd4428ae39a9f1cf6de76c Mon Sep 17 00:00:00 2001
From: David Gow <david@ingeniumdigital.com>
Date: Thu, 10 Jun 2021 17:23:01 +0800
Subject: [PATCH 2/3] The Command key should be exposed as META on macOS

SDL 1.2 uses {L,R}META for the Command key on macOS. It uses {L,R}SUPER
for the windows logo key on Windows/Linux. SDL 2.0 maps both of these to
{L,R}GUI. Just select between them at compile time.
---
 src/SDL12_compat.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c
index c05a60e..d795ae1 100644
--- a/src/SDL12_compat.c
+++ b/src/SDL12_compat.c
@@ -2414,11 +2414,19 @@ Scancode20toKeysym12(const SDL_Scancode scancode20)
     CASESCANCODE20TOKEY12(LCTRL,LCTRL);
     CASESCANCODE20TOKEY12(LSHIFT,LSHIFT);
     CASESCANCODE20TOKEY12(LALT,LALT);
+#ifdef __MACOSX__
+    CASESCANCODE20TOKEY12(LGUI,LMETA);
+#else
     CASESCANCODE20TOKEY12(LGUI,LSUPER);
+#endif
     CASESCANCODE20TOKEY12(RCTRL,RCTRL);
     CASESCANCODE20TOKEY12(RSHIFT,RSHIFT);
     CASESCANCODE20TOKEY12(RALT,RALT);
+#ifdef __MACOSX__
+    CASESCANCODE20TOKEY12(RGUI,RMETA);
+#else
     CASESCANCODE20TOKEY12(RGUI,RSUPER);
+#endif
 
     CASESCANCODE20TOKEY12(MODE,MODE);
     #undef CASESCANCODE20TOKEY12

From 0ee69695fd453993de86627b8a9c29f0976390e0 Mon Sep 17 00:00:00 2001
From: David Gow <david@ingeniumdigital.com>
Date: Thu, 10 Jun 2021 17:27:17 +0800
Subject: [PATCH 3/3] The APPLICATION key should actually map to MENU.

This is described in the SDL 2.0 docs as being either a compose key
(notably an actual, hardware compose key like the type seen on old Sun
keyboards) or the windows contextual menu. On my Linux/X11 machine with
a Microsoft USB keyboard, this is the scancode the contextual menu uses.
(What, if anything, ever produces the MENU scancode is a mystery for
another day, I guess...)
---
 src/SDL12_compat.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c
index d795ae1..6ff5000 100644
--- a/src/SDL12_compat.c
+++ b/src/SDL12_compat.c
@@ -2396,8 +2396,8 @@ Scancode20toKeysym12(const SDL_Scancode scancode20)
     CASESCANCODE20TOKEY12(KP_0,KP0);
 
     CASESCANCODE20TOKEY12(NONUSBACKSLASH,BACKSLASH);
-    /* The description of this could be MENU, or COMPOSE, or neither. */
-    CASESCANCODE20TOKEY12(APPLICATION,COMPOSE);
+    /* In theory, this could be MENU, or COMPOSE, or neither, but on my machine, it's MENU. */
+    CASESCANCODE20TOKEY12(APPLICATION,MENU);
     CASESCANCODE20TOKEY12(POWER,POWER);
     CASESCANCODE20TOKEY12(F13,F13);
     CASESCANCODE20TOKEY12(F14,F14);