mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2025-01-02 11:21:42 +00:00
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.
This commit is contained in:
parent
a5c66610be
commit
01bd1b0df6
@ -1,3 +1,10 @@
|
||||
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
|
||||
|
@ -1,5 +1,23 @@
|
||||
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,
|
||||
|
Loading…
Reference in New Issue
Block a user