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 Microsystems, Inc.
28  *      All rights reserved.
29  */
30 
31 /*LINTLIBRARY*/
32 
33 #include <sys/types.h>
34 #include "utility.h"
35 
36 #define	first(f)	(f->field [Pmin(f, P(f))])
37 #define	last(f)		(f->field [Pmax(f, P(f))])
38 #define	sfirst(f)	(f->field [Smin(f, P(f))])
39 #define	slast(f)	(f->field [Smax(f, P(f))])
40 
41 #define	Active(f)	(Opt(f, O_ACTIVE) && Opt(f, O_VISIBLE))
42 
43 /* next - return next active field on page after f(user defined order) */
44 static FIELD *
next(FIELD * f)45 next(FIELD *f)
46 {
47 	FORM	*t	= f->form;
48 	FIELD	**p	= t->field + f->index;
49 	FIELD	**pmin	= t->field + Pmin(t, P(t));
50 	FIELD	**pmax	= t->field + Pmax(t, P(t));
51 
52 	do
53 		p = p == pmax ? pmin : p+1;
54 
55 	while ((!Active(*p)) && (*p != f));
56 
57 	return (*p);
58 }
59 
60 /* prev - return previous active field on page before f */
61 static FIELD *
prev(FIELD * f)62 prev(FIELD *f)
63 {
64 	FORM  *t	= f->form;
65 	FIELD **p	= t->field + f->index;
66 	FIELD **pmin	= t->field + Pmin(t, P(t));
67 	FIELD **pmax	= t->field + Pmax(t, P(t));
68 
69 	do
70 		p = p == pmin ? pmax : p-1;
71 
72 	while ((!Active(*p)) && (*p != f));
73 
74 	return (*p);
75 }
76 
77 /* snext - return next active field on page after f(sorted order) */
78 static FIELD *
snext(FIELD * f)79 snext(FIELD *f)
80 {
81 	FIELD *x = f;
82 
83 	do
84 		f = f->snext;
85 
86 	while ((!Active(f)) && (f != x));
87 
88 	return (f);
89 }
90 
91 /* sprev - return previous active field on page before f(sorted order) */
92 static FIELD *
sprev(FIELD * f)93 sprev(FIELD *f)
94 {
95 	FIELD *x = f;
96 
97 	do
98 		f = f->sprev;
99 
100 	while ((!Active(f)) && (f != x));
101 
102 	return (f);
103 }
104 
105 /* left - return active field on page left of f */
106 static FIELD *
left(FIELD * f)107 left(FIELD *f)
108 {
109 	int row = f->frow;
110 
111 	do
112 		f = sprev(f);
113 
114 	while (f->frow != row);
115 
116 	return (f);
117 }
118 
119 /* right - return active field on page right of f */
120 static FIELD *
right(FIELD * f)121 right(FIELD *f)
122 {
123 	int row = f->frow;
124 
125 	do
126 		f = snext(f);
127 
128 	while (f->frow != row);
129 
130 	return (f);
131 }
132 
133 /* up - return active field on page above f */
134 static FIELD *
up(FIELD * f)135 up(FIELD *f)
136 {
137 	int row = f->frow;
138 	int col = f->fcol;
139 
140 	do
141 		f = sprev(f);
142 
143 	while (f->frow == row && f->fcol != col);
144 
145 	if (f->frow != row) {
146 		row = f->frow;
147 
148 		while (f->frow == row && f->fcol > col)
149 			f = sprev(f);
150 
151 		if (f->frow != row)
152 			f = snext(f);
153 	}
154 	return (f);
155 }
156 
157 /* down - return active field on page below f */
158 static FIELD *
down(FIELD * f)159 down(FIELD *f)
160 {
161 	int row = f->frow;
162 	int col = f->fcol;
163 
164 	do
165 		f = snext(f);
166 
167 	while (f->frow == row && f->fcol != col);
168 
169 	if (f->frow != row) {
170 		row = f->frow;
171 
172 		while (f->frow == row && f->fcol < col)
173 			f = snext(f);
174 
175 		if (f ->frow != row)
176 			f = sprev(f);
177 	}
178 	return (f);
179 }
180 
181 	/*
182 	 *  _next_field
183 	 */
184 
185 int
_next_field(FORM * f)186 _next_field(FORM *f)
187 {
188 	return (_set_current_field(f, next(C(f))));
189 }
190 
191 int
_prev_field(FORM * f)192 _prev_field(FORM *f)
193 {
194 	return (_set_current_field(f, prev(C(f))));
195 }
196 
197 int
_first_field(FORM * f)198 _first_field(FORM *f)
199 {
200 	return (_set_current_field(f, next(last(f))));
201 }
202 
203 int
_last_field(FORM * f)204 _last_field(FORM *f)
205 {
206 	return (_set_current_field(f, prev(first(f))));
207 }
208 
209 int
_snext_field(FORM * f)210 _snext_field(FORM *f)
211 {
212 	return (_set_current_field(f, snext(C(f))));
213 }
214 
215 int
_sprev_field(FORM * f)216 _sprev_field(FORM *f)
217 {
218 	return (_set_current_field(f, sprev(C(f))));
219 }
220 
221 int
_sfirst_field(FORM * f)222 _sfirst_field(FORM *f)
223 {
224 	return (_set_current_field(f, snext(slast(f))));
225 }
226 
227 int
_slast_field(FORM * f)228 _slast_field(FORM *f)
229 {
230 	return (_set_current_field(f, sprev(sfirst(f))));
231 }
232 
233 int
_left_field(FORM * f)234 _left_field(FORM *f)
235 {
236 	return (_set_current_field(f, left(C(f))));
237 }
238 
239 int
_right_field(FORM * f)240 _right_field(FORM *f)
241 {
242 	return (_set_current_field(f, right(C(f))));
243 }
244 
245 int
_up_field(FORM * f)246 _up_field(FORM *f)
247 {
248 	return (_set_current_field(f, up(C(f))));
249 }
250 
251 int
_down_field(FORM * f)252 _down_field(FORM *f)
253 {
254 	return (_set_current_field(f, down(C(f))));
255 }
256 
257 FIELD *
_first_active(FORM * f)258 _first_active(FORM *f)
259 {
260 	return (next(last(f)));
261 }
262