ascii-chat 0.6.0
Real-time terminal-based video chat with ASCII art conversion
Loading...
Searching...
No Matches
discovery_tui.c File Reference

TUI-based service discovery wrapper for interactive server selection. More...

Go to the source code of this file.

Macros

#define ANSI_CLEAR   "\033[2J\033[H"
 ANSI escape codes for TUI.
 
#define ANSI_BOLD   "\033[1m"
 
#define ANSI_RESET   "\033[0m"
 
#define ANSI_CYAN   "\033[36m"
 
#define ANSI_GREEN   "\033[32m"
 
#define ANSI_YELLOW   "\033[33m"
 
#define ANSI_HIDE_CURSOR   "\033[?25l"
 
#define ANSI_SHOW_CURSOR   "\033[?25h"
 
#define ANSI_CLEAR_LINE   "\033[K"
 

Functions

discovery_tui_server_tdiscovery_tui_query (const discovery_tui_config_t *config, int *out_count)
 TUI wrapper around core mDNS discovery.
 
void discovery_tui_free_results (discovery_tui_server_t *servers)
 Free results from mDNS discovery.
 
int discovery_tui_prompt_selection (const discovery_tui_server_t *servers, int count)
 Interactive server selection.
 
int discovery_tui_select (const discovery_tui_server_t *servers, int count)
 TUI-based server selection with formatted display.
 
const char * discovery_tui_get_best_address (const discovery_tui_server_t *server)
 Get best address for a server.
 

Detailed Description

TUI-based service discovery wrapper for interactive server selection.

Pure TUI wrapper that calls discovery_mdns_query() from discovery.c. Provides interactive terminal UI for server selection and address resolution.

Definition in file discovery_tui.c.

Macro Definition Documentation

◆ ANSI_BOLD

#define ANSI_BOLD   "\033[1m"

Definition at line 98 of file discovery_tui.c.

◆ ANSI_CLEAR

#define ANSI_CLEAR   "\033[2J\033[H"

ANSI escape codes for TUI.

Definition at line 97 of file discovery_tui.c.

◆ ANSI_CLEAR_LINE

#define ANSI_CLEAR_LINE   "\033[K"

Definition at line 105 of file discovery_tui.c.

◆ ANSI_CYAN

#define ANSI_CYAN   "\033[36m"

Definition at line 100 of file discovery_tui.c.

◆ ANSI_GREEN

#define ANSI_GREEN   "\033[32m"

Definition at line 101 of file discovery_tui.c.

◆ ANSI_HIDE_CURSOR

#define ANSI_HIDE_CURSOR   "\033[?25l"

Definition at line 103 of file discovery_tui.c.

◆ ANSI_RESET

#define ANSI_RESET   "\033[0m"

Definition at line 99 of file discovery_tui.c.

◆ ANSI_SHOW_CURSOR

#define ANSI_SHOW_CURSOR   "\033[?25h"

Definition at line 104 of file discovery_tui.c.

◆ ANSI_YELLOW

#define ANSI_YELLOW   "\033[33m"

Definition at line 102 of file discovery_tui.c.

Function Documentation

◆ discovery_tui_free_results()

void discovery_tui_free_results ( discovery_tui_server_t servers)

Free results from mDNS discovery.

Free results from TUI discovery query.

Definition at line 45 of file discovery_tui.c.

45 {
46 discovery_mdns_free(servers);
47}
void discovery_mdns_free(discovery_tui_server_t *servers)
Free memory from mDNS discovery results.
Definition discovery.c:408

References discovery_mdns_free().

Referenced by client_main().

◆ discovery_tui_get_best_address()

const char * discovery_tui_get_best_address ( const discovery_tui_server_t server)

Get best address for a server.

Get best address representation for a discovered server.

Definition at line 206 of file discovery_tui.c.

206 {
207 if (!server) {
208 return "";
209 }
210
211 // Prefer IPv4 > name > IPv6
212 if (server->ipv4[0] != '\0') {
213 return server->ipv4;
214 }
215 if (server->name[0] != '\0') {
216 return server->name;
217 }
218 if (server->ipv6[0] != '\0') {
219 return server->ipv6;
220 }
221
222 return server->address; // Fallback to address field
223}
char name[256]
Service instance name (e.g., "swift-river-canyon")
char ipv6[46]
IPv6 address (if available)
char ipv4[16]
IPv4 address (if available)
char address[256]
Server address (IPv4, IPv6, or hostname)

References discovery_tui_server_t::address, discovery_tui_server_t::ipv4, discovery_tui_server_t::ipv6, and discovery_tui_server_t::name.

