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, |
