mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-06-30 19:12:48 -05:00
Implement xterm 256-colour mode.
[originally from svn r4917] [this svn revision also touched putty-wishlist]
This commit is contained in:
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user