xref: /titanic_50/usr/src/lib/libeti/form/common/utility.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*	Copyright (c) 1988 AT&T	*/
23*7c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
24*7c478bd9Sstevel@tonic-gate 
25*7c478bd9Sstevel@tonic-gate 
26*7c478bd9Sstevel@tonic-gate /*
27*7c478bd9Sstevel@tonic-gate  *      Copyright (c) 1997, by Sun Microsystems, Inc.
28*7c478bd9Sstevel@tonic-gate  *      All rights reserved.
29*7c478bd9Sstevel@tonic-gate  */
30*7c478bd9Sstevel@tonic-gate 
31*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"	/* SVr4.0 1.7	*/
32*7c478bd9Sstevel@tonic-gate 
33*7c478bd9Sstevel@tonic-gate /*LINTLIBRARY*/
34*7c478bd9Sstevel@tonic-gate 
35*7c478bd9Sstevel@tonic-gate #include <sys/types.h>
36*7c478bd9Sstevel@tonic-gate #include "utility.h"
37*7c478bd9Sstevel@tonic-gate 
38*7c478bd9Sstevel@tonic-gate #define	Scrollable(f)		((f)->drows > (f)->rows || \
39*7c478bd9Sstevel@tonic-gate 					(f)->dcols > (f)->cols)
40*7c478bd9Sstevel@tonic-gate #define	Connected(f)		((f) -> form != (FORM *) 0)
41*7c478bd9Sstevel@tonic-gate #define	OnPage(f)		((f) -> page == P((f) -> form))
42*7c478bd9Sstevel@tonic-gate #define	Posted(f)		(Status((f) -> form, POSTED))
43*7c478bd9Sstevel@tonic-gate #define	Visible(f)		(Opt(f, O_VISIBLE) && OnPage(f))
44*7c478bd9Sstevel@tonic-gate #define	isCurrent(f)		((f) == C((f) -> form))
45*7c478bd9Sstevel@tonic-gate #define	Justified(f)		(Just(f) != NO_JUSTIFICATION && \
46*7c478bd9Sstevel@tonic-gate 				OneRow(f) && Opt(f, O_STATIC) && \
47*7c478bd9Sstevel@tonic-gate 				f->dcols == f->cols)
48*7c478bd9Sstevel@tonic-gate 
49*7c478bd9Sstevel@tonic-gate /* _data_beg - return ptr to first non-blank char in v[n] (v on failure) */
50*7c478bd9Sstevel@tonic-gate char *
_data_beg(char * v,int n)51*7c478bd9Sstevel@tonic-gate _data_beg(char *v, int n)
52*7c478bd9Sstevel@tonic-gate {
53*7c478bd9Sstevel@tonic-gate 	char *vend = v + n;
54*7c478bd9Sstevel@tonic-gate 	while (v < vend && *v == ' ') ++v;
55*7c478bd9Sstevel@tonic-gate 	return (v == vend ? v - n : v);
56*7c478bd9Sstevel@tonic-gate }
57*7c478bd9Sstevel@tonic-gate 
58*7c478bd9Sstevel@tonic-gate /*
59*7c478bd9Sstevel@tonic-gate  * _data_end - return ptr to char after last
60*7c478bd9Sstevel@tonic-gate  * non-blank char in v[n] (v on failure)
61*7c478bd9Sstevel@tonic-gate  */
62*7c478bd9Sstevel@tonic-gate char *
_data_end(char * v,int n)63*7c478bd9Sstevel@tonic-gate _data_end(char *v, int n)
64*7c478bd9Sstevel@tonic-gate {
65*7c478bd9Sstevel@tonic-gate 	char *vend = v + n;
66*7c478bd9Sstevel@tonic-gate 	while (vend > v && *(vend - 1) == ' ') --vend;
67*7c478bd9Sstevel@tonic-gate 	return (vend);
68*7c478bd9Sstevel@tonic-gate }
69*7c478bd9Sstevel@tonic-gate 
70*7c478bd9Sstevel@tonic-gate /* _whsp_beg - return ptr to first blank in v[n] (v on failure) */
71*7c478bd9Sstevel@tonic-gate char *
_whsp_beg(char * v,int n)72*7c478bd9Sstevel@tonic-gate _whsp_beg(char *v, int n)
73*7c478bd9Sstevel@tonic-gate {
74*7c478bd9Sstevel@tonic-gate 	char * vend = v + n;
75*7c478bd9Sstevel@tonic-gate 	while (v < vend && *v != ' ') ++v;
76*7c478bd9Sstevel@tonic-gate 	return (v == vend ? v - n : v);
77*7c478bd9Sstevel@tonic-gate }
78*7c478bd9Sstevel@tonic-gate 
79*7c478bd9Sstevel@tonic-gate /* _whsp_end - return ptr to char after last blank in v[n] (v on failure) */
80*7c478bd9Sstevel@tonic-gate char *
_whsp_end(char * v,int n)81*7c478bd9Sstevel@tonic-gate _whsp_end(char *v, int n)
82*7c478bd9Sstevel@tonic-gate {
83*7c478bd9Sstevel@tonic-gate 	char * vend = v + n;
84*7c478bd9Sstevel@tonic-gate 	while (vend > v && *(vend - 1) != ' ') --vend;
85*7c478bd9Sstevel@tonic-gate 	return (vend);
86*7c478bd9Sstevel@tonic-gate }
87*7c478bd9Sstevel@tonic-gate 
88*7c478bd9Sstevel@tonic-gate /*
89*7c478bd9Sstevel@tonic-gate  * _adjust_cursor - adjust cursor based on
90*7c478bd9Sstevel@tonic-gate  * offset of v from beginning of field buffer
91*7c478bd9Sstevel@tonic-gate  */
92*7c478bd9Sstevel@tonic-gate void
_adjust_cursor(FORM * f,char * v)93*7c478bd9Sstevel@tonic-gate _adjust_cursor(FORM *f, char *v)
94*7c478bd9Sstevel@tonic-gate {
95*7c478bd9Sstevel@tonic-gate 	int pos = (int) (v - Buf(C(f)));
96*7c478bd9Sstevel@tonic-gate 
97*7c478bd9Sstevel@tonic-gate 	Y(f) = pos / Xmax(f);
98*7c478bd9Sstevel@tonic-gate 	X(f) = pos - Y(f) * Xmax(f);
99*7c478bd9Sstevel@tonic-gate 
100*7c478bd9Sstevel@tonic-gate 	if (Y(f) >= Ymax(f))
101*7c478bd9Sstevel@tonic-gate 		Y(f) = 0;
102*7c478bd9Sstevel@tonic-gate }
103*7c478bd9Sstevel@tonic-gate 
104*7c478bd9Sstevel@tonic-gate /*
105*7c478bd9Sstevel@tonic-gate  * _buf_to_win - copy buffer to window(trailing
106*7c478bd9Sstevel@tonic-gate  * blanks on each line are not copied)
107*7c478bd9Sstevel@tonic-gate  */
108*7c478bd9Sstevel@tonic-gate void
_buf_to_win(FIELD * f,WINDOW * w)109*7c478bd9Sstevel@tonic-gate _buf_to_win(FIELD *f, WINDOW *w)
110*7c478bd9Sstevel@tonic-gate {
111*7c478bd9Sstevel@tonic-gate 	char *	v = Buf(f);
112*7c478bd9Sstevel@tonic-gate 	int	xmax, ymax, y, n;
113*7c478bd9Sstevel@tonic-gate 
114*7c478bd9Sstevel@tonic-gate 	getmaxyx(w, ymax, xmax);
115*7c478bd9Sstevel@tonic-gate 
116*7c478bd9Sstevel@tonic-gate 	for (y = 0; y < ymax; ++y) {
117*7c478bd9Sstevel@tonic-gate 		if ((n = (int) (_data_end(v, xmax) - v)) != 0) {
118*7c478bd9Sstevel@tonic-gate 			(void) wmove(w, y, 0);
119*7c478bd9Sstevel@tonic-gate 			(void) waddnstr(w, v, n);
120*7c478bd9Sstevel@tonic-gate 		}
121*7c478bd9Sstevel@tonic-gate 		v += xmax;
122*7c478bd9Sstevel@tonic-gate 	}
123*7c478bd9Sstevel@tonic-gate }
124*7c478bd9Sstevel@tonic-gate 
125*7c478bd9Sstevel@tonic-gate /* _win_to_buf - copy window to buffer */
126*7c478bd9Sstevel@tonic-gate void
_win_to_buf(WINDOW * w,FIELD * f)127*7c478bd9Sstevel@tonic-gate _win_to_buf(WINDOW *w, FIELD *f)
128*7c478bd9Sstevel@tonic-gate {
129*7c478bd9Sstevel@tonic-gate 	int		i;
130*7c478bd9Sstevel@tonic-gate 	int		size	= BufSize(f);
131*7c478bd9Sstevel@tonic-gate 	int		pad	= Pad(f);
132*7c478bd9Sstevel@tonic-gate 	char *		v	= Buf(f);
133*7c478bd9Sstevel@tonic-gate 
134*7c478bd9Sstevel@tonic-gate 	(void) wmove(w, 0, 0);
135*7c478bd9Sstevel@tonic-gate 	(void) winnstr(w, v, size);
136*7c478bd9Sstevel@tonic-gate 
137*7c478bd9Sstevel@tonic-gate 	if (pad != ' ')
138*7c478bd9Sstevel@tonic-gate 		for (i = 0; i < size; ++i, ++v)
139*7c478bd9Sstevel@tonic-gate 			if (*v == pad)
140*7c478bd9Sstevel@tonic-gate 				*v = ' '; /* replace pad char with blank */
141*7c478bd9Sstevel@tonic-gate }
142*7c478bd9Sstevel@tonic-gate 
143*7c478bd9Sstevel@tonic-gate /* _pos_form_cursor - move to cursor position and sync up cursor */
144*7c478bd9Sstevel@tonic-gate int
_pos_form_cursor(FORM * f)145*7c478bd9Sstevel@tonic-gate _pos_form_cursor(FORM *f)
146*7c478bd9Sstevel@tonic-gate {
147*7c478bd9Sstevel@tonic-gate 	WINDOW *	w = W(f);
148*7c478bd9Sstevel@tonic-gate 	FIELD *		c = C(f);
149*7c478bd9Sstevel@tonic-gate 
150*7c478bd9Sstevel@tonic-gate 	if (!w)
151*7c478bd9Sstevel@tonic-gate 		return (E_SYSTEM_ERROR);
152*7c478bd9Sstevel@tonic-gate 
153*7c478bd9Sstevel@tonic-gate 	(void) wmove(w, Y(f), X(f));
154*7c478bd9Sstevel@tonic-gate 
155*7c478bd9Sstevel@tonic-gate 	if (Opt(c, O_PUBLIC)) {
156*7c478bd9Sstevel@tonic-gate 		if (Scrollable(c)) {
157*7c478bd9Sstevel@tonic-gate 			int row, col;
158*7c478bd9Sstevel@tonic-gate 
159*7c478bd9Sstevel@tonic-gate 			if (OneRow(c)) {
160*7c478bd9Sstevel@tonic-gate 				row = c->frow;
161*7c478bd9Sstevel@tonic-gate 				col = c->fcol + X(f) - B(f);
162*7c478bd9Sstevel@tonic-gate 			} else {
163*7c478bd9Sstevel@tonic-gate 				row = c -> frow + Y(f) - T(f);
164*7c478bd9Sstevel@tonic-gate 				col = c -> fcol + X(f);
165*7c478bd9Sstevel@tonic-gate 			}
166*7c478bd9Sstevel@tonic-gate 
167*7c478bd9Sstevel@tonic-gate 			(void) wmove(Sub(f), row, col);
168*7c478bd9Sstevel@tonic-gate 			wcursyncup(Sub(f));
169*7c478bd9Sstevel@tonic-gate 		} else
170*7c478bd9Sstevel@tonic-gate 			wcursyncup(w);
171*7c478bd9Sstevel@tonic-gate 	} else {
172*7c478bd9Sstevel@tonic-gate 		(void) wmove(Sub(f), c -> frow, c -> fcol);
173*7c478bd9Sstevel@tonic-gate 		wcursyncup(Sub(f));
174*7c478bd9Sstevel@tonic-gate 	}
175*7c478bd9Sstevel@tonic-gate 	return (E_OK);
176*7c478bd9Sstevel@tonic-gate }
177*7c478bd9Sstevel@tonic-gate 
178*7c478bd9Sstevel@tonic-gate /* _update_current - sync up current field */
179*7c478bd9Sstevel@tonic-gate int
_update_current(FORM * f)180*7c478bd9Sstevel@tonic-gate _update_current(FORM *f)
181*7c478bd9Sstevel@tonic-gate {
182*7c478bd9Sstevel@tonic-gate 	WINDOW *	w = W(f);
183*7c478bd9Sstevel@tonic-gate 	FIELD *		c = C(f);
184*7c478bd9Sstevel@tonic-gate 
185*7c478bd9Sstevel@tonic-gate 	if (!w)
186*7c478bd9Sstevel@tonic-gate 		return (E_SYSTEM_ERROR);
187*7c478bd9Sstevel@tonic-gate 
188*7c478bd9Sstevel@tonic-gate 	if (Opt(c, O_PUBLIC)) {
189*7c478bd9Sstevel@tonic-gate 		if (Scrollable(c)) {
190*7c478bd9Sstevel@tonic-gate 			if (OneRow(c)) {
191*7c478bd9Sstevel@tonic-gate 				int xmax = B(f) + c->cols;
192*7c478bd9Sstevel@tonic-gate 
193*7c478bd9Sstevel@tonic-gate 				if (X(f) < B(f))
194*7c478bd9Sstevel@tonic-gate 					B(f) = X(f);
195*7c478bd9Sstevel@tonic-gate 				else if (X(f) >= xmax)
196*7c478bd9Sstevel@tonic-gate 					B(f) = X(f) - c->cols + 1;
197*7c478bd9Sstevel@tonic-gate 
198*7c478bd9Sstevel@tonic-gate 				(void) copywin(w, Sub(f), 0, B(f), c->frow,
199*7c478bd9Sstevel@tonic-gate 				    c->fcol, c->frow, c->fcol + c->cols - 1,
200*7c478bd9Sstevel@tonic-gate 				    FALSE);
201*7c478bd9Sstevel@tonic-gate 
202*7c478bd9Sstevel@tonic-gate 			} else {
203*7c478bd9Sstevel@tonic-gate 				int	ymax = T(f) + c -> rows;
204*7c478bd9Sstevel@tonic-gate 				int	ys, ye;
205*7c478bd9Sstevel@tonic-gate 
206*7c478bd9Sstevel@tonic-gate 				if (Y(f) < T(f)) {
207*7c478bd9Sstevel@tonic-gate 					T(f) = Y(f);
208*7c478bd9Sstevel@tonic-gate 					Set(c, TOP_CHG);
209*7c478bd9Sstevel@tonic-gate 				}
210*7c478bd9Sstevel@tonic-gate 				if (Y(f) >= ymax) {
211*7c478bd9Sstevel@tonic-gate 					T(f) = Y(f) - c -> rows + 1;
212*7c478bd9Sstevel@tonic-gate 					Set(c, TOP_CHG);
213*7c478bd9Sstevel@tonic-gate 				}
214*7c478bd9Sstevel@tonic-gate 				if (Status(c, TOP_CHG)) {
215*7c478bd9Sstevel@tonic-gate 					ys = T(f);
216*7c478bd9Sstevel@tonic-gate 					ye = ys + c -> rows;
217*7c478bd9Sstevel@tonic-gate 					Clr(c, TOP_CHG);
218*7c478bd9Sstevel@tonic-gate 				} else {
219*7c478bd9Sstevel@tonic-gate 	/* intersect changed lines with visible lines */
220*7c478bd9Sstevel@tonic-gate 					for (ys = T(f); ys < ymax; ++ys)
221*7c478bd9Sstevel@tonic-gate 						if (is_linetouched(w, ys))
222*7c478bd9Sstevel@tonic-gate 							break;
223*7c478bd9Sstevel@tonic-gate 
224*7c478bd9Sstevel@tonic-gate 					for (ye = ys; ye < ymax; ++ye)
225*7c478bd9Sstevel@tonic-gate 						if (! is_linetouched(w, ye))
226*7c478bd9Sstevel@tonic-gate 							break;
227*7c478bd9Sstevel@tonic-gate 				}
228*7c478bd9Sstevel@tonic-gate 				if (ye - ys) {
229*7c478bd9Sstevel@tonic-gate 					(void) copywin(w, Sub(f), ys, 0,
230*7c478bd9Sstevel@tonic-gate 					    c -> frow + ys - T(f), c -> fcol,
231*7c478bd9Sstevel@tonic-gate 					    c -> frow + ye - T(f) - 1,
232*7c478bd9Sstevel@tonic-gate 					    c -> fcol + c -> cols - 1, FALSE);
233*7c478bd9Sstevel@tonic-gate 				}
234*7c478bd9Sstevel@tonic-gate 			}
235*7c478bd9Sstevel@tonic-gate 			wsyncup(Sub(f));
236*7c478bd9Sstevel@tonic-gate 		} else
237*7c478bd9Sstevel@tonic-gate 			wsyncup(w);
238*7c478bd9Sstevel@tonic-gate 	}
239*7c478bd9Sstevel@tonic-gate 	(void) untouchwin(w);
240*7c478bd9Sstevel@tonic-gate 	return (_pos_form_cursor(f));
241*7c478bd9Sstevel@tonic-gate }
242*7c478bd9Sstevel@tonic-gate 
243*7c478bd9Sstevel@tonic-gate /* justify - justify field f in window w as given by Just(f) */
244*7c478bd9Sstevel@tonic-gate static void
justify(FIELD * f,WINDOW * w)245*7c478bd9Sstevel@tonic-gate justify(FIELD *f, WINDOW *w)
246*7c478bd9Sstevel@tonic-gate {
247*7c478bd9Sstevel@tonic-gate 	char *	v	= _data_beg(Buf(f), BufSize(f));
248*7c478bd9Sstevel@tonic-gate 	char *	vend	= _data_end(Buf(f), BufSize(f));
249*7c478bd9Sstevel@tonic-gate 	int	n	= (int) (vend - v);
250*7c478bd9Sstevel@tonic-gate 	int	x	= 0;
251*7c478bd9Sstevel@tonic-gate 
252*7c478bd9Sstevel@tonic-gate 	if (n) {
253*7c478bd9Sstevel@tonic-gate 		switch (Just(f)) {
254*7c478bd9Sstevel@tonic-gate 			case JUSTIFY_LEFT:
255*7c478bd9Sstevel@tonic-gate 				break;
256*7c478bd9Sstevel@tonic-gate 			case JUSTIFY_CENTER:
257*7c478bd9Sstevel@tonic-gate 				x = (f -> cols - n) / 2;
258*7c478bd9Sstevel@tonic-gate 				break;
259*7c478bd9Sstevel@tonic-gate 			case JUSTIFY_RIGHT:
260*7c478bd9Sstevel@tonic-gate 				x = f -> cols - n;
261*7c478bd9Sstevel@tonic-gate 				break;
262*7c478bd9Sstevel@tonic-gate 		}
263*7c478bd9Sstevel@tonic-gate 		(void) wmove(w, 0, x);
264*7c478bd9Sstevel@tonic-gate 		(void) waddnstr(w, v, n);
265*7c478bd9Sstevel@tonic-gate 	}
266*7c478bd9Sstevel@tonic-gate }
267*7c478bd9Sstevel@tonic-gate 
268*7c478bd9Sstevel@tonic-gate /* unjustify - left justify field f in window w for editing */
269*7c478bd9Sstevel@tonic-gate static void
unjustify(FIELD * f,WINDOW * w)270*7c478bd9Sstevel@tonic-gate unjustify(FIELD *f, WINDOW *w)
271*7c478bd9Sstevel@tonic-gate {
272*7c478bd9Sstevel@tonic-gate 	char *	v	= _data_beg(Buf(f), BufSize(f));
273*7c478bd9Sstevel@tonic-gate 	char *	vend	= _data_end(Buf(f), BufSize(f));
274*7c478bd9Sstevel@tonic-gate 	int	n	= (int) (vend - v);
275*7c478bd9Sstevel@tonic-gate 
276*7c478bd9Sstevel@tonic-gate 	if (n) {
277*7c478bd9Sstevel@tonic-gate 		(void) wmove(w, 0, 0);
278*7c478bd9Sstevel@tonic-gate 		(void) waddnstr(w, v, n);
279*7c478bd9Sstevel@tonic-gate 	}
280*7c478bd9Sstevel@tonic-gate }
281*7c478bd9Sstevel@tonic-gate 
282*7c478bd9Sstevel@tonic-gate /* _sync_buffer - sync current field with characters in window */
283*7c478bd9Sstevel@tonic-gate void
_sync_buffer(FORM * f)284*7c478bd9Sstevel@tonic-gate _sync_buffer(FORM *f)
285*7c478bd9Sstevel@tonic-gate {
286*7c478bd9Sstevel@tonic-gate 	if (Status(f, WIN_CHG)) {
287*7c478bd9Sstevel@tonic-gate 		Clr(f, WIN_CHG);
288*7c478bd9Sstevel@tonic-gate 		Set(f, BUF_CHG);
289*7c478bd9Sstevel@tonic-gate 		_win_to_buf(W(f), C(f));
290*7c478bd9Sstevel@tonic-gate 		(void) wmove(W(f), Y(f), X(f));
291*7c478bd9Sstevel@tonic-gate 	}
292*7c478bd9Sstevel@tonic-gate }
293*7c478bd9Sstevel@tonic-gate 
294*7c478bd9Sstevel@tonic-gate /* _sync_linked - sync fields linked to field f */
295*7c478bd9Sstevel@tonic-gate int
_sync_linked(FIELD * f)296*7c478bd9Sstevel@tonic-gate _sync_linked(FIELD *f)
297*7c478bd9Sstevel@tonic-gate {
298*7c478bd9Sstevel@tonic-gate 	FIELD *		p = f -> link;
299*7c478bd9Sstevel@tonic-gate 	int		err = 0;
300*7c478bd9Sstevel@tonic-gate 
301*7c478bd9Sstevel@tonic-gate 	while (p != f) {
302*7c478bd9Sstevel@tonic-gate 		if (_sync_field(p) != E_OK)
303*7c478bd9Sstevel@tonic-gate 			++err;
304*7c478bd9Sstevel@tonic-gate 		p = p -> link;
305*7c478bd9Sstevel@tonic-gate 	}
306*7c478bd9Sstevel@tonic-gate 	return (err ? E_SYSTEM_ERROR : E_OK);
307*7c478bd9Sstevel@tonic-gate }
308*7c478bd9Sstevel@tonic-gate 
309*7c478bd9Sstevel@tonic-gate /* display_field - display field f */
310*7c478bd9Sstevel@tonic-gate static int
display_field(FIELD * f)311*7c478bd9Sstevel@tonic-gate display_field(FIELD *f)
312*7c478bd9Sstevel@tonic-gate {
313*7c478bd9Sstevel@tonic-gate 	WINDOW *	w = derwin(Sub(f -> form), f -> rows, f -> cols,
314*7c478bd9Sstevel@tonic-gate 			    f -> frow, f -> fcol);
315*7c478bd9Sstevel@tonic-gate 
316*7c478bd9Sstevel@tonic-gate 	if (!w)
317*7c478bd9Sstevel@tonic-gate 		return (FALSE);
318*7c478bd9Sstevel@tonic-gate 
319*7c478bd9Sstevel@tonic-gate 	wbkgdset(w, Pad(f) | Back(f));
320*7c478bd9Sstevel@tonic-gate 	(void) wattrset(w, Fore(f));
321*7c478bd9Sstevel@tonic-gate 	(void) werase(w);
322*7c478bd9Sstevel@tonic-gate 
323*7c478bd9Sstevel@tonic-gate 	if (Opt(f, O_PUBLIC)) {
324*7c478bd9Sstevel@tonic-gate 		if (Justified(f))
325*7c478bd9Sstevel@tonic-gate 			justify(f, w);
326*7c478bd9Sstevel@tonic-gate 		else
327*7c478bd9Sstevel@tonic-gate 			_buf_to_win(f, w);
328*7c478bd9Sstevel@tonic-gate 	}
329*7c478bd9Sstevel@tonic-gate 	wsyncup(w);
330*7c478bd9Sstevel@tonic-gate 	(void) delwin(w);
331*7c478bd9Sstevel@tonic-gate 	Clr(f, TOP_CHG);
332*7c478bd9Sstevel@tonic-gate 	return (TRUE);
333*7c478bd9Sstevel@tonic-gate }
334*7c478bd9Sstevel@tonic-gate 
335*7c478bd9Sstevel@tonic-gate /* erase_field - erase field f */
336*7c478bd9Sstevel@tonic-gate static int
erase_field(FIELD * f)337*7c478bd9Sstevel@tonic-gate erase_field(FIELD *f)
338*7c478bd9Sstevel@tonic-gate {
339*7c478bd9Sstevel@tonic-gate 	WINDOW *	w = derwin(Sub(f -> form), f -> rows, f -> cols,
340*7c478bd9Sstevel@tonic-gate 			    f -> frow, f -> fcol);
341*7c478bd9Sstevel@tonic-gate 
342*7c478bd9Sstevel@tonic-gate 	if (!w)
343*7c478bd9Sstevel@tonic-gate 		return (FALSE);
344*7c478bd9Sstevel@tonic-gate 
345*7c478bd9Sstevel@tonic-gate 	(void) werase(w);
346*7c478bd9Sstevel@tonic-gate 	wsyncup(w);
347*7c478bd9Sstevel@tonic-gate 	(void) delwin(w);
348*7c478bd9Sstevel@tonic-gate 	return (TRUE);
349*7c478bd9Sstevel@tonic-gate }
350*7c478bd9Sstevel@tonic-gate 
351*7c478bd9Sstevel@tonic-gate /* _sync_field - sync the field after a change to the field buffer */
352*7c478bd9Sstevel@tonic-gate int
_sync_field(FIELD * f)353*7c478bd9Sstevel@tonic-gate _sync_field(FIELD *f)
354*7c478bd9Sstevel@tonic-gate {
355*7c478bd9Sstevel@tonic-gate 	int v = TRUE;
356*7c478bd9Sstevel@tonic-gate 
357*7c478bd9Sstevel@tonic-gate 	if (Connected(f) && Posted(f) && Visible(f)) {
358*7c478bd9Sstevel@tonic-gate 		if (isCurrent(f)) {
359*7c478bd9Sstevel@tonic-gate 			FORM *		p = f -> form;
360*7c478bd9Sstevel@tonic-gate 			WINDOW *	w = W(p);
361*7c478bd9Sstevel@tonic-gate 
362*7c478bd9Sstevel@tonic-gate 			Clr(p, WIN_CHG | BUF_CHG);
363*7c478bd9Sstevel@tonic-gate 
364*7c478bd9Sstevel@tonic-gate 			Y(p) = 0;
365*7c478bd9Sstevel@tonic-gate 			X(p) = 0;
366*7c478bd9Sstevel@tonic-gate 			T(p) = 0;
367*7c478bd9Sstevel@tonic-gate 			B(p) = 0;
368*7c478bd9Sstevel@tonic-gate 			(void) werase(w);
369*7c478bd9Sstevel@tonic-gate 
370*7c478bd9Sstevel@tonic-gate 			if (Opt(f, O_PUBLIC) && Justified(f))
371*7c478bd9Sstevel@tonic-gate 				unjustify(f, w);
372*7c478bd9Sstevel@tonic-gate 			else
373*7c478bd9Sstevel@tonic-gate 				_buf_to_win(f, w);
374*7c478bd9Sstevel@tonic-gate 
375*7c478bd9Sstevel@tonic-gate 			Set(f, TOP_CHG);
376*7c478bd9Sstevel@tonic-gate 			(void) _update_current(p);
377*7c478bd9Sstevel@tonic-gate 		} else
378*7c478bd9Sstevel@tonic-gate 			v = display_field(f);
379*7c478bd9Sstevel@tonic-gate 	}
380*7c478bd9Sstevel@tonic-gate 	Set(f, USR_CHG);
381*7c478bd9Sstevel@tonic-gate 
382*7c478bd9Sstevel@tonic-gate 	return (v ? E_OK : E_SYSTEM_ERROR);
383*7c478bd9Sstevel@tonic-gate }
384*7c478bd9Sstevel@tonic-gate 
385*7c478bd9Sstevel@tonic-gate /* _sync_attrs - sync the field after a change to a field attribute */
386*7c478bd9Sstevel@tonic-gate int
_sync_attrs(FIELD * f)387*7c478bd9Sstevel@tonic-gate _sync_attrs(FIELD *f)
388*7c478bd9Sstevel@tonic-gate {
389*7c478bd9Sstevel@tonic-gate 	int v = TRUE;
390*7c478bd9Sstevel@tonic-gate 
391*7c478bd9Sstevel@tonic-gate 	if (Connected(f) && Posted(f) && Visible(f)) {
392*7c478bd9Sstevel@tonic-gate 		if (isCurrent(f)) {
393*7c478bd9Sstevel@tonic-gate 			FORM *		p = f -> form;
394*7c478bd9Sstevel@tonic-gate 			WINDOW *	w = W(p);
395*7c478bd9Sstevel@tonic-gate 
396*7c478bd9Sstevel@tonic-gate 			_sync_buffer(p);
397*7c478bd9Sstevel@tonic-gate 
398*7c478bd9Sstevel@tonic-gate 			wbkgdset(w, Pad(f) | Back(f));
399*7c478bd9Sstevel@tonic-gate 			(void) wattrset(w, Fore(f));
400*7c478bd9Sstevel@tonic-gate 			(void) werase(w);
401*7c478bd9Sstevel@tonic-gate 
402*7c478bd9Sstevel@tonic-gate 			if (Opt(f, O_PUBLIC)) {
403*7c478bd9Sstevel@tonic-gate 				if (Justified(f))
404*7c478bd9Sstevel@tonic-gate 					unjustify(f, w);
405*7c478bd9Sstevel@tonic-gate 				else
406*7c478bd9Sstevel@tonic-gate 					_buf_to_win(f, w);
407*7c478bd9Sstevel@tonic-gate 			} else {
408*7c478bd9Sstevel@tonic-gate 				(void) copywin(w, Sub(p), 0, 0, f -> frow,
409*7c478bd9Sstevel@tonic-gate 				    f -> fcol, f -> rows - 1, f -> cols - 1,
410*7c478bd9Sstevel@tonic-gate 				    FALSE);
411*7c478bd9Sstevel@tonic-gate 				wsyncup(Sub(p));
412*7c478bd9Sstevel@tonic-gate 				_buf_to_win(f, w);
413*7c478bd9Sstevel@tonic-gate 			}
414*7c478bd9Sstevel@tonic-gate 			Set(f, TOP_CHG);
415*7c478bd9Sstevel@tonic-gate 			(void) _update_current(p);
416*7c478bd9Sstevel@tonic-gate 		} else
417*7c478bd9Sstevel@tonic-gate 			v = display_field(f);
418*7c478bd9Sstevel@tonic-gate 	}
419*7c478bd9Sstevel@tonic-gate 	return (v ? E_OK : E_SYSTEM_ERROR);
420*7c478bd9Sstevel@tonic-gate }
421*7c478bd9Sstevel@tonic-gate 
422*7c478bd9Sstevel@tonic-gate int
_sync_opts(FIELD * f,OPTIONS opts)423*7c478bd9Sstevel@tonic-gate _sync_opts(FIELD *f, OPTIONS opts)
424*7c478bd9Sstevel@tonic-gate {
425*7c478bd9Sstevel@tonic-gate 	int		v = TRUE;
426*7c478bd9Sstevel@tonic-gate 	OPTIONS		oldopts = f -> opts;
427*7c478bd9Sstevel@tonic-gate 	OPTIONS x = opts ^ oldopts;
428*7c478bd9Sstevel@tonic-gate 	/* x & opt indicates option opt has changed state */
429*7c478bd9Sstevel@tonic-gate 	f -> opts = opts;
430*7c478bd9Sstevel@tonic-gate 
431*7c478bd9Sstevel@tonic-gate 	if (Connected(f)) {
432*7c478bd9Sstevel@tonic-gate 		if (isCurrent(f)) {
433*7c478bd9Sstevel@tonic-gate 			f -> opts = oldopts;
434*7c478bd9Sstevel@tonic-gate 			return (E_CURRENT);
435*7c478bd9Sstevel@tonic-gate 		}
436*7c478bd9Sstevel@tonic-gate 		if (Posted(f) && OnPage(f)) {
437*7c478bd9Sstevel@tonic-gate 			if (x & O_VISIBLE) {
438*7c478bd9Sstevel@tonic-gate 				if (Opt(f, O_VISIBLE))
439*7c478bd9Sstevel@tonic-gate 					v = display_field(f);
440*7c478bd9Sstevel@tonic-gate 				else
441*7c478bd9Sstevel@tonic-gate 					v = erase_field(f);
442*7c478bd9Sstevel@tonic-gate 			} else if (x & O_PUBLIC) {
443*7c478bd9Sstevel@tonic-gate 				if (Opt(f, O_VISIBLE))
444*7c478bd9Sstevel@tonic-gate 					v = display_field(f);
445*7c478bd9Sstevel@tonic-gate 			}
446*7c478bd9Sstevel@tonic-gate 		}
447*7c478bd9Sstevel@tonic-gate 	}
448*7c478bd9Sstevel@tonic-gate 
449*7c478bd9Sstevel@tonic-gate 	if (x & O_STATIC) {
450*7c478bd9Sstevel@tonic-gate 		BOOLEAN	onerow = OneRow(f);
451*7c478bd9Sstevel@tonic-gate 		int		max = f->maxgrow;
452*7c478bd9Sstevel@tonic-gate 
453*7c478bd9Sstevel@tonic-gate 		if (Opt(f, O_STATIC)) {	/* growth being turned off */
454*7c478bd9Sstevel@tonic-gate 			Clr(f, GROWABLE);
455*7c478bd9Sstevel@tonic-gate 
456*7c478bd9Sstevel@tonic-gate 			if (onerow && f->cols == f->dcols &&
457*7c478bd9Sstevel@tonic-gate 			    Just(f) != NO_JUSTIFICATION && Posted(f) &&
458*7c478bd9Sstevel@tonic-gate 			    OnPage(f) && Opt(f, O_VISIBLE)) {
459*7c478bd9Sstevel@tonic-gate 				(void) display_field(f);
460*7c478bd9Sstevel@tonic-gate 			}
461*7c478bd9Sstevel@tonic-gate 		} else if (!max || (onerow && f->dcols < max) ||
462*7c478bd9Sstevel@tonic-gate 			(!onerow && f->drows < max)) {
463*7c478bd9Sstevel@tonic-gate 			Set(f, GROWABLE);
464*7c478bd9Sstevel@tonic-gate 
465*7c478bd9Sstevel@tonic-gate 			if (onerow && Just(f) != NO_JUSTIFICATION &&
466*7c478bd9Sstevel@tonic-gate 			    Posted(f) && OnPage(f) && Opt(f, O_VISIBLE)) {
467*7c478bd9Sstevel@tonic-gate 				(void) display_field(f);
468*7c478bd9Sstevel@tonic-gate 			}
469*7c478bd9Sstevel@tonic-gate 		}
470*7c478bd9Sstevel@tonic-gate 	}
471*7c478bd9Sstevel@tonic-gate 
472*7c478bd9Sstevel@tonic-gate 	return (v ? E_OK : E_SYSTEM_ERROR);
473*7c478bd9Sstevel@tonic-gate }
474*7c478bd9Sstevel@tonic-gate 
475*7c478bd9Sstevel@tonic-gate /* _validate - validate current field */
476*7c478bd9Sstevel@tonic-gate int
_validate(FORM * f)477*7c478bd9Sstevel@tonic-gate _validate(FORM *f)
478*7c478bd9Sstevel@tonic-gate {
479*7c478bd9Sstevel@tonic-gate 	FIELD * c = C(f);
480*7c478bd9Sstevel@tonic-gate 
481*7c478bd9Sstevel@tonic-gate 	_sync_buffer(f);
482*7c478bd9Sstevel@tonic-gate 
483*7c478bd9Sstevel@tonic-gate 	if (Status(f, BUF_CHG) || !Opt(c, O_PASSOK)) {
484*7c478bd9Sstevel@tonic-gate 		if (CheckField(c)) {
485*7c478bd9Sstevel@tonic-gate 			Clr(f, BUF_CHG);
486*7c478bd9Sstevel@tonic-gate 			Set(c, USR_CHG);
487*7c478bd9Sstevel@tonic-gate 			(void) _sync_linked(c);
488*7c478bd9Sstevel@tonic-gate 		} else
489*7c478bd9Sstevel@tonic-gate 			return (FALSE);
490*7c478bd9Sstevel@tonic-gate 	}
491*7c478bd9Sstevel@tonic-gate 	return (TRUE);
492*7c478bd9Sstevel@tonic-gate }
493*7c478bd9Sstevel@tonic-gate 
494*7c478bd9Sstevel@tonic-gate /*
495*7c478bd9Sstevel@tonic-gate  * _set_current_field - change current field on form f to given field.
496*7c478bd9Sstevel@tonic-gate  * POSTED flag is set unless this is called from post_form().
497*7c478bd9Sstevel@tonic-gate  */
498*7c478bd9Sstevel@tonic-gate int
_set_current_field(FORM * f,FIELD * field)499*7c478bd9Sstevel@tonic-gate _set_current_field(FORM *f, FIELD *field)
500*7c478bd9Sstevel@tonic-gate {
501*7c478bd9Sstevel@tonic-gate 	WINDOW *	w = W(f);
502*7c478bd9Sstevel@tonic-gate 	FIELD *		c = C(f);
503*7c478bd9Sstevel@tonic-gate 
504*7c478bd9Sstevel@tonic-gate 	if (c != field || ! Status(f, POSTED)) {
505*7c478bd9Sstevel@tonic-gate 		if (w) {
506*7c478bd9Sstevel@tonic-gate 			if (Visible(c)) {
507*7c478bd9Sstevel@tonic-gate 				(void) _update_current(f);
508*7c478bd9Sstevel@tonic-gate 
509*7c478bd9Sstevel@tonic-gate 				if (Opt(c, O_PUBLIC)) {
510*7c478bd9Sstevel@tonic-gate 					if (Scrollable(c)) {
511*7c478bd9Sstevel@tonic-gate 						if (T(f) == 0)
512*7c478bd9Sstevel@tonic-gate 							Clr(c, TOP_CHG);
513*7c478bd9Sstevel@tonic-gate 						else
514*7c478bd9Sstevel@tonic-gate 							Set(c, TOP_CHG);
515*7c478bd9Sstevel@tonic-gate 					} else if (Justified(c)) {
516*7c478bd9Sstevel@tonic-gate 						(void) werase(w);
517*7c478bd9Sstevel@tonic-gate 						justify(c, w);
518*7c478bd9Sstevel@tonic-gate 						wsyncup(w);
519*7c478bd9Sstevel@tonic-gate 					}
520*7c478bd9Sstevel@tonic-gate 				}
521*7c478bd9Sstevel@tonic-gate 			}
522*7c478bd9Sstevel@tonic-gate 			(void) delwin(w);
523*7c478bd9Sstevel@tonic-gate 		}
524*7c478bd9Sstevel@tonic-gate 		c = field;
525*7c478bd9Sstevel@tonic-gate 
526*7c478bd9Sstevel@tonic-gate 		if (!Opt(c, O_PUBLIC) || Scrollable(c))
527*7c478bd9Sstevel@tonic-gate 			w = newwin(c -> drows, c -> dcols, 0, 0);
528*7c478bd9Sstevel@tonic-gate 		else
529*7c478bd9Sstevel@tonic-gate 			w = derwin(Sub(f), c -> rows, c -> cols, c -> frow,
530*7c478bd9Sstevel@tonic-gate 			    c -> fcol);
531*7c478bd9Sstevel@tonic-gate 
532*7c478bd9Sstevel@tonic-gate 		if (!w)
533*7c478bd9Sstevel@tonic-gate 			return (E_SYSTEM_ERROR);
534*7c478bd9Sstevel@tonic-gate 
535*7c478bd9Sstevel@tonic-gate 		C(f) = c;
536*7c478bd9Sstevel@tonic-gate 		W(f) = w;
537*7c478bd9Sstevel@tonic-gate 		wbkgdset(w, Pad(c) | Back(c));
538*7c478bd9Sstevel@tonic-gate 		(void) wattrset(w, Fore(c));
539*7c478bd9Sstevel@tonic-gate 
540*7c478bd9Sstevel@tonic-gate 		if (!Opt(c, O_PUBLIC) || Scrollable(c)) {
541*7c478bd9Sstevel@tonic-gate 			(void) werase(w);
542*7c478bd9Sstevel@tonic-gate 			_buf_to_win(c, w);
543*7c478bd9Sstevel@tonic-gate 		} else if (Justified(c)) {
544*7c478bd9Sstevel@tonic-gate 			(void) werase(w);
545*7c478bd9Sstevel@tonic-gate 			unjustify(c, w);
546*7c478bd9Sstevel@tonic-gate 			wsyncup(w);
547*7c478bd9Sstevel@tonic-gate 		}
548*7c478bd9Sstevel@tonic-gate 		(void) untouchwin(w);
549*7c478bd9Sstevel@tonic-gate 		Clr(f, WIN_CHG | BUF_CHG);
550*7c478bd9Sstevel@tonic-gate 	}
551*7c478bd9Sstevel@tonic-gate 	Y(f) = 0;
552*7c478bd9Sstevel@tonic-gate 	X(f) = 0;
553*7c478bd9Sstevel@tonic-gate 	T(f) = 0;
554*7c478bd9Sstevel@tonic-gate 	B(f) = 0;
555*7c478bd9Sstevel@tonic-gate 	return (E_OK);
556*7c478bd9Sstevel@tonic-gate }
557*7c478bd9Sstevel@tonic-gate 
558*7c478bd9Sstevel@tonic-gate /*
559*7c478bd9Sstevel@tonic-gate  * _set_form_page - display given page and set current field to c.
560*7c478bd9Sstevel@tonic-gate  * if c is null, then set current field to first field on page.
561*7c478bd9Sstevel@tonic-gate  * POSTED flag is set unless this is called from post_form().
562*7c478bd9Sstevel@tonic-gate  */
563*7c478bd9Sstevel@tonic-gate int
_set_form_page(FORM * f,int page,FIELD * c)564*7c478bd9Sstevel@tonic-gate _set_form_page(FORM *f, int page, FIELD *c)
565*7c478bd9Sstevel@tonic-gate {
566*7c478bd9Sstevel@tonic-gate 	if (P(f) != page || ! Status(f, POSTED)) {
567*7c478bd9Sstevel@tonic-gate 		FIELD * x = f -> field [Smin(f, page)];
568*7c478bd9Sstevel@tonic-gate 		FIELD * p = x;
569*7c478bd9Sstevel@tonic-gate 
570*7c478bd9Sstevel@tonic-gate 		(void) werase(Sub(f));
571*7c478bd9Sstevel@tonic-gate 		P(f) = page;
572*7c478bd9Sstevel@tonic-gate 
573*7c478bd9Sstevel@tonic-gate 		do {
574*7c478bd9Sstevel@tonic-gate 			if (Opt(p, O_VISIBLE))
575*7c478bd9Sstevel@tonic-gate 				if (!display_field(p))
576*7c478bd9Sstevel@tonic-gate 					return (E_SYSTEM_ERROR);
577*7c478bd9Sstevel@tonic-gate 			p = p -> snext;
578*7c478bd9Sstevel@tonic-gate 
579*7c478bd9Sstevel@tonic-gate 		} while (p != x);
580*7c478bd9Sstevel@tonic-gate 
581*7c478bd9Sstevel@tonic-gate 		return (c ? _set_current_field(f, c) : _first_field(f));
582*7c478bd9Sstevel@tonic-gate 	}
583*7c478bd9Sstevel@tonic-gate 	return (E_OK);
584*7c478bd9Sstevel@tonic-gate }
585