150276Speter/**************************************************************************** 2262685Sdelphij * Copyright (c) 1998-2010,2012 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 35262685SdelphijMODULE_ID("$Id: frm_def.c,v 1.26 2012/03/11 00:37:16 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 163262629Sdelphij T((T_CALLED("Connect_Fields(%p,%p)"), (void *)form, (void *)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 */ 189174993Srafan if ((pg = typeMalloc(_PAGE, page_nr)) != (_PAGE *) 0) 19050276Speter { 191262629Sdelphij T((T_CREATE("_PAGE %p"), (void *)pg)); 19250276Speter form->page = pg; 19350276Speter } 19450276Speter else 19550276Speter RETURN(E_SYSTEM_ERROR); 196166124Srafan 19750276Speter /* Cycle through fields and calculate page boundaries as well as 19850276Speter size of the form */ 199166124Srafan for (j = 0; j < field_cnt; j++) 20050276Speter { 201166124Srafan if (j == 0) 202262685Sdelphij pg->pmin = (short) j; 20350276Speter else 20450276Speter { 20550276Speter if (fields[j]->status & _NEWPAGE) 20650276Speter { 207262685Sdelphij pg->pmax = (short) (j - 1); 20850276Speter pg++; 209262685Sdelphij pg->pmin = (short) j; 21050276Speter } 21150276Speter } 212166124Srafan 21350276Speter maximum_row_in_field = fields[j]->frow + fields[j]->rows; 21450276Speter maximum_col_in_field = fields[j]->fcol + fields[j]->cols; 215166124Srafan 216166124Srafan if (form->rows < maximum_row_in_field) 217262685Sdelphij form->rows = (short) maximum_row_in_field; 218166124Srafan if (form->cols < maximum_col_in_field) 219262685Sdelphij form->cols = (short) maximum_col_in_field; 22050276Speter } 221166124Srafan 222262685Sdelphij pg->pmax = (short) (field_cnt - 1); 223262685Sdelphij form->maxfield = (short) field_cnt; 224262685Sdelphij form->maxpage = (short) page_nr; 225166124Srafan 22650276Speter /* Sort fields on form pages */ 227166124Srafan for (page_nr = 0; page_nr < form->maxpage; page_nr++) 22850276Speter { 22950276Speter FIELD *fld = (FIELD *)0; 230166124Srafan 231166124Srafan for (j = form->page[page_nr].pmin; j <= form->page[page_nr].pmax; j++) 23250276Speter { 233262685Sdelphij fields[j]->index = (short) j; 234262685Sdelphij fields[j]->page = (short) page_nr; 235166124Srafan fld = Insert_Field_By_Position(fields[j], fld); 23650276Speter } 237184989Srafan if (fld) 238184989Srafan { 239184989Srafan form->page[page_nr].smin = fld->index; 240184989Srafan form->page[page_nr].smax = fld->sprev->index; 241184989Srafan } 242184989Srafan else 243184989Srafan { 244184989Srafan form->page[page_nr].smin = 0; 245184989Srafan form->page[page_nr].smax = 0; 246184989Srafan } 24750276Speter } 24850276Speter RETURN(E_OK); 24950276Speter} 25050276Speter 25150276Speter/*--------------------------------------------------------------------------- 25250276Speter| Facility : libnform 25350276Speter| Function : static int Associate_Fields(FORM *form, FIELD **fields) 25450276Speter| 25550276Speter| Description : Set association between form and array of fields. 25650276Speter| If there are fields, position to first active field. 25750276Speter| 25850276Speter| Return Values : E_OK - success 259166124Srafan| E_BAD_ARGUMENT - Invalid form pointer or field array 260166124Srafan| E_CONNECTED - a field is already connected 261166124Srafan| E_SYSTEM_ERROR - not enough memory 26250276Speter+--------------------------------------------------------------------------*/ 263166124SrafanNCURSES_INLINE static int 264166124SrafanAssociate_Fields(FORM *form, FIELD **fields) 26550276Speter{ 266166124Srafan int res = Connect_Fields(form, fields); 267166124Srafan 26850276Speter if (res == E_OK) 26950276Speter { 270166124Srafan if (form->maxpage > 0) 27150276Speter { 27250276Speter form->curpage = 0; 273166124Srafan form_driver(form, FIRST_ACTIVE_MAGIC); 27450276Speter } 27550276Speter else 27650276Speter { 27750276Speter form->curpage = -1; 27850276Speter form->current = (FIELD *)0; 279166124Srafan } 28050276Speter } 281166124Srafan return (res); 28250276Speter} 283166124Srafan 28450276Speter/*--------------------------------------------------------------------------- 28550276Speter| Facility : libnform 286262629Sdelphij| Function : FORM *new_form_sp(SCREEN* sp, FIELD** fields ) 28750276Speter| 28850276Speter| Description : Create new form with given array of fields. 28950276Speter| 290166124Srafan| Return Values : Pointer to form. NULL if error occurred. 291166124Srafan! Set errno: 292166124Srafan| E_OK - success 293166124Srafan| E_BAD_ARGUMENT - Invalid form pointer or field array 294166124Srafan| E_CONNECTED - a field is already connected 295166124Srafan| E_SYSTEM_ERROR - not enough memory 29650276Speter+--------------------------------------------------------------------------*/ 29776726SpeterNCURSES_EXPORT(FORM *) 298262629SdelphijNCURSES_SP_NAME(new_form) (NCURSES_SP_DCLx FIELD **fields) 299166124Srafan{ 30050276Speter int err = E_SYSTEM_ERROR; 301262629Sdelphij FORM *form = (FORM *)0; 30250276Speter 303262629Sdelphij T((T_CALLED("new_form(%p,%p)"), (void *)SP_PARM, (void *)fields)); 304166124Srafan 305262629Sdelphij if (IsValidScreen(SP_PARM)) 30650276Speter { 307262629Sdelphij form = typeMalloc(FORM, 1); 308262629Sdelphij 309262629Sdelphij if (form) 31050276Speter { 311262629Sdelphij T((T_CREATE("form %p"), (void *)form)); 312262629Sdelphij *form = *_nc_Default_Form; 313262629Sdelphij /* This ensures win and sub are always non-null, 314262629Sdelphij so we can derive always the SCREEN that this form is 315262629Sdelphij running on. */ 316262629Sdelphij form->win = StdScreen(SP_PARM); 317262629Sdelphij form->sub = StdScreen(SP_PARM); 318262629Sdelphij if ((err = Associate_Fields(form, fields)) != E_OK) 319262629Sdelphij { 320262629Sdelphij free_form(form); 321262629Sdelphij form = (FORM *)0; 322262629Sdelphij } 32350276Speter } 32450276Speter } 32550276Speter 32650276Speter if (!form) 32750276Speter SET_ERROR(err); 328166124Srafan 329166124Srafan returnForm(form); 33050276Speter} 33150276Speter 33250276Speter/*--------------------------------------------------------------------------- 33350276Speter| Facility : libnform 334262629Sdelphij| Function : FORM* new_form(FIELD** fields ) 335262629Sdelphij| 336262629Sdelphij| Description : Create new form with given array of fields. 337262629Sdelphij| 338262629Sdelphij| Return Values : Pointer to form. NULL if error occurred. 339262629Sdelphij! Set errno: 340262629Sdelphij| E_OK - success 341262629Sdelphij| E_BAD_ARGUMENT - Invalid form pointer or field array 342262629Sdelphij| E_CONNECTED - a field is already connected 343262629Sdelphij| E_SYSTEM_ERROR - not enough memory 344262629Sdelphij+--------------------------------------------------------------------------*/ 345262629Sdelphij#if NCURSES_SP_FUNCS 346262629SdelphijNCURSES_EXPORT(FORM *) 347262629Sdelphijnew_form(FIELD **fields) 348262629Sdelphij{ 349262629Sdelphij return NCURSES_SP_NAME(new_form) (CURRENT_SCREEN, fields); 350262629Sdelphij} 351262629Sdelphij#endif 352262629Sdelphij 353262629Sdelphij/*--------------------------------------------------------------------------- 354262629Sdelphij| Facility : libnform 35550276Speter| Function : int free_form( FORM *form ) 35650276Speter| 35750276Speter| Description : Release internal memory associated with form. 35850276Speter| 35950276Speter| Return Values : E_OK - no error 36050276Speter| E_BAD_ARGUMENT - invalid form pointer 36150276Speter| E_POSTED - form is posted 36250276Speter+--------------------------------------------------------------------------*/ 36376726SpeterNCURSES_EXPORT(int) 364166124Srafanfree_form(FORM *form) 36550276Speter{ 366262629Sdelphij T((T_CALLED("free_form(%p)"), (void *)form)); 367166124Srafan 368166124Srafan if (!form) 36950276Speter RETURN(E_BAD_ARGUMENT); 37050276Speter 371166124Srafan if (form->status & _POSTED) 37250276Speter RETURN(E_POSTED); 373166124Srafan 374166124Srafan Disconnect_Fields(form); 375166124Srafan if (form->page) 37650276Speter free(form->page); 37750276Speter free(form); 378166124Srafan 37950276Speter RETURN(E_OK); 38050276Speter} 38150276Speter 38250276Speter/*--------------------------------------------------------------------------- 38350276Speter| Facility : libnform 38450276Speter| Function : int set_form_fields( FORM *form, FIELD **fields ) 38550276Speter| 38650276Speter| Description : Set a new association of an array of fields to a form 38750276Speter| 388166124Srafan| Return Values : E_OK - no error 389166124Srafan| E_BAD_ARGUMENT - Invalid form pointer or field array 390166124Srafan| E_CONNECTED - a field is already connected 391166124Srafan| E_POSTED - form is posted 392166124Srafan| E_SYSTEM_ERROR - not enough memory 39350276Speter+--------------------------------------------------------------------------*/ 39476726SpeterNCURSES_EXPORT(int) 395166124Srafanset_form_fields(FORM *form, FIELD **fields) 39650276Speter{ 39750276Speter FIELD **old; 39850276Speter int res; 399166124Srafan 400262629Sdelphij T((T_CALLED("set_form_fields(%p,%p)"), (void *)form, (void *)fields)); 401166124Srafan 402166124Srafan if (!form) 40350276Speter RETURN(E_BAD_ARGUMENT); 40450276Speter 405166124Srafan if (form->status & _POSTED) 40650276Speter RETURN(E_POSTED); 407166124Srafan 40850276Speter old = form->field; 409166124Srafan Disconnect_Fields(form); 410166124Srafan 411166124Srafan if ((res = Associate_Fields(form, fields)) != E_OK) 412166124Srafan Connect_Fields(form, old); 413166124Srafan 41450276Speter RETURN(res); 41550276Speter} 416166124Srafan 41750276Speter/*--------------------------------------------------------------------------- 41850276Speter| Facility : libnform 41950276Speter| Function : FIELD **form_fields( const FORM *form ) 42050276Speter| 42150276Speter| Description : Retrieve array of fields 42250276Speter| 42350276Speter| Return Values : Pointer to field array 42450276Speter+--------------------------------------------------------------------------*/ 42576726SpeterNCURSES_EXPORT(FIELD **) 426166124Srafanform_fields(const FORM *form) 42750276Speter{ 428262629Sdelphij T((T_CALLED("form_field(%p)"), (const void *)form)); 429166124Srafan returnFieldPtr(Normalize_Form(form)->field); 43050276Speter} 43150276Speter 43250276Speter/*--------------------------------------------------------------------------- 43350276Speter| Facility : libnform 43450276Speter| Function : int field_count( const FORM *form ) 43550276Speter| 43650276Speter| Description : Retrieve number of fields 43750276Speter| 43850276Speter| Return Values : Number of fields, -1 if none are defined 43950276Speter+--------------------------------------------------------------------------*/ 44076726SpeterNCURSES_EXPORT(int) 441166124Srafanfield_count(const FORM *form) 44250276Speter{ 443262629Sdelphij T((T_CALLED("field_count(%p)"), (const void *)form)); 444166124Srafan 445166124Srafan returnCode(Normalize_Form(form)->maxfield); 44650276Speter} 44750276Speter 44850276Speter/* frm_def.c ends here */ 449