aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/char/vt.c37
1 files changed, 31 insertions, 6 deletions
diff --git a/drivers/char/vt.c b/drivers/char/vt.c
index b8d0c290b0db..1e33cb032e07 100644
--- a/drivers/char/vt.c
+++ b/drivers/char/vt.c
@@ -751,6 +751,7 @@ int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int lines)
751 unsigned long old_origin, new_origin, new_scr_end, rlth, rrem, err = 0; 751 unsigned long old_origin, new_origin, new_scr_end, rlth, rrem, err = 0;
752 unsigned int old_cols, old_rows, old_row_size, old_screen_size; 752 unsigned int old_cols, old_rows, old_row_size, old_screen_size;
753 unsigned int new_cols, new_rows, new_row_size, new_screen_size; 753 unsigned int new_cols, new_rows, new_row_size, new_screen_size;
754 unsigned int end;
754 unsigned short *newscreen; 755 unsigned short *newscreen;
755 756
756 WARN_CONSOLE_UNLOCKED(); 757 WARN_CONSOLE_UNLOCKED();
@@ -794,20 +795,44 @@ int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int lines)
794 old_origin = vc->vc_origin; 795 old_origin = vc->vc_origin;
795 new_origin = (long) newscreen; 796 new_origin = (long) newscreen;
796 new_scr_end = new_origin + new_screen_size; 797 new_scr_end = new_origin + new_screen_size;
797 if (new_rows < old_rows) 798
798 old_origin += (old_rows - new_rows) * old_row_size; 799 if (vc->vc_y > new_rows) {
800 if (old_rows - vc->vc_y < new_rows) {
801 /*
802 * Cursor near the bottom, copy contents from the
803 * bottom of buffer
804 */
805 old_origin += (old_rows - new_rows) * old_row_size;
806 end = vc->vc_scr_end;
807 } else {
808 /*
809 * Cursor is in no man's land, copy 1/2 screenful
810 * from the top and bottom of cursor position
811 */
812 old_origin += (vc->vc_y - new_rows/2) * old_row_size;
813 end = old_origin + new_screen_size;
814 }
815 } else
816 /*
817 * Cursor near the top, copy contents from the top of buffer
818 */
819 end = (old_rows > new_rows) ? old_origin + new_screen_size :
820 vc->vc_scr_end;
799 821
800 update_attr(vc); 822 update_attr(vc);
801 823
802 while (old_origin < vc->vc_scr_end) { 824 while (old_origin < end) {
803 scr_memcpyw((unsigned short *) new_origin, (unsigned short *) old_origin, rlth); 825 scr_memcpyw((unsigned short *) new_origin,
826 (unsigned short *) old_origin, rlth);
804 if (rrem) 827 if (rrem)
805 scr_memsetw((void *)(new_origin + rlth), vc->vc_video_erase_char, rrem); 828 scr_memsetw((void *)(new_origin + rlth),
829 vc->vc_video_erase_char, rrem);
806 old_origin += old_row_size; 830 old_origin += old_row_size;
807 new_origin += new_row_size; 831 new_origin += new_row_size;
808 } 832 }
809 if (new_scr_end > new_origin) 833 if (new_scr_end > new_origin)
810 scr_memsetw((void *)new_origin, vc->vc_video_erase_char, new_scr_end - new_origin); 834 scr_memsetw((void *)new_origin, vc->vc_video_erase_char,
835 new_scr_end - new_origin);
811 if (vc->vc_kmalloced) 836 if (vc->vc_kmalloced)
812 kfree(vc->vc_screenbuf); 837 kfree(vc->vc_screenbuf);
813 vc->vc_screenbuf = newscreen; 838 vc->vc_screenbuf = newscreen;