X-Git-Url: https://ncurses.scripts.mit.edu/?p=ncurses.git;a=blobdiff_plain;f=form%2Ffrm_driver.c;h=6390bdeee37bcd7ef75ba39d3cc5dc8339523e16;hp=1ee4c796d5cf85568abffe2382ae34d6fc3068be;hb=555811d68fc57f29fcf3d803adfbf7070b6a70e7;hpb=3a0d9d27e0cf115ff9dcc6163c251bccaa62bd7d diff --git a/form/frm_driver.c b/form/frm_driver.c index 1ee4c796..6390bdee 100644 --- a/form/frm_driver.c +++ b/form/frm_driver.c @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (c) 1998-2008,2009 Free Software Foundation, Inc. * + * Copyright (c) 1998-2011,2012 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 * @@ -32,7 +32,7 @@ #include "form.priv.h" -MODULE_ID("$Id: frm_driver.c,v 1.93 2009/10/24 23:23:32 tom Exp $") +MODULE_ID("$Id: frm_driver.c,v 1.102 2012/07/21 23:23:08 tom Exp $") /*---------------------------------------------------------------------------- This is the core module of the form library. It contains the majority @@ -172,7 +172,7 @@ static int FE_Delete_Previous(FORM *); 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) || \ + (!((unsigned)(field)->opts & O_PUBLIC) || \ Is_Scroll_Field(field)) /* Logic to decide whether or not a field needs justification */ @@ -180,7 +180,7 @@ static int FE_Delete_Previous(FORM *); (((field)->just != NO_JUSTIFICATION) && \ (Single_Line_Field(field)) && \ (((field)->dcols == (field)->cols) && \ - ((field)->opts & O_STATIC)) ) + ((unsigned)(field)->opts & O_STATIC))) /* Logic to determine whether or not a dynamic field may still grow */ #define Growable(field) ((field)->status & _MAY_GROW) @@ -188,13 +188,13 @@ static int FE_Delete_Previous(FORM *); /* Macro to set the attributes for a fields window */ #define Set_Field_Window_Attributes(field,win) \ ( wbkgdset((win),(chtype)((field)->pad | (field)->back)), \ - (void) wattrset((win),(field)->fore) ) + (void) wattrset((win), (int)(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) &&\ + ((unsigned)field->opts & O_VISIBLE) &&\ (field->page == field->form->curpage)) /* Logic to determine whether or not we are on the first position in the @@ -512,9 +512,10 @@ Buffer_To_Window(const FIELD *field, WINDOW *win) /*--------------------------------------------------------------------------- | Facility : libnform -| Function : static void Window_To_Buffer( +| Function : void _nc_get_fieldbuffer( | WINDOW * win, -| FIELD * field) +| FIELD * field, +| FIELD_CELL * buf) | | Description : Copy the content of the window into the buffer. | The multiple lines of a window are simply @@ -523,18 +524,22 @@ Buffer_To_Window(const FIELD *field, WINDOW *win) | | Return Values : - +--------------------------------------------------------------------------*/ -static void -Window_To_Buffer(WINDOW *win, FIELD *field) +NCURSES_EXPORT(void) +_nc_get_fieldbuffer(FORM *form, FIELD *field, FIELD_CELL *buf) { int pad; int len = 0; FIELD_CELL *p; int row, height; + WINDOW *win; - assert(win && field && field->buf); + assert(form && field && buf); + + win = form->w; + assert(win); pad = field->pad; - p = field->buf; + p = buf; height = getmaxy(win); for (row = 0; (row < height) && (row < field->drows); row++) @@ -561,6 +566,25 @@ Window_To_Buffer(WINDOW *win, FIELD *field) } } +/*--------------------------------------------------------------------------- +| Facility : libnform +| Function : static void Window_To_Buffer( +| FORM * form, +| 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(FORM *form, FIELD *field) +{ + _nc_get_fieldbuffer(form, field, field->buf); +} + /*--------------------------------------------------------------------------- | Facility : libnform | Function : static void Synchronize_Buffer(FORM * form) @@ -577,9 +601,9 @@ Synchronize_Buffer(FORM *form) { if (form->status & _WINDOW_MODIFIED) { - form->status &= ~_WINDOW_MODIFIED; - form->status |= _FCHECK_REQUIRED; - Window_To_Buffer(form->w, form->current); + ClrStatus(form, _WINDOW_MODIFIED); + SetStatus(form, _FCHECK_REQUIRED); + Window_To_Buffer(form, form->current); wmove(form->w, form->currow, form->curcol); } } @@ -629,7 +653,7 @@ Field_Grown(FIELD *field, int amount) growth = Minimum(field->maxgrow - field->dcols, growth); field->dcols += growth; if (field->dcols == field->maxgrow) - field->status &= ~_MAY_GROW; + ClrStatus(field, _MAY_GROW); } else { @@ -638,7 +662,7 @@ Field_Grown(FIELD *field, int amount) growth = Minimum(field->maxgrow - field->drows, growth); field->drows += growth; if (field->drows == field->maxgrow) - field->status &= ~_MAY_GROW; + ClrStatus(field, _MAY_GROW); } /* drows, dcols changed, so we get really the new buffer length */ new_buflen = Buffer_Length(field); @@ -650,7 +674,7 @@ Field_Grown(FIELD *field, int amount) field->drows = old_drows; if ((single_line_field && (field->dcols != field->maxgrow)) || (!single_line_field && (field->drows != field->maxgrow))) - field->status |= _MAY_GROW; + SetStatus(field, _MAY_GROW); } else { @@ -729,7 +753,7 @@ Field_Grown(FIELD *field, int amount) (field->dcols != field->maxgrow)) || (!single_line_field && (field->drows != field->maxgrow))) - field->status |= _MAY_GROW; + SetStatus(field, _MAY_GROW); free(newbuf); } } @@ -836,7 +860,7 @@ _nc_Refresh_Current_Field(FORM *form) field = form->current; formwin = Get_Form_Window(form); - if (field->opts & O_PUBLIC) + if ((unsigned)field->opts & O_PUBLIC) { if (Is_Scroll_Field(field)) { @@ -873,19 +897,19 @@ _nc_Refresh_Current_Field(FORM *form) if (form->currow < form->toprow) { form->toprow = form->currow; - field->status |= _NEWTOP; + SetStatus(field, _NEWTOP); } if (form->currow >= row_after_bottom) { form->toprow = form->currow - field->rows + 1; - field->status |= _NEWTOP; + SetStatus(field, _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; + ClrStatus(field, _NEWTOP); } else { @@ -1010,7 +1034,8 @@ Undo_Justification(FIELD *field, WINDOW *win) /*--------------------------------------------------------------------------- | Facility : libnform -| Function : static bool Check_Char( +| Function : static bool Check_Char(FORM *form, +| FIELD *field, | FIELDTYPE * typ, | int ch, | TypeArgument *argp) @@ -1022,7 +1047,11 @@ Undo_Justification(FIELD *field, WINDOW *win) | FALSE - Character is invalid +--------------------------------------------------------------------------*/ static bool -Check_Char(FIELDTYPE *typ, int ch, TypeArgument *argp) +Check_Char(FORM *form, + FIELD *field, + FIELDTYPE *typ, + int ch, + TypeArgument *argp) { if (typ) { @@ -1030,13 +1059,23 @@ Check_Char(FIELDTYPE *typ, int ch, TypeArgument *argp) { assert(argp); return ( - Check_Char(typ->left, ch, argp->left) || - Check_Char(typ->right, ch, argp->right)); + Check_Char(form, field, typ->left, ch, argp->left) || + Check_Char(form, field, typ->right, ch, argp->right)); } else { +#if NCURSES_INTEROP_FUNCS + if (typ->charcheck.occheck) + { + if (typ->status & _GENERIC) + return typ->charcheck.gccheck(ch, form, field, (void *)argp); + else + return typ->charcheck.occheck(ch, (void *)argp); + } +#else if (typ->ccheck) return typ->ccheck(ch, (void *)argp); +#endif } } return (!iscntrl(UChar(ch)) ? TRUE : FALSE); @@ -1072,27 +1111,27 @@ Display_Or_Erase_Field(FIELD *field, bool bEraseFlag) return E_SYSTEM_ERROR; else { - if (field->opts & O_VISIBLE) + if ((unsigned)field->opts & O_VISIBLE) { Set_Field_Window_Attributes(field, win); } else { - (void)wattrset(win, WINDOW_ATTRS(fwin)); + (void)wattrset(win, (int)WINDOW_ATTRS(fwin)); } werase(win); } if (!bEraseFlag) { - if (field->opts & O_PUBLIC) + if ((unsigned)field->opts & O_PUBLIC) { if (Justification_Allowed(field)) Perform_Justification(field, win); else Buffer_To_Window(field, win); } - field->status &= ~_NEWTOP; + ClrStatus(field, _NEWTOP); } wsyncup(win); delwin(win); @@ -1131,18 +1170,18 @@ Synchronize_Field(FIELD *field) form->currow = form->curcol = form->toprow = form->begincol = 0; werase(form->w); - if ((field->opts & O_PUBLIC) && Justification_Allowed(field)) + if (((unsigned)field->opts & O_PUBLIC) && Justification_Allowed(field)) Undo_Justification(field, form->w); else Buffer_To_Window(field, form->w); - field->status |= _NEWTOP; + SetStatus(field, _NEWTOP); res = _nc_Refresh_Current_Field(form); } else res = Display_Field(field); } - field->status |= _CHANGED; + SetStatus(field, _CHANGED); return (res); } @@ -1217,7 +1256,7 @@ _nc_Synchronize_Attributes(FIELD *field) werase(form->w); wmove(form->w, form->currow, form->curcol); - if (field->opts & O_PUBLIC) + if ((unsigned)field->opts & O_PUBLIC) { if (Justification_Allowed(field)) Undo_Justification(field, form->w); @@ -1233,7 +1272,7 @@ _nc_Synchronize_Attributes(FIELD *field) field->rows - 1, field->cols - 1, 0); wsyncup(formwin); Buffer_To_Window(field, form->w); - field->status |= _NEWTOP; /* fake refresh to paint all */ + SetStatus(field, _NEWTOP); /* fake refresh to paint all */ _nc_Refresh_Current_Field(form); } } @@ -1280,42 +1319,41 @@ _nc_Synchronize_Options(FIELD *field, Field_Options newopts) if (form) { - if (form->current == field) - { - field->opts = oldopts; - returnCode(E_CURRENT); - } - if (form->status & _POSTED) { - if ((form->curpage == field->page)) + if (form->current == field) + { + field->opts = oldopts; + returnCode(E_CURRENT); + } + if (form->curpage == field->page) { - if (changed_opts & O_VISIBLE) + if ((unsigned)changed_opts & O_VISIBLE) { - if (newopts & O_VISIBLE) + if ((unsigned)newopts & O_VISIBLE) res = Display_Field(field); else res = Erase_Field(field); } else { - if ((changed_opts & O_PUBLIC) && - (newopts & O_VISIBLE)) + if (((unsigned)changed_opts & O_PUBLIC) && + ((unsigned)newopts & O_VISIBLE)) res = Display_Field(field); } } } } - if (changed_opts & O_STATIC) + if ((unsigned)changed_opts & O_STATIC) { bool single_line_field = Single_Line_Field(field); int res2 = E_OK; - if (newopts & O_STATIC) + if ((unsigned)newopts & O_STATIC) { /* the field becomes now static */ - field->status &= ~_MAY_GROW; + ClrStatus(field, _MAY_GROW); /* if actually we have no hidden columns, justification may occur again */ if (single_line_field && @@ -1333,7 +1371,7 @@ _nc_Synchronize_Options(FIELD *field, Field_Options newopts) (single_line_field && (field->dcols < field->maxgrow)) || (!single_line_field && (field->drows < field->maxgrow))) { - field->status |= _MAY_GROW; + SetStatus(field, _MAY_GROW); /* a field with justification now changes its behavior, so we must redisplay it */ if (single_line_field && @@ -1386,24 +1424,24 @@ _nc_Set_Current_Field(FORM *form, FIELD *newfield) !(form->status & _POSTED)) { if ((form->w) && - (field->opts & O_VISIBLE) && + ((unsigned)field->opts & O_VISIBLE) && (field->form->curpage == field->page)) { _nc_Refresh_Current_Field(form); - if (field->opts & O_PUBLIC) + if ((unsigned)field->opts & O_PUBLIC) { if (field->drows > field->rows) { if (form->toprow == 0) - field->status &= ~_NEWTOP; + ClrStatus(field, _NEWTOP); else - field->status |= _NEWTOP; + SetStatus(field, _NEWTOP); } else { if (Justification_Allowed(field)) { - Window_To_Buffer(form->w, field); + Window_To_Buffer(form, field); werase(form->w); Perform_Justification(field, form->w); wsyncup(form->w); @@ -1431,7 +1469,7 @@ _nc_Set_Current_Field(FORM *form, FIELD *newfield) delwin(form->w); form->w = new_window; - form->status &= ~_WINDOW_MODIFIED; + ClrStatus(form, _WINDOW_MODIFIED); Set_Field_Window_Attributes(field, form->w); if (Has_Invisible_Parts(field)) @@ -1960,7 +1998,7 @@ Vertical_Scrolling(int (*const fct) (FORM *), FORM *form) { res = fct(form); if (res == E_OK) - form->current->status |= _NEWTOP; + SetStatus(form, _NEWTOP); } return (res); } @@ -2392,7 +2430,7 @@ Wrapping_Not_Necessary_Or_Wrapping_Ok(FORM *form) int result = E_REQUEST_DENIED; bool Last_Row = ((field->drows - 1) == form->currow); - if ((field->opts & O_WRAP) && /* wrapping wanted */ + if (((unsigned)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 */ @@ -2410,7 +2448,7 @@ Wrapping_Not_Necessary_Or_Wrapping_Ok(FORM *form) return E_SYSTEM_ERROR; } bp = Address_Of_Current_Row_In_Buffer(form); - Window_To_Buffer(form->w, field); + Window_To_Buffer(form, 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 */ @@ -2436,7 +2474,7 @@ Wrapping_Not_Necessary_Or_Wrapping_Ok(FORM *form) if (result != E_OK) { DeleteChar(form); - Window_To_Buffer(form->w, field); + Window_To_Buffer(form, field); result = E_REQUEST_DENIED; } } @@ -2475,7 +2513,7 @@ Field_Editing(int (*const fct) (FORM *), FORM *form) editable fields. */ if ((fct == FE_Delete_Previous) && - (form->opts & O_BS_OVERLOAD) && + ((unsigned)form->opts & O_BS_OVERLOAD) && First_Position_In_Current_Field(form)) { res = Inter_Field_Navigation(FN_Previous_Field, form); @@ -2484,7 +2522,7 @@ Field_Editing(int (*const fct) (FORM *), FORM *form) { if (fct == FE_New_Line) { - if ((form->opts & O_NL_OVERLOAD) && + if (((unsigned)form->opts & O_NL_OVERLOAD) && First_Position_In_Current_Field(form)) { res = Inter_Field_Navigation(FN_Next_Field, form); @@ -2496,11 +2534,11 @@ Field_Editing(int (*const fct) (FORM *), FORM *form) else { /* From now on, everything must be editable */ - if (form->current->opts & O_EDIT) + if ((unsigned)form->current->opts & O_EDIT) { res = fct(form); if (res == E_OK) - form->status |= _WINDOW_MODIFIED; + SetStatus(form, _WINDOW_MODIFIED); } } } @@ -2533,7 +2571,7 @@ FE_New_Line(FORM *form) if (Last_Row && (!(Growable(field) && !Single_Line_Field(field)))) { - if (!(form->opts & O_NL_OVERLOAD)) + if (!((unsigned)form->opts & O_NL_OVERLOAD)) returnCode(E_REQUEST_DENIED); wmove(form->w, form->currow, form->curcol); wclrtoeol(form->w); @@ -2541,7 +2579,7 @@ FE_New_Line(FORM *form) handled in the generic routine. The reason is, that FN_Next_Field may fail, but the form is definitively changed */ - form->status |= _WINDOW_MODIFIED; + SetStatus(form, _WINDOW_MODIFIED); returnCode(Inter_Field_Navigation(FN_Next_Field, form)); } else @@ -2557,7 +2595,7 @@ FE_New_Line(FORM *form) wclrtoeol(form->w); form->currow++; form->curcol = 0; - form->status |= _WINDOW_MODIFIED; + SetStatus(form, _WINDOW_MODIFIED); returnCode(E_OK); } } @@ -2567,7 +2605,7 @@ FE_New_Line(FORM *form) if (Last_Row && !(Growable(field) && !Single_Line_Field(field))) { - if (!(form->opts & O_NL_OVERLOAD)) + if (!((unsigned)form->opts & O_NL_OVERLOAD)) returnCode(E_REQUEST_DENIED); returnCode(Inter_Field_Navigation(FN_Next_Field, form)); } @@ -2589,7 +2627,7 @@ FE_New_Line(FORM *form) wmove(form->w, form->currow, form->curcol); winsertln(form->w); myADDNSTR(form->w, bp, (int)(t - bp)); - form->status |= _WINDOW_MODIFIED; + SetStatus(form, _WINDOW_MODIFIED); returnCode(E_OK); } } @@ -2611,7 +2649,8 @@ FE_Insert_Character(FORM *form) int result = E_REQUEST_DENIED; T((T_CALLED("FE_Insert_Character(%p)"), (void *)form)); - if (Check_Char(field->type, (int)C_BLANK, (TypeArgument *)(field->arg))) + if (Check_Char(form, field, field->type, (int)C_BLANK, + (TypeArgument *)(field->arg))) { bool There_Is_Room = Is_There_Room_For_A_Char_In_Line(form); @@ -2646,7 +2685,8 @@ FE_Insert_Line(FORM *form) int result = E_REQUEST_DENIED; T((T_CALLED("FE_Insert_Line(%p)"), (void *)form)); - if (Check_Char(field->type, (int)C_BLANK, (TypeArgument *)(field->arg))) + if (Check_Char(form, field, + field->type, (int)C_BLANK, (TypeArgument *)(field->arg))) { bool Maybe_Done = (form->currow != (field->drows - 1)) && Is_There_Room_For_A_Line(form); @@ -2886,7 +2926,7 @@ static int EM_Overlay_Mode(FORM *form) { T((T_CALLED("EM_Overlay_Mode(%p)"), (void *)form)); - form->status |= _OVLMODE; + SetStatus(form, _OVLMODE); returnCode(E_OK); } @@ -2902,7 +2942,7 @@ static int EM_Insert_Mode(FORM *form) { T((T_CALLED("EM_Insert_Mode(%p)"), (void *)form)); - form->status &= ~_OVLMODE; + ClrStatus(form, _OVLMODE); returnCode(E_OK); } @@ -2916,7 +2956,7 @@ EM_Insert_Mode(FORM *form) /*--------------------------------------------------------------------------- | Facility : libnform -| Function : static bool Next_Choice( +| Function : static bool Next_Choice(FORM * form, | FIELDTYPE * typ, | FIELD * field, | TypeArgument *argp) @@ -2928,7 +2968,7 @@ EM_Insert_Mode(FORM *form) | FALSE - couldn't retrieve next choice +--------------------------------------------------------------------------*/ static bool -Next_Choice(FIELDTYPE *typ, FIELD *field, TypeArgument *argp) +Next_Choice(FORM *form, FIELDTYPE *typ, FIELD *field, TypeArgument *argp) { if (!typ || !(typ->status & _HAS_CHOICE)) return FALSE; @@ -2937,19 +2977,27 @@ Next_Choice(FIELDTYPE *typ, FIELD *field, TypeArgument *argp) { assert(argp); return ( - Next_Choice(typ->left, field, argp->left) || - Next_Choice(typ->right, field, argp->right)); + Next_Choice(form, typ->left, field, argp->left) || + Next_Choice(form, typ->right, field, argp->right)); } else { +#if NCURSES_INTEROP_FUNCS + assert(typ->enum_next.onext); + if (typ->status & _GENERIC) + return typ->enum_next.gnext(form, field, (void *)argp); + else + return typ->enum_next.onext(field, (void *)argp); +#else assert(typ->next); return typ->next(field, (void *)argp); +#endif } } /*--------------------------------------------------------------------------- | Facility : libnform -| Function : static bool Previous_Choice( +| Function : static bool Previous_Choice(FORM * form, | FIELDTYPE * typ, | FIELD * field, | TypeArgument *argp) @@ -2961,7 +3009,7 @@ Next_Choice(FIELDTYPE *typ, FIELD *field, TypeArgument *argp) | FALSE - couldn't retrieve previous choice +--------------------------------------------------------------------------*/ static bool -Previous_Choice(FIELDTYPE *typ, FIELD *field, TypeArgument *argp) +Previous_Choice(FORM *form, FIELDTYPE *typ, FIELD *field, TypeArgument *argp) { if (!typ || !(typ->status & _HAS_CHOICE)) return FALSE; @@ -2970,13 +3018,21 @@ Previous_Choice(FIELDTYPE *typ, FIELD *field, TypeArgument *argp) { assert(argp); return ( - Previous_Choice(typ->left, field, argp->left) || - Previous_Choice(typ->right, field, argp->right)); + Previous_Choice(form, typ->left, field, argp->left) || + Previous_Choice(form, typ->right, field, argp->right)); } else { +#if NCURSES_INTEROP_FUNCS + assert(typ->enum_prev.oprev); + if (typ->status & _GENERIC) + return typ->enum_prev.gprev(form, field, (void *)argp); + else + return typ->enum_prev.oprev(field, (void *)argp); +#else assert(typ->prev); return typ->prev(field, (void *)argp); +#endif } } /*---------------------------------------------------------------------------- @@ -3003,7 +3059,7 @@ CR_Next_Choice(FORM *form) T((T_CALLED("CR_Next_Choice(%p)"), (void *)form)); Synchronize_Buffer(form); - returnCode((Next_Choice(field->type, field, (TypeArgument *)(field->arg))) + returnCode((Next_Choice(form, field->type, field, (TypeArgument *)(field->arg))) ? E_OK : E_REQUEST_DENIED); } @@ -3024,7 +3080,7 @@ CR_Previous_Choice(FORM *form) T((T_CALLED("CR_Previous_Choice(%p)"), (void *)form)); Synchronize_Buffer(form); - returnCode((Previous_Choice(field->type, field, (TypeArgument *)(field->arg))) + returnCode((Previous_Choice(form, field->type, field, (TypeArgument *)(field->arg))) ? E_OK : E_REQUEST_DENIED); } @@ -3038,7 +3094,7 @@ CR_Previous_Choice(FORM *form) /*--------------------------------------------------------------------------- | Facility : libnform -| Function : static bool Check_Field( +| Function : static bool Check_Field(FORM* form, | FIELDTYPE * typ, | FIELD * field, | TypeArgument * argp) @@ -3051,11 +3107,11 @@ CR_Previous_Choice(FORM *form) | FALSE - field is invalid. +--------------------------------------------------------------------------*/ static bool -Check_Field(FIELDTYPE *typ, FIELD *field, TypeArgument *argp) +Check_Field(FORM *form, FIELDTYPE *typ, FIELD *field, TypeArgument *argp) { if (typ) { - if (field->opts & O_NULLOK) + if ((unsigned)field->opts & O_NULLOK) { FIELD_CELL *bp = field->buf; @@ -3072,13 +3128,23 @@ Check_Field(FIELDTYPE *typ, FIELD *field, TypeArgument *argp) { assert(argp); return ( - Check_Field(typ->left, field, argp->left) || - Check_Field(typ->right, field, argp->right)); + Check_Field(form, typ->left, field, argp->left) || + Check_Field(form, typ->right, field, argp->right)); } else { +#if NCURSES_INTEROP_FUNCS + if (typ->fieldcheck.ofcheck) + { + if (typ->status & _GENERIC) + return typ->fieldcheck.gfcheck(form, field, (void *)argp); + else + return typ->fieldcheck.ofcheck(field, (void *)argp); + } +#else if (typ->fcheck) return typ->fcheck(field, (void *)argp); +#endif } } return TRUE; @@ -3102,12 +3168,12 @@ _nc_Internal_Validation(FORM *form) Synchronize_Buffer(form); if ((form->status & _FCHECK_REQUIRED) || - (!(field->opts & O_PASSOK))) + (!((unsigned)field->opts & O_PASSOK))) { - if (!Check_Field(field->type, field, (TypeArgument *)(field->arg))) + if (!Check_Field(form, field->type, field, (TypeArgument *)(field->arg))) return FALSE; - form->status &= ~_FCHECK_REQUIRED; - field->status |= _CHANGED; + ClrStatus(form, _FCHECK_REQUIRED); + SetStatus(field, _CHANGED); Synchronize_Linked_Fields(field); } return TRUE; @@ -3207,14 +3273,15 @@ _nc_First_Active_Field(FORM *form) do { field = (field == last_on_page) ? first : field + 1; - if (((*field)->opts & O_VISIBLE)) + if (((unsigned)(*field)->opts & O_VISIBLE)) break; } while (proposed != (*field)); proposed = *field; - if ((proposed == *last_on_page) && !(proposed->opts & O_VISIBLE)) + if ((proposed == *last_on_page) && + !((unsigned)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... @@ -3750,11 +3817,11 @@ _nc_Set_Form_Page(FORM *form, int page, FIELD *field) FIELD *last_field, *field_on_page; werase(Get_Form_Window(form)); - form->curpage = page; + form->curpage = (short)page; last_field = field_on_page = form->field[form->page[page].smin]; do { - if (field_on_page->opts & O_VISIBLE) + if ((unsigned)field_on_page->opts & O_VISIBLE) if ((res = Display_Field(field_on_page)) != E_OK) return (res); field_on_page = field_on_page->snext; @@ -3933,13 +4000,13 @@ Data_Entry(FORM *form, int c) int result = E_REQUEST_DENIED; T((T_CALLED("Data_Entry(%p,%s)"), (void *)form, _tracechtype((chtype)c))); - if ((field->opts & O_EDIT) + if (((unsigned)field->opts & O_EDIT) #if FIX_FORM_INACTIVE_BUG - && (field->opts & O_ACTIVE) + && ((unsigned)field->opts & O_ACTIVE) #endif ) { - if ((field->opts & O_BLANK) && + if (((unsigned)field->opts & O_BLANK) && First_Position_In_Current_Field(form) && !(form->status & _FCHECK_REQUIRED) && !(form->status & _WINDOW_MODIFIED)) @@ -3969,8 +4036,8 @@ Data_Entry(FORM *form, int c) 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)) + SetStatus(form, _WINDOW_MODIFIED); + if (End_Of_Field && !Growable(field) && ((unsigned)field->opts & O_AUTOSKIP)) result = Inter_Field_Navigation(FN_Next_Field, form); else { @@ -4162,7 +4229,10 @@ form_driver(FORM *form, int c) if ((c >= MIN_FORM_COMMAND && c <= MAX_FORM_COMMAND) && ((bindings[c - MIN_FORM_COMMAND].keycode & Key_Mask) == c)) - BI = &(bindings[c - MIN_FORM_COMMAND]); + { + TR(TRACE_CALLS, ("form_request %s", form_request_name(c))); + BI = &(bindings[c - MIN_FORM_COMMAND]); + } if (BI) { @@ -4180,7 +4250,7 @@ form_driver(FORM *form, int c) NULL /* Choice Request is generic */ }; size_t nMethods = (sizeof(Generic_Methods) / sizeof(Generic_Methods[0])); - size_t method = (BI->keycode >> ID_Shft) & 0xffff; /* see ID_Mask */ + size_t method = (size_t) ((BI->keycode >> ID_Shft) & 0xffff); /* see ID_Mask */ if ((method >= nMethods) || !(BI->cmd)) res = E_SYSTEM_ERROR; @@ -4189,16 +4259,20 @@ form_driver(FORM *form, int c) Generic_Method fct = Generic_Methods[method]; if (fct) - res = fct(BI->cmd, form); + { + res = fct(BI->cmd, form); + } else - res = (BI->cmd) (form); + { + res = (BI->cmd) (form); + } } } #ifdef NCURSES_MOUSE_VERSION else if (KEY_MOUSE == c) { MEVENT event; - WINDOW *win = form->win ? form->win : stdscr; + WINDOW *win = form->win ? form->win : StdScreen(Get_Form_Screen(form)); WINDOW *sub = form->sub ? form->sub : win; getmouse(&event); @@ -4285,7 +4359,7 @@ form_driver(FORM *form, int c) if (!iscntrl(UChar(c))) #else if (isprint(UChar(c)) && - Check_Char(form->current->type, c, + Check_Char(form, form->current, form->current->type, c, (TypeArgument *)(form->current->arg))) #endif res = Data_Entry(form, c); @@ -4335,14 +4409,14 @@ set_field_buffer(FIELD *field, int buffer, const char *value) if (!field || !value || ((buffer < 0) || (buffer > field->nbuf))) RETURN(E_BAD_ARGUMENT); - len = Buffer_Length(field); + len = (unsigned)Buffer_Length(field); 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); + unsigned vlen = (unsigned)strlen(value); if (vlen > len) { @@ -4351,7 +4425,9 @@ set_field_buffer(FIELD *field, int buffer, const char *value) * field->cols)))) RETURN(E_SYSTEM_ERROR); +#if !USE_WIDEC_SUPPORT len = vlen; +#endif } } @@ -4364,15 +4440,15 @@ set_field_buffer(FIELD *field, int buffer, const char *value) * and other special cases that we really do not want to handle here. */ #if NCURSES_EXT_FUNCS - if (wresize(field->working, field->drows, field->dcols) == ERR) + if (wresize(field->working, 1, Buffer_Length(field) + 1) == ERR) #endif { delwin(field->working); - field->working = newpad(field->drows, field->dcols); + field->working = newpad(1, Buffer_Length(field) + 1); } - len = Buffer_Length(field); + len = (unsigned)Buffer_Length(field); wclear(field->working); - mvwaddstr(field->working, 0, 0, value); + (void)mvwaddstr(field->working, 0, 0, value); if ((widevalue = typeCalloc(FIELD_CELL, len + 1)) == 0) { @@ -4382,9 +4458,9 @@ set_field_buffer(FIELD *field, int buffer, const char *value) { for (i = 0; i < (unsigned)field->drows; ++i) { - mvwin_wchnstr(field->working, i, 0, - widevalue + (i * field->dcols), - field->dcols); + (void)mvwin_wchnstr(field->working, 0, (int)i * field->dcols, + widevalue + ((int)i * field->dcols), + field->dcols); } for (i = 0; i < len; ++i) { @@ -4444,14 +4520,14 @@ field_buffer(const FIELD *field, int buffer) { #if USE_WIDEC_SUPPORT FIELD_CELL *data = Address_Of_Nth_Buffer(field, buffer); - unsigned need = 0; + size_t need = 0; int size = Buffer_Length(field); int n; /* determine the number of bytes needed to store the expanded string */ for (n = 0; n < size; ++n) { - if (!isWidecExt(data[n])) + if (!isWidecExt(data[n]) && data[n].chars[0] != L'\0') { mbstate_t state; size_t next; @@ -4468,12 +4544,25 @@ field_buffer(const FIELD *field, int buffer) free(field->expanded[buffer]); field->expanded[buffer] = typeMalloc(char, need + 1); - /* expand the multibyte data */ + /* + * Expand the multibyte data. + * + * It may also be multi-column data. In that case, the data for a row + * may be null-padded to align to the dcols/drows layout (or it may + * contain embedded wide-character extensions). Change the null-padding + * to blanks as needed. + */ if ((result = field->expanded[buffer]) != 0) { wclear(field->working); - mvwadd_wchnstr(field->working, 0, 0, data, size); - mvwinnstr(field->working, 0, 0, result, (int)need); + wmove(field->working, 0, 0); + for (n = 0; n < size; ++n) + { + if (!isWidecExt(data[n]) && data[n].chars[0] != L'\0') + wadd_wch(field->working, &data[n]); + } + wmove(field->working, 0, 0); + winnstr(field->working, result, (int)need); } #else result = Address_Of_Nth_Buffer(field, buffer); @@ -4532,7 +4621,7 @@ _nc_Widen_String(char *source, int *lengthp) { result[need] = wch; } - passed += status; + passed += (size_t) status; ++need; } else @@ -4552,7 +4641,7 @@ _nc_Widen_String(char *source, int *lengthp) break; result = typeCalloc(wchar_t, need); - *lengthp = need; + *lengthp = (int)need; if (result == 0) break; }