xref: /illumos-gate/usr/src/lib/libeti/menu/common/driver.c (revision 24da5b34f49324ed742a340010ed5bd3d4e06625)
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, &current);
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', &current);
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, &current);
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