OSDN Git Service

v3.0.0 Alpha5 OSDN最終版
[hengband/hengband.git] / src / main-x11.c
index 0a97dd6..1c66c9f 100644 (file)
@@ -1041,13 +1041,61 @@ struct x11_selection_type
 static x11_selection_type s_ptr[1];
 
 /*
+ * Convert to EUC-JP
+ */
+#ifdef USE_XIM
+static void convert_to_euc(char *buf)
+{
+       size_t inlen = strlen(buf);
+       size_t outlen = inlen + 1;
+       char tmp[outlen];
+
+       iconv_t iconvd = iconv_open("EUC-JP", "UTF-8");
+       char *inbuf = buf;
+       char *outbuf = tmp;
+       iconv(iconvd, &inbuf, &inlen, &outbuf, &outlen);
+       iconv_close(iconvd);
+
+       int i, l = strlen(tmp);
+       for (i = 0; i < l; i++)
+               buf[i] = tmp[i];
+       buf[l] = '\0';
+}
+#endif
+
+// ゲーム側へキーを送る
+static void send_key(const char key)
+{
+    // Windows ドライバと同様、自前でキューを操作する。
+    // 逆順に term_key_push() する方法だと長い日本語を入力したときにテキストの
+    // 順序が入れ替わってしまう。
+
+    // キーバッファが一杯なら入力を捨てる
+    const int head_nxt = Term->key_head + 1 == Term->key_size ? 0 : Term->key_head + 1;
+    if(head_nxt == Term->key_tail) {
+        plog_fmt("key buffer overflow, ignoring key 0x%02X", key);
+        return;
+    }
+
+    Term->key_queue[Term->key_head] = key;
+    Term->key_head = head_nxt;
+}
+
+// ゲーム側へキー列を送る
+static void send_keys(const char* const keys)
+{
+    for(const char* p = keys; *p != '\0'; ++p)
+        send_key(*p);
+}
+
+/*
  * Process a keypress event
  *
  * Also appears in "main-xaw.c".
  */
 static void react_keypress(XKeyEvent *xev)
 {
-       int i, n, mc, ms, mo, mx;
+       int n, mc, ms, mo, mx;
        uint ks1;
        XKeyEvent *ev = (XKeyEvent*)(xev);
        KeySym ks;
@@ -1079,9 +1127,9 @@ static void react_keypress(XKeyEvent *xev)
        buf[n] = '\0';
 
 #ifdef USE_XIM
-       if(!valid_keysym){
-               for (i = 0; buf[i]; i++) term_key_push(buf[i]);
-
+       if(!valid_keysym) { /* XIMからの入力時のみ FALSE になる */
+               convert_to_euc(buf);
+               send_keys(buf);
                return;
        }
 #endif
@@ -1095,8 +1143,7 @@ static void react_keypress(XKeyEvent *xev)
        mx = (ev->state & Mod2Mask) ? TRUE : FALSE;
        if (n && !mo && !mx && !IsSpecialKey(ks))
        {
-               for (i = 0; buf[i]; i++) term_key_push(buf[i]);
-
+               send_keys(buf);
                return;
        }
 
@@ -1104,30 +1151,30 @@ static void react_keypress(XKeyEvent *xev)
        {
                case XK_Escape:
                {
-                       term_key_push(ESCAPE);
+                       send_key(ESCAPE);
                        return;
                }
 
                case XK_Return:
                {
-                       term_key_push('\r');
+                       send_key('\r');
                        return;
                }
 
                case XK_Tab:
                {
-                       term_key_push('\t');
+                       send_key('\t');
                        return;
                }
 
                case XK_Delete:
                {
-                       term_key_push(0x7f);
+                       send_key(0x7f);
                        return;
                }
                case XK_BackSpace:
                {
-                       term_key_push('\010');
+                       send_key('\010');
                        return;
                }
        }
@@ -1147,7 +1194,7 @@ static void react_keypress(XKeyEvent *xev)
                        ev->keycode, 13);
        }
 
-       for (i = 0; msg[i]; i++) term_key_push(msg[i]);
+       send_keys(msg);
 
        if (n && (macro_find_exact(msg) < 0))
        {
@@ -2561,8 +2608,8 @@ errr init_x11(int argc, char *argv[])
                        use_graphics = TRUE;
                        pict_wid = pict_hgt = 8;
                        ANGBAND_GRAF = "old";
-                       break;
                }
+               break;
        case GRAPHICS_ADAM_BOLT:
                path_build(filename, sizeof(filename), ANGBAND_DIR_XTRA, "graf/16x16.bmp");
                if (0 == fd_close(fd_open(filename, O_RDONLY)))
@@ -2570,8 +2617,8 @@ errr init_x11(int argc, char *argv[])
                        use_graphics = TRUE;
                        pict_wid = pict_hgt = 16;
                        ANGBAND_GRAF = "new";
-                       break;
                }
+               break;
        }
 
        if (use_graphics)