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
menu_driver(MENU * m,int c)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