brintos

brintos / linux-shallow public Read only

0
0
Text · 5.5 KiB · e4d322c Raw
275 lines · c
1// SPDX-License-Identifier: GPL-2.02#include <signal.h>3#include <stdbool.h>4#include <string.h>5#include <stdlib.h>6#include <sys/ttydefaults.h>7 8#include "../browser.h"9#include "../keysyms.h"10#include "../helpline.h"11#include "../ui.h"12#include "../util.h"13#include "../libslang.h"14 15static void ui_browser__argv_write(struct ui_browser *browser,16				   void *entry, int row)17{18	char **arg = entry;19	bool current_entry = ui_browser__is_current_entry(browser, row);20 21	ui_browser__set_color(browser, current_entry ? HE_COLORSET_SELECTED :22						       HE_COLORSET_NORMAL);23	ui_browser__write_nstring(browser, *arg, browser->width);24}25 26static int popup_menu__run(struct ui_browser *menu, int *keyp)27{28	int key;29 30	if (ui_browser__show(menu, " ", "ESC: exit, ENTER|->: Select option") < 0)31		return -1;32 33	while (1) {34		key = ui_browser__run(menu, 0);35 36		switch (key) {37		case K_RIGHT:38		case K_ENTER:39			key = menu->index;40			break;41		case K_LEFT:42		case K_ESC:43		case 'q':44		case CTRL('c'):45			key = -1;46			break;47		default:48			if (keyp) {49				*keyp = key;50				key = menu->nr_entries;51				break;52			}53			continue;54		}55 56		break;57	}58 59	ui_browser__hide(menu);60	return key;61}62 63int ui__popup_menu(int argc, char * const argv[], int *keyp)64{65	struct ui_browser menu = {66		.entries    = (void *)argv,67		.refresh    = ui_browser__argv_refresh,68		.seek	    = ui_browser__argv_seek,69		.write	    = ui_browser__argv_write,70		.nr_entries = argc,71	};72	return popup_menu__run(&menu, keyp);73}74 75int ui_browser__input_window(const char *title, const char *text, char *input,76			     const char *exit_msg, int delay_secs)77{78	int x, y, len, key;79	int max_len = 60, nr_lines = 0;80	static char buf[50];81	const char *t;82 83	t = text;84	while (1) {85		const char *sep = strchr(t, '\n');86 87		if (sep == NULL)88			sep = strchr(t, '\0');89		len = sep - t;90		if (max_len < len)91			max_len = len;92		++nr_lines;93		if (*sep == '\0')94			break;95		t = sep + 1;96	}97 98	mutex_lock(&ui__lock);99 100	max_len += 2;101	nr_lines += 8;102	y = SLtt_Screen_Rows / 2 - nr_lines / 2;103	x = SLtt_Screen_Cols / 2 - max_len / 2;104 105	SLsmg_set_color(0);106	SLsmg_draw_box(y, x++, nr_lines, max_len);107	if (title) {108		SLsmg_gotorc(y, x + 1);109		SLsmg_write_string(title);110	}111	SLsmg_gotorc(++y, x);112	nr_lines -= 7;113	max_len -= 2;114	SLsmg_write_wrapped_string((unsigned char *)text, y, x,115				   nr_lines, max_len, 1);116	y += nr_lines;117	len = 5;118	while (len--) {119		SLsmg_gotorc(y + len - 1, x);120		SLsmg_write_nstring(" ", max_len);121	}122	SLsmg_draw_box(y++, x + 1, 3, max_len - 2);123 124	SLsmg_gotorc(y + 3, x);125	SLsmg_write_nstring(exit_msg, max_len);126	SLsmg_refresh();127 128	mutex_unlock(&ui__lock);129 130	x += 2;131	len = 0;132	key = ui__getch(delay_secs);133	while (key != K_TIMER && key != K_ENTER && key != K_ESC) {134		mutex_lock(&ui__lock);135 136		if (key == K_BKSPC) {137			if (len == 0) {138				mutex_unlock(&ui__lock);139				goto next_key;140			}141			SLsmg_gotorc(y, x + --len);142			SLsmg_write_char(' ');143		} else {144			buf[len] = key;145			SLsmg_gotorc(y, x + len++);146			SLsmg_write_char(key);147		}148		SLsmg_refresh();149 150		mutex_unlock(&ui__lock);151 152		/* XXX more graceful overflow handling needed */153		if (len == sizeof(buf) - 1) {154			ui_helpline__push("maximum size of symbol name reached!");155			key = K_ENTER;156			break;157		}158next_key:159		key = ui__getch(delay_secs);160	}161 162	buf[len] = '\0';163	strncpy(input, buf, len+1);164	return key;165}166 167void __ui__info_window(const char *title, const char *text, const char *exit_msg)168{169	int x, y;170	int max_len = 0, nr_lines = 0;171	const char *t;172 173	t = text;174	while (1) {175		const char *sep = strchr(t, '\n');176		int len;177 178		if (sep == NULL)179			sep = strchr(t, '\0');180		len = sep - t;181		if (max_len < len)182			max_len = len;183		++nr_lines;184		if (*sep == '\0')185			break;186		t = sep + 1;187	}188 189	max_len += 2;190	nr_lines += 2;191	if (exit_msg)192		nr_lines += 2;193	y = SLtt_Screen_Rows / 2 - nr_lines / 2,194	x = SLtt_Screen_Cols / 2 - max_len / 2;195 196	SLsmg_set_color(0);197	SLsmg_draw_box(y, x++, nr_lines, max_len);198	if (title) {199		SLsmg_gotorc(y, x + 1);200		SLsmg_write_string(title);201	}202	SLsmg_gotorc(++y, x);203	if (exit_msg)204		nr_lines -= 2;205	max_len -= 2;206	SLsmg_write_wrapped_string((unsigned char *)text, y, x,207				   nr_lines, max_len, 1);208	if (exit_msg) {209		SLsmg_gotorc(y + nr_lines - 2, x);210		SLsmg_write_nstring(" ", max_len);211		SLsmg_gotorc(y + nr_lines - 1, x);212		SLsmg_write_nstring(exit_msg, max_len);213	}214}215 216void ui__info_window(const char *title, const char *text)217{218	mutex_lock(&ui__lock);219	__ui__info_window(title, text, NULL);220	SLsmg_refresh();221	mutex_unlock(&ui__lock);222}223 224int ui__question_window(const char *title, const char *text,225			const char *exit_msg, int delay_secs)226{227	mutex_lock(&ui__lock);228	__ui__info_window(title, text, exit_msg);229	SLsmg_refresh();230	mutex_unlock(&ui__lock);231	return ui__getch(delay_secs);232}233 234int ui__help_window(const char *text)235{236	return ui__question_window("Help", text, "Press any key...", 0);237}238 239int ui__dialog_yesno(const char *msg)240{241	return ui__question_window(NULL, msg, "Enter: Yes, ESC: No", 0);242}243 244static int __ui__warning(const char *title, const char *format, va_list args)245{246	char *s;247 248	if (vasprintf(&s, format, args) > 0) {249		int key;250 251		key = ui__question_window(title, s, "Press any key...", 0);252		free(s);253		return key;254	}255 256	fprintf(stderr, "%s\n", title);257	vfprintf(stderr, format, args);258	return K_ESC;259}260 261static int perf_tui__error(const char *format, va_list args)262{263	return __ui__warning("Error:", format, args);264}265 266static int perf_tui__warning(const char *format, va_list args)267{268	return __ui__warning("Warning:", format, args);269}270 271struct perf_error_ops perf_tui_eops = {272	.error		= perf_tui__error,273	.warning	= perf_tui__warning,274};275