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

Go to the source code of this file.

Functions

asciichat_error_t ui_prompt_present (const char *prompt, const char *visible, size_t cursor, bool secret)
asciichat_error_t ui_prompt_present_kind (const char *prompt, const char *visible, size_t cursor, bool secret, ui_prompt_kind_t kind)
const char * ui_prompt_kind_name (ui_prompt_kind_t kind)
const char * ui_prompt_usage_name (const void *snapshot)
void ui_prompt_dismiss (int previous)
void ui_prompt_remove (void)
const char * ui_prompt_title (const void *snapshot)
int ui_prompt_required_rows (const void *snapshot, int cols)
void ui_media_panel_render (frame_buffer_t *buffer, terminal_size_t size, const char *title, const char *instruction, const char *text, size_t cursor)
asciichat_error_t ui_media_loading_present (void)
asciichat_error_t ui_password_prompt_present (const char *target, const char *masked, size_t cursor, size_t selected_button, bool incorrect, bool can_confirm, bool newline_limit)

Function Documentation

◆ ui_media_loading_present()

asciichat_error_t ui_media_loading_present ( void )

Present the media-loading screen while capture resolves its next source.

Definition at line 332 of file prompt.c.

332 {
333 return ui_controller_submit(UI_SCREEN_RENDER_PROGRESS, STDERR_FILENO, (terminal_size_t){.cols = 40, .rows = 8},
334 render_media_loading, "", 1);
335}
asciichat_error_t ui_controller_submit(ui_screen_t screen, int fd, terminal_size_t minimum, ui_render_fn render, const void *snapshot, size_t bytes)
@ UI_SCREEN_RENDER_PROGRESS

References ui_controller_submit(), and UI_SCREEN_RENDER_PROGRESS.

◆ ui_media_panel_render()

void ui_media_panel_render ( frame_buffer_t * buffer,
terminal_size_t size,
const char * title,
const char * instruction,
const char * text,
size_t cursor )

Shared centered media panel with the animated splash logo. NULL text shows loading.

Definition at line 72 of file prompt.c.

73 {
74 bool compact = size.cols < 52;
75 int logo_rows = compact ? 1 : 4;
76 int lines = 1;
77 if (text) {
78 for (size_t i = 0; text[i]; ++i) {
79 if (text[i] == '\n') {
80 ++lines;
81 }
82 }
83 }
84 int available = size.rows - logo_rows - 5;
85 if (available < 1)
86 available = 1;
87 int shown = text ? (lines < available ? lines : available) : 0;
88 int height = logo_rows + 3 + (text ? 1 + shown : 0);
89 int top = (size.rows - height) / 2 + 1;
90 if (top < 1)
91 top = 1;
92 bool colors = !GET_OPTION(strip_ansi) &&
93 terminal_should_color_output(frame_buffer_get_screen_output_fd(), options_terminal_settings());
94 frame_buffer_append(buffer, "\033[0m\033[H\033[?25l", 13);
95 frame_buffer_printf(buffer, "\033[%d;1H", top);
97 int tick = sample ? (int)(sample->seconds * 60) : (int)((time_get_ns() / NS_PER_MS_INT / 16) % 100000);
98 invitation_render_logo(buffer, size.cols, tick, colors, compact);
99 media_center_line(buffer, title, top + logo_rows + 1, size.cols);
100 media_center_line(buffer, instruction, top + logo_rows + 2, size.cols);
101 if (!text) {
102 media_panel_clear_background(buffer, size, top, logo_rows, 0);
103 return;
104 }
105 int width = size.cols - 6;
106 if (width > 76)
107 width = 76;
108 int longest = 20;
109 const char *line = text;
110 for (const char *p = text;; ++p) {
111 if (!*p || *p == '\n') {
112 int n = utf8_display_width_n(line, (size_t)(p - line));
113 if (n > longest)
114 longest = n;
115 if (!*p)
116 break;
117 line = p + 1;
118 }
119 }
120 if (longest < width)
121 width = longest;
122 int col = (size.cols - (width + 2)) / 2 + 1;
123 for (int i = 0; i < shown; ++i)
124 frame_buffer_printf(buffer, "\033[%d;1H\033[K", top + logo_rows + 4 + i);
125 ui_input_render(buffer, top + logo_rows + 4, col, width, shown, text, cursor, true);
126 media_panel_clear_background(buffer, size, top, logo_rows, shown);
127}
unsigned char colors[(512 *256 *2) *3]
Definition fft.c:22
unsigned int height
Definition fft.c:23
unsigned int width
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_printf(frame_buffer_t *buf, const char *fmt,...)
Printf-style append to the buffer.
int frame_buffer_get_screen_output_fd(void)
Get current output file descriptor for terminal screens.
#define NS_PER_MS_INT
Definition time.h:168
#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
int utf8_display_width_n(const char *str, size_t max_bytes)
Calculate terminal display width of a UTF-8 string up to byte limit.
Definition utf8.c:102
void invitation_render_logo(frame_buffer_t *buf, int cols, int frame, bool colors, bool compact)
Definition invitation.c:34
For animation config, this is the live record that ties type, fps, speed, hidden_policy together....
const animation_sample_t * ui_controller_animation_sample(void)
asciichat_error_t ui_input_render(frame_buffer_t *buffer, int row, int col, int width, int height, const char *text, size_t cursor, bool preserve_quotes)
Definition ui/input.c:6

