X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Flibsystemd-terminal%2Fterm-internal.h;h=8c6a00188c34ccb17ab14e187d5f1f38ce51d019;hb=b6e676ce41508e2aeea22202fc8f234126177f52;hp=a3d1f5458b43d8901ae64759a5609a90dbc9519f;hpb=1c9633d669948155455e29b0c6e770995a8b1ca3;p=elogind.git diff --git a/src/libsystemd-terminal/term-internal.h b/src/libsystemd-terminal/term-internal.h index a3d1f5458..8c6a00188 100644 --- a/src/libsystemd-terminal/term-internal.h +++ b/src/libsystemd-terminal/term-internal.h @@ -24,23 +24,20 @@ #include #include #include +#include "term.h" #include "util.h" typedef struct term_char term_char_t; typedef struct term_charbuf term_charbuf_t; -typedef struct term_color term_color; -typedef struct term_attr term_attr; typedef struct term_cell term_cell; typedef struct term_line term_line; typedef struct term_page term_page; typedef struct term_history term_history; -typedef struct term_utf8 term_utf8; -typedef struct term_seq term_seq; -typedef struct term_parser term_parser; typedef uint32_t term_charset[96]; +typedef struct term_state term_state; /* * Miscellaneous @@ -52,24 +49,6 @@ int mk_wcwidth_cjk(wchar_t ucs4); int mk_wcswidth(const wchar_t *str, size_t len); int mk_wcswidth_cjk(const wchar_t *str, size_t len); -/* - * Ageing - * Redrawing terminals is quite expensive. Therefore, we avoid redrawing on - * each single modification and mark modified cells instead. This way, we know - * which cells to redraw on the next frame. However, a single DIRTY flag is not - * enough for double/triple buffered screens, hence, we use an AGE field for - * each cell. If the cell is modified, we simply increase the age by one. Each - * framebuffer can then remember its last rendered age and request an update of - * all newer cells. - * TERM_AGE_NULL is special. If used as cell age, the cell must always be - * redrawn (forced update). If used as framebuffer age, all cells are drawn. - * This way, we can allow integer wrap-arounds. - */ - -typedef uint64_t term_age_t; - -#define TERM_AGE_NULL 0 - /* * Characters * Each cell in a terminal page contains only a single character. This is @@ -140,68 +119,6 @@ static inline void term_char_freep(term_char_t *p) { term_char_free(*p); } -/* - * Attributes - * Each cell in a terminal page can have its own set of attributes. These alter - * the behavior of the renderer for this single cell. We use term_attr to - * specify attributes. - * The only non-obvious field is "ccode" for foreground and background colors. - * This field contains the terminal color-code in case no full RGB information - * was given by the host. It is also required for dynamic color palettes. If it - * is set to TERM_CCODE_RGB, the "red", "green" and "blue" fields contain the - * full RGB color. - */ - -enum { - /* special color-codes */ - TERM_CCODE_DEFAULT, /* default foreground/background color */ - TERM_CCODE_256, /* 256color code */ - TERM_CCODE_RGB, /* color is specified as RGB */ - - /* dark color-codes */ - TERM_CCODE_BLACK, - TERM_CCODE_RED, - TERM_CCODE_GREEN, - TERM_CCODE_YELLOW, - TERM_CCODE_BLUE, - TERM_CCODE_MAGENTA, - TERM_CCODE_CYAN, - TERM_CCODE_WHITE, /* technically: light grey */ - - /* light color-codes */ - TERM_CCODE_LIGHT_BLACK = TERM_CCODE_BLACK + 8, /* technically: dark grey */ - TERM_CCODE_LIGHT_RED = TERM_CCODE_RED + 8, - TERM_CCODE_LIGHT_GREEN = TERM_CCODE_GREEN + 8, - TERM_CCODE_LIGHT_YELLOW = TERM_CCODE_YELLOW + 8, - TERM_CCODE_LIGHT_BLUE = TERM_CCODE_BLUE + 8, - TERM_CCODE_LIGHT_MAGENTA = TERM_CCODE_MAGENTA + 8, - TERM_CCODE_LIGHT_CYAN = TERM_CCODE_CYAN + 8, - TERM_CCODE_LIGHT_WHITE = TERM_CCODE_WHITE + 8, - - TERM_CCODE_CNT, -}; - -struct term_color { - uint8_t ccode; - uint8_t c256; - uint8_t red; - uint8_t green; - uint8_t blue; -}; - -struct term_attr { - term_color fg; /* foreground color */ - term_color bg; /* background color */ - - unsigned int bold : 1; /* bold font */ - unsigned int italic : 1; /* italic font */ - unsigned int underline : 1; /* underline text */ - unsigned int inverse : 1; /* inverse fg/bg */ - unsigned int protect : 1; /* protect from erase */ - unsigned int blink : 1; /* blink text */ - unsigned int hidden : 1; /* hidden */ -}; - /* * Cells * The term_cell structure respresents a single cell in a terminal page. It @@ -341,26 +258,6 @@ void term_history_push(term_history *history, term_line *line); term_line *term_history_pop(term_history *history, unsigned int reserve_width, const term_attr *attr, term_age_t age); unsigned int term_history_peek(term_history *history, unsigned int max, unsigned int reserve_width, const term_attr *attr, term_age_t age); -/* - * UTF-8 - * The UTF-decoder and encoder are adjusted for terminals and provide proper - * fallbacks for invalid UTF-8. In terminals it's quite usual to use fallbacks - * instead of rejecting invalid input. This way, old legacy applications still - * work (this is especially important for 7bit/ASCII DEC modes). - */ - -struct term_utf8 { - uint32_t chars[5]; - uint32_t ucs4; - - unsigned int i_bytes : 3; - unsigned int n_bytes : 3; - unsigned int valid : 1; -}; - -size_t term_utf8_encode(char *out_utf8, uint32_t g); -const uint32_t *term_utf8_decode(term_utf8 *p, size_t *out_len, char c); - /* * Parsers * The term_parser object parses control-sequences for both host and terminal @@ -433,8 +330,8 @@ enum { TERM_CMD_DA1, /* primary-device-attributes */ TERM_CMD_DA2, /* secondary-device-attributes */ TERM_CMD_DA3, /* tertiary-device-attributes */ - TERM_CMD_DC1, /* device-control-1 */ - TERM_CMD_DC3, /* device-control-3 */ + TERM_CMD_DC1, /* device-control-1 or XON */ + TERM_CMD_DC3, /* device-control-3 or XOFF */ TERM_CMD_DCH, /* delete-character */ TERM_CMD_DECALN, /* screen-alignment-pattern */ TERM_CMD_DECANM, /* ansi-mode */ @@ -445,137 +342,137 @@ enum { TERM_CMD_DECDHL_BH, /* double-width-double-height-line: bottom half */ TERM_CMD_DECDHL_TH, /* double-width-double-height-line: top half */ TERM_CMD_DECDWL, /* double-width-single-height-line */ - TERM_CMD_DECEFR, - TERM_CMD_DECELF, - TERM_CMD_DECELR, - TERM_CMD_DECERA, - TERM_CMD_DECFI, - TERM_CMD_DECFRA, - TERM_CMD_DECIC, - TERM_CMD_DECID, - TERM_CMD_DECINVM, - TERM_CMD_DECKBD, - TERM_CMD_DECKPAM, - TERM_CMD_DECKPNM, - TERM_CMD_DECLFKC, - TERM_CMD_DECLL, - TERM_CMD_DECLTOD, - TERM_CMD_DECPCTERM, - TERM_CMD_DECPKA, - TERM_CMD_DECPKFMR, - TERM_CMD_DECRARA, - TERM_CMD_DECRC, - TERM_CMD_DECREQTPARM, - TERM_CMD_DECRPKT, - TERM_CMD_DECRQCRA, - TERM_CMD_DECRQDE, - TERM_CMD_DECRQKT, - TERM_CMD_DECRQLP, - TERM_CMD_DECRQM_ANSI, - TERM_CMD_DECRQM_DEC, - TERM_CMD_DECRQPKFM, - TERM_CMD_DECRQPSR, - TERM_CMD_DECRQTSR, - TERM_CMD_DECRQUPSS, - TERM_CMD_DECSACE, - TERM_CMD_DECSASD, - TERM_CMD_DECSC, - TERM_CMD_DECSCA, - TERM_CMD_DECSCL, - TERM_CMD_DECSCP, - TERM_CMD_DECSCPP, - TERM_CMD_DECSCS, - TERM_CMD_DECSCUSR, - TERM_CMD_DECSDDT, - TERM_CMD_DECSDPT, - TERM_CMD_DECSED, - TERM_CMD_DECSEL, - TERM_CMD_DECSERA, - TERM_CMD_DECSFC, - TERM_CMD_DECSKCV, - TERM_CMD_DECSLCK, - TERM_CMD_DECSLE, - TERM_CMD_DECSLPP, - TERM_CMD_DECSLRM_OR_SC, - TERM_CMD_DECSMBV, - TERM_CMD_DECSMKR, - TERM_CMD_DECSNLS, - TERM_CMD_DECSPP, - TERM_CMD_DECSPPCS, - TERM_CMD_DECSPRTT, - TERM_CMD_DECSR, - TERM_CMD_DECSRFR, - TERM_CMD_DECSSCLS, - TERM_CMD_DECSSDT, - TERM_CMD_DECSSL, - TERM_CMD_DECST8C, - TERM_CMD_DECSTBM, - TERM_CMD_DECSTR, - TERM_CMD_DECSTRL, - TERM_CMD_DECSWBV, - TERM_CMD_DECSWL, - TERM_CMD_DECTID, - TERM_CMD_DECTME, - TERM_CMD_DECTST, - TERM_CMD_DL, - TERM_CMD_DSR_ANSI, - TERM_CMD_DSR_DEC, - TERM_CMD_ECH, - TERM_CMD_ED, - TERM_CMD_EL, - TERM_CMD_ENQ, - TERM_CMD_EPA, - TERM_CMD_FF, - TERM_CMD_HPA, - TERM_CMD_HPR, - TERM_CMD_HT, - TERM_CMD_HTS, - TERM_CMD_HVP, - TERM_CMD_ICH, - TERM_CMD_IL, - TERM_CMD_IND, - TERM_CMD_LF, - TERM_CMD_LS1R, - TERM_CMD_LS2, - TERM_CMD_LS2R, - TERM_CMD_LS3, - TERM_CMD_LS3R, - TERM_CMD_MC_ANSI, - TERM_CMD_MC_DEC, - TERM_CMD_NEL, - TERM_CMD_NP, - TERM_CMD_NULL, - TERM_CMD_PP, - TERM_CMD_PPA, - TERM_CMD_PPB, - TERM_CMD_PPR, - TERM_CMD_RC, - TERM_CMD_REP, - TERM_CMD_RI, - TERM_CMD_RIS, - TERM_CMD_RM_ANSI, - TERM_CMD_RM_DEC, - TERM_CMD_S7C1T, - TERM_CMD_S8C1T, - TERM_CMD_SCS, - TERM_CMD_SD, - TERM_CMD_SGR, - TERM_CMD_SI, - TERM_CMD_SM_ANSI, - TERM_CMD_SM_DEC, - TERM_CMD_SO, - TERM_CMD_SPA, - TERM_CMD_SS2, - TERM_CMD_SS3, - TERM_CMD_ST, - TERM_CMD_SU, - TERM_CMD_SUB, - TERM_CMD_TBC, - TERM_CMD_VPA, - TERM_CMD_VPR, - TERM_CMD_VT, + TERM_CMD_DECEFR, /* enable-filter-rectangle */ + TERM_CMD_DECELF, /* enable-local-functions */ + TERM_CMD_DECELR, /* enable-locator-reporting */ + TERM_CMD_DECERA, /* erase-rectangular-area */ + TERM_CMD_DECFI, /* forward-index */ + TERM_CMD_DECFRA, /* fill-rectangular-area */ + TERM_CMD_DECIC, /* insert-column */ + TERM_CMD_DECID, /* return-terminal-id */ + TERM_CMD_DECINVM, /* invoke-macro */ + TERM_CMD_DECKBD, /* keyboard-language-selection */ + TERM_CMD_DECKPAM, /* keypad-application-mode */ + TERM_CMD_DECKPNM, /* keypad-numeric-mode */ + TERM_CMD_DECLFKC, /* local-function-key-control */ + TERM_CMD_DECLL, /* load-leds */ + TERM_CMD_DECLTOD, /* load-time-of-day */ + TERM_CMD_DECPCTERM, /* pcterm-mode */ + TERM_CMD_DECPKA, /* program-key-action */ + TERM_CMD_DECPKFMR, /* program-key-free-memory-report */ + TERM_CMD_DECRARA, /* reverse-attributes-in-rectangular-area */ + TERM_CMD_DECRC, /* restore-cursor */ + TERM_CMD_DECREQTPARM, /* request-terminal-parameters */ + TERM_CMD_DECRPKT, /* report-key-type */ + TERM_CMD_DECRQCRA, /* request-checksum-of-rectangular-area */ + TERM_CMD_DECRQDE, /* request-display-extent */ + TERM_CMD_DECRQKT, /* request-key-type */ + TERM_CMD_DECRQLP, /* request-locator-position */ + TERM_CMD_DECRQM_ANSI, /* request-mode-ansi */ + TERM_CMD_DECRQM_DEC, /* request-mode-dec */ + TERM_CMD_DECRQPKFM, /* request-program-key-free-memory */ + TERM_CMD_DECRQPSR, /* request-presentation-state-report */ + TERM_CMD_DECRQTSR, /* request-terminal-state-report */ + TERM_CMD_DECRQUPSS, /* request-user-preferred-supplemental-set */ + TERM_CMD_DECSACE, /* select-attribute-change-extent */ + TERM_CMD_DECSASD, /* select-active-status-display */ + TERM_CMD_DECSC, /* save-cursor */ + TERM_CMD_DECSCA, /* select-character-protection-attribute */ + TERM_CMD_DECSCL, /* select-conformance-level */ + TERM_CMD_DECSCP, /* select-communication-port */ + TERM_CMD_DECSCPP, /* select-columns-per-page */ + TERM_CMD_DECSCS, /* select-communication-speed */ + TERM_CMD_DECSCUSR, /* set-cursor-style */ + TERM_CMD_DECSDDT, /* select-disconnect-delay-time */ + TERM_CMD_DECSDPT, /* select-digital-printed-data-type */ + TERM_CMD_DECSED, /* selective-erase-in-display */ + TERM_CMD_DECSEL, /* selective-erase-in-line */ + TERM_CMD_DECSERA, /* selective-erase-rectangular-area */ + TERM_CMD_DECSFC, /* select-flow-control */ + TERM_CMD_DECSKCV, /* set-key-click-volume */ + TERM_CMD_DECSLCK, /* set-lock-key-style */ + TERM_CMD_DECSLE, /* select-locator-events */ + TERM_CMD_DECSLPP, /* set-lines-per-page */ + TERM_CMD_DECSLRM_OR_SC, /* set-left-and-right-margins or save-cursor */ + TERM_CMD_DECSMBV, /* set-margin-bell-volume */ + TERM_CMD_DECSMKR, /* select-modifier-key-reporting */ + TERM_CMD_DECSNLS, /* set-lines-per-screen */ + TERM_CMD_DECSPP, /* set-port-parameter */ + TERM_CMD_DECSPPCS, /* select-pro-printer-character-set */ + TERM_CMD_DECSPRTT, /* select-printer-type */ + TERM_CMD_DECSR, /* secure-reset */ + TERM_CMD_DECSRFR, /* select-refresh-rate */ + TERM_CMD_DECSSCLS, /* set-scroll-speed */ + TERM_CMD_DECSSDT, /* select-status-display-line-type */ + TERM_CMD_DECSSL, /* select-setup-language */ + TERM_CMD_DECST8C, /* set-tab-at-every-8-columns */ + TERM_CMD_DECSTBM, /* set-top-and-bottom-margins */ + TERM_CMD_DECSTR, /* soft-terminal-reset */ + TERM_CMD_DECSTRL, /* set-transmit-rate-limit */ + TERM_CMD_DECSWBV, /* set-warning-bell-volume */ + TERM_CMD_DECSWL, /* single-width-single-height-line */ + TERM_CMD_DECTID, /* select-terminal-id */ + TERM_CMD_DECTME, /* terminal-mode-emulation */ + TERM_CMD_DECTST, /* invoke-confidence-test */ + TERM_CMD_DL, /* delete-line */ + TERM_CMD_DSR_ANSI, /* device-status-report-ansi */ + TERM_CMD_DSR_DEC, /* device-status-report-dec */ + TERM_CMD_ECH, /* erase-character */ + TERM_CMD_ED, /* erase-in-display */ + TERM_CMD_EL, /* erase-in-line */ + TERM_CMD_ENQ, /* enquiry */ + TERM_CMD_EPA, /* end-of-guarded-area */ + TERM_CMD_FF, /* form-feed */ + TERM_CMD_HPA, /* horizontal-position-absolute */ + TERM_CMD_HPR, /* horizontal-position-relative */ + TERM_CMD_HT, /* horizontal-tab */ + TERM_CMD_HTS, /* horizontal-tab-set */ + TERM_CMD_HVP, /* horizontal-and-vertical-position */ + TERM_CMD_ICH, /* insert-character */ + TERM_CMD_IL, /* insert-line */ + TERM_CMD_IND, /* index */ + TERM_CMD_LF, /* line-feed */ + TERM_CMD_LS1R, /* locking-shift-1-right */ + TERM_CMD_LS2, /* locking-shift-2 */ + TERM_CMD_LS2R, /* locking-shift-2-right */ + TERM_CMD_LS3, /* locking-shift-3 */ + TERM_CMD_LS3R, /* locking-shift-3-right */ + TERM_CMD_MC_ANSI, /* media-copy-ansi */ + TERM_CMD_MC_DEC, /* media-copy-dec */ + TERM_CMD_NEL, /* next-line */ + TERM_CMD_NP, /* next-page */ + TERM_CMD_NULL, /* null */ + TERM_CMD_PP, /* preceding-page */ + TERM_CMD_PPA, /* page-position-absolute */ + TERM_CMD_PPB, /* page-position-backward */ + TERM_CMD_PPR, /* page-position-relative */ + TERM_CMD_RC, /* restore-cursor */ + TERM_CMD_REP, /* repeat */ + TERM_CMD_RI, /* reverse-index */ + TERM_CMD_RIS, /* reset-to-initial-state */ + TERM_CMD_RM_ANSI, /* reset-mode-ansi */ + TERM_CMD_RM_DEC, /* reset-mode-dec */ + TERM_CMD_S7C1T, /* set-7bit-c1-terminal */ + TERM_CMD_S8C1T, /* set-8bit-c1-terminal */ + TERM_CMD_SCS, /* select-character-set */ + TERM_CMD_SD, /* scroll-down */ + TERM_CMD_SGR, /* select-graphics-rendition */ + TERM_CMD_SI, /* shift-in */ + TERM_CMD_SM_ANSI, /* set-mode-ansi */ + TERM_CMD_SM_DEC, /* set-mode-dec */ + TERM_CMD_SO, /* shift-out */ + TERM_CMD_SPA, /* start-of-protected-area */ + TERM_CMD_SS2, /* single-shift-2 */ + TERM_CMD_SS3, /* single-shift-3 */ + TERM_CMD_ST, /* string-terminator */ + TERM_CMD_SU, /* scroll-up */ + TERM_CMD_SUB, /* substitute */ + TERM_CMD_TBC, /* tab-clear */ + TERM_CMD_VPA, /* vertical-line-position-absolute */ + TERM_CMD_VPR, /* vertical-line-position-relative */ + TERM_CMD_VT, /* vertical-tab */ TERM_CMD_XTERM_CLLHP, /* xterm-cursor-lower-left-hp-bugfix */ - TERM_CMD_XTERM_IHMT, /* xterm-initiate-highlight-mouse-tracking*/ + TERM_CMD_XTERM_IHMT, /* xterm-initiate-highlight-mouse-tracking */ TERM_CMD_XTERM_MLHP, /* xterm-memory-lock-hp-bugfix */ TERM_CMD_XTERM_MUHP, /* xterm-memory-unlock-hp-bugfix */ TERM_CMD_XTERM_RPM, /* xterm-restore-private-mode */ @@ -678,9 +575,76 @@ struct term_parser { bool is_host : 1; }; -int term_parser_new(term_parser **out, bool host); -term_parser *term_parser_free(term_parser *parser); -int term_parser_feed(term_parser *parser, const term_seq **seq_out, uint32_t raw); +/* + * Screens + * A term_screen object represents the terminal-side of the communication. It + * connects the term-parser and term-pages and handles all required commands. + * All state is managed by it. + */ + +enum { + TERM_FLAG_7BIT_MODE = (1U << 0), /* 7bit mode (default: on) */ + TERM_FLAG_HIDE_CURSOR = (1U << 1), /* hide cursor caret (default: off) */ + TERM_FLAG_INHIBIT_TPARM = (1U << 2), /* do not send TPARM unrequested (default: off) */ + TERM_FLAG_NEWLINE_MODE = (1U << 3), /* perform carriage-return on line-feeds (default: off) */ + TERM_FLAG_PENDING_WRAP = (1U << 4), /* wrap-around is pending */ + TERM_FLAG_KEYPAD_MODE = (1U << 5), /* application-keypad mode (default: off) */ + TERM_FLAG_CURSOR_KEYS = (1U << 6), /* enable application cursor-keys (default: off) */ +}; + +enum { + TERM_CONFORMANCE_LEVEL_VT52, + TERM_CONFORMANCE_LEVEL_VT100, + TERM_CONFORMANCE_LEVEL_VT400, + TERM_CONFORMANCE_LEVEL_CNT, +}; + +struct term_state { + unsigned int cursor_x; + unsigned int cursor_y; + term_attr attr; + term_charset **gl; + term_charset **gr; + term_charset **glt; + term_charset **grt; + + bool auto_wrap : 1; + bool origin_mode : 1; +}; + +struct term_screen { + unsigned long ref; + term_age_t age; + + term_page *page; + term_page *page_main; + term_page *page_alt; + term_history *history; + term_history *history_main; + + unsigned int n_tabs; + uint8_t *tabs; + + term_utf8 utf8; + term_parser *parser; -#define _term_parser_free_ _cleanup_(term_parser_freep) -DEFINE_TRIVIAL_CLEANUP_FUNC(term_parser*, term_parser_free); + term_screen_write_fn write_fn; + void *write_fn_data; + term_screen_cmd_fn cmd_fn; + void *cmd_fn_data; + + unsigned int flags; + unsigned int conformance_level; + term_attr default_attr; + + term_charset *g0; + term_charset *g1; + term_charset *g2; + term_charset *g3; + + char *answerback; + + term_state state; + term_state saved; + term_state saved_alt; +};