ascii-chat 0.11.33
Video chat in your terminal
Loading...
Searching...
No Matches
terminal.c File Reference

Terminal abstraction for WASM/Emscripten via EM_JS bridge web. More...

Go to the source code of this file.

Functions

void terminal_get_default_foreground_color (int theme, uint8_t *r, uint8_t *g, uint8_t *b)
 Get theme-aware default foreground color for pixel renderers.
 
void terminal_get_default_background_color (int theme, uint8_t *r, uint8_t *g, uint8_t *b)
 Get theme-aware default background color for pixel renderers.
 
int platform_get_terminal_size (int *cols, int *rows)
 
int platform_write_terminal (const char *data, size_t len)
 
int platform_set_terminal_raw_mode (bool enable)
 
int platform_read_keyboard (char *buffer, size_t len)
 
bool platform_is_terminal (int fd)
 
int platform_get_cursor_position (int *row, int *col)
 
int platform_set_cursor_position (int row, int col)
 
asciichat_error_t get_terminal_size (unsigned short int *width, unsigned short int *height)
 Get terminal size with multiple fallback methods.
 
bool terminal_supports_utf8 (void)
 Check if terminal supports UTF-8.
 
bool terminal_is_piped_output (void)
 Check if stdout is piped or redirected.
 
bool terminal_should_color_output (int fd)
 Determine if color output should be used.
 
bool terminal_is_stdin_tty (void)
 Check if stdin is connected to a TTY.
 
bool terminal_is_stdout_tty (void)
 Check if stdout is connected to a TTY.
 
bool terminal_is_stderr_tty (void)
 Check if stderr is connected to a TTY.
 
bool terminal_is_interactive (void)
 Check if the session is fully interactive.
 
bool terminal_should_force_stderr (void)
 Determine if logs should be forced to stderr.
 
bool terminal_can_prompt_user (void)
 Determine if interactive user prompts are appropriate.
 
bool terminal_has_dark_background (void)
 Detect if terminal theme is dark.
 
asciichat_error_t terminal_flush (int fd)
 Flush terminal output.
 
terminal_capabilities_t detect_terminal_capabilities (void)
 Detect terminal capabilities.
 
bool terminal_query_background_color (uint8_t *bg_r, uint8_t *bg_g, uint8_t *bg_b)
 Query terminal background color using OSC 11 escape sequence.
 
asciichat_error_t terminal_set_echo (bool enabled)
 Set terminal echo mode.
 
bool terminal_should_use_control_sequences (int fd)
 Check if terminal control sequences should be used for the given fd.
 
asciichat_error_t terminal_clear_screen (void)
 Clear the terminal screen.
 
asciichat_error_t terminal_cursor_home (int fd)
 Move cursor to home position (top-left)
 
asciichat_error_t terminal_move_cursor_relative (int offset)
 Move cursor relative to current position.
 

Detailed Description

Terminal abstraction for WASM/Emscripten via EM_JS bridge web.

Definition in file platform/wasm/terminal.c.

Function Documentation

◆ detect_terminal_capabilities()

terminal_capabilities_t detect_terminal_capabilities ( void  )

Detect terminal capabilities.

Returns
Terminal capabilities structure with all detected features

Comprehensively detects terminal capabilities including:

  • Color support level (none, 16, 256, truecolor)
  • UTF-8 encoding support
  • Terminal type and environment variables
  • Render mode preferences
  • Detection reliability

Detection uses multiple methods:

  • Environment variable analysis ($TERM, $COLORTERM, $LC_ALL, $LANG)
  • Terminal type database lookups
  • Runtime capability queries (where available)
Note
Returns a structure with all detected capabilities.
Detection reliability is indicated by detection_reliable field.
Use apply_color_mode_override() to apply command-line overrides.

Definition at line 169 of file platform/wasm/terminal.c.