References colors, frame_buffer_append(), frame_buffer_get_screen_output_fd(), frame_buffer_printf(), GET_OPTION, height, invitation_render_logo(), NS_PER_MS_INT, options_terminal_settings, animation_sample_t::seconds, ui_controller_animation_sample(), ui_input_render(), utf8_display_width_n(), and width.

◆ ui_password_prompt_present()

asciichat_error_t ui_password_prompt_present ( const char * target,
const char * masked,
size_t cursor,
size_t selected_button,
bool incorrect,
bool can_confirm,
bool newline_limit )

The snapshot contains masked text only. Selection: confirm=0, cancel=1.

Definition at line 337 of file prompt.c.

339 {
340 if (!target || !masked || selected_button > 1)
341 return SET_ERRNO(ERROR_INVALID_PARAM, "Invalid password presentation");
342 size_t target_bytes = strlen(target) + 1, masked_bytes = strlen(masked) + 1;
343 size_t bytes = sizeof(prompt_snapshot_t) + target_bytes + masked_bytes;
345 if (!s)
346 return SET_ERRNO(ERROR_MEMORY, "Cannot allocate password presentation");
347 s->prompt_bytes = target_bytes;
348 s->cursor = cursor;
349 s->selected_button = selected_button;
350 s->kind = UI_PROMPT_PASSWORD;
351 s->password_dialog = true;
352 s->secret = true;
353 s->incorrect = incorrect;
354 s->can_confirm = can_confirm;
355 s->newline_limit = newline_limit;
356 s->color = !GET_OPTION(strip_ansi) && terminal_should_color_output(prompt_fd(), options_terminal_settings());
357 memcpy(s->text, target, target_bytes);
358 memcpy(s->text + target_bytes, masked, masked_bytes);
360 (terminal_size_t){.cols = 40, .rows = 19}, render_prompt, s, bytes);
361 SAFE_FREE(s);
362 return result;
363}
#define SET_ERRNO(code,...)
#define SAFE_FREE(ptr)
Definition common.h:377
#define SAFE_CALLOC(count, size, cast)
Definition common.h:275
asciichat_error_t
Error and exit codes - unified status values (0-255).
Definition error_codes.h:44
@ ERROR_MEMORY
Definition error_codes.h:51
@ ERROR_INVALID_PARAM
bool newline_limit
Definition prompt.c:29
size_t cursor
Definition prompt.c:27
size_t prompt_bytes
Definition prompt.c:26
bool password_dialog
Definition prompt.c:29
ui_prompt_kind_t kind
Definition prompt.c:25
size_t selected_button
Definition prompt.c:28
@ UI_SCREEN_PROMPT

References prompt_snapshot_t::can_confirm, prompt_snapshot_t::color, prompt_snapshot_t::cursor, ERROR_INVALID_PARAM, ERROR_MEMORY, GET_OPTION, prompt_snapshot_t::incorrect, prompt_snapshot_t::kind, prompt_snapshot_t::newline_limit, options_terminal_settings, prompt_snapshot_t::password_dialog, prompt_snapshot_t::prompt_bytes, SAFE_CALLOC, SAFE_FREE, prompt_snapshot_t::secret, prompt_snapshot_t::selected_button, SET_ERRNO, prompt_snapshot_t::text, ui_controller_submit(), and UI_SCREEN_PROMPT.

