summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Rumney <jasonr@gnu.org>2010-01-27 21:59:13 +0800
committerJason Rumney <jasonr@gnu.org>2010-01-27 21:59:13 +0800
commit7e23373040046d7dd1cfe7dd77c78a0ac1075028 (patch)
tree7518be1d351cf1933dab3bf5366f34b35569cc87
parentc8b96b2a9548c65ad6b0f22f79b724ff2b63054a (diff)
downloademacs-7e23373040046d7dd1cfe7dd77c78a0ac1075028.tar.gz
Use Unicode for console keyboard input on Windows.
w32inevt.c (w32_kbd_patch_key): Save the unicode character. (key_event): Use unicode for characters 128 and higher.
-rw-r--r--src/ChangeLog5
-rw-r--r--src/w32inevt.c77
2 files changed, 73 insertions, 9 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index dc340eaa873..e667cd7f392 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,8 @@
+2010-01-27 Jason Rumney <jasonr@gnu.org>
+
+ * w32inevt.c (w32_kbd_patch_key): Save the unicode character.
+ (key_event): Use unicode for characters 128 and higher.
+
2010-01-27 Kenichi Handa <handa@m17n.org>
* regex.c (analyse_first): Fix setting of fastmap for unibyte
diff --git a/src/w32inevt.c b/src/w32inevt.c
index 5ba8430eb84..ebdff1357a1 100644
--- a/src/w32inevt.c
+++ b/src/w32inevt.c
@@ -81,6 +81,9 @@ extern unsigned int w32_key_to_modifier (int key);
static INPUT_RECORD event_queue[EVENT_QUEUE_SIZE];
static INPUT_RECORD *queue_ptr = event_queue, *queue_end = event_queue;
+/* Temporarily store lead byte of DBCS input sequences. */
+static char dbcs_lead = 0;
+
static int
fill_queue (BOOL block)
{
@@ -253,13 +256,15 @@ w32_kbd_patch_key (KEY_EVENT_RECORD *event)
keystate, buf, 128, 0);
if (isdead > 0)
{
- char cp[20];
- int cpId;
+ char cp[20];
+ int cpId;
- GetLocaleInfo (GetThreadLocale (),
+ event->uChar.UnicodeChar = buf[isdead - 1];
+
+ GetLocaleInfo (GetThreadLocale (),
LOCALE_IDEFAULTANSICODEPAGE, cp, 20);
- cpId = atoi (cp);
- isdead = WideCharToMultiByte (cpId, 0, buf, isdead,
+ cpId = atoi (cp);
+ isdead = WideCharToMultiByte (cpId, 0, buf, isdead,
ansi_code, 4, NULL, NULL);
}
else
@@ -425,8 +430,6 @@ key_event (KEY_EVENT_RECORD *event, struct input_event *emacs_ev, int *isdead)
if (lispy_function_keys[event->wVirtualKeyCode] == 0)
{
- emacs_ev->kind = ASCII_KEYSTROKE_EVENT;
-
if (!NILP (Vw32_recognize_altgr)
&& (event->dwControlKeyState & LEFT_CTRL_PRESSED)
&& (event->dwControlKeyState & RIGHT_ALT_PRESSED))
@@ -461,9 +464,65 @@ key_event (KEY_EVENT_RECORD *event, struct input_event *emacs_ev, int *isdead)
else if (event->uChar.AsciiChar == 0)
w32_kbd_patch_key (event);
}
+
if (event->uChar.AsciiChar == 0)
- return 0;
- emacs_ev->code = event->uChar.AsciiChar;
+ {
+ emacs_ev->kind = NO_EVENT;
+ return 0;
+ }
+ else if (event->uChar.AsciiChar < 128)
+ {
+ emacs_ev->kind = ASCII_KEYSTROKE_EVENT;
+ emacs_ev->code = event->uChar.AsciiChar;
+ }
+ else if (event->uChar.UnicodeChar > 0)
+ {
+ emacs_ev->kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT;
+ emacs_ev->code = event->uChar.UnicodeChar;
+ }
+ else
+ {
+ /* Fallback for non-Unicode versions of Windows. */
+ wchar_t code;
+ char dbcs[2];
+ char cp[20];
+ int cpId;
+
+ /* Get the codepage to interpret this key with. */
+ GetLocaleInfo (GetThreadLocale (),
+ LOCALE_IDEFAULTANSICODEPAGE, cp, 20);
+ cpId = atoi (cp);
+
+ dbcs[0] = dbcs_lead;
+ dbcs[1] = event->uChar.AsciiChar;
+ if (dbcs_lead)
+ {
+ dbcs_lead = 0;
+ if (!MultiByteToWideChar (cpId, 0, dbcs, 2, &code, 1))
+ {
+ /* Garbage */
+ DebPrint (("Invalid DBCS sequence: %d %d\n",
+ dbcs[0], dbcs[1]));
+ emacs_ev.kind = NO_EVENT;
+ }
+ }
+ else if (IsDBCSLeadByteEx (cpId, dbcs[1]))
+ {
+ dbcs_lead = dbcs[1];
+ emacs_ev.kind = NO_EVENT;
+ }
+ else
+ {
+ if (!MultiByteToWideChar (cpId, 0, &dbcs[1], 1, &code, 1))
+ {
+ /* Garbage */
+ DebPrint (("Invalid character: %d\n", dbcs[1]));
+ emacs_ev.kind = NO_EVENT;
+ }
+ }
+ emacs_ev->kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT;
+ emacs_ev->code = code;
+ }
}
else
{