kconfig/lxdialog/util.c
author "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
Tue Sep 23 14:48:10 2008 +0000 (2008-09-23)
changeset 872 fd4bf138f08f
child 943 1cca90ce0481
permissions -rw-r--r--
Bart De VOS pointed out that removing absolute paths from the libc linker scripts is plainly wrong.
It dates from dawn ages of the original crosstool code, and is not well explained. At that time, binutils might not understand the sysroot stuff, and it was necessary to remove absolute paths in that case.

/trunk/scripts/build/libc/glibc.sh | 14 2 12 0 ++------------
1 file changed, 2 insertions(+), 12 deletions(-)
yann@1
     1
/*
yann@1
     2
 *  util.c
yann@1
     3
 *
yann@1
     4
 *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
yann@1
     5
 *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
yann@1
     6
 *
yann@1
     7
 *  This program is free software; you can redistribute it and/or
yann@1
     8
 *  modify it under the terms of the GNU General Public License
yann@1
     9
 *  as published by the Free Software Foundation; either version 2
yann@1
    10
 *  of the License, or (at your option) any later version.
yann@1
    11
 *
yann@1
    12
 *  This program is distributed in the hope that it will be useful,
yann@1
    13
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
yann@1
    14
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
yann@1
    15
 *  GNU General Public License for more details.
yann@1
    16
 *
yann@1
    17
 *  You should have received a copy of the GNU General Public License
yann@1
    18
 *  along with this program; if not, write to the Free Software
yann@1
    19
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
yann@1
    20
 */
yann@1
    21
yann@1
    22
#include "dialog.h"
yann@1
    23
yann@1
    24
struct dialog_info dlg;
yann@1
    25
yann@1
    26
static void set_mono_theme(void)
yann@1
    27
{
yann@1
    28
	dlg.screen.atr = A_NORMAL;
yann@1
    29
	dlg.shadow.atr = A_NORMAL;
yann@1
    30
	dlg.dialog.atr = A_NORMAL;
yann@1
    31
	dlg.title.atr = A_BOLD;
yann@1
    32
	dlg.border.atr = A_NORMAL;
yann@1
    33
	dlg.button_active.atr = A_REVERSE;
yann@1
    34
	dlg.button_inactive.atr = A_DIM;
yann@1
    35
	dlg.button_key_active.atr = A_REVERSE;
yann@1
    36
	dlg.button_key_inactive.atr = A_BOLD;
yann@1
    37
	dlg.button_label_active.atr = A_REVERSE;
yann@1
    38
	dlg.button_label_inactive.atr = A_NORMAL;
yann@1
    39
	dlg.inputbox.atr = A_NORMAL;
yann@1
    40
	dlg.inputbox_border.atr = A_NORMAL;
yann@1
    41
	dlg.searchbox.atr = A_NORMAL;
yann@1
    42
	dlg.searchbox_title.atr = A_BOLD;
yann@1
    43
	dlg.searchbox_border.atr = A_NORMAL;
yann@1
    44
	dlg.position_indicator.atr = A_BOLD;
yann@1
    45
	dlg.menubox.atr = A_NORMAL;
yann@1
    46
	dlg.menubox_border.atr = A_NORMAL;
yann@1
    47
	dlg.item.atr = A_NORMAL;
yann@1
    48
	dlg.item_selected.atr = A_REVERSE;
yann@1
    49
	dlg.tag.atr = A_BOLD;
yann@1
    50
	dlg.tag_selected.atr = A_REVERSE;
yann@1
    51
	dlg.tag_key.atr = A_BOLD;
yann@1
    52
	dlg.tag_key_selected.atr = A_REVERSE;
yann@1
    53
	dlg.check.atr = A_BOLD;
yann@1
    54
	dlg.check_selected.atr = A_REVERSE;
yann@1
    55
	dlg.uarrow.atr = A_BOLD;
yann@1
    56
	dlg.darrow.atr = A_BOLD;
yann@1
    57
}
yann@1
    58
yann@1
    59
#define DLG_COLOR(dialog, f, b, h) \
yann@1
    60
do {                               \
yann@1
    61
	dlg.dialog.fg = (f);       \
yann@1
    62
	dlg.dialog.bg = (b);       \
yann@1
    63
	dlg.dialog.hl = (h);       \
yann@1
    64
} while (0)
yann@1
    65
yann@1
    66
