xref: /openbmc/linux/scripts/kconfig/lxdialog/util.c (revision 8be98d2f2a0a262f8bf8a0bc1fdf522b3c7aab17)
10c874100SMasahiro Yamada // SPDX-License-Identifier: GPL-2.0+
26f6046cfSSam Ravnborg /*
36f6046cfSSam Ravnborg  *  util.c
46f6046cfSSam Ravnborg  *
56f6046cfSSam Ravnborg  *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
66f6046cfSSam Ravnborg  *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
76f6046cfSSam Ravnborg  */
86f6046cfSSam Ravnborg 
9668cdedfSArnaud Lacombe #include <stdarg.h>
10668cdedfSArnaud Lacombe 
116f6046cfSSam Ravnborg #include "dialog.h"
126f6046cfSSam Ravnborg 
133eb95c84SDirk Gouders /* Needed in signal handler in mconf.c */
143eb95c84SDirk Gouders int saved_x, saved_y;
153eb95c84SDirk Gouders 
1698e5a157SSam Ravnborg struct dialog_info dlg;
176f6046cfSSam Ravnborg 
set_mono_theme(void)1898e5a157SSam Ravnborg static void set_mono_theme(void)
1998e5a157SSam Ravnborg {
2098e5a157SSam Ravnborg 	dlg.screen.atr = A_NORMAL;
2198e5a157SSam Ravnborg 	dlg.shadow.atr = A_NORMAL;
2298e5a157SSam Ravnborg 	dlg.dialog.atr = A_NORMAL;
2398e5a157SSam Ravnborg 	dlg.title.atr = A_BOLD;
2498e5a157SSam Ravnborg 	dlg.border.atr = A_NORMAL;
2598e5a157SSam Ravnborg 	dlg.button_active.atr = A_REVERSE;
2698e5a157SSam Ravnborg 	dlg.button_inactive.atr = A_DIM;
2798e5a157SSam Ravnborg 	dlg.button_key_active.atr = A_REVERSE;
2898e5a157SSam Ravnborg 	dlg.button_key_inactive.atr = A_BOLD;
2998e5a157SSam Ravnborg 	dlg.button_label_active.atr = A_REVERSE;
3098e5a157SSam Ravnborg 	dlg.button_label_inactive.atr = A_NORMAL;
3198e5a157SSam Ravnborg 	dlg.inputbox.atr = A_NORMAL;
3298e5a157SSam Ravnborg 	dlg.inputbox_border.atr = A_NORMAL;
3398e5a157SSam Ravnborg 	dlg.searchbox.atr = A_NORMAL;
3498e5a157SSam Ravnborg 	dlg.searchbox_title.atr = A_BOLD;
3598e5a157SSam Ravnborg 	dlg.searchbox_border.atr = A_NORMAL;
3698e5a157SSam Ravnborg 	dlg.position_indicator.atr = A_BOLD;
3798e5a157SSam Ravnborg 	dlg.menubox.atr = A_NORMAL;
3898e5a157SSam Ravnborg 	dlg.menubox_border.atr = A_NORMAL;
3998e5a157SSam Ravnborg 	dlg.item.atr = A_NORMAL;
4098e5a157SSam Ravnborg 	dlg.item_selected.atr = A_REVERSE;
4198e5a157SSam Ravnborg 	dlg.tag.atr = A_BOLD;
4298e5a157SSam Ravnborg 	dlg.tag_selected.atr = A_REVERSE;
4398e5a157SSam Ravnborg 	dlg.tag_key.atr = A_BOLD;
4498e5a157SSam Ravnborg 	dlg.tag_key_selected.atr = A_REVERSE;
4598e5a157SSam Ravnborg 	dlg.check.atr = A_BOLD;
4698e5a157SSam Ravnborg 	dlg.check_selected.atr = A_REVERSE;
4798e5a157SSam Ravnborg 	dlg.uarrow.atr = A_BOLD;
4898e5a157SSam Ravnborg 	dlg.darrow.atr = A_BOLD;
4998e5a157SSam Ravnborg }
5098e5a157SSam Ravnborg 
5198e5a157SSam Ravnborg #define DLG_COLOR(dialog, f, b, h) \
5298e5a157SSam Ravnborg do {                               \
5398e5a157SSam Ravnborg 	dlg.dialog.fg = (f);       \
5498e5a157SSam Ravnborg 	dlg.dialog.bg = (b);       \
5598e5a157SSam Ravnborg 	dlg.dialog.hl = (h);       \
5698e5a157SSam Ravnborg } while (0)
5798e5a157SSam Ravnborg 
set_classic_theme(void)5898e5a157SSam Ravnborg static void set_classic_theme(void)
5998e5a157SSam Ravnborg {
6098e5a157SSam Ravnborg 	DLG_COLOR(screen,                COLOR_CYAN,   COLOR_BLUE,   true);
6198e5a157SSam Ravnborg 	DLG_COLOR(shadow,                COLOR_BLACK,  COLOR_BLACK,  true);
6298e5a157SSam Ravnborg 	DLG_COLOR(dialog,                COLOR_BLACK,  COLOR_WHITE,  false);
6398e5a157SSam Ravnborg 	DLG_COLOR(title,                 COLOR_YELLOW, COLOR_WHITE,  true);
6498e5a157SSam Ravnborg 	DLG_COLOR(border,                COLOR_WHITE,  COLOR_WHITE,  true);
6598e5a157SSam Ravnborg 	DLG_COLOR(button_active,         COLOR_WHITE,  COLOR_BLUE,   true);
6698e5a157SSam Ravnborg 	DLG_COLOR(button_inactive,       COLOR_BLACK,  COLOR_WHITE,  false);
6798e5a157SSam Ravnborg 	DLG_COLOR(button_key_active,     COLOR_WHITE,  COLOR_BLUE,   true);
6898e5a157SSam Ravnborg 	DLG_COLOR(button_key_inactive,   COLOR_RED,    COLOR_WHITE,  false);
6998e5a157SSam Ravnborg 	DLG_COLOR(button_label_active,   COLOR_YELLOW, COLOR_BLUE,   true);
7098e5a157SSam Ravnborg 	DLG_COLOR(button_label_inactive, COLOR_BLACK,  COLOR_WHITE,  true);
7198e5a157SSam Ravnborg 	DLG_COLOR(inputbox,              COLOR_BLACK,  COLOR_WHITE,  false);
7298e5a157SSam Ravnborg 	DLG_COLOR(inputbox_border,       COLOR_BLACK,  COLOR_WHITE,  false);
7398e5a157SSam Ravnborg 	DLG_COLOR(searchbox,             COLOR_BLACK,  COLOR_WHITE,  false);
7498e5a157SSam Ravnborg 	DLG_COLOR(searchbox_title,       COLOR_YELLOW, COLOR_WHITE,  true);
7598e5a157SSam Ravnborg 	DLG_COLOR(searchbox_border,      COLOR_WHITE,  COLOR_WHITE,  true);
7698e5a157SSam Ravnborg 	DLG_COLOR(position_indicator,    COLOR_YELLOW, COLOR_WHITE,  true);
7798e5a157SSam Ravnborg 	DLG_COLOR(menubox,               COLOR_BLACK,  COLOR_WHITE,  false);
7898e5a157SSam Ravnborg 	DLG_COLOR(menubox_border,        COLOR_WHITE,  COLOR_WHITE,  true);
7998e5a157SSam Ravnborg 	DLG_COLOR(item,                  COLOR_BLACK,  COLOR_WHITE,  false);
8098e5a157SSam Ravnborg 	DLG_COLOR(item_selected,         COLOR_WHITE,  COLOR_BLUE,   true);
8198e5a157SSam Ravnborg 	DLG_COLOR(tag,                   COLOR_YELLOW, COLOR_WHITE,  true);
8298e5a157SSam Ravnborg 	DLG_COLOR(tag_selected,          COLOR_YELLOW, COLOR_BLUE,   true);
8398e5a157SSam Ravnborg 	DLG_COLOR(tag_key,               COLOR_YELLOW, COLOR_WHITE,  true);
8498e5a157SSam Ravnborg 	DLG_COLOR(tag_key_selected,      COLOR_YELLOW, COLOR_BLUE,   true);
8598e5a157SSam Ravnborg 	DLG_COLOR(check,                 COLOR_BLACK,  COLOR_WHITE,  false);
8698e5a157SSam Ravnborg 	DLG_COLOR(check_selected,        COLOR_WHITE,  COLOR_BLUE,   true);
8798e5a157SSam Ravnborg 	DLG_COLOR(uarrow,                COLOR_GREEN,  COLOR_WHITE,  true);
8898e5a157SSam Ravnborg 	DLG_COLOR(darrow,                COLOR_GREEN,  COLOR_WHITE,  true);
8998e5a157SSam Ravnborg }
9098e5a157SSam Ravnborg 
set_blackbg_theme(void)9145897213SSam Ravnborg static void set_blackbg_theme(void)
9245897213SSam Ravnborg {
9345897213SSam Ravnborg 	DLG_COLOR(screen, COLOR_RED,   COLOR_BLACK, true);
9445897213SSam Ravnborg 	DLG_COLOR(shadow, COLOR_BLACK, COLOR_BLACK, false);
9545897213SSam Ravnborg 	DLG_COLOR(dialog, COLOR_WHITE, COLOR_BLACK, false);
9645897213SSam Ravnborg 	DLG_COLOR(title,  COLOR_RED,   COLOR_BLACK, false);
9745897213SSam Ravnborg 	DLG_COLOR(border, COLOR_BLACK, COLOR_BLACK, true);
9845897213SSam Ravnborg 
9945897213SSam Ravnborg 	DLG_COLOR(button_active,         COLOR_YELLOW, COLOR_RED,   false);
10045897213SSam Ravnborg 	DLG_COLOR(button_inactive,       COLOR_YELLOW, COLOR_BLACK, false);
10145897213SSam Ravnborg 	DLG_COLOR(button_key_active,     COLOR_YELLOW, COLOR_RED,   true);
10245897213SSam Ravnborg 	DLG_COLOR(button_key_inactive,   COLOR_RED,    COLOR_BLACK, false);
10345897213SSam Ravnborg 	DLG_COLOR(button_label_active,   COLOR_WHITE,  COLOR_RED,   false);
10445897213SSam Ravnborg 	DLG_COLOR(button_label_inactive, COLOR_BLACK,  COLOR_BLACK, true);
10545897213SSam Ravnborg 
10645897213SSam Ravnborg 	DLG_COLOR(inputbox,         COLOR_YELLOW, COLOR_BLACK, false);
10745897213SSam Ravnborg 	DLG_COLOR(inputbox_border,  COLOR_YELLOW, COLOR_BLACK, false);
10845897213SSam Ravnborg 
10945897213SSam Ravnborg 	DLG_COLOR(searchbox,        COLOR_YELLOW, COLOR_BLACK, false);
11045897213SSam Ravnborg 	DLG_COLOR(searchbox_title,  COLOR_YELLOW, COLOR_BLACK, true);
11145897213SSam Ravnborg 	DLG_COLOR(searchbox_border, COLOR_BLACK,  COLOR_BLACK, true);
11245897213SSam Ravnborg 
11345897213SSam Ravnborg 	DLG_COLOR(position_indicator, COLOR_RED, COLOR_BLACK,  false);
11445897213SSam Ravnborg 
11545897213SSam Ravnborg 	DLG_COLOR(menubox,          COLOR_YELLOW, COLOR_BLACK, false);
11645897213SSam Ravnborg 	DLG_COLOR(menubox_border,   COLOR_BLACK,  COLOR_BLACK, true);
11745897213SSam Ravnborg 
11845897213SSam Ravnborg 	DLG_COLOR(item,             COLOR_WHITE, COLOR_BLACK, false);
11945897213SSam Ravnborg 	DLG_COLOR(item_selected,    COLOR_WHITE, COLOR_RED,   false);
12045897213SSam Ravnborg 
12145897213SSam Ravnborg 	DLG_COLOR(tag,              COLOR_RED,    COLOR_BLACK, false);
12245897213SSam Ravnborg 	DLG_COLOR(tag_selected,     COLOR_YELLOW, COLOR_RED,   true);
12345897213SSam Ravnborg 	DLG_COLOR(tag_key,          COLOR_RED,    COLOR_BLACK, false);
12445897213SSam Ravnborg 	DLG_COLOR(tag_key_selected, COLOR_YELLOW, COLOR_RED,   true);
12545897213SSam Ravnborg 
12645897213SSam Ravnborg 	DLG_COLOR(check,            COLOR_YELLOW, COLOR_BLACK, false);
12745897213SSam Ravnborg 	DLG_COLOR(check_selected,   COLOR_YELLOW, COLOR_RED,   true);
12845897213SSam Ravnborg 
12945897213SSam Ravnborg 	DLG_COLOR(uarrow, COLOR_RED, COLOR_BLACK, false);
13045897213SSam Ravnborg 	DLG_COLOR(darrow, COLOR_RED, COLOR_BLACK, false);
13145897213SSam Ravnborg }
13245897213SSam Ravnborg 
set_bluetitle_theme(void)133350b5b76SSam Ravnborg static void set_bluetitle_theme(void)
134350b5b76SSam Ravnborg {
135350b5b76SSam Ravnborg 	set_classic_theme();
136350b5b76SSam Ravnborg 	DLG_COLOR(title,               COLOR_BLUE,   COLOR_WHITE, true);
137350b5b76SSam Ravnborg 	DLG_COLOR(button_key_active,   COLOR_YELLOW, COLOR_BLUE,  true);
138350b5b76SSam Ravnborg 	DLG_COLOR(button_label_active, COLOR_WHITE,  COLOR_BLUE,  true);
139350b5b76SSam Ravnborg 	DLG_COLOR(searchbox_title,     COLOR_BLUE,   COLOR_WHITE, true);
140350b5b76SSam Ravnborg 	DLG_COLOR(position_indicator,  COLOR_BLUE,   COLOR_WHITE, true);
141350b5b76SSam Ravnborg 	DLG_COLOR(tag,                 COLOR_BLUE,   COLOR_WHITE, true);
142350b5b76SSam Ravnborg 	DLG_COLOR(tag_key,             COLOR_BLUE,   COLOR_WHITE, true);
143350b5b76SSam Ravnborg 
144350b5b76SSam Ravnborg }
145350b5b76SSam Ravnborg 
14645897213SSam Ravnborg /*
14745897213SSam Ravnborg  * Select color theme
14845897213SSam Ravnborg  */
set_theme(const char * theme)14945897213SSam Ravnborg static int set_theme(const char *theme)
15045897213SSam Ravnborg {
15145897213SSam Ravnborg 	int use_color = 1;
15245897213SSam Ravnborg 	if (!theme)
153350b5b76SSam Ravnborg 		set_bluetitle_theme();
15445897213SSam Ravnborg 	else if (strcmp(theme, "classic") == 0)
15545897213SSam Ravnborg 		set_classic_theme();
156350b5b76SSam Ravnborg 	else if (strcmp(theme, "bluetitle") == 0)
157350b5b76SSam Ravnborg 		set_bluetitle_theme();
15845897213SSam Ravnborg 	else if (strcmp(theme, "blackbg") == 0)
15945897213SSam Ravnborg 		set_blackbg_theme();
16045897213SSam Ravnborg 	else if (strcmp(theme, "mono") == 0)
16145897213SSam Ravnborg 		use_color = 0;
16245897213SSam Ravnborg 
16345897213SSam Ravnborg 	return use_color;
16445897213SSam Ravnborg }
16545897213SSam Ravnborg 
init_one_color(struct dialog_color * color)16698e5a157SSam Ravnborg static void init_one_color(struct dialog_color *color)
16798e5a157SSam Ravnborg {
16898e5a157SSam Ravnborg 	static int pair = 0;
16998e5a157SSam Ravnborg 
17098e5a157SSam Ravnborg 	pair++;
17198e5a157SSam Ravnborg 	init_pair(pair, color->fg, color->bg);
17298e5a157SSam Ravnborg 	if (color->hl)
17398e5a157SSam Ravnborg 		color->atr = A_BOLD | COLOR_PAIR(pair);
17498e5a157SSam Ravnborg 	else
17598e5a157SSam Ravnborg 		color->atr = COLOR_PAIR(pair);
17698e5a157SSam Ravnborg }
17798e5a157SSam Ravnborg 
init_dialog_colors(void)17898e5a157SSam Ravnborg static void init_dialog_colors(void)
17998e5a157SSam Ravnborg {
18098e5a157SSam Ravnborg 	init_one_color(&dlg.screen);
18198e5a157SSam Ravnborg 	init_one_color(&dlg.shadow);
18298e5a157SSam Ravnborg 	init_one_color(&dlg.dialog);
18398e5a157SSam Ravnborg 	init_one_color(&dlg.title);
18498e5a157SSam Ravnborg 	init_one_color(&dlg.border);
18598e5a157SSam Ravnborg 	init_one_color(&dlg.button_active);
18698e5a157SSam Ravnborg 	init_one_color(&dlg.button_inactive);
18798e5a157SSam Ravnborg 	init_one_color(&dlg.button_key_active);
18898e5a157SSam Ravnborg 	init_one_color(&dlg.button_key_inactive);
18998e5a157SSam Ravnborg 	init_one_color(&dlg.button_label_active);
19098e5a157SSam Ravnborg 	init_one_color(&dlg.button_label_inactive);
19198e5a157SSam Ravnborg 	init_one_color(&dlg.inputbox);
19298e5a157SSam Ravnborg 	init_one_color(&dlg.inputbox_border);
19398e5a157SSam Ravnborg 	init_one_color(&dlg.searchbox);
19498e5a157SSam Ravnborg 	init_one_color(&dlg.searchbox_title);
19598e5a157SSam Ravnborg 	init_one_color(&dlg.searchbox_border);
19698e5a157SSam Ravnborg 	init_one_color(&dlg.position_indicator);
19798e5a157SSam Ravnborg 	init_one_color(&dlg.menubox);
19898e5a157SSam Ravnborg 	init_one_color(&dlg.menubox_border);
19998e5a157SSam Ravnborg 	init_one_color(&dlg.item);
20098e5a157SSam Ravnborg 	init_one_color(&dlg.item_selected);
20198e5a157SSam Ravnborg 	init_one_color(&dlg.tag);
20298e5a157SSam Ravnborg 	init_one_color(&dlg.tag_selected);
20398e5a157SSam Ravnborg 	init_one_color(&dlg.tag_key);
20498e5a157SSam Ravnborg 	init_one_color(&dlg.tag_key_selected);
20598e5a157SSam Ravnborg 	init_one_color(&dlg.check);
20698e5a157SSam Ravnborg 	init_one_color(&dlg.check_selected);
20798e5a157SSam Ravnborg 	init_one_color(&dlg.uarrow);
20898e5a157SSam Ravnborg 	init_one_color(&dlg.darrow);
20998e5a157SSam Ravnborg }
2106f6046cfSSam Ravnborg 
2116f6046cfSSam Ravnborg /*
21298e5a157SSam Ravnborg  * Setup for color display
2136f6046cfSSam Ravnborg  */
color_setup(const char * theme)21445897213SSam Ravnborg static void color_setup(const char *theme)
21598e5a157SSam Ravnborg {
216c154348fSRoman Zippel 	int use_color;
217c154348fSRoman Zippel 
218c154348fSRoman Zippel 	use_color = set_theme(theme);
219c154348fSRoman Zippel 	if (use_color && has_colors()) {
22098e5a157SSam Ravnborg 		start_color();
22198e5a157SSam Ravnborg 		init_dialog_colors();
222c154348fSRoman Zippel 	} else
22398e5a157SSam Ravnborg 		set_mono_theme();
22498e5a157SSam Ravnborg }
2256f6046cfSSam Ravnborg 
2266f6046cfSSam Ravnborg /*
2276f6046cfSSam Ravnborg  * Set window to attribute 'attr'
2286f6046cfSSam Ravnborg  */
attr_clear(WINDOW * win,int height,int width,chtype attr)2296f6046cfSSam Ravnborg void attr_clear(WINDOW * win, int height, int width, chtype attr)
2306f6046cfSSam Ravnborg {
2316f6046cfSSam Ravnborg 	int i, j;
2326f6046cfSSam Ravnborg 
2336f6046cfSSam Ravnborg 	wattrset(win, attr);
2346f6046cfSSam Ravnborg 	for (i = 0; i < height; i++) {
2356f6046cfSSam Ravnborg 		wmove(win, i, 0);
2366f6046cfSSam Ravnborg 		for (j = 0; j < width; j++)
2376f6046cfSSam Ravnborg 			waddch(win, ' ');
2386f6046cfSSam Ravnborg 	}
2396f6046cfSSam Ravnborg 	touchwin(win);
2406f6046cfSSam Ravnborg }
2416f6046cfSSam Ravnborg 
dialog_clear(void)2426f6046cfSSam Ravnborg void dialog_clear(void)
2436f6046cfSSam Ravnborg {
2444f2de3e1SDirk Gouders 	int lines, columns;
2454f2de3e1SDirk Gouders 
2464f2de3e1SDirk Gouders 	lines = getmaxy(stdscr);
2474f2de3e1SDirk Gouders 	columns = getmaxx(stdscr);
2484f2de3e1SDirk Gouders 
2494f2de3e1SDirk Gouders 	attr_clear(stdscr, lines, columns, dlg.screen.atr);
2506f6046cfSSam Ravnborg 	/* Display background title if it exists ... - SLH */
25198e5a157SSam Ravnborg 	if (dlg.backtitle != NULL) {
2529a69abf8SBenjamin Poirier 		int i, len = 0, skip = 0;
2539a69abf8SBenjamin Poirier 		struct subtitle_list *pos;
2546f6046cfSSam Ravnborg 
25598e5a157SSam Ravnborg 		wattrset(stdscr, dlg.screen.atr);
25698e5a157SSam Ravnborg 		mvwaddstr(stdscr, 0, 1, (char *)dlg.backtitle);
2579a69abf8SBenjamin Poirier 
2589a69abf8SBenjamin Poirier 		for (pos = dlg.subtitles; pos != NULL; pos = pos->next) {
2599a69abf8SBenjamin Poirier 			/* 3 is for the arrow and spaces */
2609a69abf8SBenjamin Poirier 			len += strlen(pos->text) + 3;
2619a69abf8SBenjamin Poirier 		}
2629a69abf8SBenjamin Poirier 
2636f6046cfSSam Ravnborg 		wmove(stdscr, 1, 1);
2644f2de3e1SDirk Gouders 		if (len > columns - 2) {
2659a69abf8SBenjamin Poirier 			const char *ellipsis = "[...] ";
2669a69abf8SBenjamin Poirier 			waddstr(stdscr, ellipsis);
2674f2de3e1SDirk Gouders 			skip = len - (columns - 2 - strlen(ellipsis));
2689a69abf8SBenjamin Poirier 		}
2699a69abf8SBenjamin Poirier 
2709a69abf8SBenjamin Poirier 		for (pos = dlg.subtitles; pos != NULL; pos = pos->next) {
2719a69abf8SBenjamin Poirier 			if (skip == 0)
2729a69abf8SBenjamin Poirier 				waddch(stdscr, ACS_RARROW);
2739a69abf8SBenjamin Poirier 			else
2749a69abf8SBenjamin Poirier 				skip--;
2759a69abf8SBenjamin Poirier 
2769a69abf8SBenjamin Poirier 			if (skip == 0)
2779a69abf8SBenjamin Poirier 				waddch(stdscr, ' ');
2789a69abf8SBenjamin Poirier 			else
2799a69abf8SBenjamin Poirier 				skip--;
2809a69abf8SBenjamin Poirier 
2819a69abf8SBenjamin Poirier 			if (skip < strlen(pos->text)) {
2829a69abf8SBenjamin Poirier 				waddstr(stdscr, pos->text + skip);
2839a69abf8SBenjamin Poirier 				skip = 0;
2849a69abf8SBenjamin Poirier 			} else
2859a69abf8SBenjamin Poirier 				skip -= strlen(pos->text);
2869a69abf8SBenjamin Poirier 
2879a69abf8SBenjamin Poirier 			if (skip == 0)
2889a69abf8SBenjamin Poirier 				waddch(stdscr, ' ');
2899a69abf8SBenjamin Poirier 			else
2909a69abf8SBenjamin Poirier 				skip--;
2919a69abf8SBenjamin Poirier 		}
2929a69abf8SBenjamin Poirier 
2934f2de3e1SDirk Gouders 		for (i = len + 1; i < columns - 1; i++)
2946f6046cfSSam Ravnborg 			waddch(stdscr, ACS_HLINE);
2956f6046cfSSam Ravnborg 	}
2966f6046cfSSam Ravnborg 	wnoutrefresh(stdscr);
2976f6046cfSSam Ravnborg }
2986f6046cfSSam Ravnborg 
2996f6046cfSSam Ravnborg /*
3006f6046cfSSam Ravnborg  * Do some initialization for dialog
3016f6046cfSSam Ravnborg  */
init_dialog(const char * backtitle)30209af091fSLadislav Michl int init_dialog(const char *backtitle)
3032982de69SSam Ravnborg {
30409af091fSLadislav Michl 	int height, width;
30509af091fSLadislav Michl 
30609af091fSLadislav Michl 	initscr();		/* Init curses */
3073eb95c84SDirk Gouders 
3083eb95c84SDirk Gouders 	/* Get current cursor position for signal handler in mconf.c */
3093eb95c84SDirk Gouders 	getyx(stdscr, saved_y, saved_x);
3103eb95c84SDirk Gouders 
31109af091fSLadislav Michl 	getmaxyx(stdscr, height, width);
312851f6657SSedat Dilek 	if (height < WINDOW_HEIGTH_MIN || width < WINDOW_WIDTH_MIN) {
31309af091fSLadislav Michl 		endwin();
31409af091fSLadislav Michl 		return -ERRDISPLAYTOOSMALL;
31509af091fSLadislav Michl 	}
31609af091fSLadislav Michl 
3172982de69SSam Ravnborg 	dlg.backtitle = backtitle;
3182982de69SSam Ravnborg 	color_setup(getenv("MENUCONFIG_COLOR"));
31909af091fSLadislav Michl 
32009af091fSLadislav Michl 	keypad(stdscr, TRUE);
32109af091fSLadislav Michl 	cbreak();
32209af091fSLadislav Michl 	noecho();
32309af091fSLadislav Michl 	dialog_clear();
32409af091fSLadislav Michl 
32509af091fSLadislav Michl 	return 0;
3262982de69SSam Ravnborg }
3272982de69SSam Ravnborg 
set_dialog_backtitle(const char * backtitle)32895e30f95SSam Ravnborg void set_dialog_backtitle(const char *backtitle)
32995e30f95SSam Ravnborg {
33095e30f95SSam Ravnborg 	dlg.backtitle = backtitle;
33195e30f95SSam Ravnborg }
33295e30f95SSam Ravnborg 
set_dialog_subtitles(struct subtitle_list * subtitles)3339a69abf8SBenjamin Poirier void set_dialog_subtitles(struct subtitle_list *subtitles)
3349a69abf8SBenjamin Poirier {
3359a69abf8SBenjamin Poirier 	dlg.subtitles = subtitles;
3369a69abf8SBenjamin Poirier }
3379a69abf8SBenjamin Poirier 
3386f6046cfSSam Ravnborg /*
3396f6046cfSSam Ravnborg  * End using dialog functions.
3406f6046cfSSam Ravnborg  */
end_dialog(int x,int y)34109af091fSLadislav Michl void end_dialog(int x, int y)
3426f6046cfSSam Ravnborg {
34309af091fSLadislav Michl 	/* move cursor back to original position */
34409af091fSLadislav Michl 	move(y, x);
34509af091fSLadislav Michl 	refresh();
3466f6046cfSSam Ravnborg 	endwin();
3476f6046cfSSam Ravnborg }
3486f6046cfSSam Ravnborg 
3496f6046cfSSam Ravnborg /* Print the title of the dialog. Center the title and truncate
3506f6046cfSSam Ravnborg  * tile if wider than dialog (- 2 chars).
3516f6046cfSSam Ravnborg  **/
print_title(WINDOW * dialog,const char * title,int width)3526f6046cfSSam Ravnborg void print_title(WINDOW *dialog, const char *title, int width)
3536f6046cfSSam Ravnborg {
3546f6046cfSSam Ravnborg 	if (title) {
3556f6046cfSSam Ravnborg 		int tlen = MIN(width - 2, strlen(title));
35698e5a157SSam Ravnborg 		wattrset(dialog, dlg.title.atr);
3576f6046cfSSam Ravnborg 		mvwaddch(dialog, 0, (width - tlen) / 2 - 1, ' ');
3586f6046cfSSam Ravnborg 		mvwaddnstr(dialog, 0, (width - tlen)/2, title, tlen);
3596f6046cfSSam Ravnborg 		waddch(dialog, ' ');
3606f6046cfSSam Ravnborg 	}
3616f6046cfSSam Ravnborg }
3626f6046cfSSam Ravnborg 
3636f6046cfSSam Ravnborg /*
3646f6046cfSSam Ravnborg  * Print a string of text in a window, automatically wrap around to the
3656f6046cfSSam Ravnborg  * next line if the string is too long to fit on one line. Newline
366*bffbf6e2SBhaskar Chowdhury  * characters '\n' are properly processed.  We start on a new line
3676f6046cfSSam Ravnborg  * if there is no room for at least 4 nonblanks following a double-space.
3686f6046cfSSam Ravnborg  */
print_autowrap(WINDOW * win,const char * prompt,int width,int y,int x)3696f6046cfSSam Ravnborg void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x)
3706f6046cfSSam Ravnborg {
3716f6046cfSSam Ravnborg 	int newl, cur_x, cur_y;
37213763916SDirk Gouders 	int prompt_len, room, wlen;
37313763916SDirk Gouders 	char tempstr[MAX_LEN + 1], *word, *sp, *sp2, *newline_separator = 0;
3746f6046cfSSam Ravnborg 
3756f6046cfSSam Ravnborg 	strcpy(tempstr, prompt);
3766f6046cfSSam Ravnborg 
3776f6046cfSSam Ravnborg 	prompt_len = strlen(tempstr);
3786f6046cfSSam Ravnborg 
3796f6046cfSSam Ravnborg 	if (prompt_len <= width - x * 2) {	/* If prompt is short */
3806f6046cfSSam Ravnborg 		wmove(win, y, (width - prompt_len) / 2);
3816f6046cfSSam Ravnborg 		waddstr(win, tempstr);
3826f6046cfSSam Ravnborg 	} else {
3836f6046cfSSam Ravnborg 		cur_x = x;
3846f6046cfSSam Ravnborg 		cur_y = y;
3856f6046cfSSam Ravnborg 		newl = 1;
3866f6046cfSSam Ravnborg 		word = tempstr;
3876f6046cfSSam Ravnborg 		while (word && *word) {
38813763916SDirk Gouders 			sp = strpbrk(word, "\n ");
38913763916SDirk Gouders 			if (sp && *sp == '\n')
39013763916SDirk Gouders 				newline_separator = sp;
39113763916SDirk Gouders 
3926f6046cfSSam Ravnborg 			if (sp)
3936f6046cfSSam Ravnborg 				*sp++ = 0;
3946f6046cfSSam Ravnborg 
3956f6046cfSSam Ravnborg 			/* Wrap to next line if either the word does not fit,
3966f6046cfSSam Ravnborg 			   or it is the first word of a new sentence, and it is
3976f6046cfSSam Ravnborg 			   short, and the next word does not fit. */
3986f6046cfSSam Ravnborg 			room = width - cur_x;
3996f6046cfSSam Ravnborg 			wlen = strlen(word);
4006f6046cfSSam Ravnborg 			if (wlen > room ||
4016f6046cfSSam Ravnborg 			    (newl && wlen < 4 && sp
4026f6046cfSSam Ravnborg 			     && wlen + 1 + strlen(sp) > room
40313763916SDirk Gouders 			     && (!(sp2 = strpbrk(sp, "\n "))
4046f6046cfSSam Ravnborg 				 || wlen + 1 + (sp2 - sp) > room))) {
4056f6046cfSSam Ravnborg 				cur_y++;
4066f6046cfSSam Ravnborg 				cur_x = x;
4076f6046cfSSam Ravnborg 			}
4086f6046cfSSam Ravnborg 			wmove(win, cur_y, cur_x);
4096f6046cfSSam Ravnborg 			waddstr(win, word);
4106f6046cfSSam Ravnborg 			getyx(win, cur_y, cur_x);
41113763916SDirk Gouders 
41213763916SDirk Gouders 			/* Move to the next line if the word separator was a newline */
41313763916SDirk Gouders 			if (newline_separator) {
41413763916SDirk Gouders 				cur_y++;
41513763916SDirk Gouders 				cur_x = x;
41613763916SDirk Gouders 				newline_separator = 0;
41713763916SDirk Gouders 			} else
4186f6046cfSSam Ravnborg 				cur_x++;
41913763916SDirk Gouders 
4206f6046cfSSam Ravnborg 			if (sp && *sp == ' ') {
4216f6046cfSSam Ravnborg 				cur_x++;	/* double space */
4226f6046cfSSam Ravnborg 				while (*++sp == ' ') ;
4236f6046cfSSam Ravnborg 				newl = 1;
4246f6046cfSSam Ravnborg 			} else
4256f6046cfSSam Ravnborg 				newl = 0;
4266f6046cfSSam Ravnborg 			word = sp;
4276f6046cfSSam Ravnborg 		}
4286f6046cfSSam Ravnborg 	}
4296f6046cfSSam Ravnborg }
4306f6046cfSSam Ravnborg 
4316f6046cfSSam Ravnborg /*
4326f6046cfSSam Ravnborg  * Print a button
4336f6046cfSSam Ravnborg  */
print_button(WINDOW * win,const char * label,int y,int x,int selected)4346f6046cfSSam Ravnborg void print_button(WINDOW * win, const char *label, int y, int x, int selected)
4356f6046cfSSam Ravnborg {
4366f6046cfSSam Ravnborg 	int i, temp;
4376f6046cfSSam Ravnborg 
4386f6046cfSSam Ravnborg 	wmove(win, y, x);
43998e5a157SSam Ravnborg 	wattrset(win, selected ? dlg.button_active.atr
44098e5a157SSam Ravnborg 		 : dlg.button_inactive.atr);
4416f6046cfSSam Ravnborg 	waddstr(win, "<");
4426f6046cfSSam Ravnborg 	temp = strspn(label, " ");
4436f6046cfSSam Ravnborg 	label += temp;
44498e5a157SSam Ravnborg 	wattrset(win, selected ? dlg.button_label_active.atr
44598e5a157SSam Ravnborg 		 : dlg.button_label_inactive.atr);
4466f6046cfSSam Ravnborg 	for (i = 0; i < temp; i++)
4476f6046cfSSam Ravnborg 		waddch(win, ' ');
44898e5a157SSam Ravnborg 	wattrset(win, selected ? dlg.button_key_active.atr
44998e5a157SSam Ravnborg 		 : dlg.button_key_inactive.atr);
4506f6046cfSSam Ravnborg 	waddch(win, label[0]);
45198e5a157SSam Ravnborg 	wattrset(win, selected ? dlg.button_label_active.atr
45298e5a157SSam Ravnborg 		 : dlg.button_label_inactive.atr);
4536f6046cfSSam Ravnborg 	waddstr(win, (char *)label + 1);
45498e5a157SSam Ravnborg 	wattrset(win, selected ? dlg.button_active.atr
45598e5a157SSam Ravnborg 		 : dlg.button_inactive.atr);
4566f6046cfSSam Ravnborg 	waddstr(win, ">");
4576f6046cfSSam Ravnborg 	wmove(win, y, x + temp + 1);
4586f6046cfSSam Ravnborg }
4596f6046cfSSam Ravnborg 
4606f6046cfSSam Ravnborg /*
4616f6046cfSSam Ravnborg  * Draw a rectangular box with line drawing characters
4626f6046cfSSam Ravnborg  */
4636f6046cfSSam Ravnborg void
draw_box(WINDOW * win,int y,int x,int height,int width,chtype box,chtype border)4646f6046cfSSam Ravnborg draw_box(WINDOW * win, int y, int x, int height, int width,
4656f6046cfSSam Ravnborg 	 chtype box, chtype border)
4666f6046cfSSam Ravnborg {
4676f6046cfSSam Ravnborg 	int i, j;
4686f6046cfSSam Ravnborg 
4696f6046cfSSam Ravnborg 	wattrset(win, 0);
4706f6046cfSSam Ravnborg 	for (i = 0; i < height; i++) {
4716f6046cfSSam Ravnborg 		wmove(win, y + i, x);
4726f6046cfSSam Ravnborg 		for (j = 0; j < width; j++)
4736f6046cfSSam Ravnborg 			if (!i && !j)
4746f6046cfSSam Ravnborg 				waddch(win, border | ACS_ULCORNER);
4756f6046cfSSam Ravnborg 			else if (i == height - 1 && !j)
4766f6046cfSSam Ravnborg 				waddch(win, border | ACS_LLCORNER);
4776f6046cfSSam Ravnborg 			else if (!i && j == width - 1)
4786f6046cfSSam Ravnborg 				waddch(win, box | ACS_URCORNER);
4796f6046cfSSam Ravnborg 			else if (i == height - 1 && j == width - 1)
4806f6046cfSSam Ravnborg 				waddch(win, box | ACS_LRCORNER);
4816f6046cfSSam Ravnborg 			else if (!i)
4826f6046cfSSam Ravnborg 				waddch(win, border | ACS_HLINE);
4836f6046cfSSam Ravnborg 			else if (i == height - 1)
4846f6046cfSSam Ravnborg 				waddch(win, box | ACS_HLINE);
4856f6046cfSSam Ravnborg 			else if (!j)
4866f6046cfSSam Ravnborg 				waddch(win, border | ACS_VLINE);
4876f6046cfSSam Ravnborg 			else if (j == width - 1)
4886f6046cfSSam Ravnborg 				waddch(win, box | ACS_VLINE);
4896f6046cfSSam Ravnborg 			else
4906f6046cfSSam Ravnborg 				waddch(win, box | ' ');
4916f6046cfSSam Ravnborg 	}
4926f6046cfSSam Ravnborg }
4936f6046cfSSam Ravnborg 
4946f6046cfSSam Ravnborg /*
4956f6046cfSSam Ravnborg  * Draw shadows along the right and bottom edge to give a more 3D look
4966f6046cfSSam Ravnborg  * to the boxes
4976f6046cfSSam Ravnborg  */
draw_shadow(WINDOW * win,int y,int x,int height,int width)4986f6046cfSSam Ravnborg void draw_shadow(WINDOW * win, int y, int x, int height, int width)
4996f6046cfSSam Ravnborg {
5006f6046cfSSam Ravnborg 	int i;
5016f6046cfSSam Ravnborg 
5026f6046cfSSam Ravnborg 	if (has_colors()) {	/* Whether terminal supports color? */
50398e5a157SSam Ravnborg 		wattrset(win, dlg.shadow.atr);
5046f6046cfSSam Ravnborg 		wmove(win, y + height, x + 2);
5056f6046cfSSam Ravnborg 		for (i = 0; i < width; i++)
5066f6046cfSSam Ravnborg 			waddch(win, winch(win) & A_CHARTEXT);
5076f6046cfSSam Ravnborg 		for (i = y + 1; i < y + height + 1; i++) {
5086f6046cfSSam Ravnborg 			wmove(win, i, x + width);
5096f6046cfSSam Ravnborg 			waddch(win, winch(win) & A_CHARTEXT);
5106f6046cfSSam Ravnborg 			waddch(win, winch(win) & A_CHARTEXT);
5116f6046cfSSam Ravnborg 		}
5126f6046cfSSam Ravnborg 		wnoutrefresh(win);
5136f6046cfSSam Ravnborg 	}
5146f6046cfSSam Ravnborg }
5156f6046cfSSam Ravnborg 
5166f6046cfSSam Ravnborg /*
5176f6046cfSSam Ravnborg  *  Return the position of the first alphabetic character in a string.
5186f6046cfSSam Ravnborg  */
first_alpha(const char * string,const char * exempt)5196f6046cfSSam Ravnborg int first_alpha(const char *string, const char *exempt)
5206f6046cfSSam Ravnborg {
5216f6046cfSSam Ravnborg 	int i, in_paren = 0, c;
5226f6046cfSSam Ravnborg 
5236f6046cfSSam Ravnborg 	for (i = 0; i < strlen(string); i++) {
5246f6046cfSSam Ravnborg 		c = tolower(string[i]);
5256f6046cfSSam Ravnborg 
5266f6046cfSSam Ravnborg 		if (strchr("<[(", c))
5276f6046cfSSam Ravnborg 			++in_paren;
5286f6046cfSSam Ravnborg 		if (strchr(">])", c) && in_paren > 0)
5296f6046cfSSam Ravnborg 			--in_paren;
5306f6046cfSSam Ravnborg 
5316f6046cfSSam Ravnborg 		if ((!in_paren) && isalpha(c) && strchr(exempt, c) == 0)
5326f6046cfSSam Ravnborg 			return i;
5336f6046cfSSam Ravnborg 	}
5346f6046cfSSam Ravnborg 
5356f6046cfSSam Ravnborg 	return 0;
5366f6046cfSSam Ravnborg }
5372982de69SSam Ravnborg 
538f3cbcdc9SSam Ravnborg /*
539f3cbcdc9SSam Ravnborg  * ncurses uses ESC to detect escaped char sequences. This resutl in
540f3cbcdc9SSam Ravnborg  * a small timeout before ESC is actually delivered to the application.
541f3cbcdc9SSam Ravnborg  * lxdialog suggest <ESC> <ESC> which is correctly translated to two
542f3cbcdc9SSam Ravnborg  * times esc. But then we need to ignore the second esc to avoid stepping
543f3cbcdc9SSam Ravnborg  * out one menu too much. Filter away all escaped key sequences since
544*bffbf6e2SBhaskar Chowdhury  * keypad(FALSE) turn off ncurses support for escape sequences - and that's
545f3cbcdc9SSam Ravnborg  * needed to make notimeout() do as expected.
546f3cbcdc9SSam Ravnborg  */
on_key_esc(WINDOW * win)547f3cbcdc9SSam Ravnborg int on_key_esc(WINDOW *win)
548f3cbcdc9SSam Ravnborg {
549f3cbcdc9SSam Ravnborg 	int key;
550f3cbcdc9SSam Ravnborg 	int key2;
551f3cbcdc9SSam Ravnborg 	int key3;
552f3cbcdc9SSam Ravnborg 
553f3cbcdc9SSam Ravnborg 	nodelay(win, TRUE);
554f3cbcdc9SSam Ravnborg 	keypad(win, FALSE);
555f3cbcdc9SSam Ravnborg 	key = wgetch(win);
556f3cbcdc9SSam Ravnborg 	key2 = wgetch(win);
557f3cbcdc9SSam Ravnborg 	do {
558f3cbcdc9SSam Ravnborg 		key3 = wgetch(win);
559f3cbcdc9SSam Ravnborg 	} while (key3 != ERR);
560f3cbcdc9SSam Ravnborg 	nodelay(win, FALSE);
561f3cbcdc9SSam Ravnborg 	keypad(win, TRUE);
562f3cbcdc9SSam Ravnborg 	if (key == KEY_ESC && key2 == ERR)
563f3cbcdc9SSam Ravnborg 		return KEY_ESC;
564f3cbcdc9SSam Ravnborg 	else if (key != ERR && key != KEY_ESC && key2 == ERR)
565f3cbcdc9SSam Ravnborg 		ungetch(key);
566f3cbcdc9SSam Ravnborg 
567f3cbcdc9SSam Ravnborg 	return -1;
568f3cbcdc9SSam Ravnborg }
569f3cbcdc9SSam Ravnborg 
570c8dc68adSSam Ravnborg /* redraw screen in new size */
on_key_resize(void)571c8dc68adSSam Ravnborg int on_key_resize(void)
572c8dc68adSSam Ravnborg {
573c8dc68adSSam Ravnborg 	dialog_clear();
574c8dc68adSSam Ravnborg 	return KEY_RESIZE;
575c8dc68adSSam Ravnborg }
576f3cbcdc9SSam Ravnborg 
5772982de69SSam Ravnborg struct dialog_list *item_cur;
5782982de69SSam Ravnborg struct dialog_list item_nil;
5792982de69SSam Ravnborg struct dialog_list *item_head;
5802982de69SSam Ravnborg 
item_reset(void)5812982de69SSam Ravnborg void item_reset(void)
5822982de69SSam Ravnborg {
5832982de69SSam Ravnborg 	struct dialog_list *p, *next;
5842982de69SSam Ravnborg 
5852982de69SSam Ravnborg 	for (p = item_head; p; p = next) {
5862982de69SSam Ravnborg 		next = p->next;
5872982de69SSam Ravnborg 		free(p);
5882982de69SSam Ravnborg 	}
5892982de69SSam Ravnborg 	item_head = NULL;
5902982de69SSam Ravnborg 	item_cur = &item_nil;
5912982de69SSam Ravnborg }
5922982de69SSam Ravnborg 
item_make(const char * fmt,...)5932982de69SSam Ravnborg void item_make(const char *fmt, ...)
5942982de69SSam Ravnborg {
5952982de69SSam Ravnborg 	va_list ap;
5962982de69SSam Ravnborg 	struct dialog_list *p = malloc(sizeof(*p));
5972982de69SSam Ravnborg 
5982982de69SSam Ravnborg 	if (item_head)
5992982de69SSam Ravnborg 		item_cur->next = p;
6002982de69SSam Ravnborg 	else
6012982de69SSam Ravnborg 		item_head = p;
6022982de69SSam Ravnborg 	item_cur = p;
6032982de69SSam Ravnborg 	memset(p, 0, sizeof(*p));
6042982de69SSam Ravnborg 
6052982de69SSam Ravnborg 	va_start(ap, fmt);
6062982de69SSam Ravnborg 	vsnprintf(item_cur->node.str, sizeof(item_cur->node.str), fmt, ap);
6072982de69SSam Ravnborg 	va_end(ap);
6082982de69SSam Ravnborg }
6092982de69SSam Ravnborg 
item_add_str(const char * fmt,...)6102982de69SSam Ravnborg void item_add_str(const char *fmt, ...)
6112982de69SSam Ravnborg {
6122982de69SSam Ravnborg 	va_list ap;
6132982de69SSam Ravnborg 	size_t avail;
6142982de69SSam Ravnborg 
6152982de69SSam Ravnborg 	avail = sizeof(item_cur->node.str) - strlen(item_cur->node.str);
6162982de69SSam Ravnborg 
6172982de69SSam Ravnborg 	va_start(ap, fmt);
6182982de69SSam Ravnborg 	vsnprintf(item_cur->node.str + strlen(item_cur->node.str),
6192982de69SSam Ravnborg 		  avail, fmt, ap);
6202982de69SSam Ravnborg 	item_cur->node.str[sizeof(item_cur->node.str) - 1] = '\0';
6212982de69SSam Ravnborg 	va_end(ap);
6222982de69SSam Ravnborg }
6232982de69SSam Ravnborg 
item_set_tag(char tag)6242982de69SSam Ravnborg void item_set_tag(char tag)
6252982de69SSam Ravnborg {
6262982de69SSam Ravnborg 	item_cur->node.tag = tag;
6272982de69SSam Ravnborg }
item_set_data(void * ptr)6282982de69SSam Ravnborg void item_set_data(void *ptr)
6292982de69SSam Ravnborg {
6302982de69SSam Ravnborg 	item_cur->node.data = ptr;
6312982de69SSam Ravnborg }
6322982de69SSam Ravnborg 
item_set_selected(int val)6332982de69SSam Ravnborg void item_set_selected(int val)
6342982de69SSam Ravnborg {
6352982de69SSam Ravnborg 	item_cur->node.selected = val;
6362982de69SSam Ravnborg }
6372982de69SSam Ravnborg 
item_activate_selected(void)6382982de69SSam Ravnborg int item_activate_selected(void)
6392982de69SSam Ravnborg {
6402982de69SSam Ravnborg 	item_foreach()
6412982de69SSam Ravnborg 		if (item_is_selected())
6422982de69SSam Ravnborg 			return 1;
6432982de69SSam Ravnborg 	return 0;
6442982de69SSam Ravnborg }
6452982de69SSam Ravnborg 
item_data(void)6462982de69SSam Ravnborg void *item_data(void)
6472982de69SSam Ravnborg {
6482982de69SSam Ravnborg 	return item_cur->node.data;
6492982de69SSam Ravnborg }
6502982de69SSam Ravnborg 
item_tag(void)6512982de69SSam Ravnborg char item_tag(void)
6522982de69SSam Ravnborg {
6532982de69SSam Ravnborg 	return item_cur->node.tag;
6542982de69SSam Ravnborg }
6552982de69SSam Ravnborg 
item_count(void)6562982de69SSam Ravnborg int item_count(void)
6572982de69SSam Ravnborg {
6582982de69SSam Ravnborg 	int n = 0;
6592982de69SSam Ravnborg 	struct dialog_list *p;
6602982de69SSam Ravnborg 
6612982de69SSam Ravnborg 	for (p = item_head; p; p = p->next)
6622982de69SSam Ravnborg 		n++;
6632982de69SSam Ravnborg 	return n;
6642982de69SSam Ravnborg }
6652982de69SSam Ravnborg 
item_set(int n)6662982de69SSam Ravnborg void item_set(int n)
6672982de69SSam Ravnborg {
6682982de69SSam Ravnborg 	int i = 0;
6692982de69SSam Ravnborg 	item_foreach()
6702982de69SSam Ravnborg 		if (i++ == n)
6712982de69SSam Ravnborg 			return;
6722982de69SSam Ravnborg }
6732982de69SSam Ravnborg 
item_n(void)6742982de69SSam Ravnborg int item_n(void)
6752982de69SSam Ravnborg {
6762982de69SSam Ravnborg 	int n = 0;
6772982de69SSam Ravnborg 	struct dialog_list *p;
6782982de69SSam Ravnborg 
6792982de69SSam Ravnborg 	for (p = item_head; p; p = p->next) {
6802982de69SSam Ravnborg 		if (p == item_cur)
6812982de69SSam Ravnborg 			return n;
6822982de69SSam Ravnborg 		n++;
6832982de69SSam Ravnborg 	}
6842982de69SSam Ravnborg 	return 0;
6852982de69SSam Ravnborg }
6862982de69SSam Ravnborg 
item_str(void)6872982de69SSam Ravnborg const char *item_str(void)
6882982de69SSam Ravnborg {
6892982de69SSam Ravnborg 	return item_cur->node.str;
6902982de69SSam Ravnborg }
6912982de69SSam Ravnborg 
item_is_selected(void)6922982de69SSam Ravnborg int item_is_selected(void)
6932982de69SSam Ravnborg {
6942982de69SSam Ravnborg 	return (item_cur->node.selected != 0);
6952982de69SSam Ravnborg }
6962982de69SSam Ravnborg 
item_is_tag(char tag)6972982de69SSam Ravnborg int item_is_tag(char tag)
6982982de69SSam Ravnborg {
6992982de69SSam Ravnborg 	return (item_cur->node.tag == tag);
7002982de69SSam Ravnborg }
701