]> git.ipfire.org Git - thirdparty/newt.git/blame - whiptcl.c
0.52.24
[thirdparty/newt.git] / whiptcl.c
CommitLineData
feef2cb5 1#include "config.h"
649a0152 2#include <string.h>
3#include <stdlib.h>
4
feef2cb5 5#include "nls.h"
649a0152 6#include "dialogboxes.h"
7#include "newt.h"
4e66d95a
ML
8#include <popt.h>
9#include <tcl.h>
649a0152 10
11enum mode { MODE_NONE, MODE_MSGBOX, MODE_YESNO, MODE_CHECKLIST, MODE_INPUTBOX,
6f481af2 12 MODE_RADIOLIST, MODE_MENU };
649a0152 13
6f481af2 14#define OPT_MSGBOX 1000
15#define OPT_CHECKLIST 1001
16#define OPT_YESNO 1002
17#define OPT_INPUTBOX 1003
18#define OPT_MENU 1005
19#define OPT_RADIOLIST 1006
649a0152 20
21static char * setBacktext(ClientData data, Tcl_Interp * interp,
4e66d95a 22 const char * name1, const char * name2, int flags);
649a0152 23static char * setHelptext(ClientData data, Tcl_Interp * interp,
4e66d95a 24 const char * name1, const char * name2, int flags);
649a0152 25static char * setFullButtons(ClientData data, Tcl_Interp * interp,
4e66d95a 26 const char * name1, const char * name2, int flags);
649a0152 27
28static int wtFinish(ClientData clientData, Tcl_Interp * interp, int argc,
4e66d95a 29 const char ** argv) {
649a0152 30 newtFinished();
31
32 return TCL_OK;
33}
34
35static int wtInit(ClientData clientData, Tcl_Interp * interp, int argc,
4e66d95a 36 const char ** argv) {
649a0152 37 newtInit();
38 newtCls();
39
40 newtPushHelpLine("");
41
42 Tcl_TraceVar(interp, "whiptcl_backtext",
6f481af2 43 TCL_TRACE_WRITES | TCL_GLOBAL_ONLY, setBacktext, NULL);
649a0152 44 Tcl_TraceVar(interp, "whiptcl_helpline",
6f481af2 45 TCL_TRACE_WRITES | TCL_TRACE_UNSETS | TCL_GLOBAL_ONLY,
46 setHelptext, NULL);
649a0152 47 Tcl_TraceVar(interp, "whiptcl_fullbuttons",
6f481af2 48 TCL_TRACE_WRITES | TCL_TRACE_UNSETS | TCL_GLOBAL_ONLY,
49 setFullButtons, NULL);
649a0152 50
51 Tcl_SetVar(interp, "whiptcl_helpline", "", TCL_GLOBAL_ONLY);
52 Tcl_SetVar(interp, "whiptcl_fullbuttons", "1", TCL_GLOBAL_ONLY);
53
54 return TCL_OK;
55}
56
57static int wtCmd(ClientData clientData, Tcl_Interp * interp, int argc,
b3ddfdd7 58 const char ** argv) {
649a0152 59 enum mode mode = MODE_NONE;
60 poptContext optCon;
61 int arg;
eb0a0545 62 const char * optArg;
63 const char * text;
64 const char * nextArg;
649a0152 65 char * end;
66 int height;
67 int width;
9c4eb622 68 int listHeight;
649a0152 69 int noCancel = 0;
70 int noItem = 0;
71 int scrollText = 0;
72 int rc = 0;
73 int flags = 0;
74 int defaultNo = 0;
f40f18ae
ML
75 char * result;
76 char ** selections, ** next;
649a0152 77 char * title = NULL;
feef2cb5 78 char *default_item = NULL;
649a0152 79 struct poptOption optionsTable[] = {
6f481af2 80 { "checklist", '\0', 0, 0, OPT_CHECKLIST },
81 { "defaultno", '\0', 0, &defaultNo, 0 },
82 { "inputbox", '\0', 0, 0, OPT_INPUTBOX },
83 { "menu", '\0', 0, 0, OPT_MENU },
84 { "msgbox", '\0', 0, 0, OPT_MSGBOX },
85 { "nocancel", '\0', 0, &noCancel, 0 },
86 { "noitem", '\0', 0, &noItem, 0 },
87 { "radiolist", '\0', 0, 0, OPT_RADIOLIST },
88 { "scrolltext", '\0', 0, &scrollText, 0 },
89 { "title", '\0', POPT_ARG_STRING, &title, 0 },
feef2cb5 90 { "default-item", '\0', POPT_ARG_STRING, &default_item, 0 },
6f481af2 91 { "yesno", '\0', 0, 0, OPT_YESNO },
92 { 0, 0, 0, 0, 0 }
649a0152 93 };
feef2cb5 94
1eda60fb 95#ifdef ENABLE_NLS
feef2cb5 96 setlocale (LC_ALL, "");
97 bindtextdomain (PACKAGE, LOCALEDIR);
98 textdomain (PACKAGE);
1eda60fb 99#endif
feef2cb5 100
649a0152 101 optCon = poptGetContext("whiptcl", argc, argv, optionsTable, 0);
102
103 while ((arg = poptGetNextOpt(optCon)) > 0) {
6f481af2 104 optArg = poptGetOptArg(optCon);
105
106 switch (arg) {
107 case OPT_MENU:
108 if (mode != MODE_NONE) rc = -1;
109 mode = MODE_MENU;
110 break;
111
112 case OPT_MSGBOX:
113 if (mode != MODE_NONE) rc = -1;
114 mode = MODE_MSGBOX;
115 break;
116
117 case OPT_RADIOLIST:
118 if (mode != MODE_NONE) rc = -1;
119 mode = MODE_RADIOLIST;
120 break;
121
122 case OPT_CHECKLIST:
123 if (mode != MODE_NONE) rc = -1;
124 mode = MODE_CHECKLIST;
125 break;
126
127 case OPT_YESNO:
128 if (mode != MODE_NONE) rc = -1;
129 mode = MODE_YESNO;
130 break;
131
132 case OPT_INPUTBOX:
133 if (mode != MODE_NONE) rc = -1;
134 mode = MODE_INPUTBOX;
135 break;
136 }
649a0152 137 }
138
139 if (arg < -1) {
6f481af2 140 /* this could buffer oveflow, bug we're not setuid so I don't care */
141 interp->result = malloc(200);
142 interp->freeProc = TCL_DYNAMIC;
143 sprintf(interp->result, "%s: %s\n",
144 poptBadOption(optCon, POPT_BADOPTION_NOALIAS),
145 poptStrerror(arg));
146
147 return TCL_ERROR;
649a0152 148 }
149
150 if (mode == MODE_NONE) {
6f481af2 151 interp->result = "no dialog mode was specified";
152 return TCL_ERROR;
649a0152 153 } else if (rc) {
6f481af2 154 interp->result = "multiple modes were specified";
155 return TCL_ERROR;
649a0152 156 }
157
158 if (!(text = poptGetArg(optCon))) {
6f481af2 159 interp->result = "missing text parameter";
160 return TCL_ERROR;
649a0152 161 }
162
163 if (!(nextArg = poptGetArg(optCon))) {
6f481af2 164 interp->result = "height missing";
165 return TCL_ERROR;
649a0152 166 }
167 height = strtoul(nextArg, &end, 10);
168 if (*end) {
6f481af2 169 interp->result = "height is not a number";
170 return TCL_ERROR;
649a0152 171 }
172
173 if (!(nextArg = poptGetArg(optCon))) {
6f481af2 174 interp->result = "width missing";
175 return TCL_ERROR;
649a0152 176 }
177 width = strtoul(nextArg, &end, 10);
178 if (*end) {
6f481af2 179 interp->result = "width is not a number";
180 return TCL_ERROR;
649a0152 181 }
182
9c4eb622
ML
183 switch (mode) {
184 case MODE_MENU:
185 case MODE_RADIOLIST:
186 case MODE_CHECKLIST:
187 if (!(nextArg = poptGetArg(optCon))) {
188 interp->result = "list-height missing";
189 return TCL_ERROR;
190 }
191 listHeight = strtoul(nextArg, &end, 10);
192 if (*end) {
193 interp->result = "list-height is not a number";
194 return TCL_ERROR;
195 }
196 break;
197 }
198
649a0152 199 width -= 2;
200 height -= 2;
201 newtOpenWindow((80 - width) / 2, (24 - height) / 2, width, height, title);
202
203 if (noCancel) flags |= FLAG_NOCANCEL;
204 if (noItem) flags |= FLAG_NOITEM;
205 if (scrollText) flags |= FLAG_SCROLL_TEXT;
206 if (defaultNo) flags |= FLAG_DEFAULT_NO;
207
208 switch (mode) {
209 case MODE_MSGBOX:
6f481af2 210 rc = messageBox(text, height, width, MSGBOX_MSG, flags);
211 break;
649a0152 212
213 case MODE_YESNO:
6f481af2 214 rc = messageBox(text, height, width, MSGBOX_YESNO, flags);
215 if (rc == DLG_OKAY)
216 interp->result = "yes";
217 else
218 interp->result = "no";
219 if (rc == DLG_ERROR) rc = 0;
220 break;
649a0152 221
222 case MODE_INPUTBOX:
6f481af2 223 rc = inputBox(text, height, width, optCon, flags, &result);
feef2cb5 224 if (rc ==DLG_OKAY) {
f40f18ae 225 interp->result = result;
6f481af2 226 interp->freeProc = TCL_DYNAMIC;
227 }
228 break;
649a0152 229
230 case MODE_MENU:
9c4eb622
ML
231 rc = listBox(text, height, width, listHeight, optCon, flags, default_item,
232 &result);
feef2cb5 233 if (rc==DLG_OKAY) {
f40f18ae 234 interp->result = result;
6f481af2 235 interp->freeProc = TCL_DYNAMIC;
236 }
237 break;
649a0152 238
239 case MODE_RADIOLIST:
9c4eb622
ML
240 rc = checkList(text, height, width, listHeight, optCon, 1, flags,
241 &selections);
feef2cb5 242 if (rc==DLG_OKAY) {
f40f18ae 243 interp->result = selections[0];
6f481af2 244 interp->freeProc = TCL_DYNAMIC;
f40f18ae
ML
245
246 free(selections);
6f481af2 247 }
248 break;
649a0152 249
250 case MODE_CHECKLIST:
9c4eb622
ML
251 rc = checkList(text, height, width, listHeight, optCon, 0, flags,
252 &selections);
649a0152 253
feef2cb5 254 if (rc==DLG_OKAY) {
6f481af2 255 for (next = selections; *next; next++)
256 Tcl_AppendElement(interp, *next);
649a0152 257
6f481af2 258 free(selections);
259 }
260 break;
649a0152 261
262 case MODE_NONE:
4e66d95a 263 ; /* this can't happen */
b3ddfdd7 264 break;
649a0152 265 }
266
267 newtPopWindow();
268
269 if (rc == DLG_ERROR) {
6f481af2 270 interp->result = "bad paramter for whiptcl dialog box";
271 return TCL_ERROR;
649a0152 272 }
273
274 Tcl_SetVar(interp, "whiptcl_canceled", (rc == DLG_CANCEL) ? "1" : "0",
6f481af2 275 0);
feef2cb5 276 Tcl_SetVar(interp, "whiptcl_escaped", (rc == DLG_ESCAPE) ? "1" : "0",
277 0);
649a0152 278
279 return TCL_OK;
280}
281
282static char * setBacktext(ClientData data, Tcl_Interp * interp,
4e66d95a 283 const char * name1, const char * name2, int flags) {
649a0152 284 static char blankLine[81] = " "
285 " ";
286
287 newtDrawRootText(0, 0, blankLine);
288 newtDrawRootText(0, 0, Tcl_GetVar(interp, "whiptcl_backtext",
6f481af2 289 TCL_GLOBAL_ONLY));
649a0152 290
291 return NULL;
292}
293
294static char * setHelptext(ClientData data, Tcl_Interp * interp,
4e66d95a
ML
295 const char * name1, const char * name2, int flags) {
296 const char * text = Tcl_GetVar(interp, "whiptcl_helpline", TCL_GLOBAL_ONLY);
649a0152 297
298 if (!text)
6f481af2 299 text = "";
649a0152 300 else if (!strlen(text))
6f481af2 301 text = NULL;
649a0152 302
303 newtPopHelpLine();
304 newtPushHelpLine(text);
305
306 return NULL;
307}
308
309static char * setFullButtons(ClientData data, Tcl_Interp * interp,
4e66d95a
ML
310 const char * name1, const char * name2, int flags) {
311 const char * val = Tcl_GetVar(interp, "whiptcl_fullbuttons", TCL_GLOBAL_ONLY);
649a0152 312 int rc;
313 int state;
314
315 if ((rc = Tcl_ExprBoolean(interp, val, &state))) {
6f481af2 316 Tcl_FreeResult(interp);
317 return "whiptcl_fullbuttons may only contain a boolean value";
649a0152 318 }
319
320 useFullButtons(state);
321
322 return NULL;
323}
324
325int Whiptcl_Init(Tcl_Interp * interp) {
326 Tcl_CreateCommand(interp, "whiptcl_finish", wtFinish, NULL, NULL);
327 Tcl_CreateCommand(interp, "whiptcl_init", wtInit, NULL, NULL);
b3ddfdd7 328 Tcl_CreateCommand(interp, "whiptcl_cmd", (Tcl_CmdProc *) wtCmd, NULL, NULL);
649a0152 329
4e66d95a
ML
330 Tcl_PkgProvide(interp, "Whip", VERSION);
331
649a0152 332 return TCL_OK;
333}