ascii-chat
Binary v0.15.83-53-gb711d8720
Library lib/v0.3.2-701-gb711d8720
Video chat in your terminal
Loading...
Searching...
No Matches
session_status.c File Reference

Go to the source code of this file.

Data Structures

struct  log_row_ref_t

Macros

#define TUI_SESSION_STATUS_STATUS_LINE_BUFFER_SIZE   512
#define TUI_SESSION_STATUS_STATUS_LINE_TRUNCATED_BUFFER_SIZE   512
#define TUI_SESSION_STATUS_STATUS_LINE_COLORED_BUFFER_SIZE   600
#define TUI_SESSION_STATUS_UPTIME_BUFFER_SIZE   12
#define TUI_SESSION_STATUS_ADDR_LINE_BUFFER_SIZE   512
#define TUI_SESSION_STATUS_ADDR_LINE_TRUNCATED_BUFFER_SIZE   512
#define TUI_SESSION_STATUS_IPV4_ONLY_BUFFER_SIZE   64
#define TUI_SESSION_STATUS_IPV6_ONLY_BUFFER_SIZE   64
#define TUI_SESSION_STATUS_TEXT_BUFFER_SIZE   2048
#define TUI_SESSION_STATUS_FOOTER_BUFFER_SIZE   128
#define TUI_SESSION_STATUS_KEYS_BUFFER_SIZE   96

Functions

void ui_status_render_header (frame_buffer_t *buf, terminal_size_t term_size, void *user_data)
void terminal_screen_compose (frame_buffer_t *output, terminal_size_t size, const terminal_screen_config_t *config, session_log_buffer_t *logs)
void terminal_screen_logs_render_help (frame_buffer_t *output, terminal_size_t size)

Macro Definition Documentation

◆ TUI_SESSION_STATUS_ADDR_LINE_BUFFER_SIZE

#define TUI_SESSION_STATUS_ADDR_LINE_BUFFER_SIZE   512

Definition at line 7 of file session_status.c.

Referenced by ui_status_render_header().

◆ TUI_SESSION_STATUS_ADDR_LINE_TRUNCATED_BUFFER_SIZE

#define TUI_SESSION_STATUS_ADDR_LINE_TRUNCATED_BUFFER_SIZE   512

Definition at line 8 of file session_status.c.

Referenced by ui_status_render_header().

◆ TUI_SESSION_STATUS_FOOTER_BUFFER_SIZE

#define TUI_SESSION_STATUS_FOOTER_BUFFER_SIZE   128

Definition at line 12 of file session_status.c.

Referenced by terminal_screen_logs_render_help().

◆ TUI_SESSION_STATUS_IPV4_ONLY_BUFFER_SIZE

#define TUI_SESSION_STATUS_IPV4_ONLY_BUFFER_SIZE   64

Definition at line 9 of file session_status.c.

Referenced by ui_status_render_header().

◆ TUI_SESSION_STATUS_IPV6_ONLY_BUFFER_SIZE

#define TUI_SESSION_STATUS_IPV6_ONLY_BUFFER_SIZE   64

Definition at line 10 of file session_status.c.

Referenced by ui_status_render_header().

◆ TUI_SESSION_STATUS_KEYS_BUFFER_SIZE

#define TUI_SESSION_STATUS_KEYS_BUFFER_SIZE   96

Definition at line 13 of file session_status.c.

Referenced by terminal_screen_logs_render_help().

◆ TUI_SESSION_STATUS_STATUS_LINE_BUFFER_SIZE

#define TUI_SESSION_STATUS_STATUS_LINE_BUFFER_SIZE   512

Definition at line 3 of file session_status.c.

Referenced by ui_status_render_header().

◆ TUI_SESSION_STATUS_STATUS_LINE_COLORED_BUFFER_SIZE

#define TUI_SESSION_STATUS_STATUS_LINE_COLORED_BUFFER_SIZE   600

Definition at line 5 of file session_status.c.