Referenced by client_main(), discovery_tui_prompt_selection(), and discovery_tui_select().

◆ discovery_tui_prompt_selection()

int discovery_tui_prompt_selection ( const discovery_tui_server_t servers,
int  count 
)

Interactive server selection.

Display discovered servers to user and prompt for selection.

Definition at line 52 of file discovery_tui.c.

52 {
53 if (!servers || count <= 0) {
54 return -1;
55 }
56
57 // Display available servers
58 printf("\nAvailable ASCII-Chat servers on LAN:\n");
59 for (int i = 0; i < count; i++) {
60 const discovery_tui_server_t *srv = &servers[i];
61 const char *addr = discovery_tui_get_best_address(srv);
62 printf(" %d. %s (%s:%u)\n", i + 1, srv->name, addr, srv->port);
63 }
64
65 // Prompt for selection
66 printf("\nSelect server (1-%d) or press Enter to cancel: ", count);
67 fflush(stdout);
68
69 // Read user input
70 char input[32];
71 if (fgets(input, sizeof(input), stdin) == NULL) {
72 printf("\n");
73 return -1; // EOF or error
74 }
75
76 // Check for empty input (Enter pressed)
77 if (input[0] == '\n' || input[0] == '\r' || input[0] == '\0') {
78 return -1; // User cancelled
79 }
80
81 // Parse input as number
82 char *endptr;
83 long selection = strtol(input, &endptr, 10);
84
85 // Validate input
86 if (selection < 1 || selection > count) {
87 printf("āš ļø Invalid selection. Please enter a number between 1 and %d\n", count);
88 return discovery_tui_prompt_selection(servers, count); // Re-prompt
89 }
90
91 return (int)(selection - 1); // Convert to 0-based index
92}
int discovery_tui_prompt_selection(const discovery_tui_server_t *servers, int count)
Interactive server selection.
const char * discovery_tui_get_best_address(const discovery_tui_server_t *server)
Get best address for a server.
Discovered server information from mDNS.
uint16_t port
Server port number.

References discovery_tui_get_best_address(), discovery_tui_prompt_selection(), discovery_tui_server_t::name, and discovery_tui_server_t::port.

Referenced by discovery_tui_prompt_selection().

◆ discovery_tui_query()

discovery_tui_server_t * discovery_tui_query ( const discovery_tui_config_t config,
int *  out_count 
)

TUI wrapper around core mDNS discovery.

Discover ASCII-Chat servers on the local network via mDNS.

Calls discovery_mdns_query() from discovery.c with TUI-friendly configuration.

Definition at line 25 of file discovery_tui.c.

25 {
26 if (!out_count) {
27 SET_ERRNO(ERROR_INVALID_PARAM, "out_count pointer is NULL");
28 return NULL;
29 }
30
31 *out_count = 0;
32
33 // Apply defaults if needed
34 int timeout_ms = (config && config->timeout_ms > 0) ? config->timeout_ms : 2000;
35 int max_servers = (config && config->max_servers > 0) ? config->max_servers : 20;
36 bool quiet = (config && config->quiet);
37
38 // Call the core mDNS discovery function from discovery.c
39 return discovery_mdns_query(timeout_ms, max_servers, quiet, out_count);
40}
discovery_tui_server_t * discovery_mdns_query(int timeout_ms, int max_servers, bool quiet, int *out_count)
Public mDNS query function used by both parallel discovery and TUI wrapper.
Definition discovery.c:320
#define SET_ERRNO(code, context_msg,...)
Set error code with custom context message and log it.
@ ERROR_INVALID_PARAM
int max_servers
Maximum servers to collect (default: 20)
bool quiet
Suppress discovery messages (default: false)
int timeout_ms
Maximum time to wait for responses (default: 2000)

References discovery_mdns_query(), ERROR_INVALID_PARAM, discovery_tui_config_t::max_servers, discovery_tui_config_t::quiet, SET_ERRNO, and discovery_tui_config_t::timeout_ms.

Referenced by client_main().

◆ discovery_tui_select()

int discovery_tui_select ( const discovery_tui_server_t servers,
int  count 
)

TUI-based server selection with formatted display.

Displays discovered servers in a terminal UI with the following features:

  • Clears terminal and displays formatted server list
  • Shows "No results" message if no servers available
  • Allows numeric input for selection
  • Shows helpful prompts and icons
Parameters
serversArray of discovered servers
countNumber of servers
Returns
0-based index of selected server, or -1 to cancel