static void set_classic_theme(void)
yann@1
    67
{
yann@1
    68
	DLG_COLOR(screen,                COLOR_CYAN,   COLOR_BLUE,   true);
yann@1
    69
	DLG_COLOR(shadow,                COLOR_BLACK,  COLOR_BLACK,  true);
yann@1
    70
	DLG_COLOR(dialog,                COLOR_BLACK,  COLOR_WHITE,  false);
yann@1
    71
	DLG_COLOR(title,                 COLOR_YELLOW, COLOR_WHITE,  true);
yann@1
    72
	DLG_COLOR(border,                COLOR_WHITE,  COLOR_WHITE,  true);
yann@1
    73
	DLG_COLOR(button_active,         COLOR_WHITE,  COLOR_BLUE,   true);
yann@1
    74
	DLG_COLOR(button_inactive,       COLOR_BLACK,  COLOR_WHITE,  false);
yann@1
    75
	DLG_COLOR(button_key_active,     COLOR_WHITE,  COLOR_BLUE,   true);
yann@1
    76
	DLG_COLOR(button_key_inactive,   COLOR_RED,    COLOR_WHITE,  false);
yann@1
    77
	DLG_COLOR(button_label_active,   COLOR_YELLOW, COLOR_BLUE,   true);
yann@1
    78
	DLG_COLOR(button_label_inactive, COLOR_BLACK,  COLOR_WHITE,  true);
yann@1
    79
	DLG_COLOR(inputbox,              COLOR_BLACK,  COLOR_WHITE,  false);
yann@1
    80
	DLG_COLOR(inputbox_border,       COLOR_BLACK,  COLOR_WHITE,  false);
yann@1
    81
	DLG_COLOR(searchbox,             COLOR_BLACK,  COLOR_WHITE,  false);
yann@1
    82
	DLG_COLOR(searchbox_title,       COLOR_YELLOW, COLOR_WHITE,  true);
yann@1
    83
	DLG_COLOR(searchbox_border,      COLOR_WHITE,  COLOR_WHITE,  true);
yann@1
    84
	DLG_COLOR(position_indicator,    COLOR_YELLOW, COLOR_WHITE,  true);
yann@1
    85
	DLG_COLOR(menubox,               COLOR_BLACK,  COLOR_WHITE,  false);
yann@1
    86
	DLG_COLOR(menubox_border,        COLOR_WHITE,  COLOR_WHITE,  true);
yann@1
    87
	DLG_COLOR(item,                  COLOR_BLACK,  COLOR_WHITE,  false);
yann@1
    88
	DLG_COLOR(item_selected,         COLOR_WHITE,  COLOR_BLUE,   true);
yann@1
    89
	DLG_COLOR(tag,                   COLOR_YELLOW, COLOR_WHITE,  true);
yann@1
    90
	DLG_COLOR(tag_selected,          COLOR_YELLOW, COLOR_BLUE,   true);
yann@1
    91
	DLG_COLOR(tag_key,               COLOR_YELLOW, COLOR_WHITE,  true);
yann@1
    92
	DLG_COLOR(tag_key_selected,      COLOR_YELLOW, COLOR_BLUE,   true);
yann@1
    93
	DLG_COLOR(check,                 COLOR_BLACK,  COLOR_WHITE,  false);
yann@1
    94
	DLG_COLOR(check_selected,        COLOR_WHITE,  COLOR_BLUE,   true);
yann@1
    95
	DLG_COLOR(uarrow,                COLOR_GREEN,  COLOR_WHITE,  true);
yann@1
    96
	DLG_COLOR(darrow,                COLOR_GREEN,  COLOR_WHITE,  true);
yann@1
    97
}
yann@1
    98
yann@1
    99
