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

📊 Status screen display and management for server/discovery service modes More...

Go to the source code of this file.

Data Structures

struct  ui_status_t
 Status information for server/discovery service modes. More...
 

Functions

asciichat_error_t ui_status_gather (tcp_server_t *server, const char *session_string, const char *ipv4_address, const char *ipv6_address, uint16_t port, time_t start_time, const char *mode_name, bool session_is_mdns_only, ui_status_t *out_status)
 Gather current status information.
 
void ui_status_display (const ui_status_t *status)
 Display status screen.
 
bool ui_status_display_interactive (const ui_status_t *status)
 Display status screen with interactive keyboard support.
 
void ui_status_update (tcp_server_t *server, const char *session_string, const char *ipv4_address, const char *ipv6_address, uint16_t port, time_t start_time, const char *mode_name, bool session_is_mdns_only, uint64_t *last_update_ns)
 Periodically update status display with live logs at FPS rate.
 
void ui_status_log_init (void)
 Initialize status screen log capture system.
 
void ui_status_log_destroy (void)
 Cleanup status screen log capture system.
 
void ui_status_log_append (const char *message)
 Append a log message to status screen buffer.
 
void ui_status_log_clear (void)
 Clear all log messages from status screen buffer.
 

Detailed Description

📊 Status screen display and management for server/discovery service modes

Manages periodic display of status information including:

  • Session string (memorable 3-word string)
  • Bind addresses (IPv4 and IPv6)
  • Connected client/server count
  • Server uptime

The status screen is updated periodically from the TCP server accept loop via callback and can be disabled with –no-status-screen flag.

Author
Zachary Fogg me@zf.nosp@m.o.gg
Date
February 2026

Definition in file status.h.

Function Documentation

◆ ui_status_display()

void ui_status_display ( const ui_status_t *  status)

Display status screen.

Outputs formatted status to stdout. Uses ANSI escape codes for clean display that doesn't interfere with logging output.

Parameters
statusStatus information

Definition at line 194 of file status.c.

194 {
195 if (!status) {
196 return;
197 }
198
199 // Only render the status screen if:
200 // 1. Terminal is interactive (default behavior), OR
201 // 2. User explicitly set --status-screen on command line (force it regardless of terminal)
202 // In non-interactive mode without explicit flag, logs flow to stdout/stderr normally
203 if (!terminal_is_interactive() && !GET_OPTION(status_screen_explicitly_set)) {
204 return;
205 }
206
207 // Redirect status screen to stderr when stdout is piped (not a TTY).
208 // This keeps stdout clean for frame data while status goes to stderr.
209 // Uses platform_isatty() so non-desktop platforms (iOS, WASM) can override.
210 if (!platform_isatty(STDOUT_FILENO)) {
211 terminal_screen_set_output_fd(STDERR_FILENO);
212 }
213
214 // If --grep pattern was provided, enter interactive grep mode with it pre-populated
215 // Only do this once (check if not already entering)
216 static bool grep_mode_entered = false;
217 if (!grep_mode_entered && grep_get_last_pattern() && grep_get_last_pattern()[0] != '\0') {
219 grep_mode_entered = true;
220 }
221
222 // Use terminal_screen abstraction for rendering
223 terminal_screen_config_t config = {
225 .render_header = render_ui_status_header,
226 .user_data = (void *)status,
227 .show_logs = true,
228 };
229
230 terminal_screen_render(&config);
231}
const char * grep_get_last_pattern(void)
Get the last (most recent) filter pattern string.
Definition grep.c:1326
#define GET_OPTION(field)
Safely get a specific option field (lock-free read)
bool terminal_is_interactive(void)
Check if the session is fully interactive.
void log_search_enter_mode(void)
Enter search mode (user pressed '/')
Definition search.c:214
Configuration for terminal screen rendering.
int fixed_header_lines
How many lines the header takes (e.g., 4 for status, 8 for splash)
void terminal_screen_render(const terminal_screen_config_t *config)
Render a terminal screen with fixed header and scrolling logs.
void terminal_screen_set_output_fd(int fd)
Set output file descriptor for terminal screens (splash/status)
int platform_isatty(int fd)
Check if a file descriptor is a terminal.
Definition util.c:63

