Linux - POSIX On A PC For FREE
==============================================================================
Patch File For dialog(1)
==============================================================================

== Introduction ==============================================================

       This is a patch for the dialog(1) utility, which allows it to work
       with ncurses 1.8.5, provided you also patch ncurses 1.8.5!

       There's also some bug fixes, and a new radiolist option.

== What You Need =============================================================

       You need the following source code :

       * dialog v0.3
               dialog-slack-8-bit.tar.gz, from ftp.cdrom.com, in the
               /pub/linux/slackware_source/a hierarchy.

       * ncurses 1.8.5
               1.8.5.tar.gz, from ftp.netcom.com, in /pub/zmbenhal/ncurses.
               If you have Slackware 1.2.x, you should upgrade to ncurses
               1.8.5.

       You also need the following patches :

       * dialog-0.4-patch
               This file.  Patches dialog v0.3 to produce v0.4

       * ncurses-1.8.5-patch
               Should be found with this file; if you can't find it, mail
               me, or look in the Linux Software Map.

== What They Do ==============================================================

       * werase()
               The werase() function in ncurses 1.8.5 is broken; the patch
               for ncurses fixes it.

       * support for ncurses 1.8.5
               dialog 0.3 doesn't work with ncurses 1.8.5 as-is (textbox
               scrolling screws up the screen).  I don't know whether
               ncurses is to blame, but dialog 0.4 gets round the problem.

       * word wrap fixed
               the word wrap for text output did anything but; this has been
               fixed.

       * new colour defaults
               dialog 0.4 provides a pseudo 3D look, to go with the drop
               shadow effect.

       * new option -- radiolist
               allow for radio buttons, which some users might prefer

       * key change on textbox
               pressing 'enter' in a textbox will quit the textbox; although
               not normal unix behaviour, it's more consistent with the
               other dialog options

== How To Patch ==============================================================

       Unpack the dialog and ncurses source code.

       For ncurses, cd <where you put ncurses>/ncurses-1.8.5, and then
       patch -p1 < <wherever you put it>/ncurses-1.8.5-patch.

       For dialog, cd <where you put dialog>/dialog-slack-8-bit, and then
       patch -p1 < <where you put it>/dialog-0.4-patch

       Compile and install ncurses 1.8.5, before compiling dialog v0.4.  If
       you install ncurses to somewhere different from /usr/local/... then
       you'll need to change dialog's makefile accordingly.

==============================================================================
Stuart Herbert - [email protected]

---- patch starts here ----

diff -u --recursive --new-file dialog-slack-8-bit/src/Makefile dialog-0.4/src/Makefile
--- dialog-slack-8-bit/src/Makefile     Mon Mar 21 02:09:57 1994
+++ dialog-0.4/src/Makefile     Wed Jun  8 01:24:20 1994
@@ -1,6 +1,6 @@

INSTALL = install
-BINDIR = /usr/local/bin
+BINDIR = /bin
MANDIR = /usr/local/man
MANEXT = 1

@@ -10,12 +10,12 @@
DEFS = -DHAVE_NCURSES -DLOCALE
LIBS = -lncurses

-CFLAGS = -O2 -Wall -Wstrict-prototypes -fomit-frame-pointer -I/usr/include/ncurses
+CFLAGS = -O2 -Wall -Wstrict-prototypes -fomit-frame-pointer -I/usr/local/ncurses
LDFLAGS = -s

HDRS = dialog.h colors.h rc.h
-SRCS = dialog.c rc.c checklist.c inputbox.c menubox.c msgbox.c textbox.c yesno.c
-OBJS = dialog.o rc.o checklist.o inputbox.o menubox.o msgbox.o textbox.o yesno.o
+SRCS = dialog.c rc.c checklist.c inputbox.c menubox.c msgbox.c radiolist.c textbox.c yesno.c
+OBJS = dialog.o rc.o checklist.o inputbox.o menubox.o msgbox.o radiolist.o textbox.o yesno.o

all: dialog

diff -u --recursive --new-file dialog-slack-8-bit/src/Makefile.linux dialog-0.4/src/Makefile.linux
--- dialog-slack-8-bit/src/Makefile.linux       Fri Feb 11 20:16:57 1994
+++ dialog-0.4/src/Makefile.linux       Wed Jun  8 01:24:31 1994
@@ -1,21 +1,21 @@

INSTALL = install
-BINDIR = /usr/local/bin
+BINDIR = /bin
MANDIR = /usr/local/man
MANEXT = 1

CC = gcc
CPP = $(CC) -E

-DEFS = -DHAVE_NCURSES -DBROKEN_WSCRL
+DEFS = -DHAVE_NCURSES -DLOCALE
LIBS = -lncurses

-CFLAGS = -s -O2 -Wall -Wstrict-prototypes -fomit-frame-pointer
+CFLAGS = -O2 -Wall -Wstrict-prototypes -fomit-frame-pointer -I/usr/local/ncurses
LDFLAGS = -s

HDRS = dialog.h colors.h rc.h
-SRCS = dialog.c rc.c checklist.c inputbox.c menubox.c msgbox.c textbox.c yesno.c
-OBJS = dialog.o rc.o checklist.o inputbox.o menubox.o msgbox.o textbox.o yesno.o
+SRCS = dialog.c rc.c checklist.c inputbox.c menubox.c msgbox.c radiolist.c textbox.c yesno.c
+OBJS = dialog.o rc.o checklist.o inputbox.o menubox.o msgbox.o radiolist.o textbox.o yesno.o

