diff options
Diffstat (limited to 'Source/CursesDialog/form')
47 files changed, 10081 insertions, 0 deletions
diff --git a/Source/CursesDialog/form/CMakeLists.txt b/Source/CursesDialog/form/CMakeLists.txt new file mode 100644 index 0000000..7691bc9 --- /dev/null +++ b/Source/CursesDialog/form/CMakeLists.txt @@ -0,0 +1,46 @@ +PROJECT(CMAKE_FORM) + +SOURCE_FILES(FORM_SRCS + fld_arg.c + fld_attr.c + fld_current.c + fld_def.c + fld_dup.c + fld_ftchoice.c + fld_ftlink.c + fld_info.c + fld_just.c + fld_link.c + fld_max.c + fld_move.c + fld_newftyp.c + fld_opts.c + fld_pad.c + fld_page.c + fld_stat.c + fld_type.c + fld_user.c + frm_cursor.c + frm_data.c + frm_def.c + frm_driver.c + frm_hook.c + frm_opts.c + frm_page.c + frm_post.c + frm_req_name.c + frm_scale.c + frm_sub.c + frm_user.c + frm_win.c + fty_alnum.c + fty_alpha.c + fty_enum.c + fty_int.c + fty_ipv4.c + fty_num.c + fty_regex.c + ) + +INCLUDE_DIRECTORIES(${CMAKE_FORM_SOURCE_DIR}) +ADD_LIBRARY(cmForm FORM_SRCS)
\ No newline at end of file diff --git a/Source/CursesDialog/form/READ.ME b/Source/CursesDialog/form/READ.ME new file mode 100644 index 0000000..dd91693 --- /dev/null +++ b/Source/CursesDialog/form/READ.ME @@ -0,0 +1,15 @@ +This is a clone of the form library that is available with typical +System V curses implementations (ETI). + +It is modelled after the documentation that comes for this library with +a 386 based SVR4 implementation (ESIX). + +The development environment was and is an ELF based Linux system. + +For things that still need doing, see the TO-DO file in the top-level +directory. + +Juergen Pfeifer + +eMail: juergen.pfeifer@gmx.net + diff --git a/Source/CursesDialog/form/eti.h b/Source/CursesDialog/form/eti.h new file mode 100644 index 0000000..cc1c830 --- /dev/null +++ b/Source/CursesDialog/form/eti.h @@ -0,0 +1,52 @@ +/**************************************************************************** + * Copyright (c) 1998 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 <juergen.pfeifer@gmx.net> 1995,1997 * + ****************************************************************************/ + +#ifndef _ETI_ERRNO_H_ +#define _ETI_ERRNO_H_ + +#define E_OK (0) +#define E_SYSTEM_ERROR (-1) +#define E_BAD_ARGUMENT (-2) +#define E_POSTED (-3) +#define E_CONNECTED (-4) +#define E_BAD_STATE (-5) +#define E_NO_ROOM (-6) +#define E_NOT_POSTED (-7) +#define E_UNKNOWN_COMMAND (-8) +#define E_NO_MATCH (-9) +#define E_NOT_SELECTABLE (-10) +#define E_NOT_CONNECTED (-11) +#define E_REQUEST_DENIED (-12) +#define E_INVALID_FIELD (-13) +#define E_CURRENT (-14) + +#endif diff --git a/Source/CursesDialog/form/fld_arg.c b/Source/CursesDialog/form/fld_arg.c new file mode 100644 index 0000000..91ad79f --- /dev/null +++ b/Source/CursesDialog/form/fld_arg.c @@ -0,0 +1,91 @@ +/**************************************************************************** + * Copyright (c) 1998 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 <juergen.pfeifer@gmx.net> 1995,1997 * + ****************************************************************************/ + +#include "form.priv.h" + +MODULE_ID("$Id$") + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : int set_fieldtype_arg( +| FIELDTYPE *typ, +| void * (* const make_arg)(va_list *), +| void * (* const copy_arg)(const void *), +| void (* const free_arg)(void *) ) +| +| Description : Connects to the type additional arguments necessary +| for a set_field_type call. The various function pointer +| arguments are: +| make_arg : allocates a structure for the field +| specific parameters. +| copy_arg : duplicate the structure created by +| make_arg +| free_arg : Release the memory allocated by make_arg +| or copy_arg +| +| At least make_arg must be non-NULL. +| You may pass NULL for copy_arg and free_arg if your +| make_arg function doesn't allocate memory and your +| arg fits into the storage for a (void*). +| +| Return Values : E_OK - success +| E_BAD_ARGUMENT - invalid argument ++--------------------------------------------------------------------------*/ +int set_fieldtype_arg(FIELDTYPE * typ, + void * (* const make_arg)(va_list *), + void * (* const copy_arg)(const void *), + void (* const free_arg)(void *)) +{ + if ( !typ || !make_arg ) + RETURN(E_BAD_ARGUMENT); + + typ->status |= _HAS_ARGS; + typ->makearg = make_arg; + typ->copyarg = copy_arg; + typ->freearg = free_arg; + RETURN(E_OK); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : void *field_arg(const FIELD *field) +| +| Description : Retrieve pointer to the fields argument structure. +| +| Return Values : Pointer to structure or NULL if none is defined. ++--------------------------------------------------------------------------*/ +void *field_arg(const FIELD * field) +{ + return Normalize_Field(field)->arg; +} + +/* fld_arg.c ends here */ diff --git a/Source/CursesDialog/form/fld_attr.c b/Source/CursesDialog/form/fld_attr.c new file mode 100644 index 0000000..ccf0415 --- /dev/null +++ b/Source/CursesDialog/form/fld_attr.c @@ -0,0 +1,111 @@ +/**************************************************************************** + * Copyright (c) 1998 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 <juergen.pfeifer@gmx.net> 1995,1997 * + ****************************************************************************/ +#include "form.priv.h" + +MODULE_ID("$Id$") + +/*---------------------------------------------------------------------------- + Field-Attribute manipulation routines + --------------------------------------------------------------------------*/ +/* "Template" macro to generate a function to set a fields attribute */ +#define GEN_FIELD_ATTR_SET_FCT( name ) \ +int set_field_ ## name (FIELD * field, chtype attr)\ +{\ + int res = E_BAD_ARGUMENT;\ + if ( attr==A_NORMAL || ((attr & A_ATTRIBUTES)==attr) )\ + {\ + Normalize_Field( field );\ + if ((field -> name) != attr)\ + {\ + field -> name = attr;\ + res = _nc_Synchronize_Attributes( field );\ + }\ + else\ + res = E_OK;\ + }\ + RETURN(res);\ +} + +/* "Template" macro to generate a function to get a fields attribute */ +#define GEN_FIELD_ATTR_GET_FCT( name ) \ +chtype field_ ## name (const FIELD * field)\ +{\ + return ( A_ATTRIBUTES & (Normalize_Field( field ) -> name) );\ +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : int set_field_fore(FIELD *field, chtype attr) +| +| Description : Sets the foreground of the field used to display the +| field contents. +| +| Return Values : E_OK - success +| E_BAD_ARGUMENT - invalid attributes +| E_SYSTEM_ERROR - system error ++--------------------------------------------------------------------------*/ +GEN_FIELD_ATTR_SET_FCT( fore ) + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : chtype field_fore(const FIELD *) +| +| Description : Retrieve fields foreground attribute +| +| Return Values : The foreground attribute ++--------------------------------------------------------------------------*/ +GEN_FIELD_ATTR_GET_FCT( fore ) + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : int set_field_back(FIELD *field, chtype attr) +| +| Description : Sets the background of the field used to display the +| fields extend. +| +| Return Values : E_OK - success +| E_BAD_ARGUMENT - invalid attributes +| E_SYSTEM_ERROR - system error ++--------------------------------------------------------------------------*/ +GEN_FIELD_ATTR_SET_FCT( back ) + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : chtype field_back(const +| +| Description : Retrieve fields background attribute +| +| Return Values : The background attribute ++--------------------------------------------------------------------------*/ +GEN_FIELD_ATTR_GET_FCT( back ) + +/* fld_attr.c ends here */ diff --git a/Source/CursesDialog/form/fld_current.c b/Source/CursesDialog/form/fld_current.c new file mode 100644 index 0000000..d4b1254 --- /dev/null +++ b/Source/CursesDialog/form/fld_current.c @@ -0,0 +1,124 @@ +/**************************************************************************** + * Copyright (c) 1998 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 <juergen.pfeifer@gmx.net> 1995,1997 * + ****************************************************************************/ +#include "form.priv.h" + +MODULE_ID("$Id$") + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : int set_current_field(FORM * form,FIELD * field) +| +| Description : Set the current field of the form to the specified one. +| +| Return Values : E_OK - success +| E_BAD_ARGUMENT - invalid form or field pointer +| E_REQUEST_DENIED - field not selectable +| E_BAD_STATE - called from a hook routine +| E_INVALID_FIELD - current field can't be left +| E_SYSTEM_ERROR - system error ++--------------------------------------------------------------------------*/ +int set_current_field(FORM * form, FIELD * field) +{ + int err = E_OK; + + if ( !form || !field ) + RETURN(E_BAD_ARGUMENT); + + if ( (form != field->form) || Field_Is_Not_Selectable(field) ) + RETURN(E_REQUEST_DENIED); + + if (!(form->status & _POSTED)) + { + form->current = field; + form->curpage = field->page; + } + else + { + if (form->status & _IN_DRIVER) + err = E_BAD_STATE; + else + { + if (form->current != field) + { + if (!_nc_Internal_Validation(form)) + err = E_INVALID_FIELD; + else + { + Call_Hook(form,fieldterm); + if (field->page != form->curpage) + { + Call_Hook(form,formterm); + err = _nc_Set_Form_Page(form,field->page,field); + Call_Hook(form,forminit); + } + else + { + err = _nc_Set_Current_Field(form,field); + } + Call_Hook(form,fieldinit); + _nc_Refresh_Current_Field(form); + } + } + } + } + RETURN(err); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : FIELD *current_field(const FORM * form) +| +| Description : Return the current field. +| +| Return Values : Pointer to the current field. ++--------------------------------------------------------------------------*/ +FIELD *current_field(const FORM * form) +{ + return Normalize_Form(form)->current; +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : int field_index(const FIELD * field) +| +| Description : Return the index of the field in the field-array of +| the form. +| +| Return Values : >= 0 : field index +| -1 : fieldpointer invalid or field not connected ++--------------------------------------------------------------------------*/ +int field_index(const FIELD * field) +{ + return ( (field && field->form) ? field->index : -1 ); +} + +/* fld_current.c ends here */ diff --git a/Source/CursesDialog/form/fld_def.c b/Source/CursesDialog/form/fld_def.c new file mode 100644 index 0000000..7b88693 --- /dev/null +++ b/Source/CursesDialog/form/fld_def.c @@ -0,0 +1,346 @@ +/**************************************************************************** + * Copyright (c) 1998 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 <juergen.pfeifer@gmx.net> 1995,1997 * + ****************************************************************************/ + +#include "form.priv.h" + +MODULE_ID("$Id$") + +/* this can't be readonly */ +static FIELD default_field = { + 0, /* status */ + 0, /* rows */ + 0, /* cols */ + 0, /* frow */ + 0, /* fcol */ + 0, /* drows */ + 0, /* dcols */ + 0, /* maxgrow*/ + 0, /* nrow */ + 0, /* nbuf */ + NO_JUSTIFICATION, /* just */ + 0, /* page */ + 0, /* index */ + (int)' ', /* pad */ + A_NORMAL, /* fore */ + A_NORMAL, /* back */ + ALL_FIELD_OPTS, /* opts */ + (FIELD *)0, /* snext */ + (FIELD *)0, /* sprev */ + (FIELD *)0, /* link */ + (FORM *)0, /* form */ + (FIELDTYPE *)0, /* type */ + (char *)0, /* arg */ + (char *)0, /* buf */ + (char *)0 /* usrptr */ +}; + +FIELD *_nc_Default_Field = &default_field; + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : TypeArgument *_nc_Make_Argument( +| const FIELDTYPE *typ, +| va_list *ap, +| int *err ) +| +| Description : Create an argument structure for the specified type. +| Use the type-dependant argument list to construct +| it. +| +| Return Values : Pointer to argument structure. Maybe NULL. +| In case of an error in *err an errorcounter is increased. ++--------------------------------------------------------------------------*/ +TypeArgument* +_nc_Make_Argument(const FIELDTYPE *typ, va_list *ap, int *err) +{ + TypeArgument *res = (TypeArgument *)0; + TypeArgument *p; + + if (typ && (typ->status & _HAS_ARGS)) + { + assert(err && ap); + if (typ->status & _LINKED_TYPE) + { + p = (TypeArgument *)malloc(sizeof(TypeArgument)); + if (p) + { + p->left = _nc_Make_Argument(typ->left ,ap,err); + p->right = _nc_Make_Argument(typ->right,ap,err); + return p; + } + else + *err += 1; + } else + { + assert(typ->makearg); + if ( !(res=(TypeArgument *)typ->makearg(ap)) ) + *err += 1; + } + } + return res; +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : TypeArgument *_nc_Copy_Argument(const FIELDTYPE *typ, +| const TypeArgument *argp, +| int *err ) +| +| Description : Create a copy of an argument structure for the specified +| type. +| +| Return Values : Pointer to argument structure. Maybe NULL. +| In case of an error in *err an errorcounter is increased. ++--------------------------------------------------------------------------*/ +TypeArgument* +_nc_Copy_Argument(const FIELDTYPE *typ, + const TypeArgument *argp, int *err) +{ + TypeArgument *res = (TypeArgument *)0; + TypeArgument *p; + + if ( typ && (typ->status & _HAS_ARGS) ) + { + assert(err && argp); + if (typ->status & _LINKED_TYPE) + { + p = (TypeArgument *)malloc(sizeof(TypeArgument)); + if (p) + { + p->left = _nc_Copy_Argument(typ,argp->left ,err); + p->right = _nc_Copy_Argument(typ,argp->right,err); + return p; + } + *err += 1; + } + else + { + if (typ->copyarg) + { + if (!(res = (TypeArgument *)(typ->copyarg((const void *)argp)))) + *err += 1; + } + else + res = (TypeArgument *)argp; + } + } + return res; +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : void _nc_Free_Argument(const FIELDTYPE *typ, +| TypeArgument * argp ) +| +| Description : Release memory associated with the argument structure +| for the given fieldtype. +| +| Return Values : - ++--------------------------------------------------------------------------*/ +void +_nc_Free_Argument(const FIELDTYPE * typ, TypeArgument * argp) +{ + if (!typ || !(typ->status & _HAS_ARGS)) + return; + + if (typ->status & _LINKED_TYPE) + { + assert(argp); + _nc_Free_Argument(typ->left ,argp->left ); + _nc_Free_Argument(typ->right,argp->right); + free(argp); + } + else + { + if (typ->freearg) + typ->freearg((void *)argp); + } +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : bool _nc_Copy_Type( FIELD *dst, FIELD const *src ) +| +| Description : Copy argument structure of field src to field dst +| +| Return Values : TRUE - copy worked +| FALSE - error occured ++--------------------------------------------------------------------------*/ +bool +_nc_Copy_Type(FIELD *dst, FIELD const *src) +{ + int err = 0; + + assert(dst && src); + + dst->type = src->type; + dst->arg = (void *)_nc_Copy_Argument(src->type,(TypeArgument *)(src->arg),&err); + + if (err) + { + _nc_Free_Argument(dst->type,(TypeArgument *)(dst->arg)); + dst->type = (FIELDTYPE *)0; + dst->arg = (void *)0; + return FALSE; + } + else + { + if (dst->type) + dst->type->ref++; + return TRUE; + } +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : void _nc_Free_Type( FIELD *field ) +| +| Description : Release Argument structure for this field +| +| Return Values : - ++--------------------------------------------------------------------------*/ +void +_nc_Free_Type(FIELD *field) +{ + assert(field); + if (field->type) + field->type->ref--; + _nc_Free_Argument(field->type,(TypeArgument *)(field->arg)); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : FIELD *new_field( int rows, int cols, +| int frow, int fcol, +| int nrow, int nbuf ) +| +| Description : Create a new field with this many 'rows' and 'cols', +| starting at 'frow/fcol' in the subwindow of the form. +| Allocate 'nrow' off-screen rows and 'nbuf' additional +| buffers. If an error occurs, errno is set to +| +| E_BAD_ARGUMENT - invalid argument +| E_SYSTEM_ERROR - system error +| +| Return Values : Pointer to the new field or NULL if failure. ++--------------------------------------------------------------------------*/ +FIELD *new_field(int rows, int cols, int frow, int fcol, int nrow, int nbuf) +{ + FIELD *New_Field = (FIELD *)0; + int err = E_BAD_ARGUMENT; + + if (rows>0 && + cols>0 && + frow>=0 && + fcol>=0 && + nrow>=0 && + nbuf>=0 && + ((err = E_SYSTEM_ERROR) != 0) && /* trick: this resets the default error */ + (New_Field=(FIELD *)malloc(sizeof(FIELD))) ) + { + *New_Field = default_field; + New_Field->rows = rows; + New_Field->cols = cols; + New_Field->drows = rows + nrow; + New_Field->dcols = cols; + New_Field->frow = frow; + New_Field->fcol = fcol; + New_Field->nrow = nrow; + New_Field->nbuf = nbuf; + New_Field->link = New_Field; + + if (_nc_Copy_Type(New_Field,&default_field)) + { + size_t len; + + len = Total_Buffer_Size(New_Field); + if ((New_Field->buf = (char *)malloc(len))) + { + /* Prefill buffers with blanks and insert terminating zeroes + between buffers */ + int i; + + memset(New_Field->buf,' ',len); + for(i=0;i<=New_Field->nbuf;i++) + { + New_Field->buf[(New_Field->drows*New_Field->cols+1)*(i+1)-1] + = '\0'; + } + return New_Field; + } + } + } + + if (New_Field) + free_field(New_Field); + + SET_ERROR( err ); + return (FIELD *)0; +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : int free_field( FIELD *field ) +| +| Description : Frees the storage allocated for the field. +| +| Return Values : E_OK - success +| E_BAD_ARGUMENT - invalid field pointer +| E_CONNECTED - field is connected ++--------------------------------------------------------------------------*/ +int free_field(FIELD * field) +{ + if (!field) + RETURN(E_BAD_ARGUMENT); + + if (field->form) + RETURN(E_CONNECTED); + + if (field == field->link) + { + if (field->buf) + free(field->buf); + } + else + { + FIELD *f; + + for(f=field;f->link != field;f = f->link) + {} + f->link = field->link; + } + _nc_Free_Type(field); + free(field); + RETURN(E_OK); +} + +/* fld_def.c ends here */ diff --git a/Source/CursesDialog/form/fld_dup.c b/Source/CursesDialog/form/fld_dup.c new file mode 100644 index 0000000..1c5301d --- /dev/null +++ b/Source/CursesDialog/form/fld_dup.c @@ -0,0 +1,97 @@ +/**************************************************************************** + * Copyright (c) 1998 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 <juergen.pfeifer@gmx.net> 1995,1997 * + ****************************************************************************/ + +#include "form.priv.h" + +MODULE_ID("$Id$") + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : FIELD *dup_field(FIELD *field, int frow, int fcol) +| +| Description : Duplicates the field at the specified position. All +| field attributes and the buffers are copied. +| If an error occurs, errno is set to +| +| E_BAD_ARGUMENT - invalid argument +| E_SYSTEM_ERROR - system error +| +| Return Values : Pointer to the new field or NULL if failure ++--------------------------------------------------------------------------*/ +FIELD *dup_field(FIELD * field, int frow, int fcol) +{ + FIELD *New_Field = (FIELD *)0; + int err = E_BAD_ARGUMENT; + + if (field && (frow>=0) && (fcol>=0) && + ((err=E_SYSTEM_ERROR) != 0) && /* trick : this resets the default error */ + (New_Field=(FIELD *)malloc(sizeof(FIELD))) ) + { + *New_Field = *_nc_Default_Field; + New_Field->frow = frow; + New_Field->fcol = fcol; + New_Field->link = New_Field; + New_Field->rows = field->rows; + New_Field->cols = field->cols; + New_Field->nrow = field->nrow; + New_Field->drows = field->drows; + New_Field->dcols = field->dcols; + New_Field->maxgrow = field->maxgrow; + New_Field->nbuf = field->nbuf; + New_Field->just = field->just; + New_Field->fore = field->fore; + New_Field->back = field->back; + New_Field->pad = field->pad; + New_Field->opts = field->opts; + New_Field->usrptr = field->usrptr; + + if (_nc_Copy_Type(New_Field,field)) + { + size_t len; + + len = Total_Buffer_Size(New_Field); + if ( (New_Field->buf=(char *)malloc(len)) ) + { + memcpy(New_Field->buf,field->buf,len); + return New_Field; + } + } + } + + if (New_Field) + free_field(New_Field); + + SET_ERROR(err); + return (FIELD *)0; +} + +/* fld_dup.c ends here */ diff --git a/Source/CursesDialog/form/fld_ftchoice.c b/Source/CursesDialog/form/fld_ftchoice.c new file mode 100644 index 0000000..bb37073 --- /dev/null +++ b/Source/CursesDialog/form/fld_ftchoice.c @@ -0,0 +1,62 @@ +/**************************************************************************** + * Copyright (c) 1998 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 <juergen.pfeifer@gmx.net> 1995,1997 * + ****************************************************************************/ + +#include "form.priv.h" + +MODULE_ID("$Id$") + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : int set_fieldtype_choice( +| FIELDTYPE *typ, +| bool (* const next_choice)(FIELD *,const void *), +| bool (* const prev_choice)(FIELD *,const void *)) +| +| Description : Define implementation of enumeration requests. +| +| Return Values : E_OK - success +| E_BAD_ARGUMENT - invalid arguments ++--------------------------------------------------------------------------*/ +int set_fieldtype_choice(FIELDTYPE * typ, + bool (* const next_choice) (FIELD *,const void *), + bool (* const prev_choice) (FIELD *,const void *)) +{ + if ( !typ || !next_choice || !prev_choice ) + RETURN(E_BAD_ARGUMENT); + + typ->status |= _HAS_CHOICE; + typ->next = next_choice; + typ->prev = prev_choice; + RETURN(E_OK); +} + +/* fld_ftchoice.c ends here */ diff --git a/Source/CursesDialog/form/fld_ftlink.c b/Source/CursesDialog/form/fld_ftlink.c new file mode 100644 index 0000000..1cb80d1 --- /dev/null +++ b/Source/CursesDialog/form/fld_ftlink.c @@ -0,0 +1,83 @@ +/**************************************************************************** + * Copyright (c) 1998 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 <juergen.pfeifer@gmx.net> 1995,1997 * + ****************************************************************************/ + +#include "form.priv.h" + +MODULE_ID("$Id$") + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : FIELDTYPE *link_fieldtype( +| FIELDTYPE *type1, +| FIELDTYPE *type2) +| +| Description : Create a new fieldtype built from the two given types. +| They are connected by an logical 'OR'. +| If an error occurs, errno is set to +| E_BAD_ARGUMENT - invalid arguments +| E_SYSTEM_ERROR - system error (no memory) +| +| Return Values : Fieldtype pointer or NULL if error occured. ++--------------------------------------------------------------------------*/ +FIELDTYPE *link_fieldtype(FIELDTYPE * type1, FIELDTYPE * type2) +{ + FIELDTYPE *nftyp = (FIELDTYPE *)0; + + if ( type1 && type2 ) + { + nftyp = (FIELDTYPE *)malloc(sizeof(FIELDTYPE)); + if (nftyp) + { + *nftyp = *_nc_Default_FieldType; + nftyp->status |= _LINKED_TYPE; + if ((type1->status & _HAS_ARGS) || (type2->status & _HAS_ARGS) ) + nftyp->status |= _HAS_ARGS; + if ((type1->status & _HAS_CHOICE) || (type2->status & _HAS_CHOICE) ) + nftyp->status |= _HAS_CHOICE; + nftyp->left = type1; + nftyp->right = type2; + type1->ref++; + type2->ref++; + } + else + { + SET_ERROR( E_SYSTEM_ERROR ); + } + } + else + { + SET_ERROR( E_BAD_ARGUMENT ); + } + return nftyp; +} + +/* fld_ftlink.c ends here */ diff --git a/Source/CursesDialog/form/fld_info.c b/Source/CursesDialog/form/fld_info.c new file mode 100644 index 0000000..7c50b1d --- /dev/null +++ b/Source/CursesDialog/form/fld_info.c @@ -0,0 +1,91 @@ +/**************************************************************************** + * Copyright (c) 1998 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 <juergen.pfeifer@gmx.net> 1995,1997 * + ****************************************************************************/ + +#include "form.priv.h" + +MODULE_ID("$Id$") + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : int field_info(const FIELD *field, +| int *rows, int *cols, +| int *frow, int *fcol, +| int *nrow, int *nbuf) +| +| Description : Retrieve infos about the fields creation parameters. +| +| Return Values : E_OK - success +| E_BAD_ARGUMENT - invalid field pointer ++--------------------------------------------------------------------------*/ +int field_info(const FIELD *field, + int *rows, int *cols, + int *frow, int *fcol, + int *nrow, int *nbuf) +{ + if (!field) + RETURN(E_BAD_ARGUMENT); + + if (rows) *rows = field->rows; + if (cols) *cols = field->cols; + if (frow) *frow = field->frow; + if (fcol) *fcol = field->fcol; + if (nrow) *nrow = field->nrow; + if (nbuf) *nbuf = field->nbuf; + RETURN(E_OK); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : int dynamic_field_info(const FIELD *field, +| int *drows, int *dcols, +| int *maxgrow) +| +| Description : Retrieve informations about a dynamic fields current +| dynamic parameters. +| +| Return Values : E_OK - success +| E_BAD_ARGUMENT - invalid argument ++--------------------------------------------------------------------------*/ +int dynamic_field_info(const FIELD *field, + int *drows, int *dcols, int *maxgrow) +{ + if (!field) + RETURN(E_BAD_ARGUMENT); + + if (drows) *drows = field->drows; + if (dcols) *dcols = field->dcols; + if (maxgrow) *maxgrow = field->maxgrow; + + RETURN(E_OK); +} + +/* fld_info.c ends here */ diff --git a/Source/CursesDialog/form/fld_just.c b/Source/CursesDialog/form/fld_just.c new file mode 100644 index 0000000..7015654 --- /dev/null +++ b/Source/CursesDialog/form/fld_just.c @@ -0,0 +1,81 @@ +/**************************************************************************** + * Copyright (c) 1998 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 <juergen.pfeifer@gmx.net> 1995,1997 * + ****************************************************************************/ + +#include "form.priv.h" + +MODULE_ID("$Id$") + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : int set_field_just(FIELD *field, int just) +| +| Description : Set the fields type of justification. +| +| Return Values : E_OK - success +| E_BAD_ARGUMENT - one of the arguments was incorrect +| E_SYSTEM_ERROR - system error ++--------------------------------------------------------------------------*/ +int set_field_just(FIELD * field, int just) +{ + int res = E_BAD_ARGUMENT; + + if ((just==NO_JUSTIFICATION) || + (just==JUSTIFY_LEFT) || + (just==JUSTIFY_CENTER) || + (just==JUSTIFY_RIGHT) ) + { + Normalize_Field( field ); + if (field->just != just) + { + field->just = just; + res = _nc_Synchronize_Attributes( field ); + } + else + res = E_OK; + } + RETURN(res); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : int field_just( const FIELD *field ) +| +| Description : Retrieve the fields type of justification +| +| Return Values : The justification type. ++--------------------------------------------------------------------------*/ +int field_just(const FIELD * field) +{ + return Normalize_Field( field )->just; +} + +/* fld_just.c ends here */ diff --git a/Source/CursesDialog/form/fld_link.c b/Source/CursesDialog/form/fld_link.c new file mode 100644 index 0000000..164f51b --- /dev/null +++ b/Source/CursesDialog/form/fld_link.c @@ -0,0 +1,90 @@ +/**************************************************************************** + * Copyright (c) 1998 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 <juergen.pfeifer@gmx.net> 1995,1997 * + ****************************************************************************/ + +#include "form.priv.h" + +MODULE_ID("$Id$") + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : FIELD *link_field(FIELD *field, int frow, int fcol) +| +| Description : Duplicates the field at the specified position. The +| new field shares its buffers with the original one, +| the attributes are independent. +| If an error occurs, errno is set to +| +| E_BAD_ARGUMENT - invalid argument +| E_SYSTEM_ERROR - system error +| +| Return Values : Pointer to the new field or NULL if failure ++--------------------------------------------------------------------------*/ +FIELD *link_field(FIELD * field, int frow, int fcol) +{ + FIELD *New_Field = (FIELD *)0; + int err = E_BAD_ARGUMENT; + + if (field && (frow>=0) && (fcol>=0) && + ((err=E_SYSTEM_ERROR) != 0) && /* trick: this resets the default error */ + (New_Field = (FIELD *)malloc(sizeof(FIELD))) ) + { + *New_Field = *_nc_Default_Field; + New_Field->frow = frow; + New_Field->fcol = fcol; + New_Field->link = field->link; + field->link = New_Field; + New_Field->buf = field->buf; + New_Field->rows = field->rows; + New_Field->cols = field->cols; + New_Field->nrow = field->nrow; + New_Field->nbuf = field->nbuf; + New_Field->drows = field->drows; + New_Field->dcols = field->dcols; + New_Field->maxgrow= field->maxgrow; + New_Field->just = field->just; + New_Field->fore = field->fore; + New_Field->back = field->back; + New_Field->pad = field->pad; + New_Field->opts = field->opts; + New_Field->usrptr = field->usrptr; + if (_nc_Copy_Type(New_Field,field)) + return New_Field; + } + + if (New_Field) + free_field(New_Field); + + SET_ERROR( err ); + return (FIELD *)0; +} + +/* fld_link.c ends here */ diff --git a/Source/CursesDialog/form/fld_max.c b/Source/CursesDialog/form/fld_max.c new file mode 100644 index 0000000..cca8dc5 --- /dev/null +++ b/Source/CursesDialog/form/fld_max.c @@ -0,0 +1,74 @@ +/**************************************************************************** + * Copyright (c) 1998 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 <juergen.pfeifer@gmx.net> 1995,1997 * + ****************************************************************************/ + +#include "form.priv.h" + +MODULE_ID("$Id$") + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : int set_max_field(FIELD *field, int maxgrow) +| +| Description : Set the maximum growth for a dynamic field. If maxgrow=0 +| the field may grow to any possible size. +| +| Return Values : E_OK - success +| E_BAD_ARGUMENT - invalid argument ++--------------------------------------------------------------------------*/ +int set_max_field(FIELD *field, int maxgrow) +{ + if (!field || (maxgrow<0)) + RETURN(E_BAD_ARGUMENT); + else + { + bool single_line_field = Single_Line_Field(field); + + if (maxgrow>0) + { + if (( single_line_field && (maxgrow < field->dcols)) || + (!single_line_field && (maxgrow < field->drows))) + RETURN(E_BAD_ARGUMENT); + } + field->maxgrow = maxgrow; + field->status &= ~_MAY_GROW; + if (!(field->opts & O_STATIC)) + { + if ((maxgrow==0) || + ( single_line_field && (field->dcols < maxgrow)) || + (!single_line_field && (field->drows < maxgrow))) + field->status |= _MAY_GROW; + } + } + RETURN(E_OK); +} + +/* fld_max.c ends here */ diff --git a/Source/CursesDialog/form/fld_move.c b/Source/CursesDialog/form/fld_move.c new file mode 100644 index 0000000..2293477 --- /dev/null +++ b/Source/CursesDialog/form/fld_move.c @@ -0,0 +1,62 @@ +/**************************************************************************** + * Copyright (c) 1998 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 <juergen.pfeifer@gmx.net> 1995,1997 * + ****************************************************************************/ + +#include "form.priv.h" + +MODULE_ID("$Id$") + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : int move_field(FIELD *field,int frow, int fcol) +| +| Description : Moves the disconnected field to the new location in +| the forms subwindow. +| +| Return Values : E_OK - success +| E_BAD_ARGUMENT - invalid argument passed +| E_CONNECTED - field is connected ++--------------------------------------------------------------------------*/ +int move_field(FIELD *field, int frow, int fcol) +{ + if ( !field || (frow<0) || (fcol<0) ) + RETURN(E_BAD_ARGUMENT); + + if (field->form) + RETURN(E_CONNECTED); + + field->frow = frow; + field->fcol = fcol; + RETURN(E_OK); +} + +/* fld_move.c ends here */ + diff --git a/Source/CursesDialog/form/fld_newftyp.c b/Source/CursesDialog/form/fld_newftyp.c new file mode 100644 index 0000000..b45ebd8 --- /dev/null +++ b/Source/CursesDialog/form/fld_newftyp.c @@ -0,0 +1,125 @@ +/**************************************************************************** + * Copyright (c) 1998 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 <juergen.pfeifer@gmx.net> 1995,1997 * + ****************************************************************************/ + +#include "form.priv.h" + +MODULE_ID("$Id$") + +static FIELDTYPE const default_fieldtype = { + 0, /* status */ + 0L, /* reference count */ + (FIELDTYPE *)0, /* pointer to left operand */ + (FIELDTYPE *)0, /* pointer to right operand */ + NULL, /* makearg function */ + NULL, /* copyarg function */ + NULL, /* freearg function */ + NULL, /* field validation function */ + NULL, /* Character check function */ + NULL, /* enumerate next function */ + NULL /* enumerate previous function */ +}; + +const FIELDTYPE* _nc_Default_FieldType = &default_fieldtype; + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : FIELDTYPE *new_fieldtype( +| bool (* const field_check)(FIELD *,const void *), +| bool (* const char_check) (int, const void *) ) +| +| Description : Create a new fieldtype. The application programmer must +| write a field_check and a char_check function and give +| them as input to this call. +| If an error occurs, errno is set to +| E_BAD_ARGUMENT - invalid arguments +| E_SYSTEM_ERROR - system error (no memory) +| +| Return Values : Fieldtype pointer or NULL if error occured ++--------------------------------------------------------------------------*/ +FIELDTYPE *new_fieldtype( + bool (* const field_check)(FIELD *,const void *), + bool (* const char_check) (int,const void *) ) +{ + FIELDTYPE *nftyp = (FIELDTYPE *)0; + + if ( (field_check) || (char_check) ) + { + nftyp = (FIELDTYPE *)malloc(sizeof(FIELDTYPE)); + if (nftyp) + { + *nftyp = default_fieldtype; + nftyp->fcheck = field_check; + nftyp->ccheck = char_check; + } + else + { + SET_ERROR( E_SYSTEM_ERROR ); + } + } + else + { + SET_ERROR( E_BAD_ARGUMENT ); + } + return nftyp; +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : int free_fieldtype(FIELDTYPE *typ) +| +| Description : Release the memory associated with this fieldtype. +| +| Return Values : E_OK - success +| E_CONNECTED - there are fields referencing the type +| E_BAD_ARGUMENT - invalid fieldtype pointer ++--------------------------------------------------------------------------*/ +int free_fieldtype(FIELDTYPE *typ) +{ + if (!typ) + RETURN(E_BAD_ARGUMENT); + + if (typ->ref!=0) + RETURN(E_CONNECTED); + + if (typ->status & _RESIDENT) + RETURN(E_CONNECTED); + + if (typ->status & _LINKED_TYPE) + { + if (typ->left ) typ->left->ref--; + if (typ->right) typ->right->ref--; + } + free(typ); + RETURN(E_OK); +} + +/* fld_newftyp.c ends here */ diff --git a/Source/CursesDialog/form/fld_opts.c b/Source/CursesDialog/form/fld_opts.c new file mode 100644 index 0000000..234634b --- /dev/null +++ b/Source/CursesDialog/form/fld_opts.c @@ -0,0 +1,124 @@ +/**************************************************************************** + * Copyright (c) 1998 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 <juergen.pfeifer@gmx.net> 1995,1997 * + ****************************************************************************/ +#include "form.priv.h" + +MODULE_ID("$Id$") + +/*---------------------------------------------------------------------------- + Field-Options manipulation routines + --------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : int set_field_opts(FIELD *field, Field_Options opts) +| +| Description : Turns on the named options for this field and turns +| off all the remaining options. +| +| Return Values : E_OK - success +| E_CURRENT - the field is the current field +| E_BAD_ARGUMENT - invalid options +| E_SYSTEM_ERROR - system error ++--------------------------------------------------------------------------*/ +int set_field_opts(FIELD * field, Field_Options opts) +{ + int res = E_BAD_ARGUMENT; + opts &= ALL_FIELD_OPTS; + if (!(opts & ~ALL_FIELD_OPTS)) + res = _nc_Synchronize_Options( Normalize_Field(field), opts ); + RETURN(res); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : Field_Options field_opts(const FIELD *field) +| +| Description : Retrieve the fields options. +| +| Return Values : The options. ++--------------------------------------------------------------------------*/ +Field_Options field_opts(const FIELD * field) +{ + return ALL_FIELD_OPTS & Normalize_Field( field )->opts; +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : int field_opts_on(FIELD *field, Field_Options opts) +| +| Description : Turns on the named options for this field and all the +| remaining options are unchanged. +| +| Return Values : E_OK - success +| E_CURRENT - the field is the current field +| E_BAD_ARGUMENT - invalid options +| E_SYSTEM_ERROR - system error ++--------------------------------------------------------------------------*/ +int field_opts_on(FIELD * field, Field_Options opts) +{ + int res = E_BAD_ARGUMENT; + + opts &= ALL_FIELD_OPTS; + if (!(opts & ~ALL_FIELD_OPTS)) + { + Normalize_Field( field ); + res = _nc_Synchronize_Options( field, field->opts | opts ); + } + RETURN(res); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : int field_opts_off(FIELD *field, Field_Options opts) +| +| Description : Turns off the named options for this field and all the +| remaining options are unchanged. +| +| Return Values : E_OK - success +| E_CURRENT - the field is the current field +| E_BAD_ARGUMENT - invalid options +| E_SYSTEM_ERROR - system error ++--------------------------------------------------------------------------*/ +int field_opts_off(FIELD * field, Field_Options opts) +{ + int res = E_BAD_ARGUMENT; + + opts &= ALL_FIELD_OPTS; + if (!(opts & ~ALL_FIELD_OPTS)) + { + Normalize_Field( field ); + res = _nc_Synchronize_Options( field, field->opts & ~opts ); + } + RETURN(res); +} + +/* fld_opts.c ends here */ diff --git a/Source/CursesDialog/form/fld_pad.c b/Source/CursesDialog/form/fld_pad.c new file mode 100644 index 0000000..4598340 --- /dev/null +++ b/Source/CursesDialog/form/fld_pad.c @@ -0,0 +1,78 @@ +/**************************************************************************** + * Copyright (c) 1998 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 <juergen.pfeifer@gmx.net> 1995,1997 * + ****************************************************************************/ +#include "form.priv.h" + +MODULE_ID("$Id$") + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : int set_field_pad(FIELD *field, int ch) +| +| Description : Set the pad character used to fill the field. This must +| be a printable character. +| +| Return Values : E_OK - success +| E_BAD_ARGUMENT - invalid field pointer or pad character +| E_SYSTEM_ERROR - system error ++--------------------------------------------------------------------------*/ +int set_field_pad(FIELD * field, int ch) +{ + int res = E_BAD_ARGUMENT; + + Normalize_Field( field ); + if (isprint((unsigned char)ch)) + { + if (field->pad != ch) + { + field->pad = ch; + res = _nc_Synchronize_Attributes( field ); + } + else + res = E_OK; + } + RETURN(res); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : int field_pad(const FIELD *field) +| +| Description : Retrieve the fields pad character. +| +| Return Values : The pad character. ++--------------------------------------------------------------------------*/ +int field_pad(const FIELD * field) +{ + return Normalize_Field( field )->pad; +} + +/* fld_pad.c ends here */ diff --git a/Source/CursesDialog/form/fld_page.c b/Source/CursesDialog/form/fld_page.c new file mode 100644 index 0000000..408e712 --- /dev/null +++ b/Source/CursesDialog/form/fld_page.c @@ -0,0 +1,76 @@ +/**************************************************************************** + * Copyright (c) 1998 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 <juergen.pfeifer@gmx.net> 1995,1997 * + ****************************************************************************/ + +#include "form.priv.h" + +MODULE_ID("$Id$") + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : int set_new_page(FIELD *field, bool new_page_flag) +| +| Description : Marks the field as the beginning of a new page of +| the form. +| +| Return Values : E_OK - success +| E_CONNECTED - field is connected ++--------------------------------------------------------------------------*/ +int set_new_page(FIELD * field, bool new_page_flag) +{ + Normalize_Field(field); + if (field->form) + RETURN(E_CONNECTED); + + if (new_page_flag) + field->status |= _NEWPAGE; + else + field->status &= ~_NEWPAGE; + + RETURN(E_OK); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : bool new_page(const FIELD *field) +| +| Description : Retrieve the info whether or not the field starts a +| new page on the form. +| +| Return Values : TRUE - field starts a new page +| FALSE - field doesn't start a new page ++--------------------------------------------------------------------------*/ +bool new_page(const FIELD * field) +{ + return (Normalize_Field(field)->status & _NEWPAGE) ? TRUE : FALSE; +} + +/* fld_page.c ends here */ diff --git a/Source/CursesDialog/form/fld_stat.c b/Source/CursesDialog/form/fld_stat.c new file mode 100644 index 0000000..ee6831b --- /dev/null +++ b/Source/CursesDialog/form/fld_stat.c @@ -0,0 +1,73 @@ +/**************************************************************************** + * Copyright (c) 1998 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 <juergen.pfeifer@gmx.net> 1995,1997 * + ****************************************************************************/ + +#include "form.priv.h" + +MODULE_ID("$Id$") + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : int set_field_status(FIELD *field, bool status) +| +| Description : Set or clear the 'changed' indication flag for that +| fields primary buffer. +| +| Return Values : E_OK - success ++--------------------------------------------------------------------------*/ +int set_field_status(FIELD * field, bool status) +{ + Normalize_Field( field ); + + if (status) + field->status |= _CHANGED; + else + field->status &= ~_CHANGED; + + return(E_OK); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : bool field_status(const FIELD *field) +| +| Description : Retrieve the value of the 'changed' indication flag +| for that fields primary buffer. +| +| Return Values : TRUE - buffer has been changed +| FALSE - buffer has not been changed ++--------------------------------------------------------------------------*/ +bool field_status(const FIELD * field) +{ + return ((Normalize_Field(field)->status & _CHANGED) ? TRUE : FALSE); +} + +/* fld_stat.c ends here */ diff --git a/Source/CursesDialog/form/fld_type.c b/Source/CursesDialog/form/fld_type.c new file mode 100644 index 0000000..1e0657c --- /dev/null +++ b/Source/CursesDialog/form/fld_type.c @@ -0,0 +1,92 @@ +/**************************************************************************** + * Copyright (c) 1998 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 <juergen.pfeifer@gmx.net> 1995,1997 * + ****************************************************************************/ + +#include "form.priv.h" + +MODULE_ID("$Id$") + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : int set_field_type(FIELD *field, FIELDTYPE *type,...) +| +| Description : Associate the specified fieldtype with the field. +| Certain field types take additional arguments. Look +| at the spec of the field types ! +| +| Return Values : E_OK - success +| E_SYSTEM_ERROR - system error ++--------------------------------------------------------------------------*/ +int set_field_type(FIELD *field,FIELDTYPE *type, ...) +{ + va_list ap; + int res = E_SYSTEM_ERROR; + int err = 0; + + va_start(ap,type); + + Normalize_Field(field); + _nc_Free_Type(field); + + field->type = type; + field->arg = (void *)_nc_Make_Argument(field->type,&ap,&err); + + if (err) + { + _nc_Free_Argument(field->type,(TypeArgument *)(field->arg)); + field->type = (FIELDTYPE *)0; + field->arg = (void *)0; + } + else + { + res = E_OK; + if (field->type) + field->type->ref++; + } + + va_end(ap); + RETURN(res); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : FIELDTYPE *field_type(const FIELD *field) +| +| Description : Retrieve the associated fieldtype for this field. +| +| Return Values : Pointer to fieldtype of NULL if none is defined. ++--------------------------------------------------------------------------*/ +FIELDTYPE *field_type(const FIELD * field) +{ + return Normalize_Field(field)->type; +} + +/* fld_type.c ends here */ diff --git a/Source/CursesDialog/form/fld_user.c b/Source/CursesDialog/form/fld_user.c new file mode 100644 index 0000000..7ffca9c --- /dev/null +++ b/Source/CursesDialog/form/fld_user.c @@ -0,0 +1,67 @@ +/**************************************************************************** + * Copyright (c) 1998 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 <juergen.pfeifer@gmx.net> 1995,1997 * + ****************************************************************************/ + +#include "form.priv.h" + +MODULE_ID("$Id$") + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : int set_field_userptr(FIELD *field, void *usrptr) +| +| Description : Set the pointer that is reserved in any field to store +| application relevant informations +| +| Return Values : E_OK - on success ++--------------------------------------------------------------------------*/ +int set_field_userptr(FIELD * field, void *usrptr) +{ + Normalize_Field( field )->usrptr = usrptr; + RETURN(E_OK); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : void *field_userptr(const FIELD *field) +| +| Description : Return the pointer that is reserved in any field to +| store application relevant informations. +| +| Return Values : Value of pointer. If no such pointer has been set, +| NULL is returned ++--------------------------------------------------------------------------*/ +void *field_userptr(const FIELD *field) +{ + return Normalize_Field( field )->usrptr; +} + +/* fld_user.c ends here */ diff --git a/Source/CursesDialog/form/form.h b/Source/CursesDialog/form/form.h new file mode 100644 index 0000000..2453985 --- /dev/null +++ b/Source/CursesDialog/form/form.h @@ -0,0 +1,389 @@ +/**************************************************************************** + * Copyright (c) 1998 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 <juergen.pfeifer@gmx.net> 1995,1997 * + ****************************************************************************/ + +#ifndef FORM_H +#define FORM_H + +#include <curses.h> +#include <eti.h> +#include <stdarg.h> + +#ifdef __cplusplus + extern "C" { +#endif + +typedef int Form_Options; +typedef int Field_Options; + + /********** + * _PAGE * + **********/ + +typedef struct { + short pmin; /* index of first field on page */ + short pmax; /* index of last field on page */ + short smin; /* index of top leftmost field on page */ + short smax; /* index of bottom rightmost field on page */ +} _PAGE; + + /********** + * FIELD * + **********/ + +typedef struct fieldnode { + unsigned short status; /* flags */ + short rows; /* size in rows */ + short cols; /* size in cols */ + short frow; /* first row */ + short fcol; /* first col */ + int drows; /* dynamic rows */ + int dcols; /* dynamic cols */ + int maxgrow; /* maximum field growth */ + int nrow; /* offscreen rows */ + short nbuf; /* additional buffers */ + short just; /* justification */ + short page; /* page on form */ + short index; /* into form -> field */ + int pad; /* pad character */ + chtype fore; /* foreground attribute */ + chtype back; /* background attribute */ + Field_Options opts; /* options */ + struct fieldnode * snext; /* sorted order pointer */ + struct fieldnode * sprev; /* sorted order pointer */ + struct fieldnode * link; /* linked field chain */ + struct formnode * form; /* containing form */ + struct typenode * type; /* field type */ + void * arg; /* argument for type */ + char * buf; /* field buffers */ + void * usrptr; /* user pointer */ +} FIELD; + + /************** + * FIELDTYPE * + **************/ + +typedef struct typenode { + unsigned short status; /* flags */ + long ref; /* reference count */ + struct typenode * left; /* ptr to operand for | */ + struct typenode * right; /* ptr to operand for | */ + + void* (*makearg)(va_list *); /* make fieldtype arg */ + void* (*copyarg)(const void *); /* copy fieldtype arg */ + void (*freearg)(void *); /* free fieldtype arg */ + + bool (*fcheck)(FIELD *,const void *); /* field validation */ + bool (*ccheck)(int,const void *); /* character validation */ + + bool (*next)(FIELD *,const void *); /* enumerate next value */ + bool (*prev)(FIELD *,const void *); /* enumerate prev value */ + +} FIELDTYPE; + + /********* + * FORM * + *********/ + +typedef struct formnode { + unsigned short status; /* flags */ + short rows; /* size in rows */ + short cols; /* size in cols */ + int currow; /* current row in field window*/ + int curcol; /* current col in field window*/ + int toprow; /* in scrollable field window */ + int begincol; /* in horiz. scrollable field */ + short maxfield; /* number of fields */ + short maxpage; /* number of pages */ + short curpage; /* index into page */ + Form_Options opts; /* options */ + WINDOW * win; /* window */ + WINDOW * sub; /* subwindow */ + WINDOW * w; /* window for current field */ + FIELD ** field; /* field [maxfield] */ + FIELD * current; /* current field */ + _PAGE * page; /* page [maxpage] */ + void * usrptr; /* user pointer */ + + void (*forminit)(struct formnode *); + void (*formterm)(struct formnode *); + void (*fieldinit)(struct formnode *); + void (*fieldterm)(struct formnode *); + +} FORM; + +typedef void (*Form_Hook)(FORM *); + + /*************************** + * miscellaneous #defines * + ***************************/ + +/* field justification */ +#define NO_JUSTIFICATION (0) +#define JUSTIFY_LEFT (1) +#define JUSTIFY_CENTER (2) +#define JUSTIFY_RIGHT (3) + +/* field options */ +#define O_VISIBLE (0x0001) +#define O_ACTIVE (0x0002) +#define O_PUBLIC (0x0004) +#define O_EDIT (0x0008) +#define O_WRAP (0x0010) +#define O_BLANK (0x0020) +#define O_AUTOSKIP (0x0040) +#define O_NULLOK (0x0080) +#define O_PASSOK (0x0100) +#define O_STATIC (0x0200) + +/* form options */ +#define O_NL_OVERLOAD (0x0001) +#define O_BS_OVERLOAD (0x0002) + +/* form driver commands */ +#define REQ_NEXT_PAGE (KEY_MAX + 1) /* move to next page */ +#define REQ_PREV_PAGE (KEY_MAX + 2) /* move to previous page */ +#define REQ_FIRST_PAGE (KEY_MAX + 3) /* move to first page */ +#define REQ_LAST_PAGE (KEY_MAX + 4) /* move to last page */ + +#define REQ_NEXT_FIELD (KEY_MAX + 5) /* move to next field */ +#define REQ_PREV_FIELD (KEY_MAX + 6) /* move to previous field */ +#define REQ_FIRST_FIELD (KEY_MAX + 7) /* move to first field */ +#define REQ_LAST_FIELD (KEY_MAX + 8) /* move to last field */ +#define REQ_SNEXT_FIELD (KEY_MAX + 9) /* move to sorted next field */ +#define REQ_SPREV_FIELD (KEY_MAX + 10) /* move to sorted prev field */ +#define REQ_SFIRST_FIELD (KEY_MAX + 11) /* move to sorted first field */ +#define REQ_SLAST_FIELD (KEY_MAX + 12) /* move to sorted last field */ +#define REQ_LEFT_FIELD (KEY_MAX + 13) /* move to left to field */ +#define REQ_RIGHT_FIELD (KEY_MAX + 14) /* move to right to field */ +#define REQ_UP_FIELD (KEY_MAX + 15) /* move to up to field */ +#define REQ_DOWN_FIELD (KEY_MAX + 16) /* move to down to field */ + +#define REQ_NEXT_CHAR (KEY_MAX + 17) /* move to next char in field */ +#define REQ_PREV_CHAR (KEY_MAX + 18) /* move to prev char in field */ +#define REQ_NEXT_LINE (KEY_MAX + 19) /* move to next line in field */ +#define REQ_PREV_LINE (KEY_MAX + 20) /* move to prev line in field */ +#define REQ_NEXT_WORD (KEY_MAX + 21) /* move to next word in field */ +#define REQ_PREV_WORD (KEY_MAX + 22) /* move to prev word in field */ +#define REQ_BEG_FIELD (KEY_MAX + 23) /* move to first char in field */ +#define REQ_END_FIELD (KEY_MAX + 24) /* move after last char in fld */ +#define REQ_BEG_LINE (KEY_MAX + 25) /* move to beginning of line */ +#define REQ_END_LINE (KEY_MAX + 26) /* move after last char in line */ +#define REQ_LEFT_CHAR (KEY_MAX + 27) /* move left in field */ +#define REQ_RIGHT_CHAR (KEY_MAX + 28) /* move right in field */ +#define REQ_UP_CHAR (KEY_MAX + 29) /* move up in field */ +#define REQ_DOWN_CHAR (KEY_MAX + 30) /* move down in field */ + +#define REQ_NEW_LINE (KEY_MAX + 31) /* insert/overlay new line */ +#define REQ_INS_CHAR (KEY_MAX + 32) /* insert blank char at cursor */ +#define REQ_INS_LINE (KEY_MAX + 33) /* insert blank line at cursor */ +#define REQ_DEL_CHAR (KEY_MAX + 34) /* delete char at cursor */ +#define REQ_DEL_PREV (KEY_MAX + 35) /* delete char before cursor */ +#define REQ_DEL_LINE (KEY_MAX + 36) /* delete line at cursor */ +#define REQ_DEL_WORD (KEY_MAX + 37) /* delete line at cursor */ +#define REQ_CLR_EOL (KEY_MAX + 38) /* clear to end of line */ +#define REQ_CLR_EOF (KEY_MAX + 39) /* clear to end of field */ +#define REQ_CLR_FIELD (KEY_MAX + 40) /* clear entire field */ +#define REQ_OVL_MODE (KEY_MAX + 41) /* begin overlay mode */ +#define REQ_INS_MODE (KEY_MAX + 42) /* begin insert mode */ +#define REQ_SCR_FLINE (KEY_MAX + 43) /* scroll field forward a line */ +#define REQ_SCR_BLINE (KEY_MAX + 44) /* scroll field backward a line */ +#define REQ_SCR_FPAGE (KEY_MAX + 45) /* scroll field forward a page */ +#define REQ_SCR_BPAGE (KEY_MAX + 46) /* scroll field backward a page */ +#define REQ_SCR_FHPAGE (KEY_MAX + 47) /* scroll field forward half page */ +#define REQ_SCR_BHPAGE (KEY_MAX + 48) /* scroll field backward half page */ +#define REQ_SCR_FCHAR (KEY_MAX + 49) /* horizontal scroll char */ +#define REQ_SCR_BCHAR (KEY_MAX + 50) /* horizontal scroll char */ +#define REQ_SCR_HFLINE (KEY_MAX + 51) /* horizontal scroll line */ +#define REQ_SCR_HBLINE (KEY_MAX + 52) /* horizontal scroll line */ +#define REQ_SCR_HFHALF (KEY_MAX + 53) /* horizontal scroll half line */ +#define REQ_SCR_HBHALF (KEY_MAX + 54) /* horizontal scroll half line */ + +#define REQ_VALIDATION (KEY_MAX + 55) /* validate field */ +#define REQ_NEXT_CHOICE (KEY_MAX + 56) /* display next field choice */ +#define REQ_PREV_CHOICE (KEY_MAX + 57) /* display prev field choice */ + +#define MIN_FORM_COMMAND (KEY_MAX + 1) /* used by form_driver */ +#define MAX_FORM_COMMAND (KEY_MAX + 57) /* used by form_driver */ + +#if defined(MAX_COMMAND) +# if (MAX_FORM_COMMAND > MAX_COMMAND) +# error Something is wrong -- MAX_FORM_COMMAND is greater than MAX_COMMAND +# elif (MAX_COMMAND != (KEY_MAX + 128)) +# error Something is wrong -- MAX_COMMAND is already inconsistently defined. +# endif +#else +# define MAX_COMMAND (KEY_MAX + 128) +#endif + + /************************* + * standard field types * + *************************/ +extern FIELDTYPE *TYPE_ALPHA, + *TYPE_ALNUM, + *TYPE_ENUM, + *TYPE_INTEGER, + *TYPE_NUMERIC, + *TYPE_REGEXP; + + /************************************ + * built-in additional field types * + * They are not defined in SVr4 * + ************************************/ +extern FIELDTYPE *TYPE_IPV4; /* Internet IP Version 4 address */ + + /*********************** + * Default objects * + ***********************/ +extern FORM *_nc_Default_Form; +extern FIELD *_nc_Default_Field; + + + /*********************** + * FIELDTYPE routines * + ***********************/ +extern FIELDTYPE + *new_fieldtype( + bool (* const field_check)(FIELD *,const void *), + bool (* const char_check)(int,const void *)), + *link_fieldtype(FIELDTYPE *,FIELDTYPE *); + +extern int free_fieldtype(FIELDTYPE *), + set_fieldtype_arg(FIELDTYPE *, + void * (* const make_arg)(va_list *), + void * (* const copy_arg)(const void *), + void (* const free_arg)(void *)), + set_fieldtype_choice (FIELDTYPE *, + bool (* const next_choice)(FIELD *,const void *), + bool (* const prev_choice)(FIELD *,const void *)); + + /******************* + * FIELD routines * + *******************/ +extern FIELD *new_field(int,int,int,int,int,int), + *dup_field(FIELD *,int,int), + *link_field(FIELD *,int,int); + +extern int free_field(FIELD *), + field_info(const FIELD *,int *,int *,int *,int *,int *,int *), + dynamic_field_info(const FIELD *,int *,int *,int *), + set_max_field( FIELD *,int), + move_field(FIELD *,int,int), + set_field_type(FIELD *,FIELDTYPE *,...), + set_new_page(FIELD *,bool), + set_field_just(FIELD *,int), + field_just(const FIELD *), + set_field_fore(FIELD *,chtype), + set_field_back(FIELD *,chtype), + set_field_pad(FIELD *,int), + field_pad(const FIELD *), + set_field_buffer(FIELD *,int,const char *), + set_field_status(FIELD *,bool), + set_field_userptr(FIELD *, void *), + set_field_opts(FIELD *,Field_Options), + field_opts_on(FIELD *,Field_Options), + field_opts_off(FIELD *,Field_Options); + +extern chtype field_fore(const FIELD *), + field_back(const FIELD *); + +extern bool new_page(const FIELD *), + field_status(const FIELD *); + +extern void *field_arg(const FIELD *); + +extern void *field_userptr(const FIELD *); + +extern FIELDTYPE + *field_type(const FIELD *); + +extern char* field_buffer(const FIELD *,int); + +extern Field_Options + field_opts(const FIELD *); + + /****************** + * FORM routines * + ******************/ +extern FORM *new_form(FIELD **); + +extern FIELD **form_fields(const FORM *), + *current_field(const FORM *); + +extern WINDOW *form_win(const FORM *), + *form_sub(const FORM *); + +extern Form_Hook + form_init(const FORM *), + form_term(const FORM *), + field_init(const FORM *), + field_term(const FORM *); + +extern int free_form(FORM *), + set_form_fields(FORM *,FIELD **), + field_count(const FORM *), + set_form_win(FORM *,WINDOW *), + set_form_sub(FORM *,WINDOW *), + set_current_field(FORM *,FIELD *), + field_index(const FIELD *), + set_form_page(FORM *,int), + form_page(const FORM *), + scale_form(const FORM *,int *,int *), + set_form_init(FORM *,Form_Hook), + set_form_term(FORM *,Form_Hook), + set_field_init(FORM *,Form_Hook), + set_field_term(FORM *,Form_Hook), + post_form(FORM *), + unpost_form(FORM *), + pos_form_cursor(FORM *), + form_driver(FORM *,int), + set_form_userptr(FORM *,void *), + set_form_opts(FORM *,Form_Options), + form_opts_on(FORM *,Form_Options), + form_opts_off(FORM *,Form_Options), + form_request_by_name(const char *); + +extern const char + *form_request_name(int); + +extern void *form_userptr(const FORM *); + +extern Form_Options + form_opts(const FORM *); + +extern bool data_ahead(const FORM *), + data_behind(const FORM *); + +#ifdef __cplusplus + } +#endif + +#endif /* FORM_H */ diff --git a/Source/CursesDialog/form/form.priv.h b/Source/CursesDialog/form/form.priv.h new file mode 100644 index 0000000..886121c --- /dev/null +++ b/Source/CursesDialog/form/form.priv.h @@ -0,0 +1,128 @@ +/**************************************************************************** + * Copyright (c) 1998 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 <juergen.pfeifer@gmx.net> 1995,1997 * + ****************************************************************************/ + +#include "mf_common.h" +#include "form.h" + +/* form status values */ +#define _OVLMODE (0x04) /* Form is in overlay mode */ +#define _WINDOW_MODIFIED (0x10) /* Current field window has been modified */ +#define _FCHECK_REQUIRED (0x20) /* Current field needs validation */ + +/* field status values */ +#define _CHANGED (0x01) /* Field has been changed */ +#define _NEWTOP (0x02) /* Vertical scrolling occured */ +#define _NEWPAGE (0x04) /* field begins new page of form */ +#define _MAY_GROW (0x08) /* dynamic field may still grow */ + +/* fieldtype status values */ +#define _LINKED_TYPE (0x01) /* Type is a linked type */ +#define _HAS_ARGS (0x02) /* Type has arguments */ +#define _HAS_CHOICE (0x04) /* Type has choice methods */ +#define _RESIDENT (0x08) /* Type is builtin */ + +/* This are the field options required to be a selectable field in field + navigation requests */ +#define O_SELECTABLE (O_ACTIVE | O_VISIBLE) + +/* If form is NULL replace form argument by default-form */ +#define Normalize_Form(form) ((form)=(form)?(form):_nc_Default_Form) + +/* If field is NULL replace field argument by default-field */ +#define Normalize_Field(field) ((field)=(field)?(field):_nc_Default_Field) + +/* Retrieve forms window */ +#define Get_Form_Window(form) \ + ((form)->sub?(form)->sub:((form)->win?(form)->win:stdscr)) + +/* Calculate the size for a single buffer for this field */ +#define Buffer_Length(field) ((field)->drows * (field)->dcols) + +/* Calculate the total size of all buffers for this field */ +#define Total_Buffer_Size(field) \ + ( (Buffer_Length(field) + 1) * (1+(field)->nbuf) ) + +/* Logic to determine whether or not a field is single lined */ +#define Single_Line_Field(field) \ + (((field)->rows + (field)->nrow) == 1) + +/* Logic to determine whether or not a field is selectable */ +#define Field_Is_Selectable(f) (((f)->opts & O_SELECTABLE)==O_SELECTABLE) +#define Field_Is_Not_Selectable(f) (((f)->opts & O_SELECTABLE)!=O_SELECTABLE) + +typedef struct typearg { + struct typearg *left; + struct typearg *right; +} TypeArgument; + +/* This is a dummy request code (normally invalid) to be used internally + with the form_driver() routine to position to the first active field + on the form +*/ +#define FIRST_ACTIVE_MAGIC (-291056) + +#define ALL_FORM_OPTS ( \ + O_NL_OVERLOAD |\ + O_BS_OVERLOAD ) + +#define ALL_FIELD_OPTS ( \ + O_VISIBLE |\ + O_ACTIVE |\ + O_PUBLIC |\ + O_EDIT |\ + O_WRAP |\ + O_BLANK |\ + O_AUTOSKIP|\ + O_NULLOK |\ + O_PASSOK |\ + O_STATIC ) + + +#define C_BLANK ' ' +#define is_blank(c) ((c)==C_BLANK) + +extern const FIELDTYPE* _nc_Default_FieldType; + +extern TypeArgument* _nc_Make_Argument(const FIELDTYPE*,va_list*,int*); +extern TypeArgument *_nc_Copy_Argument(const FIELDTYPE*,const TypeArgument*, int*); +extern void _nc_Free_Argument(const FIELDTYPE*,TypeArgument*); +extern bool _nc_Copy_Type(FIELD*, FIELD const *); +extern void _nc_Free_Type(FIELD *); + +extern int _nc_Synchronize_Attributes(FIELD*); +extern int _nc_Synchronize_Options(FIELD*,Field_Options); +extern int _nc_Set_Form_Page(FORM*,int,FIELD*); +extern int _nc_Refresh_Current_Field(FORM*); +extern FIELD* _nc_First_Active_Field(FORM*); +extern bool _nc_Internal_Validation(FORM*); +extern int _nc_Set_Current_Field(FORM*,FIELD*); +extern int _nc_Position_Form_Cursor(FORM*); diff --git a/Source/CursesDialog/form/frm_cursor.c b/Source/CursesDialog/form/frm_cursor.c new file mode 100644 index 0000000..6c311fe --- /dev/null +++ b/Source/CursesDialog/form/frm_cursor.c @@ -0,0 +1,66 @@ +/**************************************************************************** + * Copyright (c) 1998 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 <juergen.pfeifer@gmx.net> 1995,1997 * + ****************************************************************************/ +#include "form.priv.h" + +MODULE_ID("$Id$") + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : int pos_form_cursor(FORM * form) +| +| Description : Moves the form window cursor to the location required +| by the form driver to resume form processing. This may +| be needed after the application calls a curses library +| I/O routine that modifies the cursor position. +| +| Return Values : E_OK - Success +| E_SYSTEM_ERROR - System error. +| E_BAD_ARGUMENT - Invalid form pointer +| E_NOT_POSTED - Form is not posted ++--------------------------------------------------------------------------*/ +int pos_form_cursor(FORM * form) +{ + int res; + + if (!form) + res = E_BAD_ARGUMENT; + else + { + if (!(form->status & _POSTED)) + res = E_NOT_POSTED; + else + res = _nc_Position_Form_Cursor(form); + } + RETURN(res); +} + +/* frm_cursor.c ends here */ diff --git a/Source/CursesDialog/form/frm_data.c b/Source/CursesDialog/form/frm_data.c new file mode 100644 index 0000000..a96b4f1 --- /dev/null +++ b/Source/CursesDialog/form/frm_data.c @@ -0,0 +1,181 @@ +/**************************************************************************** + * Copyright (c) 1998 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 <juergen.pfeifer@gmx.net> 1995,1997 * + ****************************************************************************/ + +#include "form.priv.h" + +MODULE_ID("$Id$") + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : bool data_behind(const FORM *form) +| +| Description : Check for off-screen data behind. This is nearly trivial +| becose the begin of a field is fixed. +| +| Return Values : TRUE - there are off-screen data behind +| FALSE - there are no off-screen data behind ++--------------------------------------------------------------------------*/ +bool data_behind(const FORM *form) +{ + bool result = FALSE; + + if (form && (form->status & _POSTED) && form->current) + { + FIELD *field; + + field = form->current; + if (!Single_Line_Field(field)) + { + result = (form->toprow==0) ? FALSE : TRUE; + } + else + { + result = (form->begincol==0) ? FALSE : TRUE; + } + } + return(result); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static char * After_Last_Non_Pad_Position( +| char *buffer, +| int len, +| int pad) +| +| Description : Find the last position in the buffer that doesn't +| contain a padding character. +| +| Return Values : The pointer to this position ++--------------------------------------------------------------------------*/ +INLINE +static char * After_Last_Non_Pad_Position(char *buffer, int len, int pad) +{ + char *end = buffer + len; + + assert(buffer && len>=0); + while ( (buffer < end) && (*(end-1)==pad) ) + end--; + + return end; +} + +#define SMALL_BUFFER_SIZE (80) + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : bool data_ahead(const FORM *form) +| +| Description : Check for off-screen data ahead. This is more difficult +| because a dynamic field has a variable end. +| +| Return Values : TRUE - there are off-screen data ahead +| FALSE - there are no off-screen data ahead ++--------------------------------------------------------------------------*/ +bool data_ahead(const FORM *form) +{ + bool result = FALSE; + + if (form && (form->status & _POSTED) && form->current) + { + static char buffer[SMALL_BUFFER_SIZE + 1]; + FIELD *field; + bool large_buffer; + bool cursor_moved = FALSE; + char *bp; + char *found_content; + int pos; + + field = form->current; + assert(form->w); + + large_buffer = (field->cols > SMALL_BUFFER_SIZE); + if (large_buffer) + bp = (char *)malloc((size_t)(field->cols) + 1); + else + bp = buffer; + + assert(bp); + + if (Single_Line_Field(field)) + { + int check_len; + + pos = form->begincol + field->cols; + while (pos < field->dcols) + { + check_len = field->dcols - pos; + if ( check_len >= field->cols ) + check_len = field->cols; + cursor_moved = TRUE; + wmove(form->w,0,pos); + winnstr(form->w,bp,check_len); + found_content = + After_Last_Non_Pad_Position(bp,check_len,field->pad); + if (found_content==bp) + pos += field->cols; + else + { + result = TRUE; + break; + } + } + } + else + { + pos = form->toprow + field->rows; + while (pos < field->drows) + { + cursor_moved = TRUE; + wmove(form->w,pos,0); + pos++; + winnstr(form->w,bp,field->cols); + found_content = + After_Last_Non_Pad_Position(bp,field->cols,field->pad); + if (found_content!=bp) + { + result = TRUE; + break; + } + } + } + + if (large_buffer) + free(bp); + + if (cursor_moved) + wmove(form->w,form->currow,form->curcol); + } + return(result); +} + +/* frm_data.c ends here */ diff --git a/Source/CursesDialog/form/frm_def.c b/Source/CursesDialog/form/frm_def.c new file mode 100644 index 0000000..489dae3 --- /dev/null +++ b/Source/CursesDialog/form/frm_def.c @@ -0,0 +1,376 @@ +/**************************************************************************** + * Copyright (c) 1998 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 <juergen.pfeifer@gmx.net> 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 */ +}; + +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; + + 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) + RETURN(E_BAD_ARGUMENT); + + /* allocate page structures */ + if ( (pg = (_PAGE *)malloc(page_nr * sizeof(_PAGE))) != (_PAGE *)0 ) + { + 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); + } + form->page[page_nr].smin = fld->index; + form->page[page_nr].smax = fld->sprev->index; + } + 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 +| any other - error occured ++--------------------------------------------------------------------------*/ +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( FIELD **fields ) +| +| Description : Create new form with given array of fields. +| +| Return Values : Pointer to form. NULL if error occured. ++--------------------------------------------------------------------------*/ +FORM *new_form(FIELD ** fields) +{ + int err = E_SYSTEM_ERROR; + + FORM *form = (FORM *)malloc(sizeof(FORM)); + + if (form) + { + *form = *_nc_Default_Form; + if ((err=Associate_Fields(form,fields))!=E_OK) + { + free_form(form); + form = (FORM *)0; + } + } + + if (!form) + SET_ERROR(err); + + return(form); +} + +/*--------------------------------------------------------------------------- +| 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 ++--------------------------------------------------------------------------*/ +int free_form(FORM * 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 +| E_POSTED - form is posted ++--------------------------------------------------------------------------*/ +int set_form_fields(FORM * form, FIELD ** fields) +{ + FIELD **old; + int res; + + 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 ++--------------------------------------------------------------------------*/ +FIELD **form_fields(const FORM * form) +{ + return (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 ++--------------------------------------------------------------------------*/ +int field_count(const FORM * form) +{ + return (Normalize_Form( form )->maxfield); +} + +/* frm_def.c ends here */ diff --git a/Source/CursesDialog/form/frm_driver.c b/Source/CursesDialog/form/frm_driver.c new file mode 100644 index 0000000..6ea5dab --- /dev/null +++ b/Source/CursesDialog/form/frm_driver.c @@ -0,0 +1,3843 @@ +/**************************************************************************** + * Copyright (c) 1998 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 <juergen.pfeifer@gmx.net> 1995,1997 * + ****************************************************************************/ +#include "form.priv.h" + +MODULE_ID("$Id$") + +/*---------------------------------------------------------------------------- + This is the core module of the form library. It contains the majority + of the driver routines as well as the form_driver function. + + Essentially this module is nearly the whole library. This is because + all the functions in this module depends on some others in the module, + so it makes no sense to split them into separate files because they + will always be linked together. The only acceptable concern is turnaround + time for this module, but now we have all Pentiums or Riscs, so what! + + The driver routines are grouped into nine generic categories: + + a) Page Navigation ( all functions prefixed by PN_ ) + The current page of the form is left and some new page is + entered. + b) Inter-Field Navigation ( all functions prefixed by FN_ ) + The current field of the form is left and some new field is + entered. + c) Intra-Field Navigation ( all functions prefixed by IFN_ ) + The current position in the current field is changed. + d) Vertical Scrolling ( all functions prefixed by VSC_ ) + Esseantially this is a specialization of Intra-Field navigation. + It has to check for a multi-line field. + e) Horizontal Scrolling ( all functions prefixed by HSC_ ) + Esseantially this is a specialization of Intra-Field navigation. + It has to check for a single-line field. + f) Field Editing ( all functions prefixed by FE_ ) + The content of the current field is changed + g) Edit Mode requests ( all functions prefixed by EM_ ) + Switching between insert and overlay mode + h) Field-Validation requests ( all functions prefixed by FV_ ) + Perform verifications of the field. + i) Choice requests ( all functions prefixed by CR_ ) + Requests to enumerate possible field values + --------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + Some remarks on the placements of assert() macros : + I use them only on "strategic" places, i.e. top level entries where + I want to make sure that things are set correctly. Throughout subordinate + routines I omit them mostly. + --------------------------------------------------------------------------*/ + +/* +Some options that may effect compatibility in behavior to SVr4 forms, +but they are here to allow a more intuitive and user friendly behaviour of +our form implementation. This doesn't affect the API, so we feel it is +uncritical. + +The initial implementation tries to stay very close with the behaviour +of the original SVr4 implementation, although in some areas it is quite +clear that this isn't the most appropriate way. As far as possible this +sources will allow you to build a forms lib that behaves quite similar +to SVr4, but now and in the future we will give you better options. +Perhaps at some time we will make this configurable at runtime. +*/ + +/* Implement a more user-friendly previous/next word behaviour */ +#define FRIENDLY_PREV_NEXT_WORD (1) +/* Fix the wrong behaviour for forms with all fields inactive */ +#define FIX_FORM_INACTIVE_BUG (1) +/* Allow dynamic field growth also when navigating past the end */ +#define GROW_IF_NAVIGATE (1) + +/*---------------------------------------------------------------------------- + Forward references to some internally used static functions + --------------------------------------------------------------------------*/ +static int Inter_Field_Navigation ( int (* const fct) (FORM *), FORM * form ); +static int FN_Next_Field (FORM * form); +static int FN_Previous_Field (FORM * form); +static int FE_New_Line(FORM *); +static int FE_Delete_Previous(FORM *); + +/*---------------------------------------------------------------------------- + Macro Definitions. + + Some Remarks on that: I use the convention to use UPPERCASE for constants + defined by Macros. If I provide a macro as a kind of inline routine to + provide some logic, I use my Upper_Lower case style. + --------------------------------------------------------------------------*/ + +/* Calculate the position of a single row in a field buffer */ +#define Position_Of_Row_In_Buffer(field,row) ((row)*(field)->dcols) + +/* Calculate start address for the fields buffer# N */ +#define Address_Of_Nth_Buffer(field,N) \ + ((field)->buf + (N)*(1+Buffer_Length(field))) + +/* Calculate the start address of the row in the fields specified buffer# N */ +#define Address_Of_Row_In_Nth_Buffer(field,N,row) \ + (Address_Of_Nth_Buffer(field,N) + Position_Of_Row_In_Buffer(field,row)) + +/* Calculate the start address of the row in the fields primary buffer */ +#define Address_Of_Row_In_Buffer(field,row) \ + Address_Of_Row_In_Nth_Buffer(field,0,row) + +/* Calculate the start address of the row in the forms current field + buffer# N */ +#define Address_Of_Current_Row_In_Nth_Buffer(form,N) \ + Address_Of_Row_In_Nth_Buffer((form)->current,N,(form)->currow) + +/* Calculate the start address of the row in the forms current field + primary buffer */ +#define Address_Of_Current_Row_In_Buffer(form) \ + Address_Of_Current_Row_In_Nth_Buffer(form,0) + +/* Calculate the address of the cursor in the forms current field + primary buffer */ +#define Address_Of_Current_Position_In_Nth_Buffer(form,N) \ + (Address_Of_Current_Row_In_Nth_Buffer(form,N) + (form)->curcol) + +/* Calculate the address of the cursor in the forms current field + buffer# N */ +#define Address_Of_Current_Position_In_Buffer(form) \ + Address_Of_Current_Position_In_Nth_Buffer(form,0) + +/* Logic to decide wether or not a field is actually a field with + vertical or horizontal scrolling */ +#define Is_Scroll_Field(field) \ + (((field)->drows > (field)->rows) || \ + ((field)->dcols > (field)->cols)) + +/* Logic to decide whether or not a field needs to have an individual window + instead of a derived window because it contains invisible parts. + This is true for non-public fields and for scrollable fields. */ +#define Has_Invisible_Parts(field) \ + (!((field)->opts & O_PUBLIC) || \ + Is_Scroll_Field(field)) + +/* Logic to decide whether or not a field needs justification */ +#define Justification_Allowed(field) \ + (((field)->just != NO_JUSTIFICATION) && \ + (Single_Line_Field(field)) && \ + (((field)->dcols == (field)->cols) && \ + ((field)->opts & O_STATIC)) ) + +/* Logic to determine whether or not a dynamic field may still grow */ +#define Growable(field) ((field)->status & _MAY_GROW) + +/* Macro to set the attributes for a fields window */ +#define Set_Field_Window_Attributes(field,win) \ +( wbkgdset((win),(chtype)((field)->pad | (field)->back)), \ + wattrset((win),(field)->fore) ) + +/* Logic to decide whether or not a field really appears on the form */ +#define Field_Really_Appears(field) \ + ((field->form) &&\ + (field->form->status & _POSTED) &&\ + (field->opts & O_VISIBLE) &&\ + (field->page == field->form->curpage)) + +/* Logic to determine whether or not we are on the first position in the + current field */ +#define First_Position_In_Current_Field(form) \ + (((form)->currow==0) && ((form)->curcol==0)) + + +#define Minimum(a,b) (((a)<=(b)) ? (a) : (b)) +#define Maximum(a,b) (((a)>=(b)) ? (a) : (b)) + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static char *Get_Start_Of_Data(char * buf, int blen) +| +| Description : Return pointer to first non-blank position in buffer. +| If buffer is empty return pointer to buffer itself. +| +| Return Values : Pointer to first non-blank position in buffer ++--------------------------------------------------------------------------*/ +INLINE static char *Get_Start_Of_Data(char * buf, int blen) +{ + char *p = buf; + char *end = &buf[blen]; + + assert(buf && blen>=0); + while( (p < end) && is_blank(*p) ) + p++; + return( (p==end) ? buf : p ); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static char *After_End_Of_Data(char * buf, int blen) +| +| Description : Return pointer after last non-blank position in buffer. +| If buffer is empty, return pointer to buffer itself. +| +| Return Values : Pointer to position after last non-blank position in +| buffer. ++--------------------------------------------------------------------------*/ +INLINE static char *After_End_Of_Data(char * buf,int blen) +{ + char *p = &buf[blen]; + + assert(buf && blen>=0); + while( (p>buf) && is_blank(p[-1]) ) + p--; + return( p ); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static char *Get_First_Whitespace_Character( +| char * buf, int blen) +| +| Description : Position to the first whitespace character. +| +| Return Values : Pointer to first whitespace character in buffer. ++--------------------------------------------------------------------------*/ +INLINE static char *Get_First_Whitespace_Character(char * buf, int blen) +{ + char *p = buf; + char *end = &p[blen]; + + assert(buf && blen>=0); + while( (p < end) && !is_blank(*p)) + p++; + return( (p==end) ? buf : p ); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static char *After_Last_Whitespace_Character( +| char * buf, int blen) +| +| Description : Get the position after the last whitespace character. +| +| Return Values : Pointer to position after last whitespace character in +| buffer. ++--------------------------------------------------------------------------*/ +INLINE static char *After_Last_Whitespace_Character(char * buf, int blen) +{ + char *p = &buf[blen]; + + assert(buf && blen>=0); + while( (p>buf) && !is_blank(p[-1]) ) + p--; + return( p ); +} + +/* Set this to 1 to use the div_t version. This is a good idea if your + compiler has an intrinsic div() support. Unfortunately GNU-C has it + not yet. + N.B.: This only works if form->curcol follows immediately form->currow + and both are of type int. +*/ +#define USE_DIV_T (0) + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static void Adjust_Cursor_Position( +| FORM * form, const char * pos) +| +| Description : Set current row and column of the form to values +| corresponding to the buffer position. +| +| Return Values : - ++--------------------------------------------------------------------------*/ +INLINE static void Adjust_Cursor_Position(FORM * form, const char * pos) +{ + FIELD *field; + int idx; + + field = form->current; + assert( pos >= field->buf && field->dcols > 0); + idx = (int)( pos - field->buf ); +#if USE_DIV_T + *((div_t *)&(form->currow)) = div(idx,field->dcols); +#else + form->currow = idx / field->dcols; + form->curcol = idx - field->cols * form->currow; +#endif + if ( field->drows < form->currow ) + form->currow = 0; +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static void Buffer_To_Window( +| const FIELD * field, +| WINDOW * win) +| +| Description : Copy the buffer to the window. If its a multiline +| field, the buffer is split to the lines of the +| window without any editing. +| +| Return Values : - ++--------------------------------------------------------------------------*/ +static void Buffer_To_Window(const FIELD * field, WINDOW * win) +{ + int width, height; + int len; + int row; + char *pBuffer; + + assert(win && field); + + width = getmaxx(win); + height = getmaxy(win); + + for(row=0, pBuffer=field->buf; + row < height; + row++, pBuffer += width ) + { + if ((len = (int)( After_End_Of_Data( pBuffer, width ) - pBuffer )) > 0) + { + wmove( win, row, 0 ); + waddnstr( win, pBuffer, len ); + } + } +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static void Window_To_Buffer( +| WINDOW * win, +| FIELD * field) +| +| Description : Copy the content of the window into the buffer. +| The multiple lines of a window are simply +| concatenated into the buffer. Pad characters in +| the window will be replaced by blanks in the buffer. +| +| Return Values : - ++--------------------------------------------------------------------------*/ +static void Window_To_Buffer(WINDOW * win, FIELD * field) +{ + int pad; + int len = 0; + char *p; + int row, height; + + assert(win && field && field->buf ); + + pad = field->pad; + p = field->buf; + height = getmaxy(win); + + for(row=0; (row < height) && (row < field->drows); row++ ) + { + wmove( win, row, 0 ); + len += winnstr( win, p+len, field->dcols ); + } + p[len] = '\0'; + + /* replace visual padding character by blanks in buffer */ + if (pad != C_BLANK) + { + int i; + for(i=0; i<len; i++, p++) + { + if (*p==pad) + *p = C_BLANK; + } + } +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static void Synchronize_Buffer(FORM * form) +| +| Description : If there was a change, copy the content of the +| window into the buffer, so the buffer is synchronized +| with the windows content. We have to indicate that the +| buffer needs validation due to the change. +| +| Return Values : - ++--------------------------------------------------------------------------*/ +INLINE static void Synchronize_Buffer(FORM * form) +{ + if (form->status & _WINDOW_MODIFIED) + { + form->status &= ~_WINDOW_MODIFIED; + form->status |= _FCHECK_REQUIRED; + Window_To_Buffer(form->w,form->current); + wmove(form->w,form->currow,form->curcol); + } +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static bool Field_Grown( FIELD *field, int amount) +| +| Description : This function is called for growable dynamic fields +| only. It has to increase the buffers and to allocate +| a new window for this field. +| This function has the side effect to set a new +| field-buffer pointer, the dcols and drows values +| as well as a new current Window for the field. +| +| Return Values : TRUE - field successfully increased +| FALSE - there was some error ++--------------------------------------------------------------------------*/ +static bool Field_Grown(FIELD * field, int amount) +{ + bool result = FALSE; + + if (field && Growable(field)) + { + bool single_line_field = Single_Line_Field(field); + int old_buflen = Buffer_Length(field); + int new_buflen; + int old_dcols = field->dcols; + int old_drows = field->drows; + char *oldbuf = field->buf; + char *newbuf; + + int growth; + FORM *form = field->form; + bool need_visual_update = ((form != (FORM *)0) && + (form->status & _POSTED) && + (form->current==field)); + + if (need_visual_update) + Synchronize_Buffer(form); + + if (single_line_field) + { + growth = field->cols * amount; + if (field->maxgrow) + growth = Minimum(field->maxgrow - field->dcols,growth); + field->dcols += growth; + if (field->dcols == field->maxgrow) + field->status &= ~_MAY_GROW; + } + else + { + growth = (field->rows + field->nrow) * amount; + if (field->maxgrow) + growth = Minimum(field->maxgrow - field->drows,growth); + field->drows += growth; + if (field->drows == field->maxgrow) + field->status &= ~_MAY_GROW; + } + /* drows, dcols changed, so we get really the new buffer length */ + new_buflen = Buffer_Length(field); + newbuf=(char *)malloc((size_t)Total_Buffer_Size(field)); + if (!newbuf) + { /* restore to previous state */ + field->dcols = old_dcols; + field->drows = old_drows; + if (( single_line_field && (field->dcols!=field->maxgrow)) || + (!single_line_field && (field->drows!=field->maxgrow))) + field->status |= _MAY_GROW; + return FALSE; + } + else + { /* Copy all the buffers. This is the reason why we can't + just use realloc(). + */ + int i; + char *old_bp; + char *new_bp; + + field->buf = newbuf; + for(i=0;i<=field->nbuf;i++) + { + new_bp = Address_Of_Nth_Buffer(field,i); + old_bp = oldbuf + i*(1+old_buflen); + memcpy(new_bp,old_bp,(size_t)old_buflen); + if (new_buflen > old_buflen) + memset(new_bp + old_buflen,C_BLANK, + (size_t)(new_buflen - old_buflen)); + *(new_bp + new_buflen) = '\0'; + } + + if (need_visual_update) + { + WINDOW *new_window = newpad(field->drows,field->dcols); + if (!new_window) + { /* restore old state */ + field->dcols = old_dcols; + field->drows = old_drows; + field->buf = oldbuf; + if (( single_line_field && + (field->dcols!=field->maxgrow)) || + (!single_line_field && + (field->drows!=field->maxgrow))) + field->status |= _MAY_GROW; + free( newbuf ); + return FALSE; + } + assert(form!=(FORM *)0); + delwin(form->w); + form->w = new_window; + Set_Field_Window_Attributes(field,form->w); + werase(form->w); + Buffer_To_Window(field,form->w); + untouchwin(form->w); + wmove(form->w,form->currow,form->curcol); + } + + free(oldbuf); + /* reflect changes in linked fields */ + if (field != field->link) + { + FIELD *linked_field; + for(linked_field = field->link; + linked_field!= field; + linked_field = linked_field->link) + { + linked_field->buf = field->buf; + linked_field->drows = field->drows; + linked_field->dcols = field->dcols; + } + } + result = TRUE; + } + } + return(result); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : int _nc_Position_Form_Cursor(FORM * form) +| +| Description : Position the cursor in the window for the current +| field to be in sync. with the currow and curcol +| values. +| +| Return Values : E_OK - success +| E_BAD_ARGUMENT - invalid form pointer +| E_SYSTEM_ERROR - form has no current field or +| field-window ++--------------------------------------------------------------------------*/ +int +_nc_Position_Form_Cursor(FORM * form) +{ + FIELD *field; + WINDOW *formwin; + + if (!form) + return(E_BAD_ARGUMENT); + + if (!form->w || !form->current) + return(E_SYSTEM_ERROR); + + field = form->current; + formwin = Get_Form_Window(form); + + wmove( form->w, form->currow, form->curcol ); + if ( Has_Invisible_Parts(field) ) + { + /* in this case fieldwin isn't derived from formwin, so we have + to move the cursor in formwin by hand... */ + wmove(formwin, + field->frow + form->currow - form->toprow, + field->fcol + form->curcol - form->begincol); + wcursyncup(formwin); + } + else + wcursyncup(form->w); + return(E_OK); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : int _nc_Refresh_Current_Field(FORM * form) +| +| Description : Propagate the changes in the fields window to the +| window of the form. +| +| Return Values : E_OK - on success +| E_BAD_ARGUMENT - invalid form pointer +| E_SYSTEM_ERROR - general error ++--------------------------------------------------------------------------*/ +int +_nc_Refresh_Current_Field(FORM * form) +{ + WINDOW *formwin; + FIELD *field; + + if (!form) + RETURN(E_BAD_ARGUMENT); + + if (!form->w || !form->current) + RETURN(E_SYSTEM_ERROR); + + field = form->current; + formwin = Get_Form_Window(form); + + if (field->opts & O_PUBLIC) + { + if (Is_Scroll_Field(field)) + { + /* Again, in this case the fieldwin isn't derived from formwin, + so we have to perform a copy operation. */ + if (Single_Line_Field(field)) + { /* horizontal scrolling */ + if (form->curcol < form->begincol) + form->begincol = form->curcol; + else + { + if (form->curcol >= (form->begincol + field->cols)) + form->begincol = form->curcol - field->cols + 1; + } + copywin(form->w, + formwin, + 0, + form->begincol, + field->frow, + field->fcol, + field->frow, + field->cols + field->fcol - 1, + 0); + } + else + { /* A multiline, i.e. vertical scrolling field */ + int row_after_bottom,first_modified_row,first_unmodified_row; + + if (field->drows > field->rows) + { + row_after_bottom = form->toprow + field->rows; + if (form->currow < form->toprow) + { + form->toprow = form->currow; + field->status |= _NEWTOP; + } + if (form->currow >= row_after_bottom) + { + form->toprow = form->currow - field->rows + 1; + field->status |= _NEWTOP; + } + if (field->status & _NEWTOP) + { /* means we have to copy whole range */ + first_modified_row = form->toprow; + first_unmodified_row = first_modified_row + field->rows; + field->status &= ~_NEWTOP; + } + else + { /* we try to optimize : finding the range of touched + lines */ + first_modified_row = form->toprow; + while(first_modified_row < row_after_bottom) + { + if (is_linetouched(form->w,first_modified_row)) + break; + first_modified_row++; + } + first_unmodified_row = first_modified_row; + while(first_unmodified_row < row_after_bottom) + { + if (!is_linetouched(form->w,first_unmodified_row)) + break; + first_unmodified_row++; + } + } + } + else + { + first_modified_row = form->toprow; + first_unmodified_row = first_modified_row + field->rows; + } + if (first_unmodified_row != first_modified_row) + copywin(form->w, + formwin, + first_modified_row, + 0, + field->frow + first_modified_row - form->toprow, + field->fcol, + field->frow + first_unmodified_row - form->toprow - 1, + field->cols + field->fcol - 1, + 0); + } + wsyncup(formwin); + } + else + { /* if the field-window is simply a derived window, i.e. contains + no invisible parts, the whole thing is trivial + */ + wsyncup(form->w); + } + } + untouchwin(form->w); + return _nc_Position_Form_Cursor(form); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static void Perform_Justification( +| FIELD * field, +| WINDOW * win) +| +| Description : Output field with requested justification +| +| Return Values : - ++--------------------------------------------------------------------------*/ +static void Perform_Justification(FIELD * field, WINDOW * win) +{ + char *bp; + int len; + int col = 0; + + bp = Get_Start_Of_Data(field->buf,Buffer_Length(field)); + len = (int)(After_End_Of_Data(field->buf,Buffer_Length(field)) - bp); + + if (len>0) + { + assert(win && (field->drows == 1) && (field->dcols == field->cols)); + + switch(field->just) + { + case JUSTIFY_LEFT: + break; + case JUSTIFY_CENTER: + col = (field->cols - len)/2; + break; + case JUSTIFY_RIGHT: + col = field->cols - len; + break; + default: + break; + } + + wmove(win,0,col); + waddnstr(win,bp,len); + } +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static void Undo_Justification( +| FIELD * field, +| WINDOW * win) +| +| Description : Display field without any justification, i.e. +| left justified +| +| Return Values : - ++--------------------------------------------------------------------------*/ +static void Undo_Justification(FIELD * field, WINDOW * win) +{ + char *bp; + int len; + + bp = Get_Start_Of_Data(field->buf,Buffer_Length(field)); + len = (int)(After_End_Of_Data(field->buf,Buffer_Length(field))-bp); + + if (len>0) + { + assert(win); + wmove(win,0,0); + waddnstr(win,bp,len); + } +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static bool Check_Char( +| FIELDTYPE * typ, +| int ch, +| TypeArgument *argp) +| +| Description : Perform a single character check for character ch +| according to the fieldtype instance. +| +| Return Values : TRUE - Character is valid +| FALSE - Character is invalid ++--------------------------------------------------------------------------*/ +static bool Check_Char(FIELDTYPE * typ, int ch, TypeArgument *argp) +{ + if (typ) + { + if (typ->status & _LINKED_TYPE) + { + assert(argp); + return( + Check_Char(typ->left ,ch,argp->left ) || + Check_Char(typ->right,ch,argp->right) ); + } + else + { + if (typ->ccheck) + return typ->ccheck(ch,(void *)argp); + } + } + return (isprint((unsigned char)ch) ? TRUE : FALSE); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int Display_Or_Erase_Field( +| FIELD * field, +| bool bEraseFlag) +| +| Description : Create a subwindow for the field and display the +| buffer contents (apply justification if required) +| or simply erase the field. +| +| Return Values : E_OK - on success +| E_SYSTEM_ERROR - some error (typical no memory) ++--------------------------------------------------------------------------*/ +static int Display_Or_Erase_Field(FIELD * field, bool bEraseFlag) +{ + WINDOW *win; + WINDOW *fwin; + + if (!field) + return E_SYSTEM_ERROR; + + fwin = Get_Form_Window(field->form); + win = derwin(fwin, + field->rows,field->cols,field->frow,field->fcol); + + if (!win) + return E_SYSTEM_ERROR; + else + { + if (field->opts & O_VISIBLE) + Set_Field_Window_Attributes(field,win); + else + wattrset(win,getattrs(fwin)); + werase(win); + } + + if (!bEraseFlag) + { + if (field->opts & O_PUBLIC) + { + if (Justification_Allowed(field)) + Perform_Justification(field,win); + else + Buffer_To_Window(field,win); + } + field->status &= ~_NEWTOP; + } + wsyncup(win); + delwin(win); + return E_OK; +} + +/* Macros to preset the bEraseFlag */ +#define Display_Field(field) Display_Or_Erase_Field(field,FALSE) +#define Erase_Field(field) Display_Or_Erase_Field(field,TRUE) + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int Synchronize_Field(FIELD * field) +| +| Description : Synchronize the windows content with the value in +| the buffer. +| +| Return Values : E_OK - success +| E_BAD_ARGUMENT - invalid field pointer +| E_SYSTEM_ERROR - some severe basic error ++--------------------------------------------------------------------------*/ +static int Synchronize_Field(FIELD * field) +{ + FORM *form; + int res = E_OK; + + if (!field) + return(E_BAD_ARGUMENT); + + if (((form=field->form) != (FORM *)0) + && Field_Really_Appears(field)) + { + if (field == form->current) + { + form->currow = form->curcol = form->toprow = form->begincol = 0; + werase(form->w); + + if ( (field->opts & O_PUBLIC) && Justification_Allowed(field) ) + Undo_Justification( field, form->w ); + else + Buffer_To_Window( field, form->w ); + + field->status |= _NEWTOP; + res = _nc_Refresh_Current_Field( form ); + } + else + res = Display_Field( field ); + } + field->status |= _CHANGED; + return(res); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int Synchronize_Linked_Fields(FIELD * field) +| +| Description : Propagate the Synchronize_Field function to all linked +| fields. The first error that occurs in the sequence +| of updates is the returnvalue. +| +| Return Values : E_OK - success +| E_BAD_ARGUMENT - invalid field pointer +| E_SYSTEM_ERROR - some severe basic error ++--------------------------------------------------------------------------*/ +static int Synchronize_Linked_Fields(FIELD * field) +{ + FIELD *linked_field; + int res = E_OK; + int syncres; + + if (!field) + return(E_BAD_ARGUMENT); + + if (!field->link) + return(E_SYSTEM_ERROR); + + for(linked_field = field->link; + linked_field!= field; + linked_field = linked_field->link ) + { + if (((syncres=Synchronize_Field(linked_field)) != E_OK) && + (res==E_OK)) + res = syncres; + } + return(res); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : int _nc_Synchronize_Attributes(FIELD * field) +| +| Description : If a fields visual attributes have changed, this +| routine is called to propagate those changes to the +| screen. +| +| Return Values : E_OK - success +| E_BAD_ARGUMENT - invalid field pointer +| E_SYSTEM_ERROR - some severe basic error ++--------------------------------------------------------------------------*/ +int _nc_Synchronize_Attributes(FIELD * field) +{ + FORM *form; + int res = E_OK; + WINDOW *formwin; + + if (!field) + return(E_BAD_ARGUMENT); + + if (((form=field->form) != (FORM *)0) + && Field_Really_Appears(field)) + { + if (form->current==field) + { + Synchronize_Buffer(form); + Set_Field_Window_Attributes(field,form->w); + werase(form->w); + if (field->opts & O_PUBLIC) + { + if (Justification_Allowed(field)) + Undo_Justification(field,form->w); + else + Buffer_To_Window(field,form->w); + } + else + { + formwin = Get_Form_Window(form); + copywin(form->w,formwin, + 0,0, + field->frow,field->fcol, + field->rows-1,field->cols-1,0); + wsyncup(formwin); + Buffer_To_Window(field,form->w); + field->status |= _NEWTOP; /* fake refresh to paint all */ + _nc_Refresh_Current_Field(form); + } + } + else + { + res = Display_Field(field); + } + } + return(res); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : int _nc_Synchronize_Options(FIELD * field, +| Field_Options newopts) +| +| Description : If a fields options have changed, this routine is +| called to propagate these changes to the screen and +| to really change the behaviour of the field. +| +| Return Values : E_OK - success +| E_BAD_ARGUMENT - invalid field pointer +| E_SYSTEM_ERROR - some severe basic error ++--------------------------------------------------------------------------*/ +int +_nc_Synchronize_Options(FIELD *field, Field_Options newopts) +{ + Field_Options oldopts; + Field_Options changed_opts; + FORM *form; + int res = E_OK; + + if (!field) + return(E_BAD_ARGUMENT); + + oldopts = field->opts; + changed_opts = oldopts ^ newopts; + field->opts = newopts; + form = field->form; + + if (form) + { + if (form->current == field) + { + field->opts = oldopts; + return(E_CURRENT); + } + + if (form->status & _POSTED) + { + if ((form->curpage == field->page)) + { + if (changed_opts & O_VISIBLE) + { + if (newopts & O_VISIBLE) + res = Display_Field(field); + else + res = Erase_Field(field); + } + else + { + if ((changed_opts & O_PUBLIC) && + (newopts & O_VISIBLE)) + res = Display_Field(field); + } + } + } + } + + if (changed_opts & O_STATIC) + { + bool single_line_field = Single_Line_Field(field); + int res2 = E_OK; + + if (newopts & O_STATIC) + { /* the field becomes now static */ + field->status &= ~_MAY_GROW; + /* if actually we have no hidden columns, justification may + occur again */ + if (single_line_field && + (field->cols == field->dcols) && + (field->just != NO_JUSTIFICATION) && + Field_Really_Appears(field)) + { + res2 = Display_Field(field); + } + } + else + { /* field is no longer static */ + if ((field->maxgrow==0) || + ( single_line_field && (field->dcols < field->maxgrow)) || + (!single_line_field && (field->drows < field->maxgrow))) + { + field->status |= _MAY_GROW; + /* a field with justification now changes its behaviour, + so we must redisplay it */ + if (single_line_field && + (field->just != NO_JUSTIFICATION) && + Field_Really_Appears(field)) + { + res2 = Display_Field(field); + } + } + } + if (res2 != E_OK) + res = res2; + } + + return(res); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : int _nc_Set_Current_Field(FORM * form, +| FIELD * newfield) +| +| Description : Make the newfield the new current field. +| +| Return Values : E_OK - success +| E_BAD_ARGUMENT - invalid form or field pointer +| E_SYSTEM_ERROR - some severe basic error ++--------------------------------------------------------------------------*/ +int +_nc_Set_Current_Field(FORM *form, FIELD *newfield) +{ + FIELD *field; + WINDOW *new_window; + + if (!form || !newfield || !form->current || (newfield->form!=form)) + return(E_BAD_ARGUMENT); + + if ( (form->status & _IN_DRIVER) ) + return(E_BAD_STATE); + + if (!(form->field)) + return(E_NOT_CONNECTED); + + field = form->current; + + if ((field!=newfield) || + !(form->status & _POSTED)) + { + if ((form->w) && + (field->opts & O_VISIBLE) && + (field->form->curpage == field->page)) + { + _nc_Refresh_Current_Field(form); + if (field->opts & O_PUBLIC) + { + if (field->drows > field->rows) + { + if (form->toprow==0) + field->status &= ~_NEWTOP; + else + field->status |= _NEWTOP; + } + else + { + if (Justification_Allowed(field)) + { + Window_To_Buffer(form->w,field); + werase(form->w); + Perform_Justification(field,form->w); + wsyncup(form->w); + } + } + } + delwin(form->w); + } + + field = newfield; + + if (Has_Invisible_Parts(field)) + new_window = newpad(field->drows,field->dcols); + else + new_window = derwin(Get_Form_Window(form), + field->rows,field->cols,field->frow,field->fcol); + + if (!new_window) + return(E_SYSTEM_ERROR); + + form->current = field; + form->w = new_window; + form->status &= ~_WINDOW_MODIFIED; + Set_Field_Window_Attributes(field,form->w); + + if (Has_Invisible_Parts(field)) + { + werase(form->w); + Buffer_To_Window(field,form->w); + } + else + { + if (Justification_Allowed(field)) + { + werase(form->w); + Undo_Justification(field,form->w); + wsyncup(form->w); + } + } + + untouchwin(form->w); + } + + form->currow = form->curcol = form->toprow = form->begincol = 0; + return(E_OK); +} + +/*---------------------------------------------------------------------------- + Intra-Field Navigation routines + --------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int IFN_Next_Character(FORM * form) +| +| Description : Move to the next character in the field. In a multiline +| field this wraps at the end of the line. +| +| Return Values : E_OK - success +| E_REQUEST_DENIED - at the rightmost position ++--------------------------------------------------------------------------*/ +static int IFN_Next_Character(FORM * form) +{ + FIELD *field = form->current; + + if ((++(form->curcol))==field->dcols) + { + if ((++(form->currow))==field->drows) + { +#if GROW_IF_NAVIGATE + if (!Single_Line_Field(field) && Field_Grown(field,1)) { + form->curcol = 0; + return(E_OK); + } +#endif + form->currow--; +#if GROW_IF_NAVIGATE + if (Single_Line_Field(field) && Field_Grown(field,1)) + return(E_OK); +#endif + form->curcol--; + return(E_REQUEST_DENIED); + } + form->curcol = 0; + } + return(E_OK); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int IFN_Previous_Character(FORM * form) +| +| Description : Move to the previous character in the field. In a +| multiline field this wraps and the beginning of the +| line. +| +| Return Values : E_OK - success +| E_REQUEST_DENIED - at the leftmost position ++--------------------------------------------------------------------------*/ +static int IFN_Previous_Character(FORM * form) +{ + if ((--(form->curcol))<0) + { + if ((--(form->currow))<0) + { + form->currow++; + form->curcol++; + return(E_REQUEST_DENIED); + } + form->curcol = form->current->dcols - 1; + } + return(E_OK); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int IFN_Next_Line(FORM * form) +| +| Description : Move to the beginning of the next line in the field +| +| Return Values : E_OK - success +| E_REQUEST_DENIED - at the last line ++--------------------------------------------------------------------------*/ +static int IFN_Next_Line(FORM * form) +{ + FIELD *field = form->current; + + if ((++(form->currow))==field->drows) + { +#if GROW_IF_NAVIGATE + if (!Single_Line_Field(field) && Field_Grown(field,1)) + return(E_OK); +#endif + form->currow--; + return(E_REQUEST_DENIED); + } + form->curcol = 0; + return(E_OK); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int IFN_Previous_Line(FORM * form) +| +| Description : Move to the beginning of the previous line in the field +| +| Return Values : E_OK - success +| E_REQUEST_DENIED - at the first line ++--------------------------------------------------------------------------*/ +static int IFN_Previous_Line(FORM * form) +{ + if ( (--(form->currow)) < 0 ) + { + form->currow++; + return(E_REQUEST_DENIED); + } + form->curcol = 0; + return(E_OK); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int IFN_Next_Word(FORM * form) +| +| Description : Move to the beginning of the next word in the field. +| +| Return Values : E_OK - success +| E_REQUEST_DENIED - there is no next word ++--------------------------------------------------------------------------*/ +static int IFN_Next_Word(FORM * form) +{ + FIELD *field = form->current; + char *bp = Address_Of_Current_Position_In_Buffer(form); + char *s; + char *t; + + /* We really need access to the data, so we have to synchronize */ + Synchronize_Buffer(form); + + /* Go to the first whitespace after the current position (including + current position). This is then the startpoint to look for the + next non-blank data */ + s = Get_First_Whitespace_Character(bp,Buffer_Length(field) - + (int)(bp - field->buf)); + + /* Find the start of the next word */ + t = Get_Start_Of_Data(s,Buffer_Length(field) - + (int)(s - field->buf)); +#if !FRIENDLY_PREV_NEXT_WORD + if (s==t) + return(E_REQUEST_DENIED); + else +#endif + { + Adjust_Cursor_Position(form,t); + return(E_OK); + } +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int IFN_Previous_Word(FORM * form) +| +| Description : Move to the beginning of the previous word in the field. +| +| Return Values : E_OK - success +| E_REQUEST_DENIED - there is no previous word ++--------------------------------------------------------------------------*/ +static int IFN_Previous_Word(FORM * form) +{ + FIELD *field = form->current; + char *bp = Address_Of_Current_Position_In_Buffer(form); + char *s; + char *t; + bool again = FALSE; + + /* We really need access to the data, so we have to synchronize */ + Synchronize_Buffer(form); + + s = After_End_Of_Data(field->buf,(int)(bp-field->buf)); + /* s points now right after the last non-blank in the buffer before bp. + If bp was in a word, s equals bp. In this case we must find the last + whitespace in the buffer before bp and repeat the game to really find + the previous word! */ + if (s==bp) + again = TRUE; + + /* And next call now goes backward to look for the last whitespace + before that, pointing right after this, so it points to the begin + of the previous word. + */ + t = After_Last_Whitespace_Character(field->buf,(int)(s - field->buf)); +#if !FRIENDLY_PREV_NEXT_WORD + if (s==t) + return(E_REQUEST_DENIED); +#endif + if (again) + { /* and do it again, replacing bp by t */ + s = After_End_Of_Data(field->buf,(int)(t - field->buf)); + t = After_Last_Whitespace_Character(field->buf,(int)(s - field->buf)); +#if !FRIENDLY_PREV_NEXT_WORD + if (s==t) + return(E_REQUEST_DENIED); +#endif + } + Adjust_Cursor_Position(form,t); + return(E_OK); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int IFN_Beginning_Of_Field(FORM * form) +| +| Description : Place the cursor at the first non-pad character in +| the field. +| +| Return Values : E_OK - success ++--------------------------------------------------------------------------*/ +static int IFN_Beginning_Of_Field(FORM * form) +{ + FIELD *field = form->current; + + Synchronize_Buffer(form); + Adjust_Cursor_Position(form, + Get_Start_Of_Data(field->buf,Buffer_Length(field))); + return(E_OK); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int IFN_End_Of_Field(FORM * form) +| +| Description : Place the cursor after the last non-pad character in +| the field. If the field occupies the last position in +| the buffer, the cursos is positioned on the last +| character. +| +| Return Values : E_OK - success ++--------------------------------------------------------------------------*/ +static int IFN_End_Of_Field(FORM * form) +{ + FIELD *field = form->current; + char *pos; + + Synchronize_Buffer(form); + pos = After_End_Of_Data(field->buf,Buffer_Length(field)); + if (pos==(field->buf + Buffer_Length(field))) + pos--; + Adjust_Cursor_Position(form,pos); + return(E_OK); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int IFN_Beginning_Of_Line(FORM * form) +| +| Description : Place the cursor on the first non-pad character in +| the current line of the field. +| +| Return Values : E_OK - success ++--------------------------------------------------------------------------*/ +static int IFN_Beginning_Of_Line(FORM * form) +{ + FIELD *field = form->current; + + Synchronize_Buffer(form); + Adjust_Cursor_Position(form, + Get_Start_Of_Data(Address_Of_Current_Row_In_Buffer(form), + field->dcols)); + return(E_OK); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int IFN_End_Of_Line(FORM * form) +| +| Description : Place the cursor after the last non-pad character in the +| current line of the field. If the field occupies the +| last column in the line, the cursor is positioned on the +| last character of the line. +| +| Return Values : E_OK - success ++--------------------------------------------------------------------------*/ +static int IFN_End_Of_Line(FORM * form) +{ + FIELD *field = form->current; + char *pos; + char *bp; + + Synchronize_Buffer(form); + bp = Address_Of_Current_Row_In_Buffer(form); + pos = After_End_Of_Data(bp,field->dcols); + if (pos == (bp + field->dcols)) + pos--; + Adjust_Cursor_Position(form,pos); + return(E_OK); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int IFN_Left_Character(FORM * form) +| +| Description : Move one character to the left in the current line. +| This doesn't cycle. +| +| Return Values : E_OK - success +| E_REQUEST_DENIED - already in first column ++--------------------------------------------------------------------------*/ +static int IFN_Left_Character(FORM * form) +{ + if ( (--(form->curcol)) < 0 ) + { + form->curcol++; + return(E_REQUEST_DENIED); + } + return(E_OK); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int IFN_Right_Character(FORM * form) +| +| Description : Move one character to the right in the current line. +| This doesn't cycle. +| +| Return Values : E_OK - success +| E_REQUEST_DENIED - already in last column ++--------------------------------------------------------------------------*/ +static int IFN_Right_Character(FORM * form) +{ + if ( (++(form->curcol)) == form->current->dcols ) + { +#if GROW_IF_NAVIGATE + FIELD *field = form->current; + if (Single_Line_Field(field) && Field_Grown(field,1)) + return(E_OK); +#endif + --(form->curcol); + return(E_REQUEST_DENIED); + } + return(E_OK); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int IFN_Up_Character(FORM * form) +| +| Description : Move one line up. This doesn't cycle through the lines +| of the field. +| +| Return Values : E_OK - success +| E_REQUEST_DENIED - already in last column ++--------------------------------------------------------------------------*/ +static int IFN_Up_Character(FORM * form) +{ + if ( (--(form->currow)) < 0 ) + { + form->currow++; + return(E_REQUEST_DENIED); + } + return(E_OK); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int IFN_Down_Character(FORM * form) +| +| Description : Move one line down. This doesn't cycle through the +| lines of the field. +| +| Return Values : E_OK - success +| E_REQUEST_DENIED - already in last column ++--------------------------------------------------------------------------*/ +static int IFN_Down_Character(FORM * form) +{ + FIELD *field = form->current; + + if ( (++(form->currow)) == field->drows ) + { +#if GROW_IF_NAVIGATE + if (!Single_Line_Field(field) && Field_Grown(field,1)) + return(E_OK); +#endif + --(form->currow); + return(E_REQUEST_DENIED); + } + return(E_OK); +} +/*---------------------------------------------------------------------------- + END of Intra-Field Navigation routines + --------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + Vertical scrolling helper routines + --------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int VSC_Generic(FORM *form, int lines) +| +| Description : Scroll multi-line field forward (lines>0) or +| backward (lines<0) this many lines. +| +| Return Values : E_OK - success +| E_REQUEST_DENIED - can't scroll ++--------------------------------------------------------------------------*/ +static int VSC_Generic(FORM *form, int lines) +{ + FIELD *field = form->current; + int res = E_REQUEST_DENIED; + int rows_to_go = (lines > 0 ? lines : -lines); + + if (lines > 0) + { + if ( (rows_to_go + form->toprow) > (field->drows - field->rows) ) + rows_to_go = (field->drows - field->rows - form->toprow); + + if (rows_to_go > 0) + { + form->currow += rows_to_go; + form->toprow += rows_to_go; + res = E_OK; + } + } + else + { + if (rows_to_go > form->toprow) + rows_to_go = form->toprow; + + if (rows_to_go > 0) + { + form->currow -= rows_to_go; + form->toprow -= rows_to_go; + res = E_OK; + } + } + return(res); +} +/*---------------------------------------------------------------------------- + End of Vertical scrolling helper routines + --------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + Vertical scrolling routines + --------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int Vertical_Scrolling( +| int (* const fct) (FORM *), +| FORM * form) +| +| Description : Performs the generic vertical scrolling routines. +| This has to check for a multi-line field and to set +| the _NEWTOP flag if scrolling really occured. +| +| Return Values : Propagated error code from low-level driver calls ++--------------------------------------------------------------------------*/ +static int Vertical_Scrolling(int (* const fct) (FORM *), FORM * form) +{ + int res = E_REQUEST_DENIED; + + if (!Single_Line_Field(form->current)) + { + res = fct(form); + if (res == E_OK) + form->current->status |= _NEWTOP; + } + return(res); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int VSC_Scroll_Line_Forward(FORM * form) +| +| Description : Scroll multi-line field forward a line +| +| Return Values : E_OK - success +| E_REQUEST_DENIED - no data ahead ++--------------------------------------------------------------------------*/ +static int VSC_Scroll_Line_Forward(FORM * form) +{ + return VSC_Generic(form,1); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int VSC_Scroll_Line_Backward(FORM * form) +| +| Description : Scroll multi-line field backward a line +| +| Return Values : E_OK - success +| E_REQUEST_DENIED - no data behind ++--------------------------------------------------------------------------*/ +static int VSC_Scroll_Line_Backward(FORM * form) +{ + return VSC_Generic(form,-1); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int VSC_Scroll_Page_Forward(FORM * form) +| +| Description : Scroll a multi-line field forward a page +| +| Return Values : E_OK - success +| E_REQUEST_DENIED - no data ahead ++--------------------------------------------------------------------------*/ +static int VSC_Scroll_Page_Forward(FORM * form) +{ + return VSC_Generic(form,form->current->rows); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int VSC_Scroll_Half_Page_Forward(FORM * form) +| +| Description : Scroll a multi-line field forward half a page +| +| Return Values : E_OK - success +| E_REQUEST_DENIED - no data ahead ++--------------------------------------------------------------------------*/ +static int VSC_Scroll_Half_Page_Forward(FORM * form) +{ + return VSC_Generic(form,(form->current->rows + 1)/2); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int VSC_Scroll_Page_Backward(FORM * form) +| +| Description : Scroll a multi-line field backward a page +| +| Return Values : E_OK - success +| E_REQUEST_DENIED - no data behind ++--------------------------------------------------------------------------*/ +static int VSC_Scroll_Page_Backward(FORM * form) +{ + return VSC_Generic(form, -(form->current->rows)); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int VSC_Scroll_Half_Page_Backward(FORM * form) +| +| Description : Scroll a multi-line field backward half a page +| +| Return Values : E_OK - success +| E_REQUEST_DENIED - no data behind ++--------------------------------------------------------------------------*/ +static int VSC_Scroll_Half_Page_Backward(FORM * form) +{ + return VSC_Generic(form, -((form->current->rows + 1)/2)); +} +/*---------------------------------------------------------------------------- + End of Vertical scrolling routines + --------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + Horizontal scrolling helper routines + --------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int HSC_Generic(FORM *form, int columns) +| +| Description : Scroll single-line field forward (columns>0) or +| backward (columns<0) this many columns. +| +| Return Values : E_OK - success +| E_REQUEST_DENIED - can't scroll ++--------------------------------------------------------------------------*/ +static int HSC_Generic(FORM *form, int columns) +{ + FIELD *field = form->current; + int res = E_REQUEST_DENIED; + int cols_to_go = (columns > 0 ? columns : -columns); + + if (columns > 0) + { + if ((cols_to_go + form->begincol) > (field->dcols - field->cols)) + cols_to_go = field->dcols - field->cols - form->begincol; + + if (cols_to_go > 0) + { + form->curcol += cols_to_go; + form->begincol += cols_to_go; + res = E_OK; + } + } + else + { + if ( cols_to_go > form->begincol ) + cols_to_go = form->begincol; + + if (cols_to_go > 0) + { + form->curcol -= cols_to_go; + form->begincol -= cols_to_go; + res = E_OK; + } + } + return(res); +} +/*---------------------------------------------------------------------------- + End of Horizontal scrolling helper routines + --------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + Horizontal scrolling routines + --------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int Horizontal_Scrolling( +| int (* const fct) (FORM *), +| FORM * form) +| +| Description : Performs the generic horizontal scrolling routines. +| This has to check for a single-line field. +| +| Return Values : Propagated error code from low-level driver calls ++--------------------------------------------------------------------------*/ +static int Horizontal_Scrolling(int (* const fct) (FORM *), FORM * form) +{ + if (Single_Line_Field(form->current)) + return fct(form); + else + return(E_REQUEST_DENIED); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int HSC_Scroll_Char_Forward(FORM * form) +| +| Description : Scroll single-line field forward a character +| +| Return Values : E_OK - success +| E_REQUEST_DENIED - no data ahead ++--------------------------------------------------------------------------*/ +static int HSC_Scroll_Char_Forward(FORM *form) +{ + return HSC_Generic(form,1); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int HSC_Scroll_Char_Backward(FORM * form) +| +| Description : Scroll single-line field backward a character +| +| Return Values : E_OK - success +| E_REQUEST_DENIED - no data behind ++--------------------------------------------------------------------------*/ +static int HSC_Scroll_Char_Backward(FORM *form) +{ + return HSC_Generic(form,-1); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int HSC_Horizontal_Line_Forward(FORM* form) +| +| Description : Scroll single-line field forward a line +| +| Return Values : E_OK - success +| E_REQUEST_DENIED - no data ahead ++--------------------------------------------------------------------------*/ +static int HSC_Horizontal_Line_Forward(FORM * form) +{ + return HSC_Generic(form,form->current->cols); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int HSC_Horizontal_Half_Line_Forward(FORM* form) +| +| Description : Scroll single-line field forward half a line +| +| Return Values : E_OK - success +| E_REQUEST_DENIED - no data ahead ++--------------------------------------------------------------------------*/ +static int HSC_Horizontal_Half_Line_Forward(FORM * form) +{ + return HSC_Generic(form,(form->current->cols + 1)/2); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int HSC_Horizontal_Line_Backward(FORM* form) +| +| Description : Scroll single-line field backward a line +| +| Return Values : E_OK - success +| E_REQUEST_DENIED - no data behind ++--------------------------------------------------------------------------*/ +static int HSC_Horizontal_Line_Backward(FORM * form) +{ + return HSC_Generic(form,-(form->current->cols)); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int HSC_Horizontal_Half_Line_Backward(FORM* form) +| +| Description : Scroll single-line field backward half a line +| +| Return Values : E_OK - success +| E_REQUEST_DENIED - no data behind ++--------------------------------------------------------------------------*/ +static int HSC_Horizontal_Half_Line_Backward(FORM * form) +{ + return HSC_Generic(form,-((form->current->cols + 1)/2)); +} + +/*---------------------------------------------------------------------------- + End of Horizontal scrolling routines + --------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + Helper routines for Field Editing + --------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static bool Is_There_Room_For_A_Line(FORM * form) +| +| Description : Check whether or not there is enough room in the +| buffer to enter a whole line. +| +| Return Values : TRUE - there is enough space +| FALSE - there is not enough space ++--------------------------------------------------------------------------*/ +INLINE static bool Is_There_Room_For_A_Line(FORM * form) +{ + FIELD *field = form->current; + char *begin_of_last_line, *s; + + Synchronize_Buffer(form); + begin_of_last_line = Address_Of_Row_In_Buffer(field,(field->drows-1)); + s = After_End_Of_Data(begin_of_last_line,field->dcols); + return ((s==begin_of_last_line) ? TRUE : FALSE); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static bool Is_There_Room_For_A_Char_In_Line(FORM * form) +| +| Description : Checks whether or not there is room for a new character +| in the current line. +| +| Return Values : TRUE - there is room +| FALSE - there is not enough room (line full) ++--------------------------------------------------------------------------*/ +INLINE static bool Is_There_Room_For_A_Char_In_Line(FORM * form) +{ + int last_char_in_line; + + wmove(form->w,form->currow,form->current->dcols-1); + last_char_in_line = (int)(winch(form->w) & A_CHARTEXT); + wmove(form->w,form->currow,form->curcol); + return (((last_char_in_line == form->current->pad) || + is_blank(last_char_in_line)) ? TRUE : FALSE); +} + +#define There_Is_No_Room_For_A_Char_In_Line(f) \ + !Is_There_Room_For_A_Char_In_Line(f) + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int Insert_String( +| FORM * form, +| int row, +| char *txt, +| int len ) +| +| Description : Insert the 'len' characters beginning at pointer 'txt' +| into the 'row' of the 'form'. The insertion occurs +| on the beginning of the row, all other characters are +| moved to the right. After the text a pad character will +| be inserted to separate the text from the rest. If +| necessary the insertion moves characters on the next +| line to make place for the requested insertion string. +| +| Return Values : E_OK - success +| E_REQUEST_DENIED - +| E_SYSTEM_ERROR - system error ++--------------------------------------------------------------------------*/ +static int Insert_String(FORM *form, int row, char *txt, int len) +{ + FIELD *field = form->current; + char *bp = Address_Of_Row_In_Buffer(field,row); + int datalen = (int)(After_End_Of_Data(bp,field->dcols) - bp); + int freelen = field->dcols - datalen; + int requiredlen = len+1; + char *split; + int result = E_REQUEST_DENIED; + const char *Space = " "; + + if (freelen >= requiredlen) + { + wmove(form->w,row,0); + winsnstr(form->w,txt,len); + wmove(form->w,row,len); + winsnstr(form->w,Space,1); + return E_OK; + } + else + { /* we have to move characters on the next line. If we are on the + last line this may work, if the field is growable */ + if ((row == (field->drows - 1)) && Growable(field)) + { + if (!Field_Grown(field,1)) + return(E_SYSTEM_ERROR); + /* !!!Side-Effect : might be changed due to growth!!! */ + bp = Address_Of_Row_In_Buffer(field,row); + } + + if (row < (field->drows - 1)) + { + split = After_Last_Whitespace_Character(bp, + (int)(Get_Start_Of_Data(bp + field->dcols - requiredlen , + requiredlen) - bp)); + /* split points now to the first character of the portion of the + line that must be moved to the next line */ + datalen = (int)(split-bp); /* + freelen has to stay on this line */ + freelen = field->dcols - (datalen + freelen); /* for the next line */ + + if ((result=Insert_String(form,row+1,split,freelen))==E_OK) + { + wmove(form->w,row,datalen); + wclrtoeol(form->w); + wmove(form->w,row,0); + winsnstr(form->w,txt,len); + wmove(form->w,row,len); + winsnstr(form->w,Space,1); + return E_OK; + } + } + return(result); + } +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int Wrapping_Not_Necessary_Or_Wrapping_Ok( +| FORM * form) +| +| Description : If a character has been entered into a field, it may +| be that wrapping has to occur. This routine checks +| whether or not wrapping is required and if so, performs +| the wrapping. +| +| Return Values : E_OK - no wrapping required or wrapping +| was successfull +| E_REQUEST_DENIED - +| E_SYSTEM_ERROR - some system error ++--------------------------------------------------------------------------*/ +static int Wrapping_Not_Necessary_Or_Wrapping_Ok(FORM * form) +{ + FIELD *field = form->current; + int result = E_REQUEST_DENIED; + bool Last_Row = ((field->drows - 1) == form->currow); + + if ( (field->opts & O_WRAP) && /* wrapping wanted */ + (!Single_Line_Field(field)) && /* must be multi-line */ + (There_Is_No_Room_For_A_Char_In_Line(form)) && /* line is full */ + (!Last_Row || Growable(field)) ) /* there are more lines*/ + { + char *bp; + char *split; + int chars_to_be_wrapped; + int chars_to_remain_on_line; + if (Last_Row) + { /* the above logic already ensures, that in this case the field + is growable */ + if (!Field_Grown(field,1)) + return E_SYSTEM_ERROR; + } + bp = Address_Of_Current_Row_In_Buffer(form); + Window_To_Buffer(form->w,field); + split = After_Last_Whitespace_Character(bp,field->dcols); + /* split points to the first character of the sequence to be brought + on the next line */ + chars_to_remain_on_line = (int)(split - bp); + chars_to_be_wrapped = field->dcols - chars_to_remain_on_line; + if (chars_to_remain_on_line > 0) + { + if ((result=Insert_String(form,form->currow+1,split, + chars_to_be_wrapped)) == E_OK) + { + wmove(form->w,form->currow,chars_to_remain_on_line); + wclrtoeol(form->w); + if (form->curcol >= chars_to_remain_on_line) + { + form->currow++; + form->curcol -= chars_to_remain_on_line; + } + return E_OK; + } + } + else + return E_OK; + if (result!=E_OK) + { + wmove(form->w,form->currow,form->curcol); + wdelch(form->w); + Window_To_Buffer(form->w,field); + result = E_REQUEST_DENIED; + } + } + else + result = E_OK; /* wrapping was not necessary */ + return(result); +} + +/*---------------------------------------------------------------------------- + Field Editing routines + --------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int Field_Editing( +| int (* const fct) (FORM *), +| FORM * form) +| +| Description : Generic routine for field editing requests. The driver +| routines are only called for editable fields, the +| _WINDOW_MODIFIED flag is set if editing occured. +| This is somewhat special due to the overload semantics +| of the NEW_LINE and DEL_PREV requests. +| +| Return Values : Error code from low level drivers. ++--------------------------------------------------------------------------*/ +static int Field_Editing(int (* const fct) (FORM *), FORM * form) +{ + int res = E_REQUEST_DENIED; + + /* We have to deal here with the specific case of the overloaded + behaviour of New_Line and Delete_Previous requests. + They may end up in navigational requests if we are on the first + character in a field. But navigation is also allowed on non- + editable fields. + */ + if ((fct==FE_Delete_Previous) && + (form->opts & O_BS_OVERLOAD) && + First_Position_In_Current_Field(form) ) + { + res = Inter_Field_Navigation(FN_Previous_Field,form); + } + else + { + if (fct==FE_New_Line) + { + if ((form->opts & O_NL_OVERLOAD) && + First_Position_In_Current_Field(form)) + { + res = Inter_Field_Navigation(FN_Next_Field,form); + } + else + /* FE_New_Line deals itself with the _WINDOW_MODIFIED flag */ + res = fct(form); + } + else + { + /* From now on, everything must be editable */ + if (form->current->opts & O_EDIT) + { + res = fct(form); + if (res==E_OK) + form->status |= _WINDOW_MODIFIED; + } + } + } + return res; +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int FE_New_Line(FORM * form) +| +| Description : Perform a new line request. This is rather complex +| compared to other routines in this code due to the +| rather difficult to understand description in the +| manuals. +| +| Return Values : E_OK - success +| E_REQUEST_DENIED - new line not allowed +| E_SYSTEM_ERROR - system error ++--------------------------------------------------------------------------*/ +static int FE_New_Line(FORM * form) +{ + FIELD *field = form->current; + char *bp, *t; + bool Last_Row = ((field->drows - 1)==form->currow); + + if (form->status & _OVLMODE) + { + if (Last_Row && + (!(Growable(field) && !Single_Line_Field(field)))) + { + if (!(form->opts & O_NL_OVERLOAD)) + return(E_REQUEST_DENIED); + wclrtoeol(form->w); + /* we have to set this here, although it is also + handled in the generic routine. The reason is, + that FN_Next_Field may fail, but the form is + definitively changed */ + form->status |= _WINDOW_MODIFIED; + return Inter_Field_Navigation(FN_Next_Field,form); + } + else + { + if (Last_Row && !Field_Grown(field,1)) + { /* N.B.: due to the logic in the 'if', LastRow==TRUE + means here that the field is growable and not + a single-line field */ + return(E_SYSTEM_ERROR); + } + wclrtoeol(form->w); + form->currow++; + form->curcol = 0; + form->status |= _WINDOW_MODIFIED; + return(E_OK); + } + } + else + { /* Insert Mode */ + if (Last_Row && + !(Growable(field) && !Single_Line_Field(field))) + { + if (!(form->opts & O_NL_OVERLOAD)) + return(E_REQUEST_DENIED); + return Inter_Field_Navigation(FN_Next_Field,form); + } + else + { + bool May_Do_It = !Last_Row && Is_There_Room_For_A_Line(form); + + if (!(May_Do_It || Growable(field))) + return(E_REQUEST_DENIED); + if (!May_Do_It && !Field_Grown(field,1)) + return(E_SYSTEM_ERROR); + + bp= Address_Of_Current_Position_In_Buffer(form); + t = After_End_Of_Data(bp,field->dcols - form->curcol); + wclrtoeol(form->w); + form->currow++; + form->curcol=0; + wmove(form->w,form->currow,form->curcol); + winsertln(form->w); + waddnstr(form->w,bp,(int)(t-bp)); + form->status |= _WINDOW_MODIFIED; + return E_OK; + } + } +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int FE_Insert_Character(FORM * form) +| +| Description : Insert blank character at the cursor position +| +| Return Values : E_OK +| E_REQUEST_DENIED ++--------------------------------------------------------------------------*/ +static int FE_Insert_Character(FORM * form) +{ + FIELD *field = form->current; + int result = E_REQUEST_DENIED; + + if (Check_Char(field->type,(int)C_BLANK,(TypeArgument *)(field->arg))) + { + bool There_Is_Room = Is_There_Room_For_A_Char_In_Line(form); + + if (There_Is_Room || + ((Single_Line_Field(field) && Growable(field)))) + { + if (!There_Is_Room && !Field_Grown(field,1)) + result = E_SYSTEM_ERROR; + else + { + winsch(form->w,(chtype)C_BLANK); + result = Wrapping_Not_Necessary_Or_Wrapping_Ok(form); + } + } + } + return result; +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int FE_Insert_Line(FORM * form) +| +| Description : Insert a blank line at the cursor position +| +| Return Values : E_OK - success +| E_REQUEST_DENIED - line can not be inserted ++--------------------------------------------------------------------------*/ +static int FE_Insert_Line(FORM * form) +{ + FIELD *field = form->current; + int result = E_REQUEST_DENIED; + + if (Check_Char(field->type,(int)C_BLANK,(TypeArgument *)(field->arg))) + { + bool Maybe_Done = (form->currow!=(field->drows-1)) && + Is_There_Room_For_A_Line(form); + + if (!Single_Line_Field(field) && + (Maybe_Done || Growable(field))) + { + if (!Maybe_Done && !Field_Grown(field,1)) + result = E_SYSTEM_ERROR; + else + { + form->curcol = 0; + winsertln(form->w); + result = E_OK; + } + } + } + return result; +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int FE_Delete_Character(FORM * form) +| +| Description : Delete character at the cursor position +| +| Return Values : E_OK - success ++--------------------------------------------------------------------------*/ +static int FE_Delete_Character(FORM * form) +{ + wdelch(form->w); + return E_OK; +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int FE_Delete_Previous(FORM * form) +| +| Description : Delete character before cursor. Again this is a rather +| difficult piece compared to others due to the overloading +| semantics of backspace. +| N.B.: The case of overloaded BS on first field position +| is already handled in the generic routine. +| +| Return Values : E_OK - success +| E_REQUEST_DENIED - Character can't be deleted ++--------------------------------------------------------------------------*/ +static int FE_Delete_Previous(FORM * form) +{ + FIELD *field = form->current; + + if (First_Position_In_Current_Field(form)) + return E_REQUEST_DENIED; + + if ( (--(form->curcol))<0 ) + { + char *this_line, *prev_line, *prev_end, *this_end; + + form->curcol++; + if (form->status & _OVLMODE) + return E_REQUEST_DENIED; + + prev_line = Address_Of_Row_In_Buffer(field,(form->currow-1)); + this_line = Address_Of_Row_In_Buffer(field,(form->currow)); + Synchronize_Buffer(form); + prev_end = After_End_Of_Data(prev_line,field->dcols); + this_end = After_End_Of_Data(this_line,field->dcols); + if ((int)(this_end-this_line) > + (field->cols-(int)(prev_end-prev_line))) + return E_REQUEST_DENIED; + wdeleteln(form->w); + Adjust_Cursor_Position(form,prev_end); + wmove(form->w,form->currow,form->curcol); + waddnstr(form->w,this_line,(int)(this_end-this_line)); + } + else + { + wmove(form->w,form->currow,form->curcol); + wdelch(form->w); + } + return E_OK; +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int FE_Delete_Line(FORM * form) +| +| Description : Delete line at cursor position. +| +| Return Values : E_OK - success ++--------------------------------------------------------------------------*/ +static int FE_Delete_Line(FORM * form) +{ + form->curcol = 0; + wdeleteln(form->w); + return E_OK; +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int FE_Delete_Word(FORM * form) +| +| Description : Delete word at cursor position +| +| Return Values : E_OK - success +| E_REQUEST_DENIED - failure ++--------------------------------------------------------------------------*/ +static int FE_Delete_Word(FORM * form) +{ + FIELD *field = form->current; + char *bp = Address_Of_Current_Row_In_Buffer(form); + char *ep = bp + field->dcols; + char *cp = bp + form->curcol; + char *s; + + Synchronize_Buffer(form); + if (is_blank(*cp)) + return E_REQUEST_DENIED; /* not in word */ + + /* move cursor to begin of word and erase to end of screen-line */ + Adjust_Cursor_Position(form, + After_Last_Whitespace_Character(bp,form->curcol)); + wmove(form->w,form->currow,form->curcol); + wclrtoeol(form->w); + + /* skip over word in buffer */ + s = Get_First_Whitespace_Character(cp,(int)(ep-cp)); + /* to begin of next word */ + s = Get_Start_Of_Data(s,(int)(ep - s)); + if ( (s!=cp) && !is_blank(*s)) + { + /* copy remaining line to window */ + waddnstr(form->w,s,(int)(s - After_End_Of_Data(s,(int)(ep - s)))); + } + return E_OK; +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int FE_Clear_To_End_Of_Line(FORM * form) +| +| Description : Clear to end of current line. +| +| Return Values : E_OK - success ++--------------------------------------------------------------------------*/ +static int FE_Clear_To_End_Of_Line(FORM * form) +{ + wclrtoeol(form->w); + return E_OK; +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int FE_Clear_To_End_Of_Form(FORM * form) +| +| Description : Clear to end of form. +| +| Return Values : E_OK - success ++--------------------------------------------------------------------------*/ +static int FE_Clear_To_End_Of_Form(FORM * form) +{ + wclrtobot(form->w); + return E_OK; +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int FE_Clear_Field(FORM * form) +| +| Description : Clear entire field. +| +| Return Values : E_OK - success ++--------------------------------------------------------------------------*/ +static int FE_Clear_Field(FORM * form) +{ + form->currow = form->curcol = 0; + werase(form->w); + return E_OK; +} +/*---------------------------------------------------------------------------- + END of Field Editing routines + --------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + Edit Mode routines + --------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int EM_Overlay_Mode(FORM * form) +| +| Description : Switch to overlay mode. +| +| Return Values : E_OK - success ++--------------------------------------------------------------------------*/ +static int EM_Overlay_Mode(FORM * form) +{ + form->status |= _OVLMODE; + return E_OK; +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int EM_Insert_Mode(FORM * form) +| +| Description : Switch to insert mode +| +| Return Values : E_OK - success ++--------------------------------------------------------------------------*/ +static int EM_Insert_Mode(FORM * form) +{ + form->status &= ~_OVLMODE; + return E_OK; +} + +/*---------------------------------------------------------------------------- + END of Edit Mode routines + --------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + Helper routines for Choice Requests + --------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static bool Next_Choice( +| FIELDTYPE * typ, +| FIELD * field, +| TypeArgument *argp) +| +| Description : Get the next field choice. For linked types this is +| done recursively. +| +| Return Values : TRUE - next choice successfully retrieved +| FALSE - couldn't retrieve next choice ++--------------------------------------------------------------------------*/ +static bool Next_Choice(FIELDTYPE * typ, FIELD *field, TypeArgument *argp) +{ + if (!typ || !(typ->status & _HAS_CHOICE)) + return FALSE; + + if (typ->status & _LINKED_TYPE) + { + assert(argp); + return( + Next_Choice(typ->left ,field,argp->left) || + Next_Choice(typ->right,field,argp->right) ); + } + else + { + assert(typ->next); + return typ->next(field,(void *)argp); + } +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static bool Previous_Choice( +| FIELDTYPE * typ, +| FIELD * field, +| TypeArgument *argp) +| +| Description : Get the previous field choice. For linked types this +| is done recursively. +| +| Return Values : TRUE - previous choice successfully retrieved +| FALSE - couldn't retrieve previous choice ++--------------------------------------------------------------------------*/ +static bool Previous_Choice(FIELDTYPE *typ, FIELD *field, TypeArgument *argp) +{ + if (!typ || !(typ->status & _HAS_CHOICE)) + return FALSE; + + if (typ->status & _LINKED_TYPE) + { + assert(argp); + return( + Previous_Choice(typ->left ,field,argp->left) || + Previous_Choice(typ->right,field,argp->right)); + } + else + { + assert(typ->prev); + return typ->prev(field,(void *)argp); + } +} +/*---------------------------------------------------------------------------- + End of Helper routines for Choice Requests + --------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + Routines for Choice Requests + --------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int CR_Next_Choice(FORM * form) +| +| Description : Get the next field choice. +| +| Return Values : E_OK - success +| E_REQUEST_DENIED - next choice couldn't be retrieved ++--------------------------------------------------------------------------*/ +static int CR_Next_Choice(FORM * form) +{ + FIELD *field = form->current; + Synchronize_Buffer(form); + return ((Next_Choice(field->type,field,(TypeArgument *)(field->arg))) ? + E_OK : E_REQUEST_DENIED); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int CR_Previous_Choice(FORM * form) +| +| Description : Get the previous field choice. +| +| Return Values : E_OK - success +| E_REQUEST_DENIED - prev. choice couldn't be retrieved ++--------------------------------------------------------------------------*/ +static int CR_Previous_Choice(FORM * form) +{ + FIELD *field = form->current; + Synchronize_Buffer(form); + return ((Previous_Choice(field->type,field,(TypeArgument *)(field->arg))) ? + E_OK : E_REQUEST_DENIED); +} +/*---------------------------------------------------------------------------- + End of Routines for Choice Requests + --------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + Helper routines for Field Validations. + --------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static bool Check_Field( +| FIELDTYPE * typ, +| FIELD * field, +| TypeArgument * argp) +| +| Description : Check the field according to its fieldtype and its +| actual arguments. For linked fieldtypes this is done +| recursively. +| +| Return Values : TRUE - field is valid +| FALSE - field is invalid. ++--------------------------------------------------------------------------*/ +static bool Check_Field(FIELDTYPE *typ, FIELD *field, TypeArgument *argp) +{ + if (typ) + { + if (field->opts & O_NULLOK) + { + char *bp = field->buf; + assert(bp); + while(is_blank(*bp)) + { bp++; } + if (*bp == '\0') + return TRUE; + } + + if (typ->status & _LINKED_TYPE) + { + assert(argp); + return( + Check_Field(typ->left ,field,argp->left ) || + Check_Field(typ->right,field,argp->right) ); + } + else + { + if (typ->fcheck) + return typ->fcheck(field,(void *)argp); + } + } + return TRUE; +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : bool _nc_Internal_Validation(FORM * form ) +| +| Description : Validate the current field of the form. +| +| Return Values : TRUE - field is valid +| FALSE - field is invalid ++--------------------------------------------------------------------------*/ +bool +_nc_Internal_Validation(FORM *form) +{ + FIELD *field; + + field = form->current; + + Synchronize_Buffer(form); + if ((form->status & _FCHECK_REQUIRED) || + (!(field->opts & O_PASSOK))) + { + if (!Check_Field(field->type,field,(TypeArgument *)(field->arg))) + return FALSE; + form->status &= ~_FCHECK_REQUIRED; + field->status |= _CHANGED; + Synchronize_Linked_Fields(field); + } + return TRUE; +} +/*---------------------------------------------------------------------------- + End of Helper routines for Field Validations. + --------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + Routines for Field Validation. + --------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int FV_Validation(FORM * form) +| +| Description : Validate the current field of the form. +| +| Return Values : E_OK - field valid +| E_INVALID_FIELD - field not valid ++--------------------------------------------------------------------------*/ +static int FV_Validation(FORM * form) +{ + if (_nc_Internal_Validation(form)) + return E_OK; + else + return E_INVALID_FIELD; +} +/*---------------------------------------------------------------------------- + End of routines for Field Validation. + --------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + Helper routines for Inter-Field Navigation + --------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static FIELD *Next_Field_On_Page(FIELD * field) +| +| Description : Get the next field after the given field on the current +| page. The order of fields is the one defined by the +| fields array. Only visible and active fields are +| counted. +| +| Return Values : Pointer to the next field. ++--------------------------------------------------------------------------*/ +INLINE static FIELD *Next_Field_On_Page(FIELD * field) +{ + FORM *form = field->form; + FIELD **field_on_page = &form->field[field->index]; + FIELD **first_on_page = &form->field[form->page[form->curpage].pmin]; + FIELD **last_on_page = &form->field[form->page[form->curpage].pmax]; + + do + { + field_on_page = + (field_on_page==last_on_page) ? first_on_page : field_on_page + 1; + if (Field_Is_Selectable(*field_on_page)) + break; + } while(field!=(*field_on_page)); + return(*field_on_page); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : FIELD* _nc_First_Active_Field(FORM * form) +| +| Description : Get the first active field on the current page, +| if there are such. If there are none, get the first +| visible field on the page. If there are also none, +| we return the first field on page and hope the best. +| +| Return Values : Pointer to calculated field. ++--------------------------------------------------------------------------*/ +FIELD* +_nc_First_Active_Field(FORM * form) +{ + FIELD **last_on_page = &form->field[form->page[form->curpage].pmax]; + FIELD *proposed = Next_Field_On_Page(*last_on_page); + + if (proposed == *last_on_page) + { /* there might be the special situation, where there is no + active and visible field on the current page. We then select + the first visible field on this readonly page + */ + if (Field_Is_Not_Selectable(proposed)) + { + FIELD **field = &form->field[proposed->index]; + FIELD **first = &form->field[form->page[form->curpage].pmin]; + + do + { + field = (field==last_on_page) ? first : field + 1; + if (((*field)->opts & O_VISIBLE)) + break; + } while(proposed!=(*field)); + + proposed = *field; + + if ((proposed == *last_on_page) && !(proposed->opts&O_VISIBLE)) + { /* This means, there is also no visible field on the page. + So we propose the first one and hope the very best... + Some very clever user has designed a readonly and invisible + page on this form. + */ + proposed = *first; + } + } + } + return(proposed); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static FIELD *Previous_Field_On_Page(FIELD * field) +| +| Description : Get the previous field before the given field on the +| current page. The order of fields is the one defined by +| the fields array. Only visible and active fields are +| counted. +| +| Return Values : Pointer to the previous field. ++--------------------------------------------------------------------------*/ +INLINE static FIELD *Previous_Field_On_Page(FIELD * field) +{ + FORM *form = field->form; + FIELD **field_on_page = &form->field[field->index]; + FIELD **first_on_page = &form->field[form->page[form->curpage].pmin]; + FIELD **last_on_page = &form->field[form->page[form->curpage].pmax]; + + do + { + field_on_page = + (field_on_page==first_on_page) ? last_on_page : field_on_page - 1; + if (Field_Is_Selectable(*field_on_page)) + break; + } while(field!=(*field_on_page)); + + return (*field_on_page); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static FIELD *Sorted_Next_Field(FIELD * field) +| +| Description : Get the next field after the given field on the current +| page. The order of fields is the one defined by the +| (row,column) geometry, rows are major. +| +| Return Values : Pointer to the next field. ++--------------------------------------------------------------------------*/ +INLINE static FIELD *Sorted_Next_Field(FIELD * field) +{ + FIELD *field_on_page = field; + + do + { + field_on_page = field_on_page->snext; + if (Field_Is_Selectable(field_on_page)) + break; + } while(field_on_page!=field); + + return (field_on_page); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static FIELD *Sorted_Previous_Field(FIELD * field) +| +| Description : Get the previous field before the given field on the +| current page. The order of fields is the one defined +| by the (row,column) geometry, rows are major. +| +| Return Values : Pointer to the previous field. ++--------------------------------------------------------------------------*/ +INLINE static FIELD *Sorted_Previous_Field(FIELD * field) +{ + FIELD *field_on_page = field; + + do + { + field_on_page = field_on_page->sprev; + if (Field_Is_Selectable(field_on_page)) + break; + } while(field_on_page!=field); + + return (field_on_page); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static FIELD *Left_Neighbour_Field(FIELD * field) +| +| Description : Get the left neighbour of the field on the same line +| and the same page. Cycles through the line. +| +| Return Values : Pointer to left neighbour field. ++--------------------------------------------------------------------------*/ +INLINE static FIELD *Left_Neighbour_Field(FIELD * field) +{ + FIELD *field_on_page = field; + + /* For a field that has really a left neighbour, the while clause + immediately fails and the loop is left, positioned at the right + neighbour. Otherwise we cycle backwards through the sorted fieldlist + until we enter the same line (from the right end). + */ + do + { + field_on_page = Sorted_Previous_Field(field_on_page); + } while(field_on_page->frow != field->frow); + + return (field_on_page); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static FIELD *Right_Neighbour_Field(FIELD * field) +| +| Description : Get the right neighbour of the field on the same line +| and the same page. +| +| Return Values : Pointer to right neighbour field. ++--------------------------------------------------------------------------*/ +INLINE static FIELD *Right_Neighbour_Field(FIELD * field) +{ + FIELD *field_on_page = field; + + /* See the comments on Left_Neighbour_Field to understand how it works */ + do + { + field_on_page = Sorted_Next_Field(field_on_page); + } while(field_on_page->frow != field->frow); + + return (field_on_page); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static FIELD *Upper_Neighbour_Field(FIELD * field) +| +| Description : Because of the row-major nature of sorting the fields, +| its more difficult to define whats the upper neighbour +| field really means. We define that it must be on a +| 'previous' line (cyclic order!) and is the rightmost +| field laying on the left side of the given field. If +| this set is empty, we take the first field on the line. +| +| Return Values : Pointer to the upper neighbour field. ++--------------------------------------------------------------------------*/ +static FIELD *Upper_Neighbour_Field(FIELD * field) +{ + FIELD *field_on_page = field; + int frow = field->frow; + int fcol = field->fcol; + + /* Walk back to the 'previous' line. The second term in the while clause + just guarantees that we stop if we cycled through the line because + there might be no 'previous' line if the page has just one line. + */ + do + { + field_on_page = Sorted_Previous_Field(field_on_page); + } while(field_on_page->frow==frow && field_on_page->fcol!=fcol); + + if (field_on_page->frow!=frow) + { /* We really found a 'previous' line. We are positioned at the + rightmost field on this line */ + frow = field_on_page->frow; + + /* We walk to the left as long as we are really right of the + field. */ + while(field_on_page->frow==frow && field_on_page->fcol>fcol) + field_on_page = Sorted_Previous_Field(field_on_page); + + /* If we wrapped, just go to the right which is the first field on + the row */ + if (field_on_page->frow!=frow) + field_on_page = Sorted_Next_Field(field_on_page); + } + + return (field_on_page); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static FIELD *Down_Neighbour_Field(FIELD * field) +| +| Description : Because of the row-major nature of sorting the fields, +| its more difficult to define whats the down neighbour +| field really means. We define that it must be on a +| 'next' line (cyclic order!) and is the leftmost +| field laying on the right side of the given field. If +| this set is empty, we take the last field on the line. +| +| Return Values : Pointer to the upper neighbour field. ++--------------------------------------------------------------------------*/ +static FIELD *Down_Neighbour_Field(FIELD * field) +{ + FIELD *field_on_page = field; + int frow = field->frow; + int fcol = field->fcol; + + /* Walk forward to the 'next' line. The second term in the while clause + just guarantees that we stop if we cycled through the line because + there might be no 'next' line if the page has just one line. + */ + do + { + field_on_page = Sorted_Next_Field(field_on_page); + } while(field_on_page->frow==frow && field_on_page->fcol!=fcol); + + if (field_on_page->frow!=frow) + { /* We really found a 'next' line. We are positioned at the rightmost + field on this line */ + frow = field_on_page->frow; + + /* We walk to the right as long as we are really left of the + field. */ + while(field_on_page->frow==frow && field_on_page->fcol<fcol) + field_on_page = Sorted_Next_Field(field_on_page); + + /* If we wrapped, just go to the left which is the last field on + the row */ + if (field_on_page->frow!=frow) + field_on_page = Sorted_Previous_Field(field_on_page); + } + + return(field_on_page); +} + +/*---------------------------------------------------------------------------- + Inter-Field Navigation routines + --------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int Inter_Field_Navigation( +| int (* const fct) (FORM *), +| FORM * form) +| +| Description : Generic behaviour for changing the current field, the +| field is left and a new field is entered. So the field +| must be validated and the field init/term hooks must +| be called. +| +| Return Values : E_OK - success +| E_INVALID_FIELD - field is invalid +| some other - error from subordinate call ++--------------------------------------------------------------------------*/ +static int Inter_Field_Navigation(int (* const fct) (FORM *),FORM *form) +{ + int res; + + if (!_nc_Internal_Validation(form)) + res = E_INVALID_FIELD; + else + { + Call_Hook(form,fieldterm); + res = fct(form); + Call_Hook(form,fieldinit); + } + return res; +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int FN_Next_Field(FORM * form) +| +| Description : Move to the next field on the current page of the form +| +| Return Values : E_OK - success +| != E_OK - error from subordinate call ++--------------------------------------------------------------------------*/ +static int FN_Next_Field(FORM * form) +{ + return _nc_Set_Current_Field(form, + Next_Field_On_Page(form->current)); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int FN_Previous_Field(FORM * form) +| +| Description : Move to the previous field on the current page of the +| form +| +| Return Values : E_OK - success +| != E_OK - error from subordinate call ++--------------------------------------------------------------------------*/ +static int FN_Previous_Field(FORM * form) +{ + return _nc_Set_Current_Field(form, + Previous_Field_On_Page(form->current)); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int FN_First_Field(FORM * form) +| +| Description : Move to the first field on the current page of the form +| +| Return Values : E_OK - success +| != E_OK - error from subordinate call ++--------------------------------------------------------------------------*/ +static int FN_First_Field(FORM * form) +{ + return _nc_Set_Current_Field(form, + Next_Field_On_Page(form->field[form->page[form->curpage].pmax])); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int FN_Last_Field(FORM * form) +| +| Description : Move to the last field on the current page of the form +| +| Return Values : E_OK - success +| != E_OK - error from subordinate call ++--------------------------------------------------------------------------*/ +static int FN_Last_Field(FORM * form) +{ + return + _nc_Set_Current_Field(form, + Previous_Field_On_Page(form->field[form->page[form->curpage].pmin])); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int FN_Sorted_Next_Field(FORM * form) +| +| Description : Move to the sorted next field on the current page +| of the form. +| +| Return Values : E_OK - success +| != E_OK - error from subordinate call ++--------------------------------------------------------------------------*/ +static int FN_Sorted_Next_Field(FORM * form) +{ + return _nc_Set_Current_Field(form, + Sorted_Next_Field(form->current)); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int FN_Sorted_Previous_Field(FORM * form) +| +| Description : Move to the sorted previous field on the current page +| of the form. +| +| Return Values : E_OK - success +| != E_OK - error from subordinate call ++--------------------------------------------------------------------------*/ +static int FN_Sorted_Previous_Field(FORM * form) +{ + return _nc_Set_Current_Field(form, + Sorted_Previous_Field(form->current)); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int FN_Sorted_First_Field(FORM * form) +| +| Description : Move to the sorted first field on the current page +| of the form. +| +| Return Values : E_OK - success +| != E_OK - error from subordinate call ++--------------------------------------------------------------------------*/ +static int FN_Sorted_First_Field(FORM * form) +{ + return _nc_Set_Current_Field(form, + Sorted_Next_Field(form->field[form->page[form->curpage].smax])); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int FN_Sorted_Last_Field(FORM * form) +| +| Description : Move to the sorted last field on the current page +| of the form. +| +| Return Values : E_OK - success +| != E_OK - error from subordinate call ++--------------------------------------------------------------------------*/ +static int FN_Sorted_Last_Field(FORM * form) +{ + return _nc_Set_Current_Field(form, + Sorted_Previous_Field(form->field[form->page[form->curpage].smin])); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int FN_Left_Field(FORM * form) +| +| Description : Get the field on the left of the current field on the +| same line and the same page. Cycles through the line. +| +| Return Values : E_OK - success +| != E_OK - error from subordinate call ++--------------------------------------------------------------------------*/ +static int FN_Left_Field(FORM * form) +{ + return _nc_Set_Current_Field(form, + Left_Neighbour_Field(form->current)); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int FN_Right_Field(FORM * form) +| +| Description : Get the field on the right of the current field on the +| same line and the same page. Cycles through the line. +| +| Return Values : E_OK - success +| != E_OK - error from subordinate call ++--------------------------------------------------------------------------*/ +static int FN_Right_Field(FORM * form) +{ + return _nc_Set_Current_Field(form, + Right_Neighbour_Field(form->current)); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int FN_Up_Field(FORM * form) +| +| Description : Get the upper neighbour of the current field. This +| cycles through the page. See the comments of the +| Upper_Neighbour_Field function to understand how +| 'upper' is defined. +| +| Return Values : E_OK - success +| != E_OK - error from subordinate call ++--------------------------------------------------------------------------*/ +static int FN_Up_Field(FORM * form) +{ + return _nc_Set_Current_Field(form, + Upper_Neighbour_Field(form->current)); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int FN_Down_Field(FORM * form) +| +| Description : Get the down neighbour of the current field. This +| cycles through the page. See the comments of the +| Down_Neighbour_Field function to understand how +| 'down' is defined. +| +| Return Values : E_OK - success +| != E_OK - error from subordinate call ++--------------------------------------------------------------------------*/ +static int FN_Down_Field(FORM * form) +{ + return _nc_Set_Current_Field(form, + Down_Neighbour_Field(form->current)); +} +/*---------------------------------------------------------------------------- + END of Field Navigation routines + --------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + Helper routines for Page Navigation + --------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : int _nc_Set_Form_Page(FORM * form, +| int page, +| FIELD * field) +| +| Description : Make the given page nr. the current page and make +| the given field the current field on the page. If +| for the field NULL is given, make the first field on +| the page the current field. The routine acts only +| if the requested page is not the current page. +| +| Return Values : E_OK - success +| != E_OK - error from subordinate call ++--------------------------------------------------------------------------*/ +int +_nc_Set_Form_Page(FORM * form, int page, FIELD * field) +{ + int res = E_OK; + + if ((form->curpage!=page)) + { + FIELD *last_field, *field_on_page; + + werase(Get_Form_Window(form)); + form->curpage = page; + last_field = field_on_page = form->field[form->page[page].smin]; + do + { + if (field_on_page->opts & O_VISIBLE) + if ((res=Display_Field(field_on_page))!=E_OK) + return(res); + field_on_page = field_on_page->snext; + } while(field_on_page != last_field); + + if (field) + res = _nc_Set_Current_Field(form,field); + else + /* N.B.: we don't encapsulate this by Inter_Field_Navigation(), + because this is already executed in a page navigation + context that contains field navigation + */ + res = FN_First_Field(form); + } + return(res); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int Next_Page_Number(const FORM * form) +| +| Description : Calculate the page number following the current page +| number. This cycles if the highest page number is +| reached. +| +| Return Values : The next page number ++--------------------------------------------------------------------------*/ +INLINE static int Next_Page_Number(const FORM * form) +{ + return (form->curpage + 1) % form->maxpage; +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int Previous_Page_Number(const FORM * form) +| +| Description : Calculate the page number before the current page +| number. This cycles if the first page number is +| reached. +| +| Return Values : The previous page number ++--------------------------------------------------------------------------*/ +INLINE static int Previous_Page_Number(const FORM * form) +{ + return (form->curpage!=0 ? form->curpage - 1 : form->maxpage - 1); +} + +/*---------------------------------------------------------------------------- + Page Navigation routines + --------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int Page_Navigation( +| int (* const fct) (FORM *), +| FORM * form) +| +| Description : Generic behaviour for changing a page. This means +| that the field is left and a new field is entered. +| So the field must be validated and the field init/term +| hooks must be called. Because also the page is changed, +| the forms init/term hooks must be called also. +| +| Return Values : E_OK - success +| E_INVALID_FIELD - field is invalid +| some other - error from subordinate call ++--------------------------------------------------------------------------*/ +static int Page_Navigation(int (* const fct) (FORM *), FORM * form) +{ + int res; + + if (!_nc_Internal_Validation(form)) + res = E_INVALID_FIELD; + else + { + Call_Hook(form,fieldterm); + Call_Hook(form,formterm); + res = fct(form); + Call_Hook(form,forminit); + Call_Hook(form,fieldinit); + } + return res; +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int PN_Next_Page(FORM * form) +| +| Description : Move to the next page of the form +| +| Return Values : E_OK - success +| != E_OK - error from subordinate call ++--------------------------------------------------------------------------*/ +static int PN_Next_Page(FORM * form) +{ + return _nc_Set_Form_Page(form,Next_Page_Number(form),(FIELD *)0); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int PN_Previous_Page(FORM * form) +| +| Description : Move to the previous page of the form +| +| Return Values : E_OK - success +| != E_OK - error from subordinate call ++--------------------------------------------------------------------------*/ +static int PN_Previous_Page(FORM * form) +{ + return _nc_Set_Form_Page(form,Previous_Page_Number(form),(FIELD *)0); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int PN_First_Page(FORM * form) +| +| Description : Move to the first page of the form +| +| Return Values : E_OK - success +| != E_OK - error from subordinate call ++--------------------------------------------------------------------------*/ +static int PN_First_Page(FORM * form) +{ + return _nc_Set_Form_Page(form,0,(FIELD *)0); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int PN_Last_Page(FORM * form) +| +| Description : Move to the last page of the form +| +| Return Values : E_OK - success +| != E_OK - error from subordinate call ++--------------------------------------------------------------------------*/ +static int PN_Last_Page(FORM * form) +{ + return _nc_Set_Form_Page(form,form->maxpage-1,(FIELD *)0); +} +/*---------------------------------------------------------------------------- + END of Field Navigation routines + --------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + Helper routines for the core form driver. + --------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int Data_Entry(FORM * form,int c) +| +| Description : Enter character c into at the current position of the +| current field of the form. +| +| Return Values : E_OK - +| E_REQUEST_DENIED - +| E_SYSTEM_ERROR - ++--------------------------------------------------------------------------*/ +static int Data_Entry(FORM * form, int c) +{ + FIELD *field = form->current; + int result = E_REQUEST_DENIED; + + if ( (field->opts & O_EDIT) +#if FIX_FORM_INACTIVE_BUG + && (field->opts & O_ACTIVE) +#endif + ) + { + if ( (field->opts & O_BLANK) && + First_Position_In_Current_Field(form) && + !(form->status & _FCHECK_REQUIRED) && + !(form->status & _WINDOW_MODIFIED) ) + werase(form->w); + + if (form->status & _OVLMODE) + { + waddch(form->w,(chtype)c); + } + else /* no _OVLMODE */ + { + bool There_Is_Room = Is_There_Room_For_A_Char_In_Line(form); + + if (!(There_Is_Room || + ((Single_Line_Field(field) && Growable(field))))) + return E_REQUEST_DENIED; + + if (!There_Is_Room && !Field_Grown(field,1)) + return E_SYSTEM_ERROR; + + winsch(form->w,(chtype)c); + } + + if ((result=Wrapping_Not_Necessary_Or_Wrapping_Ok(form))==E_OK) + { + bool End_Of_Field= (((field->drows-1)==form->currow) && + ((field->dcols-1)==form->curcol)); + form->status |= _WINDOW_MODIFIED; + if (End_Of_Field && !Growable(field) && (field->opts & O_AUTOSKIP)) + result = Inter_Field_Navigation(FN_Next_Field,form); + else + { + if (End_Of_Field && Growable(field) && !Field_Grown(field,1)) + result = E_SYSTEM_ERROR; + else + { + IFN_Next_Character(form); + result = E_OK; + } + } + } + } + return result; +} + +/* Structure to describe the binding of a request code to a function. + The member keycode codes the request value as well as the generic + routine to use for the request. The code for the generic routine + is coded in the upper 16 Bits while the request code is coded in + the lower 16 bits. + + In terms of C++ you might think of a request as a class with a + virtual method "perform". The different types of request are + derived from this base class and overload (or not) the base class + implementation of perform. +*/ +typedef struct { + int keycode; /* must be at least 32 bit: hi:mode, lo: key */ + int (*cmd)(FORM *); /* low level driver routine for this key */ +} Binding_Info; + +/* You may see this is the class-id of the request type class */ +#define ID_PN (0x00000000) /* Page navigation */ +#define ID_FN (0x00010000) /* Inter-Field navigation */ +#define ID_IFN (0x00020000) /* Intra-Field navigation */ +#define ID_VSC (0x00030000) /* Vertical Scrolling */ +#define ID_HSC (0x00040000) /* Horizontal Scrolling */ +#define ID_FE (0x00050000) /* Field Editing */ +#define ID_EM (0x00060000) /* Edit Mode */ +#define ID_FV (0x00070000) /* Field Validation */ +#define ID_CH (0x00080000) /* Choice */ +#define ID_Mask (0xffff0000) +#define Key_Mask (0x0000ffff) +#define ID_Shft (16) + +/* This array holds all the Binding Infos */ +static const Binding_Info bindings[MAX_FORM_COMMAND - MIN_FORM_COMMAND + 1] = +{ + { REQ_NEXT_PAGE |ID_PN ,PN_Next_Page}, + { REQ_PREV_PAGE |ID_PN ,PN_Previous_Page}, + { REQ_FIRST_PAGE |ID_PN ,PN_First_Page}, + { REQ_LAST_PAGE |ID_PN ,PN_Last_Page}, + + { REQ_NEXT_FIELD |ID_FN ,FN_Next_Field}, + { REQ_PREV_FIELD |ID_FN ,FN_Previous_Field}, + { REQ_FIRST_FIELD |ID_FN ,FN_First_Field}, + { REQ_LAST_FIELD |ID_FN ,FN_Last_Field}, + { REQ_SNEXT_FIELD |ID_FN ,FN_Sorted_Next_Field}, + { REQ_SPREV_FIELD |ID_FN ,FN_Sorted_Previous_Field}, + { REQ_SFIRST_FIELD |ID_FN ,FN_Sorted_First_Field}, + { REQ_SLAST_FIELD |ID_FN ,FN_Sorted_Last_Field}, + { REQ_LEFT_FIELD |ID_FN ,FN_Left_Field}, + { REQ_RIGHT_FIELD |ID_FN ,FN_Right_Field}, + { REQ_UP_FIELD |ID_FN ,FN_Up_Field}, + { REQ_DOWN_FIELD |ID_FN ,FN_Down_Field}, + + { REQ_NEXT_CHAR |ID_IFN ,IFN_Next_Character}, + { REQ_PREV_CHAR |ID_IFN ,IFN_Previous_Character}, + { REQ_NEXT_LINE |ID_IFN ,IFN_Next_Line}, + { REQ_PREV_LINE |ID_IFN ,IFN_Previous_Line}, + { REQ_NEXT_WORD |ID_IFN ,IFN_Next_Word}, + { REQ_PREV_WORD |ID_IFN ,IFN_Previous_Word}, + { REQ_BEG_FIELD |ID_IFN ,IFN_Beginning_Of_Field}, + { REQ_END_FIELD |ID_IFN ,IFN_End_Of_Field}, + { REQ_BEG_LINE |ID_IFN ,IFN_Beginning_Of_Line}, + { REQ_END_LINE |ID_IFN ,IFN_End_Of_Line}, + { REQ_LEFT_CHAR |ID_IFN ,IFN_Left_Character}, + { REQ_RIGHT_CHAR |ID_IFN ,IFN_Right_Character}, + { REQ_UP_CHAR |ID_IFN ,IFN_Up_Character}, + { REQ_DOWN_CHAR |ID_IFN ,IFN_Down_Character}, + + { REQ_NEW_LINE |ID_FE ,FE_New_Line}, + { REQ_INS_CHAR |ID_FE ,FE_Insert_Character}, + { REQ_INS_LINE |ID_FE ,FE_Insert_Line}, + { REQ_DEL_CHAR |ID_FE ,FE_Delete_Character}, + { REQ_DEL_PREV |ID_FE ,FE_Delete_Previous}, + { REQ_DEL_LINE |ID_FE ,FE_Delete_Line}, + { REQ_DEL_WORD |ID_FE ,FE_Delete_Word}, + { REQ_CLR_EOL |ID_FE ,FE_Clear_To_End_Of_Line}, + { REQ_CLR_EOF |ID_FE ,FE_Clear_To_End_Of_Form}, + { REQ_CLR_FIELD |ID_FE ,FE_Clear_Field}, + + { REQ_OVL_MODE |ID_EM ,EM_Overlay_Mode}, + { REQ_INS_MODE |ID_EM ,EM_Insert_Mode}, + + { REQ_SCR_FLINE |ID_VSC ,VSC_Scroll_Line_Forward}, + { REQ_SCR_BLINE |ID_VSC ,VSC_Scroll_Line_Backward}, + { REQ_SCR_FPAGE |ID_VSC ,VSC_Scroll_Page_Forward}, + { REQ_SCR_BPAGE |ID_VSC ,VSC_Scroll_Page_Backward}, + { REQ_SCR_FHPAGE |ID_VSC ,VSC_Scroll_Half_Page_Forward}, + { REQ_SCR_BHPAGE |ID_VSC ,VSC_Scroll_Half_Page_Backward}, + + { REQ_SCR_FCHAR |ID_HSC ,HSC_Scroll_Char_Forward}, + { REQ_SCR_BCHAR |ID_HSC ,HSC_Scroll_Char_Backward}, + { REQ_SCR_HFLINE |ID_HSC ,HSC_Horizontal_Line_Forward}, + { REQ_SCR_HBLINE |ID_HSC ,HSC_Horizontal_Line_Backward}, + { REQ_SCR_HFHALF |ID_HSC ,HSC_Horizontal_Half_Line_Forward}, + { REQ_SCR_HBHALF |ID_HSC ,HSC_Horizontal_Half_Line_Backward}, + + { REQ_VALIDATION |ID_FV ,FV_Validation}, + + { REQ_NEXT_CHOICE |ID_CH ,CR_Next_Choice}, + { REQ_PREV_CHOICE |ID_CH ,CR_Previous_Choice} +}; + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : int form_driver(FORM * form,int c) +| +| Description : This is the workhorse of the forms system. It checks +| to determine whether the character c is a request or +| data. If it is a request, the form driver executes +| the request and returns the result. If it is data +| (printable character), it enters the data into the +| current position in the current field. If it is not +| recognized, the form driver assumes it is an application +| defined command and returns E_UNKNOWN_COMMAND. +| Application defined command should be defined relative +| to MAX_FORM_COMMAND, the maximum value of a request. +| +| Return Values : E_OK - success +| E_SYSTEM_ERROR - system error +| E_BAD_ARGUMENT - an argument is incorrect +| E_NOT_POSTED - form is not posted +| E_INVALID_FIELD - field contents are invalid +| E_BAD_STATE - called from inside a hook routine +| E_REQUEST_DENIED - request failed +| E_UNKNOWN_COMMAND - command not known ++--------------------------------------------------------------------------*/ +int form_driver(FORM * form, int c) +{ + const Binding_Info* BI = (Binding_Info *)0; + int res = E_UNKNOWN_COMMAND; + + if (!form) + RETURN(E_BAD_ARGUMENT); + + if (!(form->field)) + RETURN(E_NOT_CONNECTED); + + assert(form->page); + + if (c==FIRST_ACTIVE_MAGIC) + { + form->current = _nc_First_Active_Field(form); + return E_OK; + } + + assert(form->current && + form->current->buf && + (form->current->form == form) + ); + + if ( form->status & _IN_DRIVER ) + RETURN(E_BAD_STATE); + + if ( !( form->status & _POSTED ) ) + RETURN(E_NOT_POSTED); + + if ((c>=MIN_FORM_COMMAND && c<=MAX_FORM_COMMAND) && + ((bindings[c-MIN_FORM_COMMAND].keycode & Key_Mask) == c)) + BI = &(bindings[c-MIN_FORM_COMMAND]); + + if (BI) + { + typedef int (*Generic_Method)(int (* const)(FORM *),FORM *); + static const Generic_Method Generic_Methods[] = + { + Page_Navigation, /* overloaded to call field&form hooks */ + Inter_Field_Navigation, /* overloaded to call field hooks */ + NULL, /* Intra-Field is generic */ + Vertical_Scrolling, /* Overloaded to check multi-line */ + Horizontal_Scrolling, /* Overloaded to check single-line */ + Field_Editing, /* Overloaded to mark modification */ + NULL, /* Edit Mode is generic */ + NULL, /* Field Validation is generic */ + NULL /* Choice Request is generic */ + }; + size_t nMethods = (sizeof(Generic_Methods)/sizeof(Generic_Methods[0])); + size_t method = ((BI->keycode & ID_Mask) >> ID_Shft) & 0xffff; + + if ( (method >= nMethods) || !(BI->cmd) ) + res = E_SYSTEM_ERROR; + else + { + Generic_Method fct = Generic_Methods[method]; + if (fct) + res = fct(BI->cmd,form); + else + res = (BI->cmd)(form); + } + } + else + { + if (!(c & (~(int)MAX_REGULAR_CHARACTER)) && + isprint((unsigned char)c) && + Check_Char(form->current->type,c, + (TypeArgument *)(form->current->arg))) + res = Data_Entry(form,c); + } + _nc_Refresh_Current_Field(form); + RETURN(res); +} + +/*---------------------------------------------------------------------------- + Field-Buffer manipulation routines. + The effects of setting a buffer is tightly coupled to the core of the form + driver logic. This is especially true in the case of growable fields. + So I don't separate this into an own module. + --------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : int set_field_buffer(FIELD *field, +| int buffer, char *value) +| +| Description : Set the given buffer of the field to the given value. +| Buffer 0 stores the displayed content of the field. +| For dynamic fields this may grow the fieldbuffers if +| the length of the value exceeds the current buffer +| length. For buffer 0 only printable values are allowed. +| For static fields, the value needs not to be zero ter- +| minated. It is copied up to the length of the buffer. +| +| Return Values : E_OK - success +| E_BAD_ARGUMENT - invalid argument +| E_SYSTEM_ERROR - system error ++--------------------------------------------------------------------------*/ +int set_field_buffer(FIELD * field, int buffer, const char * value) +{ + char *s, *p; + int res = E_OK; + unsigned int len; + + if ( !field || !value || ((buffer < 0)||(buffer > field->nbuf)) ) + RETURN(E_BAD_ARGUMENT); + + len = Buffer_Length(field); + + if (buffer==0) + { + const char *v; + unsigned int i = 0; + + for(v=value; *v && (i<len); v++,i++) + { + if (!isprint((unsigned char)*v)) + RETURN(E_BAD_ARGUMENT); + } + } + + if (Growable(field)) + { + /* for a growable field we must assume zero terminated strings, because + somehow we have to detect the length of what should be copied. + */ + unsigned int vlen = strlen(value); + if (vlen > len) + { + if (!Field_Grown(field, + (int)(1 + (vlen-len)/((field->rows+field->nrow)*field->cols)))) + RETURN(E_SYSTEM_ERROR); + + /* in this case we also have to check, wether or not the remaining + characters in value are also printable for buffer 0. */ + if (buffer==0) + { + unsigned int i; + + for(i=len; i<vlen; i++) + if (!isprint(value[i])) + RETURN(E_BAD_ARGUMENT); + } + len = vlen; + } + } + + p = Address_Of_Nth_Buffer(field,buffer); + +#if HAVE_MEMCCPY + s = memccpy(p,value,0,len); +#else + for(s=(char *)value; *s && (s < (value+len)); s++) + p[s-value] = *s; + if (s < (value+len)) + { + p[s-value] = *s++; + s = p + (s-value); + } + else + s=(char *)0; +#endif + + if (s) + { /* this means, value was null terminated and not greater than the + buffer. We have to pad with blanks. Please note that due to memccpy + logic s points after the terminating null. */ + s--; /* now we point to the terminator. */ + assert(len >= (unsigned int)(s-p)); + if (len > (unsigned int)(s-p)) + memset(s,C_BLANK,len-(unsigned int)(s-p)); + } + + if (buffer==0) + { + int syncres; + if (((syncres=Synchronize_Field( field ))!=E_OK) && + (res==E_OK)) + res = syncres; + if (((syncres=Synchronize_Linked_Fields(field ))!=E_OK) && + (res==E_OK)) + res = syncres; + } + RETURN(res); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : char *field_buffer(const FIELD *field,int buffer) +| +| Description : Return the address of the buffer for the field. +| +| Return Values : Pointer to buffer or NULL if arguments were invalid. ++--------------------------------------------------------------------------*/ +char *field_buffer(const FIELD * field, int buffer) +{ + if (field && (buffer >= 0) && (buffer <= field->nbuf)) + return Address_Of_Nth_Buffer(field,buffer); + else + return (char *)0; +} + +/* frm_driver.c ends here */ diff --git a/Source/CursesDialog/form/frm_hook.c b/Source/CursesDialog/form/frm_hook.c new file mode 100644 index 0000000..eb654c4 --- /dev/null +++ b/Source/CursesDialog/form/frm_hook.c @@ -0,0 +1,140 @@ +/**************************************************************************** + * Copyright (c) 1998 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 <juergen.pfeifer@gmx.net> 1995,1997 * + ****************************************************************************/ + +#include "form.priv.h" + +MODULE_ID("$Id$") + +/* "Template" macro to generate function to set application specific hook */ +#define GEN_HOOK_SET_FUNCTION( typ, name ) \ +int set_ ## typ ## _ ## name (FORM *form, Form_Hook func)\ +{\ + (Normalize_Form( form ) -> typ ## name) = func ;\ + RETURN(E_OK);\ +} + +/* "Template" macro to generate function to get application specific hook */ +#define GEN_HOOK_GET_FUNCTION( typ, name ) \ +Form_Hook typ ## _ ## name ( const FORM *form )\ +{\ + return ( Normalize_Form( form ) -> typ ## name );\ +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : int set_field_init(FORM *form, Form_Hook f) +| +| Description : Assigns an application defined initialization function +| to be called when the form is posted and just after +| the current field changes. +| +| Return Values : E_OK - success ++--------------------------------------------------------------------------*/ +GEN_HOOK_SET_FUNCTION(field,init) + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : Form_Hook field_init(const FORM *form) +| +| Description : Retrieve field initialization routine address. +| +| Return Values : The address or NULL if no hook defined. ++--------------------------------------------------------------------------*/ +GEN_HOOK_GET_FUNCTION(field,init) + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : int set_field_term(FORM *form, Form_Hook f) +| +| Description : Assigns an application defined finalization function +| to be called when the form is unposted and just before +| the current field changes. +| +| Return Values : E_OK - success ++--------------------------------------------------------------------------*/ +GEN_HOOK_SET_FUNCTION(field,term) + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : Form_Hook field_term(const FORM *form) +| +| Description : Retrieve field finalization routine address. +| +| Return Values : The address or NULL if no hook defined. ++--------------------------------------------------------------------------*/ +GEN_HOOK_GET_FUNCTION(field,term) + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : int set_form_init(FORM *form, Form_Hook f) +| +| Description : Assigns an application defined initialization function +| to be called when the form is posted and just after +| a page change. +| +| Return Values : E_OK - success ++--------------------------------------------------------------------------*/ +GEN_HOOK_SET_FUNCTION(form,init) + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : Form_Hook form_init(const FORM *form) +| +| Description : Retrieve form initialization routine address. +| +| Return Values : The address or NULL if no hook defined. ++--------------------------------------------------------------------------*/ +GEN_HOOK_GET_FUNCTION(form,init) + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : int set_form_term(FORM *form, Form_Hook f) +| +| Description : Assigns an application defined finalization function +| to be called when the form is unposted and just before +| a page change. +| +| Return Values : E_OK - success ++--------------------------------------------------------------------------*/ +GEN_HOOK_SET_FUNCTION(form,term) + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : Form_Hook form_term(const FORM *form) +| +| Description : Retrieve form finalization routine address. +| +| Return Values : The address or NULL if no hook defined. ++--------------------------------------------------------------------------*/ +GEN_HOOK_GET_FUNCTION(form,term) + +/* frm_hook.c ends here */ diff --git a/Source/CursesDialog/form/frm_opts.c b/Source/CursesDialog/form/frm_opts.c new file mode 100644 index 0000000..7bbeaa1 --- /dev/null +++ b/Source/CursesDialog/form/frm_opts.c @@ -0,0 +1,116 @@ +/**************************************************************************** + * Copyright (c) 1998 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 <juergen.pfeifer@gmx.net> 1995,1997 * + ****************************************************************************/ + +#include "form.priv.h" + +MODULE_ID("$Id$") + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : int set_form_opts(FORM *form, Form_Options opts) +| +| Description : Turns on the named options and turns off all the +| remaining options for that form. +| +| Return Values : E_OK - success +| E_BAD_ARGUMENT - invalid options ++--------------------------------------------------------------------------*/ +int set_form_opts(FORM * form, Form_Options opts) +{ + opts &= ALL_FORM_OPTS; + if (opts & ~ALL_FORM_OPTS) + RETURN(E_BAD_ARGUMENT); + else + { + Normalize_Form( form )->opts = opts; + RETURN(E_OK); + } +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : Form_Options form_opts(const FORM *) +| +| Description : Retrieves the current form options. +| +| Return Values : The option flags. ++--------------------------------------------------------------------------*/ +Form_Options form_opts(const FORM * form) +{ + return (Normalize_Form(form)->opts & ALL_FORM_OPTS); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : int form_opts_on(FORM *form, Form_Options opts) +| +| Description : Turns on the named options; no other options are +| changed. +| +| Return Values : E_OK - success +| E_BAD_ARGUMENT - invalid options ++--------------------------------------------------------------------------*/ +int form_opts_on(FORM * form, Form_Options opts) +{ + opts &= ALL_FORM_OPTS; + if (opts & ~ALL_FORM_OPTS) + RETURN(E_BAD_ARGUMENT); + else + { + Normalize_Form( form )->opts |= opts; + RETURN(E_OK); + } +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : int form_opts_off(FORM *form, Form_Options opts) +| +| Description : Turns off the named options; no other options are +| changed. +| +| Return Values : E_OK - success +| E_BAD_ARGUMENT - invalid options ++--------------------------------------------------------------------------*/ +int form_opts_off(FORM * form, Form_Options opts) +{ + opts &= ALL_FORM_OPTS; + if (opts & ~ALL_FORM_OPTS) + RETURN(E_BAD_ARGUMENT); + else + { + Normalize_Form(form)->opts &= ~opts; + RETURN(E_OK); + } +} + +/* frm_opts.c ends here */ diff --git a/Source/CursesDialog/form/frm_page.c b/Source/CursesDialog/form/frm_page.c new file mode 100644 index 0000000..842cbce --- /dev/null +++ b/Source/CursesDialog/form/frm_page.c @@ -0,0 +1,100 @@ +/**************************************************************************** + * Copyright (c) 1998 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 <juergen.pfeifer@gmx.net> 1995,1997 * + ****************************************************************************/ + +#include "form.priv.h" + +MODULE_ID("$Id$") + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : int set_form_page(FORM * form,int page) +| +| Description : Set the page number of the form. +| +| Return Values : E_OK - success +| E_BAD_ARGUMENT - invalid form pointer or page number +| E_BAD_STATE - called from a hook routine +| E_INVALID_FIELD - current field can't be left +| E_SYSTEM_ERROR - system error ++--------------------------------------------------------------------------*/ +int set_form_page(FORM * form, int page) +{ + int err = E_OK; + + if ( !form || (page<0) || (page>=form->maxpage) ) + RETURN(E_BAD_ARGUMENT); + + if (!(form->status & _POSTED)) + { + form->curpage = page; + form->current = _nc_First_Active_Field(form); + } + else + { + if (form->status & _IN_DRIVER) + err = E_BAD_STATE; + else + { + if (form->curpage != page) + { + if (!_nc_Internal_Validation(form)) + err = E_INVALID_FIELD; + else + { + Call_Hook(form,fieldterm); + Call_Hook(form,formterm); + err = _nc_Set_Form_Page(form,page,(FIELD *)0); + Call_Hook(form,forminit); + Call_Hook(form,fieldinit); + _nc_Refresh_Current_Field(form); + } + } + } + } + RETURN(err); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : int form_page(const FORM * form) +| +| Description : Return the current page of the form. +| +| Return Values : >= 0 : current page number +| -1 : invalid form pointer ++--------------------------------------------------------------------------*/ +int form_page(const FORM * form) +{ + return Normalize_Form(form)->curpage; +} + +/* frm_page.c ends here */ diff --git a/Source/CursesDialog/form/frm_post.c b/Source/CursesDialog/form/frm_post.c new file mode 100644 index 0000000..5ead942 --- /dev/null +++ b/Source/CursesDialog/form/frm_post.c @@ -0,0 +1,117 @@ +/**************************************************************************** + * Copyright (c) 1998 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 <juergen.pfeifer@gmx.net> 1995,1997 * + ****************************************************************************/ +#include "form.priv.h" + +MODULE_ID("$Id$") + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : int post_form(FORM * form) +| +| Description : Writes the form into its associated subwindow. +| +| Return Values : E_OK - success +| E_BAD_ARGUMENT - invalid form pointer +| E_POSTED - form already posted +| E_NOT_CONNECTED - no fields connected to form +| E_NO_ROOM - form doesn't fit into subwindow +| E_SYSTEM_ERROR - system error ++--------------------------------------------------------------------------*/ +int post_form(FORM * form) +{ + WINDOW *formwin; + int err; + int page; + + if (!form) + RETURN(E_BAD_ARGUMENT); + + if (form->status & _POSTED) + RETURN(E_POSTED); + + if (!(form->field)) + RETURN(E_NOT_CONNECTED); + + formwin = Get_Form_Window(form); + if ((form->cols > getmaxx(formwin)) || (form->rows > getmaxy(formwin))) + RETURN(E_NO_ROOM); + + /* reset form->curpage to an invald value. This forces Set_Form_Page + to do the page initialization which is required by post_form. + */ + page = form->curpage; + form->curpage = -1; + if ((err = _nc_Set_Form_Page(form,page,form->current))!=E_OK) + RETURN(err); + + form->status |= _POSTED; + + Call_Hook(form,forminit); + Call_Hook(form,fieldinit); + + _nc_Refresh_Current_Field(form); + RETURN(E_OK); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : int unpost_form(FORM * form) +| +| Description : Erase form from its associated subwindow. +| +| Return Values : E_OK - success +| E_BAD_ARGUMENT - invalid form pointer +| E_NOT_POSTED - form isn't posted +| E_BAD_STATE - called from a hook routine ++--------------------------------------------------------------------------*/ +int unpost_form(FORM * form) +{ + if (!form) + RETURN(E_BAD_ARGUMENT); + + if (!(form->status & _POSTED)) + RETURN(E_NOT_POSTED); + + if (form->status & _IN_DRIVER) + RETURN(E_BAD_STATE); + + Call_Hook(form,fieldterm); + Call_Hook(form,formterm); + + werase(Get_Form_Window(form)); + delwin(form->w); + form->w = (WINDOW *)0; + form->status &= ~_POSTED; + RETURN(E_OK); +} + +/* frm_post.c ends here */ diff --git a/Source/CursesDialog/form/frm_req_name.c b/Source/CursesDialog/form/frm_req_name.c new file mode 100644 index 0000000..e9cd426 --- /dev/null +++ b/Source/CursesDialog/form/frm_req_name.c @@ -0,0 +1,163 @@ +/**************************************************************************** + * Copyright (c) 1998 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 <juergen.pfeifer@gmx.net> 1995,1997 * + ****************************************************************************/ + +/*************************************************************************** +* Module form_request_name * +* Routines to handle external names of menu requests * +***************************************************************************/ + +#include "form.priv.h" + +MODULE_ID("$Id$") + +static const char *request_names[ MAX_FORM_COMMAND - MIN_FORM_COMMAND + 1 ] = { + "NEXT_PAGE" , + "PREV_PAGE" , + "FIRST_PAGE" , + "LAST_PAGE" , + + "NEXT_FIELD" , + "PREV_FIELD" , + "FIRST_FIELD" , + "LAST_FIELD" , + "SNEXT_FIELD" , + "SPREV_FIELD" , + "SFIRST_FIELD" , + "SLAST_FIELD" , + "LEFT_FIELD" , + "RIGHT_FIELD" , + "UP_FIELD" , + "DOWN_FIELD" , + + "NEXT_CHAR" , + "PREV_CHAR" , + "NEXT_LINE" , + "PREV_LINE" , + "NEXT_WORD" , + "PREV_WORD" , + "BEG_FIELD" , + "END_FIELD" , + "BEG_LINE" , + "END_LINE" , + "LEFT_CHAR" , + "RIGHT_CHAR" , + "UP_CHAR" , + "DOWN_CHAR" , + + "NEW_LINE" , + "INS_CHAR" , + "INS_LINE" , + "DEL_CHAR" , + "DEL_PREV" , + "DEL_LINE" , + "DEL_WORD" , + "CLR_EOL" , + "CLR_EOF" , + "CLR_FIELD" , + "OVL_MODE" , + "INS_MODE" , + "SCR_FLINE" , + "SCR_BLINE" , + "SCR_FPAGE" , + "SCR_BPAGE" , + "SCR_FHPAGE" , + "SCR_BHPAGE" , + "SCR_FCHAR" , + "SCR_BCHAR" , + "SCR_HFLINE" , + "SCR_HBLINE" , + "SCR_HFHALF" , + "SCR_HBHALF" , + + "VALIDATION" , + "NEXT_CHOICE" , + "PREV_CHOICE" +}; +#define A_SIZE (sizeof(request_names)/sizeof(request_names[0])) + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : const char * form_request_name (int request); +| +| Description : Get the external name of a form request. +| +| Return Values : Pointer to name - on success +| NULL - on invalid request code ++--------------------------------------------------------------------------*/ +const char *form_request_name( int request ) +{ + if ( (request < MIN_FORM_COMMAND) || (request > MAX_FORM_COMMAND) ) + { + SET_ERROR (E_BAD_ARGUMENT); + return (const char *)0; + } + else + return request_names[ request - MIN_FORM_COMMAND ]; +} + + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : int form_request_by_name (const char *str); +| +| Description : Search for a request with this name. +| +| Return Values : Request Id - on success +| E_NO_MATCH - request not found ++--------------------------------------------------------------------------*/ +int form_request_by_name( const char *str ) +{ + /* because the table is so small, it doesn't really hurt + to run sequentially through it. + */ + unsigned int i = 0; + char buf[16]; + + if (str) + { + strncpy(buf,str,sizeof(buf)); + while( (i<sizeof(buf)) && (buf[i] != '\0') ) + { + buf[i] = toupper(buf[i]); + i++; + } + + for (i=0; i < A_SIZE; i++) + { + if (strncmp(request_names[i],buf,sizeof(buf))==0) + return MIN_FORM_COMMAND + i; + } + } + RETURN(E_NO_MATCH); +} + +/* frm_req_name.c ends here */ diff --git a/Source/CursesDialog/form/frm_scale.c b/Source/CursesDialog/form/frm_scale.c new file mode 100644 index 0000000..028e9e2 --- /dev/null +++ b/Source/CursesDialog/form/frm_scale.c @@ -0,0 +1,63 @@ +/**************************************************************************** + * Copyright (c) 1998 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 <juergen.pfeifer@gmx.net> 1995,1997 * + ****************************************************************************/ + +#include "form.priv.h" + +MODULE_ID("$Id$") + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : int scale_form( const FORM *form, int *rows, int *cols ) +| +| Description : Retrieve size of form +| +| Return Values : E_OK - no error +| E_BAD_ARGUMENT - invalid form pointer +| E_NOT_CONNECTED - no fields connected to form ++--------------------------------------------------------------------------*/ +int scale_form(const FORM * form, int * rows, int * cols) +{ + if ( !form ) + RETURN(E_BAD_ARGUMENT); + + if ( !(form->field) ) + RETURN(E_NOT_CONNECTED); + + if (rows) + *rows = form->rows; + if (cols) + *cols = form->cols; + + RETURN(E_OK); +} + +/* frm_scale.c ends here */ diff --git a/Source/CursesDialog/form/frm_sub.c b/Source/CursesDialog/form/frm_sub.c new file mode 100644 index 0000000..62dc613 --- /dev/null +++ b/Source/CursesDialog/form/frm_sub.c @@ -0,0 +1,69 @@ +/**************************************************************************** + * Copyright (c) 1998 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 <juergen.pfeifer@gmx.net> 1995,1997 * + ****************************************************************************/ + +#include "form.priv.h" + +MODULE_ID("$Id$") + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : int set_form_sub(FORM *form, WINDOW *win) +| +| Description : Set the subwindow of the form to win. +| +| Return Values : E_OK - success +| E_POSTED - form is posted ++--------------------------------------------------------------------------*/ +int set_form_sub(FORM * form, WINDOW * win) +{ + if (form && (form->status & _POSTED)) + RETURN(E_POSTED); + + Normalize_Form( form )->sub = win; + RETURN(E_OK); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : WINDOW *form_sub(const FORM *) +| +| Description : Retrieve the window of the form. +| +| Return Values : The pointer to the Subwindow. ++--------------------------------------------------------------------------*/ +WINDOW *form_sub(const FORM * form) +{ + const FORM* f = Normalize_Form( form ); + return Get_Form_Window(f); +} + +/* frm_sub.c ends here */ diff --git a/Source/CursesDialog/form/frm_user.c b/Source/CursesDialog/form/frm_user.c new file mode 100644 index 0000000..8f0edbc --- /dev/null +++ b/Source/CursesDialog/form/frm_user.c @@ -0,0 +1,67 @@ +/**************************************************************************** + * Copyright (c) 1998 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 <juergen.pfeifer@gmx.net> 1995,1997 * + ****************************************************************************/ + +#include "form.priv.h" + +MODULE_ID("$Id$") + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : int set_form_userptr(FORM *form, void *usrptr) +| +| Description : Set the pointer that is reserved in any form to store +| application relevant informations +| +| Return Values : E_OK - on success ++--------------------------------------------------------------------------*/ +int set_form_userptr(FORM * form, void *usrptr) +{ + Normalize_Form(form)->usrptr = usrptr; + RETURN(E_OK); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : void *form_userptr(const FORM *form) +| +| Description : Return the pointer that is reserved in any form to +| store application relevant informations. +| +| Return Values : Value of pointer. If no such pointer has been set, +| NULL is returned ++--------------------------------------------------------------------------*/ +void *form_userptr(const FORM * form) +{ + return Normalize_Form(form)->usrptr; +} + +/* frm_user.c ends here */ diff --git a/Source/CursesDialog/form/frm_win.c b/Source/CursesDialog/form/frm_win.c new file mode 100644 index 0000000..82d716f --- /dev/null +++ b/Source/CursesDialog/form/frm_win.c @@ -0,0 +1,70 @@ +/**************************************************************************** + * Copyright (c) 1998 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 <juergen.pfeifer@gmx.net> 1995,1997 * + ****************************************************************************/ + +#include "form.priv.h" + +MODULE_ID("$Id$") + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : int set_form_win(FORM *form,WINDOW *win) +| +| Description : Set the window of the form to win. +| +| Return Values : E_OK - success +| E_POSTED - form is posted ++--------------------------------------------------------------------------*/ +int set_form_win(FORM * form, WINDOW * win) +{ + if (form && (form->status & _POSTED)) + RETURN(E_POSTED); + + Normalize_Form( form )->win = win; + RETURN(E_OK); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : WINDOW *form_win(const FORM *) +| +| Description : Retrieve the window of the form. +| +| Return Values : The pointer to the Window or stdscr if there is none. ++--------------------------------------------------------------------------*/ +WINDOW *form_win(const FORM * form) +{ + const FORM* f = Normalize_Form( form ); + return (f->win ? f->win : stdscr); +} + +/* frm_win.c ends here */ + diff --git a/Source/CursesDialog/form/fty_alnum.c b/Source/CursesDialog/form/fty_alnum.c new file mode 100644 index 0000000..0642899 --- /dev/null +++ b/Source/CursesDialog/form/fty_alnum.c @@ -0,0 +1,137 @@ + +/* + * THIS CODE IS SPECIFICALLY EXEMPTED FROM THE NCURSES PACKAGE COPYRIGHT. + * You may freely copy it for use as a template for your own field types. + * If you develop a field type that might be of general use, please send + * it back to the ncurses maintainers for inclusion in the next version. + */ +/*************************************************************************** +* * +* Author : Juergen Pfeifer, juergen.pfeifer@gmx.net * +* * +***************************************************************************/ + +#include "form.priv.h" + +MODULE_ID("$Id$") + +typedef struct { + int width; +} alnumARG; + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static void *Make_AlphaNumeric_Type(va_list *ap) +| +| Description : Allocate structure for alphanumeric type argument. +| +| Return Values : Pointer to argument structure or NULL on error ++--------------------------------------------------------------------------*/ +static void *Make_AlphaNumeric_Type(va_list * ap) +{ + alnumARG *argp = (alnumARG *)malloc(sizeof(alnumARG)); + + if (argp) + argp->width = va_arg(*ap,int); + + return ((void *)argp); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static void *Copy_AlphaNumericType(const void *argp) +| +| Description : Copy structure for alphanumeric type argument. +| +| Return Values : Pointer to argument structure or NULL on error. ++--------------------------------------------------------------------------*/ +static void *Copy_AlphaNumeric_Type(const void *argp) +{ + const alnumARG *ap = (const alnumARG *)argp; + alnumARG *result = (alnumARG *)malloc(sizeof(alnumARG)); + + if (result) + *result = *ap; + + return ((void *)result); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static void Free_AlphaNumeric_Type(void *argp) +| +| Description : Free structure for alphanumeric type argument. +| +| Return Values : - ++--------------------------------------------------------------------------*/ +static void Free_AlphaNumeric_Type(void * argp) +{ + if (argp) + free(argp); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static bool Check_AlphaNumeric_Field( +| FIELD *field, +| const void *argp) +| +| Description : Validate buffer content to be a valid alphanumeric value +| +| Return Values : TRUE - field is valid +| FALSE - field is invalid ++--------------------------------------------------------------------------*/ +static bool Check_AlphaNumeric_Field(FIELD * field, const void * argp) +{ + int width = ((const alnumARG *)argp)->width; + unsigned char *bp = (unsigned char *)field_buffer(field,0); + int l = -1; + unsigned char *s; + + while(*bp && *bp==' ') + bp++; + if (*bp) + { + s = bp; + while(*bp && isalnum(*bp)) + bp++; + l = (int)(bp-s); + while(*bp && *bp==' ') + bp++; + } + return ((*bp || (l < width)) ? FALSE : TRUE); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static bool Check_AlphaNumeric_Character( +| int c, +| const void *argp ) +| +| Description : Check a character for the alphanumeric type. +| +| Return Values : TRUE - character is valid +| FALSE - character is invalid ++--------------------------------------------------------------------------*/ +static bool Check_AlphaNumeric_Character(int c, const void * argp) +{ + return (isalnum(c) ? TRUE : FALSE); +} + +static FIELDTYPE typeALNUM = { + _HAS_ARGS | _RESIDENT, + 1, /* this is mutable, so we can't be const */ + (FIELDTYPE *)0, + (FIELDTYPE *)0, + Make_AlphaNumeric_Type, + Copy_AlphaNumeric_Type, + Free_AlphaNumeric_Type, + Check_AlphaNumeric_Field, + Check_AlphaNumeric_Character, + NULL, + NULL +}; + +FIELDTYPE* TYPE_ALNUM = &typeALNUM; + +/* fty_alnum.c ends here */ diff --git a/Source/CursesDialog/form/fty_alpha.c b/Source/CursesDialog/form/fty_alpha.c new file mode 100644 index 0000000..8f41de1 --- /dev/null +++ b/Source/CursesDialog/form/fty_alpha.c @@ -0,0 +1,138 @@ + +/* + * THIS CODE IS SPECIFICALLY EXEMPTED FROM THE NCURSES PACKAGE COPYRIGHT. + * You may freely copy it for use as a template for your own field types. + * If you develop a field type that might be of general use, please send + * it back to the ncurses maintainers for inclusion in the next version. + */ +/*************************************************************************** +* * +* Author : Juergen Pfeifer, juergen.pfeifer@gmx.net * +* * +***************************************************************************/ + +#include "form.priv.h" + +MODULE_ID("$Id$") + +typedef struct { + int width; +} alphaARG; + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static void *Make_Alpha_Type(va_list *ap) +| +| Description : Allocate structure for alpha type argument. +| +| Return Values : Pointer to argument structure or NULL on error ++--------------------------------------------------------------------------*/ +static void *Make_Alpha_Type(va_list * ap) +{ + alphaARG *argp = (alphaARG *)malloc(sizeof(alphaARG)); + if (argp) + { + argp->width = va_arg(*ap,int); + } + return ((void *)argp); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static void *Copy_Alpha_Type(const void * argp) +| +| Description : Copy structure for alpha type argument. +| +| Return Values : Pointer to argument structure or NULL on error. ++--------------------------------------------------------------------------*/ +static void *Copy_Alpha_Type(const void * argp) +{ + const alphaARG *ap = (const alphaARG *)argp; + alphaARG *result = (alphaARG *)malloc(sizeof(alphaARG)); + + if (result) + { + *result = *ap; + } + return ((void *)result); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static void Free_Alpha_Type( void * argp ) +| +| Description : Free structure for alpha type argument. +| +| Return Values : - ++--------------------------------------------------------------------------*/ +static void Free_Alpha_Type(void * argp) +{ + if (argp) + free(argp); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static bool Check_Alpha_Field( +| FIELD * field, +| const void * argp) +| +| Description : Validate buffer content to be a valid alpha value +| +| Return Values : TRUE - field is valid +| FALSE - field is invalid ++--------------------------------------------------------------------------*/ +static bool Check_Alpha_Field(FIELD * field, const void * argp) +{ + int width = ((const alphaARG *)argp)->width; + unsigned char *bp = (unsigned char *)field_buffer(field,0); + int l = -1; + unsigned char *s; + + while(*bp && *bp==' ') + bp++; + if (*bp) + { + s = bp; + while(*bp && isalpha(*bp)) + bp++; + l = (int)(bp-s); + while(*bp && *bp==' ') + bp++; + } + return ((*bp || (l < width)) ? FALSE : TRUE); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static bool Check_Alpha_Character( +| int c, +| const void * argp) +| +| Description : Check a character for the alpha type. +| +| Return Values : TRUE - character is valid +| FALSE - character is invalid ++--------------------------------------------------------------------------*/ +static bool Check_Alpha_Character(int c, const void * argp) +{ + return (isalpha(c) ? TRUE : FALSE); +} + +static FIELDTYPE typeALPHA = { + _HAS_ARGS | _RESIDENT, + 1, /* this is mutable, so we can't be const */ + (FIELDTYPE *)0, + (FIELDTYPE *)0, + Make_Alpha_Type, + Copy_Alpha_Type, + Free_Alpha_Type, + Check_Alpha_Field, + Check_Alpha_Character, + NULL, + NULL +}; + +FIELDTYPE* TYPE_ALPHA = &typeALPHA; + +/* fty_alpha.c ends here */ diff --git a/Source/CursesDialog/form/fty_enum.c b/Source/CursesDialog/form/fty_enum.c new file mode 100644 index 0000000..8fc4cd7 --- /dev/null +++ b/Source/CursesDialog/form/fty_enum.c @@ -0,0 +1,295 @@ + +/* + * THIS CODE IS SPECIFICALLY EXEMPTED FROM THE NCURSES PACKAGE COPYRIGHT. + * You may freely copy it for use as a template for your own field types. + * If you develop a field type that might be of general use, please send + * it back to the ncurses maintainers for inclusion in the next version. + */ +/*************************************************************************** +* * +* Author : Juergen Pfeifer, juergen.pfeifer@gmx.net * +* * +***************************************************************************/ + +#include "form.priv.h" + +MODULE_ID("$Id$") + +typedef struct { + char **kwds; + int count; + bool checkcase; + bool checkunique; +} enumARG; + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static void *Make_Enum_Type( va_list * ap ) +| +| Description : Allocate structure for enumeration type argument. +| +| Return Values : Pointer to argument structure or NULL on error ++--------------------------------------------------------------------------*/ +static void *Make_Enum_Type(va_list * ap) +{ + enumARG *argp = (enumARG *)malloc(sizeof(enumARG)); + + if (argp) + { + int cnt = 0; + char **kp = (char **)0; + int ccase, cunique; + + argp->kwds = va_arg(*ap,char **); + ccase = va_arg(*ap,int); + cunique = va_arg(*ap,int); + argp->checkcase = ccase ? TRUE : FALSE; + argp->checkunique = cunique ? TRUE : FALSE; + + kp = argp->kwds; + while( kp && (*kp++) ) cnt++; + argp->count = cnt; + } + return (void *)argp; +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static void *Copy_Enum_Type( const void * argp ) +| +| Description : Copy structure for enumeration type argument. +| +| Return Values : Pointer to argument structure or NULL on error. ++--------------------------------------------------------------------------*/ +static void *Copy_Enum_Type(const void * argp) +{ + enumARG *result = (enumARG *)0; + + if (argp) + { + const enumARG *ap = (const enumARG *)argp; + + result = (enumARG *)malloc(sizeof(enumARG)); + if (result) + *result = *ap; + } + return (void *)result; +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static void Free_Enum_Type( void * argp ) +| +| Description : Free structure for enumeration type argument. +| +| Return Values : - ++--------------------------------------------------------------------------*/ +static void Free_Enum_Type(void * argp) +{ + if (argp) + free(argp); +} + +#define SKIP_SPACE(x) while(((*(x))!='\0') && (is_blank(*(x)))) (x)++ +#define NOMATCH 0 +#define PARTIAL 1 +#define EXACT 2 + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static int Compare(const unsigned char * s, +| const unsigned char * buf, +| bool ccase ) +| +| Description : Check wether or not the text in 'buf' matches the +| text in 's', at least partial. +| +| Return Values : NOMATCH - buffer doesn't match +| PARTIAL - buffer matches partially +| EXACT - buffer matches exactly ++--------------------------------------------------------------------------*/ +static int Compare(const unsigned char *s, const unsigned char *buf, + bool ccase) +{ + SKIP_SPACE(buf); /* Skip leading spaces in both texts */ + SKIP_SPACE(s); + + if (*buf=='\0') + { + return (((*s)!='\0') ? NOMATCH : EXACT); + } + else + { + if (ccase) + { + while(*s++ == *buf) + { + if (*buf++=='\0') return EXACT; + } + } + else + { + while(toupper(*s++)==toupper(*buf)) + { + if (*buf++=='\0') return EXACT; + } + } + } + /* At this location buf points to the first character where it no longer + matches with s. So if only blanks are following, we have a partial + match otherwise there is no match */ + SKIP_SPACE(buf); + if (*buf) + return NOMATCH; + + /* If it happens that the reference buffer is at its end, the partial + match is actually an exact match. */ + return ((s[-1]!='\0') ? PARTIAL : EXACT); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static bool Check_Enum_Field( +| FIELD * field, +| const void * argp) +| +| Description : Validate buffer content to be a valid enumeration value +| +| Return Values : TRUE - field is valid +| FALSE - field is invalid ++--------------------------------------------------------------------------*/ +static bool Check_Enum_Field(FIELD * field, const void * argp) +{ + char **kwds = ((const enumARG *)argp)->kwds; + bool ccase = ((const enumARG *)argp)->checkcase; + bool unique = ((const enumARG *)argp)->checkunique; + unsigned char *bp = (unsigned char *)field_buffer(field,0); + char *s, *t, *p; + int res; + + while( kwds && (s=(*kwds++)) ) + { + if ((res=Compare((unsigned char *)s,bp,ccase))!=NOMATCH) + { + p=t=s; /* t is at least a partial match */ + if ((unique && res!=EXACT)) + { + while( kwds && (p = *kwds++) ) + { + if ((res=Compare((unsigned char *)p,bp,ccase))!=NOMATCH) + { + if (res==EXACT) + { + t = p; + break; + } + else + t = (char *)0; + } + } + } + if (t) + { + set_field_buffer(field,0,t); + return TRUE; + } + if (!p) + break; + } + } + return FALSE; +} + +static const char *dummy[] = { (char *)0 }; + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static bool Next_Enum(FIELD * field, +| const void * argp) +| +| Description : Check for the next enumeration value +| +| Return Values : TRUE - next value found and loaded +| FALSE - no next value loaded ++--------------------------------------------------------------------------*/ +static bool Next_Enum(FIELD * field, const void * argp) +{ + const enumARG *args = (const enumARG *)argp; + char **kwds = args->kwds; + bool ccase = args->checkcase; + int cnt = args->count; + unsigned char *bp = (unsigned char *)field_buffer(field,0); + + if (kwds) { + while(cnt--) + { + if (Compare((unsigned char *)(*kwds++),bp,ccase)==EXACT) + break; + } + if (cnt<=0) + kwds = args->kwds; + if ((cnt>=0) || (Compare((const unsigned char *)dummy,bp,ccase)==EXACT)) + { + set_field_buffer(field,0,*kwds); + return TRUE; + } + } + return FALSE; +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static bool Previous_Enum( +| FIELD * field, +| const void * argp) +| +| Description : Check for the previous enumeration value +| +| Return Values : TRUE - previous value found and loaded +| FALSE - no previous value loaded ++--------------------------------------------------------------------------*/ +static bool Previous_Enum(FIELD * field, const void * argp) +{ + const enumARG *args = (const enumARG *)argp; + int cnt = args->count; + char **kwds = &args->kwds[cnt-1]; + bool ccase = args->checkcase; + unsigned char *bp = (unsigned char *)field_buffer(field,0); + + if (kwds) { + while(cnt--) + { + if (Compare((unsigned char *)(*kwds--),bp,ccase)==EXACT) + break; + } + + if (cnt<=0) + kwds = &args->kwds[args->count-1]; + + if ((cnt>=0) || (Compare((const unsigned char *)dummy,bp,ccase)==EXACT)) + { + set_field_buffer(field,0,*kwds); + return TRUE; + } + } + return FALSE; +} + + +static FIELDTYPE typeENUM = { + _HAS_ARGS | _HAS_CHOICE | _RESIDENT, + 1, /* this is mutable, so we can't be const */ + (FIELDTYPE *)0, + (FIELDTYPE *)0, + Make_Enum_Type, + Copy_Enum_Type, + Free_Enum_Type, + Check_Enum_Field, + NULL, + Next_Enum, + Previous_Enum +}; + +FIELDTYPE* TYPE_ENUM = &typeENUM; + +/* fty_enum.c ends here */ diff --git a/Source/CursesDialog/form/fty_int.c b/Source/CursesDialog/form/fty_int.c new file mode 100644 index 0000000..2f14ca2 --- /dev/null +++ b/Source/CursesDialog/form/fty_int.c @@ -0,0 +1,160 @@ + +/* + * THIS CODE IS SPECIFICALLY EXEMPTED FROM THE NCURSES PACKAGE COPYRIGHT. + * You may freely copy it for use as a template for your own field types. + * If you develop a field type that might be of general use, please send + * it back to the ncurses maintainers for inclusion in the next version. + */ +/*************************************************************************** +* * +* Author : Juergen Pfeifer, juergen.pfeifer@gmx.net * +* * +***************************************************************************/ + +#include "form.priv.h" + +MODULE_ID("$Id$") + +typedef struct { + int precision; + long low; + long high; +} integerARG; + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static void *Make_Integer_Type( va_list * ap ) +| +| Description : Allocate structure for integer type argument. +| +| Return Values : Pointer to argument structure or NULL on error ++--------------------------------------------------------------------------*/ +static void *Make_Integer_Type(va_list * ap) +{ + integerARG *argp = (integerARG *)malloc(sizeof(integerARG)); + + if (argp) + { + argp->precision = va_arg(*ap,int); + argp->low = va_arg(*ap,long); + argp->high = va_arg(*ap,long); + } + return (void *)argp; +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static void *Copy_Integer_Type(const void * argp) +| +| Description : Copy structure for integer type argument. +| +| Return Values : Pointer to argument structure or NULL on error. ++--------------------------------------------------------------------------*/ +static void *Copy_Integer_Type(const void * argp) +{ + const integerARG *ap = (const integerARG *)argp; + integerARG *result = (integerARG *)0; + + if (argp) + { + result = (integerARG *)malloc(sizeof(integerARG)); + if (result) + *result = *ap; + } + return (void *)result; +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static void Free_Integer_Type(void * argp) +| +| Description : Free structure for integer type argument. +| +| Return Values : - ++--------------------------------------------------------------------------*/ +static void Free_Integer_Type(void * argp) +{ + if (argp) + free(argp); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static bool Check_Integer_Field( +| FIELD * field, +| const void * argp) +| +| Description : Validate buffer content to be a valid integer value +| +| Return Values : TRUE - field is valid +| FALSE - field is invalid ++--------------------------------------------------------------------------*/ +static bool Check_Integer_Field(FIELD * field, const void * argp) +{ + const integerARG *argi = (const integerARG *)argp; + long low = argi->low; + long high = argi->high; + int prec = argi->precision; + unsigned char *bp = (unsigned char *)field_buffer(field,0); + char *s = (char *)bp; + long val; + char buf[100]; + + while( *bp && *bp==' ') bp++; + if (*bp) + { + if (*bp=='-') bp++; + while (*bp) + { + if (!isdigit(*bp)) break; + bp++; + } + while(*bp && *bp==' ') bp++; + if (*bp=='\0') + { + val = atol(s); + if (low<high) + { + if (val<low || val>high) return FALSE; + } + sprintf(buf,"%.*ld",(prec>0?prec:0),val); + set_field_buffer(field,0,buf); + return TRUE; + } + } + return FALSE; +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static bool Check_Integer_Character( +| int c, +| const void * argp) +| +| Description : Check a character for the integer type. +| +| Return Values : TRUE - character is valid +| FALSE - character is invalid ++--------------------------------------------------------------------------*/ +static bool Check_Integer_Character(int c, const void * argp) +{ + return ((isdigit(c) || (c=='-')) ? TRUE : FALSE); +} + +static FIELDTYPE typeINTEGER = { + _HAS_ARGS | _RESIDENT, + 1, /* this is mutable, so we can't be const */ + (FIELDTYPE *)0, + (FIELDTYPE *)0, + Make_Integer_Type, + Copy_Integer_Type, + Free_Integer_Type, + Check_Integer_Field, + Check_Integer_Character, + NULL, + NULL +}; + +FIELDTYPE* TYPE_INTEGER = &typeINTEGER; + +/* fty_int.c ends here */ diff --git a/Source/CursesDialog/form/fty_ipv4.c b/Source/CursesDialog/form/fty_ipv4.c new file mode 100644 index 0000000..d7f2296 --- /dev/null +++ b/Source/CursesDialog/form/fty_ipv4.c @@ -0,0 +1,81 @@ + +/* + * THIS CODE IS SPECIFICALLY EXEMPTED FROM THE NCURSES PACKAGE COPYRIGHT. + * You may freely copy it for use as a template for your own field types. + * If you develop a field type that might be of general use, please send + * it back to the ncurses maintainers for inclusion in the next version. + */ +/*************************************************************************** +* * +* Author : Per Foreby, perf@efd.lth.se * +* * +***************************************************************************/ + +#include "form.priv.h" + +MODULE_ID("$Id$") + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static bool Check_IPV4_Field( +| FIELD * field, +| const void * argp) +| +| Description : Validate buffer content to be a valid IP number (Ver. 4) +| +| Return Values : TRUE - field is valid +| FALSE - field is invalid ++--------------------------------------------------------------------------*/ +static bool Check_IPV4_Field(FIELD * field, const void * argp) +{ + char *bp = field_buffer(field,0); + int num = 0, len; + unsigned int d1, d2, d3, d4; + + if(isdigit(*bp)) /* Must start with digit */ + { + num = sscanf(bp, "%u.%u.%u.%u%n", &d1, &d2, &d3, &d4, &len); + if (num == 4) + { + bp += len; /* Make bp point to what sscanf() left */ + while (*bp && isspace(*bp)) + bp++; /* Allow trailing whitespace */ + } + } + return ((num != 4 || *bp || d1 > 255 || d2 > 255 + || d3 > 255 || d4 > 255) ? FALSE : TRUE); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static bool Check_IPV4_Character( +| int c, +| const void *argp ) +| +| Description : Check a character for unsigned type or period. +| +| Return Values : TRUE - character is valid +| FALSE - character is invalid ++--------------------------------------------------------------------------*/ +static bool Check_IPV4_Character(int c, const void * argp) +{ + return ((isdigit(c) || (c=='.')) ? TRUE : FALSE); +} + +static FIELDTYPE typeIPV4 = { + _RESIDENT, + 1, /* this is mutable, so we can't be const */ + (FIELDTYPE *)0, + (FIELDTYPE *)0, + NULL, + NULL, + NULL, + Check_IPV4_Field, + Check_IPV4_Character, + NULL, + NULL +}; + +FIELDTYPE* TYPE_IPV4 = &typeIPV4; + +/* fty_ipv4.c ends here */ diff --git a/Source/CursesDialog/form/fty_num.c b/Source/CursesDialog/form/fty_num.c new file mode 100644 index 0000000..ba15ab8 --- /dev/null +++ b/Source/CursesDialog/form/fty_num.c @@ -0,0 +1,195 @@ + +/* + * THIS CODE IS SPECIFICALLY EXEMPTED FROM THE NCURSES PACKAGE COPYRIGHT. + * You may freely copy it for use as a template for your own field types. + * If you develop a field type that might be of general use, please send + * it back to the ncurses maintainers for inclusion in the next version. + */ +/*************************************************************************** +* * +* Author : Juergen Pfeifer, juergen.pfeifer@gmx.net * +* * +***************************************************************************/ + +#include "form.priv.h" + +MODULE_ID("$Id$") + +#if HAVE_LOCALE_H +#include <locale.h> +#endif + +typedef struct { + int precision; + double low; + double high; + struct lconv* L; +} numericARG; + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static void *Make_Numeric_Type(va_list * ap) +| +| Description : Allocate structure for numeric type argument. +| +| Return Values : Pointer to argument structure or NULL on error ++--------------------------------------------------------------------------*/ +static void *Make_Numeric_Type(va_list * ap) +{ + numericARG *argn = (numericARG *)malloc(sizeof(numericARG)); + + if (argn) + { + argn->precision = va_arg(*ap,int); + argn->low = va_arg(*ap,double); + argn->high = va_arg(*ap,double); +#if HAVE_LOCALE_H + argn->L = localeconv(); +#else + argn->L = NULL; +#endif + } + return (void *)argn; +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static void *Copy_Numeric_Type(const void * argp) +| +| Description : Copy structure for numeric type argument. +| +| Return Values : Pointer to argument structure or NULL on error. ++--------------------------------------------------------------------------*/ +static void *Copy_Numeric_Type(const void * argp) +{ + const numericARG *ap = (const numericARG *)argp; + numericARG *result = (numericARG *)0; + + if (argp) + { + result = (numericARG *)malloc(sizeof(numericARG)); + if (result) + *result = *ap; + } + return (void *)result; +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static void Free_Numeric_Type(void * argp) +| +| Description : Free structure for numeric type argument. +| +| Return Values : - ++--------------------------------------------------------------------------*/ +static void Free_Numeric_Type(void * argp) +{ + if (argp) + free(argp); +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static bool Check_Numeric_Field(FIELD * field, +| const void * argp) +| +| Description : Validate buffer content to be a valid numeric value +| +| Return Values : TRUE - field is valid +| FALSE - field is invalid ++--------------------------------------------------------------------------*/ +static bool Check_Numeric_Field(FIELD * field, const void * argp) +{ + const numericARG *argn = (const numericARG *)argp; + double low = argn->low; + double high = argn->high; + int prec = argn->precision; + unsigned char *bp = (unsigned char *)field_buffer(field,0); + char *s = (char *)bp; + double val = 0.0; + struct lconv* L = argn->L; + char buf[64]; + + while(*bp && *bp==' ') bp++; + if (*bp) + { + if (*bp=='-' || *bp=='+') + bp++; + while(*bp) + { + if (!isdigit(*bp)) break; + bp++; + } + if (*bp==( +#if HAVE_LOCALE_H + (L && L->decimal_point) ? *(L->decimal_point) : +#endif + '.')) + { + bp++; + while(*bp) + { + if (!isdigit(*bp)) break; + bp++; + } + } + while(*bp && *bp==' ') bp++; + if (*bp=='\0') + { + val = atof(s); + if (low<high) + { + if (val<low || val>high) return FALSE; + } + sprintf(buf,"%.*f",(prec>0?prec:0),val); + set_field_buffer(field,0,buf); + return TRUE; + } + } + return FALSE; +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static bool Check_Numeric_Character( +| int c, +| const void * argp) +| +| Description : Check a character for the numeric type. +| +| Return Values : TRUE - character is valid +| FALSE - character is invalid ++--------------------------------------------------------------------------*/ +static bool Check_Numeric_Character(int c, const void * argp) +{ + const numericARG *argn = (const numericARG *)argp; + struct lconv* L = argn->L; + + return (isdigit(c) || + c == '+' || + c == '-' || + c == ( +#if HAVE_LOCALE_H + (L && L->decimal_point) ? *(L->decimal_point) : +#endif + '.') + ) ? TRUE : FALSE; +} + +static FIELDTYPE typeNUMERIC = { + _HAS_ARGS | _RESIDENT, + 1, /* this is mutable, so we can't be const */ + (FIELDTYPE *)0, + (FIELDTYPE *)0, + Make_Numeric_Type, + Copy_Numeric_Type, + Free_Numeric_Type, + Check_Numeric_Field, + Check_Numeric_Character, + NULL, + NULL +}; + +FIELDTYPE* TYPE_NUMERIC = &typeNUMERIC; + +/* fty_num.c ends here */ diff --git a/Source/CursesDialog/form/fty_regex.c b/Source/CursesDialog/form/fty_regex.c new file mode 100644 index 0000000..ec02157 --- /dev/null +++ b/Source/CursesDialog/form/fty_regex.c @@ -0,0 +1,257 @@ + +/* + * THIS CODE IS SPECIFICALLY EXEMPTED FROM THE NCURSES PACKAGE COPYRIGHT. + * You may freely copy it for use as a template for your own field types. + * If you develop a field type that might be of general use, please send + * it back to the ncurses maintainers for inclusion in the next version. + */ +/*************************************************************************** +* * +* Author : Juergen Pfeifer, juergen.pfeifer@gmx.net * +* * +***************************************************************************/ + +#include "form.priv.h" + +MODULE_ID("$Id$") + +#if HAVE_REGEX_H_FUNCS /* We prefer POSIX regex */ +#include <regex.h> + +typedef struct +{ + regex_t *pRegExp; + unsigned long *refCount; +} RegExp_Arg; + +#elif HAVE_REGEXP_H_FUNCS | HAVE_REGEXPR_H_FUNCS +#undef RETURN +static int reg_errno; + +static char *RegEx_Init(char *instring) +{ + reg_errno = 0; + return instring; +} + +static char *RegEx_Error(int code) +{ + reg_errno = code; + return 0; +} + +#define INIT register char *sp = RegEx_Init(instring); +#define GETC() (*sp++) +#define PEEKC() (*sp) +#define UNGETC(c) (--sp) +#define RETURN(c) return(c) +#define ERROR(c) return RegEx_Error(c) + +#if HAVE_REGEXP_H_FUNCS +#include <regexp.h> +#else +#include <regexpr.h> +#endif + +typedef struct +{ + char *compiled_expression; + unsigned long *refCount; +} RegExp_Arg; + +/* Maximum Length we allow for a compiled regular expression */ +#define MAX_RX_LEN (2048) +#define RX_INCREMENT (256) + +#endif + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static void *Make_RegularExpression_Type(va_list * ap) +| +| Description : Allocate structure for regex type argument. +| +| Return Values : Pointer to argument structure or NULL on error ++--------------------------------------------------------------------------*/ +static void *Make_RegularExpression_Type(va_list * ap) +{ +#if HAVE_REGEX_H_FUNCS + char *rx = va_arg(*ap,char *); + RegExp_Arg *preg; + + preg = (RegExp_Arg*)malloc(sizeof(RegExp_Arg)); + if (preg) + { + if (((preg->pRegExp = (regex_t*)malloc(sizeof(regex_t))) != (regex_t*)0) + && !regcomp(preg->pRegExp,rx, + (REG_EXTENDED | REG_NOSUB | REG_NEWLINE) )) + { + preg->refCount = (unsigned long *)malloc(sizeof(unsigned long)); + *(preg->refCount) = 1; + } + else + { + if (preg->pRegExp) + free(preg->pRegExp); + free(preg); + preg = (RegExp_Arg*)0; + } + } + return((void *)preg); +#elif HAVE_REGEXP_H_FUNCS | HAVE_REGEXPR_H_FUNCS + char *rx = va_arg(*ap,char *); + RegExp_Arg *pArg; + + pArg = (RegExp_Arg *)malloc(sizeof(RegExp_Arg)); + + if (pArg) + { + int blen = RX_INCREMENT; + pArg->compiled_expression = NULL; + pArg->refCount = (unsigned long *)malloc(sizeof(unsigned long)); + *(pArg->refCount) = 1; + + do { + char *buf = (char *)malloc(blen); + if (buf) + { +#if HAVE_REGEXP_H_FUNCS + char *last_pos = compile (rx, buf, &buf[blen], '\0'); +#else /* HAVE_REGEXPR_H_FUNCS */ + char *last_pos = compile (rx, buf, &buf[blen]); +#endif + if (reg_errno) + { + free(buf); + if (reg_errno==50) + blen += RX_INCREMENT; + else + { + free(pArg); + pArg = NULL; + break; + } + } + else + { + pArg->compiled_expression = buf; + break; + } + } + } while( blen <= MAX_RX_LEN ); + } + if (pArg && !pArg->compiled_expression) + { + free(pArg); + pArg = NULL; + } + return (void *)pArg; +#else + return 0; +#endif +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static void *Copy_RegularExpression_Type( +| const void * argp) +| +| Description : Copy structure for regex type argument. +| +| Return Values : Pointer to argument structure or NULL on error. ++--------------------------------------------------------------------------*/ +static void *Copy_RegularExpression_Type(const void * argp) +{ +#if (HAVE_REGEX_H_FUNCS | HAVE_REGEXP_H_FUNCS | HAVE_REGEXPR_H_FUNCS) + const RegExp_Arg *ap = (const RegExp_Arg *)argp; + const RegExp_Arg *result = (const RegExp_Arg *)0; + + if (ap) + { + *(ap->refCount) += 1; + result = ap; + } + return (void *)result; +#else + return 0; +#endif +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static void Free_RegularExpression_Type(void * argp) +| +| Description : Free structure for regex type argument. +| +| Return Values : - ++--------------------------------------------------------------------------*/ +static void Free_RegularExpression_Type(void * argp) +{ +#if HAVE_REGEX_H_FUNCS | HAVE_REGEXP_H_FUNCS | HAVE_REGEXPR_H_FUNCS + RegExp_Arg *ap = (RegExp_Arg *)argp; + if (ap) + { + if (--(*(ap->refCount)) == 0) + { +#if HAVE_REGEX_H_FUNCS + if (ap->pRegExp) + { + free(ap->refCount); + regfree(ap->pRegExp); + } +#elif HAVE_REGEXP_H_FUNCS | HAVE_REGEXPR_H_FUNCS + if (ap->compiled_expression) + { + free(ap->refCount); + free(ap->compiled_expression); + } +#endif + free(ap); + } + } +#endif +} + +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static bool Check_RegularExpression_Field( +| FIELD * field, +| const void * argp) +| +| Description : Validate buffer content to be a valid regular expression +| +| Return Values : TRUE - field is valid +| FALSE - field is invalid ++--------------------------------------------------------------------------*/ +static bool Check_RegularExpression_Field(FIELD * field, const void * argp) +{ + bool match = FALSE; +#if HAVE_REGEX_H_FUNCS + const RegExp_Arg *ap = (const RegExp_Arg*)argp; + if (ap && ap->pRegExp) + match = (regexec(ap->pRegExp,field_buffer(field,0),0,NULL,0) ? FALSE:TRUE); +#elif HAVE_REGEXP_H_FUNCS | HAVE_REGEXPR_H_FUNCS + RegExp_Arg *ap = (RegExp_Arg *)argp; + if (ap && ap->compiled_expression) + match = (step(field_buffer(field,0),ap->compiled_expression) ? TRUE:FALSE); +#endif + return match; +} + +static FIELDTYPE typeREGEXP = { + _HAS_ARGS | _RESIDENT, + 1, /* this is mutable, so we can't be const */ + (FIELDTYPE *)0, + (FIELDTYPE *)0, + Make_RegularExpression_Type, + Copy_RegularExpression_Type, + Free_RegularExpression_Type, + Check_RegularExpression_Field, + NULL, + NULL, + NULL +}; + +FIELDTYPE* TYPE_REGEXP = &typeREGEXP; + +/* fty_regex.c ends here */ diff --git a/Source/CursesDialog/form/llib-lform b/Source/CursesDialog/form/llib-lform new file mode 100644 index 0000000..ac2ba43 --- /dev/null +++ b/Source/CursesDialog/form/llib-lform @@ -0,0 +1,694 @@ +/**************************************************************************** + * Copyright (c) 1998 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: Thomas E. Dickey <dickey@clark.net> 1996,1997 * + ****************************************************************************/ +/* LINTLIBRARY */ + +/* ./fld_arg.c */ + +#include "form.priv.h" + +#undef set_fieldtype_arg +int set_fieldtype_arg( + FIELDTYPE *typ, + void *(*const make_arg)( + va_list *p1), + void *(*const copy_arg)( + const void *p1), + void (*const free_arg)( + void *p1)) + { return(*(int *)0); } + +#undef field_arg +void *field_arg( + const FIELD *field) + { return(*(void **)0); } + +/* ./fld_attr.c */ + +#undef set_field_fore +int set_field_fore( + FIELD *field, + chtype attr) + { return(*(int *)0); } + +#undef field_fore +chtype field_fore( + const FIELD *field) + { return(*(chtype *)0); } + +#undef set_field_back +int set_field_back( + FIELD *field, + chtype attr) + { return(*(int *)0); } + +#undef field_back +chtype field_back( + const FIELD *field) + { return(*(chtype *)0); } + +/* ./fld_current.c */ + +#undef set_current_field +int set_current_field( + FORM *form, + FIELD *field) + { return(*(int *)0); } + +#undef current_field +FIELD *current_field( + const FORM *form) + { return(*(FIELD **)0); } + +#undef field_index +int field_index( + const FIELD *field) + { return(*(int *)0); } + +/* ./fld_def.c */ + +#undef _nc_Default_Field +FIELD *_nc_Default_Field; + +#undef _nc_Make_Argument +TypeArgument *_nc_Make_Argument( + const FIELDTYPE *typ, + va_list *ap, + int *err) + { return(*(TypeArgument **)0); } + +#undef _nc_Copy_Argument +TypeArgument *_nc_Copy_Argument( + const FIELDTYPE *typ, + const TypeArgument *argp, + int *err) + { return(*(TypeArgument **)0); } + +#undef _nc_Free_Argument +void _nc_Free_Argument( + const FIELDTYPE *typ, + TypeArgument *argp) + { /* void */ } + +#undef _nc_Copy_Type +bool _nc_Copy_Type( + FIELD *dst, + FIELD const *src) + { return(*(bool *)0); } + +#undef _nc_Free_Type +void _nc_Free_Type( + FIELD *field) + { /* void */ } + +#undef new_field +FIELD *new_field( + int rows, + int cols, + int frow, + int fcol, + int nrow, + int nbuf) + { return(*(FIELD **)0); } + +#undef free_field +int free_field( + FIELD *field) + { return(*(int *)0); } + +/* ./fld_dup.c */ + +#undef dup_field +FIELD *dup_field( + FIELD *field, + int frow, + int fcol) + { return(*(FIELD **)0); } + +/* ./fld_ftchoice.c */ + +#undef set_fieldtype_choice +int set_fieldtype_choice( + FIELDTYPE *typ, + bool (*const next_choice)( + FIELD *p1, + const void *p2), + bool (*const prev_choice)( + FIELD *p1, + const void *p2)) + { return(*(int *)0); } + +/* ./fld_ftlink.c */ + +#undef link_fieldtype +FIELDTYPE *link_fieldtype( + FIELDTYPE *type1, + FIELDTYPE *type2) + { return(*(FIELDTYPE **)0); } + +/* ./fld_info.c */ + +#undef field_info +int field_info( + const FIELD *field, + int *rows, + int *cols, + int *frow, + int *fcol, + int *nrow, + int *nbuf) + { return(*(int *)0); } + +#undef dynamic_field_info +int dynamic_field_info( + const FIELD *field, + int *drows, + int *dcols, + int *maxgrow) + { return(*(int *)0); } + +/* ./fld_just.c */ + +#undef set_field_just +int set_field_just( + FIELD *field, + int just) + { return(*(int *)0); } + +#undef field_just +int field_just( + const FIELD *field) + { return(*(int *)0); } + +/* ./fld_link.c */ + +#undef link_field +FIELD *link_field( + FIELD *field, + int frow, + int fcol) + { return(*(FIELD **)0); } + +/* ./fld_max.c */ + +#undef set_max_field +int set_max_field( + FIELD *field, + int maxgrow) + { return(*(int *)0); } + +/* ./fld_move.c */ + +#undef move_field +int move_field( + FIELD *field, + int frow, + int fcol) + { return(*(int *)0); } + +/* ./fld_newftyp.c */ + +#undef _nc_Default_FieldType +const FIELDTYPE *_nc_Default_FieldType = {0}; + +#undef new_fieldtype +FIELDTYPE *new_fieldtype( + bool (*const field_check)( + FIELD *p1, + const void *p2), + bool (*const char_check)( + int p1, + const void *p2)) + { return(*(FIELDTYPE **)0); } + +#undef free_fieldtype +int free_fieldtype( + FIELDTYPE *typ) + { return(*(int *)0); } + +/* ./fld_opts.c */ + +#undef set_field_opts +int set_field_opts( + FIELD *field, + Field_Options opts) + { return(*(int *)0); } + +#undef field_opts +Field_Options field_opts( + const FIELD *field) + { return(*(Field_Options *)0); } + +#undef field_opts_on +int field_opts_on( + FIELD *field, + Field_Options opts) + { return(*(int *)0); } + +#undef field_opts_off +int field_opts_off( + FIELD *field, + Field_Options opts) + { return(*(int *)0); } + +/* ./fld_pad.c */ + +#undef set_field_pad +int set_field_pad( + FIELD *field, + int ch) + { return(*(int *)0); } + +#undef field_pad +int field_pad( + const FIELD *field) + { return(*(int *)0); } + +/* ./fld_page.c */ + +#undef set_new_page +int set_new_page( + FIELD *field, + bool new_page_flag) + { return(*(int *)0); } + +#undef new_page +bool new_page( + const FIELD *field) + { return(*(bool *)0); } + +/* ./fld_stat.c */ + +#undef set_field_status +int set_field_status( + FIELD *field, + bool status) + { return(*(int *)0); } + +#undef field_status +bool field_status( + const FIELD *field) + { return(*(bool *)0); } + +/* ./fld_type.c */ + +#undef set_field_type +int set_field_type( + FIELD *field, + FIELDTYPE *type, + ...) + { return(*(int *)0); } + +#undef field_type +FIELDTYPE *field_type( + const FIELD *field) + { return(*(FIELDTYPE **)0); } + +/* ./fld_user.c */ + +#undef set_field_userptr +int set_field_userptr( + FIELD *field, + void *usrptr) + { return(*(int *)0); } + +#undef field_userptr +void *field_userptr( + const FIELD *field) + { return(*(void **)0); } + +/* ./frm_cursor.c */ + +#undef pos_form_cursor +int pos_form_cursor( + FORM *form) + { return(*(int *)0); } + +/* ./frm_data.c */ + +#undef data_behind +bool data_behind( + const FORM *form) + { return(*(bool *)0); } + +#undef data_ahead +bool data_ahead( + const FORM *form) + { return(*(bool *)0); } + +/* ./frm_def.c */ + +#undef _nc_Default_Form +FORM *_nc_Default_Form; + +#undef new_form +FORM *new_form( + FIELD **fields) + { return(*(FORM **)0); } + +#undef free_form +int free_form( + FORM *form) + { return(*(int *)0); } + +#undef set_form_fields +int set_form_fields( + FORM *form, + FIELD **fields) + { return(*(int *)0); } + +#undef form_fields +FIELD **form_fields( + const FORM *form) + { return(*(FIELD ***)0); } + +#undef field_count +int field_count( + const FORM *form) + { return(*(int *)0); } + +/* ./frm_driver.c */ + +#undef _nc_Position_Form_Cursor +int _nc_Position_Form_Cursor( + FORM *form) + { return(*(int *)0); } + +#undef _nc_Refresh_Current_Field +int _nc_Refresh_Current_Field( + FORM *form) + { return(*(int *)0); } + +#undef _nc_Synchronize_Attributes +int _nc_Synchronize_Attributes( + FIELD *field) + { return(*(int *)0); } + +#undef _nc_Synchronize_Options +int _nc_Synchronize_Options( + FIELD *field, + Field_Options newopts) + { return(*(int *)0); } + +#undef _nc_Set_Current_Field +int _nc_Set_Current_Field( + FORM *form, + FIELD *newfield) + { return(*(int *)0); } + +#undef _nc_Internal_Validation +bool _nc_Internal_Validation( + FORM *form) + { return(*(bool *)0); } + +#undef _nc_First_Active_Field +FIELD *_nc_First_Active_Field( + FORM *form) + { return(*(FIELD **)0); } + +#undef _nc_Set_Form_Page +int _nc_Set_Form_Page( + FORM *form, + int page, + FIELD *field) + { return(*(int *)0); } + +typedef struct { + int keycode; + int (*cmd)(FORM *); +} Binding_Info; + +#undef form_driver +int form_driver( + FORM *form, + int c) + { return(*(int *)0); } + +#undef set_field_buffer +int set_field_buffer( + FIELD *field, + int buffer, + const char *value) + { return(*(int *)0); } + +#undef field_buffer +char *field_buffer( + const FIELD *field, + int buffer) + { return(*(char **)0); } + +/* ./frm_hook.c */ + +#undef set_field_init +int set_field_init( + FORM *form, + Form_Hook func) + { return(*(int *)0); } + +#undef field_init +Form_Hook field_init( + const FORM *form) + { return(*(Form_Hook *)0); } + +#undef set_field_term +int set_field_term( + FORM *form, + Form_Hook func) + { return(*(int *)0); } + +#undef field_term +Form_Hook field_term( + const FORM *form) + { return(*(Form_Hook *)0); } + +#undef set_form_init +int set_form_init( + FORM *form, + Form_Hook func) + { return(*(int *)0); } + +#undef form_init +Form_Hook form_init( + const FORM *form) + { return(*(Form_Hook *)0); } + +#undef set_form_term +int set_form_term( + FORM *form, + Form_Hook func) + { return(*(int *)0); } + +#undef form_term +Form_Hook form_term( + const FORM *form) + { return(*(Form_Hook *)0); } + +/* ./frm_opts.c */ + +#undef set_form_opts +int set_form_opts( + FORM *form, + Form_Options opts) + { return(*(int *)0); } + +#undef form_opts +Form_Options form_opts( + const FORM *form) + { return(*(Form_Options *)0); } + +#undef form_opts_on +int form_opts_on( + FORM *form, + Form_Options opts) + { return(*(int *)0); } + +#undef form_opts_off +int form_opts_off( + FORM *form, + Form_Options opts) + { return(*(int *)0); } + +/* ./frm_page.c */ + +#undef set_form_page +int set_form_page( + FORM *form, + int page) + { return(*(int *)0); } + +#undef form_page +int form_page( + const FORM *form) + { return(*(int *)0); } + +/* ./frm_post.c */ + +#undef post_form +int post_form( + FORM *form) + { return(*(int *)0); } + +#undef unpost_form +int unpost_form( + FORM *form) + { return(*(int *)0); } + +/* ./frm_req_name.c */ + +#undef form_request_name +const char *form_request_name( + int request) + { return(*(const char **)0); } + +#undef form_request_by_name +int form_request_by_name( + const char *str) + { return(*(int *)0); } + +/* ./frm_scale.c */ + +#undef scale_form +int scale_form( + const FORM *form, + int *rows, + int *cols) + { return(*(int *)0); } + +/* ./frm_sub.c */ + +#undef set_form_sub +int set_form_sub( + FORM *form, + WINDOW *win) + { return(*(int *)0); } + +#undef form_sub +WINDOW *form_sub( + const FORM *form) + { return(*(WINDOW **)0); } + +/* ./frm_user.c */ + +#undef set_form_userptr +int set_form_userptr( + FORM *form, + void *usrptr) + { return(*(int *)0); } + +#undef form_userptr +void *form_userptr( + const FORM *form) + { return(*(void **)0); } + +/* ./frm_win.c */ + +#undef set_form_win +int set_form_win( + FORM *form, + WINDOW *win) + { return(*(int *)0); } + +#undef form_win +WINDOW *form_win( + const FORM *form) + { return(*(WINDOW **)0); } + +/* ./fty_alnum.c */ + +typedef struct { + int width; +} alnumARG; + +#undef TYPE_ALNUM +FIELDTYPE *TYPE_ALNUM; + +/* ./fty_alpha.c */ + +typedef struct { + int width; +} alphaARG; + +#undef TYPE_ALPHA +FIELDTYPE *TYPE_ALPHA; + +/* ./fty_enum.c */ + +typedef struct { + char **kwds; + int count; + bool checkcase; + bool checkunique; +} enumARG; + +#undef TYPE_ENUM +FIELDTYPE *TYPE_ENUM; + +/* ./fty_int.c */ + +typedef struct { + int precision; + long low; + long high; +} integerARG; + +#undef TYPE_INTEGER +FIELDTYPE *TYPE_INTEGER; + +/* ./fty_ipv4.c */ +#undef TYPE_IPV4 +FIELDTYPE *TYPE_IPV4; + +/* ./fty_num.c */ + +#include <locale.h> + +typedef struct { + int precision; + double low; + double high; + struct lconv* L; +} numericARG; + +#undef TYPE_NUMERIC +FIELDTYPE *TYPE_NUMERIC; + +/* ./fty_regex.c */ + +#include <regex.h> + +typedef struct +{ + regex_t *pRegExp; + unsigned long *refCount; +} RegExp_Arg; + +#undef TYPE_REGEXP +FIELDTYPE *TYPE_REGEXP; diff --git a/Source/CursesDialog/form/mf_common.h b/Source/CursesDialog/form/mf_common.h new file mode 100644 index 0000000..6b1e8fe --- /dev/null +++ b/Source/CursesDialog/form/mf_common.h @@ -0,0 +1,93 @@ +/**************************************************************************** + * Copyright (c) 1998,2000 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 <juergen.pfeifer@gmx.net> 1995,1997 * + ****************************************************************************/ + +/* Common internal header for menu and form library */ + +#if HAVE_CONFIG_H +# include <ncurses_cfg.h> +#endif + +#include <stdlib.h> +#include <sys/types.h> +#include <assert.h> +#include <string.h> +#include <ctype.h> +#include <errno.h> + +#if DECL_ERRNO +extern int errno; +#endif + +/* in case of debug version we ignore the suppression of assertions */ +#ifdef TRACE +# ifdef NDEBUG +# undef NDEBUG +# endif +#endif + +#include <nc_alloc.h> + +#if USE_RCS_IDS +#define MODULE_ID(id) static const char Ident[] = id; +#else +#define MODULE_ID(id) /*nothing*/ +#endif + + +/* Maximum regular 8-bit character code */ +#define MAX_REGULAR_CHARACTER (0xff) + +#define SET_ERROR(code) (errno=(code)) +#define GET_ERROR() (errno) +#define RETURN(code) return( SET_ERROR(code) ) + +/* The few common values in the status fields for menus and forms */ +#define _POSTED (0x01) /* menu or form is posted */ +#define _IN_DRIVER (0x02) /* menu or form is processing hook routine */ + +/* Call object hook */ +#define Call_Hook( object, handler ) \ + if ( (object) && ((object)->handler) )\ + {\ + (object)->status |= _IN_DRIVER;\ + (object)->handler(object);\ + (object)->status &= ~_IN_DRIVER;\ + } + +#define INLINE + +#ifndef TRACE +# if CC_HAS_INLINE_FUNCS +# undef INLINE +# define INLINE inline +# endif +#endif diff --git a/Source/CursesDialog/form/nc_alloc.h b/Source/CursesDialog/form/nc_alloc.h new file mode 100644 index 0000000..80ce3f4 --- /dev/null +++ b/Source/CursesDialog/form/nc_alloc.h @@ -0,0 +1,83 @@ +/**************************************************************************** + * Copyright (c) 1998 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: Thomas E. Dickey <dickey@clark.net> 1996,1997 * + ****************************************************************************/ +/* $Id$ */ + +#ifndef NC_ALLOC_included +#define NC_ALLOC_included 1 + +#if HAVE_LIBDMALLOC +#include <dmalloc.h> /* Gray Watson's library */ +#else +#undef HAVE_LIBDMALLOC +#define HAVE_LIBDMALLOC 0 +#endif + +#if HAVE_LIBDBMALLOC +#include <dbmalloc.h> /* Conor Cahill's library */ +#else +#undef HAVE_LIBDBMALLOC +#define HAVE_LIBDBMALLOC 0 +#endif + +#ifndef NO_LEAKS +#define NO_LEAKS 0 +#endif + +#if HAVE_LIBDBMALLOC || HAVE_LIBDMALLOC || NO_LEAKS +#define HAVE_NC_FREEALL 1 +struct termtype; +extern void _nc_free_and_exit(int) GCC_NORETURN; +extern void _nc_free_tparm(void); +extern void _nc_leaks_dump_entry(void); +#define ExitProgram(code) _nc_free_and_exit(code) +#endif + +#ifndef HAVE_NC_FREEALL +#define HAVE_NC_FREEALL 0 +#endif + +#ifndef ExitProgram +#define ExitProgram(code) return code +#endif + +/* doalloc.c */ +extern void *_nc_doalloc(void *, size_t); +#if !HAVE_STRDUP +#define strdup _nc_strdup +extern char *_nc_strdup(const char *); +#endif + +#define typeMalloc(type,elts) (type *)malloc((elts)*sizeof(type)) +#define typeCalloc(type,elts) (type *)calloc((elts),sizeof(type)) +#define typeRealloc(type,elts,ptr) (type *)_nc_doalloc(ptr, (elts)*sizeof(type)) + +#endif /* NC_ALLOC_included */ |