169 {
170 terminal_capabilities_t caps = {0};
172 caps.capabilities = 0;
173 caps.color_count = 16777216;
174 caps.utf8_support = true;
175 caps.detection_reliable = true;
176 caps.render_mode = RENDER_MODE_FOREGROUND; // Default to foreground mode
177 platform_strlcpy(caps.term_type, "xterm-256color", sizeof(caps.term_type));
178 platform_strlcpy(caps.colorterm, "truecolor", sizeof(caps.colorterm));
179 caps.wants_background = true;
180 caps.palette_type = 0; // Default palette
181 // Browser rendering uses requestAnimationFrame and supports the same
182 // 60 FPS default as the native terminal paths.
185 return caps;
186}
#define DEFAULT_MAX_FPS
Default maximum frame rate (frames per second)
Definition limits.h:29
size_t platform_strlcpy(char *dst, const char *src, size_t size)
Safe string copy with size tracking (strlcpy)
Complete terminal capabilities structure.
Definition terminal.h:709
int palette_type
Palette type enum value (palette_type_t)
Definition terminal.h:729
terminal_color_mode_t color_level
Detected color support level (terminal_color_mode_t)
Definition terminal.h:711
uint8_t desired_fps
Client's desired frame rate (1-144 FPS)
Definition terminal.h:733
render_mode_t render_mode
Preferred rendering mode (render_mode_t)
Definition terminal.h:721
bool utf8_support
True if terminal supports UTF-8 encoding.
Definition terminal.h:717
uint32_t capabilities
Capability flags bitmask (terminal_capability_flags_t)
Definition terminal.h:713
uint32_t color_count
Maximum number of colors (2, 16, 256, or 16777216)
Definition terminal.h:715
color_filter_t color_filter
Monochromatic color filter enum value (color_filter_t)
Definition terminal.h:735
char term_type[64]
$TERM environment variable value (for debugging)
Definition terminal.h:723
char colorterm[64]
$COLORTERM environment variable value (for debugging)
Definition terminal.h:725
bool detection_reliable
True if detection is confident (reliable detection)
Definition terminal.h:719
bool wants_background
True if background colors are preferred.
Definition terminal.h:727
@ COLOR_FILTER_NONE
No filtering (default)
Definition terminal.h:601
@ RENDER_MODE_FOREGROUND
Foreground colors only (text color)
Definition terminal.h:664
@ TERM_COLOR_TRUECOLOR
24-bit truecolor support (RGB colors)
Definition terminal.h:588

References terminal_capabilities_t::capabilities, terminal_capabilities_t::color_count, terminal_capabilities_t::color_filter, COLOR_FILTER_NONE, terminal_capabilities_t::color_level, terminal_capabilities_t::colorterm, DEFAULT_MAX_FPS, terminal_capabilities_t::desired_fps, terminal_capabilities_t::detection_reliable, terminal_capabilities_t::palette_type, platform_strlcpy(), terminal_capabilities_t::render_mode, RENDER_MODE_FOREGROUND, TERM_COLOR_TRUECOLOR, terminal_capabilities_t::term_type, terminal_capabilities_t::utf8_support, and terminal_capabilities_t::wants_background.

Referenced by action_show_capabilities_immediate(), log_redetect_terminal_capabilities(), main(), session_display_create(), and threaded_send_terminal_size_with_auto_detect().

◆ get_terminal_size()

asciichat_error_t get_terminal_size ( unsigned short int *  width,
unsigned short int *  height 
)

Get terminal size with multiple fallback methods.

Parameters
widthPointer to store width in columns (must not be NULL)
heightPointer to store height in rows (must not be NULL)
Returns
ASCIICHAT_OK on success, error code on failure

Detects terminal size using multiple fallback methods for reliability:

  1. Terminal size query (ioctl TIOCGWINSZ on Unix, Console API on Windows)
  2. Environment variable fallback ($COLUMNS, $LINES)
  3. Default size fallback (80x24) if all methods fail
Note
On failure, output parameters are not modified.
Terminal size may change if terminal is resized.
This function is more reliable than terminal_get_size() due to fallbacks.

Definition at line 103 of file platform/wasm/terminal.c.

