Project

General

Profile

Feature #6418 » ansi_escape2.diff

usa (Usaku NAKAMURA), 05/09/2012 06:29 PM

View differences:

win32/win32.c (working copy)
HANDLE handle;
DWORD dwMode, reslen;
VALUE str = strarg;
rb_encoding *utf16 = rb_enc_find("UTF-16LE");
char *ptr;
long len;
static WORD attr = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED;
if (disable) return -1L;
handle = (HANDLE)_osfhnd(fd);
......
!rb_econv_has_convpath_p(rb_enc_name(rb_enc_get(str)), "UTF-16LE"))
return -1L;
str = rb_str_encode(str, rb_enc_from_encoding(rb_enc_find("UTF-16LE")),
str = rb_str_encode(str, rb_enc_from_encoding(utf16),
ECONV_INVALID_REPLACE|ECONV_UNDEF_REPLACE, Qnil);
if (!WriteConsoleW(handle, (LPWSTR)RSTRING_PTR(str), RSTRING_LEN(str)/2,
&reslen, NULL)) {
if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
disable = TRUE;
return -1L;
ptr = RSTRING_PTR(str);
len = RSTRING_LEN(str);
while (len > 0) {
long pos = rb_memsearch(L"\x1B[", 4, ptr, len, utf16);
long curlen = pos < 0 ? len : pos;
if (curlen > 0) {
if (!WriteConsoleW(handle, (LPWSTR)ptr, curlen/2, &reslen, NULL)) {
if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
disable = TRUE;
return -1L;
}
ptr += curlen;
len -= curlen;
}
if (pos >= 0) {
int seq = -1;
int rev = 0;
ptr += 4;
len -= 4;
while (len > 1) {
WCHAR w = *(LPWSTR)ptr;
if (w == L';' || w == L'm') {
ptr += 2;
len -= 2;
switch (seq) {
case 0:
attr = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED;
rev = 0;
break;
case 4:
#ifndef COMMON_LVB_UNDERSCORE
#define COMMON_LVB_UNDERSCORE 0x8000
#endif
attr |= COMMON_LVB_UNDERSCORE;
break;
case 7:
rev = 1;
break;
case 30:
attr &= ~(FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED);
case 17:
case 31:
attr = attr & ~(FOREGROUND_BLUE | FOREGROUND_GREEN) | FOREGROUND_RED;
break;
case 18:
case 32:
attr = attr & ~(FOREGROUND_BLUE | FOREGROUND_RED) | FOREGROUND_GREEN;
break;
case 19:
case 33:
attr = attr & ~FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED;
break;
case 20:
case 34:
attr = attr & ~(FOREGROUND_GREEN | FOREGROUND_RED) | FOREGROUND_BLUE;
break;
case 21:
case 35:
attr = attr & ~FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED;
break;
case 22:
case 36:
attr = attr & ~FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN;
break;
case 23:
case 37:
attr |= FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED;
break;
case 40:
attr &= ~(BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED);
case 41:
attr = attr & ~(BACKGROUND_BLUE | BACKGROUND_GREEN) | BACKGROUND_RED;
break;
case 42:
attr = attr & ~(BACKGROUND_BLUE | BACKGROUND_RED) | BACKGROUND_GREEN;
break;
case 43:
attr = attr & ~BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED;
break;
case 44:
attr = attr & ~(BACKGROUND_GREEN | BACKGROUND_RED) | BACKGROUND_BLUE;
break;
case 45:
attr = attr & ~BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_RED;
break;
case 46:
attr = attr & ~BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_GREEN;
break;
case 47:
attr |= BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED;
break;
}
if (rev) {
WORD attr2 = attr & ~(FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED) | ((attr & (FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED)) << 4) | ((attr & (BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED)) >> 4);
SetConsoleTextAttribute(handle, attr2);
}
else {
SetConsoleTextAttribute(handle, attr);
}
if (w == L'm') {
break;
}
seq = -1;
}
else if (w == L'A') {
CONSOLE_SCREEN_BUFFER_INFO csbi;
ptr += 2;
len -= 2;
if (GetConsoleScreenBufferInfo(handle, &csbi)) {
csbi.dwCursorPosition.Y -= (seq < 0 ? 1 : seq);
if (csbi.dwCursorPosition.Y >= 0) {
SetConsoleCursorPosition(handle, csbi.dwCursorPosition);
}
}
seq = -1;
}
else if (w == L'B') {
CONSOLE_SCREEN_BUFFER_INFO csbi;
ptr += 2;
len -= 2;
if (GetConsoleScreenBufferInfo(handle, &csbi)) {
csbi.dwCursorPosition.Y += (seq < 0 ? 1 : seq);
if (csbi.dwCursorPosition.Y < csbi.dwSize.Y) {
SetConsoleCursorPosition(handle, csbi.dwCursorPosition);
}
}
seq = -1;
}
else if (w == L'C') {
CONSOLE_SCREEN_BUFFER_INFO csbi;
ptr += 2;
len -= 2;
if (GetConsoleScreenBufferInfo(handle, &csbi)) {
csbi.dwCursorPosition.X += (seq < 0 ? 1 : seq);
if (csbi.dwCursorPosition.X < csbi.dwSize.X) {
SetConsoleCursorPosition(handle, csbi.dwCursorPosition);
}
}
seq = -1;
}
else if (w == L'D') {
CONSOLE_SCREEN_BUFFER_INFO csbi;
ptr += 2;
len -= 2;
if (GetConsoleScreenBufferInfo(handle, &csbi)) {
csbi.dwCursorPosition.X -= (seq < 0 ? 1 : seq);
if (csbi.dwCursorPosition.X >= 0) {
SetConsoleCursorPosition(handle, csbi.dwCursorPosition);
}
}
seq = -1;
}
else if (w == L'K') {
CONSOLE_SCREEN_BUFFER_INFO csbi;
COORD pos;
DWORD written;
ptr += 2;
len -= 2;
if (GetConsoleScreenBufferInfo(handle, &csbi)) {
switch (seq) {
case 0: /* erase after cursor */
case -1:
FillConsoleOutputCharacterW(handle, L' ', csbi.dwSize.X - csbi.dwCursorPosition.X, csbi.dwCursorPosition, &written);
break;
case 1: /* erase before cursor */
pos.X = 0;
pos.Y = csbi.dwCursorPosition.Y;
FillConsoleOutputCharacterW(handle, L' ', csbi.dwCursorPosition.X, pos, &written);
break;
case 2: /* erase entire line */
pos.X = 0;
pos.Y = csbi.dwCursorPosition.Y;
FillConsoleOutputCharacterW(handle, L' ', csbi.dwSize.X, pos, &written);
break;
}
}
seq = -1;
break;
}
else if (w >= L'0' && w <= L'9') {
ptr += 2;
len -= 2;
seq = (seq < 0 ? 0 : seq * 10) + w - L'0';
}
else {
break;
}
}
}
}
RB_GC_GUARD(str);
return (long)reslen;
}
(2-2/4)