| Line | Branch | Exec | Source | 
|---|---|---|---|
| 1 | #ifndef TERMINAL_OUTPUT_H | ||
| 2 | #define TERMINAL_OUTPUT_H | ||
| 3 | |||
| 4 | #include <stdbool.h> | ||
| 5 | #include <stddef.h> | ||
| 6 | #include "color.h" | ||
| 7 | #include "style.h" | ||
| 8 | #include "terminal.h" | ||
| 9 | #include "util/macros.h" | ||
| 10 | #include "util/unicode.h" | ||
| 11 | |||
| 12 | enum { | ||
| 13 | // Minimum repeat count for which ECMA-48 REP sequence makes sense. | ||
| 14 | // STRLEN("_\033[5b") is 5 bytes and the sequence fills 6 columns. | ||
| 15 | // Any repeat count lower than 6 can be done with memset(3) in equal | ||
| 16 | // or fewer bytes. | ||
| 17 | ECMA48_REP_MIN = 6, | ||
| 18 | |||
| 19 | // Maximum repeat count for which ECMA-48 REP sequence should be used | ||
| 20 | // (fits in 15 bits, to avoid issues in terminals using int16_t params). | ||
| 21 | ECMA48_REP_MAX = 30000, | ||
| 22 | }; | ||
| 23 | |||
| 24 | typedef enum { | ||
| 25 | // Indicates that term_set_bytes() wrote 1 byte followed by an ECMA-48 | ||
| 26 | // (§8.3.103) REP sequence, in order to instruct the terminal to fill | ||
| 27 | // a run of cells with the same character | ||
| 28 | TERM_SET_BYTES_REP, | ||
| 29 | |||
| 30 | // Indicates that term_set_bytes() simply called memset(3), in order | ||
| 31 | // to fill the output buffer (and thus also the terminal) with a run | ||
| 32 | // of the same character | ||
| 33 | TERM_SET_BYTES_MEMSET, | ||
| 34 | } TermSetBytesMethod; | ||
| 35 | |||
| 36 | enum { | ||
| 37 | // Returned by term_clear_eol() to indicate that an ECMA-48 (§8.3.41) | ||
| 38 | // EL sequence was used to erase the remainder of the current line, | ||
| 39 | // instead of REP or memset(3) | ||
| 40 | TERM_CLEAR_EOL_USED_EL = -1, | ||
| 41 | }; | ||
| 42 | |||
| 43 | #define term_put_literal(buf, s) term_put_bytes(buf, s, STRLEN(s)) | ||
| 44 | |||
| 45 | #define TERM_OUTPUT_INIT { \ | ||
| 46 | .tab_mode = TAB_CONTROL, \ | ||
| 47 | .tab_width = 8, \ | ||
| 48 | .style = {.fg = COLOR_DEFAULT, .bg = COLOR_DEFAULT}, \ | ||
| 49 | .cursor_style = {.type = CURSOR_DEFAULT, .color = COLOR_DEFAULT}, \ | ||
| 50 | } | ||
| 51 | |||
| 52 | 88 | static inline size_t obuf_avail(TermOutputBuffer *obuf) | |
| 53 | { | ||
| 54 | 88 | return TERM_OUTBUF_SIZE - obuf->count; | |
| 55 | } | ||
| 56 | |||
| 57 | char *term_output_reserve_space(TermOutputBuffer *obuf, size_t count) NONNULL_ARGS_AND_RETURN WARN_UNUSED_RESULT; | ||
| 58 | void term_output_reset(Terminal *term, size_t start_x, size_t width, size_t scroll_x) NONNULL_ARGS; | ||
| 59 | void term_put_byte(TermOutputBuffer *obuf, char ch) NONNULL_ARGS; | ||
| 60 | void term_put_bytes(TermOutputBuffer *obuf, const char *str, size_t count) NONNULL_ARGS; | ||
| 61 | TermSetBytesMethod term_set_bytes(Terminal *term, char ch, size_t count) NONNULL_ARGS; | ||
| 62 | void term_put_str(TermOutputBuffer *obuf, const char *str) NONNULL_ARGS; | ||
| 63 | void term_put_initial_queries(Terminal *term, unsigned int level) NONNULL_ARGS; | ||
| 64 | void term_put_level_2_queries(Terminal *term, bool emit_all) NONNULL_ARGS; | ||
| 65 | void term_put_level_3_queries(Terminal *term, bool emit_all) NONNULL_ARGS; | ||
| 66 | void term_use_alt_screen_buffer(Terminal *term) NONNULL_ARGS; | ||
| 67 | void term_use_normal_screen_buffer(Terminal *term) NONNULL_ARGS; | ||
| 68 | void term_hide_cursor(Terminal *term) NONNULL_ARGS; | ||
| 69 | void term_show_cursor(Terminal *term) NONNULL_ARGS; | ||
| 70 | void term_begin_sync_update(Terminal *term) NONNULL_ARGS; | ||
| 71 | void term_end_sync_update(Terminal *term) NONNULL_ARGS; | ||
| 72 | void term_move_cursor(TermOutputBuffer *obuf, unsigned int x, unsigned int y) NONNULL_ARGS; | ||
| 73 | void term_save_title(Terminal *term) NONNULL_ARGS; | ||
| 74 | void term_restore_title(Terminal *term) NONNULL_ARGS; | ||
| 75 | void term_restore_and_save_title(Terminal *term) NONNULL_ARGS; | ||
| 76 | bool term_can_clear_eol_with_el_sequence(const Terminal *term) NONNULL_ARGS; | ||
| 77 | int term_clear_eol(Terminal *term) NONNULL_ARGS; | ||
| 78 | void term_clear_screen(TermOutputBuffer *obuf) NONNULL_ARGS; | ||
| 79 | void term_output_flush(TermOutputBuffer *obuf) NOINLINE NONNULL_ARGS; | ||
| 80 | bool term_put_char(TermOutputBuffer *obuf, CodePoint u) NONNULL_ARGS; | ||
| 81 | void term_set_style(Terminal *term, TermStyle style) NONNULL_ARGS; | ||
| 82 | void term_set_cursor_style(Terminal *term, TermCursorStyle style) NONNULL_ARGS; | ||
| 83 | |||
| 84 | #endif | ||
| 85 |