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 37static Boolean exited; 38 39int 40dmenuDisplayFile(dialogMenuItem *tmp) 41{ 42 systemDisplayHelp((char *)tmp->data); 43 return DITEM_SUCCESS; 44} 45 46int 47dmenuSubmenu(dialogMenuItem *tmp) 48{ 49 return (dmenuOpenSimple((DMenu *)(tmp->data), FALSE) ? DITEM_SUCCESS : DITEM_FAILURE); 50} 51 52int 53dmenuSystemCommand(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 66int 67dmenuSystemCommandBox(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 78int 79dmenuExit(dialogMenuItem *tmp) 80{ 81 exited = TRUE; 82 return DITEM_LEAVE_MENU; 83} 84 85int 86dmenuSetVariable(dialogMenuItem *tmp) 87{ 88 variable_set((char *)tmp->data, *((char *)tmp->data) != '_'); 89 return DITEM_SUCCESS; 90} 91 92int 93dmenuSetVariables(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 108int 109dmenuToggleVariable(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 129int 130dmenuISetVariable(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 148int 149dmenuSetFlag(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 158int 159dmenuSetValue(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 */ 166Boolean 167dmenuOpenSimple(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 */ 176int 177dmenuFlagCheck(dialogMenuItem *item) 178{ 179 return (*((unsigned int *)item->data) & item->aux); 180} 181 182int 183dmenuVarCheck(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 193int 194dmenuVarsCheck(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 221int 222dmenuRadioCheck(dialogMenuItem *item) 223{ 224 return (*((long *)item->data) == item->aux); 225} 226 227static int 228menu_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 */ 244Boolean 245dmenuOpen(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} 296