1 /****************************************************************************
2 * Copyright (c) 1998-2002,2003 Free Software Foundation, Inc. *
4 * Permission is hereby granted, free of charge, to any person obtaining a *
5 * copy of this software and associated documentation files (the *
6 * "Software"), to deal in the Software without restriction, including *
7 * without limitation the rights to use, copy, modify, merge, publish, *
8 * distribute, distribute with modifications, sublicense, and/or sell *
9 * copies of the Software, and to permit persons to whom the Software is *
10 * furnished to do so, subject to the following conditions: *
12 * The above copyright notice and this permission notice shall be included *
13 * in all copies or substantial portions of the Software. *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS *
16 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. *
18 * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR *
21 * THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
23 * Except as contained in this notice, the name(s) of the above copyright *
24 * holders shall not be used in advertising or otherwise to promote the *
25 * sale, use or other dealings in this Software without prior written *
27 ****************************************************************************/
29 /****************************************************************************
30 * Author: Juergen Pfeifer, 1995,1997 *
31 ****************************************************************************/
33 #include "form.priv.h"
35 MODULE_ID("$Id: frm_def.c,v 1.13 2003/11/08 20:37:53 tom Exp $")
37 /* this can't be readonly */
38 static FORM default_form
= {
49 ALL_FORM_OPTS
, /* opts */
50 (WINDOW
*)0, /* win */
51 (WINDOW
*)0, /* sub */
53 (FIELD
**)0, /* field */
54 (FIELD
*)0, /* current */
55 (_PAGE
*)0, /* page */
56 (char *)0, /* usrptr */
63 NCURSES_EXPORT_VAR(FORM
*) _nc_Default_Form
= &default_form
;
65 /*---------------------------------------------------------------------------
67 | Function : static FIELD *Insert_Field_By_Position(
71 | Description : Insert new_field into sorted fieldlist with head "head"
72 | and return new head of sorted fieldlist. Sorting
73 | criteria is (row,column). This is a circular list.
75 | Return Values : New head of sorted fieldlist
76 +--------------------------------------------------------------------------*/
77 static FIELD
*Insert_Field_By_Position(FIELD
*newfield
, FIELD
*head
)
79 FIELD
*current
, *newhead
;
84 { /* empty list is trivial */
85 newhead
= newfield
->snext
= newfield
->sprev
= newfield
;
89 newhead
= current
= head
;
90 while((current
->frow
< newfield
->frow
) ||
91 ((current
->frow
==newfield
->frow
) &&
92 (current
->fcol
< newfield
->fcol
)) )
94 current
= current
->snext
;
96 { /* We cycled through. Reset head to indicate that */
101 /* we leave the loop with current pointing to the field after newfield*/
102 newfield
->snext
= current
;
103 newfield
->sprev
= current
->sprev
;
104 newfield
->snext
->sprev
= newfield
;
105 newfield
->sprev
->snext
= newfield
;
112 /*---------------------------------------------------------------------------
113 | Facility : libnform
114 | Function : static void Disconnect_Fields(FORM *form)
116 | Description : Break association between form and array of fields.
119 +--------------------------------------------------------------------------*/
120 static void Disconnect_Fields( FORM
* form
)
126 for(fields
=form
->field
;*fields
;fields
++)
128 if (form
== (*fields
)->form
)
129 (*fields
)->form
= (FORM
*)0;
132 form
->rows
= form
->cols
= 0;
133 form
->maxfield
= form
->maxpage
= -1;
134 form
->field
= (FIELD
**)0;
137 form
->page
= (_PAGE
*)0;
141 /*---------------------------------------------------------------------------
142 | Facility : libnform
143 | Function : static int Connect_Fields(FORM *form, FIELD **fields)
145 | Description : Set association between form and array of fields.
147 | Return Values : E_OK - no error
148 | E_CONNECTED - a field is already connected
149 | E_BAD_ARGUMENT - Invalid form pointer or field array
150 | E_SYSTEM_ERROR - not enough memory
151 +--------------------------------------------------------------------------*/
152 static int Connect_Fields(FORM
* form
, FIELD
** fields
)
156 int maximum_row_in_field
, maximum_col_in_field
;
161 form
->field
= fields
;
169 /* store formpointer in fields and count pages */
170 for(field_cnt
=0;fields
[field_cnt
];field_cnt
++)
172 if (fields
[field_cnt
]->form
)
175 (fields
[field_cnt
]->status
& _NEWPAGE
))
177 fields
[field_cnt
]->form
= form
;
180 RETURN(E_BAD_ARGUMENT
);
182 /* allocate page structures */
183 if ( (pg
= (_PAGE
*)malloc(page_nr
* sizeof(_PAGE
))) != (_PAGE
*)0 )
188 RETURN(E_SYSTEM_ERROR
);
190 /* Cycle through fields and calculate page boundaries as well as
192 for(j
=0;j
<field_cnt
;j
++)
198 if (fields
[j
]->status
& _NEWPAGE
)
206 maximum_row_in_field
= fields
[j
]->frow
+ fields
[j
]->rows
;
207 maximum_col_in_field
= fields
[j
]->fcol
+ fields
[j
]->cols
;
209 if (form
->rows
< maximum_row_in_field
)
210 form
->rows
= maximum_row_in_field
;
211 if (form
->cols
< maximum_col_in_field
)
212 form
->cols
= maximum_col_in_field
;
215 pg
->pmax
= field_cnt
-1;
216 form
->maxfield
= field_cnt
;
217 form
->maxpage
= page_nr
;
219 /* Sort fields on form pages */
220 for(page_nr
= 0;page_nr
< form
->maxpage
; page_nr
++)
222 FIELD
*fld
= (FIELD
*)0;
223 for(j
= form
->page
[page_nr
].pmin
;j
<= form
->page
[page_nr
].pmax
;j
++)
225 fields
[j
]->index
= j
;
226 fields
[j
]->page
= page_nr
;
227 fld
= Insert_Field_By_Position(fields
[j
],fld
);
229 form
->page
[page_nr
].smin
= fld
->index
;
230 form
->page
[page_nr
].smax
= fld
->sprev
->index
;
235 /*---------------------------------------------------------------------------
236 | Facility : libnform
237 | Function : static int Associate_Fields(FORM *form, FIELD **fields)
239 | Description : Set association between form and array of fields.
240 | If there are fields, position to first active field.
242 | Return Values : E_OK - success
243 | any other - error occurred
244 +--------------------------------------------------------------------------*/
245 INLINE
static int Associate_Fields(FORM
*form
, FIELD
**fields
)
247 int res
= Connect_Fields(form
,fields
);
253 form_driver(form
,FIRST_ACTIVE_MAGIC
);
258 form
->current
= (FIELD
*)0;
264 /*---------------------------------------------------------------------------
265 | Facility : libnform
266 | Function : FORM *new_form( FIELD **fields )
268 | Description : Create new form with given array of fields.
270 | Return Values : Pointer to form. NULL if error occurred.
271 +--------------------------------------------------------------------------*/
272 NCURSES_EXPORT(FORM
*)
273 new_form (FIELD
** fields
)
275 int err
= E_SYSTEM_ERROR
;
277 FORM
*form
= (FORM
*)malloc(sizeof(FORM
));
281 *form
= *_nc_Default_Form
;
282 if ((err
=Associate_Fields(form
,fields
))!=E_OK
)
295 /*---------------------------------------------------------------------------
296 | Facility : libnform
297 | Function : int free_form( FORM *form )
299 | Description : Release internal memory associated with form.
301 | Return Values : E_OK - no error
302 | E_BAD_ARGUMENT - invalid form pointer
303 | E_POSTED - form is posted
304 +--------------------------------------------------------------------------*/
306 free_form (FORM
* form
)
309 RETURN(E_BAD_ARGUMENT
);
311 if ( form
->status
& _POSTED
)
314 Disconnect_Fields( form
);
322 /*---------------------------------------------------------------------------
323 | Facility : libnform
324 | Function : int set_form_fields( FORM *form, FIELD **fields )
326 | Description : Set a new association of an array of fields to a form
328 | Return Values : E_OK - no error
329 | E_BAD_ARGUMENT - invalid form pointer
330 | E_POSTED - form is posted
331 +--------------------------------------------------------------------------*/
333 set_form_fields (FORM
* form
, FIELD
** fields
)
339 RETURN(E_BAD_ARGUMENT
);
341 if ( form
->status
& _POSTED
)
345 Disconnect_Fields( form
);
347 if( (res
= Associate_Fields( form
, fields
)) != E_OK
)
348 Connect_Fields( form
, old
);
353 /*---------------------------------------------------------------------------
354 | Facility : libnform
355 | Function : FIELD **form_fields( const FORM *form )
357 | Description : Retrieve array of fields
359 | Return Values : Pointer to field array
360 +--------------------------------------------------------------------------*/
361 NCURSES_EXPORT(FIELD
**)
362 form_fields (const FORM
* form
)
364 return (Normalize_Form( form
)->field
);
367 /*---------------------------------------------------------------------------
368 | Facility : libnform
369 | Function : int field_count( const FORM *form )
371 | Description : Retrieve number of fields
373 | Return Values : Number of fields, -1 if none are defined
374 +--------------------------------------------------------------------------*/
376 field_count (const FORM
* form
)
378 return (Normalize_Form( form
)->maxfield
);
381 /* frm_def.c ends here */