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