static void set_blackbg_theme(void)
yann@1
   100
{
yann@1
   101
	DLG_COLOR(screen, COLOR_RED,   COLOR_BLACK, true);
yann@1
   102
	DLG_COLOR(shadow, COLOR_BLACK, COLOR_BLACK, false);
yann@1
   103
	DLG_COLOR(dialog, COLOR_WHITE, COLOR_BLACK, false);
yann@1
   104
	DLG_COLOR(title,  COLOR_RED,   COLOR_BLACK, false);
yann@1
   105
	DLG_COLOR(border, COLOR_BLACK, COLOR_BLACK, true);
yann@1
   106
yann@1
   107
	DLG_COLOR(button_active,         COLOR_YELLOW, COLOR_RED,   false);
yann@1
   108
	DLG_COLOR(button_inactive,       COLOR_YELLOW, COLOR_BLACK, false);
yann@1
   109
	DLG_COLOR(button_key_active,     COLOR_YELLOW, COLOR_RED,   true);
yann@1
   110
	DLG_COLOR(button_key_inactive,   COLOR_RED,    COLOR_BLACK, false);
yann@1
   111
	DLG_COLOR(button_label_active,   COLOR_WHITE,  COLOR_RED,   false);
yann@1
   112
	DLG_COLOR(button_label_inactive, COLOR_BLACK,  COLOR_BLACK, true);
yann@1
   113
yann@1
   114
	DLG_COLOR(inputbox,         COLOR_YELLOW, COLOR_BLACK, false);
yann@1
   115
	DLG_COLOR(inputbox_border,  COLOR_YELLOW, COLOR_BLACK, false);
yann@1
   116
yann@1
   117
	DLG_COLOR(searchbox,        COLOR_YELLOW, COLOR_BLACK, false);
yann@1
   118
	DLG_COLOR(searchbox_title,  COLOR_YELLOW, COLOR_BLACK, true);
yann@1
   119
	DLG_COLOR(searchbox_border, COLOR_BLACK,  COLOR_BLACK, true);
yann@1
   120
yann@1
   121
	DLG_COLOR(position_indicator, COLOR_RED, COLOR_BLACK,  false);
yann@1
   122
yann@1
   123
	DLG_COLOR(menubox,          COLOR_YELLOW, COLOR_BLACK, false);
yann@1
   124
	DLG_COLOR(menubox_border,   COLOR_BLACK,  COLOR_BLACK, true);
yann@1
   125
yann@1
   126
	DLG_COLOR(item,             COLOR_WHITE, COLOR_BLACK, false);
yann@1
   127
	DLG_COLOR(item_selected,    COLOR_WHITE, COLOR_RED,   false);
yann@1
   128
yann@1
   129
	DLG_COLOR(tag,              COLOR_RED,    COLOR_BLACK, false);
yann@1
   130
	DLG_COLOR(tag_selected,     COLOR_YELLOW, COLOR_RED,   true);
yann@1
   131
	DLG_COLOR(tag_key,          COLOR_RED,    COLOR_BLACK, false);
yann@1
   132
	DLG_COLOR(tag_key_selected, COLOR_YELLOW, COLOR_RED,   true);
yann@1
   133
yann@1
   134
	DLG_COLOR(check,            COLOR_YELLOW, COLOR_BLACK, false);
yann@1
   135
	DLG_COLOR(check_selected,   COLOR_YELLOW, COLOR_RED,   true);
yann@1
   136
yann@1
   137
	DLG_COLOR(uarrow, COLOR_RED, COLOR_BLACK, false);
yann@1
   138
	DLG_COLOR(darrow, COLOR_RED, COLOR_BLACK, false);
yann@1
   139
}
yann@1
   140
yann@1
   141
static void set_bluetitle_theme(void)
yann@1
   142
{
yann@1
   143
	set_classic_theme();
yann@1
   144
	DLG_COLOR(title,               COLOR_BLUE,   COLOR_WHITE, true);
yann@1
   145
	DLG_COLOR(button_key_active,   COLOR_YELLOW, COLOR_BLUE,  true);
yann@1
   146
	DLG_COLOR(button_label_active, COLOR_WHITE,  COLOR_BLUE,  true);
yann@1
   147
	DLG_COLOR(searchbox_title,     COLOR_BLUE,   COLOR_WHITE, true);
yann@1
   148
	DLG_COLOR(position_indicator,  COLOR_BLUE,   COLOR_WHITE, true);
yann@1
   149
	DLG_COLOR(tag,                 COLOR_BLUE,   COLOR_WHITE, true);
yann@1
   150
	DLG_COLOR(tag_key,             COLOR_BLUE,   COLOR_WHITE, true);
yann@1
   151
yann@1
   152
}
yann@1
   153
yann@1
   154
/*
yann@1
   155
 * Select color theme
yann@1
   156
 */
yann@1
   157
static int set_theme(const char *theme)
yann@1
   158
{
yann@1
   159
	int use_color = 1;
yann@1
   160
	if (!theme)
yann@1
   161
		set_bluetitle_theme();
yann@1
   162
	else if (strcmp(theme, "classic") == 0)
yann@1
   163
		set_classic_theme();
yann@1
   164
	else if (strcmp(theme, "bluetitle") == 0)
yann@1
   165
		set_bluetitle_theme();
yann@1
   166
	else if (strcmp(theme, "blackbg") == 0)
yann@1
   167
		set_blackbg_theme();
yann@1
   168
	else if (strcmp(theme, "mono") == 0)
yann@1
   169
		use_color = 0;
yann@1
   170
yann@1
   171
	return use_color;
yann@1
   172
}
yann@1
   173
