/pidgin/main: 028f6001b4cd: cross-win32: finch: unicode input, p...
Tomasz Wasilczyk
twasilczyk at pidgin.im
Tue Apr 22 18:56:05 EDT 2014
Changeset: 028f6001b4cd5922462251b63d08fc70f649ba8d
Author: Tomasz Wasilczyk <twasilczyk at pidgin.im>
Date: 2014-04-23 00:55 +0200
Branch: default
URL: https://hg.pidgin.im/pidgin/main/rev/028f6001b4cd
Description:
cross-win32: finch: unicode input, properly escape special keys
diffstat:
finch/libgnt/gntkeys.c | 9 +++++++-
finch/libgnt/gntkeys.h | 54 +++++++++++++++++++++++-----------------------
finch/libgnt/gntmain.c | 57 ++++++++++++++++++++++++++++++++++++++-----------
3 files changed, 79 insertions(+), 41 deletions(-)
diffs (220 lines):
diff --git a/finch/libgnt/gntkeys.c b/finch/libgnt/gntkeys.c
--- a/finch/libgnt/gntkeys.c
+++ b/finch/libgnt/gntkeys.c
@@ -51,6 +51,12 @@ void gnt_init_keys()
term = ""; /* Just in case */
}
+#ifdef _WIN32
+ gnt_key_cup = GNT_KEY_CTRL_UP;
+ gnt_key_cdown = GNT_KEY_CTRL_DOWN;
+ gnt_key_cright = GNT_KEY_CTRL_RIGHT;
+ gnt_key_cleft = GNT_KEY_CTRL_LEFT;
+#else
if (strstr(term, "xterm") == term || strcmp(term, "rxvt") == 0) {
gnt_key_cup = "\033" "[1;5A";
gnt_key_cdown = "\033" "[1;5B";
@@ -62,6 +68,7 @@ void gnt_init_keys()
gnt_key_cright = "\033" "Oc";
gnt_key_cleft = "\033" "Od";
}
+#endif
specials = g_hash_table_new(g_str_hash, g_str_equal);
@@ -141,7 +148,7 @@ void gnt_init_keys()
}
}
c = 0;
- for (a = 0; alts[a]; a++) {
+ for (a = 0; alts[a]; a++) { /* XXX: is that loop necessary? */
/* Upper-case alphabets */
for (ch = 0; ch < 26; ch++) {
char str[2] = {'A' + ch, 0}, code[] = {'\033', 'A' + ch, 0};
diff --git a/finch/libgnt/gntkeys.h b/finch/libgnt/gntkeys.h
--- a/finch/libgnt/gntkeys.h
+++ b/finch/libgnt/gntkeys.h
@@ -49,40 +49,40 @@ extern char *gnt_key_cright;
#define GNT_KEY_POPUP "" /* not supported? */
-#define GNT_KEY_UP "\xe0\x48"
-#define GNT_KEY_DOWN "\xe0\x50"
-#define GNT_KEY_LEFT "\xe0\x4B"
-#define GNT_KEY_RIGHT "\xe0\x4D"
+#define GNT_KEY_UP "\033\xe0\x48"
+#define GNT_KEY_DOWN "\033\xe0\x50"
+#define GNT_KEY_LEFT "\033\xe0\x4B"
+#define GNT_KEY_RIGHT "\033\xe0\x4D"
-#define GNT_KEY_CTRL_UP "\xe0\x8d"
-#define GNT_KEY_CTRL_DOWN "\xe0\x91"
-#define GNT_KEY_CTRL_LEFT "\xe0\x73"
-#define GNT_KEY_CTRL_RIGHT "\xe0\x74"
+#define GNT_KEY_CTRL_UP "\033\xe0\x8d"
+#define GNT_KEY_CTRL_DOWN "\033\xe0\x91"
+#define GNT_KEY_CTRL_LEFT "\033\xe0\x73"
+#define GNT_KEY_CTRL_RIGHT "\033\xe0\x74"
-#define GNT_KEY_PGUP "\xe0\x49"
-#define GNT_KEY_PGDOWN "\xe0\x51"
-#define GNT_KEY_HOME "\xe0\x47"
-#define GNT_KEY_END "\xe0\x4f"
+#define GNT_KEY_PGUP "\033\xe0\x49"
+#define GNT_KEY_PGDOWN "\033\xe0\x51"
+#define GNT_KEY_HOME "\033\xe0\x47"
+#define GNT_KEY_END "\033\xe0\x4f"
#define GNT_KEY_ENTER "\x0d"
#define GNT_KEY_BACKSPACE "\x08"
-#define GNT_KEY_DEL "\xe0\x53"
-#define GNT_KEY_INS "\xe0\x52"
-#define GNT_KEY_BACK_TAB "\xe1\x94"
+#define GNT_KEY_DEL "\033\xe0\x53"
+#define GNT_KEY_INS "\033\xe0\x52"
+#define GNT_KEY_BACK_TAB "\033\xe1\x94"
-#define GNT_KEY_F1 "\xe1\x3b"
-#define GNT_KEY_F2 "\xe1\x3c"
-#define GNT_KEY_F3 "\xe1\x3d"
-#define GNT_KEY_F4 "\xe1\x3e"
-#define GNT_KEY_F5 "\xe1\x3f"
-#define GNT_KEY_F6 "\xe1\x40"
-#define GNT_KEY_F7 "\xe1\x41"
-#define GNT_KEY_F8 "\xe1\x42"
-#define GNT_KEY_F9 "\xe1\x43"
-#define GNT_KEY_F10 "\xe1\x44"
-#define GNT_KEY_F11 "\xe0\x85"
-#define GNT_KEY_F12 "\xe0\x86"
+#define GNT_KEY_F1 "\033\xe1\x3b"
+#define GNT_KEY_F2 "\033\xe1\x3c"
+#define GNT_KEY_F3 "\033\xe1\x3d"
+#define GNT_KEY_F4 "\033\xe1\x3e"
+#define GNT_KEY_F5 "\033\xe1\x3f"
+#define GNT_KEY_F6 "\033\xe1\x40"
+#define GNT_KEY_F7 "\033\xe1\x41"
+#define GNT_KEY_F8 "\033\xe1\x42"
+#define GNT_KEY_F9 "\033\xe1\x43"
+#define GNT_KEY_F10 "\033\xe1\x44"
+#define GNT_KEY_F11 "\033\xe0\x85"
+#define GNT_KEY_F12 "\033\xe0\x86"
#else
diff --git a/finch/libgnt/gntmain.c b/finch/libgnt/gntmain.c
--- a/finch/libgnt/gntmain.c
+++ b/finch/libgnt/gntmain.c
@@ -66,6 +66,7 @@
#ifdef _WIN32
#undef _getch
#undef getch
+#include <windows.h>
#include <conio.h>
#endif
@@ -247,22 +248,34 @@ static gboolean
io_invoke(GIOChannel *source, GIOCondition cond, gpointer null)
{
#ifdef _WIN32
+ /* We need:
+ * - 1 for escape prefix
+ * - 6 for gunichar-to-gchar conversion (see g_unichar_to_utf8)
+ * - 1 for the terminating NUL
+ * or:
+ * - 1 for escape prefix
+ * - 1 for special key prefix
+ * - 1 for the key
+ * - 1 for the terminating NUL
+ */
gchar keys[8];
gchar *k = keys;
int ch;
gboolean is_special = FALSE;
+ gboolean is_escape = FALSE;
if (wm->mode == GNT_KP_MODE_WAIT_ON_CHILD)
return FALSE;
if (HOLDING_ESCAPE) {
+ is_escape = TRUE;
*k = '\033';
k++;
g_source_remove(escape_stuff.timer);
escape_stuff.timer = 0;
}
- ch = _getch(); /* we could use _getch_nolock */
+ ch = _getwch(); /* we could use _getwch_nolock */
/* a small hack - we don't want to put NUL anywhere */
if (ch == 0x00)
@@ -270,14 +283,16 @@ io_invoke(GIOChannel *source, GIOConditi
if (ch == 0xE0 || ch == 0xE1) {
is_special = TRUE;
+ if (!is_escape) {
+ *k = '\033';
+ k++;
+ }
*k = ch;
k++;
- ch = _getch();
+ ch = _getwch();
}
- k[0] = ch;
- k[1] = '\0';
- if (ch == 0x1B && !is_special) { /* ESC */
+ if (ch == 0x1B && !is_special) { /* ESC key */
escape_stuff.timer = g_timeout_add(250, escape_timeout, NULL);
return TRUE;
}
@@ -285,16 +300,26 @@ io_invoke(GIOChannel *source, GIOConditi
if (wm)
gnt_wm_set_event_stack(wm, TRUE);
- if (!is_special) {
- gchar *converted;
- gsize converted_len = 0;
+ if (is_special) {
+ if (ch > 0xFF) {
+ gnt_warning("a special key out of gchar range (%d)", ch);
+ return TRUE;
+ }
+ *k = ch;
+ k++;
+ } else {
+ gint result_len;
- converted = g_locale_to_utf8(k, 1, NULL, &converted_len, NULL);
- if (converted_len > 0 && converted_len <= 4) {
- memcpy(k, converted, converted_len);
- k[converted_len] = '\0';
- }
+ result_len = g_unichar_to_utf8(ch, k);
+ k += result_len;
}
+ *k = '\0';
+
+#if 0
+ gnt_warning("a key: [%s] %#x %#x %#x %#x %#x %#x", keys,
+ (guchar)keys[0], (guchar)keys[1], (guchar)keys[2],
+ (guchar)keys[3], (guchar)keys[4], (guchar)keys[5]);
+#endif
/* TODO: we could call detect_mouse_action here, but no
* events are triggered (yet?) for mouse on win32.
@@ -554,6 +579,12 @@ void gnt_init()
if (channel)
return;
+#ifdef _WIN32
+ /* UTF-8 for input */
+ /* TODO: check it with NO_WIDECHAR. */
+ SetConsoleCP(65001);
+#endif
+
locale = setlocale(LC_ALL, "");
setup_io();
More information about the Commits
mailing list