#include "config.h" #include #include #include "nls.h" #include "dialogboxes.h" #include "newt.h" #include #include 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, const char * name1, const char * name2, int flags); static char * setHelptext(ClientData data, Tcl_Interp * interp, const char * name1, const char * name2, int flags); static char * setFullButtons(ClientData data, Tcl_Interp * interp, const char * name1, const char * name2, int flags); static int wtFinish(ClientData clientData, Tcl_Interp * interp, int argc, const char ** argv) { newtFinished(); return TCL_OK; } static int wtInit(ClientData clientData, Tcl_Interp * interp, int argc, const 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, const char ** argv) { enum mode mode = MODE_NONE; poptContext optCon; int arg; const char * optArg; const char * text; const 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; char *default_item = 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 }, { "default-item", '\0', POPT_ARG_STRING, &default_item, 0 }, { "yesno", '\0', 0, 0, OPT_YESNO }, { 0, 0, 0, 0, 0 } }; #ifdef ENABLE_NLS setlocale (LC_ALL, ""); bindtextdomain (PACKAGE, LOCALEDIR); textdomain (PACKAGE); #endif 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 ==DLG_OKAY) { interp->result = result; interp->freeProc = TCL_DYNAMIC; } break; case MODE_MENU: rc = listBox(text, height, width, optCon, flags, default_item, &result); if (rc==DLG_OKAY) { interp->result = result; interp->freeProc = TCL_DYNAMIC; } break; case MODE_RADIOLIST: rc = checkList(text, height, width, optCon, 1, flags, &selections); if (rc==DLG_OKAY) { interp->result = selections[0]; interp->freeProc = TCL_DYNAMIC; free(selections); } break; case MODE_CHECKLIST: rc = checkList(text, height, width, optCon, 0, flags, &selections); if (rc==DLG_OKAY) { for (next = selections; *next; next++) Tcl_AppendElement(interp, *next); free(selections); } break; case MODE_NONE: ; /* this can't happen */ break; } 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); Tcl_SetVar(interp, "whiptcl_escaped", (rc == DLG_ESCAPE) ? "1" : "0", 0); return TCL_OK; } static char * setBacktext(ClientData data, Tcl_Interp * interp, const char * name1, const 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, const char * name1, const char * name2, int flags) { const 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, const char * name1, const char * name2, int flags) { const 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", (Tcl_CmdProc *) wtCmd, NULL, NULL); Tcl_PkgProvide(interp, "Whip", VERSION); return TCL_OK; }