]> git.rm.cloudns.org Git - xonotic/darkplaces.git/commitdiff
Fixed two keyboard bugs:
authorNaitLee <naitli@foxmail.com>
Sun, 29 Jan 2023 14:09:37 +0000 (22:09 +0800)
committerNaitLee <naitli@foxmail.com>
Sun, 29 Jan 2023 14:09:37 +0000 (22:09 +0800)
Fixed inability to bind non-ascii keys;
Fixed only the first character being input when using an Input Method

Signed-off-by: NaitLee <naitli@foxmail.com>
keys.c
keys.h
menu.c
prvm_cmds.c
vid_sdl.c

diff --git a/keys.c b/keys.c
index bcf1c916f0826eed2f9f61748a5876392886bd37..1d320ec7c14ea866d9e499701e23ccfbfeb9ba86 100644 (file)
--- a/keys.c
+++ b/keys.c
@@ -1351,6 +1351,7 @@ the K_* names are matched up.
 int
 Key_StringToKeynum (const char *str)
 {
+       Uchar ch;
        const keyname_t  *kn;
 
        if (!str || !str[0])
@@ -1362,7 +1363,10 @@ Key_StringToKeynum (const char *str)
                if (!strcasecmp (str, kn->name))
                        return kn->keynum;
        }
-       return -1;
+
+       // non-ascii keys are Unicode codepoints, so give the character
+       ch = u8_getnchar(str, &str, 3);
+       return ch == 0 ? -1 : (int)ch;
 }
 
 /*
@@ -1387,13 +1391,9 @@ Key_KeynumToString (int keynum, char *tinystr, size_t tinystrlength)
                        return kn->name;
 
        // if it is printable, output it as a single character
-       if (keynum > 32 && keynum < 256)
+       if (keynum > 32)
        {
-               if (tinystrlength >= 2)
-               {
-                       tinystr[0] = keynum;
-                       tinystr[1] = 0;
-               }
+               u8_fromchar(keynum, tinystr, tinystrlength);
                return tinystr;
        }
 
@@ -1586,7 +1586,7 @@ static void
 Key_PrintBindList(int j)
 {
        char bindbuf[MAX_INPUTLINE];
-       char tinystr[2];
+       char tinystr[TINYSTR_LEN];
        const char *p;
        int i;
 
@@ -1679,7 +1679,7 @@ Key_WriteBindings (qfile_t *f)
 {
        int         i, j;
        char bindbuf[MAX_INPUTLINE];
-       char tinystr[2];
+       char tinystr[TINYSTR_LEN];
        const char *p;
 
        // Override default binds
diff --git a/keys.h b/keys.h
index 57ec1702c909bf8cf1cbf50a61cb0c0436b3ee44..26c711d0838e17dfa9699afd391a2f59e4710aee 100644 (file)
--- a/keys.h
+++ b/keys.h
 #include "fs.h"
 #include "cmd.h"
 
+// the highest Unicode character to allow key binding.
+// note that an excessively high value may degrade fps
+// when code is looping through the bindings
+#define MAX_KEY_BINDS 0xfff0
+
+// how long is a "tinystr" to hold a keyboard key's
+// Unicode utf-8 presentation, plus final \x00
+// to allow all characters <= 0xffff, use 4
+#define TINYSTR_LEN 4
+
 //
 // these are the key numbers that should be passed to Key_Event
 //
@@ -353,7 +363,7 @@ typedef enum keynum_e
        K_MIDINOTE126,
        K_MIDINOTE127,
 
-       MAX_KEYS
+       MAX_KEYS = MAX_KEY_BINDS
 }
 keynum_t;
 
diff --git a/menu.c b/menu.c
index ce154097118e91e32c8aef969f53f0c789caa89a..990d6db3e0e1c708b97d3527da7cb11f1267ffc8 100644 (file)
--- a/menu.c
+++ b/menu.c
@@ -2643,7 +2643,7 @@ static void M_Keys_Draw (void)
                        strlcpy(keystring, "???", sizeof(keystring));
                else
                {
-                       char tinystr[2];
+                       char tinystr[TINYSTR_LEN];
                        keystring[0] = 0;
                        for (j = 0;j < NUMKEYS;j++)
                        {
@@ -2669,7 +2669,7 @@ static void M_Keys_Key(cmd_state_t *cmd, int k, int ascii)
 {
        char    line[80];
        int             keys[NUMKEYS];
-       char    tinystr[2];
+       char    tinystr[TINYSTR_LEN];
 
        if (bind_grab)
        {       // defining a key
index 3ef0b74cf939fc417757249a4e328f1a5d0dcfb8..1cf7e852b6f98b2743fe6e6c8bf11c9494d9595f 100644 (file)
@@ -3268,7 +3268,7 @@ string keynumtostring(float keynum)
 */
 void VM_keynumtostring (prvm_prog_t *prog)
 {
-       char tinystr[2];
+       char tinystr[TINYSTR_LEN];
        VM_SAFEPARMCOUNT(1, VM_keynumtostring);
 
        PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, Key_KeynumToString((int)PRVM_G_FLOAT(OFS_PARM0), tinystr, sizeof(tinystr)));
index 5845e07356c1a3342641b5ccef32be31d4cb86d2..528882a895daeb8f971e4c33320d2684ab516a24 100644 (file)
--- a/vid_sdl.c
+++ b/vid_sdl.c
@@ -100,7 +100,8 @@ static int MapKey( unsigned int sdlkey )
 {
        switch(sdlkey)
        {
-       default: return 0;
+       // sdlkey can be Unicode codepoint for non-ascii keys, which are valid
+       default:                      return sdlkey;
 //     case SDLK_UNKNOWN:            return K_UNKNOWN;
        case SDLK_RETURN:             return K_ENTER;
        case SDLK_ESCAPE:             return K_ESCAPE;
@@ -1066,6 +1067,7 @@ void Sys_SendKeyEvents( void )
        static qbool sound_active = true;
        int keycode;
        int i;
+       const char *chp;
        qbool isdown;
        Uchar unicode;
        SDL_Event event;
@@ -1222,9 +1224,14 @@ void Sys_SendKeyEvents( void )
 #endif
                                // convert utf8 string to char
                                // NOTE: this code is supposed to run even if utf8enable is 0
-                               unicode = u8_getchar_utf8_enabled(event.text.text + (int)u8_bytelen(event.text.text, 0), NULL);
-                               Key_Event(K_TEXT, unicode, true);
-                               Key_Event(K_TEXT, unicode, false);
+                               chp = event.text.text;
+                               while (*chp != 0)
+                               {
+                                       // input the chars one by one (there can be multiple chars when e.g. using an "input method")
+                                       unicode = u8_getchar_utf8_enabled(chp, &chp);
+                                       Key_Event(K_TEXT, unicode, true);
+                                       Key_Event(K_TEXT, unicode, false);
+                               }
                                break;
                        case SDL_MOUSEMOTION:
                                break;