-LIBS = -lslang -lm #-lefence
+LIBS = -lslang -lm -lc #-lefence
CFLAGS = $(RPM_OPT_FLAGS) -Wall
ifeq ($(RPM_OPT_FLAGS),)
-CFLAGS += -g
+CFLAGS += -g -O2
endif
VERSION = 0.9
-SONAME = 0
+SONAME = 0.9
-PROGS = test whiptail
+PROGS = test whiptail whiptcl.so
TESTOBJS = test.o
-NDIALOGOBJS = whiptail.o popt.o
+NDIALOGOBJS = whiptail.o dialogboxes.o popt.o
+WHIPTCLOBJS = whiptcl.o dialogboxes.o popt.o
LIBNEWT = libnewt.a
LIBNEWTSH = libnewt.so.$(VERSION)
LIBNEWTSONAME = libnewt.so.$(SONAME)
whiptail: $(NDIALOGOBJS) $(LIBNEWTSH)
gcc -g -o whiptail $(NDIALOGOBJS) $(LIBNEWTSH) $(LIBS)
+whiptcl.so: $(WHIPTCLOBJS) $(LIBNEWTSH)
+ gcc -shared -o whiptcl.so $(WHIPTCLOBJS) $(LIBNEWTSH) -ltcl -lslang -lm
+
$(LIBNEWT): $(LIBNEWT)($(LIBOBJS))
newt.o: newt.c Makefile
install-sh: sharedlib
install -m 755 $(LIBNEWTSH) $(libdir)
ln -sf $(LIBNEWTSH) $(libdir)/libnewt.so
+ install -m 755 whiptcl.so $(libdir)
/sbin/ldconfig
archive:
--- /dev/null
+/* simple dialog boxes, used by both whiptail and tcl dialog bindings */
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "dialogboxes.h"
+#include "newt.h"
+#include "popt.h"
+
+/* globals -- ick */
+int buttonHeight = 1;
+newtComponent (*makeButton)(int left, int right, char * text) =
+ newtCompactButton;
+
+static void addButtons(int height, int width, newtComponent form,
+ newtComponent * okay, newtComponent * cancel,
+ int flags) {
+ if (flags & FLAG_NOCANCEL) {
+ *okay = makeButton((width - 8) / 2, height - buttonHeight - 1, "Ok");
+ *cancel = NULL;
+ newtFormAddComponent(form, *okay);
+ } else {
+ *okay = makeButton((width - 18) / 3, height - buttonHeight - 1, "Ok");
+ *cancel = makeButton(((width - 18) / 3) * 2 + 9,
+ height - buttonHeight - 1, "Cancel");
+ newtFormAddComponents(form, *okay, *cancel, NULL);
+ }
+}
+
+static newtComponent textbox(int maxHeight, int width, char * text, int flags,
+ int * height) {
+ newtComponent tb;
+ int sFlag = (flags & FLAG_SCROLL_TEXT) ? NEWT_FLAG_SCROLL : 0;
+ int i;
+ char * buf, * src, * dst;
+
+ dst = buf = alloca(strlen(text) + 1);
+ src = text;
+ while (*src) {
+ if (*src == '\\' && *(src + 1) == 'n') {
+ src += 2;
+ *dst++ = '\n';
+ } else
+ *dst++ = *src++;
+ }
+ *dst++ = '\0';
+
+ tb = newtTextbox(1, 0, width, maxHeight, NEWT_FLAG_WRAP | sFlag);
+ newtTextboxSetText(tb, buf);
+
+ i = newtTextboxGetNumLines(tb);
+ if (i < maxHeight) {
+ newtTextboxSetHeight(tb, i);
+ maxHeight = i;
+ }
+
+ *height = maxHeight;
+
+ return tb;
+}
+
+int gauge(char * text, int height, int width, poptContext optCon, int fd,
+ int flags) {
+ newtComponent form, scale, tb;
+ int top;
+ char * arg, * end;
+ int val;
+ FILE * f = fdopen(fd, "r");
+ char buf[3000];
+ char buf3[50];
+ int i;
+
+ setlinebuf(f);
+
+ if (!(arg = poptGetArg(optCon))) return DLG_ERROR;
+ val = strtoul(arg, &end, 10);
+ if (*end) return DLG_ERROR;
+
+ tb = textbox(height - 3, width - 2, text, flags, &top);
+
+ form = newtForm(NULL, NULL, 0);
+
+ scale = newtScale(2, height - 2, width - 4, 100);
+ newtScaleSet(scale, val);
+
+ newtFormAddComponents(form, tb, scale, NULL);
+
+ newtDrawForm(form);
+ newtRefresh();
+
+ while (fgets(buf, sizeof(buf) - 1, f)) {
+ buf[strlen(buf) - 1] = '\0';
+
+ if (!strcmp(buf, "XXX")) {
+ fgets(buf3, sizeof(buf3) - 1, f);
+ buf3[strlen(buf3) - 1] = '\0';
+ arg = buf3;
+
+ i = 0;
+ while (fgets(buf + i, sizeof(buf) - 1 - i, f)) {
+ buf[strlen(buf) - 1] = '\0';
+ if (!strcmp(buf + i, "XXX")) {
+ *(buf + i) = '\0';
+ break;
+ }
+ i = strlen(buf);
+ }
+
+ newtTextboxSetText(tb, buf);
+ } else {
+ arg = buf;
+ }
+
+ val = strtoul(buf, &end, 10);
+ if (!*end) {
+ newtScaleSet(scale, val);
+ newtDrawForm(form);
+ newtRefresh();
+ }
+ }
+
+ return DLG_OKAY;
+}
+
+int inputBox(char * text, int height, int width, poptContext optCon,
+ int flags, char ** result) {
+ newtComponent form, entry, okay, cancel, answer, tb;
+ char * val;
+ int rc = DLG_OKAY;
+ int top;
+
+ val = poptGetArg(optCon);
+ tb = textbox(height - 3 - buttonHeight, width - 2,
+ text, flags, &top);
+
+ form = newtForm(NULL, NULL, 0);
+ entry = newtEntry(1, top + 1, val, width - 2, &val,
+ NEWT_FLAG_SCROLL | NEWT_FLAG_RETURNEXIT);
+
+ newtFormAddComponents(form, tb, entry, NULL);
+
+ addButtons(height, width, form, &okay, &cancel, flags);
+
+ answer = newtRunForm(form);
+ if (answer == cancel)
+ rc = DLG_CANCEL;
+
+ *result = val;
+
+ return rc;
+}
+
+int listBox(char * text, int height, int width, poptContext optCon,
+ int flags, char ** result) {
+ newtComponent form, okay, tb, answer, listBox;
+ newtComponent cancel = NULL;
+ char * arg, * end;
+ int listHeight;
+ int numItems = 0;
+ int allocedItems = 5;
+ int i, top;
+ int rc = DLG_OKAY;
+ char buf[80], format[20];
+ int maxTagWidth = 0;
+ int maxTextWidth = 0;
+ int noScrollFlag;
+ struct {
+ char * text;
+ char * tag;
+ } * itemInfo = malloc(allocedItems * sizeof(*itemInfo));
+
+ if (!(arg = poptGetArg(optCon))) return DLG_ERROR;
+ listHeight = strtoul(arg, &end, 10);
+ if (*end) return DLG_ERROR;
+
+ while ((arg = poptGetArg(optCon))) {
+ if (allocedItems == numItems) {
+ allocedItems += 5;
+ itemInfo = realloc(itemInfo, sizeof(*itemInfo) * allocedItems);
+ }
+
+ itemInfo[numItems].tag = arg;
+ if (!(arg = poptGetArg(optCon))) return DLG_ERROR;
+
+ if (!(flags & FLAG_NOITEM)) {
+ itemInfo[numItems].text = arg;
+ } else
+ itemInfo[numItems].text = "";
+
+ if (strlen(itemInfo[numItems].text) > maxTextWidth)
+ maxTextWidth = strlen(itemInfo[numItems].text);
+ if (strlen(itemInfo[numItems].tag) > maxTagWidth)
+ maxTagWidth = strlen(itemInfo[numItems].tag);
+
+ numItems++;
+ }
+
+ form = newtForm(NULL, NULL, 0);
+
+ tb = textbox(height - 4 - buttonHeight - listHeight, width - 2,
+ text, flags, &top);
+
+ if (listHeight >= numItems) {
+ noScrollFlag = NEWT_FLAG_NOSCROLL;
+ i = 0;
+ } else {
+ noScrollFlag = 0;
+ i = 2;
+ }
+
+ listBox = newtListbox(3 + ((width - 10 - maxTagWidth - maxTextWidth - i)
+ / 2),
+ top + 1, listHeight,
+ NEWT_FLAG_RETURNEXIT | noScrollFlag);
+
+ sprintf(format, "%%-%ds %%s", maxTagWidth);
+ for (i = 0; i < numItems; i++) {
+ sprintf(buf, format, itemInfo[i].tag, itemInfo[i].text);
+ newtListboxAddEntry(listBox, buf, (void *) i);
+ }
+
+ newtFormAddComponents(form, tb, listBox, NULL);
+
+ addButtons(height, width, form, &okay, &cancel, flags);
+
+ answer = newtRunForm(form);
+ if (answer == cancel)
+ rc = DLG_CANCEL;
+
+ i = (int) newtListboxGetCurrent(listBox);
+ *result = itemInfo[i].tag;
+
+ return rc;
+}
+
+int checkList(char * text, int height, int width, poptContext optCon,
+ int useRadio, int flags, char *** selections) {
+ newtComponent form, okay, tb, subform, answer;
+ newtComponent sb = NULL, cancel = NULL;
+ char * arg, * end;
+ int listHeight;
+ int numBoxes = 0;
+ int allocedBoxes = 5;
+ int i;
+ int numSelected;
+ int rc = DLG_OKAY;
+ char buf[80], format[20];
+ int maxWidth = 0;
+ int top;
+ struct {
+ char * text;
+ char * tag;
+ newtComponent comp;
+ } * cbInfo = malloc(allocedBoxes * sizeof(*cbInfo));
+ char * cbStates = malloc(allocedBoxes * sizeof(cbStates));
+
+ if (!(arg = poptGetArg(optCon))) return DLG_ERROR;
+ listHeight = strtoul(arg, &end, 10);
+ if (*end) return DLG_ERROR;
+
+ while ((arg = poptGetArg(optCon))) {
+ if (allocedBoxes == numBoxes) {
+ allocedBoxes += 5;
+ cbInfo = realloc(cbInfo, sizeof(*cbInfo) * allocedBoxes);
+ cbStates = realloc(cbStates, sizeof(*cbStates) * allocedBoxes);
+ }
+
+ cbInfo[numBoxes].tag = arg;
+ if (!(arg = poptGetArg(optCon))) return DLG_ERROR;
+
+ if (!(flags & FLAG_NOITEM)) {
+ cbInfo[numBoxes].text = arg;
+ if (!(arg = poptGetArg(optCon))) return DLG_ERROR;
+ } else
+ cbInfo[numBoxes].text = "";
+
+ if (!strcmp(arg, "1") || !strcasecmp(arg, "on") ||
+ !strcasecmp(arg, "yes"))
+ cbStates[numBoxes] = '*';
+ else
+ cbStates[numBoxes] = ' ';
+
+ if (strlen(cbInfo[numBoxes].tag) > maxWidth)
+ maxWidth = strlen(cbInfo[numBoxes].tag);
+
+ numBoxes++;
+ }
+
+ form = newtForm(NULL, NULL, 0);
+
+ tb = textbox(height - 3 - buttonHeight - listHeight, width - 2,
+ text, flags, &top);
+
+ if (listHeight < numBoxes) {
+ sb = newtVerticalScrollbar(width - 4,
+ top + 1,
+ listHeight, NEWT_COLORSET_CHECKBOX,
+ NEWT_COLORSET_ACTCHECKBOX);
+ newtFormAddComponent(form, sb);
+ }
+ subform = newtForm(sb, NULL, 0);
+ newtFormSetBackground(subform, NEWT_COLORSET_CHECKBOX);
+
+ sprintf(format, "%%-%ds %%s", maxWidth);
+ for (i = 0; i < numBoxes; i++) {
+ sprintf(buf, format, cbInfo[i].tag, cbInfo[i].text);
+
+ if (useRadio)
+ cbInfo[i].comp = newtRadiobutton(4, top + 1 + i, buf,
+ cbStates[i] != ' ',
+ i ? cbInfo[i - 1].comp : NULL);
+ else
+ cbInfo[i].comp = newtCheckbox(4, top + 1 + i, buf,
+ cbStates[i], NULL, cbStates + i);
+
+ newtFormAddComponent(subform, cbInfo[i].comp);
+ }
+
+ newtFormSetHeight(subform, listHeight);
+ newtFormSetWidth(subform, width - 10);
+
+ newtFormAddComponents(form, tb, subform, NULL);
+
+ addButtons(height, width, form, &okay, &cancel, flags);
+
+ answer = newtRunForm(form);
+ if (answer == cancel)
+ rc = DLG_CANCEL;
+
+ if (useRadio) {
+ answer = newtRadioGetCurrent(cbInfo[0].comp);
+ for (i = 0; i < numBoxes; i++)
+ if (cbInfo[i].comp == answer) {
+ *selections = malloc(sizeof(char *) * 2);
+ (*selections)[0] = cbInfo[i].tag;
+ (*selections)[1] = NULL;
+ break;
+ }
+ } else {
+ numSelected = 0;
+ for (i = 0; i < numBoxes; i++) {
+ if (cbStates[i] != ' ') numSelected++;
+ }
+
+ *selections = malloc(sizeof(char *) * (numSelected + 1));
+
+ numSelected = 0;
+ for (i = 0; i < numBoxes; i++) {
+ if (cbStates[i] != ' ')
+ (*selections)[numSelected++] = cbInfo[i].tag;
+ }
+
+ (*selections)[numSelected] = NULL;
+ }
+
+ return rc;
+}
+
+int messageBox(char * text, int height, int width, int type, int flags) {
+ newtComponent form, yes, tb, answer;
+ newtComponent no = NULL;
+ int tFlag = (flags & FLAG_SCROLL_TEXT) ? NEWT_FLAG_SCROLL : 0;
+
+ form = newtForm(NULL, NULL, 0);
+
+ tb = newtTextbox(1, 1, width - 2, height - 3 - buttonHeight,
+ NEWT_FLAG_WRAP | tFlag);
+ newtTextboxSetText(tb, text);
+
+ newtFormAddComponent(form, tb);
+
+ if (type == MSGBOX_MSG) {
+ yes = makeButton((width - 8) / 2, height - 1 - buttonHeight, "Ok");
+ newtFormAddComponent(form, yes);
+ } else {
+ yes = makeButton((width - 16) / 3, height - 1 - buttonHeight, "Yes");
+ no = makeButton(((width - 16) / 3) * 2 + 9, height - 1 - buttonHeight,
+ "No");
+ newtFormAddComponents(form, yes, no, NULL);
+
+ if (flags & FLAG_DEFAULT_NO)
+ newtFormSetCurrent(form, no);
+ }
+
+ newtRunForm(form);
+ answer = newtFormGetCurrent(form);
+
+ if (answer == no)
+ return DLG_CANCEL;
+
+ return DLG_OKAY;
+}
+
+void useFullButtons(int state) {
+ if (state) {
+ buttonHeight = 3;
+ makeButton = newtButton;
+ } else {
+ buttonHeight = 1;
+ makeButton = newtCompactButton;
+ }
+}
--- /dev/null
+#ifndef H_DIALOGBOXES
+#define H_DIALOGBOXES
+
+#include "popt.h"
+
+#define MSGBOX_MSG 0
+#define MSGBOX_YESNO 1
+
+#define FLAG_NOITEM (1 << 0)
+#define FLAG_NOCANCEL (1 << 1)
+#define FLAG_SCROLL_TEXT (1 << 2)
+#define FLAG_DEFAULT_NO (1 << 3)
+
+#define DLG_ERROR -1
+#define DLG_OKAY 0
+#define DLG_CANCEL 1
+
+int messageBox(char * text, int height, int width, int type, int flags);
+int checkList(char * text, int height, int width, poptContext optCon,
+ int useRadio, int flags, char *** selections);
+int listBox(char * text, int height, int width, poptContext optCon,
+ int flags, char ** result);
+int inputBox(char * text, int height, int width, poptContext optCon,
+ int flags, char ** result);
+int gauge(char * text, int height, int width, poptContext optCon, int fd,
+ int flags);
+void useFullButtons(int state);
+
+#endif
currentWindow->top = top;
currentWindow->width = width;
currentWindow->height = height;
- currentWindow->title = strdup(title);
+ currentWindow->title = title ? strdup(title) : NULL;
currentWindow->buffer = malloc(sizeof(short) * (width + 3) * (height + 3));
void newtEntrySetFlags(newtComponent co, int flags, enum newtFlagsSense sense);
newtComponent newtScale(int left, int top, int width, long long fullValue);
-void newtScaleSet(newtComponent co, long long amount);
+void newtScaleSet(newtComponent co, unsigned long long amount);
void newtComponentAddCallback(newtComponent co, newtCallback f, void * data);
return co;
}
-void newtScaleSet(newtComponent co, long long amount) {
+void newtScaleSet(newtComponent co, unsigned long long amount) {
struct scale * sc = co->data;
int newCharsSet;
#include <stdlib.h>
#include <unistd.h>
+#include "dialogboxes.h"
#include "newt.h"
#include "popt.h"
#define OPT_RADIOLIST 1006
#define OPT_GAUGE 1007
-#define MSGBOX_MSG 0
-#define MSGBOX_YESNO 1
-
-#define FLAG_NOITEM (1 << 0)
-#define FLAG_NOCANCEL (1 << 1)
-#define FLAG_SEPARATE_OUTPUT (1 << 2)
-#define FLAG_SCROLL_TEXT (1 << 3)
-#define FLAG_DEFAULT_NO (1 << 4)
-
static void usage(void) {
- fprintf(stderr, "ndialog: bad parametrs (see man dialog(1) for details)\n");
+ fprintf(stderr, "whiptail: bad parametrs (see man dialog(1) for details)\n");
exit(1);
}
-/* globals -- ick */
-int buttonHeight = 1;
-newtComponent (*makeButton)(int left, int right, char * text) =
- newtCompactButton;
-
-void addButtons(int height, int width, newtComponent form,
- newtComponent * okay, newtComponent * cancel, int flags) {
- if (flags & FLAG_NOCANCEL) {
- *okay = makeButton((width - 8) / 2, height - buttonHeight - 1, "Ok");
- *cancel = NULL;
- newtFormAddComponent(form, *okay);
- } else {
- *okay = makeButton((width - 18) / 3, height - buttonHeight - 1, "Ok");
- *cancel = makeButton(((width - 18) / 3) * 2 + 9,
- height - buttonHeight - 1, "Cancel");
- newtFormAddComponents(form, *okay, *cancel, NULL);
- }
-}
-
-newtComponent textbox(int maxHeight, int width, char * text, int flags,
- int * height) {
- newtComponent tb;
- int sFlag = (flags & FLAG_SCROLL_TEXT) ? NEWT_FLAG_SCROLL : 0;
- int i;
- char * buf, * src, * dst;
-
- dst = buf = alloca(strlen(text) + 1);
- src = text;
- while (*src) {
- if (*src == '\\' && *(src + 1) == 'n') {
- src += 2;
- *dst++ = '\n';
- } else
- *dst++ = *src++;
- }
- *dst++ = '\0';
-
- tb = newtTextbox(1, 0, width, maxHeight, NEWT_FLAG_WRAP | sFlag);
- newtTextboxSetText(tb, buf);
-
- i = newtTextboxGetNumLines(tb);
- if (i < maxHeight) {
- newtTextboxSetHeight(tb, i);
- maxHeight = i;
- }
-
- *height = maxHeight;
-
- return tb;
-}
-
-
-int gauge(char * text, int height, int width, poptContext optCon, int fd,
- int flags) {
- newtComponent form, scale, tb;
- int rc;
- int top;
- char * arg, * end;
- int val;
- FILE * f = fdopen(fd, "r");
- char buf[3000];
- char buf3[50];
- int i;
-
- setlinebuf(f);
-
- if (!(arg = poptGetArg(optCon))) usage();
- val = strtoul(arg, &end, 10);
- if (*end) usage();
-
- tb = textbox(height - 3, width - 2, text, flags, &top);
-
- form = newtForm(NULL, NULL, 0);
-
- scale = newtScale(2, height - 2, width - 4, 100);
- newtScaleSet(scale, val);
-
- newtFormAddComponents(form, tb, scale, NULL);
-
- newtDrawForm(form);
- newtRefresh();
-
- while (fgets(buf, sizeof(buf) - 1, f)) {
- buf[strlen(buf) - 1] = '\0';
-
- if (!strcmp(buf, "XXX")) {
- fgets(buf3, sizeof(buf3) - 1, f);
- buf3[strlen(buf3) - 1] = '\0';
- arg = buf3;
-
- i = 0;
- while (fgets(buf + i, sizeof(buf) - 1 - i, f)) {
- buf[strlen(buf) - 1] = '\0';
- if (!strcmp(buf + i, "XXX")) {
- *(buf + i) = '\0';
- break;
- }
- i = strlen(buf);
- }
-
- newtTextboxSetText(tb, buf);
- } else {
- arg = buf;
- }
-
- val = strtoul(buf, &end, 10);
- if (!*end) {
- newtScaleSet(scale, val);
- newtDrawForm(form);
- newtRefresh();
- }
- }
-
- return rc;
-}
-
-int inputBox(char * text, int height, int width, poptContext optCon,
- int flags) {
- newtComponent form, entry, okay, cancel, answer, tb;
- char * val;
- int rc = 0;
- int top;
-
- val = poptGetArg(optCon);
- tb = textbox(height - 3 - buttonHeight, width - 2,
- text, flags, &top);
-
- form = newtForm(NULL, NULL, 0);
- entry = newtEntry(1, top + 1, val, width - 2, &val,
- NEWT_FLAG_SCROLL | NEWT_FLAG_RETURNEXIT);
-
- newtFormAddComponents(form, tb, entry, NULL);
-
- addButtons(height, width, form, &okay, &cancel, flags);
-
- answer = newtRunForm(form);
- if (answer == cancel)
- rc = 1;
-
- fprintf(stderr, "%s", val);
-
- return rc;
-}
-
-int listBox(char * text, int height, int width, poptContext optCon,
- int flags) {
- newtComponent form, okay, tb, answer, listBox;
- newtComponent cancel = NULL;
- char * arg, * end;
- int listHeight;
- int numItems = 0;
- int allocedItems = 5;
- int i, top;
- int rc = 0;
- char buf[80], format[20];
- int maxTagWidth = 0;
- int maxTextWidth = 0;
- int noScrollFlag;
- struct {
- char * text;
- char * tag;
- } * itemInfo = malloc(allocedItems * sizeof(*itemInfo));
-
- if (!(arg = poptGetArg(optCon))) usage();
- listHeight = strtoul(arg, &end, 10);
- if (*end) usage();
-
- while ((arg = poptGetArg(optCon))) {
- if (allocedItems == numItems) {
- allocedItems += 5;
- itemInfo = realloc(itemInfo, sizeof(*itemInfo) * allocedItems);
- }
-
- itemInfo[numItems].tag = arg;
- if (!(arg = poptGetArg(optCon))) usage();
-
- if (!(flags & FLAG_NOITEM)) {
- itemInfo[numItems].text = arg;
- } else
- itemInfo[numItems].text = "";
-
- if (strlen(itemInfo[numItems].text) > maxTextWidth)
- maxTextWidth = strlen(itemInfo[numItems].text);
- if (strlen(itemInfo[numItems].tag) > maxTagWidth)
- maxTagWidth = strlen(itemInfo[numItems].tag);
-
- numItems++;
- }
-
- form = newtForm(NULL, NULL, 0);
-
- tb = textbox(height - 4 - buttonHeight - listHeight, width - 2,
- text, flags, &top);
-
- if (listHeight >= numItems) {
- noScrollFlag = NEWT_FLAG_NOSCROLL;
- i = 0;
- } else {
- i = 2;
- }
-
- listBox = newtListbox(3 + ((width - 10 - maxTagWidth - maxTextWidth - i)
- / 2),
- top + 1, listHeight,
- NEWT_FLAG_RETURNEXIT | noScrollFlag);
-
- sprintf(format, "%%-%ds %%s", maxTagWidth);
- for (i = 0; i < numItems; i++) {
- sprintf(buf, format, itemInfo[i].tag, itemInfo[i].text);
- newtListboxAddEntry(listBox, buf, (void *) i);
- }
-
- newtFormAddComponents(form, tb, listBox, NULL);
-
- addButtons(height, width, form, &okay, &cancel, flags);
-
- answer = newtRunForm(form);
- if (answer == cancel)
- rc = 1;
-
- i = (int) newtListboxGetCurrent(listBox);
- fprintf(stderr, "%s", itemInfo[i].tag);
-
- return rc;
-}
-
-int checkList(char * text, int height, int width, poptContext optCon,
- int useRadio, int flags) {
- newtComponent form, okay, tb, subform, answer;
- newtComponent sb = NULL, cancel = NULL;
- char * arg, * end;
- int listHeight;
- int numBoxes = 0;
- int allocedBoxes = 5;
- int i;
- int rc = 0;
- char buf[80], format[20];
- int maxWidth = 0;
- int needSpace = 0;
- int top;
- struct {
- char * text;
- char * tag;
- newtComponent comp;
- } * cbInfo = malloc(allocedBoxes * sizeof(*cbInfo));
- char * cbStates = malloc(allocedBoxes * sizeof(cbStates));
-
- if (!(arg = poptGetArg(optCon))) usage();
- listHeight = strtoul(arg, &end, 10);
- if (*end) usage();
-
- while ((arg = poptGetArg(optCon))) {
- if (allocedBoxes == numBoxes) {
- allocedBoxes += 5;
- cbInfo = realloc(cbInfo, sizeof(*cbInfo) * allocedBoxes);
- cbStates = realloc(cbStates, sizeof(*cbStates) * allocedBoxes);
- }
-
- cbInfo[numBoxes].tag = arg;
- if (!(arg = poptGetArg(optCon))) usage();
-
- if (!(flags & FLAG_NOITEM)) {
- cbInfo[numBoxes].text = arg;
- if (!(arg = poptGetArg(optCon))) usage();
- } else
- cbInfo[numBoxes].text = "";
-
- if (!strcmp(arg, "1") || !strcasecmp(arg, "on") ||
- !strcasecmp(arg, "yes"))
- cbStates[numBoxes] = '*';
- else
- cbStates[numBoxes] = ' ';
-
- if (strlen(cbInfo[numBoxes].tag) > maxWidth)
- maxWidth = strlen(cbInfo[numBoxes].tag);
-
- numBoxes++;
- }
-
- form = newtForm(NULL, NULL, 0);
-
- tb = textbox(height - 3 - buttonHeight - listHeight, width - 2,
- text, flags, &top);
-
- if (listHeight < numBoxes) {
- sb = newtVerticalScrollbar(width - 4,
- top + 1,
- listHeight, NEWT_COLORSET_CHECKBOX,
- NEWT_COLORSET_ACTCHECKBOX);
- newtFormAddComponent(form, sb);
- }
- subform = newtForm(sb, NULL, 0);
- newtFormSetBackground(subform, NEWT_COLORSET_CHECKBOX);
-
- sprintf(format, "%%-%ds %%s", maxWidth);
- for (i = 0; i < numBoxes; i++) {
- sprintf(buf, format, cbInfo[i].tag, cbInfo[i].text);
-
- if (useRadio)
- cbInfo[i].comp = newtRadiobutton(4, top + 1 + i, buf,
- cbStates[i] != ' ',
- i ? cbInfo[i - 1].comp : NULL);
- else
- cbInfo[i].comp = newtCheckbox(4, top + 1 + i, buf,
- cbStates[i], NULL, cbStates + i);
-
- newtFormAddComponent(subform, cbInfo[i].comp);
- }
-
- newtFormSetHeight(subform, listHeight);
- newtFormSetWidth(subform, width - 10);
-
- newtFormAddComponents(form, tb, subform, NULL);
-
- addButtons(height, width, form, &okay, &cancel, flags);
-
- answer = newtRunForm(form);
- if (answer == cancel)
- rc = 1;
-
- if (useRadio) {
- answer = newtRadioGetCurrent(cbInfo[0].comp);
- for (i = 0; i < numBoxes; i++)
- if (cbInfo[i].comp == answer) {
- fprintf(stderr, "%s", cbInfo[i].tag);
- break;
- }
- } else {
- for (i = 0; i < numBoxes; i++) {
- /* this should do proper quoting */
- if (cbStates[i] != ' ') {
- if (!(flags & FLAG_SEPARATE_OUTPUT)) {
- if (needSpace) putc(' ', stderr);
- fprintf(stderr, "\"%s\"", cbInfo[i].tag);
- needSpace = 1;
- } else {
- fprintf(stderr, "%s\n", cbInfo[i].tag);
- }
- }
- }
- }
-
- return rc;
-}
-
-int messageBox(char * text, int height, int width, int type, int flags) {
- newtComponent form, yes, tb, answer;
- newtComponent no = NULL;
- int tFlag = (flags & FLAG_SCROLL_TEXT) ? NEWT_FLAG_SCROLL : 0;
-
- form = newtForm(NULL, NULL, 0);
-
- tb = newtTextbox(1, 1, width - 2, height - 3 - buttonHeight,
- NEWT_FLAG_WRAP | tFlag);
- newtTextboxSetText(tb, text);
-
- newtFormAddComponent(form, tb);
-
- if (type == MSGBOX_MSG) {
- yes = makeButton((width - 8) / 2, height - 1 - buttonHeight, "Ok");
- newtFormAddComponent(form, yes);
- } else {
- yes = makeButton((width - 16) / 3, height - 1 - buttonHeight, "Yes");
- no = makeButton(((width - 16) / 3) * 2 + 9, height - 1 - buttonHeight,
- "No");
- newtFormAddComponents(form, yes, no, NULL);
-
- if (flags & FLAG_DEFAULT_NO)
- newtFormSetCurrent(form, no);
- }
-
- newtRunForm(form);
- answer = newtFormGetCurrent(form);
-
- if (answer == no)
- return 1;
-
- return 0;
-}
-
int main(int argc, char ** argv) {
enum mode mode = MODE_NONE;
poptContext optCon;
char * end;
int height;
int width;
- int fd;
+ int fd = -1;
+ int needSpace = 0;
int noCancel = 0;
int noItem = 0;
int clear = 0;
int flags = 0;
int defaultNo = 0;
int separateOutput = 0;
+ char * result;
+ char ** selections, ** next;
char * title = NULL;
char * backtitle = NULL;
struct poptOption optionsTable[] = {
{ 0, 0, 0, 0, 0 }
};
- optCon = poptGetContext("ndialog", argc, argv, optionsTable, 0);
+ optCon = poptGetContext("whiptail", argc, argv, optionsTable, 0);
while ((arg = poptGetNextOpt(optCon)) > 0) {
optArg = poptGetOptArg(optCon);
break;
case OPT_FULLBUTTONS:
- buttonHeight = 3;
- makeButton = newtButton;
+ useFullButtons(1);
break;
case OPT_YESNO:
if (noCancel) flags |= FLAG_NOCANCEL;
if (noItem) flags |= FLAG_NOITEM;
- if (separateOutput) flags |= FLAG_SEPARATE_OUTPUT;
if (scrollText) flags |= FLAG_SCROLL_TEXT;
if (defaultNo) flags |= FLAG_DEFAULT_NO;
break;
case MODE_INPUTBOX:
- rc = inputBox(text, height, width, optCon, flags);
+ rc = inputBox(text, height, width, optCon, flags, &result);
+ if (!rc) fprintf(stderr, "%s", result);
break;
case MODE_MENU:
- rc = listBox(text, height, width, optCon, flags);
+ rc = listBox(text, height, width, optCon, flags, &result);
+ if (!rc) fprintf(stderr, "%s", result);
break;
case MODE_RADIOLIST:
- rc = checkList(text, height, width, optCon, 1, flags);
+ rc = checkList(text, height, width, optCon, 1, flags, &selections);
+ if (!rc) {
+ fprintf(stderr, "%s", selections[0]);
+ free(selections);
+ }
break;
case MODE_CHECKLIST:
- rc = checkList(text, height, width, optCon, 0, flags);
+ rc = checkList(text, height, width, optCon, 0, flags, &selections);
+
+ if (!rc) {
+ for (next = selections; *next; next++) {
+ if (!separateOutput) {
+ if (needSpace) putc(' ', stderr);
+ fprintf(stderr, "\"%s\"", *next);
+ needSpace = 1;
+ } else {
+ fprintf(stderr, "%s\n", *next);
+ }
+ }
+
+ free(selections);
+ }
break;
case MODE_GAUGE:
usage();
}
+ if (rc == -1) usage();
+
if (clear)
newtPopWindow();
newtFinished();
--- /dev/null
+#include <string.h>
+#include <stdlib.h>
+
+#include "dialogboxes.h"
+#include "newt.h"
+#include "popt.h"
+#include "tcl.h"
+
+enum mode { MODE_NONE, MODE_MSGBOX, MODE_YESNO, MODE_CHECKLIST, MODE_INPUTBOX,
+ MODE_RADIOLIST, MODE_MENU };
+
+#define OPT_MSGBOX 1000
+#define OPT_CHECKLIST 1001
+#define OPT_YESNO 1002
+#define OPT_INPUTBOX 1003
+#define OPT_MENU 1005
+#define OPT_RADIOLIST 1006
+
+static char * setBacktext(ClientData data, Tcl_Interp * interp,
+ char * name1, char * name2, int flags);
+static char * setHelptext(ClientData data, Tcl_Interp * interp,
+ char * name1, char * name2, int flags);
+static char * setFullButtons(ClientData data, Tcl_Interp * interp,
+ char * name1, char * name2, int flags);
+
+static int wtFinish(ClientData clientData, Tcl_Interp * interp, int argc,
+ char ** argv) {
+ newtFinished();
+
+ return TCL_OK;
+}
+
+static int wtInit(ClientData clientData, Tcl_Interp * interp, int argc,
+ char ** argv) {
+ newtInit();
+ newtCls();
+
+ newtPushHelpLine("");
+
+ Tcl_TraceVar(interp, "whiptcl_backtext",
+ TCL_TRACE_WRITES | TCL_GLOBAL_ONLY, setBacktext, NULL);
+ Tcl_TraceVar(interp, "whiptcl_helpline",
+ TCL_TRACE_WRITES | TCL_TRACE_UNSETS | TCL_GLOBAL_ONLY,
+ setHelptext, NULL);
+ Tcl_TraceVar(interp, "whiptcl_fullbuttons",
+ TCL_TRACE_WRITES | TCL_TRACE_UNSETS | TCL_GLOBAL_ONLY,
+ setFullButtons, NULL);
+
+ Tcl_SetVar(interp, "whiptcl_helpline", "", TCL_GLOBAL_ONLY);
+ Tcl_SetVar(interp, "whiptcl_fullbuttons", "1", TCL_GLOBAL_ONLY);
+
+ return TCL_OK;
+}
+
+static int wtCmd(ClientData clientData, Tcl_Interp * interp, int argc,
+ char ** argv) {
+ enum mode mode = MODE_NONE;
+ poptContext optCon;
+ int arg;
+ char * optArg;
+ char * text;
+ char * nextArg;
+ char * end;
+ int height;
+ int width;
+ int noCancel = 0;
+ int noItem = 0;
+ int scrollText = 0;
+ int rc = 0;
+ int flags = 0;
+ int defaultNo = 0;
+ char * result;
+ char ** selections, ** next;
+ char * title = NULL;
+ struct poptOption optionsTable[] = {
+ { "checklist", '\0', 0, 0, OPT_CHECKLIST },
+ { "defaultno", '\0', 0, &defaultNo, 0 },
+ { "inputbox", '\0', 0, 0, OPT_INPUTBOX },
+ { "menu", '\0', 0, 0, OPT_MENU },
+ { "msgbox", '\0', 0, 0, OPT_MSGBOX },
+ { "nocancel", '\0', 0, &noCancel, 0 },
+ { "noitem", '\0', 0, &noItem, 0 },
+ { "radiolist", '\0', 0, 0, OPT_RADIOLIST },
+ { "scrolltext", '\0', 0, &scrollText, 0 },
+ { "title", '\0', POPT_ARG_STRING, &title, 0 },
+ { "yesno", '\0', 0, 0, OPT_YESNO },
+ { 0, 0, 0, 0, 0 }
+ };
+
+ optCon = poptGetContext("whiptcl", argc, argv, optionsTable, 0);
+
+ while ((arg = poptGetNextOpt(optCon)) > 0) {
+ optArg = poptGetOptArg(optCon);
+
+ switch (arg) {
+ case OPT_MENU:
+ if (mode != MODE_NONE) rc = -1;
+ mode = MODE_MENU;
+ break;
+
+ case OPT_MSGBOX:
+ if (mode != MODE_NONE) rc = -1;
+ mode = MODE_MSGBOX;
+ break;
+
+ case OPT_RADIOLIST:
+ if (mode != MODE_NONE) rc = -1;
+ mode = MODE_RADIOLIST;
+ break;
+
+ case OPT_CHECKLIST:
+ if (mode != MODE_NONE) rc = -1;
+ mode = MODE_CHECKLIST;
+ break;
+
+ case OPT_YESNO:
+ if (mode != MODE_NONE) rc = -1;
+ mode = MODE_YESNO;
+ break;
+
+ case OPT_INPUTBOX:
+ if (mode != MODE_NONE) rc = -1;
+ mode = MODE_INPUTBOX;
+ break;
+ }
+ }
+
+ if (arg < -1) {
+ /* this could buffer oveflow, bug we're not setuid so I don't care */
+ interp->result = malloc(200);
+ interp->freeProc = TCL_DYNAMIC;
+ sprintf(interp->result, "%s: %s\n",
+ poptBadOption(optCon, POPT_BADOPTION_NOALIAS),
+ poptStrerror(arg));
+
+ return TCL_ERROR;
+ }
+
+ if (mode == MODE_NONE) {
+ interp->result = "no dialog mode was specified";
+ return TCL_ERROR;
+ } else if (rc) {
+ interp->result = "multiple modes were specified";
+ return TCL_ERROR;
+ }
+
+ if (!(text = poptGetArg(optCon))) {
+ interp->result = "missing text parameter";
+ return TCL_ERROR;
+ }
+
+ if (!(nextArg = poptGetArg(optCon))) {
+ interp->result = "height missing";
+ return TCL_ERROR;
+ }
+ height = strtoul(nextArg, &end, 10);
+ if (*end) {
+ interp->result = "height is not a number";
+ return TCL_ERROR;
+ }
+
+ if (!(nextArg = poptGetArg(optCon))) {
+ interp->result = "width missing";
+ return TCL_ERROR;
+ }
+ width = strtoul(nextArg, &end, 10);
+ if (*end) {
+ interp->result = "width is not a number";
+ return TCL_ERROR;
+ }
+
+ width -= 2;
+ height -= 2;
+ newtOpenWindow((80 - width) / 2, (24 - height) / 2, width, height, title);
+
+ if (noCancel) flags |= FLAG_NOCANCEL;
+ if (noItem) flags |= FLAG_NOITEM;
+ if (scrollText) flags |= FLAG_SCROLL_TEXT;
+ if (defaultNo) flags |= FLAG_DEFAULT_NO;
+
+ switch (mode) {
+ case MODE_MSGBOX:
+ rc = messageBox(text, height, width, MSGBOX_MSG, flags);
+ break;
+
+ case MODE_YESNO:
+ rc = messageBox(text, height, width, MSGBOX_YESNO, flags);
+ if (rc == DLG_OKAY)
+ interp->result = "yes";
+ else
+ interp->result = "no";
+ if (rc == DLG_ERROR) rc = 0;
+ break;
+
+ case MODE_INPUTBOX:
+ rc = inputBox(text, height, width, optCon, flags, &result);
+ if (!rc) {
+ interp->result = strdup(result);
+ interp->freeProc = TCL_DYNAMIC;
+ }
+ break;
+
+ case MODE_MENU:
+ rc = listBox(text, height, width, optCon, flags, &result);
+ if (!rc) {
+ interp->result = strdup(result);
+ interp->freeProc = TCL_DYNAMIC;
+ }
+ break;
+
+ case MODE_RADIOLIST:
+ rc = checkList(text, height, width, optCon, 1, flags, &selections);
+ if (!rc) {
+ interp->result = strdup(selections[0]);
+ interp->freeProc = TCL_DYNAMIC;
+ }
+ break;
+
+ case MODE_CHECKLIST:
+ rc = checkList(text, height, width, optCon, 0, flags, &selections);
+
+ if (!rc) {
+ for (next = selections; *next; next++)
+ Tcl_AppendElement(interp, *next);
+
+ free(selections);
+ }
+ break;
+
+ case MODE_NONE:
+ /* this can't happen */
+ }
+
+ newtPopWindow();
+
+ if (rc == DLG_ERROR) {
+ interp->result = "bad paramter for whiptcl dialog box";
+ return TCL_ERROR;
+ }
+
+ Tcl_SetVar(interp, "whiptcl_canceled", (rc == DLG_CANCEL) ? "1" : "0",
+ 0);
+
+ return TCL_OK;
+}
+
+static char * setBacktext(ClientData data, Tcl_Interp * interp,
+ char * name1, char * name2, int flags) {
+ static char blankLine[81] = " "
+ " ";
+
+ newtDrawRootText(0, 0, blankLine);
+ newtDrawRootText(0, 0, Tcl_GetVar(interp, "whiptcl_backtext",
+ TCL_GLOBAL_ONLY));
+
+ return NULL;
+}
+
+static char * setHelptext(ClientData data, Tcl_Interp * interp,
+ char * name1, char * name2, int flags) {
+ char * text = Tcl_GetVar(interp, "whiptcl_helpline", TCL_GLOBAL_ONLY);
+
+ if (!text)
+ text = "";
+ else if (!strlen(text))
+ text = NULL;
+
+ newtPopHelpLine();
+ newtPushHelpLine(text);
+
+ return NULL;
+}
+
+static char * setFullButtons(ClientData data, Tcl_Interp * interp,
+ char * name1, char * name2, int flags) {
+ char * val = Tcl_GetVar(interp, "whiptcl_fullbuttons", TCL_GLOBAL_ONLY);
+ int rc;
+ int state;
+
+ if ((rc = Tcl_ExprBoolean(interp, val, &state))) {
+ Tcl_FreeResult(interp);
+ return "whiptcl_fullbuttons may only contain a boolean value";
+ }
+
+ useFullButtons(state);
+
+ return NULL;
+}
+
+int Whiptcl_Init(Tcl_Interp * interp) {
+ Tcl_CreateCommand(interp, "whiptcl_finish", wtFinish, NULL, NULL);
+ Tcl_CreateCommand(interp, "whiptcl_init", wtInit, NULL, NULL);
+ Tcl_CreateCommand(interp, "whiptcl_cmd", wtCmd, NULL, NULL);
+
+ return TCL_OK;
+}