diff options
Diffstat (limited to 'ncurses-5.9/form/frm_def.c')
-rw-r--r-- | ncurses-5.9/form/frm_def.c | 448 |
1 files changed, 448 insertions, 0 deletions
diff --git a/ncurses-5.9/form/frm_def.c b/ncurses-5.9/form/frm_def.c new file mode 100644 index 0000000..9dfc82f --- /dev/null +++ b/ncurses-5.9/form/frm_def.c @@ -0,0 +1,448 @@ +/**************************************************************************** + * Copyright (c) 1998-2009,2010 Free Software Foundation, Inc. * + * * + * Permission is hereby granted, free of charge, to any person obtaining a * + * copy of this software and associated documentation files (the * + * "Software"), to deal in the Software without restriction, including * + * without limitation the rights to use, copy, modify, merge, publish, * + * distribute, distribute with modifications, sublicense, and/or sell * + * copies of the Software, and to permit persons to whom the Software is * + * furnished to do so, subject to the following conditions: * + * * + * The above copyright notice and this permission notice shall be included * + * in all copies or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * + * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * + * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + * * + * Except as contained in this notice, the name(s) of the above copyright * + * holders shall not be used in advertising or otherwise to promote the * + * sale, use or other dealings in this Software without prior written * + * authorization. * + ****************************************************************************/ + +/**************************************************************************** + * Author: Juergen Pfeifer, 1995,1997 * + ****************************************************************************/ + +#include "form.priv.h" + +MODULE_ID("$Id$") + +/* this can't be readonly */ +static FORM default_form = +{ + 0, /* status */ + 0, /* rows */ + 0, /* cols */ + 0, /* currow */ + 0, /* curcol */ + 0, /* toprow */ + 0, /* begincol */ + -1, /* maxfield */ + -1, /* maxpage */ + -1, /* curpage */ + ALL_FORM_OPTS, /* opts */ + (WINDOW *)0, /* win */ + (WINDOW *)0, /* sub */ + (WINDOW *)0, /* w */ + (FIELD **)0, /* field */ + (FIELD *)0, /* current */ + (_PAGE *) 0, /* page */ + (char *)0, /* usrptr */ + NULL, /* forminit */ + NULL, /* formterm */ + NULL, /* fieldinit */ + NULL /* fieldterm */ +}; + +NCURSES_EXPORT_VAR(FORM *) _nc_Default_Form = &default_form; + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static FIELD *Insert_Field_By_Position( +| FIELD *new_field, +| FIELD *head ) +| +| Description : Insert new_field into sorted fieldlist with head "head" +| and return new head of sorted fieldlist. Sorting +| criteria is (row,column). This is a circular list. +| +| Return Values : New head of sorted fieldlist ++--------------------------------------------------------------------------*/ +static FIELD * +Insert_Field_By_Position(FIELD *newfield, FIELD *head) +{ + FIELD *current, *newhead; + + assert(newfield); + + if (!head) + { /* empty list is trivial */ + newhead = newfield->snext = newfield->sprev = newfield; + } + else + { + newhead = current = head; + while ((current->frow < newfield->frow) || + ((current->frow == newfield->frow) && + (current->fcol < newfield->fcol))) + { + current = current->snext; + if (current == head) + { /* We cycled through. Reset head to indicate that */ + head = (FIELD *)0; + break; + } + } + /* we leave the loop with current pointing to the field after newfield */ + newfield->snext = current; + newfield->sprev = current->sprev; + newfield->snext->sprev = newfield; + newfield->sprev->snext = newfield; + if (current == head) + newhead = newfield; + } + return (newhead); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static void Disconnect_Fields(FORM *form) +| +| Description : Break association between form and array of fields. +| +| Return Values : - ++--------------------------------------------------------------------------*/ +static void +Disconnect_Fields(FORM *form) +{ + if (form->field) + { + FIELD **fields; + + for (fields = form->field; *fields; fields++) + { + if (form == (*fields)->form) + (*fields)->form = (FORM *)0; + } + + form->rows = form->cols = 0; + form->maxfield = form->maxpage = -1; + form->field = (FIELD **)0; + if (form->page) + free(form->page); + form->page = (_PAGE *) 0; + } +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int Connect_Fields(FORM *form, FIELD **fields) +| +| Description : Set association between form and array of fields. +| +| Return Values : E_OK - no error +| E_CONNECTED - a field is already connected +| E_BAD_ARGUMENT - Invalid form pointer or field array +| E_SYSTEM_ERROR - not enough memory ++--------------------------------------------------------------------------*/ +static int +Connect_Fields(FORM *form, FIELD **fields) +{ + int field_cnt, j; + int page_nr; + int maximum_row_in_field, maximum_col_in_field; + _PAGE *pg; + + T((T_CALLED("Connect_Fields(%p,%p)"), (void *)form, (void *)fields)); + + assert(form); + + form->field = fields; + form->maxfield = 0; + form->maxpage = 0; + + if (!fields) + RETURN(E_OK); + + page_nr = 0; + /* store formpointer in fields and count pages */ + for (field_cnt = 0; fields[field_cnt]; field_cnt++) + { + if (fields[field_cnt]->form) + RETURN(E_CONNECTED); + if (field_cnt == 0 || + (fields[field_cnt]->status & _NEWPAGE)) + page_nr++; + fields[field_cnt]->form = form; + } + if (field_cnt == 0 || (short)field_cnt < 0) + RETURN(E_BAD_ARGUMENT); + + /* allocate page structures */ + if ((pg = typeMalloc(_PAGE, page_nr)) != (_PAGE *) 0) + { + T((T_CREATE("_PAGE %p"), (void *)pg)); + form->page = pg; + } + else + RETURN(E_SYSTEM_ERROR); + + /* Cycle through fields and calculate page boundaries as well as + size of the form */ + for (j = 0; j < field_cnt; j++) + { + if (j == 0) + pg->pmin = j; + else + { + if (fields[j]->status & _NEWPAGE) + { + pg->pmax = j - 1; + pg++; + pg->pmin = j; + } + } + + maximum_row_in_field = fields[j]->frow + fields[j]->rows; + maximum_col_in_field = fields[j]->fcol + fields[j]->cols; + + if (form->rows < maximum_row_in_field) + form->rows = maximum_row_in_field; + if (form->cols < maximum_col_in_field) + form->cols = maximum_col_in_field; + } + + pg->pmax = field_cnt - 1; + form->maxfield = field_cnt; + form->maxpage = page_nr; + + /* Sort fields on form pages */ + for (page_nr = 0; page_nr < form->maxpage; page_nr++) + { + FIELD *fld = (FIELD *)0; + + for (j = form->page[page_nr].pmin; j <= form->page[page_nr].pmax; j++) + { + fields[j]->index = j; + fields[j]->page = page_nr; + fld = Insert_Field_By_Position(fields[j], fld); + } + if (fld) + { + form->page[page_nr].smin = fld->index; + form->page[page_nr].smax = fld->sprev->index; + } + else + { + form->page[page_nr].smin = 0; + form->page[page_nr].smax = 0; + } + } + RETURN(E_OK); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int Associate_Fields(FORM *form, FIELD **fields) +| +| Description : Set association between form and array of fields. +| If there are fields, position to first active field. +| +| Return Values : E_OK - success +| E_BAD_ARGUMENT - Invalid form pointer or field array +| E_CONNECTED - a field is already connected +| E_SYSTEM_ERROR - not enough memory ++--------------------------------------------------------------------------*/ +NCURSES_INLINE static int +Associate_Fields(FORM *form, FIELD **fields) +{ + int res = Connect_Fields(form, fields); + + if (res == E_OK) + { + if (form->maxpage > 0) + { + form->curpage = 0; + form_driver(form, FIRST_ACTIVE_MAGIC); + } + else + { + form->curpage = -1; + form->current = (FIELD *)0; + } + } + return (res); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : FORM *new_form_sp(SCREEN* sp, FIELD** fields ) +| +| Description : Create new form with given array of fields. +| +| Return Values : Pointer to form. NULL if error occurred. +! Set errno: +| E_OK - success +| E_BAD_ARGUMENT - Invalid form pointer or field array +| E_CONNECTED - a field is already connected +| E_SYSTEM_ERROR - not enough memory ++--------------------------------------------------------------------------*/ +NCURSES_EXPORT(FORM *) +NCURSES_SP_NAME(new_form) (NCURSES_SP_DCLx FIELD **fields) +{ + int err = E_SYSTEM_ERROR; + FORM *form = (FORM *)0; + + T((T_CALLED("new_form(%p,%p)"), (void *)SP_PARM, (void *)fields)); + + if (IsValidScreen(SP_PARM)) + { + form = typeMalloc(FORM, 1); + + if (form) + { + T((T_CREATE("form %p"), (void *)form)); + *form = *_nc_Default_Form; + /* This ensures win and sub are always non-null, + so we can derive always the SCREEN that this form is + running on. */ + form->win = StdScreen(SP_PARM); + form->sub = StdScreen(SP_PARM); + if ((err = Associate_Fields(form, fields)) != E_OK) + { + free_form(form); + form = (FORM *)0; + } + } + } + + if (!form) + SET_ERROR(err); + + returnForm(form); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : FORM* new_form(FIELD** fields ) +| +| Description : Create new form with given array of fields. +| +| Return Values : Pointer to form. NULL if error occurred. +! Set errno: +| E_OK - success +| E_BAD_ARGUMENT - Invalid form pointer or field array +| E_CONNECTED - a field is already connected +| E_SYSTEM_ERROR - not enough memory ++--------------------------------------------------------------------------*/ +#if NCURSES_SP_FUNCS +NCURSES_EXPORT(FORM *) +new_form(FIELD **fields) +{ + return NCURSES_SP_NAME(new_form) (CURRENT_SCREEN, fields); +} +#endif + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : int free_form( FORM *form ) +| +| Description : Release internal memory associated with form. +| +| Return Values : E_OK - no error +| E_BAD_ARGUMENT - invalid form pointer +| E_POSTED - form is posted ++--------------------------------------------------------------------------*/ +NCURSES_EXPORT(int) +free_form(FORM *form) +{ + T((T_CALLED("free_form(%p)"), (void *)form)); + + if (!form) + RETURN(E_BAD_ARGUMENT); + + if (form->status & _POSTED) + RETURN(E_POSTED); + + Disconnect_Fields(form); + if (form->page) + free(form->page); + free(form); + + RETURN(E_OK); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : int set_form_fields( FORM *form, FIELD **fields ) +| +| Description : Set a new association of an array of fields to a form +| +| Return Values : E_OK - no error +| E_BAD_ARGUMENT - Invalid form pointer or field array +| E_CONNECTED - a field is already connected +| E_POSTED - form is posted +| E_SYSTEM_ERROR - not enough memory ++--------------------------------------------------------------------------*/ +NCURSES_EXPORT(int) +set_form_fields(FORM *form, FIELD **fields) +{ + FIELD **old; + int res; + + T((T_CALLED("set_form_fields(%p,%p)"), (void *)form, (void *)fields)); + + if (!form) + RETURN(E_BAD_ARGUMENT); + + if (form->status & _POSTED) + RETURN(E_POSTED); + + old = form->field; + Disconnect_Fields(form); + + if ((res = Associate_Fields(form, fields)) != E_OK) + Connect_Fields(form, old); + + RETURN(res); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : FIELD **form_fields( const FORM *form ) +| +| Description : Retrieve array of fields +| +| Return Values : Pointer to field array ++--------------------------------------------------------------------------*/ +NCURSES_EXPORT(FIELD **) +form_fields(const FORM *form) +{ + T((T_CALLED("form_field(%p)"), (const void *)form)); + returnFieldPtr(Normalize_Form(form)->field); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : int field_count( const FORM *form ) +| +| Description : Retrieve number of fields +| +| Return Values : Number of fields, -1 if none are defined ++--------------------------------------------------------------------------*/ +NCURSES_EXPORT(int) +field_count(const FORM *form) +{ + T((T_CALLED("field_count(%p)"), (const void *)form)); + + returnCode(Normalize_Form(form)->maxfield); +} + +/* frm_def.c ends here */ |