yann@1
   174
static void init_one_color(struct dialog_color *color)
yann@1
   175
{
yann@1
   176
	static int pair = 0;
yann@1
   177
yann@1
   178
	pair++;
yann@1
   179
	init_pair(pair, color->fg, color->bg);
yann@1
   180
	if (color->hl)
yann@1
   181
		color->atr = A_BOLD | COLOR_PAIR(pair);
yann@1
   182
	else
yann@1
   183
		color->atr = COLOR_PAIR(pair);
yann@1
   184
}
yann@1
   185
yann@1
   186
static void init_dialog_colors(void)
yann@1
   187
{
yann@1
   188
	init_one_color(&dlg.screen);
yann@1
   189
	init_one_color(&dlg.shadow);
yann@1
   190
	init_one_color(&dlg.dialog);
yann@1
   191
	init_one_color(&dlg.title);
yann@1
   192
	init_one_color(&dlg.border);
yann@1
   193
	init_one_color(&dlg.button_active);
yann@1
   194
	init_one_color(&dlg.button_inactive);
yann@1
   195
	init_one_color(&dlg.button_key_active);
yann@1
   196
	init_one_color(&dlg.button_key_inactive);
yann@1
   197
	init_one_color(&dlg.button_label_active);
yann@1
   198
	init_one_color(&dlg.button_label_inactive);
yann@1
   199
	init_one_color(&dlg.inputbox);
yann@1
   200
	init_one_color(&dlg.inputbox_border);
yann@1
   201
	init_one_color(&dlg.searchbox);
yann@1
   202
	init_one_color(&dlg.searchbox_title);
yann@1
   203
	init_one_color(&dlg.searchbox_border);
yann@1
   204
	init_one_color(&dlg.position_indicator);
yann@1
   205
	init_one_color(&dlg.menubox);
yann@1
   206
	init_one_color(&dlg.menubox_border);
yann@1
   207
	init_one_color(&dlg.item);
yann@1
   208
	init_one_color(&dlg.item_selected);
yann@1
   209
	init_one_color(&dlg.tag);
yann@1
   210
	init_one_color(&dlg.tag_selected);
yann@1
   211
	init_one_color(&dlg.tag_key);
yann@1
   212
	init_one_color(&dlg.tag_key_selected);
yann@1
   213
	init_one_color(&dlg.check);
yann@1
   214
	init_one_color(&dlg.check_selected);
yann@1
   215
	init_one_color(&dlg.uarrow);
yann@1
   216
	init_one_color(&dlg.darrow);
yann@1
   217
}
yann@1
   218
yann@1
   219
/*
yann@1
   220
 * Setup for color display
yann@1
   221
 */
yann@1
   222
static void color_setup(const char *theme)
yann@1
   223
{
yann@1
   224
	if (set_theme(theme)) {
yann@1
   225
		if (has_colors()) {	/* Terminal supports color? */
yann@1
   226
			start_color();
yann@1
   227
			init_dialog_colors();
yann@1
   228
		}
yann@1
   229
	}
yann@1
   230
	else
yann@1
   231
	{
yann@1
   232
		set_mono_theme();
yann@1
   233
	}
yann@1
   234
}
yann@1
   235
yann@1
   236
/*
yann@1
   237
 * Set window to attribute 'attr'
yann@1
   238
 */
yann@1
   239
void attr_clear(WINDOW * win, int height, int width, chtype attr)
yann@1
   240
{
yann@1
   241
	int i, j;
yann@1
   242
yann@1
   243
	wattrset(win, attr);
yann@1
   244
	for (i = 0; i < height; i++) {
yann@1
   245
		wmove(win, i, 0);
yann@1
   246
		for (j = 0; j < width; j++)
yann@1
   247
			waddch(win, ' ');
yann@1
   248
	}
yann@1
   249
	touchwin(win);
yann@1
   250
}
yann@1
   251
yann@1
   252
