kconfig/nconf.gui.c
author "Yann E. MORIN" <yann.morin.1998@free.fr>
Thu Dec 27 12:45:22 2012 +0100 (2012-12-27)
changeset 3152 b286c7993be5
permissions -rw-r--r--
scripts/addToolsVersion: properly handle .in vs. .in.2

While most components have their version in the .in file, some
have it in the .in.2 (eg. elf2flt).

Currently, to handle this case, we indiscriminately munge both files,
but this is wrong: in the elf2flt case, if we add a binutils version,
we do not want it to be added to elf2flt, and conversely.

So, for each tool, we need to explicitly know what file to munge.

Signed-off-by: "Yann E. MORIN" <yann.morin.1998@free.fr>
     1 /*
     2  * Copyright (C) 2008 Nir Tzachar <nir.tzachar@gmail.com?
     3  * Released under the terms of the GNU GPL v2.0.
     4  *
     5  * Derived from menuconfig.
     6  *
     7  */
     8 #include "nconf.h"
     9 
    10 /* a list of all the different widgets we use */
    11 attributes_t attributes[ATTR_MAX+1] = {0};
    12 
    13 /* available colors:
    14    COLOR_BLACK   0
    15    COLOR_RED     1
    16    COLOR_GREEN   2
    17    COLOR_YELLOW  3
    18    COLOR_BLUE    4
    19    COLOR_MAGENTA 5
    20    COLOR_CYAN    6
    21    COLOR_WHITE   7
    22    */
    23 static void set_normal_colors(void)
    24 {
    25 	init_pair(NORMAL, -1, -1);
    26 	init_pair(MAIN_HEADING, COLOR_MAGENTA, -1);
    27 
    28 	/* FORE is for the selected item */
    29 	init_pair(MAIN_MENU_FORE, -1, -1);
    30 	/* BACK for all the rest */
    31 	init_pair(MAIN_MENU_BACK, -1, -1);
    32 	init_pair(MAIN_MENU_GREY, -1, -1);
    33 	init_pair(MAIN_MENU_HEADING, COLOR_GREEN, -1);
    34 	init_pair(MAIN_MENU_BOX, COLOR_YELLOW, -1);
    35 
    36 	init_pair(SCROLLWIN_TEXT, -1, -1);
    37 	init_pair(SCROLLWIN_HEADING, COLOR_GREEN, -1);
    38 	init_pair(SCROLLWIN_BOX, COLOR_YELLOW, -1);
    39 
    40 	init_pair(DIALOG_TEXT, -1, -1);
    41 	init_pair(DIALOG_BOX, COLOR_YELLOW, -1);
    42 	init_pair(DIALOG_MENU_BACK, COLOR_YELLOW, -1);
    43 	init_pair(DIALOG_MENU_FORE, COLOR_RED, -1);
    44 
    45 	init_pair(INPUT_BOX, COLOR_YELLOW, -1);
    46 	init_pair(INPUT_HEADING, COLOR_GREEN, -1);
    47 	init_pair(INPUT_TEXT, -1, -1);
    48 	init_pair(INPUT_FIELD, -1, -1);
    49 
    50 	init_pair(FUNCTION_HIGHLIGHT, -1, -1);
    51 	init_pair(FUNCTION_TEXT, COLOR_BLUE, -1);
    52 }
    53 
    54 /* available attributes:
    55    A_NORMAL        Normal display (no highlight)
    56    A_STANDOUT      Best highlighting mode of the terminal.
    57    A_UNDERLINE     Underlining
    58    A_REVERSE       Reverse video
    59    A_BLINK         Blinking
    60    A_DIM           Half bright
    61    A_BOLD          Extra bright or bold
    62    A_PROTECT       Protected mode
    63    A_INVIS         Invisible or blank mode
    64    A_ALTCHARSET    Alternate character set
    65    A_CHARTEXT      Bit-mask to extract a character
    66    COLOR_PAIR(n)   Color-pair number n
    67    */
    68 static void normal_color_theme(void)
    69 {
    70 	/* automatically add color... */
    71 #define mkattr(name, attr) do { \
    72 attributes[name] = attr | COLOR_PAIR(name); } while (0)
    73 	mkattr(NORMAL, NORMAL);
    74 	mkattr(MAIN_HEADING, A_BOLD | A_UNDERLINE);
    75 
    76 	mkattr(MAIN_MENU_FORE, A_REVERSE);
    77 	mkattr(MAIN_MENU_BACK, A_NORMAL);
    78 	mkattr(MAIN_MENU_GREY, A_NORMAL);
    79 	mkattr(MAIN_MENU_HEADING, A_BOLD);
    80 	mkattr(MAIN_MENU_BOX, A_NORMAL);
    81 
    82 	mkattr(SCROLLWIN_TEXT, A_NORMAL);
    83 	mkattr(SCROLLWIN_HEADING, A_BOLD);
    84 	mkattr(SCROLLWIN_BOX, A_BOLD);
    85 
    86 	mkattr(DIALOG_TEXT, A_BOLD);
    87 	mkattr(DIALOG_BOX, A_BOLD);
    88 	mkattr(DIALOG_MENU_FORE, A_STANDOUT);
    89 	mkattr(DIALOG_MENU_BACK, A_NORMAL);
    90 
    91 	mkattr(INPUT_BOX, A_NORMAL);
    92 	mkattr(INPUT_HEADING, A_BOLD);
    93 	mkattr(INPUT_TEXT, A_NORMAL);
    94 	mkattr(INPUT_FIELD, A_UNDERLINE);
    95 
    96 	mkattr(FUNCTION_HIGHLIGHT, A_BOLD);
    97 	mkattr(FUNCTION_TEXT, A_REVERSE);
    98 }
    99 
   100 static void no_colors_theme(void)
   101 {
   102 	/* automatically add highlight, no color */
   103 #define mkattrn(name, attr) { attributes[name] = attr; }
   104 
   105 	mkattrn(NORMAL, NORMAL);
   106 	mkattrn(MAIN_HEADING, A_BOLD | A_UNDERLINE);
   107 
   108 	mkattrn(MAIN_MENU_FORE, A_STANDOUT);
   109 	mkattrn(MAIN_MENU_BACK, A_NORMAL);
   110 	mkattrn(MAIN_MENU_GREY, A_NORMAL);
   111 	mkattrn(MAIN_MENU_HEADING, A_BOLD);
   112 	mkattrn(MAIN_MENU_BOX, A_NORMAL);
   113 
   114 	mkattrn(SCROLLWIN_TEXT, A_NORMAL);
   115 	mkattrn(SCROLLWIN_HEADING, A_BOLD);
   116 	mkattrn(SCROLLWIN_BOX, A_BOLD);
   117 
   118 	mkattrn(DIALOG_TEXT, A_NORMAL);
   119 	mkattrn(DIALOG_BOX, A_BOLD);
   120 	mkattrn(DIALOG_MENU_FORE, A_STANDOUT);
   121 	mkattrn(DIALOG_MENU_BACK, A_NORMAL);
   122 
   123 	mkattrn(INPUT_BOX, A_BOLD);
   124 	mkattrn(INPUT_HEADING, A_BOLD);
   125 	mkattrn(INPUT_TEXT, A_NORMAL);
   126 	mkattrn(INPUT_FIELD, A_UNDERLINE);
   127 
   128 	mkattrn(FUNCTION_HIGHLIGHT, A_BOLD);
   129 	mkattrn(FUNCTION_TEXT, A_REVERSE);
   130 }
   131 
   132 void set_colors()
   133 {
   134 	start_color();
   135 	use_default_colors();
   136 	set_normal_colors();
   137 	if (has_colors()) {
   138 		normal_color_theme();
   139 	} else {
   140 		/* give defaults */
   141 		no_colors_theme();
   142 	}
   143 }
   144 
   145 
   146 /* this changes the windows attributes !!! */
   147 void print_in_middle(WINDOW *win,
   148 		int starty,
   149 		int startx,
   150 		int width,
   151 		const char *string,
   152 		chtype color)
   153 {      int length, x, y;
   154 	float temp;
   155 
   156 
   157 	if (win == NULL)
   158 		win = stdscr;
   159 	getyx(win, y, x);
   160 	if (startx != 0)
   161 		x = startx;
   162 	if (starty != 0)
   163 		y = starty;
   164 	if (width == 0)
   165 		width = 80;
   166 
   167 	length = strlen(string);
   168 	temp = (width - length) / 2;
   169 	x = startx + (int)temp;
   170 	(void) wattrset(win, color);
   171 	mvwprintw(win, y, x, "%s", string);
   172 	refresh();
   173 }
   174 
   175 int get_line_no(const char *text)
   176 {
   177 	int i;
   178 	int total = 1;
   179 
   180 	if (!text)
   181 		return 0;
   182 
   183 	for (i = 0; text[i] != '\0'; i++)
   184 		if (text[i] == '\n')
   185 			total++;
   186 	return total;
   187 }
   188 
   189 const char *get_line(const char *text, int line_no)
   190 {
   191 	int i;
   192 	int lines = 0;
   193 
   194 	if (!text)
   195 		return 0;
   196 
   197 	for (i = 0; text[i] != '\0' && lines < line_no; i++)
   198 		if (text[i] == '\n')
   199 			lines++;
   200 	return text+i;
   201 }
   202 
   203 int get_line_length(const char *line)
   204 {
   205 	int res = 0;
   206 	while (*line != '\0' && *line != '\n') {
   207 		line++;
   208 		res++;
   209 	}
   210 	return res;
   211 }
   212 
   213 /* print all lines to the window. */
   214 void fill_window(WINDOW *win, const char *text)
   215 {
   216 	int x, y;
   217 	int total_lines = get_line_no(text);
   218 	int i;
   219 
   220 	getmaxyx(win, y, x);
   221 	/* do not go over end of line */
   222 	total_lines = min(total_lines, y);
   223 	for (i = 0; i < total_lines; i++) {
   224 		char tmp[x+10];
   225 		const char *line = get_line(text, i);
   226 		int len = get_line_length(line);
   227 		strncpy(tmp, line, min(len, x));
   228 		tmp[len] = '\0';
   229 		mvwprintw(win, i, 0, "%s", tmp);
   230 	}
   231 }
   232 
   233 /* get the message, and buttons.
   234  * each button must be a char*
   235  * return the selected button
   236  *
   237  * this dialog is used for 2 different things:
   238  * 1) show a text box, no buttons.
   239  * 2) show a dialog, with horizontal buttons
   240  */
   241 int btn_dialog(WINDOW *main_window, const char *msg, int btn_num, ...)
   242 {
   243 	va_list ap;
   244 	char *btn;
   245 	int btns_width = 0;
   246 	int msg_lines = 0;
   247 	int msg_width = 0;
   248 	int total_width;
   249 	int win_rows = 0;
   250 	WINDOW *win;
   251 	WINDOW *msg_win;
   252 	WINDOW *menu_win;
   253 	MENU *menu;
   254 	ITEM *btns[btn_num+1];
   255 	int i, x, y;
   256 	int res = -1;
   257 
   258 
   259 	va_start(ap, btn_num);
   260 	for (i = 0; i < btn_num; i++) {
   261 		btn = va_arg(ap, char *);
   262 		btns[i] = new_item(btn, "");
   263 		btns_width += strlen(btn)+1;
   264 	}
   265 	va_end(ap);
   266 	btns[btn_num] = NULL;
   267 
   268 	/* find the widest line of msg: */
   269 	msg_lines = get_line_no(msg);
   270 	for (i = 0; i < msg_lines; i++) {
   271 		const char *line = get_line(msg, i);
   272 		int len = get_line_length(line);
   273 		if (msg_width < len)
   274 			msg_width = len;
   275 	}
   276 
   277 	total_width = max(msg_width, btns_width);
   278 	/* place dialog in middle of screen */
   279 	y = (LINES-(msg_lines+4))/2;
   280 	x = (COLS-(total_width+4))/2;
   281 
   282 
   283 	/* create the windows */
   284 	if (btn_num > 0)
   285 		win_rows = msg_lines+4;
   286 	else
   287 		win_rows = msg_lines+2;
   288 
   289 	win = newwin(win_rows, total_width+4, y, x);
   290 	keypad(win, TRUE);
   291 	menu_win = derwin(win, 1, btns_width, win_rows-2,
   292 			1+(total_width+2-btns_width)/2);
   293 	menu = new_menu(btns);
   294 	msg_win = derwin(win, win_rows-2, msg_width, 1,
   295 			1+(total_width+2-msg_width)/2);
   296 
   297 	set_menu_fore(menu, attributes[DIALOG_MENU_FORE]);
   298 	set_menu_back(menu, attributes[DIALOG_MENU_BACK]);
   299 
   300 	(void) wattrset(win, attributes[DIALOG_BOX]);
   301 	box(win, 0, 0);
   302 
   303 	/* print message */
   304 	(void) wattrset(msg_win, attributes[DIALOG_TEXT]);
   305 	fill_window(msg_win, msg);
   306 
   307 	set_menu_win(menu, win);
   308 	set_menu_sub(menu, menu_win);
   309 	set_menu_format(menu, 1, btn_num);
   310 	menu_opts_off(menu, O_SHOWDESC);
   311 	menu_opts_off(menu, O_SHOWMATCH);
   312 	menu_opts_on(menu, O_ONEVALUE);
   313 	menu_opts_on(menu, O_NONCYCLIC);
   314 	set_menu_mark(menu, "");
   315 	post_menu(menu);
   316 
   317 
   318 	touchwin(win);
   319 	refresh_all_windows(main_window);
   320 	while ((res = wgetch(win))) {
   321 		switch (res) {
   322 		case KEY_LEFT:
   323 			menu_driver(menu, REQ_LEFT_ITEM);
   324 			break;
   325 		case KEY_RIGHT:
   326 			menu_driver(menu, REQ_RIGHT_ITEM);
   327 			break;
   328 		case 10: /* ENTER */
   329 		case 27: /* ESCAPE */
   330 		case ' ':
   331 		case KEY_F(F_BACK):
   332 		case KEY_F(F_EXIT):
   333 			break;
   334 		}
   335 		touchwin(win);
   336 		refresh_all_windows(main_window);
   337 
   338 		if (res == 10 || res == ' ') {
   339 			res = item_index(current_item(menu));
   340 			break;
   341 		} else if (res == 27 || res == KEY_F(F_BACK) ||
   342 				res == KEY_F(F_EXIT)) {
   343 			res = KEY_EXIT;
   344 			break;
   345 		}
   346 	}
   347 
   348 	unpost_menu(menu);
   349 	free_menu(menu);
   350 	for (i = 0; i < btn_num; i++)
   351 		free_item(btns[i]);
   352 
   353 	delwin(win);
   354 	return res;
   355 }
   356 
   357 int dialog_inputbox(WINDOW *main_window,
   358 		const char *title, const char *prompt,
   359 		const char *init, char *result, int result_len)
   360 {
   361 	int prompt_lines = 0;
   362 	int prompt_width = 0;
   363 	WINDOW *win;
   364 	WINDOW *prompt_win;
   365 	WINDOW *form_win;
   366 	PANEL *panel;
   367 	int i, x, y;
   368 	int res = -1;
   369 	int cursor_position = strlen(init);
   370 
   371 
   372 	/* find the widest line of msg: */
   373 	prompt_lines = get_line_no(prompt);
   374 	for (i = 0; i < prompt_lines; i++) {
   375 		const char *line = get_line(prompt, i);
   376 		int len = get_line_length(line);
   377 		prompt_width = max(prompt_width, len);
   378 	}
   379 
   380 	if (title)
   381 		prompt_width = max(prompt_width, strlen(title));
   382 
   383 	/* place dialog in middle of screen */
   384 	y = (LINES-(prompt_lines+4))/2;
   385 	x = (COLS-(prompt_width+4))/2;
   386 
   387 	strncpy(result, init, result_len);
   388 
   389 	/* create the windows */
   390 	win = newwin(prompt_lines+6, prompt_width+7, y, x);
   391 	prompt_win = derwin(win, prompt_lines+1, prompt_width, 2, 2);
   392 	form_win = derwin(win, 1, prompt_width, prompt_lines+3, 2);
   393 	keypad(form_win, TRUE);
   394 
   395 	(void) wattrset(form_win, attributes[INPUT_FIELD]);
   396 
   397 	(void) wattrset(win, attributes[INPUT_BOX]);
   398 	box(win, 0, 0);
   399 	(void) wattrset(win, attributes[INPUT_HEADING]);
   400 	if (title)
   401 		mvwprintw(win, 0, 3, "%s", title);
   402 
   403 	/* print message */
   404 	(void) wattrset(prompt_win, attributes[INPUT_TEXT]);
   405 	fill_window(prompt_win, prompt);
   406 
   407 	mvwprintw(form_win, 0, 0, "%*s", prompt_width, " ");
   408 	mvwprintw(form_win, 0, 0, "%s", result);
   409 
   410 	/* create panels */
   411 	panel = new_panel(win);
   412 
   413 	/* show the cursor */
   414 	curs_set(1);
   415 
   416 	touchwin(win);
   417 	refresh_all_windows(main_window);
   418 	while ((res = wgetch(form_win))) {
   419 		int len = strlen(result);
   420 		switch (res) {
   421 		case 10: /* ENTER */
   422 		case 27: /* ESCAPE */
   423 		case KEY_F(F_HELP):
   424 		case KEY_F(F_EXIT):
   425 		case KEY_F(F_BACK):
   426 			break;
   427 		case 127:
   428 		case KEY_BACKSPACE:
   429 			if (cursor_position > 0) {
   430 				memmove(&result[cursor_position-1],
   431 						&result[cursor_position],
   432 						len-cursor_position+1);
   433 				cursor_position--;
   434 			}
   435 			break;
   436 		case KEY_DC:
   437 			if (cursor_position >= 0 && cursor_position < len) {
   438 				memmove(&result[cursor_position],
   439 						&result[cursor_position+1],
   440 						len-cursor_position+1);
   441 			}
   442 			break;
   443 		case KEY_UP:
   444 		case KEY_RIGHT:
   445 			if (cursor_position < len &&
   446 			    cursor_position < min(result_len, prompt_width))
   447 				cursor_position++;
   448 			break;
   449 		case KEY_DOWN:
   450 		case KEY_LEFT:
   451 			if (cursor_position > 0)
   452 				cursor_position--;
   453 			break;
   454 		default:
   455 			if ((isgraph(res) || isspace(res)) &&
   456 					len-2 < result_len) {
   457 				/* insert the char at the proper position */
   458 				memmove(&result[cursor_position+1],
   459 						&result[cursor_position],
   460 						len+1);
   461 				result[cursor_position] = res;
   462 				cursor_position++;
   463 			} else {
   464 				mvprintw(0, 0, "unknow key: %d\n", res);
   465 			}
   466 			break;
   467 		}
   468 		wmove(form_win, 0, 0);
   469 		wclrtoeol(form_win);
   470 		mvwprintw(form_win, 0, 0, "%*s", prompt_width, " ");
   471 		mvwprintw(form_win, 0, 0, "%s", result);
   472 		wmove(form_win, 0, cursor_position);
   473 		touchwin(win);
   474 		refresh_all_windows(main_window);
   475 
   476 		if (res == 10) {
   477 			res = 0;
   478 			break;
   479 		} else if (res == 27 || res == KEY_F(F_BACK) ||
   480 				res == KEY_F(F_EXIT)) {
   481 			res = KEY_EXIT;
   482 			break;
   483 		} else if (res == KEY_F(F_HELP)) {
   484 			res = 1;
   485 			break;
   486 		}
   487 	}
   488 
   489 	/* hide the cursor */
   490 	curs_set(0);
   491 	del_panel(panel);
   492 	delwin(prompt_win);
   493 	delwin(form_win);
   494 	delwin(win);
   495 	return res;
   496 }
   497 
   498 /* refresh all windows in the correct order */
   499 void refresh_all_windows(WINDOW *main_window)
   500 {
   501 	update_panels();
   502 	touchwin(main_window);
   503 	refresh();
   504 }
   505 
   506 /* layman's scrollable window... */
   507 void show_scroll_win(WINDOW *main_window,
   508 		const char *title,
   509 		const char *text)
   510 {
   511 	int res;
   512 	int total_lines = get_line_no(text);
   513 	int x, y;
   514 	int start_x = 0, start_y = 0;
   515 	int text_lines = 0, text_cols = 0;
   516 	int total_cols = 0;
   517 	int win_cols = 0;
   518 	int win_lines = 0;
   519 	int i = 0;
   520 	WINDOW *win;
   521 	WINDOW *pad;
   522 	PANEL *panel;
   523 
   524 	/* find the widest line of msg: */
   525 	total_lines = get_line_no(text);
   526 	for (i = 0; i < total_lines; i++) {
   527 		const char *line = get_line(text, i);
   528 		int len = get_line_length(line);
   529 		total_cols = max(total_cols, len+2);
   530 	}
   531 
   532 	/* create the pad */
   533 	pad = newpad(total_lines+10, total_cols+10);
   534 	(void) wattrset(pad, attributes[SCROLLWIN_TEXT]);
   535 	fill_window(pad, text);
   536 
   537 	win_lines = min(total_lines+4, LINES-2);
   538 	win_cols = min(total_cols+2, COLS-2);
   539 	text_lines = max(win_lines-4, 0);
   540 	text_cols = max(win_cols-2, 0);
   541 
   542 	/* place window in middle of screen */
   543 	y = (LINES-win_lines)/2;
   544 	x = (COLS-win_cols)/2;
   545 
   546 	win = newwin(win_lines, win_cols, y, x);
   547 	keypad(win, TRUE);
   548 	/* show the help in the help window, and show the help panel */
   549 	(void) wattrset(win, attributes[SCROLLWIN_BOX]);
   550 	box(win, 0, 0);
   551 	(void) wattrset(win, attributes[SCROLLWIN_HEADING]);
   552 	mvwprintw(win, 0, 3, " %s ", title);
   553 	panel = new_panel(win);
   554 
   555 	/* handle scrolling */
   556 	do {
   557 
   558 		copywin(pad, win, start_y, start_x, 2, 2, text_lines,
   559 				text_cols, 0);
   560 		print_in_middle(win,
   561 				text_lines+2,
   562 				0,
   563 				text_cols,
   564 				"<OK>",
   565 				attributes[DIALOG_MENU_FORE]);
   566 		wrefresh(win);
   567 
   568 		res = wgetch(win);
   569 		switch (res) {
   570 		case KEY_NPAGE:
   571 		case ' ':
   572 			start_y += text_lines-2;
   573 			break;
   574 		case KEY_PPAGE:
   575 			start_y -= text_lines+2;
   576 			break;
   577 		case KEY_HOME:
   578 			start_y = 0;
   579 			break;
   580 		case KEY_END:
   581 			start_y = total_lines-text_lines;
   582 			break;
   583 		case KEY_DOWN:
   584 		case 'j':
   585 			start_y++;
   586 			break;
   587 		case KEY_UP:
   588 		case 'k':
   589 			start_y--;
   590 			break;
   591 		case KEY_LEFT:
   592 		case 'h':
   593 			start_x--;
   594 			break;
   595 		case KEY_RIGHT:
   596 		case 'l':
   597 			start_x++;
   598 			break;
   599 		}
   600 		if (res == 10 || res == 27 || res == 'q'
   601 		    || res == KEY_F(F_BACK) || res == KEY_F(F_EXIT)) {
   602 			break;
   603 		}
   604 		if (start_y < 0)
   605 			start_y = 0;
   606 		if (start_y >= total_lines-text_lines)
   607 			start_y = total_lines-text_lines;
   608 		if (start_x < 0)
   609 			start_x = 0;
   610 		if (start_x >= total_cols-text_cols)
   611 			start_x = total_cols-text_cols;
   612 	} while (res);
   613 
   614 	del_panel(panel);
   615 	delwin(win);
   616 	refresh_all_windows(main_window);
   617 }