103 {
104 if (!width || !height) {
105 return ERROR_INVALID_PARAM;
106 }
107 int cols, rows;
108 if (platform_get_terminal_size(&cols, &rows) != 0) {
109 return ERROR_PLATFORM_INIT;
110 }
111 *width = (unsigned short int)cols;
112 *height = (unsigned short int)rows;
113 return ASCIICHAT_OK;
114}
@ ERROR_PLATFORM_INIT
Definition error_codes.h:60
@ ASCIICHAT_OK
Definition error_codes.h:51
@ ERROR_INVALID_PARAM
int platform_get_terminal_size(int *cols, int *rows)

References ASCIICHAT_OK, ERROR_INVALID_PARAM, ERROR_PLATFORM_INIT, and platform_get_terminal_size().

Referenced by session_render_loop(), update_dimensions_for_full_height(), and update_dimensions_to_terminal_size().

◆ platform_get_cursor_position()

int platform_get_cursor_position ( int *  row,
int *  col 
)

Definition at line 90 of file platform/wasm/terminal.c.

90 {
91 (void)row;
92 (void)col;
93 return -1; // Not supported in WASM
94}

◆ platform_get_terminal_size()

int platform_get_terminal_size ( int *  cols,
int *  rows 
)

Definition at line 56 of file platform/wasm/terminal.c.

56 {
57 if (!cols || !rows) {
58 return -1;
59 }
60 *cols = js_get_terminal_cols();
61 *rows = js_get_terminal_rows();
62 return 0;
63}

Referenced by get_terminal_size().

◆ platform_is_terminal()

bool platform_is_terminal ( int  fd)

Definition at line 85 of file platform/wasm/terminal.c.

85 {
86 (void)fd;
87 return true; // Always true for WASM terminal
88}

◆ platform_read_keyboard()

int platform_read_keyboard ( char *  buffer,
size_t  len 
)

Definition at line 79 of file platform/wasm/terminal.c.

79 {
80 (void)buffer;
81 (void)len;
82 return -1; // Not supported: use JavaScript event listeners
83}

◆ platform_set_cursor_position()

int platform_set_cursor_position ( int  row,
int  col 
)

Definition at line 96 of file platform/wasm/terminal.c.

96 {
97 (void)row;
98 (void)col;
99 return -1; // Not supported in WASM
100}

◆ platform_set_terminal_raw_mode()

int platform_set_terminal_raw_mode ( bool  enable)

Definition at line 74 of file platform/wasm/terminal.c.

74 {
75 (void)enable;
76 return 0;
77}

◆ platform_write_terminal()

int platform_write_terminal ( const char *  data,
size_t  len 
)

Definition at line 68 of file platform/wasm/terminal.c.

68 {
69 js_terminal_write(data, (int)len);
70 return (int)len;
71}

◆ terminal_can_prompt_user()

bool terminal_can_prompt_user ( void  )

Determine if interactive user prompts are appropriate.

Returns
true if prompts can be shown, false if non-interactive/automated

Determines whether interactive user prompts (yes/no, passwords, confirmations) should be displayed. Returns false in non-interactive or automated contexts.

Use this to decide whether:

  • Password prompts should be shown (or auto-cancel)
  • Yes/No confirmations should wait for input (or use defaults)
  • Known hosts prompts should be interactive (or auto-deny)

Logic:

  1. If not fully interactive (stdin or stdout not TTY) → false
  2. If in snapshot mode (–snapshot) → false
  3. If ASCII_CHAT_QUESTION_PROMPT_RESPONSE set → false (automated responses)
  4. Otherwise → true (interactive prompts OK)

Examples:

  • ascii-chat client in terminal → true (can prompt)
  • ascii-chat client --snapshot → false (non-interactive mode)
  • echo data | ascii-chat client → false (stdin piped)
  • ‘ASCII_CHAT_QUESTION_PROMPT_RESPONSE='y’ ascii-chat client→ false (automated) -ascii-chat client > output.txt` → false (stdout redirected)
Note
Combines checks for: TTY status, snapshot mode, automation env vars
Used by password prompts, known_hosts verification, user confirmations
When false, password prompts should auto-cancel with error
When false, yes/no prompts should use default value or deny

Definition at line 153 of file platform/wasm/terminal.c.

