Reputation: 5338
I have a Java application which uses ANSI escape sequences to display colours, position the cursor, etc.
It works fine under regular Unices,
and also under xterm
and mintty
(in Cygwin),
but I'm having trouble running it under the cygwin
terminal (i. e. bash
launched from cmd.exe
).
As you can see from the screen shot:
escape sequences are output "as is", without processing. On the other hand, I can easily run smth like echo -e '\033[1;31mTest'
-- and colour text will be just there.
At the same time, if I launch exactly the same application from a Midnight Commander subshell, escape sequences produced by the application will be interpreted correctly:
Also, if I log in to my Windows box using SSH (i. e. replace the local connection with the remote one, but retain the same cygwin
terminal), again, escape sequences are processed just fine.
It looks like when a subshell of some kind is created (mc
or ssh
), the terminal is put into some other mode. But playing with stty
wasn't helpful, nor was export'ing TERM=ansi
.
Could anyone please suggest any solution?
I'm running
CYGWIN_NT-6.3 UNIT-725 2.5.1(0.297/5/3) 2016-04-21 22:14 x86_64 Cygwin
and Windows 8.1.
Upvotes: 3
Views: 1732
Reputation: 5338
In order for an application to be able to use ANSI escape sequences when launched from cmd.exe
(TERM=cygwin
), either the application itself needs to be linked with cygwin1.dll
, or its output needs to be filtered through another one which is (e. g.: mc
or ssh
subshells).
The same C program:
#include <stdio.h>
int main() {
const char esc = 0x1b;
printf("%c[31;91;1mHello, World!%c[0m\n", esc, esc);
return 0;
}
supports colour output when compiled with Cygwin GCC:
$ ldd test-ansi-escape.exe
ntdll.dll => /cygdrive/c/Windows/SYSTEM32/ntdll.dll (0x7ffeeb450000)
KERNEL32.DLL => /cygdrive/c/Windows/system32/KERNEL32.DLL (0x7ffee92c0000)
KERNELBASE.dll => /cygdrive/c/Windows/system32/KERNELBASE.dll (0x7ffee8700000)
cygwin1.dll => /usr/bin/cygwin1.dll (0x180040000)
but displays garbage like
←[31;91;1mHello, World!←[0m
when compiled with MSVC or mingw64-x86_64-gcc
:
$ ldd test-ansi-escape.exe
ntdll.dll => /cygdrive/c/Windows/SYSTEM32/ntdll.dll (0x7ffeeb450000)
ntdll.dll => /cygdrive/c/Windows/SYSTEM32/ntdll.dll (0x770a0000)
wow64.dll => /cygdrive/c/Windows/SYSTEM32/wow64.dll (0x76fd0000)
wow64win.dll => /cygdrive/c/Windows/system32/wow64win.dll (0x77020000)
wow64cpu.dll => /cygdrive/c/Windows/system32/wow64cpu.dll (0x77090000)
??? => ??? (0x1040000)
KERNEL32.DLL => /cygdrive/c/Windows/SYSTEM32/KERNEL32.DLL (0x76480000)
??? => ??? (0x1040000)
??? => ??? (0x1040000)
KERNEL32.DLL => /cygdrive/c/Windows/SYSTEM32/KERNEL32.DLL (0x76480000)
KERNELBASE.dll => /cygdrive/c/Windows/SYSTEM32/KERNELBASE.dll (0x74b40000)
MSVCR120D.dll => /cygdrive/c/Windows/SYSTEM32/MSVCR120D.dll (0x62b90000)
An alternative solution is using ConEmu as the external output filter (bash.exe
running as a direct child of ConEmu.exe
). This approach doesn't require linking with cygwin1.dll
, as output filtering is performed by ConEmu itself. The downside is that ConEmu's support for escape sequences is limited (particularly, it doesn't understand the VT100 alternate character set used for line drawing).
Upvotes: 7