From 70b0f37994c80b2ecf30178e140a144d45afcb8b Mon Sep 17 00:00:00 2001 From: patthoyts Date: Thu, 3 Nov 2005 11:53:59 +0000 Subject: * win/tclWin32Dll.c: Backported Anton Kovalenko's patch #1256872 * win/tclWinConsole.c: to give unicode console support on * win/tclWinInt.h: suitable systems (eg: NT/XP) --- ChangeLog | 6 ++++ win/tclWin32Dll.c | 6 +++- win/tclWinConsole.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++------ win/tclWinInt.h | 16 +++++++++- 4 files changed, 102 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9232bb0..9573811 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2005-11-03 Pat Thoyts + + * win/tclWin32Dll.c: Backported Anton Kovalenko's patch #1256872 + * win/tclWinConsole.c: to give unicode console support on + * win/tclWinInt.h: suitable systems (eg: NT/XP) + 2005-11-01 Don Porter * generic/tclCmdMZ.c (TclCheckExecutionTraces): Corrected mistaken diff --git a/win/tclWin32Dll.c b/win/tclWin32Dll.c index bd2ebd0..1e4a0b3 100644 --- a/win/tclWin32Dll.c +++ b/win/tclWin32Dll.c @@ -9,7 +9,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclWin32Dll.c,v 1.24.2.7 2005/06/06 21:04:47 kennykb Exp $ + * RCS: @(#) $Id: tclWin32Dll.c,v 1.24.2.8 2005/11/03 11:53:59 patthoyts Exp $ */ #include "tclWinInt.h" @@ -118,6 +118,8 @@ static TclWinProcs asciiProcs = { (int (__cdecl*)(CONST TCHAR *, struct _utimbuf *)) _utime, NULL, NULL, + (BOOL (WINAPI *)(HANDLE, LPVOID, DWORD, LPDWORD, LPVOID)) ReadConsoleA, + (BOOL (WINAPI *)(HANDLE, const VOID*, DWORD, LPDWORD, LPVOID)) WriteConsoleA }; static TclWinProcs unicodeProcs = { @@ -167,6 +169,8 @@ static TclWinProcs unicodeProcs = { (int (__cdecl*)(CONST TCHAR *, struct _utimbuf *)) _wutime, NULL, NULL, + (BOOL (WINAPI *)(HANDLE, LPVOID, DWORD, LPDWORD, LPVOID)) ReadConsoleW, + (BOOL (WINAPI *)(HANDLE, const VOID*, DWORD, LPDWORD, LPVOID)) WriteConsoleW }; TclWinProcs *tclWinProcs; diff --git a/win/tclWinConsole.c b/win/tclWinConsole.c index 2370a22..fa38a6c 100644 --- a/win/tclWinConsole.c +++ b/win/tclWinConsole.c @@ -9,7 +9,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclWinConsole.c,v 1.11.2.1 2005/01/27 22:53:37 andreas_kupries Exp $ + * RCS: @(#) $Id: tclWinConsole.c,v 1.11.2.2 2005/11/03 11:53:59 patthoyts Exp $ */ #include "tclWinInt.h" @@ -190,6 +190,70 @@ static Tcl_ChannelType consoleChannelType = { /* *---------------------------------------------------------------------- * + * readConsoleBytes -- + * + * Wrapper for ReadConsole{A,W}, that takes and returns number of + * bytes instead of number of TCHARS + * + * Results: + * FALSE if there was a problem else TRUE + * + * Side effects: + * Reads characters from the console. + * + *---------------------------------------------------------------------- + */ + +static BOOL +readConsoleBytes(HANDLE hConsole, LPVOID lpBuffer, + DWORD nbytes, LPDWORD nbytesread) +{ + DWORD ntchars; + BOOL result; + int tcharsize; + tcharsize = tclWinProcs->useWide? 2 : 1; + result = tclWinProcs->readConsoleProc( + hConsole, lpBuffer, nbytes / tcharsize, &ntchars, NULL); + if (nbytesread) + *nbytesread = (ntchars*tcharsize); + return result; +} + +/* + *---------------------------------------------------------------------- + * + * writeConsoleBytes -- + * + * Wrapper for WriteConsole{A,W}, that takes and returns number of + * bytes instead of number of TCHARS + * + * Results: + * FALSE if there was a problem else TRUE + * + * Side effects: + * Writes characters from the console. + * + *---------------------------------------------------------------------- + */ + +static BOOL +writeConsoleBytes(HANDLE hConsole, const VOID *lpBuffer, + DWORD nbytes, LPDWORD nbyteswritten) +{ + DWORD ntchars; + BOOL result; + int tcharsize; + tcharsize = tclWinProcs->useWide? 2 : 1; + result = tclWinProcs->writeConsoleProc( + hConsole, lpBuffer, nbytes / tcharsize, &ntchars, NULL); + if (nbyteswritten) + *nbyteswritten = (ntchars*tcharsize); + return result; +} + +/* + *---------------------------------------------------------------------- + * * ConsoleInit -- * * This function initializes the static variables for this file. @@ -705,8 +769,8 @@ ConsoleInputProc( * at least one byte is available or an EOF occurs. */ - if (ReadConsole(infoPtr->handle, (LPVOID) buf, (DWORD) bufSize, &count, - (LPOVERLAPPED) NULL) == TRUE) { + if (readConsoleBytes(infoPtr->handle, (LPVOID) buf, + (DWORD) bufSize, &count) == TRUE) { buf[count] = '\0'; return count; } @@ -792,8 +856,8 @@ ConsoleOutputProc( * This avoids an unnecessary copy. */ - if (WriteFile(infoPtr->handle, (LPVOID) buf, (DWORD) toWrite, - &bytesWritten, (LPOVERLAPPED) NULL) == FALSE) { + if (writeConsoleBytes(infoPtr->handle, (LPVOID) buf, (DWORD) toWrite, + &bytesWritten) == FALSE) { TclWinConvertError(GetLastError()); goto error; } @@ -1144,8 +1208,8 @@ ConsoleReaderThread(LPVOID arg) * Look for data on the console, but first ignore any events * that are not KEY_EVENTs */ - if (ReadConsoleA(handle, infoPtr->buffer, CONSOLE_BUFFER_SIZE, - (LPDWORD) &infoPtr->bytesRead, NULL) != FALSE) { + if (readConsoleBytes(handle, infoPtr->buffer, CONSOLE_BUFFER_SIZE, + (LPDWORD) &infoPtr->bytesRead) != FALSE) { /* * Data was stored in the buffer. */ @@ -1240,7 +1304,7 @@ ConsoleWriterThread(LPVOID arg) */ while (toWrite > 0) { - if (WriteConsoleA(handle, buf, toWrite, &count, NULL) == FALSE) { + if (writeConsoleBytes(handle, buf, toWrite, &count) == FALSE) { infoPtr->writeError = GetLastError(); break; } else { @@ -1367,7 +1431,10 @@ TclWinOpenConsoleChannel(handle, channelName, permissions) Tcl_SetChannelOption(NULL, infoPtr->channel, "-translation", "auto"); Tcl_SetChannelOption(NULL, infoPtr->channel, "-eofchar", "\032 {}"); - Tcl_SetChannelOption(NULL, infoPtr->channel, "-encoding", encoding); + if (tclWinProcs->useWide) + Tcl_SetChannelOption(NULL, infoPtr->channel, "-encoding", "unicode"); + else + Tcl_SetChannelOption(NULL, infoPtr->channel, "-encoding", encoding); return infoPtr->channel; } diff --git a/win/tclWinInt.h b/win/tclWinInt.h index 7ff2775..5cefc9d 100644 --- a/win/tclWinInt.h +++ b/win/tclWinInt.h @@ -8,7 +8,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclWinInt.h,v 1.20.2.3 2004/05/03 18:01:37 kennykb Exp $ + * RCS: @(#) $Id: tclWinInt.h,v 1.20.2.4 2005/11/03 11:53:59 patthoyts Exp $ */ #ifndef _TCLWININT @@ -111,6 +111,20 @@ typedef struct TclWinProcs { LPVOID, UINT, LPVOID, DWORD); BOOL (WINAPI *getVolumeNameForVMPProc)(CONST TCHAR*, TCHAR*, DWORD); + + /* + * Unicode console support. WriteConsole and ReadConsole + */ + BOOL (WINAPI *readConsoleProc)(HANDLE hConsoleInput, + LPVOID lpBuffer, + DWORD nNumberOfCharsToRead, + LPDWORD lpNumberOfCharsRead, + LPVOID lpReserved); + BOOL (WINAPI *writeConsoleProc)(HANDLE hConsoleOutput, + const VOID* lpBuffer, + DWORD nNumberOfCharsToWrite, + LPDWORD lpNumberOfCharsWritten, + LPVOID lpReserved); } TclWinProcs; EXTERN TclWinProcs *tclWinProcs; -- cgit v0.12