Commit 01bd1b0d authored by Eli Zaretskii's avatar Eli Zaretskii

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.
parent a5c66610
2012-07-28 Eli Zaretskii <eliz@gnu.org>
* 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.
(Bug#12055)
2012-07-28 Chong Yidong <cyd@gnu.org>
* progmodes/gdb-mi.el (gdb-place-breakpoints): Fix the call to
......
......@@ -2655,23 +2655,32 @@ See also `locale-charset-language-names', `locale-language-names',
;; On Windows, override locale-coding-system,
;; default-file-name-coding-system, keyboard-coding-system,
;; terminal-coding-system with system codepage.
;; terminal-coding-system with the appropriate codepages.
(when (boundp 'w32-ansi-code-page)
(let ((code-page-coding (intern (format "cp%d" w32-ansi-code-page))))
(when (coding-system-p code-page-coding)
(unless frame (setq locale-coding-system code-page-coding))
(set-keyboard-coding-system code-page-coding frame)
(set-terminal-coding-system code-page-coding frame)
;; Set default-file-name-coding-system last, so that Emacs
;; doesn't try to use cpNNNN when it defines keyboard and
;; terminal encoding. That's because the above two lines
;; will want to load code-pages.el, where cpNNNN are
;; defined; if default-file-name-coding-system were set to
;; cpNNNN while these two lines run, Emacs will want to use
;; it for encoding the file name it wants to load. And that
;; will fail, since cpNNNN is not yet usable until
;; code-pages.el finishes loading.
(setq default-file-name-coding-system code-page-coding))))
(let ((ansi-code-page-coding (intern (format "cp%d" w32-ansi-code-page)))
(oem-code-page-coding
(intern (format "cp%d" (w32-get-console-codepage))))
(oem-code-page-output-coding
(intern (format "cp%d" (w32-get-console-output-codepage))))
ansi-cs-p oem-cs-p oem-o-cs-p)
(setq ansi-cs-p (coding-system-p ansi-code-page-coding))
(setq oem-cs-p (coding-system-p oem-code-page-coding))
(setq oem-o-cs-p (coding-system-p oem-code-page-output-coding))
;; Set the keyboard and display encoding to either the current
;; ANSI codepage of the OEM codepage, depending on whether
;; this is a GUI or a TTY frame.
(when ansi-cs-p
(unless frame (setq locale-coding-system ansi-code-page-coding))
(when (display-graphic-p frame)
(set-keyboard-coding-system ansi-code-page-coding frame)
(set-terminal-coding-system ansi-code-page-coding frame))
(setq default-file-name-coding-system ansi-code-page-coding))
(when oem-cs-p
(unless (display-graphic-p frame)
(set-keyboard-coding-system oem-code-page-coding frame)
(set-terminal-coding-system
(if oem-o-cs-p oem-code-page-output-coding oem-code-page-coding)
frame)))))
(when (eq system-type 'darwin)
;; On Darwin, file names are always encoded in utf-8, no matter
......
2012-07-28 Eli Zaretskii <eliz@gnu.org>
Fix non-ASCII input in non-GUI frames on MS-Windows. (Bug#12055)
* 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.
* 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.
* w32inevt.h: Declare w32_console_unicode_input.
* xdisp.c (init_iterator): Don't reference tip_frame in a build
--without-x. (Bug#11742)
......
......@@ -37,6 +37,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include "termhooks.h"
#include "termchar.h"
#include "dispextern.h"
#include "w32heap.h" /* for os_subtype */
#include "w32inevt.h"
/* from window.c */
......@@ -67,6 +68,7 @@ static CONSOLE_CURSOR_INFO prev_console_cursor;
#endif
HANDLE keyboard_handle;
int w32_console_unicode_input;
/* Setting this as the ctrl handler prevents emacs from being killed when
......@@ -786,6 +788,11 @@ initialize_w32_display (struct terminal *term)
info.srWindow.Left);
}
if (os_subtype == OS_NT)
w32_console_unicode_input = 1;
else
w32_console_unicode_input = 0;
/* Setup w32_display_info structure for this frame. */
w32_initialize_display_info (build_string ("Console"));
......
......@@ -41,6 +41,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include "termchar.h"
#include "w32heap.h"
#include "w32term.h"
#include "w32inevt.h"
/* stdin, from w32console.c */
extern HANDLE keyboard_handle;
......@@ -61,6 +62,15 @@ 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 inline BOOL
w32_read_console_input (HANDLE h, INPUT_RECORD *rec, DWORD recsize,
DWORD *waiting)
{
return (w32_console_unicode_input
? ReadConsoleInputW (h, rec, recsize, waiting)
: ReadConsoleInputA (h, rec, recsize, waiting));
}
static int
fill_queue (BOOL block)
{
......@@ -80,8 +90,8 @@ fill_queue (BOOL block)
return 0;
}
rc = ReadConsoleInput (keyboard_handle, event_queue, EVENT_QUEUE_SIZE,
&events_waiting);
rc = w32_read_console_input (keyboard_handle, event_queue, EVENT_QUEUE_SIZE,
&events_waiting);
if (!rc)
return -1;
queue_ptr = event_queue;
......@@ -224,7 +234,7 @@ w32_kbd_patch_key (KEY_EVENT_RECORD *event)
#endif
/* On NT, call ToUnicode instead and then convert to the current
locale's default codepage. */
console input codepage. */
if (os_subtype == OS_NT)
{
WCHAR buf[128];
......@@ -233,14 +243,9 @@ w32_kbd_patch_key (KEY_EVENT_RECORD *event)
keystate, buf, 128, 0);
if (isdead > 0)
{
char cp[20];
int cpId;
int cpId = GetConsoleCP ();
event->uChar.UnicodeChar = buf[isdead - 1];
GetLocaleInfo (GetThreadLocale (),
LOCALE_IDEFAULTANSICODEPAGE, cp, 20);
cpId = atoi (cp);
isdead = WideCharToMultiByte (cpId, 0, buf, isdead,
ansi_code, 4, NULL, NULL);
}
......@@ -447,26 +452,34 @@ key_event (KEY_EVENT_RECORD *event, struct input_event *emacs_ev, int *isdead)
}
else if (event->uChar.AsciiChar > 0)
{
/* Pure ASCII characters < 128. */
emacs_ev->kind = ASCII_KEYSTROKE_EVENT;
emacs_ev->code = event->uChar.AsciiChar;
}
else if (event->uChar.UnicodeChar > 0)
else if (event->uChar.UnicodeChar > 0
&& w32_console_unicode_input)
{
/* Unicode codepoint; only valid if we are using Unicode
console input mode. */
emacs_ev->kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT;
emacs_ev->code = event->uChar.UnicodeChar;
}
else
{
/* Fallback for non-Unicode versions of Windows. */
/* Fallback handling of non-ASCII characters for non-Unicode
versions of Windows, and for non-Unicode input on NT
family of Windows. Only characters in the current
console codepage are supported by this fallback. */
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);
/* Get the current console input codepage to interpret this
key with. Note that the system defaults for the OEM
codepage could have been changed by calling SetConsoleCP
or w32-set-console-codepage, so using GetLocaleInfo to
get LOCALE_IDEFAULTCODEPAGE is not TRT here. */
cpId = GetConsoleCP ();
dbcs[0] = dbcs_lead;
dbcs[1] = event->uChar.AsciiChar;
......@@ -501,6 +514,7 @@ key_event (KEY_EVENT_RECORD *event, struct input_event *emacs_ev, int *isdead)
}
else
{
/* Function keys and other non-character keys. */
emacs_ev->kind = NON_ASCII_KEYSTROKE_EVENT;
emacs_ev->code = event->wVirtualKeyCode;
}
......
......@@ -19,6 +19,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#ifndef EMACS_W32INEVT_H
#define EMACS_W32INEVT_H
extern int w32_console_unicode_input;
extern int w32_console_read_socket (struct terminal *term, int numchars,
struct input_event *hold_quit);
extern void w32_console_mouse_position (FRAME_PTR *f, int insist,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment