tMake GetKey Unicode aware - vaccinewars - be a doctor and try to vaccinate the world
 (HTM) git clone git://src.adamsgaard.dk/vaccinewars
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit e130417a91a7f36a252fab10e0bcb6a5d784d482
 (DIR) parent d3f6073683e5ce50eb65de0e232374232d5a8fe2
 (HTM) Author: Ben Webb <ben@salilab.org>
       Date:   Sun,  3 Jan 2021 10:58:34 -0800
       
       Make GetKey Unicode aware
       
       Allow Unicode (UTF8) keys whenever a question
       is asked of the user (this is not yet fully
       functional since bgetch() returns ASCII).
       
       Diffstat:
         M src/curses_client/curses_client.c   |      57 +++++++++++++++++++++++++------
       
       1 file changed, 46 insertions(+), 11 deletions(-)
       ---
 (DIR) diff --git a/src/curses_client/curses_client.c b/src/curses_client/curses_client.c
       t@@ -32,6 +32,7 @@
        #endif
        #include <ctype.h>
        #include <signal.h>
       +#include <assert.h>
        #include <errno.h>
        #include <glib.h>
        #include "configfile.h"
       t@@ -1589,6 +1590,22 @@ void Bank(Player *Play)
          } while (action != 'L' && money != 0);
        }
        
       +/* Output a single Unicode character */
       +static void addunich(gunichar ch, int attr)
       +{
       +  if (LocaleIsUTF8) {
       +    char utf8buf[20];
       +    gint utf8len = g_unichar_to_utf8(ch, utf8buf);
       +    utf8buf[utf8len] = '\0';
       +    attrset(attr);
       +    addstr(utf8buf);
       +  } else {
       +    addch((guchar)ch | attr);
       +  }
       +}
       +
       +#define MAX_GET_KEY 30
       +
        /* 
         * Waits for keyboard input; will only accept a key listed in the
         * translated form of the "orig_allowed" string.
       t@@ -1603,8 +1620,9 @@ void Bank(Player *Play)
        int GetKey(const char *orig_allowed, gboolean AllowOther,
                   gboolean PrintAllowed, gboolean ExpandOut)
        {
       -  int ch;
       +  int ch, i, num_allowed;
          guint AllowInd, WordInd;
       +  gunichar allowed[MAX_GET_KEY];
        
          /* Expansions of the single-letter keypresses for the benefit of the
             user. i.e. "Yes" is printed for the key "Y" etc. You should indicate
       t@@ -1619,17 +1637,33 @@ int GetKey(const char *orig_allowed, gboolean AllowOther,
          /* Translate allowed keys
           * Note that allowed is in the locale encoding, usually UTF-8, while
           * orig_allowed is plain ASCII */
       -  char *allowed = _(orig_allowed);
       +  char *allowed_str = _(orig_allowed);
        
       -  curs_set(1);
       -  ch = '\0';
       +  num_allowed = strlen(orig_allowed);
       +  assert(num_allowed <= MAX_GET_KEY);
       +  assert(strcharlen(allowed_str) == num_allowed);
        
       -  if (!allowed || strlen(allowed) == 0)
       +  if (num_allowed == 0)
            return 0;
        
       +  /* Get Unicode allowed keys */
       +  if (LocaleIsUTF8) {
       +    const char *pt;
       +    for (pt = allowed_str, i = 0; pt && *pt; pt = g_utf8_next_char(pt), ++i) {
       +      allowed[i] = g_utf8_get_char(pt);
       +    }
       +  } else {
       +    for (i = 0; i < num_allowed; ++i) {
       +      allowed[i] = (guchar)allowed_str[i];
       +    }
       +  }
       +
       +  curs_set(1);
       +  ch = '\0';
       +
          if (PrintAllowed) {
            addch('[' | TextAttr);
       -    for (AllowInd = 0; AllowInd < strlen(allowed); AllowInd++) {
       +    for (AllowInd = 0; AllowInd < num_allowed; AllowInd++) {
              if (AllowInd > 0)
                addch('/' | TextAttr);
              WordInd = 0;
       t@@ -1643,8 +1677,9 @@ int GetKey(const char *orig_allowed, gboolean AllowOther,
                if (*trWord) trWord++;
                attrset(TextAttr);
                addstr(trWord);
       -      } else
       -        addch((guchar)allowed[AllowInd] | TextAttr);
       +      } else {
       +        addunich(allowed[AllowInd], TextAttr);
       +      }
            }
            addch(']' | TextAttr);
            addch(' ' | TextAttr);
       t@@ -1652,7 +1687,7 @@ int GetKey(const char *orig_allowed, gboolean AllowOther,
        
          do {
            ch = bgetch();
       -    ch = toupper(ch);
       +    ch = LocaleIsUTF8 ? g_unichar_toupper(ch) : toupper(ch);
            /* Handle scrolling of message window */
            if (ch == '-') {
              scroll_msg_area_up();
       t@@ -1661,9 +1696,9 @@ int GetKey(const char *orig_allowed, gboolean AllowOther,
              scroll_msg_area_down();
              continue;
            }
       -    for (AllowInd = 0; AllowInd < strlen(allowed); AllowInd++) {
       +    for (AllowInd = 0; AllowInd < num_allowed; AllowInd++) {
              if (allowed[AllowInd] == ch) {
       -        addch((guint)ch | TextAttr);
       +        addunich(allowed[AllowInd], TextAttr);
                curs_set(0);
                return orig_allowed[AllowInd];
              }