* autoload.cc (CharToOemA): Remove.
(CharNextExA): Define. * environ.cc (codepage_init): Un-static. Set active_codepage to active codepage. Default to ansi regardless of buf pointer. * fhandler.h (dev_console::get_console_cp): New method. (dev_console::con_to_str): Change declaration according to new implementation. (dev_console::str_to_con): Ditto. * fhandler_console.cc (cp_convert): Remove. (dev_console::con_to_str): Redefine to take WCHAR as incoming console char. (dev_console::get_console_cp): Return correct codepage according to alternate_charset_active setting. (dev_console::str_to_con): Redefine to create WCHAR buffer for console output. (fhandler_console::read): Read console input as WCHARs. (base_chars): Fix typo in comment. (fhandler_console::char_command): Save and restore console output buffer using UNICODE functions. (fhandler_console::write_normal): Convert to write output in UNICODE. Use CharNextExA to recognize multibyte characters in input. Workaround problem with UTF-8 and MultiByteToWideChar. Simplify the loop for printing "normal" characters. * strfuncs.cc (active_codepage): New variable to store active codepage. (get_cp): Call codepage_init() if active_codepage is uninitialized. Just return active_codepage. (is_cp_multibyte): New function. * winsup.h (active_codepage): Declare. (codepage_init): Declare. (is_cp_multibyte): Declare.
This commit is contained in:
parent
58d470721b
commit
a7197550f3
@ -1,3 +1,36 @@
|
|||||||
|
2008-02-05 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* autoload.cc (CharToOemA): Remove.
|
||||||
|
(CharNextExA): Define.
|
||||||
|
* environ.cc (codepage_init): Un-static. Set active_codepage to
|
||||||
|
active codepage. Default to ansi regardless of buf pointer.
|
||||||
|
* fhandler.h (dev_console::get_console_cp): New method.
|
||||||
|
(dev_console::con_to_str): Change declaration according to new
|
||||||
|
implementation.
|
||||||
|
(dev_console::str_to_con): Ditto.
|
||||||
|
* fhandler_console.cc (cp_convert): Remove.
|
||||||
|
(dev_console::con_to_str): Redefine to take WCHAR as incoming console
|
||||||
|
char.
|
||||||
|
(dev_console::get_console_cp): Return correct codepage according to
|
||||||
|
alternate_charset_active setting.
|
||||||
|
(dev_console::str_to_con): Redefine to create WCHAR buffer for console
|
||||||
|
output.
|
||||||
|
(fhandler_console::read): Read console input as WCHARs.
|
||||||
|
(base_chars): Fix typo in comment.
|
||||||
|
(fhandler_console::char_command): Save and restore console output
|
||||||
|
buffer using UNICODE functions.
|
||||||
|
(fhandler_console::write_normal): Convert to write output in UNICODE.
|
||||||
|
Use CharNextExA to recognize multibyte characters in input. Workaround
|
||||||
|
problem with UTF-8 and MultiByteToWideChar. Simplify the loop for
|
||||||
|
printing "normal" characters.
|
||||||
|
* strfuncs.cc (active_codepage): New variable to store active codepage.
|
||||||
|
(get_cp): Call codepage_init() if active_codepage is uninitialized.
|
||||||
|
Just return active_codepage.
|
||||||
|
(is_cp_multibyte): New function.
|
||||||
|
* winsup.h (active_codepage): Declare.
|
||||||
|
(codepage_init): Declare.
|
||||||
|
(is_cp_multibyte): Declare.
|
||||||
|
|
||||||
2008-02-03 Brian Dessent <brian@dessent.net>
|
2008-02-03 Brian Dessent <brian@dessent.net>
|
||||||
|
|
||||||
* smallprint.cc (__small_vsprintf): Use HEAP_NOTHEAP for type.
|
* smallprint.cc (__small_vsprintf): Use HEAP_NOTHEAP for type.
|
||||||
|
@ -320,7 +320,7 @@ LoadDLLfuncEx (LsaLogonUser, 56, secur32, 1)
|
|||||||
LoadDLLfuncEx (LsaLookupAuthenticationPackage, 12, secur32, 1)
|
LoadDLLfuncEx (LsaLookupAuthenticationPackage, 12, secur32, 1)
|
||||||
LoadDLLfuncEx (LsaRegisterLogonProcess, 12, secur32, 1)
|
LoadDLLfuncEx (LsaRegisterLogonProcess, 12, secur32, 1)
|
||||||
|
|
||||||
LoadDLLfunc (CharToOemA, 8, user32)
|
LoadDLLfunc (CharNextExA, 12, user32)
|
||||||
LoadDLLfunc (CloseClipboard, 0, user32)
|
LoadDLLfunc (CloseClipboard, 0, user32)
|
||||||
LoadDLLfunc (CloseDesktop, 4, user32)
|
LoadDLLfunc (CloseDesktop, 4, user32)
|
||||||
LoadDLLfunc (CloseWindowStation, 4, user32)
|
LoadDLLfunc (CloseWindowStation, 4, user32)
|
||||||
|
@ -16,6 +16,7 @@ details. */
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <sys/cygwin.h>
|
#include <sys/cygwin.h>
|
||||||
#include <cygwin/version.h>
|
#include <cygwin/version.h>
|
||||||
|
#include <winnls.h>
|
||||||
#include "pinfo.h"
|
#include "pinfo.h"
|
||||||
#include "perprocess.h"
|
#include "perprocess.h"
|
||||||
#include "security.h"
|
#include "security.h"
|
||||||
@ -513,20 +514,30 @@ set_file_api_mode (codepage_type cp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
codepage_init (const char *buf)
|
codepage_init (const char *buf)
|
||||||
{
|
{
|
||||||
if (!buf || !*buf)
|
if (!buf)
|
||||||
return;
|
buf = "ansi";
|
||||||
|
|
||||||
if (ascii_strcasematch (buf, "oem"))
|
if (ascii_strcasematch (buf, "oem"))
|
||||||
current_codepage = oem_cp;
|
{
|
||||||
else if (ascii_strcasematch (buf, "ansi"))
|
current_codepage = oem_cp;
|
||||||
current_codepage = ansi_cp;
|
active_codepage = GetOEMCP ();
|
||||||
|
}
|
||||||
else if (ascii_strcasematch (buf, "utf8"))
|
else if (ascii_strcasematch (buf, "utf8"))
|
||||||
current_codepage = utf8_cp;
|
{
|
||||||
|
current_codepage = utf8_cp;
|
||||||
|
active_codepage = CP_UTF8;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
debug_printf ("Wrong codepage name: %s", buf);
|
{
|
||||||
|
if (!ascii_strcasematch (buf, "ansi"))
|
||||||
|
debug_printf ("Wrong codepage name: %s", buf);
|
||||||
|
/* Fallback to ANSI */
|
||||||
|
current_codepage = ansi_cp;
|
||||||
|
active_codepage = GetACP ();
|
||||||
|
}
|
||||||
set_file_api_mode (current_codepage);
|
set_file_api_mode (current_codepage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -879,8 +879,9 @@ class dev_console
|
|||||||
bool use_mouse;
|
bool use_mouse;
|
||||||
bool raw_win32_keyboard_mode;
|
bool raw_win32_keyboard_mode;
|
||||||
|
|
||||||
bool con_to_str (char *d, const char *s, DWORD sz);
|
inline UINT get_console_cp ();
|
||||||
bool str_to_con (char *d, const char *s, DWORD sz);
|
bool con_to_str (char *d, int dlen, WCHAR w);
|
||||||
|
DWORD str_to_con (PWCHAR d, const char *s, DWORD sz);
|
||||||
void set_color (HANDLE);
|
void set_color (HANDLE);
|
||||||
bool fillin_info (HANDLE);
|
bool fillin_info (HANDLE);
|
||||||
void set_default_attr ();
|
void set_default_attr ();
|
||||||
|
@ -35,28 +35,6 @@ details. */
|
|||||||
|
|
||||||
#define CONVERT_LIMIT 16384
|
#define CONVERT_LIMIT 16384
|
||||||
|
|
||||||
static bool
|
|
||||||
cp_convert (UINT destcp, char *dest, UINT srccp, const char *src, DWORD size)
|
|
||||||
{
|
|
||||||
if (!size)
|
|
||||||
/* no action */;
|
|
||||||
else if (destcp == srccp)
|
|
||||||
{
|
|
||||||
if (dest != src)
|
|
||||||
memcpy (dest, src, size);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
WCHAR wbuffer[CONVERT_LIMIT]; /* same size as the maximum input, s.b. */
|
|
||||||
if (!MultiByteToWideChar (srccp, 0, src, size, wbuffer, sizeof (wbuffer)))
|
|
||||||
return false;
|
|
||||||
if (!WideCharToMultiByte (destcp, 0, wbuffer, size, dest, size,
|
|
||||||
NULL, NULL))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Scroll the screen context.
|
* Scroll the screen context.
|
||||||
* x1, y1 - ul corner
|
* x1, y1 - ul corner
|
||||||
@ -175,21 +153,21 @@ set_console_state_for_spawn (bool iscyg)
|
|||||||
cached, because a program or the user can change these values at
|
cached, because a program or the user can change these values at
|
||||||
any time. */
|
any time. */
|
||||||
inline bool
|
inline bool
|
||||||
dev_console::con_to_str (char *d, const char *s, DWORD sz)
|
dev_console::con_to_str (char *d, int dlen, WCHAR w)
|
||||||
{
|
{
|
||||||
return cp_convert (get_cp (), d, GetConsoleCP (), s, sz);
|
return !!sys_wcstombs (d, dlen, &w, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool
|
inline UINT
|
||||||
dev_console::str_to_con (char *d, const char *s, DWORD sz)
|
dev_console::get_console_cp ()
|
||||||
{
|
{
|
||||||
if (alternate_charset_active)
|
return alternate_charset_active ? GetConsoleOutputCP () : get_cp ();
|
||||||
{
|
}
|
||||||
/* no translation when alternate charset is active */
|
|
||||||
memcpy(d, s, sz);
|
inline DWORD
|
||||||
return true;
|
dev_console::str_to_con (PWCHAR d, const char *s, DWORD sz)
|
||||||
}
|
{
|
||||||
return cp_convert (GetConsoleOutputCP (), d, get_cp (), s, sz);
|
return MultiByteToWideChar (get_console_cp (), 0, s, sz, d, CONVERT_LIMIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@ -292,7 +270,7 @@ fhandler_console::read (void *pv, size_t& buflen)
|
|||||||
INPUT_RECORD input_rec;
|
INPUT_RECORD input_rec;
|
||||||
const char *toadd = NULL;
|
const char *toadd = NULL;
|
||||||
|
|
||||||
if (!ReadConsoleInput (h, &input_rec, 1, &nread))
|
if (!ReadConsoleInputW (h, &input_rec, 1, &nread))
|
||||||
{
|
{
|
||||||
syscall_printf ("ReadConsoleInput failed, %E");
|
syscall_printf ("ReadConsoleInput failed, %E");
|
||||||
goto err; /* seems to be failure */
|
goto err; /* seems to be failure */
|
||||||
@ -376,18 +354,14 @@ fhandler_console::read (void *pv, size_t& buflen)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
tmp[1] = ich;
|
dev_state->con_to_str (tmp + 1, 59, wch);
|
||||||
/* Need this check since US code page seems to have a bug when
|
|
||||||
converting a CTRL-U. */
|
|
||||||
if ((unsigned char) ich > 0x7f)
|
|
||||||
dev_state->con_to_str (tmp + 1, tmp + 1, 1);
|
|
||||||
/* Determine if the keystroke is modified by META. The tricky
|
/* Determine if the keystroke is modified by META. The tricky
|
||||||
part is to distinguish whether the right Alt key should be
|
part is to distinguish whether the right Alt key should be
|
||||||
recognized as Alt, or as AltGr. */
|
recognized as Alt, or as AltGr. */
|
||||||
bool meta;
|
bool meta;
|
||||||
meta = (control_key_state & ALT_PRESSED) != 0
|
meta = (control_key_state & ALT_PRESSED) != 0
|
||||||
&& ((control_key_state & CTRL_PRESSED) == 0
|
&& ((control_key_state & CTRL_PRESSED) == 0
|
||||||
|| ((signed char) ich >= 0 && ich <= 0x1f || ich == 0x7f));
|
|| (wch <= 0x1f || wch == 0x7f));
|
||||||
if (!meta)
|
if (!meta)
|
||||||
toadd = tmp + 1;
|
toadd = tmp + 1;
|
||||||
else if (dev_state->metabit)
|
else if (dev_state->metabit)
|
||||||
@ -1081,7 +1055,7 @@ static const char base_chars[256] =
|
|||||||
/*10 11 12 13 14 15 16 17 */ NOR, NOR, ERR, ERR, ERR, ERR, ERR, ERR,
|
/*10 11 12 13 14 15 16 17 */ NOR, NOR, ERR, ERR, ERR, ERR, ERR, ERR,
|
||||||
/*18 19 1A 1B 1C 1D 1E 1F */ NOR, NOR, ERR, ESC, ERR, ERR, ERR, ERR,
|
/*18 19 1A 1B 1C 1D 1E 1F */ NOR, NOR, ERR, ESC, ERR, ERR, ERR, ERR,
|
||||||
/* ! " # $ % & ' */ NOR, NOR, NOR, NOR, NOR, NOR, NOR, NOR,
|
/* ! " # $ % & ' */ NOR, NOR, NOR, NOR, NOR, NOR, NOR, NOR,
|
||||||
/*() * + , - . / */ NOR, NOR, NOR, NOR, NOR, NOR, NOR, NOR,
|
/*( ) * + , - . / */ NOR, NOR, NOR, NOR, NOR, NOR, NOR, NOR,
|
||||||
/*0 1 2 3 4 5 6 7 */ NOR, NOR, NOR, NOR, NOR, NOR, NOR, NOR,
|
/*0 1 2 3 4 5 6 7 */ NOR, NOR, NOR, NOR, NOR, NOR, NOR, NOR,
|
||||||
/*8 9 : ; < = > ? */ NOR, NOR, NOR, NOR, NOR, NOR, NOR, NOR,
|
/*8 9 : ; < = > ? */ NOR, NOR, NOR, NOR, NOR, NOR, NOR, NOR,
|
||||||
/*@ A B C D E F G */ NOR, NOR, NOR, NOR, NOR, NOR, NOR, NOR,
|
/*@ A B C D E F G */ NOR, NOR, NOR, NOR, NOR, NOR, NOR, NOR,
|
||||||
@ -1243,7 +1217,7 @@ fhandler_console::char_command (char c)
|
|||||||
dev_state->savebuf = (PCHAR_INFO) cmalloc_abort (HEAP_1_BUF, sizeof (CHAR_INFO) *
|
dev_state->savebuf = (PCHAR_INFO) cmalloc_abort (HEAP_1_BUF, sizeof (CHAR_INFO) *
|
||||||
dev_state->savebufsiz.X * dev_state->savebufsiz.Y);
|
dev_state->savebufsiz.X * dev_state->savebufsiz.Y);
|
||||||
|
|
||||||
ReadConsoleOutputA (get_output_handle (), dev_state->savebuf,
|
ReadConsoleOutputW (get_output_handle (), dev_state->savebuf,
|
||||||
dev_state->savebufsiz, cob, &now.srWindow);
|
dev_state->savebufsiz, cob, &now.srWindow);
|
||||||
}
|
}
|
||||||
else /* restore */
|
else /* restore */
|
||||||
@ -1257,7 +1231,7 @@ fhandler_console::char_command (char c)
|
|||||||
if (!dev_state->savebuf)
|
if (!dev_state->savebuf)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
WriteConsoleOutputA (get_output_handle (), dev_state->savebuf,
|
WriteConsoleOutputW (get_output_handle (), dev_state->savebuf,
|
||||||
dev_state->savebufsiz, cob, &now.srWindow);
|
dev_state->savebufsiz, cob, &now.srWindow);
|
||||||
|
|
||||||
cfree (dev_state->savebuf);
|
cfree (dev_state->savebuf);
|
||||||
@ -1457,50 +1431,66 @@ fhandler_console::write_normal (const unsigned char *src,
|
|||||||
{
|
{
|
||||||
/* Scan forward to see what a char which needs special treatment */
|
/* Scan forward to see what a char which needs special treatment */
|
||||||
DWORD done;
|
DWORD done;
|
||||||
const unsigned char *found = src;
|
unsigned char *found = (unsigned char *) src;
|
||||||
|
UINT cp = dev_state->get_console_cp ();
|
||||||
|
bool mb = is_cp_multibyte (cp);
|
||||||
|
|
||||||
while (found < end)
|
while (found < end
|
||||||
|
&& found - src < CONVERT_LIMIT
|
||||||
|
&& base_chars[*found] == NOR)
|
||||||
{
|
{
|
||||||
char ch = base_chars[*found];
|
if (mb && *found && *found >= 0x80)
|
||||||
if (ch != NOR)
|
{
|
||||||
break;
|
unsigned char *nfound = (unsigned char *)
|
||||||
found++;
|
CharNextExA (cp, (const CHAR *) found, 0);
|
||||||
|
/* Sanity check for UTF-8 to workaround the problem in
|
||||||
|
MultiByteToWideChar, that it's not capable of using replacement
|
||||||
|
characters for invalid source chars in the given codepage. */
|
||||||
|
if (nfound == found + 1 && cp == CP_UTF8)
|
||||||
|
*found++ = '?';
|
||||||
|
else
|
||||||
|
found = nfound;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
++found;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Print all the base ones out */
|
/* Print all the base ones out */
|
||||||
if (found != src)
|
if (found != src)
|
||||||
{
|
{
|
||||||
DWORD len = found - src;
|
DWORD len = found - src;
|
||||||
|
DWORD buf_len;
|
||||||
|
PWCHAR buf = (PWCHAR) alloca (CONVERT_LIMIT * sizeof (WCHAR));
|
||||||
|
|
||||||
|
buf_len = dev_state->str_to_con (buf, (const char *) src, len);
|
||||||
|
if (!buf_len)
|
||||||
|
{
|
||||||
|
debug_printf ("conversion error, handle %p",
|
||||||
|
get_output_handle ());
|
||||||
|
__seterrno ();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dev_state->insert_mode)
|
||||||
|
{
|
||||||
|
int x, y;
|
||||||
|
cursor_get (&x, &y);
|
||||||
|
scroll_screen (x, y, -1, y, x + buf_len, y);
|
||||||
|
}
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
DWORD buf_len;
|
if (!WriteConsoleW (get_output_handle (), buf, buf_len, &done, 0))
|
||||||
char buf[CONVERT_LIMIT];
|
|
||||||
done = buf_len = min (sizeof (buf), len);
|
|
||||||
if (!dev_state->str_to_con (buf, (const char *) src, buf_len))
|
|
||||||
{
|
|
||||||
debug_printf ("conversion error, handle %p",
|
|
||||||
get_output_handle ());
|
|
||||||
__seterrno ();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dev_state->insert_mode)
|
|
||||||
{
|
|
||||||
int x, y;
|
|
||||||
cursor_get (&x, &y);
|
|
||||||
scroll_screen (x, y, -1, y, x + buf_len, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!WriteFile (get_output_handle (), buf, buf_len, &done, 0))
|
|
||||||
{
|
{
|
||||||
debug_printf ("write failed, handle %p", get_output_handle ());
|
debug_printf ("write failed, handle %p", get_output_handle ());
|
||||||
__seterrno ();
|
__seterrno ();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
len -= done;
|
buf_len -= done;
|
||||||
src += done;
|
buf += done;
|
||||||
}
|
}
|
||||||
while (len > 0);
|
while (buf_len > 0);
|
||||||
|
src = found;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (src < end)
|
if (src < end)
|
||||||
@ -1519,7 +1509,7 @@ fhandler_console::write_normal (const unsigned char *src,
|
|||||||
if (y >= srBottom)
|
if (y >= srBottom)
|
||||||
{
|
{
|
||||||
if (y >= dev_state->info.winBottom && !dev_state->scroll_region.Top)
|
if (y >= dev_state->info.winBottom && !dev_state->scroll_region.Top)
|
||||||
WriteFile (get_output_handle (), "\n", 1, &done, 0);
|
WriteConsoleW (get_output_handle (), L"\n", 1, &done, 0);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
scroll_screen (0, srTop + 1, -1, srBottom, 0, srTop);
|
scroll_screen (0, srTop + 1, -1, srBottom, 0, srTop);
|
||||||
|
@ -22,20 +22,26 @@ details. */
|
|||||||
#include "cygheap.h"
|
#include "cygheap.h"
|
||||||
|
|
||||||
codepage_type current_codepage = ansi_cp;
|
codepage_type current_codepage = ansi_cp;
|
||||||
|
UINT active_codepage = 0;
|
||||||
|
|
||||||
|
#ifdef __OUTSIDE_CYGWIN__
|
||||||
|
#define codepage_init(cp) (active_codepage = GetACP ())
|
||||||
|
#endif
|
||||||
|
|
||||||
UINT
|
UINT
|
||||||
get_cp ()
|
get_cp ()
|
||||||
{
|
{
|
||||||
switch (current_codepage)
|
if (!active_codepage)
|
||||||
{
|
codepage_init ("ansi");
|
||||||
case oem_cp:
|
return active_codepage;
|
||||||
return GetOEMCP ();
|
}
|
||||||
case utf8_cp:
|
|
||||||
return CP_UTF8;
|
bool
|
||||||
case ansi_cp:
|
is_cp_multibyte (UINT cp)
|
||||||
default:
|
{
|
||||||
return GetACP ();
|
CPINFO cpi;
|
||||||
}
|
GetCPInfo (cp, &cpi);
|
||||||
|
return cpi.MaxCharSize > 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* tlen is always treated as the maximum buffer size, including the '\0'
|
/* tlen is always treated as the maximum buffer size, including the '\0'
|
||||||
|
@ -112,8 +112,11 @@ extern "C" DWORD WINAPI GetLastError (void);
|
|||||||
|
|
||||||
enum codepage_type {ansi_cp, oem_cp, utf8_cp};
|
enum codepage_type {ansi_cp, oem_cp, utf8_cp};
|
||||||
extern codepage_type current_codepage;
|
extern codepage_type current_codepage;
|
||||||
|
extern UINT active_codepage;
|
||||||
|
|
||||||
|
void codepage_init (const char *buf);
|
||||||
UINT get_cp ();
|
UINT get_cp ();
|
||||||
|
bool is_cp_multibyte (UINT cp);
|
||||||
|
|
||||||
/* Used as type by sys_wcstombs_alloc and sys_mbstowcs_alloc. For a
|
/* Used as type by sys_wcstombs_alloc and sys_mbstowcs_alloc. For a
|
||||||
description see there. */
|
description see there. */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user