qulogic/libgnt

6ecab9b95a62
Parents 2bda4d16a629
Children 6ed9965a8241
cross-win32: finch: unicode input, properly escape special keys
  • +8 -1
    gntkeys.c
  • +27 -27
    gntkeys.h
  • +44 -13
    gntmain.c
  • --- a/gntkeys.c Tue Apr 22 04:28:36 2014 +0200
    +++ b/gntkeys.c Wed Apr 23 00:55:55 2014 +0200
    @@ -51,6 +51,12 @@
    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 @@
    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 @@
    }
    }
    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};
    --- a/gntkeys.h Tue Apr 22 04:28:36 2014 +0200
    +++ b/gntkeys.h Wed Apr 23 00:55:55 2014 +0200
    @@ -49,40 +49,40 @@
    #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
    --- a/gntmain.c Tue Apr 22 04:28:36 2014 +0200
    +++ b/gntmain.c Wed Apr 23 00:55:55 2014 +0200
    @@ -66,6 +66,7 @@
    #ifdef _WIN32
    #undef _getch
    #undef getch
    +#include <windows.h>
    #include <conio.h>
    #endif
    @@ -247,22 +248,34 @@
    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 @@
    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 @@
    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 @@
    if (channel)
    return;
    +#ifdef _WIN32
    + /* UTF-8 for input */
    + /* TODO: check it with NO_WIDECHAR. */
    + SetConsoleCP(65001);
    +#endif
    +
    locale = setlocale(LC_ALL, "");
    setup_io();