frm_def.c revision 166124
150276Speter/**************************************************************************** 2166124Srafan * Copyright (c) 1998-2005,2006 Free Software Foundation, Inc. * 350276Speter * * 450276Speter * Permission is hereby granted, free of charge, to any person obtaining a * 550276Speter * copy of this software and associated documentation files (the * 650276Speter * "Software"), to deal in the Software without restriction, including * 750276Speter * without limitation the rights to use, copy, modify, merge, publish, * 850276Speter * distribute, distribute with modifications, sublicense, and/or sell * 950276Speter * copies of the Software, and to permit persons to whom the Software is * 1050276Speter * furnished to do so, subject to the following conditions: * 1150276Speter * * 1250276Speter * The above copyright notice and this permission notice shall be included * 1350276Speter * in all copies or substantial portions of the Software. * 1450276Speter * * 1550276Speter * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * 1650276Speter * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * 1750276Speter * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * 1850276Speter * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * 1950276Speter * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * 2050276Speter * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * 2150276Speter * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * 2250276Speter * * 2350276Speter * Except as contained in this notice, the name(s) of the above copyright * 2450276Speter * holders shall not be used in advertising or otherwise to promote the * 2550276Speter * sale, use or other dealings in this Software without prior written * 2650276Speter * authorization. * 2750276Speter ****************************************************************************/ 2850276Speter 2950276Speter/**************************************************************************** 30166124Srafan * Author: Juergen Pfeifer, 1995,1997 * 3150276Speter ****************************************************************************/ 3250276Speter 3350276Speter#include "form.priv.h" 3450276Speter 35166124SrafanMODULE_ID("$Id: frm_def.c,v 1.20 2006/11/04 16:57:15 tom Exp $") 3650276Speter 3750276Speter/* this can't be readonly */ 38166124Srafanstatic FORM default_form = 39166124Srafan{ 40166124Srafan 0, /* status */ 41166124Srafan 0, /* rows */ 42166124Srafan 0, /* cols */ 43166124Srafan 0, /* currow */ 44166124Srafan 0, /* curcol */ 45166124Srafan 0, /* toprow */ 46166124Srafan 0, /* begincol */ 47166124Srafan -1, /* maxfield */ 48166124Srafan -1, /* maxpage */ 49166124Srafan -1, /* curpage */ 50166124Srafan ALL_FORM_OPTS, /* opts */ 51166124Srafan (WINDOW *)0, /* win */ 52166124Srafan (WINDOW *)0, /* sub */ 53166124Srafan (WINDOW *)0, /* w */ 54166124Srafan (FIELD **)0, /* field */ 55166124Srafan (FIELD *)0, /* current */ 56166124Srafan (_PAGE *) 0, /* page */ 57166124Srafan (char *)0, /* usrptr */ 58166124Srafan NULL, /* forminit */ 59166124Srafan NULL, /* formterm */ 60166124Srafan NULL, /* fieldinit */ 61166124Srafan NULL /* fieldterm */ 6250276Speter}; 6350276Speter 6476726SpeterNCURSES_EXPORT_VAR(FORM *) _nc_Default_Form = &default_form; 6550276Speter 6650276Speter/*--------------------------------------------------------------------------- 6750276Speter| Facility : libnform 6850276Speter| Function : static FIELD *Insert_Field_By_Position( 6950276Speter| FIELD *new_field, 7050276Speter| FIELD *head ) 7150276Speter| 7250276Speter| Description : Insert new_field into sorted fieldlist with head "head" 7350276Speter| and return new head of sorted fieldlist. Sorting 7450276Speter| criteria is (row,column). This is a circular list. 7550276Speter| 7650276Speter| Return Values : New head of sorted fieldlist 7750276Speter+--------------------------------------------------------------------------*/ 78166124Srafanstatic FIELD * 79166124SrafanInsert_Field_By_Position(FIELD *newfield, FIELD *head) 8050276Speter{ 8150276Speter FIELD *current, *newhead; 82166124Srafan 8350276Speter assert(newfield); 8450276Speter 8550276Speter if (!head) 86166124Srafan { /* empty list is trivial */ 8750276Speter newhead = newfield->snext = newfield->sprev = newfield; 8850276Speter } 8950276Speter else 9050276Speter { 9150276Speter newhead = current = head; 92166124Srafan while ((current->frow < newfield->frow) || 93166124Srafan ((current->frow == newfield->frow) && 94166124Srafan (current->fcol < newfield->fcol))) 9550276Speter { 9650276Speter current = current->snext; 97166124Srafan if (current == head) 98166124Srafan { /* We cycled through. Reset head to indicate that */ 9950276Speter head = (FIELD *)0; 10050276Speter break; 10150276Speter } 10250276Speter } 103166124Srafan /* we leave the loop with current pointing to the field after newfield */ 104166124Srafan newfield->snext = current; 105166124Srafan newfield->sprev = current->sprev; 10650276Speter newfield->snext->sprev = newfield; 10750276Speter newfield->sprev->snext = newfield; 108166124Srafan if (current == head) 10950276Speter newhead = newfield; 11050276Speter } 111166124Srafan return (newhead); 11250276Speter} 11350276Speter 11450276Speter/*--------------------------------------------------------------------------- 11550276Speter| Facility : libnform 11650276Speter| Function : static void Disconnect_Fields(FORM *form) 11750276Speter| 11850276Speter| Description : Break association between form and array of fields. 11950276Speter| 12050276Speter| Return Values : - 12150276Speter+--------------------------------------------------------------------------*/ 122166124Srafanstatic void 123166124SrafanDisconnect_Fields(FORM *form) 12450276Speter{ 12550276Speter if (form->field) 12650276Speter { 12750276Speter FIELD **fields; 12850276Speter 129166124Srafan for (fields = form->field; *fields; fields++) 13050276Speter { 131166124Srafan if (form == (*fields)->form) 13250276Speter (*fields)->form = (FORM *)0; 13350276Speter } 134166124Srafan 13550276Speter form->rows = form->cols = 0; 13650276Speter form->maxfield = form->maxpage = -1; 13750276Speter form->field = (FIELD **)0; 138166124Srafan if (form->page) 13950276Speter free(form->page); 140166124Srafan form->page = (_PAGE *) 0; 141166124Srafan } 14250276Speter} 14350276Speter 14450276Speter/*--------------------------------------------------------------------------- 14550276Speter| Facility : libnform 14650276Speter| Function : static int Connect_Fields(FORM *form, FIELD **fields) 14750276Speter| 14850276Speter| Description : Set association between form and array of fields. 14950276Speter| 15050276Speter| Return Values : E_OK - no error 15150276Speter| E_CONNECTED - a field is already connected 15250276Speter| E_BAD_ARGUMENT - Invalid form pointer or field array 15350276Speter| E_SYSTEM_ERROR - not enough memory 15450276Speter+--------------------------------------------------------------------------*/ 155166124Srafanstatic int 156166124SrafanConnect_Fields(FORM *form, FIELD **fields) 15750276Speter{ 15850276Speter int field_cnt, j; 15950276Speter int page_nr; 16050276Speter int maximum_row_in_field, maximum_col_in_field; 16150276Speter _PAGE *pg; 162166124Srafan 163166124Srafan T((T_CALLED("Connect_Fields(%p,%p)"), form, fields)); 164166124Srafan 16550276Speter assert(form); 16650276Speter 167166124Srafan form->field = fields; 16850276Speter form->maxfield = 0; 169166124Srafan form->maxpage = 0; 17050276Speter 17150276Speter if (!fields) 17250276Speter RETURN(E_OK); 173166124Srafan 17450276Speter page_nr = 0; 17550276Speter /* store formpointer in fields and count pages */ 176166124Srafan for (field_cnt = 0; fields[field_cnt]; field_cnt++) 17750276Speter { 178166124Srafan if (fields[field_cnt]->form) 17950276Speter RETURN(E_CONNECTED); 180166124Srafan if (field_cnt == 0 || 181166124Srafan (fields[field_cnt]->status & _NEWPAGE)) 18250276Speter page_nr++; 18350276Speter fields[field_cnt]->form = form; 184166124Srafan } 185166124Srafan if (field_cnt == 0 || (short)field_cnt < 0) 18650276Speter RETURN(E_BAD_ARGUMENT); 187166124Srafan 18850276Speter /* allocate page structures */ 189166124Srafan if ((pg = (_PAGE *) malloc(page_nr * sizeof(_PAGE))) != (_PAGE *) 0) 19050276Speter { 19150276Speter form->page = pg; 19250276Speter } 19350276Speter else 19450276Speter RETURN(E_SYSTEM_ERROR); 195166124Srafan 19650276Speter /* Cycle through fields and calculate page boundaries as well as 19750276Speter size of the form */ 198166124Srafan for (j = 0; j < field_cnt; j++) 19950276Speter { 200166124Srafan if (j == 0) 20150276Speter pg->pmin = j; 20250276Speter else 20350276Speter { 20450276Speter if (fields[j]->status & _NEWPAGE) 20550276Speter { 206166124Srafan pg->pmax = j - 1; 20750276Speter pg++; 20850276Speter pg->pmin = j; 20950276Speter } 21050276Speter } 211166124Srafan 21250276Speter maximum_row_in_field = fields[j]->frow + fields[j]->rows; 21350276Speter maximum_col_in_field = fields[j]->fcol + fields[j]->cols; 214166124Srafan 215166124Srafan if (form->rows < maximum_row_in_field) 21650276Speter form->rows = maximum_row_in_field; 217166124Srafan if (form->cols < maximum_col_in_field) 21850276Speter form->cols = maximum_col_in_field; 21950276Speter } 220166124Srafan 221166124Srafan pg->pmax = field_cnt - 1; 22250276Speter form->maxfield = field_cnt; 223166124Srafan form->maxpage = page_nr; 224166124Srafan 22550276Speter /* Sort fields on form pages */ 226166124Srafan for (page_nr = 0; page_nr < form->maxpage; page_nr++) 22750276Speter { 22850276Speter FIELD *fld = (FIELD *)0; 229166124Srafan 230166124Srafan for (j = form->page[page_nr].pmin; j <= form->page[page_nr].pmax; j++) 23150276Speter { 23250276Speter fields[j]->index = j; 233166124Srafan fields[j]->page = page_nr; 234166124Srafan fld = Insert_Field_By_Position(fields[j], fld); 23550276Speter } 23650276Speter form->page[page_nr].smin = fld->index; 23750276Speter form->page[page_nr].smax = fld->sprev->index; 23850276Speter } 23950276Speter RETURN(E_OK); 24050276Speter} 24150276Speter 24250276Speter/*--------------------------------------------------------------------------- 24350276Speter| Facility : libnform 24450276Speter| Function : static int Associate_Fields(FORM *form, FIELD **fields) 24550276Speter| 24650276Speter| Description : Set association between form and array of fields. 24750276Speter| If there are fields, position to first active field. 24850276Speter| 24950276Speter| Return Values : E_OK - success 250166124Srafan| E_BAD_ARGUMENT - Invalid form pointer or field array 251166124Srafan| E_CONNECTED - a field is already connected 252166124Srafan| E_SYSTEM_ERROR - not enough memory 25350276Speter+--------------------------------------------------------------------------*/ 254166124SrafanNCURSES_INLINE static int 255166124SrafanAssociate_Fields(FORM *form, FIELD **fields) 25650276Speter{ 257166124Srafan int res = Connect_Fields(form, fields); 258166124Srafan 25950276Speter if (res == E_OK) 26050276Speter { 261166124Srafan if (form->maxpage > 0) 26250276Speter { 26350276Speter form->curpage = 0; 264166124Srafan form_driver(form, FIRST_ACTIVE_MAGIC); 26550276Speter } 26650276Speter else 26750276Speter { 26850276Speter form->curpage = -1; 26950276Speter form->current = (FIELD *)0; 270166124Srafan } 27150276Speter } 272166124Srafan return (res); 27350276Speter} 274166124Srafan 27550276Speter/*--------------------------------------------------------------------------- 27650276Speter| Facility : libnform 27750276Speter| Function : FORM *new_form( FIELD **fields ) 27850276Speter| 27950276Speter| Description : Create new form with given array of fields. 28050276Speter| 281166124Srafan| Return Values : Pointer to form. NULL if error occurred. 282166124Srafan! Set errno: 283166124Srafan| E_OK - success 284166124Srafan| E_BAD_ARGUMENT - Invalid form pointer or field array 285166124Srafan| E_CONNECTED - a field is already connected 286166124Srafan| E_SYSTEM_ERROR - not enough memory 28750276Speter+--------------------------------------------------------------------------*/ 28876726SpeterNCURSES_EXPORT(FORM *) 289166124Srafannew_form(FIELD **fields) 290166124Srafan{ 29150276Speter int err = E_SYSTEM_ERROR; 29250276Speter 29350276Speter FORM *form = (FORM *)malloc(sizeof(FORM)); 294166124Srafan 295166124Srafan T((T_CALLED("new_form(%p)"), fields)); 29650276Speter if (form) 29750276Speter { 29850276Speter *form = *_nc_Default_Form; 299166124Srafan if ((err = Associate_Fields(form, fields)) != E_OK) 30050276Speter { 30150276Speter free_form(form); 30250276Speter form = (FORM *)0; 30350276Speter } 30450276Speter } 30550276Speter 30650276Speter if (!form) 30750276Speter SET_ERROR(err); 308166124Srafan 309166124Srafan returnForm(form); 31050276Speter} 31150276Speter 31250276Speter/*--------------------------------------------------------------------------- 31350276Speter| Facility : libnform 31450276Speter| Function : int free_form( FORM *form ) 31550276Speter| 31650276Speter| Description : Release internal memory associated with form. 31750276Speter| 31850276Speter| Return Values : E_OK - no error 31950276Speter| E_BAD_ARGUMENT - invalid form pointer 32050276Speter| E_POSTED - form is posted 32150276Speter+--------------------------------------------------------------------------*/ 32276726SpeterNCURSES_EXPORT(int) 323166124Srafanfree_form(FORM *form) 32450276Speter{ 325166124Srafan T((T_CALLED("free_form(%p)"), form)); 326166124Srafan 327166124Srafan if (!form) 32850276Speter RETURN(E_BAD_ARGUMENT); 32950276Speter 330166124Srafan if (form->status & _POSTED) 33150276Speter RETURN(E_POSTED); 332166124Srafan 333166124Srafan Disconnect_Fields(form); 334166124Srafan if (form->page) 33550276Speter free(form->page); 33650276Speter free(form); 337166124Srafan 33850276Speter RETURN(E_OK); 33950276Speter} 34050276Speter 34150276Speter/*--------------------------------------------------------------------------- 34250276Speter| Facility : libnform 34350276Speter| Function : int set_form_fields( FORM *form, FIELD **fields ) 34450276Speter| 34550276Speter| Description : Set a new association of an array of fields to a form 34650276Speter| 347166124Srafan| Return Values : E_OK - no error 348166124Srafan| E_BAD_ARGUMENT - Invalid form pointer or field array 349166124Srafan| E_CONNECTED - a field is already connected 350166124Srafan| E_POSTED - form is posted 351166124Srafan| E_SYSTEM_ERROR - not enough memory 35250276Speter+--------------------------------------------------------------------------*/ 35376726SpeterNCURSES_EXPORT(int) 354166124Srafanset_form_fields(FORM *form, FIELD **fields) 35550276Speter{ 35650276Speter FIELD **old; 35750276Speter int res; 358166124Srafan 359166124Srafan T((T_CALLED("set_form_fields(%p,%p)"), form, fields)); 360166124Srafan 361166124Srafan if (!form) 36250276Speter RETURN(E_BAD_ARGUMENT); 36350276Speter 364166124Srafan if (form->status & _POSTED) 36550276Speter RETURN(E_POSTED); 366166124Srafan 36750276Speter old = form->field; 368166124Srafan Disconnect_Fields(form); 369166124Srafan 370166124Srafan if ((res = Associate_Fields(form, fields)) != E_OK) 371166124Srafan Connect_Fields(form, old); 372166124Srafan 37350276Speter RETURN(res); 37450276Speter} 375166124Srafan 37650276Speter/*--------------------------------------------------------------------------- 37750276Speter| Facility : libnform 37850276Speter| Function : FIELD **form_fields( const FORM *form ) 37950276Speter| 38050276Speter| Description : Retrieve array of fields 38150276Speter| 38250276Speter| Return Values : Pointer to field array 38350276Speter+--------------------------------------------------------------------------*/ 38476726SpeterNCURSES_EXPORT(FIELD **) 385166124Srafanform_fields(const FORM *form) 38650276Speter{ 387166124Srafan T((T_CALLED("form_field(%p)"), form)); 388166124Srafan returnFieldPtr(Normalize_Form(form)->field); 38950276Speter} 39050276Speter 39150276Speter/*--------------------------------------------------------------------------- 39250276Speter| Facility : libnform 39350276Speter| Function : int field_count( const FORM *form ) 39450276Speter| 39550276Speter| Description : Retrieve number of fields 39650276Speter| 39750276Speter| Return Values : Number of fields, -1 if none are defined 39850276Speter+--------------------------------------------------------------------------*/ 39976726SpeterNCURSES_EXPORT(int) 400166124Srafanfield_count(const FORM *form) 40150276Speter{ 402166124Srafan T((T_CALLED("field_count(%p)"), form)); 403166124Srafan 404166124Srafan returnCode(Normalize_Form(form)->maxfield); 40550276Speter} 40650276Speter 40750276Speter/* frm_def.c ends here */ 408