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