Line data Source code
1 : #ifndef PLATFORM_TERMINAL_H
2 : #define PLATFORM_TERMINAL_H
3 :
4 : #include <stddef.h>
5 : #include <stdint.h>
6 :
7 : /** Logical key codes returned by terminal_read_key(). */
8 : typedef enum {
9 : TERM_KEY_QUIT = 0, /* Ctrl-C */
10 : TERM_KEY_NEXT_PAGE = 1, /* PgDn */
11 : TERM_KEY_PREV_PAGE = 2, /* PgUp */
12 : TERM_KEY_NEXT_LINE = 3, /* Down-arrow */
13 : TERM_KEY_PREV_LINE = 4, /* Up-arrow */
14 : TERM_KEY_IGNORE = 5, /* unknown / Space */
15 : TERM_KEY_ENTER = 6, /* Enter (\n or \r) */
16 : TERM_KEY_ESC = 7, /* bare ESC */
17 : TERM_KEY_BACK = 8, /* Backspace / DEL */
18 : TERM_KEY_TAB = 9, /* Tab (\t) */
19 : TERM_KEY_LEFT = 10, /* Left arrow */
20 : TERM_KEY_RIGHT = 11, /* Right arrow */
21 : TERM_KEY_HOME = 12, /* Home key */
22 : TERM_KEY_END = 13, /* End key */
23 : TERM_KEY_DELETE = 14, /* Delete (forward delete) */
24 : TERM_KEY_SHIFT_TAB = 15 /* Shift+Tab (backtab, ESC[Z) */
25 : } TermKey;
26 :
27 : /** Opaque saved terminal state (used for raw-mode enter/exit). */
28 : typedef struct TermRawState TermRawState;
29 :
30 : /** Returns the terminal width in columns, or 80 if unknown. */
31 : int terminal_cols(void);
32 :
33 : /** Returns the terminal height in rows, or 0 if unknown. */
34 : int terminal_rows(void);
35 :
36 : /** Returns 1 if fd is connected to a terminal, 0 otherwise. */
37 : int terminal_is_tty(int fd);
38 :
39 : /**
40 : * Save current terminal mode and enter raw mode
41 : * (no echo, no canonical, no signal generation).
42 : * Returns an allocated TermRawState on success, NULL on failure.
43 : * Caller must call terminal_raw_exit() to restore and free.
44 : */
45 : TermRawState *terminal_raw_enter(void);
46 :
47 : /**
48 : * Restore the terminal to the state saved in *state and free it.
49 : * Sets *state = NULL. Safe to call with NULL or *state == NULL.
50 : */
51 : void terminal_raw_exit(TermRawState **state);
52 :
53 : /** RAII cleanup wrapper for terminal_raw_exit. */
54 41 : static inline void terminal_raw_exit_ptr(TermRawState **p) {
55 41 : terminal_raw_exit(p);
56 41 : }
57 : #define RAII_TERM_RAW __attribute__((cleanup(terminal_raw_exit_ptr)))
58 :
59 : /**
60 : * Read one keypress and return a TermKey code.
61 : * The terminal must already be in raw mode.
62 : * Fully consumes multi-byte escape sequences.
63 : */
64 : TermKey terminal_read_key(void);
65 :
66 : /**
67 : * Returns the last printable ASCII character (32–126) that caused
68 : * terminal_read_key() to return TERM_KEY_IGNORE.
69 : * Returns 0 if the last ignored keystroke was not a printable character.
70 : */
71 : int terminal_last_printable(void);
72 :
73 : /**
74 : * Display column width of Unicode codepoint cp.
75 : * Returns 0 for non-printable/control characters,
76 : * 1 for normal characters, 2 for wide (CJK/emoji) characters.
77 : */
78 : int terminal_wcwidth(uint32_t cp);
79 :
80 : /**
81 : * Prompt for a password with echo suppressed.
82 : * Writes at most size-1 bytes to buf (NUL-terminated).
83 : * Returns the number of characters read, or -1 on error.
84 : */
85 : int terminal_read_password(const char *prompt, char *buf, size_t size);
86 :
87 : #endif /* PLATFORM_TERMINAL_H */
|