Referenced by ui_status_render_header().

◆ TUI_SESSION_STATUS_STATUS_LINE_TRUNCATED_BUFFER_SIZE

#define TUI_SESSION_STATUS_STATUS_LINE_TRUNCATED_BUFFER_SIZE   512

Definition at line 4 of file session_status.c.

Referenced by ui_status_render_header().

◆ TUI_SESSION_STATUS_TEXT_BUFFER_SIZE

#define TUI_SESSION_STATUS_TEXT_BUFFER_SIZE   2048

Definition at line 11 of file session_status.c.

Referenced by terminal_screen_compose().

◆ TUI_SESSION_STATUS_UPTIME_BUFFER_SIZE

#define TUI_SESSION_STATUS_UPTIME_BUFFER_SIZE   12

Definition at line 6 of file session_status.c.

Referenced by ui_status_render_header().

Function Documentation

◆ terminal_screen_compose()

void terminal_screen_compose ( frame_buffer_t * output,
terminal_size_t size,
const terminal_screen_config_t * config,
session_log_buffer_t * logs )

Compose the existing status/splash UI without terminal I/O.

Definition at line 262 of file session_status.c.

263 {
264 if (!output || !config || !config->render_header || size.cols < 1 || size.rows < 1)
265 return;
266 if (config->show_logs)
268 frame_buffer_t *body = frame_buffer_create(size.rows, size.cols);
269 if (!body)
270 return;
271 config->render_header(body, size, config->user_data);
272
273 // Measure the actual header, including wrapped lines, as the native status UI does.
274 int header_rows = 0;
275 const char *line = frame_buffer_get_content(body);
276 const char *end = line + frame_buffer_get_length(body);
277 for (const char *cursor = line; cursor < end; ++cursor) {
278 if (*cursor == '\n') {
280 size_t length = (size_t)(cursor - line);
281 if (length >= sizeof(text))
282 length = sizeof(text) - 1;
283 memcpy(text, line, length);
284 text[length] = '\0';
285 int height = display_height(text, size.cols);
286 header_rows += height > 0 ? height : 1;
287 line = cursor + 1;
288 }
289 }
290 if (!header_rows)
291 header_rows = config->fixed_header_lines;
292 bool entering = config->show_logs && log_search_is_entering();
293 // Search owns the final row for its prompt. Otherwise logs fill it.
294 int available = size.rows - header_rows - (entering ? 1 : 0);
295 bool compact_startup = config->screen == UI_SCREEN_SPLASH;
296 session_log_entry_t *entries = NULL;
297 size_t count = 0;
298 size_t scroll_total = 0, scroll_offset = 0;
299 if (config->show_logs && available > 0) {
301 log_search_filter_buffer(logs, &entries, &count);
302 else {
303 entries = SAFE_MALLOC(SESSION_LOG_BUFFER_SIZE * sizeof(*entries), session_log_entry_t *);
304 if (entries)
306 }
307 log_row_ref_t *rows = SAFE_MALLOC((size_t)available * sizeof(*rows), log_row_ref_t *);
308 if (rows) {
309 size_t total_rows = 0;
310 uint64_t previous_tail_sequence = 0;
311 size_t appended_rows = 0;
312 for (size_t entry = 0; entry < count; ++entry) {
313 size_t height = (size_t)log_message_rows(entries[entry].message, size.cols, compact_startup);
314 if (SIZE_MAX - total_rows < height)
315 total_rows = SIZE_MAX;
316 else
317 total_rows += height;
318 }
319 uint64_t tail_sequence = count ? entries[count - 1].sequence : 0;
320 previous_tail_sequence = terminal_screen_logs_last_tail_sequence();
321 if (previous_tail_sequence && tail_sequence > previous_tail_sequence) {
322 for (size_t entry = 0; entry < count; ++entry) {
323 if (entries[entry].sequence > previous_tail_sequence)
324 appended_rows += (size_t)log_message_rows(entries[entry].message, size.cols, compact_startup);
325 }
326 }
327 size_t max_offset = total_rows ? total_rows - 1 : 0;
328 size_t skip = terminal_screen_logs_retain_position(tail_sequence, appended_rows, max_offset);
329 scroll_total = total_rows;
330 scroll_offset = total_rows > (size_t)available + skip ? total_rows - (size_t)available - skip : 0;
331 size_t row_count = 0;
332 for (size_t entry = count; entry && row_count < (size_t)available; --entry) {
333 int height = log_message_rows(entries[entry - 1].message, size.cols, compact_startup);
334 if (skip >= (size_t)height) {
335 skip -= (size_t)height;
336 continue;
337 }
338 int row = height - 1 - (int)skip;
339 skip = 0;
340 for (; row >= 0 && row_count < (size_t)available; --row)
341 rows[row_count++] = (log_row_ref_t){.entry = entry - 1, .row = row};
342 }
343 for (size_t row = row_count; row; --row)
344 append_log_row(body, entries[rows[row - 1].entry].message, rows[row - 1].row, size.cols, compact_startup);
345 while (row_count++ < (size_t)available)
346 frame_buffer_printf(body, "\n");
347 SAFE_FREE(rows);
348 }
349 }
350 SAFE_FREE(entries);
351
352 // Preserve the existing repaint-in-place behavior, also supplying CR for browser terminals.
353 bool log_help_open = config->show_logs && terminal_screen_logs_help_open();
354 bool hide_cursor = log_help_open || (!entering && (config->hide_cursor || config->show_logs));
355 frame_buffer_printf(output, "\033[H%s", hide_cursor ? "\033[?25l" : "\033[?25h");
356 const char *content = frame_buffer_get_content(body);
357 size_t length = frame_buffer_get_length(body);
358 for (size_t i = 0; i < length; ++i) {
359 // Normalize CRLF before erasing the line; erasing after CR removes its text.
360 if (content[i] == '\r' && i + 1 < length && content[i + 1] == '\n')
361 continue;
362 if (content[i] == '\n') {
363 frame_buffer_printf(output, "\033[K\r");
364 // Do not advance past the bottom row when the idle log view fills it.
365 if (config->show_logs && !entering && i + 1 == length)
366 continue;
367 }
368 frame_buffer_append(output, content + i, 1);
369 }
370 if (config->show_logs && available > 0 && scroll_total > (size_t)available)
371 ui_scrollbar_render(output, header_rows + 1, size.cols, available, scroll_total, (size_t)available, scroll_offset);
372 if (entering) {
373 mutex_t *mutex = log_search_get_mutex();
374 mutex_lock(mutex);
375 const char *pattern = log_search_get_input_buffer();
376 int cursor = log_search_get_cursor_position();
377 // Keep the edit cursor visible even when a pattern exceeds the viewport.
378 int offset = cursor >= size.cols - 2 ? cursor - (size.cols - 3) : 0;
379 frame_buffer_printf(output, "\033[%d;1H/%.*s\033[K\033[%d;%dH", size.rows, size.cols - 2,
380 pattern ? pattern + offset : "", size.rows, cursor - offset + 2);
381 mutex_unlock(mutex);
382 }
383 if (log_help_open) {
385 } else if (config->show_logs && terminal_screen_logs_help_too_small()) {
386 frame_buffer_printf(output, "\033[%d;1H%s", size.rows, "Help needs at least 12 terminal rows");
387 }
389}
unsigned int height
Definition fft.c:23
void frame_buffer_append(frame_buffer_t *buf, const char *str, size_t len)
Append raw bytes to the buffer.
void frame_buffer_destroy(frame_buffer_t *buf)
Destroy a frame buffer.
size_t frame_buffer_get_length(const frame_buffer_t *buf)
Get the current content length of the frame buffer.
const char * frame_buffer_get_content(const frame_buffer_t *buf)
Get a pointer to the buffer content.
frame_buffer_t * frame_buffer_create(int rows, int cols)
Create a new frame buffer.
void frame_buffer_printf(frame_buffer_t *buf, const char *fmt,...)
Printf-style append to the buffer.
struct frame_buffer frame_buffer_t
Opaque frame buffer handle.
#define SAFE_FREE(ptr)
Definition common.h:377
#define SAFE_MALLOC(size, cast)
Definition common.h:265
unsigned long long uint64_t
Definition common.h:63
int display_height(const char *text, int terminal_width)
Calculate how many display lines text will consume when wrapped.
void ui_scrollbar_render(frame_buffer_t *out, int row, int col, int height, size_t total, size_t visible, size_t offset)
Definition scrollbar.c:40
void * log_search_get_mutex(void)
Get the mutex protecting grep state.
Definition search.c:985
bool log_search_is_entering(void)
Check if currently in input mode (typing pattern).
Definition search.c:408
void log_search_process_pending(void)
Definition search.c:469
asciichat_error_t log_search_filter_buffer(session_log_buffer_t *log_buf, session_log_entry_t **out_entries, size_t *out_count)
Definition search.c:574
const char * log_search_get_input_buffer(void)
Get current input buffer content (must hold mutex).
Definition search.c:997
bool log_search_is_active(void)
Check if filtering is active.
Definition search.c:413
int log_search_get_cursor_position(void)
Get current cursor position in input buffer (must hold mutex).
Definition search.c:993
size_t session_log_buffer_get_recent(session_log_buffer_t *buf, session_log_entry_t *out_entries, size_t max_count)
Get recent log entries from buffer.
#define SESSION_LOG_BUFFER_SIZE
#define TUI_SESSION_STATUS_TEXT_BUFFER_SIZE
void terminal_screen_logs_render_help(frame_buffer_t *output, terminal_size_t size)
One formatted session log line and its monotonic history sequence.
uint64_t sequence
Sequence number (monotonic, for ordering).
terminal_screen_header_fn render_header
Callback to draw header content.
int fixed_header_lines
How many lines the header takes (e.g., 4 for status, 8 for splash).
bool show_logs
Whether to show log feed below header.
bool hide_cursor
Hide cursor while this screen owns the terminal.
void * user_data
Passed to render_header callback.
bool terminal_screen_logs_help_open(void)
size_t terminal_screen_logs_retain_position(uint64_t tail_sequence, size_t appended_rows, size_t maximum_offset)
uint64_t terminal_screen_logs_last_tail_sequence(void)
bool terminal_screen_logs_help_too_small(void)
@ UI_SCREEN_SPLASH

