diff options
Diffstat (limited to 'drivers/char/vt.c')
| -rw-r--r-- | drivers/char/vt.c | 37 |
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; |
