frm_def.c revision 184989
1235537Sgber/**************************************************************************** 2235537Sgber * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc. * 3235537Sgber * * 4235537Sgber * Permission is hereby granted, free of charge, to any person obtaining a * 5235537Sgber * copy of this software and associated documentation files (the * 6235537Sgber * "Software"), to deal in the Software without restriction, including * 7235537Sgber * without limitation the rights to use, copy, modify, merge, publish, * 8235537Sgber * distribute, distribute with modifications, sublicense, and/or sell * 9235537Sgber * copies of the Software, and to permit persons to whom the Software is * 10235537Sgber * furnished to do so, subject to the following conditions: * 11235537Sgber * * 12235537Sgber * The above copyright notice and this permission notice shall be included * 13235537Sgber * in all copies or substantial portions of the Software. * 14235537Sgber * * 15235537Sgber * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * 16235537Sgber * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * 17235537Sgber * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * 18235537Sgber * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * 19235537Sgber * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * 20235537Sgber * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * 21235537Sgber * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * 22235537Sgber * * 23235537Sgber * Except as contained in this notice, the name(s) of the above copyright * 24235537Sgber * holders shall not be used in advertising or otherwise to promote the * 25235537Sgber * sale, use or other dealings in this Software without prior written * 26235537Sgber * authorization. * 27235537Sgber ****************************************************************************/ 28235537Sgber 29235537Sgber/**************************************************************************** 30235537Sgber * Author: Juergen Pfeifer, 1995,1997 * 31235537Sgber ****************************************************************************/ 32235537Sgber 33235537Sgber#include "form.priv.h" 34235537Sgber 35235537SgberMODULE_ID("$Id: frm_def.c,v 1.23 2008/08/04 00:07:55 tom Exp $") 36235537Sgber 37235537Sgber/* this can't be readonly */ 38235537Sgberstatic FORM default_form = 39235537Sgber{ 40235537Sgber 0, /* status */ 41235537Sgber 0, /* rows */ 42235537Sgber 0, /* cols */ 43235537Sgber 0, /* currow */ 44235537Sgber 0, /* curcol */ 45235537Sgber 0, /* toprow */ 46235537Sgber 0, /* begincol */ 47235537Sgber -1, /* maxfield */ 48235537Sgber -1, /* maxpage */ 49235537Sgber -1, /* curpage */ 50235537Sgber ALL_FORM_OPTS, /* opts */ 51235537Sgber (WINDOW *)0, /* win */ 52235537Sgber (WINDOW *)0, /* sub */ 53235537Sgber (WINDOW *)0, /* w */ 54235537Sgber (FIELD **)0, /* field */ 55235537Sgber (FIELD *)0, /* current */ 56235537Sgber (_PAGE *) 0, /* page */ 57235537Sgber (char *)0, /* usrptr */ 58235537Sgber NULL, /* forminit */ 59235537Sgber NULL, /* formterm */ 60235537Sgber NULL, /* fieldinit */ 61235537Sgber NULL /* fieldterm */ 62235537Sgber}; 63235537Sgber 64235537SgberNCURSES_EXPORT_VAR(FORM *) _nc_Default_Form = &default_form; 65235537Sgber 66235537Sgber/*--------------------------------------------------------------------------- 67235537Sgber| Facility : libnform 68235537Sgber| Function : static FIELD *Insert_Field_By_Position( 69235537Sgber| FIELD *new_field, 70235537Sgber| FIELD *head ) 71235537Sgber| 72235537Sgber| Description : Insert new_field into sorted fieldlist with head "head" 73235537Sgber| and return new head of sorted fieldlist. Sorting 74235537Sgber| criteria is (row,column). This is a circular list. 75235537Sgber| 76235537Sgber| Return Values : New head of sorted fieldlist 77235537Sgber+--------------------------------------------------------------------------*/ 78235537Sgberstatic FIELD * 79235537SgberInsert_Field_By_Position(FIELD *newfield, FIELD *head) 80235537Sgber{ 81235537Sgber FIELD *current, *newhead; 82235537Sgber 83235537Sgber assert(newfield); 84235537Sgber 85235537Sgber if (!head) 86235537Sgber { /* empty list is trivial */ 87235537Sgber newhead = newfield->snext = newfield->sprev = newfield; 88235537Sgber } 89235537Sgber else 90235537Sgber { 91235537Sgber newhead = current = head; 92235537Sgber while ((current->frow < newfield->frow) || 93235537Sgber ((current->frow == newfield->frow) && 94235537Sgber (current->fcol < newfield->fcol))) 95235537Sgber { 96235537Sgber current = current->snext; 97235537Sgber if (current == head) 98235537Sgber { /* We cycled through. Reset head to indicate that */ 99235537Sgber head = (FIELD *)0; 100235537Sgber break; 101235537Sgber } 102235537Sgber } 103235537Sgber /* we leave the loop with current pointing to the field after newfield */ 104235537Sgber newfield->snext = current; 105235537Sgber newfield->sprev = current->sprev; 106235537Sgber newfield->snext->sprev = newfield; 107235537Sgber newfield->sprev->snext = newfield; 108235537Sgber if (current == head) 109235537Sgber newhead = newfield; 110235537Sgber } 111235537Sgber return (newhead); 112235537Sgber} 113235537Sgber 114235537Sgber/*--------------------------------------------------------------------------- 115235537Sgber| Facility : libnform 116235537Sgber| Function : static void Disconnect_Fields(FORM *form) 117235537Sgber| 118235537Sgber| Description : Break association between form and array of fields. 119235537Sgber| 120235537Sgber| Return Values : - 121235537Sgber+--------------------------------------------------------------------------*/ 122235537Sgberstatic void 123235537SgberDisconnect_Fields(FORM *form) 124235537Sgber{ 125235537Sgber if (form->field) 126235537Sgber { 127235537Sgber FIELD **fields; 128235537Sgber 129235537Sgber for (fields = form->field; *fields; fields++) 130235537Sgber { 131235537Sgber if (form == (*fields)->form) 132235537Sgber (*fields)->form = (FORM *)0; 133235537Sgber } 134235537Sgber 135235537Sgber form->rows = form->cols = 0; 136235537Sgber form->maxfield = form->maxpage = -1; 137235537Sgber form->field = (FIELD **)0; 138235537Sgber if (form->page) 139235537Sgber free(form->page); 140235537Sgber form->page = (_PAGE *) 0; 141235537Sgber } 142235537Sgber} 143235537Sgber 144235537Sgber/*--------------------------------------------------------------------------- 145235537Sgber| Facility : libnform 146235537Sgber| Function : static int Connect_Fields(FORM *form, FIELD **fields) 147235537Sgber| 148235537Sgber| Description : Set association between form and array of fields. 149235537Sgber| 150235537Sgber| Return Values : E_OK - no error 151235537Sgber| E_CONNECTED - a field is already connected 152235537Sgber| E_BAD_ARGUMENT - Invalid form pointer or field array 153235537Sgber| E_SYSTEM_ERROR - not enough memory 154235537Sgber+--------------------------------------------------------------------------*/ 155235537Sgberstatic int 156235537SgberConnect_Fields(FORM *form, FIELD **fields) 157235537Sgber{ 158235537Sgber int field_cnt, j; 159235537Sgber int page_nr; 160235537Sgber int maximum_row_in_field, maximum_col_in_field; 161235537Sgber _PAGE *pg; 162235537Sgber 163235537Sgber T((T_CALLED("Connect_Fields(%p,%p)"), form, fields)); 164235537Sgber 165235537Sgber assert(form); 166235537Sgber 167235537Sgber form->field = fields; 168235537Sgber form->maxfield = 0; 169235537Sgber form->maxpage = 0; 170235537Sgber 171235537Sgber if (!fields) 172235537Sgber RETURN(E_OK); 173235537Sgber 174235537Sgber page_nr = 0; 175235537Sgber /* store formpointer in fields and count pages */ 176235537Sgber for (field_cnt = 0; fields[field_cnt]; field_cnt++) 177235537Sgber { 178235537Sgber if (fields[field_cnt]->form) 179235537Sgber RETURN(E_CONNECTED); 180235537Sgber if (field_cnt == 0 || 181235537Sgber (fields[field_cnt]->status & _NEWPAGE)) 182235537Sgber page_nr++; 183235537Sgber fields[field_cnt]->form = form; 184235537Sgber } 185235537Sgber if (field_cnt == 0 || (short)field_cnt < 0) 186235537Sgber RETURN(E_BAD_ARGUMENT); 187235537Sgber 188235537Sgber /* allocate page structures */ 189235537Sgber if ((pg = typeMalloc(_PAGE, page_nr)) != (_PAGE *) 0) 190235537Sgber { 191235537Sgber T((T_CREATE("_PAGE %p"), pg)); 192235537Sgber form->page = pg; 193235537Sgber } 194235537Sgber else 195235537Sgber RETURN(E_SYSTEM_ERROR); 196235537Sgber 197235537Sgber /* Cycle through fields and calculate page boundaries as well as 198235537Sgber size of the form */ 199235537Sgber for (j = 0; j < field_cnt; j++) 200235537Sgber { 201235537Sgber if (j == 0) 202235537Sgber pg->pmin = j; 203235537Sgber else 204235537Sgber { 205235537Sgber if (fields[j]->status & _NEWPAGE) 206235537Sgber { 207235537Sgber pg->pmax = j - 1; 208235537Sgber pg++; 209235537Sgber pg->pmin = j; 210235537Sgber } 211235537Sgber } 212235537Sgber 213235537Sgber maximum_row_in_field = fields[j]->frow + fields[j]->rows; 214235537Sgber maximum_col_in_field = fields[j]->fcol + fields[j]->cols; 215235537Sgber 216235537Sgber if (form->rows < maximum_row_in_field) 217235537Sgber form->rows = maximum_row_in_field; 218235537Sgber if (form->cols < maximum_col_in_field) 219235537Sgber form->cols = maximum_col_in_field; 220235537Sgber } 221235537Sgber 222235537Sgber pg->pmax = field_cnt - 1; 223235537Sgber form->maxfield = field_cnt; 224235537Sgber form->maxpage = page_nr; 225235537Sgber 226235537Sgber /* Sort fields on form pages */ 227235537Sgber for (page_nr = 0; page_nr < form->maxpage; page_nr++) 228235537Sgber { 229235537Sgber FIELD *fld = (FIELD *)0; 230235537Sgber 231235537Sgber for (j = form->page[page_nr].pmin; j <= form->page[page_nr].pmax; j++) 232235537Sgber { 233235537Sgber fields[j]->index = j; 234235537Sgber fields[j]->page = page_nr; 235235537Sgber fld = Insert_Field_By_Position(fields[j], fld); 236235537Sgber } 237235537Sgber if (fld) 238235537Sgber { 239235537Sgber form->page[page_nr].smin = fld->index; 240235537Sgber form->page[page_nr].smax = fld->sprev->index; 241235537Sgber } 242235537Sgber else 243235537Sgber { 244235537Sgber form->page[page_nr].smin = 0; 245235537Sgber form->page[page_nr].smax = 0; 246235537Sgber } 247235537Sgber } 248235537Sgber RETURN(E_OK); 249235537Sgber} 250235537Sgber 251235537Sgber/*--------------------------------------------------------------------------- 252235537Sgber| Facility : libnform 253235537Sgber| Function : static int Associate_Fields(FORM *form, FIELD **fields) 254235537Sgber| 255235537Sgber| Description : Set association between form and array of fields. 256235537Sgber| If there are fields, position to first active field. 257235537Sgber| 258235537Sgber| Return Values : E_OK - success 259235537Sgber| E_BAD_ARGUMENT - Invalid form pointer or field array 260235537Sgber| E_CONNECTED - a field is already connected 261235537Sgber| E_SYSTEM_ERROR - not enough memory 262235537Sgber+--------------------------------------------------------------------------*/ 263235537SgberNCURSES_INLINE static int 264235537SgberAssociate_Fields(FORM *form, FIELD **fields) 265235537Sgber{ 266235537Sgber int res = Connect_Fields(form, fields); 267235537Sgber 268235537Sgber if (res == E_OK) 269235537Sgber { 270235537Sgber if (form->maxpage > 0) 271235537Sgber { 272235537Sgber form->curpage = 0; 273235537Sgber form_driver(form, FIRST_ACTIVE_MAGIC); 274235537Sgber } 275235537Sgber else 276235537Sgber { 277235537Sgber form->curpage = -1; 278235537Sgber form->current = (FIELD *)0; 279235537Sgber } 280235537Sgber } 281235537Sgber return (res); 282235537Sgber} 283235537Sgber 284235537Sgber/*--------------------------------------------------------------------------- 285235537Sgber| Facility : libnform 286235537Sgber| Function : FORM *new_form( FIELD **fields ) 287235537Sgber| 288235537Sgber| Description : Create new form with given array of fields. 289235537Sgber| 290235537Sgber| Return Values : Pointer to form. NULL if error occurred. 291235537Sgber! Set errno: 292235537Sgber| E_OK - success 293235537Sgber| E_BAD_ARGUMENT - Invalid form pointer or field array 294235537Sgber| E_CONNECTED - a field is already connected 295235537Sgber| E_SYSTEM_ERROR - not enough memory 296235537Sgber+--------------------------------------------------------------------------*/ 297235537SgberNCURSES_EXPORT(FORM *) 298235537Sgbernew_form(FIELD **fields) 299235537Sgber{ 300235537Sgber int err = E_SYSTEM_ERROR; 301235537Sgber 302235537Sgber FORM *form = typeMalloc(FORM, 1); 303235537Sgber 304235537Sgber T((T_CALLED("new_form(%p)"), fields)); 305235537Sgber if (form) 306235537Sgber { 307235537Sgber T((T_CREATE("form %p"), form)); 308235537Sgber *form = *_nc_Default_Form; 309235537Sgber if ((err = Associate_Fields(form, fields)) != E_OK) 310235537Sgber { 311235537Sgber free_form(form); 312235537Sgber form = (FORM *)0; 313235537Sgber } 314235537Sgber } 315235537Sgber 316235537Sgber if (!form) 317236188Smarcel SET_ERROR(err); 318236188Smarcel 319235537Sgber returnForm(form); 320236188Smarcel} 321236188Smarcel 322236188Smarcel/*--------------------------------------------------------------------------- 323236188Smarcel| Facility : libnform 324236188Smarcel| Function : int free_form( FORM *form ) 325235537Sgber| 326235537Sgber| Description : Release internal memory associated with form. 327235537Sgber| 328235537Sgber| Return Values : E_OK - no error 329235537Sgber| E_BAD_ARGUMENT - invalid form pointer 330235537Sgber| E_POSTED - form is posted 331235537Sgber+--------------------------------------------------------------------------*/ 332235537SgberNCURSES_EXPORT(int) 333235537Sgberfree_form(FORM *form) 334235537Sgber{ 335235537Sgber T((T_CALLED("free_form(%p)"), form)); 336235537Sgber 337235537Sgber if (!form) 338235537Sgber RETURN(E_BAD_ARGUMENT); 339235537Sgber 340235537Sgber if (form->status & _POSTED) 341235537Sgber RETURN(E_POSTED); 342235537Sgber 343235537Sgber Disconnect_Fields(form); 344235537Sgber if (form->page) 345235537Sgber free(form->page); 346235537Sgber free(form); 347235537Sgber 348235537Sgber RETURN(E_OK); 349235537Sgber} 350235537Sgber 351235537Sgber/*--------------------------------------------------------------------------- 352235537Sgber| Facility : libnform 353235537Sgber| Function : int set_form_fields( FORM *form, FIELD **fields ) 354235537Sgber| 355235537Sgber| Description : Set a new association of an array of fields to a form 356235537Sgber| 357235537Sgber| Return Values : E_OK - no error 358235537Sgber| E_BAD_ARGUMENT - Invalid form pointer or field array 359235537Sgber| E_CONNECTED - a field is already connected 360235537Sgber| E_POSTED - form is posted 361235537Sgber| E_SYSTEM_ERROR - not enough memory 362235537Sgber+--------------------------------------------------------------------------*/ 363235537SgberNCURSES_EXPORT(int) 364235537Sgberset_form_fields(FORM *form, FIELD **fields) 365235537Sgber{ 366235537Sgber FIELD **old; 367235537Sgber int res; 368235537Sgber 369235537Sgber T((T_CALLED("set_form_fields(%p,%p)"), form, fields)); 370235537Sgber 371235537Sgber if (!form) 372235537Sgber RETURN(E_BAD_ARGUMENT); 373235537Sgber 374235537Sgber if (form->status & _POSTED) 375235537Sgber RETURN(E_POSTED); 376235537Sgber 377235537Sgber old = form->field; 378235537Sgber Disconnect_Fields(form); 379235537Sgber 380235537Sgber if ((res = Associate_Fields(form, fields)) != E_OK) 381235537Sgber Connect_Fields(form, old); 382235537Sgber 383235537Sgber RETURN(res); 384235537Sgber} 385235537Sgber 386235537Sgber/*--------------------------------------------------------------------------- 387235537Sgber| Facility : libnform 388235537Sgber| Function : FIELD **form_fields( const FORM *form ) 389235537Sgber| 390235537Sgber| Description : Retrieve array of fields 391235537Sgber| 392235537Sgber| Return Values : Pointer to field array 393235537Sgber+--------------------------------------------------------------------------*/ 394235537SgberNCURSES_EXPORT(FIELD **) 395235537Sgberform_fields(const FORM *form) 396235537Sgber{ 397235537Sgber T((T_CALLED("form_field(%p)"), form)); 398235537Sgber returnFieldPtr(Normalize_Form(form)->field); 399235537Sgber} 400235537Sgber 401235537Sgber/*--------------------------------------------------------------------------- 402235537Sgber| Facility : libnform 403235537Sgber| Function : int field_count( const FORM *form ) 404235537Sgber| 405235537Sgber| Description : Retrieve number of fields 406235537Sgber| 407235537Sgber| Return Values : Number of fields, -1 if none are defined 408235537Sgber+--------------------------------------------------------------------------*/ 409235537SgberNCURSES_EXPORT(int) 410235537Sgberfield_count(const FORM *form) 411235537Sgber{ 412235537Sgber T((T_CALLED("field_count(%p)"), form)); 413235537Sgber 414235537Sgber returnCode(Normalize_Form(form)->maxfield); 415235537Sgber} 416235537Sgber 417235537Sgber/* frm_def.c ends here */ 418235537Sgber