References display_height(), terminal_screen_config_t::fixed_header_lines, frame_buffer_append(), frame_buffer_create(), frame_buffer_destroy(), frame_buffer_get_content(), frame_buffer_get_length(), frame_buffer_printf(), height, terminal_screen_config_t::hide_cursor, log_search_filter_buffer(), log_search_get_cursor_position(), log_search_get_input_buffer(), log_search_get_mutex(), log_search_is_active(), log_search_is_entering(), log_search_process_pending(), terminal_screen_config_t::render_header, SAFE_FREE, SAFE_MALLOC, terminal_screen_config_t::screen, session_log_entry_t::sequence, session_log_buffer_get_recent(), SESSION_LOG_BUFFER_SIZE, terminal_screen_config_t::show_logs, terminal_screen_logs_help_open(), terminal_screen_logs_help_too_small(), terminal_screen_logs_last_tail_sequence(), terminal_screen_logs_render_help(), terminal_screen_logs_retain_position(), TUI_SESSION_STATUS_TEXT_BUFFER_SIZE, UI_SCREEN_SPLASH, ui_scrollbar_render(), and terminal_screen_config_t::user_data.

Referenced by ui_session_logs_render().

◆ terminal_screen_logs_render_help()

void terminal_screen_logs_render_help ( frame_buffer_t * output,
terminal_size_t size )

