static int win32_setattrs(char_u *name, int attrs);
static int win32_set_archive(char_u *name);
+#ifndef FEAT_GUI_W32
+static int vtp_working = 0;
+static void vtp_init();
+static void vtp_exit();
+static int vtp_printf(char *format, ...);
+static void vtp_sgr_bulk(int arg);
+static void vtp_sgr_bulks(int argc, int *argv);
+
+static guicolor_T save_console_bg_rgb;
+static guicolor_T save_console_fg_rgb;
+
+# ifdef FEAT_TERMGUICOLORS
+# define USE_VTP (vtp_working && p_tgc)
+# else
+# define USE_VTP 0
+# endif
+
+static void set_console_color_rgb(void);
+static void reset_console_color_rgb(void);
+#endif
+
+/* This flag is newly created from Windows 10 */
+#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
+# define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
+#endif
+
#ifndef FEAT_GUI_W32
static int suppress_winsize = 1; /* don't fiddle with console */
#endif
static BOOL win8_or_later = FALSE;
#ifndef FEAT_GUI_W32
+/* Dynamic loading for portability */
+typedef struct _DYN_CONSOLE_SCREEN_BUFFER_INFOEX
+{
+ ULONG cbSize;
+ COORD dwSize;
+ COORD dwCursorPosition;
+ WORD wAttributes;
+ SMALL_RECT srWindow;
+ COORD dwMaximumWindowSize;
+ WORD wPopupAttributes;
+ BOOL bFullscreenSupported;
+ COLORREF ColorTable[16];
+} DYN_CONSOLE_SCREEN_BUFFER_INFOEX, *PDYN_CONSOLE_SCREEN_BUFFER_INFOEX;
+typedef BOOL (WINAPI *PfnGetConsoleScreenBufferInfoEx)(HANDLE, PDYN_CONSOLE_SCREEN_BUFFER_INFOEX);
+static PfnGetConsoleScreenBufferInfoEx pGetConsoleScreenBufferInfoEx;
+typedef BOOL (WINAPI *PfnSetConsoleScreenBufferInfoEx)(HANDLE, PDYN_CONSOLE_SCREEN_BUFFER_INFOEX);
+static PfnSetConsoleScreenBufferInfoEx pSetConsoleScreenBufferInfoEx;
+static BOOL has_csbiex = FALSE;
+
+/*
+ * Get version number including build number
+ */
+typedef BOOL (WINAPI *PfnRtlGetVersion)(LPOSVERSIONINFOW);
+# define MAKE_VER(major, minor, build) \
+ (((major) << 24) | ((minor) << 16) | (build))
+
+ static DWORD
+get_build_number(void)
+{
+ OSVERSIONINFOW osver = {sizeof(OSVERSIONINFOW)};
+ HMODULE hNtdll;
+ PfnRtlGetVersion pRtlGetVersion;
+ DWORD ver = MAKE_VER(0, 0, 0);
+
+ hNtdll = GetModuleHandle("ntdll.dll");
+ if (hNtdll != NULL)
+ {
+ pRtlGetVersion =
+ (PfnRtlGetVersion)GetProcAddress(hNtdll, "RtlGetVersion");
+ pRtlGetVersion(&osver);
+ ver = MAKE_VER(min(osver.dwMajorVersion, 255),
+ min(osver.dwMinorVersion, 255),
+ min(osver.dwBuildNumber, 32767));
+ }
+ return ver;
+}
+
+
/*
* Version of ReadConsoleInput() that works with IME.
* Works around problems on Windows 8.
/* set termcap codes to current text attributes */
update_tcap(g_attrCurrent);
+ swap_tcap();
GetConsoleCursorInfo(g_hConOut, &g_cci);
GetConsoleMode(g_hConIn, &g_cmodein);
#ifdef FEAT_CLIPBOARD
win_clip_init();
#endif
+
+ vtp_init();
}
/*
{
exiting = TRUE;
+ vtp_exit();
+
stoptermcap();
if (g_fWindInitCalled)
settmode(TMODE_COOK);
if (g_fMouseActive)
cmodein |= ENABLE_MOUSE_INPUT;
#endif
- cmodeout &= ~(ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT);
+ cmodeout &= ~(
+#ifdef FEAT_TERMGUICOLORS
+ /* Do not turn off the ENABLE_PROCESSRD_OUTPUT flag when using
+ * VTP. */
+ ((vtp_working) ? 0 : ENABLE_PROCESSED_OUTPUT) |
+#else
+ ENABLE_PROCESSED_OUTPUT |
+#endif
+ ENABLE_WRAP_AT_EOL_OUTPUT);
bEnableHandler = TRUE;
}
else /* cooked */
* to restore the actual contents of the buffer.
*/
RestoreConsoleBuffer(&g_cbTermcap, FALSE);
+ reset_console_color_rgb();
SetConsoleWindowInfo(g_hConOut, TRUE, &g_cbTermcap.Info.srWindow);
Rows = g_cbTermcap.Info.dwSize.Y;
Columns = g_cbTermcap.Info.dwSize.X;
* size. We will use this as the size of our editing environment.
*/
ClearConsoleBuffer(g_attrCurrent);
+ set_console_color_rgb();
ResizeConBufAndWindow(g_hConOut, Columns, Rows);
}
cb = &g_cbNonTermcap;
#endif
RestoreConsoleBuffer(cb, p_rs);
+ reset_console_color_rgb();
SetConsoleCursorInfo(g_hConOut, &g_cci);
if (p_rs || exiting)
DWORD dwDummy;
FillConsoleOutputCharacter(g_hConOut, ' ', n, coord, &dwDummy);
- FillConsoleOutputAttribute(g_hConOut, g_attrCurrent, n, coord, &dwDummy);
+
+ if (!USE_VTP)
+ FillConsoleOutputAttribute(g_hConOut, g_attrCurrent, n, coord, &dwDummy);
+ else
+ FillConsoleOutputAttribute(g_hConOut, 0, n, coord, &dwDummy);
}
clear_screen(void)
{
g_coord.X = g_coord.Y = 0;
- clear_chars(g_coord, Rows * Columns);
+
+ if (!USE_VTP)
+ clear_chars(g_coord, Rows * Columns);
+ else
+ {
+ set_console_color_rgb();
+ gotoxy(1, 1);
+ vtp_printf("\033[2J");
+ }
}
static void
clear_to_end_of_display(void)
{
- clear_chars(g_coord, (Rows - g_coord.Y - 1)
+ COORD save = g_coord;
+
+ if (!USE_VTP)
+ clear_chars(g_coord, (Rows - g_coord.Y - 1)
* Columns + (Columns - g_coord.X));
+ else
+ {
+ set_console_color_rgb();
+ gotoxy(g_coord.X + 1, g_coord.Y + 1);
+ vtp_printf("\033[0J");
+
+ gotoxy(save.X + 1, save.Y + 1);
+ g_coord = save;
+ }
}
static void
clear_to_end_of_line(void)
{
- clear_chars(g_coord, Columns - g_coord.X);
+ COORD save = g_coord;
+
+ if (!USE_VTP)
+ clear_chars(g_coord, Columns - g_coord.X);
+ else
+ {
+ set_console_color_rgb();
+ gotoxy(g_coord.X + 1, g_coord.Y + 1);
+ vtp_printf("\033[0K");
+
+ gotoxy(save.X + 1, save.Y + 1);
+ g_coord = save;
+ }
}
g_srScrollRegion.Top = top;
g_srScrollRegion.Right = right;
g_srScrollRegion.Bottom = bottom;
+
+ if (USE_VTP)
+ vtp_printf("\033[%d;%dr", top + 1, bottom + 1);
}
source.Right = g_srScrollRegion.Right;
source.Bottom = g_srScrollRegion.Bottom - cLines;
- fill.Char.AsciiChar = ' ';
- fill.Attributes = g_attrCurrent;
+ if (!USE_VTP)
+ {
+ fill.Char.AsciiChar = ' ';
+ fill.Attributes = g_attrCurrent;
- ScrollConsoleScreenBuffer(g_hConOut, &source, NULL, dest, &fill);
+ ScrollConsoleScreenBuffer(g_hConOut, &source, NULL, dest, &fill);
+ }
+ else
+ {
+ set_console_color_rgb();
+
+ gotoxy(1, source.Top + 1);
+ vtp_printf("\033[%dT", cLines);
+ }
/* Here we have to deal with a win32 console flake: If the scroll
* region looks like abc and we scroll c to a and fill with d we get
source.Right = g_srScrollRegion.Right;
source.Bottom = g_srScrollRegion.Bottom;
- fill.Char.AsciiChar = ' ';
- fill.Attributes = g_attrCurrent;
+ if (!USE_VTP)
+ {
+ fill.Char.AsciiChar = ' ';
+ fill.Attributes = g_attrCurrent;
- ScrollConsoleScreenBuffer(g_hConOut, &source, NULL, dest, &fill);
+ ScrollConsoleScreenBuffer(g_hConOut, &source, NULL, dest, &fill);
+ }
+ else
+ {
+ set_console_color_rgb();
+
+ gotoxy(1, source.Top + 1);
+ vtp_printf("\033[%dS", cLines);
+ }
/* Here we have to deal with a win32 console flake: If the scroll
* region looks like abc and we scroll c to a and fill with d we get
/* external cursor coords are 1-based; internal are 0-based */
g_coord.X = x - 1;
g_coord.Y = y - 1;
- SetConsoleCursorPosition(g_hConOut, g_coord);
+
+ if (!USE_VTP)
+ SetConsoleCursorPosition(g_hConOut, g_coord);
+ else
+ vtp_printf("\033[%d;%dH", y, x);
}
{
g_attrCurrent = (g_attrCurrent & 0xf0) + (wAttr & 0x0f);
- SetConsoleTextAttribute(g_hConOut, g_attrCurrent);
+ if (!USE_VTP)
+ SetConsoleTextAttribute(g_hConOut, g_attrCurrent);
+ else
+ vtp_sgr_bulk(wAttr);
}
{
g_attrCurrent = (g_attrCurrent & 0x0f) + ((wAttr & 0x0f) << 4);
- SetConsoleTextAttribute(g_hConOut, g_attrCurrent);
+ if (!USE_VTP)
+ SetConsoleTextAttribute(g_hConOut, g_attrCurrent);
+ else
+ vtp_sgr_bulk(wAttr);
}
static void
normvideo(void)
{
- textattr(g_attrDefault);
+ if (!USE_VTP)
+ textattr(g_attrDefault);
+ else
+ vtp_sgr_bulk(0);
}
standout(void)
{
g_attrPreStandout = g_attrCurrent;
+
textattr((WORD) (g_attrCurrent|FOREGROUND_INTENSITY|BACKGROUND_INTENSITY));
}
standend(void)
{
if (g_attrPreStandout)
- {
textattr(g_attrPreStandout);
- g_attrPreStandout = 0;
- }
+
+ g_attrPreStandout = 0;
}
cterm_normal_fg_color = (g_attrDefault & 0xf) + 1;
cterm_normal_bg_color = ((g_attrDefault >> 4) & 0xf) + 1;
- if (T_ME[0] == ESC && T_ME[1] == '|')
+ if (
+#ifdef FEAT_TERMGUICOLORS
+ !p_tgc &&
+#endif
+ T_ME[0] == ESC && T_ME[1] == '|')
{
p = T_ME + 2;
n = getdigits(&p);
cterm_normal_bg_color = ((n >> 4) & 0xf) + 1;
}
}
+#ifdef FEAT_TERMGUICOLORS
+ cterm_normal_fg_gui_color = INVALCOLOR;
+ cterm_normal_bg_gui_color = INVALCOLOR;
+#endif
}
coordOrigin, &dwDummy);
Sleep(15); /* wait for 15 msec */
- WriteConsoleOutputAttribute(g_hConOut, oldattrs, Rows * Columns,
+ if (!USE_VTP)
+ WriteConsoleOutputAttribute(g_hConOut, oldattrs, Rows * Columns,
coordOrigin, &dwDummy);
vim_free(oldattrs);
}
unicodebuf, unibuflen);
cells = mb_string2cells(pchBuf, cbToWrite);
- FillConsoleOutputAttribute(g_hConOut, g_attrCurrent, cells,
- coord, &written);
- /* When writing fails or didn't write a single character, pretend one
- * character was written, otherwise we get stuck. */
- if (WriteConsoleOutputCharacterW(g_hConOut, unicodebuf, length,
- coord, &cchwritten) == 0
- || cchwritten == 0)
- cchwritten = 1;
+
+ if (!USE_VTP)
+ {
+ FillConsoleOutputAttribute(g_hConOut, g_attrCurrent, cells,
+ coord, &written);
+ /* When writing fails or didn't write a single character, pretend one
+ * character was written, otherwise we get stuck. */
+ if (WriteConsoleOutputCharacterW(g_hConOut, unicodebuf, length,
+ coord, &cchwritten) == 0
+ || cchwritten == 0)
+ cchwritten = 1;
+ }
+ else
+ {
+ if (WriteConsoleW(g_hConOut, unicodebuf, length, &cchwritten,
+ NULL) == 0 || cchwritten == 0)
+ cchwritten = 1;
+ }
if (cchwritten == length)
{
else
#endif
{
- FillConsoleOutputAttribute(g_hConOut, g_attrCurrent, cbToWrite,
- coord, &written);
- /* When writing fails or didn't write a single character, pretend one
- * character was written, otherwise we get stuck. */
- if (WriteConsoleOutputCharacter(g_hConOut, (LPCSTR)pchBuf, cbToWrite,
- coord, &written) == 0
- || written == 0)
- written = 1;
+ if (!USE_VTP)
+ {
+ FillConsoleOutputAttribute(g_hConOut, g_attrCurrent, cbToWrite,
+ coord, &written);
+ /* When writing fails or didn't write a single character, pretend one
+ * character was written, otherwise we get stuck. */
+ if (WriteConsoleOutputCharacter(g_hConOut, (LPCSTR)pchBuf, cbToWrite,
+ coord, &written) == 0
+ || written == 0)
+ written = 1;
+ }
+ else
+ {
+ if (WriteConsole(g_hConOut, (LPCSTR)pchBuf, cbToWrite, &written,
+ NULL) == 0 || written == 0)
+ written = 1;
+ }
g_coord.X += (SHORT) written;
}
char_u *old_s = s;
#endif
char_u *p;
- int arg1 = 0, arg2 = 0;
+ int arg1 = 0, arg2 = 0, argc = 0, args[16];
switch (s[2])
{
- /* one or two numeric arguments, separated by ';' */
-
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
- p = s + 2;
- arg1 = getdigits(&p); /* no check for length! */
- if (p > s + len)
- break;
-
- if (*p == ';')
+ p = s + 1;
+ do
{
++p;
- arg2 = getdigits(&p); /* no check for length! */
+ args[argc] = getdigits(&p);
+ argc += (argc < 15) ? 1 : 0;
if (p > s + len)
break;
+ } while (*p == ';');
+
+ if (p > s + len)
+ break;
- if (*p == 'H')
- gotoxy(arg2, arg1);
- else if (*p == 'r')
- set_scroll_region(0, arg1 - 1, Columns - 1, arg2 - 1);
+ arg1 = args[0];
+ arg2 = args[1];
+ if (*p == 'm')
+ {
+ if (argc == 1 && args[0] == 0)
+ normvideo();
+ else if (argc == 1)
+ {
+ if (USE_VTP)
+ textcolor((WORD) arg1);
+ else
+ textattr((WORD) arg1);
+ }
+ else if (USE_VTP)
+ vtp_sgr_bulks(argc, args);
}
- else if (*p == 'A')
+ else if (argc == 2 && *p == 'H')
{
- /* move cursor up arg1 lines in same column */
- gotoxy(g_coord.X + 1,
- max(g_srScrollRegion.Top, g_coord.Y - arg1) + 1);
+ gotoxy(arg2, arg1);
}
- else if (*p == 'C')
+ else if (argc == 2 && *p == 'r')
{
- /* move cursor right arg1 columns in same line */
- gotoxy(min(g_srScrollRegion.Right, g_coord.X + arg1) + 1,
- g_coord.Y + 1);
+ set_scroll_region(0, arg1 - 1, Columns - 1, arg2 - 1);
}
- else if (*p == 'H')
+ else if (argc == 1 && *p == 'A')
{
- gotoxy(1, arg1);
+ gotoxy(g_coord.X + 1,
+ max(g_srScrollRegion.Top, g_coord.Y - arg1) + 1);
}
- else if (*p == 'L')
+ else if (argc == 1 && *p == 'b')
{
- insert_lines(arg1);
+ textbackground((WORD) arg1);
}
- else if (*p == 'm')
+ else if (argc == 1 && *p == 'C')
{
- if (arg1 == 0)
- normvideo();
- else
- textattr((WORD) arg1);
+ gotoxy(min(g_srScrollRegion.Right, g_coord.X + arg1) + 1,
+ g_coord.Y + 1);
}
- else if (*p == 'f')
+ else if (argc == 1 && *p == 'f')
{
textcolor((WORD) arg1);
}
- else if (*p == 'b')
+ else if (argc == 1 && *p == 'H')
{
- textbackground((WORD) arg1);
+ gotoxy(1, arg1);
}
- else if (*p == 'M')
+ else if (argc == 1 && *p == 'L')
+ {
+ insert_lines(arg1);
+ }
+ else if (argc == 1 && *p == 'M')
{
delete_lines(arg1);
}
s = p + 1;
break;
-
- /* Three-character escape sequences */
-
case 'A':
- /* move cursor up one line in same column */
gotoxy(g_coord.X + 1,
max(g_srScrollRegion.Top, g_coord.Y - 1) + 1);
goto got3;
goto got3;
case 'C':
- /* move cursor right one column in same line */
gotoxy(min(g_srScrollRegion.Right, g_coord.X + 1) + 1,
g_coord.Y + 1);
goto got3;
return 0;
}
+
+#ifndef FEAT_GUI_W32
+
+/*
+ * Support for 256 colors and 24-bit colors was added in Windows 10
+ * version 1703 (Creators update).
+ */
+# define VTP_FIRST_SUPPORT_BUILD MAKE_VER(10, 0, 15063)
+
+ static void
+vtp_init(void)
+{
+ DWORD ver, mode;
+ HMODULE hKerneldll;
+ DYN_CONSOLE_SCREEN_BUFFER_INFOEX csbi;
+
+ ver = get_build_number();
+ vtp_working = (ver >= VTP_FIRST_SUPPORT_BUILD) ? 1 : 0;
+ GetConsoleMode(g_hConOut, &mode);
+ mode |= (ENABLE_PROCESSED_OUTPUT | ENABLE_VIRTUAL_TERMINAL_PROCESSING);
+ if (SetConsoleMode(g_hConOut, mode) == 0)
+ vtp_working = 0;
+
+ /* Use functions supported from Vista */
+ hKerneldll = GetModuleHandle("kernel32.dll");
+ if (hKerneldll != NULL)
+ {
+ pGetConsoleScreenBufferInfoEx =
+ (PfnGetConsoleScreenBufferInfoEx)GetProcAddress(
+ hKerneldll, "GetConsoleScreenBufferInfoEx");
+ pSetConsoleScreenBufferInfoEx =
+ (PfnSetConsoleScreenBufferInfoEx)GetProcAddress(
+ hKerneldll, "SetConsoleScreenBufferInfoEx");
+ if (pGetConsoleScreenBufferInfoEx != NULL
+ && pSetConsoleScreenBufferInfoEx != NULL)
+ has_csbiex = TRUE;
+ }
+
+ csbi.cbSize = sizeof(csbi);
+ if (has_csbiex)
+ pGetConsoleScreenBufferInfoEx(g_hConOut, &csbi);
+ save_console_bg_rgb = (guicolor_T)csbi.ColorTable[0];
+ save_console_fg_rgb = (guicolor_T)csbi.ColorTable[7];
+
+ set_console_color_rgb();
+}
+
+ static void
+vtp_exit(void)
+{
+ reset_console_color_rgb();
+}
+
+ static int
+vtp_printf(
+ char *format,
+ ...)
+{
+ char_u buf[100];
+ va_list list;
+ DWORD result;
+
+ va_start(list, format);
+ vim_vsnprintf((char *)buf, 100, (char *)format, list);
+ va_end(list);
+ WriteConsoleA(g_hConOut, buf, (DWORD)STRLEN(buf), &result, NULL);
+ return (int)result;
+}
+
+ static void
+vtp_sgr_bulk(
+ int arg)
+{
+ int args[1];
+
+ args[0] = arg;
+ vtp_sgr_bulks(1, args);
+}
+
+ static void
+vtp_sgr_bulks(
+ int argc,
+ int *args
+)
+{
+ /* 2('\033[') + 4('255.') * 16 + NUL */
+ char_u buf[2 + (4 * 16) + 1];
+ char_u *p;
+ int i;
+
+ p = buf;
+ *p++ = '\033';
+ *p++ = '[';
+
+ for (i = 0; i < argc; ++i)
+ {
+ p += vim_snprintf((char *)p, 4, "%d", args[i] & 0xff);
+ *p++ = ';';
+ }
+ p--;
+ *p++ = 'm';
+ *p = NUL;
+ vtp_printf((char *)buf);
+}
+
+ static void
+set_console_color_rgb(void)
+{
+# ifdef FEAT_TERMGUICOLORS
+ DYN_CONSOLE_SCREEN_BUFFER_INFOEX csbi;
+ int id;
+ guicolor_T fg = INVALCOLOR;
+ guicolor_T bg = INVALCOLOR;
+
+ if (!USE_VTP)
+ return;
+
+ id = syn_name2id((char_u *)"Normal");
+ if (id > 0)
+ syn_id2colors(id, &fg, &bg);
+ if (fg == INVALCOLOR)
+ fg = 0xc0c0c0; /* white text */
+ if (bg == INVALCOLOR)
+ bg = 0x000000; /* black background */
+ fg = (GetRValue(fg) << 16) | (GetGValue(fg) << 8) | GetBValue(fg);
+ bg = (GetRValue(bg) << 16) | (GetGValue(bg) << 8) | GetBValue(bg);
+
+ csbi.cbSize = sizeof(csbi);
+ if (has_csbiex)
+ pGetConsoleScreenBufferInfoEx(g_hConOut, &csbi);
+
+ csbi.cbSize = sizeof(csbi);
+ csbi.srWindow.Right += 1;
+ csbi.srWindow.Bottom += 1;
+ csbi.ColorTable[0] = (COLORREF)bg;
+ csbi.ColorTable[7] = (COLORREF)fg;
+ if (has_csbiex)
+ pSetConsoleScreenBufferInfoEx(g_hConOut, &csbi);
+# endif
+}
+
+ static void
+reset_console_color_rgb(void)
+{
+# ifdef FEAT_TERMGUICOLORS
+ DYN_CONSOLE_SCREEN_BUFFER_INFOEX csbi;
+
+ csbi.cbSize = sizeof(csbi);
+ if (has_csbiex)
+ pGetConsoleScreenBufferInfoEx(g_hConOut, &csbi);
+
+ csbi.cbSize = sizeof(csbi);
+ csbi.srWindow.Right += 1;
+ csbi.srWindow.Bottom += 1;
+ csbi.ColorTable[0] = (COLORREF)save_console_bg_rgb;
+ csbi.ColorTable[7] = (COLORREF)save_console_fg_rgb;
+ if (has_csbiex)
+ pSetConsoleScreenBufferInfoEx(g_hConOut, &csbi);
+# endif
+}
+
+ void
+control_console_color_rgb(void)
+{
+ if (USE_VTP)
+ set_console_color_rgb();
+ else
+ reset_console_color_rgb();
+}
+
+ int
+has_vtp_working(void)
+{
+ return vtp_working;
+}
+
+ int
+use_vtp(void)
+{
+ return USE_VTP;
+}
+
+#endif
static struct builtin_term *find_builtin_term(char_u *name);
static void parse_builtin_tcap(char_u *s);
-static void term_color(char_u *s, int n);
static void gather_termleader(void);
#ifdef FEAT_TERMRESPONSE
static void req_codes_from_term(void);
# else
{(int)KS_CS, "\033|%i%d;%dr"},/* scroll region */
# endif
+# ifdef FEAT_TERMGUICOLORS
+ {(int)KS_8F, "\033|38;2;%lu;%lu;%lum"},
+ {(int)KS_8B, "\033|48;2;%lu;%lu;%lum"},
+# endif
{K_UP, "\316H"},
{K_DOWN, "\316P"},
may_req_termresponse();
#endif
+#if defined(WIN3264) && !defined(FEAT_GUI) && defined(FEAT_TERMGUICOLORS)
+ if (STRCMP(term, "win32") == 0)
+ set_color_count((p_tgc) ? 256 : 16);
+#endif
+
return OK;
}
}
#endif
- void
-term_fg_color(int n)
-{
- /* Use "AF" termcap entry if present, "Sf" entry otherwise */
- if (*T_CAF)
- term_color(T_CAF, n);
- else if (*T_CSF)
- term_color(T_CSF, n);
-}
-
- void
-term_bg_color(int n)
-{
- /* Use "AB" termcap entry if present, "Sb" entry otherwise */
- if (*T_CAB)
- term_color(T_CAB, n);
- else if (*T_CSB)
- term_color(T_CSB, n);
-}
-
static void
term_color(char_u *s, int n)
{
char buf[20];
- int i = 2; /* index in s[] just after <Esc>[ or CSI */
+ int i = *s == CSI ? 1 : 2;
+ /* index in s[] just after <Esc>[ or CSI */
/* Special handling of 16 colors, because termcap can't handle it */
/* Also accept "\e[3%dm" for TERMINFO, it is sometimes used */
OUT_STR(tgoto((char *)s, 0, n));
}
+ void
+term_fg_color(int n)
+{
+ /* Use "AF" termcap entry if present, "Sf" entry otherwise */
+ if (*T_CAF)
+ term_color(T_CAF, n);
+ else if (*T_CSF)
+ term_color(T_CSF, n);
+}
+
+ void
+term_bg_color(int n)
+{
+ /* Use "AB" termcap entry if present, "Sb" entry otherwise */
+ if (*T_CAB)
+ term_color(T_CAB, n);
+ else if (*T_CSB)
+ term_color(T_CSB, n);
+}
+
#if defined(FEAT_TERMGUICOLORS) || defined(PROTO)
#define RED(rgb) (((long_u)(rgb) >> 16) & 0xFF)
++p;
}
}
+
+struct ks_tbl_s
+{
+ int code; /* value of KS_ */
+ char *vtp; /* code in vtp mode */
+ char *buf; /* buffer in non-vtp mode */
+ char *vbuf; /* buffer in vtp mode */
+};
+
+static struct ks_tbl_s ks_tbl[] =
+{
+ {(int)KS_ME, "\033|0m" }, /* normal */
+ {(int)KS_MR, "\033|7m" }, /* reverse */
+ {(int)KS_MD, "\033|1m" }, /* bold */
+ {(int)KS_SO, "\033|91m"}, /* standout: bright red text */
+ {(int)KS_SE, "\033|39m"}, /* standout end: default color */
+ {(int)KS_CZH, "\033|95m"}, /* italic: bright magenta text */
+ {(int)KS_CZR, "\033|0m",}, /* italic end */
+ {(int)KS_US, "\033|4m",}, /* underscore */
+ {(int)KS_UE, "\033|24m"}, /* underscore end */
+ {(int)KS_NAME, NULL}
+};
+
+ static struct builtin_term *
+find_first_tcap(
+ char_u *name,
+ int code)
+{
+ struct builtin_term *p;
+
+ p = find_builtin_term(name);
+ while (p->bt_string != NULL)
+ {
+ if (p->bt_entry == code)
+ return p;
+ p++;
+ }
+ return NULL;
+}
+
+/*
+ * For Win32 console: replace the sequence immediately after termguicolors.
+ */
+ void
+swap_tcap(void)
+{
+# ifdef FEAT_TERMGUICOLORS
+ static int init = 0;
+ static int last_tgc;
+ struct ks_tbl_s *ks;
+ struct builtin_term *bt;
+
+ /* buffer initialization */
+ if (init == 0)
+ {
+ ks = ks_tbl;
+ while (ks->vtp != NULL)
+ {
+ bt = find_first_tcap(DEFAULT_TERM, ks->code);
+ ks->buf = bt->bt_string;
+ ks->vbuf = ks->vtp;
+ ks++;
+ }
+ init++;
+ last_tgc = p_tgc;
+ return;
+ }
+
+ if (last_tgc != p_tgc)
+ {
+ if (p_tgc)
+ {
+ /* switch to special character sequence */
+ ks = ks_tbl;
+ while (ks->vtp != NULL)
+ {
+ bt = find_first_tcap(DEFAULT_TERM, ks->code);
+ ks->buf = bt->bt_string;
+ bt->bt_string = ks->vbuf;
+ ks++;
+ }
+ }
+ else
+ {
+ /* switch to index color */
+ ks = ks_tbl;
+ while (ks->vtp != NULL)
+ {
+ bt = find_first_tcap(DEFAULT_TERM, ks->code);
+ ks->vbuf = bt->bt_string;
+ bt->bt_string = ks->buf;
+ ks++;
+ }
+ }
+
+ last_tgc = p_tgc;
+ }
+# endif
+}
+
#endif
#if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) || defined(PROTO)