Commit 20067d73 authored by Antonino Daplas's avatar Antonino Daplas Committed by Linus Torvalds

[PATCH] fbcon: Cursor fixes

From Jiri Benc:

we found several bugs in framebuffer console code in recent kernels.

1. The escape sequence '\033[?25l' does not work (should disable cursor).

2. When scrolling console using Shift-PgUp with cursor in the upper half
   part of the screen, cursor position is not updated.

3. If cursor is placed at some character and console is scrolled using
   Shift-PgUp, that character remains on the screen.
Signed-off-by: default avatarAntonino Daplas <adaplas@pol.net>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent bbfda4e4
...@@ -236,7 +236,7 @@ static void bit_clear_margins(struct vc_data *vc, struct fb_info *info, ...@@ -236,7 +236,7 @@ static void bit_clear_margins(struct vc_data *vc, struct fb_info *info,
} }
static void bit_cursor(struct vc_data *vc, struct fb_info *info, static void bit_cursor(struct vc_data *vc, struct fb_info *info,
struct display *p, int mode, int fg, int bg) struct display *p, int mode, int softback_lines, int fg, int bg)
{ {
struct fb_cursor cursor; struct fb_cursor cursor;
struct fbcon_ops *ops = (struct fbcon_ops *) info->fbcon_par; struct fbcon_ops *ops = (struct fbcon_ops *) info->fbcon_par;
...@@ -248,6 +248,15 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info, ...@@ -248,6 +248,15 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info,
cursor.set = 0; cursor.set = 0;
if (softback_lines) {
if (y + softback_lines >= vc->vc_rows) {
mode = CM_ERASE;
ops->cursor_flash = 0;
return;
} else
y += softback_lines;
}
c = scr_readw((u16 *) vc->vc_pos); c = scr_readw((u16 *) vc->vc_pos);
attribute = get_attribute(info, c); attribute = get_attribute(info, c);
src = vc->vc_font.data + ((c & charmask) * (w * vc->vc_font.height)); src = vc->vc_font.data + ((c & charmask) * (w * vc->vc_font.height));
......
...@@ -279,7 +279,7 @@ static void fb_flashcursor(void *private) ...@@ -279,7 +279,7 @@ static void fb_flashcursor(void *private)
c = scr_readw((u16 *) vc->vc_pos); c = scr_readw((u16 *) vc->vc_pos);
mode = (!ops->cursor_flash || ops->cursor_state.enable) ? mode = (!ops->cursor_flash || ops->cursor_state.enable) ?
CM_ERASE : CM_DRAW; CM_ERASE : CM_DRAW;
ops->cursor(vc, info, p, mode, get_color(vc, info, c, 1), ops->cursor(vc, info, p, mode, softback_lines, get_color(vc, info, c, 1),
get_color(vc, info, c, 0)); get_color(vc, info, c, 0));
release_console_sem(); release_console_sem();
} }
...@@ -1086,27 +1086,23 @@ static void fbcon_cursor(struct vc_data *vc, int mode) ...@@ -1086,27 +1086,23 @@ static void fbcon_cursor(struct vc_data *vc, int mode)
struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
struct fbcon_ops *ops = info->fbcon_par; struct fbcon_ops *ops = info->fbcon_par;
struct display *p = &fb_display[vc->vc_num]; struct display *p = &fb_display[vc->vc_num];
int y = real_y(p, vc->vc_y); int y;
int c = scr_readw((u16 *) vc->vc_pos); int c = scr_readw((u16 *) vc->vc_pos);
if (fbcon_is_inactive(vc, info)) if (fbcon_is_inactive(vc, info))
return; return;
ops->cursor_flash = 1; ops->cursor_flash = (mode == CM_ERASE) ? 0 : 1;
if (mode & CM_SOFTBACK) { if (mode & CM_SOFTBACK) {
mode &= ~CM_SOFTBACK; mode &= ~CM_SOFTBACK;
if (softback_lines) { y = softback_lines;
if (y + softback_lines >= vc->vc_rows) { } else {
mode = CM_ERASE; if (softback_lines)
ops->cursor_flash = 0;
}
else
y += softback_lines;
}
} else if (softback_lines)
fbcon_set_origin(vc); fbcon_set_origin(vc);
y = 0;
}
ops->cursor(vc, info, p, mode, get_color(vc, info, c, 1), ops->cursor(vc, info, p, mode, y, get_color(vc, info, c, 1),
get_color(vc, info, c, 0)); get_color(vc, info, c, 0));
vbl_cursor_cnt = CURSOR_DRAW_DELAY; vbl_cursor_cnt = CURSOR_DRAW_DELAY;
} }
......
...@@ -59,7 +59,7 @@ struct fbcon_ops { ...@@ -59,7 +59,7 @@ struct fbcon_ops {
void (*clear_margins)(struct vc_data *vc, struct fb_info *info, void (*clear_margins)(struct vc_data *vc, struct fb_info *info,
int bottom_only); int bottom_only);
void (*cursor)(struct vc_data *vc, struct fb_info *info, void (*cursor)(struct vc_data *vc, struct fb_info *info,
struct display *p, int mode, int fg, int bg); struct display *p, int mode, int softback_lines, int fg, int bg);
struct timer_list cursor_timer; /* Cursor timer */ struct timer_list cursor_timer; /* Cursor timer */
struct fb_cursor cursor_state; struct fb_cursor cursor_state;
......
...@@ -81,7 +81,8 @@ static void tile_clear_margins(struct vc_data *vc, struct fb_info *info, ...@@ -81,7 +81,8 @@ static void tile_clear_margins(struct vc_data *vc, struct fb_info *info,
} }
static void tile_cursor(struct vc_data *vc, struct fb_info *info, static void tile_cursor(struct vc_data *vc, struct fb_info *info,
struct display *p, int mode, int fg, int bg) struct display *p, int mode, int softback_lines,
int fg, int bg)
{ {
struct fb_tilecursor cursor; struct fb_tilecursor cursor;
int use_sw = (vc->vc_cursor_type & 0x01); int use_sw = (vc->vc_cursor_type & 0x01);
......
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