all: dialog

diff -u --recursive --new-file dialog-slack-8-bit/src/checklist.c dialog-0.4/src/checklist.c
--- dialog-slack-8-bit/src/checklist.c  Fri Feb 11 20:34:19 1994
+++ dialog-0.4/src/checklist.c  Tue Jun  7 23:52:26 1994
@@ -66,6 +66,7 @@
  waddch(dialog, ACS_LTEE);
  for (i = 0; i < width-2; i++)
    waddch(dialog, ACS_HLINE);
+  wattrset(dialog, dialog_attr);
  waddch(dialog, ACS_RTEE);
  wmove(dialog, height-2, 1);
  for (i = 0; i < width-2; i++)
@@ -91,7 +92,7 @@
  keypad(list, TRUE);

  /* draw a box around the list items */
-  draw_box(dialog, box_y, box_x, list_height+2, list_width+2, menubox_attr, menubox_border_attr);
+  draw_box(dialog, box_y, box_x, list_height+2, list_width+2, menubox_border_attr, menubox_attr);

  check_x = 0;
  item_x = 0;
@@ -165,7 +166,7 @@

            /* print the up/down arrows */
            wmove(dialog, box_y, box_x + check_x + 5);
-            wattrset(dialog, scroll ? uarrow_attr : menubox_border_attr);
+            wattrset(dialog, scroll ? uarrow_attr : menubox_attr);
            waddch(dialog, scroll ? ACS_UARROW : ACS_HLINE);
            wmove(dialog, box_y, box_x + check_x + 6);
            waddch(dialog, scroll ? '(' : ACS_HLINE);
diff -u --recursive --new-file dialog-slack-8-bit/src/colors.h dialog-0.4/src/colors.h
--- dialog-slack-8-bit/src/colors.h     Fri Feb 11 20:16:57 1994
+++ dialog-0.4/src/colors.h     Wed Jun  8 02:00:40 1994
@@ -26,24 +26,24 @@
 *   *_BG = background
 *   *_HL = highlight?
 */
-#define SCREEN_FG                    COLOR_WHITE
+#define SCREEN_FG                    COLOR_CYAN
#define SCREEN_BG                    COLOR_BLUE
-#define SCREEN_HL                    FALSE
+#define SCREEN_HL                    TRUE

-#define SHADOW_FG                    COLOR_WHITE
+#define SHADOW_FG                    COLOR_BLACK
#define SHADOW_BG                    COLOR_BLACK
-#define SHADOW_HL                    FALSE
+#define SHADOW_HL                    TRUE

#define DIALOG_FG                    COLOR_BLACK
-#define DIALOG_BG                    COLOR_CYAN
+#define DIALOG_BG                    COLOR_WHITE
#define DIALOG_HL                    FALSE

#define TITLE_FG                     COLOR_YELLOW
-#define TITLE_BG                     COLOR_CYAN
+#define TITLE_BG                     COLOR_WHITE
#define TITLE_HL                     TRUE

-#define BORDER_FG                    COLOR_CYAN
-#define BORDER_BG                    COLOR_CYAN
+#define BORDER_FG                    COLOR_WHITE
+#define BORDER_BG                    COLOR_WHITE
#define BORDER_HL                    TRUE

#define BUTTON_ACTIVE_FG             COLOR_WHITE
@@ -51,95 +51,95 @@
#define BUTTON_ACTIVE_HL             TRUE

#define BUTTON_INACTIVE_FG           COLOR_BLACK
-#define BUTTON_INACTIVE_BG           COLOR_CYAN
+#define BUTTON_INACTIVE_BG           COLOR_WHITE
#define BUTTON_INACTIVE_HL           FALSE

#define BUTTON_KEY_ACTIVE_FG         COLOR_WHITE
#define BUTTON_KEY_ACTIVE_BG         COLOR_BLUE
#define BUTTON_KEY_ACTIVE_HL         TRUE

-#define BUTTON_KEY_INACTIVE_FG       COLOR_BLACK
-#define BUTTON_KEY_INACTIVE_BG       COLOR_CYAN
+#define BUTTON_KEY_INACTIVE_FG       COLOR_RED
+#define BUTTON_KEY_INACTIVE_BG       COLOR_WHITE
#define BUTTON_KEY_INACTIVE_HL       FALSE

-#define BUTTON_LABEL_ACTIVE_FG       COLOR_WHITE
+#define BUTTON_LABEL_ACTIVE_FG       COLOR_YELLOW
#define BUTTON_LABEL_ACTIVE_BG       COLOR_BLUE
#define BUTTON_LABEL_ACTIVE_HL       TRUE

#define BUTTON_LABEL_INACTIVE_FG     COLOR_BLACK
-#define BUTTON_LABEL_INACTIVE_BG     COLOR_CYAN
+#define BUTTON_LABEL_INACTIVE_BG     COLOR_WHITE
#define BUTTON_LABEL_INACTIVE_HL     TRUE

-#define INPUTBOX_FG                  COLOR_BLUE
+#define INPUTBOX_FG                  COLOR_BLACK
#define INPUTBOX_BG                  COLOR_WHITE
#define INPUTBOX_HL                  FALSE

