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