void dialog_clear(void)
yann@1
   253
{
yann@1
   254
	attr_clear(stdscr, LINES, COLS, dlg.screen.atr);
yann@1
   255
	/* Display background title if it exists ... - SLH */
yann@1
   256
	if (dlg.backtitle != NULL) {
yann@1
   257
		int i;
yann@1
   258
yann@1
   259
		wattrset(stdscr, dlg.screen.atr);
yann@1
   260
		mvwaddstr(stdscr, 0, 1, (char *)dlg.backtitle);
yann@1
   261
		wmove(stdscr, 1, 1);
yann@1
   262
		for (i = 1; i < COLS - 1; i++)
yann@1
   263
			waddch(stdscr, ACS_HLINE);
yann@1
   264
	}
yann@1
   265
	wnoutrefresh(stdscr);
yann@1
   266
}
yann@1
   267
yann@1
   268
/*
yann@1
   269
 * Do some initialization for dialog
yann@1
   270
 */
yann@1
   271
void init_dialog(const char *backtitle)
yann@1
   272
{
yann@1
   273
	dlg.backtitle = backtitle;
yann@1
   274
	color_setup(getenv("MENUCONFIG_COLOR"));
yann@1
   275
}
yann@1
   276
yann@1
   277
void reset_dialog(void)
yann@1
   278
{
yann@1
   279
	initscr();		/* Init curses */
yann@1
   280
	keypad(stdscr, TRUE);
yann@1
   281
	cbreak();
yann@1
   282
	noecho();
yann@1
   283
	dialog_clear();
yann@1
   284
}
yann@1
   285
yann@1
   286
/*
yann@1
   287
 * End using dialog functions.
yann@1
   288
 */
yann@1
   289
void end_dialog(void)
yann@1
   290
{
yann@1
   291
	endwin();
yann@1
   292
}
yann@1
   293
yann@1
   294
/* Print the title of the dialog. Center the title and truncate
yann@1
   295
 * tile if wider than dialog (- 2 chars).
yann@1
   296
 **/
yann@1
   297
void print_title(WINDOW *dialog, const char *title, int width)
yann@1
   298
{
yann@1
   299
	if (title) {
yann@1
   300
		int tlen = MIN(width - 2, strlen(title));
yann@1
   301
		wattrset(dialog, dlg.title.atr);
yann@1
   302
		mvwaddch(dialog, 0, (width - tlen) / 2 - 1, ' ');
yann@1
   303
		mvwaddnstr(dialog, 0, (width - tlen)/2, title, tlen);
yann@1
   304
		waddch(dialog, ' ');
yann@1
   305
	}
yann@1
   306
}
yann@1
   307
yann@1
   308
/*
yann@1
   309
 * Print a string of text in a window, automatically wrap around to the
yann@1
   310
 * next line if the string is too long to fit on one line. Newline
yann@1
   311
 * characters '\n' are replaced by spaces.  We start on a new line
yann@1
   312
 * if there is no room for at least 4 nonblanks following a double-space.
yann@1
   313
 */
yann@1
   314
void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x)
yann@1
   315
{
yann@1
   316
	int newl, cur_x, cur_y;
yann@1
   317
	int i, prompt_len, room, wlen;
yann@1
   318
	char tempstr[MAX_LEN + 1], *word, *sp, *sp2;
yann@1
   319
yann@1
   320
	strcpy(tempstr, prompt);
yann@1
   321
yann@1
   322
	prompt_len = strlen(tempstr);
yann@1
   323
yann@1
   324
	/*
yann@1
   325
	 * Remove newlines
yann@1
   326
	 */
yann@1
   327
	for (i = 0; i < prompt_len; i++) {
yann@1
   328
		if (tempstr[i] == '\n')
yann@1
   329
			tempstr[i] = ' ';
yann@1
   330
	}
yann@1
   331
yann@1
   332
	if (prompt_len <= width - x * 2) {	/* If prompt is short */
yann@1
   333
		wmove(win, y, (width - prompt_len) / 2);
yann@1
   334
		waddstr(win, tempstr);
yann@1
   335
	} else {
yann@1
   336
		cur_x = x;
yann@1
   337
		cur_y = y;
yann@1
   338
		newl = 1;
yann@1
   339
		word = tempstr;
yann@1
   340
		while (word && *word) {
yann@1
   341
			sp = index(word, ' ');
yann@1
   342
			if (sp)
yann@1
   343
				*sp++ = 0;
yann@1
   344
yann@1
   345
			/* Wrap to next line if either the word does not fit,
yann@1
   346
			   or it is the first word of a new sentence, and it is
yann@1
   347
			   short, and the next word does not fit. */
yann@1
   348
			room = width - cur_x;
yann@1
   349
			wlen = strlen(word);
yann@1
   350
			if (wlen > room ||
yann@1
   351
			    (newl && wlen < 4 && sp
yann@1
   352
			     && wlen + 1 + strlen(sp) > room
yann@1
   353
			     && (!(sp2 = index(sp, ' '))
yann@1
   354
				 || wlen + 1 + (sp2 - sp) > room))) {
yann@1
   355
				cur_y++;
yann@1
   356
				cur_x = x;
yann@1
   357
			}
yann@1
   358
			wmove(win, cur_y, cur_x);
yann@1
   359
			waddstr(win, word);
yann@1
   360
			getyx(win, cur_y, cur_x);
yann@1
   361
			cur_x++;
yann@1
   362
			if (sp && *sp == ' ') {
yann@1
   363
				cur_x++;	/* double space */
yann@1
   364
				while (*++sp == ' ') ;
yann@1
   365
				newl = 1;
yann@1
   366
			} else
yann@1
   367
				newl = 0;
yann@1
   368
			word = sp;
yann@1
   369
		}
yann@1
   370
	}
yann@1
   371
}
yann@1
   372
