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 /*LINTLIBRARY*/ 32 33 #include <sys/types.h> 34 #include "private.h" 35 36 int 37 menu_driver(MENU *m, int c) 38 { 39 int i, n; 40 int top; 41 ITEM *current; 42 int ret; 43 44 if (!m) { 45 return (E_BAD_ARGUMENT); 46 } 47 ret = E_OK; 48 if (Indriver(m)) { 49 return (E_BAD_STATE); 50 } 51 if (!Posted(m)) { 52 return (E_NOT_POSTED); 53 } 54 top = Top(m); 55 current = Current(m); 56 57 if (c > KEY_MAX && c < MAX_COMMAND) { 58 59 /* Clear the pattern buffer if not one of these requests */ 60 if (c != REQ_BACK_PATTERN && 61 c != REQ_NEXT_MATCH && 62 c != REQ_PREV_MATCH) { 63 Pindex(m) = 0; 64 IthPattern(m, 0) = '\0'; 65 } 66 67 switch (c) { 68 69 case REQ_RIGHT_ITEM: { 70 if (Right(current) == (ITEM *)0) { 71 ret = E_REQUEST_DENIED; 72 break; 73 } 74 current = Right(current); 75 break; 76 } 77 case REQ_LEFT_ITEM: { 78 if (Left(current) == (ITEM *)0) { 79 ret = E_REQUEST_DENIED; 80 break; 81 } 82 current = Left(current); 83 break; 84 } 85 case REQ_UP_ITEM: { 86 if (Up(current) == (ITEM *)0) { 87 ret = E_REQUEST_DENIED; 88 break; 89 } 90 current = Up(current); 91 break; 92 } 93 case REQ_DOWN_ITEM: { 94 if (Down(current) == (ITEM *)0) { 95 ret = E_REQUEST_DENIED; 96 break; 97 } 98 current = Down(current); 99 break; 100 } 101 case REQ_SCR_ULINE: { 102 if (--top < 0) { 103 ++top; 104 ret = E_REQUEST_DENIED; 105 break; 106 } 107 current = Up(current); 108 break; 109 } 110 case REQ_SCR_DLINE: { 111 if (++top > Rows(m) - Height(m)) { 112 --top; 113 ret = E_REQUEST_DENIED; 114 break; 115 } 116 current = Down(current); 117 break; 118 } 119 case REQ_SCR_UPAGE: { 120 n = min(Height(m), top); 121 if (n) { 122 top -= n; 123 for (i = n; i--; ) { 124 current = Up(current); 125 } 126 } else { 127 ret = E_REQUEST_DENIED; 128 break; 129 } 130 break; 131 } 132 case REQ_SCR_DPAGE: { 133 n = min(Height(m), Rows(m) - Height(m) - top); 134 if (n) { 135 top += n; 136 for (i = n; i--; ) { 137 current = Down(current); 138 } 139 } else { 140 ret = E_REQUEST_DENIED; 141 break; 142 } 143 break; 144 } 145 case REQ_FIRST_ITEM: { 146 current = IthItem(m, 0); 147 break; 148 } 149 case REQ_LAST_ITEM: { 150 current = IthItem(m, Nitems(m)-1); 151 break; 152 } 153 case REQ_NEXT_MATCH: { 154 if (IthPattern(m, 0) != '\0') { 155 ret = _match(m, '\0', ¤t); 156 } else { 157 if (Index(current)+1 >= Nitems(m)) { 158 current = IthItem(m, 0); 159 } else { 160 current = IthItem(m, Index(current)+1); 161 } 162 } 163 break; 164 } 165 case REQ_NEXT_ITEM: { 166 if (Index(current)+1 >= Nitems(m)) { 167 if (Cyclic(m)) { 168 current = IthItem(m, 0); 169 } else { 170 ret = E_REQUEST_DENIED; 171 } 172 } else { 173 current = IthItem(m, Index(current)+1); 174 } 175 break; 176 } 177 case REQ_PREV_MATCH: { 178 if (IthPattern(m, 0) != '\0') { 179 ret = _match(m, '\b', ¤t); 180 } else { 181 /* This differs from PREV_ITEM in that */ 182 /* it is cyclic */ 183 if (Index(current)-1 < 0) { 184 current = IthItem(m, Nitems(m)-1); 185 } else { 186 current = IthItem(m, Index(current)-1); 187 } 188 } 189 break; 190 } 191 case REQ_PREV_ITEM: { 192 if (Index(current)-1 < 0) { 193 if (Cyclic(m)) { 194 current = IthItem(m, Nitems(m)-1); 195 } else { 196 ret = E_REQUEST_DENIED; 197 } 198 } else { 199 current = IthItem(m, Index(current)-1); 200 } 201 break; 202 } 203 case REQ_TOGGLE_ITEM: { 204 if (!OneValue(m)) { 205 if (Selectable(Current(m))) { 206 Value(Current(m)) ^= TRUE; 207 _move_post_item(m, Current(m)); 208 _show(m); 209 } else { 210 ret = E_NOT_SELECTABLE; 211 } 212 } else { 213 ret = E_REQUEST_DENIED; 214 } 215 break; 216 } 217 case REQ_BACK_PATTERN: { 218 if (Pindex(m) > 0) { 219 Pindex(m) -= 1; 220 IthPattern(m, Pindex(m)) = '\0'; 221 _position_cursor(m); 222 } else { 223 ret = E_REQUEST_DENIED; 224 } 225 break; 226 } 227 case REQ_CLEAR_PATTERN: { 228 /* This was already done at the top */ 229 break; 230 } 231 default: { 232 ret = E_UNKNOWN_COMMAND; 233 } 234 } 235 } else { 236 if (c > 037 && c < 0177) { 237 /*LINTED [E_PASS_INT_TO_SMALL_INT]*/ 238 ret = _match(m, c, ¤t); 239 } else { 240 ret = E_UNKNOWN_COMMAND; 241 } 242 } 243 244 /* Verify the location of the top row */ 245 246 _chk_top(m, &top, current); 247 248 /* Go change the actual values of Top and Current and do init/term */ 249 250 _affect_change(m, top, current); 251 252 return (ret); 253 } 254