闲来没事儿,就编译裁剪内核玩玩,这次玩的是PC上的了。在标准配置文件上作了一定到删减,然后加上了Framebuffer和主板JMI368的驱动,另外打上了控制台中文补丁。就开定了。现在内核版本v2.6.32-rc8(git来的,快到release了)。
相关补丁文件如下:
<li>控制台显示中文补丁:<pre lang="diff" colla="-">
diff –git a/drivers/char/selection.c b/drivers/char/selection.c
index f97b9e8..8810628 100644
— a/drivers/char/selection.c
+++ b/drivers/char/selection.c
@@ -59,8 +59,7 @@ static inline void highlight_pointer(const int where)
static u16
sel_pos(int n)
{
-
return inverse_translate(sel_cons, screen_glyph(sel_cons, n),
-
use_unicode);
- return screen_glyph(sel_cons, n);
}
/* remove the current selection highlight, if any,
@@ -295,6 +294,8 @@ int set_selection(const struct tiocl_selection __user *sel, struct tty_struct *t
}
obp = bp;
}
-
if (c > 0x80)
-
i += 2;
}
sel_buffer_lth = bp - sel_buffer;
return 0;
diff –git a/drivers/char/vt.c b/drivers/char/vt.c
index 0c80c68..1c0465d 100644
— a/drivers/char/vt.c
+++ b/drivers/char/vt.c
@@ -277,6 +277,19 @@ static inline unsigned short *screenpos(struct vc_data *vc, int offset, int view
return p;
}
+static inline unsigned short *screenpos_utf8(struct vc_data *vc, int offset, int viewed)
+{
-
unsigned short *p;
-
if (!viewed)
-
p = (unsigned short *)(vc->vc_origin + offset + vc->vc_screenbuf_size);
-
else if (!vc->vc_sw->con_screen_pos)
-
p = (unsigned short *)(vc->vc_visible_origin + offset + vc->vc_screenbuf_size);
-
else
-
p = vc->vc_sw->con_screen_pos(vc, -offset - 1);
-
return p;
+}
static inline void scrolldelta(int lines)
{
scrollback_delta += lines;
@@ -303,6 +316,11 @@ static void scrup(struct vc_data *vc, unsigned int t, unsigned int b, int 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);
-
d += (vc->vc_screenbuf_size » 1);
-
s += (vc->vc_screenbuf_size » 1);
-
scr_memmovew(d, s, (b - t - nr) * vc->vc_size_row);
-
scr_memsetw(d + (b - t - nr) * vc->vc_cols, 0,
-
vc->vc_size_row * nr);
}
static void scrdown(struct vc_data *vc, unsigned int t, unsigned int b, int nr)
@@ -320,6 +338,9 @@ static void scrdown(struct vc_data *vc, unsigned int t, unsigned int b, int nr)
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);
-
s += (vc->vc_screenbuf_size » 1);
-
scr_memmovew(s + step, s, (b - t - nr) * vc->vc_size_row);
-
scr_memsetw(s, 0, 2 * step);
}
static void do_update_region(struct vc_data *vc, unsigned long start, int count)
@@ -487,6 +508,8 @@ void complement_pos(struct vc_data *vc, int offset)
static int old_offset = -1;
static unsigned short old;
static unsigned short oldx, oldy;
-
static unsigned short *p_ext = NULL;
-
static unsigned short old_ext = 0;
WARN_CONSOLE_UNLOCKED();
@@ -494,7 +517,7 @@ void complement_pos(struct vc_data *vc, int offset)
old_offset < vc->vc_screenbuf_size) {
scr_writew(old, screenpos(vc, old_offset, 1));
if (DO_UPDATE(vc))
-
vc->vc_sw->con_putc(vc, old, oldy, oldx);
-
vc->vc_sw->con_putc(vc, (old_ext << 16)|old, oldy, oldx);
}
old_offset = offset;
@@ -504,13 +527,15 @@ void complement_pos(struct vc_data *vc, int offset)
unsigned short new;
unsigned short *p;
p = screenpos(vc, offset, 1);
-
p_ext = screenpos_utf8(vc, offset, 1); old = scr_readw(p);
-
old_ext = scr_readw(p_ext); 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;
-
vc->vc_sw->con_putc(vc, new, oldy, oldx);
-
vc->vc_sw->con_putc(vc, (old_ext << 16)|new, oldy, oldx); }
}
@@ -769,7 +794,7 @@ int vc_allocate(unsigned int currcons) /* return 0 on success */
visual_init(vc, currcons, 1);
if (!*vc->vc_uni_pagedir_loc)
con_set_default_unimap(vc);
-
vc->vc_screenbuf = kmalloc(vc->vc_screenbuf_size, GFP_KERNEL);
-
vc->vc_screenbuf = kmalloc(vc->vc_screenbuf_size * 2, GFP_KERNEL); if (!vc->vc_screenbuf) { kfree(vc); vc_cons[currcons].d = NULL;
@@ -846,7 +871,7 @@ static int vc_do_resize(struct tty_struct *tty, struct vc_data *vc,
if (new_cols == vc->vc_cols && new_rows == vc->vc_rows)
return 0;
- newscreen = kmalloc(new_screen_size, GFP_USER);
-
newscreen = kmalloc(new_screen_size * 2, GFP_USER);
if (!newscreen)
return -ENOMEM;
@@ -901,15 +926,23 @@ static int vc_do_resize(struct tty_struct *tty, struct vc_data *vc,
while (old_origin < end) {
scr_memcpyw((unsigned short *) new_origin,
(unsigned short *) old_origin, rlth);
-
if (rrem)
-
scr_memcpyw((unsigned short *) new_origin + (new_screen_size >> 1),
-
(unsigned short *) old_origin + (old_screen_size >> 1), rlth);
-
if (rrem){ scr_memsetw((void *)(new_origin + rlth), vc->vc_video_erase_char, rrem);
-
scr_memsetw((void *)(new_origin + rlth + (new_screen_size)),
-
vc->vc_video_erase_char, rrem);
-
} old_origin += old_row_size; new_origin += new_row_size;
}
- if (new_scr_end > new_origin)
-
if (new_scr_end > new_origin){
scr_memsetw((void *)new_origin, vc->vc_video_erase_char, new_scr_end - new_origin);
-
scr_memsetw((void *)new_origin + (new_screen_size), vc->vc_video_erase_char,
-
new_scr_end - new_origin);
-
}
kfree(vc->vc_screenbuf);
vc->vc_screenbuf = newscreen;
vc->vc_screenbuf_size = new_screen_size;
@@ -2100,7 +2133,7 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co
}
#endif
- int c, tc, ok, n = 0, draw_x = -1;
-
int c, tc, tc_1, ok, n = 0, draw_x = -1;
unsigned int currcons;
unsigned long draw_from = 0, draw_to = 0;
struct vc_data *vc;
@@ -2112,6 +2145,7 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co
u16 himask, charmask;
const unsigned char *orig_buf = NULL;
int orig_count;
-
int is_utf8 = 0;
if (in_interrupt())
return count;
@@ -2154,6 +2188,8 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co
rescan = 0;
inverse = 0;
width = 1;
-
vc->vc_utf = 1;
-
vc->vc_disp_ctrl = 0; /* Do no translation at all in control states */ if (vc->vc_state != ESnormal) {
@@ -2195,6 +2231,7 @@ rescan_last_byte:
vc->vc_utf_count = 0;
c = 0xfffd;
} else if (c > 0x7f) {
-
is_utf8 = 1; /* First byte of a multibyte sequence received */ vc->vc_npar = 0; if ((c & 0xe0) == 0xc0) {
@@ -2220,8 +2257,9 @@ rescan_last_byte:
/* Still need some bytes */
continue;
}
-
} else {
-
is_utf8 = 0; }
-
/* Nothing to do if an ASCII byte was received */ } /* End of UTF-8 decoding. */ /* c is the received character, or U+FFFD for invalid sequences. */
@@ -2299,39 +2337,123 @@ rescan_last_byte:
}
while (1) {
-
if (vc->vc_need_wrap || vc->vc_decim)
-
FLUSH
-
if (vc->vc_need_wrap) {
-
cr(vc);
-
lf(vc);
-
}
-
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);
-
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;
-
} else {
-
vc->vc_x++;
-
draw_to = (vc->vc_pos += 2);
-
}
-
if(is_utf8 == 0) {
-
if (vc->vc_need_wrap || vc->vc_decim)
-
FLUSH
-
if (vc->vc_need_wrap) {
-
cr(vc);
-
lf(vc);
-
}
-
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(0, (u16 *) vc->vc_pos + (vc->vc_screenbuf_size >> 1));
-
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;
-
} else {
-
vc->vc_x++;
-
draw_to = (vc->vc_pos += 2);
-
}
-
if (!--width) break;
-
tc = conv_uni_to_pc(vc, ' '); /* A space is printed in the second column */
-
if (tc < 0) tc = ' ';
-
notify_write(vc, c);
-
if (inverse) {
-
FLUSH
-
}
-
if (!--width) break;
-
} else {
-
tc = 0xff;
-
tc_1 = 0xfe;
-
if (vc->vc_need_wrap || vc->vc_decim)
-
FLUSH
-
if (vc->vc_need_wrap) {
-
cr(vc);
-
lf(vc);
-
}
-
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(c,
-
(u16 *) vc->vc_pos + (vc->vc_screenbuf_size >> 1));
-
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;
-
} else {
-
vc->vc_x++;
-
draw_to = (vc->vc_pos += 2);
-
}
-
if (!--width) break;
-
tc = conv_uni_to_pc(vc, ' '); /* A space is printed in the second column */
-
if (tc < 0) tc = ' ';
-
notify_write(vc, c);
-
if (inverse) {
-
FLUSH
-
}
-
if (vc->vc_need_wrap || vc->vc_decim)
-
FLUSH
-
if (vc->vc_need_wrap) {
-
cr(vc);
-
lf(vc);
-
}
-
if (vc->vc_decim)
-
insert_char(vc, 1);
-
scr_writew(himask ?
-
((vc_attr << 8) & ~himask) + ((tc_1 & 0x100) ? himask : 0) + (tc_1 & 0xff) :
-
(vc_attr << 8) + tc_1,
-
(u16 *) vc->vc_pos);
-
scr_writew(c,
-
(u16 *) vc->vc_pos + (vc->vc_screenbuf_size >> 1));
-
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;
-
} else {
-
vc->vc_x++;
-
draw_to = (vc->vc_pos += 2);
-
}
-
if (!--width) break;
-
tc = conv_uni_to_pc(vc, ' '); /* A space is printed in the second column */
-
if (tc < 0) tc = ' ';
-
tc = conv_uni_to_pc(vc, ' '); /* A space is printed in the second column */
-
if (tc < 0) tc = ' ';
-
}
-
notify_write(vc, c);
-
notify_write(vc, c);
-
if (inverse) {
-
FLUSH
-
if (inverse) {
-
FLUSH
-
}
-
} } if (rescan) {
@@ -2871,7 +2993,7 @@ static int __init con_init(void)
vc_cons[currcons].d = vc = kzalloc(sizeof(struct vc_data), GFP_NOWAIT);
INIT_WORK(&vc_cons[currcons].SAK_work, vc_SAK);
visual_init(vc, currcons, 1);
-
vc->vc_screenbuf = kzalloc(vc->vc_screenbuf_size, GFP_NOWAIT);
-
vc->vc_screenbuf = kzalloc(vc->vc_screenbuf_size * 2, GFP_NOWAIT); vc_init(vc, vc->vc_rows, vc->vc_cols, currcons || !vc->vc_sw->con_save_screen);
}
@@ -4022,9 +4144,15 @@ 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;
-
u16 c_utf8 = scr_readw(screenpos_utf8(vc, offset, 1));
-
if ( (c == 0xff || c == 0xfe) && c_utf8 != 0){
-
return c_utf8;
-
}else{
-
if (w & vc->vc_hi_font_mask)
-
c |= 0x100;
-
return c;
-
}
}
EXPORT_SYMBOL_GPL(screen_glyph);
diff –git a/drivers/video/console/bitblit.c b/drivers/video/console/bitblit.c
index 6b7c8fb..9f041a9 100644
— a/drivers/video/console/bitblit.c
+++ b/drivers/video/console/bitblit.c
@@ -10,6 +10,8 @@
- more details.
*/
+#include <linux/font.h>
+#include “fonts_utf8.h”
#include <linux/module.h>
#include <linux/string.h>
#include <linux/fb.h>
@@ -42,6 +44,25 @@ static inline void update_attr(u8 *dst, u8 *src, int attribute,
}
}
+static int fbcon_softback_size = 32768;
+extern int fbcon_is_softback(const unsigned short *str);
+u16 utf8_pos(struct vc_data *vc, const unsigned short *utf8)
+{
-
unsigned long p = (long)utf8;
-
if (p >= vc->vc_origin && p < vc->vc_scr_end) {
-
return scr_readw((unsigned short *)(p + vc->vc_screenbuf_size));
-
} else if (vc->vc_num == fg_console && fbcon_is_softback(utf8)){
-
return scr_readw((unsigned short *)(p + fbcon_softback_size));
-
} else {
-
u16 extra_c;
-
int c = *(int*)utf8;
-
extra_c = (c >> 16 ) & 0x0000ffff;
-
return extra_c;
-
}
+}
static void bit_bmove(struct vc_data *vc, struct fb_info *info, int sy,
int sx, int dy, int dx, int height, int width)
{
@@ -82,14 +103,24 @@ static inline void bit_putcs_aligned(struct vc_data *vc, struct fb_info *info,
u32 idx = vc->vc_font.width >> 3;
u8 *src;
-
int utf8_c = 0;
while (cnt–) {
-
src = vc->vc_font.data + (scr_readw(s++)&
-
charmask)*cellsize;
-
utf8_c = utf8_pos(vc, s);
-
if(((scr_readw(s) & charmask) == 0xff || (scr_readw(s) & charmask) == 0xfe ) && utf8_c != 0){
-
if((scr_readw(s) & charmask) == 0xff){
-
src = font_utf8 + (utf8_c * 32);
-
}else{
-
src = font_utf8 + (utf8_c * 32 + 16);
-
}
-
}else{
-
src = vc->vc_font.data + (scr_readw(s) &
-
charmask) * cellsize;
-
} if (attr) { update_attr(buf, src, attr, vc); src = buf; }
-
s++; if (likely(idx == 1)) __fb_pad_aligned_buffer(dst, d_pitch, src, idx,
@@ -117,14 +148,24 @@ static inline void bit_putcs_unaligned(struct vc_data *vc,
u32 idx = vc->vc_font.width >> 3;
u8 *src;
-
int utf8_c = 0;
while (cnt–) {
-
src = vc->vc_font.data + (scr_readw(s++)&
-
charmask)*cellsize;
-
utf8_c = utf8_pos(vc, s);
-
if(((scr_readw(s) & charmask) == 0xff || (scr_readw(s) & charmask) == 0xfe ) && utf8_c != 0){
-
if((scr_readw(s) & charmask) == 0xff){
-
src = font_utf8 + (utf8_c * 32);
-
}else{
-
src = font_utf8 + (utf8_c * 32 + 16);
-
}
-
}else{
-
src = vc->vc_font.data + (scr_readw(s) &
-
charmask) * cellsize;
-
} if (attr) { update_attr(buf, src, attr, vc); src = buf; }
-
s++; fb_pad_unaligned_buffer(dst, d_pitch, src, idx, image->height, shift_high,
@@ -240,6 +281,7 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info, int mode,
struct fbcon_ops *ops = info->fbcon_par;
unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
int w = DIV_ROUND_UP(vc->vc_font.width, 8), c;
-
int c_extra;
int y = real_y(ops->p, vc->vc_y);
int attribute, use_sw = (vc->vc_cursor_type & 0x10);
int err = 1;
@@ -257,8 +299,17 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info, int mode,
}
c = scr_readw((u16 *) vc->vc_pos);
-
c_extra = utf8_pos(vc, (u16 *) vc->vc_pos);
attribute = get_attribute(info, c);
- src = vc->vc_font.data + ((c & charmask) * (w * vc->vc_font.height));
-
if(((c&charmask) == 0xff || (c & charmask) == 0xfe) && c_extra != 0){
-
if((c & charmask) == 0xff){
-
src = (char *) (font_utf8 + (c_extra * 32));
-
}else{
-
src = (char *) (font_utf8 + (c_extra * 32 + 16));
-
}
-
}else{
-
src = vc->vc_font.data + ((c & charmask) * (w * vc->vc_font.height));
-
}
if (ops->cursor_state.image.data != src ||
ops->cursor_reset) {
diff –git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 3681c6a..07f8636 100644
— a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -196,6 +196,14 @@ static void fbcon_start(void);
static void fbcon_exit(void);
static struct device *fbcon_device;
+int fbcon_is_softback(const unsigned short *str)
+{
-
unsigned long p = (long)str;
-
if(p >= softback_buf && p <softback_end)
-
return 1;
-
return 0;
+}
#ifdef CONFIG_FRAMEBUFFER_CONSOLE_ROTATION
static inline void fbcon_set_rotation(struct fb_info *info)
{
@@ -964,7 +972,7 @@ static const char *fbcon_startup(void)
if (!softback_buf) {
softback_buf =
(unsigned long)
-
kmalloc(fbcon_softback_size,
-
kmalloc(fbcon_softback_size * 2, GFP_KERNEL); if (!softback_buf) { fbcon_softback_size = 0;
@@ -1266,10 +1274,7 @@ static void fbcon_putcs(struct vc_data *vc, const unsigned short *s,
static void fbcon_putc(struct vc_data *vc, int c, int ypos, int xpos)
{
-
unsigned short chr;
-
scr_writew(c, &chr);
-
fbcon_putcs(vc, &chr, 1, ypos, xpos);
- fbcon_putcs(vc, (unsigned short *)&c, 1, ypos, xpos);
}
static void fbcon_clear_margins(struct vc_data *vc, int bottom_only)
@@ -1520,6 +1525,7 @@ static inline void ypan_down_redraw(struct vc_data *vc, int t, int count)
static void fbcon_redraw_softback(struct vc_data *vc, struct display *p,
long delta)
{
-
u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
int count = vc->vc_rows;
unsigned short *d, *s;
unsigned long n;
@@ -1582,7 +1588,9 @@ static void fbcon_redraw_softback(struct vc_data *vc, struct display *p,
start = s;
}
}
-
if (c == scr_readw(d)) {
-
if( ((scr_readw(s) & charmask) == 0xff || (scr_readw(s) & charmask) == 0xfe) && scr_readw(s + (vc->vc_screenbuf_size >> 1)) != 0){
-
}else{
-
if (c == scr_readw(d)) { if (s > start) { fbcon_putcs(vc, start, s - start, line, x);
@@ -1593,6 +1601,7 @@ static void fbcon_redraw_softback(struct vc_data *vc, struct display *p,
start++;
}
}
-
} s++; d++; } while (s < le);
@@ -1675,6 +1684,7 @@ static void fbcon_redraw_blit(struct vc_data *vc, struct fb_info *info,
}
scr_writew(c, d);
-
scr_writew(scr_readw(s + (vc->vc_screenbuf_size >> 1)), d + (vc->vc_screenbuf_size >> 1)); console_conditional_schedule(); s++; d++;
@@ -1697,6 +1707,7 @@ static void fbcon_redraw_blit(struct vc_data *vc, struct fb_info *info,
static void fbcon_redraw(struct vc_data *vc, struct display *p,
int line, int count, int offset)
{
-
u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
unsigned short *d = (unsigned short *)
(vc->vc_origin + vc->vc_size_row * line);
unsigned short *s = d + offset;
@@ -1719,18 +1730,22 @@ static void fbcon_redraw(struct vc_data *vc, struct display *p,
start = s;
}
}
-
if (c == scr_readw(d)) {
-
if (s > start) {
-
fbcon_putcs(vc, start, s - start,
-
line, x);
-
x += s - start + 1;
-
start = s + 1;
-
} else {
-
x++;
-
start++;
-
if( ((scr_readw(s) & charmask) == 0xff || (scr_readw(s) & charmask) == 0xfe) && scr_readw(s + (vc->vc_screenbuf_size >> 1)) != 0){
-
}else{
-
if (c == scr_readw(d)) {
-
if (s > start) {
-
fbcon_putcs(vc, start, s - start,
-
line, x);
-
x += s - start + 1;
-
start = s + 1;
-
} else {
-
x++;
-
start++;
-
} } } scr_writew(c, d);
-
scr_writew(scr_readw(s + (vc->vc_screenbuf_size >> 1)), d + (vc->vc_screenbuf_size >> 1)); console_conditional_schedule(); s++; d++;
@@ -1760,6 +1775,7 @@ static inline void fbcon_softback_note(struct vc_data *vc, int t,
while (count) {
scr_memcpyw((u16 *) softback_in, p, vc->vc_size_row);
-
scr_memcpyw((u16 *) softback_in + (fbcon_softback_size >> 1), p + (vc->vc_screenbuf_size >> 1), vc->vc_size_row); count--; p = advance_row(p, 1); softback_in += vc->vc_size_row;
@@ -2645,7 +2661,20 @@ static u16 *fbcon_screen_pos(struct vc_data *vc, int offset)
{
unsigned long p;
int line;
-
if (offset < 0) {
-
offset = -offset - 1;
-
if (vc->vc_num != fg_console || !softback_lines)
-
return (u16 *)(vc->vc_origin + offset + (vc->vc_screenbuf_size));
-
line = offset / vc->vc_size_row;
-
if (line >= softback_lines)
-
return (u16 *) (vc->vc_origin + offset - softback_lines * vc->vc_size_row + (vc->vc_screenbuf_size));
-
p = softback_curr + offset;
-
if (p >= softback_end)
-
p += softback_buf - softback_end;
-
return (u16 *) (p + (fbcon_softback_size));
-
}
if (vc->vc_num != fg_console || !softback_lines)
return (u16 *) (vc->vc_origin + offset);
line = offset / vc->vc_size_row;
@@ -2753,6 +2782,9 @@ static int fbcon_scrolldelta(struct vc_data *vc, int lines)
q -= vc->vc_size_row;
scr_memcpyw((u16 *) q, (u16 *) p,
vc->vc_size_row);
-
scr_memcpyw((u16 *) (q + (vc->vc_screenbuf_size >> 1)), (u16 *) (p + (fbcon_softback_size >> 1)),
-
vc->vc_size_row);
}
softback_in = softback_curr = p;
update_region(vc, vc->vc_origin,
diff –git a/drivers/video/console/fbcon_ccw.c b/drivers/video/console/fbcon_ccw.c
index bdf913e..d342c1d 100644
— a/drivers/video/console/fbcon_ccw.c
+++ b/drivers/video/console/fbcon_ccw.c
@@ -16,6 +16,9 @@
#include <asm/types.h>
#include “fbcon.h”
#include “fbcon_rotate.h”
+#include “fonts_utf8.h”
+extern u16 utf8_pos(struct vc_data *vc, const unsigned short *utf8);
/*
- Rotation 270 degrees
@@ -104,13 +107,28 @@ static inline void ccw_putcs_aligned(struct vc_data *vc, struct fb_info *info,
u32 idx = (vc->vc_font.height + 7) >> 3;
u8 *src;
-
int utf8_c = 0;
while (cnt–) {
-
src = ops->fontbuffer + (scr_readw(s--) & charmask)*cellsize;
-
utf8_c = utf8_pos(vc, s);
-
if(((scr_readw(s) & charmask) == 0xff || (scr_readw(s) & charmask) == 0xfe ) && utf8_c != 0){
-
char dst[16];
-
if((scr_readw(s) & charmask) == 0xff){
-
src = font_utf8 + (utf8_c * 32);
-
}else{
-
src = font_utf8 + (utf8_c * 32 + 16);
-
}
-
memset(dst, 0, 16);
-
rotate_ccw(src, dst, vc->vc_font.width,
-
vc->vc_font.height);
-
src = dst;
-
}else{
-
src = ops->fontbuffer + (scr_readw(s) & charmask)*cellsize;
-
} if (attr) { ccw_update_attr(buf, src, attr, vc); src = buf; }
-
s--; if (likely(idx == 1)) __fb_pad_aligned_buffer(dst, d_pitch, src, idx,
@@ -224,6 +242,7 @@ static void ccw_cursor(struct vc_data *vc, struct fb_info *info, int mode,
struct fb_cursor cursor;
struct fbcon_ops *ops = info->fbcon_par;
unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
-
int c_extra;
int w = (vc->vc_font.height + 7) » 3, c;
int y = real_y(ops->p, vc->vc_y);
int attribute, use_sw = (vc->vc_cursor_type & 0x10);
@@ -246,8 +265,22 @@ static void ccw_cursor(struct vc_data *vc, struct fb_info *info, int mode,
}
c = scr_readw((u16 *) vc->vc_pos);
-
c_extra = utf8_pos(vc, (u16 *) vc->vc_pos);
attribute = get_attribute(info, c);
- src = ops->fontbuffer + ((c & charmask) * (w * vc->vc_font.width));
-
if(((c&charmask) == 0xff || (c & charmask) == 0xfe) && c_extra != 0){
-
char dst[16];
-
if((c & charmask) == 0xff){
-
src = font_utf8 + (c_extra * 32);
-
}else{
-
src = font_utf8 + (c_extra * 32 + 16);
-
}
-
memset(dst, 0, 16);
-
rotate_ccw(src, dst, vc->vc_font.width,
-
vc->vc_font.height);
-
src = dst;
-
}else{
-
src = ops->fontbuffer + ((c & charmask) * (w * vc->vc_font.width));
-
}
if (ops->cursor_state.image.data != src ||
ops->cursor_reset) {
diff –git a/drivers/video/console/fbcon_cw.c b/drivers/video/console/fbcon_cw.c
index a6819b9..904f4e0 100644
— a/drivers/video/console/fbcon_cw.c
+++ b/drivers/video/console/fbcon_cw.c
@@ -16,6 +16,9 @@
#include <asm/types.h>
#include “fbcon.h”
#include “fbcon_rotate.h”
+#include “fonts_utf8.h”
+extern u16 utf8_pos(struct vc_data *vc, const unsigned short *utf8);
/*
- Rotation 90 degrees
@@ -90,13 +93,28 @@ static inline void cw_putcs_aligned(struct vc_data *vc, struct fb_info *info,
u32 idx = (vc->vc_font.height + 7) >> 3;
u8 *src;
-
int utf8_c = 0;
while (cnt–) {
-
src = ops->fontbuffer + (scr_readw(s++) & charmask)*cellsize;
-
utf8_c = utf8_pos(vc, s);
-
if(((scr_readw(s) & charmask) == 0xff || (scr_readw(s) & charmask) == 0xfe ) && utf8_c != 0){
-
char dst[16];
-
if((scr_readw(s) & charmask) == 0xff){
-
src = font_utf8 + (utf8_c * 32);
-
}else{
-
src = font_utf8 + (utf8_c * 32 + 16);
-
}
-
memset(dst, 0, 16);
-
rotate_cw(src, dst, vc->vc_font.width,
-
vc->vc_font.height);
-
src = dst;
-
}else{
-
src = ops->fontbuffer + (scr_readw(s) & charmask)*cellsize;
-
} if (attr) { cw_update_attr(buf, src, attr, vc); src = buf; }
-
s++; if (likely(idx == 1)) __fb_pad_aligned_buffer(dst, d_pitch, src, idx,
@@ -208,6 +226,7 @@ static void cw_cursor(struct vc_data *vc, struct fb_info *info, int mode,
struct fb_cursor cursor;
struct fbcon_ops *ops = info->fbcon_par;
unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
-
int c_extra;
int w = (vc->vc_font.height + 7) » 3, c;
int y = real_y(ops->p, vc->vc_y);
int attribute, use_sw = (vc->vc_cursor_type & 0x10);
@@ -230,8 +249,22 @@ static void cw_cursor(struct vc_data *vc, struct fb_info *info, int mode,
}
c = scr_readw((u16 *) vc->vc_pos);
-
c_extra = utf8_pos(vc, (u16 *) vc->vc_pos);
attribute = get_attribute(info, c);
- src = ops->fontbuffer + ((c & charmask) * (w * vc->vc_font.width));
-
if(((c&charmask) == 0xff || (c & charmask) == 0xfe) && c_extra != 0){
-
char dst[16];
-
if((c & charmask) == 0xff){
-
src = font_utf8 + (c_extra * 32);
-
}else{
-
src = font_utf8 + (c_extra * 32 + 16);
-
}
-
memset(dst, 0, 16);
-
rotate_cw(src, dst, vc->vc_font.width,
-
vc->vc_font.height);
-
src = dst;
-
}else{
-
src = ops->fontbuffer + ((c & charmask) * (w * vc->vc_font.width));
-
}
if (ops->cursor_state.image.data != src ||
ops->cursor_reset) {
diff –git a/drivers/video/console/fbcon_ud.c b/drivers/video/console/fbcon_ud.c
index d9b5d6e..e529594 100644
— a/drivers/video/console/fbcon_ud.c
+++ b/drivers/video/console/fbcon_ud.c
@@ -17,6 +17,10 @@
#include “fbcon.h”
#include “fbcon_rotate.h”
+#include “fonts_utf8.h”
+extern u16 utf8_pos(struct vc_data *vc, const unsigned short *utf8);
/*
- Rotation 180 degrees
*/
@@ -91,13 +95,29 @@ static inline void ud_putcs_aligned(struct vc_data *vc, struct fb_info *info,
u32 idx = vc->vc_font.width >> 3;
u8 *src;
-
int utf8_c = 0;
while (cnt–) {
-
src = ops->fontbuffer + (scr_readw(s--) & charmask)*cellsize;
-
utf8_c = utf8_pos(vc, s);
-
if(((scr_readw(s) & charmask) == 0xff || (scr_readw(s) & charmask) == 0xfe ) && utf8_c != 0){
-
char dst[16];
-
if((scr_readw(s) & charmask) == 0xff){
-
src = font_utf8 + (utf8_c * 32);
-
}else{
-
src = font_utf8 + (utf8_c * 32 + 16);
-
}
-
memset(dst, 0, 16);
-
rotate_ud(src, dst, vc->vc_font.width,
-
vc->vc_font.height);
-
src = dst;
-
}else{
-
src = ops->fontbuffer + (scr_readw(s) & charmask)*cellsize;
-
} if (attr) { ud_update_attr(buf, src, attr, vc); src = buf; }
-
s--; if (likely(idx == 1)) __fb_pad_aligned_buffer(dst, d_pitch, src, idx,
@@ -126,13 +146,29 @@ static inline void ud_putcs_unaligned(struct vc_data *vc,
u32 idx = vc->vc_font.width >> 3;
u8 *src;
-
int utf8_c = 0;
while (cnt–) {
-
src = ops->fontbuffer + (scr_readw(s--) & charmask)*cellsize;
-
utf8_c = utf8_pos(vc, s);
-
if(((scr_readw(s) & charmask) == 0xff || (scr_readw(s) & charmask) == 0xfe ) && utf8_c != 0){
-
char dst[16];
-
if((scr_readw(s) & charmask) == 0xff){
-
src = font_utf8 + (utf8_c * 32);
-
}else{
-
src = font_utf8 + (utf8_c * 32 + 16);
-
}
-
memset(dst, 0, 16);
-
rotate_ud(src, dst, vc->vc_font.width,
-
vc->vc_font.height);
-
src = dst;
-
}else{
-
src = ops->fontbuffer + (scr_readw(s) & charmask)*cellsize;
-
} if (attr) { ud_update_attr(buf, src, attr, vc); src = buf; }
-
s--; fb_pad_unaligned_buffer(dst, d_pitch, src, idx, image->height, shift_high,
@@ -254,6 +290,7 @@ static void ud_cursor(struct vc_data *vc, struct fb_info *info, int mode,
struct fb_cursor cursor;
struct fbcon_ops *ops = info->fbcon_par;
unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
-
int c_extra;
int w = (vc->vc_font.width + 7) » 3, c;
int y = real_y(ops->p, vc->vc_y);
int attribute, use_sw = (vc->vc_cursor_type & 0x10);
@@ -277,8 +314,22 @@ static void ud_cursor(struct vc_data *vc, struct fb_info *info, int mode,
}
c = scr_readw((u16 *) vc->vc_pos);
-
c_extra = utf8_pos(vc, (u16 *) vc->vc_pos);
attribute = get_attribute(info, c);
- src = ops->fontbuffer + ((c & charmask) * (w * vc->vc_font.height));
-
if(((c&charmask) == 0xff || (c & charmask) == 0xfe) && c_extra != 0){
-
char dst[16];
-
if((c & charmask) == 0xff){
-
src = font_utf8 + (c_extra * 32);
-
}else{
-
src = font_utf8 + (c_extra * 32 + 16);
-
}
-
memset(dst, 0, 16);
-
rotate_ud(src, dst, vc->vc_font.width,
-
vc->vc_font.height);
-
src = dst;
-
}else{
-
src = ops->fontbuffer + ((c & charmask) * (w * vc->vc_font.height));
-
}
if (ops->cursor_state.image.data != src ||
ops->cursor_reset) {
<li>内核.config文件