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