util.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:9k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  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. #include "dialog.h"
  22. /* use colors by default? */
  23. bool use_colors = 1;
  24. const char *backtitle = NULL;
  25. const char *dialog_result;
  26. /* 
  27.  * Attribute values, default is for mono display
  28.  */
  29. chtype attributes[] =
  30. {
  31.     A_NORMAL, /* screen_attr */
  32.     A_NORMAL, /* shadow_attr */
  33.     A_NORMAL, /* dialog_attr */
  34.     A_BOLD, /* title_attr */
  35.     A_NORMAL, /* border_attr */
  36.     A_REVERSE, /* button_active_attr */
  37.     A_DIM, /* button_inactive_attr */
  38.     A_REVERSE, /* button_key_active_attr */
  39.     A_BOLD, /* button_key_inactive_attr */
  40.     A_REVERSE, /* button_label_active_attr */
  41.     A_NORMAL, /* button_label_inactive_attr */
  42.     A_NORMAL, /* inputbox_attr */
  43.     A_NORMAL, /* inputbox_border_attr */
  44.     A_NORMAL, /* searchbox_attr */
  45.     A_BOLD, /* searchbox_title_attr */
  46.     A_NORMAL, /* searchbox_border_attr */
  47.     A_BOLD, /* position_indicator_attr */
  48.     A_NORMAL, /* menubox_attr */
  49.     A_NORMAL, /* menubox_border_attr */
  50.     A_NORMAL, /* item_attr */
  51.     A_REVERSE, /* item_selected_attr */
  52.     A_BOLD, /* tag_attr */
  53.     A_REVERSE, /* tag_selected_attr */
  54.     A_BOLD, /* tag_key_attr */
  55.     A_REVERSE, /* tag_key_selected_attr */
  56.     A_BOLD, /* check_attr */
  57.     A_REVERSE, /* check_selected_attr */
  58.     A_BOLD, /* uarrow_attr */
  59.     A_BOLD /* darrow_attr */
  60. };
  61. #include "colors.h"
  62. /*
  63.  * Table of color values
  64.  */
  65. int color_table[][3] =
  66. {
  67.     {SCREEN_FG, SCREEN_BG, SCREEN_HL},
  68.     {SHADOW_FG, SHADOW_BG, SHADOW_HL},
  69.     {DIALOG_FG, DIALOG_BG, DIALOG_HL},
  70.     {TITLE_FG, TITLE_BG, TITLE_HL},
  71.     {BORDER_FG, BORDER_BG, BORDER_HL},
  72.     {BUTTON_ACTIVE_FG, BUTTON_ACTIVE_BG, BUTTON_ACTIVE_HL},
  73.     {BUTTON_INACTIVE_FG, BUTTON_INACTIVE_BG, BUTTON_INACTIVE_HL},
  74.     {BUTTON_KEY_ACTIVE_FG, BUTTON_KEY_ACTIVE_BG, BUTTON_KEY_ACTIVE_HL},
  75.     {BUTTON_KEY_INACTIVE_FG, BUTTON_KEY_INACTIVE_BG, BUTTON_KEY_INACTIVE_HL},
  76.     {BUTTON_LABEL_ACTIVE_FG, BUTTON_LABEL_ACTIVE_BG, BUTTON_LABEL_ACTIVE_HL},
  77.     {BUTTON_LABEL_INACTIVE_FG, BUTTON_LABEL_INACTIVE_BG,
  78.      BUTTON_LABEL_INACTIVE_HL},
  79.     {INPUTBOX_FG, INPUTBOX_BG, INPUTBOX_HL},
  80.     {INPUTBOX_BORDER_FG, INPUTBOX_BORDER_BG, INPUTBOX_BORDER_HL},
  81.     {SEARCHBOX_FG, SEARCHBOX_BG, SEARCHBOX_HL},
  82.     {SEARCHBOX_TITLE_FG, SEARCHBOX_TITLE_BG, SEARCHBOX_TITLE_HL},
  83.     {SEARCHBOX_BORDER_FG, SEARCHBOX_BORDER_BG, SEARCHBOX_BORDER_HL},
  84.     {POSITION_INDICATOR_FG, POSITION_INDICATOR_BG, POSITION_INDICATOR_HL},
  85.     {MENUBOX_FG, MENUBOX_BG, MENUBOX_HL},
  86.     {MENUBOX_BORDER_FG, MENUBOX_BORDER_BG, MENUBOX_BORDER_HL},
  87.     {ITEM_FG, ITEM_BG, ITEM_HL},
  88.     {ITEM_SELECTED_FG, ITEM_SELECTED_BG, ITEM_SELECTED_HL},
  89.     {TAG_FG, TAG_BG, TAG_HL},
  90.     {TAG_SELECTED_FG, TAG_SELECTED_BG, TAG_SELECTED_HL},
  91.     {TAG_KEY_FG, TAG_KEY_BG, TAG_KEY_HL},
  92.     {TAG_KEY_SELECTED_FG, TAG_KEY_SELECTED_BG, TAG_KEY_SELECTED_HL},
  93.     {CHECK_FG, CHECK_BG, CHECK_HL},
  94.     {CHECK_SELECTED_FG, CHECK_SELECTED_BG, CHECK_SELECTED_HL},
  95.     {UARROW_FG, UARROW_BG, UARROW_HL},
  96.     {DARROW_FG, DARROW_BG, DARROW_HL},
  97. }; /* color_table */
  98. /*
  99.  * Set window to attribute 'attr'
  100.  */
  101. void
  102. attr_clear (WINDOW * win, int height, int width, chtype attr)
  103. {
  104.     int i, j;
  105.     wattrset (win, attr);
  106.     for (i = 0; i < height; i++) {
  107. wmove (win, i, 0);
  108. for (j = 0; j < width; j++)
  109.     waddch (win, ' ');
  110.     }
  111.     touchwin (win);
  112. }
  113. void dialog_clear (void)
  114. {
  115.     attr_clear (stdscr, LINES, COLS, screen_attr);
  116.     /* Display background title if it exists ... - SLH */
  117.     if (backtitle != NULL) {
  118.         int i;
  119.         wattrset (stdscr, screen_attr);
  120.         mvwaddstr (stdscr, 0, 1, (char *)backtitle);
  121.         wmove (stdscr, 1, 1);
  122.         for (i = 1; i < COLS - 1; i++)
  123.             waddch (stdscr, ACS_HLINE);
  124.     }
  125.     wnoutrefresh (stdscr);
  126. }
  127. /*
  128.  * Do some initialization for dialog
  129.  */
  130. void
  131. init_dialog (void)
  132. {
  133.     initscr (); /* Init curses */
  134.     keypad (stdscr, TRUE);
  135.     cbreak ();
  136.     noecho ();
  137.     if (use_colors) /* Set up colors */
  138. color_setup ();
  139.     dialog_clear ();
  140. }
  141. /*
  142.  * Setup for color display
  143.  */
  144. void
  145. color_setup (void)
  146. {
  147.     int i;
  148.     if (has_colors ()) { /* Terminal supports color? */
  149. start_color ();
  150. /* Initialize color pairs */
  151. for (i = 0; i < ATTRIBUTE_COUNT; i++)
  152.     init_pair (i + 1, color_table[i][0], color_table[i][1]);
  153. /* Setup color attributes */
  154. for (i = 0; i < ATTRIBUTE_COUNT; i++)
  155.     attributes[i] = C_ATTR (color_table[i][2], i + 1);
  156.     }
  157. }
  158. /*
  159.  * End using dialog functions.
  160.  */
  161. void
  162. end_dialog (void)
  163. {
  164.     endwin ();
  165. }
  166. /*
  167.  * Print a string of text in a window, automatically wrap around to the
  168.  * next line if the string is too long to fit on one line. Newline
  169.  * characters 'n' are replaced by spaces.  We start on a new line
  170.  * if there is no room for at least 4 nonblanks following a double-space.
  171.  */
  172. void
  173. print_autowrap (WINDOW * win, const char *prompt, int width, int y, int x)
  174. {
  175.     int newl, cur_x, cur_y;
  176.     int i, prompt_len, room, wlen;
  177.     char tempstr[MAX_LEN + 1], *word, *sp, *sp2;
  178.     strcpy (tempstr, prompt);
  179.     prompt_len = strlen(tempstr);
  180.     /*
  181.      * Remove newlines
  182.      */
  183.     for(i=0; i<prompt_len; i++) {
  184. if(tempstr[i] == 'n') tempstr[i] = ' ';
  185.     }
  186.     if (prompt_len <= width - x * 2) { /* If prompt is short */
  187. wmove (win, y, (width - prompt_len) / 2);
  188. waddstr (win, tempstr);
  189.     } else {
  190. cur_x = x;
  191. cur_y = y;
  192. newl = 1;
  193. word = tempstr;
  194. while (word && *word) {
  195.     sp = index(word, ' ');
  196.     if (sp)
  197.         *sp++ = 0;
  198.     /* Wrap to next line if either the word does not fit,
  199.        or it is the first word of a new sentence, and it is
  200.        short, and the next word does not fit. */
  201.     room = width - cur_x;
  202.     wlen = strlen(word);
  203.     if (wlen > room ||
  204.        (newl && wlen < 4 && sp && wlen+1+strlen(sp) > room
  205.      && (!(sp2 = index(sp, ' ')) || wlen+1+(sp2-sp) > room))) {
  206. cur_y++;
  207. cur_x = x;
  208.     }
  209.     wmove (win, cur_y, cur_x);
  210.     waddstr (win, word);
  211.     getyx (win, cur_y, cur_x);
  212.     cur_x++;
  213.     if (sp && *sp == ' ') {
  214.         cur_x++; /* double space */
  215. while (*++sp == ' ');
  216. newl = 1;
  217.     } else
  218.         newl = 0;
  219.     word = sp;
  220. }
  221.     }
  222. }
  223. /*
  224.  * Print a button
  225.  */
  226. void
  227. print_button (WINDOW * win, const char *label, int y, int x, int selected)
  228. {
  229.     int i, temp;
  230.     wmove (win, y, x);
  231.     wattrset (win, selected ? button_active_attr : button_inactive_attr);
  232.     waddstr (win, "<");
  233.     temp = strspn (label, " ");
  234.     label += temp;
  235.     wattrset (win, selected ? button_label_active_attr
  236.       : button_label_inactive_attr);
  237.     for (i = 0; i < temp; i++)
  238. waddch (win, ' ');
  239.     wattrset (win, selected ? button_key_active_attr
  240.       : button_key_inactive_attr);
  241.     waddch (win, label[0]);
  242.     wattrset (win, selected ? button_label_active_attr
  243.       : button_label_inactive_attr);
  244.     waddstr (win, (char *)label + 1);
  245.     wattrset (win, selected ? button_active_attr : button_inactive_attr);
  246.     waddstr (win, ">");
  247.     wmove (win, y, x + temp + 1);
  248. }
  249. /*
  250.  * Draw a rectangular box with line drawing characters
  251.  */
  252. void
  253. draw_box (WINDOW * win, int y, int x, int height, int width,
  254.   chtype box, chtype border)
  255. {
  256.     int i, j;
  257.     wattrset (win, 0);
  258.     for (i = 0; i < height; i++) {
  259. wmove (win, y + i, x);
  260. for (j = 0; j < width; j++)
  261.     if (!i && !j)
  262. waddch (win, border | ACS_ULCORNER);
  263.     else if (i == height - 1 && !j)
  264. waddch (win, border | ACS_LLCORNER);
  265.     else if (!i && j == width - 1)
  266. waddch (win, box | ACS_URCORNER);
  267.     else if (i == height - 1 && j == width - 1)
  268. waddch (win, box | ACS_LRCORNER);
  269.     else if (!i)
  270. waddch (win, border | ACS_HLINE);
  271.     else if (i == height - 1)
  272. waddch (win, box | ACS_HLINE);
  273.     else if (!j)
  274. waddch (win, border | ACS_VLINE);
  275.     else if (j == width - 1)
  276. waddch (win, box | ACS_VLINE);
  277.     else
  278. waddch (win, box | ' ');
  279.     }
  280. }
  281. /*
  282.  * Draw shadows along the right and bottom edge to give a more 3D look
  283.  * to the boxes
  284.  */
  285. void
  286. draw_shadow (WINDOW * win, int y, int x, int height, int width)
  287. {
  288.     int i;
  289.     if (has_colors ()) { /* Whether terminal supports color? */
  290. wattrset (win, shadow_attr);
  291. wmove (win, y + height, x + 2);
  292. for (i = 0; i < width; i++)
  293.     waddch (win, winch (win) & A_CHARTEXT);
  294. for (i = y + 1; i < y + height + 1; i++) {
  295.     wmove (win, i, x + width);
  296.     waddch (win, winch (win) & A_CHARTEXT);
  297.     waddch (win, winch (win) & A_CHARTEXT);
  298. }
  299. wnoutrefresh (win);
  300.     }
  301. }
  302. /*
  303.  *  Return the position of the first alphabetic character in a string.
  304.  */
  305. int
  306. first_alpha(const char *string, const char *exempt)
  307. {
  308. int i, in_paren=0, c;
  309. for (i = 0; i < strlen(string); i++) {
  310. c = tolower(string[i]);
  311. if (strchr("<[(", c)) ++in_paren;
  312. if (strchr(">])", c)) --in_paren;
  313. if ((! in_paren) && isalpha(c) && 
  314.      strchr(exempt, c) == 0)
  315. return i;
  316. }
  317. return 0;
  318. }