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