Re: console output in 8.4.12 on windows
Available news archives: comp.lang.tcl - comp.lang.python - comp.security.firewalls - sci.crypt - comp.lang.php - comp.lang.javascript
Google
 
Web news.hping.org


comp.lang.tcl archive

Re: console output in 8.4.12 on windows

From: David Gravereaux <davygrvy@pobox.com>
Date: Thu Dec 29 2005 - 14:52:08 CET

On Fri, 16 Dec 2005 18:40:13 +0100, Benjamin Riefenstahl
<b.riefenstahl@turtle-trading.net> wrote:

>Hi David,
>
>
>David Gravereaux writes:
>> IOW, Even if you can send the full unicode charset by the fact we're
>> using WriteConsoleW() on NT, GetConsoleCP()/GetConsoleOutputCP()
>> still returns the oem code page and you still are restricted to that
>> charset?
>
>No. WriteConsoleW() ignores the console codepage completely.
>
>You are limited by the font you have selected, so you want to select a
>TrueType font for coverage outside of the console codepage. But that
>is outside of the control of Tcl, of course.
>
>
>benny

Thanks Benny. You're right. I looked into it. Yes, fonts are
limited. Lucida is a WGL4 limited one, and could only find "Everson
Mono Unicode" to work, but is still WGL4 limited. I would have been
pleased if I could have gotten Code2000 to work, but it isn't
monospaced. There aren't too many options for full set unicode fonts
in monospaced.

To me, it doesn't seem to make sense to allow the channel encoding to
be different than what the console [or the bypass though the wide
Write()] is set to be at.

This isn't like a socket where what is on the other end is not in our
control, or with files where they could be under any encoding scheme.

Both ends are under our control. IOW, say we set the channel encoding
to be unicode. It makes perfect sense to me that each time the
Tcl_DriverOutputProc is called, the driver shall know the buffer is
uint* and ready for WriteConsoleW(). Or if we have cp932 set for
Japanese CJK, call SetConsoleCP(932) to make the output buffer set for
that, then use WriteConsoleA() in our Tcl_DriverOutputProc.

TclWinOpenConsoleChannel() does assert the input buffer codepage to
the generic layer's encoding, but if the user chages it, no such
notice back to the driver to call SetConsoleCP() is given. We should
be in control of both sides.

But the troble with Tcl's generic layer is it doesn't tell the driver
what encoding we've changed to be.

Sure would be nice if drivers could overload the generic layer
fconfigures to either just get notices for such changes or to trap
them to apply rules such as "trap -blocking 1 because this custom
driver for XYZ doesn't support it" and return an error before the
generic layer can accept the new setting.

Having to verify each call to writeConsoleBytes to make sure we've set
the proper input and output buffer codepages and switched to the wide
call for an encoding of unicode would be a huge waste of processing
time, but would be unfortunetely correct.

static BOOL
writeConsoleBytes(
    HANDLE hConsole,
    const VOID *lpBuffer,
    DWORD nbytes,
    LPDWORD nbyteswritten)
{
    DWORD ntchars;
    BOOL result;
    int codepage;
    Tcl_DSting dstr;

    Tcl_GetChannelOption(NULL, infoPtr->channel, "-encoding", &dstr);
    if (Tcl_StringMatch(Tcl_DStringValue(&dstr), "unicode")) {

        // Don't worry about codepage as we're bypassing it.
        result = WriteConsoleW(hConsole, lpBuffer, nbytes / 2,
                &ntchars, NULL);
        if (nbyteswritten)
                *nbyteswritten = ntchars * 2;
    } else {

        // Reassert the encoding from this channel to the cosole
        // itself (make same).
        sscanf(Tcl_DStringValue(&dstr), "cp%d", &codepage);
        SetConsoleCP(codepage);
        SetConsoleOutputCP(codepage);
        result = WriteConsoleA(hConsole, lpBuffer, nbytes,
                &ntchars, NULL);
        if (nbyteswritten)
                *nbyteswritten = ntchars;
    }
    return result;
}

^-- untested, but looks right.
Received on Tue Jan 3 03:09:34 2006