[PATCH 1/2] Enlarge the storage of chars in virtual terminal

From: Frank Pan
Date: Wed May 26 2010 - 02:59:56 EST


Enlarge the storage of char in virtual terminal.

Signed-off-by: Frank Pan <frankpzh@xxxxxxxxx>
---
diff --git a/drivers/char/selection.c b/drivers/char/selection.c
index f97b9e8..200a790 100644
--- a/drivers/char/selection.c
+++ b/drivers/char/selection.c
@@ -158,8 +158,8 @@ int set_selection(const struct tiocl_selection
__user *sel, struct tty_struct *t
ys = limit(ys, vc->vc_rows - 1);
xe = limit(xe, vc->vc_cols - 1);
ye = limit(ye, vc->vc_rows - 1);
- ps = ys * vc->vc_size_row + (xs << 1);
- pe = ye * vc->vc_size_row + (xe << 1);
+ ps = ys * vc->vc_size_row + (xs << 2);
+ pe = ye * vc->vc_size_row + (xe << 2);

if (sel_mode == TIOCL_SELCLEAR) {
/* useful for screendump without selection highlights */
@@ -194,7 +194,7 @@ int set_selection(const struct tiocl_selection
__user *sel, struct tty_struct *t
break;
case TIOCL_SELWORD: /* word-by-word selection */
spc = isspace(sel_pos(ps));
- for (new_sel_start = ps; ; ps -= 2)
+ for (new_sel_start = ps; ; ps -= 4)
{
if ((spc && !isspace(sel_pos(ps))) ||
(!spc && !inword(sel_pos(ps))))
@@ -204,20 +204,20 @@ int set_selection(const struct tiocl_selection
__user *sel, struct tty_struct *t
break;
}
spc = isspace(sel_pos(pe));
- for (new_sel_end = pe; ; pe += 2)
+ for (new_sel_end = pe; ; pe += 4)
{
if ((spc && !isspace(sel_pos(pe))) ||
(!spc && !inword(sel_pos(pe))))
break;
new_sel_end = pe;
- if (!((pe + 2) % vc->vc_size_row))
+ if (!((pe + 4) % vc->vc_size_row))
break;
}
break;
case TIOCL_SELLINE: /* line-by-line selection */
new_sel_start = ps - ps % vc->vc_size_row;
new_sel_end = pe + vc->vc_size_row
- - pe % vc->vc_size_row - 2;
+ - pe % vc->vc_size_row - 4;
break;
case TIOCL_SELPOINTER:
highlight_pointer(pe);
@@ -233,7 +233,7 @@ int set_selection(const struct tiocl_selection
__user *sel, struct tty_struct *t
if (new_sel_end > new_sel_start &&
!atedge(new_sel_end, vc->vc_size_row) &&
isspace(sel_pos(new_sel_end))) {
- for (pe = new_sel_end + 2; ; pe += 2)
+ for (pe = new_sel_end + 4; ; pe += 4)
if (!isspace(sel_pos(pe)) ||
atedge(pe, vc->vc_size_row))
break;
@@ -247,16 +247,16 @@ int set_selection(const struct tiocl_selection
__user *sel, struct tty_struct *t
if (new_sel_end == sel_end) /* no action required */
return 0;
else if (new_sel_end > sel_end) /* extend to right */
- highlight(sel_end + 2, new_sel_end);
+ highlight(sel_end + 4, new_sel_end);
else /* contract from right */
- highlight(new_sel_end + 2, sel_end);
+ highlight(new_sel_end + 4, sel_end);
}
else if (new_sel_end == sel_end)
{
if (new_sel_start < sel_start) /* extend to left */
- highlight(new_sel_start, sel_start - 2);
+ highlight(new_sel_start, sel_start - 4);
else /* contract from left */
- highlight(sel_start, new_sel_start - 2);
+ highlight(sel_start, new_sel_start - 4);
}
else /* some other case; start selection from scratch */
{
@@ -278,7 +278,7 @@ int set_selection(const struct tiocl_selection
__user *sel, struct tty_struct *t
sel_buffer = bp;

obp = bp;
- for (i = sel_start; i <= sel_end; i += 2) {
+ for (i = sel_start; i <= sel_end; i += 4) {
c = sel_pos(i);
if (use_unicode)
bp += store_utf8(c, bp);
@@ -286,7 +286,7 @@ int set_selection(const struct tiocl_selection
__user *sel, struct tty_struct *t
*bp++ = c;
if (!isspace(c))
obp = bp;
- if (! ((i + 2) % vc->vc_size_row)) {
+ if (! ((i + 4) % vc->vc_size_row)) {
/* strip trailing blanks from line and add newline,
unless non-space at end of line. */
if (obp != bp) {
diff --git a/drivers/char/vc_screen.c b/drivers/char/vc_screen.c
index c1791a6..b4018b4 100644
--- a/drivers/char/vc_screen.c
+++ b/drivers/char/vc_screen.c
@@ -105,7 +105,7 @@ vcs_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
long pos;
long viewed, attr, read;
int col, maxcol;
- unsigned short *org = NULL;
+ u32 *org = NULL;
ssize_t ret;

mutex_lock(&con_buf_mtx);
@@ -279,7 +279,7 @@ vcs_write(struct file *file, const char __user
*buf, size_t count, loff_t *ppos)
long viewed, attr, size, written;
char *con_buf0;
int col, maxcol;
- u16 *org0 = NULL, *org = NULL;
+ u32 *org0 = NULL, *org = NULL;
size_t ret;

mutex_lock(&con_buf_mtx);
@@ -369,7 +369,7 @@ vcs_write(struct file *file, const char __user
*buf, size_t count, loff_t *ppos)

this_round--;
vcs_scr_writew(vc,
- (vcs_scr_readw(vc, org) & 0xff00) | c, org);
+ (vcs_scr_readw(vc, org) & VT_BUF_ATTR_MASK) | c, org);
org++;
if (++col == maxcol) {
org = screen_pos(vc, p, viewed);
@@ -400,7 +400,7 @@ vcs_write(struct file *file, const char __user
*buf, size_t count, loff_t *ppos)
c = *con_buf0++;
#ifdef __BIG_ENDIAN
vcs_scr_writew(vc, c |
- (vcs_scr_readw(vc, org) & 0xff00), org);
+ (vcs_scr_readw(vc, org) & VT_BUF_ATTR_MASK), org);
#else
vcs_scr_writew(vc, (c << 8) |
(vcs_scr_readw(vc, org) & 0xff), org);
diff --git a/drivers/char/vt.c b/drivers/char/vt.c
index bd1d116..2c5ebd4 100644
--- a/drivers/char/vt.c
+++ b/drivers/char/vt.c
@@ -267,14 +267,14 @@ static void notify_update(struct vc_data *vc)
#define DO_UPDATE(vc) (CON_IS_VISIBLE(vc) && !console_blanked)
#endif

-static inline unsigned short *screenpos(struct vc_data *vc, int
offset, int viewed)
+static inline u32 *screenpos(struct vc_data *vc, int offset, int viewed)
{
- unsigned short *p;
+ u32 *p;

if (!viewed)
- p = (unsigned short *)(vc->vc_origin + offset);
+ p = (u32 *)(vc->vc_origin + offset);
else if (!vc->vc_sw->con_screen_pos)
- p = (unsigned short *)(vc->vc_visible_origin + offset);
+ p = (u32 *)(vc->vc_visible_origin + offset);
else
p = vc->vc_sw->con_screen_pos(vc, offset);
return p;
@@ -293,7 +293,7 @@ void schedule_console_callback(void)

static void scrup(struct vc_data *vc, unsigned int t, unsigned int b, int nr)
{
- unsigned short *d, *s;
+ u32 *d, *s;

if (t+nr >= b)
nr = b - t - 1;
@@ -301,8 +301,8 @@ static void scrup(struct vc_data *vc, unsigned int
t, unsigned int b, int nr)
return;
if (CON_IS_VISIBLE(vc) && vc->vc_sw->con_scroll(vc, t, b, SM_UP, nr))
return;
- d = (unsigned short *)(vc->vc_origin + vc->vc_size_row * t);
- s = (unsigned short *)(vc->vc_origin + vc->vc_size_row * (t + nr));
+ d = (u32 *)(vc->vc_origin + vc->vc_size_row * t);
+ s = (u32 *)(vc->vc_origin + vc->vc_size_row * (t + nr));
scr_memmovew(d, s, (b - t - nr) * vc->vc_size_row);
scr_memsetw(d + (b - t - nr) * vc->vc_cols, vc->vc_video_erase_char,
vc->vc_size_row * nr);
@@ -310,7 +310,7 @@ static void scrup(struct vc_data *vc, unsigned int
t, unsigned int b, int nr)

static void scrdown(struct vc_data *vc, unsigned int t, unsigned int b, int nr)
{
- unsigned short *s;
+ u32 *s;
unsigned int step;

if (t+nr >= b)
@@ -319,21 +319,21 @@ static void scrdown(struct vc_data *vc, unsigned
int t, unsigned int b, int nr)
return;
if (CON_IS_VISIBLE(vc) && vc->vc_sw->con_scroll(vc, t, b, SM_DOWN, nr))
return;
- s = (unsigned short *)(vc->vc_origin + vc->vc_size_row * t);
+ s = (u32 *)(vc->vc_origin + vc->vc_size_row * t);
step = vc->vc_cols * nr;
scr_memmovew(s + step, s, (b - t - nr) * vc->vc_size_row);
- scr_memsetw(s, vc->vc_video_erase_char, 2 * step);
+ scr_memsetw(s, vc->vc_video_erase_char, 4 * step);
}

static void do_update_region(struct vc_data *vc, unsigned long start,
int count)
{
#ifndef VT_BUF_VRAM_ONLY
unsigned int xx, yy, offset;
- u16 *p;
+ u32 *p;

- p = (u16 *) start;
+ p = (u32 *) start;
if (!vc->vc_sw->con_getxy) {
- offset = (start - vc->vc_origin) / 2;
+ offset = (start - vc->vc_origin) / 4;
xx = offset % vc->vc_cols;
yy = offset / vc->vc_cols;
} else {
@@ -342,16 +342,16 @@ static void do_update_region(struct vc_data *vc,
unsigned long start, int count)
xx = nxx; yy = nyy;
}
for(;;) {
- u16 attrib = scr_readw(p) & 0xff00;
+ u32 attrib = scr_readw(p) & VT_BUF_ATTR_MASK;
int startx = xx;
- u16 *q = p;
+ u32 *q = p;
while (xx < vc->vc_cols && count) {
- if (attrib != (scr_readw(p) & 0xff00)) {
+ if (attrib != (scr_readw(p) & VT_BUF_ATTR_MASK)) {
if (p > q)
vc->vc_sw->con_putcs(vc, q, p-q, yy, startx);
startx = xx;
q = p;
- attrib = scr_readw(p) & 0xff00;
+ attrib = scr_readw(p) & VT_BUF_ATTR_MASK;
}
p++;
xx++;
@@ -364,7 +364,7 @@ static void do_update_region(struct vc_data *vc,
unsigned long start, int count)
xx = 0;
yy++;
if (vc->vc_sw->con_getxy) {
- p = (u16 *)start;
+ p = (u32 *)start;
start = vc->vc_sw->con_getxy(vc, start, NULL, NULL);
}
}
@@ -411,7 +411,7 @@ static u8 build_attr(struct vc_data *vc, u8
_color, u8 _intensity, u8 _blink,
(_reverse ? 8 : 0) |
(_blink ? 0x80 : 0);
if (_italic)
- a = (a & 0xF0) | vc->vc_itcolor;
+ a = (a & 0xf0) | vc->vc_itcolor;
else if (_underline)
a = (a & 0xf0) | vc->vc_ulcolor;
else if (_intensity == 0)
@@ -436,44 +436,51 @@ 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_italic);
- vc->vc_video_erase_char = (build_attr(vc, vc->vc_color, 1,
vc->vc_blink, 0, vc->vc_decscnm, 0) << 8) | ' ';
+ vc->vc_video_erase_char = (build_attr(vc, vc->vc_color, 1,
+ vc->vc_blink, 0, vc->vc_decscnm, 0) << VT_BUF_ATTR_SHIFT) | ' ';
}

/* Note: inverting the screen twice should revert to the original state */
void invert_screen(struct vc_data *vc, int offset, int count, int viewed)
{
- unsigned short *p;
+ u32 *p;

WARN_CONSOLE_UNLOCKED();

- count /= 2;
+ count /= 4;
p = screenpos(vc, offset, viewed);
if (vc->vc_sw->con_invert_region)
vc->vc_sw->con_invert_region(vc, p, count);
#ifndef VT_BUF_VRAM_ONLY
else {
- u16 *q = p;
+ u32 *q = p;
int cnt = count;
- u16 a;
+ u32 a;

if (!vc->vc_can_do_color) {
while (cnt--) {
a = scr_readw(q);
- a ^= 0x0800;
+ a ^= 0x08 << VT_BUF_ATTR_SHIFT;
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);
+ a = (a & ~VT_BUF_ATTR_MASK) |
+ (a & (0x10 << VT_BUF_ATTR_SHIFT)) |
+ ((a & (0xe0 << VT_BUF_ATTR_SHIFT)) >> 4) |
+ ((a & (0x0e << VT_BUF_ATTR_SHIFT)) << 4);
scr_writew(a, q);
q++;
}
} else {
while (cnt--) {
a = scr_readw(q);
- a = ((a) & 0x88ff) | (((a) & 0x7000) >> 4) | (((a) & 0x0700) << 4);
+ a = (a & ~VT_BUF_ATTR_MASK) |
+ (a & (0x88 << VT_BUF_ATTR_SHIFT)) |
+ ((a & (0x70 << VT_BUF_ATTR_SHIFT)) >> 4) |
+ ((a & (0x07 << VT_BUF_ATTR_SHIFT)) << 4);
scr_writew(a, q);
q++;
}
@@ -488,7 +495,7 @@ void invert_screen(struct vc_data *vc, int offset,
int count, int viewed)
void complement_pos(struct vc_data *vc, int offset)
{
static int old_offset = -1;
- static unsigned short old;
+ static u32 old;
static unsigned short oldx, oldy;

WARN_CONSOLE_UNLOCKED();
@@ -504,15 +511,15 @@ void complement_pos(struct vc_data *vc, int offset)

if (offset != -1 && offset >= 0 &&
offset < vc->vc_screenbuf_size) {
- unsigned short new;
- unsigned short *p;
+ u32 new;
+ u32 *p;
p = screenpos(vc, offset, 1);
old = scr_readw(p);
new = old ^ vc->vc_complement_mask;
scr_writew(new, p);
if (DO_UPDATE(vc)) {
- oldx = (offset >> 1) % vc->vc_cols;
- oldy = (offset >> 1) / vc->vc_cols;
+ oldx = (offset >> 2) % vc->vc_cols;
+ oldy = (offset >> 2) / vc->vc_cols;
vc->vc_sw->con_putc(vc, new, oldy, oldx);
}
}
@@ -521,18 +528,18 @@ void complement_pos(struct vc_data *vc, int offset)

static void insert_char(struct vc_data *vc, unsigned int nr)
{
- unsigned short *p, *q = (unsigned short *)vc->vc_pos;
+ u32 *p, *q = (u32 *)vc->vc_pos;

p = q + vc->vc_cols - nr - vc->vc_x;
while (--p >= q)
scr_writew(scr_readw(p), p + nr);
- scr_memsetw(q, vc->vc_video_erase_char, nr * 2);
+ scr_memsetw(q, vc->vc_video_erase_char, nr * 4);
vc->vc_need_wrap = 0;
if (DO_UPDATE(vc)) {
- unsigned short oldattr = vc->vc_attr;
+ u8 oldattr = vc->vc_attr;
vc->vc_sw->con_bmove(vc, vc->vc_y, vc->vc_x, vc->vc_y, vc->vc_x + nr, 1,
vc->vc_cols - vc->vc_x - nr);
- vc->vc_attr = vc->vc_video_erase_char >> 8;
+ vc->vc_attr = vc->vc_video_erase_char >> VT_BUF_ATTR_SHIFT;
while (nr--)
vc->vc_sw->con_putc(vc, vc->vc_video_erase_char, vc->vc_y, vc->vc_x + nr);
vc->vc_attr = oldattr;
@@ -542,19 +549,19 @@ static void insert_char(struct vc_data *vc,
unsigned int nr)
static void delete_char(struct vc_data *vc, unsigned int nr)
{
unsigned int i = vc->vc_x;
- unsigned short *p = (unsigned short *)vc->vc_pos;
+ u32 *p = (u32 *)vc->vc_pos;

while (++i <= vc->vc_cols - nr) {
- scr_writew(scr_readw(p+nr), p);
+ scr_writew(scr_readw(p + nr), p);
p++;
}
- scr_memsetw(p, vc->vc_video_erase_char, nr * 2);
+ scr_memsetw(p, vc->vc_video_erase_char, nr * 4);
vc->vc_need_wrap = 0;
if (DO_UPDATE(vc)) {
- unsigned short oldattr = vc->vc_attr;
+ u8 oldattr = vc->vc_attr;
vc->vc_sw->con_bmove(vc, vc->vc_y, vc->vc_x + nr, vc->vc_y, vc->vc_x, 1,
vc->vc_cols - vc->vc_x - nr);
- vc->vc_attr = vc->vc_video_erase_char >> 8;
+ vc->vc_attr = vc->vc_video_erase_char >> VT_BUF_ATTR_SHIFT;
while (nr--)
vc->vc_sw->con_putc(vc, vc->vc_video_erase_char, vc->vc_y,
vc->vc_cols - 1 - nr);
@@ -562,21 +569,29 @@ static void delete_char(struct vc_data *vc,
unsigned int nr)
}
}

-static int softcursor_original;
+static u32 softcursor_original;

static void add_softcursor(struct vc_data *vc)
{
- int i = scr_readw((u16 *) vc->vc_pos);
+ u32 i = scr_readw((u32 *) vc->vc_pos);
u32 type = vc->vc_cursor_type;

- if (! (type & 0x10)) return;
- if (softcursor_original != -1) return;
+ if (! (type & 0x10))
+ return;
+ if (softcursor_original != -1)
+ return;
softcursor_original = i;
- i |= ((type >> 8) & 0xff00 );
- i ^= ((type) & 0xff00 );
- if ((type & 0x20) && ((softcursor_original & 0x7000) == (i &
0x7000))) i ^= 0x7000;
- if ((type & 0x40) && ((i & 0x700) == ((i & 0x7000) >> 4))) i ^= 0x0700;
- scr_writew(i, (u16 *) vc->vc_pos);
+ i |= (((type >> 16) & 0xff) << VT_BUF_ATTR_SHIFT);
+ i ^= (((type >> 8) & 0xff) << VT_BUF_ATTR_SHIFT);
+ if ((type & 0x20) &&
+ ((softcursor_original & (0x70 << VT_BUF_ATTR_SHIFT)) ==
+ (i & (0x70 << VT_BUF_ATTR_SHIFT))))
+ i ^= 0x70 << VT_BUF_ATTR_SHIFT;
+ if ((type & 0x40) &&
+ ((i & (0x07 << VT_BUF_ATTR_SHIFT)) ==
+ ((i & (0x70 << VT_BUF_ATTR_SHIFT)) >> 4)))
+ i ^= 0x07 << VT_BUF_ATTR_SHIFT;
+ scr_writew(i, (u32 *) vc->vc_pos);
if (DO_UPDATE(vc))
vc->vc_sw->con_putc(vc, i, vc->vc_y, vc->vc_x);
}
@@ -584,7 +599,7 @@ static void add_softcursor(struct vc_data *vc)
static void hide_softcursor(struct vc_data *vc)
{
if (softcursor_original != -1) {
- scr_writew(softcursor_original, (u16 *)vc->vc_pos);
+ scr_writew(softcursor_original, (u32 *)vc->vc_pos);
if (DO_UPDATE(vc))
vc->vc_sw->con_putc(vc, softcursor_original,
vc->vc_y, vc->vc_x);
@@ -625,7 +640,7 @@ static void set_origin(struct vc_data *vc)
vc->vc_origin = (unsigned long)vc->vc_screenbuf;
vc->vc_visible_origin = vc->vc_origin;
vc->vc_scr_end = vc->vc_origin + vc->vc_screenbuf_size;
- vc->vc_pos = vc->vc_origin + vc->vc_size_row * vc->vc_y + 2 * vc->vc_x;
+ vc->vc_pos = vc->vc_origin + vc->vc_size_row * vc->vc_y + 4 * vc->vc_x;
}

static inline void save_screen(struct vc_data *vc)
@@ -642,12 +657,12 @@ static inline void save_screen(struct vc_data *vc)

static void clear_buffer_attributes(struct vc_data *vc)
{
- unsigned short *p = (unsigned short *)vc->vc_origin;
- int count = vc->vc_screenbuf_size / 2;
- int mask = vc->vc_hi_font_mask | 0xff;
+ u32 *p = (u32 *)vc->vc_origin;
+ int count = vc->vc_screenbuf_size / 4;
+ u32 mask = ~VT_BUF_ATTR_MASK;

for (; count > 0; count--, p++) {
- scr_writew((scr_readw(p)&mask) | (vc->vc_video_erase_char & ~mask), p);
+ scr_writew((scr_readw(p) & mask) | (vc->vc_video_erase_char & ~mask), p);
}
}

@@ -699,7 +714,7 @@ void redraw_screen(struct vc_data *vc, int is_switch)
clear_buffer_attributes(vc);
}
if (update && vc->vc_mode != KD_GRAPHICS)
- do_update_region(vc, vc->vc_origin, vc->vc_screenbuf_size / 2);
+ do_update_region(vc, vc->vc_origin, vc->vc_screenbuf_size / 4);
}
set_cursor(vc);
if (is_switch) {
@@ -738,9 +753,9 @@ static void visual_init(struct vc_data *vc, int
num, int init)
vc->vc_can_do_color = 0;
vc->vc_sw->con_init(vc, init);
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) <<
VT_BUF_ATTR_SHIFT;
vc->vc_s_complement_mask = vc->vc_complement_mask;
- vc->vc_size_row = vc->vc_cols << 1;
+ vc->vc_size_row = vc->vc_cols << 2;
vc->vc_screenbuf_size = vc->vc_rows * vc->vc_size_row;
}

@@ -834,7 +849,7 @@ static int vc_do_resize(struct tty_struct *tty,
struct vc_data *vc,
unsigned int old_cols, old_rows, old_row_size, old_screen_size;
unsigned int new_cols, new_rows, new_row_size, new_screen_size;
unsigned int end, user;
- unsigned short *newscreen;
+ u32 *newscreen;

WARN_CONSOLE_UNLOCKED();

@@ -849,7 +864,7 @@ static int vc_do_resize(struct tty_struct *tty,
struct vc_data *vc,

new_cols = (cols ? cols : vc->vc_cols);
new_rows = (lines ? lines : vc->vc_rows);
- new_row_size = new_cols << 1;
+ new_row_size = new_cols << 2;
new_screen_size = new_row_size * new_rows;

if (new_cols == vc->vc_cols && new_rows == vc->vc_rows)
@@ -894,7 +909,7 @@ static int vc_do_resize(struct tty_struct *tty,
struct vc_data *vc,
* Cursor is in no man's land, copy 1/2 screenful
* from the top and bottom of cursor position
*/
- old_origin += (vc->vc_y - new_rows/2) * old_row_size;
+ old_origin += (vc->vc_y - new_rows / 2) * old_row_size;
end = old_origin + (old_row_size * new_rows);
}
} else
@@ -908,8 +923,8 @@ static int vc_do_resize(struct tty_struct *tty,
struct vc_data *vc,
update_attr(vc);

while (old_origin < end) {
- scr_memcpyw((unsigned short *) new_origin,
- (unsigned short *) old_origin, rlth);
+ scr_memcpyw((u32 *) new_origin,
+ (u32 *) old_origin, rlth);
if (rrem)
scr_memsetw((void *)(new_origin + rlth),
vc->vc_video_erase_char, rrem);
@@ -917,7 +932,7 @@ static int vc_do_resize(struct tty_struct *tty,
struct vc_data *vc,
new_origin += new_row_size;
}
if (new_scr_end > new_origin)
- scr_memsetw((void *)new_origin, vc->vc_video_erase_char,
+ scr_memsetw((u32 *)new_origin, vc->vc_video_erase_char,
new_scr_end - new_origin);
kfree(vc->vc_screenbuf);
vc->vc_screenbuf = newscreen;
@@ -1072,7 +1087,7 @@ static void gotoxy(struct vc_data *vc, int
new_x, int new_y)
vc->vc_y = max_y - 1;
else
vc->vc_y = new_y;
- vc->vc_pos = vc->vc_origin + vc->vc_y * vc->vc_size_row + (vc->vc_x<<1);
+ vc->vc_pos = vc->vc_origin + vc->vc_y * vc->vc_size_row + (vc->vc_x << 2);
vc->vc_need_wrap = 0;
}

@@ -1127,7 +1142,7 @@ static void ri(struct vc_data *vc)

static inline void cr(struct vc_data *vc)
{
- vc->vc_pos -= vc->vc_x << 1;
+ vc->vc_pos -= vc->vc_x << 2;
vc->vc_need_wrap = vc->vc_x = 0;
notify_write(vc, '\r');
}
@@ -1135,7 +1150,7 @@ static inline void cr(struct vc_data *vc)
static inline void bs(struct vc_data *vc)
{
if (vc->vc_x) {
- vc->vc_pos -= 2;
+ vc->vc_pos -= 4;
vc->vc_x--;
vc->vc_need_wrap = 0;
notify_write(vc, '\b');
@@ -1150,12 +1165,12 @@ static inline void del(struct vc_data *vc)
static void csi_J(struct vc_data *vc, int vpar)
{
unsigned int count;
- unsigned short * start;
+ u32 *start;

switch (vpar) {
case 0: /* erase from cursor to end of display */
- count = (vc->vc_scr_end - vc->vc_pos) >> 1;
- start = (unsigned short *)vc->vc_pos;
+ count = (vc->vc_scr_end - vc->vc_pos) >> 2;
+ start = (u32 *)vc->vc_pos;
if (DO_UPDATE(vc)) {
/* do in two stages */
vc->vc_sw->con_clear(vc, vc->vc_y, vc->vc_x, 1,
@@ -1166,8 +1181,8 @@ static void csi_J(struct vc_data *vc, int vpar)
}
break;
case 1: /* erase from start to cursor */
- count = ((vc->vc_pos - vc->vc_origin) >> 1) + 1;
- start = (unsigned short *)vc->vc_origin;
+ count = ((vc->vc_pos - vc->vc_origin) >> 2) + 1;
+ start = (u32 *)vc->vc_origin;
if (DO_UPDATE(vc)) {
/* do in two stages */
vc->vc_sw->con_clear(vc, 0, 0, vc->vc_y,
@@ -1178,7 +1193,7 @@ static void csi_J(struct vc_data *vc, int vpar)
break;
case 2: /* erase whole display */
count = vc->vc_cols * vc->vc_rows;
- start = (unsigned short *)vc->vc_origin;
+ start = (u32 *)vc->vc_origin;
if (DO_UPDATE(vc))
vc->vc_sw->con_clear(vc, 0, 0,
vc->vc_rows,
@@ -1187,32 +1202,32 @@ static void csi_J(struct vc_data *vc, int vpar)
default:
return;
}
- scr_memsetw(start, vc->vc_video_erase_char, 2 * count);
+ scr_memsetw(start, vc->vc_video_erase_char, 4 * count);
vc->vc_need_wrap = 0;
}

static void csi_K(struct vc_data *vc, int vpar)
{
unsigned int count;
- unsigned short * start;
+ u32 *start;

switch (vpar) {
case 0: /* erase from cursor to end of line */
count = vc->vc_cols - vc->vc_x;
- start = (unsigned short *)vc->vc_pos;
+ start = (u32 *)vc->vc_pos;
if (DO_UPDATE(vc))
vc->vc_sw->con_clear(vc, vc->vc_y, vc->vc_x, 1,
vc->vc_cols - vc->vc_x);
break;
case 1: /* erase from start of line to cursor */
- start = (unsigned short *)(vc->vc_pos - (vc->vc_x << 1));
+ start = (u32 *)(vc->vc_pos - (vc->vc_x << 2));
count = vc->vc_x + 1;
if (DO_UPDATE(vc))
vc->vc_sw->con_clear(vc, vc->vc_y, 0, 1,
vc->vc_x + 1);
break;
case 2: /* erase whole line */
- start = (unsigned short *)(vc->vc_pos - (vc->vc_x << 1));
+ start = (u32 *)(vc->vc_pos - (vc->vc_x << 2));
count = vc->vc_cols;
if (DO_UPDATE(vc))
vc->vc_sw->con_clear(vc, vc->vc_y, 0, 1,
@@ -1221,7 +1236,7 @@ static void csi_K(struct vc_data *vc, int vpar)
default:
return;
}
- scr_memsetw(start, vc->vc_video_erase_char, 2 * count);
+ scr_memsetw(start, vc->vc_video_erase_char, 4 * count);
vc->vc_need_wrap = 0;
}

@@ -1233,7 +1248,7 @@ static void csi_X(struct vc_data *vc, int vpar)
/* erase the following vpar posi
vpar++;
count = (vpar > vc->vc_cols - vc->vc_x) ? (vc->vc_cols - vc->vc_x) : vpar;

- scr_memsetw((unsigned short *)vc->vc_pos, vc->vc_video_erase_char, 2 * count);
+ scr_memsetw((u32 *)vc->vc_pos, vc->vc_video_erase_char, 4 * count);
if (DO_UPDATE(vc))
vc->vc_sw->con_clear(vc, vc->vc_y, vc->vc_x, 1, count);
vc->vc_need_wrap = 0;
@@ -1681,13 +1696,13 @@ static void do_con_trol(struct tty_struct
*tty, struct vc_data *vc, int c)
bs(vc);
return;
case 9:
- vc->vc_pos -= (vc->vc_x << 1);
+ vc->vc_pos -= (vc->vc_x << 2);
while (vc->vc_x < vc->vc_cols - 1) {
vc->vc_x++;
if (vc->vc_tab_stop[vc->vc_x >> 5] & (1 << (vc->vc_x & 31)))
break;
}
- vc->vc_pos += (vc->vc_x << 1);
+ vc->vc_pos += (vc->vc_x << 2);
notify_write(vc, '\t');
return;
case 10: case 11: case 12:
@@ -2008,11 +2023,11 @@ static void do_con_trol(struct tty_struct
*tty, struct vc_data *vc, int 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 & VT_BUF_ATTR_MASK) | 'E';
csi_J(vc, 2);
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 & VT_BUF_ATTR_MASK) | ' ';
+ do_update_region(vc, vc->vc_origin, vc->vc_screenbuf_size / 4);
}
return;
case ESsetG0:
@@ -2104,7 +2119,7 @@ static int do_con_write(struct tty_struct *tty,
const unsigned char *buf, int co
#define FLUSH do { } while(0);
#else
#define FLUSH if (draw_x >= 0) { \
- vc->vc_sw->con_putcs(vc, (u16 *)draw_from, (u16 *)draw_to - (u16
*)draw_from, vc->vc_y, draw_x); \
+ vc->vc_sw->con_putcs(vc, (u32 *)draw_from, (u32 *)draw_to - (u32
*)draw_from, vc->vc_y, draw_x); \
draw_x = -1; \
}
#endif
@@ -2118,7 +2133,8 @@ static int do_con_write(struct tty_struct *tty,
const unsigned char *buf, int co
uint8_t rescan;
uint8_t inverse;
uint8_t width;
- u16 himask, charmask;
+ u32 charmask = ~VT_BUF_ATTR_MASK;
+ uint8_t char_found;

if (in_interrupt())
return count;
@@ -2141,9 +2157,6 @@ static int do_con_write(struct tty_struct *tty,
const unsigned char *buf, int co
return 0;
}

- himask = vc->vc_hi_font_mask;
- charmask = himask ? 0x1ff : 0xff;
-
/* undraw cursor first */
if (IS_FG(vc))
hide_cursor(vc);
@@ -2267,6 +2280,7 @@ rescan_last_byte:
/* Now try to find out how to display it */
tc = conv_uni_to_pc(vc, tc);
if (tc & ~charmask) {
+ char_found = 0;
if (tc == -1 || tc == -2) {
continue; /* nothing to display */
}
@@ -2288,6 +2302,9 @@ rescan_last_byte:
}
}
}
+ else {
+ char_found = 1;
+ }

if (!inverse) {
vc_attr = vc->vc_attr;
@@ -2312,26 +2329,31 @@ rescan_last_byte:
}
if (vc->vc_decim)
insert_char(vc, 1);
- scr_writew(himask ?
- ((vc_attr << 8) & ~himask) + ((tc & 0x100) ? himask : 0) +
(tc & 0xff) :
- (vc_attr << 8) + tc,
- (u16 *) vc->vc_pos);
+ scr_writew((vc_attr << VT_BUF_ATTR_SHIFT) + tc,
+ (u32 *) vc->vc_pos);
if (DO_UPDATE(vc) && draw_x < 0) {
draw_x = vc->vc_x;
draw_from = vc->vc_pos;
}
if (vc->vc_x == vc->vc_cols - 1) {
vc->vc_need_wrap = vc->vc_decawm;
- draw_to = vc->vc_pos + 2;
+ draw_to = vc->vc_pos + 4;
} else {
vc->vc_x++;
- draw_to = (vc->vc_pos += 2);
+ draw_to = (vc->vc_pos += 4);
}

if (!--width) break;

- tc = conv_uni_to_pc(vc, ' '); /* A space is printed in the second column */
- if (tc < 0) tc = ' ';
+ if (char_found) {
+ /* The 2nd half of wide char is right after the 1st */
+ tc++;
+ }
+ else {
+ /* A space is printed in the second column */
+ tc = conv_uni_to_pc(vc, ' ');
+ if (tc < 0) tc = ' ';
+ }
}
notify_write(vc, c);

@@ -2473,7 +2495,7 @@ static void vt_console_print(struct console *co,
const char *b, unsigned count)
struct vc_data *vc = vc_cons[fg_console].d;
unsigned char c;
static DEFINE_SPINLOCK(printing_lock);
- const ushort *start;
+ const u32 *start;
ushort cnt = 0;
ushort myx;
int kmsg_console;
@@ -2505,7 +2527,7 @@ static void vt_console_print(struct console *co,
const char *b, unsigned count)
if (IS_FG(vc))
hide_cursor(vc);

- start = (ushort *)vc->vc_pos;
+ start = (u32 *)vc->vc_pos;

/* Contrived structure to try to emulate original need_wrap behaviour
* Problems caused when we have need_wrap set on '\n' character */
@@ -2522,26 +2544,26 @@ static void vt_console_print(struct console
*co, const char *b, unsigned count)
}
if (c == 8) { /* backspace */
bs(vc);
- start = (ushort *)vc->vc_pos;
+ start = (u32 *)vc->vc_pos;
myx = vc->vc_x;
continue;
}
if (c != 13)
lf(vc);
cr(vc);
- start = (ushort *)vc->vc_pos;
+ start = (u32 *)vc->vc_pos;
myx = vc->vc_x;
if (c == 10 || c == 13)
continue;
}
- scr_writew((vc->vc_attr << 8) + c, (unsigned short *)vc->vc_pos);
+ scr_writew((vc->vc_attr << VT_BUF_ATTR_SHIFT) + c, (u32 *)vc->vc_pos);
notify_write(vc, c);
cnt++;
if (myx == vc->vc_cols - 1) {
vc->vc_need_wrap = 1;
continue;
}
- vc->vc_pos += 2;
+ vc->vc_pos += 4;
myx++;
}
if (cnt > 0) {
@@ -2843,7 +2865,7 @@ static void vc_init(struct vc_data *vc, unsigned int rows,

vc->vc_cols = cols;
vc->vc_rows = rows;
- vc->vc_size_row = cols << 1;
+ vc->vc_size_row = cols << 2;
vc->vc_screenbuf_size = vc->vc_rows * vc->vc_size_row;

set_origin(vc);
@@ -4057,19 +4079,15 @@ int con_font_op(struct vc_data *vc, struct
console_font_op *op)
/* used by selection */
u16 screen_glyph(struct vc_data *vc, int offset)
{
- u16 w = scr_readw(screenpos(vc, offset, 1));
- u16 c = w & 0xff;
-
- if (w & vc->vc_hi_font_mask)
- c |= 0x100;
- return c;
+ u32 w = scr_readw(screenpos(vc, offset, 1));
+ return w & ~VT_BUF_ATTR_MASK;
}
EXPORT_SYMBOL_GPL(screen_glyph);

/* used by vcs - note the word offset */
-unsigned short *screen_pos(struct vc_data *vc, int w_offset, int viewed)
+u32 *screen_pos(struct vc_data *vc, int w_offset, int viewed)
{
- return screenpos(vc, 2 * w_offset, viewed);
+ return screenpos(vc, 4 * w_offset, viewed);
}

void getconsxy(struct vc_data *vc, unsigned char *p)
@@ -4085,14 +4103,14 @@ void putconsxy(struct vc_data *vc, unsigned char *p)
set_cursor(vc);
}

-u16 vcs_scr_readw(struct vc_data *vc, const u16 *org)
+u32 vcs_scr_readw(struct vc_data *vc, const u32 *org)
{
if ((unsigned long)org == vc->vc_pos && softcursor_original != -1)
return softcursor_original;
return scr_readw(org);
}

-void vcs_scr_writew(struct vc_data *vc, u16 val, u16 *org)
+void vcs_scr_writew(struct vc_data *vc, u32 val, u32 *org)
{
scr_writew(val, org);
if ((unsigned long)org == vc->vc_pos) {
diff --git a/include/linux/console.h b/include/linux/console.h
index dcca533..ff374f9 100644
--- a/include/linux/console.h
+++ b/include/linux/console.h
@@ -34,8 +34,8 @@ struct consw {
void (*con_init)(struct vc_data *, int);
void (*con_deinit)(struct vc_data *);
void (*con_clear)(struct vc_data *, int, int, int, int);
- void (*con_putc)(struct vc_data *, int, int, int);
- void (*con_putcs)(struct vc_data *, const unsigned short *, int, int, int);
+ void (*con_putc)(struct vc_data *, u32, int, int);
+ void (*con_putcs)(struct vc_data *, const u32 *, int, int, int);
void (*con_cursor)(struct vc_data *, int);
int (*con_scroll)(struct vc_data *, int, int, int, int);
void (*con_bmove)(struct vc_data *, int, int, int, int, int, int);
@@ -52,8 +52,8 @@ struct consw {
int (*con_set_origin)(struct vc_data *);
void (*con_save_screen)(struct vc_data *);
u8 (*con_build_attr)(struct vc_data *, u8, u8, u8, u8, u8, u8);
- void (*con_invert_region)(struct vc_data *, u16 *, int);
- u16 *(*con_screen_pos)(struct vc_data *, int);
+ void (*con_invert_region)(struct vc_data *, u32 *, int);
+ u32 *(*con_screen_pos)(struct vc_data *, int);
unsigned long (*con_getxy)(struct vc_data *, unsigned long, int *, int *);
};

diff --git a/include/linux/console_struct.h b/include/linux/console_struct.h
index 38fe59d..767596d 100644
--- a/include/linux/console_struct.h
+++ b/include/linux/console_struct.h
@@ -31,7 +31,7 @@ struct vc_data {
unsigned long vc_visible_origin; /* [!] Top of visible window */
unsigned int vc_top, vc_bottom; /* Scrolling region */
const struct consw *vc_sw;
- unsigned short *vc_screenbuf; /* In-memory character/attribute buffer */
+ unsigned int *vc_screenbuf; /* In-memory character/attribute buffer */
unsigned int vc_screenbuf_size;
unsigned char vc_mode; /* KD_TEXT, ... */
/* attributes for all characters on screen */
@@ -44,15 +44,15 @@ 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 int vc_x, vc_y; /* Cursor position */
unsigned int vc_saved_x, vc_saved_y;
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 console_font vc_font; /* Current VC font set */
- unsigned short vc_video_erase_char; /* Background erase character */
+ 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 */
diff --git a/include/linux/selection.h b/include/linux/selection.h
index 8cdaa11..6570574 100644
--- a/include/linux/selection.h
+++ b/include/linux/selection.h
@@ -29,7 +29,7 @@ extern int default_red[];
extern int default_grn[];
extern int default_blu[];

-extern unsigned short *screen_pos(struct vc_data *vc, int w_offset,
int viewed);
+extern u32 *screen_pos(struct vc_data *vc, int w_offset, int viewed);
extern u16 screen_glyph(struct vc_data *vc, int offset);
extern void complement_pos(struct vc_data *vc, int offset);
extern void invert_screen(struct vc_data *vc, int offset, int count,
int shift);
@@ -37,7 +37,7 @@ extern void invert_screen(struct vc_data *vc, int
offset, int count, int shift);
extern void getconsxy(struct vc_data *vc, unsigned char *p);
extern void putconsxy(struct vc_data *vc, unsigned char *p);

-extern u16 vcs_scr_readw(struct vc_data *vc, const u16 *org);
-extern void vcs_scr_writew(struct vc_data *vc, u16 val, u16 *org);
+extern u32 vcs_scr_readw(struct vc_data *vc, const u32 *org);
+extern void vcs_scr_writew(struct vc_data *vc, u32 val, u32 *org);

#endif
diff --git a/include/linux/vt_buffer.h b/include/linux/vt_buffer.h
index 057db7d..e4669fa 100644
--- a/include/linux/vt_buffer.h
+++ b/include/linux/vt_buffer.h
@@ -28,30 +28,30 @@
#endif

#ifndef VT_BUF_HAVE_MEMSETW
-static inline void scr_memsetw(u16 *s, u16 c, unsigned int count)
+static inline void scr_memsetw(u32 *s, u32 c, unsigned int count)
{
- count /= 2;
+ count /= 4;
while (count--)
scr_writew(c, s++);
}
#endif

#ifndef VT_BUF_HAVE_MEMCPYW
-static inline void scr_memcpyw(u16 *d, const u16 *s, unsigned int count)
+static inline void scr_memcpyw(u32 *d, const u32 *s, unsigned int count)
{
- count /= 2;
+ count /= 4;
while (count--)
scr_writew(scr_readw(s++), d++);
}
#endif

#ifndef VT_BUF_HAVE_MEMMOVEW
-static inline void scr_memmovew(u16 *d, const u16 *s, unsigned int count)
+static inline void scr_memmovew(u32 *d, const u32 *s, unsigned int count)
{
if (d < s)
scr_memcpyw(d, s, count);
else {
- count /= 2;
+ count /= 4;
d += count;
s += count;
while (count--)
@@ -60,4 +60,7 @@ static inline void scr_memmovew(u16 *d, const u16
*s, unsigned int count)
}
#endif

+#define VT_BUF_ATTR_MASK 0xff000000
+#define VT_BUF_ATTR_SHIFT 24
+
#endif
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/