◆ ui_prompt_dismiss()

void ui_prompt_dismiss ( int previous)

Dismiss a prompt and restore its previous interactive owner, if still live.

Definition at line 301 of file prompt.c.

301 {
304 ui_controller_write(prompt_fd(), "\r\n", 2);
305}
void ui_controller_dismiss(ui_screen_t screen, int previous)
bool ui_controller_is_presenting(void)
asciichat_error_t ui_controller_write(int fd, const char *data, size_t len)

References ui_controller_dismiss(), ui_controller_is_presenting(), ui_controller_write(), and UI_SCREEN_PROMPT.

Referenced by ui_prompt_remove().

◆ ui_prompt_kind_name()

const char * ui_prompt_kind_name ( ui_prompt_kind_t kind)

Definition at line 235 of file prompt.c.

235 {
236 switch (kind) {
237 case UI_PROMPT_PASSWORD:
238 return "password_prompt";
239 case UI_PROMPT_MEDIA_INPUT:
240 return "media_input_prompt";
241 case UI_PROMPT_CONFIRMATION:
242 return "confirmation_prompt";
243 case UI_PROMPT_SSH_PASSPHRASE:
244 return "ssh_passphrase_prompt";
245 case UI_PROMPT_GPG_PASSPHRASE:
246 return "gpg_passphrase_prompt";
247 case UI_PROMPT_TRUST_HOST:
248 return "trust_host_prompt";
249 case UI_PROMPT_UNVERIFIED_HOST:
250 return "unverified_host_prompt";
251 case UI_PROMPT_DISCOVERY_KEY_CHANGE:
252 return "discovery_key_change_prompt";
253 case UI_PROMPT_IP_DISCLOSURE:
254 return "ip_disclosure_prompt";
255 case UI_PROMPT_CONFIG_OVERWRITE:
256 return "config_overwrite_prompt";
257 case UI_PROMPT_MANPAGE_OVERWRITE:
258 return "manpage_overwrite_prompt";
259 case UI_PROMPT_COMPLETION_OVERWRITE:
260 return "completion_overwrite_prompt";
261 default:
262 return "input_prompt";
263 }
264}

Referenced by main(), and ui_prompt_usage_name().

◆ ui_prompt_present()

asciichat_error_t ui_prompt_present ( const char * prompt,
const char * visible,
size_t cursor,
bool secret )

Only display-safe text crosses this boundary; never pass an unmasked password.

Definition at line 266 of file prompt.c.

266 {
267 return ui_prompt_present_kind(prompt, visible, cursor, secret, secret ? UI_PROMPT_PASSWORD : UI_PROMPT_INPUT);
268}
asciichat_error_t ui_prompt_present_kind(const char *prompt, const char *visible, size_t cursor, bool secret, ui_prompt_kind_t kind)
Definition prompt.c:270

References ui_prompt_present_kind().

◆ ui_prompt_present_kind()

asciichat_error_t ui_prompt_present_kind ( const char * prompt,
const char * visible,
size_t cursor,
bool secret,
ui_prompt_kind_t kind )

Definition at line 270 of file prompt.c.