yann@1
   373
/*
yann@1
   374
 * Print a button
yann@1
   375
 */
yann@1
   376
void print_button(WINDOW * win, const char *label, int y, int x, int selected)
yann@1
   377
{
yann@1
   378
	int i, temp;
yann@1
   379
yann@1
   380
	wmove(win, y, x);
yann@1
   381
	wattrset(win, selected ? dlg.button_active.atr
yann@1
   382
		 : dlg.button_inactive.atr);
yann@1
   383
	waddstr(win, "<");
yann@1
   384
	temp = strspn(label, " ");
yann@1
   385
	label += temp;
yann@1
   386
	wattrset(win, selected ? dlg.button_label_active.atr
yann@1
   387
		 : dlg.button_label_inactive.atr);
yann@1
   388
	for (i = 0; i < temp; i++)
yann@1
   389
		waddch(win, ' ');
yann@1
   390
	wattrset(win, selected ? dlg.button_key_active.atr
yann@1
   391
		 : dlg.button_key_inactive.atr);
yann@1
   392
	waddch(win, label[0]);
yann@1
   393
	wattrset(win, selected ? dlg.button_label_active.atr
yann@1
   394
		 : dlg.button_label_inactive.atr);
yann@1
   395
	waddstr(win, (char *)label + 1);
yann@1
   396
	wattrset(win, selected ? dlg.button_active.atr
yann@1
   397
		 : dlg.button_inactive.atr);
yann@1
   398
	waddstr(win, ">");
yann@1
   399
	wmove(win, y, x + temp + 1);
yann@1
   400
}
yann@1
   401
yann@1
   402
/*
yann@1
   403
 * Draw a rectangular box with line drawing characters
yann@1
   404
 */
yann@1
   405
void
yann@1
   406
draw_box(WINDOW * win, int y, int x, int height, int width,
yann@1
   407
	 chtype box, chtype border)
yann@1
   408
{
yann@1
   409
	int i, j;
yann@1
   410
yann@1
   411
	wattrset(win, 0);
yann@1
   412
	for (i = 0; i < height; i++) {
yann@1
   413
		wmove(win, y + i, x);
yann@1
   414
		for (j = 0; j < width; j++)
yann@1
   415
			if (!i && !j)
yann@1
   416
				waddch(win, border | ACS_ULCORNER);
yann@1
   417
			else if (i == height - 1 && !j)
yann@1
   418
				waddch(win, border | ACS_LLCORNER);
yann@1
   419
			else if (!i && j == width - 1)
yann@1
   420
				waddch(win, box | ACS_URCORNER);
yann@1
   421
			else if (i == height - 1 && j == width - 1)
yann@1
   422
				waddch(win, box | ACS_LRCORNER);
yann@1
   423
			else if (!i)
yann@1
   424
				waddch(win, border | ACS_HLINE);
yann@1
   425
			else if (i == height - 1)
yann@1
   426
				waddch(win, box | ACS_HLINE);
yann@1
   427
			else if (!j)
yann@1
   428
				waddch(win, border | ACS_VLINE);
yann@1
   429
			else if (j == width - 1)
yann@1
   430
				waddch(win, box | ACS_VLINE);
yann@1
   431
			else
yann@1
   432
				waddch(win, box | ' ');
yann@1
   433
	}
yann@1
   434
}
yann@1
   435
