From 169a78358af41a6e77a814a0a73f663542c51a6f Mon Sep 17 00:00:00 2001 From: patthoyts Date: Thu, 3 Nov 2005 01:16:07 +0000 Subject: * win/tclWin32Dll.c: Applied patch #1256872 to provide unicode * win/tclWinConsole.c: support in the console on suitable systems. * win/tclWinInt.h: Patch by Anton Kovalenko --- ChangeLog | 6 ++++++ win/tclWin32Dll.c | 16 +++++++++++--- win/tclWinConsole.c | 61 +++++++++++++++++++++++++++++++++++++++++++++-------- win/tclWinInt.h | 19 ++++++++++++++++- 4 files changed, 89 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9da7ba3..212aa4c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2005-11-03 Pat Thoyts + + * win/tclWin32Dll.c: Applied patch #1256872 to provide unicode + * win/tclWinConsole.c: support in the console on suitable systems. + * win/tclWinInt.h: Patch by Anton Kovalenko + 2005-11-02 Pat Thoyts Applied patch #1096916 to support building with MSVC 8. diff --git a/win/tclWin32Dll.c b/win/tclWin32Dll.c index ce54eee..ae8de51 100644 --- a/win/tclWin32Dll.c +++ b/win/tclWin32Dll.c @@ -10,7 +10,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.46 2005/07/24 22:56:46 dkf Exp $ + * RCS: @(#) $Id: tclWin32Dll.c,v 1.47 2005/11/03 01:16:07 patthoyts Exp $ */ #include "tclWinInt.h" @@ -118,8 +118,13 @@ static TclWinProcs asciiProcs = { /* deleted (int (__cdecl*)(CONST TCHAR *, struct _utimbuf *)) _utime, */ NULL, NULL, + /* getLongPathNameProc */ + NULL, /* Security SDK - not available on 95,98,ME */ - NULL, NULL, NULL, NULL, NULL, NULL + NULL, NULL, NULL, NULL, NULL, NULL, + /* ReadConsole and WriteConsole */ + (BOOL (WINAPI *)(HANDLE, LPVOID, DWORD, LPDWORD, LPVOID)) ReadConsoleA, + (BOOL (WINAPI *)(HANDLE, const VOID*, DWORD, LPDWORD, LPVOID)) WriteConsoleA }; static TclWinProcs unicodeProcs = { @@ -171,8 +176,13 @@ static TclWinProcs unicodeProcs = { /* deleted (int (__cdecl*)(CONST TCHAR *, struct _utimbuf *)) _wutime, */ NULL, NULL, + /* getLongPathNameProc */ + NULL, /* Security SDK - will be filled in on NT,XP,2000,2003 */ - NULL, NULL, NULL, NULL, NULL, NULL + NULL, NULL, NULL, NULL, NULL, NULL, + /* ReadConsole and WriteConsole */ + (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 83ef862..c59bc6f 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.15 2005/07/24 22:56:47 dkf Exp $ + * RCS: @(#) $Id: tclWinConsole.c,v 1.16 2005/11/03 01:16:07 patthoyts Exp $ */ #include "tclWinInt.h" @@ -54,6 +54,7 @@ TCL_DECLARE_MUTEX(consoleMutex) * This structure describes per-instance data for a console based channel. */ + typedef struct ConsoleInfo { HANDLE handle; int type; @@ -187,6 +188,45 @@ static Tcl_ChannelType consoleChannelType = { /* *---------------------------------------------------------------------- + * + * readConsoleBytes, writeConsoleBytes -- + * Wrapper for ReadConsole{A,W}, that takes and returns number of bytes + * instead of number of TCHARS + */ +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; +} + +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 -- * @@ -701,8 +741,8 @@ ConsoleInputProc( * 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; } @@ -788,8 +828,8 @@ ConsoleOutputProc( * avoids an unnecessary copy. */ - if (WriteConsole(infoPtr->handle, buf, toWrite, &bytesWritten, - NULL) == FALSE) { + if (writeConsoleBytes(infoPtr->handle, buf, toWrite, &bytesWritten) + == FALSE) { TclWinConvertError(GetLastError()); goto error; } @@ -1133,8 +1173,8 @@ ConsoleReaderThread(LPVOID arg) * 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. */ @@ -1233,7 +1273,7 @@ ConsoleWriterThread(LPVOID arg) */ while (toWrite > 0) { - if (WriteConsole(handle, buf, toWrite, &count, NULL) == FALSE) { + if (writeConsoleBytes(handle, buf, toWrite, &count) == FALSE) { infoPtr->writeError = GetLastError(); break; } else { @@ -1363,7 +1403,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 d7f4a70..40aa67c 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.28 2004/11/03 00:26:59 davygrvy Exp $ + * RCS: @(#) $Id: tclWinInt.h,v 1.29 2005/11/03 01:16:07 patthoyts Exp $ */ #ifndef _TCLWININT @@ -127,6 +127,23 @@ typedef struct TclWinProcs { LPDWORD PrivilegeSetLength, LPDWORD GrantedAccess, LPBOOL AccessStatus); + /* + * 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; MODULE_SCOPE TclWinProcs *tclWinProcs; -- cgit v0.12