home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / utils / shell / dialog-0.000 / dialog-0 / dialog-0.6c / util.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-08-18  |  9.7 KB  |  364 lines

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