Commit fa6ce9ab authored by Jan Engelhardt's avatar Jan Engelhardt Committed by Linus Torvalds

vt: add color support to the "underline" and "italic" attributes

Add color support to the "underline" and "italic" attributes as in
OpenBSD/NetBSD-style (vt220) and xterm.
Signed-off-by: default avatarJan Engelhardt <jengelh@gmx.de>
Acked-by: default avatar"Antonino A. Daplas" <adaplas@pol.net>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 1c2bbe6a
...@@ -348,10 +348,12 @@ void update_region(struct vc_data *vc, unsigned long start, int count) ...@@ -348,10 +348,12 @@ void update_region(struct vc_data *vc, unsigned long start, int count)
/* Structure of attributes is hardware-dependent */ /* Structure of attributes is hardware-dependent */
static u8 build_attr(struct vc_data *vc, u8 _color, u8 _intensity, u8 _blink, u8 _underline, u8 _reverse) static u8 build_attr(struct vc_data *vc, u8 _color, u8 _intensity, u8 _blink,
u8 _underline, u8 _reverse, u8 _italic)
{ {
if (vc->vc_sw->con_build_attr) if (vc->vc_sw->con_build_attr)
return vc->vc_sw->con_build_attr(vc, _color, _intensity, _blink, _underline, _reverse); return vc->vc_sw->con_build_attr(vc, _color, _intensity,
_blink, _underline, _reverse, _italic);
#ifndef VT_BUF_VRAM_ONLY #ifndef VT_BUF_VRAM_ONLY
/* /*
...@@ -368,10 +370,13 @@ static u8 build_attr(struct vc_data *vc, u8 _color, u8 _intensity, u8 _blink, u8 ...@@ -368,10 +370,13 @@ static u8 build_attr(struct vc_data *vc, u8 _color, u8 _intensity, u8 _blink, u8
u8 a = vc->vc_color; u8 a = vc->vc_color;
if (!vc->vc_can_do_color) if (!vc->vc_can_do_color)
return _intensity | return _intensity |
(_italic ? 2 : 0) |
(_underline ? 4 : 0) | (_underline ? 4 : 0) |
(_reverse ? 8 : 0) | (_reverse ? 8 : 0) |
(_blink ? 0x80 : 0); (_blink ? 0x80 : 0);
if (_underline) if (_italic)
a = (a & 0xF0) | vc->vc_itcolor;
else if (_underline)
a = (a & 0xf0) | vc->vc_ulcolor; a = (a & 0xf0) | vc->vc_ulcolor;
else if (_intensity == 0) else if (_intensity == 0)
a = (a & 0xf0) | vc->vc_ulcolor; a = (a & 0xf0) | vc->vc_ulcolor;
...@@ -392,8 +397,10 @@ static u8 build_attr(struct vc_data *vc, u8 _color, u8 _intensity, u8 _blink, u8 ...@@ -392,8 +397,10 @@ static u8 build_attr(struct vc_data *vc, u8 _color, u8 _intensity, u8 _blink, u8
static void update_attr(struct vc_data *vc) static void update_attr(struct vc_data *vc)
{ {
vc->vc_attr = build_attr(vc, vc->vc_color, vc->vc_intensity, vc->vc_blink, vc->vc_underline, vc->vc_reverse ^ vc->vc_decscnm); vc->vc_attr = build_attr(vc, vc->vc_color, vc->vc_intensity,
vc->vc_video_erase_char = (build_attr(vc, vc->vc_color, 1, vc->vc_blink, 0, vc->vc_decscnm) << 8) | ' '; vc->vc_blink, vc->vc_underline,
vc->vc_reverse ^ vc->vc_decscnm, vc->vc_italic);
vc->vc_video_erase_char = (build_attr(vc, vc->vc_color, 1, vc->vc_blink, 0, vc->vc_decscnm, 0) << 8) | ' ';
} }
/* Note: inverting the screen twice should revert to the original state */ /* Note: inverting the screen twice should revert to the original state */
...@@ -1136,6 +1143,7 @@ static void csi_X(struct vc_data *vc, int vpar) /* erase the following vpar posi ...@@ -1136,6 +1143,7 @@ static void csi_X(struct vc_data *vc, int vpar) /* erase the following vpar posi
static void default_attr(struct vc_data *vc) static void default_attr(struct vc_data *vc)
{ {
vc->vc_intensity = 1; vc->vc_intensity = 1;
vc->vc_italic = 0;
vc->vc_underline = 0; vc->vc_underline = 0;
vc->vc_reverse = 0; vc->vc_reverse = 0;
vc->vc_blink = 0; vc->vc_blink = 0;
...@@ -1158,6 +1166,9 @@ static void csi_m(struct vc_data *vc) ...@@ -1158,6 +1166,9 @@ static void csi_m(struct vc_data *vc)
case 2: case 2:
vc->vc_intensity = 0; vc->vc_intensity = 0;
break; break;
case 3:
vc->vc_italic = 1;
break;
case 4: case 4:
vc->vc_underline = 1; vc->vc_underline = 1;
break; break;
...@@ -1198,6 +1209,9 @@ static void csi_m(struct vc_data *vc) ...@@ -1198,6 +1209,9 @@ static void csi_m(struct vc_data *vc)
case 22: case 22:
vc->vc_intensity = 1; vc->vc_intensity = 1;
break; break;
case 23:
vc->vc_italic = 0;
break;
case 24: case 24:
vc->vc_underline = 0; vc->vc_underline = 0;
break; break;
...@@ -1458,6 +1472,7 @@ static void save_cur(struct vc_data *vc) ...@@ -1458,6 +1472,7 @@ static void save_cur(struct vc_data *vc)
vc->vc_saved_x = vc->vc_x; vc->vc_saved_x = vc->vc_x;
vc->vc_saved_y = vc->vc_y; vc->vc_saved_y = vc->vc_y;
vc->vc_s_intensity = vc->vc_intensity; vc->vc_s_intensity = vc->vc_intensity;
vc->vc_s_italic = vc->vc_italic;
vc->vc_s_underline = vc->vc_underline; vc->vc_s_underline = vc->vc_underline;
vc->vc_s_blink = vc->vc_blink; vc->vc_s_blink = vc->vc_blink;
vc->vc_s_reverse = vc->vc_reverse; vc->vc_s_reverse = vc->vc_reverse;
...@@ -1472,6 +1487,7 @@ static void restore_cur(struct vc_data *vc) ...@@ -1472,6 +1487,7 @@ static void restore_cur(struct vc_data *vc)
{ {
gotoxy(vc, vc->vc_saved_x, vc->vc_saved_y); gotoxy(vc, vc->vc_saved_x, vc->vc_saved_y);
vc->vc_intensity = vc->vc_s_intensity; vc->vc_intensity = vc->vc_s_intensity;
vc->vc_italic = vc->vc_s_italic;
vc->vc_underline = vc->vc_s_underline; vc->vc_underline = vc->vc_s_underline;
vc->vc_blink = vc->vc_s_blink; vc->vc_blink = vc->vc_s_blink;
vc->vc_reverse = vc->vc_s_reverse; vc->vc_reverse = vc->vc_s_reverse;
...@@ -2686,6 +2702,11 @@ static void con_close(struct tty_struct *tty, struct file *filp) ...@@ -2686,6 +2702,11 @@ static void con_close(struct tty_struct *tty, struct file *filp)
mutex_unlock(&tty_mutex); mutex_unlock(&tty_mutex);
} }
static int default_italic_color = 2; // green (ASCII)
static int default_underline_color = 3; // cyan (ASCII)
module_param_named(italic, default_italic_color, int, S_IRUGO | S_IWUSR);
module_param_named(underline, default_underline_color, int, S_IRUGO | S_IWUSR);
static void vc_init(struct vc_data *vc, unsigned int rows, static void vc_init(struct vc_data *vc, unsigned int rows,
unsigned int cols, int do_clear) unsigned int cols, int do_clear)
{ {
...@@ -2705,7 +2726,8 @@ static void vc_init(struct vc_data *vc, unsigned int rows, ...@@ -2705,7 +2726,8 @@ static void vc_init(struct vc_data *vc, unsigned int rows,
vc->vc_palette[k++] = default_blu[j] ; vc->vc_palette[k++] = default_blu[j] ;
} }
vc->vc_def_color = 0x07; /* white */ vc->vc_def_color = 0x07; /* white */
vc->vc_ulcolor = 0x0f; /* bold white */ vc->vc_ulcolor = default_underline_color;
vc->vc_itcolor = default_italic_color;
vc->vc_halfcolor = 0x08; /* grey */ vc->vc_halfcolor = 0x08; /* grey */
init_waitqueue_head(&vc->paste_wait); init_waitqueue_head(&vc->paste_wait);
reset_terminal(vc, do_clear); reset_terminal(vc, do_clear);
......
...@@ -384,7 +384,7 @@ static inline u16 mda_convert_attr(u16 ch) ...@@ -384,7 +384,7 @@ static inline u16 mda_convert_attr(u16 ch)
} }
static u8 mdacon_build_attr(struct vc_data *c, u8 color, u8 intensity, static u8 mdacon_build_attr(struct vc_data *c, u8 color, u8 intensity,
u8 blink, u8 underline, u8 reverse) u8 blink, u8 underline, u8 reverse, u8 italic)
{ {
/* The attribute is just a bit vector: /* The attribute is just a bit vector:
* *
...@@ -397,6 +397,7 @@ static u8 mdacon_build_attr(struct vc_data *c, u8 color, u8 intensity, ...@@ -397,6 +397,7 @@ static u8 mdacon_build_attr(struct vc_data *c, u8 color, u8 intensity,
return (intensity & 3) | return (intensity & 3) |
((underline & 1) << 2) | ((underline & 1) << 2) |
((reverse & 1) << 3) | ((reverse & 1) << 3) |
(!!italic << 4) |
((blink & 1) << 7); ((blink & 1) << 7);
} }
......
...@@ -548,7 +548,8 @@ promcon_scroll(struct vc_data *conp, int t, int b, int dir, int count) ...@@ -548,7 +548,8 @@ promcon_scroll(struct vc_data *conp, int t, int b, int dir, int count)
} }
#if !(PROMCON_COLOR) #if !(PROMCON_COLOR)
static u8 promcon_build_attr(struct vc_data *conp, u8 _color, u8 _intensity, u8 _blink, u8 _underline, u8 _reverse) static u8 promcon_build_attr(struct vc_data *conp, u8 _color, u8 _intensity,
u8 _blink, u8 _underline, u8 _reverse, u8 _italic)
{ {
return (_reverse) ? 0xf : 0x7; return (_reverse) ? 0xf : 0x7;
} }
......
...@@ -314,7 +314,7 @@ static unsigned long sticon_getxy(struct vc_data *conp, unsigned long pos, ...@@ -314,7 +314,7 @@ static unsigned long sticon_getxy(struct vc_data *conp, unsigned long pos,
} }
static u8 sticon_build_attr(struct vc_data *conp, u8 color, u8 intens, static u8 sticon_build_attr(struct vc_data *conp, u8 color, u8 intens,
u8 blink, u8 underline, u8 reverse) u8 blink, u8 underline, u8 reverse, u8 italic)
{ {
u8 attr = ((color & 0x70) >> 1) | ((color & 7)); u8 attr = ((color & 0x70) >> 1) | ((color & 7));
......
...@@ -87,7 +87,7 @@ static void vgacon_save_screen(struct vc_data *c); ...@@ -87,7 +87,7 @@ static void vgacon_save_screen(struct vc_data *c);
static int vgacon_scroll(struct vc_data *c, int t, int b, int dir, static int vgacon_scroll(struct vc_data *c, int t, int b, int dir,
int lines); int lines);
static u8 vgacon_build_attr(struct vc_data *c, u8 color, u8 intensity, static u8 vgacon_build_attr(struct vc_data *c, u8 color, u8 intensity,
u8 blink, u8 underline, u8 reverse); u8 blink, u8 underline, u8 reverse, u8);
static void vgacon_invert_region(struct vc_data *c, u16 * p, int count); static void vgacon_invert_region(struct vc_data *c, u16 * p, int count);
static unsigned long vgacon_uni_pagedir[2]; static unsigned long vgacon_uni_pagedir[2];
...@@ -578,12 +578,14 @@ static void vgacon_deinit(struct vc_data *c) ...@@ -578,12 +578,14 @@ static void vgacon_deinit(struct vc_data *c)
} }
static u8 vgacon_build_attr(struct vc_data *c, u8 color, u8 intensity, static u8 vgacon_build_attr(struct vc_data *c, u8 color, u8 intensity,
u8 blink, u8 underline, u8 reverse) u8 blink, u8 underline, u8 reverse, u8 italic)
{ {
u8 attr = color; u8 attr = color;
if (vga_can_do_color) { if (vga_can_do_color) {
if (underline) if (italic)
attr = (attr & 0xF0) | c->vc_itcolor;
else if (underline)
attr = (attr & 0xf0) | c->vc_ulcolor; attr = (attr & 0xf0) | c->vc_ulcolor;
else if (intensity == 0) else if (intensity == 0)
attr = (attr & 0xf0) | c->vc_halfcolor; attr = (attr & 0xf0) | c->vc_halfcolor;
...@@ -597,7 +599,9 @@ static u8 vgacon_build_attr(struct vc_data *c, u8 color, u8 intensity, ...@@ -597,7 +599,9 @@ static u8 vgacon_build_attr(struct vc_data *c, u8 color, u8 intensity,
if (intensity == 2) if (intensity == 2)
attr ^= 0x08; attr ^= 0x08;
if (!vga_can_do_color) { if (!vga_can_do_color) {
if (underline) if (italic)
attr = (attr & 0xF8) | 0x02;
else if (underline)
attr = (attr & 0xf8) | 0x01; attr = (attr & 0xf8) | 0x01;
else if (intensity == 0) else if (intensity == 0)
attr = (attr & 0xf0) | 0x08; attr = (attr & 0xf0) | 0x08;
......
...@@ -51,7 +51,7 @@ struct consw { ...@@ -51,7 +51,7 @@ struct consw {
int (*con_scrolldelta)(struct vc_data *, int); int (*con_scrolldelta)(struct vc_data *, int);
int (*con_set_origin)(struct vc_data *); int (*con_set_origin)(struct vc_data *);
void (*con_save_screen)(struct vc_data *); void (*con_save_screen)(struct vc_data *);
u8 (*con_build_attr)(struct vc_data *, u8, u8, u8, u8, u8); u8 (*con_build_attr)(struct vc_data *, u8, u8, u8, u8, u8, u8);
void (*con_invert_region)(struct vc_data *, u16 *, int); void (*con_invert_region)(struct vc_data *, u16 *, int);
u16 *(*con_screen_pos)(struct vc_data *, int); u16 *(*con_screen_pos)(struct vc_data *, int);
unsigned long (*con_getxy)(struct vc_data *, unsigned long, int *, int *); unsigned long (*con_getxy)(struct vc_data *, unsigned long, int *, int *);
......
...@@ -37,6 +37,7 @@ struct vc_data { ...@@ -37,6 +37,7 @@ struct vc_data {
unsigned char vc_color; /* Foreground & background */ unsigned char vc_color; /* Foreground & background */
unsigned char vc_s_color; /* Saved foreground & background */ unsigned char vc_s_color; /* Saved foreground & background */
unsigned char vc_ulcolor; /* Color for underline mode */ unsigned char vc_ulcolor; /* Color for underline mode */
unsigned char vc_itcolor;
unsigned char vc_halfcolor; /* Color for half intensity mode */ unsigned char vc_halfcolor; /* Color for half intensity mode */
/* cursor */ /* cursor */
unsigned int vc_cursor_type; unsigned int vc_cursor_type;
...@@ -71,10 +72,12 @@ struct vc_data { ...@@ -71,10 +72,12 @@ struct vc_data {
unsigned int vc_deccolm : 1; /* 80/132 Column Mode */ unsigned int vc_deccolm : 1; /* 80/132 Column Mode */
/* attribute flags */ /* attribute flags */
unsigned int vc_intensity : 2; /* 0=half-bright, 1=normal, 2=bold */ unsigned int vc_intensity : 2; /* 0=half-bright, 1=normal, 2=bold */
unsigned int vc_italic:1;
unsigned int vc_underline : 1; unsigned int vc_underline : 1;
unsigned int vc_blink : 1; unsigned int vc_blink : 1;
unsigned int vc_reverse : 1; unsigned int vc_reverse : 1;
unsigned int vc_s_intensity : 2; /* saved rendition */ unsigned int vc_s_intensity : 2; /* saved rendition */
unsigned int vc_s_italic:1;
unsigned int vc_s_underline : 1; unsigned int vc_s_underline : 1;
unsigned int vc_s_blink : 1; unsigned int vc_s_blink : 1;
unsigned int vc_s_reverse : 1; unsigned int vc_s_reverse : 1;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment