123 |
unsigned int bgcol_def; |
unsigned int bgcol_def; |
124 |
unsigned int fgcol_def; |
unsigned int fgcol_def; |
125 |
conchar_attr_t current; |
conchar_attr_t current; |
126 |
|
/* True if in alternate character set (ASCII graphic) mode. */ |
127 |
|
unsigned int altchar; |
128 |
}; |
}; |
129 |
typedef struct attr *attr_t; |
typedef struct attr *attr_t; |
130 |
|
|
298 |
} |
} |
299 |
|
|
300 |
/* Requires DISPLAY to be locked. */ |
/* Requires DISPLAY to be locked. */ |
301 |
void |
static void |
302 |
display_notice_filechange (display_t display, enum file_changed_type type, |
display_notice_filechange (display_t display, enum file_changed_type type, |
303 |
off_t start, off_t end) |
off_t start, off_t end) |
304 |
{ |
{ |
393 |
} |
} |
394 |
} |
} |
395 |
|
|
|
|
|
396 |
/* Record a change in the matrix ringbuffer. */ |
/* Record a change in the matrix ringbuffer. */ |
397 |
static void |
static void |
398 |
display_record_filechange (display_t display, off_t start, off_t end) |
display_record_filechange (display_t display, off_t start, off_t end) |
471 |
display->changes.end = end; |
display->changes.end = end; |
472 |
} |
} |
473 |
} |
} |
|
|
|
474 |
|
|
475 |
|
|
476 |
static void |
static void |
737 |
memset (&attr->current, 0, sizeof (conchar_attr_t)); |
memset (&attr->current, 0, sizeof (conchar_attr_t)); |
738 |
attr->current.fgcol = attr->fgcol_def; |
attr->current.fgcol = attr->fgcol_def; |
739 |
attr->current.bgcol = attr->bgcol_def; |
attr->current.bgcol = attr->bgcol_def; |
740 |
|
attr->altchar = 0; |
741 |
break; |
break; |
742 |
case 1: |
case 1: |
743 |
/* Bold on: <bold>. */ |
/* Bold on: <bold>. */ |
763 |
/* Concealed on: <invis>. */ |
/* Concealed on: <invis>. */ |
764 |
attr->current.concealed = 1; |
attr->current.concealed = 1; |
765 |
break; |
break; |
766 |
|
case 10: |
767 |
|
/* Alternate character set mode off: <rmacs>. */ |
768 |
|
attr->altchar = 0; |
769 |
|
break; |
770 |
|
case 11: |
771 |
|
/* Alternate character set mode on: <smacs>. */ |
772 |
|
attr->altchar = 1; |
773 |
|
break; |
774 |
case 22: |
case 22: |
775 |
/* Normal intensity. */ |
/* Normal intensity. */ |
776 |
attr->current.intensity = CONS_ATTR_INTENSITY_NORMAL; |
attr->current.intensity = CONS_ATTR_INTENSITY_NORMAL; |
810 |
} |
} |
811 |
} |
} |
812 |
|
|
813 |
|
static |
814 |
|
void limit_cursor (display_t display) |
815 |
|
{ |
816 |
|
struct cons_display *user = display->user; |
817 |
|
|
818 |
|
if (user->cursor.col >= user->screen.width) |
819 |
|
user->cursor.col = user->screen.width - 1; |
820 |
|
else if (user->cursor.col < 0) |
821 |
|
user->cursor.col = 0; |
822 |
|
|
823 |
|
if (user->cursor.row >= user->screen.height) |
824 |
|
user->cursor.row = user->screen.height - 1; |
825 |
|
else if (user->cursor.row < 0) |
826 |
|
user->cursor.row = 0; |
827 |
|
|
828 |
|
/* XXX Flag cursor change. */ |
829 |
|
} |
830 |
|
|
831 |
|
|
832 |
static void |
static void |
833 |
handle_esc_bracket (display_t display, char op) |
linefeed (display_t display) |
834 |
{ |
{ |
835 |
struct cons_display *user = display->user; |
struct cons_display *user = display->user; |
|
parse_t parse = &display->output.parse; |
|
|
int i; |
|
836 |
|
|
837 |
static void limit_cursor (void) |
if (user->cursor.row < user->screen.height - 1) |
838 |
{ |
{ |
839 |
if (user->cursor.col >= user->screen.width) |
user->cursor.row++; |
840 |
user->cursor.col = user->screen.width - 1; |
/* XXX Flag cursor update. */ |
841 |
else if (user->cursor.col < 0) |
} |
842 |
user->cursor.col = 0; |
else |
843 |
|
{ |
844 |
if (user->cursor.row >= user->screen.height) |
user->screen.cur_line++; |
845 |
user->cursor.row = user->screen.height - 1; |
user->screen.cur_line %= user->screen.lines; |
|
else if (user->cursor.row < 0) |
|
|
user->cursor.row = 0; |
|
846 |
|
|
847 |
/* XXX Flag cursor change. */ |
screen_fill (display, 0, user->screen.height - 1, |
848 |
|
user->screen.width - 1, user->screen.height - 1, |
849 |
|
L' ', display->attr.current); |
850 |
|
if (user->screen.scr_lines < |
851 |
|
user->screen.lines - user->screen.height) |
852 |
|
user->screen.scr_lines++; |
853 |
|
/* XXX Flag current line change. */ |
854 |
|
/* XXX Possibly flag change of length of scroll back buffer. */ |
855 |
} |
} |
856 |
|
} |
857 |
|
|
858 |
|
static void |
859 |
|
horizontal_tab (display_t display) |
860 |
|
{ |
861 |
|
struct cons_display *user = display->user; |
862 |
|
|
863 |
|
user->cursor.col = (user->cursor.col | 7) + 1; |
864 |
|
if (user->cursor.col >= user->screen.width) |
865 |
|
{ |
866 |
|
user->cursor.col = 0; |
867 |
|
linefeed (display); |
868 |
|
} |
869 |
|
/* XXX Flag cursor update. */ |
870 |
|
} |
871 |
|
|
872 |
|
static void |
873 |
|
handle_esc_bracket (display_t display, char op) |
874 |
|
{ |
875 |
|
struct cons_display *user = display->user; |
876 |
|
parse_t parse = &display->output.parse; |
877 |
|
int i; |
878 |
|
|
879 |
switch (op) |
switch (op) |
880 |
{ |
{ |
883 |
/* Cursor position: <cup>. */ |
/* Cursor position: <cup>. */ |
884 |
user->cursor.col = (parse->params[1] ?: 1) - 1; |
user->cursor.col = (parse->params[1] ?: 1) - 1; |
885 |
user->cursor.row = (parse->params[0] ?: 1) - 1; |
user->cursor.row = (parse->params[0] ?: 1) - 1; |
886 |
limit_cursor (); |
limit_cursor (display); |
887 |
break; |
break; |
888 |
case 'G': /* ECMA-48 <CHA>. */ |
case 'G': /* ECMA-48 <CHA>. */ |
889 |
case '`': /* ECMA-48 <HPA>. */ |
case '`': /* ECMA-48 <HPA>. */ |
890 |
|
case '\'': /* VT100. */ |
891 |
/* Horizontal cursor position: <hpa>. */ |
/* Horizontal cursor position: <hpa>. */ |
892 |
user->cursor.col = (parse->params[0] ?: 1) - 1; |
user->cursor.col = (parse->params[0] ?: 1) - 1; |
893 |
limit_cursor (); |
limit_cursor (display); |
894 |
|
break; |
895 |
|
case 'a': /* ECMA-48 <HPR>. */ |
896 |
|
/* Horizontal cursor position relative. */ |
897 |
|
user->cursor.col += (parse->params[1] ?: 1) - 1; |
898 |
|
limit_cursor (display); |
899 |
break; |
break; |
900 |
case 'd': /* ECMA-48 <VPA>. */ |
case 'd': /* ECMA-48 <VPA>. */ |
901 |
/* Vertical cursor position: <hpa>. */ |
/* Vertical cursor position: <vpa>. */ |
902 |
user->cursor.row = (parse->params[0] ?: 1) - 1; |
user->cursor.row = (parse->params[0] ?: 1) - 1; |
903 |
limit_cursor (); |
limit_cursor (display); |
904 |
break; |
break; |
905 |
case 'F': /* ECMA-48 <CPL>. */ |
case 'F': /* ECMA-48 <CPL>. */ |
906 |
/* Beginning of previous line. */ |
/* Beginning of previous line. */ |
910 |
case 'k': /* ECMA-48 <VPB>. */ |
case 'k': /* ECMA-48 <VPB>. */ |
911 |
/* Cursor up: <cuu>, <cuu1>. */ |
/* Cursor up: <cuu>, <cuu1>. */ |
912 |
user->cursor.row -= (parse->params[0] ?: 1); |
user->cursor.row -= (parse->params[0] ?: 1); |
913 |
limit_cursor (); |
limit_cursor (display); |
914 |
break; |
break; |
915 |
case 'E': /* ECMA-48 <CNL>. */ |
case 'E': /* ECMA-48 <CNL>. */ |
916 |
/* Beginning of next line. */ |
/* Beginning of next line. */ |
920 |
case 'e': /* ECMA-48 <VPR>. */ |
case 'e': /* ECMA-48 <VPR>. */ |
921 |
/* Cursor down: <cud1>, <cud>. */ |
/* Cursor down: <cud1>, <cud>. */ |
922 |
user->cursor.row += (parse->params[0] ?: 1); |
user->cursor.row += (parse->params[0] ?: 1); |
923 |
limit_cursor (); |
limit_cursor (display); |
924 |
break; |
break; |
925 |
case 'C': /* ECMA-48 <CUF>. */ |
case 'C': /* ECMA-48 <CUF>. */ |
926 |
/* Cursor right: <cuf1>, <cuf>. */ |
/* Cursor right: <cuf1>, <cuf>. */ |
927 |
user->cursor.col += (parse->params[0] ?: 1); |
user->cursor.col += (parse->params[0] ?: 1); |
928 |
limit_cursor (); |
limit_cursor (display); |
929 |
break; |
break; |
930 |
case 'D': /* ECMA-48 <CUB>. */ |
case 'D': /* ECMA-48 <CUB>. */ |
931 |
/* Cursor left: <cub>, <cub1>. */ |
/* Cursor left: <cub>, <cub1>. */ |
932 |
user->cursor.col -= (parse->params[0] ?: 1); |
user->cursor.col -= (parse->params[0] ?: 1); |
933 |
limit_cursor (); |
limit_cursor (display); |
|
break; |
|
|
case 's': |
|
|
/* Save cursor position: <sc>. */ |
|
|
display->cursor.saved_x = user->cursor.col; |
|
|
display->cursor.saved_y = user->cursor.row; |
|
|
break; |
|
|
case 'u': |
|
|
/* Restore cursor position: <rc>. */ |
|
|
user->cursor.col = display->cursor.saved_x; |
|
|
user->cursor.row = display->cursor.saved_y; |
|
|
/* In case the screen was larger before: */ |
|
|
limit_cursor (); |
|
934 |
break; |
break; |
935 |
case 'h': |
case 'h': |
936 |
/* Reset mode. */ |
/* Reset mode. */ |
942 |
for (i = 0; i < parse->nparams; i++) |
for (i = 0; i < parse->nparams; i++) |
943 |
handle_esc_bracket_hl (display, parse->params[i], 1); |
handle_esc_bracket_hl (display, parse->params[i], 1); |
944 |
break; |
break; |
945 |
case 'm': /* ECME-48 <SGR>. */ |
case 'm': /* ECMA-48 <SGR>. */ |
946 |
for (i = 0; i < parse->nparams; i++) |
for (i = 0; i < parse->nparams; i++) |
947 |
handle_esc_bracket_m (&display->attr, parse->params[i]); |
handle_esc_bracket_m (&display->attr, parse->params[i]); |
948 |
break; |
break; |
949 |
case 'J': /* ECME-48 <ED>. */ |
case 'J': /* ECMA-48 <ED>. */ |
950 |
switch (parse->params[0]) |
switch (parse->params[0]) |
951 |
{ |
{ |
952 |
case 0: |
case 0: |
969 |
break; |
break; |
970 |
} |
} |
971 |
break; |
break; |
972 |
case 'K': /* ECME-48 <EL>. */ |
case 'K': /* ECMA-48 <EL>. */ |
973 |
switch (parse->params[0]) |
switch (parse->params[0]) |
974 |
{ |
{ |
975 |
case 0: |
case 0: |
992 |
break; |
break; |
993 |
} |
} |
994 |
break; |
break; |
995 |
case 'L': /* ECME-48 <IL>. */ |
case 'L': /* ECMA-48 <IL>. */ |
996 |
/* Insert line(s): <il1>, <il>. */ |
/* Insert line(s): <il1>, <il>. */ |
997 |
screen_shift_right (display, 0, user->cursor.row, |
screen_shift_right (display, 0, user->cursor.row, |
998 |
user->screen.width - 1, user->screen.height - 1, |
user->screen.width - 1, user->screen.height - 1, |
999 |
(parse->params[0] ?: 1) * user->screen.width, |
(parse->params[0] ?: 1) * user->screen.width, |
1000 |
L' ', display->attr.current); |
L' ', display->attr.current); |
1001 |
break; |
break; |
1002 |
case 'M': /* ECME-48 <DL>. */ |
case 'M': /* ECMA-48 <DL>. */ |
1003 |
/* Delete line(s): <dl1>, <dl>. */ |
/* Delete line(s): <dl1>, <dl>. */ |
1004 |
screen_shift_left (display, 0, user->cursor.row, |
screen_shift_left (display, 0, user->cursor.row, |
1005 |
user->screen.width - 1, user->screen.height - 1, |
user->screen.width - 1, user->screen.height - 1, |
1006 |
(parse->params[0] ?: 1) * user->screen.width, |
(parse->params[0] ?: 1) * user->screen.width, |
1007 |
L' ', display->attr.current); |
L' ', display->attr.current); |
1008 |
break; |
break; |
1009 |
case '@': /* ECME-48 <ICH>. */ |
case '@': /* ECMA-48 <ICH>. */ |
1010 |
/* Insert character(s): <ich1>, <ich>. */ |
/* Insert character(s): <ich1>, <ich>. */ |
1011 |
screen_shift_right (display, user->cursor.col, user->cursor.row, |
screen_shift_right (display, user->cursor.col, user->cursor.row, |
1012 |
user->screen.width - 1, user->cursor.row, |
user->screen.width - 1, user->cursor.row, |
1013 |
parse->params[0] ?: 1, |
parse->params[0] ?: 1, |
1014 |
L' ', display->attr.current); |
L' ', display->attr.current); |
1015 |
break; |
break; |
1016 |
case 'P': /* ECME-48 <DCH>. */ |
case 'P': /* ECMA-48 <DCH>. */ |
1017 |
/* Delete character(s): <dch1>, <dch>. */ |
/* Delete character(s): <dch1>, <dch>. */ |
1018 |
screen_shift_left (display, user->cursor.col, user->cursor.row, |
screen_shift_left (display, user->cursor.col, user->cursor.row, |
1019 |
user->screen.width - 1, user->cursor.row, |
user->screen.width - 1, user->cursor.row, |
1020 |
parse->params[0] ?: 1, |
parse->params[0] ?: 1, |
1021 |
L' ', display->attr.current); |
L' ', display->attr.current); |
1022 |
break; |
break; |
1023 |
case 'S': /* ECME-48 <SU>. */ |
case 'S': /* ECMA-48 <SU>. */ |
1024 |
/* Scroll up: <ind>, <indn>. */ |
/* Scroll up: <ind>, <indn>. */ |
1025 |
screen_shift_left (display, 0, 0, |
screen_shift_left (display, 0, 0, |
1026 |
user->screen.width - 1, user->screen.height - 1, |
user->screen.width - 1, user->screen.height - 1, |
1027 |
(parse->params[0] ?: 1) * user->screen.width, |
(parse->params[0] ?: 1) * user->screen.width, |
1028 |
L' ', display->attr.current); |
L' ', display->attr.current); |
1029 |
break; |
break; |
1030 |
case 'T': /* ECME-48 <SD>. */ |
case 'T': /* ECMA-48 <SD>. */ |
1031 |
/* Scroll down: <ri>, <rin>. */ |
/* Scroll down: <ri>, <rin>. */ |
1032 |
screen_shift_right (display, 0, 0, |
screen_shift_right (display, 0, 0, |
1033 |
user->screen.width, user->screen.height, |
user->screen.width, user->screen.height, |
1034 |
(parse->params[0] ?: 1) * user->screen.width, |
(parse->params[0] ?: 1) * user->screen.width, |
1035 |
L' ', display->attr.current); |
L' ', display->attr.current); |
1036 |
break; |
break; |
1037 |
case 'X': /* ECME-48 <ECH>. */ |
case 'X': /* ECMA-48 <ECH>. */ |
1038 |
/* Erase character(s): <ech>. */ |
/* Erase character(s): <ech>. */ |
1039 |
screen_fill (display, user->cursor.col, user->cursor.row, |
screen_fill (display, user->cursor.col, user->cursor.row, |
1040 |
/* XXX limit ? */user->cursor.col + (parse->params[0] ?: 1), |
/* XXX limit ? */user->cursor.col + (parse->params[0] ?: 1), |
1041 |
user->cursor.row, |
user->cursor.row, |
1042 |
L' ', display->attr.current); |
L' ', display->attr.current); |
1043 |
break; |
break; |
1044 |
|
case 'I': /* ECMA-48 <CHT>. */ |
1045 |
|
/* Horizontal tab. */ |
1046 |
|
if (!parse->params[0]) |
1047 |
|
parse->params[0] = 1; |
1048 |
|
while (parse->params[0]--) |
1049 |
|
horizontal_tab (display); |
1050 |
|
break; |
1051 |
|
case 'Z': /* ECMA-48 <CBT>. */ |
1052 |
|
/* Cursor backward tabulation: <cbt>. */ |
1053 |
|
if (parse->params[0] > user->screen.height * (user->screen.width / 8)) |
1054 |
|
{ |
1055 |
|
user->cursor.col = 0; |
1056 |
|
user->cursor.row = 0; |
1057 |
|
} |
1058 |
|
else |
1059 |
|
{ |
1060 |
|
int i = parse->params[0] ?: 1; |
1061 |
|
|
1062 |
|
while (i--) |
1063 |
|
{ |
1064 |
|
if (user->cursor.col == 0) |
1065 |
|
{ |
1066 |
|
if (user->cursor.row == 0) |
1067 |
|
break; |
1068 |
|
else |
1069 |
|
{ |
1070 |
|
user->cursor.col = user->screen.width - 1; |
1071 |
|
user->cursor.row--; |
1072 |
|
} |
1073 |
|
} |
1074 |
|
else |
1075 |
|
user->cursor.col--; |
1076 |
|
user->cursor.col &= ~7; |
1077 |
|
} |
1078 |
|
} |
1079 |
} |
} |
1080 |
} |
} |
1081 |
|
|
1117 |
} |
} |
1118 |
} |
} |
1119 |
|
|
1120 |
|
static wchar_t |
1121 |
|
altchar_to_ucs4 (wchar_t chr) |
1122 |
|
{ |
1123 |
|
/* Alternative character set frobbing. */ |
1124 |
|
switch (chr) |
1125 |
|
{ |
1126 |
|
case L'+': |
1127 |
|
return CONS_CHAR_RARROW; |
1128 |
|
case L',': |
1129 |
|
return CONS_CHAR_LARROW; |
1130 |
|
case L'-': |
1131 |
|
return CONS_CHAR_UARROW; |
1132 |
|
case L'.': |
1133 |
|
return CONS_CHAR_DARROW; |
1134 |
|
case L'0': |
1135 |
|
return CONS_CHAR_BLOCK; |
1136 |
|
case L'I': |
1137 |
|
return CONS_CHAR_LANTERN; |
1138 |
|
case L'`': |
1139 |
|
return CONS_CHAR_DIAMOND; |
1140 |
|
case L'a': |
1141 |
|
return CONS_CHAR_CKBOARD; |
1142 |
|
case L'f': |
1143 |
|
return CONS_CHAR_DEGREE; |
1144 |
|
case L'g': |
1145 |
|
return CONS_CHAR_PLMINUS; |
1146 |
|
case L'h': |
1147 |
|
return CONS_CHAR_BOARD; |
1148 |
|
case L'j': |
1149 |
|
return CONS_CHAR_LRCORNER; |
1150 |
|
case L'k': |
1151 |
|
return CONS_CHAR_URCORNER; |
1152 |
|
case L'l': |
1153 |
|
return CONS_CHAR_ULCORNER; |
1154 |
|
case L'm': |
1155 |
|
return CONS_CHAR_LLCORNER; |
1156 |
|
case L'n': |
1157 |
|
return CONS_CHAR_PLUS; |
1158 |
|
case L'o': |
1159 |
|
return CONS_CHAR_S1; |
1160 |
|
case L'p': |
1161 |
|
return CONS_CHAR_S3; |
1162 |
|
case L'q': |
1163 |
|
return CONS_CHAR_HLINE; |
1164 |
|
case L'r': |
1165 |
|
return CONS_CHAR_S7; |
1166 |
|
case L's': |
1167 |
|
return CONS_CHAR_S9; |
1168 |
|
case L't': |
1169 |
|
return CONS_CHAR_LTEE; |
1170 |
|
case L'u': |
1171 |
|
return CONS_CHAR_RTEE; |
1172 |
|
case L'v': |
1173 |
|
return CONS_CHAR_BTEE; |
1174 |
|
case L'w': |
1175 |
|
return CONS_CHAR_TTEE; |
1176 |
|
case L'x': |
1177 |
|
return CONS_CHAR_VLINE; |
1178 |
|
case L'y': |
1179 |
|
return CONS_CHAR_LEQUAL; |
1180 |
|
case L'z': |
1181 |
|
return CONS_CHAR_GEQUAL; |
1182 |
|
case L'{': |
1183 |
|
return CONS_CHAR_PI; |
1184 |
|
case L'|': |
1185 |
|
return CONS_CHAR_NEQUAL; |
1186 |
|
case L'}': |
1187 |
|
return CONS_CHAR_STERLING; |
1188 |
|
case L'~': |
1189 |
|
return CONS_CHAR_BULLET; |
1190 |
|
default: |
1191 |
|
return chr; |
1192 |
|
} |
1193 |
|
} |
1194 |
|
|
1195 |
/* Display must be locked. */ |
/* Display must be locked. */ |
1196 |
static void |
static void |
1197 |
display_output_one (display_t display, wchar_t chr) |
display_output_one (display_t display, wchar_t chr) |
1199 |
struct cons_display *user = display->user; |
struct cons_display *user = display->user; |
1200 |
parse_t parse = &display->output.parse; |
parse_t parse = &display->output.parse; |
1201 |
|
|
|
void linefeed (void) |
|
|
{ |
|
|
if (user->cursor.row < user->screen.height - 1) |
|
|
{ |
|
|
user->cursor.row++; |
|
|
/* XXX Flag cursor update. */ |
|
|
} |
|
|
else |
|
|
{ |
|
|
user->screen.cur_line++; |
|
|
user->screen.cur_line %= user->screen.lines; |
|
|
|
|
|
screen_fill (display, 0, user->screen.height - 1, |
|
|
user->screen.width - 1, user->screen.height - 1, |
|
|
L' ', display->attr.current); |
|
|
if (user->screen.scr_lines < |
|
|
user->screen.lines - user->screen.height) |
|
|
user->screen.scr_lines++; |
|
|
/* XXX Flag current line change. */ |
|
|
/* XXX Possibly flag change of length of scroll back buffer. */ |
|
|
} |
|
|
} |
|
|
|
|
1202 |
switch (parse->state) |
switch (parse->state) |
1203 |
{ |
{ |
1204 |
case STATE_NORMAL: |
case STATE_NORMAL: |
1214 |
break; |
break; |
1215 |
case L'\n': |
case L'\n': |
1216 |
/* Line feed. */ |
/* Line feed. */ |
1217 |
linefeed (); |
linefeed (display); |
1218 |
break; |
break; |
1219 |
case L'\b': |
case L'\b': |
1220 |
/* Backspace. */ |
/* Backspace. */ |
1234 |
break; |
break; |
1235 |
case L'\t': |
case L'\t': |
1236 |
/* Horizontal tab: <ht> */ |
/* Horizontal tab: <ht> */ |
1237 |
user->cursor.col = (user->cursor.col | 7) + 1; |
horizontal_tab (display); |
|
if (user->cursor.col >= user->screen.width) |
|
|
{ |
|
|
user->cursor.col = 0; |
|
|
linefeed (); |
|
|
} |
|
|
/* XXX Flag cursor update. */ |
|
1238 |
break; |
break; |
1239 |
case L'\033': |
case L'\033': |
1240 |
parse->state = STATE_ESC; |
parse->state = STATE_ESC; |
1247 |
int line = (user->screen.cur_line + user->cursor.row) |
int line = (user->screen.cur_line + user->cursor.row) |
1248 |
% user->screen.lines; |
% user->screen.lines; |
1249 |
int idx = line * user->screen.width + user->cursor.col; |
int idx = line * user->screen.width + user->cursor.col; |
1250 |
user->_matrix[idx].chr = chr; |
|
1251 |
|
user->_matrix[idx].chr = display->attr.altchar |
1252 |
|
? altchar_to_ucs4 (chr) : chr; |
1253 |
user->_matrix[idx].attr = display->attr.current; |
user->_matrix[idx].attr = display->attr.current; |
1254 |
|
|
1255 |
display_record_filechange (display, idx, idx); |
display_record_filechange (display, idx, idx); |
1257 |
if (user->cursor.col == user->screen.width) |
if (user->cursor.col == user->screen.width) |
1258 |
{ |
{ |
1259 |
user->cursor.col = 0; |
user->cursor.col = 0; |
1260 |
linefeed (); |
linefeed (display); |
1261 |
} |
} |
1262 |
} |
} |
1263 |
break; |
break; |
1270 |
case L'[': |
case L'[': |
1271 |
parse->state = STATE_ESC_BRACKET_INIT; |
parse->state = STATE_ESC_BRACKET_INIT; |
1272 |
break; |
break; |
1273 |
|
case L'M': /* ECMA-48 <RIS>. */ |
1274 |
|
/* Reset: <rs2>. */ |
1275 |
|
* (uint32_t *) &display->attr.current = 0; |
1276 |
|
display->attr.current.bgcol = display->attr.bgcol_def; |
1277 |
|
display->attr.current.fgcol = display->attr.fgcol_def; |
1278 |
|
display->attr.altchar = 0; |
1279 |
|
/* Fall through. */ |
1280 |
case L'c': |
case L'c': |
1281 |
/* Clear screen and home cursor: <clear>. */ |
/* Clear screen and home cursor: <clear>. */ |
1282 |
screen_fill (display, 0, 0, |
screen_fill (display, 0, 0, |
1289 |
case L'E': /* ECMA-48 <NEL>. */ |
case L'E': /* ECMA-48 <NEL>. */ |
1290 |
/* Newline. */ |
/* Newline. */ |
1291 |
user->cursor.col = 0; |
user->cursor.col = 0; |
1292 |
linefeed (); |
linefeed (display); |
1293 |
|
break; |
1294 |
|
case L'7': /* VT100: Save cursor and attributes. */ |
1295 |
|
/* Save cursor position: <sc>. */ |
1296 |
|
display->cursor.saved_x = user->cursor.col; |
1297 |
|
display->cursor.saved_y = user->cursor.row; |
1298 |
|
break; |
1299 |
|
case L'8': /* VT100: Restore cursor and attributes. */ |
1300 |
|
/* Restore cursor position: <rc>. */ |
1301 |
|
user->cursor.col = display->cursor.saved_x; |
1302 |
|
user->cursor.row = display->cursor.saved_y; |
1303 |
|
/* In case the screen was larger before: */ |
1304 |
|
limit_cursor (display); |
1305 |
break; |
break; |
1306 |
default: |
default: |
1307 |
/* Unsupported escape sequence. */ |
/* Unsupported escape sequence. */ |
1393 |
display_flush_filechange (display, ~0); |
display_flush_filechange (display, ~0); |
1394 |
return err; |
return err; |
1395 |
} |
} |
1396 |
|
|
1397 |
|
|
1398 |
void |
void |
1399 |
display_init (void) |
display_init (void) |
1408 |
(any_t)pager_bucket)); |
(any_t)pager_bucket)); |
1409 |
} |
} |
1410 |
|
|
1411 |
|
|
1412 |
/* Create a new virtual console display, with the system encoding |
/* Create a new virtual console display, with the system encoding |
1413 |
being ENCODING. */ |
being ENCODING. */ |
1414 |
error_t |
error_t |