remove unmatched endif
[dragonfly.git] / release / sysinstall / dmenu.c
1 /*
2  * The new sysinstall program.
3  *
4  * This is probably the last attempt in the `sysinstall' line, the next
5  * generation being slated for what's essentially a complete rewrite.
6  *
7  * $FreeBSD: src/release/sysinstall/dmenu.c,v 1.44 2000/03/08 14:20:26 jkh Exp $
8  * $DragonFly: src/release/sysinstall/Attic/dmenu.c,v 1.2 2003/06/17 04:27:21 dillon Exp $
9  *
10  * Copyright (c) 1995
11  *      Jordan Hubbard.  All rights reserved.
12  *
13  * Redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions
15  * are met:
16  * 1. Redistributions of source code must retain the above copyright
17  *    notice, this list of conditions and the following disclaimer,
18  *    verbatim and that no modifications are made prior to this
19  *    point in the file.
20  * 2. Redistributions in binary form must reproduce the above copyright
21  *    notice, this list of conditions and the following disclaimer in the
22  *    documentation and/or other materials provided with the distribution.
23  *
24  * THIS SOFTWARE IS PROVIDED BY JORDAN HUBBARD ``AS IS'' AND
25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27  * ARE DISCLAIMED.  IN NO EVENT SHALL JORDAN HUBBARD OR HIS PETS BE LIABLE
28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30  * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION)
31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34  * SUCH DAMAGE.
35  *
36  */
37
38 #include "sysinstall.h"
39 #include <errno.h>
40
41 #define MAX_MENU                15
42
43 static Boolean exited;
44
45 int
46 dmenuDisplayFile(dialogMenuItem *tmp)
47 {
48     systemDisplayHelp((char *)tmp->data);
49     return DITEM_SUCCESS;
50 }
51
52 int
53 dmenuSubmenu(dialogMenuItem *tmp)
54 {
55     return (dmenuOpenSimple((DMenu *)(tmp->data), FALSE) ? DITEM_SUCCESS : DITEM_FAILURE);
56 }
57
58 int
59 dmenuSystemCommand(dialogMenuItem *self)
60 {
61     WINDOW *w = NULL;   /* Keep lint happy */
62
63     /* If aux is set, the command is known not to produce any screen-spoiling output */
64     if (!self->aux)
65         w = savescr();
66     systemExecute((char *)self->data);
67     if (!self->aux)
68         restorescr(w);
69     return DITEM_SUCCESS;
70 }
71
72 int
73 dmenuSystemCommandBox(dialogMenuItem *tmp)
74 {
75     WINDOW *w = savescr();
76     
77     use_helpfile(NULL);
78     use_helpline("Select OK to dismiss this dialog");
79     dialog_prgbox(tmp->title, (char *)tmp->data, 22, 76, 1, 1);
80     restorescr(w);
81     return DITEM_SUCCESS;
82 }
83
84 int
85 dmenuExit(dialogMenuItem *tmp)
86 {
87     exited = TRUE;
88     return DITEM_LEAVE_MENU;
89 }
90
91 int
92 dmenuSetVariable(dialogMenuItem *tmp)
93 {
94     variable_set((char *)tmp->data, *((char *)tmp->data) != '_');
95     return DITEM_SUCCESS;
96 }
97
98 int
99 dmenuSetVariables(dialogMenuItem *tmp)
100 {
101     char *cp1, *cp2;
102     char *copy = strdup((char *)tmp->data);
103
104     for (cp1 = copy; cp1 != NULL;) {
105         cp2 = index(cp1, ',');
106         if (cp2 != NULL) *cp2++ = '\0';
107         variable_set(cp1, *cp1 != '_');
108         cp1 = cp2;
109     }
110     free(copy);
111     return DITEM_SUCCESS;
112 }
113
114 int
115 dmenuSetKmapVariable(dialogMenuItem *tmp)
116 {
117     char *lang;
118     int err;
119
120     variable_set((char *)tmp->data, TRUE);
121     lang = variable_get(VAR_KEYMAP);
122     if (lang != NULL)
123     {
124         err = loadKeymap(lang);
125         if (err == -1)
126             msgConfirm("No appropriate keyboard map found, sorry.");
127         else if (err == -2)
128             msgConfirm("Error installing keyboard map, errno = %d.", errno);
129     }
130     return DITEM_SUCCESS;
131 }
132
133 int
134 dmenuToggleVariable(dialogMenuItem *tmp)
135 {
136     char *var, *cp;
137     int status;
138
139     if (!(var = strdup((char *)tmp->data))) {
140         msgConfirm("Incorrect data field for `%s'!", tmp->title);
141         return DITEM_FAILURE;
142     }
143     if (!(cp = index(var, '='))) {
144         msgConfirm("Data field for %s is not in var=value format!", tmp->title);
145         return DITEM_FAILURE;
146     }
147     status = variable_check(var);
148     *cp = '\0';
149     variable_set2(var, status ? "NO" : "YES", *var != '_');
150     free(var);
151     return DITEM_SUCCESS;
152 }
153
154 int
155 dmenuISetVariable(dialogMenuItem *tmp)
156 {
157     char *ans, *var;
158
159     if (!(var = (char *)tmp->data)) {
160         msgConfirm("Incorrect data field for `%s'!", tmp->title);
161         return DITEM_FAILURE;
162     }
163     ans = msgGetInput(variable_get(var), tmp->title, 1);
164     if (!ans)
165         return DITEM_FAILURE;
166     else if (!*ans)
167         variable_unset(var);
168     else
169         variable_set2(var, ans, *var != '_');
170     return DITEM_SUCCESS;
171 }
172
173 int
174 dmenuSetFlag(dialogMenuItem *tmp)
175 {
176     if (*((unsigned int *)tmp->data) & tmp->aux)
177         *((unsigned int *)tmp->data) &= ~tmp->aux;
178     else
179         *((unsigned int *)tmp->data) |= tmp->aux;
180     return DITEM_SUCCESS;
181 }
182
183 int
184 dmenuSetValue(dialogMenuItem *tmp)
185 {
186     *((unsigned int *)tmp->data) = tmp->aux;
187     return DITEM_SUCCESS;
188 }
189
190 /* Traverse menu but give user no control over positioning */
191 Boolean
192 dmenuOpenSimple(DMenu *menu, Boolean buttons)
193 {
194     int choice, scroll, curr, max;
195
196     choice = scroll = curr = max = 0;
197     return dmenuOpen(menu, &choice, &scroll, &curr, &max, buttons);
198 }
199
200 /* Work functions for the state hook */
201 int
202 dmenuFlagCheck(dialogMenuItem *item)
203 {
204     return (*((unsigned int *)item->data) & item->aux);
205 }
206
207 int
208 dmenuVarCheck(dialogMenuItem *item)
209 {
210     char *w;
211
212     w = (char *)item->aux;
213     if (!w)
214         w = (char *)item->data;
215     return variable_check(w);
216 }
217
218 int
219 dmenuVarsCheck(dialogMenuItem *item)
220 {
221     int res, init;
222     char *w, *cp1, *cp2;
223     char *copy;
224
225     w = (char *)item->aux;
226     if (!w)
227         w = (char *)item->data;
228     if (!w)
229         return FALSE;
230     
231     copy = strdup(w);
232     res = TRUE;
233     init = FALSE;
234     for (cp1 = copy; cp1 != NULL;) {
235         init = TRUE;
236         cp2 = index(cp1, ',');
237         if (cp2 != NULL)
238             *cp2++ = '\0';
239         res = res && variable_check(cp1);
240         cp1 = cp2;
241     }
242     free(copy);
243     return res && init;
244 }
245
246 int
247 dmenuRadioCheck(dialogMenuItem *item)
248 {
249     return (*((unsigned int *)item->data) == item->aux);
250 }
251
252 static int
253 menu_height(DMenu *menu, int n)
254 {
255     int max;
256     char *t;
257
258     max = MAX_MENU;
259     if (StatusLine > 24)
260         max += StatusLine - 24;
261     for (t = menu->prompt; *t; t++) {
262         if (*t == '\n')
263             --max;
264     }
265     return n > max ? max : n;
266 }
267
268 /* Traverse over an internal menu */
269 Boolean
270 dmenuOpen(DMenu *menu, int *choice, int *scroll, int *curr, int *max, Boolean buttons)
271 {
272     int n, rval = 0;
273     dialogMenuItem *items;
274
275     items = menu->items;
276     if (buttons)
277         items += 2;
278     /* Count up all the items */
279     for (n = 0; items[n].title; n++);
280
281     while (1) {
282         char buf[FILENAME_MAX];
283         WINDOW *w = savescr();
284
285         /* Any helpful hints, put 'em up! */
286         use_helpline(menu->helpline);
287         use_helpfile(systemHelpFile(menu->helpfile, buf));
288         dialog_clear_norefresh();
289         /* Pop up that dialog! */
290         if (menu->type & DMENU_NORMAL_TYPE)
291             rval = dialog_menu((u_char *)menu->title, (u_char *)menu->prompt, -1, -1,
292                                menu_height(menu, n), -n, items, (char *)buttons, choice, scroll);
293
294         else if (menu->type & DMENU_RADIO_TYPE)
295             rval = dialog_radiolist((u_char *)menu->title, (u_char *)menu->prompt, -1, -1,
296                                     menu_height(menu, n), -n, items, (char *)buttons);
297
298         else if (menu->type & DMENU_CHECKLIST_TYPE)
299             rval = dialog_checklist((u_char *)menu->title, (u_char *)menu->prompt, -1, -1,
300                                     menu_height(menu, n), -n, items, (char *)buttons);
301         else
302             msgFatal("Menu: `%s' is of an unknown type\n", menu->title);
303         if (exited) {
304             exited = FALSE;
305             restorescr(w);
306             return TRUE;
307         }
308         else if (rval) {
309             restorescr(w);
310             return FALSE;
311         }
312         else if (menu->type & DMENU_SELECTION_RETURNS) {
313             restorescr(w);
314             return TRUE;
315         }
316     }
317 }