xref: /onnv-gate/usr/src/lib/libeti/form/common/chg_data.c (revision 0:68f95e015346)
1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * CDDL HEADER START
3*0Sstevel@tonic-gate  *
4*0Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*0Sstevel@tonic-gate  * with the License.
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate  * and limitations under the License.
13*0Sstevel@tonic-gate  *
14*0Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate  *
20*0Sstevel@tonic-gate  * CDDL HEADER END
21*0Sstevel@tonic-gate  */
22*0Sstevel@tonic-gate /*	Copyright (c) 1988 AT&T	*/
23*0Sstevel@tonic-gate /*	  All Rights Reserved  	*/
24*0Sstevel@tonic-gate 
25*0Sstevel@tonic-gate 
26*0Sstevel@tonic-gate /*
27*0Sstevel@tonic-gate  *      Copyright (c) 1997, by Sun Microsystems, Inc.
28*0Sstevel@tonic-gate  *      All rights reserved.
29*0Sstevel@tonic-gate  */
30*0Sstevel@tonic-gate 
31*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
32*0Sstevel@tonic-gate 
33*0Sstevel@tonic-gate /*LINTLIBRARY*/
34*0Sstevel@tonic-gate 
35*0Sstevel@tonic-gate #include <sys/types.h>
36*0Sstevel@tonic-gate #include <stdlib.h>
37*0Sstevel@tonic-gate #include "utility.h"
38*0Sstevel@tonic-gate 
39*0Sstevel@tonic-gate #define	AT_BOTTOM(f)	(Y(f) == Ymax(f) - 1)		/* last line	*/
40*0Sstevel@tonic-gate #define	AT_END(f)	(Y(f) == Ymax(f) - 1 && X(f) == Xmax(f) - 1)
41*0Sstevel@tonic-gate 							/* last char */
42*0Sstevel@tonic-gate #define	AT_BEGINNING(f)	(Y(f) == 0 && X(f) == 0)	/* first char	*/
43*0Sstevel@tonic-gate 
44*0Sstevel@tonic-gate static int
room_for_line(FORM * f)45*0Sstevel@tonic-gate room_for_line(FORM *f)
46*0Sstevel@tonic-gate {
47*0Sstevel@tonic-gate 	char *v;
48*0Sstevel@tonic-gate 
49*0Sstevel@tonic-gate 	_sync_buffer(f);
50*0Sstevel@tonic-gate 	v = LineBuf(C(f), Ymax(f) - 1);
51*0Sstevel@tonic-gate 	return (v == _data_end(v, Xmax(f)));	/* check for empty line */
52*0Sstevel@tonic-gate }
53*0Sstevel@tonic-gate 
54*0Sstevel@tonic-gate static int
room_for_char(FORM * f)55*0Sstevel@tonic-gate room_for_char(FORM *f)
56*0Sstevel@tonic-gate {
57*0Sstevel@tonic-gate 	WINDOW * w = W(f);
58*0Sstevel@tonic-gate 	int c;
59*0Sstevel@tonic-gate 
60*0Sstevel@tonic-gate 	(void) wmove(w, Y(f), Xmax(f) - 1);
61*0Sstevel@tonic-gate 	c = (int)(winch(w) & A_CHARTEXT);
62*0Sstevel@tonic-gate 	(void) wmove(w, Y(f), X(f));
63*0Sstevel@tonic-gate 	return (c == Pad(C(f)));	/* check for empty char */
64*0Sstevel@tonic-gate }
65*0Sstevel@tonic-gate 
66*0Sstevel@tonic-gate static int
extra_padding(char * str,int nstr)67*0Sstevel@tonic-gate extra_padding(char *str, int nstr)		/* used for word wrapping */
68*0Sstevel@tonic-gate {
69*0Sstevel@tonic-gate 	int c = *(str + nstr - 1);
70*0Sstevel@tonic-gate 
71*0Sstevel@tonic-gate 	if (c == '"' || c == '\'')
72*0Sstevel@tonic-gate 		c = *(str + nstr - 2);
73*0Sstevel@tonic-gate 
74*0Sstevel@tonic-gate 	return ((c == '.' || c == '?' || c == '!' || c == ':') ? 2 : 1);
75*0Sstevel@tonic-gate 
76*0Sstevel@tonic-gate }
77*0Sstevel@tonic-gate 
78*0Sstevel@tonic-gate BOOLEAN
_grow_field(FIELD * c,int chunks)79*0Sstevel@tonic-gate _grow_field(FIELD *c, int chunks)
80*0Sstevel@tonic-gate {
81*0Sstevel@tonic-gate 	/* This function handles the growth of dymanically growable fields */
82*0Sstevel@tonic-gate 	/* Returns TRUE if successful, FALSE otherwise	*/
83*0Sstevel@tonic-gate 
84*0Sstevel@tonic-gate 	FORM		*f = c->form;
85*0Sstevel@tonic-gate 	WINDOW		*w = W(f);
86*0Sstevel@tonic-gate 	BOOLEAN		current = Status(f, POSTED) && c == C(f);
87*0Sstevel@tonic-gate 	char		*old_buf;
88*0Sstevel@tonic-gate 	char		*new_buf;
89*0Sstevel@tonic-gate 	char		*save;
90*0Sstevel@tonic-gate 	int		old_len = BufSize(c);
91*0Sstevel@tonic-gate 	int		grow;
92*0Sstevel@tonic-gate 	int		lcv;
93*0Sstevel@tonic-gate 	int		max = c->maxgrow;
94*0Sstevel@tonic-gate 	int		i;
95*0Sstevel@tonic-gate 
96*0Sstevel@tonic-gate 	if (current && Status(f, WIN_CHG)) {
97*0Sstevel@tonic-gate 		_win_to_buf(w, c);
98*0Sstevel@tonic-gate 		Clr(f, WIN_CHG);
99*0Sstevel@tonic-gate 		Set(f, BUF_CHG);
100*0Sstevel@tonic-gate 	}
101*0Sstevel@tonic-gate 
102*0Sstevel@tonic-gate 	if (OneRow(c)) {
103*0Sstevel@tonic-gate 		grow = chunks * c->cols;
104*0Sstevel@tonic-gate 
105*0Sstevel@tonic-gate 		if (max)
106*0Sstevel@tonic-gate 			grow = MIN(max - c->dcols, grow);
107*0Sstevel@tonic-gate 
108*0Sstevel@tonic-gate 		c->dcols += grow;
109*0Sstevel@tonic-gate 
110*0Sstevel@tonic-gate 		if (c->dcols == max)
111*0Sstevel@tonic-gate 			Clr(c, GROWABLE);
112*0Sstevel@tonic-gate 	} else {
113*0Sstevel@tonic-gate 		grow = chunks * (c->rows + c->nrow);
114*0Sstevel@tonic-gate 
115*0Sstevel@tonic-gate 		if (max)
116*0Sstevel@tonic-gate 			grow = MIN(max - c->drows, grow);
117*0Sstevel@tonic-gate 
118*0Sstevel@tonic-gate 		c->drows += grow;
119*0Sstevel@tonic-gate 		grow *= c->cols;
120*0Sstevel@tonic-gate 
121*0Sstevel@tonic-gate 		if (c->drows == max)
122*0Sstevel@tonic-gate 			Clr(c, GROWABLE);
123*0Sstevel@tonic-gate 	}
124*0Sstevel@tonic-gate 
125*0Sstevel@tonic-gate 	save = old_buf = Buf(c);
126*0Sstevel@tonic-gate 	new_buf = Buf(c) = malloc(TotalBuf(c));
127*0Sstevel@tonic-gate 
128*0Sstevel@tonic-gate 	if (!new_buf)
129*0Sstevel@tonic-gate 		return (FALSE);
130*0Sstevel@tonic-gate 
131*0Sstevel@tonic-gate 	lcv = c->nbuf + 1;
132*0Sstevel@tonic-gate 
133*0Sstevel@tonic-gate 	for (i = 0; i < lcv; i++) {
134*0Sstevel@tonic-gate 		(void) memcpy(new_buf, old_buf, old_len);
135*0Sstevel@tonic-gate 		(void) memset(new_buf + old_len, ' ', grow);
136*0Sstevel@tonic-gate 		old_buf += old_len + 1;
137*0Sstevel@tonic-gate 		new_buf += old_len + grow;
138*0Sstevel@tonic-gate 		*new_buf++ = '\0';
139*0Sstevel@tonic-gate 	}
140*0Sstevel@tonic-gate 
141*0Sstevel@tonic-gate 	free(save);	/* delete old buffer */
142*0Sstevel@tonic-gate 
143*0Sstevel@tonic-gate 	if (current) {
144*0Sstevel@tonic-gate 		(void) delwin(w);
145*0Sstevel@tonic-gate 		W(f) = w = newwin(c->drows, c->dcols, 0, 0);
146*0Sstevel@tonic-gate 
147*0Sstevel@tonic-gate 		if (!w)
148*0Sstevel@tonic-gate 			return (FALSE);
149*0Sstevel@tonic-gate 
150*0Sstevel@tonic-gate 		wbkgdset(w, Pad(c) | Back(c));
151*0Sstevel@tonic-gate 		(void) wattrset(w, Fore(c));
152*0Sstevel@tonic-gate 		(void) werase(w);
153*0Sstevel@tonic-gate 		_buf_to_win(c, w);
154*0Sstevel@tonic-gate 		(void) untouchwin(w);
155*0Sstevel@tonic-gate 		(void) wmove(w, Y(f), X(f));
156*0Sstevel@tonic-gate 	}
157*0Sstevel@tonic-gate 
158*0Sstevel@tonic-gate 	if (c->link != c) {
159*0Sstevel@tonic-gate 		FIELD	*p = c->link;
160*0Sstevel@tonic-gate 
161*0Sstevel@tonic-gate 		while (p != c) {
162*0Sstevel@tonic-gate 			Buf(p) = Buf(c);
163*0Sstevel@tonic-gate 			p->drows = c->drows;
164*0Sstevel@tonic-gate 			p->dcols = c->dcols;
165*0Sstevel@tonic-gate 			/* _sync_field(p) */
166*0Sstevel@tonic-gate 			p = p->link;
167*0Sstevel@tonic-gate 		}
168*0Sstevel@tonic-gate 	}
169*0Sstevel@tonic-gate 
170*0Sstevel@tonic-gate 	return (TRUE);
171*0Sstevel@tonic-gate }
172*0Sstevel@tonic-gate 
173*0Sstevel@tonic-gate static int
insert_str(FORM * f,int y,int off,int nstr)174*0Sstevel@tonic-gate insert_str(FORM *f, int y, int off, int nstr)	/* used for word wrapping */
175*0Sstevel@tonic-gate {
176*0Sstevel@tonic-gate 	WINDOW		*w	= W(f);
177*0Sstevel@tonic-gate 	FIELD		*c	= C(f);
178*0Sstevel@tonic-gate 	char		*vbeg	= LineBuf(c, y);
179*0Sstevel@tonic-gate 	char		*v	= _data_end(vbeg, Xmax(f));
180*0Sstevel@tonic-gate 	int		x	= (int)(v - vbeg);
181*0Sstevel@tonic-gate 	int		n	= Xmax(f) - x;
182*0Sstevel@tonic-gate 	int		pad	= extra_padding(Buf(c) + off, nstr);
183*0Sstevel@tonic-gate 	int		siz	= nstr + 1 + pad;
184*0Sstevel@tonic-gate 	int		ret 	= E_REQUEST_DENIED;
185*0Sstevel@tonic-gate 
186*0Sstevel@tonic-gate 	if (n >= siz) {	/* check for fit on this line */
187*0Sstevel@tonic-gate 		(void) wmove(w, y, 0);
188*0Sstevel@tonic-gate 		(void) winsnstr(w, Buf(c) + off, nstr);
189*0Sstevel@tonic-gate 		(void) wmove(w, y, nstr);
190*0Sstevel@tonic-gate 		(void) winsnstr(w, "  ", pad);
191*0Sstevel@tonic-gate 	} else {		/* wrap */
192*0Sstevel@tonic-gate 		if (y == Ymax(f) - 1 && Status(c, GROWABLE)) {
193*0Sstevel@tonic-gate 			if (!_grow_field(c, 1))
194*0Sstevel@tonic-gate 				return (E_SYSTEM_ERROR);
195*0Sstevel@tonic-gate 
196*0Sstevel@tonic-gate 			vbeg = LineBuf(c, y);	/* grow changes buffer */
197*0Sstevel@tonic-gate 			w = W(f);		/* grow changes window */
198*0Sstevel@tonic-gate 		}
199*0Sstevel@tonic-gate 
200*0Sstevel@tonic-gate 		v = _data_beg(vbeg + Xmax(f) - siz, siz);
201*0Sstevel@tonic-gate 		v = _whsp_end(vbeg, (int)(v - vbeg));
202*0Sstevel@tonic-gate 		x = (int)(v - vbeg);
203*0Sstevel@tonic-gate 		n = Xmax(f) - x - n;
204*0Sstevel@tonic-gate 
205*0Sstevel@tonic-gate 		if (y < Ymax(f) - 1 && (ret =
206*0Sstevel@tonic-gate 		    insert_str(f, y+1, (int)(v - Buf(c)), n)) == E_OK) {
207*0Sstevel@tonic-gate 			(void) wmove(w, y, x);
208*0Sstevel@tonic-gate 			(void) wclrtoeol(w);
209*0Sstevel@tonic-gate 			(void) wmove(w, y, 0);
210*0Sstevel@tonic-gate 			(void) winsnstr(w, Buf(c) + off, nstr);
211*0Sstevel@tonic-gate 			(void) wmove(w, y, nstr);
212*0Sstevel@tonic-gate 			(void) winsnstr(w, "  ", pad);
213*0Sstevel@tonic-gate 		} else
214*0Sstevel@tonic-gate 			return (ret);	/* no room for wrap */
215*0Sstevel@tonic-gate 	}
216*0Sstevel@tonic-gate 	return (E_OK);
217*0Sstevel@tonic-gate }
218*0Sstevel@tonic-gate 
219*0Sstevel@tonic-gate static int
wrap_ok(FORM * f)220*0Sstevel@tonic-gate wrap_ok(FORM *f)		/* used for word wrapping */
221*0Sstevel@tonic-gate {
222*0Sstevel@tonic-gate /*
223*0Sstevel@tonic-gate  * when this routine is called a char has already been added/inserted
224*0Sstevel@tonic-gate  * on the screen at Y(f), X(f).  this routine checks to see if the current
225*0Sstevel@tonic-gate  * line needs wrapping and if so attempts the wrap.  if unsuccessful
226*0Sstevel@tonic-gate  * it deletes the char at Y(f), X(f) and returns FALSE.
227*0Sstevel@tonic-gate  */
228*0Sstevel@tonic-gate 	FIELD		*c = C(f);
229*0Sstevel@tonic-gate 	BOOLEAN		at_bottom = AT_BOTTOM(f);
230*0Sstevel@tonic-gate 	int		ret = E_REQUEST_DENIED;
231*0Sstevel@tonic-gate 
232*0Sstevel@tonic-gate 	if (Opt(c, O_WRAP) && !OneRow(c) && !room_for_char(f) &&
233*0Sstevel@tonic-gate 	    (!at_bottom || Status(c, GROWABLE))) {
234*0Sstevel@tonic-gate 		WINDOW *w;
235*0Sstevel@tonic-gate 		char *vbeg;
236*0Sstevel@tonic-gate 		char *v;
237*0Sstevel@tonic-gate 		int x, n;
238*0Sstevel@tonic-gate 
239*0Sstevel@tonic-gate 		if (at_bottom && !_grow_field(c, 1))
240*0Sstevel@tonic-gate 			return (E_SYSTEM_ERROR);
241*0Sstevel@tonic-gate 
242*0Sstevel@tonic-gate 		vbeg = LineBuf(c, Y(f));
243*0Sstevel@tonic-gate 		w = W(f);
244*0Sstevel@tonic-gate 
245*0Sstevel@tonic-gate 		_win_to_buf(w, c);	/* sync buffer without changing flags */
246*0Sstevel@tonic-gate 
247*0Sstevel@tonic-gate 		v = _whsp_end(vbeg, Xmax(f));
248*0Sstevel@tonic-gate 		x = (int)(v - vbeg);
249*0Sstevel@tonic-gate 		n = Xmax(f) - x;
250*0Sstevel@tonic-gate 
251*0Sstevel@tonic-gate 		if (x && (ret = insert_str(f, Y(f)+1, (int)(v - Buf(c)), n)) ==
252*0Sstevel@tonic-gate 		    E_OK) {
253*0Sstevel@tonic-gate 			w = W(f);	/* window may change in insert_str */
254*0Sstevel@tonic-gate 			(void) wmove(w, Y(f), x);
255*0Sstevel@tonic-gate 			(void) wclrtoeol(w);
256*0Sstevel@tonic-gate 
257*0Sstevel@tonic-gate 			if (X(f) >= x) {
258*0Sstevel@tonic-gate 				++Y(f);
259*0Sstevel@tonic-gate 				X(f) = X(f) - x;
260*0Sstevel@tonic-gate 			}
261*0Sstevel@tonic-gate 		} else {	/* error condition */
262*0Sstevel@tonic-gate 			if (ret == E_SYSTEM_ERROR)
263*0Sstevel@tonic-gate 				return (E_SYSTEM_ERROR);
264*0Sstevel@tonic-gate 
265*0Sstevel@tonic-gate 			(void) wmove(w, Y(f), X(f));
266*0Sstevel@tonic-gate 			(void) wdelch(w);	/* delete the char */
267*0Sstevel@tonic-gate 			_win_to_buf(w, c);	/* restore buffer  */
268*0Sstevel@tonic-gate 			return (E_REQUEST_DENIED);
269*0Sstevel@tonic-gate 		}
270*0Sstevel@tonic-gate 	}
271*0Sstevel@tonic-gate 	return (E_OK);
272*0Sstevel@tonic-gate }
273*0Sstevel@tonic-gate 
274*0Sstevel@tonic-gate int
_new_line(FORM * f)275*0Sstevel@tonic-gate _new_line(FORM *f)
276*0Sstevel@tonic-gate {
277*0Sstevel@tonic-gate /*
278*0Sstevel@tonic-gate  *		overloaded operation
279*0Sstevel@tonic-gate  *
280*0Sstevel@tonic-gate  *	if at beginning of field
281*0Sstevel@tonic-gate  *		move to next field
282*0Sstevel@tonic-gate  *
283*0Sstevel@tonic-gate  *	else if in OVERLAY mode
284*0Sstevel@tonic-gate  *		if on last line of field
285*0Sstevel@tonic-gate  *			clear to eol and move to next field
286*0Sstevel@tonic-gate  *		else
287*0Sstevel@tonic-gate  *			clear to eol and move to beginning of next line
288*0Sstevel@tonic-gate  *
289*0Sstevel@tonic-gate  *	else if in INSERT mode
290*0Sstevel@tonic-gate  *		if on last line of field
291*0Sstevel@tonic-gate  *			move to next field
292*0Sstevel@tonic-gate  *		else
293*0Sstevel@tonic-gate  *			move text from cursor to eol to new line
294*0Sstevel@tonic-gate  */
295*0Sstevel@tonic-gate 	BOOLEAN		at_bottom = AT_BOTTOM(f);
296*0Sstevel@tonic-gate 	FIELD *		c = C(f);
297*0Sstevel@tonic-gate 
298*0Sstevel@tonic-gate 	if (Opt(f, O_NL_OVERLOAD) && AT_BEGINNING(f))
299*0Sstevel@tonic-gate 		return (_field_navigation(_next_field, f));
300*0Sstevel@tonic-gate 
301*0Sstevel@tonic-gate 	if (!Opt(c, O_EDIT))
302*0Sstevel@tonic-gate 		return (E_REQUEST_DENIED);
303*0Sstevel@tonic-gate 
304*0Sstevel@tonic-gate 	if (Status(f, OVERLAY)) {		/* OVERLAY mode	*/
305*0Sstevel@tonic-gate 		if (at_bottom && (!Status(c, GROWABLE) || OneRow(c))) {
306*0Sstevel@tonic-gate 			if (Opt(f, O_NL_OVERLOAD)) {
307*0Sstevel@tonic-gate 				(void) wclrtoeol(W(f));
308*0Sstevel@tonic-gate 				Set(f, WIN_CHG);
309*0Sstevel@tonic-gate 				return (_field_navigation(_next_field, f));
310*0Sstevel@tonic-gate 			} else
311*0Sstevel@tonic-gate 				return (E_REQUEST_DENIED);
312*0Sstevel@tonic-gate 		}
313*0Sstevel@tonic-gate 
314*0Sstevel@tonic-gate 		if (at_bottom && !_grow_field(c, 1))
315*0Sstevel@tonic-gate 			return (E_SYSTEM_ERROR);
316*0Sstevel@tonic-gate 
317*0Sstevel@tonic-gate 		(void) wclrtoeol(W(f));
318*0Sstevel@tonic-gate 		++Y(f); X(f) = 0;
319*0Sstevel@tonic-gate 	} else {		/* INSERT mode	*/
320*0Sstevel@tonic-gate 		BOOLEAN		room;
321*0Sstevel@tonic-gate 
322*0Sstevel@tonic-gate 		if (at_bottom && (!Status(c, GROWABLE) || OneRow(c))) {
323*0Sstevel@tonic-gate 			if (Opt(f, O_NL_OVERLOAD))
324*0Sstevel@tonic-gate 				return (_field_navigation(_next_field, f));
325*0Sstevel@tonic-gate 			else
326*0Sstevel@tonic-gate 				return (E_REQUEST_DENIED);
327*0Sstevel@tonic-gate 		}
328*0Sstevel@tonic-gate 
329*0Sstevel@tonic-gate 		room = !at_bottom && room_for_line(f);
330*0Sstevel@tonic-gate 
331*0Sstevel@tonic-gate 		if (room || Status(c, GROWABLE)) {
332*0Sstevel@tonic-gate 			WINDOW	*w;
333*0Sstevel@tonic-gate 			char *v;
334*0Sstevel@tonic-gate 			char *vend;
335*0Sstevel@tonic-gate 
336*0Sstevel@tonic-gate 			if (!room && !_grow_field(c, 1))
337*0Sstevel@tonic-gate 				return (E_SYSTEM_ERROR);
338*0Sstevel@tonic-gate 
339*0Sstevel@tonic-gate 			w = W(f);
340*0Sstevel@tonic-gate 			v = LineBuf(c, Y(f)) + X(f);
341*0Sstevel@tonic-gate 			vend = _data_end(v, Xmax(f) - X(f));
342*0Sstevel@tonic-gate 
343*0Sstevel@tonic-gate 			(void) wclrtoeol(w);
344*0Sstevel@tonic-gate 			++Y(f); X(f) = 0;
345*0Sstevel@tonic-gate 			(void) wmove(w, Y(f), X(f));
346*0Sstevel@tonic-gate 			(void) winsertln(w);
347*0Sstevel@tonic-gate 			(void) waddnstr(w, v, (int)(vend - v));
348*0Sstevel@tonic-gate 		} else
349*0Sstevel@tonic-gate 			return (E_REQUEST_DENIED);
350*0Sstevel@tonic-gate 	}
351*0Sstevel@tonic-gate 	Set(f, WIN_CHG);
352*0Sstevel@tonic-gate 	return (E_OK);
353*0Sstevel@tonic-gate }
354*0Sstevel@tonic-gate 
355*0Sstevel@tonic-gate /* _ins_char - insert blank char with error on overflow */
356*0Sstevel@tonic-gate int
_ins_char(FORM * f)357*0Sstevel@tonic-gate _ins_char(FORM *f)
358*0Sstevel@tonic-gate {
359*0Sstevel@tonic-gate 	FIELD	*c = C(f);
360*0Sstevel@tonic-gate 	BOOLEAN	room = room_for_char(f);
361*0Sstevel@tonic-gate 
362*0Sstevel@tonic-gate 	if (CheckChar(c, ' ') && (room || (OneRow(c) &&
363*0Sstevel@tonic-gate 	    Status(c, GROWABLE)))) {
364*0Sstevel@tonic-gate 		if (!room && !_grow_field(c, 1))
365*0Sstevel@tonic-gate 			return (E_SYSTEM_ERROR);
366*0Sstevel@tonic-gate 
367*0Sstevel@tonic-gate 		(void) winsch(W(f), ' ');
368*0Sstevel@tonic-gate 
369*0Sstevel@tonic-gate 		return (wrap_ok(f));
370*0Sstevel@tonic-gate 	}
371*0Sstevel@tonic-gate 	return (E_REQUEST_DENIED);
372*0Sstevel@tonic-gate }
373*0Sstevel@tonic-gate 
374*0Sstevel@tonic-gate /* _ins_line -  insert blank line with error on overflow */
375*0Sstevel@tonic-gate int
_ins_line(FORM * f)376*0Sstevel@tonic-gate _ins_line(FORM *f)
377*0Sstevel@tonic-gate {
378*0Sstevel@tonic-gate 	BOOLEAN		room = !AT_BOTTOM(f) && room_for_line(f);
379*0Sstevel@tonic-gate 	FIELD		*c = C(f);
380*0Sstevel@tonic-gate 
381*0Sstevel@tonic-gate 	if (CheckChar(c, ' ') && !OneRow(c) && (room || Status(c, GROWABLE))) {
382*0Sstevel@tonic-gate 		if (!room && !_grow_field(c, 1))
383*0Sstevel@tonic-gate 			return (E_SYSTEM_ERROR);
384*0Sstevel@tonic-gate 
385*0Sstevel@tonic-gate 		X(f) = 0;
386*0Sstevel@tonic-gate 		(void) winsertln(W(f));
387*0Sstevel@tonic-gate 		return (E_OK);
388*0Sstevel@tonic-gate 	}
389*0Sstevel@tonic-gate 	return (E_REQUEST_DENIED);
390*0Sstevel@tonic-gate }
391*0Sstevel@tonic-gate 
392*0Sstevel@tonic-gate /* _del_char - delete char at cursor */
393*0Sstevel@tonic-gate int
_del_char(FORM * f)394*0Sstevel@tonic-gate _del_char(FORM *f)
395*0Sstevel@tonic-gate {
396*0Sstevel@tonic-gate 	(void) wdelch(W(f));
397*0Sstevel@tonic-gate 	return (E_OK);
398*0Sstevel@tonic-gate }
399*0Sstevel@tonic-gate 
400*0Sstevel@tonic-gate int
_del_prev(FORM * f)401*0Sstevel@tonic-gate _del_prev(FORM *f)
402*0Sstevel@tonic-gate {
403*0Sstevel@tonic-gate /*
404*0Sstevel@tonic-gate  *		overloaded operation
405*0Sstevel@tonic-gate  *
406*0Sstevel@tonic-gate  *	if at beginning of field
407*0Sstevel@tonic-gate  *		move to previous field
408*0Sstevel@tonic-gate  *
409*0Sstevel@tonic-gate  *	else if in OVERLAY mode
410*0Sstevel@tonic-gate  *		if at beginning of line
411*0Sstevel@tonic-gate  *			error
412*0Sstevel@tonic-gate  *		else
413*0Sstevel@tonic-gate  *			delete previous char
414*0Sstevel@tonic-gate  *
415*0Sstevel@tonic-gate  *	else if in INSERT mode
416*0Sstevel@tonic-gate  *		if at beginning of line
417*0Sstevel@tonic-gate  *			if current line can fit on preceding
418*0Sstevel@tonic-gate  *				join current line with preceding line
419*0Sstevel@tonic-gate  *			else
420*0Sstevel@tonic-gate  *				error
421*0Sstevel@tonic-gate  *		else
422*0Sstevel@tonic-gate  *			delete previous char
423*0Sstevel@tonic-gate  */
424*0Sstevel@tonic-gate 	WINDOW *	w = W(f);
425*0Sstevel@tonic-gate 	FIELD *		c = C(f);
426*0Sstevel@tonic-gate 
427*0Sstevel@tonic-gate 	if (AT_BEGINNING(f)) {
428*0Sstevel@tonic-gate 		if (Opt(f, O_BS_OVERLOAD))
429*0Sstevel@tonic-gate 			return (_field_navigation(_prev_field, f));
430*0Sstevel@tonic-gate 		else
431*0Sstevel@tonic-gate 			return (E_REQUEST_DENIED);
432*0Sstevel@tonic-gate 	}
433*0Sstevel@tonic-gate 	if (!Opt(c, O_EDIT))
434*0Sstevel@tonic-gate 		return (E_REQUEST_DENIED);
435*0Sstevel@tonic-gate 
436*0Sstevel@tonic-gate 	if (--X(f) < 0) {
437*0Sstevel@tonic-gate 		++X(f);
438*0Sstevel@tonic-gate 
439*0Sstevel@tonic-gate 		if (Status(f, OVERLAY))	/* OVERLAY mode	*/
440*0Sstevel@tonic-gate 			return (E_REQUEST_DENIED);
441*0Sstevel@tonic-gate 		else {			/* INSERT mode	*/
442*0Sstevel@tonic-gate 			char *p = LineBuf(c, Y(f) - 1);
443*0Sstevel@tonic-gate 			char *v = LineBuf(c, Y(f));
444*0Sstevel@tonic-gate 			char *pend;
445*0Sstevel@tonic-gate 			char *vend;
446*0Sstevel@tonic-gate 
447*0Sstevel@tonic-gate 			_sync_buffer(f);
448*0Sstevel@tonic-gate 			pend = _data_end(p, Xmax(f));
449*0Sstevel@tonic-gate 			vend = _data_end(v, Xmax(f));
450*0Sstevel@tonic-gate 
451*0Sstevel@tonic-gate 			if ((vend - v) > (Xmax(f) - (pend - p)))
452*0Sstevel@tonic-gate 				return (E_REQUEST_DENIED);
453*0Sstevel@tonic-gate 			else {
454*0Sstevel@tonic-gate 				(void) wdeleteln(w);
455*0Sstevel@tonic-gate 				_adjust_cursor(f, pend);
456*0Sstevel@tonic-gate 				(void) wmove(w, Y(f), X(f));
457*0Sstevel@tonic-gate 				(void) waddnstr(w, v, (int)(vend - v));
458*0Sstevel@tonic-gate 			}
459*0Sstevel@tonic-gate 		}
460*0Sstevel@tonic-gate 	} else {
461*0Sstevel@tonic-gate 		(void) wmove(w, Y(f), X(f));
462*0Sstevel@tonic-gate 		(void) wdelch(w);
463*0Sstevel@tonic-gate 	}
464*0Sstevel@tonic-gate 	Set(f, WIN_CHG);
465*0Sstevel@tonic-gate 	return (E_OK);
466*0Sstevel@tonic-gate }
467*0Sstevel@tonic-gate 
468*0Sstevel@tonic-gate /* _del_line - delete current line */
469*0Sstevel@tonic-gate int
_del_line(FORM * f)470*0Sstevel@tonic-gate _del_line(FORM *f)
471*0Sstevel@tonic-gate {
472*0Sstevel@tonic-gate 	X(f) = 0;
473*0Sstevel@tonic-gate 	(void) wdeleteln(W(f));
474*0Sstevel@tonic-gate 	return (E_OK);
475*0Sstevel@tonic-gate }
476*0Sstevel@tonic-gate 
477*0Sstevel@tonic-gate /* _del_word - delete word under cursor plus trailing blanks */
478*0Sstevel@tonic-gate int
_del_word(FORM * f)479*0Sstevel@tonic-gate _del_word(FORM *f)
480*0Sstevel@tonic-gate {
481*0Sstevel@tonic-gate 	FIELD *c = C(f);
482*0Sstevel@tonic-gate 	WINDOW *w = W(f);
483*0Sstevel@tonic-gate 	char *y = LineBuf(c, Y(f));
484*0Sstevel@tonic-gate 	char *t = y + Xmax(f);
485*0Sstevel@tonic-gate 	char *v = y + X(f);
486*0Sstevel@tonic-gate 	char *x = v;
487*0Sstevel@tonic-gate 
488*0Sstevel@tonic-gate 	_sync_buffer(f);
489*0Sstevel@tonic-gate 
490*0Sstevel@tonic-gate 	if (*v == ' ')
491*0Sstevel@tonic-gate 		return (E_REQUEST_DENIED);
492*0Sstevel@tonic-gate 
493*0Sstevel@tonic-gate 	_adjust_cursor(f, _whsp_end(y, X(f)));
494*0Sstevel@tonic-gate 	(void) wmove(w, Y(f), X(f));
495*0Sstevel@tonic-gate 	(void) wclrtoeol(w);
496*0Sstevel@tonic-gate 
497*0Sstevel@tonic-gate 	v = _whsp_beg(v, (int)(t - v));
498*0Sstevel@tonic-gate 	v = _data_beg(v, (int)(t - v));
499*0Sstevel@tonic-gate 
500*0Sstevel@tonic-gate 	if (v != x && *v != ' ')
501*0Sstevel@tonic-gate 		(void) waddnstr(w, v, (int)(_data_end(v, (int)(t - v)) - v));
502*0Sstevel@tonic-gate 
503*0Sstevel@tonic-gate 	return (E_OK);
504*0Sstevel@tonic-gate }
505*0Sstevel@tonic-gate 
506*0Sstevel@tonic-gate /* _clr_eol - clear to end of line */
507*0Sstevel@tonic-gate int
_clr_eol(FORM * f)508*0Sstevel@tonic-gate _clr_eol(FORM *f)
509*0Sstevel@tonic-gate {
510*0Sstevel@tonic-gate 	(void) wclrtoeol(W(f));
511*0Sstevel@tonic-gate 	return (E_OK);
512*0Sstevel@tonic-gate }
513*0Sstevel@tonic-gate 
514*0Sstevel@tonic-gate /* _clr_eof - clear to end of field */
515*0Sstevel@tonic-gate int
_clr_eof(FORM * f)516*0Sstevel@tonic-gate _clr_eof(FORM *f)
517*0Sstevel@tonic-gate {
518*0Sstevel@tonic-gate 	(void) wclrtobot(W(f));
519*0Sstevel@tonic-gate 	return (E_OK);
520*0Sstevel@tonic-gate }
521*0Sstevel@tonic-gate 
522*0Sstevel@tonic-gate /* _clr_field - clear entire field */
523*0Sstevel@tonic-gate int
_clr_field(FORM * f)524*0Sstevel@tonic-gate _clr_field(FORM *f)
525*0Sstevel@tonic-gate {
526*0Sstevel@tonic-gate 	X(f) = 0; Y(f) = 0;
527*0Sstevel@tonic-gate 	(void) werase(W(f));
528*0Sstevel@tonic-gate 	return (E_OK);
529*0Sstevel@tonic-gate }
530*0Sstevel@tonic-gate 
531*0Sstevel@tonic-gate /* _ovl_mode - go into overlay mode */
532*0Sstevel@tonic-gate int
_ovl_mode(FORM * f)533*0Sstevel@tonic-gate _ovl_mode(FORM *f)
534*0Sstevel@tonic-gate {
535*0Sstevel@tonic-gate 	Set(f, OVERLAY);
536*0Sstevel@tonic-gate 	return (E_OK);
537*0Sstevel@tonic-gate }
538*0Sstevel@tonic-gate 
539*0Sstevel@tonic-gate /* _ins_mode - go into insert mode */
540*0Sstevel@tonic-gate int
_ins_mode(FORM * f)541*0Sstevel@tonic-gate _ins_mode(FORM *f)
542*0Sstevel@tonic-gate {
543*0Sstevel@tonic-gate 	Clr(f, OVERLAY);
544*0Sstevel@tonic-gate 	return (E_OK);
545*0Sstevel@tonic-gate }
546*0Sstevel@tonic-gate 
547*0Sstevel@tonic-gate /* _validation - apply validation function associated with field type */
548*0Sstevel@tonic-gate int
_validation(FORM * f)549*0Sstevel@tonic-gate _validation(FORM *f)
550*0Sstevel@tonic-gate {
551*0Sstevel@tonic-gate 	return (_validate(f) ? E_OK : E_INVALID_FIELD);
552*0Sstevel@tonic-gate }
553*0Sstevel@tonic-gate 
554*0Sstevel@tonic-gate /* _next_choice - apply next choice function associated with field type */
555*0Sstevel@tonic-gate int
_next_choice(FORM * f)556*0Sstevel@tonic-gate _next_choice(FORM *f)
557*0Sstevel@tonic-gate {
558*0Sstevel@tonic-gate 	_sync_buffer(f);
559*0Sstevel@tonic-gate 	return (NextChoice(C(f)) ? E_OK : E_REQUEST_DENIED);
560*0Sstevel@tonic-gate }
561*0Sstevel@tonic-gate 
562*0Sstevel@tonic-gate /* _prev_choice - apply previous choice function associated with field type */
563*0Sstevel@tonic-gate int
_prev_choice(FORM * f)564*0Sstevel@tonic-gate _prev_choice(FORM *f)
565*0Sstevel@tonic-gate {
566*0Sstevel@tonic-gate 	_sync_buffer(f);
567*0Sstevel@tonic-gate 	return (PrevChoice(C(f)) ? E_OK : E_REQUEST_DENIED);
568*0Sstevel@tonic-gate }
569*0Sstevel@tonic-gate 
570*0Sstevel@tonic-gate /*
571*0Sstevel@tonic-gate  * _data_entry - enter printable ascii char ch
572*0Sstevel@tonic-gate  * in current field at cursor position
573*0Sstevel@tonic-gate  */
574*0Sstevel@tonic-gate int
_data_entry(FORM * f,int ch)575*0Sstevel@tonic-gate _data_entry(FORM *f, int ch)
576*0Sstevel@tonic-gate {
577*0Sstevel@tonic-gate 	FIELD *		c = C(f);	/* current field	*/
578*0Sstevel@tonic-gate 	WINDOW *	w = W(f);	/* field window		*/
579*0Sstevel@tonic-gate 	BOOLEAN		at_end;
580*0Sstevel@tonic-gate 	int		ret;
581*0Sstevel@tonic-gate 
582*0Sstevel@tonic-gate 	if (!Opt(c, O_EDIT))
583*0Sstevel@tonic-gate 		return (E_REQUEST_DENIED);
584*0Sstevel@tonic-gate 
585*0Sstevel@tonic-gate 	if (AT_BEGINNING(f) && Opt(c, O_BLANK) && ! Status(f, BUF_CHG) &&
586*0Sstevel@tonic-gate 	    !Status(f, WIN_CHG))
587*0Sstevel@tonic-gate 		(void) werase(w);
588*0Sstevel@tonic-gate 
589*0Sstevel@tonic-gate 	if (Status(f, OVERLAY))	/* OVERLAY mode	*/
590*0Sstevel@tonic-gate 		(void) waddch(w, (chtype) ch);
591*0Sstevel@tonic-gate 	else {				/* INSERT mode	*/
592*0Sstevel@tonic-gate 		BOOLEAN	room = room_for_char(f);
593*0Sstevel@tonic-gate 
594*0Sstevel@tonic-gate 		if (room || (OneRow(c) && Status(c, GROWABLE))) {
595*0Sstevel@tonic-gate 			if (!room && !_grow_field(c, 1))
596*0Sstevel@tonic-gate 				return (E_SYSTEM_ERROR);
597*0Sstevel@tonic-gate 
598*0Sstevel@tonic-gate 			(void) winsch(w, (chtype) ch);
599*0Sstevel@tonic-gate 		} else
600*0Sstevel@tonic-gate 			return (E_REQUEST_DENIED);
601*0Sstevel@tonic-gate 	}
602*0Sstevel@tonic-gate 
603*0Sstevel@tonic-gate 	if ((ret = wrap_ok(f)) != E_OK)
604*0Sstevel@tonic-gate 		return (ret);
605*0Sstevel@tonic-gate 
606*0Sstevel@tonic-gate 	Set(f, WIN_CHG);
607*0Sstevel@tonic-gate 
608*0Sstevel@tonic-gate 	at_end = AT_END(f);
609*0Sstevel@tonic-gate 
610*0Sstevel@tonic-gate 	if (at_end && !Status(c, GROWABLE) && Opt(c, O_AUTOSKIP))
611*0Sstevel@tonic-gate 		return (_field_navigation(_next_field, f));
612*0Sstevel@tonic-gate 
613*0Sstevel@tonic-gate 	if (at_end && Status(c, GROWABLE) && !_grow_field(c, 1))
614*0Sstevel@tonic-gate 		return (E_SYSTEM_ERROR);
615*0Sstevel@tonic-gate 
616*0Sstevel@tonic-gate 	(void) _next_char(f);
617*0Sstevel@tonic-gate 	return (E_OK);
618*0Sstevel@tonic-gate }
619