Recompose log-viewer help above modal error notifications.

Definition at line 391 of file session_status.c.

391 {
392 const ui_help_entry_t entries[] = {{"Down", "newer log"}, {"Up", "older log"}, {"PageDown", "newer page"},
393 {"PageUp", "older page"}, {"End", "newest log"}, {"Home", "oldest log"},
394 {"/", "search logs"}, {"q / Esc", "close viewer"}};
396 ui_help_keys(keys, sizeof(keys), "? / Esc");
397 snprintf(footer, sizeof(footer), "%s closes this help", keys);
398 ui_help_menu_t menu = {.title = "Log Viewer Keyboard Controls",
399 .entries = entries,
400 .count = sizeof(entries) / sizeof(*entries),
401 .footer = footer};
402 (void)ui_help_menu_render(output, size, &menu);
403}
void ui_help_keys(char *out, size_t cap, const char *keys)
Definition help_menu.c:25
bool ui_help_menu_render(frame_buffer_t *out, terminal_size_t size, const ui_help_menu_t *m)
Definition help_menu.c:101
#define TUI_SESSION_STATUS_FOOTER_BUFFER_SIZE
#define TUI_SESSION_STATUS_KEYS_BUFFER_SIZE
Definition help_menu.h:3
ui help entry keeps the values that move through the subsystem: keys, description....
Definition help_menu.h:12

