diff options
Diffstat (limited to 'tools/perf/ui/tui/util.c')
| -rw-r--r-- | tools/perf/ui/tui/util.c | 256 | 
1 files changed, 256 insertions, 0 deletions
diff --git a/tools/perf/ui/tui/util.c b/tools/perf/ui/tui/util.c new file mode 100644 index 00000000000..bf890f72fe8 --- /dev/null +++ b/tools/perf/ui/tui/util.c @@ -0,0 +1,256 @@ +#include "../../util/util.h" +#include <signal.h> +#include <stdbool.h> +#include <string.h> +#include <sys/ttydefaults.h> + +#include "../../util/cache.h" +#include "../../util/debug.h" +#include "../browser.h" +#include "../keysyms.h" +#include "../helpline.h" +#include "../ui.h" +#include "../util.h" +#include "../libslang.h" + +static void ui_browser__argv_write(struct ui_browser *browser, +				   void *entry, int row) +{ +	char **arg = entry; +	bool current_entry = ui_browser__is_current_entry(browser, row); + +	ui_browser__set_color(browser, current_entry ? HE_COLORSET_SELECTED : +						       HE_COLORSET_NORMAL); +	slsmg_write_nstring(*arg, browser->width); +} + +static int popup_menu__run(struct ui_browser *menu) +{ +	int key; + +	if (ui_browser__show(menu, " ", "ESC: exit, ENTER|->: Select option") < 0) +		return -1; + +	while (1) { +		key = ui_browser__run(menu, 0); + +		switch (key) { +		case K_RIGHT: +		case K_ENTER: +			key = menu->index; +			break; +		case K_LEFT: +		case K_ESC: +		case 'q': +		case CTRL('c'): +			key = -1; +			break; +		default: +			continue; +		} + +		break; +	} + +	ui_browser__hide(menu); +	return key; +} + +int ui__popup_menu(int argc, char * const argv[]) +{ +	struct ui_browser menu = { +		.entries    = (void *)argv, +		.refresh    = ui_browser__argv_refresh, +		.seek	    = ui_browser__argv_seek, +		.write	    = ui_browser__argv_write, +		.nr_entries = argc, +	}; + +	return popup_menu__run(&menu); +} + +int ui_browser__input_window(const char *title, const char *text, char *input, +			     const char *exit_msg, int delay_secs) +{ +	int x, y, len, key; +	int max_len = 60, nr_lines = 0; +	static char buf[50]; +	const char *t; + +	t = text; +	while (1) { +		const char *sep = strchr(t, '\n'); + +		if (sep == NULL) +			sep = strchr(t, '\0'); +		len = sep - t; +		if (max_len < len) +			max_len = len; +		++nr_lines; +		if (*sep == '\0') +			break; +		t = sep + 1; +	} + +	pthread_mutex_lock(&ui__lock); + +	max_len += 2; +	nr_lines += 8; +	y = SLtt_Screen_Rows / 2 - nr_lines / 2; +	x = SLtt_Screen_Cols / 2 - max_len / 2; + +	SLsmg_set_color(0); +	SLsmg_draw_box(y, x++, nr_lines, max_len); +	if (title) { +		SLsmg_gotorc(y, x + 1); +		SLsmg_write_string((char *)title); +	} +	SLsmg_gotorc(++y, x); +	nr_lines -= 7; +	max_len -= 2; +	SLsmg_write_wrapped_string((unsigned char *)text, y, x, +				   nr_lines, max_len, 1); +	y += nr_lines; +	len = 5; +	while (len--) { +		SLsmg_gotorc(y + len - 1, x); +		SLsmg_write_nstring((char *)" ", max_len); +	} +	SLsmg_draw_box(y++, x + 1, 3, max_len - 2); + +	SLsmg_gotorc(y + 3, x); +	SLsmg_write_nstring((char *)exit_msg, max_len); +	SLsmg_refresh(); + +	pthread_mutex_unlock(&ui__lock); + +	x += 2; +	len = 0; +	key = ui__getch(delay_secs); +	while (key != K_TIMER && key != K_ENTER && key != K_ESC) { +		pthread_mutex_lock(&ui__lock); + +		if (key == K_BKSPC) { +			if (len == 0) { +				pthread_mutex_unlock(&ui__lock); +				goto next_key; +			} +			SLsmg_gotorc(y, x + --len); +			SLsmg_write_char(' '); +		} else { +			buf[len] = key; +			SLsmg_gotorc(y, x + len++); +			SLsmg_write_char(key); +		} +		SLsmg_refresh(); + +		pthread_mutex_unlock(&ui__lock); + +		/* XXX more graceful overflow handling needed */ +		if (len == sizeof(buf) - 1) { +			ui_helpline__push("maximum size of symbol name reached!"); +			key = K_ENTER; +			break; +		} +next_key: +		key = ui__getch(delay_secs); +	} + +	buf[len] = '\0'; +	strncpy(input, buf, len+1); +	return key; +} + +int ui__question_window(const char *title, const char *text, +			const char *exit_msg, int delay_secs) +{ +	int x, y; +	int max_len = 0, nr_lines = 0; +	const char *t; + +	t = text; +	while (1) { +		const char *sep = strchr(t, '\n'); +		int len; + +		if (sep == NULL) +			sep = strchr(t, '\0'); +		len = sep - t; +		if (max_len < len) +			max_len = len; +		++nr_lines; +		if (*sep == '\0') +			break; +		t = sep + 1; +	} + +	pthread_mutex_lock(&ui__lock); + +	max_len += 2; +	nr_lines += 4; +	y = SLtt_Screen_Rows / 2 - nr_lines / 2, +	x = SLtt_Screen_Cols / 2 - max_len / 2; + +	SLsmg_set_color(0); +	SLsmg_draw_box(y, x++, nr_lines, max_len); +	if (title) { +		SLsmg_gotorc(y, x + 1); +		SLsmg_write_string((char *)title); +	} +	SLsmg_gotorc(++y, x); +	nr_lines -= 2; +	max_len -= 2; +	SLsmg_write_wrapped_string((unsigned char *)text, y, x, +				   nr_lines, max_len, 1); +	SLsmg_gotorc(y + nr_lines - 2, x); +	SLsmg_write_nstring((char *)" ", max_len); +	SLsmg_gotorc(y + nr_lines - 1, x); +	SLsmg_write_nstring((char *)exit_msg, max_len); +	SLsmg_refresh(); + +	pthread_mutex_unlock(&ui__lock); + +	return ui__getch(delay_secs); +} + +int ui__help_window(const char *text) +{ +	return ui__question_window("Help", text, "Press any key...", 0); +} + +int ui__dialog_yesno(const char *msg) +{ +	return ui__question_window(NULL, msg, "Enter: Yes, ESC: No", 0); +} + +static int __ui__warning(const char *title, const char *format, va_list args) +{ +	char *s; + +	if (vasprintf(&s, format, args) > 0) { +		int key; + +		key = ui__question_window(title, s, "Press any key...", 0); +		free(s); +		return key; +	} + +	fprintf(stderr, "%s\n", title); +	vfprintf(stderr, format, args); +	return K_ESC; +} + +static int perf_tui__error(const char *format, va_list args) +{ +	return __ui__warning("Error:", format, args); +} + +static int perf_tui__warning(const char *format, va_list args) +{ +	return __ui__warning("Warning:", format, args); +} + +struct perf_error_ops perf_tui_eops = { +	.error		= perf_tui__error, +	.warning	= perf_tui__warning, +};  | 