153 {
154 return false; // Cannot prompt in WASM
155}

◆ terminal_get_default_background_color()

void terminal_get_default_background_color ( int  theme,
uint8_t *  r,
uint8_t *  g,
uint8_t *  b 
)

Get theme-aware default background color for pixel renderers.

Parameters
themeTerminal theme (0=dark, 1=light, 2=auto)
out_rPointer to store red component (0-255)
out_gPointer to store green component (0-255)
out_bPointer to store blue component (0-255)

Used by both Linux and macOS renderers for consistent color selection. Returns appropriate background color based on terminal theme.

Get theme-aware default background color for pixel renderers.

Parameters
themeTerminal theme (dark or light)
out_rPointer to store red component (0-255)
out_gPointer to store green component (0-255)
out_bPointer to store blue component (0-255)

Returns appropriate default background color based on terminal theme. Light theme uses white background, dark theme uses black background.

Definition at line 46 of file platform/wasm/terminal.c.

46 {
48 if (r)
49 *r = value;
50 if (g)
51 *g = value;
52 if (b)
53 *b = value;
54}
unsigned char uint8_t
Definition common.h:56
#define TERMINAL_COLOR_THEME_LIGHT_BG_R
Default background color for light theme (RGB)
Definition terminal.h:135
#define TERMINAL_COLOR_THEME_DARK_BG_R
Default background color for dark theme (RGB)
Definition terminal.h:144

References TERMINAL_COLOR_THEME_DARK_BG_R, and TERMINAL_COLOR_THEME_LIGHT_BG_R.

◆ terminal_get_default_foreground_color()

void terminal_get_default_foreground_color ( int  theme,
uint8_t *  r,
uint8_t *  g,
uint8_t *  b 
)

Get theme-aware default foreground color for pixel renderers.

Parameters
themeTerminal theme (0=dark, 1=light, 2=auto)
out_rPointer to store red component (0-255)
out_gPointer to store green component (0-255)
out_bPointer to store blue component (0-255)

Used by both Linux and macOS renderers for consistent color selection. Returns appropriate text color based on terminal theme.

Get theme-aware default foreground color for pixel renderers.

Parameters
themeTerminal theme (dark or light)
out_rPointer to store red component (0-255)
out_gPointer to store green component (0-255)
out_bPointer to store blue component (0-255)

Returns appropriate default text color based on terminal theme. Both Linux and macOS renderers use this for consistent color selection.

Definition at line 36 of file platform/wasm/terminal.c.

36 {
38 if (r)
39 *r = value;
40 if (g)
41 *g = value;
42 if (b)
43 *b = value;
44}
#define TERMINAL_COLOR_THEME_DARK_FG_R
Default text color for dark theme (RGB)
Definition terminal.h:126
#define TERMINAL_COLOR_THEME_LIGHT_FG_R
Platform-specific getopt include.
Definition terminal.h:116

References TERMINAL_COLOR_THEME_DARK_FG_R, and TERMINAL_COLOR_THEME_LIGHT_FG_R.

◆ terminal_has_dark_background()

bool terminal_has_dark_background ( void  )

Detect if terminal theme is dark.

Returns
true if terminal has a dark theme, false if light theme or unknown

Attempts to detect terminal's color theme (dark or light background) using:

  1. OSC 11 escape sequence query with luminance calculation (modern terminals)
  2. Common environment variables (COLORFGBG, TERM_PROGRAM)
  3. Terminal-specific hints (iTerm2, VS Code, Konsole, etc.)
  4. Defaults to dark theme (most common for developer terminals)

Used by the theme system to select appropriate colors throughout the UI:

  • Color schemes adapt based on detected theme
  • Highlight colors choose better contrast for the detected theme
  • Text colors are selected to work with the background theme
