root/scripts/lxdialog/util.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. attr_clear
  2. dialog_clear
  3. init_dialog
  4. color_setup
  5. end_dialog
  6. print_autowrap
  7. print_button
  8. draw_box
  9. draw_shadow
  10. first_alpha

   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? */
  26 bool use_colors = 1;
  27 
  28 const char *backtitle = NULL;
  29 
  30 const char *dialog_result;
  31 
  32 /* 
  33  * Attribute values, default is for mono display
  34  */
  35 chtype attributes[] =
  36 {
  37     A_NORMAL,                   /* screen_attr */
  38     A_NORMAL,                   /* shadow_attr */
  39     A_REVERSE,                  /* dialog_attr */
  40     A_REVERSE,                  /* title_attr */
  41     A_REVERSE,                  /* border_attr */
  42     A_BOLD,                     /* button_active_attr */
  43     A_DIM,                      /* button_inactive_attr */
  44     A_UNDERLINE,                /* button_key_active_attr */
  45     A_UNDERLINE,                /* button_key_inactive_attr */
  46     A_NORMAL,                   /* button_label_active_attr */
  47     A_NORMAL,                   /* button_label_inactive_attr */
  48     A_REVERSE,                  /* inputbox_attr */
  49     A_REVERSE,                  /* inputbox_border_attr */
  50     A_REVERSE,                  /* searchbox_attr */
  51     A_REVERSE,                  /* searchbox_title_attr */
  52     A_REVERSE,                  /* searchbox_border_attr */
  53     A_REVERSE,                  /* position_indicator_attr */
  54     A_REVERSE,                  /* menubox_attr */
  55     A_REVERSE,                  /* menubox_border_attr */
  56     A_REVERSE,                  /* item_attr */
  57     A_NORMAL,                   /* item_selected_attr */
  58     A_REVERSE,                  /* tag_attr */
  59     A_REVERSE,                  /* tag_selected_attr */
  60     A_NORMAL,                   /* tag_key_attr */
  61     A_BOLD,                     /* tag_key_selected_attr */
  62     A_REVERSE,                  /* check_attr */
  63     A_REVERSE,                  /* check_selected_attr */
  64     A_REVERSE,                  /* uarrow_attr */
  65     A_REVERSE                   /* darrow_attr */
  66 };
  67 
  68 
  69 #include "colors.h"
  70 
  71 /*
  72  * Table of color values
  73  */
  74 int 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  */
 111 void
 112 attr_clear (WINDOW * win, int height, int width, chtype attr)
     /* [previous][next][first][last][top][bottom][index][help] */
 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 
 125 void dialog_clear (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 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  */
 144 void
 145 init_dialog (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 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  */
 163 void
 164 color_setup (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 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  */
 184 void
 185 end_dialog (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 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  */
 197 void
 198 print_autowrap (WINDOW * win, const char *prompt, int width, int y, int x)
     /* [previous][next][first][last][top][bottom][index][help] */
 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  */
 257 void
 258 print_button (WINDOW * win, const char *label, int y, int x, int selected)
     /* [previous][next][first][last][top][bottom][index][help] */
 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  */
 285 void
 286 draw_box (WINDOW * win, int y, int x, int height, int width,
     /* [previous][next][first][last][top][bottom][index][help] */
 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  */
 320 void
 321 draw_shadow (WINDOW * win, int y, int x, int height, int width)
     /* [previous][next][first][last][top][bottom][index][help] */
 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  */
 342 int
 343 first_alpha(const char *string)
     /* [previous][next][first][last][top][bottom][index][help] */
 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 (c == '(') ++in_paren;
 351                 if (c == ')') --in_paren;
 352 
 353                 if ((! in_paren) && isalpha(c) && 
 354                      strchr("nNyYmM", c) == 0)
 355                         return i;
 356         }
 357 
 358         return 0;
 359 }

/* [previous][next][first][last][top][bottom][index][help] */