home *** CD-ROM | disk | FTP | other *** search
/ PC-Online 1996 May / PCOnline_05_1996.bin / linux / source / a / hdsetup / dialog-0.4-1 / dialog-0 / dialog-0.4-slackware / src / dialog.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-09  |  14.3 KB  |  512 lines

  1. /*
  2.  *  dialog - Display simple dialog boxes from shell scripts
  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.  *  HISTORY:
  22.  *
  23.  *  17/12/93 - Version 0.1 released.
  24.  *
  25.  *  19/12/93 - menu will now scroll if there are more items than can fit
  26.  *             on the screen.
  27.  *           - added 'checklist', a dialog box with a list of options that
  28.  *             can be turned on or off. A list of options that are on is 
  29.  *             returned on exit.
  30.  *
  31.  *  20/12/93 - Version 0.15 released.
  32.  *
  33.  *  29/12/93 - Incorporated patch from Patrick J. Volkerding
  34.  *             (volkerdi@mhd1.moorhead.msus.edu) that made these changes:
  35.  *             - increased MAX_LEN to 2048
  36.  *             - added 'infobox', equivalent to a message box without pausing
  37.  *             - added option '--clear' that will clear the screen
  38.  *             - Explicit line breaking when printing prompt text can be
  39.  *               invoked by real newline '\n' besides the string "\n"
  40.  *           - an optional parameter '--title <string>' can be used to
  41.  *             specify a title string for the dialog box
  42.  *
  43.  *  03/01/94 - added 'textbox', a dialog box for displaying text from a file.
  44.  *           - Version 0.2 released.
  45.  *
  46.  *  04/01/94 - some fixes and improvements for 'textbox':
  47.  *             - fixed a bug that will cause a segmentation violation when a
  48.  *               line is longer than MAX_LEN characters. Lines will now be
  49.  *               truncated if they are longer than MAX_LEN characters.
  50.  *             - removed wrefresh() from print_line(). This will increase
  51.  *               efficiency of print_page() which calls print_line().
  52.  *             - display current position in the form of percentage into file.
  53.  *           - Version 0.21 released.
  54.  *
  55.  *  05/01/94 - some changes for faster screen update.
  56.  *
  57.  *  07/01/94 - much more flexible color settings. Can use all 16 colors
  58.  *             (8 normal, 8 highlight) of the Linux console.
  59.  *
  60.  *  08/01/94 - added run-time configuration using configuration file.
  61.  *
  62.  *  09/01/94 - some minor bug fixes and cleanups for menubox, checklist and
  63.  *             textbox.
  64.  *
  65.  *  11/01/94 - added a man page.
  66.  *
  67.  *  13/01/94 - some changes for easier porting to other Unix systems (tested
  68.  *             on Ultrix, SunOS and HPUX)
  69.  *           - Version 0.3 released.
  70.  * 
  71.  *  08/06/94 - Patches by Stuart Herbert - S.Herbert@shef.ac.uk
  72.  *            Fixed attr_clear and the textbox stuff to work with ncurses 1.8.5
  73.  *            Fixed the wordwrap routine - it'll actually wrap properly now
  74.  *           Added a more 3D look to everything - having your own rc file could
  75.  *             prove 'interesting' to say the least :-)
  76.  *             Added radiolist option
  77.  *         - Version 0.4 released.
  78.  */
  79.  
  80.  
  81. #define __DIALOG_MAIN__
  82.  
  83.  
  84. #include "dialog.h"
  85. #ifdef HAVE_NCURSES
  86. #include "colors.h"
  87. #endif
  88.  
  89.  
  90. int main(int argc, unsigned char *argv[])
  91. {
  92.   int offset = 0, clear_screen = 0, end_common_opts = 0, retval;
  93.   unsigned char *title = NULL;
  94.  
  95. #if defined(LOCALE)
  96.   (void) setlocale(LC_ALL, "");
  97. #endif
  98.  
  99. #if defined(LOCALE)
  100.   (void) setlocale(LC_ALL, "");
  101. #endif
  102.  
  103.   if (argc < 2) {
  104.     Usage(argv[0]);
  105.     exit(-1);
  106.   }
  107.  
  108.   while (offset < argc-1 && !end_common_opts) {    /* Common options */
  109.     if (!strcmp(argv[offset+1], "--title")) {
  110.       if (argc-offset < 3 || title != NULL) {    /* No two "--title" please! */
  111.         Usage(argv[0]);
  112.         exit(-1);
  113.       }
  114.       else {
  115.         title = argv[offset+2];
  116.         offset += 2;
  117.       }
  118.     }
  119.     else if (!strcmp(argv[offset+1], "--clear")) {
  120.       if (clear_screen) {    /* Hey, "--clear" can't appear twice! */
  121.         Usage(argv[0]);
  122.         exit(-1);
  123.       }
  124.       else if (argc == 2) {    /* we only want to clear the screen */
  125.         init_dialog();
  126.         refresh();    /* init_dialog() will clear the screen for us */
  127.         endwin();
  128.         return 0;
  129.       }
  130.       else {
  131.         clear_screen = 1;
  132.         offset++;
  133.       }
  134.     }
  135.     else    /* no more common options */
  136.       end_common_opts = 1;
  137.   }
  138.  
  139.   if (argc-1 == offset) {    /* no more options */
  140.     Usage(argv[0]);
  141.     exit(-1);
  142.   }
  143.  
  144.   /* Box options */
  145.  
  146.   if (!strcmp(argv[offset+1], "--yesno")) {
  147.     if (argc-offset != 5) {
  148.       Usage(argv[0]);
  149.       exit(-1);
  150.     }
  151.     init_dialog();
  152.     retval = dialog_yesno(title, argv[offset+2], atoi(argv[offset+3]),
  153.                           atoi(argv[offset+4]));
  154.  
  155.     if (clear_screen) {    /* clear screen before exit */
  156.       attr_clear(stdscr, LINES, COLS, screen_attr);
  157.       refresh();
  158.     }
  159.     endwin();
  160.     return retval;
  161.   }
  162.   else if (!strcmp(argv[offset+1], "--msgbox")) {
  163.     if (argc-offset != 5) {
  164.       Usage(argv[0]);
  165.       exit(-1);
  166.     }
  167.     init_dialog();
  168.     retval = dialog_msgbox(title, argv[offset+2], atoi(argv[offset+3]),
  169.                            atoi(argv[offset+4]), 1);
  170.  
  171.     if (clear_screen) {    /* clear screen before exit */
  172.       attr_clear(stdscr, LINES, COLS, screen_attr);
  173.       refresh();
  174.     }
  175.     endwin();
  176.     return retval;
  177.   }
  178.   else if (!strcmp(argv[offset+1], "--infobox")) {
  179.     if (argc-offset != 5) {
  180.       Usage(argv[0]);
  181.       exit(-1);
  182.     }
  183.     init_dialog();
  184.     retval = dialog_msgbox(title, argv[offset+2], atoi(argv[offset+3]),
  185.                            atoi(argv[offset+4]), 0);
  186.  
  187.     if (clear_screen) {    /* clear screen before exit */
  188.       attr_clear(stdscr, LINES, COLS, screen_attr);
  189.       refresh();
  190.     }
  191.     endwin();
  192.     return retval;
  193.   }
  194.   else if (!strcmp(argv[offset+1], "--textbox")) {
  195.     if (argc-offset != 5) {
  196.       Usage(argv[0]);
  197.       exit(-1);
  198.     }
  199.     init_dialog();
  200.     retval = dialog_textbox(title, argv[offset+2], atoi(argv[offset+3]),
  201.                             atoi(argv[offset+4]));
  202.  
  203.     if (clear_screen) {    /* clear screen before exit */
  204.       attr_clear(stdscr, LINES, COLS, screen_attr);
  205.       refresh();
  206.     }
  207.     endwin();
  208.     return retval;
  209.   }
  210.   else if (!strcmp(argv[offset+1], "--menu")) {
  211.     if (argc-offset < 8 || ((argc-offset) % 2)) {
  212.       Usage(argv[0]);
  213.       exit(-1);
  214.     }
  215.     init_dialog();
  216.     retval = dialog_menu(title, argv[offset+2], atoi(argv[offset+3]),
  217.                          atoi(argv[offset+4]), atoi(argv[offset+5]),
  218.                          (argc-offset-6)/2, argv+offset + 6);
  219.  
  220.     if (clear_screen) {    /* clear screen before exit */
  221.       attr_clear(stdscr, LINES, COLS, screen_attr);
  222.       refresh();
  223.     }
  224.     endwin();
  225.     return retval;
  226.   }
  227.   else if (!strcmp(argv[offset+1], "--checklist")) {
  228.     if (argc-offset < 9 || ((argc-offset-6) % 3)) {
  229.       Usage(argv[0]);
  230.       exit(-1);
  231.     }
  232.     init_dialog();
  233.     retval = dialog_checklist(title, argv[offset+2], atoi(argv[offset+3]),
  234.                               atoi(argv[offset+4]), atoi(argv[offset+5]),
  235.                               (argc-offset-6)/3, argv+offset + 6);
  236.  
  237.     if (clear_screen) {    /* clear screen before exit */
  238.       attr_clear(stdscr, LINES, COLS, screen_attr);
  239.       refresh();
  240.     }
  241.     endwin();
  242.     return retval;
  243.   }
  244.   else if (!strcmp(argv[offset+1], "--inputbox")) {
  245.     if (argc-offset != 5) {
  246.       Usage(argv[0]);
  247.       exit(-1);
  248.     }
  249.     init_dialog();
  250.     retval = dialog_inputbox(title, argv[offset+2], atoi(argv[offset+3]),
  251.                              atoi(argv[offset+4]));
  252.  
  253.     if (clear_screen) {    /* clear screen before exit */
  254.       attr_clear(stdscr, LINES, COLS, screen_attr);
  255.       refresh();
  256.     }
  257.     endwin();
  258.     return retval;
  259.   }
  260.  
  261.   Usage(argv[0]);
  262.   exit(-1);
  263. }
  264. /* End of main() */
  265.  
  266.  
  267. /*
  268.  * Print program usage
  269.  */
  270. void Usage(unsigned char *name)
  271. {
  272.   fprintf(stderr, "\
  273. \ndialog version 0.3, by Savio Lam (lam836@cs.cuhk.hk).\
  274. \n  patched to version %s by Stuart Herbert (S.Herbert@shef.ac.uk)\
  275. \n\
  276. \n* Display dialog boxes from shell scripts *\
  277. \n\
  278. \nUsage: %s --clear\
  279. \n       %s [--title <title>] [--clear] <Box options>\
  280. \n\
  281. \nBox options:\
  282. \n\
  283. \n  --yesno     <text> <height> <width>\
  284. \n  --msgbox    <text> <height> <width>\
  285. \n  --infobox   <text> <height> <width>\
  286. \n  --inputbox  <text> <height> <width>\
  287. \n  --textbox   <file> <height> <width>\
  288. \n  --menu      <text> <height> <width> <menu height> <tag1> <item1>...\
  289. \n  --checklist <text> <height> <width> <list height> <tag1> <item1> <status1>...\
  290. /*\n  --radiolist <text> <height> <width> <list height> <tag1> <item1> <status1>...*/\n", VERSION, name, name);
  291. }
  292. /* End of Usage() */
  293.  
  294.  
  295. /*
  296.  * Do some initialization for dialog
  297.  */
  298. void init_dialog(void)
  299. {
  300.  
  301.   initscr();     /* Init curses */
  302.   keypad(stdscr, TRUE);
  303.   cbreak();
  304.   noecho();
  305.  
  306. #ifdef HAVE_NCURSES
  307.   if (use_colors || use_shadow)    /* Set up colors */
  308.     color_setup();
  309. #endif
  310.  
  311.   /* Set screen to screen attribute */
  312.   attr_clear(stdscr, LINES, COLS, screen_attr);
  313.   wnoutrefresh(stdscr);
  314. }
  315. /* End of init_dialog() */
  316.  
  317.  
  318. #ifdef HAVE_NCURSES
  319. /*
  320.  * Setup for color display
  321.  */
  322. void color_setup(void)
  323. {
  324.   int i;
  325.  
  326.   if (has_colors()) {    /* Terminal supports color? */
  327.     start_color();
  328.  
  329.     /* Initialize color pairs */
  330.     for (i = 0; i < ATTRIBUTE_COUNT; i++)
  331.       init_pair(i+1, color_table[i][0], color_table[i][1]);
  332.  
  333.     /* Setup color attributes */
  334.     for (i = 0; i < ATTRIBUTE_COUNT; i++)
  335.       attributes[i] = C_ATTR(color_table[i][2], i+1);
  336.   }
  337. }
  338. /* End of color_setup() */
  339. #endif
  340.  
  341.  
  342. /*
  343.  * Set window to attribute 'attr'
  344.  */
  345. void attr_clear(WINDOW *win, int height, int width, chtype attr)
  346. {
  347. #ifdef HAVE_NCURSES
  348.   wattrset(win, attr);    /* Set window to attribute 'attr' */
  349.   werase(win);
  350. #else
  351.   int i, j;
  352.  
  353.   wattrset(win, attr);    /* Set window to attribute 'attr' */
  354.   for (i = 0; i < height; i++) {
  355.     wmove(win, i, 0);
  356.     for (j = 0; j < width; j++)
  357.       waddch(win, ' ');
  358.   }
  359.   touchwin(win);
  360. #endif
  361. }
  362. /* End of attr_clear() */
  363.  
  364. /*
  365.  * Print a string of text in a window, automatically wrap around to the
  366.  * next line if the string is too long to fit on one line. Note that the
  367.  * string may contain "\n" to represent a newline character or the real
  368.  * newline '\n', but in that case, auto wrap around will be disabled.
  369.  */
  370. void print_autowrap(WINDOW *win, unsigned char *prompt, int width, int y, int x)
  371. {
  372.   int first = 1, cur_x, cur_y;
  373.   unsigned char tempstr[MAX_LEN+1], *word, *tempptr, *tempptr1;
  374.  
  375.   strcpy(tempstr, prompt);
  376.   if ((strstr(tempstr, "\\n") != NULL) ||
  377.       (strchr(tempstr, '\n') != NULL)) {    /* Prompt contains "\n" or '\n' */
  378.     word = tempstr;
  379.     cur_y = 1;
  380.     wmove(win, cur_y, x);
  381.     while (1) {
  382.       tempptr = strstr(word, "\\n");
  383.       tempptr1 = strchr(word, '\n');
  384.       if (tempptr == NULL && tempptr1 == NULL)
  385.         break;
  386.       else if (tempptr == NULL) {    /* No more "\n" */
  387.         tempptr = tempptr1;
  388.         tempptr[0] = '\0';
  389.       }
  390.       else if (tempptr1 == NULL) {    /* No more '\n' */
  391.         tempptr[0] = '\0';
  392.         tempptr++;
  393.       }
  394.       else {    /* Prompt contains both "\n" and '\n' */
  395.         if (strlen(tempptr)-2 < strlen(tempptr1)-1) {
  396.           tempptr = tempptr1;
  397.           tempptr[0] = '\0';
  398.         }
  399.         else {
  400.           tempptr[0] = '\0';
  401.           tempptr++;
  402.         }
  403.       }
  404.  
  405.       waddstr(win, word);
  406.       word = tempptr + 1;
  407.       wmove(win, ++cur_y, x);
  408.     }
  409.     waddstr(win, word);
  410.   }
  411.   else if (strlen(tempstr) <= width-x*2) {    /* If prompt is short */
  412.     wmove(win, 1, (width - strlen(tempstr)) / 2);
  413.     waddstr(win, tempstr);
  414.   }
  415.   else {
  416.     cur_x = x;
  417.     cur_y = y;
  418.     /* Print prompt word by word, wrap around if necessary */
  419.     while ((word = strtok(first ? tempstr : NULL, " ")) != NULL) {
  420.       if (first)    /* First iteration */
  421.         first = 0;
  422.       if (cur_x+strlen(word) > width-x) {    /* wrap around to next line */
  423.         cur_y++;
  424.         cur_x = x;
  425.       }
  426.       wmove(win, cur_y, cur_x);
  427.       waddstr(win, word);
  428.       getyx(win, cur_y, cur_x);
  429.       cur_x++;
  430.     }
  431.   }
  432. }
  433. /* End of print_autowrap() */
  434.  
  435. /*
  436.  * Print a button
  437.  */
  438. void print_button(WINDOW *win, unsigned char *label, int y, int x, int selected)
  439. {
  440.   int i, temp;
  441.  
  442.   wmove(win, y, x);
  443.   wattrset(win, selected ? button_active_attr : button_inactive_attr);
  444.   waddstr(win, "<");
  445.   temp = strspn(label, " ");
  446.   label += temp;
  447.   wattrset(win, selected ? button_label_active_attr : button_label_inactive_attr);
  448.   for (i = 0; i < temp; i++)
  449.     waddch(win, ' ');
  450.   wattrset(win, selected ? button_key_active_attr : button_key_inactive_attr);
  451.   waddch(win, label[0]);
  452.   wattrset(win, selected ? button_label_active_attr : button_label_inactive_attr);
  453.   waddstr(win, label+1);
  454.   wattrset(win, selected ? button_active_attr : button_inactive_attr);
  455.   waddstr(win, ">");
  456.   wmove(win, y, x+temp+1);
  457. }
  458. /* End of print_button() */
  459.  
  460. void draw_box(WINDOW *win, int y, int x, int height, int width, chtype box, chtype border)
  461. {
  462.   int i, j;
  463.  
  464.   wattrset(win, 0);
  465.   for (i = 0; i < height; i++) {
  466.     wmove(win, y + i, x);
  467.     for (j = 0; j < width; j++)
  468.       if (!i && !j)
  469.         waddch(win, border | ACS_ULCORNER);
  470.       else if (i == height-1 && !j)
  471.         waddch(win, border | ACS_LLCORNER);
  472.       else if (!i && j == width-1)
  473.         waddch(win, border | ACS_URCORNER);
  474.       else if (i == height-1 && j == width-1)
  475.         waddch(win, border | ACS_LRCORNER);
  476.       else if (!i || i == height-1)
  477.         waddch(win, border | ACS_HLINE);
  478.       else if (!j || j == width-1)
  479.         waddch(win, border | ACS_VLINE);
  480.       else
  481.         waddch(win, box | ' ');
  482.   }
  483. }
  484. /* End of draw_box() */
  485.  
  486.  
  487.  
  488. #ifdef HAVE_NCURSES
  489. /*
  490.  * Draw shadows along the right and bottom edge to give a more 3D look
  491.  * to the boxes
  492.  */
  493. void draw_shadow(WINDOW *win, int y, int x, int height, int width)
  494. {
  495.   int i;
  496.  
  497.   if (has_colors()) {    /* Whether terminal supports color? */
  498.     wattrset(win, shadow_attr);
  499.     wmove(win, y + height, x + 2);
  500.     for (i = 0; i < width; i++)
  501.       waddch(win, winch(win) & A_CHARTEXT);
  502.     for (i = y + 1; i < y + height + 1; i++) {
  503.       wmove(win, i, x + width);
  504.       waddch(win, winch(win) & A_CHARTEXT);
  505.       waddch(win, winch(win) & A_CHARTEXT);
  506.     }
  507.     wnoutrefresh(win);
  508.   }
  509. }
  510. /* End of draw_shadow() */
  511. #endif
  512.