-#define INPUTBOX_BORDER_FG           COLOR_CYAN
-#define INPUTBOX_BORDER_BG           COLOR_CYAN
-#define INPUTBOX_BORDER_HL           TRUE
+#define INPUTBOX_BORDER_FG           COLOR_BLACK
+#define INPUTBOX_BORDER_BG           COLOR_WHITE
+#define INPUTBOX_BORDER_HL           FALSE

-#define SEARCHBOX_FG                 COLOR_YELLOW
+#define SEARCHBOX_FG                 COLOR_BLACK
#define SEARCHBOX_BG                 COLOR_WHITE
-#define SEARCHBOX_HL                 TRUE
+#define SEARCHBOX_HL                 FALSE

-#define SEARCHBOX_TITLE_FG           COLOR_WHITE
+#define SEARCHBOX_TITLE_FG           COLOR_YELLOW
#define SEARCHBOX_TITLE_BG           COLOR_WHITE
#define SEARCHBOX_TITLE_HL           TRUE

-#define SEARCHBOX_BORDER_FG          COLOR_RED
+#define SEARCHBOX_BORDER_FG          COLOR_WHITE
#define SEARCHBOX_BORDER_BG          COLOR_WHITE
-#define SEARCHBOX_BORDER_HL          FALSE
+#define SEARCHBOX_BORDER_HL          TRUE

-#define POSITION_INDICATOR_FG        COLOR_RED
-#define POSITION_INDICATOR_BG        COLOR_CYAN
-#define POSITION_INDICATOR_HL        FALSE
+#define POSITION_INDICATOR_FG        COLOR_YELLOW
+#define POSITION_INDICATOR_BG        COLOR_WHITE
+#define POSITION_INDICATOR_HL        TRUE

#define MENUBOX_FG                   COLOR_BLACK
-#define MENUBOX_BG                   COLOR_CYAN
+#define MENUBOX_BG                   COLOR_WHITE
#define MENUBOX_HL                   FALSE

-#define MENUBOX_BORDER_FG            COLOR_CYAN
-#define MENUBOX_BORDER_BG            COLOR_CYAN
+#define MENUBOX_BORDER_FG            COLOR_WHITE
+#define MENUBOX_BORDER_BG            COLOR_WHITE
#define MENUBOX_BORDER_HL            TRUE

#define ITEM_FG                      COLOR_BLACK
-#define ITEM_BG                      COLOR_CYAN
+#define ITEM_BG                      COLOR_WHITE
#define ITEM_HL                      FALSE

#define ITEM_SELECTED_FG             COLOR_WHITE
#define ITEM_SELECTED_BG             COLOR_BLUE
-#define ITEM_SELECTED_HL             FALSE
+#define ITEM_SELECTED_HL             TRUE

#define TAG_FG                       COLOR_YELLOW
-#define TAG_BG                       COLOR_CYAN
+#define TAG_BG                       COLOR_WHITE
#define TAG_HL                       TRUE

-#define TAG_SELECTED_FG              COLOR_WHITE
+#define TAG_SELECTED_FG              COLOR_YELLOW
#define TAG_SELECTED_BG              COLOR_BLUE
-#define TAG_SELECTED_HL              FALSE
+#define TAG_SELECTED_HL              TRUE

#define TAG_KEY_FG                   COLOR_RED
-#define TAG_KEY_BG                   COLOR_CYAN
-#define TAG_KEY_HL                   FALSE
+#define TAG_KEY_BG                   COLOR_WHITE
+#define TAG_KEY_HL                   TRUE

#define TAG_KEY_SELECTED_FG          COLOR_RED
#define TAG_KEY_SELECTED_BG          COLOR_BLUE
#define TAG_KEY_SELECTED_HL          TRUE

#define CHECK_FG                     COLOR_BLACK
-#define CHECK_BG                     COLOR_CYAN
+#define CHECK_BG                     COLOR_WHITE
#define CHECK_HL                     FALSE

#define CHECK_SELECTED_FG            COLOR_WHITE
-#define CHECK_SELECTED_BG            COLOR_CYAN
+#define CHECK_SELECTED_BG            COLOR_BLUE
#define CHECK_SELECTED_HL            TRUE

#define UARROW_FG                    COLOR_GREEN
-#define UARROW_BG                    COLOR_CYAN
+#define UARROW_BG                    COLOR_WHITE
#define UARROW_HL                    TRUE

#define DARROW_FG                    COLOR_GREEN
-#define DARROW_BG                    COLOR_CYAN
+#define DARROW_BG                    COLOR_WHITE
#define DARROW_HL                    TRUE

/* End of default color definitions */
diff -u --recursive --new-file dialog-slack-8-bit/src/dialog.c dialog-0.4/src/dialog.c
--- dialog-slack-8-bit/src/dialog.c     Mon Mar 21 02:08:10 1994
+++ dialog-0.4/src/dialog.c     Wed Jun  8 01:22:29 1994
@@ -67,6 +67,14 @@
 *  13/01/94 - some changes for easier porting to other Unix systems (tested
 *             on Ultrix, SunOS and HPUX)
 *           - Version 0.3 released.
