1/* 2 * util.c 3 * 4 * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) 5 * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 */ 21 22#include "dialog.h" 23 24 25/* use colors by default? */ 26bool use_colors = 1; 27 28char *backtitle = NULL; 29 30const char *dialog_result; 31 32/* 33 * Attribute values, default is for mono display 34 */ 35chtype attributes[] = 36{ 37 A_NORMAL, /* screen_attr */ 38 A_NORMAL, /* shadow_attr */ 39 A_NORMAL, /* dialog_attr */ 40 A_BOLD, /* title_attr */ 41 A_NORMAL, /* border_attr */ 42 A_REVERSE, /* button_active_attr */ 43 A_DIM, /* button_inactive_attr */ 44 A_REVERSE, /* button_key_active_attr */ 45 A_BOLD, /* button_key_inactive_attr */ 46 A_REVERSE, /* button_label_active_attr */ 47 A_NORMAL, /* button_label_inactive_attr */ 48 A_NORMAL, /* inputbox_attr */ 49 A_NORMAL, /* inputbox_border_attr */ 50 A_NORMAL, /* searchbox_attr */ 51 A_BOLD, /* searchbox_title_attr */ 52 A_NORMAL, /* searchbox_border_attr */ 53 A_BOLD, /* position_indicator_attr */ 54 A_NORMAL, /* menubox_attr */ 55 A_NORMAL, /* menubox_border_attr */ 56 A_NORMAL, /* item_attr */ 57 A_REVERSE, /* item_selected_attr */ 58 A_BOLD, /* tag_attr */ 59 A_REVERSE, /* tag_selected_attr */ 60 A_BOLD, /* tag_key_attr */ 61 A_REVERSE, /* tag_key_selected_attr */ 62 A_BOLD, /* check_attr */ 63 A_REVERSE, /* check_selected_attr */ 64 A_BOLD, /* uarrow_attr */ 65 A_BOLD /* darrow_attr */ 66}; 67 68 69#include "colors.h" 70 71/* 72 * Table of color values 73 */ 74int color_table[][3] = 75{ 76 {SCREEN_FG, SCREEN_BG, SCREEN_HL}, 77 {SHADOW_FG, SHADOW_BG, SHADOW_HL}, 78 {DIALOG_FG, DIALOG_BG, DIALOG_HL}, 79 {TITLE_FG, TITLE_BG, TITLE_HL}, 80 {BORDER_FG, BORDER_BG, BORDER_HL}, 81 {BUTTON_ACTIVE_FG, BUTTON_ACTIVE_BG, BUTTON_ACTIVE_HL}, 82 {BUTTON_INACTIVE_FG, BUTTON_INACTIVE_BG, BUTTON_INACTIVE_HL}, 83 {BUTTON_KEY_ACTIVE_FG, BUTTON_KEY_ACTIVE_BG, BUTTON_KEY_ACTIVE_HL}, 84 {BUTTON_KEY_INACTIVE_FG, BUTTON_KEY_INACTIVE_BG, BUTTON_KEY_INACTIVE_HL}, 85 {BUTTON_LABEL_ACTIVE_FG, BUTTON_LABEL_ACTIVE_BG, BUTTON_LABEL_ACTIVE_HL}, 86 {BUTTON_LABEL_INACTIVE_FG, BUTTON_LABEL_INACTIVE_BG, 87 BUTTON_LABEL_INACTIVE_HL}, 88 {INPUTBOX_FG, INPUTBOX_BG, INPUTBOX_HL}, 89 {INPUTBOX_BORDER_FG, INPUTBOX_BORDER_BG, INPUTBOX_BORDER_HL}, 90 {SEARCHBOX_FG, SEARCHBOX_BG, SEARCHBOX_HL}, 91 {SEARCHBOX_TITLE_FG, SEARCHBOX_TITLE_BG, SEARCHBOX_TITLE_HL}, 92 {SEARCHBOX_BORDER_FG, SEARCHBOX_BORDER_BG, SEARCHBOX_BORDER_HL}, 93 {POSITION_INDICATOR_FG, POSITION_INDICATOR_BG, POSITION_INDICATOR_HL}, 94 {MENUBOX_FG, MENUBOX_BG, MENUBOX_HL}, 95 {MENUBOX_BORDER_FG, MENUBOX_BORDER_BG, MENUBOX_BORDER_HL}, 96 {ITEM_FG, ITEM_BG, ITEM_HL}, 97 {ITEM_SELECTED_FG, ITEM_SELECTED_BG, ITEM_SELECTED_HL}, 98 {TAG_FG, TAG_BG, TAG_HL}, 99 {TAG_SELECTED_FG, TAG_SELECTED_BG, TAG_SELECTED_HL}, 100 {TAG_KEY_FG, TAG_KEY_BG, TAG_KEY_HL}, 101 {TAG_KEY_SELECTED_FG, TAG_KEY_SELECTED_BG, TAG_KEY_SELECTED_HL}, 102 {CHECK_FG, CHECK_BG, CHECK_HL}, 103 {CHECK_SELECTED_FG, CHECK_SELECTED_BG, CHECK_SELECTED_HL}, 104 {UARROW_FG, UARROW_BG, UARROW_HL}, 105 {DARROW_FG, DARROW_BG, DARROW_HL}, 106}; /* color_table */ 107 108/* 109 * Set window to attribute 'attr' 110 */ 111void 112attr_clear (WINDOW * win, int height, int width, chtype attr) 113{ 114 int i, j; 115 116 wattrset (win, attr); 117 for (i = 0; i < height; i++) { 118 wmove (win, i, 0); 119 for (j = 0; j < width; j++) 120 waddch (win, ' '); 121 } 122 touchwin (win); 123} 124 125void dialog_clear (void) 126{ 127 attr_clear (stdscr, LINES, COLS, screen_attr); 128 /* Display background title if it exists ... - SLH */ 129 if (backtitle != NULL) { 130 int i; 131 132 wattrset (stdscr, screen_attr); 133 mvwaddstr (stdscr, 0, 1, (char *)backtitle); 134 wmove (stdscr, 1, 1); 135 for (i = 1; i < COLS - 1; i++) 136 waddch (stdscr, ACS_HLINE); 137 } 138 wnoutrefresh (stdscr); 139} 140 141/* 142 * Do some initialization for dialog 143 */ 144void 145init_dialog (void) 146{ 147 initscr (); /* Init curses */ 148 keypad (stdscr, TRUE); 149 cbreak (); 150 noecho (); 151 152 153 if (use_colors) /* Set up colors */ 154 color_setup (); 155 156 157 dialog_clear (); 158} 159 160/* 161 * Setup for color display 162 */ 163void 164color_setup (void) 165{ 166 int i; 167 168 if (has_colors ()) { /* Terminal supports color? */ 169 start_color (); 170 171 /* Initialize color pairs */ 172 for (i = 0; i < ATTRIBUTE_COUNT; i++) 173 init_pair (i + 1, color_table[i][0], color_table[i][1]); 174 175 /* Setup color attributes */ 176 for (i = 0; i < ATTRIBUTE_COUNT; i++) 177 attributes[i] = C_ATTR (color_table[i][2], i + 1); 178 } 179} 180 181/* 182 * End using dialog functions. 183 */ 184void 185end_dialog (void) 186{ 187 endwin (); 188} 189 190 191/* 192 * Print a string of text in a window, automatically wrap around to the 193 * next line if the string is too long to fit on one line. Newline 194 * characters '\n' are replaced by spaces. We start on a new line 195 * if there is no room for at least 4 nonblanks following a double-space. 196 */ 197void 198print_autowrap (WINDOW * win, const char *prompt, int width, int y, int x) 199{ 200 int newl, cur_x, cur_y; 201 int i, prompt_len, room, wlen; 202 char tempstr[MAX_LEN + 1], *word, *sp, *sp2; 203 204 strcpy (tempstr, prompt); 205 206 prompt_len = strlen(tempstr); 207 208 /* 209 * Remove newlines 210 */ 211 for(i=0; i<prompt_len; i++) { 212 if(tempstr[i] == '\n') tempstr[i] = ' '; 213 } 214 215 if (prompt_len <= width - x * 2) { /* If prompt is short */ 216 wmove (win, y, (width - prompt_len) / 2); 217 waddstr (win, tempstr); 218 } else { 219 cur_x = x; 220 cur_y = y; 221 newl = 1; 222 word = tempstr; 223 while (word && *word) { 224 sp = index(word, ' '); 225 if (sp) 226 *sp++ = 0; 227 228 /* Wrap to next line if either the word does not fit, 229 or it is the first word of a new sentence, and it is 230 short, and the next word does not fit. */ 231 room = width - cur_x; 232 wlen = strlen(word); 233 if (wlen > room || 234 (newl && wlen < 4 && sp && wlen+1+strlen(sp) > room 235 && (!(sp2 = index(sp, ' ')) || wlen+1+(sp2-sp) > room))) { 236 cur_y++; 237 cur_x = x; 238 } 239 wmove (win, cur_y, cur_x); 240 waddstr (win, word); 241 getyx (win, cur_y, cur_x); 242 cur_x++; 243 if (sp && *sp == ' ') { 244 cur_x++; /* double space */ 245 while (*++sp == ' '); 246 newl = 1; 247 } else 248 newl = 0; 249 word = sp; 250 } 251 } 252} 253 254/* 255 * Print a button 256 */ 257void 258print_button (WINDOW * win, const char *label, int y, int x, int selected) 259{ 260 int i, temp; 261 262 wmove (win, y, x); 263 wattrset (win, selected ? button_active_attr : button_inactive_attr); 264 waddstr (win, "<"); 265 temp = strspn (label, " "); 266 label += temp; 267 wattrset (win, selected ? button_label_active_attr 268 : button_label_inactive_attr); 269 for (i = 0; i < temp; i++) 270 waddch (win, ' '); 271 wattrset (win, selected ? button_key_active_attr 272 : button_key_inactive_attr); 273 waddch (win, label[0]); 274 wattrset (win, selected ? button_label_active_attr 275 : button_label_inactive_attr); 276 waddstr (win, (char *)label + 1); 277 wattrset (win, selected ? button_active_attr : button_inactive_attr); 278 waddstr (win, ">"); 279 wmove (win, y, x + temp + 1); 280} 281 282/* 283 * Draw a rectangular box with line drawing characters 284 */ 285void 286draw_box (WINDOW * win, int y, int x, int height, int width, 287 chtype box, chtype border) 288{ 289 int i, j; 290 291 wattrset (win, 0); 292 for (i = 0; i < height; i++) { 293 wmove (win, y + i, x); 294 for (j = 0; j < width; j++) 295 if (!i && !j) 296 waddch (win, border | ACS_ULCORNER); 297 else if (i == height - 1 && !j) 298 waddch (win, border | ACS_LLCORNER); 299 else if (!i && j == width - 1) 300 waddch (win, box | ACS_URCORNER); 301 else if (i == height - 1 && j == width - 1) 302 waddch (win, box | ACS_LRCORNER); 303 else if (!i) 304 waddch (win, border | ACS_HLINE); 305 else if (i == height - 1) 306 waddch (win, box | ACS_HLINE); 307 else if (!j) 308 waddch (win, border | ACS_VLINE); 309 else if (j == width - 1) 310 waddch (win, box | ACS_VLINE); 311 else 312 waddch (win, box | ' '); 313 } 314} 315 316/* 317 * Draw shadows along the right and bottom edge to give a more 3D look 318 * to the boxes 319 */ 320void 321draw_shadow (WINDOW * win, int y, int x, int height, int width) 322{ 323 int i; 324 325 if (has_colors ()) { /* Whether terminal supports color? */ 326 wattrset (win, shadow_attr); 327 wmove (win, y + height, x + 2); 328 for (i = 0; i < width; i++) 329 waddch (win, winch (win) & A_CHARTEXT); 330 for (i = y + 1; i < y + height + 1; i++) { 331 wmove (win, i, x + width); 332 waddch (win, winch (win) & A_CHARTEXT); 333 waddch (win, winch (win) & A_CHARTEXT); 334 } 335 wnoutrefresh (win); 336 } 337} 338 339/* 340 * Return the position of the first alphabetic character in a string. 341 */ 342int 343first_alpha(const char *string, const char *exempt) 344{ 345 int i, in_paren=0, c; 346 347 for (i = 0; i < strlen(string); i++) { 348 c = tolower(string[i]); 349 350 if (strchr("<[(", c)) ++in_paren; 351 if (strchr(">])", c)) --in_paren; 352 353 if ((! in_paren) && isalpha(c) && 354 strchr(exempt, c) == 0) 355 return i; 356 } 357 358 return 0; 359} 360 361/* 362 * Get the first selected item in the dialog_list_item list. 363 */ 364struct dialog_list_item * 365first_sel_item(int item_no, struct dialog_list_item ** items) 366{ 367 int i; 368 369 for (i = 0; i < item_no; i++) { 370 if (items[i]->selected) 371 return items[i]; 372 } 373 374 return NULL; 375} 376