Note
This is a best-effort heuristic and may not be 100% accurate
Result is cached for performance (theme doesn't change during session)
User can override via TERM_BACKGROUND environment variable

Definition at line 158 of file platform/wasm/terminal.c.

158 {
159 return true; // Default to dark background for terminals
160}

Referenced by detect_terminal_background(), and render_file_create().

◆ terminal_is_interactive()

bool terminal_is_interactive ( void  )

Check if the session is fully interactive.

Returns
true if BOTH stdin AND stdout are TTYs, false otherwise

Determines whether the session is fully interactive (user at terminal). Returns true only when BOTH stdin and stdout are connected to TTYs.

Use this to decide whether:

  • User prompts and interactive input should be shown
  • Splash screens and animations should be displayed
  • Frame padding should be enabled
  • Password prompts are appropriate

Examples:

  • ascii-chat mirror in terminal → true (interactive)
  • ascii-chat mirror | less → false (stdout piped)
  • cat file | ascii-chat client → false (stdin piped)
  • ascii-chat client < input.txt > output.txt → false (both piped)
Note
Equivalent to: terminal_is_stdin_tty() && terminal_is_stdout_tty()
Used for enabling interactive features (prompts, padding, splash)
Snapshot mode is checked separately via GET_OPTION(snapshot_mode)

Definition at line 145 of file platform/wasm/terminal.c.

145 {
146 return false; // WASM mirror mode is not interactive
147}

◆ terminal_is_piped_output()

bool terminal_is_piped_output ( void  )

Check if stdout is piped or redirected.

Returns
true if stdout is piped/redirected, false if connected to TTY

Determines whether standard output is being piped or redirected to a file. This is the logical inverse of terminal_is_stdout_tty().

Use this to decide whether:

  • Logs should be forced to stderr (to avoid corrupting piped output)
  • Frame padding should be disabled
  • Clean, parseable output should be preferred

Examples:

  • ascii-chat mirror > output.txt → true (redirected)
  • ascii-chat client | grep pattern → true (piped)
  • ascii-chat mirror in terminal → false (TTY)
Note
Equivalent to: !terminal_is_stdout_tty()
Common pattern: force stderr when piped to prevent data corruption

Definition at line 122 of file platform/wasm/terminal.c.

122 {
123 return false; // WASM mirror mode is not piped
124}

◆ terminal_is_stderr_tty()

bool terminal_is_stderr_tty ( void  )

Check if stderr is connected to a TTY.

Returns
true if stderr is a TTY, false otherwise

Determines whether standard error is connected to a terminal device. Returns false when stderr is piped or redirected to a file.

Use this to decide whether diagnostic messages should include colors.

Note
Wrapper around platform_isatty(STDERR_FILENO) for clarity
stderr is often a TTY even when stdout is piped

Definition at line 141 of file platform/wasm/terminal.c.

141 {
142 return true;
143}

◆ terminal_is_stdin_tty()

bool terminal_is_stdin_tty ( void  )

Check if stdin is connected to a TTY.

Returns
true if stdin is a TTY (can read interactive input), false otherwise

Determines whether standard input is connected to a terminal device. Returns false when stdin is piped or redirected from a file.

Use this to decide whether interactive input (prompts, keyboard events) is possible.

Note
Wrapper around platform_isatty(STDIN_FILENO) for clarity
Returns false in non-interactive environments (CI, scripts, pipes)

Definition at line 133 of file platform/wasm/terminal.c.

133 {
134 return false; // No stdin in WASM
135}

◆ terminal_is_stdout_tty()

bool terminal_is_stdout_tty ( void  )

Check if stdout is connected to a TTY.

Returns
true if stdout is a TTY (not piped/redirected), false otherwise

Determines whether standard output is connected to a terminal device. Returns false when stdout is piped or redirected to a file.

Use this to decide whether:

  • Terminal control sequences (colors, cursor movement) should be used
  • Output padding/formatting should be applied
  • Progress bars or animations should be shown
Note
Wrapper around platform_isatty(STDOUT_FILENO) for clarity
Returns false in piped contexts (e.g., ascii-chat client | less)

Definition at line 137 of file platform/wasm/terminal.c.

137 {
138 return true;
139}

◆ terminal_query_background_color()

bool terminal_query_background_color ( uint8_t *  bg_r,
uint8_t *  bg_g,
uint8_t *  bg_b 
)

Query terminal background color using OSC 11 escape sequence.

Parameters
bg_rPointer to store red component (0-255)
bg_gPointer to store green component (0-255)
bg_bPointer to store blue component (0-255)
Returns
true if successful, false if query failed or timed out

Sends OSC 11 query to terminal and parses RGB response. Works with modern terminals (iTerm2, kitty, Konsole, etc.) Returns false if terminal doesn't support OSC 11 or times out.

Note
Requires raw terminal mode to read response
Has 100ms timeout to prevent hanging
Only works if stdout is a TTY

Definition at line 189 of file platform/wasm/terminal.c.

189 {
190 // Return dark background (black)
191 if (bg_r)
192 *bg_r = 0;
193 if (bg_g)
194 *bg_g = 0;
195 if (bg_b)
196 *bg_b = 0;
197 return true;
198}

◆ terminal_should_color_output()

bool terminal_should_color_output ( int  fd)

Determine if color output should be used.

Priority order:

  1. If –color flag is set → ALWAYS use colors (force override)
  2. If CLAUDECODE env var is set → NEVER use colors (LLM automation)
  3. If output is not a TTY (piping) → NO colors
  4. If –color-mode=none → NO colors (user choice)
  5. Otherwise → Use colors
Parameters
fdFile descriptor to check (STDOUT_FILENO or STDERR_FILENO)
Returns
true if colors should be used, false otherwise

Definition at line 127 of file platform/wasm/terminal.c.

127 {
128 (void)fd;
129 return true; // WASM mirror mode supports color
130}

◆ terminal_should_force_stderr()

bool terminal_should_force_stderr ( void  )

Determine if logs should be forced to stderr.

Returns
true if logs should go to stderr only, false if stdout is acceptable

Determines whether logging output should be forced to stderr instead of stdout. Returns true when stdout is piped/redirected (to avoid corrupting output data).

Use this to decide whether to call log_set_force_stderr(true).

Logic:

  1. If stdout is piped/redirected → force stderr (true)
  2. If in TESTING environment → allow stdout (false)
  3. Otherwise → allow stdout (false)

Examples:

  • ascii-chat mirror > frames.txt → true (don't corrupt frame data)
  • ascii-chat mirror in terminal → false (stdout is fine)
  • TESTING=1 ascii-chat mirror → false (tests may capture stdout)
Note
This prevents logs from corrupting piped ASCII frame data
TESTING environment variable bypasses this for test environments
Typical usage: if (terminal_should_force_stderr()) log_set_force_stderr(true);

Definition at line 149 of file platform/wasm/terminal.c.

149 {
150 return false; // Don't force stderr in WASM
151}

◆ terminal_should_use_control_sequences()

bool terminal_should_use_control_sequences ( int  fd)

Check if terminal control sequences should be used for the given fd.

Parameters
fdFile descriptor to check (must be valid or -1)
Returns
true if terminal control sequences should be used, false otherwise

Determines whether terminal control sequences (cursor home, clear screen, etc.) should be sent to the given file descriptor. Checks:

  1. File descriptor is valid (>= 0)
  2. Not in snapshot mode
  3. Not in TESTING environment
  4. File descriptor is connected to a TTY (not piped/redirected)

This is useful for deciding whether to send ANSI escape sequences to output. When piped or redirected, escape sequences should not be sent.

Note
Returns false if fd is invalid (-1) to be safe.
Returns false in snapshot mode to provide clean output.
Checks TESTING environment variable for test/CI environments.
Primary use case: determining if output is going to a TTY.
Parameters
fdFile descriptor to check
Returns
true if terminal control sequences should be used, false otherwise

This function determines whether to send terminal POSITIONING and CONTROL sequences (cursor home, clear screen, hide cursor, etc.) which should only be sent to TTY and never to pipes/redirected output.

Note: This does NOT control ANSI COLOR CODES, which are controlled by –color-mode option and may be sent to pipes if explicitly requested.

Definition at line 217 of file platform/wasm/terminal.c.

217 {
218 (void)fd;
219 return true; // Always use ANSI sequences in browser
220}