+ *
+ *  08/06/94 - Patches by Stuart Herbert - [email protected]
+ *            Fixed attr_clear and the textbox stuff to work with ncurses 1.8.5
+ *            Fixed the wordwrap routine - it'll actually wrap properly now
+ *            Added a more 3D look to everything - having your own rc file could
+ *              prove 'interesting' to say the least :-)
+ *             Added radiolist option
+ *          - Version 0.4 released.
 */


@@ -242,6 +250,23 @@
    endwin();
    return retval;
  }
+  else if (!strcmp(argv[offset+1], "--radiolist")) {
+    if (argc-offset < 9 || ((argc-offset-6) % 3)) {
+      Usage(argv[0]);
+      exit(-1);
+    }
+    init_dialog();
+    retval = dialog_radiolist(title, argv[offset+2], atoi(argv[offset+3]),
+                              atoi(argv[offset+4]), atoi(argv[offset+5]),
+                              (argc-offset-6)/3, argv+offset + 6);
+
+    if (clear_screen) {    /* clear screen before exit */
+      attr_clear(stdscr, LINES, COLS, screen_attr);
+      refresh();
+    }
+    endwin();
+    return retval;
+  }
  else if (!strcmp(argv[offset+1], "--inputbox")) {
    if (argc-offset != 5) {
      Usage(argv[0]);
@@ -271,7 +296,8 @@
void Usage(char *name)
{
  fprintf(stderr, "\
-\ndialog version %s, by Savio Lam ([email protected]).\
+\ndialog version 0.3, by Savio Lam ([email protected]).\
+\n  patched to version %s by Stuart Herbert ([email protected])\
\n\
\n* Display dialog boxes from shell scripts *\
\n\
@@ -287,7 +313,8 @@
\n  --inputbox  <text> <height> <width>\
\n  --textbox   <file> <height> <width>\
\n  --menu      <text> <height> <width> <menu height> <tag1> <item1>...\
-\n  --checklist <text> <height> <width> <list height> <tag1> <item1> <status1>...\n", VERSION, name, name, name);
+\n  --checklist <text> <height> <width> <list height> <tag1> <item1> <status1>...\
+\n  --radiolist <text> <height> <width> <list height> <tag1> <item1> <status1>...\n", VERSION, name, name, name);
}
/* End of Usage() */

@@ -350,7 +377,7 @@
{
#ifdef HAVE_NCURSES
  wattrset(win, attr);    /* Set window to attribute 'attr' */
-  wclear(win);
+  werase(win);
#else
  int i, j;

@@ -381,7 +408,7 @@
  if ((strstr(tempstr, "\\n") != NULL) ||
      (strchr(tempstr, '\n') != NULL)) {    /* Prompt contains "\n" or '\n' */
    word = tempstr;
-    cur_y = 1;
+    cur_y = y;
    wmove(win, cur_y, x);
    while (1) {
      tempptr = strstr(word, "\\n");
@@ -414,7 +441,7 @@
    waddstr(win, word);
  }
  else if (strlen(tempstr) <= width-x*2) {    /* If prompt is short */
-    wmove(win, 1, (width - strlen(tempstr)) / 2);
+    wmove(win, y, (width - strlen(tempstr)) / 2);
    waddstr(win, tempstr);
  }
  else {
@@ -424,7 +451,7 @@
    while ((word = strtok(first ? tempstr : NULL, " ")) != NULL) {
      if (first)    /* First iteration */
        first = 0;
-      if (cur_x+strlen(word) > width-x) {    /* wrap around to next line */
+      if (cur_x+strlen(word) > width) {    /* wrap around to next line */
        cur_y++;
        cur_x = x;
      }
@@ -480,13 +507,17 @@
      else if (i == height-1 && !j)
        waddch(win, border | ACS_LLCORNER);
      else if (!i && j == width-1)
-        waddch(win, border | ACS_URCORNER);
+        waddch(win, box | ACS_URCORNER);
      else if (i == height-1 && j == width-1)
-        waddch(win, border | ACS_LRCORNER);
-      else if (!i || i == height-1)
+        waddch(win, box | ACS_LRCORNER);
+      else if (!i)
        waddch(win, border | ACS_HLINE);
-      else if (!j || j == width-1)
+      else if (i == height-1)
+        waddch(win, box | ACS_HLINE);
+      else if (!j)
        waddch(win, border | ACS_VLINE);
+      else if (j == width-1)
+        waddch(win, box | ACS_VLINE);
      else
        waddch(win, box | ' ');
  }
diff -u --recursive --new-file dialog-slack-8-bit/src/dialog.h dialog-0.4/src/dialog.h
--- dialog-slack-8-bit/src/dialog.h     Mon Mar 21 02:08:10 1994
+++ dialog-0.4/src/dialog.h     Wed Jun  8 01:00:46 1994
@@ -51,7 +51,7 @@



-#define VERSION "0.3"
+#define VERSION "0.4"
#define ESC 27
#define TAB 9
#define MAX_LEN 2048
@@ -228,5 +228,6 @@
int dialog_textbox(char *title, char *file, int height, int width);
int dialog_menu(char *title, char *prompt, int height, int width, int menu_height, int item_no, char **items);
int dialog_checklist(char *title, char *prompt, int height, int width, int list_height, int item_no, char **items);
+int dialog_radiolist(char *title, char *prompt, int height, int width, int list_height, int item_no, char **items);
int dialog_inputbox(char *title, char *prompt, int height, int width);

diff -u --recursive --new-file dialog-slack-8-bit/src/inputbox.c dialog-0.4/src/inputbox.c
--- dialog-slack-8-bit/src/inputbox.c   Mon Mar 21 02:08:10 1994
+++ dialog-0.4/src/inputbox.c   Wed Jun  8 00:21:14 1994
@@ -49,6 +49,7 @@
  waddch(dialog, ACS_LTEE);
  for (i = 0; i < width-2; i++)
    waddch(dialog, ACS_HLINE);
+  wattrset(dialog, dialog_attr);
  waddch(dialog, ACS_RTEE);
  wmove(dialog, height-2, 1);
  for (i = 0; i < width-2; i++)
@@ -69,7 +70,7 @@
  getyx(dialog, y, x);
  box_y = y + 2;
  box_x = (width - box_width)/2;
-  draw_box(dialog, y+1, box_x-1, 3, box_width+2, inputbox_attr, inputbox_border_attr);
+  draw_box(dialog, y+1, box_x-1, 3, box_width+2, border_attr, dialog_attr);

  x = width/2-11;
  y = height-2;
diff -u --recursive --new-file dialog-slack-8-bit/src/menubox.c dialog-0.4/src/menubox.c
--- dialog-slack-8-bit/src/menubox.c    Sat Feb 12 02:53:53 1994
+++ dialog-0.4/src/menubox.c    Tue Jun  7 23:52:47 1994
@@ -56,6 +56,7 @@
  waddch(dialog, ACS_LTEE);
  for (i = 0; i < width-2; i++)
    waddch(dialog, ACS_HLINE);
+  wattrset(dialog, dialog_attr);
  waddch(dialog, ACS_RTEE);
  wmove(dialog, height-2, 1);
  for (i = 0; i < width-2; i++)
@@ -81,7 +82,7 @@
  keypad(menu, TRUE);

  /* draw a box around the menu items */
-  draw_box(dialog, box_y, box_x, menu_height+2, menu_width+2, menubox_attr, menubox_border_attr);
+  draw_box(dialog, box_y, box_x, menu_height+2, menu_width+2, menubox_border_attr, menubox_attr);

  tag_x = 0;
  item_x = 0;
@@ -154,7 +155,7 @@

            /* print the up/down arrows */
            wmove(dialog, box_y, box_x + tag_x + 1);
-            wattrset(dialog, scroll ? uarrow_attr : menubox_border_attr);
+            wattrset(dialog, scroll ? uarrow_attr : menubox_attr);
            waddch(dialog, scroll ? ACS_UARROW : ACS_HLINE);
            wmove(dialog, box_y, box_x + tag_x + 2);
            waddch(dialog, scroll ? '(' : ACS_HLINE);
diff -u --recursive --new-file dialog-slack-8-bit/src/msgbox.c dialog-0.4/src/msgbox.c
--- dialog-slack-8-bit/src/msgbox.c     Fri Feb 11 20:16:57 1994
+++ dialog-0.4/src/msgbox.c     Tue Jun  7 23:54:49 1994
@@ -52,7 +52,7 @@
    waddch(dialog, ' ');
  }
  wattrset(dialog, dialog_attr);
-  print_autowrap(dialog, prompt, width, 1, 3);
+  print_autowrap(dialog, prompt, width-2, 1, 2);

  if (pause) {
    wattrset(dialog, border_attr);
@@ -60,6 +60,7 @@
    waddch(dialog, ACS_LTEE);
    for (i = 0; i < width-2; i++)
      waddch(dialog, ACS_HLINE);
+    wattrset(dialog, dialog_attr);
    waddch(dialog, ACS_RTEE);
    wmove(dialog, height-2, 1);
    for (i = 0; i < width-2; i++)
diff -u --recursive --new-file dialog-slack-8-bit/src/radiolist.c dialog-0.4/src/radiolist.c
--- dialog-slack-8-bit/src/radiolist.c  Wed Jun  8 01:07:36 1994
+++ dialog-0.4/src/radiolist.c  Wed Jun  8 02:00:06 1994
@@ -0,0 +1,352 @@
+/*
+ *  radiolist.c -- implements the radiolist box
+ *
+ *  AUTHOR: Stuart Herbert - [email protected]
+ *   (from checklist.c by Savio Lam ([email protected]))
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version 2
+ *  of the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include "dialog.h"
+
+
+static void print_item(WINDOW *win, char *tag, char *item, int status, int choice, int selected);
+
+
+static int list_width, check_x, item_x;
+
+
+/*
+ * Display a dialog box with a list of options that can be turned on or off
+ */
+int dialog_radiolist(char *title, char *prompt, int height, int width, int list_height, int item_no, char **items)
+{
+  int i, x, y, cur_x, cur_y, box_x, box_y, key = 0, button = 0, choice = 0,
+      scroll = 0, max_choice, *status;
+  WINDOW *dialog, *list;
+
+  /* Allocate space for storing item on/off status */
+  if ((status = malloc(sizeof(int)*item_no)) == NULL) {
+    endwin();
+    fprintf(stderr, "\nCan't allocate memory in dialog_radiolist().\n");
+    exit(-1);
+  }
+  /* Initializes status */
+  for (i = 0; i < item_no; i++)
+    status[i] = !strcasecmp(items[i*3 + 2], "on");
+
+  max_choice = MIN(list_height, item_no);
+
+  /* center dialog box on screen */
+  x = (COLS - width)/2;
+  y = (LINES - height)/2;
+
+#ifdef HAVE_NCURSES
+  if (use_shadow)
+    draw_shadow(stdscr, y, x, height, width);
+#endif
+  dialog = newwin(height, width, y, x);
+  keypad(dialog, TRUE);
+
+  draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
+  wattrset(dialog, border_attr);
+  wmove(dialog, height-3, 0);
+  waddch(dialog, ACS_LTEE);
+  for (i = 0; i < width-2; i++)
+    waddch(dialog, ACS_HLINE);
+  wattrset(dialog, dialog_attr);
+  waddch(dialog, ACS_RTEE);
+  wmove(dialog, height-2, 1);
+  for (i = 0; i < width-2; i++)
+    waddch(dialog, ' ');
+
+  if (title != NULL) {
+    wattrset(dialog, title_attr);
+    wmove(dialog, 0, (width - strlen(title))/2 - 1);
+    waddch(dialog, ' ');
+    waddstr(dialog, title);
+    waddch(dialog, ' ');
+  }
+  wattrset(dialog, dialog_attr);
+  print_autowrap(dialog, prompt, width, 1, 3);
+
+  list_width = width-6;
+  getyx(dialog, cur_y, cur_x);
+  box_y = cur_y + 1;
+  box_x = (width - list_width)/2 - 1;
+
+  /* create new window for the list */
+  list = subwin(dialog, list_height, list_width, y + box_y + 1, x + box_x + 1);
+  keypad(list, TRUE);
+
+  /* draw a box around the list items */
+  draw_box(dialog, box_y, box_x, list_height+2, list_width+2, menubox_border_attr, menubox_attr);
+
+  check_x = 0;
+  item_x = 0;
+  /* Find length of longest item in order to center radiolist */
+  for (i = 0; i < item_no; i++) {
+    check_x = MAX(check_x, strlen(items[i*3]) + strlen(items[i*3 + 1]) + 6);
+    item_x = MAX(item_x, strlen(items[i*3]));
+  }
+  check_x = (list_width - check_x) / 2;
+  item_x = check_x + item_x + 6;
+
+  /* Print the list */
+  for (i = 0; i < max_choice; i++)
+    print_item(list, items[i*3], items[i*3 + 1], status[i], i, i == choice);
+  wnoutrefresh(list);
+
+  if (list_height < item_no) {
+    wattrset(dialog, darrow_attr);
+    wmove(dialog, box_y + list_height + 1, box_x + check_x + 5);
+    waddch(dialog, ACS_DARROW);
+    wmove(dialog, box_y + list_height + 1, box_x + check_x + 6);
+    waddstr(dialog, "(+)");
+  }
+
+  x = width/2-11;
+  y = height-2;
+  print_button(dialog, "Cancel", y, x+14, FALSE);
+  print_button(dialog, "  OK  ", y, x, TRUE);
+  wrefresh(dialog);
+
+  while (key != ESC) {
+    key = wgetch(dialog);
+    /* Check if key pressed matches first character of any item tag in list */
+    for (i = 0; i < max_choice; i++)
+      if (toupper(key) == toupper(items[(scroll+i)*3][0]))
+        break;
+
+    if (i < max_choice || (key >= '1' && key <= MIN('9', '0'+max_choice)) ||
+        key == KEY_UP || key == KEY_DOWN || key == ' ' ||
+        key == '+' || key == '-' ) {
+      if (key >= '1' && key <= MIN('9', '0'+max_choice))
+        i = key - '1';
+      else if (key == KEY_UP || key == '-') {
+        if (!choice) {
+          if (scroll) {
+#ifdef BROKEN_WSCRL
+    /* wscrl() in ncurses 1.8.1 seems to be broken, causing a segmentation
+       violation when scrolling windows of height = 4, so scrolling is not
+       used for now */
+            scroll--;
+            getyx(dialog, cur_y, cur_x);    /* Save cursor position */
+            /* Reprint list to scroll down */
+            for (i = 0; i < max_choice; i++)
+              print_item(list, items[(scroll+i)*3], items[(scroll+i)*3 + 1], status[scroll+i], i, i == choice);
+
+#else
+
+            /* Scroll list down */
+            getyx(dialog, cur_y, cur_x);    /* Save cursor position */
+            if (list_height > 1) {
+              /* De-highlight current first item before scrolling down */
+              print_item(list, items[scroll*3], items[scroll*3 + 1], status[scroll], 0, FALSE);
+              scrollok(list, TRUE);
+              wscrl(list, -1);
+              scrollok(list, FALSE);
+            }
+            scroll--;
+            print_item(list, items[scroll*3], items[scroll*3 + 1], status[scroll], 0, TRUE);
+#endif
+            wnoutrefresh(list);
+
+            /* print the up/down arrows */
+            wmove(dialog, box_y, box_x + check_x + 5);
+            wattrset(dialog, scroll ? uarrow_attr : menubox_attr);
+            waddch(dialog, scroll ? ACS_UARROW : ACS_HLINE);
+            wmove(dialog, box_y, box_x + check_x + 6);
+            waddch(dialog, scroll ? '(' : ACS_HLINE);
+            wmove(dialog, box_y, box_x + check_x + 7);
+            waddch(dialog, scroll ? '-' : ACS_HLINE);
+            wmove(dialog, box_y, box_x + check_x + 8);
+            waddch(dialog, scroll ? ')' : ACS_HLINE);
+            wattrset(dialog, darrow_attr);
+            wmove(dialog, box_y + list_height + 1, box_x + check_x + 5);
+            waddch(dialog, ACS_DARROW);
+            wmove(dialog, box_y + list_height + 1, box_x + check_x + 6);
+            waddch(dialog, '(');
+            wmove(dialog, box_y + list_height + 1, box_x + check_x + 7);
+            waddch(dialog, '+');
+            wmove(dialog, box_y + list_height + 1, box_x + check_x + 8);
+            waddch(dialog, ')');
+            wmove(dialog, cur_y, cur_x);  /* Restore cursor position */
+            wrefresh(dialog);
+          }
+          continue;    /* wait for another key press */
+        }
+        else
+          i = choice - 1;
+      }
+      else if (key == KEY_DOWN || key == '+') {
+        if (choice == max_choice - 1) {
+          if (scroll+choice < item_no-1) {
+#ifdef BROKEN_WSCRL
+    /* wscrl() in ncurses 1.8.1 seems to be broken, causing a segmentation
+       violation when scrolling windows of height = 4, so scrolling is not
+       used for now */
+            scroll++;
+            getyx(dialog, cur_y, cur_x);    /* Save cursor position */
+            /* Reprint list to scroll up */
+            for (i = 0; i < max_choice; i++)
+              print_item(list, items[(scroll+i)*3], items[(scroll+i)*3 + 1], status[scroll+i], i, i == choice);
+
+#else
+
+            /* Scroll list up */
+            getyx(dialog, cur_y, cur_x);    /* Save cursor position */
+            if (list_height > 1) {
+              /* De-highlight current last item before scrolling up */
+              print_item(list, items[(scroll+max_choice-1)*3], items[(scroll+max_choice-1)*3 + 1], status[scroll+max_choice-1], max_choice-1, FALSE);
+              scrollok(list, TRUE);
+              scroll(list);
+              scrollok(list, FALSE);
+            }
+            scroll++;
+            print_item(list, items[(scroll+max_choice-1)*3], items[(scroll+max_choice-1)*3 + 1], status[scroll+max_choice-1], max_choice-1, TRUE);
+#endif
+            wnoutrefresh(list);
+
+            /* print the up/down arrows */
+            wattrset(dialog, uarrow_attr);
+            wmove(dialog, box_y, box_x + check_x + 5);
+            waddch(dialog, ACS_UARROW);
+            wmove(dialog, box_y, box_x + check_x + 6);
+            waddstr(dialog, "(-)");
+            wmove(dialog, box_y + list_height + 1, box_x + check_x + 5);
+            wattrset(dialog, scroll+choice < item_no-1 ? darrow_attr : menubox_border_attr);
+            waddch(dialog, scroll+choice < item_no-1 ? ACS_DARROW : ACS_HLINE);
+            wmove(dialog, box_y + list_height + 1, box_x + check_x + 6);
+            waddch(dialog, scroll+choice < item_no-1 ? '(' : ACS_HLINE);
+            wmove(dialog, box_y + list_height + 1, box_x + check_x + 7);
+            waddch(dialog, scroll+choice < item_no-1 ? '+' : ACS_HLINE);
+            wmove(dialog, box_y + list_height + 1, box_x + check_x + 8);
+            waddch(dialog, scroll+choice < item_no-1 ? ')' : ACS_HLINE);
+            wmove(dialog, cur_y, cur_x);  /* Restore cursor position */
+            wrefresh(dialog);
+          }
+          continue;    /* wait for another key press */
+        }
+        else
+          i = choice + 1;
+      }
+      else if (key == ' ') {    /* Toggle item status */
+       if (!status[scroll+choice])
+       {
+         for (i=0; i<item_no; i++)
+           status[i]=0;
+         status[scroll+choice]=1;
+          getyx(dialog, cur_y, cur_x);    /* Save cursor position */
+          for (i = 0; i < max_choice; i++)
+            print_item(list, items[(scroll+i)*3], items[(scroll+i)*3 + 1], status[scroll+i], i, i == choice);
+          wnoutrefresh(list);
+          wmove(dialog, cur_y, cur_x);  /* Restore cursor to previous position */
+          wrefresh(dialog);
+       }
+        continue;    /* wait for another key press */
+      }
+
+      if (i != choice) {
+        /* De-highlight current item */
+        getyx(dialog, cur_y, cur_x);    /* Save cursor position */
+       print_item(list, items[(scroll+choice)*3], items[(scroll+choice)*3 +1], status[scroll+choice], choice, FALSE);
+        /* Highlight new item */
+        choice = i;
+        print_item(list, items[(scroll+choice)*3], items[(scroll+choice)*3 + 1], status[scroll+choice], choice, TRUE);
+        wnoutrefresh(list);
+        wmove(dialog, cur_y, cur_x);  /* Restore cursor to previous position */
+        wrefresh(dialog);
+      }
+      continue;    /* wait for another key press */
+    }
+
+    switch (key) {
+      case 'O':
+      case 'o':
+        delwin(dialog);
+        for (i = 0; i < item_no; i++)
+          if (status[i])
+            fprintf(stderr, "%s", items[i*3]);
+        free(status);
+        return 0;
+      case 'C':
+      case 'c':
+        delwin(dialog);
+        free(status);
+        return 1;
+      case TAB:
+      case KEY_LEFT:
+      case KEY_RIGHT:
+        if (!button) {
+          button = 1;    /* Indicates "Cancel" button is selected */
+          print_button(dialog, "  OK  ", y, x, FALSE);
+          print_button(dialog, "Cancel", y, x+14, TRUE);
+        }
+        else {
+          button = 0;    /* Indicates "OK" button is selected */
+          print_button(dialog, "Cancel", y, x+14, FALSE);
+          print_button(dialog, "  OK  ", y, x, TRUE);
+        }
+        wrefresh(dialog);
+        break;
+      case ' ':
+      case '\n':
+        delwin(dialog);
+        if (!button)
+          for (i = 0; i < item_no; i++)
+            if (status[i])
+              fprintf(stderr, items[i*3]);
+        free(status);
+        return button;
+      case ESC:
+        break;
+    }
+  }
+
+  delwin(dialog);
+  free(status);
+  return -1;    /* ESC pressed */
+}
+/* End of dialog_radiolist() */
+
+
+/*
+ * Print list item
+ */
+static void print_item(WINDOW *win, char *tag, char *item, int status, int choice, int selected)
+{
+  int i;
+
+  /* Clear 'residue' of last item */
+  wattrset(win, menubox_attr);
+  wmove(win, choice, 0);
+  for (i = 0; i < list_width; i++)
+    waddch(win, ' ');
+  wmove(win, choice, check_x);
+  wattrset(win, selected ? check_selected_attr : check_attr);
+  wprintw(win, "(%c)", status ? '*' : ' ');
+  wattrset(win, menubox_attr);
+  waddch(win, ' ');
+  wattrset(win, selected ? tag_key_selected_attr : tag_key_attr);
+  waddch(win, tag[0]);
+  wattrset(win, selected ? tag_selected_attr : tag_attr);
+  waddstr(win, tag + 1);
+  wmove(win, choice, item_x);
+  wattrset(win, selected ? item_selected_attr : item_attr);
+  waddstr(win, item);
+}
+/* End of print_item() */
diff -u --recursive --new-file dialog-slack-8-bit/src/textbox.c dialog-0.4/src/textbox.c
--- dialog-slack-8-bit/src/textbox.c    Fri Feb 11 20:16:57 1994
+++ dialog-0.4/src/textbox.c    Tue Jun  7 23:24:41 1994
@@ -105,6 +105,7 @@
  waddch(dialog, ACS_LTEE);
  for (i = 0; i < width-2; i++)
    waddch(dialog, ACS_HLINE);
+  wattrset(dialog, dialog_attr);
  waddch(dialog, ACS_RTEE);
  wmove(dialog, height-2, 1);
  for (i = 0; i < width-2; i++)
@@ -128,7 +129,7 @@
  wmove(dialog, cur_y, cur_x);    /* Restore cursor position */
  wrefresh(dialog);

-  while (key != ESC) {
+  while ((key != ESC) && (key != '\n')) {
    key = wgetch(dialog);
    switch (key) {
      case 'E':    /* Exit */
@@ -247,7 +248,6 @@
        break;
      case 'J':    /* Next line */
      case 'j':
-      case '\n':
      case KEY_DOWN:
        if (!end_reached) {
          begin_reached = 0;
@@ -541,7 +541,8 @@

  line = get_line();
  line += MIN(strlen(line),hscroll);    /* Scroll horizontally */
-  wmove(win, row, 1);    /* move cursor to correct line */
+  wmove(win, row, 0);    /* move cursor to correct line */
+  waddch(win,' ');
#ifdef HAVE_NCURSES
  waddnstr(win, line, MIN(strlen(line),width-2));
#else
@@ -551,7 +552,7 @@

  getyx(win, y, x);
  /* Clear 'residue' of previous line */
-  for (i = 0; i < width-2-x+1; i++)
+  for (i = 0; i < width-x; i++)
    waddch(win, ' ');
}
/* End of print_line() */
@@ -625,7 +626,7 @@
  if (use_shadow)
    draw_shadow(win, y, x, box_height, box_width);
#endif
-  draw_box(win, y, x, box_height, box_width, searchbox_attr, searchbox_border_attr);
+  draw_box(win, y, x, box_height, box_width, dialog_attr, searchbox_border_attr);
  wattrset(win, searchbox_title_attr);
  wmove(win, y, x+box_width/2-4);
  waddstr(win, " Search ");
diff -u --recursive --new-file dialog-slack-8-bit/src/yesno.c dialog-0.4/src/yesno.c
--- dialog-slack-8-bit/src/yesno.c      Fri Feb 11 20:16:57 1994
+++ dialog-0.4/src/yesno.c      Wed Jun  8 00:17:44 1994
@@ -47,6 +47,7 @@
  waddch(dialog, ACS_LTEE);
  for (i = 0; i < width-2; i++)
    waddch(dialog, ACS_HLINE);
+  wattrset(dialog, dialog_attr);
  waddch(dialog, ACS_RTEE);
  wmove(dialog, height-2, 1);
  for (i = 0; i < width-2; i++)