tSupport Unicode in text input - vaccinewars - be a doctor and try to vaccinate… | |
git clone git://src.adamsgaard.dk/vaccinewars | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit 594e648055b50a8e1bda0b1401e16502fb48d14c | |
parent a1765422bbab17983838549b5ef7e909e3fd3247 | |
Author: Ben Webb <[email protected]> | |
Date: Sun, 3 Jan 2021 21:57:57 -0800 | |
Support Unicode in text input | |
When in a UTF-8 locale, allow Unicode characters | |
tto be input to prompts (e.g. for the user's name). | |
Closes #60. | |
Diffstat: | |
M ChangeLog.md | 5 +++++ | |
M src/curses_client/curses_client.c | 58 ++++++++++++++++++++++-------… | |
2 files changed, 47 insertions(+), 16 deletions(-) | |
--- | |
diff --git a/ChangeLog.md b/ChangeLog.md | |
t@@ -1,3 +1,8 @@ | |
+# HEAD | |
+- The text-mode client should now support Unicode input when in UTF-8 | |
+ locales, e.g. allowing player names containing accented characters | |
+ to be input (#60). | |
+ | |
# 1.6.1 - 2020-12-11 | |
- Improved display in non-English text-mode clients; previously | |
columns were not aligned properly in some cases and occasionally | |
diff --git a/src/curses_client/curses_client.c b/src/curses_client/curses_clien… | |
t@@ -2272,7 +2272,8 @@ Player *ListPlayers(Player *Play, gboolean Select, char … | |
char *nice_input(char *prompt, int sy, int sx, gboolean digitsonly, | |
char *displaystr, char passwdchar) | |
{ | |
- int i, c, x; | |
+ int ibyte, ichar, x; | |
+ gunichar c; | |
gboolean DecimalPoint, Suffix; | |
GString *text; | |
gchar *ReturnString; | |
t@@ -2289,47 +2290,72 @@ char *nice_input(char *prompt, int sy, int sx, gboolea… | |
attrset(TextAttr); | |
if (displaystr) { | |
if (passwdchar) { | |
- for (i = strlen(displaystr); i; i--) | |
+ int i; | |
+ for (i = strcharlen(displaystr); i; i--) | |
addch((guint)passwdchar); | |
} else { | |
addstr(displaystr); | |
} | |
- i = strlen(displaystr); | |
+ ibyte = strlen(displaystr); | |
+ ichar = strcharlen(displaystr); | |
text = g_string_new(displaystr); | |
} else { | |
- i = 0; | |
+ ibyte = ichar = 0; | |
text = g_string_new(""); | |
} | |
curs_set(1); | |
do { | |
- move(sy + (x + i) / Width, (x + i) % Width); | |
+ move(sy + (x + ichar) / Width, (x + ichar) % Width); | |
c = bgetch(); | |
- if ((c == 8 || c == KEY_BACKSPACE || c == 127) && i > 0) { | |
- move(sy + (x + i - 1) / Width, (x + i - 1) % Width); | |
+ if ((c == 8 || c == KEY_BACKSPACE || c == 127) && ichar > 0) { | |
+ move(sy + (x + ichar - 1) / Width, (x + ichar - 1) % Width); | |
addch(' '); | |
- i--; | |
- if (DecimalPoint && text->str[i] == '.') | |
+ ichar--; | |
+ if (LocaleIsUTF8) { | |
+ char *p = g_utf8_find_prev_char(text->str, text->str+ibyte); | |
+ assert(p); | |
+ ibyte = p - text->str; | |
+ } else { | |
+ ibyte--; | |
+ } | |
+ if (DecimalPoint && text->str[ibyte] == '.') | |
DecimalPoint = FALSE; | |
if (Suffix) | |
Suffix = FALSE; | |
- g_string_truncate(text, i); | |
+ g_string_truncate(text, ibyte); | |
} else if (!Suffix) { | |
if ((digitsonly && c >= '0' && c <= '9') || | |
- (!digitsonly && c >= 32 && c != '^' && c < 127)) { | |
- g_string_append_c(text, c); | |
- i++; | |
- addch((guint)passwdchar ? passwdchar : c); | |
+ (!digitsonly && c >= 32 && c != '^' && c != 127)) { | |
+ if (LocaleIsUTF8) { | |
+ char utf8buf[20]; | |
+ gint utf8len = g_unichar_to_utf8(c, utf8buf); | |
+ utf8buf[utf8len] = '\0'; | |
+ ibyte += utf8len; | |
+ g_string_append(text, utf8buf); | |
+ if (passwdchar) { | |
+ addch((guint)passwdchar); | |
+ } else { | |
+ addstr(utf8buf); | |
+ } | |
+ } else { | |
+ g_string_append_c(text, c); | |
+ ibyte++; | |
+ addch((guint)passwdchar ? passwdchar : c); | |
+ } | |
+ ichar++; | |
} else if (digitsonly && (c == '.' || c == ',') && !DecimalPoint) { | |
g_string_append_c(text, '.'); | |
- i++; | |
+ ibyte++; | |
+ ichar++; | |
addch((guint)passwdchar ? passwdchar : c); | |
DecimalPoint = TRUE; | |
} else if (digitsonly | |
&& (c == 'M' || c == 'm' || c == 'k' || c == 'K') | |
&& !Suffix) { | |
g_string_append_c(text, c); | |
- i++; | |
+ ibyte++; | |
+ ichar++; | |
addch((guint)passwdchar ? passwdchar : c); | |
Suffix = TRUE; | |
} |