yann@1
   436
/*
yann@1
   437
 * Draw shadows along the right and bottom edge to give a more 3D look
yann@1
   438
 * to the boxes
yann@1
   439
 */
yann@1
   440
void draw_shadow(WINDOW * win, int y, int x, int height, int width)
yann@1
   441
{
yann@1
   442
	int i;
yann@1
   443
yann@1
   444
	if (has_colors()) {	/* Whether terminal supports color? */
yann@1
   445
		wattrset(win, dlg.shadow.atr);
yann@1
   446
		wmove(win, y + height, x + 2);
yann@1
   447
		for (i = 0; i < width; i++)
yann@1
   448
			waddch(win, winch(win) & A_CHARTEXT);
yann@1
   449
		for (i = y + 1; i < y + height + 1; i++) {
yann@1
   450
			wmove(win, i, x + width);
yann@1
   451
			waddch(win, winch(win) & A_CHARTEXT);
yann@1
   452
			waddch(win, winch(win) & A_CHARTEXT);
yann@1
   453
		}
yann@1
   454
		wnoutrefresh(win);
yann@1
   455
	}
yann@1
   456
}
yann@1
   457
yann@1
   458
/*
yann@1
   459
 *  Return the position of the first alphabetic character in a string.
yann@1
   460
 */
yann@1
   461
int first_alpha(const char *string, const char *exempt)
yann@1
   462
{
yann@1
   463
	int i, in_paren = 0, c;
yann@1
   464
yann@1
   465
	for (i = 0; i < strlen(string); i++) {
yann@1
   466
		c = tolower(string[i]);
yann@1
   467
yann@1
   468
		if (strchr("<[(", c))
yann@1
   469
			++in_paren;
yann@1
   470
		if (strchr(">])", c) && in_paren > 0)
yann@1
   471
			--in_paren;
yann@1
   472
yann@1
   473
		if ((!in_paren) && isalpha(c) && strchr(exempt, c) == 0)
yann@1
   474
			return i;
yann@1
   475
	}
yann@1
   476
yann@1
   477
	return 0;
yann@1
   478
}
yann@1
   479
yann@1
   480
/*
yann@1
   481
 * ncurses uses ESC to detect escaped char sequences. This resutl in
yann@1
   482
 * a small timeout before ESC is actually delivered to the application.
yann@1
   483
 * lxdialog suggest <ESC> <ESC> which is correctly translated to two
yann@1
   484
 * times esc. But then we need to ignore the second esc to avoid stepping
yann@1
   485
 * out one menu too much. Filter away all escaped key sequences since
yann@1
   486
 * keypad(FALSE) turn off ncurses support for escape sequences - and thats
yann@1
   487
 * needed to make notimeout() do as expected.
yann@1
   488
 */
yann@1
   489
int on_key_esc(WINDOW *win)
yann@1
   490
{
yann@1
   491
	int key;
yann@1
   492
	int key2;
yann@1
   493
	int key3;
yann@1
   494
yann@1
   495
	nodelay(win, TRUE);
yann@1
   496
	keypad(win, FALSE);
yann@1
   497
	key = wgetch(win);
yann@1
   498
	key2 = wgetch(win);
yann@1
   499
	do {
yann@1
   500
		key3 = wgetch(win);
yann@1
   501
	} while (key3 != ERR);
yann@1
   502
	nodelay(win, FALSE);
yann@1
   503
	keypad(win, TRUE);
yann@1
   504
	if (key == KEY_ESC && key2 == ERR)
yann@1
   505
		return KEY_ESC;
yann@1
   506
	else if (key != ERR && key != KEY_ESC && key2 == ERR)
yann@1
   507
		ungetch(key);
yann@1
   508
yann@1
   509
	return -1;
yann@1
   510
}
yann@1
   511
yann@1
   512
/* redraw screen in new size */
yann@1
   513
int on_key_resize(void)
yann@1
   514
{
yann@1
   515
	dialog_clear();
yann@1
   516
	return KEY_RESIZE;
yann@1
   517
}
yann@1
   518
yann@1
   519
struct dialog_list *item_cur;
yann@1
   520
struct dialog_list item_nil;
yann@1
   521
struct dialog_list *item_head;
yann@1
   522
yann@1
   523