Definition at line 120 of file discovery_tui.c.

120 {
121 if (!servers || count <= 0) {
122 // No servers found - return special code
123 // Message will be printed at exit in client main
124 return -1;
125 }
126
127 // Lock terminal to prevent concurrent logging from overwriting TUI
128 bool prev_lock_state = log_lock_terminal();
129
130 // Clear terminal
131 log_plain("%s", ANSI_CLEAR);
132
133 // Display header
134 log_plain("\n");
135 log_plain("%s╭─ šŸ” ASCII-Chat Server Discovery %s────────────╮%s\n", ANSI_BOLD, ANSI_RESET, ANSI_BOLD);
136 log_plain("│%s\n", ANSI_RESET);
137 log_plain("%s│%s Found %d server%s on your local network:%s\n", ANSI_BOLD, ANSI_GREEN, count, count == 1 ? "" : "s",
138 ANSI_RESET);
139 log_plain("%s│%s\n", ANSI_BOLD, ANSI_RESET);
140
141 // Display server list with formatting
142 for (int i = 0; i < count; i++) {
143 const discovery_tui_server_t *srv = &servers[i];
144 const char *addr = discovery_tui_get_best_address(srv);
145
146 log_plain("%s│%s ", ANSI_BOLD, ANSI_RESET);
147 log_plain("%s[%d]%s %-30s %s%s:%u%s", ANSI_CYAN, i + 1, ANSI_RESET, srv->name, ANSI_YELLOW, addr, srv->port,
148 ANSI_RESET);
149 log_plain("\n");
150 }
151
152 log_plain("%s│%s\n", ANSI_BOLD, ANSI_RESET);
153 log_plain("%s╰────────────────────────────────────────────╯%s\n", ANSI_BOLD, ANSI_RESET);
154
155 // Prompt for selection
156 log_plain("\n");
157 log_plain("Enter server number (1-%d) or press Enter to cancel: ", count);
158 fflush(stdout);
159
160 // Unlock before waiting for input (user might take time)
161 log_unlock_terminal(prev_lock_state);
162
163 // Read user input
164 char input[32];
165 if (fgets(input, sizeof(input), stdin) == NULL) {
166 return -1;
167 }
168
169 // Check for empty input (Enter pressed)
170 if (input[0] == '\n' || input[0] == '\r' || input[0] == '\0') {
171 return -1;
172 }
173
174 // Parse input as number
175 char *endptr;
176 long selection = strtol(input, &endptr, 10);
177
178 // Validate input
179 if (selection < 1 || selection > count) {
180 printf("%sError:%s Please enter a number between 1 and %d\n\n", ANSI_YELLOW, ANSI_RESET, count);
181 return discovery_tui_select(servers, count); // Re-prompt
182 }
183
184 // Lock terminal again for final output
185 prev_lock_state = log_lock_terminal();
186
187 // Clear screen and show connection status
188 log_plain("%s", ANSI_CLEAR);
189 log_plain("\n");
190 log_plain("%sšŸ”— Connecting to %s...%s\n", ANSI_GREEN, servers[selection - 1].name, ANSI_RESET);
191 log_plain("\n");
192 fflush(stdout);
193
194 // Brief delay so user can see the selection before logs overwrite it
196
197 // Unlock terminal now that TUI is complete
198 log_unlock_terminal(prev_lock_state);
199
200 return (int)(selection - 1); // Convert to 0-based index
201}
#define ANSI_BOLD
#define ANSI_CLEAR
ANSI escape codes for TUI.
int discovery_tui_select(const discovery_tui_server_t *servers, int count)
TUI-based server selection with formatted display.
#define ANSI_CYAN
#define ANSI_GREEN
#define ANSI_YELLOW
#define ANSI_RESET
bool log_lock_terminal(void)
Lock terminal output for exclusive access by the calling thread.
#define log_plain(...)
Plain logging - writes to both log file and stderr without timestamps or log levels.
void log_unlock_terminal(bool previous_state)
Release terminal lock and flush buffered messages.
void platform_sleep_ms(unsigned int ms)
Sleep for a specified number of milliseconds.

References ANSI_BOLD, ANSI_CLEAR, ANSI_CYAN, ANSI_GREEN, ANSI_RESET, ANSI_YELLOW, discovery_tui_get_best_address(), discovery_tui_select(), log_lock_terminal(), log_plain, log_unlock_terminal(), discovery_tui_server_t::name, platform_sleep_ms(), and discovery_tui_server_t::port.

Referenced by client_main(), and discovery_tui_select().