1 /****************************************************************************
2 * Copyright (c) 1998,2000 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 * Contact: http://www.familiepfeifer.de/Contact.aspx?Lang=en *
32 ****************************************************************************/
34 #include "form.priv.h"
36 MODULE_ID("$Id: frm_def.c,v 1.11 2002/07/06 15:33:27 juergen Exp $")
38 /* this can't be readonly */
39 static FORM default_form = {
50 ALL_FORM_OPTS, /* opts */
51 (WINDOW *)0, /* win */
52 (WINDOW *)0, /* sub */
54 (FIELD **)0, /* field */
55 (FIELD *)0, /* current */
56 (_PAGE *)0, /* page */
57 (char *)0, /* usrptr */
64 NCURSES_EXPORT_VAR(FORM *) _nc_Default_Form = &default_form;
66 /*---------------------------------------------------------------------------
68 | Function : static FIELD *Insert_Field_By_Position(
72 | Description : Insert new_field into sorted fieldlist with head "head"
73 | and return new head of sorted fieldlist. Sorting
74 | criteria is (row,column). This is a circular list.
76 | Return Values : New head of sorted fieldlist
77 +--------------------------------------------------------------------------*/
78 static FIELD *Insert_Field_By_Position(FIELD *newfield, FIELD *head)
80 FIELD *current, *newhead;
85 { /* empty list is trivial */
86 newhead = newfield->snext = newfield->sprev = newfield;
90 newhead = current = head;
91 while((current->frow < newfield->frow) ||
92 ((current->frow==newfield->frow) &&
93 (current->fcol < newfield->fcol)) )
95 current = current->snext;
97 { /* We cycled through. Reset head to indicate that */
102 /* we leave the loop with current pointing to the field after newfield*/
103 newfield->snext = current;
104 newfield->sprev = current->sprev;
105 newfield->snext->sprev = newfield;
106 newfield->sprev->snext = newfield;
113 /*---------------------------------------------------------------------------
114 | Facility : libnform
115 | Function : static void Disconnect_Fields(FORM *form)
117 | Description : Break association between form and array of fields.
120 +--------------------------------------------------------------------------*/
121 static void Disconnect_Fields( FORM * form )
127 for(fields=form->field;*fields;fields++)
129 if (form == (*fields)->form)
130 (*fields)->form = (FORM *)0;
133 form->rows = form->cols = 0;
134 form->maxfield = form->maxpage = -1;
135 form->field = (FIELD **)0;
138 form->page = (_PAGE *)0;
142 /*---------------------------------------------------------------------------
143 | Facility : libnform
144 | Function : static int Connect_Fields(FORM *form, FIELD **fields)
146 | Description : Set association between form and array of fields.
148 | Return Values : E_OK - no error
149 | E_CONNECTED - a field is already connected
150 | E_BAD_ARGUMENT - Invalid form pointer or field array
151 | E_SYSTEM_ERROR - not enough memory
152 +--------------------------------------------------------------------------*/
153 static int Connect_Fields(FORM * form, FIELD ** fields)
157 int maximum_row_in_field, maximum_col_in_field;
162 form->field = fields;
170 /* store formpointer in fields and count pages */
171 for(field_cnt=0;fields[field_cnt];field_cnt++)
173 if (fields[field_cnt]->form)
176 (fields[field_cnt]->status & _NEWPAGE))
178 fields[field_cnt]->form = form;
181 RETURN(E_BAD_ARGUMENT);
183 /* allocate page structures */
184 if ( (pg = (_PAGE *)malloc(page_nr * sizeof(_PAGE))) != (_PAGE *)0 )
189 RETURN(E_SYSTEM_ERROR);
191 /* Cycle through fields and calculate page boundaries as well as
193 for(j=0;j<field_cnt;j++)
199 if (fields[j]->status & _NEWPAGE)
207 maximum_row_in_field = fields[j]->frow + fields[j]->rows;
208 maximum_col_in_field = fields[j]->fcol + fields[j]->cols;
210 if (form->rows < maximum_row_in_field)
211 form->rows = maximum_row_in_field;
212 if (form->cols < maximum_col_in_field)
213 form->cols = maximum_col_in_field;
216 pg->pmax = field_cnt-1;
217 form->maxfield = field_cnt;
218 form->maxpage = page_nr;
220 /* Sort fields on form pages */
221 for(page_nr = 0;page_nr < form->maxpage; page_nr++)
223 FIELD *fld = (FIELD *)0;
224 for(j = form->page[page_nr].pmin;j <= form->page[page_nr].pmax;j++)
226 fields[j]->index = j;
227 fields[j]->page = page_nr;
228 fld = Insert_Field_By_Position(fields[j],fld);
230 form->page[page_nr].smin = fld->index;
231 form->page[page_nr].smax = fld->sprev->index;
236 /*---------------------------------------------------------------------------
237 | Facility : libnform
238 | Function : static int Associate_Fields(FORM *form, FIELD **fields)
240 | Description : Set association between form and array of fields.
241 | If there are fields, position to first active field.
243 | Return Values : E_OK - success
244 | any other - error occured
245 +--------------------------------------------------------------------------*/
246 INLINE static int Associate_Fields(FORM *form, FIELD **fields)
248 int res = Connect_Fields(form,fields);
254 form_driver(form,FIRST_ACTIVE_MAGIC);
259 form->current = (FIELD *)0;
265 /*---------------------------------------------------------------------------
266 | Facility : libnform
267 | Function : FORM *new_form( FIELD **fields )
269 | Description : Create new form with given array of fields.
271 | Return Values : Pointer to form. NULL if error occured.
272 +--------------------------------------------------------------------------*/
273 NCURSES_EXPORT(FORM *)
274 new_form (FIELD ** fields)
276 int err = E_SYSTEM_ERROR;
278 FORM *form = (FORM *)malloc(sizeof(FORM));
282 *form = *_nc_Default_Form;
283 if ((err=Associate_Fields(form,fields))!=E_OK)
296 /*---------------------------------------------------------------------------
297 | Facility : libnform
298 | Function : int free_form( FORM *form )
300 | Description : Release internal memory associated with form.
302 | Return Values : E_OK - no error
303 | E_BAD_ARGUMENT - invalid form pointer
304 | E_POSTED - form is posted
305 +--------------------------------------------------------------------------*/
307 free_form (FORM * form)
310 RETURN(E_BAD_ARGUMENT);
312 if ( form->status & _POSTED)
315 Disconnect_Fields( form );
323 /*---------------------------------------------------------------------------
324 | Facility : libnform
325 | Function : int set_form_fields( FORM *form, FIELD **fields )
327 | Description : Set a new association of an array of fields to a form
329 | Return Values : E_OK - no error
330 | E_BAD_ARGUMENT - invalid form pointer
331 | E_POSTED - form is posted
332 +--------------------------------------------------------------------------*/
334 set_form_fields (FORM * form, FIELD ** fields)
340 RETURN(E_BAD_ARGUMENT);
342 if ( form->status & _POSTED )
346 Disconnect_Fields( form );
348 if( (res = Associate_Fields( form, fields )) != E_OK )
349 Connect_Fields( form, old );
354 /*---------------------------------------------------------------------------
355 | Facility : libnform
356 | Function : FIELD **form_fields( const FORM *form )
358 | Description : Retrieve array of fields
360 | Return Values : Pointer to field array
361 +--------------------------------------------------------------------------*/
362 NCURSES_EXPORT(FIELD **)
363 form_fields (const FORM * form)
365 return (Normalize_Form( form )->field);
368 /*---------------------------------------------------------------------------
369 | Facility : libnform
370 | Function : int field_count( const FORM *form )
372 | Description : Retrieve number of fields
374 | Return Values : Number of fields, -1 if none are defined
375 +--------------------------------------------------------------------------*/
377 field_count (const FORM * form)
379 return (Normalize_Form( form )->maxfield);
382 /* frm_def.c ends here */