[Patch 4/9]: Amend internal manipulation of glyph structure
From: Alan Mackenzie
Date: Thu Aug 27 2026 - 14:49:20 EST
vt: 32b glyph: 4. Amend internal manipulation of glyph structure
This manipulation is the extraction/insertion of bit fields from/into the
16-bit/32-bit glyph. It uses the new fields of struct vc_data,
vc_char_mask, vc_attr_mask, vc_attr_shift_pos in place of old hard coded
constants such as 0xff, 0xff00, 8.
Signed-off-by: Alan Mackenzie <acm@xxxxxx>
diff --git a/drivers/tty/vt/vc_screen.c b/drivers/tty/vt/vc_screen.c
index 7d40eacc21b3..f23d61fe10c1 100644
--- a/drivers/tty/vt/vc_screen.c
+++ b/drivers/tty/vt/vc_screen.c
@@ -272,6 +273,10 @@ static int vcs_read_buf_uni(struct vc_data *vc, char *con_buf,
return 0;
}
+/*
+ * NOTE: This function returns the bottom 8 bits of the glyph for each pertinent
+ * screen character. It is not very useful for a 9-bit or 21-bit glyph setup.
+ */
static void vcs_read_buf_noattr(const struct vc_data *vc, char *con_buf,
unsigned int pos, unsigned int count, bool viewed)
{
@@ -470,6 +499,10 @@ vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
return ret;
}
+/*
+ * NOTE: This function writes the bottom 8-bits of the glyph code into the
+ * screen buffer. It is not very useful for 9-bit or 21-bit glyphs.
+ */
static u16 *vcs_write_buf_noattr(struct vc_data *vc, const char *con_buf,
unsigned int pos, unsigned int count, bool viewed, u16 **org0)
{
@@ -497,25 +533,15 @@ static u16 *vcs_write_buf_noattr(struct vc_data *vc, const char *con_buf,
return org;
}
-/*
- * Compilers (gcc 10) are unable to optimize the swap in cpu_to_le16. So do it
- * the poor man way.
- */
-static inline u16 vc_compile_le16(u8 hi, u8 lo)
-{
-#ifdef __BIG_ENDIAN
- return (lo << 8u) | hi;
-#else
- return (hi << 8u) | lo;
-#endif
-}
-
static u16 *vcs_write_buf(struct vc_data *vc, const char *con_buf,
unsigned int pos, unsigned int count, bool viewed, u16 **org0)
{
u16 *org;
unsigned int col, maxcol = vc->vc_cols;
unsigned char c;
+ unsigned int sz = GLYPH_SZ;
+ int i;
+ u8 lo_to_hi[4];
/* header */
if (pos < HEADER_SIZE) {
@@ -573,11 +619,27 @@ static u16 *vcs_write_buf(struct vc_data *vc, const char *con_buf,
if (!count)
return org;
- /* odd pos -- the remaining character */
- c = *con_buf++;
- vcs_scr_writew(vc, vc_compile_le16(vcs_scr_readw(vc, org) >> 8, c),
- org);
+ /* Unaligned bytes at end of buffer */
+ {
+ u32 old_char = vcs_scr_readw(vc, org);
+ u32 new_char = 0;
+ for (i = 0; i < sz; i++, old_char >>= 8)
+ lo_to_hi[i] = old_char & 0xff;
+ for (i = 0; i < count; i++) {
+ c = *con_buf++;
+#ifdef __BIG_ENDIAN
+ lo_to_hi[sz - i - 1] = c;
+#else
+ lo_to_hi[i] = c;
+#endif
+ }
+ for (i = sz - 1; i >= 0; i--) {
+ new_char <<= 8;
+ new_char |= lo_to_hi[i];
+ }
+ vcs_scr_writew(vc, new_char, org);
+ }
return org;
}
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 8f467b22b799..0c389a564357 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -543,7 +544,7 @@ int vc_uniscr_check(struct vc_data *vc)
* unicode content will be available after a complete screen refresh.
*/
p = (unsigned short *)vc->vc_origin;
- mask = vc->vc_hi_font_mask | 0xff;
+ mask = vc->vc_char_mask;
for (y = 0; y < vc->vc_rows; y++) {
u32 *line = uni_lines[y];
for (x = 0; x < vc->vc_cols; x++) {
@@ -713,8 +719,6 @@ static u8 build_attr(struct vc_data *vc, u8 _color,
a ^= 0x80;
if (_intensity == VCI_BOLD)
a ^= 0x08;
- if (vc->vc_hi_font_mask == 0x100)
- a <<= 1;
return a;
}
}
@@ -726,11 +730,11 @@ static void update_attr(struct vc_data *vc)
vc->state.reverse ^ vc->vc_decscnm, vc->state.italic);
vc->vc_video_erase_char = ' ' | (build_attr(vc, vc->state.color,
VCI_NORMAL, vc->state.blink, false,
- vc->vc_decscnm, false) << 8);
+ vc->vc_decscnm, false) << vc->vc_attr_shift_pos);
}
-/* Note: inverting the screen twice should revert to the original state */
+/* Note: inverting the screen twice should revert to the original state. */
void invert_screen(struct vc_data *vc, int offset, int count, bool viewed)
{
u16 *p;
@@ -742,34 +746,21 @@ void invert_screen(struct vc_data *vc, int offset, int count, bool viewed)
vc->vc_sw->con_invert_region(vc, p, count);
} else {
u16 *q = p;
int cnt = count;
- u16 a;
-
- if (!vc->vc_can_do_color) {
- while (cnt--) {
- a = scr_readw(q);
- a ^= 0x0800;
- scr_writew(a, q);
- q++;
- }
- } else if (vc->vc_hi_font_mask == 0x100) {
- while (cnt--) {
- a = scr_readw(q);
- a = (a & 0x11ff) |
- ((a & 0xe000) >> 4) |
- ((a & 0x0e00) << 4);
- scr_writew(a, q);
- q++;
- }
- } else {
- while (cnt--) {
- a = scr_readw(q);
- a = (a & 0x88ff) |
- ((a & 0x7000) >> 4) |
- ((a & 0x0700) << 4);
- scr_writew(a, q);
- q++;
- }
+ u32 a, c;
+
+ while (cnt--) {
+ c = scr_readg(q);
+ a = c >> vc->vc_attr_shift_pos;
+ if (!vc->vc_can_do_color)
+ a ^= 0x08;
+ else
+ a = (a & 0x88) |
+ ((a & 0x70) >> 4) |
+ ((a & 0x07) << 4);
+ c = (c & vc->vc_char_mask) |
+ (a << vc->vc_attr_shift_pos);
+ scr_writeg_plusplus(c, q++);
}
}
@@ -1041,19 +1037,37 @@ static void visual_init(struct vc_data *vc, int num, bool init)
con_free_unimap(vc);
vc->uni_pagedict_loc = &vc->uni_pagedict;
vc->uni_pagedict = NULL;
- vc->vc_hi_font_mask = 0;
+ vc->vc_hi_font_mask = 0; /* Probably redundant, 2025-01-16. */
vc->vc_complement_mask = 0;
vc->vc_can_do_color = 0;
vc->vc_cur_blink_ms = DEFAULT_CURSOR_BLINK_MS;
+
vc->vc_sw->con_init(vc, init);
+ if (init) {
+#ifdef CONFIG_FB_GLYPH_21BIT
+ vc->vc_char_mask = 0x1fffff;
+ vc->vc_attr_mask = 0xff000000;
+ vc->vc_attr_shift_pos = 24;
+#else
+ if (vc->vc_font.charcount == 256) {
+ vc->vc_char_mask = 0xff;
+ vc->vc_attr_mask = 0xff00;
+ vc->vc_attr_shift_pos = 8;
+ } else {
+ vc->vc_char_mask = 0x1ff;
+ vc->vc_attr_mask = 0xfe00;
+ vc->vc_attr_shift_pos = 9;
+ }
+#endif
+ }
if (!vc->vc_complement_mask)
- vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800;
+ vc->vc_complement_mask = (vc->vc_can_do_color ? 0x77 : 0x08)
+ << vc->vc_attr_shift_pos;
vc->vc_s_complement_mask = vc->vc_complement_mask;
- vc->vc_size_row = vc->vc_cols << 1;
+ vc->vc_size_row = vc->vc_cols * GLYPH_SZ;
vc->vc_screenbuf_size = vc->vc_rows * vc->vc_size_row;
}
-
static void visual_deinit(struct vc_data *vc)
{
vc->vc_sw->con_deinit(vc);
@@ -1175,11 +1189,30 @@ static int vc_do_resize(struct tty_struct *tty, struct vc_data *vc,
unsigned int new_cols, new_rows, new_row_size, new_screen_size;
unsigned short *oldscreen, *newscreen;
u32 **new_uniscr = NULL;
-
+ unsigned int new_vc_char_mask = vc->vc_char_mask;
+ unsigned int new_vc_attr_mask = vc->vc_attr_mask;
+ unsigned int new_vc_attr_shift_pos = vc->vc_attr_shift_pos;
+ unsigned int new_vc_video_erase_char = vc->vc_video_erase_char;
WARN_CONSOLE_UNLOCKED();
if (cols > VC_MAXCOL || lines > VC_MAXROW)
return -EINVAL;
+#ifndef CONFIG_FB_GLYPH_21BIT
+ if (vc->vc_hi_font_mask == 0x100) {
+ new_vc_char_mask = 0x1ff;
+ new_vc_attr_mask = 0xfe00;
+ new_vc_attr_shift_pos = 9;
+ } else {
+ new_vc_char_mask = 0xff;
+ new_vc_attr_mask = 0xff00;
+ new_vc_attr_shift_pos = 8;
+ }
+#endif
+ new_vc_video_erase_char =
+ (vc->vc_video_erase_char & vc->vc_char_mask) |
+ ((vc->vc_video_erase_char >> vc->vc_attr_shift_pos) <<
+ new_vc_attr_shift_pos);
+
new_cols = (cols ? cols : vc->vc_cols);
new_rows = (lines ? lines : vc->vc_rows);
@@ -2114,8 +2164,10 @@ static void csi_RSB(struct vc_data *vc)
break;
case CSI_RSB_MAKE_CUR_COLOR_DEFAULT:
vc->vc_def_color = vc->vc_attr;
+#ifndef CONFIG_FB_GLYPH_21BIT
if (vc->vc_hi_font_mask == 0x100)
vc->vc_def_color >>= 1;
+#endif
default_attr(vc);
update_attr(vc);
break;
@@ -2856,11 +2908,13 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, u8 c)
if (c == '8') {
/* DEC screen alignment test. kludge :-) */
vc->vc_video_erase_char =
- (vc->vc_video_erase_char & 0xff00) | 'E';
+ (vc->vc_video_erase_char & vc->vc_attr_mask) | 'E';
csi_J(vc, CSI_J_VISIBLE);
vc->vc_video_erase_char =
- (vc->vc_video_erase_char & 0xff00) | ' ';
- do_update_region(vc, vc->vc_origin, vc->vc_screenbuf_size / 2);
+ (vc->vc_video_erase_char & vc->vc_attr_mask) | ' ';
+ do_update_region(vc, vc->vc_origin,
+ vc->vc_screenbuf_size /
+ GLYPH_SZ);
}
return;
case ESsetG0: /* ESC ( */
@@ -3021,10 +3076,12 @@ static inline unsigned char vc_invert_attr(const struct vc_data *vc)
if (!vc->vc_can_do_color)
return vc->vc_attr ^ 0x08;
+#ifndef CONFIG_FB_GLYPH_21BIT
if (vc->vc_hi_font_mask == 0x100)
return (vc->vc_attr & 0x11) |
((vc->vc_attr & 0xe0) >> 4) |
((vc->vc_attr & 0x0e) << 4);
+#endif
return (vc->vc_attr & 0x88) |
((vc->vc_attr & 0x70) >> 4) |
@@ -3153,16 +3210,15 @@ static int vc_process_ucs(struct vc_data *vc, int *c, int *tc)
static int vc_get_glyph(struct vc_data *vc, int tc)
{
int glyph = conv_uni_to_pc(vc, tc);
- u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
- if (!(glyph & ~charmask))
+ if (!(glyph & ~vc->vc_char_mask))
return glyph;
if (glyph == -1)
return -1; /* nothing to display */
/* Glyph not found */
- if ((!vc->vc_utf || vc->vc_disp_ctrl || tc < 128) && !(tc & ~charmask)) {
+ if ((!vc->vc_utf || vc->vc_disp_ctrl || tc < 128) && !(tc & ~vc->vc_char_mask)) {
/*
* In legacy mode use the glyph we get by a 1:1 mapping.
* This would make absolutely no sense with Unicode in mind, but do this for
diff --git a/drivers/video/fbdev/core/bitblit.c b/drivers/video/fbdev/core/bitblit.c
index 65681dcc5930..84e073162311 100644
--- a/drivers/video/fbdev/core/bitblit.c
+++ b/drivers/video/fbdev/core/bitblit.c
@@ -77,8 +77,8 @@ static inline void bit_putcs_aligned(struct vc_data *vc, struct fb_info *info,
u32 d_pitch, u32 s_pitch, u32 cellsize,
struct fb_image *image, u8 *buf, u8 *dst)
{
- u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
unsigned int charcnt = vc->vc_font.charcount;
+ u32 charmask = vc->vc_char_mask;
u32 idx = vc->vc_font.width >> 3;
const u8 *src;
@@ -114,8 +113,8 @@ static inline void bit_putcs_unaligned(struct vc_data *vc,
struct fb_image *image, u8 *buf,
u8 *dst)
{
- u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
unsigned int charcnt = vc->vc_font.charcount;
+ u32 charmask = vc->vc_char_mask;
u32 shift_low = 0, mod = vc->vc_font.width % 8;
u32 shift_high = 8;
u32 idx = vc->vc_font.width >> 3;
@@ -261,7 +260,7 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info, bool enable,
{
struct fb_cursor cursor;
struct fbcon_par *par = info->fbcon_par;
- unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
+ unsigned int charmask = vc->vc_char_mask;
int w = DIV_ROUND_UP(vc->vc_font.width, 8), c;
int y = real_y(par->p, vc->state.y);
int attribute, use_sw = vc->vc_cursor_type & CUR_SW;
diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c
index 9f5c4c101581..18fbf7cf11dd 100644
--- a/drivers/video/fbdev/core/fbcon.c
+++ b/drivers/video/fbdev/core/fbcon.c
@@ -319,14 +319,14 @@ static int get_color(struct vc_data *vc, struct fb_info *info,
int color = 0;
if (console_blanked) {
- unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
+ unsigned int charmask = vc->vc_char_mask;
c = vc->vc_video_erase_char & charmask;
}
if (depth != 1)
- color = (is_fg) ? attr_fgcol((vc->vc_hi_font_mask) ? 9 : 8, c)
- : attr_bgcol((vc->vc_hi_font_mask) ? 13 : 12, c);
+ color = (is_fg) ? ((c >> vc->vc_attr_shift_pos) & 0x0f)
+ : (c >> (vc->vc_attr_shift_pos + 4));
switch (depth) {
case 1:
@@ -1150,14 +1157,8 @@ static void fbcon_init(struct vc_data *vc, bool init)
}
vc->vc_can_do_color = (fb_get_color_depth(&info->var, &info->fix)!=1);
- vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800;
- if (vc->vc_font.charcount == 256) {
- vc->vc_hi_font_mask = 0;
- } else {
- vc->vc_hi_font_mask = 0x100;
- if (vc->vc_can_do_color)
- vc->vc_complement_mask <<= 1;
- }
+ vc->vc_complement_mask = (vc->vc_can_do_color ? 0x77 : 0x08) <<
+ (vc->vc_attr_shift_pos ? vc->vc_attr_shift_pos : 8);
if (!*svc->uni_pagedict_loc)
con_set_default_unimap(svc);
@@ -1242,7 +1244,9 @@ static void fbcon_free_font(struct fbcon_display *p)
}
}
+#ifndef CONFIG_FB_GLYPH_21BIT
static void set_vc_hi_font(struct vc_data *vc, bool set);
+#endif
static void fbcon_release_all(void)
{
@@ -1298,8 +1302,10 @@ static void fbcon_deinit(struct vc_data *vc)
fbcon_free_font(p);
vc->vc_font.data = NULL;
+#ifndef CONFIG_FB_GLYPH_21BIT
if (vc->vc_hi_font_mask && vc->vc_screenbuf)
set_vc_hi_font(vc, false);
+#endif
if (!con_is_bound(&fb_con))
fbcon_release_all();
@@ -1471,16 +1477,28 @@ static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var,
var->xoffset = info->var.xoffset;
fb_set_var(info, var);
par->var = info->var;
- vc->vc_can_do_color = (fb_get_color_depth(&info->var, &info->fix)!=1);
- vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800;
+#ifdef CONFIG_FB_GLYPH_21BIT
+ vc->vc_hi_font_mask = 0;
+ vc->vc_char_mask = 0x1fffff;
+ vc->vc_attr_mask = 0xff000000;
+ vc->vc_attr_shift_pos = 24;
+#else
if (vc->vc_font.charcount == 256) {
vc->vc_hi_font_mask = 0;
+ vc->vc_char_mask = 0xff;
+ vc->vc_attr_mask = 0xff00;
+ vc->vc_attr_shift_pos = 8;
} else {
vc->vc_hi_font_mask = 0x100;
- if (vc->vc_can_do_color)
- vc->vc_complement_mask <<= 1;
+ vc->vc_char_mask = 0x1ff;
+ vc->vc_attr_mask = 0xfe00;
+ vc->vc_attr_shift_pos = 9;
}
+#endif
+ vc->vc_can_do_color = (fb_get_color_depth(&info->var, &info->fix) != 1);
+ vc->vc_complement_mask = (vc->vc_can_do_color ? 0x77 : 0x08) <<
+ (vc->vc_attr_shift_pos ? vc->vc_attr_shift_pos : 8);
if (!*svc->uni_pagedict_loc)
con_set_default_unimap(svc);
if (!*vc->uni_pagedict_loc)
@@ -2220,10 +2258,8 @@ static bool fbcon_switch(struct vc_data *vc)
}
vc->vc_can_do_color = (fb_get_color_depth(&info->var, &info->fix)!=1);
- vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800;
-
- if (vc->vc_font.charcount > 256)
- vc->vc_complement_mask <<= 1;
+ vc->vc_complement_mask = (vc->vc_can_do_color ? 0x77 : 0x08) <<
+ (vc->vc_attr_shift_pos ? vc->vc_attr_shift_pos : 8);
updatescrollmode(p, info, vc);
@@ -2270,9 +2306,8 @@ static void fbcon_generic_blank(struct vc_data *vc, struct fb_info *info,
int blank)
{
if (blank) {
- unsigned short charmask = vc->vc_hi_font_mask ?
- 0x1ff : 0xff;
- unsigned short oldc;
+ unsigned int charmask = vc->vc_char_mask;
+ unsigned int oldc;
oldc = vc->vc_video_erase_char;
vc->vc_video_erase_char &= charmask;
@@ -2336,11 +2373,15 @@ static int fbcon_get_font(struct vc_data *vc, struct console_font *font, unsigned int vpitch)
return font_data_export(p->fontdata, font, vpitch);
}
+#ifndef CONFIG_FB_GLYPH_21BIT
/* set/clear vc_hi_font_mask and update vc attrs accordingly */
static void set_vc_hi_font(struct vc_data *vc, bool set)
{
if (!set) {
vc->vc_hi_font_mask = 0;
+ vc->vc_attr_mask = 0xff00;
+ vc->vc_char_mask = 0xff;
+ vc->vc_attr_shift_pos = 8;
if (vc->vc_can_do_color) {
vc->vc_complement_mask >>= 1;
vc->vc_s_complement_mask >>= 1;
@@ -2406,7 +2452,9 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h, int charcount,
int resize, ret, old_width, old_height, old_charcount;
font_data_t *old_fontdata = p->fontdata;
const u8 *old_data = vc->vc_font.data;
+#ifndef CONFIG_FB_GLYPH_21BIT
unsigned short old_hi_font_mask = vc->vc_hi_font_mask;
+#endif
font_data_get(data);
@@ -2453,11 +2504,13 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h, int charcount,
vc->vc_font.height = old_height;
vc->vc_font.charcount = old_charcount;
+#ifndef CONFIG_FB_GLYPH_21BIT
/* Restore the hi_font state and screen buffer */
if (old_hi_font_mask && !vc->vc_hi_font_mask)
set_vc_hi_font(vc, true);
else if (!old_hi_font_mask && vc->vc_hi_font_mask)
set_vc_hi_font(vc, false);
+#endif
font_data_put(data);
@@ -2583,19 +2645,23 @@ static void fbcon_set_palette(struct vc_data *vc, const unsigned char *table)
/* As we might be inside of softback, we may work with non-contiguous buffer,
that's why we have to use a separate routine. */
-static void fbcon_invert_region(struct vc_data *vc, u16 * p, int cnt)
+static void fbcon_invert_region(struct vc_data *vc, u16 *p, int cnt)
{
+ u32 attr;
+
while (cnt--) {
- u16 a = scr_readw(p);
+ u32 a = scr_readg(p);
+
+ attr = a >> vc->vc_attr_shift_pos;
if (!vc->vc_can_do_color)
- a ^= 0x0800;
- else if (vc->vc_hi_font_mask == 0x100)
- a = ((a) & 0x11ff) | (((a) & 0xe000) >> 4) |
- (((a) & 0x0e00) << 4);
+ attr ^= 0x08;
else
- a = ((a) & 0x88ff) | (((a) & 0x7000) >> 4) |
- (((a) & 0x0700) << 4);
- scr_writew(a, p++);
+ attr = (attr & 0x88) |
+ ((attr & 0x70) >> 4) |
+ ((attr & 0x07) << 4);
+ a = (a & vc->vc_char_mask) |
+ (attr << vc->vc_attr_shift_pos);
+ scr_writeg_plusplus(a, p++);
}
}
diff --git a/drivers/video/fbdev/core/fbcon.h b/drivers/video/fbdev/core/fbcon.h
index 407d207b14f1..5aaef363a343 100644
--- a/drivers/video/fbdev/core/fbcon.h
+++ b/drivers/video/fbdev/core/fbcon.h
@@ -105,12 +105,6 @@ struct fbcon_par {
* Attribute Decoding
*/
-/* Color */
-#define attr_fgcol(fgshift,s) \
- (((s) >> (fgshift)) & 0x0f)
-#define attr_bgcol(bgshift,s) \
- (((s) >> (bgshift)) & 0x0f)
-
/* Monochrome */
#define attr_bold(s) \
((s) & 0x200)
diff --git a/include/linux/console_struct.h b/include/linux/console_struct.h
index fe915afdece5..5afce52057ca 100644
--- a/include/linux/console_struct.h
+++ b/include/linux/console_struct.h
@@ -144,13 +153,16 @@ struct vc_data {
unsigned char vc_halfcolor; /* Color for half intensity mode */
/* cursor */
unsigned int vc_cursor_type;
- unsigned short vc_complement_mask; /* [#] Xor mask for mouse pointer */
- unsigned short vc_s_complement_mask; /* Saved mouse pointer mask */
+ unsigned int vc_complement_mask; /* [#] Xor mask for mouse pointer */
+ unsigned int vc_s_complement_mask; /* Saved mouse pointer mask */
unsigned long vc_pos; /* Cursor address */
/* fonts */
unsigned short vc_hi_font_mask; /* [#] Attribute set for upper 256 chars of font or 0 if not supported */
- struct vc_font vc_font; /* Current VC font set */
- unsigned short vc_video_erase_char; /* Background erase character */
+ unsigned int vc_char_mask; /* Character mask. 0x1fffff, 0x1ff, or 0xff. */
+ unsigned int vc_attr_mask; /* Attribute mask. 0xff000000, 0xfe00, 0xff00. */
+ unsigned int vc_attr_shift_pos; /* Position of 8-bit attributes: 24, 9, or 8. */
+ struct vc_font vc_font; /* Current VC font set */
+ unsigned int vc_video_erase_char; /* Background erase character */
/* VT terminal data */
unsigned int vc_state; /* Escape sequence parser state */
unsigned int vc_npar,vc_par[NPAR]; /* Parameters of current escape sequence */
@@ -217,9 +229,18 @@ extern void vc_SAK(struct work_struct *work);
#define CUR_SW 0x000010
#define CUR_ALWAYS_BG 0x000020
#define CUR_INVERT_FG_BG 0x000040
+
+#ifdef CONFIG_FB_GLYPH_21BIT
+#define CUR_FG (0x07 << vc->vc_attr_shift_pos)
+#define CUR_BG (0x70 << vc->vc_attr_shift_pos)
+#define CUR_TYPE_CHANGE 0x00ff00
+#define CUR_CHANGE(c) (((c) & CUR_TYPE_CHANGE) << (vc->vc_attr_shift_pos - 8))
+#else
#define CUR_FG 0x000700
#define CUR_BG 0x007000
#define CUR_CHANGE(c) ((c) & 0x00ff00)
+#endif
+
#define CUR_SET(c) (((c) & 0xff0000) >> 8)
bool con_is_visible(const struct vc_data *vc);
--
Alan Mackenzie (Nuremberg, Germany).