shithub: choc

Download patch

ref: d3cb02d8105b78408e22a115c1abe80a2743d0f5
parent: 4e3ab57537d4d6ec11af3787ff963b9d000b90a6
author: Simon Howard <fraggle@soulsphere.org>
date: Sat Dec 17 20:41:21 EST 2016

textscreen: Use SDL API for getting key names.

SDL2 has an API for getting a string description of a key. Change the
textscreen API which does the same to use it. This has the added bonus
that the setup tool will now adjust to show key descriptions that match
the system keyboard layout.

--- a/textscreen/txt_main.h
+++ b/textscreen/txt_main.h
@@ -139,8 +139,11 @@
 // Read the current state of modifier keys that are held down.
 int TXT_GetModifierState(txt_modifier_t mod);
 
-// Provides a short description of a key code, placing into the 
-// provided buffer.
+// Provides a short description of a key code, placing into the provided
+// buffer. Note that the key is assumed to represent a physical key on the
+// keyboard (like that returned by TXT_INPUT_RAW), and the resulting string
+// takes keyboard layout into consideration. For example,
+// TXT_GetKeyDescription('q') on a French keyboard returns "A".
 void TXT_GetKeyDescription(int key, char *buf, size_t buf_len);
 
 // Retrieve the current position of the mouse
--- a/textscreen/txt_sdl.c
+++ b/textscreen/txt_sdl.c
@@ -712,84 +712,64 @@
     }
 }
 
-static const char *SpecialKeyName(int key)
+static const char *NameForKey(int key)
 {
+    int i;
+
     switch (key)
     {
-        case ' ':             return "SPACE";
-        case KEY_RIGHTARROW:  return "RIGHT";
-        case KEY_LEFTARROW:   return "LEFT";
-        case KEY_UPARROW:     return "UP";
-        case KEY_DOWNARROW:   return "DOWN";
-        case KEY_ESCAPE:      return "ESC";
-        case KEY_ENTER:       return "ENTER";
-        case KEY_TAB:         return "TAB";
-        case KEY_F1:          return "F1";
-        case KEY_F2:          return "F2";
-        case KEY_F3:          return "F3";
-        case KEY_F4:          return "F4";
-        case KEY_F5:          return "F5";
-        case KEY_F6:          return "F6";
-        case KEY_F7:          return "F7";
-        case KEY_F8:          return "F8";
-        case KEY_F9:          return "F9";
-        case KEY_F10:         return "F10";
-        case KEY_F11:         return "F11";
-        case KEY_F12:         return "F12";
-        case KEY_BACKSPACE:   return "BKSP";
-        case KEY_PAUSE:       return "PAUSE";
-        case KEY_EQUALS:      return "EQUALS";
-        case KEY_MINUS:       return "MINUS";
+        // A few keys which are not in the scancodes table:
         case KEY_RSHIFT:      return "SHIFT";
         case KEY_RCTRL:       return "CTRL";
         case KEY_RALT:        return "ALT";
+
+        // Keys where we want to use specific strings to look more
+        // like setup.exe:
         case KEY_CAPSLOCK:    return "CAPS";
+        case KEY_BACKSPACE:   return "BKSP";
+        case KEY_ESCAPE:      return "ESC";
+        case KEY_ENTER:       return "ENTER";
         case KEY_SCRLCK:      return "SCRLCK";
-        case KEY_HOME:        return "HOME";
-        case KEY_END:         return "END";
         case KEY_PGUP:        return "PGUP";
         case KEY_PGDN:        return "PGDN";
         case KEY_INS:         return "INS";
         case KEY_DEL:         return "DEL";
         case KEY_PRTSCR:      return "PRTSC";
-                 /*
-        case KEYP_0:          return "PAD0";
-        case KEYP_1:          return "PAD1";
-        case KEYP_2:          return "PAD2";
-        case KEYP_3:          return "PAD3";
-        case KEYP_4:          return "PAD4";
-        case KEYP_5:          return "PAD5";
-        case KEYP_6:          return "PAD6";
-        case KEYP_7:          return "PAD7";
-        case KEYP_8:          return "PAD8";
-        case KEYP_9:          return "PAD9";
-        case KEYP_UPARROW:    return "PAD_U";
-        case KEYP_DOWNARROW:  return "PAD_D";
-        case KEYP_LEFTARROW:  return "PAD_L";
-        case KEYP_RIGHTARROW: return "PAD_R";
-        case KEYP_MULTIPLY:   return "PAD*";
-        case KEYP_PLUS:       return "PAD+";
-        case KEYP_MINUS:      return "PAD-";
-        case KEYP_DIVIDE:     return "PAD/";
-                   */
 
-        default:              return NULL;
+        default:
+            break;
     }
+
+    // This key presumably maps to a scan code that is listed in the
+    // translation table. Find which mapping and once we have a scancode,
+    // we can convert it into a virtual key, then a string via SDL.
+    for (i = 0; i < arrlen(scancode_translate_table); ++i)
+    {
+        if (scancode_translate_table[i] == key)
+        {
+            return SDL_GetKeyName(SDL_GetKeyFromScancode(i));
+        }
+    }
+
+    return NULL;
 }
 
 void TXT_GetKeyDescription(int key, char *buf, size_t buf_len)
 {
     const char *keyname;
+    int i;
 
-    keyname = SpecialKeyName(key);
+    keyname = NameForKey(key);
 
     if (keyname != NULL)
     {
         TXT_StringCopy(buf, keyname, buf_len);
-    }
-    else if (isprint(key))
-    {
-        TXT_snprintf(buf, buf_len, "%c", toupper(key));
+
+        // Key description should be all-uppercase to match setup.exe.
+        for (i = 0; buf[i] != '\0'; ++i)
+        {
+            buf[i] = toupper(buf[i]);
+        }
     }
     else
     {