References terminal_screen_config_t::fixed_header_lines, GET_OPTION, grep_get_last_pattern(), log_search_enter_mode(), platform_isatty(), terminal_is_interactive(), terminal_screen_render(), and terminal_screen_set_output_fd().

Referenced by ui_status_update().

◆ ui_status_display_interactive()

bool ui_status_display_interactive ( const ui_status_t *  status)

Display status screen with interactive keyboard support.

Renders status screen and handles keyboard input:

  • Escape cancels grep if active, otherwise exits status screen
  • Other keys handled by interactive grep if active
Parameters
statusStatus information
Returns
true if status screen should continue, false if user pressed Escape to exit

Display status screen with interactive keyboard support.

Definition at line 237 of file status.c.

237 {
238 if (!status) {
239 return true;
240 }
241
242 // Only render the status screen if:
243 // 1. Terminal is interactive (default behavior), OR
244 // 2. User explicitly set --status-screen on command line (force it regardless of terminal)
245 // In non-interactive mode without explicit flag, logs flow to stdout/stderr normally
246 if (!terminal_is_interactive() && !GET_OPTION(status_screen_explicitly_set)) {
247 return true;
248 }
249
250 // If --grep pattern was provided, enter interactive grep mode with it pre-populated
251 static bool grep_mode_entered = false;
252 if (!grep_mode_entered && grep_get_last_pattern() && grep_get_last_pattern()[0] != '\0') {
254 grep_mode_entered = true;
255 }
256
257 // Initialize keyboard for interactive grep
258 bool keyboard_enabled = false;
259 if (keyboard_init() == ASCIICHAT_OK) {
260 keyboard_enabled = true;
261 }
262
263 // Use terminal_screen abstraction for rendering
264 terminal_screen_config_t config = {
266 .render_header = render_ui_status_header,
267 .user_data = (void *)status,
268 .show_logs = true,
269 };
270
271 terminal_screen_render(&config);
272
273 // Poll keyboard for Escape to exit or for interactive grep
274 bool should_exit_status = false;
275 if (keyboard_enabled) {
277 if (key == KEY_ESCAPE) {
278 // Escape key: cancel grep if active, otherwise exit status screen
279 if (log_search_is_active()) {
280 log_search_exit_mode(false); // Cancel grep without applying
281 } else {
282 should_exit_status = true; // Exit status screen
283 }
284 } else if (key != KEY_NONE && log_search_should_handle(key)) {
286 }
287 }
288
289 // Cleanup keyboard
290 if (keyboard_enabled) {
292 }
293
294 return !should_exit_status; // Return false if user wants to exit
295}
@ ASCIICHAT_OK
Definition error_codes.h:51
asciichat_error_t keyboard_init(void)
Initialize keyboard input system.
keyboard_key_t keyboard_read_nonblocking(void)
Read next keyboard input without blocking.
void keyboard_destroy(void)
Cleanup keyboard input system and restore terminal.
keyboard_key_t
Unified keyboard key code enumeration.
Definition keyboard.h:54
@ KEY_ESCAPE
Escape key (ESC)
Definition keyboard.h:56
@ KEY_NONE
No key pressed or no input available.
Definition keyboard.h:55
bool log_search_is_active(void)
Check if filtering is active.
Definition search.c:390
void log_search_exit_mode(bool accept)
Exit search mode.
Definition search.c:287
bool log_search_should_handle(int key)
Check if a key should be handled by grep module.
Definition search.c:399
asciichat_error_t log_search_handle_key(keyboard_key_t key)
Process keyboard input for grep.
Definition search.c:414

References ASCIICHAT_OK, terminal_screen_config_t::fixed_header_lines, GET_OPTION, grep_get_last_pattern(), KEY_ESCAPE, KEY_NONE, keyboard_destroy(), keyboard_init(), keyboard_read_nonblocking(), log_search_enter_mode(), log_search_exit_mode(), log_search_handle_key(), log_search_is_active(), log_search_should_handle(), terminal_is_interactive(), and terminal_screen_render().

◆ ui_status_gather()

asciichat_error_t ui_status_gather ( tcp_server_t *  server,
const char *  session_string,
const char *  ipv4_address,
const char *  ipv6_address,
uint16_t  port,
time_t  start_time,
const char *  mode_name,
bool  session_is_mdns_only,
ui_status_t *  out_status 
)

