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