References TUI_SESSION_STATUS_FOOTER_BUFFER_SIZE, TUI_SESSION_STATUS_KEYS_BUFFER_SIZE, ui_help_keys(), and ui_help_menu_render().

Referenced by terminal_screen_compose().

◆ ui_status_render_header()

void ui_status_render_header ( frame_buffer_t * buf,
terminal_size_t term_size,
void * user_data )

Server status presentation shared by native and browser sessions.

Definition at line 34 of file session_status.c.

34 {
35 const ui_status_t *status = (const ui_status_t *)user_data;
36 if (!status) {
37 return;
38 }
39
40 // Calculate uptime
41 time_t now = time(NULL);
42 time_t uptime_secs = now - status->start_time;
43 int uptime_hours = uptime_secs / SEC_PER_HOUR;
44 int uptime_mins = (uptime_secs % SEC_PER_HOUR) / SEC_PER_MIN;
45 int uptime_secs_rem = uptime_secs % 60;
46
47 // Line 1: Top border
48 bool unicode = terminal_should_use_utf8(GET_OPTION(force_utf8));
49 bool colors = !GET_OPTION(strip_ansi) &&
50 terminal_should_color_output(frame_buffer_get_screen_output_fd(), options_terminal_settings());
51 frame_buffer_render_divider(buf, term_size.cols - 1, unicode, colors);
52
53 // The bundled browser font does not contain the emoji used in native status titles.
54#ifdef __EMSCRIPTEN__
55 bool status_icons = false;
56#else
57 bool status_icons = unicode;
58#endif
59
60 // Line 2: Title + Stats (centered)
65 format_uptime_hms(uptime_hours, uptime_mins, uptime_secs_rem, uptime_str, sizeof(uptime_str));
66 bool generic_log_header = status->detail && strstr(status->detail, "keyboard controls") != NULL;
67 if (generic_log_header)
68 snprintf(status_line, sizeof(status_line), status_icons ? "ascii-chat | ⏱️ %s" : "ascii-chat | uptime %s",
69 uptime_str);
70 else if (status->detail)
71 snprintf(status_line, sizeof(status_line), status_icons ? "ascii-chat %s | ⏱️ %s" : "ascii-chat %s | uptime %s",
72 status->mode_name, uptime_str);
73 else
74 snprintf(status_line, sizeof(status_line),
75 status_icons ? "ascii-chat %s | 👥 %zu | ⏱️ %s" : "ascii-chat %s | clients %zu | uptime %s",
76 status->mode_name, status->connected_count, uptime_str);
77
78 // Truncate if needed (ANSI-aware)
79 truncate_with_ellipsis(status_line, status_line_truncated, sizeof(status_line_truncated), term_size.cols - 2);
80 snprintf(status_line_colored, sizeof(status_line_colored), "\033[1m%s\033[0m",
81 colored_string(LOG_COLOR_DEBUG, status_line_truncated));
82
83 int padding = display_center_horizontal(status_line_truncated, term_size.cols);
84 for (int i = 0; i < padding; i++) {
85 frame_buffer_printf(buf, " ");
86 }
87 frame_buffer_printf(buf, "%s\n", status_line_colored);
88
89 // Line 3: Session + Addresses (centered)
90 char addr_line[TUI_SESSION_STATUS_ADDR_LINE_BUFFER_SIZE] = {0};
92 int pos = 0;
93 if (status->session_string[0] != '\0') {
94 pos += snprintf(addr_line + pos, sizeof(addr_line) - pos, unicode ? "🔗 %s" : "Session %s", status->session_string);
95 }
96 if (status->ipv4_bound && pos < (int)sizeof(addr_line) - 30) {
97 if (pos > 0) {
98 pos += snprintf(addr_line + pos, sizeof(addr_line) - pos, " | ");
99 }
100 // Extract IP and get type
102 if (extract_ip_from_address(status->ipv4_address, ipv4_only, sizeof(ipv4_only)) == 0) {
103 const char *type = get_ip_type_string(ipv4_only);
104 pos += snprintf(addr_line + pos, sizeof(addr_line) - pos, "%s (%s)", status->ipv4_address, type);
105 } else {
106 pos += snprintf(addr_line + pos, sizeof(addr_line) - pos, "%s", status->ipv4_address);
107 }
108 }
109 if (status->ipv6_bound && pos < (int)sizeof(addr_line) - 30) {
110 if (pos > 0) {
111 pos += snprintf(addr_line + pos, sizeof(addr_line) - pos, " | ");
112 }
113 // Extract IP and get type
115 if (extract_ip_from_address(status->ipv6_address, ipv6_only, sizeof(ipv6_only)) == 0) {
116 const char *type = get_ip_type_string(ipv6_only);
117 snprintf(addr_line + pos, sizeof(addr_line) - pos, "%s (%s)", status->ipv6_address, type);
118 } else {
119 snprintf(addr_line + pos, sizeof(addr_line) - pos, "%s", status->ipv6_address);
120 }
121 }
122
123 if (status->detail)
124 SAFE_STRNCPY(addr_line, status->detail, sizeof(addr_line));
125
126 // Truncate if needed (ANSI-aware)
127 truncate_with_ellipsis(addr_line, addr_line_truncated, sizeof(addr_line_truncated), term_size.cols - 2);
128
129 int addr_padding = display_center_horizontal(addr_line_truncated, term_size.cols);
130 for (int i = 0; i < addr_padding; i++) {
131 frame_buffer_printf(buf, " ");
132 }
133 frame_buffer_printf(buf, "%s\n", addr_line_truncated);
134
135 // Line 4: Bottom border
136 frame_buffer_render_divider(buf, term_size.cols - 1, unicode, colors);
137}
unsigned char colors[(512 *256 *2) *3]
Definition fft.c:22
void frame_buffer_render_divider(frame_buffer_t *buf, int width, bool use_utf8, bool use_colors)
int frame_buffer_get_screen_output_fd(void)
Get current output file descriptor for terminal screens.
#define SAFE_STRNCPY(dst, src, size)
Definition common.h:423
@ LOG_COLOR_DEBUG
Definition log/log.h:149
#define SEC_PER_HOUR
Definition time.h:180
int format_uptime_hms(int hours, int minutes, int seconds, char *buffer, size_t buffer_size)
Format uptime as HH:MM:SS string.
Definition time.c:318
#define SEC_PER_MIN
Definition time.h:179
#define GET_OPTION(field)
Safely get a specific option field (lock-free read).
Definition options.h:1336
#define options_terminal_settings()
Definition options.h:1296
const char * colored_string(log_color_t color, const char *text)
Build a colored string for terminal output.
Definition string.c:284
int extract_ip_from_address(const char *addr_with_port, char *ip_out, size_t ip_out_size)
Extract IP address (without port) from formatted address string.
Definition ip.c:972
const char * get_ip_type_string(const char *ip)
Get human-readable string describing IP address type.
Definition ip.c:1010
int display_center_horizontal(const char *text, int terminal_width)
Calculate left padding needed to center text horizontally.
void truncate_with_ellipsis(const char *input, char *output, size_t output_size, int max_width)
Truncate a string to a maximum display width, with ellipsis.
Definition string.c:370
#define TUI_SESSION_STATUS_IPV4_ONLY_BUFFER_SIZE
#define TUI_SESSION_STATUS_ADDR_LINE_TRUNCATED_BUFFER_SIZE
#define TUI_SESSION_STATUS_UPTIME_BUFFER_SIZE
#define TUI_SESSION_STATUS_IPV6_ONLY_BUFFER_SIZE
#define TUI_SESSION_STATUS_STATUS_LINE_COLORED_BUFFER_SIZE
#define TUI_SESSION_STATUS_ADDR_LINE_BUFFER_SIZE
#define TUI_SESSION_STATUS_STATUS_LINE_BUFFER_SIZE
#define TUI_SESSION_STATUS_STATUS_LINE_TRUNCATED_BUFFER_SIZE
Status information for server/discovery service modes.
Definition status.h:38
bool ipv4_bound
Whether IPv4 socket is bound.
Definition status.h:44
char ipv4_address[256]
Formatted IPv4 bind address with port.
Definition status.h:40
const char * detail
Optional client controls in the address row.
Definition status.h:48
bool ipv6_bound
Whether IPv6 socket is bound.
Definition status.h:45
char ipv6_address[256]
Formatted IPv6 bind address with port.
Definition status.h:41
char session_string[64]
Memorable session string (e.g., "happy-sunset-ocean").
Definition status.h:39
const char * mode_name
Mode name (e.g., "Server", "Discovery Service").
Definition status.h:49
time_t start_time
Server start time (for uptime calculation).
Definition status.h:47
size_t connected_count
Number of connected clients/servers.
Definition status.h:43