271 {
272 size_t prompt_bytes = strlen(prompt) + 1;
273 size_t visible_bytes = strlen(visible) + 1;
274 prompt_snapshot_t *snapshot = SAFE_MALLOC(sizeof(*snapshot) + prompt_bytes + visible_bytes, prompt_snapshot_t *);
275 if (!snapshot)
276 return SET_ERRNO(ERROR_MEMORY, "Cannot allocate prompt presentation");
277 snapshot->kind = kind;
278 snapshot->password_dialog = snapshot->incorrect = snapshot->can_confirm = snapshot->newline_limit = false;
279 snapshot->selected_button = 0;
280 snapshot->prompt_bytes = prompt_bytes;
281 snapshot->cursor = cursor;
282 snapshot->secret = secret;
284 bool media = strncmp(prompt, "Open media:", 11) == 0;
285 snapshot->color =
286 !media && !GET_OPTION(strip_ansi) && terminal_should_color_output(prompt_fd(), options_terminal_settings());
287 snapshot->unicode = !media && terminal_should_use_utf8(GET_OPTION(force_utf8));
288 memcpy(snapshot->text, prompt, prompt_bytes);
289 memcpy(snapshot->text + prompt_bytes, visible, visible_bytes);
290 // Height is measured at the minimum width, so every larger terminal fits.
291 terminal_size_t minimum = {.cols = 40,
292 .rows = ui_notice_render(NULL, prompt, snapshot->severity, 40, false, false) + 3};
293 if (media)
294 minimum.rows = 8;
295 asciichat_error_t result = ui_controller_submit(UI_SCREEN_PROMPT, prompt_fd(), minimum, render_prompt, snapshot,
296 sizeof(*snapshot) + prompt_bytes + visible_bytes);
297 SAFE_FREE(snapshot);
298 return result;
299}
#define SAFE_MALLOC(size, cast)
Definition common.h:265
int ui_notice_render(frame_buffer_t *buffer, const char *text, ui_notice_severity_t severity, int cols, bool unicode, bool color)
Definition notice.c:64
ui_notice_severity_t ui_notice_prompt_severity(void)
Definition notice.c:522
ui_notice_severity_t severity
Definition prompt.c:30

References prompt_snapshot_t::can_confirm, prompt_snapshot_t::color, prompt_snapshot_t::cursor, ERROR_MEMORY, GET_OPTION, prompt_snapshot_t::incorrect, prompt_snapshot_t::kind, prompt_snapshot_t::newline_limit, options_terminal_settings, prompt_snapshot_t::password_dialog, prompt_snapshot_t::prompt_bytes, SAFE_FREE, SAFE_MALLOC, prompt_snapshot_t::secret, prompt_snapshot_t::selected_button, SET_ERRNO, prompt_snapshot_t::severity, prompt_snapshot_t::text, ui_controller_submit(), ui_notice_prompt_severity(), ui_notice_render(), UI_SCREEN_PROMPT, and prompt_snapshot_t::unicode.

Referenced by ui_input_media_begin(), ui_input_read_key(), and ui_prompt_present().

◆ ui_prompt_remove()

void ui_prompt_remove ( void )

Remove an asynchronous prompt without restoring an earlier interactive view.

Definition at line 307 of file prompt.c.

307 {
309}
void ui_prompt_dismiss(int previous)
Definition prompt.c:301

References ui_prompt_dismiss().

Referenced by session_handle_keyboard_input(), and ui_input_read_key().

◆ ui_prompt_required_rows()

int ui_prompt_required_rows ( const void * snapshot,
int cols )

Definition at line 311 of file prompt.c.

311 {
312 const prompt_snapshot_t *snapshot = data;
313 if (snapshot->password_dialog) {
314 int rows = 15 + password_lines(snapshot);
315 return rows < 19 ? 19 : rows;
316 }
317 if (strncmp(snapshot->text, "Open media:", 11) == 0)
318 return cols < 52 ? 8 : 11;
319 return ui_notice_render(NULL, snapshot->text, snapshot->severity, cols, false, false) + 3;
320}

References prompt_snapshot_t::password_dialog, prompt_snapshot_t::severity, prompt_snapshot_t::text, and ui_notice_render().

◆ ui_prompt_title()

const char * ui_prompt_title ( const void * snapshot)

Definition at line 183 of file prompt.c.

183 {
184 const prompt_snapshot_t *snapshot = data;
185 if (strncmp(snapshot->text, "Open media:", 11) == 0)
186 return "load file/url";
187 if (strstr(snapshot->text, "(y/N)") || strstr(snapshot->text, "(Y/n)"))
188 return "confirmation";
189 if (snapshot->secret)
190 return "password required";
191 return "input";
192}

References prompt_snapshot_t::secret, and prompt_snapshot_t::text.

◆ ui_prompt_usage_name()

const char * ui_prompt_usage_name ( const void * snapshot)

Definition at line 228 of file prompt.c.

228 {
229 const prompt_snapshot_t *snapshot = data;
230 if (!snapshot)
231 return "input_prompt";
232 return ui_prompt_kind_name(snapshot->kind);
233}
const char * ui_prompt_kind_name(ui_prompt_kind_t kind)
Definition prompt.c:235

References prompt_snapshot_t::kind, and ui_prompt_kind_name().