void item_reset(void)
yann@1
   524
{
yann@1
   525
	struct dialog_list *p, *next;
yann@1
   526
yann@1
   527
	for (p = item_head; p; p = next) {
yann@1
   528
		next = p->next;
yann@1
   529
		free(p);
yann@1
   530
	}
yann@1
   531
	item_head = NULL;
yann@1
   532
	item_cur = &item_nil;
yann@1
   533
}
yann@1
   534
yann@1
   535
void item_make(const char *fmt, ...)
yann@1
   536
{
yann@1
   537
	va_list ap;
yann@1
   538
	struct dialog_list *p = malloc(sizeof(*p));
yann@1
   539
yann@1
   540
	if (item_head)
yann@1
   541
		item_cur->next = p;
yann@1
   542
	else
yann@1
   543
		item_head = p;
yann@1
   544
	item_cur = p;
yann@1
   545
	memset(p, 0, sizeof(*p));
yann@1
   546
yann@1
   547
	va_start(ap, fmt);
yann@1
   548
	vsnprintf(item_cur->node.str, sizeof(item_cur->node.str), fmt, ap);
yann@1
   549
	va_end(ap);
yann@1
   550
}
yann@1
   551
yann@1
   552
void item_add_str(const char *fmt, ...)
yann@1
   553
{
yann@1
   554
	va_list ap;
yann@1
   555
        size_t avail;
yann@1
   556
yann@1
   557
	avail = sizeof(item_cur->node.str) - strlen(item_cur->node.str);
yann@1
   558
yann@1
   559
	va_start(ap, fmt);
yann@1
   560
	vsnprintf(item_cur->node.str + strlen(item_cur->node.str),
yann@1
   561
		  avail, fmt, ap);
yann@1
   562
	item_cur->node.str[sizeof(item_cur->node.str) - 1] = '\0';
yann@1
   563
	va_end(ap);
yann@1
   564
}
yann@1
   565
yann@1
   566
void item_set_tag(char tag)
yann@1
   567
{
yann@1
   568
	item_cur->node.tag = tag;
yann@1
   569
}
yann@1
   570
void item_set_data(void *ptr)
yann@1
   571
{
yann@1
   572
	item_cur->node.data = ptr;
yann@1
   573
}
yann@1
   574
yann@1
   575
void item_set_selected(int val)
yann@1
   576
{
yann@1
   577
	item_cur->node.selected = val;
yann@1
   578
}
yann@1
   579
yann@1
   580
int item_activate_selected(void)
yann@1
   581
{
yann@1
   582
	item_foreach()
yann@1
   583
		if (item_is_selected())
yann@1
   584
			return 1;
yann@1
   585
	return 0;
yann@1
   586
}
yann@1
   587
yann@1
   588
void *item_data(void)
yann@1
   589
{
yann@1
   590
	return item_cur->node.data;
yann@1
   591
}
yann@1
   592
yann@1
   593
char item_tag(void)
yann@1
   594
{
yann@1
   595
	return item_cur->node.tag;
yann@1
   596
}
yann@1
   597
yann@1
   598
int item_count(void)
yann@1
   599
{
yann@1
   600
	int n = 0;
yann@1
   601
	struct dialog_list *p;
yann@1
   602
yann@1
   603
	for (p = item_head; p; p = p->next)
yann@1
   604
		n++;
yann@1
   605
	return n;
yann@1
   606
}
yann@1
   607
yann@1
   608
void item_set(int n)
yann@1
   609
{
yann@1
   610
	int i = 0;
yann@1
   611
	item_foreach()
yann@1
   612
		if (i++ == n)
yann@1
   613
			return;
yann@1
   614
}
yann@1
   615
yann@1
   616
int item_n(void)
yann@1
   617
{
yann@1
   618
	int n = 0;
yann@1
   619
	struct dialog_list *p;
yann@1
   620
yann@1
   621
	for (p = item_head; p; p = p->next) {
yann@1
   622
		if (p == item_cur)
yann@1
   623
			return n;
yann@1
   624
		n++;
yann@1
   625
	}
yann@1
   626
	return 0;
yann@1
   627
}
yann@1
   628
yann@1
   629
const char *item_str(void)
yann@1
   630
{
yann@1
   631
	return item_cur->node.str;
yann@1
   632
}
yann@1
   633
yann@1
   634
int item_is_selected(void)
yann@1
   635
{
yann@1
   636
	return (item_cur->node.selected != 0);
yann@1
   637
}
yann@1
   638
yann@1
   639
int item_is_tag(char tag)
yann@1
   640
{
yann@1
   641
	return (item_cur->node.tag == tag);
yann@1
   642
}