|
@@ -751,6 +751,7 @@ int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int lines)
|
|
unsigned long old_origin, new_origin, new_scr_end, rlth, rrem, err = 0;
|
|
unsigned long old_origin, new_origin, new_scr_end, rlth, rrem, err = 0;
|
|
unsigned int old_cols, old_rows, old_row_size, old_screen_size;
|
|
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 new_cols, new_rows, new_row_size, new_screen_size;
|
|
|
|
+ unsigned int end;
|
|
unsigned short *newscreen;
|
|
unsigned short *newscreen;
|
|
|
|
|
|
WARN_CONSOLE_UNLOCKED();
|
|
WARN_CONSOLE_UNLOCKED();
|
|
@@ -794,20 +795,44 @@ int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int lines)
|
|
old_origin = vc->vc_origin;
|
|
old_origin = vc->vc_origin;
|
|
new_origin = (long) newscreen;
|
|
new_origin = (long) newscreen;
|
|
new_scr_end = new_origin + new_screen_size;
|
|
new_scr_end = new_origin + new_screen_size;
|
|
- if (new_rows < old_rows)
|
|
|
|
- old_origin += (old_rows - new_rows) * old_row_size;
|
|
|
|
|
|
+
|
|
|
|
+ if (vc->vc_y > new_rows) {
|
|
|
|
+ if (old_rows - vc->vc_y < new_rows) {
|
|
|
|
+ /*
|
|
|
|
+ * Cursor near the bottom, copy contents from the
|
|
|
|
+ * bottom of buffer
|
|
|
|
+ */
|
|
|
|
+ old_origin += (old_rows - new_rows) * old_row_size;
|
|
|
|
+ end = vc->vc_scr_end;
|
|
|
|
+ } else {
|
|
|
|
+ /*
|
|
|
|
+ * 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;
|
|
|
|
+ end = old_origin + new_screen_size;
|
|
|
|
+ }
|
|
|
|
+ } else
|
|
|
|
+ /*
|
|
|
|
+ * Cursor near the top, copy contents from the top of buffer
|
|
|
|
+ */
|
|
|
|
+ end = (old_rows > new_rows) ? old_origin + new_screen_size :
|
|
|
|
+ vc->vc_scr_end;
|
|
|
|
|
|
update_attr(vc);
|
|
update_attr(vc);
|
|
|
|
|
|
- while (old_origin < vc->vc_scr_end) {
|
|
|
|
- scr_memcpyw((unsigned short *) new_origin, (unsigned short *) old_origin, rlth);
|
|
|
|
|
|
+ while (old_origin < end) {
|
|
|
|
+ scr_memcpyw((unsigned short *) new_origin,
|
|
|
|
+ (unsigned short *) old_origin, rlth);
|
|
if (rrem)
|
|
if (rrem)
|
|
- scr_memsetw((void *)(new_origin + rlth), vc->vc_video_erase_char, rrem);
|
|
|
|
|
|
+ scr_memsetw((void *)(new_origin + rlth),
|
|
|
|
+ vc->vc_video_erase_char, rrem);
|
|
old_origin += old_row_size;
|
|
old_origin += old_row_size;
|
|
new_origin += new_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, vc->vc_video_erase_char,
|
|
|
|
+ new_scr_end - new_origin);
|
|
if (vc->vc_kmalloced)
|
|
if (vc->vc_kmalloced)
|
|
kfree(vc->vc_screenbuf);
|
|
kfree(vc->vc_screenbuf);
|
|
vc->vc_screenbuf = newscreen;
|
|
vc->vc_screenbuf = newscreen;
|