106bfebdeSXin LI /**************************************************************************** 2*73f0a83dSXin LI * Copyright (c) 2008-2010,2012 Free Software Foundation, Inc. * 306bfebdeSXin LI * * 406bfebdeSXin LI * Permission is hereby granted, free of charge, to any person obtaining a * 506bfebdeSXin LI * copy of this software and associated documentation files (the * 606bfebdeSXin LI * "Software"), to deal in the Software without restriction, including * 706bfebdeSXin LI * without limitation the rights to use, copy, modify, merge, publish, * 806bfebdeSXin LI * distribute, distribute with modifications, sublicense, and/or sell * 906bfebdeSXin LI * copies of the Software, and to permit persons to whom the Software is * 1006bfebdeSXin LI * furnished to do so, subject to the following conditions: * 1106bfebdeSXin LI * * 1206bfebdeSXin LI * The above copyright notice and this permission notice shall be included * 1306bfebdeSXin LI * in all copies or substantial portions of the Software. * 1406bfebdeSXin LI * * 1506bfebdeSXin LI * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * 1606bfebdeSXin LI * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * 1706bfebdeSXin LI * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * 1806bfebdeSXin LI * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * 1906bfebdeSXin LI * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * 2006bfebdeSXin LI * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * 2106bfebdeSXin LI * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * 2206bfebdeSXin LI * * 2306bfebdeSXin LI * Except as contained in this notice, the name(s) of the above copyright * 2406bfebdeSXin LI * holders shall not be used in advertising or otherwise to promote the * 2506bfebdeSXin LI * sale, use or other dealings in this Software without prior written * 2606bfebdeSXin LI * authorization. * 2706bfebdeSXin LI ****************************************************************************/ 2806bfebdeSXin LI 2906bfebdeSXin LI /*************************************************************************** 3006bfebdeSXin LI * * 3106bfebdeSXin LI * Author : Juergen Pfeifer * 3206bfebdeSXin LI * * 3306bfebdeSXin LI ***************************************************************************/ 3406bfebdeSXin LI 3506bfebdeSXin LI #include "form.priv.h" 3606bfebdeSXin LI 37*73f0a83dSXin LI MODULE_ID("$Id: fty_generic.c,v 1.6 2012/06/10 00:27:49 tom Exp $") 3806bfebdeSXin LI 3906bfebdeSXin LI /* 4006bfebdeSXin LI * This is not a full implementation of a field type, but adds some 4106bfebdeSXin LI * support for higher level languages with some restrictions to interop 4206bfebdeSXin LI * with C language. Especially the collection of arguments for the 4306bfebdeSXin LI * various fieldtypes is not based on the vararg C mechanism, but on a 4406bfebdeSXin LI * iterator based callback mechanism that allowes the high level language 4506bfebdeSXin LI * to provide the arguments as a structure. Most languages have mechanisms 4606bfebdeSXin LI * to layout structures so that they can be passed to C. 4706bfebdeSXin LI * The languages can register a new generic fieldtype dynamically and store 4806bfebdeSXin LI * a handle (key) to the calling object as an argument. Together with that 4906bfebdeSXin LI * it can register a freearg callback, so that the high level language 5006bfebdeSXin LI * remains in control of the memory management of the arguments they pass. 5106bfebdeSXin LI * The design idea is, that the high-level language - typically a OO 5206bfebdeSXin LI * language like C# or Java, uses it's own dispatching mechanisms 5306bfebdeSXin LI * (polymorphism) to call the proper check routines responsible for the 5406bfebdeSXin LI * argument type. So these language implement typically only one generic 5506bfebdeSXin LI * fieldtype they register with the forms library using this call. 5606bfebdeSXin LI * 5706bfebdeSXin LI * For that purpose we have extended the fieldtype struc by a new element 5806bfebdeSXin LI * that gets the arguments from a single struct passed by the caller. 5906bfebdeSXin LI * 6006bfebdeSXin LI */ 6106bfebdeSXin LI #if NCURSES_INTEROP_FUNCS 6206bfebdeSXin LI 6306bfebdeSXin LI /*--------------------------------------------------------------------------- 6406bfebdeSXin LI | Facility : libnform 6506bfebdeSXin LI | Function : static void *Generic_This_Type( void * arg ) 6606bfebdeSXin LI | 6706bfebdeSXin LI | Description : We interpret the passed arg just as a handle the 6806bfebdeSXin LI | calling language uses to keep track of its allocated 6906bfebdeSXin LI | argument structures. We can simply copy it back. 7006bfebdeSXin LI | 7106bfebdeSXin LI | Return Values : Pointer to argument structure 7206bfebdeSXin LI +--------------------------------------------------------------------------*/ 7306bfebdeSXin LI static void * 7406bfebdeSXin LI Generic_This_Type(void *arg) 7506bfebdeSXin LI { 7606bfebdeSXin LI return (arg); 7706bfebdeSXin LI } 7806bfebdeSXin LI 7906bfebdeSXin LI /*--------------------------------------------------------------------------- 8006bfebdeSXin LI | Facility : libnform 8106bfebdeSXin LI | Function : FIELDTYPE *_nc_generic_fieldtype( 8206bfebdeSXin LI | bool (* const field_check)(FIELD *,const void *), 8306bfebdeSXin LI | bool (* const char_check) (int, const void *), 8406bfebdeSXin LI | bool (*const next)(FORM*,FIELD*,const void*), 8506bfebdeSXin LI | bool (*const prev)(FORM*,FIELD*,const void*), 8606bfebdeSXin LI | void (*freecallback)(void*)) 8706bfebdeSXin LI | 8806bfebdeSXin LI | Description : Create a new fieldtype. The application programmer must 8906bfebdeSXin LI | write a field_check and a char_check function and give 9006bfebdeSXin LI | them as input to this call. A callback to allow the 9106bfebdeSXin LI | release of the allocated memory must also be provided. 9206bfebdeSXin LI | For generic field types, we provide some more 9306bfebdeSXin LI | information about the field as parameters. 9406bfebdeSXin LI | 9506bfebdeSXin LI | If an error occurs, errno is set to 9606bfebdeSXin LI | E_BAD_ARGUMENT - invalid arguments 9706bfebdeSXin LI | E_SYSTEM_ERROR - system error (no memory) 9806bfebdeSXin LI | 9906bfebdeSXin LI | Return Values : Fieldtype pointer or NULL if error occurred 10006bfebdeSXin LI +--------------------------------------------------------------------------*/ 10106bfebdeSXin LI NCURSES_EXPORT(FIELDTYPE *) 10206bfebdeSXin LI _nc_generic_fieldtype(bool (*const field_check) (FORM *, FIELD *, const void *), 10306bfebdeSXin LI bool (*const char_check) (int, FORM *, FIELD *, const 10406bfebdeSXin LI void *), 10506bfebdeSXin LI bool (*const next) (FORM *, FIELD *, const void *), 10606bfebdeSXin LI bool (*const prev) (FORM *, FIELD *, const void *), 10706bfebdeSXin LI void (*freecallback) (void *)) 10806bfebdeSXin LI { 10906bfebdeSXin LI int code = E_SYSTEM_ERROR; 11006bfebdeSXin LI FIELDTYPE *res = (FIELDTYPE *)0; 11106bfebdeSXin LI 11206bfebdeSXin LI T((T_CALLED("_nc_generic_fieldtype(%p,%p,%p,%p,%p)"), 11306bfebdeSXin LI field_check, char_check, next, prev, freecallback)); 11406bfebdeSXin LI 11506bfebdeSXin LI if (field_check || char_check) 11606bfebdeSXin LI { 11706bfebdeSXin LI res = typeMalloc(FIELDTYPE, 1); 11806bfebdeSXin LI 11906bfebdeSXin LI if (res) 12006bfebdeSXin LI { 12106bfebdeSXin LI *res = *_nc_Default_FieldType; 122*73f0a83dSXin LI SetStatus(res, (_HAS_ARGS | _GENERIC)); 12306bfebdeSXin LI res->fieldcheck.gfcheck = field_check; 12406bfebdeSXin LI res->charcheck.gccheck = char_check; 12506bfebdeSXin LI res->genericarg = Generic_This_Type; 12606bfebdeSXin LI res->freearg = freecallback; 12706bfebdeSXin LI res->enum_next.gnext = next; 12806bfebdeSXin LI res->enum_prev.gprev = prev; 12906bfebdeSXin LI code = E_OK; 13006bfebdeSXin LI } 13106bfebdeSXin LI } 13206bfebdeSXin LI else 13306bfebdeSXin LI code = E_BAD_ARGUMENT; 13406bfebdeSXin LI 13506bfebdeSXin LI if (E_OK != code) 13606bfebdeSXin LI SET_ERROR(code); 13706bfebdeSXin LI 13806bfebdeSXin LI returnFieldType(res); 13906bfebdeSXin LI } 14006bfebdeSXin LI 14106bfebdeSXin LI /*--------------------------------------------------------------------------- 14206bfebdeSXin LI | Facility : libnform 14306bfebdeSXin LI | Function : static TypeArgument *GenericArgument( 14406bfebdeSXin LI | const FIELDTYPE* typ, 14506bfebdeSXin LI | int (*argiterator)(void**), 14606bfebdeSXin LI | int* err) 14706bfebdeSXin LI | 14806bfebdeSXin LI | Description : The iterator callback must browse through all fieldtype 14906bfebdeSXin LI | parameters that have an argument associated with the 15006bfebdeSXin LI | type. The iterator returns 1 if the operation to get 15106bfebdeSXin LI | the next element was successfull, 0 otherwise. If the 15206bfebdeSXin LI | iterator could move to the next argument, it fills 15306bfebdeSXin LI | the void* pointer representing the argument into the 15406bfebdeSXin LI | location provided as argument to the iterator. 15506bfebdeSXin LI | The err reference is used to keep track of errors. 15606bfebdeSXin LI | 15706bfebdeSXin LI | Return Values : Pointer to argument structure 15806bfebdeSXin LI +--------------------------------------------------------------------------*/ 15906bfebdeSXin LI static TypeArgument * 16006bfebdeSXin LI GenericArgument(const FIELDTYPE *typ, 16106bfebdeSXin LI int (*argiterator) (void **), int *err) 16206bfebdeSXin LI { 16306bfebdeSXin LI TypeArgument *res = (TypeArgument *)0; 16406bfebdeSXin LI 16506bfebdeSXin LI if (typ != 0 && (typ->status & _HAS_ARGS) != 0 && err != 0 && argiterator != 0) 16606bfebdeSXin LI { 16706bfebdeSXin LI if (typ->status & _LINKED_TYPE) 16806bfebdeSXin LI { 16906bfebdeSXin LI /* Composite fieldtypes keep track internally of their own memory */ 17006bfebdeSXin LI TypeArgument *p = typeMalloc(TypeArgument, 1); 17106bfebdeSXin LI 17206bfebdeSXin LI if (p) 17306bfebdeSXin LI { 17406bfebdeSXin LI p->left = GenericArgument(typ->left, argiterator, err); 17506bfebdeSXin LI p->right = GenericArgument(typ->right, argiterator, err); 17606bfebdeSXin LI return p; 17706bfebdeSXin LI } 17806bfebdeSXin LI else 17906bfebdeSXin LI *err += 1; 18006bfebdeSXin LI } 18106bfebdeSXin LI else 18206bfebdeSXin LI { 18306bfebdeSXin LI assert(typ->genericarg != (void *)0); 18406bfebdeSXin LI if (typ->genericarg == 0) 18506bfebdeSXin LI *err += 1; 18606bfebdeSXin LI else 18706bfebdeSXin LI { 18806bfebdeSXin LI void *argp; 18906bfebdeSXin LI int valid = argiterator(&argp); 19006bfebdeSXin LI 19106bfebdeSXin LI if (valid == 0 || argp == 0 || 19206bfebdeSXin LI !(res = (TypeArgument *)typ->genericarg(argp))) 19306bfebdeSXin LI { 19406bfebdeSXin LI *err += 1; 19506bfebdeSXin LI } 19606bfebdeSXin LI } 19706bfebdeSXin LI } 19806bfebdeSXin LI } 19906bfebdeSXin LI return res; 20006bfebdeSXin LI } 20106bfebdeSXin LI 20206bfebdeSXin LI /*--------------------------------------------------------------------------- 20306bfebdeSXin LI | Facility : libnform 20406bfebdeSXin LI | Function : int _nc_set_generic_fieldtype( 20506bfebdeSXin LI | FIELD* field, 20606bfebdeSXin LI | FIELDTYPE* ftyp, 20706bfebdeSXin LI | int (*argiterator)(void**)) 20806bfebdeSXin LI | 20906bfebdeSXin LI | Description : Assign the fieldtype to the field and use the iterator 21006bfebdeSXin LI | mechanism to get the arguments when a check is 21106bfebdeSXin LI | performed. 21206bfebdeSXin LI | 21306bfebdeSXin LI | Return Values : E_OK if all went well 21406bfebdeSXin LI | E_SYSTEM_ERROR if an error occurred 21506bfebdeSXin LI +--------------------------------------------------------------------------*/ 21606bfebdeSXin LI NCURSES_EXPORT(int) 21706bfebdeSXin LI _nc_set_generic_fieldtype(FIELD *field, 21806bfebdeSXin LI FIELDTYPE *ftyp, 21906bfebdeSXin LI int (*argiterator) (void **)) 22006bfebdeSXin LI { 22106bfebdeSXin LI int code = E_SYSTEM_ERROR; 22206bfebdeSXin LI int err = 0; 22306bfebdeSXin LI 22406bfebdeSXin LI if (field) 22506bfebdeSXin LI { 22606bfebdeSXin LI if (field && field->type) 22706bfebdeSXin LI _nc_Free_Type(field); 22806bfebdeSXin LI 22906bfebdeSXin LI field->type = ftyp; 23006bfebdeSXin LI if (ftyp) 23106bfebdeSXin LI { 23206bfebdeSXin LI if (argiterator) 23306bfebdeSXin LI { 23406bfebdeSXin LI /* The precondition is that the iterator is reset */ 23506bfebdeSXin LI field->arg = (void *)GenericArgument(field->type, argiterator, &err); 23606bfebdeSXin LI 23706bfebdeSXin LI if (err) 23806bfebdeSXin LI { 23906bfebdeSXin LI _nc_Free_Argument(field->type, (TypeArgument *)(field->arg)); 24006bfebdeSXin LI field->type = (FIELDTYPE *)0; 24106bfebdeSXin LI field->arg = (void *)0; 24206bfebdeSXin LI } 24306bfebdeSXin LI else 24406bfebdeSXin LI { 24506bfebdeSXin LI code = E_OK; 24606bfebdeSXin LI if (field->type) 24706bfebdeSXin LI field->type->ref++; 24806bfebdeSXin LI } 24906bfebdeSXin LI } 25006bfebdeSXin LI } 25106bfebdeSXin LI else 25206bfebdeSXin LI { 25306bfebdeSXin LI field->arg = (void *)0; 25406bfebdeSXin LI code = E_OK; 25506bfebdeSXin LI } 25606bfebdeSXin LI } 25706bfebdeSXin LI return code; 25806bfebdeSXin LI } 25906bfebdeSXin LI 26006bfebdeSXin LI /*--------------------------------------------------------------------------- 26106bfebdeSXin LI | Facility : libnform 26206bfebdeSXin LI | Function : WINDOW* _nc_form_cursor( 26306bfebdeSXin LI | FORM* form, 26406bfebdeSXin LI | int *pRow, int *pCol) 26506bfebdeSXin LI | 26606bfebdeSXin LI | Description : Get the current position of the form cursor position 26706bfebdeSXin LI | We also return the field window 26806bfebdeSXin LI | 26906bfebdeSXin LI | Return Values : The fields Window or NULL on error 27006bfebdeSXin LI +--------------------------------------------------------------------------*/ 27106bfebdeSXin LI NCURSES_EXPORT(WINDOW *) 27206bfebdeSXin LI _nc_form_cursor(const FORM *form, int *pRow, int *pCol) 27306bfebdeSXin LI { 27406bfebdeSXin LI int code = E_SYSTEM_ERROR; 27506bfebdeSXin LI WINDOW *res = (WINDOW *)0; 27606bfebdeSXin LI 27706bfebdeSXin LI if (!(form == 0 || pRow == 0 || pCol == 0)) 27806bfebdeSXin LI { 27906bfebdeSXin LI *pRow = form->currow; 28006bfebdeSXin LI *pCol = form->curcol; 28106bfebdeSXin LI res = form->w; 28206bfebdeSXin LI code = E_OK; 28306bfebdeSXin LI } 28406bfebdeSXin LI if (code != E_OK) 28506bfebdeSXin LI SET_ERROR(code); 28606bfebdeSXin LI return res; 28706bfebdeSXin LI } 28806bfebdeSXin LI 28906bfebdeSXin LI #else 29006bfebdeSXin LI extern void _nc_fty_generic(void); 29106bfebdeSXin LI void 29206bfebdeSXin LI _nc_fty_generic(void) 29306bfebdeSXin LI { 29406bfebdeSXin LI } 29506bfebdeSXin LI #endif 29606bfebdeSXin LI 29706bfebdeSXin LI /* fty_generic.c ends here */ 298