1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright (C) 2014 David Herrmann <dh.herrmann@gmail.com>
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
30 typedef struct term_char term_char_t;
31 typedef struct term_charbuf term_charbuf_t;
33 typedef struct term_cell term_cell;
34 typedef struct term_line term_line;
36 typedef struct term_page term_page;
37 typedef struct term_history term_history;
39 typedef uint32_t term_charset[96];
43 * Sundry things and external helpers.
46 int mk_wcwidth(wchar_t ucs4);
47 int mk_wcwidth_cjk(wchar_t ucs4);
48 int mk_wcswidth(const wchar_t *str, size_t len);
49 int mk_wcswidth_cjk(const wchar_t *str, size_t len);
53 * Each cell in a terminal page contains only a single character. This is
54 * usually a single UCS-4 value. However, Unicode allows combining-characters,
55 * therefore, the number of UCS-4 characters per cell must be unlimited. The
56 * term_char_t object wraps the internal combining char API so it can be
57 * treated as a single object.
61 /* never access this value directly */
66 /* 3 bytes + zero-terminator */
70 #define TERM_CHAR_INIT(_val) ((term_char_t){ ._value = (_val) })
71 #define TERM_CHAR_NULL TERM_CHAR_INIT(0)
73 term_char_t term_char_set(term_char_t previous, uint32_t append_ucs4);
74 term_char_t term_char_merge(term_char_t base, uint32_t append_ucs4);
75 term_char_t term_char_dup(term_char_t ch);
76 term_char_t term_char_dup_append(term_char_t base, uint32_t append_ucs4);
78 const uint32_t *term_char_resolve(term_char_t ch, size_t *s, term_charbuf_t *b);
79 unsigned int term_char_lookup_width(term_char_t ch);
81 /* true if @ch is TERM_CHAR_NULL, otherwise false */
82 static inline bool term_char_is_null(term_char_t ch) {
83 return ch._value == 0;
86 /* true if @ch is dynamically allocated and needs to be freed */
87 static inline bool term_char_is_allocated(term_char_t ch) {
88 return !term_char_is_null(ch) && !(ch._value & 0x1);
91 /* true if (a == b), otherwise false; this is (a == b), NOT (*a == *b) */
92 static inline bool term_char_same(term_char_t a, term_char_t b) {
93 return a._value == b._value;
96 /* true if (*a == *b), otherwise false; this is implied by (a == b) */
97 static inline bool term_char_equal(term_char_t a, term_char_t b) {
98 const uint32_t *sa, *sb;
99 term_charbuf_t ca, cb;
102 sa = term_char_resolve(a, &na, &ca);
103 sb = term_char_resolve(b, &nb, &cb);
104 return na == nb && !memcmp(sa, sb, sizeof(*sa) * na);
107 /* free @ch in case it is dynamically allocated */
108 static inline term_char_t term_char_free(term_char_t ch) {
109 if (term_char_is_allocated(ch))
110 term_char_set(ch, 0);
112 return TERM_CHAR_NULL;
115 /* gcc _cleanup_ helpers */
116 #define _term_char_free_ _cleanup_(term_char_freep)
117 static inline void term_char_freep(term_char_t *p) {
123 * The term_cell structure respresents a single cell in a terminal page. It
124 * contains the stored character, the age of the cell and all its attributes.
128 term_char_t ch; /* stored char or TERM_CHAR_NULL */
129 term_age_t age; /* cell age or TERM_AGE_NULL */
130 term_attr attr; /* cell attributes */
131 unsigned int cwidth; /* cached term_char_lookup_width(cell->ch) */
136 * Instead of storing cells in a 2D array, we store them in an array of
137 * dynamically allocated lines. This way, scrolling can be implemented very
138 * fast without moving any cells at all. Similarly, the scrollback-buffer is
139 * much simpler to implement.
140 * We use term_line to store a single line. It contains an array of cells, a
141 * fill-state which remembers the amount of blanks on the right side, a
142 * separate age just for the line which can overwrite the age for all cells,
143 * and some management data.
147 term_line *lines_next; /* linked-list for histories */
148 term_line *lines_prev; /* linked-list for histories */
150 unsigned int width; /* visible width of line */
151 unsigned int n_cells; /* # of allocated cells */
152 term_cell *cells; /* cell-array */
154 term_age_t age; /* line age */
155 unsigned int fill; /* # of valid cells; starting left */
158 int term_line_new(term_line **out);
159 term_line *term_line_free(term_line *line);
161 #define _term_line_free_ _cleanup_(term_line_freep)
162 DEFINE_TRIVIAL_CLEANUP_FUNC(term_line*, term_line_free);
164 int term_line_reserve(term_line *line, unsigned int width, const term_attr *attr, term_age_t age, unsigned int protect_width);
165 void term_line_set_width(term_line *line, unsigned int width);
166 void term_line_write(term_line *line, unsigned int pos_x, term_char_t ch, unsigned int cwidth, const term_attr *attr, term_age_t age, bool insert_mode);
167 void term_line_insert(term_line *line, unsigned int from, unsigned int num, const term_attr *attr, term_age_t age);
168 void term_line_delete(term_line *line, unsigned int from, unsigned int num, const term_attr *attr, term_age_t age);
169 void term_line_append_combchar(term_line *line, unsigned int pos_x, uint32_t ucs4, term_age_t age);
170 void term_line_erase(term_line *line, unsigned int from, unsigned int num, const term_attr *attr, term_age_t age, bool keep_protected);
171 void term_line_reset(term_line *line, const term_attr *attr, term_age_t age);
173 void term_line_link(term_line *line, term_line **first, term_line **last);
174 void term_line_link_tail(term_line *line, term_line **first, term_line **last);
175 void term_line_unlink(term_line *line, term_line **first, term_line **last);
177 #define TERM_LINE_LINK(_line, _head) term_line_link((_line), &(_head)->lines_first, &(_head)->lines_last)
178 #define TERM_LINE_LINK_TAIL(_line, _head) term_line_link_tail((_line), &(_head)->lines_first, &(_head)->lines_last)
179 #define TERM_LINE_UNLINK(_line, _head) term_line_unlink((_line), &(_head)->lines_first, &(_head)->lines_last)
183 * A page represents the 2D table containing all cells of a terminal. It stores
184 * lines as an array of pointers so scrolling becomes a simple line-shuffle
186 * Scrolling is always targeted only at the scroll-region defined via scroll_idx
187 * and scroll_num. The fill-state keeps track of the number of touched lines in
188 * the scroll-region. @width and @height describe the visible region of the page
189 * and are guaranteed to be allocated at all times.
193 term_age_t age; /* page age */
195 term_line **lines; /* array of line-pointers */
196 term_line **line_cache; /* cache for temporary operations */
197 unsigned int n_lines; /* # of allocated lines */
199 unsigned int width; /* width of visible area */
200 unsigned int height; /* height of visible area */
201 unsigned int scroll_idx; /* scrolling-region start index */
202 unsigned int scroll_num; /* scrolling-region length in lines */
203 unsigned int scroll_fill; /* # of valid scroll-lines */
206 int term_page_new(term_page **out);
207 term_page *term_page_free(term_page *page);
209 #define _term_page_free_ _cleanup_(term_page_freep)
210 DEFINE_TRIVIAL_CLEANUP_FUNC(term_page*, term_page_free);
212 term_cell *term_page_get_cell(term_page *page, unsigned int x, unsigned int y);
214 int term_page_reserve(term_page *page, unsigned int cols, unsigned int rows, const term_attr *attr, term_age_t age);
215 void term_page_resize(term_page *page, unsigned int cols, unsigned int rows, const term_attr *attr, term_age_t age, term_history *history);
216 void term_page_write(term_page *page, unsigned int pos_x, unsigned int pos_y, term_char_t ch, unsigned int cwidth, const term_attr *attr, term_age_t age, bool insert_mode);
217 void term_page_insert_cells(term_page *page, unsigned int from_x, unsigned int from_y, unsigned int num, const term_attr *attr, term_age_t age);
218 void term_page_delete_cells(term_page *page, unsigned int from_x, unsigned int from_y, unsigned int num, const term_attr *attr, term_age_t age);
219 void term_page_append_combchar(term_page *page, unsigned int pos_x, unsigned int pos_y, uint32_t ucs4, term_age_t age);
220 void term_page_erase(term_page *page, unsigned int from_x, unsigned int from_y, unsigned int to_x, unsigned int to_y, const term_attr *attr, term_age_t age, bool keep_protected);
221 void term_page_reset(term_page *page, const term_attr *attr, term_age_t age);
223 void term_page_set_scroll_region(term_page *page, unsigned int idx, unsigned int num);
224 void term_page_scroll_up(term_page *page, unsigned int num, const term_attr *attr, term_age_t age, term_history *history);
225 void term_page_scroll_down(term_page *page, unsigned int num, const term_attr *attr, term_age_t age, term_history *history);
226 void term_page_insert_lines(term_page *page, unsigned int pos_y, unsigned int num, const term_attr *attr, term_age_t age);
227 void term_page_delete_lines(term_page *page, unsigned int pos_y, unsigned int num, const term_attr *attr, term_age_t age);
231 * Scroll-back buffers use term_history objects to store scroll-back lines. A
232 * page is independent of the history used. All page operations that modify a
233 * history take it as separate argument. You're free to pass NULL at all times
234 * if no history should be used.
235 * Lines are stored in a linked list as no complex operations are ever done on
236 * history lines, besides pushing/poping. Note that history lines do not have a
237 * guaranteed minimum length. Any kind of line might be stored there. Missing
238 * cells should be cleared to the background color.
241 struct term_history {
242 term_line *lines_first;
243 term_line *lines_last;
244 unsigned int n_lines;
245 unsigned int max_lines;
248 int term_history_new(term_history **out);
249 term_history *term_history_free(term_history *history);
251 #define _term_history_free_ _cleanup_(term_history_freep)
252 DEFINE_TRIVIAL_CLEANUP_FUNC(term_history*, term_history_free);
254 void term_history_clear(term_history *history);
255 void term_history_trim(term_history *history, unsigned int max);
256 void term_history_push(term_history *history, term_line *line);
257 term_line *term_history_pop(term_history *history, unsigned int reserve_width, const term_attr *attr, term_age_t age);
258 unsigned int term_history_peek(term_history *history, unsigned int max, unsigned int reserve_width, const term_attr *attr, term_age_t age);
262 * The term_parser object parses control-sequences for both host and terminal
263 * side. Based on this parser, there is a set of command-parsers that take a
264 * term_seq sequence and returns the command it represents. This is different
265 * for host and terminal side so a different set of parsers is provided.
269 TERM_SEQ_NONE, /* placeholder, no sequence parsed */
271 TERM_SEQ_IGNORE, /* no-op character */
272 TERM_SEQ_GRAPHIC, /* graphic character */
273 TERM_SEQ_CONTROL, /* control character */
274 TERM_SEQ_ESCAPE, /* escape sequence */
275 TERM_SEQ_CSI, /* control sequence function */
276 TERM_SEQ_DCS, /* device control string */
277 TERM_SEQ_OSC, /* operating system control */
283 /* these must be kept compatible to (1U << (ch - 0x20)) */
285 TERM_SEQ_FLAG_SPACE = (1U << 0), /* char: */
286 TERM_SEQ_FLAG_BANG = (1U << 1), /* char: ! */
287 TERM_SEQ_FLAG_DQUOTE = (1U << 2), /* char: " */
288 TERM_SEQ_FLAG_HASH = (1U << 3), /* char: # */
289 TERM_SEQ_FLAG_CASH = (1U << 4), /* char: $ */
290 TERM_SEQ_FLAG_PERCENT = (1U << 5), /* char: % */
291 TERM_SEQ_FLAG_AND = (1U << 6), /* char: & */
292 TERM_SEQ_FLAG_SQUOTE = (1U << 7), /* char: ' */
293 TERM_SEQ_FLAG_POPEN = (1U << 8), /* char: ( */
294 TERM_SEQ_FLAG_PCLOSE = (1U << 9), /* char: ) */
295 TERM_SEQ_FLAG_MULT = (1U << 10), /* char: * */
296 TERM_SEQ_FLAG_PLUS = (1U << 11), /* char: + */
297 TERM_SEQ_FLAG_COMMA = (1U << 12), /* char: , */
298 TERM_SEQ_FLAG_MINUS = (1U << 13), /* char: - */
299 TERM_SEQ_FLAG_DOT = (1U << 14), /* char: . */
300 TERM_SEQ_FLAG_SLASH = (1U << 15), /* char: / */
302 /* 16-35 is reserved for numbers; unused */
304 /* COLON is reserved = (1U << 26), char: : */
305 /* SEMICOLON is reserved = (1U << 27), char: ; */
306 TERM_SEQ_FLAG_LT = (1U << 28), /* char: < */
307 TERM_SEQ_FLAG_EQUAL = (1U << 29), /* char: = */
308 TERM_SEQ_FLAG_GT = (1U << 30), /* char: > */
309 TERM_SEQ_FLAG_WHAT = (1U << 31), /* char: ? */
313 TERM_CMD_NONE, /* placeholder */
314 TERM_CMD_GRAPHIC, /* graphics character */
316 TERM_CMD_BEL, /* bell */
317 TERM_CMD_BS, /* backspace */
318 TERM_CMD_CBT, /* cursor-backward-tabulation */
319 TERM_CMD_CHA, /* cursor-horizontal-absolute */
320 TERM_CMD_CHT, /* cursor-horizontal-forward-tabulation */
321 TERM_CMD_CNL, /* cursor-next-line */
322 TERM_CMD_CPL, /* cursor-previous-line */
323 TERM_CMD_CR, /* carriage-return */
324 TERM_CMD_CUB, /* cursor-backward */
325 TERM_CMD_CUD, /* cursor-down */
326 TERM_CMD_CUF, /* cursor-forward */
327 TERM_CMD_CUP, /* cursor-position */
328 TERM_CMD_CUU, /* cursor-up */
329 TERM_CMD_DA1, /* primary-device-attributes */
330 TERM_CMD_DA2, /* secondary-device-attributes */
331 TERM_CMD_DA3, /* tertiary-device-attributes */
332 TERM_CMD_DC1, /* device-control-1 or XON */
333 TERM_CMD_DC3, /* device-control-3 or XOFF */
334 TERM_CMD_DCH, /* delete-character */
335 TERM_CMD_DECALN, /* screen-alignment-pattern */
336 TERM_CMD_DECANM, /* ansi-mode */
337 TERM_CMD_DECBI, /* back-index */
338 TERM_CMD_DECCARA, /* change-attributes-in-rectangular-area */
339 TERM_CMD_DECCRA, /* copy-rectangular-area */
340 TERM_CMD_DECDC, /* delete-column */
341 TERM_CMD_DECDHL_BH, /* double-width-double-height-line: bottom half */
342 TERM_CMD_DECDHL_TH, /* double-width-double-height-line: top half */
343 TERM_CMD_DECDWL, /* double-width-single-height-line */
344 TERM_CMD_DECEFR, /* enable-filter-rectangle */
345 TERM_CMD_DECELF, /* enable-local-functions */
346 TERM_CMD_DECELR, /* enable-locator-reporting */
347 TERM_CMD_DECERA, /* erase-rectangular-area */
348 TERM_CMD_DECFI, /* forward-index */
349 TERM_CMD_DECFRA, /* fill-rectangular-area */
350 TERM_CMD_DECIC, /* insert-column */
351 TERM_CMD_DECID, /* return-terminal-id */
352 TERM_CMD_DECINVM, /* invoke-macro */
353 TERM_CMD_DECKBD, /* keyboard-language-selection */
354 TERM_CMD_DECKPAM, /* keypad-application-mode */
355 TERM_CMD_DECKPNM, /* keypad-numeric-mode */
356 TERM_CMD_DECLFKC, /* local-function-key-control */
357 TERM_CMD_DECLL, /* load-leds */
358 TERM_CMD_DECLTOD, /* load-time-of-day */
359 TERM_CMD_DECPCTERM, /* pcterm-mode */
360 TERM_CMD_DECPKA, /* program-key-action */
361 TERM_CMD_DECPKFMR, /* program-key-free-memory-report */
362 TERM_CMD_DECRARA, /* reverse-attributes-in-rectangular-area */
363 TERM_CMD_DECRC, /* restore-cursor */
364 TERM_CMD_DECREQTPARM, /* request-terminal-parameters */
365 TERM_CMD_DECRPKT, /* report-key-type */
366 TERM_CMD_DECRQCRA, /* request-checksum-of-rectangular-area */
367 TERM_CMD_DECRQDE, /* request-display-extent */
368 TERM_CMD_DECRQKT, /* request-key-type */
369 TERM_CMD_DECRQLP, /* request-locator-position */
370 TERM_CMD_DECRQM_ANSI, /* request-mode-ansi */
371 TERM_CMD_DECRQM_DEC, /* request-mode-dec */
372 TERM_CMD_DECRQPKFM, /* request-program-key-free-memory */
373 TERM_CMD_DECRQPSR, /* request-presentation-state-report */
374 TERM_CMD_DECRQTSR, /* request-terminal-state-report */
375 TERM_CMD_DECRQUPSS, /* request-user-preferred-supplemental-set */
376 TERM_CMD_DECSACE, /* select-attribute-change-extent */
377 TERM_CMD_DECSASD, /* select-active-status-display */
378 TERM_CMD_DECSC, /* save-cursor */
379 TERM_CMD_DECSCA, /* select-character-protection-attribute */
380 TERM_CMD_DECSCL, /* select-conformance-level */
381 TERM_CMD_DECSCP, /* select-communication-port */
382 TERM_CMD_DECSCPP, /* select-columns-per-page */
383 TERM_CMD_DECSCS, /* select-communication-speed */
384 TERM_CMD_DECSCUSR, /* set-cursor-style */
385 TERM_CMD_DECSDDT, /* select-disconnect-delay-time */
386 TERM_CMD_DECSDPT, /* select-digital-printed-data-type */
387 TERM_CMD_DECSED, /* selective-erase-in-display */
388 TERM_CMD_DECSEL, /* selective-erase-in-line */
389 TERM_CMD_DECSERA, /* selective-erase-rectangular-area */
390 TERM_CMD_DECSFC, /* select-flow-control */
391 TERM_CMD_DECSKCV, /* set-key-click-volume */
392 TERM_CMD_DECSLCK, /* set-lock-key-style */
393 TERM_CMD_DECSLE, /* select-locator-events */
394 TERM_CMD_DECSLPP, /* set-lines-per-page */
395 TERM_CMD_DECSLRM_OR_SC, /* set-left-and-right-margins or save-cursor */
396 TERM_CMD_DECSMBV, /* set-margin-bell-volume */
397 TERM_CMD_DECSMKR, /* select-modifier-key-reporting */
398 TERM_CMD_DECSNLS, /* set-lines-per-screen */
399 TERM_CMD_DECSPP, /* set-port-parameter */
400 TERM_CMD_DECSPPCS, /* select-pro-printer-character-set */
401 TERM_CMD_DECSPRTT, /* select-printer-type */
402 TERM_CMD_DECSR, /* secure-reset */
403 TERM_CMD_DECSRFR, /* select-refresh-rate */
404 TERM_CMD_DECSSCLS, /* set-scroll-speed */
405 TERM_CMD_DECSSDT, /* select-status-display-line-type */
406 TERM_CMD_DECSSL, /* select-setup-language */
407 TERM_CMD_DECST8C, /* set-tab-at-every-8-columns */
408 TERM_CMD_DECSTBM, /* set-top-and-bottom-margins */
409 TERM_CMD_DECSTR, /* soft-terminal-reset */
410 TERM_CMD_DECSTRL, /* set-transmit-rate-limit */
411 TERM_CMD_DECSWBV, /* set-warning-bell-volume */
412 TERM_CMD_DECSWL, /* single-width-single-height-line */
413 TERM_CMD_DECTID, /* select-terminal-id */
414 TERM_CMD_DECTME, /* terminal-mode-emulation */
415 TERM_CMD_DECTST, /* invoke-confidence-test */
416 TERM_CMD_DL, /* delete-line */
417 TERM_CMD_DSR_ANSI, /* device-status-report-ansi */
418 TERM_CMD_DSR_DEC, /* device-status-report-dec */
419 TERM_CMD_ECH, /* erase-character */
420 TERM_CMD_ED, /* erase-in-display */
421 TERM_CMD_EL, /* erase-in-line */
422 TERM_CMD_ENQ, /* enquiry */
423 TERM_CMD_EPA, /* end-of-guarded-area */
424 TERM_CMD_FF, /* form-feed */
425 TERM_CMD_HPA, /* horizontal-position-absolute */
426 TERM_CMD_HPR, /* horizontal-position-relative */
427 TERM_CMD_HT, /* horizontal-tab */
428 TERM_CMD_HTS, /* horizontal-tab-set */
429 TERM_CMD_HVP, /* horizontal-and-vertical-position */
430 TERM_CMD_ICH, /* insert-character */
431 TERM_CMD_IL, /* insert-line */
432 TERM_CMD_IND, /* index */
433 TERM_CMD_LF, /* line-feed */
434 TERM_CMD_LS1R, /* locking-shift-1-right */
435 TERM_CMD_LS2, /* locking-shift-2 */
436 TERM_CMD_LS2R, /* locking-shift-2-right */
437 TERM_CMD_LS3, /* locking-shift-3 */
438 TERM_CMD_LS3R, /* locking-shift-3-right */
439 TERM_CMD_MC_ANSI, /* media-copy-ansi */
440 TERM_CMD_MC_DEC, /* media-copy-dec */
441 TERM_CMD_NEL, /* next-line */
442 TERM_CMD_NP, /* next-page */
443 TERM_CMD_NULL, /* null */
444 TERM_CMD_PP, /* preceding-page */
445 TERM_CMD_PPA, /* page-position-absolute */
446 TERM_CMD_PPB, /* page-position-backward */
447 TERM_CMD_PPR, /* page-position-relative */
448 TERM_CMD_RC, /* restore-cursor */
449 TERM_CMD_REP, /* repeat */
450 TERM_CMD_RI, /* reverse-index */
451 TERM_CMD_RIS, /* reset-to-initial-state */
452 TERM_CMD_RM_ANSI, /* reset-mode-ansi */
453 TERM_CMD_RM_DEC, /* reset-mode-dec */
454 TERM_CMD_S7C1T, /* set-7bit-c1-terminal */
455 TERM_CMD_S8C1T, /* set-8bit-c1-terminal */
456 TERM_CMD_SCS, /* select-character-set */
457 TERM_CMD_SD, /* scroll-down */
458 TERM_CMD_SGR, /* select-graphics-rendition */
459 TERM_CMD_SI, /* shift-in */
460 TERM_CMD_SM_ANSI, /* set-mode-ansi */
461 TERM_CMD_SM_DEC, /* set-mode-dec */
462 TERM_CMD_SO, /* shift-out */
463 TERM_CMD_SPA, /* start-of-protected-area */
464 TERM_CMD_SS2, /* single-shift-2 */
465 TERM_CMD_SS3, /* single-shift-3 */
466 TERM_CMD_ST, /* string-terminator */
467 TERM_CMD_SU, /* scroll-up */
468 TERM_CMD_SUB, /* substitute */
469 TERM_CMD_TBC, /* tab-clear */
470 TERM_CMD_VPA, /* vertical-line-position-absolute */
471 TERM_CMD_VPR, /* vertical-line-position-relative */
472 TERM_CMD_VT, /* vertical-tab */
473 TERM_CMD_XTERM_CLLHP, /* xterm-cursor-lower-left-hp-bugfix */
474 TERM_CMD_XTERM_IHMT, /* xterm-initiate-highlight-mouse-tracking*/
475 TERM_CMD_XTERM_MLHP, /* xterm-memory-lock-hp-bugfix */
476 TERM_CMD_XTERM_MUHP, /* xterm-memory-unlock-hp-bugfix */
477 TERM_CMD_XTERM_RPM, /* xterm-restore-private-mode */
478 TERM_CMD_XTERM_RRV, /* xterm-reset-resource-value */
479 TERM_CMD_XTERM_RTM, /* xterm-reset-title-mode */
480 TERM_CMD_XTERM_SACL1, /* xterm-set-ansi-conformance-level-1 */
481 TERM_CMD_XTERM_SACL2, /* xterm-set-ansi-conformance-level-2 */
482 TERM_CMD_XTERM_SACL3, /* xterm-set-ansi-conformance-level-3 */
483 TERM_CMD_XTERM_SDCS, /* xterm-set-default-character-set */
484 TERM_CMD_XTERM_SGFX, /* xterm-sixel-graphics */
485 TERM_CMD_XTERM_SPM, /* xterm-set-private-mode */
486 TERM_CMD_XTERM_SRV, /* xterm-set-resource-value */
487 TERM_CMD_XTERM_STM, /* xterm-set-title-mode */
488 TERM_CMD_XTERM_SUCS, /* xterm-set-utf8-character-set */
489 TERM_CMD_XTERM_WM, /* xterm-window-management */
496 * Charsets: DEC marks charsets according to "Digital Equ. Corp.".
497 * NRCS marks charsets according to the "National Replacement
498 * Character Sets". ISO marks charsets according to ISO-8859.
499 * The USERDEF charset is special and can be modified by the host.
504 /* 96-compat charsets */
505 TERM_CHARSET_ISO_LATIN1_SUPPLEMENTAL,
506 TERM_CHARSET_BRITISH_NRCS = TERM_CHARSET_ISO_LATIN1_SUPPLEMENTAL,
507 TERM_CHARSET_ISO_LATIN2_SUPPLEMENTAL,
508 TERM_CHARSET_AMERICAN_NRCS = TERM_CHARSET_ISO_LATIN2_SUPPLEMENTAL,
509 TERM_CHARSET_ISO_LATIN5_SUPPLEMENTAL,
510 TERM_CHARSET_ISO_GREEK_SUPPLEMENTAL,
511 TERM_CHARSET_ISO_HEBREW_SUPPLEMENTAL,
512 TERM_CHARSET_ISO_LATIN_CYRILLIC,
516 /* 94-compat charsets */
517 TERM_CHARSET_DEC_SPECIAL_GRAPHIC = TERM_CHARSET_96_CNT,
518 TERM_CHARSET_DEC_SUPPLEMENTAL,
519 TERM_CHARSET_DEC_TECHNICAL,
520 TERM_CHARSET_CYRILLIC_DEC,
521 TERM_CHARSET_DUTCH_NRCS,
522 TERM_CHARSET_FINNISH_NRCS,
523 TERM_CHARSET_FRENCH_NRCS,
524 TERM_CHARSET_FRENCH_CANADIAN_NRCS,
525 TERM_CHARSET_GERMAN_NRCS,
526 TERM_CHARSET_GREEK_DEC,
527 TERM_CHARSET_GREEK_NRCS,
528 TERM_CHARSET_HEBREW_DEC,
529 TERM_CHARSET_HEBREW_NRCS,
530 TERM_CHARSET_ITALIAN_NRCS,
531 TERM_CHARSET_NORWEGIAN_DANISH_NRCS,
532 TERM_CHARSET_PORTUGUESE_NRCS,
533 TERM_CHARSET_RUSSIAN_NRCS,
534 TERM_CHARSET_SCS_NRCS,
535 TERM_CHARSET_SPANISH_NRCS,
536 TERM_CHARSET_SWEDISH_NRCS,
537 TERM_CHARSET_SWISS_NRCS,
538 TERM_CHARSET_TURKISH_DEC,
539 TERM_CHARSET_TURKISH_NRCS,
543 /* special charsets */
544 TERM_CHARSET_USERPREF_SUPPLEMENTAL = TERM_CHARSET_94_CNT,
549 extern term_charset term_unicode_lower;
550 extern term_charset term_unicode_upper;
551 extern term_charset term_dec_supplemental_graphics;
552 extern term_charset term_dec_special_graphics;
554 #define TERM_PARSER_ARG_MAX (16)
555 #define TERM_PARSER_ST_MAX (4096)
559 unsigned int command;
561 unsigned int intermediates;
562 unsigned int charset;
564 int args[TERM_PARSER_ARG_MAX];
579 * A term_screen object represents the terminal-side of the communication. It
580 * connects the term-parser and term-pages and handles all required commands.
581 * All state is managed by it.
585 TERM_FLAG_7BIT_MODE = (1U << 0), /* 7bit mode (default: on) */
586 TERM_FLAG_HIDE_CURSOR = (1U << 1), /* hide cursor caret (default: off) */
587 TERM_FLAG_INHIBIT_TPARM = (1U << 2), /* do not send TPARM unrequested (default: off) */
588 TERM_FLAG_NEWLINE_MODE = (1U << 3), /* perform carriage-return on line-feeds (default: off) */
589 TERM_FLAG_ORIGIN_MODE = (1U << 4), /* in origin mode, the cursor is bound by the margins (default: off) */
590 TERM_FLAG_PENDING_WRAP = (1U << 5), /* wrap-around is pending */
591 TERM_FLAG_AUTO_WRAP = (1U << 6), /* auto-wrap mode causes line-wraps at line-ends (default: off) */
592 TERM_FLAG_KEYPAD_MODE = (1U << 7), /* application-keypad mode (default: off) */
593 TERM_FLAG_CURSOR_KEYS = (1U << 8), /* enable application cursor-keys (default: off) */
597 TERM_CONFORMANCE_LEVEL_VT52,
598 TERM_CONFORMANCE_LEVEL_VT100,
599 TERM_CONFORMANCE_LEVEL_VT400,
600 TERM_CONFORMANCE_LEVEL_CNT,
608 term_page *page_main;
610 term_history *history;
611 term_history *history_main;
619 term_screen_write_fn write_fn;
621 term_screen_cmd_fn cmd_fn;
625 unsigned int conformance_level;
626 unsigned int cursor_x;
627 unsigned int cursor_y;
629 term_attr default_attr;
643 unsigned int cursor_x;
644 unsigned int cursor_y;