Gather current status information.

Collects current status information including connected count, bind addresses, and session string.

Parameters
serverInitialized TCP server structure
session_stringMemorable session string
ipv4_addressIPv4 bind address (can be NULL or empty)
ipv6_addressIPv6 bind address (can be NULL or empty)
portTCP listen port
start_timeServer start time
mode_nameMode name for display (e.g., "Server")
session_is_mdns_onlyWhether session is mDNS-only or ACDS
[out]out_statusOutput status structure
Returns
ASCIICHAT_OK on success

Definition at line 52 of file status.c.

54 {
55 if (!server || !out_status || !mode_name) {
56 return SET_ERRNO(ERROR_INVALID_PARAM, "Invalid parameters for ui_status_gather");
57 }
58
59 memset(out_status, 0, sizeof(*out_status));
60
61 // Copy session string
62 if (session_string) {
63 SAFE_STRNCPY(out_status->session_string, session_string, sizeof(out_status->session_string));
64 }
65
66 // Format IPv4 address
67 out_status->ipv4_bound = (ipv4_address && ipv4_address[0] != '\0');
68 if (out_status->ipv4_bound) {
69 snprintf(out_status->ipv4_address, sizeof(out_status->ipv4_address), "%s:%u", ipv4_address, port);
70 }
71
72 // Format IPv6 address
73 out_status->ipv6_bound = (ipv6_address && ipv6_address[0] != '\0');
74 if (out_status->ipv6_bound) {
75 snprintf(out_status->ipv6_address, sizeof(out_status->ipv6_address), "[%s]:%u", ipv6_address, port);
76 }
77
78 out_status->port = port;
79 out_status->start_time = start_time;
80 out_status->mode_name = mode_name;
81 out_status->session_is_mdns_only = session_is_mdns_only;
82 out_status->connected_count = tcp_server_get_client_count(server);
83
84 return ASCIICHAT_OK;
85}
#define SAFE_STRNCPY(dst, src, size)
Definition common.h:414
#define SET_ERRNO(code, context_msg,...)
Set error code with custom context message and log it, returning the error code.
@ ERROR_INVALID_PARAM
size_t tcp_server_get_client_count(tcp_server_t *server)
Get client count.
bool ipv4_bound
Whether IPv4 socket is bound.
Definition status.h:36
char ipv4_address[256]
Formatted IPv4 bind address with port.
Definition status.h:32
bool ipv6_bound
Whether IPv6 socket is bound.
Definition status.h:37
uint16_t port
TCP listen port.
Definition status.h:34
char ipv6_address[256]
Formatted IPv6 bind address with port.
Definition status.h:33
char session_string[64]
Memorable session string (e.g., "happy-sunset-ocean")
Definition status.h:31
const char * mode_name
Mode name (e.g., "Server", "Discovery Service")
Definition status.h:40
time_t start_time
Server start time (for uptime calculation)
Definition status.h:39
bool session_is_mdns_only
Whether session is mDNS-only or ACDS.
Definition status.h:38
size_t connected_count
Number of connected clients/servers.
Definition status.h:35

References ASCIICHAT_OK, ui_status_t::connected_count, ERROR_INVALID_PARAM, ui_status_t::ipv4_address, ui_status_t::ipv4_bound, ui_status_t::ipv6_address, ui_status_t::ipv6_bound, ui_status_t::mode_name, ui_status_t::port, SAFE_STRNCPY, ui_status_t::session_is_mdns_only, ui_status_t::session_string, SET_ERRNO, ui_status_t::start_time, and tcp_server_get_client_count().

Referenced by ui_status_update().

◆ ui_status_log_append()

void ui_status_log_append ( const char *  message)

Append a log message to status screen buffer.

Thread-safe. Called from logging system to capture messages.

Parameters
messageLog message text (already formatted with colors)

◆ ui_status_log_clear()

void ui_status_log_clear ( void  )

Clear all log messages from status screen buffer.

Thread-safe. Resets buffer to empty state, discarding all captured logs. Used to clear initialization logs before status screen starts rendering.

Definition at line 43 of file status.c.