References colored_string(), colors, ui_status_t::connected_count, ui_status_t::detail, display_center_horizontal(), extract_ip_from_address(), format_uptime_hms(), frame_buffer_get_screen_output_fd(), frame_buffer_printf(), frame_buffer_render_divider(), get_ip_type_string(), GET_OPTION, ui_status_t::ipv4_address, ui_status_t::ipv4_bound, ui_status_t::ipv6_address, ui_status_t::ipv6_bound, LOG_COLOR_DEBUG, ui_status_t::mode_name, options_terminal_settings, SAFE_STRNCPY, SEC_PER_HOUR, SEC_PER_MIN, ui_status_t::session_string, ui_status_t::start_time, truncate_with_ellipsis(), TUI_SESSION_STATUS_ADDR_LINE_BUFFER_SIZE, TUI_SESSION_STATUS_ADDR_LINE_TRUNCATED_BUFFER_SIZE, TUI_SESSION_STATUS_IPV4_ONLY_BUFFER_SIZE, TUI_SESSION_STATUS_IPV6_ONLY_BUFFER_SIZE, TUI_SESSION_STATUS_STATUS_LINE_BUFFER_SIZE, TUI_SESSION_STATUS_STATUS_LINE_COLORED_BUFFER_SIZE, TUI_SESSION_STATUS_STATUS_LINE_TRUNCATED_BUFFER_SIZE, and TUI_SESSION_STATUS_UPTIME_BUFFER_SIZE.

Referenced by ui_session_logs_render(), ui_status_display(), and ui_status_display_interactive().