|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2016-08-05 16:38 UTC] mlocati at gmail dot com
Description: ------------ The standard console of newer versions of Windows 10 add support to ANSI control codes. BTW, every console executable should explicitly tell to use that new feature with the flag ENABLE_VIRTUAL_TERMINAL_PROCESSING. For instance, at http://imgur.com/a/heYHm you see the the output of the application compiled from the code at the bottom. What about adding this flag to php.exe? #include <windows.h> #include <stdio.h> #ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING #define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004 #endif int main(void) { const char* sampleText = "\033[101;93m Yellow text on red background \033[0m\n"; HANDLE hStdout; DWORD handleMode; printf(sampleText); hStdout = GetStdHandle(STD_OUTPUT_HANDLE); GetConsoleMode(hStdout, &handleMode); handleMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING; SetConsoleMode(hStdout, handleMode); printf(sampleText); return 0; } Patches0001-Start-adding-VT100-support-for-Windows-v3 (last revision 2016-08-26 16:36 UTC by mlocati at gmail dot com)0001-Start-adding-VT100-support-for-Windows-v2 (last revision 2016-08-26 14:10 UTC by mlocati at gmail dot com) 0001-Start-adding-VT100-support-for-Windows.patch (last revision 2016-08-25 13:05 UTC by mlocati at gmail dot com) Pull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Thu Oct 30 22:00:01 2025 UTC |
@ab I fully understand that PHP scripts that output control codes on older systems (or when the ENABLE_VIRTUAL_TERMINAL_PROCESSING flag is not set for the current process) is really bad. That's why I suggested to use ini_get/ini_set. For instance, if the key used to control if the system has color support is 'win_vt100', a script could do something like this: <php ini_set('win_vt100', true); // returns true on success, false on failure if (ini_get('win_vt100')) { // print with ANSI control codes } else { // print without ANSI control codes } ?> About potential problems with the multibyte encodings: I think it's cmd.exe that takes care of it. BTW, to solve any problem and to be backward compatibile, vt100 could be disabled by default, and enabled only by the scripts that wants it. By using the ini_get/ini_set approach, people that wants ANSI codes enabled by default could set its value to true in their php.ini file. PS: I created a gist with a sample C code that implements the following functions: - check if the current console may have has colors - determine if the current console has colors - enable/disable color support for the current console You can find it here: https://gist.github.com/mlocati/21a9233ac83f7d3d7837535bc109b3b7@mlocati, amazing work, thanks! Your code can already be used as base framework to support the PHP integration. The issue with a new ini is, that there are already quite a few. That's the reason it's preferable to not to introduce a new one, especially if it's solvable another way. Regarding streams, my thought was like piece of code below: $fd = fopen("php://stdout", "r"); stream_context_set_option($fd, "stdio", "vt100_enabled", true); fwrite($fd, "\033[101;93m Yellow text on red background \033[0m\n"); fclose($fd); Same with php/stdin, etc. Any such stream is an isolated version of the original system descriptor, it won't affect all the output. OFC in fact, it might have to be a singleton, as it's only one I/O device at the end. But, as a stream is buffered, the decision whether to out/read the control sequences can be deferred.It could be cool ofc, to be able doing the same with the std I/O constants, fe like stream_context_set_option(STDOUT, "stdio", "vt100_enabled", true); but i'm not sure it can work exactly that way, but need to double check. Still, it could be an additional user land stream function to deliver the terminal info or switch to the required mode. Maybe a function were even more universal in that case, like stream_vt100_supported(STDOUT), etc. As it looks like after thinking a bit more, stripping the control sequences might be relatively easy. Should research more yet, but the sequences i've seen follow a particular pattern. Especially in the case of the direct I/O, one could just scroll over them. Even with the buffered stream, that might be not a big overhead. So probably shouldn't completely abandon that option. Another nice thing in streams could be a stream filter, which could be used for this task. The point with the mb encodings - I'd not write it off yet. We'll have to test and do some adjustments under circumstances. Fe for xterm, there are several dedicated versions for Asian encodings, the question is just why. One point with your latest test code - to check were whether it'd fail for a non standard terminal. There are nice alternative terminals like ConEmu, which already provide the functionality even on lower Windows versions. I'm not sure yet, how to solve this without checking any possible APIs. This would probably prevent the automation in some case, but is probably an overhead ATM and can be checked at some later stage. It's ATM only about the standard cmd.exe, anyway. It is already a very good start. If you've mood and time, you could already begin the PHP patch. Maybe you've a better idea how to integrate it with PHP, please let me know. Writing the tests for the prospective usage, then matching with internals to correct/improve the actual implementation might be next step. Thanks.I changed the stream_vt100_support function to accept strings ('php://stdout', 'php://stderr') instead of stream objects. This is a bit a workaround, but I really don't know how to determine the standard stream (stdin/stdout/stderr) from stream objects. See patch 0001-Start-adding-VT100-support-for-Windows-v3