mirror of
https://github.com/VARCem/PDCurses.git
synced 2026-09-23 23:35:20 +00:00
256 colors for the Windows console. This version doesn't allow
init_color() or color_content() for colors 16-255, just uses Windows' predefined palette. To Do: Determine when to revert to COLORS = 16; fix for ConEmu if possible.
This commit is contained in:
216
wincon/pdcdisp.c
216
wincon/pdcdisp.c
@@ -80,56 +80,201 @@ void PDC_gotoyx(int row, int col)
|
||||
SetConsoleCursorPosition(pdc_con_out, coord);
|
||||
}
|
||||
|
||||
void _set_ansi_color(short f, short b, attr_t attr)
|
||||
{
|
||||
char esc[64], *p;
|
||||
static short oldf = -1;
|
||||
static short oldb = -1;
|
||||
static short oldu = 0;
|
||||
short tmp, underline;
|
||||
|
||||
if (f < 16)
|
||||
f = pdc_curstoansi[f];
|
||||
|
||||
if (b < 16)
|
||||
b = pdc_curstoansi[b];
|
||||
|
||||
if (attr & A_REVERSE)
|
||||
{
|
||||
tmp = f;
|
||||
f = b;
|
||||
b = tmp;
|
||||
}
|
||||
underline = !!(attr & A_UNDERLINE);
|
||||
|
||||
p = esc + sprintf(esc, "\x1b[");
|
||||
|
||||
if (f != oldf)
|
||||
{
|
||||
if (f < 8)
|
||||
p += sprintf(p, "%d", f + 30);
|
||||
else if (f < 16)
|
||||
p += sprintf(p, "%d", f + 82);
|
||||
else
|
||||
p += sprintf(p, "38;5;%d", f);
|
||||
|
||||
oldf = f;
|
||||
}
|
||||
|
||||
if (b != oldb)
|
||||
{
|
||||
if (strlen(esc) > 2)
|
||||
p += sprintf(p, ";");
|
||||
|
||||
if (b < 8)
|
||||
p += sprintf(p, "%d", b + 40);
|
||||
else if (b < 16)
|
||||
p += sprintf(p, "%d", b + 92);
|
||||
else
|
||||
p += sprintf(p, "48;5;%d", b);
|
||||
|
||||
oldb = b;
|
||||
}
|
||||
|
||||
if (underline != oldu)
|
||||
{
|
||||
if (strlen(esc) > 2)
|
||||
p += sprintf(p, ";");
|
||||
|
||||
if (underline)
|
||||
p += sprintf(p, "4");
|
||||
else
|
||||
p += sprintf(p, "24");
|
||||
|
||||
oldu = underline;
|
||||
}
|
||||
|
||||
if (strlen(esc) > 2)
|
||||
{
|
||||
sprintf(p, "m");
|
||||
SetConsoleMode(pdc_con_out, 0x0015);
|
||||
WriteConsoleA(pdc_con_out, esc, strlen(esc), NULL, NULL);
|
||||
SetConsoleMode(pdc_con_out, 0x0010);
|
||||
}
|
||||
}
|
||||
|
||||
void _new_packet(attr_t attr, int lineno, int x, int len, const chtype *srcp)
|
||||
{
|
||||
union {
|
||||
CHAR_INFO ci[512];
|
||||
#ifdef PDC_WIDE
|
||||
WCHAR text[512];
|
||||
#else
|
||||
char text[512];
|
||||
#endif
|
||||
} buffer;
|
||||
WORD mapped_attr;
|
||||
int j;
|
||||
short fore, back;
|
||||
bool blink, ansi;
|
||||
|
||||
PDC_pair_content(PAIR_NUMBER(attr), &fore, &back);
|
||||
ansi = (fore >= 16 || back >= 16);
|
||||
blink = (SP->termattrs & A_BLINK) && (attr & A_BLINK);
|
||||
|
||||
if (blink)
|
||||
{
|
||||
attr &= ~A_BLINK;
|
||||
if (blinked_off)
|
||||
attr &= ~(A_UNDERLINE | A_RIGHT | A_LEFT);
|
||||
}
|
||||
|
||||
if (attr & A_BOLD)
|
||||
fore |= 8;
|
||||
if (attr & A_BLINK)
|
||||
back |= 8;
|
||||
|
||||
if (!ansi)
|
||||
{
|
||||
fore = pdc_curstoreal[fore];
|
||||
back = pdc_curstoreal[back];
|
||||
|
||||
if (attr & A_REVERSE)
|
||||
mapped_attr = back | (fore << 4);
|
||||
else
|
||||
mapped_attr = fore | (back << 4);
|
||||
|
||||
if (attr & A_UNDERLINE)
|
||||
mapped_attr |= COMMON_LVB_UNDERSCORE;
|
||||
if (attr & A_LEFT)
|
||||
mapped_attr |= COMMON_LVB_GRID_LVERTICAL;
|
||||
if (attr & A_RIGHT)
|
||||
mapped_attr |= COMMON_LVB_GRID_RVERTICAL;
|
||||
}
|
||||
|
||||
for (j = 0; j < len; j++)
|
||||
{
|
||||
chtype ch = srcp[j];
|
||||
#ifdef CHTYPE_LONG
|
||||
if (ch & A_ALTCHARSET && !(ch & 0xff80))
|
||||
ch = acs_map[ch & 0x7f];
|
||||
#endif
|
||||
if (blink && blinked_off)
|
||||
ch = ' ';
|
||||
|
||||
if (ansi)
|
||||
buffer.text[j] = ch & A_CHARTEXT;
|
||||
else
|
||||
{
|
||||
buffer.ci[j].Attributes = mapped_attr;
|
||||
buffer.ci[j].Char.UnicodeChar = ch & A_CHARTEXT;
|
||||
}
|
||||
}
|
||||
|
||||
if (ansi)
|
||||
{
|
||||
PDC_gotoyx(lineno, x);
|
||||
_set_ansi_color(fore, back, attr);
|
||||
#ifdef PDC_WIDE
|
||||
WriteConsoleW(pdc_con_out, buffer.text, len, NULL, NULL);
|
||||
#else
|
||||
WriteConsoleA(pdc_con_out, buffer.text, len, NULL, NULL);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
COORD bufSize, bufPos;
|
||||
SMALL_RECT sr;
|
||||
|
||||
bufPos.X = bufPos.Y = 0;
|
||||
bufSize.X = len;
|
||||
bufSize.Y = 1;
|
||||
|
||||
sr.Top = sr.Bottom = lineno;
|
||||
sr.Left = x;
|
||||
sr.Right = x + len - 1;
|
||||
|
||||
WriteConsoleOutput(pdc_con_out, buffer.ci, bufSize, bufPos, &sr);
|
||||
}
|
||||
}
|
||||
|
||||
/* update the given physical line to look like the corresponding line in
|
||||
curscr */
|
||||
|
||||
void PDC_transform_line(int lineno, int x, int len, const chtype *srcp)
|
||||
{
|
||||
CHAR_INFO ci[512];
|
||||
int j;
|
||||
COORD bufSize, bufPos;
|
||||
SMALL_RECT sr;
|
||||
bool sysblink;
|
||||
attr_t old_attr, attr;
|
||||
int i, j;
|
||||
|
||||
PDC_LOG(("PDC_transform_line() - called: lineno=%d\n", lineno));
|
||||
|
||||
bufPos.X = bufPos.Y = 0;
|
||||
old_attr = *srcp & (A_ATTRIBUTES ^ A_ALTCHARSET);
|
||||
|
||||
bufSize.X = len;
|
||||
bufSize.Y = 1;
|
||||
|
||||
sr.Top = lineno;
|
||||
sr.Bottom = lineno;
|
||||
sr.Left = x;
|
||||
sr.Right = x + len - 1;
|
||||
|
||||
sysblink = !!(SP->termattrs & A_BLINK);
|
||||
|
||||
for (j = 0; j < len; j++)
|
||||
for (i = 1, j = 1; j < len; i++, j++)
|
||||
{
|
||||
chtype att, ch = srcp[j];
|
||||
att = ch;
|
||||
attr = srcp[i] & (A_ATTRIBUTES ^ A_ALTCHARSET);
|
||||
|
||||
if (sysblink && (att & A_BLINK))
|
||||
if (attr != old_attr)
|
||||
{
|
||||
att &= ~A_BLINK;
|
||||
if (blinked_off)
|
||||
att &= ~(A_UNDERLINE | A_RIGHT | A_LEFT);
|
||||
_new_packet(old_attr, lineno, x, i, srcp);
|
||||
old_attr = attr;
|
||||
srcp += i;
|
||||
x += i;
|
||||
i = 0;
|
||||
}
|
||||
|
||||
ci[j].Attributes = pdc_atrtab[att >> PDC_ATTR_SHIFT];
|
||||
|
||||
#ifdef CHTYPE_LONG
|
||||
if (ch & A_ALTCHARSET && !(ch & 0xff80))
|
||||
ch = acs_map[ch & 0x7f];
|
||||
#endif
|
||||
if (sysblink && blinked_off && (ch & A_BLINK))
|
||||
ch = ' ';
|
||||
|
||||
ci[j].Char.UnicodeChar = ch & A_CHARTEXT;
|
||||
}
|
||||
|
||||
WriteConsoleOutput(pdc_con_out, ci, bufSize, bufPos, &sr);
|
||||
_new_packet(old_attr, lineno, x, i, srcp);
|
||||
}
|
||||
|
||||
void PDC_blink_text(void)
|
||||
@@ -156,5 +301,6 @@ void PDC_blink_text(void)
|
||||
}
|
||||
}
|
||||
|
||||
PDC_gotoyx(SP->cursrow, SP->curscol);
|
||||
pdc_last_blink = GetTickCount();
|
||||
}
|
||||
|
||||
105
wincon/pdcscrn.c
105
wincon/pdcscrn.c
@@ -4,15 +4,9 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef CHTYPE_LONG
|
||||
# define PDC_OFFSET 128
|
||||
#else
|
||||
# define PDC_OFFSET 8
|
||||
#endif
|
||||
|
||||
/* COLOR_PAIR to attribute encoding table. */
|
||||
|
||||
WORD *pdc_atrtab = (WORD *)NULL;
|
||||
static struct {short f, b;} atrtab[PDC_COLOR_PAIRS];
|
||||
|
||||
HANDLE std_con_out = INVALID_HANDLE_VALUE;
|
||||
HANDLE pdc_con_out = INVALID_HANDLE_VALUE;
|
||||
@@ -20,7 +14,7 @@ HANDLE pdc_con_in = INVALID_HANDLE_VALUE;
|
||||
|
||||
DWORD pdc_quick_edit;
|
||||
|
||||
static short curstoreal[16], realtocurs[16] =
|
||||
static short realtocurs[16] =
|
||||
{
|
||||
COLOR_BLACK, COLOR_BLUE, COLOR_GREEN, COLOR_CYAN, COLOR_RED,
|
||||
COLOR_MAGENTA, COLOR_YELLOW, COLOR_WHITE, COLOR_BLACK + 8,
|
||||
@@ -28,6 +22,16 @@ static short curstoreal[16], realtocurs[16] =
|
||||
COLOR_MAGENTA + 8, COLOR_YELLOW + 8, COLOR_WHITE + 8
|
||||
};
|
||||
|
||||
static short ansitocurs[16] =
|
||||
{
|
||||
COLOR_BLACK, COLOR_RED, COLOR_GREEN, COLOR_YELLOW, COLOR_BLUE,
|
||||
COLOR_MAGENTA, COLOR_CYAN, COLOR_WHITE, COLOR_BLACK + 8,
|
||||
COLOR_RED + 8, COLOR_GREEN + 8, COLOR_YELLOW + 8, COLOR_BLUE + 8,
|
||||
COLOR_MAGENTA + 8, COLOR_CYAN + 8, COLOR_WHITE + 8
|
||||
};
|
||||
|
||||
short pdc_curstoreal[16], pdc_curstoansi[16];
|
||||
|
||||
enum { PDC_RESTORE_NONE, PDC_RESTORE_BUFFER };
|
||||
|
||||
/* Struct for storing console registry keys, and for use with the
|
||||
@@ -330,10 +334,6 @@ void PDC_scr_free(void)
|
||||
{
|
||||
if (SP)
|
||||
free(SP);
|
||||
if (pdc_atrtab)
|
||||
free(pdc_atrtab);
|
||||
|
||||
pdc_atrtab = (WORD *)NULL;
|
||||
|
||||
if (pdc_con_out != std_con_out)
|
||||
{
|
||||
@@ -359,13 +359,15 @@ int PDC_scr_open(int argc, char **argv)
|
||||
PDC_LOG(("PDC_scr_open() - called\n"));
|
||||
|
||||
SP = calloc(1, sizeof(SCREEN));
|
||||
pdc_atrtab = calloc(PDC_COLOR_PAIRS * PDC_OFFSET, sizeof(WORD));
|
||||
|
||||
if (!SP || !pdc_atrtab)
|
||||
if (!SP)
|
||||
return ERR;
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
curstoreal[realtocurs[i]] = i;
|
||||
{
|
||||
pdc_curstoreal[realtocurs[i]] = i;
|
||||
pdc_curstoansi[ansitocurs[i]] = i;
|
||||
}
|
||||
|
||||
std_con_out =
|
||||
pdc_con_out = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
@@ -598,41 +600,14 @@ void PDC_save_screen_mode(int i)
|
||||
|
||||
void PDC_init_pair(short pair, short fg, short bg)
|
||||
{
|
||||
WORD att;
|
||||
chtype i;
|
||||
|
||||
fg = curstoreal[fg];
|
||||
bg = curstoreal[bg];
|
||||
|
||||
for (i = 0; i < PDC_OFFSET; i++)
|
||||
{
|
||||
short f = fg, b = bg;
|
||||
|
||||
if (i & (A_BOLD >> PDC_ATTR_SHIFT))
|
||||
f |= 8;
|
||||
if (i & (A_BLINK >> PDC_ATTR_SHIFT))
|
||||
b |= 8;
|
||||
|
||||
if (i & (A_REVERSE >> PDC_ATTR_SHIFT))
|
||||
att = b | (f << 4);
|
||||
else
|
||||
att = f | (b << 4);
|
||||
|
||||
if (i & (A_UNDERLINE >> PDC_ATTR_SHIFT))
|
||||
att |= COMMON_LVB_UNDERSCORE;
|
||||
if (i & (A_LEFT >> PDC_ATTR_SHIFT))
|
||||
att |= COMMON_LVB_GRID_LVERTICAL;
|
||||
if (i & (A_RIGHT >> PDC_ATTR_SHIFT))
|
||||
att |= COMMON_LVB_GRID_RVERTICAL;
|
||||
|
||||
pdc_atrtab[pair * PDC_OFFSET + i] = att;
|
||||
}
|
||||
atrtab[pair].f = fg;
|
||||
atrtab[pair].b = bg;
|
||||
}
|
||||
|
||||
int PDC_pair_content(short pair, short *fg, short *bg)
|
||||
{
|
||||
*fg = realtocurs[pdc_atrtab[pair * PDC_OFFSET] & 0x0F];
|
||||
*bg = realtocurs[(pdc_atrtab[pair * PDC_OFFSET] & 0xF0) >> 4];
|
||||
*fg = atrtab[pair].f;
|
||||
*bg = atrtab[pair].b;
|
||||
|
||||
return OK;
|
||||
}
|
||||
@@ -644,17 +619,20 @@ bool PDC_can_change_color(void)
|
||||
|
||||
int PDC_color_content(short color, short *red, short *green, short *blue)
|
||||
{
|
||||
COLORREF *color_table = _get_colors();
|
||||
|
||||
if (color_table)
|
||||
if (color < 16)
|
||||
{
|
||||
DWORD col = color_table[curstoreal[color]];
|
||||
COLORREF *color_table = _get_colors();
|
||||
|
||||
*red = DIVROUND(GetRValue(col) * 1000, 255);
|
||||
*green = DIVROUND(GetGValue(col) * 1000, 255);
|
||||
*blue = DIVROUND(GetBValue(col) * 1000, 255);
|
||||
if (color_table)
|
||||
{
|
||||
DWORD col = color_table[pdc_curstoreal[color]];
|
||||
|
||||
return OK;
|
||||
*red = DIVROUND(GetRValue(col) * 1000, 255);
|
||||
*green = DIVROUND(GetGValue(col) * 1000, 255);
|
||||
*blue = DIVROUND(GetBValue(col) * 1000, 255);
|
||||
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
|
||||
return ERR;
|
||||
@@ -662,16 +640,19 @@ int PDC_color_content(short color, short *red, short *green, short *blue)
|
||||
|
||||
int PDC_init_color(short color, short red, short green, short blue)
|
||||
{
|
||||
COLORREF *color_table = _get_colors();
|
||||
|
||||
if (color_table)
|
||||
if (color < 16)
|
||||
{
|
||||
color_table[curstoreal[color]] =
|
||||
RGB(DIVROUND(red * 255, 1000),
|
||||
DIVROUND(green * 255, 1000),
|
||||
DIVROUND(blue * 255, 1000));
|
||||
COLORREF *color_table = _get_colors();
|
||||
|
||||
return _set_colors();
|
||||
if (color_table)
|
||||
{
|
||||
color_table[pdc_curstoreal[color]] =
|
||||
RGB(DIVROUND(red * 255, 1000),
|
||||
DIVROUND(green * 255, 1000),
|
||||
DIVROUND(blue * 255, 1000));
|
||||
|
||||
return _set_colors();
|
||||
}
|
||||
}
|
||||
|
||||
return ERR;
|
||||
|
||||
@@ -89,7 +89,7 @@ void PDC_set_title(const char *title)
|
||||
int PDC_set_blink(bool blinkon)
|
||||
{
|
||||
if (pdc_color_started)
|
||||
COLORS = 16;
|
||||
COLORS = 256;
|
||||
|
||||
if (blinkon)
|
||||
{
|
||||
|
||||
@@ -13,16 +13,10 @@
|
||||
# define _CRT_SECURE_NO_DEPRECATE 1 /* kill nonsense warnings */
|
||||
#endif
|
||||
|
||||
#ifdef CHTYPE_LONG
|
||||
# define PDC_ATTR_SHIFT 17
|
||||
#else
|
||||
# define PDC_ATTR_SHIFT 8
|
||||
#endif
|
||||
|
||||
extern WORD *pdc_atrtab;
|
||||
extern HANDLE pdc_con_out, pdc_con_in;
|
||||
extern DWORD pdc_quick_edit;
|
||||
extern DWORD pdc_last_blink;
|
||||
extern short pdc_curstoreal[16], pdc_curstoansi[16];
|
||||
|
||||
extern int PDC_get_buffer_rows(void);
|
||||
extern void PDC_blink_text(void);
|
||||
|
||||
Reference in New Issue
Block a user