1 /*-----------------------------------------------------------------------------+
2 | The ncurses form library is Copyright (C) 1995-1997 |
3 | by Juergen Pfeifer <Juergen.Pfeifer@T-Online.de> |
4 | All Rights Reserved. |
6 | Permission to use, copy, modify, and distribute this software and its |
7 | documentation for any purpose and without fee is hereby granted, provided |
8 | that the above copyright notice appear in all copies and that both that |
9 | copyright notice and this permission notice appear in supporting |
10 | documentation, and that the name of the above listed copyright holder(s) not |
11 | be used in advertising or publicity pertaining to distribution of the |
12 | software without specific, written prior permission. |
14 | THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD TO |
15 | THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT- |
16 | NESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR |
17 | ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RE- |
18 | SULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, |
19 | NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH |
20 | THE USE OR PERFORMANCE OF THIS SOFTWARE. |
21 +-----------------------------------------------------------------------------*/
23 #include "form.priv.h"
25 MODULE_ID("$Id: fld_def.c,v 1.6 1997/05/01 16:47:54 juergen Exp $")
27 /* this can't be readonly */
28 static FIELD default_field = {
39 NO_JUSTIFICATION, /* just */
45 ALL_FIELD_OPTS, /* opts */
46 (FIELD *)0, /* snext */
47 (FIELD *)0, /* sprev */
48 (FIELD *)0, /* link */
50 (FIELDTYPE *)0, /* type */
53 (char *)0 /* usrptr */
56 FIELD *_nc_Default_Field = &default_field;
58 /*---------------------------------------------------------------------------
60 | Function : static TypeArgument *Make_Argument(
61 | const FIELDTYPE *typ,
65 | Description : Create an argument structure for the specified type.
66 | Use the type-dependant argument list to construct
69 | Return Values : Pointer to argument structure. Maybe NULL.
70 | In case of an error in *err an errorcounter is increased.
71 +--------------------------------------------------------------------------*/
72 static TypeArgument* Make_Argument(const FIELDTYPE *typ, va_list *ap, int *err)
74 TypeArgument *res = (TypeArgument *)0;
77 if (typ && (typ->status & _HAS_ARGS))
80 if (typ->status & _LINKED_TYPE)
82 p = (TypeArgument *)malloc(sizeof(TypeArgument));
85 p->left = Make_Argument(typ->left ,ap,err);
86 p->right = Make_Argument(typ->right,ap,err);
93 if ( !(res=(TypeArgument *)typ->makearg(ap)) )
100 /*---------------------------------------------------------------------------
101 | Facility : libnform
102 | Function : static TypeArgument *Copy_Argument(
103 | const FIELDTYPE *typ,
104 | const TypeArgument *argp,
107 | Description : Create a copy of an argument structure for the specified
110 | Return Values : Pointer to argument structure. Maybe NULL.
111 | In case of an error in *err an errorcounter is increased.
112 +--------------------------------------------------------------------------*/
113 static TypeArgument *Copy_Argument(const FIELDTYPE *typ,
114 const TypeArgument *argp, int *err)
116 TypeArgument *res = (TypeArgument *)0;
119 if ( typ && (typ->status & _HAS_ARGS) )
122 if (typ->status & _LINKED_TYPE)
124 p = (TypeArgument *)malloc(sizeof(TypeArgument));
127 p->left = Copy_Argument(typ,argp->left ,err);
128 p->right = Copy_Argument(typ,argp->right,err);
135 if (!(res = (TypeArgument *)(typ->copyarg((const void *)argp))))
142 /*---------------------------------------------------------------------------
143 | Facility : libnform
144 | Function : static void Free_Argument(
145 | const FIELDTYPE *typ,
146 | TypeArgument * argp )
148 | Description : Release memory associated with the argument structure
149 | for the given fieldtype.
152 +--------------------------------------------------------------------------*/
153 static void Free_Argument(const FIELDTYPE * typ, TypeArgument * argp)
155 if (!typ || !(typ->status & _HAS_ARGS))
158 if (typ->status & _LINKED_TYPE)
161 Free_Argument(typ->left ,argp->left );
162 Free_Argument(typ->right,argp->right);
167 typ->freearg((void *)argp);
171 /*---------------------------------------------------------------------------
172 | Facility : libnform
173 | Function : static bool Copy_Type( FIELD *new, FIELD const *old )
175 | Description : Copy argument structure of field old to field new
177 | Return Values : TRUE - copy worked
178 | FALSE - error occured
179 +--------------------------------------------------------------------------*/
180 static bool Copy_Type(FIELD *new, FIELD const *old)
186 new->type = old->type;
187 new->arg = (void *)Copy_Argument(old->type,(TypeArgument *)(old->arg),&err);
191 Free_Argument(new->type,(TypeArgument *)(new->arg));
192 new->type = (FIELDTYPE *)0;
193 new->arg = (void *)0;
204 /*---------------------------------------------------------------------------
205 | Facility : libnform
206 | Function : static void Free_Type( FIELD *field )
208 | Description : Release Argument structure for this field
211 +--------------------------------------------------------------------------*/
212 INLINE static void Free_Type(FIELD *field)
217 Free_Argument(field->type,(TypeArgument *)(field->arg));
220 /*---------------------------------------------------------------------------
221 | Facility : libnform
222 | Function : FIELD *new_field( int rows, int cols,
223 | int frow, int fcol,
224 | int nrow, int nbuf )
226 | Description : Create a new field with this many 'rows' and 'cols',
227 | starting at 'frow/fcol' in the subwindow of the form.
228 | Allocate 'nrow' off-screen rows and 'nbuf' additional
229 | buffers. If an error occurs, errno is set to
231 | E_BAD_ARGUMENT - invalid argument
232 | E_SYSTEM_ERROR - system error
234 | Return Values : Pointer to the new field or NULL if failure.
235 +--------------------------------------------------------------------------*/
236 FIELD *new_field(int rows, int cols, int frow, int fcol, int nrow, int nbuf)
238 FIELD *New_Field = (FIELD *)0;
239 int err = E_BAD_ARGUMENT;
247 ((err = E_SYSTEM_ERROR) != 0) && /* trick: this resets the default error */
248 (New_Field=(FIELD *)malloc(sizeof(FIELD))) )
250 *New_Field = default_field;
251 New_Field->rows = rows;
252 New_Field->cols = cols;
253 New_Field->drows = rows + nrow;
254 New_Field->dcols = cols;
255 New_Field->frow = frow;
256 New_Field->fcol = fcol;
257 New_Field->nrow = nrow;
258 New_Field->nbuf = nbuf;
259 New_Field->link = New_Field;
261 if (Copy_Type(New_Field,&default_field))
265 len = Total_Buffer_Size(New_Field);
266 if ((New_Field->buf = (char *)malloc(len)))
268 /* Prefill buffers with blanks and insert terminating zeroes
272 memset(New_Field->buf,' ',len);
273 for(i=0;i<=New_Field->nbuf;i++)
275 New_Field->buf[(New_Field->drows*New_Field->cols+1)*(i+1)-1]
284 free_field(New_Field);
290 /*---------------------------------------------------------------------------
291 | Facility : libnform
292 | Function : FIELD *dup_field(FIELD *field, int frow, int fcol)
294 | Description : Duplicates the field at the specified position. All
295 | field attributes and the buffers are copied.
296 | If an error occurs, errno is set to
298 | E_BAD_ARGUMENT - invalid argument
299 | E_SYSTEM_ERROR - system error
301 | Return Values : Pointer to the new field or NULL if failure
302 +--------------------------------------------------------------------------*/
303 FIELD *dup_field(FIELD * field, int frow, int fcol)
305 FIELD *New_Field = (FIELD *)0;
306 int err = E_BAD_ARGUMENT;
308 if (field && (frow>=0) && (fcol>=0) &&
309 ((err=E_SYSTEM_ERROR) != 0) && /* trick : this resets the default error */
310 (New_Field=(FIELD *)malloc(sizeof(FIELD))) )
312 *New_Field = default_field;
313 New_Field->frow = frow;
314 New_Field->fcol = fcol;
315 New_Field->link = New_Field;
316 New_Field->rows = field->rows;
317 New_Field->cols = field->cols;
318 New_Field->nrow = field->nrow;
319 New_Field->drows = field->drows;
320 New_Field->dcols = field->dcols;
321 New_Field->maxgrow = field->maxgrow;
322 New_Field->nbuf = field->nbuf;
323 New_Field->just = field->just;
324 New_Field->fore = field->fore;
325 New_Field->back = field->back;
326 New_Field->pad = field->pad;
327 New_Field->opts = field->opts;
328 New_Field->usrptr = field->usrptr;
330 if (Copy_Type(New_Field,field))
334 len = Total_Buffer_Size(New_Field);
335 if ( (New_Field->buf=(char *)malloc(len)) )
337 memcpy(New_Field->buf,field->buf,len);
344 free_field(New_Field);
350 /*---------------------------------------------------------------------------
351 | Facility : libnform
352 | Function : FIELD *link_field(FIELD *field, int frow, int fcol)
354 | Description : Duplicates the field at the specified position. The
355 | new field shares its buffers with the original one,
356 | the attributes are independent.
357 | If an error occurs, errno is set to
359 | E_BAD_ARGUMENT - invalid argument
360 | E_SYSTEM_ERROR - system error
362 | Return Values : Pointer to the new field or NULL if failure
363 +--------------------------------------------------------------------------*/
364 FIELD *link_field(FIELD * field, int frow, int fcol)
366 FIELD *New_Field = (FIELD *)0;
367 int err = E_BAD_ARGUMENT;
369 if (field && (frow>=0) && (fcol>=0) &&
370 ((err=E_SYSTEM_ERROR) != 0) && /* trick: this resets the default error */
371 (New_Field = (FIELD *)malloc(sizeof(FIELD))) )
373 *New_Field = default_field;
374 New_Field->frow = frow;
375 New_Field->fcol = fcol;
376 New_Field->link = field->link;
377 field->link = New_Field;
378 New_Field->buf = field->buf;
379 New_Field->rows = field->rows;
380 New_Field->cols = field->cols;
381 New_Field->nrow = field->nrow;
382 New_Field->nbuf = field->nbuf;
383 New_Field->drows = field->drows;
384 New_Field->dcols = field->dcols;
385 New_Field->maxgrow= field->maxgrow;
386 New_Field->just = field->just;
387 New_Field->fore = field->fore;
388 New_Field->back = field->back;
389 New_Field->pad = field->pad;
390 New_Field->opts = field->opts;
391 New_Field->usrptr = field->usrptr;
392 if (Copy_Type(New_Field,field))
397 free_field(New_Field);
403 /*---------------------------------------------------------------------------
404 | Facility : libnform
405 | Function : int free_field( FIELD *field )
407 | Description : Frees the storage allocated for the field.
409 | Return Values : E_OK - success
410 | E_BAD_ARGUMENT - invalid field pointer
411 | E_CONNECTED - field is connected
412 +--------------------------------------------------------------------------*/
413 int free_field(FIELD * field)
416 RETURN(E_BAD_ARGUMENT);
421 if (field == field->link)
430 for(f=field;f->link != field;f = f->link)
432 f->link = field->link;
439 /*---------------------------------------------------------------------------
440 | Facility : libnform
441 | Function : int field_info(const FIELD *field,
442 | int *rows, int *cols,
443 | int *frow, int *fcol,
444 | int *nrow, int *nbuf)
446 | Description : Retrieve infos about the fields creation parameters.
448 | Return Values : E_OK - success
449 | E_BAD_ARGUMENT - invalid field pointer
450 +--------------------------------------------------------------------------*/
451 int field_info(const FIELD *field,
452 int *rows, int *cols,
453 int *frow, int *fcol,
454 int *nrow, int *nbuf)
457 RETURN(E_BAD_ARGUMENT);
459 if (rows) *rows = field->rows;
460 if (cols) *cols = field->cols;
461 if (frow) *frow = field->frow;
462 if (fcol) *fcol = field->fcol;
463 if (nrow) *nrow = field->nrow;
464 if (nbuf) *nbuf = field->nbuf;
468 /*---------------------------------------------------------------------------
469 | Facility : libnform
470 | Function : int move_field(FIELD *field,int frow, int fcol)
472 | Description : Moves the disconnected field to the new location in
473 | the forms subwindow.
475 | Return Values : E_OK - success
476 | E_BAD_ARGUMENT - invalid argument passed
477 | E_CONNECTED - field is connected
478 +--------------------------------------------------------------------------*/
479 int move_field(FIELD *field, int frow, int fcol)
481 if ( !field || (frow<0) || (fcol<0) )
482 RETURN(E_BAD_ARGUMENT);
492 /*---------------------------------------------------------------------------
493 | Facility : libnform
494 | Function : int set_field_type(FIELD *field, FIELDTYPE *type,...)
496 | Description : Associate the specified fieldtype with the field.
497 | Certain field types take additional arguments. Look
498 | at the spec of the field types !
500 | Return Values : E_OK - success
501 | E_SYSTEM_ERROR - system error
502 +--------------------------------------------------------------------------*/
503 int set_field_type(FIELD *field,FIELDTYPE *type, ...)
506 int res = E_SYSTEM_ERROR;
511 Normalize_Field(field);
515 field->arg = (void *)Make_Argument(field->type,&ap,&err);
519 Free_Argument(field->type,(TypeArgument *)(field->arg));
520 field->type = (FIELDTYPE *)0;
521 field->arg = (void *)0;
534 /*---------------------------------------------------------------------------
535 | Facility : libnform
536 | Function : FIELDTYPE *field_type(const FIELD *field)
538 | Description : Retrieve the associated fieldtype for this field.
540 | Return Values : Pointer to fieldtype of NULL if none is defined.
541 +--------------------------------------------------------------------------*/
542 FIELDTYPE *field_type(const FIELD * field)
544 return Normalize_Field(field)->type;
547 /*---------------------------------------------------------------------------
548 | Facility : libnform
549 | Function : void *field_arg(const FIELD *field)
551 | Description : Retrieve pointer to the fields argument structure.
553 | Return Values : Pointer to structure or NULL if none is defined.
554 +--------------------------------------------------------------------------*/
555 void *field_arg(const FIELD * field)
557 return Normalize_Field(field)->arg;
560 /*---------------------------------------------------------------------------
561 | Facility : libnform
562 | Function : int set_max_field(FIELD *field, int maxgrow)
564 | Description : Set the maximum growth for a dynamic field. If maxgrow=0
565 | the field may grow to any possible size.
567 | Return Values : E_OK - success
568 | E_BAD_ARGUMENT - invalid argument
569 +--------------------------------------------------------------------------*/
570 int set_max_field(FIELD *field, int maxgrow)
572 if (!field || (maxgrow<0))
573 RETURN(E_BAD_ARGUMENT);
576 bool single_line_field = Single_Line_Field(field);
580 if (( single_line_field && (maxgrow < field->dcols)) ||
581 (!single_line_field && (maxgrow < field->drows)))
582 RETURN(E_BAD_ARGUMENT);
584 field->maxgrow = maxgrow;
585 field->status &= ~_MAY_GROW;
586 if (!(field->opts & O_STATIC))
589 ( single_line_field && (field->dcols < maxgrow)) ||
590 (!single_line_field && (field->drows < maxgrow)))
591 field->status |= _MAY_GROW;
597 /*---------------------------------------------------------------------------
598 | Facility : libnform
599 | Function : int dynamic_field_info(const FIELD *field,
600 | int *drows, int *dcols,
603 | Description : Retrieve informations about a dynamic fields current
604 | dynamic parameters.
606 | Return Values : E_OK - success
607 | E_BAD_ARGUMENT - invalid argument
608 +--------------------------------------------------------------------------*/
609 int dynamic_field_info(const FIELD *field,
610 int *drows, int *dcols, int *maxgrow)
613 RETURN(E_BAD_ARGUMENT);
615 if (drows) *drows = field->drows;
616 if (dcols) *dcols = field->dcols;
617 if (maxgrow) *maxgrow = field->maxgrow;
622 /*---------------------------------------------------------------------------
623 | Facility : libnform
624 | Function : int set_new_page(FIELD *field, bool new_page_flag)
626 | Description : Marks the field as the beginning of a new page of
629 | Return Values : E_OK - success
630 | E_CONNECTED - field is connected
631 +--------------------------------------------------------------------------*/
632 int set_new_page(FIELD * field, bool new_page_flag)
634 Normalize_Field(field);
639 field->status |= _NEWPAGE;
641 field->status &= ~_NEWPAGE;
646 /*---------------------------------------------------------------------------
647 | Facility : libnform
648 | Function : bool new_page(const FIELD *field)
650 | Description : Retrieve the info whether or not the field starts a
651 | new page on the form.
653 | Return Values : TRUE - field starts a new page
654 | FALSE - field doesn't start a new page
655 +--------------------------------------------------------------------------*/
656 bool new_page(const FIELD * field)
658 return (Normalize_Field(field)->status & _NEWPAGE) ? TRUE : FALSE;
661 /* fld_def.c ends here */