1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* Copyright (c) 1988 AT&T */ 23 /* All Rights Reserved */ 24 25 26 /* 27 * Copyright (c) 1997, by Sun Mircrosystems, Inc. 28 * All rights reserved. 29 */ 30 31 #pragma ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.10 */ 32 33 /*LINTLIBRARY*/ 34 35 #include <sys/types.h> 36 #include "private.h" 37 38 int 39 menu_driver(MENU *m, int c) 40 { 41 int i, n; 42 int top; 43 ITEM *current; 44 int ret; 45 46 if (!m) { 47 return (E_BAD_ARGUMENT); 48 } 49 ret = E_OK; 50 if (Indriver(m)) { 51 return (E_BAD_STATE); 52 } 53 if (!Posted(m)) { 54 return (E_NOT_POSTED); 55 } 56 top = Top(m); 57 current = Current(m); 58 59 if (c > KEY_MAX && c < MAX_COMMAND) { 60 61 /* Clear the pattern buffer if not one of these requests */ 62 if (c != REQ_BACK_PATTERN && 63 c != REQ_NEXT_MATCH && 64 c != REQ_PREV_MATCH) { 65 Pindex(m) = 0; 66 IthPattern(m, 0) = '\0'; 67 } 68 69 switch (c) { 70 71 case REQ_RIGHT_ITEM: { 72 if (Right(current) == (ITEM *)0) { 73 ret = E_REQUEST_DENIED; 74 break; 75 } 76 current = Right(current); 77 break; 78 } 79 case REQ_LEFT_ITEM: { 80 if (Left(current) == (ITEM *)0) { 81 ret = E_REQUEST_DENIED; 82 break; 83 } 84 current = Left(current); 85 break; 86 } 87 case REQ_UP_ITEM: { 88 if (Up(current) == (ITEM *)0) { 89 ret = E_REQUEST_DENIED; 90 break; 91 } 92 current = Up(current); 93 break; 94 } 95 case REQ_DOWN_ITEM: { 96 if (Down(current) == (ITEM *)0) { 97 ret = E_REQUEST_DENIED; 98 break; 99 } 100 current = Down(current); 101 break; 102 } 103 case REQ_SCR_ULINE: { 104 if (--top < 0) { 105 ++top; 106 ret = E_REQUEST_DENIED; 107 break; 108 } 109 current = Up(current); 110 break; 111 } 112 case REQ_SCR_DLINE: { 113 if (++top > Rows(m) - Height(m)) { 114 --top; 115 ret = E_REQUEST_DENIED; 116 break; 117 } 118 current = Down(current); 119 break; 120 } 121 case REQ_SCR_UPAGE: { 122 n = min(Height(m), top); 123 if (n) { 124 top -= n; 125 for (i = n; i--; ) { 126 current = Up(current); 127 } 128 } else { 129 ret = E_REQUEST_DENIED; 130 break; 131 } 132 break; 133 } 134 case REQ_SCR_DPAGE: { 135 n = min(Height(m), Rows(m) - Height(m) - top); 136 if (n) { 137 top += n; 138 for (i = n; i--; ) { 139 current = Down(current); 140 } 141 } else { 142 ret = E_REQUEST_DENIED; 143 break; 144 } 145 break; 146 } 147 case REQ_FIRST_ITEM: { 148 current = IthItem(m, 0); 149 break; 150 } 151 case REQ_LAST_ITEM: { 152 current = IthItem(m, Nitems(m)-1); 153 break; 154 } 155 case REQ_NEXT_MATCH: { 156 if (IthPattern(m, 0) != NULL) { 157 ret = _match(m, NULL, ¤t); 158 } else { 159 if (Index(current)+1 >= Nitems(m)) { 160 current = IthItem(m, 0); 161 } else { 162 current = IthItem(m, Index(current)+1); 163 } 164 } 165 break; 166 } 167 case REQ_NEXT_ITEM: { 168 if (Index(current)+1 >= Nitems(m)) { 169 if (Cyclic(m)) { 170 current = IthItem(m, 0); 171 } else { 172 ret = E_REQUEST_DENIED; 173 } 174 } else { 175 current = IthItem(m, Index(current)+1); 176 } 177 break; 178 } 179 case REQ_PREV_MATCH: { 180 if (IthPattern(m, 0) != NULL) { 181 ret = _match(m, '\b', ¤t); 182 } else { 183 /* This differs from PREV_ITEM in that */ 184 /* it is cyclic */ 185 if (Index(current)-1 < 0) { 186 current = IthItem(m, Nitems(m)-1); 187 } else { 188 current = IthItem(m, Index(current)-1); 189 } 190 } 191 break; 192 } 193 case REQ_PREV_ITEM: { 194 if (Index(current)-1 < 0) { 195 if (Cyclic(m)) { 196 current = IthItem(m, Nitems(m)-1); 197 } else { 198 ret = E_REQUEST_DENIED; 199 } 200 } else { 201 current = IthItem(m, Index(current)-1); 202 } 203 break; 204 } 205 case REQ_TOGGLE_ITEM: { 206 if (!OneValue(m)) { 207 if (Selectable(Current(m))) { 208 Value(Current(m)) ^= TRUE; 209 _move_post_item(m, Current(m)); 210 _show(m); 211 } else { 212 ret = E_NOT_SELECTABLE; 213 } 214 } else { 215 ret = E_REQUEST_DENIED; 216 } 217 break; 218 } 219 case REQ_BACK_PATTERN: { 220 if (Pindex(m) > 0) { 221 Pindex(m) -= 1; 222 IthPattern(m, Pindex(m)) = '\0'; 223 _position_cursor(m); 224 } else { 225 ret = E_REQUEST_DENIED; 226 } 227 break; 228 } 229 case REQ_CLEAR_PATTERN: { 230 /* This was already done at the top */ 231 break; 232 } 233 default: { 234 ret = E_UNKNOWN_COMMAND; 235 } 236 } 237 } else { 238 if (c > 037 && c < 0177) { 239 /*LINTED [E_PASS_INT_TO_SMALL_INT]*/ 240 ret = _match(m, c, ¤t); 241 } else { 242 ret = E_UNKNOWN_COMMAND; 243 } 244 } 245 246 /* Verify the location of the top row */ 247 248 _chk_top(m, &top, current); 249 250 /* Go change the actual values of Top and Current and do init/term */ 251 252 _affect_change(m, top, current); 253 254 return (ret); 255 } 256