forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-02-19 1c055e55a242a33e574e48be530e06770a210dcd
kernel/drivers/tty/vt/vt.c
....@@ -127,14 +127,6 @@
127127 static struct con_driver registered_con_driver[MAX_NR_CON_DRIVER];
128128 const struct consw *conswitchp;
129129
130
-/* A bitmap for codes <32. A bit of 1 indicates that the code
131
- * corresponding to that bit number invokes some special action
132
- * (such as cursor movement) and should not be displayed as a
133
- * glyph unless the disp_ctrl mode is explicitly enabled.
134
- */
135
-#define CTRL_ACTION 0x0d00ff81
136
-#define CTRL_ALWAYS 0x0800f501 /* Cannot be overridden by disp_ctrl */
137
-
138130 /*
139131 * Here is the default bell parameters: 750HZ, 1/8th of a second
140132 */
....@@ -171,7 +163,7 @@
171163 int global_cursor_default = -1;
172164 module_param(global_cursor_default, int, S_IRUGO | S_IWUSR);
173165
174
-static int cur_default = CUR_DEFAULT;
166
+static int cur_default = CUR_UNDERLINE;
175167 module_param(cur_default, int, S_IRUGO | S_IWUSR);
176168
177169 /*
....@@ -291,7 +283,8 @@
291283 return con_is_visible(vc) && !console_blanked;
292284 }
293285
294
-static inline unsigned short *screenpos(struct vc_data *vc, int offset, int viewed)
286
+static inline unsigned short *screenpos(const struct vc_data *vc, int offset,
287
+ bool viewed)
295288 {
296289 unsigned short *p;
297290
....@@ -351,7 +344,7 @@
351344 /* allocate everything in one go */
352345 memsize = cols * rows * sizeof(char32_t);
353346 memsize += rows * sizeof(char32_t *);
354
- p = vmalloc(memsize);
347
+ p = vzalloc(memsize);
355348 if (!p)
356349 return NULL;
357350
....@@ -381,7 +374,7 @@
381374 struct uni_screen *uniscr = get_vc_uniscr(vc);
382375
383376 if (uniscr)
384
- uniscr->lines[vc->vc_y][vc->vc_x] = uc;
377
+ uniscr->lines[vc->state.y][vc->state.x] = uc;
385378 }
386379
387380 static void vc_uniscr_insert(struct vc_data *vc, unsigned int nr)
....@@ -389,8 +382,8 @@
389382 struct uni_screen *uniscr = get_vc_uniscr(vc);
390383
391384 if (uniscr) {
392
- char32_t *ln = uniscr->lines[vc->vc_y];
393
- unsigned int x = vc->vc_x, cols = vc->vc_cols;
385
+ char32_t *ln = uniscr->lines[vc->state.y];
386
+ unsigned int x = vc->state.x, cols = vc->vc_cols;
394387
395388 memmove(&ln[x + nr], &ln[x], (cols - x - nr) * sizeof(*ln));
396389 memset32(&ln[x], ' ', nr);
....@@ -402,8 +395,8 @@
402395 struct uni_screen *uniscr = get_vc_uniscr(vc);
403396
404397 if (uniscr) {
405
- char32_t *ln = uniscr->lines[vc->vc_y];
406
- unsigned int x = vc->vc_x, cols = vc->vc_cols;
398
+ char32_t *ln = uniscr->lines[vc->state.y];
399
+ unsigned int x = vc->state.x, cols = vc->vc_cols;
407400
408401 memcpy(&ln[x], &ln[x + nr], (cols - x - nr) * sizeof(*ln));
409402 memset32(&ln[cols - nr], ' ', nr);
....@@ -416,7 +409,7 @@
416409 struct uni_screen *uniscr = get_vc_uniscr(vc);
417410
418411 if (uniscr) {
419
- char32_t *ln = uniscr->lines[vc->vc_y];
412
+ char32_t *ln = uniscr->lines[vc->state.y];
420413
421414 memset32(&ln[x], ' ', nr);
422415 }
....@@ -551,7 +544,7 @@
551544 * This must be preceded by a successful call to vc_uniscr_check() once
552545 * the console lock has been taken.
553546 */
554
-void vc_uniscr_copy_line(struct vc_data *vc, void *dest, int viewed,
547
+void vc_uniscr_copy_line(const struct vc_data *vc, void *dest, bool viewed,
555548 unsigned int row, unsigned int col, unsigned int nr)
556549 {
557550 struct uni_screen *uniscr = get_vc_uniscr(vc);
....@@ -705,8 +698,9 @@
705698
706699 /* Structure of attributes is hardware-dependent */
707700
708
-static u8 build_attr(struct vc_data *vc, u8 _color, u8 _intensity, u8 _blink,
709
- u8 _underline, u8 _reverse, u8 _italic)
701
+static u8 build_attr(struct vc_data *vc, u8 _color,
702
+ enum vc_intensity _intensity, bool _blink, bool _underline,
703
+ bool _reverse, bool _italic)
710704 {
711705 if (vc->vc_sw->con_build_attr)
712706 return vc->vc_sw->con_build_attr(vc, _color, _intensity,
....@@ -726,21 +720,21 @@
726720 u8 a = _color;
727721 if (!vc->vc_can_do_color)
728722 return _intensity |
729
- (_italic ? 2 : 0) |
730
- (_underline ? 4 : 0) |
731
- (_reverse ? 8 : 0) |
732
- (_blink ? 0x80 : 0);
723
+ (_italic << 1) |
724
+ (_underline << 2) |
725
+ (_reverse << 3) |
726
+ (_blink << 7);
733727 if (_italic)
734728 a = (a & 0xF0) | vc->vc_itcolor;
735729 else if (_underline)
736730 a = (a & 0xf0) | vc->vc_ulcolor;
737
- else if (_intensity == 0)
731
+ else if (_intensity == VCI_HALF_BRIGHT)
738732 a = (a & 0xf0) | vc->vc_halfcolor;
739733 if (_reverse)
740
- a = ((a) & 0x88) | ((((a) >> 4) | ((a) << 4)) & 0x77);
734
+ a = (a & 0x88) | (((a >> 4) | (a << 4)) & 0x77);
741735 if (_blink)
742736 a ^= 0x80;
743
- if (_intensity == 2)
737
+ if (_intensity == VCI_BOLD)
744738 a ^= 0x08;
745739 if (vc->vc_hi_font_mask == 0x100)
746740 a <<= 1;
....@@ -750,14 +744,16 @@
750744
751745 static void update_attr(struct vc_data *vc)
752746 {
753
- vc->vc_attr = build_attr(vc, vc->vc_color, vc->vc_intensity,
754
- vc->vc_blink, vc->vc_underline,
755
- vc->vc_reverse ^ vc->vc_decscnm, vc->vc_italic);
756
- vc->vc_video_erase_char = (build_attr(vc, vc->vc_color, 1, vc->vc_blink, 0, vc->vc_decscnm, 0) << 8) | ' ';
747
+ vc->vc_attr = build_attr(vc, vc->state.color, vc->state.intensity,
748
+ vc->state.blink, vc->state.underline,
749
+ vc->state.reverse ^ vc->vc_decscnm, vc->state.italic);
750
+ vc->vc_video_erase_char = ' ' | (build_attr(vc, vc->state.color,
751
+ VCI_NORMAL, vc->state.blink, false,
752
+ vc->vc_decscnm, false) << 8);
757753 }
758754
759755 /* Note: inverting the screen twice should revert to the original state */
760
-void invert_screen(struct vc_data *vc, int offset, int count, int viewed)
756
+void invert_screen(struct vc_data *vc, int offset, int count, bool viewed)
761757 {
762758 unsigned short *p;
763759
....@@ -782,14 +778,18 @@
782778 } else if (vc->vc_hi_font_mask == 0x100) {
783779 while (cnt--) {
784780 a = scr_readw(q);
785
- a = ((a) & 0x11ff) | (((a) & 0xe000) >> 4) | (((a) & 0x0e00) << 4);
781
+ a = (a & 0x11ff) |
782
+ ((a & 0xe000) >> 4) |
783
+ ((a & 0x0e00) << 4);
786784 scr_writew(a, q);
787785 q++;
788786 }
789787 } else {
790788 while (cnt--) {
791789 a = scr_readw(q);
792
- a = ((a) & 0x88ff) | (((a) & 0x7000) >> 4) | (((a) & 0x0700) << 4);
790
+ a = (a & 0x88ff) |
791
+ ((a & 0x7000) >> 4) |
792
+ ((a & 0x0700) << 4);
793793 scr_writew(a, q);
794794 q++;
795795 }
....@@ -812,7 +812,7 @@
812812
813813 if (old_offset != -1 && old_offset >= 0 &&
814814 old_offset < vc->vc_screenbuf_size) {
815
- scr_writew(old, screenpos(vc, old_offset, 1));
815
+ scr_writew(old, screenpos(vc, old_offset, true));
816816 if (con_should_update(vc))
817817 vc->vc_sw->con_putc(vc, old, oldy, oldx);
818818 notify_update(vc);
....@@ -824,7 +824,7 @@
824824 offset < vc->vc_screenbuf_size) {
825825 unsigned short new;
826826 unsigned short *p;
827
- p = screenpos(vc, offset, 1);
827
+ p = screenpos(vc, offset, true);
828828 old = scr_readw(p);
829829 new = old ^ vc->vc_complement_mask;
830830 scr_writew(new, p);
....@@ -842,12 +842,12 @@
842842 unsigned short *p = (unsigned short *) vc->vc_pos;
843843
844844 vc_uniscr_insert(vc, nr);
845
- scr_memmovew(p + nr, p, (vc->vc_cols - vc->vc_x - nr) * 2);
845
+ scr_memmovew(p + nr, p, (vc->vc_cols - vc->state.x - nr) * 2);
846846 scr_memsetw(p, vc->vc_video_erase_char, nr * 2);
847847 vc->vc_need_wrap = 0;
848848 if (con_should_update(vc))
849849 do_update_region(vc, (unsigned long) p,
850
- vc->vc_cols - vc->vc_x);
850
+ vc->vc_cols - vc->state.x);
851851 }
852852
853853 static void delete_char(struct vc_data *vc, unsigned int nr)
....@@ -855,13 +855,13 @@
855855 unsigned short *p = (unsigned short *) vc->vc_pos;
856856
857857 vc_uniscr_delete(vc, nr);
858
- scr_memcpyw(p, p + nr, (vc->vc_cols - vc->vc_x - nr) * 2);
859
- scr_memsetw(p + vc->vc_cols - vc->vc_x - nr, vc->vc_video_erase_char,
858
+ scr_memmovew(p, p + nr, (vc->vc_cols - vc->state.x - nr) * 2);
859
+ scr_memsetw(p + vc->vc_cols - vc->state.x - nr, vc->vc_video_erase_char,
860860 nr * 2);
861861 vc->vc_need_wrap = 0;
862862 if (con_should_update(vc))
863863 do_update_region(vc, (unsigned long) p,
864
- vc->vc_cols - vc->vc_x);
864
+ vc->vc_cols - vc->state.x);
865865 }
866866
867867 static int softcursor_original = -1;
....@@ -871,16 +871,21 @@
871871 int i = scr_readw((u16 *) vc->vc_pos);
872872 u32 type = vc->vc_cursor_type;
873873
874
- if (! (type & 0x10)) return;
875
- if (softcursor_original != -1) return;
874
+ if (!(type & CUR_SW))
875
+ return;
876
+ if (softcursor_original != -1)
877
+ return;
876878 softcursor_original = i;
877
- i |= ((type >> 8) & 0xff00 );
878
- i ^= ((type) & 0xff00 );
879
- if ((type & 0x20) && ((softcursor_original & 0x7000) == (i & 0x7000))) i ^= 0x7000;
880
- if ((type & 0x40) && ((i & 0x700) == ((i & 0x7000) >> 4))) i ^= 0x0700;
881
- scr_writew(i, (u16 *) vc->vc_pos);
879
+ i |= CUR_SET(type);
880
+ i ^= CUR_CHANGE(type);
881
+ if ((type & CUR_ALWAYS_BG) &&
882
+ (softcursor_original & CUR_BG) == (i & CUR_BG))
883
+ i ^= CUR_BG;
884
+ if ((type & CUR_INVERT_FG_BG) && (i & CUR_FG) == ((i & CUR_BG) >> 4))
885
+ i ^= CUR_FG;
886
+ scr_writew(i, (u16 *)vc->vc_pos);
882887 if (con_should_update(vc))
883
- vc->vc_sw->con_putc(vc, i, vc->vc_y, vc->vc_x);
888
+ vc->vc_sw->con_putc(vc, i, vc->state.y, vc->state.x);
884889 }
885890
886891 static void hide_softcursor(struct vc_data *vc)
....@@ -889,7 +894,7 @@
889894 scr_writew(softcursor_original, (u16 *)vc->vc_pos);
890895 if (con_should_update(vc))
891896 vc->vc_sw->con_putc(vc, softcursor_original,
892
- vc->vc_y, vc->vc_x);
897
+ vc->state.y, vc->state.x);
893898 softcursor_original = -1;
894899 }
895900 }
....@@ -911,7 +916,7 @@
911916 if (vc_is_sel(vc))
912917 clear_selection();
913918 add_softcursor(vc);
914
- if ((vc->vc_cursor_type & 0x0f) != 1)
919
+ if (CUR_SIZE(vc->vc_cursor_type) != CUR_NONE)
915920 vc->vc_sw->con_cursor(vc, CM_DRAW);
916921 } else
917922 hide_cursor(vc);
....@@ -927,7 +932,8 @@
927932 vc->vc_origin = (unsigned long)vc->vc_screenbuf;
928933 vc->vc_visible_origin = vc->vc_origin;
929934 vc->vc_scr_end = vc->vc_origin + vc->vc_screenbuf_size;
930
- vc->vc_pos = vc->vc_origin + vc->vc_size_row * vc->vc_y + 2 * vc->vc_x;
935
+ vc->vc_pos = vc->vc_origin + vc->vc_size_row * vc->state.y +
936
+ 2 * vc->state.x;
931937 }
932938
933939 static void save_screen(struct vc_data *vc)
....@@ -1025,9 +1031,7 @@
10251031 clear_buffer_attributes(vc);
10261032 }
10271033
1028
- /* Forcibly update if we're panicing */
1029
- if ((update && vc->vc_mode != KD_GRAPHICS) ||
1030
- vt_force_oops_output(vc))
1034
+ if (update && vc->vc_mode != KD_GRAPHICS)
10311035 do_update_region(vc, vc->vc_origin, vc->vc_screenbuf_size / 2);
10321036 }
10331037 set_cursor(vc);
....@@ -1067,7 +1071,6 @@
10671071 vc->vc_hi_font_mask = 0;
10681072 vc->vc_complement_mask = 0;
10691073 vc->vc_can_do_color = 0;
1070
- vc->vc_panic_force_write = false;
10711074 vc->vc_cur_blink_ms = DEFAULT_CURSOR_BLINK_MS;
10721075 vc->vc_sw->con_init(vc, init);
10731076 if (!vc->vc_complement_mask)
....@@ -1178,7 +1181,6 @@
11781181 /**
11791182 * vc_do_resize - resizing method for the tty
11801183 * @tty: tty being resized
1181
- * @real_tty: real tty (different to tty if a pty/tty pair)
11821184 * @vc: virtual console private data
11831185 * @cols: columns
11841186 * @lines: lines
....@@ -1276,8 +1278,8 @@
12761278 new_origin = (long) newscreen;
12771279 new_scr_end = new_origin + new_screen_size;
12781280
1279
- if (vc->vc_y > new_rows) {
1280
- if (old_rows - vc->vc_y < new_rows) {
1281
+ if (vc->state.y > new_rows) {
1282
+ if (old_rows - vc->state.y < new_rows) {
12811283 /*
12821284 * Cursor near the bottom, copy contents from the
12831285 * bottom of buffer
....@@ -1288,7 +1290,7 @@
12881290 * Cursor is in no man's land, copy 1/2 screenful
12891291 * from the top and bottom of cursor position
12901292 */
1291
- first_copied_row = (vc->vc_y - new_rows/2);
1293
+ first_copied_row = (vc->state.y - new_rows/2);
12921294 }
12931295 old_origin += first_copied_row * old_row_size;
12941296 } else
....@@ -1323,7 +1325,7 @@
13231325 /* do part of a reset_terminal() */
13241326 vc->vc_top = 0;
13251327 vc->vc_bottom = vc->vc_rows;
1326
- gotoxy(vc, vc->vc_x, vc->vc_y);
1328
+ gotoxy(vc, vc->state.x, vc->state.y);
13271329 save_cur(vc);
13281330
13291331 if (tty) {
....@@ -1410,6 +1412,8 @@
14101412 * VT102 emulator
14111413 */
14121414
1415
+enum { EPecma = 0, EPdec, EPeq, EPgt, EPlt};
1416
+
14131417 #define set_kbd(vc, x) vt_set_kbd_mode_bit((vc)->vc_num, (x))
14141418 #define clr_kbd(vc, x) vt_clr_kbd_mode_bit((vc)->vc_num, (x))
14151419 #define is_kbd(vc, x) vt_get_kbd_mode_bit((vc)->vc_num, (x))
....@@ -1418,12 +1422,6 @@
14181422 #define decckm VC_CKMODE
14191423 #define kbdapplic VC_APPLIC
14201424 #define lnm VC_CRLF
1421
-
1422
-/*
1423
- * this is what the terminal answers to a ESC-Z or csi0c query.
1424
- */
1425
-#define VT100ID "\033[?1;2c"
1426
-#define VT102ID "\033[?6c"
14271425
14281426 const unsigned char color_table[] = { 0, 4, 2, 6, 1, 5, 3, 7,
14291427 8,12,10,14, 9,13,11,15 };
....@@ -1457,12 +1455,12 @@
14571455 int min_y, max_y;
14581456
14591457 if (new_x < 0)
1460
- vc->vc_x = 0;
1458
+ vc->state.x = 0;
14611459 else {
14621460 if (new_x >= vc->vc_cols)
1463
- vc->vc_x = vc->vc_cols - 1;
1461
+ vc->state.x = vc->vc_cols - 1;
14641462 else
1465
- vc->vc_x = new_x;
1463
+ vc->state.x = new_x;
14661464 }
14671465
14681466 if (vc->vc_decom) {
....@@ -1473,12 +1471,13 @@
14731471 max_y = vc->vc_rows;
14741472 }
14751473 if (new_y < min_y)
1476
- vc->vc_y = min_y;
1474
+ vc->state.y = min_y;
14771475 else if (new_y >= max_y)
1478
- vc->vc_y = max_y - 1;
1476
+ vc->state.y = max_y - 1;
14791477 else
1480
- vc->vc_y = new_y;
1481
- vc->vc_pos = vc->vc_origin + vc->vc_y * vc->vc_size_row + (vc->vc_x<<1);
1478
+ vc->state.y = new_y;
1479
+ vc->vc_pos = vc->vc_origin + vc->state.y * vc->vc_size_row +
1480
+ (vc->state.x << 1);
14821481 vc->vc_need_wrap = 0;
14831482 }
14841483
....@@ -1505,10 +1504,10 @@
15051504 /* don't scroll if above bottom of scrolling region, or
15061505 * if below scrolling region
15071506 */
1508
- if (vc->vc_y + 1 == vc->vc_bottom)
1507
+ if (vc->state.y + 1 == vc->vc_bottom)
15091508 con_scroll(vc, vc->vc_top, vc->vc_bottom, SM_UP, 1);
1510
- else if (vc->vc_y < vc->vc_rows - 1) {
1511
- vc->vc_y++;
1509
+ else if (vc->state.y < vc->vc_rows - 1) {
1510
+ vc->state.y++;
15121511 vc->vc_pos += vc->vc_size_row;
15131512 }
15141513 vc->vc_need_wrap = 0;
....@@ -1520,10 +1519,10 @@
15201519 /* don't scroll if below top of scrolling region, or
15211520 * if above scrolling region
15221521 */
1523
- if (vc->vc_y == vc->vc_top)
1522
+ if (vc->state.y == vc->vc_top)
15241523 con_scroll(vc, vc->vc_top, vc->vc_bottom, SM_DOWN, 1);
1525
- else if (vc->vc_y > 0) {
1526
- vc->vc_y--;
1524
+ else if (vc->state.y > 0) {
1525
+ vc->state.y--;
15271526 vc->vc_pos -= vc->vc_size_row;
15281527 }
15291528 vc->vc_need_wrap = 0;
....@@ -1531,16 +1530,16 @@
15311530
15321531 static inline void cr(struct vc_data *vc)
15331532 {
1534
- vc->vc_pos -= vc->vc_x << 1;
1535
- vc->vc_need_wrap = vc->vc_x = 0;
1533
+ vc->vc_pos -= vc->state.x << 1;
1534
+ vc->vc_need_wrap = vc->state.x = 0;
15361535 notify_write(vc, '\r');
15371536 }
15381537
15391538 static inline void bs(struct vc_data *vc)
15401539 {
1541
- if (vc->vc_x) {
1540
+ if (vc->state.x) {
15421541 vc->vc_pos -= 2;
1543
- vc->vc_x--;
1542
+ vc->state.x--;
15441543 vc->vc_need_wrap = 0;
15451544 notify_write(vc, '\b');
15461545 }
....@@ -1558,22 +1557,22 @@
15581557
15591558 switch (vpar) {
15601559 case 0: /* erase from cursor to end of display */
1561
- vc_uniscr_clear_line(vc, vc->vc_x,
1562
- vc->vc_cols - vc->vc_x);
1563
- vc_uniscr_clear_lines(vc, vc->vc_y + 1,
1564
- vc->vc_rows - vc->vc_y - 1);
1560
+ vc_uniscr_clear_line(vc, vc->state.x,
1561
+ vc->vc_cols - vc->state.x);
1562
+ vc_uniscr_clear_lines(vc, vc->state.y + 1,
1563
+ vc->vc_rows - vc->state.y - 1);
15651564 count = (vc->vc_scr_end - vc->vc_pos) >> 1;
15661565 start = (unsigned short *)vc->vc_pos;
15671566 break;
15681567 case 1: /* erase from start to cursor */
1569
- vc_uniscr_clear_line(vc, 0, vc->vc_x + 1);
1570
- vc_uniscr_clear_lines(vc, 0, vc->vc_y);
1568
+ vc_uniscr_clear_line(vc, 0, vc->state.x + 1);
1569
+ vc_uniscr_clear_lines(vc, 0, vc->state.y);
15711570 count = ((vc->vc_pos - vc->vc_origin) >> 1) + 1;
15721571 start = (unsigned short *)vc->vc_origin;
15731572 break;
15741573 case 3: /* include scrollback */
15751574 flush_scrollback(vc);
1576
- /* fallthrough */
1575
+ fallthrough;
15771576 case 2: /* erase whole display */
15781577 vc_uniscr_clear_lines(vc, 0, vc->vc_rows);
15791578 count = vc->vc_cols * vc->vc_rows;
....@@ -1597,49 +1596,51 @@
15971596 switch (vpar) {
15981597 case 0: /* erase from cursor to end of line */
15991598 offset = 0;
1600
- count = vc->vc_cols - vc->vc_x;
1599
+ count = vc->vc_cols - vc->state.x;
16011600 break;
16021601 case 1: /* erase from start of line to cursor */
1603
- offset = -vc->vc_x;
1604
- count = vc->vc_x + 1;
1602
+ offset = -vc->state.x;
1603
+ count = vc->state.x + 1;
16051604 break;
16061605 case 2: /* erase whole line */
1607
- offset = -vc->vc_x;
1606
+ offset = -vc->state.x;
16081607 count = vc->vc_cols;
16091608 break;
16101609 default:
16111610 return;
16121611 }
1613
- vc_uniscr_clear_line(vc, vc->vc_x + offset, count);
1612
+ vc_uniscr_clear_line(vc, vc->state.x + offset, count);
16141613 scr_memsetw(start + offset, vc->vc_video_erase_char, 2 * count);
16151614 vc->vc_need_wrap = 0;
16161615 if (con_should_update(vc))
16171616 do_update_region(vc, (unsigned long)(start + offset), count);
16181617 }
16191618
1620
-static void csi_X(struct vc_data *vc, int vpar) /* erase the following vpar positions */
1619
+/* erase the following vpar positions */
1620
+static void csi_X(struct vc_data *vc, unsigned int vpar)
16211621 { /* not vt100? */
1622
- int count;
1622
+ unsigned int count;
16231623
16241624 if (!vpar)
16251625 vpar++;
1626
- count = (vpar > vc->vc_cols - vc->vc_x) ? (vc->vc_cols - vc->vc_x) : vpar;
16271626
1628
- vc_uniscr_clear_line(vc, vc->vc_x, count);
1627
+ count = min(vpar, vc->vc_cols - vc->state.x);
1628
+
1629
+ vc_uniscr_clear_line(vc, vc->state.x, count);
16291630 scr_memsetw((unsigned short *)vc->vc_pos, vc->vc_video_erase_char, 2 * count);
16301631 if (con_should_update(vc))
1631
- vc->vc_sw->con_clear(vc, vc->vc_y, vc->vc_x, 1, count);
1632
+ vc->vc_sw->con_clear(vc, vc->state.y, vc->state.x, 1, count);
16321633 vc->vc_need_wrap = 0;
16331634 }
16341635
16351636 static void default_attr(struct vc_data *vc)
16361637 {
1637
- vc->vc_intensity = 1;
1638
- vc->vc_italic = 0;
1639
- vc->vc_underline = 0;
1640
- vc->vc_reverse = 0;
1641
- vc->vc_blink = 0;
1642
- vc->vc_color = vc->vc_def_color;
1638
+ vc->state.intensity = VCI_NORMAL;
1639
+ vc->state.italic = false;
1640
+ vc->state.underline = false;
1641
+ vc->state.reverse = false;
1642
+ vc->state.blink = false;
1643
+ vc->state.color = vc->vc_def_color;
16431644 }
16441645
16451646 struct rgb { u8 r; u8 g; u8 b; };
....@@ -1675,27 +1676,27 @@
16751676
16761677 if (hue == 7 && max <= 0x55) {
16771678 hue = 0;
1678
- vc->vc_intensity = 2;
1679
+ vc->state.intensity = VCI_BOLD;
16791680 } else if (max > 0xaa)
1680
- vc->vc_intensity = 2;
1681
+ vc->state.intensity = VCI_BOLD;
16811682 else
1682
- vc->vc_intensity = 1;
1683
+ vc->state.intensity = VCI_NORMAL;
16831684
1684
- vc->vc_color = (vc->vc_color & 0xf0) | hue;
1685
+ vc->state.color = (vc->state.color & 0xf0) | hue;
16851686 }
16861687
16871688 static void rgb_background(struct vc_data *vc, const struct rgb *c)
16881689 {
16891690 /* For backgrounds, err on the dark side. */
1690
- vc->vc_color = (vc->vc_color & 0x0f)
1691
+ vc->state.color = (vc->state.color & 0x0f)
16911692 | (c->r&0x80) >> 1 | (c->g&0x80) >> 2 | (c->b&0x80) >> 3;
16921693 }
16931694
16941695 /*
16951696 * ITU T.416 Higher colour modes. They break the usual properties of SGR codes
1696
- * and thus need to be detected and ignored by hand. Strictly speaking, that
1697
- * standard also wants : rather than ; as separators, contrary to ECMA-48, but
1698
- * no one produces such codes and almost no one accepts them.
1697
+ * and thus need to be detected and ignored by hand. That standard also
1698
+ * wants : rather than ; as separators but sequences containing : are currently
1699
+ * completely ignored by the parser.
16991700 *
17001701 * Subcommands 3 (CMY) and 4 (CMYK) are so insane there's no point in
17011702 * supporting them.
....@@ -1738,13 +1739,13 @@
17381739 default_attr(vc);
17391740 break;
17401741 case 1:
1741
- vc->vc_intensity = 2;
1742
+ vc->state.intensity = VCI_BOLD;
17421743 break;
17431744 case 2:
1744
- vc->vc_intensity = 0;
1745
+ vc->state.intensity = VCI_HALF_BRIGHT;
17451746 break;
17461747 case 3:
1747
- vc->vc_italic = 1;
1748
+ vc->state.italic = true;
17481749 break;
17491750 case 21:
17501751 /*
....@@ -1752,21 +1753,19 @@
17521753 * convert it to a single underline.
17531754 */
17541755 case 4:
1755
- vc->vc_underline = 1;
1756
+ vc->state.underline = true;
17561757 break;
17571758 case 5:
1758
- vc->vc_blink = 1;
1759
+ vc->state.blink = true;
17591760 break;
17601761 case 7:
1761
- vc->vc_reverse = 1;
1762
+ vc->state.reverse = true;
17621763 break;
17631764 case 10: /* ANSI X3.64-1979 (SCO-ish?)
17641765 * Select primary font, don't display control chars if
17651766 * defined, don't set bit 8 on output.
17661767 */
1767
- vc->vc_translate = set_translate(vc->vc_charset == 0
1768
- ? vc->vc_G0_charset
1769
- : vc->vc_G1_charset, vc);
1768
+ vc->vc_translate = set_translate(vc->state.Gx_charset[vc->state.charset], vc);
17701769 vc->vc_disp_ctrl = 0;
17711770 vc->vc_toggle_meta = 0;
17721771 break;
....@@ -1787,19 +1786,19 @@
17871786 vc->vc_toggle_meta = 1;
17881787 break;
17891788 case 22:
1790
- vc->vc_intensity = 1;
1789
+ vc->state.intensity = VCI_NORMAL;
17911790 break;
17921791 case 23:
1793
- vc->vc_italic = 0;
1792
+ vc->state.italic = false;
17941793 break;
17951794 case 24:
1796
- vc->vc_underline = 0;
1795
+ vc->state.underline = false;
17971796 break;
17981797 case 25:
1799
- vc->vc_blink = 0;
1798
+ vc->state.blink = false;
18001799 break;
18011800 case 27:
1802
- vc->vc_reverse = 0;
1801
+ vc->state.reverse = false;
18031802 break;
18041803 case 38:
18051804 i = vc_t416_color(vc, i, rgb_foreground);
....@@ -1808,67 +1807,73 @@
18081807 i = vc_t416_color(vc, i, rgb_background);
18091808 break;
18101809 case 39:
1811
- vc->vc_color = (vc->vc_def_color & 0x0f) |
1812
- (vc->vc_color & 0xf0);
1810
+ vc->state.color = (vc->vc_def_color & 0x0f) |
1811
+ (vc->state.color & 0xf0);
18131812 break;
18141813 case 49:
1815
- vc->vc_color = (vc->vc_def_color & 0xf0) |
1816
- (vc->vc_color & 0x0f);
1814
+ vc->state.color = (vc->vc_def_color & 0xf0) |
1815
+ (vc->state.color & 0x0f);
18171816 break;
18181817 default:
18191818 if (vc->vc_par[i] >= 90 && vc->vc_par[i] <= 107) {
18201819 if (vc->vc_par[i] < 100)
1821
- vc->vc_intensity = 2;
1820
+ vc->state.intensity = VCI_BOLD;
18221821 vc->vc_par[i] -= 60;
18231822 }
18241823 if (vc->vc_par[i] >= 30 && vc->vc_par[i] <= 37)
1825
- vc->vc_color = color_table[vc->vc_par[i] - 30]
1826
- | (vc->vc_color & 0xf0);
1824
+ vc->state.color = color_table[vc->vc_par[i] - 30]
1825
+ | (vc->state.color & 0xf0);
18271826 else if (vc->vc_par[i] >= 40 && vc->vc_par[i] <= 47)
1828
- vc->vc_color = (color_table[vc->vc_par[i] - 40] << 4)
1829
- | (vc->vc_color & 0x0f);
1827
+ vc->state.color = (color_table[vc->vc_par[i] - 40] << 4)
1828
+ | (vc->state.color & 0x0f);
18301829 break;
18311830 }
18321831 update_attr(vc);
18331832 }
18341833
1835
-static void respond_string(const char *p, struct tty_port *port)
1834
+static void respond_string(const char *p, size_t len, struct tty_port *port)
18361835 {
1837
- while (*p) {
1838
- tty_insert_flip_char(port, *p, 0);
1839
- p++;
1840
- }
1841
- tty_schedule_flip(port);
1836
+ tty_insert_flip_string(port, p, len);
1837
+ tty_flip_buffer_push(port);
18421838 }
18431839
18441840 static void cursor_report(struct vc_data *vc, struct tty_struct *tty)
18451841 {
18461842 char buf[40];
1843
+ int len;
18471844
1848
- sprintf(buf, "\033[%d;%dR", vc->vc_y + (vc->vc_decom ? vc->vc_top + 1 : 1), vc->vc_x + 1);
1849
- respond_string(buf, tty->port);
1845
+ len = sprintf(buf, "\033[%d;%dR", vc->state.y +
1846
+ (vc->vc_decom ? vc->vc_top + 1 : 1),
1847
+ vc->state.x + 1);
1848
+ respond_string(buf, len, tty->port);
18501849 }
18511850
18521851 static inline void status_report(struct tty_struct *tty)
18531852 {
1854
- respond_string("\033[0n", tty->port); /* Terminal ok */
1853
+ static const char teminal_ok[] = "\033[0n";
1854
+
1855
+ respond_string(teminal_ok, strlen(teminal_ok), tty->port);
18551856 }
18561857
18571858 static inline void respond_ID(struct tty_struct *tty)
18581859 {
1859
- respond_string(VT102ID, tty->port);
1860
+ /* terminal answer to an ESC-Z or csi0c query. */
1861
+ static const char vt102_id[] = "\033[?6c";
1862
+
1863
+ respond_string(vt102_id, strlen(vt102_id), tty->port);
18601864 }
18611865
18621866 void mouse_report(struct tty_struct *tty, int butt, int mrx, int mry)
18631867 {
18641868 char buf[8];
1869
+ int len;
18651870
1866
- sprintf(buf, "\033[M%c%c%c", (char)(' ' + butt), (char)('!' + mrx),
1867
- (char)('!' + mry));
1868
- respond_string(buf, tty->port);
1871
+ len = sprintf(buf, "\033[M%c%c%c", (char)(' ' + butt),
1872
+ (char)('!' + mrx), (char)('!' + mry));
1873
+ respond_string(buf, len, tty->port);
18691874 }
18701875
1871
-/* invoked via ioctl(TIOCLINUX) and through set_selection */
1876
+/* invoked via ioctl(TIOCLINUX) and through set_selection_user */
18721877 int mouse_reporting(void)
18731878 {
18741879 return vc_cons[fg_console].d->vc_report_mouse;
....@@ -1880,7 +1885,7 @@
18801885 int i;
18811886
18821887 for (i = 0; i <= vc->vc_npar; i++)
1883
- if (vc->vc_ques) {
1888
+ if (vc->vc_priv == EPdec) {
18841889 switch(vc->vc_par[i]) { /* DEC private modes set/reset */
18851890 case 1: /* Cursor keys send ^[Ox/^[[x */
18861891 if (on_off)
....@@ -1898,7 +1903,9 @@
18981903 case 5: /* Inverted screen on/off */
18991904 if (vc->vc_decscnm != on_off) {
19001905 vc->vc_decscnm = on_off;
1901
- invert_screen(vc, 0, vc->vc_screenbuf_size, 0);
1906
+ invert_screen(vc, 0,
1907
+ vc->vc_screenbuf_size,
1908
+ false);
19021909 update_attr(vc);
19031910 }
19041911 break;
....@@ -1946,75 +1953,73 @@
19461953 /* console_lock is held */
19471954 static void setterm_command(struct vc_data *vc)
19481955 {
1949
- switch(vc->vc_par[0]) {
1950
- case 1: /* set color for underline mode */
1951
- if (vc->vc_can_do_color &&
1952
- vc->vc_par[1] < 16) {
1953
- vc->vc_ulcolor = color_table[vc->vc_par[1]];
1954
- if (vc->vc_underline)
1955
- update_attr(vc);
1956
- }
1957
- break;
1958
- case 2: /* set color for half intensity mode */
1959
- if (vc->vc_can_do_color &&
1960
- vc->vc_par[1] < 16) {
1961
- vc->vc_halfcolor = color_table[vc->vc_par[1]];
1962
- if (vc->vc_intensity == 0)
1963
- update_attr(vc);
1964
- }
1965
- break;
1966
- case 8: /* store colors as defaults */
1967
- vc->vc_def_color = vc->vc_attr;
1968
- if (vc->vc_hi_font_mask == 0x100)
1969
- vc->vc_def_color >>= 1;
1970
- default_attr(vc);
1971
- update_attr(vc);
1972
- break;
1973
- case 9: /* set blanking interval */
1974
- blankinterval = ((vc->vc_par[1] < 60) ? vc->vc_par[1] : 60) * 60;
1975
- poke_blanked_console();
1976
- break;
1977
- case 10: /* set bell frequency in Hz */
1978
- if (vc->vc_npar >= 1)
1979
- vc->vc_bell_pitch = vc->vc_par[1];
1980
- else
1981
- vc->vc_bell_pitch = DEFAULT_BELL_PITCH;
1982
- break;
1983
- case 11: /* set bell duration in msec */
1984
- if (vc->vc_npar >= 1)
1985
- vc->vc_bell_duration = (vc->vc_par[1] < 2000) ?
1986
- msecs_to_jiffies(vc->vc_par[1]) : 0;
1987
- else
1988
- vc->vc_bell_duration = DEFAULT_BELL_DURATION;
1989
- break;
1990
- case 12: /* bring specified console to the front */
1991
- if (vc->vc_par[1] >= 1 && vc_cons_allocated(vc->vc_par[1] - 1))
1992
- set_console(vc->vc_par[1] - 1);
1993
- break;
1994
- case 13: /* unblank the screen */
1995
- poke_blanked_console();
1996
- break;
1997
- case 14: /* set vesa powerdown interval */
1998
- vesa_off_interval = ((vc->vc_par[1] < 60) ? vc->vc_par[1] : 60) * 60 * HZ;
1999
- break;
2000
- case 15: /* activate the previous console */
2001
- set_console(last_console);
2002
- break;
2003
- case 16: /* set cursor blink duration in msec */
2004
- if (vc->vc_npar >= 1 && vc->vc_par[1] >= 50 &&
2005
- vc->vc_par[1] <= USHRT_MAX)
2006
- vc->vc_cur_blink_ms = vc->vc_par[1];
2007
- else
2008
- vc->vc_cur_blink_ms = DEFAULT_CURSOR_BLINK_MS;
2009
- break;
1956
+ switch (vc->vc_par[0]) {
1957
+ case 1: /* set color for underline mode */
1958
+ if (vc->vc_can_do_color && vc->vc_par[1] < 16) {
1959
+ vc->vc_ulcolor = color_table[vc->vc_par[1]];
1960
+ if (vc->state.underline)
1961
+ update_attr(vc);
1962
+ }
1963
+ break;
1964
+ case 2: /* set color for half intensity mode */
1965
+ if (vc->vc_can_do_color && vc->vc_par[1] < 16) {
1966
+ vc->vc_halfcolor = color_table[vc->vc_par[1]];
1967
+ if (vc->state.intensity == VCI_HALF_BRIGHT)
1968
+ update_attr(vc);
1969
+ }
1970
+ break;
1971
+ case 8: /* store colors as defaults */
1972
+ vc->vc_def_color = vc->vc_attr;
1973
+ if (vc->vc_hi_font_mask == 0x100)
1974
+ vc->vc_def_color >>= 1;
1975
+ default_attr(vc);
1976
+ update_attr(vc);
1977
+ break;
1978
+ case 9: /* set blanking interval */
1979
+ blankinterval = min(vc->vc_par[1], 60U) * 60;
1980
+ poke_blanked_console();
1981
+ break;
1982
+ case 10: /* set bell frequency in Hz */
1983
+ if (vc->vc_npar >= 1)
1984
+ vc->vc_bell_pitch = vc->vc_par[1];
1985
+ else
1986
+ vc->vc_bell_pitch = DEFAULT_BELL_PITCH;
1987
+ break;
1988
+ case 11: /* set bell duration in msec */
1989
+ if (vc->vc_npar >= 1)
1990
+ vc->vc_bell_duration = (vc->vc_par[1] < 2000) ?
1991
+ msecs_to_jiffies(vc->vc_par[1]) : 0;
1992
+ else
1993
+ vc->vc_bell_duration = DEFAULT_BELL_DURATION;
1994
+ break;
1995
+ case 12: /* bring specified console to the front */
1996
+ if (vc->vc_par[1] >= 1 && vc_cons_allocated(vc->vc_par[1] - 1))
1997
+ set_console(vc->vc_par[1] - 1);
1998
+ break;
1999
+ case 13: /* unblank the screen */
2000
+ poke_blanked_console();
2001
+ break;
2002
+ case 14: /* set vesa powerdown interval */
2003
+ vesa_off_interval = min(vc->vc_par[1], 60U) * 60 * HZ;
2004
+ break;
2005
+ case 15: /* activate the previous console */
2006
+ set_console(last_console);
2007
+ break;
2008
+ case 16: /* set cursor blink duration in msec */
2009
+ if (vc->vc_npar >= 1 && vc->vc_par[1] >= 50 &&
2010
+ vc->vc_par[1] <= USHRT_MAX)
2011
+ vc->vc_cur_blink_ms = vc->vc_par[1];
2012
+ else
2013
+ vc->vc_cur_blink_ms = DEFAULT_CURSOR_BLINK_MS;
2014
+ break;
20102015 }
20112016 }
20122017
20132018 /* console_lock is held */
20142019 static void csi_at(struct vc_data *vc, unsigned int nr)
20152020 {
2016
- if (nr > vc->vc_cols - vc->vc_x)
2017
- nr = vc->vc_cols - vc->vc_x;
2021
+ if (nr > vc->vc_cols - vc->state.x)
2022
+ nr = vc->vc_cols - vc->state.x;
20182023 else if (!nr)
20192024 nr = 1;
20202025 insert_char(vc, nr);
....@@ -2023,19 +2028,19 @@
20232028 /* console_lock is held */
20242029 static void csi_L(struct vc_data *vc, unsigned int nr)
20252030 {
2026
- if (nr > vc->vc_rows - vc->vc_y)
2027
- nr = vc->vc_rows - vc->vc_y;
2031
+ if (nr > vc->vc_rows - vc->state.y)
2032
+ nr = vc->vc_rows - vc->state.y;
20282033 else if (!nr)
20292034 nr = 1;
2030
- con_scroll(vc, vc->vc_y, vc->vc_bottom, SM_DOWN, nr);
2035
+ con_scroll(vc, vc->state.y, vc->vc_bottom, SM_DOWN, nr);
20312036 vc->vc_need_wrap = 0;
20322037 }
20332038
20342039 /* console_lock is held */
20352040 static void csi_P(struct vc_data *vc, unsigned int nr)
20362041 {
2037
- if (nr > vc->vc_cols - vc->vc_x)
2038
- nr = vc->vc_cols - vc->vc_x;
2042
+ if (nr > vc->vc_cols - vc->state.x)
2043
+ nr = vc->vc_cols - vc->state.x;
20392044 else if (!nr)
20402045 nr = 1;
20412046 delete_char(vc, nr);
....@@ -2044,63 +2049,49 @@
20442049 /* console_lock is held */
20452050 static void csi_M(struct vc_data *vc, unsigned int nr)
20462051 {
2047
- if (nr > vc->vc_rows - vc->vc_y)
2048
- nr = vc->vc_rows - vc->vc_y;
2052
+ if (nr > vc->vc_rows - vc->state.y)
2053
+ nr = vc->vc_rows - vc->state.y;
20492054 else if (!nr)
20502055 nr=1;
2051
- con_scroll(vc, vc->vc_y, vc->vc_bottom, SM_UP, nr);
2056
+ con_scroll(vc, vc->state.y, vc->vc_bottom, SM_UP, nr);
20522057 vc->vc_need_wrap = 0;
20532058 }
20542059
20552060 /* console_lock is held (except via vc_init->reset_terminal */
20562061 static void save_cur(struct vc_data *vc)
20572062 {
2058
- vc->vc_saved_x = vc->vc_x;
2059
- vc->vc_saved_y = vc->vc_y;
2060
- vc->vc_s_intensity = vc->vc_intensity;
2061
- vc->vc_s_italic = vc->vc_italic;
2062
- vc->vc_s_underline = vc->vc_underline;
2063
- vc->vc_s_blink = vc->vc_blink;
2064
- vc->vc_s_reverse = vc->vc_reverse;
2065
- vc->vc_s_charset = vc->vc_charset;
2066
- vc->vc_s_color = vc->vc_color;
2067
- vc->vc_saved_G0 = vc->vc_G0_charset;
2068
- vc->vc_saved_G1 = vc->vc_G1_charset;
2063
+ memcpy(&vc->saved_state, &vc->state, sizeof(vc->state));
20692064 }
20702065
20712066 /* console_lock is held */
20722067 static void restore_cur(struct vc_data *vc)
20732068 {
2074
- gotoxy(vc, vc->vc_saved_x, vc->vc_saved_y);
2075
- vc->vc_intensity = vc->vc_s_intensity;
2076
- vc->vc_italic = vc->vc_s_italic;
2077
- vc->vc_underline = vc->vc_s_underline;
2078
- vc->vc_blink = vc->vc_s_blink;
2079
- vc->vc_reverse = vc->vc_s_reverse;
2080
- vc->vc_charset = vc->vc_s_charset;
2081
- vc->vc_color = vc->vc_s_color;
2082
- vc->vc_G0_charset = vc->vc_saved_G0;
2083
- vc->vc_G1_charset = vc->vc_saved_G1;
2084
- vc->vc_translate = set_translate(vc->vc_charset ? vc->vc_G1_charset : vc->vc_G0_charset, vc);
2069
+ memcpy(&vc->state, &vc->saved_state, sizeof(vc->state));
2070
+
2071
+ gotoxy(vc, vc->state.x, vc->state.y);
2072
+ vc->vc_translate = set_translate(vc->state.Gx_charset[vc->state.charset],
2073
+ vc);
20852074 update_attr(vc);
20862075 vc->vc_need_wrap = 0;
20872076 }
20882077
20892078 enum { ESnormal, ESesc, ESsquare, ESgetpars, ESfunckey,
2090
- EShash, ESsetG0, ESsetG1, ESpercent, ESignore, ESnonstd,
2091
- ESpalette, ESosc };
2079
+ EShash, ESsetG0, ESsetG1, ESpercent, EScsiignore, ESnonstd,
2080
+ ESpalette, ESosc, ESapc, ESpm, ESdcs };
20922081
20932082 /* console_lock is held (except via vc_init()) */
20942083 static void reset_terminal(struct vc_data *vc, int do_clear)
20952084 {
2085
+ unsigned int i;
2086
+
20962087 vc->vc_top = 0;
20972088 vc->vc_bottom = vc->vc_rows;
20982089 vc->vc_state = ESnormal;
2099
- vc->vc_ques = 0;
2090
+ vc->vc_priv = EPecma;
21002091 vc->vc_translate = set_translate(LAT1_MAP, vc);
2101
- vc->vc_G0_charset = LAT1_MAP;
2102
- vc->vc_G1_charset = GRAF_MAP;
2103
- vc->vc_charset = 0;
2092
+ vc->state.Gx_charset[0] = LAT1_MAP;
2093
+ vc->state.Gx_charset[1] = GRAF_MAP;
2094
+ vc->state.charset = 0;
21042095 vc->vc_need_wrap = 0;
21052096 vc->vc_report_mouse = 0;
21062097 vc->vc_utf = default_utf8;
....@@ -2123,14 +2114,9 @@
21232114 default_attr(vc);
21242115 update_attr(vc);
21252116
2126
- vc->vc_tab_stop[0] =
2127
- vc->vc_tab_stop[1] =
2128
- vc->vc_tab_stop[2] =
2129
- vc->vc_tab_stop[3] =
2130
- vc->vc_tab_stop[4] =
2131
- vc->vc_tab_stop[5] =
2132
- vc->vc_tab_stop[6] =
2133
- vc->vc_tab_stop[7] = 0x01010101;
2117
+ bitmap_zero(vc->vc_tab_stop, VC_TABSTOPS_COUNT);
2118
+ for (i = 0; i < VC_TABSTOPS_COUNT; i += 8)
2119
+ set_bit(i, vc->vc_tab_stop);
21342120
21352121 vc->vc_bell_pitch = DEFAULT_BELL_PITCH;
21362122 vc->vc_bell_duration = DEFAULT_BELL_DURATION;
....@@ -2142,20 +2128,51 @@
21422128 csi_J(vc, 2);
21432129 }
21442130
2131
+static void vc_setGx(struct vc_data *vc, unsigned int which, int c)
2132
+{
2133
+ unsigned char *charset = &vc->state.Gx_charset[which];
2134
+
2135
+ switch (c) {
2136
+ case '0':
2137
+ *charset = GRAF_MAP;
2138
+ break;
2139
+ case 'B':
2140
+ *charset = LAT1_MAP;
2141
+ break;
2142
+ case 'U':
2143
+ *charset = IBMPC_MAP;
2144
+ break;
2145
+ case 'K':
2146
+ *charset = USER_MAP;
2147
+ break;
2148
+ }
2149
+
2150
+ if (vc->state.charset == which)
2151
+ vc->vc_translate = set_translate(*charset, vc);
2152
+}
2153
+
2154
+/* is this state an ANSI control string? */
2155
+static bool ansi_control_string(unsigned int state)
2156
+{
2157
+ if (state == ESosc || state == ESapc || state == ESpm || state == ESdcs)
2158
+ return true;
2159
+ return false;
2160
+}
2161
+
21452162 /* console_lock is held */
21462163 static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
21472164 {
21482165 /*
21492166 * Control characters can be used in the _middle_
2150
- * of an escape sequence.
2167
+ * of an escape sequence, aside from ANSI control strings.
21512168 */
2152
- if (vc->vc_state == ESosc && c>=8 && c<=13) /* ... except for OSC */
2169
+ if (ansi_control_string(vc->vc_state) && c >= 8 && c <= 13)
21532170 return;
21542171 switch (c) {
21552172 case 0:
21562173 return;
21572174 case 7:
2158
- if (vc->vc_state == ESosc)
2175
+ if (ansi_control_string(vc->vc_state))
21592176 vc->vc_state = ESnormal;
21602177 else if (vc->vc_bell_duration)
21612178 kd_mksound(vc->vc_bell_pitch, vc->vc_bell_duration);
....@@ -2164,30 +2181,33 @@
21642181 bs(vc);
21652182 return;
21662183 case 9:
2167
- vc->vc_pos -= (vc->vc_x << 1);
2168
- while (vc->vc_x < vc->vc_cols - 1) {
2169
- vc->vc_x++;
2170
- if (vc->vc_tab_stop[7 & (vc->vc_x >> 5)] & (1 << (vc->vc_x & 31)))
2171
- break;
2172
- }
2173
- vc->vc_pos += (vc->vc_x << 1);
2184
+ vc->vc_pos -= (vc->state.x << 1);
2185
+
2186
+ vc->state.x = find_next_bit(vc->vc_tab_stop,
2187
+ min(vc->vc_cols - 1, VC_TABSTOPS_COUNT),
2188
+ vc->state.x + 1);
2189
+ if (vc->state.x >= VC_TABSTOPS_COUNT)
2190
+ vc->state.x = vc->vc_cols - 1;
2191
+
2192
+ vc->vc_pos += (vc->state.x << 1);
21742193 notify_write(vc, '\t');
21752194 return;
21762195 case 10: case 11: case 12:
21772196 lf(vc);
21782197 if (!is_kbd(vc, lnm))
21792198 return;
2199
+ fallthrough;
21802200 case 13:
21812201 cr(vc);
21822202 return;
21832203 case 14:
2184
- vc->vc_charset = 1;
2185
- vc->vc_translate = set_translate(vc->vc_G1_charset, vc);
2204
+ vc->state.charset = 1;
2205
+ vc->vc_translate = set_translate(vc->state.Gx_charset[1], vc);
21862206 vc->vc_disp_ctrl = 1;
21872207 return;
21882208 case 15:
2189
- vc->vc_charset = 0;
2190
- vc->vc_translate = set_translate(vc->vc_G0_charset, vc);
2209
+ vc->state.charset = 0;
2210
+ vc->vc_translate = set_translate(vc->state.Gx_charset[0], vc);
21912211 vc->vc_disp_ctrl = 0;
21922212 return;
21932213 case 24: case 26:
....@@ -2213,6 +2233,12 @@
22132233 case ']':
22142234 vc->vc_state = ESnonstd;
22152235 return;
2236
+ case '_':
2237
+ vc->vc_state = ESapc;
2238
+ return;
2239
+ case '^':
2240
+ vc->vc_state = ESpm;
2241
+ return;
22162242 case '%':
22172243 vc->vc_state = ESpercent;
22182244 return;
....@@ -2227,7 +2253,11 @@
22272253 lf(vc);
22282254 return;
22292255 case 'H':
2230
- vc->vc_tab_stop[7 & (vc->vc_x >> 5)] |= (1 << (vc->vc_x & 31));
2256
+ if (vc->state.x < VC_TABSTOPS_COUNT)
2257
+ set_bit(vc->state.x, vc->vc_tab_stop);
2258
+ return;
2259
+ case 'P':
2260
+ vc->vc_state = ESdcs;
22312261 return;
22322262 case 'Z':
22332263 respond_ID(tty);
....@@ -2299,9 +2329,22 @@
22992329 vc->vc_state=ESfunckey;
23002330 return;
23012331 }
2302
- vc->vc_ques = (c == '?');
2303
- if (vc->vc_ques)
2332
+ switch (c) {
2333
+ case '?':
2334
+ vc->vc_priv = EPdec;
23042335 return;
2336
+ case '>':
2337
+ vc->vc_priv = EPgt;
2338
+ return;
2339
+ case '=':
2340
+ vc->vc_priv = EPeq;
2341
+ return;
2342
+ case '<':
2343
+ vc->vc_priv = EPlt;
2344
+ return;
2345
+ }
2346
+ vc->vc_priv = EPecma;
2347
+ fallthrough;
23052348 case ESgetpars:
23062349 if (c == ';' && vc->vc_npar < NPAR - 1) {
23072350 vc->vc_npar++;
....@@ -2311,25 +2354,34 @@
23112354 vc->vc_par[vc->vc_npar] += c - '0';
23122355 return;
23132356 }
2357
+ if (c >= 0x20 && c <= 0x3f) { /* 0x2x, 0x3a and 0x3c - 0x3f */
2358
+ vc->vc_state = EScsiignore;
2359
+ return;
2360
+ }
23142361 vc->vc_state = ESnormal;
23152362 switch(c) {
23162363 case 'h':
2317
- set_mode(vc, 1);
2364
+ if (vc->vc_priv <= EPdec)
2365
+ set_mode(vc, 1);
23182366 return;
23192367 case 'l':
2320
- set_mode(vc, 0);
2368
+ if (vc->vc_priv <= EPdec)
2369
+ set_mode(vc, 0);
23212370 return;
23222371 case 'c':
2323
- if (vc->vc_ques) {
2372
+ if (vc->vc_priv == EPdec) {
23242373 if (vc->vc_par[0])
2325
- vc->vc_cursor_type = vc->vc_par[0] | (vc->vc_par[1] << 8) | (vc->vc_par[2] << 16);
2374
+ vc->vc_cursor_type =
2375
+ CUR_MAKE(vc->vc_par[0],
2376
+ vc->vc_par[1],
2377
+ vc->vc_par[2]);
23262378 else
23272379 vc->vc_cursor_type = cur_default;
23282380 return;
23292381 }
23302382 break;
23312383 case 'm':
2332
- if (vc->vc_ques) {
2384
+ if (vc->vc_priv == EPdec) {
23332385 clear_selection();
23342386 if (vc->vc_par[0])
23352387 vc->vc_complement_mask = vc->vc_par[0] << 8 | vc->vc_par[1];
....@@ -2339,7 +2391,7 @@
23392391 }
23402392 break;
23412393 case 'n':
2342
- if (!vc->vc_ques) {
2394
+ if (vc->vc_priv == EPecma) {
23432395 if (vc->vc_par[0] == 5)
23442396 status_report(tty);
23452397 else if (vc->vc_par[0] == 6)
....@@ -2347,50 +2399,50 @@
23472399 }
23482400 return;
23492401 }
2350
- if (vc->vc_ques) {
2351
- vc->vc_ques = 0;
2402
+ if (vc->vc_priv != EPecma) {
2403
+ vc->vc_priv = EPecma;
23522404 return;
23532405 }
23542406 switch(c) {
23552407 case 'G': case '`':
23562408 if (vc->vc_par[0])
23572409 vc->vc_par[0]--;
2358
- gotoxy(vc, vc->vc_par[0], vc->vc_y);
2410
+ gotoxy(vc, vc->vc_par[0], vc->state.y);
23592411 return;
23602412 case 'A':
23612413 if (!vc->vc_par[0])
23622414 vc->vc_par[0]++;
2363
- gotoxy(vc, vc->vc_x, vc->vc_y - vc->vc_par[0]);
2415
+ gotoxy(vc, vc->state.x, vc->state.y - vc->vc_par[0]);
23642416 return;
23652417 case 'B': case 'e':
23662418 if (!vc->vc_par[0])
23672419 vc->vc_par[0]++;
2368
- gotoxy(vc, vc->vc_x, vc->vc_y + vc->vc_par[0]);
2420
+ gotoxy(vc, vc->state.x, vc->state.y + vc->vc_par[0]);
23692421 return;
23702422 case 'C': case 'a':
23712423 if (!vc->vc_par[0])
23722424 vc->vc_par[0]++;
2373
- gotoxy(vc, vc->vc_x + vc->vc_par[0], vc->vc_y);
2425
+ gotoxy(vc, vc->state.x + vc->vc_par[0], vc->state.y);
23742426 return;
23752427 case 'D':
23762428 if (!vc->vc_par[0])
23772429 vc->vc_par[0]++;
2378
- gotoxy(vc, vc->vc_x - vc->vc_par[0], vc->vc_y);
2430
+ gotoxy(vc, vc->state.x - vc->vc_par[0], vc->state.y);
23792431 return;
23802432 case 'E':
23812433 if (!vc->vc_par[0])
23822434 vc->vc_par[0]++;
2383
- gotoxy(vc, 0, vc->vc_y + vc->vc_par[0]);
2435
+ gotoxy(vc, 0, vc->state.y + vc->vc_par[0]);
23842436 return;
23852437 case 'F':
23862438 if (!vc->vc_par[0])
23872439 vc->vc_par[0]++;
2388
- gotoxy(vc, 0, vc->vc_y - vc->vc_par[0]);
2440
+ gotoxy(vc, 0, vc->state.y - vc->vc_par[0]);
23892441 return;
23902442 case 'd':
23912443 if (vc->vc_par[0])
23922444 vc->vc_par[0]--;
2393
- gotoxay(vc, vc->vc_x ,vc->vc_par[0]);
2445
+ gotoxay(vc, vc->state.x ,vc->vc_par[0]);
23942446 return;
23952447 case 'H': case 'f':
23962448 if (vc->vc_par[0])
....@@ -2419,18 +2471,10 @@
24192471 respond_ID(tty);
24202472 return;
24212473 case 'g':
2422
- if (!vc->vc_par[0])
2423
- vc->vc_tab_stop[7 & (vc->vc_x >> 5)] &= ~(1 << (vc->vc_x & 31));
2424
- else if (vc->vc_par[0] == 3) {
2425
- vc->vc_tab_stop[0] =
2426
- vc->vc_tab_stop[1] =
2427
- vc->vc_tab_stop[2] =
2428
- vc->vc_tab_stop[3] =
2429
- vc->vc_tab_stop[4] =
2430
- vc->vc_tab_stop[5] =
2431
- vc->vc_tab_stop[6] =
2432
- vc->vc_tab_stop[7] = 0;
2433
- }
2474
+ if (!vc->vc_par[0] && vc->state.x < VC_TABSTOPS_COUNT)
2475
+ set_bit(vc->state.x, vc->vc_tab_stop);
2476
+ else if (vc->vc_par[0] == 3)
2477
+ bitmap_zero(vc->vc_tab_stop, VC_TABSTOPS_COUNT);
24342478 return;
24352479 case 'm':
24362480 csi_m(vc);
....@@ -2471,6 +2515,11 @@
24712515 return;
24722516 }
24732517 return;
2518
+ case EScsiignore:
2519
+ if (c >= 20 && c <= 0x3f)
2520
+ return;
2521
+ vc->vc_state = ESnormal;
2522
+ return;
24742523 case ESpercent:
24752524 vc->vc_state = ESnormal;
24762525 switch (c) {
....@@ -2499,32 +2548,20 @@
24992548 }
25002549 return;
25012550 case ESsetG0:
2502
- if (c == '0')
2503
- vc->vc_G0_charset = GRAF_MAP;
2504
- else if (c == 'B')
2505
- vc->vc_G0_charset = LAT1_MAP;
2506
- else if (c == 'U')
2507
- vc->vc_G0_charset = IBMPC_MAP;
2508
- else if (c == 'K')
2509
- vc->vc_G0_charset = USER_MAP;
2510
- if (vc->vc_charset == 0)
2511
- vc->vc_translate = set_translate(vc->vc_G0_charset, vc);
2551
+ vc_setGx(vc, 0, c);
25122552 vc->vc_state = ESnormal;
25132553 return;
25142554 case ESsetG1:
2515
- if (c == '0')
2516
- vc->vc_G1_charset = GRAF_MAP;
2517
- else if (c == 'B')
2518
- vc->vc_G1_charset = LAT1_MAP;
2519
- else if (c == 'U')
2520
- vc->vc_G1_charset = IBMPC_MAP;
2521
- else if (c == 'K')
2522
- vc->vc_G1_charset = USER_MAP;
2523
- if (vc->vc_charset == 1)
2524
- vc->vc_translate = set_translate(vc->vc_G1_charset, vc);
2555
+ vc_setGx(vc, 1, c);
25252556 vc->vc_state = ESnormal;
25262557 return;
2558
+ case ESapc:
2559
+ return;
25272560 case ESosc:
2561
+ return;
2562
+ case ESpm:
2563
+ return;
2564
+ case ESdcs:
25282565 return;
25292566 default:
25302567 vc->vc_state = ESnormal;
....@@ -2533,7 +2570,7 @@
25332570
25342571 /* is_double_width() is based on the wcwidth() implementation by
25352572 * Markus Kuhn -- 2007-05-26 (Unicode 5.0)
2536
- * Latest version: http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c
2573
+ * Latest version: https://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c
25372574 */
25382575 struct interval {
25392576 uint32_t first;
....@@ -2568,35 +2605,306 @@
25682605 sizeof(struct interval), ucs_cmp) != NULL;
25692606 }
25702607
2571
-static void con_flush(struct vc_data *vc, unsigned long draw_from,
2572
- unsigned long draw_to, int *draw_x)
2608
+struct vc_draw_region {
2609
+ unsigned long from, to;
2610
+ int x;
2611
+};
2612
+
2613
+static void con_flush(struct vc_data *vc, struct vc_draw_region *draw)
25732614 {
2574
- if (*draw_x < 0)
2615
+ if (draw->x < 0)
25752616 return;
25762617
2577
- vc->vc_sw->con_putcs(vc, (u16 *)draw_from,
2578
- (u16 *)draw_to - (u16 *)draw_from, vc->vc_y, *draw_x);
2579
- *draw_x = -1;
2618
+ vc->vc_sw->con_putcs(vc, (u16 *)draw->from,
2619
+ (u16 *)draw->to - (u16 *)draw->from, vc->state.y,
2620
+ draw->x);
2621
+ draw->x = -1;
2622
+}
2623
+
2624
+static inline int vc_translate_ascii(const struct vc_data *vc, int c)
2625
+{
2626
+ if (IS_ENABLED(CONFIG_CONSOLE_TRANSLATIONS)) {
2627
+ if (vc->vc_toggle_meta)
2628
+ c |= 0x80;
2629
+
2630
+ return vc->vc_translate[c];
2631
+ }
2632
+
2633
+ return c;
2634
+}
2635
+
2636
+
2637
+/**
2638
+ * vc_sanitize_unicode -- Replace invalid Unicode code points with U+FFFD
2639
+ * @c: the received character, or U+FFFD for invalid sequences.
2640
+ */
2641
+static inline int vc_sanitize_unicode(const int c)
2642
+{
2643
+ if ((c >= 0xd800 && c <= 0xdfff) || c == 0xfffe || c == 0xffff)
2644
+ return 0xfffd;
2645
+
2646
+ return c;
2647
+}
2648
+
2649
+/**
2650
+ * vc_translate_unicode -- Combine UTF-8 into Unicode in @vc_utf_char
2651
+ * @vc: virtual console
2652
+ * @c: character to translate
2653
+ * @rescan: we return true if we need more (continuation) data
2654
+ *
2655
+ * @vc_utf_char is the being-constructed unicode character.
2656
+ * @vc_utf_count is the number of continuation bytes still expected to arrive.
2657
+ * @vc_npar is the number of continuation bytes arrived so far.
2658
+ */
2659
+static int vc_translate_unicode(struct vc_data *vc, int c, bool *rescan)
2660
+{
2661
+ static const u32 utf8_length_changes[] = {
2662
+ 0x0000007f, 0x000007ff, 0x0000ffff,
2663
+ 0x001fffff, 0x03ffffff, 0x7fffffff
2664
+ };
2665
+
2666
+ /* Continuation byte received */
2667
+ if ((c & 0xc0) == 0x80) {
2668
+ /* Unexpected continuation byte? */
2669
+ if (!vc->vc_utf_count)
2670
+ return 0xfffd;
2671
+
2672
+ vc->vc_utf_char = (vc->vc_utf_char << 6) | (c & 0x3f);
2673
+ vc->vc_npar++;
2674
+ if (--vc->vc_utf_count)
2675
+ goto need_more_bytes;
2676
+
2677
+ /* Got a whole character */
2678
+ c = vc->vc_utf_char;
2679
+ /* Reject overlong sequences */
2680
+ if (c <= utf8_length_changes[vc->vc_npar - 1] ||
2681
+ c > utf8_length_changes[vc->vc_npar])
2682
+ return 0xfffd;
2683
+
2684
+ return vc_sanitize_unicode(c);
2685
+ }
2686
+
2687
+ /* Single ASCII byte or first byte of a sequence received */
2688
+ if (vc->vc_utf_count) {
2689
+ /* Continuation byte expected */
2690
+ *rescan = true;
2691
+ vc->vc_utf_count = 0;
2692
+ return 0xfffd;
2693
+ }
2694
+
2695
+ /* Nothing to do if an ASCII byte was received */
2696
+ if (c <= 0x7f)
2697
+ return c;
2698
+
2699
+ /* First byte of a multibyte sequence received */
2700
+ vc->vc_npar = 0;
2701
+ if ((c & 0xe0) == 0xc0) {
2702
+ vc->vc_utf_count = 1;
2703
+ vc->vc_utf_char = (c & 0x1f);
2704
+ } else if ((c & 0xf0) == 0xe0) {
2705
+ vc->vc_utf_count = 2;
2706
+ vc->vc_utf_char = (c & 0x0f);
2707
+ } else if ((c & 0xf8) == 0xf0) {
2708
+ vc->vc_utf_count = 3;
2709
+ vc->vc_utf_char = (c & 0x07);
2710
+ } else if ((c & 0xfc) == 0xf8) {
2711
+ vc->vc_utf_count = 4;
2712
+ vc->vc_utf_char = (c & 0x03);
2713
+ } else if ((c & 0xfe) == 0xfc) {
2714
+ vc->vc_utf_count = 5;
2715
+ vc->vc_utf_char = (c & 0x01);
2716
+ } else {
2717
+ /* 254 and 255 are invalid */
2718
+ return 0xfffd;
2719
+ }
2720
+
2721
+need_more_bytes:
2722
+ return -1;
2723
+}
2724
+
2725
+static int vc_translate(struct vc_data *vc, int *c, bool *rescan)
2726
+{
2727
+ /* Do no translation at all in control states */
2728
+ if (vc->vc_state != ESnormal)
2729
+ return *c;
2730
+
2731
+ if (vc->vc_utf && !vc->vc_disp_ctrl)
2732
+ return *c = vc_translate_unicode(vc, *c, rescan);
2733
+
2734
+ /* no utf or alternate charset mode */
2735
+ return vc_translate_ascii(vc, *c);
2736
+}
2737
+
2738
+static inline unsigned char vc_invert_attr(const struct vc_data *vc)
2739
+{
2740
+ if (!vc->vc_can_do_color)
2741
+ return vc->vc_attr ^ 0x08;
2742
+
2743
+ if (vc->vc_hi_font_mask == 0x100)
2744
+ return (vc->vc_attr & 0x11) |
2745
+ ((vc->vc_attr & 0xe0) >> 4) |
2746
+ ((vc->vc_attr & 0x0e) << 4);
2747
+
2748
+ return (vc->vc_attr & 0x88) |
2749
+ ((vc->vc_attr & 0x70) >> 4) |
2750
+ ((vc->vc_attr & 0x07) << 4);
2751
+}
2752
+
2753
+static bool vc_is_control(struct vc_data *vc, int tc, int c)
2754
+{
2755
+ /*
2756
+ * A bitmap for codes <32. A bit of 1 indicates that the code
2757
+ * corresponding to that bit number invokes some special action (such
2758
+ * as cursor movement) and should not be displayed as a glyph unless
2759
+ * the disp_ctrl mode is explicitly enabled.
2760
+ */
2761
+ static const u32 CTRL_ACTION = 0x0d00ff81;
2762
+ /* Cannot be overridden by disp_ctrl */
2763
+ static const u32 CTRL_ALWAYS = 0x0800f501;
2764
+
2765
+ if (vc->vc_state != ESnormal)
2766
+ return true;
2767
+
2768
+ if (!tc)
2769
+ return true;
2770
+
2771
+ /*
2772
+ * If the original code was a control character we only allow a glyph
2773
+ * to be displayed if the code is not normally used (such as for cursor
2774
+ * movement) or if the disp_ctrl mode has been explicitly enabled.
2775
+ * Certain characters (as given by the CTRL_ALWAYS bitmap) are always
2776
+ * displayed as control characters, as the console would be pretty
2777
+ * useless without them; to display an arbitrary font position use the
2778
+ * direct-to-font zone in UTF-8 mode.
2779
+ */
2780
+ if (c < 32) {
2781
+ if (vc->vc_disp_ctrl)
2782
+ return CTRL_ALWAYS & BIT(c);
2783
+ else
2784
+ return vc->vc_utf || (CTRL_ACTION & BIT(c));
2785
+ }
2786
+
2787
+ if (c == 127 && !vc->vc_disp_ctrl)
2788
+ return true;
2789
+
2790
+ if (c == 128 + 27)
2791
+ return true;
2792
+
2793
+ return false;
2794
+}
2795
+
2796
+static int vc_con_write_normal(struct vc_data *vc, int tc, int c,
2797
+ struct vc_draw_region *draw)
2798
+{
2799
+ int next_c;
2800
+ unsigned char vc_attr = vc->vc_attr;
2801
+ u16 himask = vc->vc_hi_font_mask, charmask = himask ? 0x1ff : 0xff;
2802
+ u8 width = 1;
2803
+ bool inverse = false;
2804
+
2805
+ if (vc->vc_utf && !vc->vc_disp_ctrl) {
2806
+ if (is_double_width(c))
2807
+ width = 2;
2808
+ }
2809
+
2810
+ /* Now try to find out how to display it */
2811
+ tc = conv_uni_to_pc(vc, tc);
2812
+ if (tc & ~charmask) {
2813
+ if (tc == -1 || tc == -2)
2814
+ return -1; /* nothing to display */
2815
+
2816
+ /* Glyph not found */
2817
+ if ((!vc->vc_utf || vc->vc_disp_ctrl || c < 128) &&
2818
+ !(c & ~charmask)) {
2819
+ /*
2820
+ * In legacy mode use the glyph we get by a 1:1
2821
+ * mapping.
2822
+ * This would make absolutely no sense with Unicode in
2823
+ * mind, but do this for ASCII characters since a font
2824
+ * may lack Unicode mapping info and we don't want to
2825
+ * end up with having question marks only.
2826
+ */
2827
+ tc = c;
2828
+ } else {
2829
+ /*
2830
+ * Display U+FFFD. If it's not found, display an inverse
2831
+ * question mark.
2832
+ */
2833
+ tc = conv_uni_to_pc(vc, 0xfffd);
2834
+ if (tc < 0) {
2835
+ inverse = true;
2836
+ tc = conv_uni_to_pc(vc, '?');
2837
+ if (tc < 0)
2838
+ tc = '?';
2839
+
2840
+ vc_attr = vc_invert_attr(vc);
2841
+ con_flush(vc, draw);
2842
+ }
2843
+ }
2844
+ }
2845
+
2846
+ next_c = c;
2847
+ while (1) {
2848
+ if (vc->vc_need_wrap || vc->vc_decim)
2849
+ con_flush(vc, draw);
2850
+ if (vc->vc_need_wrap) {
2851
+ cr(vc);
2852
+ lf(vc);
2853
+ }
2854
+ if (vc->vc_decim)
2855
+ insert_char(vc, 1);
2856
+ vc_uniscr_putc(vc, next_c);
2857
+
2858
+ if (himask)
2859
+ tc = ((tc & 0x100) ? himask : 0) |
2860
+ (tc & 0xff);
2861
+ tc |= (vc_attr << 8) & ~himask;
2862
+
2863
+ scr_writew(tc, (u16 *)vc->vc_pos);
2864
+
2865
+ if (con_should_update(vc) && draw->x < 0) {
2866
+ draw->x = vc->state.x;
2867
+ draw->from = vc->vc_pos;
2868
+ }
2869
+ if (vc->state.x == vc->vc_cols - 1) {
2870
+ vc->vc_need_wrap = vc->vc_decawm;
2871
+ draw->to = vc->vc_pos + 2;
2872
+ } else {
2873
+ vc->state.x++;
2874
+ draw->to = (vc->vc_pos += 2);
2875
+ }
2876
+
2877
+ if (!--width)
2878
+ break;
2879
+
2880
+ /* A space is printed in the second column */
2881
+ tc = conv_uni_to_pc(vc, ' ');
2882
+ if (tc < 0)
2883
+ tc = ' ';
2884
+ next_c = ' ';
2885
+ }
2886
+ notify_write(vc, c);
2887
+
2888
+ if (inverse)
2889
+ con_flush(vc, draw);
2890
+
2891
+ return 0;
25802892 }
25812893
25822894 /* acquires console_lock */
25832895 static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int count)
25842896 {
2585
- int c, next_c, tc, ok, n = 0, draw_x = -1;
2897
+ struct vc_draw_region draw = {
2898
+ .x = -1,
2899
+ };
2900
+ int c, tc, n = 0;
25862901 unsigned int currcons;
2587
- unsigned long draw_from = 0, draw_to = 0;
25882902 struct vc_data *vc;
2589
- unsigned char vc_attr;
25902903 struct vt_notifier_param param;
2591
- uint8_t rescan;
2592
- uint8_t inverse;
2593
- uint8_t width;
2594
- u16 himask, charmask;
2904
+ bool rescan;
25952905
25962906 if (in_interrupt())
25972907 return count;
2598
-
2599
- might_sleep();
26002908
26012909 console_lock();
26022910 vc = tty->driver_data;
....@@ -2614,8 +2922,6 @@
26142922 return 0;
26152923 }
26162924
2617
- himask = vc->vc_hi_font_mask;
2618
- charmask = himask ? 0x1ff : 0xff;
26192925
26202926 /* undraw cursor first */
26212927 if (con_is_fg(vc))
....@@ -2625,209 +2931,35 @@
26252931
26262932 while (!tty->stopped && count) {
26272933 int orig = *buf;
2628
- c = orig;
26292934 buf++;
26302935 n++;
26312936 count--;
2632
- rescan = 0;
2633
- inverse = 0;
2634
- width = 1;
2635
-
2636
- /* Do no translation at all in control states */
2637
- if (vc->vc_state != ESnormal) {
2638
- tc = c;
2639
- } else if (vc->vc_utf && !vc->vc_disp_ctrl) {
2640
- /* Combine UTF-8 into Unicode in vc_utf_char.
2641
- * vc_utf_count is the number of continuation bytes still
2642
- * expected to arrive.
2643
- * vc_npar is the number of continuation bytes arrived so
2644
- * far
2645
- */
26462937 rescan_last_byte:
2647
- if ((c & 0xc0) == 0x80) {
2648
- /* Continuation byte received */
2649
- static const uint32_t utf8_length_changes[] = { 0x0000007f, 0x000007ff, 0x0000ffff, 0x001fffff, 0x03ffffff, 0x7fffffff };
2650
- if (vc->vc_utf_count) {
2651
- vc->vc_utf_char = (vc->vc_utf_char << 6) | (c & 0x3f);
2652
- vc->vc_npar++;
2653
- if (--vc->vc_utf_count) {
2654
- /* Still need some bytes */
2655
- continue;
2656
- }
2657
- /* Got a whole character */
2658
- c = vc->vc_utf_char;
2659
- /* Reject overlong sequences */
2660
- if (c <= utf8_length_changes[vc->vc_npar - 1] ||
2661
- c > utf8_length_changes[vc->vc_npar])
2662
- c = 0xfffd;
2663
- } else {
2664
- /* Unexpected continuation byte */
2665
- vc->vc_utf_count = 0;
2666
- c = 0xfffd;
2667
- }
2668
- } else {
2669
- /* Single ASCII byte or first byte of a sequence received */
2670
- if (vc->vc_utf_count) {
2671
- /* Continuation byte expected */
2672
- rescan = 1;
2673
- vc->vc_utf_count = 0;
2674
- c = 0xfffd;
2675
- } else if (c > 0x7f) {
2676
- /* First byte of a multibyte sequence received */
2677
- vc->vc_npar = 0;
2678
- if ((c & 0xe0) == 0xc0) {
2679
- vc->vc_utf_count = 1;
2680
- vc->vc_utf_char = (c & 0x1f);
2681
- } else if ((c & 0xf0) == 0xe0) {
2682
- vc->vc_utf_count = 2;
2683
- vc->vc_utf_char = (c & 0x0f);
2684
- } else if ((c & 0xf8) == 0xf0) {
2685
- vc->vc_utf_count = 3;
2686
- vc->vc_utf_char = (c & 0x07);
2687
- } else if ((c & 0xfc) == 0xf8) {
2688
- vc->vc_utf_count = 4;
2689
- vc->vc_utf_char = (c & 0x03);
2690
- } else if ((c & 0xfe) == 0xfc) {
2691
- vc->vc_utf_count = 5;
2692
- vc->vc_utf_char = (c & 0x01);
2693
- } else {
2694
- /* 254 and 255 are invalid */
2695
- c = 0xfffd;
2696
- }
2697
- if (vc->vc_utf_count) {
2698
- /* Still need some bytes */
2699
- continue;
2700
- }
2701
- }
2702
- /* Nothing to do if an ASCII byte was received */
2703
- }
2704
- /* End of UTF-8 decoding. */
2705
- /* c is the received character, or U+FFFD for invalid sequences. */
2706
- /* Replace invalid Unicode code points with U+FFFD too */
2707
- if ((c >= 0xd800 && c <= 0xdfff) || c == 0xfffe || c == 0xffff)
2708
- c = 0xfffd;
2709
- tc = c;
2710
- } else { /* no utf or alternate charset mode */
2711
- tc = vc_translate(vc, c);
2712
- }
2938
+ c = orig;
2939
+ rescan = false;
2940
+
2941
+ tc = vc_translate(vc, &c, &rescan);
2942
+ if (tc == -1)
2943
+ continue;
27132944
27142945 param.c = tc;
27152946 if (atomic_notifier_call_chain(&vt_notifier_list, VT_PREWRITE,
27162947 &param) == NOTIFY_STOP)
27172948 continue;
27182949
2719
- /* If the original code was a control character we
2720
- * only allow a glyph to be displayed if the code is
2721
- * not normally used (such as for cursor movement) or
2722
- * if the disp_ctrl mode has been explicitly enabled.
2723
- * Certain characters (as given by the CTRL_ALWAYS
2724
- * bitmap) are always displayed as control characters,
2725
- * as the console would be pretty useless without
2726
- * them; to display an arbitrary font position use the
2727
- * direct-to-font zone in UTF-8 mode.
2728
- */
2729
- ok = tc && (c >= 32 ||
2730
- !(vc->vc_disp_ctrl ? (CTRL_ALWAYS >> c) & 1 :
2731
- vc->vc_utf || ((CTRL_ACTION >> c) & 1)))
2732
- && (c != 127 || vc->vc_disp_ctrl)
2733
- && (c != 128+27);
2734
-
2735
- if (vc->vc_state == ESnormal && ok) {
2736
- if (vc->vc_utf && !vc->vc_disp_ctrl) {
2737
- if (is_double_width(c))
2738
- width = 2;
2739
- }
2740
- /* Now try to find out how to display it */
2741
- tc = conv_uni_to_pc(vc, tc);
2742
- if (tc & ~charmask) {
2743
- if (tc == -1 || tc == -2) {
2744
- continue; /* nothing to display */
2745
- }
2746
- /* Glyph not found */
2747
- if ((!(vc->vc_utf && !vc->vc_disp_ctrl) || c < 128) && !(c & ~charmask)) {
2748
- /* In legacy mode use the glyph we get by a 1:1 mapping.
2749
- This would make absolutely no sense with Unicode in mind,
2750
- but do this for ASCII characters since a font may lack
2751
- Unicode mapping info and we don't want to end up with
2752
- having question marks only. */
2753
- tc = c;
2754
- } else {
2755
- /* Display U+FFFD. If it's not found, display an inverse question mark. */
2756
- tc = conv_uni_to_pc(vc, 0xfffd);
2757
- if (tc < 0) {
2758
- inverse = 1;
2759
- tc = conv_uni_to_pc(vc, '?');
2760
- if (tc < 0) tc = '?';
2761
- }
2762
- }
2763
- }
2764
-
2765
- if (!inverse) {
2766
- vc_attr = vc->vc_attr;
2767
- } else {
2768
- /* invert vc_attr */
2769
- if (!vc->vc_can_do_color) {
2770
- vc_attr = (vc->vc_attr) ^ 0x08;
2771
- } else if (vc->vc_hi_font_mask == 0x100) {
2772
- vc_attr = ((vc->vc_attr) & 0x11) | (((vc->vc_attr) & 0xe0) >> 4) | (((vc->vc_attr) & 0x0e) << 4);
2773
- } else {
2774
- vc_attr = ((vc->vc_attr) & 0x88) | (((vc->vc_attr) & 0x70) >> 4) | (((vc->vc_attr) & 0x07) << 4);
2775
- }
2776
- con_flush(vc, draw_from, draw_to, &draw_x);
2777
- }
2778
-
2779
- next_c = c;
2780
- while (1) {
2781
- if (vc->vc_need_wrap || vc->vc_decim)
2782
- con_flush(vc, draw_from, draw_to,
2783
- &draw_x);
2784
- if (vc->vc_need_wrap) {
2785
- cr(vc);
2786
- lf(vc);
2787
- }
2788
- if (vc->vc_decim)
2789
- insert_char(vc, 1);
2790
- vc_uniscr_putc(vc, next_c);
2791
- scr_writew(himask ?
2792
- ((vc_attr << 8) & ~himask) + ((tc & 0x100) ? himask : 0) + (tc & 0xff) :
2793
- (vc_attr << 8) + tc,
2794
- (u16 *) vc->vc_pos);
2795
- if (con_should_update(vc) && draw_x < 0) {
2796
- draw_x = vc->vc_x;
2797
- draw_from = vc->vc_pos;
2798
- }
2799
- if (vc->vc_x == vc->vc_cols - 1) {
2800
- vc->vc_need_wrap = vc->vc_decawm;
2801
- draw_to = vc->vc_pos + 2;
2802
- } else {
2803
- vc->vc_x++;
2804
- draw_to = (vc->vc_pos += 2);
2805
- }
2806
-
2807
- if (!--width) break;
2808
-
2809
- tc = conv_uni_to_pc(vc, ' '); /* A space is printed in the second column */
2810
- if (tc < 0) tc = ' ';
2811
- next_c = ' ';
2812
- }
2813
- notify_write(vc, c);
2814
-
2815
- if (inverse)
2816
- con_flush(vc, draw_from, draw_to, &draw_x);
2817
-
2818
- if (rescan) {
2819
- rescan = 0;
2820
- inverse = 0;
2821
- width = 1;
2822
- c = orig;
2823
- goto rescan_last_byte;
2824
- }
2950
+ if (vc_is_control(vc, tc, c)) {
2951
+ con_flush(vc, &draw);
2952
+ do_con_trol(tty, vc, orig);
28252953 continue;
28262954 }
2827
- con_flush(vc, draw_from, draw_to, &draw_x);
2828
- do_con_trol(tty, vc, orig);
2955
+
2956
+ if (vc_con_write_normal(vc, tc, c, &draw) < 0)
2957
+ continue;
2958
+
2959
+ if (rescan)
2960
+ goto rescan_last_byte;
28292961 }
2830
- con_flush(vc, draw_from, draw_to, &draw_x);
2962
+ con_flush(vc, &draw);
28312963 vc_uniscr_debug_check(vc);
28322964 console_conditional_schedule();
28332965 notify_update(vc);
....@@ -2969,7 +3101,7 @@
29693101 goto quit;
29703102 }
29713103
2972
- if (vc->vc_mode != KD_TEXT && !vt_force_oops_output(vc))
3104
+ if (vc->vc_mode != KD_TEXT)
29733105 goto quit;
29743106
29753107 /* undraw cursor first */
....@@ -2977,25 +3109,25 @@
29773109 hide_cursor(vc);
29783110
29793111 start = (ushort *)vc->vc_pos;
2980
- start_x = vc->vc_x;
3112
+ start_x = vc->state.x;
29813113 cnt = 0;
29823114 while (count--) {
29833115 c = *b++;
29843116 if (c == 10 || c == 13 || c == 8 || vc->vc_need_wrap) {
29853117 if (cnt && con_is_visible(vc))
2986
- vc->vc_sw->con_putcs(vc, start, cnt, vc->vc_y, start_x);
3118
+ vc->vc_sw->con_putcs(vc, start, cnt, vc->state.y, start_x);
29873119 cnt = 0;
29883120 if (c == 8) { /* backspace */
29893121 bs(vc);
29903122 start = (ushort *)vc->vc_pos;
2991
- start_x = vc->vc_x;
3123
+ start_x = vc->state.x;
29923124 continue;
29933125 }
29943126 if (c != 13)
29953127 lf(vc);
29963128 cr(vc);
29973129 start = (ushort *)vc->vc_pos;
2998
- start_x = vc->vc_x;
3130
+ start_x = vc->state.x;
29993131 if (c == 10 || c == 13)
30003132 continue;
30013133 }
....@@ -3003,15 +3135,15 @@
30033135 scr_writew((vc->vc_attr << 8) + c, (unsigned short *)vc->vc_pos);
30043136 notify_write(vc, c);
30053137 cnt++;
3006
- if (vc->vc_x == vc->vc_cols - 1) {
3138
+ if (vc->state.x == vc->vc_cols - 1) {
30073139 vc->vc_need_wrap = 1;
30083140 } else {
30093141 vc->vc_pos += 2;
3010
- vc->vc_x++;
3142
+ vc->state.x++;
30113143 }
30123144 }
30133145 if (cnt && con_is_visible(vc))
3014
- vc->vc_sw->con_putcs(vc, start, cnt, vc->vc_y, start_x);
3146
+ vc->vc_sw->con_putcs(vc, start, cnt, vc->state.y, start_x);
30153147 set_cursor(vc);
30163148 notify_update(vc);
30173149
....@@ -3047,7 +3179,7 @@
30473179 * There are some functions which can sleep for arbitrary periods
30483180 * (paste_selection) but we don't need the lock there anyway.
30493181 *
3050
- * set_selection has locking, and definitely needs it
3182
+ * set_selection_user has locking, and definitely needs it
30513183 */
30523184
30533185 int tioclinux(struct tty_struct *tty, unsigned long arg)
....@@ -3066,7 +3198,8 @@
30663198 switch (type)
30673199 {
30683200 case TIOCL_SETSEL:
3069
- ret = set_selection((struct tiocl_selection __user *)(p+1), tty);
3201
+ ret = set_selection_user((struct tiocl_selection
3202
+ __user *)(p+1), tty);
30703203 break;
30713204 case TIOCL_PASTESEL:
30723205 ret = paste_selection(tty);
....@@ -3362,8 +3495,9 @@
33623495
33633496 console_lock();
33643497
3365
- if (conswitchp)
3366
- display_desc = conswitchp->con_startup();
3498
+ if (!conswitchp)
3499
+ conswitchp = &dummy_con;
3500
+ display_desc = conswitchp->con_startup();
33673501 if (!display_desc) {
33683502 fg_console = 0;
33693503 console_unlock();
....@@ -3405,7 +3539,7 @@
34053539 master_display_fg = vc = vc_cons[currcons].d;
34063540 set_origin(vc);
34073541 save_screen(vc);
3408
- gotoxy(vc, vc->vc_x, vc->vc_y);
3542
+ gotoxy(vc, vc->state.x, vc->state.y);
34093543 csi_J(vc, 0);
34103544 update_screen(vc);
34113545 pr_info("Console: %s %s %dx%d\n",
....@@ -3605,7 +3739,6 @@
36053739
36063740
36073741 #ifdef CONFIG_VT_HW_CONSOLE_BINDING
3608
-/* unlocked version of unbind_con_driver() */
36093742 int do_unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
36103743 {
36113744 struct module *owner = csw->owner;
....@@ -3809,7 +3942,11 @@
38093942 char *buf)
38103943 {
38113944 struct con_driver *con = dev_get_drvdata(dev);
3812
- int bind = con_is_bound(con->con);
3945
+ int bind;
3946
+
3947
+ console_lock();
3948
+ bind = con_is_bound(con->con);
3949
+ console_unlock();
38133950
38143951 return snprintf(buf, PAGE_SIZE, "%i\n", bind);
38153952 }
....@@ -3860,6 +3997,8 @@
38603997 {
38613998 int i, bound = 0;
38623999
4000
+ WARN_CONSOLE_UNLOCKED();
4001
+
38634002 for (i = 0; i < MAX_NR_CONSOLES; i++) {
38644003 if (con_driver_map[i] == csw) {
38654004 bound = 1;
....@@ -3872,8 +4011,22 @@
38724011 EXPORT_SYMBOL(con_is_bound);
38734012
38744013 /**
4014
+ * con_is_visible - checks whether the current console is visible
4015
+ * @vc: virtual console
4016
+ *
4017
+ * RETURNS: zero if not visible, nonzero if visible
4018
+ */
4019
+bool con_is_visible(const struct vc_data *vc)
4020
+{
4021
+ WARN_CONSOLE_UNLOCKED();
4022
+
4023
+ return *vc->vc_display_fg == vc;
4024
+}
4025
+EXPORT_SYMBOL(con_is_visible);
4026
+
4027
+/**
38754028 * con_debug_enter - prepare the console for the kernel debugger
3876
- * @sw: console driver
4029
+ * @vc: virtual console
38774030 *
38784031 * Called when the console is taken over by the kernel debugger, this
38794032 * function needs to save the current console state, then put the console
....@@ -3931,7 +4084,6 @@
39314084
39324085 /**
39334086 * con_debug_leave - restore console state
3934
- * @sw: console driver
39354087 *
39364088 * Restore the console state to what it was before the kernel debugger
39374089 * was invoked.
....@@ -4113,7 +4265,7 @@
41134265 * when a driver wants to take over some existing consoles
41144266 * and become default driver for newly opened ones.
41154267 *
4116
- * do_take_over_console is basically a register followed by unbind
4268
+ * do_take_over_console is basically a register followed by bind
41174269 */
41184270 int do_take_over_console(const struct consw *csw, int first, int last, int deflt)
41194271 {
....@@ -4204,6 +4356,8 @@
42044356 struct vc_data *vc = vc_cons[fg_console].d;
42054357 int i;
42064358
4359
+ might_sleep();
4360
+
42074361 WARN_CONSOLE_UNLOCKED();
42084362
42094363 if (console_blanked) {
....@@ -4281,8 +4435,7 @@
42814435 return;
42824436 }
42834437 vc = vc_cons[fg_console].d;
4284
- /* Try to unblank in oops case too */
4285
- if (vc->vc_mode != KD_TEXT && !vt_force_oops_output(vc))
4438
+ if (vc->vc_mode != KD_TEXT)
42864439 return; /* but leave console_blanked != 0 */
42874440
42884441 if (blankinterval) {
....@@ -4291,7 +4444,7 @@
42914444 }
42924445
42934446 console_blanked = 0;
4294
- if (vc->vc_sw->con_blank(vc, 0, leaving_gfx) || vt_force_oops_output(vc))
4447
+ if (vc->vc_sw->con_blank(vc, 0, leaving_gfx))
42954448 /* Low-level driver cannot restore -> do it ourselves */
42964449 update_screen(vc);
42974450 if (console_blank_hook)
....@@ -4472,16 +4625,8 @@
44724625
44734626 if (op->data && font.charcount > op->charcount)
44744627 rc = -ENOSPC;
4475
- if (!(op->flags & KD_FONT_FLAG_OLD)) {
4476
- if (font.width > op->width || font.height > op->height)
4477
- rc = -ENOSPC;
4478
- } else {
4479
- if (font.width != 8)
4480
- rc = -EIO;
4481
- else if ((op->height && font.height > op->height) ||
4482
- font.height > 32)
4483
- rc = -ENOSPC;
4484
- }
4628
+ if (font.width > op->width || font.height > op->height)
4629
+ rc = -ENOSPC;
44854630 if (rc)
44864631 goto out;
44874632
....@@ -4509,7 +4654,7 @@
45094654 return -EINVAL;
45104655 if (op->charcount > 512)
45114656 return -EINVAL;
4512
- if (op->width <= 0 || op->width > 32 || op->height > 32)
4657
+ if (op->width <= 0 || op->width > 32 || !op->height || op->height > 32)
45134658 return -EINVAL;
45144659 size = (op->width+7)/8 * 32 * op->charcount;
45154660 if (size > max_font_size)
....@@ -4519,31 +4664,6 @@
45194664 if (IS_ERR(font.data))
45204665 return PTR_ERR(font.data);
45214666
4522
- if (!op->height) { /* Need to guess font height [compat] */
4523
- int h, i;
4524
- u8 *charmap = font.data;
4525
-
4526
- /*
4527
- * If from KDFONTOP ioctl, don't allow things which can be done
4528
- * in userland,so that we can get rid of this soon
4529
- */
4530
- if (!(op->flags & KD_FONT_FLAG_OLD)) {
4531
- kfree(font.data);
4532
- return -EINVAL;
4533
- }
4534
-
4535
- for (h = 32; h > 0; h--)
4536
- for (i = 0; i < op->charcount; i++)
4537
- if (charmap[32*i+h-1])
4538
- goto nonzero;
4539
-
4540
- kfree(font.data);
4541
- return -EINVAL;
4542
-
4543
- nonzero:
4544
- op->height = h;
4545
- }
4546
-
45474667 font.charcount = op->charcount;
45484668 font.width = op->width;
45494669 font.height = op->height;
....@@ -4551,9 +4671,11 @@
45514671 console_lock();
45524672 if (vc->vc_mode != KD_TEXT)
45534673 rc = -EINVAL;
4554
- else if (vc->vc_sw->con_font_set)
4674
+ else if (vc->vc_sw->con_font_set) {
4675
+ if (vc_is_sel(vc))
4676
+ clear_selection();
45554677 rc = vc->vc_sw->con_font_set(vc, &font, op->flags);
4556
- else
4678
+ } else
45574679 rc = -ENOSYS;
45584680 console_unlock();
45594681 kfree(font.data);
....@@ -4580,9 +4702,11 @@
45804702 console_unlock();
45814703 return -EINVAL;
45824704 }
4583
- if (vc->vc_sw->con_font_default)
4705
+ if (vc->vc_sw->con_font_default) {
4706
+ if (vc_is_sel(vc))
4707
+ clear_selection();
45844708 rc = vc->vc_sw->con_font_default(vc, &font, s);
4585
- else
4709
+ } else
45864710 rc = -ENOSYS;
45874711 console_unlock();
45884712 if (!rc) {
....@@ -4613,9 +4737,9 @@
46134737 */
46144738
46154739 /* used by selection */
4616
-u16 screen_glyph(struct vc_data *vc, int offset)
4740
+u16 screen_glyph(const struct vc_data *vc, int offset)
46174741 {
4618
- u16 w = scr_readw(screenpos(vc, offset, 1));
4742
+ u16 w = scr_readw(screenpos(vc, offset, true));
46194743 u16 c = w & 0xff;
46204744
46214745 if (w & vc->vc_hi_font_mask)
....@@ -4624,7 +4748,7 @@
46244748 }
46254749 EXPORT_SYMBOL_GPL(screen_glyph);
46264750
4627
-u32 screen_glyph_unicode(struct vc_data *vc, int n)
4751
+u32 screen_glyph_unicode(const struct vc_data *vc, int n)
46284752 {
46294753 struct uni_screen *uniscr = get_vc_uniscr(vc);
46304754
....@@ -4635,26 +4759,27 @@
46354759 EXPORT_SYMBOL_GPL(screen_glyph_unicode);
46364760
46374761 /* used by vcs - note the word offset */
4638
-unsigned short *screen_pos(struct vc_data *vc, int w_offset, int viewed)
4762
+unsigned short *screen_pos(const struct vc_data *vc, int w_offset, bool viewed)
46394763 {
46404764 return screenpos(vc, 2 * w_offset, viewed);
46414765 }
46424766 EXPORT_SYMBOL_GPL(screen_pos);
46434767
4644
-void getconsxy(struct vc_data *vc, unsigned char *p)
4768
+void getconsxy(const struct vc_data *vc, unsigned char xy[static 2])
46454769 {
4646
- p[0] = vc->vc_x;
4647
- p[1] = vc->vc_y;
4770
+ /* clamp values if they don't fit */
4771
+ xy[0] = min(vc->state.x, 0xFFu);
4772
+ xy[1] = min(vc->state.y, 0xFFu);
46484773 }
46494774
4650
-void putconsxy(struct vc_data *vc, unsigned char *p)
4775
+void putconsxy(struct vc_data *vc, unsigned char xy[static const 2])
46514776 {
46524777 hide_cursor(vc);
4653
- gotoxy(vc, p[0], p[1]);
4778
+ gotoxy(vc, xy[0], xy[1]);
46544779 set_cursor(vc);
46554780 }
46564781
4657
-u16 vcs_scr_readw(struct vc_data *vc, const u16 *org)
4782
+u16 vcs_scr_readw(const struct vc_data *vc, const u16 *org)
46584783 {
46594784 if ((unsigned long)org == vc->vc_pos && softcursor_original != -1)
46604785 return softcursor_original;