aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii2012-07-28 19:57:57 +0300
committerEli Zaretskii2012-07-28 19:57:57 +0300
commit01bd1b0df605d644ae31e8f1f81d926a5d8c7099 (patch)
tree4831ac9d45815c50fe276079dd5edb7cb8e63ef8 /src
parenta5c66610be0d94045c417dde54f8ffadd26977b5 (diff)
downloademacs-01bd1b0df605d644ae31e8f1f81d926a5d8c7099.tar.gz
emacs-01bd1b0df605d644ae31e8f1f81d926a5d8c7099.zip
Fix non-ASCII input in non-GUI frames on MS-Windows. (Bug#12055)
src/w32inevt.c: Include w32inevt.h. (w32_read_console_input): New inline function, calls either ReadConsoleInputA or ReadConsoleInputW, depending on the value of w32_console_unicode_input. (fill_queue): Call w32_read_console_input instead of ReadConsoleInput. (w32_kbd_patch_key, key_event): Use the codepage returned by GetConsoleCP, rather than the ANSI codepage returned by GetLocaleInfo. (key_event): use uChar.UnicodeChar only if w32_console_unicode_input is non-zero. src/w32console.c: Include w32heap.h. <w32_console_unicode_input>: New global variable. (initialize_w32_display): Set w32_console_unicode_input to 1 on NT family of Windows, zero otherwise. src/w32inevt.h: Declare w32_console_unicode_input. lisp/international/mule-cmds.el (set-locale-environment): In a console session on MS-Windows, set up keyboard and terminal encoding from the OEM codepage, not the ANSI codepage.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog18
-rw-r--r--src/w32console.c7
-rw-r--r--src/w32inevt.c46
-rw-r--r--src/w32inevt.h2
4 files changed, 57 insertions, 16 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 8d0e7caf4ea..6457fc2209b 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,23 @@
12012-07-28 Eli Zaretskii <eliz@gnu.org> 12012-07-28 Eli Zaretskii <eliz@gnu.org>
2 2
3 Fix non-ASCII input in non-GUI frames on MS-Windows. (Bug#12055)
4 * w32inevt.c: Include w32inevt.h.
5 (w32_read_console_input): New inline function, calls either
6 ReadConsoleInputA or ReadConsoleInputW, depending on the value of
7 w32_console_unicode_input.
8 (fill_queue): Call w32_read_console_input instead of ReadConsoleInput.
9 (w32_kbd_patch_key, key_event): Use the codepage returned by
10 GetConsoleCP, rather than the ANSI codepage returned by GetLocaleInfo.
11 (key_event): use uChar.UnicodeChar only if
12 w32_console_unicode_input is non-zero.
13
14 * w32console.c: Include w32heap.h.
15 <w32_console_unicode_input>: New global variable.
16 (initialize_w32_display): Set w32_console_unicode_input to 1 on NT
17 family of Windows, zero otherwise.
18
19 * w32inevt.h: Declare w32_console_unicode_input.
20
3 * xdisp.c (init_iterator): Don't reference tip_frame in a build 21 * xdisp.c (init_iterator): Don't reference tip_frame in a build
4 --without-x. (Bug#11742) 22 --without-x. (Bug#11742)
5 23
diff --git a/src/w32console.c b/src/w32console.c
index 42d89cca6d7..c3a1c5d86b3 100644
--- a/src/w32console.c
+++ b/src/w32console.c
@@ -37,6 +37,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
37#include "termhooks.h" 37#include "termhooks.h"
38#include "termchar.h" 38#include "termchar.h"
39#include "dispextern.h" 39#include "dispextern.h"
40#include "w32heap.h" /* for os_subtype */
40#include "w32inevt.h" 41#include "w32inevt.h"
41 42
42/* from window.c */ 43/* from window.c */
@@ -67,6 +68,7 @@ static CONSOLE_CURSOR_INFO prev_console_cursor;
67#endif 68#endif
68 69
69HANDLE keyboard_handle; 70HANDLE keyboard_handle;
71int w32_console_unicode_input;
70 72
71 73
72/* Setting this as the ctrl handler prevents emacs from being killed when 74/* Setting this as the ctrl handler prevents emacs from being killed when
@@ -786,6 +788,11 @@ initialize_w32_display (struct terminal *term)
786 info.srWindow.Left); 788 info.srWindow.Left);
787 } 789 }
788 790
791 if (os_subtype == OS_NT)
792 w32_console_unicode_input = 1;
793 else
794 w32_console_unicode_input = 0;
795
789 /* Setup w32_display_info structure for this frame. */ 796 /* Setup w32_display_info structure for this frame. */
790 797
791 w32_initialize_display_info (build_string ("Console")); 798 w32_initialize_display_info (build_string ("Console"));
diff --git a/src/w32inevt.c b/src/w32inevt.c
index a85fdbbe435..8d041194ca1 100644
--- a/src/w32inevt.c
+++ b/src/w32inevt.c
@@ -41,6 +41,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
41#include "termchar.h" 41#include "termchar.h"
42#include "w32heap.h" 42#include "w32heap.h"
43#include "w32term.h" 43#include "w32term.h"
44#include "w32inevt.h"
44 45
45/* stdin, from w32console.c */ 46/* stdin, from w32console.c */
46extern HANDLE keyboard_handle; 47extern HANDLE keyboard_handle;
@@ -61,6 +62,15 @@ static INPUT_RECORD *queue_ptr = event_queue, *queue_end = event_queue;
61/* Temporarily store lead byte of DBCS input sequences. */ 62/* Temporarily store lead byte of DBCS input sequences. */
62static char dbcs_lead = 0; 63static char dbcs_lead = 0;
63 64
65static inline BOOL
66w32_read_console_input (HANDLE h, INPUT_RECORD *rec, DWORD recsize,
67 DWORD *waiting)
68{
69 return (w32_console_unicode_input
70 ? ReadConsoleInputW (h, rec, recsize, waiting)
71 : ReadConsoleInputA (h, rec, recsize, waiting));
72}
73
64static int 74static int
65fill_queue (BOOL block) 75fill_queue (BOOL block)
66{ 76{
@@ -80,8 +90,8 @@ fill_queue (BOOL block)
80 return 0; 90 return 0;
81 } 91 }
82 92
83 rc = ReadConsoleInput (keyboard_handle, event_queue, EVENT_QUEUE_SIZE, 93 rc = w32_read_console_input (keyboard_handle, event_queue, EVENT_QUEUE_SIZE,
84 &events_waiting); 94 &events_waiting);
85 if (!rc) 95 if (!rc)
86 return -1; 96 return -1;
87 queue_ptr = event_queue; 97 queue_ptr = event_queue;
@@ -224,7 +234,7 @@ w32_kbd_patch_key (KEY_EVENT_RECORD *event)
224#endif 234#endif
225 235
226 /* On NT, call ToUnicode instead and then convert to the current 236 /* On NT, call ToUnicode instead and then convert to the current
227 locale's default codepage. */ 237 console input codepage. */
228 if (os_subtype == OS_NT) 238 if (os_subtype == OS_NT)
229 { 239 {
230 WCHAR buf[128]; 240 WCHAR buf[128];
@@ -233,14 +243,9 @@ w32_kbd_patch_key (KEY_EVENT_RECORD *event)
233 keystate, buf, 128, 0); 243 keystate, buf, 128, 0);
234 if (isdead > 0) 244 if (isdead > 0)
235 { 245 {
236 char cp[20]; 246 int cpId = GetConsoleCP ();
237 int cpId;
238 247
239 event->uChar.UnicodeChar = buf[isdead - 1]; 248 event->uChar.UnicodeChar = buf[isdead - 1];
240
241 GetLocaleInfo (GetThreadLocale (),
242 LOCALE_IDEFAULTANSICODEPAGE, cp, 20);
243 cpId = atoi (cp);
244 isdead = WideCharToMultiByte (cpId, 0, buf, isdead, 249 isdead = WideCharToMultiByte (cpId, 0, buf, isdead,
245 ansi_code, 4, NULL, NULL); 250 ansi_code, 4, NULL, NULL);
246 } 251 }
@@ -447,26 +452,34 @@ key_event (KEY_EVENT_RECORD *event, struct input_event *emacs_ev, int *isdead)
447 } 452 }
448 else if (event->uChar.AsciiChar > 0) 453 else if (event->uChar.AsciiChar > 0)
449 { 454 {
455 /* Pure ASCII characters < 128. */
450 emacs_ev->kind = ASCII_KEYSTROKE_EVENT; 456 emacs_ev->kind = ASCII_KEYSTROKE_EVENT;
451 emacs_ev->code = event->uChar.AsciiChar; 457 emacs_ev->code = event->uChar.AsciiChar;
452 } 458 }
453 else if (event->uChar.UnicodeChar > 0) 459 else if (event->uChar.UnicodeChar > 0
460 && w32_console_unicode_input)
454 { 461 {
462 /* Unicode codepoint; only valid if we are using Unicode
463 console input mode. */
455 emacs_ev->kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT; 464 emacs_ev->kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT;
456 emacs_ev->code = event->uChar.UnicodeChar; 465 emacs_ev->code = event->uChar.UnicodeChar;
457 } 466 }
458 else 467 else
459 { 468 {
460 /* Fallback for non-Unicode versions of Windows. */ 469 /* Fallback handling of non-ASCII characters for non-Unicode
470 versions of Windows, and for non-Unicode input on NT
471 family of Windows. Only characters in the current
472 console codepage are supported by this fallback. */
461 wchar_t code; 473 wchar_t code;
462 char dbcs[2]; 474 char dbcs[2];
463 char cp[20];
464 int cpId; 475 int cpId;
465 476
466 /* Get the codepage to interpret this key with. */ 477 /* Get the current console input codepage to interpret this
467 GetLocaleInfo (GetThreadLocale (), 478 key with. Note that the system defaults for the OEM
468 LOCALE_IDEFAULTANSICODEPAGE, cp, 20); 479 codepage could have been changed by calling SetConsoleCP
469 cpId = atoi (cp); 480 or w32-set-console-codepage, so using GetLocaleInfo to
481 get LOCALE_IDEFAULTCODEPAGE is not TRT here. */
482 cpId = GetConsoleCP ();
470 483
471 dbcs[0] = dbcs_lead; 484 dbcs[0] = dbcs_lead;
472 dbcs[1] = event->uChar.AsciiChar; 485 dbcs[1] = event->uChar.AsciiChar;
@@ -501,6 +514,7 @@ key_event (KEY_EVENT_RECORD *event, struct input_event *emacs_ev, int *isdead)
501 } 514 }
502 else 515 else
503 { 516 {
517 /* Function keys and other non-character keys. */
504 emacs_ev->kind = NON_ASCII_KEYSTROKE_EVENT; 518 emacs_ev->kind = NON_ASCII_KEYSTROKE_EVENT;
505 emacs_ev->code = event->wVirtualKeyCode; 519 emacs_ev->code = event->wVirtualKeyCode;
506 } 520 }
diff --git a/src/w32inevt.h b/src/w32inevt.h
index d228637abfb..5386f2aa96c 100644
--- a/src/w32inevt.h
+++ b/src/w32inevt.h
@@ -19,6 +19,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
19#ifndef EMACS_W32INEVT_H 19#ifndef EMACS_W32INEVT_H
20#define EMACS_W32INEVT_H 20#define EMACS_W32INEVT_H
21 21
22extern int w32_console_unicode_input;
23
22extern int w32_console_read_socket (struct terminal *term, int numchars, 24extern int w32_console_read_socket (struct terminal *term, int numchars,
23 struct input_event *hold_quit); 25 struct input_event *hold_quit);
24extern void w32_console_mouse_position (FRAME_PTR *f, int insist, 26extern void w32_console_mouse_position (FRAME_PTR *f, int insist,