changeset 107015:0b67a7f89499

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.
author Jason Rumney <jasonr@gnu.org>
date Wed, 27 Jan 2010 21:59:13 +0800
parents 3baccc6f1381
children b7aa72d41625
files src/ChangeLog src/w32inevt.c
diffstat 2 files changed, 73 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Wed Jan 27 21:15:40 2010 +0800
+++ b/src/ChangeLog	Wed Jan 27 21:59:13 2010 +0800
@@ -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
--- a/src/w32inevt.c	Wed Jan 27 21:15:40 2010 +0800
+++ b/src/w32inevt.c	Wed Jan 27 21:59:13 2010 +0800
@@ -81,6 +81,9 @@
 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 @@
 			  keystate, buf, 128, 0);
       if (isdead > 0)
 	{
-          char cp[20];
-          int cpId;
+	  char cp[20];
+	  int cpId;
+
+	  event->uChar.UnicodeChar = buf[isdead - 1];
 
-          GetLocaleInfo (GetThreadLocale (),
+	  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 @@
 
   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 @@
 	  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
     {