xref: /illumos-gate/usr/src/lib/libeti/form/common/field.c (revision 5243e3342f14ea9f300eadae1c8524571a933a1b)
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 /*
32  * Copyright (c) 2018, Joyent, Inc.
33  */
34 
35 /*LINTLIBRARY*/
36 
37 #include <sys/types.h>
38 #include <stdlib.h>
39 #include "utility.h"
40 
41 	/*
42 	 *  default field
43 	 */
44 
45 static FIELD default_field =
46 {
47 			0,			/* status	*/
48 			0,			/* rows		*/
49 			0,			/* cols		*/
50 			0,			/* frow		*/
51 			0,			/* fcol		*/
52 			0,			/* drows	*/
53 			0,			/* dcols	*/
54 			0,			/* maxgrow	*/
55 			0,			/* nrow		*/
56 			0,			/* nbuf		*/
57 			NO_JUSTIFICATION,	/* just		*/
58 			0,			/* page		*/
59 			0,			/* index	*/
60 			' ',			/* pad		*/
61 			A_NORMAL,		/* fore		*/
62 			A_NORMAL,		/* back		*/
63 			O_VISIBLE	|
64 			O_ACTIVE	|
65 			O_PUBLIC	|
66 			O_EDIT		|
67 			O_WRAP		|
68 			O_BLANK		|
69 			O_AUTOSKIP	|
70 			O_NULLOK	|
71 			O_PASSOK	|
72 			O_STATIC,		/* opts		*/
73 			(FIELD *)0,		/* snext	*/
74 			(FIELD *)0,		/* sprev	*/
75 			(FIELD *)0,		/* link		*/
76 			(FORM *)0,		/* form		*/
77 			(FIELDTYPE *)0,		/* type		*/
78 			(char *)0,		/* arg		*/
79 			(char *)0,		/* buf		*/
80 			(char *)0,		/* usrptr	*/
81 };
82 
83 FIELD * _DEFAULT_FIELD	= &default_field;
84 
85 	/*
86 	 *  MakeType
87 	 */
88 
89 static int
90 MakeType(FIELD *f, va_list *ap)
91 {
92 	int err = 0;
93 
94 	f->arg = MakeArg(f, ap, &err);	/* pick off type specific args	*/
95 
96 	if (err) {
97 		FreeArg(f);		/* release type specific args	*/
98 		f->type = (FIELDTYPE *)0;
99 		f->arg = (char *)0;
100 		return (FALSE);
101 	}
102 	IncrType(f->type);		/* increment reference count	*/
103 	return (TRUE);
104 }
105 
106 	/*
107 	 *  CopyType
108 	 */
109 
110 static int
111 CopyType(FIELD *f, FIELD *fsrc)
112 {
113 	int err = 0;
114 
115 	f->type = fsrc->type;		/* copy field type		*/
116 	f->arg = CopyArg(fsrc, &err);	/* copy type specific info	*/
117 
118 	if (err) {
119 		FreeArg(f);		/* release type specific args	*/
120 		f->type = (FIELDTYPE *)0;
121 		f->arg = (char *)0;
122 		return (FALSE);
123 	}
124 	IncrType(f->type);		/* increment reference count	*/
125 	return (TRUE);
126 }
127 
128 	/*
129 	 *  FreeType
130 	 */
131 
132 static void
133 FreeType(FIELD *f)
134 {
135 	DecrType(f->type);		/* decrement reference count	*/
136 	FreeArg(f);			/* release type specific args	*/
137 }
138 
139 	/*
140 	 *  new_field
141 	 */
142 
143 FIELD *
144 new_field(int rows, int cols, int frow, int fcol, int nrow, int nbuf)
145 
146 /* int rows;	 number of visible rows		*/
147 /* int cols;	 number of visible cols		*/
148 /* int frow;	 first row relative to form origin	*/
149 /* int fcol;	 first col relative to form origin	*/
150 /* int nrow;	 number of off screen rows		*/
151 /* int nbuf;	 number of additional buffers		*/
152 {
153 	FIELD *f = (FIELD *) 0;
154 	int i, size;
155 
156 	if (rows > 0 &&	cols > 0 && frow >= 0 && fcol >= 0 && nrow >= 0 &&
157 	    nbuf >= 0 && Alloc(f, FIELD)) {
158 		*f = *_DEFAULT_FIELD;
159 
160 		f->rows	= rows;
161 		f->cols	= cols;
162 		f->frow	= frow;
163 		f->fcol	= fcol;
164 		f->drows	= rows + nrow;
165 		f->dcols	= cols;
166 		f->nrow	= nrow;
167 		f->nbuf	= nbuf;
168 		f->link	= f;
169 
170 		if (CopyType(f, _DEFAULT_FIELD)) {
171 			size = TotalBuf(f);
172 
173 			if (arrayAlloc(Buf(f), size, char)) {
174 				(void) memset(Buf(f), ' ', size);
175 
176 				for (i = 0; i <= f->nbuf; ++i)
177 					*(Buffer(f, i + 1) - 1) = '\0';
178 				return (f);
179 			}
180 		}
181 	}
182 	(void) free_field(f);
183 	return ((FIELD *) 0);
184 }
185 
186 	/*
187 	 *  dup_field
188 	 */
189 
190 FIELD *
191 dup_field(FIELD *field, int frow, int fcol)
192 
193 /* FIELD * field;	 field to duplicate		*/
194 /* int frow;	 first row relative to form origin	*/
195 /* int fcol;	 first col relative to form origin	*/
196 {
197 	FIELD *f = (FIELD *) 0;
198 	int size;
199 
200 	if (field && frow >= 0 && fcol >= 0 && Alloc(f, FIELD)) {
201 		*f = *_DEFAULT_FIELD;
202 
203 		f->frow = frow;
204 		f->fcol = fcol;
205 		f->link = f;
206 
207 		f->rows	= field->rows;
208 		f->cols	= field->cols;
209 		f->drows = field->drows;
210 		f->dcols = field->dcols;
211 		f->maxgrow = field->maxgrow;
212 		f->nrow = field->nrow;
213 		f->nbuf	= field->nbuf;
214 		f->just = field->just;
215 		f->fore	= field->fore;
216 		f->back	= field->back;
217 		f->pad	= field->pad;
218 		f->opts	= field->opts;
219 		f->usrptr = field->usrptr;
220 		f->status = Status(field, GROWABLE);
221 
222 		if (CopyType(f, field)) {
223 			size = TotalBuf(f);
224 
225 			if (arrayAlloc(Buf(f), size, char)) {
226 				(void) memcpy(Buf(f), Buf(field), size);
227 				return (f);
228 			}
229 		}
230 	}
231 	(void) free_field(f);
232 	return ((FIELD *) 0);
233 }
234 
235 	/*
236 	 *  link_field
237 	 */
238 
239 FIELD *
240 link_field(FIELD *field, int frow, int fcol)
241 
242 /* FIELD * field;	 field to link to		*/
243 /* int frow;	 first row relative to form origin	*/
244 /* int fcol;	 first col relative to form origin	*/
245 {
246 	FIELD *f = (FIELD *) 0;
247 
248 	if (field && frow >= 0 && fcol >= 0 && Alloc(f, FIELD)) {
249 		*f = *_DEFAULT_FIELD;
250 
251 		f->frow = frow;
252 		f->fcol = fcol;
253 
254 		f->link = field->link;
255 		field->link = f;		/* add field to linked list */
256 
257 		f->buf	= field->buf;
258 		f->rows	= field->rows;
259 		f->cols	= field->cols;
260 		f->drows = field->drows;
261 		f->dcols = field->dcols;
262 		f->maxgrow = field->maxgrow;
263 		f->nrow	= field->nrow;
264 		f->nbuf	= field->nbuf;
265 		f->just	= field->just;
266 		f->fore	= field->fore;
267 		f->back	= field->back;
268 		f->pad	= field->pad;
269 		f->opts	= field->opts;
270 		f->usrptr = field->usrptr;
271 		f->status = Status(field, GROWABLE);
272 
273 		if (CopyType(f, field))
274 			return (f);
275 	}
276 	(void) free_field(f);
277 	return ((FIELD *) 0);
278 }
279 
280 	/*
281 	 *  free_field
282 	 */
283 
284 int
285 free_field(FIELD *f)
286 {
287 	FIELD *p;
288 
289 	if (!f)
290 		return (E_BAD_ARGUMENT);
291 
292 	if (f->form)
293 		return (E_CONNECTED);
294 
295 	if (f->link != f) {	/* check for linked field */
296 		for (p = f->link; p->link != f; p = p->link)
297 			;
298 		p->link = f->link;	/* delete from list	*/
299 	} else
300 		Free(Buf(f));		/* free buffer space	*/
301 
302 	FreeType(f);
303 	Free(f);
304 	return (E_OK);
305 }
306 
307 	/*
308 	 *  field_info
309 	 */
310 
311 int
312 field_info(FIELD *f, int *rows, int *cols, int *frow, int *fcol,
313 	int *nrow, int *nbuf)
314 
315 /* FIELD *f;	field whose information is wanted */
316 /* int *rows;	number of visible rows		*/
317 /* int *cols;	number of visible cols		*/
318 /* int *frow;	first row relative to form origin */
319 /* int *fcol;	first col relative to form origin */
320 /* int *nrow;	number of off screen rows	*/
321 /* int *nbuf;	number of additional buffers	*/
322 {
323 	if (!f)
324 		return (E_BAD_ARGUMENT);
325 
326 	*rows = f->rows;
327 	*cols = f->cols;
328 	*frow = f->frow;
329 	*fcol = f->fcol;
330 	*nrow = f->nrow;
331 	*nbuf = f->nbuf;
332 	return (E_OK);
333 }
334 
335 	/*
336 	 *  set_max_field
337 	 */
338 
339 int
340 set_max_field(FIELD *f, int max)
341 {
342 	BOOLEAN	onerow;
343 
344 	if (f == NULL)
345 		return (E_BAD_ARGUMENT);
346 
347 	onerow = OneRow(f);
348 
349 	if (max && ((onerow && f->dcols > max) ||
350 	    (!onerow && f->drows > max)))
351 		return (E_BAD_ARGUMENT);
352 
353 	f->maxgrow = max;
354 	Clr(f, GROWABLE);
355 
356 	if (!Opt(f, O_STATIC) && ((!max || onerow && f->dcols < max) ||
357 	    (!onerow && f->drows < max))) {
358 		Set(f, GROWABLE);
359 	}
360 
361 	return (E_OK);
362 }
363 
364 	/*
365 	 *  dynamic_field_info
366 	 */
367 
368 int
369 dynamic_field_info(FIELD *f, int *drows, int *dcols, int *max)
370 
371 /* FIELD *f;	 field whose information is wanted */
372 /* int *drows;	 number of actual rows	*/
373 /* int *dcols;	 number of actual cols	*/
374 /* int *max;	 maximum growth allowable, else -1 */
375 {
376 	if (!f)
377 		return (E_BAD_ARGUMENT);
378 
379 	*drows = f->drows;
380 	*dcols = f->dcols;
381 	*max   = f->maxgrow;
382 	return (E_OK);
383 }
384 
385 	/*
386 	 *  move_field
387 	 */
388 
389 int
390 move_field(FIELD *f, int frow, int fcol)
391 
392 /* FIELD *f;	field to move	*/
393 /* int frow;	first row relative to form origin */
394 /* int fcol;	first col relative to form origin */
395 {
396 	if (! f || frow < 0 || fcol < 0)
397 		return (E_BAD_ARGUMENT);
398 
399 	if (f->form)
400 		return (E_CONNECTED);
401 
402 	f->frow = frow;
403 	f->fcol = fcol;
404 	return (E_OK);
405 }
406 
407 	/*
408 	 *  set_field_type
409 	 */
410 
411 int
412 set_field_type(FIELD *f, FIELDTYPE *ft, ...)
413 {
414 	va_list		ap;
415 	int		v = E_SYSTEM_ERROR;
416 
417 	va_start(ap, ft);
418 	f = Field(f);
419 	FreeType(f);				/* free old type	*/
420 	f->type = ft;
421 
422 	if (MakeType(f, &ap))			/* set up new type	*/
423 		v = E_OK;
424 	va_end(ap);
425 	return (v);
426 }
427 
428 FIELDTYPE *
429 field_type(FIELD *f)
430 {
431 	return (Field(f)->type);
432 }
433 
434 char *
435 field_arg(FIELD *f)
436 {
437 	return (Field(f)->arg);
438 }
439 
440 	/*
441 	 *  set_new_page
442 	 */
443 
444 int
445 set_new_page(FIELD *f, int flag)
446 {
447 	f = Field(f);
448 
449 	if (f->form)
450 		return (E_CONNECTED);
451 
452 	if (flag)
453 		Set(f, NEW_PAGE);
454 	else
455 		Clr(f, NEW_PAGE);
456 
457 	return (E_OK);
458 }
459 
460 int
461 new_page(FIELD *f)
462 {
463 	if (Status(Field(f), NEW_PAGE))
464 		return (TRUE);
465 	else
466 		return (FALSE);
467 }
468