mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-09 09:27:59 +00:00
Implement xterm 256-colour mode.
[originally from svn r4917] [this svn revision also touched putty-wishlist]
This commit is contained in:
parent
cdbb891f0f
commit
e4e10e494b
3
config.c
3
config.c
@ -1237,6 +1237,9 @@ void setup_config_box(struct controlbox *b, struct sesslist *sesslist,
|
||||
ctrl_checkbox(s, "Allow terminal to specify ANSI colours", 'i',
|
||||
HELPCTX(colours_ansi),
|
||||
dlg_stdcheckbox_handler, I(offsetof(Config,ansi_colour)));
|
||||
ctrl_checkbox(s, "Allow terminal to use xterm 256-colour mode", '2',
|
||||
HELPCTX(colours_xterm256), dlg_stdcheckbox_handler,
|
||||
I(offsetof(Config,xterm_256_colour)));
|
||||
ctrl_checkbox(s, "Bolded text is a different colour", 'b',
|
||||
HELPCTX(colours_bold),
|
||||
dlg_stdcheckbox_handler, I(offsetof(Config,bold_colour)));
|
||||
|
@ -1401,6 +1401,14 @@ If you have a particularly garish application, you might want to
|
||||
turn this option off and make PuTTY only use the default foreground
|
||||
and background colours.
|
||||
|
||||
\S{config-xtermcolour} \q{Allow terminal to use xterm 256-colour mode}
|
||||
|
||||
\cfg{winhelp-topic}{colours.xterm256}
|
||||
|
||||
This option is enabled by default. If it is disabled, PuTTY will
|
||||
ignore any control sequences sent by the server which use the
|
||||
extended 256-colour mode supported by recent versions of \cw{xterm}.
|
||||
|
||||
\S{config-boldcolour} \q{Bolded text is a different colour}
|
||||
|
||||
\cfg{winhelp-topic}{colours.bold}
|
||||
|
47
putty.h
47
putty.h
@ -80,24 +80,40 @@ typedef struct terminal_tag Terminal;
|
||||
*/
|
||||
#define UCSWIDE 0xDFFF
|
||||
|
||||
#define ATTR_NARROW 0x8000U
|
||||
#define ATTR_WIDE 0x4000U
|
||||
#define ATTR_BOLD 0x0400U
|
||||
#define ATTR_UNDER 0x0800U
|
||||
#define ATTR_REVERSE 0x1000U
|
||||
#define ATTR_BLINK 0x2000U
|
||||
#define ATTR_FGMASK 0x001FU
|
||||
#define ATTR_BGMASK 0x03E0U
|
||||
#define ATTR_COLOURS 0x03FFU
|
||||
#define ATTR_NARROW 0x800000U
|
||||
#define ATTR_WIDE 0x400000U
|
||||
#define ATTR_BOLD 0x040000U
|
||||
#define ATTR_UNDER 0x080000U
|
||||
#define ATTR_REVERSE 0x100000U
|
||||
#define ATTR_BLINK 0x200000U
|
||||
#define ATTR_FGMASK 0x0001FFU
|
||||
#define ATTR_BGMASK 0x03FE00U
|
||||
#define ATTR_COLOURS 0x03FFFFU
|
||||
#define ATTR_FGSHIFT 0
|
||||
#define ATTR_BGSHIFT 5
|
||||
#define ATTR_BGSHIFT 9
|
||||
|
||||
#define ATTR_DEFAULT 0x0128U /* bg 9, fg 8 */
|
||||
#define ATTR_DEFFG 0x0008U
|
||||
#define ATTR_DEFBG 0x0120U
|
||||
/*
|
||||
* The definitive list of colour numbers stored in terminal
|
||||
* attribute words is kept here. It is:
|
||||
*
|
||||
* - 0-7 are ANSI colours (KRGYBMCW).
|
||||
* - 8-15 are the bold versions of those colours.
|
||||
* - 16-255 are the remains of the xterm 256-colour mode (a
|
||||
* 216-colour cube with R at most significant and B at least,
|
||||
* followed by a uniform series of grey shades running between
|
||||
* black and white but not including either on grounds of
|
||||
* redundancy).
|
||||
* - 256 is default foreground
|
||||
* - 257 is default bold foreground
|
||||
* - 258 is default background
|
||||
* - 259 is default bold background
|
||||
* - 260 is cursor foreground
|
||||
* - 261 is cursor background
|
||||
*/
|
||||
|
||||
#define ATTR_CUR_AND (~(ATTR_BOLD|ATTR_REVERSE|ATTR_BLINK|ATTR_COLOURS))
|
||||
#define ATTR_CUR_XOR 0x016AU
|
||||
#define ATTR_DEFFG (256 << ATTR_FGSHIFT)
|
||||
#define ATTR_DEFBG (258 << ATTR_BGSHIFT)
|
||||
#define ATTR_DEFAULT (ATTR_DEFFG | ATTR_DEFBG)
|
||||
|
||||
struct sesslist {
|
||||
int nsessions;
|
||||
@ -447,6 +463,7 @@ struct config_tag {
|
||||
int bidi;
|
||||
/* Colour options */
|
||||
int ansi_colour;
|
||||
int xterm_256_colour;
|
||||
int system_colour;
|
||||
int try_palette;
|
||||
int bold_colour;
|
||||
|
@ -289,6 +289,7 @@ void save_open_settings(void *sesskey, int do_host, Config *cfg)
|
||||
write_setting_i(sesskey, "UseSystemColours", cfg->system_colour);
|
||||
write_setting_i(sesskey, "TryPalette", cfg->try_palette);
|
||||
write_setting_i(sesskey, "ANSIColour", cfg->ansi_colour);
|
||||
write_setting_i(sesskey, "Xterm256Colour", cfg->xterm_256_colour);
|
||||
write_setting_i(sesskey, "BoldAsColour", cfg->bold_colour);
|
||||
|
||||
for (i = 0; i < 22; i++) {
|
||||
@ -555,6 +556,7 @@ void load_open_settings(void *sesskey, int do_host, Config *cfg)
|
||||
gppi(sesskey, "UseSystemColours", 0, &cfg->system_colour);
|
||||
gppi(sesskey, "TryPalette", 0, &cfg->try_palette);
|
||||
gppi(sesskey, "ANSIColour", 1, &cfg->ansi_colour);
|
||||
gppi(sesskey, "Xterm256Colour", 1, &cfg->xterm_256_colour);
|
||||
gppi(sesskey, "BoldAsColour", 1, &cfg->bold_colour);
|
||||
|
||||
for (i = 0; i < 22; i++) {
|
||||
|
124
terminal.c
124
terminal.c
@ -554,15 +554,39 @@ static void makeliteral_attr(struct buf *b, termchar *c, unsigned long *state)
|
||||
* store a two-byte value with the top bit clear (indicating
|
||||
* just that value), or a four-byte value with the top bit set
|
||||
* (indicating the same value with its top bit clear).
|
||||
*
|
||||
* However, first I permute the bits of the attribute value, so
|
||||
* that the eight bits of colour (four in each of fg and bg)
|
||||
* which are never non-zero unless xterm 256-colour mode is in
|
||||
* use are placed higher up the word than everything else. This
|
||||
* ensures that attribute values remain 16-bit _unless_ the
|
||||
* user uses extended colour.
|
||||
*/
|
||||
if (c->attr < 0x8000) {
|
||||
add(b, (unsigned char)((c->attr >> 8) & 0xFF));
|
||||
add(b, (unsigned char)(c->attr & 0xFF));
|
||||
unsigned attr, colourbits;
|
||||
|
||||
attr = c->attr;
|
||||
|
||||
assert(ATTR_BGSHIFT > ATTR_FGSHIFT);
|
||||
|
||||
colourbits = (attr >> (ATTR_BGSHIFT + 4)) & 0xF;
|
||||
colourbits <<= 4;
|
||||
colourbits |= (attr >> (ATTR_FGSHIFT + 4)) & 0xF;
|
||||
|
||||
attr = (((attr >> (ATTR_BGSHIFT + 8)) << (ATTR_BGSHIFT + 4)) |
|
||||
(attr & ((1 << (ATTR_BGSHIFT + 4))-1)));
|
||||
attr = (((attr >> (ATTR_FGSHIFT + 8)) << (ATTR_FGSHIFT + 4)) |
|
||||
(attr & ((1 << (ATTR_FGSHIFT + 4))-1)));
|
||||
|
||||
attr |= (colourbits << (32-9));
|
||||
|
||||
if (attr < 0x8000) {
|
||||
add(b, (unsigned char)((attr >> 8) & 0xFF));
|
||||
add(b, (unsigned char)(attr & 0xFF));
|
||||
} else {
|
||||
add(b, (unsigned char)(((c->attr >> 24) & 0x7F) | 0x80));
|
||||
add(b, (unsigned char)((c->attr >> 16) & 0xFF));
|
||||
add(b, (unsigned char)((c->attr >> 8) & 0xFF));
|
||||
add(b, (unsigned char)(c->attr & 0xFF));
|
||||
add(b, (unsigned char)(((attr >> 24) & 0x7F) | 0x80));
|
||||
add(b, (unsigned char)((attr >> 16) & 0xFF));
|
||||
add(b, (unsigned char)((attr >> 8) & 0xFF));
|
||||
add(b, (unsigned char)(attr & 0xFF));
|
||||
}
|
||||
}
|
||||
static void makeliteral_cc(struct buf *b, termchar *c, unsigned long *state)
|
||||
@ -758,18 +782,30 @@ static void readliteral_chr(struct buf *b, termchar *c, termline *ldata,
|
||||
static void readliteral_attr(struct buf *b, termchar *c, termline *ldata,
|
||||
unsigned long *state)
|
||||
{
|
||||
int val;
|
||||
unsigned val, attr, colourbits;
|
||||
|
||||
val = get(b) << 8;
|
||||
val |= get(b);
|
||||
|
||||
if (val >= 0x8000) {
|
||||
val &= ~0x8000;
|
||||
val <<= 16;
|
||||
val |= get(b) << 8;
|
||||
val |= get(b);
|
||||
}
|
||||
|
||||
c->attr = val;
|
||||
colourbits = (val >> (32-9)) & 0xFF;
|
||||
attr = (val & ((1<<(32-9))-1));
|
||||
|
||||
attr = (((attr >> (ATTR_FGSHIFT + 4)) << (ATTR_FGSHIFT + 8)) |
|
||||
(attr & ((1 << (ATTR_FGSHIFT + 4))-1)));
|
||||
attr = (((attr >> (ATTR_BGSHIFT + 4)) << (ATTR_BGSHIFT + 8)) |
|
||||
(attr & ((1 << (ATTR_BGSHIFT + 4))-1)));
|
||||
|
||||
attr |= (colourbits >> 4) << (ATTR_BGSHIFT + 4);
|
||||
attr |= (colourbits & 0xF) << (ATTR_FGSHIFT + 4);
|
||||
|
||||
c->attr = attr;
|
||||
}
|
||||
static void readliteral_cc(struct buf *b, termchar *c, termline *ldata,
|
||||
unsigned long *state)
|
||||
@ -1024,6 +1060,14 @@ static void term_timer(void *ctx, long now)
|
||||
term_update(term);
|
||||
}
|
||||
|
||||
static void term_schedule_update(Terminal *term)
|
||||
{
|
||||
if (!term->window_update_pending) {
|
||||
term->window_update_pending = TRUE;
|
||||
term->next_update = schedule_timer(UPDATE_DELAY, term_timer, term);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Call this whenever the terminal window state changes, to queue
|
||||
* an update.
|
||||
@ -1031,10 +1075,7 @@ static void term_timer(void *ctx, long now)
|
||||
static void seen_disp_event(Terminal *term)
|
||||
{
|
||||
term->seen_disp_event = TRUE; /* for scrollback-reset-on-activity */
|
||||
if (!term->window_update_pending) {
|
||||
term->window_update_pending = TRUE;
|
||||
term->next_update = schedule_timer(UPDATE_DELAY, term_timer, term);
|
||||
}
|
||||
term_schedule_update(term);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -3471,7 +3512,7 @@ static void term_out(Terminal *term)
|
||||
/* xterm-style bright foreground */
|
||||
term->curr_attr &= ~ATTR_FGMASK;
|
||||
term->curr_attr |=
|
||||
((term->esc_args[i] - 90 + 16)
|
||||
((term->esc_args[i] - 90 + 8)
|
||||
<< ATTR_FGSHIFT);
|
||||
break;
|
||||
case 39: /* default-foreground */
|
||||
@ -3502,13 +3543,33 @@ static void term_out(Terminal *term)
|
||||
/* xterm-style bright background */
|
||||
term->curr_attr &= ~ATTR_BGMASK;
|
||||
term->curr_attr |=
|
||||
((term->esc_args[i] - 100 + 16)
|
||||
((term->esc_args[i] - 100 + 8)
|
||||
<< ATTR_BGSHIFT);
|
||||
break;
|
||||
case 49: /* default-background */
|
||||
term->curr_attr &= ~ATTR_BGMASK;
|
||||
term->curr_attr |= ATTR_DEFBG;
|
||||
break;
|
||||
case 38: /* xterm 256-colour mode */
|
||||
if (i+2 < term->esc_nargs &&
|
||||
term->esc_args[i+1] == 5) {
|
||||
term->curr_attr &= ~ATTR_FGMASK;
|
||||
term->curr_attr |=
|
||||
((term->esc_args[i+2] & 0xFF)
|
||||
<< ATTR_FGSHIFT);
|
||||
i += 2;
|
||||
}
|
||||
break;
|
||||
case 48: /* xterm 256-colour mode */
|
||||
if (i+2 < term->esc_nargs &&
|
||||
term->esc_args[i+1] == 5) {
|
||||
term->curr_attr &= ~ATTR_BGMASK;
|
||||
term->curr_attr |=
|
||||
((term->esc_args[i+2] & 0xFF)
|
||||
<< ATTR_BGSHIFT);
|
||||
i += 2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
set_erase_char(term);
|
||||
@ -3801,7 +3862,7 @@ static void term_out(Terminal *term)
|
||||
if (term->esc_args[0] >= 0 && term->esc_args[0] < 16) {
|
||||
long colour =
|
||||
(sco2ansicolour[term->esc_args[0] & 0x7] |
|
||||
((term->esc_args[0] & 0x8) << 1)) <<
|
||||
(term->esc_args[0] & 0x8)) <<
|
||||
ATTR_FGSHIFT;
|
||||
term->curr_attr &= ~ATTR_FGMASK;
|
||||
term->curr_attr |= colour;
|
||||
@ -3814,7 +3875,7 @@ static void term_out(Terminal *term)
|
||||
if (term->esc_args[0] >= 0 && term->esc_args[0] < 16) {
|
||||
long colour =
|
||||
(sco2ansicolour[term->esc_args[0] & 0x7] |
|
||||
((term->esc_args[0] & 0x8) << 1)) <<
|
||||
(term->esc_args[0] & 0x8)) <<
|
||||
ATTR_BGSHIFT;
|
||||
term->curr_attr &= ~ATTR_BGMASK;
|
||||
term->curr_attr |= colour;
|
||||
@ -4255,22 +4316,14 @@ static void term_out(Terminal *term)
|
||||
term->termstate = TOPLEVEL;
|
||||
term->curr_attr &= ~ATTR_FGMASK;
|
||||
term->curr_attr &= ~ATTR_BOLD;
|
||||
term->curr_attr |= (c & 0x7) << ATTR_FGSHIFT;
|
||||
if ((c & 0x8) || term->vt52_bold)
|
||||
term->curr_attr |= ATTR_BOLD;
|
||||
|
||||
term->curr_attr |= (c & 0xF) << ATTR_FGSHIFT;
|
||||
set_erase_char(term);
|
||||
break;
|
||||
case VT52_BG:
|
||||
term->termstate = TOPLEVEL;
|
||||
term->curr_attr &= ~ATTR_BGMASK;
|
||||
term->curr_attr &= ~ATTR_BLINK;
|
||||
term->curr_attr |= (c & 0x7) << ATTR_BGSHIFT;
|
||||
|
||||
/* Note: bold background */
|
||||
if (c & 0x8)
|
||||
term->curr_attr |= ATTR_BLINK;
|
||||
|
||||
term->curr_attr |= (c & 0xF) << ATTR_BGSHIFT;
|
||||
set_erase_char(term);
|
||||
break;
|
||||
#endif
|
||||
@ -4612,6 +4665,16 @@ static void do_paint(Terminal *term, Context ctx, int may_optimise)
|
||||
tattr = (tattr & ~(ATTR_FGMASK | ATTR_BGMASK)) |
|
||||
ATTR_DEFFG | ATTR_DEFBG;
|
||||
|
||||
if (!term->cfg.xterm_256_colour) {
|
||||
int colour;
|
||||
colour = (tattr & ATTR_FGMASK) >> ATTR_FGSHIFT;
|
||||
if (colour >= 16 && colour < 256)
|
||||
tattr = (tattr &~ ATTR_FGMASK) | ATTR_DEFFG;
|
||||
colour = (tattr & ATTR_BGMASK) >> ATTR_BGSHIFT;
|
||||
if (colour >= 16 && colour < 256)
|
||||
tattr = (tattr &~ ATTR_BGMASK) | ATTR_DEFBG;
|
||||
}
|
||||
|
||||
switch (tchar & CSET_MASK) {
|
||||
case CSET_ASCII:
|
||||
tchar = term->ucsdata->unitab_line[tchar & 0xFF];
|
||||
@ -4849,6 +4912,8 @@ void term_invalidate(Terminal *term)
|
||||
for (i = 0; i < term->rows; i++)
|
||||
for (j = 0; j < term->cols; j++)
|
||||
term->disptext[i]->chars[j].attr = ATTR_INVALID;
|
||||
|
||||
term_schedule_update(term);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -4875,10 +4940,7 @@ void term_paint(Terminal *term, Context ctx,
|
||||
if (immediately) {
|
||||
do_paint (term, ctx, FALSE);
|
||||
} else {
|
||||
if (!term->window_update_pending) {
|
||||
term->window_update_pending = TRUE;
|
||||
term->next_update = schedule_timer(UPDATE_DELAY, term_timer, term);
|
||||
}
|
||||
term_schedule_update(term);
|
||||
}
|
||||
}
|
||||
|
||||
|
106
unix/pterm.c
106
unix/pterm.c
@ -33,7 +33,10 @@
|
||||
#define CAT(x,y) CAT2(x,y)
|
||||
#define ASSERT(x) enum {CAT(assertion_,__LINE__) = 1 / (x)}
|
||||
|
||||
#define NCOLOURS (lenof(((Config *)0)->colours))
|
||||
/* Colours come in two flavours: configurable, and xterm-extended. */
|
||||
#define NCFGCOLOURS (lenof(((Config *)0)->colours))
|
||||
#define NEXTCOLOURS 240 /* 216 colour-cube plus 24 shades of grey */
|
||||
#define NALLCOLOURS (NCFGCOLOURS + NEXTCOLOURS)
|
||||
|
||||
GdkAtom compound_text_atom, utf8_string_atom;
|
||||
|
||||
@ -62,7 +65,7 @@ struct gui_data {
|
||||
} fontinfo[4];
|
||||
int xpos, ypos, gotpos, gravity;
|
||||
GdkCursor *rawcursor, *textcursor, *blankcursor, *currcursor;
|
||||
GdkColor cols[NCOLOURS];
|
||||
GdkColor cols[NALLCOLOURS];
|
||||
GdkColormap *colmap;
|
||||
wchar_t *pastein_data;
|
||||
int direct_to_font;
|
||||
@ -1336,15 +1339,12 @@ void set_window_background(struct gui_data *inst)
|
||||
void palette_set(void *frontend, int n, int r, int g, int b)
|
||||
{
|
||||
struct gui_data *inst = (struct gui_data *)frontend;
|
||||
static const int first[21] = {
|
||||
0, 2, 4, 6, 8, 10, 12, 14,
|
||||
1, 3, 5, 7, 9, 11, 13, 15,
|
||||
16, 17, 18, 20, 22
|
||||
};
|
||||
real_palette_set(inst, first[n], r, g, b);
|
||||
if (first[n] >= 18)
|
||||
real_palette_set(inst, first[n] + 1, r, g, b);
|
||||
if (first[n] == 18)
|
||||
if (n >= 16)
|
||||
n += 256 - 16;
|
||||
if (n > NALLCOLOURS)
|
||||
return;
|
||||
real_palette_set(inst, n, r, g, b);
|
||||
if (n == 258)
|
||||
set_window_background(inst);
|
||||
}
|
||||
|
||||
@ -1353,30 +1353,44 @@ void palette_reset(void *frontend)
|
||||
struct gui_data *inst = (struct gui_data *)frontend;
|
||||
/* This maps colour indices in inst->cfg to those used in inst->cols. */
|
||||
static const int ww[] = {
|
||||
6, 7, 8, 9, 10, 11, 12, 13,
|
||||
14, 15, 16, 17, 18, 19, 20, 21,
|
||||
0, 1, 2, 3, 4, 5
|
||||
256, 257, 258, 259, 260, 261,
|
||||
0, 8, 1, 9, 2, 10, 3, 11,
|
||||
4, 12, 5, 13, 6, 14, 7, 15
|
||||
};
|
||||
gboolean success[NCOLOURS];
|
||||
gboolean success[NALLCOLOURS];
|
||||
int i;
|
||||
|
||||
assert(lenof(ww) == NCOLOURS);
|
||||
assert(lenof(ww) == NCFGCOLOURS);
|
||||
|
||||
if (!inst->colmap) {
|
||||
inst->colmap = gdk_colormap_get_system();
|
||||
} else {
|
||||
gdk_colormap_free_colors(inst->colmap, inst->cols, NCOLOURS);
|
||||
gdk_colormap_free_colors(inst->colmap, inst->cols, NALLCOLOURS);
|
||||
}
|
||||
|
||||
for (i = 0; i < NCOLOURS; i++) {
|
||||
inst->cols[i].red = inst->cfg.colours[ww[i]][0] * 0x0101;
|
||||
inst->cols[i].green = inst->cfg.colours[ww[i]][1] * 0x0101;
|
||||
inst->cols[i].blue = inst->cfg.colours[ww[i]][2] * 0x0101;
|
||||
for (i = 0; i < NCFGCOLOURS; i++) {
|
||||
inst->cols[ww[i]].red = inst->cfg.colours[i][0] * 0x0101;
|
||||
inst->cols[ww[i]].green = inst->cfg.colours[i][1] * 0x0101;
|
||||
inst->cols[ww[i]].blue = inst->cfg.colours[i][2] * 0x0101;
|
||||
}
|
||||
|
||||
gdk_colormap_alloc_colors(inst->colmap, inst->cols, NCOLOURS,
|
||||
for (i = 0; i < NEXTCOLOURS; i++) {
|
||||
if (i < 216) {
|
||||
int r = i / 36, g = (i / 6) % 6, b = i % 6;
|
||||
inst->cols[i+16].red = r * 0x3333;
|
||||
inst->cols[i+16].green = g * 0x3333;
|
||||
inst->cols[i+16].blue = b * 0x3333;
|
||||
} else {
|
||||
int shade = i - 216;
|
||||
shade = (shade + 1) * 0xFFFF / (NEXTCOLOURS - 216 + 1);
|
||||
inst->cols[i+16].red = inst->cols[i+16].green =
|
||||
inst->cols[i+16].blue = shade;
|
||||
}
|
||||
}
|
||||
|
||||
gdk_colormap_alloc_colors(inst->colmap, inst->cols, NALLCOLOURS,
|
||||
FALSE, FALSE, success);
|
||||
for (i = 0; i < NCOLOURS; i++) {
|
||||
for (i = 0; i < NALLCOLOURS; i++) {
|
||||
if (!success[i])
|
||||
g_error("%s: couldn't allocate colour %d (#%02x%02x%02x)\n",
|
||||
appname, i, inst->cfg.colours[i][0],
|
||||
@ -1849,21 +1863,23 @@ void do_text_internal(Context ctx, int x, int y, wchar_t *text, int len,
|
||||
ncombining = 1;
|
||||
|
||||
nfg = ((attr & ATTR_FGMASK) >> ATTR_FGSHIFT);
|
||||
nfg = 2 * (nfg & 0xF) + (nfg & 0x10 ? 1 : 0);
|
||||
nbg = ((attr & ATTR_BGMASK) >> ATTR_BGSHIFT);
|
||||
nbg = 2 * (nbg & 0xF) + (nbg & 0x10 ? 1 : 0);
|
||||
if (attr & ATTR_REVERSE) {
|
||||
t = nfg;
|
||||
nfg = nbg;
|
||||
nbg = t;
|
||||
}
|
||||
if (inst->cfg.bold_colour && (attr & ATTR_BOLD))
|
||||
nfg |= 1;
|
||||
if (inst->cfg.bold_colour && (attr & ATTR_BLINK))
|
||||
nbg |= 1;
|
||||
if (inst->cfg.bold_colour && (attr & ATTR_BOLD)) {
|
||||
if (nfg < 16) nfg |= 8;
|
||||
else if (nfg >= 256) nfg |= 1;
|
||||
}
|
||||
if (inst->cfg.bold_colour && (attr & ATTR_BLINK)) {
|
||||
if (nbg < 16) nbg |= 8;
|
||||
else if (nbg >= 256) nbg |= 1;
|
||||
}
|
||||
if (attr & TATTR_ACTCURS) {
|
||||
nfg = NCOLOURS-2;
|
||||
nbg = NCOLOURS-1;
|
||||
nfg = 260;
|
||||
nbg = 261;
|
||||
}
|
||||
|
||||
fontid = shadow = 0;
|
||||
@ -2109,7 +2125,7 @@ void do_cursor(Context ctx, int x, int y, wchar_t *text, int len,
|
||||
* if it's passive.
|
||||
*/
|
||||
if (passive) {
|
||||
gdk_gc_set_foreground(gc, &inst->cols[NCOLOURS-1]);
|
||||
gdk_gc_set_foreground(gc, &inst->cols[261]);
|
||||
gdk_draw_rectangle(inst->pixmap, gc, 0,
|
||||
x*inst->font_width+inst->cfg.window_border,
|
||||
y*inst->font_height+inst->cfg.window_border,
|
||||
@ -2147,7 +2163,7 @@ void do_cursor(Context ctx, int x, int y, wchar_t *text, int len,
|
||||
length = inst->font_height;
|
||||
}
|
||||
|
||||
gdk_gc_set_foreground(gc, &inst->cols[NCOLOURS-1]);
|
||||
gdk_gc_set_foreground(gc, &inst->cols[NCFGCOLOURS-1]);
|
||||
if (passive) {
|
||||
for (i = 0; i < length; i++) {
|
||||
if (i % 2 == 0) {
|
||||
@ -2839,15 +2855,17 @@ void change_settings_menuitem(GtkMenuItem *item, gpointer data)
|
||||
{
|
||||
/* This maps colour indices in inst->cfg to those used in inst->cols. */
|
||||
static const int ww[] = {
|
||||
6, 7, 8, 9, 10, 11, 12, 13,
|
||||
14, 15, 16, 17, 18, 19, 20, 21,
|
||||
0, 1, 2, 3, 4, 5
|
||||
256, 257, 258, 259, 260, 261,
|
||||
0, 8, 1, 9, 2, 10, 3, 11,
|
||||
4, 12, 5, 13, 6, 14, 7, 15
|
||||
};
|
||||
struct gui_data *inst = (struct gui_data *)data;
|
||||
char *title = dupcat(appname, " Reconfiguration", NULL);
|
||||
Config cfg2, oldcfg;
|
||||
int i, need_size;
|
||||
|
||||
assert(lenof(ww) == NCFGCOLOURS);
|
||||
|
||||
cfg2 = inst->cfg; /* structure copy */
|
||||
|
||||
if (do_config_box(title, &cfg2, 1)) {
|
||||
@ -2877,20 +2895,20 @@ void change_settings_menuitem(GtkMenuItem *item, gpointer data)
|
||||
* have to the new default, on the assumption that the user
|
||||
* is most likely to want an immediate update.
|
||||
*/
|
||||
for (i = 0; i < NCOLOURS; i++) {
|
||||
if (oldcfg.colours[ww[i]][0] != cfg2.colours[ww[i]][0] ||
|
||||
oldcfg.colours[ww[i]][1] != cfg2.colours[ww[i]][1] ||
|
||||
oldcfg.colours[ww[i]][2] != cfg2.colours[ww[i]][2]) {
|
||||
real_palette_set(inst, i, cfg2.colours[ww[i]][0],
|
||||
cfg2.colours[ww[i]][1],
|
||||
cfg2.colours[ww[i]][2]);
|
||||
for (i = 0; i < NCFGCOLOURS; i++) {
|
||||
if (oldcfg.colours[i][0] != cfg2.colours[i][0] ||
|
||||
oldcfg.colours[i][1] != cfg2.colours[i][1] ||
|
||||
oldcfg.colours[i][2] != cfg2.colours[i][2]) {
|
||||
real_palette_set(inst, ww[i], cfg2.colours[i][0],
|
||||
cfg2.colours[i][1],
|
||||
cfg2.colours[i][2]);
|
||||
|
||||
/*
|
||||
* If the default background has changed, we must
|
||||
* repaint the space in between the window border
|
||||
* and the text area.
|
||||
*/
|
||||
if (i == 18) {
|
||||
if (i == 258) {
|
||||
set_window_background(inst);
|
||||
draw_backing_rect(inst);
|
||||
}
|
||||
|
@ -158,11 +158,13 @@ static enum {
|
||||
} und_mode;
|
||||
static int descent;
|
||||
|
||||
#define NCOLOURS 24
|
||||
static COLORREF colours[NCOLOURS];
|
||||
#define NCFGCOLOURS 24
|
||||
#define NEXTCOLOURS 240
|
||||
#define NALLCOLOURS (NCFGCOLOURS + NEXTCOLOURS)
|
||||
static COLORREF colours[NALLCOLOURS];
|
||||
static HPALETTE pal;
|
||||
static LPLOGPALETTE logpal;
|
||||
static RGBTRIPLE defpal[NCOLOURS];
|
||||
static RGBTRIPLE defpal[NALLCOLOURS];
|
||||
|
||||
static HWND hwnd;
|
||||
|
||||
@ -1023,16 +1025,29 @@ static void cfgtopalette(void)
|
||||
{
|
||||
int i;
|
||||
static const int ww[] = {
|
||||
6, 7, 8, 9, 10, 11, 12, 13,
|
||||
14, 15, 16, 17, 18, 19, 20, 21,
|
||||
0, 1, 2, 3, 4, 4, 5, 5
|
||||
256, 257, 258, 259, 260, 261,
|
||||
0, 8, 1, 9, 2, 10, 3, 11,
|
||||
4, 12, 5, 13, 6, 14, 7, 15
|
||||
};
|
||||
|
||||
for (i = 0; i < 24; i++) {
|
||||
for (i = 0; i < 22; i++) {
|
||||
int w = ww[i];
|
||||
defpal[i].rgbtRed = cfg.colours[w][0];
|
||||
defpal[i].rgbtGreen = cfg.colours[w][1];
|
||||
defpal[i].rgbtBlue = cfg.colours[w][2];
|
||||
defpal[w].rgbtRed = cfg.colours[i][0];
|
||||
defpal[w].rgbtGreen = cfg.colours[i][1];
|
||||
defpal[w].rgbtBlue = cfg.colours[i][2];
|
||||
}
|
||||
for (i = 0; i < NEXTCOLOURS; i++) {
|
||||
if (i < 216) {
|
||||
int r = i / 36, g = (i / 6) % 6, b = i % 6;
|
||||
defpal[i+16].rgbtRed = r * 0x33;
|
||||
defpal[i+16].rgbtGreen = g * 0x33;
|
||||
defpal[i+16].rgbtBlue = b * 0x33;
|
||||
} else {
|
||||
int shade = i - 216;
|
||||
shade = (shade + 1) * 0xFF / (NEXTCOLOURS - 216 + 1);
|
||||
defpal[i+16].rgbtRed = defpal[i+16].rgbtGreen =
|
||||
defpal[i+16].rgbtBlue = shade;
|
||||
}
|
||||
}
|
||||
|
||||
/* Override with system colours if appropriate */
|
||||
@ -1051,10 +1066,10 @@ static void systopalette(void)
|
||||
int i;
|
||||
static const struct { int nIndex; int norm; int bold; } or[] =
|
||||
{
|
||||
{ COLOR_WINDOWTEXT, 16, 17 }, /* Default Foreground */
|
||||
{ COLOR_WINDOW, 18, 19 }, /* Default Background */
|
||||
{ COLOR_HIGHLIGHTTEXT, 20, 21 }, /* Cursor Text */
|
||||
{ COLOR_HIGHLIGHT, 22, 23 }, /* Cursor Colour */
|
||||
{ COLOR_WINDOWTEXT, 256, 257 }, /* Default Foreground */
|
||||
{ COLOR_WINDOW, 258, 259 }, /* Default Background */
|
||||
{ COLOR_HIGHLIGHTTEXT, 260, 260 }, /* Cursor Text */
|
||||
{ COLOR_HIGHLIGHT, 261, 261 }, /* Cursor Colour */
|
||||
};
|
||||
|
||||
for (i = 0; i < (sizeof(or)/sizeof(or[0])); i++) {
|
||||
@ -1083,10 +1098,10 @@ static void init_palette(void)
|
||||
*/
|
||||
logpal = smalloc(sizeof(*logpal)
|
||||
- sizeof(logpal->palPalEntry)
|
||||
+ NCOLOURS * sizeof(PALETTEENTRY));
|
||||
+ NALLCOLOURS * sizeof(PALETTEENTRY));
|
||||
logpal->palVersion = 0x300;
|
||||
logpal->palNumEntries = NCOLOURS;
|
||||
for (i = 0; i < NCOLOURS; i++) {
|
||||
logpal->palNumEntries = NALLCOLOURS;
|
||||
for (i = 0; i < NALLCOLOURS; i++) {
|
||||
logpal->palPalEntry[i].peRed = defpal[i].rgbtRed;
|
||||
logpal->palPalEntry[i].peGreen = defpal[i].rgbtGreen;
|
||||
logpal->palPalEntry[i].peBlue = defpal[i].rgbtBlue;
|
||||
@ -1102,12 +1117,12 @@ static void init_palette(void)
|
||||
ReleaseDC(hwnd, hdc);
|
||||
}
|
||||
if (pal)
|
||||
for (i = 0; i < NCOLOURS; i++)
|
||||
for (i = 0; i < NALLCOLOURS; i++)
|
||||
colours[i] = PALETTERGB(defpal[i].rgbtRed,
|
||||
defpal[i].rgbtGreen,
|
||||
defpal[i].rgbtBlue);
|
||||
else
|
||||
for (i = 0; i < NCOLOURS; i++)
|
||||
for (i = 0; i < NALLCOLOURS; i++)
|
||||
colours[i] = RGB(defpal[i].rgbtRed,
|
||||
defpal[i].rgbtGreen, defpal[i].rgbtBlue);
|
||||
}
|
||||
@ -2905,8 +2920,12 @@ void do_text_internal(Context ctx, int x, int y, wchar_t *text, int len,
|
||||
y += offset_height;
|
||||
|
||||
if ((attr & TATTR_ACTCURS) && (cfg.cursor_type == 0 || term->big_cursor)) {
|
||||
attr &= ATTR_CUR_AND | (bold_mode != BOLD_COLOURS ? ATTR_BOLD : 0);
|
||||
attr ^= ATTR_CUR_XOR;
|
||||
attr &= ~(ATTR_REVERSE|ATTR_BLINK|ATTR_COLOURS);
|
||||
if (bold_mode == BOLD_COLOURS)
|
||||
attr &= ~ATTR_BOLD;
|
||||
|
||||
/* cursor fg and bg */
|
||||
attr |= (260 << ATTR_FGSHIFT) | (261 << ATTR_BGSHIFT);
|
||||
}
|
||||
|
||||
nfont = 0;
|
||||
@ -2964,9 +2983,7 @@ void do_text_internal(Context ctx, int x, int y, wchar_t *text, int len,
|
||||
nfont |= FONT_OEM;
|
||||
|
||||
nfg = ((attr & ATTR_FGMASK) >> ATTR_FGSHIFT);
|
||||
nfg = 2 * (nfg & 0xF) + (nfg & 0x10 ? 1 : 0);
|
||||
nbg = ((attr & ATTR_BGMASK) >> ATTR_BGSHIFT);
|
||||
nbg = 2 * (nbg & 0xF) + (nbg & 0x10 ? 1 : 0);
|
||||
if (bold_mode == BOLD_FONT && (attr & ATTR_BOLD))
|
||||
nfont |= FONT_BOLD;
|
||||
if (und_mode == UND_FONT && (attr & ATTR_UNDER))
|
||||
@ -2987,10 +3004,14 @@ void do_text_internal(Context ctx, int x, int y, wchar_t *text, int len,
|
||||
nfg = nbg;
|
||||
nbg = t;
|
||||
}
|
||||
if (bold_mode == BOLD_COLOURS && (attr & ATTR_BOLD))
|
||||
nfg |= 1;
|
||||
if (bold_mode == BOLD_COLOURS && (attr & ATTR_BLINK))
|
||||
nbg |= 1;
|
||||
if (bold_mode == BOLD_COLOURS && (attr & ATTR_BOLD)) {
|
||||
if (nfg < 16) nfg |= 8;
|
||||
else if (nfg >= 256) nfg |= 1;
|
||||
}
|
||||
if (bold_mode == BOLD_COLOURS && (attr & ATTR_BLINK)) {
|
||||
if (nbg < 16) nbg |= 8;
|
||||
else if (nbg >= 256) nbg |= 1;
|
||||
}
|
||||
fg = colours[nfg];
|
||||
bg = colours[nbg];
|
||||
SelectObject(hdc, fonts[nfont]);
|
||||
@ -3188,7 +3209,7 @@ void do_cursor(Context ctx, int x, int y, wchar_t *text, int len,
|
||||
pts[2].x = pts[3].x = x + char_width - 1;
|
||||
pts[0].y = pts[3].y = pts[4].y = y;
|
||||
pts[1].y = pts[2].y = y + font_height - 1;
|
||||
oldpen = SelectObject(hdc, CreatePen(PS_SOLID, 0, colours[23]));
|
||||
oldpen = SelectObject(hdc, CreatePen(PS_SOLID, 0, colours[261]));
|
||||
Polyline(hdc, pts, 5);
|
||||
oldpen = SelectObject(hdc, oldpen);
|
||||
DeleteObject(oldpen);
|
||||
@ -4221,21 +4242,18 @@ static void real_palette_set(int n, int r, int g, int b)
|
||||
logpal->palPalEntry[n].peBlue = b;
|
||||
logpal->palPalEntry[n].peFlags = PC_NOCOLLAPSE;
|
||||
colours[n] = PALETTERGB(r, g, b);
|
||||
SetPaletteEntries(pal, 0, NCOLOURS, logpal->palPalEntry);
|
||||
SetPaletteEntries(pal, 0, NALLCOLOURS, logpal->palPalEntry);
|
||||
} else
|
||||
colours[n] = RGB(r, g, b);
|
||||
}
|
||||
|
||||
void palette_set(void *frontend, int n, int r, int g, int b)
|
||||
{
|
||||
static const int first[21] = {
|
||||
0, 2, 4, 6, 8, 10, 12, 14,
|
||||
1, 3, 5, 7, 9, 11, 13, 15,
|
||||
16, 17, 18, 20, 22
|
||||
};
|
||||
real_palette_set(first[n], r, g, b);
|
||||
if (first[n] >= 18)
|
||||
real_palette_set(first[n] + 1, r, g, b);
|
||||
if (n >= 16)
|
||||
n += 256 - 16;
|
||||
if (n > NALLCOLOURS)
|
||||
return;
|
||||
real_palette_set(n, r, g, b);
|
||||
if (pal) {
|
||||
HDC hdc = get_ctx(frontend);
|
||||
UnrealizeObject(pal);
|
||||
@ -4248,7 +4266,8 @@ void palette_reset(void *frontend)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NCOLOURS; i++) {
|
||||
/* And this */
|
||||
for (i = 0; i < NALLCOLOURS; i++) {
|
||||
if (pal) {
|
||||
logpal->palPalEntry[i].peRed = defpal[i].rgbtRed;
|
||||
logpal->palPalEntry[i].peGreen = defpal[i].rgbtGreen;
|
||||
@ -4264,7 +4283,7 @@ void palette_reset(void *frontend)
|
||||
|
||||
if (pal) {
|
||||
HDC hdc;
|
||||
SetPaletteEntries(pal, 0, NCOLOURS, logpal->palPalEntry);
|
||||
SetPaletteEntries(pal, 0, NALLCOLOURS, logpal->palPalEntry);
|
||||
hdc = get_ctx(frontend);
|
||||
RealizePalette(hdc);
|
||||
free_ctx(hdc);
|
||||
|
@ -97,6 +97,7 @@
|
||||
#define WINHELP_CTX_selection_linedraw "selection.linedraw"
|
||||
#define WINHELP_CTX_selection_rtf "selection.rtf"
|
||||
#define WINHELP_CTX_colours_ansi "colours.ansi"
|
||||
#define WINHELP_CTX_colours_xterm256 "colours.xterm256"
|
||||
#define WINHELP_CTX_colours_bold "colours.bold"
|
||||
#define WINHELP_CTX_colours_system "colours.system"
|
||||
#define WINHELP_CTX_colours_logpal "colours.logpal"
|
||||
|
Loading…
Reference in New Issue
Block a user