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-3d < prev    next >
Encoding:
Text File  |  1994-06-09  |  15.4 KB  |  556 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.   else if (!strcmp(argv[1], "--create-rc")) {
  108. #ifdef HAVE_NCURSES
  109.     if (argc != 3) {
  110.       Usage(argv[0]);
  111.       exit(-1);
  112.     }
  113.     create_rc(argv[2]);
  114.     return 0;
  115. #else
  116.     fprintf(stderr, "\nThis option is currently unsupported on your system.\n");
  117.     return -1;
  118. #endif
  119.   }
  120.  
  121.   while (offset < argc-1 && !end_common_opts) {    /* Common options */
  122.     if (!strcmp(argv[offset+1], "--title")) {
  123.       if (argc-offset < 3 || title != NULL) {    /* No two "--title" please! */
  124.         Usage(argv[0]);
  125.         exit(-1);
  126.       }
  127.       else {
  128.         title = argv[offset+2];
  129.         offset += 2;
  130.       }
  131.     }
  132.     else if (!strcmp(argv[offset+1], "--clear")) {
  133.       if (clear_screen) {    /* Hey, "--clear" can't appear twice! */
  134.         Usage(argv[0]);
  135.         exit(-1);
  136.       }
  137.       else if (argc == 2) {    /* we only want to clear the screen */
  138.         init_dialog();
  139.         refresh();    /* init_dialog() will clear the screen for us */
  140.         endwin();
  141.         return 0;
  142.       }
  143.       else {
  144.         clear_screen = 1;
  145.         offset++;
  146.       }
  147.     }
  148.     else    /* no more common options */
  149.       end_common_opts = 1;
  150.   }
  151.  
  152.   if (argc-1 == offset) {    /* no more options */
  153.     Usage(argv[0]);
  154.     exit(-1);
  155.   }
  156.  
  157.   /* Box options */
  158.  
  159.   if (!strcmp(argv[offset+1], "--yesno")) {
  160.     if (argc-offset != 5) {
  161.       Usage(argv[0]);
  162.       exit(-1);
  163.     }
  164.     init_dialog();
  165.     retval = dialog_yesno(title, argv[offset+2], atoi(argv[offset+3]),
  166.                           atoi(argv[offset+4]));
  167.  
  168.     if (clear_screen) {    /* clear screen before exit */
  169.       attr_clear(stdscr, LINES, COLS, screen_attr);
  170.       refresh();
  171.     }
  172.     endwin();
  173.     return retval;
  174.   }
  175.   else if (!strcmp(argv[offset+1], "--msgbox")) {
  176.     if (argc-offset != 5) {
  177.       Usage(argv[0]);
  178.       exit(-1);
  179.     }
  180.     init_dialog();
  181.     retval = dialog_msgbox(title, argv[offset+2], atoi(argv[offset+3]),
  182.                            atoi(argv[offset+4]), 1);
  183.  
  184.     if (clear_screen) {    /* clear screen before exit */
  185.       attr_clear(stdscr, LINES, COLS, screen_attr);
  186.       refresh();
  187.     }
  188.     endwin();
  189.     return retval;
  190.   }
  191.   else if (!strcmp(argv[offset+1], "--infobox")) {
  192.     if (argc-offset != 5) {
  193.       Usage(argv[0]);
  194.       exit(-1);
  195.     }
  196.     init_dialog();
  197.     retval = dialog_msgbox(title, argv[offset+2], atoi(argv[offset+3]),
  198.                            atoi(argv[offset+4]), 0);
  199.  
  200.     if (clear_screen) {    /* clear screen before exit */
  201.       attr_clear(stdscr, LINES, COLS, screen_attr);
  202.       refresh();
  203.     }
  204.     endwin();
  205.     return retval;
  206.   }
  207.   else if (!strcmp(argv[offset+1], "--textbox")) {
  208.     if (argc-offset != 5) {
  209.       Usage(argv[0]);
  210.       exit(-1);
  211.     }
  212.     init_dialog();
  213.     retval = dialog_textbox(title, argv[offset+2], atoi(argv[offset+3]),
  214.                             atoi(argv[offset+4]));
  215.  
  216.     if (clear_screen) {    /* clear screen before exit */
  217.       attr_clear(stdscr, LINES, COLS, screen_attr);
  218.       refresh();
  219.     }
  220.     endwin();
  221.     return retval;
  222.   }
  223.   else if (!strcmp(argv[offset+1], "--menu")) {
  224.     if (argc-offset < 8 || ((argc-offset) % 2)) {
  225.       Usage(argv[0]);
  226.       exit(-1);
  227.     }
  228.     init_dialog();
  229.     retval = dialog_menu(title, argv[offset+2], atoi(argv[offset+3]),
  230.                          atoi(argv[offset+4]), atoi(argv[offset+5]),
  231.                          (argc-offset-6)/2, argv+offset + 6);
  232.  
  233.     if (clear_screen) {    /* clear screen before exit */
  234.       attr_clear(stdscr, LINES, COLS, screen_attr);
  235.       refresh();
  236.     }
  237.     endwin();
  238.     return retval;
  239.   }
  240.   else if (!strcmp(argv[offset+1], "--checklist")) {
  241.     if (argc-offset < 9 || ((argc-offset-6) % 3)) {
  242.       Usage(argv[0]);
  243.       exit(-1);
  244.     }
  245.     init_dialog();
  246.     retval = dialog_checklist(title, argv[offset+2], atoi(argv[offset+3]),
  247.                               atoi(argv[offset+4]), atoi(argv[offset+5]),
  248.                               (argc-offset-6)/3, argv+offset + 6);
  249.  
  250.     if (clear_screen) {    /* clear screen before exit */
  251.       attr_clear(stdscr, LINES, COLS, screen_attr);
  252.       refresh();
  253.     }
  254.     endwin();
  255.     return retval;
  256.   }
  257.   else if (!strcmp(argv[offset+1], "--radiolist")) {
  258.     if (argc-offset < 9 || ((argc-offset-6) % 3)) {
  259.       Usage(argv[0]);
  260.       exit(-1);
  261.     }
  262.     init_dialog();
  263.     retval = dialog_radiolist(title, argv[offset+2], atoi(argv[offset+3]),
  264.                               atoi(argv[offset+4]), atoi(argv[offset+5]),
  265.                               (argc-offset-6)/3, argv+offset + 6);
  266.  
  267.     if (clear_screen) {    /* clear screen before exit */
  268.       attr_clear(stdscr, LINES, COLS, screen_attr);
  269.       refresh();
  270.     }
  271.     endwin();
  272.     return retval;
  273.   }
  274.   else if (!strcmp(argv[offset+1], "--inputbox")) {
  275.     if (argc-offset != 5) {
  276.       Usage(argv[0]);
  277.       exit(-1);
  278.     }
  279.     init_dialog();
  280.     retval = dialog_inputbox(title, argv[offset+2], atoi(argv[offset+3]),
  281.                              atoi(argv[offset+4]));
  282.  
  283.     if (clear_screen) {    /* clear screen before exit */
  284.       attr_clear(stdscr, LINES, COLS, screen_attr);
  285.       refresh();
  286.     }
  287.     endwin();
  288.     return retval;
  289.   }
  290.  
  291.   Usage(argv[0]);
  292.   exit(-1);
  293. }
  294. /* End of main() */
  295.  
  296.  
  297. /*
  298.  * Print program usage
  299.  */
  300. void Usage(unsigned char *name)
  301. {
  302.   fprintf(stderr, "\
  303. \ndialog version 0.3, by Savio Lam (lam836@cs.cuhk.hk).\
  304. \n  patched to version %s by Stuart Herbert (S.Herbert@shef.ac.uk)\
  305. \n\
  306. \n* Display dialog boxes from shell scripts *\
  307. \n\
  308. \nUsage: %s --clear\
  309. \n       %s --create-rc <file>\
  310. \n       %s [--title <title>] [--clear] <Box options>\
  311. \n\
  312. \nBox options:\
  313. \n\
  314. \n  --yesno     <text> <height> <width>\
  315. \n  --msgbox    <text> <height> <width>\
  316. \n  --infobox   <text> <height> <width>\
  317. \n  --inputbox  <text> <height> <width>\
  318. \n  --textbox   <file> <height> <width>\
  319. \n  --menu      <text> <height> <width> <menu height> <tag1> <item1>...\
  320. \n  --checklist <text> <height> <width> <list height> <tag1> <item1> <status1>...\
  321. \n  --radiolist <text> <height> <width> <list height> <tag1> <item1> <status1>...\n", VERSION, name, name, name);
  322. }
  323. /* End of Usage() */
  324.  
  325.  
  326. /*
  327.  * Do some initialization for dialog
  328.  */
  329. void init_dialog(void)
  330. {
  331. #ifdef HAVE_NCURSES
  332.   if (parse_rc() == -1)    /* Read the configuration file */
  333.     exit(-1);
  334. #endif
  335.  
  336.   initscr();     /* Init curses */
  337.   keypad(stdscr, TRUE);
  338.   cbreak();
  339.   noecho();
  340.  
  341. #ifdef HAVE_NCURSES
  342.   if (use_colors || use_shadow)    /* Set up colors */
  343.     color_setup();
  344. #endif
  345.  
  346.   /* Set screen to screen attribute */
  347.   attr_clear(stdscr, LINES, COLS, screen_attr);
  348.   wnoutrefresh(stdscr);
  349. }
  350. /* End of init_dialog() */
  351.  
  352.  
  353. #ifdef HAVE_NCURSES
  354. /*
  355.  * Setup for color display
  356.  */
  357. void color_setup(void)
  358. {
  359.   int i;
  360.  
  361.   if (has_colors()) {    /* Terminal supports color? */
  362.     start_color();
  363.  
  364.     /* Initialize color pairs */
  365.     for (i = 0; i < ATTRIBUTE_COUNT; i++)
  366.       init_pair(i+1, color_table[i][0], color_table[i][1]);
  367.  
  368.     /* Setup color attributes */
  369.     for (i = 0; i < ATTRIBUTE_COUNT; i++)
  370.       attributes[i] = C_ATTR(color_table[i][2], i+1);
  371.   }
  372. }
  373. /* End of color_setup() */
  374. #endif
  375.  
  376.  
  377. /*
  378.  * Set window to attribute 'attr'
  379.  */
  380. void attr_clear(WINDOW *win, int height, int width, chtype attr)
  381. {
  382. #ifdef HAVE_NCURSES
  383.   wattrset(win, attr);    /* Set window to attribute 'attr' */
  384.   werase(win);
  385. #else
  386.   int i, j;
  387.  
  388.   wattrset(win, attr);    /* Set window to attribute 'attr' */
  389.   for (i = 0; i < height; i++) {
  390.     wmove(win, i, 0);
  391.     for (j = 0; j < width; j++)
  392.       waddch(win, ' ');
  393.   }
  394.   touchwin(win);
  395. #endif
  396. }
  397. /* End of attr_clear() */
  398.  
  399.  
  400. /*
  401.  * Print a string of text in a window, automatically wrap around to the
  402.  * next line if the string is too long to fit on one line. Note that the
  403.  * string may contain "\n" to represent a newline character or the real
  404.  * newline '\n', but in that case, auto wrap around will be disabled.
  405.  */
  406. void print_autowrap(WINDOW *win, unsigned char *prompt, int width, int y, int x)
  407. {
  408.   int first = 1, cur_x, cur_y;
  409.   unsigned char tempstr[MAX_LEN+1], *word, *tempptr, *tempptr1;
  410.  
  411.   strcpy(tempstr, prompt);
  412.   if ((strstr(tempstr, "\\n") != NULL) ||
  413.       (strchr(tempstr, '\n') != NULL)) {    /* Prompt contains "\n" or '\n' */
  414.     word = tempstr;
  415.     cur_y = y;
  416.     wmove(win, cur_y, x);
  417.     while (1) {
  418.       tempptr = strstr(word, "\\n");
  419.       tempptr1 = strchr(word, '\n');
  420.       if (tempptr == NULL && tempptr1 == NULL)
  421.         break;
  422.       else if (tempptr == NULL) {    /* No more "\n" */
  423.         tempptr = tempptr1;
  424.         tempptr[0] = '\0';
  425.       }
  426.       else if (tempptr1 == NULL) {    /* No more '\n' */
  427.         tempptr[0] = '\0';
  428.         tempptr++;
  429.       }
  430.       else {    /* Prompt contains both "\n" and '\n' */
  431.         if (strlen(tempptr)-2 < strlen(tempptr1)-1) {
  432.           tempptr = tempptr1;
  433.           tempptr[0] = '\0';
  434.         }
  435.         else {
  436.           tempptr[0] = '\0';
  437.           tempptr++;
  438.         }
  439.       }
  440.  
  441.       waddstr(win, word);
  442.       word = tempptr + 1;
  443.       wmove(win, ++cur_y, x);
  444.     }
  445.     waddstr(win, word);
  446.   }
  447.   else if (strlen(tempstr) <= width-x*2) {    /* If prompt is short */
  448.     wmove(win, y, (width - strlen(tempstr)) / 2);
  449.     waddstr(win, tempstr);
  450.   }
  451.   else {
  452.     cur_x = x;
  453.     cur_y = y;
  454.     /* Print prompt word by word, wrap around if necessary */
  455.     while ((word = strtok(first ? tempstr : NULL, " ")) != NULL) {
  456.       if (first)    /* First iteration */
  457.         first = 0;
  458.       if (cur_x+strlen(word) > width) {    /* wrap around to next line */
  459.         cur_y++;
  460.         cur_x = x;
  461.       }
  462.       wmove(win, cur_y, cur_x);
  463.       waddstr(win, word);
  464.       getyx(win, cur_y, cur_x);
  465.       cur_x++;
  466.     }
  467.   }
  468. }
  469. /* End of print_autowrap() */
  470.  
  471.  
  472. /*
  473.  * Print a button
  474.  */
  475. void print_button(WINDOW *win, unsigned char *label, int y, int x, int selected)
  476. {
  477.   int i, temp;
  478.  
  479.   wmove(win, y, x);
  480.   wattrset(win, selected ? button_active_attr : button_inactive_attr);
  481.   waddstr(win, "<");
  482.   temp = strspn(label, " ");
  483.   label += temp;
  484.   wattrset(win, selected ? button_label_active_attr : button_label_inactive_attr);
  485.   for (i = 0; i < temp; i++)
  486.     waddch(win, ' ');
  487.   wattrset(win, selected ? button_key_active_attr : button_key_inactive_attr);
  488.   waddch(win, label[0]);
  489.   wattrset(win, selected ? button_label_active_attr : button_label_inactive_attr);
  490.   waddstr(win, label+1);
  491.   wattrset(win, selected ? button_active_attr : button_inactive_attr);
  492.   waddstr(win, ">");
  493.   wmove(win, y, x+temp+1);
  494. }
  495. /* End of print_button() */
  496.  
  497.  
  498. /*
  499.  * Draw a rectangular box with line drawing characters
  500.  */
  501. void draw_box(WINDOW *win, int y, int x, int height, int width, chtype box, chtype border)
  502. {
  503.   int i, j;
  504.  
  505.   wattrset(win, 0);
  506.   for (i = 0; i < height; i++) {
  507.     wmove(win, y + i, x);
  508.     for (j = 0; j < width; j++)
  509.       if (!i && !j)
  510.         waddch(win, border | ACS_ULCORNER);
  511.       else if (i == height-1 && !j)
  512.         waddch(win, border | ACS_LLCORNER);
  513.       else if (!i && j == width-1)
  514.         waddch(win, box | ACS_URCORNER);
  515.       else if (i == height-1 && j == width-1)
  516.         waddch(win, box | ACS_LRCORNER);
  517.       else if (!i)
  518.         waddch(win, border | ACS_HLINE);
  519.       else if (i == height-1)
  520.         waddch(win, box | ACS_HLINE);
  521.       else if (!j)
  522.         waddch(win, border | ACS_VLINE);
  523.       else if (j == width-1)
  524.         waddch(win, box | ACS_VLINE);
  525.       else
  526.         waddch(win, box | ' ');
  527.   }
  528. }
  529. /* End of draw_box() */
  530.  
  531.  
  532. #ifdef HAVE_NCURSES
  533. /*
  534.  * Draw shadows along the right and bottom edge to give a more 3D look
  535.  * to the boxes
  536.  */
  537. void draw_shadow(WINDOW *win, int y, int x, int height, int width)
  538. {
  539.   int i;
  540.  
  541.   if (has_colors()) {    /* Whether terminal supports color? */
  542.     wattrset(win, shadow_attr);
  543.     wmove(win, y + height, x + 2);
  544.     for (i = 0; i < width; i++)
  545.       waddch(win, winch(win) & A_CHARTEXT);
  546.     for (i = y + 1; i < y + height + 1; i++) {
  547.       wmove(win, i, x + width);
  548.       waddch(win, winch(win) & A_CHARTEXT);
  549.       waddch(win, winch(win) & A_CHARTEXT);
  550.     }
  551.     wnoutrefresh(win);
  552.   }
  553. }
  554. /* End of draw_shadow() */
  555. #endif
  556.