43 {
44 // Delegate to terminal_screen log abstraction
46}
void terminal_screen_log_clear(void)
Clear buffered logs for terminal screens.

References terminal_screen_log_clear().

◆ ui_status_log_destroy()

void ui_status_log_destroy ( void  )

Cleanup status screen log capture system.

Call when shutting down. Frees internal log buffer.

Definition at line 36 of file status.c.

36 {
37 // Unregister from logger before destroying
39 // Cleanup the shared terminal screen log buffer
41}
void log_clear_session_log_buffer(void)
Unregister the session log buffer.
Definition log/log.c:1847
void terminal_screen_log_destroy(void)
Standard log cleanup for terminal screens.

References log_clear_session_log_buffer(), and terminal_screen_log_destroy().

Referenced by session_server_like_run().

◆ ui_status_log_init()

void ui_status_log_init ( void  )

Initialize status screen log capture system.

Must be called before using status screen. Creates internal log buffer.

Definition at line 28 of file status.c.

28 {
29 // Initialize the shared terminal screen log buffer
31 if (buf) {
33 }
34}
void log_set_session_log_buffer(session_log_buffer_t *buf)
Register a session log buffer with the logger.
Definition log/log.c:1838
Internal circular buffer structure.
session_log_buffer_t * terminal_screen_log_init(void)
Initialize session log buffer for terminal screens.

References log_set_session_log_buffer(), and terminal_screen_log_init().

Referenced by session_server_like_run().

◆ ui_status_update()

void ui_status_update ( tcp_server_t *  server,
const char *  session_string,
const char *  ipv4_address,
const char *  ipv6_address,
uint16_t  port,
time_t  start_time,
const char *  mode_name,
bool  session_is_mdns_only,
uint64_t *  last_update_ns 
)

Periodically update status display with live logs at FPS rate.

Gathers and displays status with live log feed if enough time has passed since last update (based on GET_OPTION(fps)). Updates at 60 Hz by default.

Parameters
serverInitialized TCP server structure
session_stringMemorable session string
ipv4_addressIPv4 bind address (can be NULL or empty)
ipv6_addressIPv6 bind address (can be NULL or empty)
portTCP listen port
start_timeServer start time
mode_nameMode name for display (e.g., "Server")
session_is_mdns_onlyWhether session is mDNS-only or ACDS
[in,out]last_update_nsLast update time in microseconds (from platform_get_monotonic_time_us)

Definition at line 297 of file status.c.

299 {
300 if (!server || !last_update_ns) {
301 return;
302 }
303
304 // Update at FPS rate (60 Hz = 16.67ms by default)
305 uint32_t fps = GET_OPTION(fps);
306 if (fps == 0) {
307 fps = 60; // Default
308 }
309
310 // Calculate frame interval in microseconds
311 uint64_t frame_interval_us = US_PER_SEC_INT / fps;
312
313 // Get current time in microseconds using platform abstraction
315
316 // Check if enough time has passed
317 if ((now_us - *last_update_ns) < frame_interval_us) {
318 return; // Too soon, skip frame
319 }
320
321 ui_status_t status;
322 if (ui_status_gather(server, session_string, ipv4_address, ipv6_address, port, start_time, mode_name,
323 session_is_mdns_only, &status) == ASCIICHAT_OK) {
324 ui_status_display(&status);
325 *last_update_ns = now_us;
326 }
327}
unsigned int uint32_t
Definition common.h:58
unsigned long long uint64_t
Definition common.h:59
#define US_PER_SEC_INT
Definition time.h:161
uint64_t platform_get_monotonic_time_us(void)
Get monotonic time in microseconds.
void ui_status_display(const ui_status_t *status)
Display status screen.
Definition status.c:194
asciichat_error_t ui_status_gather(tcp_server_t *server, const char *session_string, const char *ipv4_address, const char *ipv6_address, uint16_t port, time_t start_time, const char *mode_name, bool session_is_mdns_only, ui_status_t *out_status)
Gather current status information.
Definition status.c:52
Status information for server/discovery service modes.
Definition status.h:30

References ASCIICHAT_OK, GET_OPTION, platform_get_monotonic_time_us(), ui_status_display(), ui_status_gather(), and US_PER_SEC_INT.