diff options
Diffstat (limited to 'drivers/tty/vt/vt.c')
-rw-r--r-- | drivers/tty/vt/vt.c | 141 |
1 files changed, 54 insertions, 87 deletions
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index 84cbf298c094..999ca63afdef 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c | |||
@@ -537,45 +537,27 @@ void complement_pos(struct vc_data *vc, int offset) | |||
537 | 537 | ||
538 | static void insert_char(struct vc_data *vc, unsigned int nr) | 538 | static void insert_char(struct vc_data *vc, unsigned int nr) |
539 | { | 539 | { |
540 | unsigned short *p, *q = (unsigned short *)vc->vc_pos; | 540 | unsigned short *p = (unsigned short *) vc->vc_pos; |
541 | 541 | ||
542 | p = q + vc->vc_cols - nr - vc->vc_x; | 542 | scr_memmovew(p + nr, p, vc->vc_cols - vc->vc_x); |
543 | while (--p >= q) | 543 | scr_memsetw(p, vc->vc_video_erase_char, nr * 2); |
544 | scr_writew(scr_readw(p), p + nr); | ||
545 | scr_memsetw(q, vc->vc_video_erase_char, nr * 2); | ||
546 | vc->vc_need_wrap = 0; | 544 | vc->vc_need_wrap = 0; |
547 | if (DO_UPDATE(vc)) { | 545 | if (DO_UPDATE(vc)) |
548 | unsigned short oldattr = vc->vc_attr; | 546 | do_update_region(vc, (unsigned long) p, |
549 | vc->vc_sw->con_bmove(vc, vc->vc_y, vc->vc_x, vc->vc_y, vc->vc_x + nr, 1, | 547 | (vc->vc_cols - vc->vc_x) / 2 + 1); |
550 | vc->vc_cols - vc->vc_x - nr); | ||
551 | vc->vc_attr = vc->vc_video_erase_char >> 8; | ||
552 | while (nr--) | ||
553 | vc->vc_sw->con_putc(vc, vc->vc_video_erase_char, vc->vc_y, vc->vc_x + nr); | ||
554 | vc->vc_attr = oldattr; | ||
555 | } | ||
556 | } | 548 | } |
557 | 549 | ||
558 | static void delete_char(struct vc_data *vc, unsigned int nr) | 550 | static void delete_char(struct vc_data *vc, unsigned int nr) |
559 | { | 551 | { |
560 | unsigned int i = vc->vc_x; | 552 | unsigned short *p = (unsigned short *) vc->vc_pos; |
561 | unsigned short *p = (unsigned short *)vc->vc_pos; | ||
562 | 553 | ||
563 | while (++i <= vc->vc_cols - nr) { | 554 | scr_memcpyw(p, p + nr, vc->vc_cols - vc->vc_x - nr); |
564 | scr_writew(scr_readw(p+nr), p); | 555 | scr_memsetw(p + vc->vc_cols - vc->vc_x - nr, vc->vc_video_erase_char, |
565 | p++; | 556 | nr * 2); |
566 | } | ||
567 | scr_memsetw(p, vc->vc_video_erase_char, nr * 2); | ||
568 | vc->vc_need_wrap = 0; | 557 | vc->vc_need_wrap = 0; |
569 | if (DO_UPDATE(vc)) { | 558 | if (DO_UPDATE(vc)) |
570 | unsigned short oldattr = vc->vc_attr; | 559 | do_update_region(vc, (unsigned long) p, |
571 | vc->vc_sw->con_bmove(vc, vc->vc_y, vc->vc_x + nr, vc->vc_y, vc->vc_x, 1, | 560 | (vc->vc_cols - vc->vc_x) / 2); |
572 | vc->vc_cols - vc->vc_x - nr); | ||
573 | vc->vc_attr = vc->vc_video_erase_char >> 8; | ||
574 | while (nr--) | ||
575 | vc->vc_sw->con_putc(vc, vc->vc_video_erase_char, vc->vc_y, | ||
576 | vc->vc_cols - 1 - nr); | ||
577 | vc->vc_attr = oldattr; | ||
578 | } | ||
579 | } | 561 | } |
580 | 562 | ||
581 | static int softcursor_original; | 563 | static int softcursor_original; |
@@ -1172,45 +1154,26 @@ static void csi_J(struct vc_data *vc, int vpar) | |||
1172 | case 0: /* erase from cursor to end of display */ | 1154 | case 0: /* erase from cursor to end of display */ |
1173 | count = (vc->vc_scr_end - vc->vc_pos) >> 1; | 1155 | count = (vc->vc_scr_end - vc->vc_pos) >> 1; |
1174 | start = (unsigned short *)vc->vc_pos; | 1156 | start = (unsigned short *)vc->vc_pos; |
1175 | if (DO_UPDATE(vc)) { | ||
1176 | /* do in two stages */ | ||
1177 | vc->vc_sw->con_clear(vc, vc->vc_y, vc->vc_x, 1, | ||
1178 | vc->vc_cols - vc->vc_x); | ||
1179 | vc->vc_sw->con_clear(vc, vc->vc_y + 1, 0, | ||
1180 | vc->vc_rows - vc->vc_y - 1, | ||
1181 | vc->vc_cols); | ||
1182 | } | ||
1183 | break; | 1157 | break; |
1184 | case 1: /* erase from start to cursor */ | 1158 | case 1: /* erase from start to cursor */ |
1185 | count = ((vc->vc_pos - vc->vc_origin) >> 1) + 1; | 1159 | count = ((vc->vc_pos - vc->vc_origin) >> 1) + 1; |
1186 | start = (unsigned short *)vc->vc_origin; | 1160 | start = (unsigned short *)vc->vc_origin; |
1187 | if (DO_UPDATE(vc)) { | ||
1188 | /* do in two stages */ | ||
1189 | vc->vc_sw->con_clear(vc, 0, 0, vc->vc_y, | ||
1190 | vc->vc_cols); | ||
1191 | vc->vc_sw->con_clear(vc, vc->vc_y, 0, 1, | ||
1192 | vc->vc_x + 1); | ||
1193 | } | ||
1194 | break; | 1161 | break; |
1195 | case 3: /* erase scroll-back buffer (and whole display) */ | 1162 | case 3: /* erase scroll-back buffer (and whole display) */ |
1196 | scr_memsetw(vc->vc_screenbuf, vc->vc_video_erase_char, | 1163 | scr_memsetw(vc->vc_screenbuf, vc->vc_video_erase_char, |
1197 | vc->vc_screenbuf_size >> 1); | 1164 | vc->vc_screenbuf_size >> 1); |
1198 | set_origin(vc); | 1165 | set_origin(vc); |
1199 | if (CON_IS_VISIBLE(vc)) | ||
1200 | update_screen(vc); | ||
1201 | /* fall through */ | 1166 | /* fall through */ |
1202 | case 2: /* erase whole display */ | 1167 | case 2: /* erase whole display */ |
1203 | count = vc->vc_cols * vc->vc_rows; | 1168 | count = vc->vc_cols * vc->vc_rows; |
1204 | start = (unsigned short *)vc->vc_origin; | 1169 | start = (unsigned short *)vc->vc_origin; |
1205 | if (DO_UPDATE(vc)) | ||
1206 | vc->vc_sw->con_clear(vc, 0, 0, | ||
1207 | vc->vc_rows, | ||
1208 | vc->vc_cols); | ||
1209 | break; | 1170 | break; |
1210 | default: | 1171 | default: |
1211 | return; | 1172 | return; |
1212 | } | 1173 | } |
1213 | scr_memsetw(start, vc->vc_video_erase_char, 2 * count); | 1174 | scr_memsetw(start, vc->vc_video_erase_char, 2 * count); |
1175 | if (DO_UPDATE(vc)) | ||
1176 | do_update_region(vc, (unsigned long) start, count); | ||
1214 | vc->vc_need_wrap = 0; | 1177 | vc->vc_need_wrap = 0; |
1215 | } | 1178 | } |
1216 | 1179 | ||
@@ -1223,29 +1186,22 @@ static void csi_K(struct vc_data *vc, int vpar) | |||
1223 | case 0: /* erase from cursor to end of line */ | 1186 | case 0: /* erase from cursor to end of line */ |
1224 | count = vc->vc_cols - vc->vc_x; | 1187 | count = vc->vc_cols - vc->vc_x; |
1225 | start = (unsigned short *)vc->vc_pos; | 1188 | start = (unsigned short *)vc->vc_pos; |
1226 | if (DO_UPDATE(vc)) | ||
1227 | vc->vc_sw->con_clear(vc, vc->vc_y, vc->vc_x, 1, | ||
1228 | vc->vc_cols - vc->vc_x); | ||
1229 | break; | 1189 | break; |
1230 | case 1: /* erase from start of line to cursor */ | 1190 | case 1: /* erase from start of line to cursor */ |
1231 | start = (unsigned short *)(vc->vc_pos - (vc->vc_x << 1)); | 1191 | start = (unsigned short *)(vc->vc_pos - (vc->vc_x << 1)); |
1232 | count = vc->vc_x + 1; | 1192 | count = vc->vc_x + 1; |
1233 | if (DO_UPDATE(vc)) | ||
1234 | vc->vc_sw->con_clear(vc, vc->vc_y, 0, 1, | ||
1235 | vc->vc_x + 1); | ||
1236 | break; | 1193 | break; |
1237 | case 2: /* erase whole line */ | 1194 | case 2: /* erase whole line */ |
1238 | start = (unsigned short *)(vc->vc_pos - (vc->vc_x << 1)); | 1195 | start = (unsigned short *)(vc->vc_pos - (vc->vc_x << 1)); |
1239 | count = vc->vc_cols; | 1196 | count = vc->vc_cols; |
1240 | if (DO_UPDATE(vc)) | ||
1241 | vc->vc_sw->con_clear(vc, vc->vc_y, 0, 1, | ||
1242 | vc->vc_cols); | ||
1243 | break; | 1197 | break; |
1244 | default: | 1198 | default: |
1245 | return; | 1199 | return; |
1246 | } | 1200 | } |
1247 | scr_memsetw(start, vc->vc_video_erase_char, 2 * count); | 1201 | scr_memsetw(start, vc->vc_video_erase_char, 2 * count); |
1248 | vc->vc_need_wrap = 0; | 1202 | vc->vc_need_wrap = 0; |
1203 | if (DO_UPDATE(vc)) | ||
1204 | do_update_region(vc, (unsigned long) start, count); | ||
1249 | } | 1205 | } |
1250 | 1206 | ||
1251 | static void csi_X(struct vc_data *vc, int vpar) /* erase the following vpar positions */ | 1207 | static void csi_X(struct vc_data *vc, int vpar) /* erase the following vpar positions */ |
@@ -1380,7 +1336,7 @@ static void respond_string(const char *p, struct tty_struct *tty) | |||
1380 | tty_insert_flip_char(tty, *p, 0); | 1336 | tty_insert_flip_char(tty, *p, 0); |
1381 | p++; | 1337 | p++; |
1382 | } | 1338 | } |
1383 | con_schedule_flip(tty); | 1339 | tty_schedule_flip(tty); |
1384 | } | 1340 | } |
1385 | 1341 | ||
1386 | static void cursor_report(struct vc_data *vc, struct tty_struct *tty) | 1342 | static void cursor_report(struct vc_data *vc, struct tty_struct *tty) |
@@ -2792,41 +2748,52 @@ static void con_flush_chars(struct tty_struct *tty) | |||
2792 | /* | 2748 | /* |
2793 | * Allocate the console screen memory. | 2749 | * Allocate the console screen memory. |
2794 | */ | 2750 | */ |
2795 | static int con_open(struct tty_struct *tty, struct file *filp) | 2751 | static int con_install(struct tty_driver *driver, struct tty_struct *tty) |
2796 | { | 2752 | { |
2797 | unsigned int currcons = tty->index; | 2753 | unsigned int currcons = tty->index; |
2798 | int ret = 0; | 2754 | struct vc_data *vc; |
2755 | int ret; | ||
2799 | 2756 | ||
2800 | console_lock(); | 2757 | console_lock(); |
2801 | if (tty->driver_data == NULL) { | 2758 | ret = vc_allocate(currcons); |
2802 | ret = vc_allocate(currcons); | 2759 | if (ret) |
2803 | if (ret == 0) { | 2760 | goto unlock; |
2804 | struct vc_data *vc = vc_cons[currcons].d; | ||
2805 | 2761 | ||
2806 | /* Still being freed */ | 2762 | vc = vc_cons[currcons].d; |
2807 | if (vc->port.tty) { | ||
2808 | console_unlock(); | ||
2809 | return -ERESTARTSYS; | ||
2810 | } | ||
2811 | tty->driver_data = vc; | ||
2812 | vc->port.tty = tty; | ||
2813 | 2763 | ||
2814 | if (!tty->winsize.ws_row && !tty->winsize.ws_col) { | 2764 | /* Still being freed */ |
2815 | tty->winsize.ws_row = vc_cons[currcons].d->vc_rows; | 2765 | if (vc->port.tty) { |
2816 | tty->winsize.ws_col = vc_cons[currcons].d->vc_cols; | 2766 | ret = -ERESTARTSYS; |
2817 | } | 2767 | goto unlock; |
2818 | if (vc->vc_utf) | ||
2819 | tty->termios->c_iflag |= IUTF8; | ||
2820 | else | ||
2821 | tty->termios->c_iflag &= ~IUTF8; | ||
2822 | console_unlock(); | ||
2823 | return ret; | ||
2824 | } | ||
2825 | } | 2768 | } |
2769 | |||
2770 | ret = tty_port_install(&vc->port, driver, tty); | ||
2771 | if (ret) | ||
2772 | goto unlock; | ||
2773 | |||
2774 | tty->driver_data = vc; | ||
2775 | vc->port.tty = tty; | ||
2776 | |||
2777 | if (!tty->winsize.ws_row && !tty->winsize.ws_col) { | ||
2778 | tty->winsize.ws_row = vc_cons[currcons].d->vc_rows; | ||
2779 | tty->winsize.ws_col = vc_cons[currcons].d->vc_cols; | ||
2780 | } | ||
2781 | if (vc->vc_utf) | ||
2782 | tty->termios.c_iflag |= IUTF8; | ||
2783 | else | ||
2784 | tty->termios.c_iflag &= ~IUTF8; | ||
2785 | unlock: | ||
2826 | console_unlock(); | 2786 | console_unlock(); |
2827 | return ret; | 2787 | return ret; |
2828 | } | 2788 | } |
2829 | 2789 | ||
2790 | static int con_open(struct tty_struct *tty, struct file *filp) | ||
2791 | { | ||
2792 | /* everything done in install */ | ||
2793 | return 0; | ||
2794 | } | ||
2795 | |||
2796 | |||
2830 | static void con_close(struct tty_struct *tty, struct file *filp) | 2797 | static void con_close(struct tty_struct *tty, struct file *filp) |
2831 | { | 2798 | { |
2832 | /* Nothing to do - we defer to shutdown */ | 2799 | /* Nothing to do - we defer to shutdown */ |
@@ -2839,7 +2806,6 @@ static void con_shutdown(struct tty_struct *tty) | |||
2839 | console_lock(); | 2806 | console_lock(); |
2840 | vc->port.tty = NULL; | 2807 | vc->port.tty = NULL; |
2841 | console_unlock(); | 2808 | console_unlock(); |
2842 | tty_shutdown(tty); | ||
2843 | } | 2809 | } |
2844 | 2810 | ||
2845 | static int default_italic_color = 2; // green (ASCII) | 2811 | static int default_italic_color = 2; // green (ASCII) |
@@ -2947,6 +2913,7 @@ static int __init con_init(void) | |||
2947 | console_initcall(con_init); | 2913 | console_initcall(con_init); |
2948 | 2914 | ||
2949 | static const struct tty_operations con_ops = { | 2915 | static const struct tty_operations con_ops = { |
2916 | .install = con_install, | ||
2950 | .open = con_open, | 2917 | .open = con_open, |
2951 | .close = con_close, | 2918 | .close = con_close, |
2952 | .write = con_write, | 2919 | .write = con_write, |