10e3d5408SPeter Wemm /****************************************************************************
2*21817992SBaptiste Daroussin * Copyright 2018-2020,2021 Thomas E. Dickey *
3e1865124SBaptiste Daroussin * Copyright 1998-2016,2017 Free Software Foundation, Inc. *
40e3d5408SPeter Wemm * *
50e3d5408SPeter Wemm * Permission is hereby granted, free of charge, to any person obtaining a *
60e3d5408SPeter Wemm * copy of this software and associated documentation files (the *
70e3d5408SPeter Wemm * "Software"), to deal in the Software without restriction, including *
80e3d5408SPeter Wemm * without limitation the rights to use, copy, modify, merge, publish, *
90e3d5408SPeter Wemm * distribute, distribute with modifications, sublicense, and/or sell *
100e3d5408SPeter Wemm * copies of the Software, and to permit persons to whom the Software is *
110e3d5408SPeter Wemm * furnished to do so, subject to the following conditions: *
120e3d5408SPeter Wemm * *
130e3d5408SPeter Wemm * The above copyright notice and this permission notice shall be included *
140e3d5408SPeter Wemm * in all copies or substantial portions of the Software. *
150e3d5408SPeter Wemm * *
160e3d5408SPeter Wemm * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS *
170e3d5408SPeter Wemm * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
180e3d5408SPeter Wemm * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. *
190e3d5408SPeter Wemm * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
200e3d5408SPeter Wemm * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
210e3d5408SPeter Wemm * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR *
220e3d5408SPeter Wemm * THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
230e3d5408SPeter Wemm * *
240e3d5408SPeter Wemm * Except as contained in this notice, the name(s) of the above copyright *
250e3d5408SPeter Wemm * holders shall not be used in advertising or otherwise to promote the *
260e3d5408SPeter Wemm * sale, use or other dealings in this Software without prior written *
270e3d5408SPeter Wemm * authorization. *
280e3d5408SPeter Wemm ****************************************************************************/
290e3d5408SPeter Wemm
300e3d5408SPeter Wemm /****************************************************************************
314a1a9510SRong-En Fan * Author: Juergen Pfeifer, 1995,1997 *
320e3d5408SPeter Wemm ****************************************************************************/
334a1a9510SRong-En Fan
340e3d5408SPeter Wemm #include "form.priv.h"
350e3d5408SPeter Wemm
36*21817992SBaptiste Daroussin MODULE_ID("$Id: frm_driver.c,v 1.135 2021/09/01 23:34:01 tom Exp $")
370e3d5408SPeter Wemm
380e3d5408SPeter Wemm /*----------------------------------------------------------------------------
390e3d5408SPeter Wemm This is the core module of the form library. It contains the majority
400e3d5408SPeter Wemm of the driver routines as well as the form_driver function.
410e3d5408SPeter Wemm
420e3d5408SPeter Wemm Essentially this module is nearly the whole library. This is because
430e3d5408SPeter Wemm all the functions in this module depends on some others in the module,
440e3d5408SPeter Wemm so it makes no sense to split them into separate files because they
450e3d5408SPeter Wemm will always be linked together. The only acceptable concern is turnaround
464a1a9510SRong-En Fan time for this module, but now we have all Pentiums or RISCs, so what!
470e3d5408SPeter Wemm
480e3d5408SPeter Wemm The driver routines are grouped into nine generic categories:
490e3d5408SPeter Wemm
500e3d5408SPeter Wemm a) Page Navigation ( all functions prefixed by PN_ )
510e3d5408SPeter Wemm The current page of the form is left and some new page is
520e3d5408SPeter Wemm entered.
530e3d5408SPeter Wemm b) Inter-Field Navigation ( all functions prefixed by FN_ )
540e3d5408SPeter Wemm The current field of the form is left and some new field is
550e3d5408SPeter Wemm entered.
560e3d5408SPeter Wemm c) Intra-Field Navigation ( all functions prefixed by IFN_ )
570e3d5408SPeter Wemm The current position in the current field is changed.
580e3d5408SPeter Wemm d) Vertical Scrolling ( all functions prefixed by VSC_ )
594a1a9510SRong-En Fan Essentially this is a specialization of Intra-Field navigation.
600e3d5408SPeter Wemm It has to check for a multi-line field.
610e3d5408SPeter Wemm e) Horizontal Scrolling ( all functions prefixed by HSC_ )
624a1a9510SRong-En Fan Essentially this is a specialization of Intra-Field navigation.
630e3d5408SPeter Wemm It has to check for a single-line field.
640e3d5408SPeter Wemm f) Field Editing ( all functions prefixed by FE_ )
650e3d5408SPeter Wemm The content of the current field is changed
660e3d5408SPeter Wemm g) Edit Mode requests ( all functions prefixed by EM_ )
670e3d5408SPeter Wemm Switching between insert and overlay mode
680e3d5408SPeter Wemm h) Field-Validation requests ( all functions prefixed by FV_ )
690e3d5408SPeter Wemm Perform verifications of the field.
700e3d5408SPeter Wemm i) Choice requests ( all functions prefixed by CR_ )
710e3d5408SPeter Wemm Requests to enumerate possible field values
720e3d5408SPeter Wemm --------------------------------------------------------------------------*/
730e3d5408SPeter Wemm
740e3d5408SPeter Wemm /*----------------------------------------------------------------------------
750e3d5408SPeter Wemm Some remarks on the placements of assert() macros :
760e3d5408SPeter Wemm I use them only on "strategic" places, i.e. top level entries where
770e3d5408SPeter Wemm I want to make sure that things are set correctly. Throughout subordinate
780e3d5408SPeter Wemm routines I omit them mostly.
790e3d5408SPeter Wemm --------------------------------------------------------------------------*/
800e3d5408SPeter Wemm
810e3d5408SPeter Wemm /*
820e3d5408SPeter Wemm Some options that may effect compatibility in behavior to SVr4 forms,
834a1a9510SRong-En Fan but they are here to allow a more intuitive and user friendly behavior of
840e3d5408SPeter Wemm our form implementation. This doesn't affect the API, so we feel it is
850e3d5408SPeter Wemm uncritical.
860e3d5408SPeter Wemm
874a1a9510SRong-En Fan The initial implementation tries to stay very close with the behavior
880e3d5408SPeter Wemm of the original SVr4 implementation, although in some areas it is quite
890e3d5408SPeter Wemm clear that this isn't the most appropriate way. As far as possible this
900e3d5408SPeter Wemm sources will allow you to build a forms lib that behaves quite similar
910e3d5408SPeter Wemm to SVr4, but now and in the future we will give you better options.
920e3d5408SPeter Wemm Perhaps at some time we will make this configurable at runtime.
930e3d5408SPeter Wemm */
940e3d5408SPeter Wemm
954a1a9510SRong-En Fan /* Implement a more user-friendly previous/next word behavior */
960e3d5408SPeter Wemm #define FRIENDLY_PREV_NEXT_WORD (1)
974a1a9510SRong-En Fan /* Fix the wrong behavior for forms with all fields inactive */
980e3d5408SPeter Wemm #define FIX_FORM_INACTIVE_BUG (1)
990e3d5408SPeter Wemm /* Allow dynamic field growth also when navigating past the end */
1000e3d5408SPeter Wemm #define GROW_IF_NAVIGATE (1)
1010e3d5408SPeter Wemm
1024a1a9510SRong-En Fan #if USE_WIDEC_SUPPORT
103aae38d10SBaptiste Daroussin #define myADDNSTR(w, s, n) wide_waddnstr(w, s, n)
104aae38d10SBaptiste Daroussin #define myINSNSTR(w, s, n) wide_winsnstr(w, s, n)
105aae38d10SBaptiste Daroussin #define myINNSTR(w, s, n) wide_winnstr(w, s, n)
1064a1a9510SRong-En Fan #define myWCWIDTH(w, y, x) cell_width(w, y, x)
1074a1a9510SRong-En Fan #else
1084a1a9510SRong-En Fan #define myADDNSTR(w, s, n) waddnstr(w, s, n)
1094a1a9510SRong-En Fan #define myINSNSTR(w, s, n) winsnstr(w, s, n)
1104a1a9510SRong-En Fan #define myINNSTR(w, s, n) winnstr(w, s, n)
1114a1a9510SRong-En Fan #define myWCWIDTH(w, y, x) 1
1124a1a9510SRong-En Fan #endif
1134a1a9510SRong-En Fan
1140e3d5408SPeter Wemm /*----------------------------------------------------------------------------
1150e3d5408SPeter Wemm Forward references to some internally used static functions
1160e3d5408SPeter Wemm --------------------------------------------------------------------------*/
1170e3d5408SPeter Wemm static int Inter_Field_Navigation(int (*const fct) (FORM *), FORM *form);
1180e3d5408SPeter Wemm static int FN_Next_Field(FORM *form);
1190e3d5408SPeter Wemm static int FN_Previous_Field(FORM *form);
1200e3d5408SPeter Wemm static int FE_New_Line(FORM *);
1210e3d5408SPeter Wemm static int FE_Delete_Previous(FORM *);
1224a1a9510SRong-En Fan
1230e3d5408SPeter Wemm /*----------------------------------------------------------------------------
1240e3d5408SPeter Wemm Macro Definitions.
1250e3d5408SPeter Wemm
1260e3d5408SPeter Wemm Some Remarks on that: I use the convention to use UPPERCASE for constants
1270e3d5408SPeter Wemm defined by Macros. If I provide a macro as a kind of inline routine to
1280e3d5408SPeter Wemm provide some logic, I use my Upper_Lower case style.
1290e3d5408SPeter Wemm --------------------------------------------------------------------------*/
1300e3d5408SPeter Wemm
1310e3d5408SPeter Wemm /* Calculate the position of a single row in a field buffer */
1320e3d5408SPeter Wemm #define Position_Of_Row_In_Buffer(field,row) ((row)*(field)->dcols)
1330e3d5408SPeter Wemm
1347a656419SBaptiste Daroussin /* Calculate start address for the field's buffer# N */
1350e3d5408SPeter Wemm #define Address_Of_Nth_Buffer(field,N) \
1360e3d5408SPeter Wemm ((field)->buf + (N)*(1+Buffer_Length(field)))
1370e3d5408SPeter Wemm
1387a656419SBaptiste Daroussin /* Calculate the start address of the row in the field's specified buffer# N */
1390e3d5408SPeter Wemm #define Address_Of_Row_In_Nth_Buffer(field,N,row) \
1400e3d5408SPeter Wemm (Address_Of_Nth_Buffer(field,N) + Position_Of_Row_In_Buffer(field,row))
1410e3d5408SPeter Wemm
1427a656419SBaptiste Daroussin /* Calculate the start address of the row in the field's primary buffer */
1430e3d5408SPeter Wemm #define Address_Of_Row_In_Buffer(field,row) \
1440e3d5408SPeter Wemm Address_Of_Row_In_Nth_Buffer(field,0,row)
1450e3d5408SPeter Wemm
1467a656419SBaptiste Daroussin /* Calculate the start address of the row in the form's current field
1470e3d5408SPeter Wemm buffer# N */
1480e3d5408SPeter Wemm #define Address_Of_Current_Row_In_Nth_Buffer(form,N) \
1490e3d5408SPeter Wemm Address_Of_Row_In_Nth_Buffer((form)->current,N,(form)->currow)
1500e3d5408SPeter Wemm
1517a656419SBaptiste Daroussin /* Calculate the start address of the row in the form's current field
1520e3d5408SPeter Wemm primary buffer */
1530e3d5408SPeter Wemm #define Address_Of_Current_Row_In_Buffer(form) \
1540e3d5408SPeter Wemm Address_Of_Current_Row_In_Nth_Buffer(form,0)
1550e3d5408SPeter Wemm
1567a656419SBaptiste Daroussin /* Calculate the address of the cursor in the form's current field
1570e3d5408SPeter Wemm primary buffer */
1580e3d5408SPeter Wemm #define Address_Of_Current_Position_In_Nth_Buffer(form,N) \
1590e3d5408SPeter Wemm (Address_Of_Current_Row_In_Nth_Buffer(form,N) + (form)->curcol)
1600e3d5408SPeter Wemm
1617a656419SBaptiste Daroussin /* Calculate the address of the cursor in the form's current field
1620e3d5408SPeter Wemm buffer# N */
1630e3d5408SPeter Wemm #define Address_Of_Current_Position_In_Buffer(form) \
1640e3d5408SPeter Wemm Address_Of_Current_Position_In_Nth_Buffer(form,0)
1650e3d5408SPeter Wemm
1664a1a9510SRong-En Fan /* Logic to decide whether or not a field is actually a field with
1670e3d5408SPeter Wemm vertical or horizontal scrolling */
1680e3d5408SPeter Wemm #define Is_Scroll_Field(field) \
1690e3d5408SPeter Wemm (((field)->drows > (field)->rows) || \
1700e3d5408SPeter Wemm ((field)->dcols > (field)->cols))
1710e3d5408SPeter Wemm
1720e3d5408SPeter Wemm /* Logic to decide whether or not a field needs to have an individual window
1730e3d5408SPeter Wemm instead of a derived window because it contains invisible parts.
1740e3d5408SPeter Wemm This is true for non-public fields and for scrollable fields. */
1750e3d5408SPeter Wemm #define Has_Invisible_Parts(field) \
176aae38d10SBaptiste Daroussin (!(Field_Has_Option(field, O_PUBLIC)) || \
1770e3d5408SPeter Wemm Is_Scroll_Field(field))
1780e3d5408SPeter Wemm
1790e3d5408SPeter Wemm /* Logic to decide whether or not a field needs justification */
1800e3d5408SPeter Wemm #define Justification_Allowed(field) \
1810e3d5408SPeter Wemm (((field)->just != NO_JUSTIFICATION) && \
1820e3d5408SPeter Wemm (Single_Line_Field(field)) && \
183aae38d10SBaptiste Daroussin ((Field_Has_Option(field, O_STATIC) && \
184aae38d10SBaptiste Daroussin ((field)->dcols == (field)->cols)) || \
185aae38d10SBaptiste Daroussin Field_Has_Option(field, O_DYNAMIC_JUSTIFY)))
1860e3d5408SPeter Wemm
1870e3d5408SPeter Wemm /* Logic to determine whether or not a dynamic field may still grow */
1880e3d5408SPeter Wemm #define Growable(field) ((field)->status & _MAY_GROW)
1890e3d5408SPeter Wemm
1907a656419SBaptiste Daroussin /* Macro to set the attributes for a field's window */
1910e3d5408SPeter Wemm #define Set_Field_Window_Attributes(field,win) \
19273f0a83dSXin LI ( wbkgdset((win),(chtype)((chtype)((field)->pad) | (field)->back)), \
19373f0a83dSXin LI (void) wattrset((win), (int)(field)->fore) )
1940e3d5408SPeter Wemm
1950e3d5408SPeter Wemm /* Logic to decide whether or not a field really appears on the form */
1960e3d5408SPeter Wemm #define Field_Really_Appears(field) \
1970e3d5408SPeter Wemm ((field->form) &&\
1980e3d5408SPeter Wemm (field->form->status & _POSTED) &&\
199aae38d10SBaptiste Daroussin (Field_Has_Option(field, O_VISIBLE)) &&\
2000e3d5408SPeter Wemm (field->page == field->form->curpage))
2010e3d5408SPeter Wemm
2020e3d5408SPeter Wemm /* Logic to determine whether or not we are on the first position in the
2030e3d5408SPeter Wemm current field */
2040e3d5408SPeter Wemm #define First_Position_In_Current_Field(form) \
2050e3d5408SPeter Wemm (((form)->currow==0) && ((form)->curcol==0))
2060e3d5408SPeter Wemm
2070e3d5408SPeter Wemm #define Minimum(a,b) (((a)<=(b)) ? (a) : (b))
2080e3d5408SPeter Wemm #define Maximum(a,b) (((a)>=(b)) ? (a) : (b))
2094a1a9510SRong-En Fan
2104a1a9510SRong-En Fan /*----------------------------------------------------------------------------
2114a1a9510SRong-En Fan Useful constants
2124a1a9510SRong-En Fan --------------------------------------------------------------------------*/
2134a1a9510SRong-En Fan static FIELD_CELL myBLANK = BLANK;
2144a1a9510SRong-En Fan static FIELD_CELL myZEROS;
2154a1a9510SRong-En Fan
2164a1a9510SRong-En Fan #ifdef TRACE
2174a1a9510SRong-En Fan static void
check_pos(FORM * form,int lineno)2184a1a9510SRong-En Fan check_pos(FORM *form, int lineno)
2194a1a9510SRong-En Fan {
2204a1a9510SRong-En Fan if (form && form->w)
2214a1a9510SRong-En Fan {
222*21817992SBaptiste Daroussin int y, x;
223*21817992SBaptiste Daroussin
2244a1a9510SRong-En Fan getyx(form->w, y, x);
2254a1a9510SRong-En Fan if (y != form->currow || x != form->curcol)
2264a1a9510SRong-En Fan {
2274a1a9510SRong-En Fan T(("CHECKPOS %s@%d have position %d,%d vs want %d,%d",
2284a1a9510SRong-En Fan __FILE__, lineno,
2294a1a9510SRong-En Fan y, x,
2304a1a9510SRong-En Fan form->currow, form->curcol));
2314a1a9510SRong-En Fan }
2324a1a9510SRong-En Fan }
2334a1a9510SRong-En Fan }
2344a1a9510SRong-En Fan #define CHECKPOS(form) check_pos(form, __LINE__)
2354a1a9510SRong-En Fan #else
2364a1a9510SRong-En Fan #define CHECKPOS(form) /* nothing */
2374a1a9510SRong-En Fan #endif
2384a1a9510SRong-En Fan
2394a1a9510SRong-En Fan /*----------------------------------------------------------------------------
2404a1a9510SRong-En Fan Wide-character special functions
2414a1a9510SRong-En Fan --------------------------------------------------------------------------*/
2424a1a9510SRong-En Fan #if USE_WIDEC_SUPPORT
243aae38d10SBaptiste Daroussin /* add like waddnstr, but using cchar_t* rather than char*
244aae38d10SBaptiste Daroussin */
2454a1a9510SRong-En Fan static int
wide_waddnstr(WINDOW * w,const cchar_t * s,int n)246aae38d10SBaptiste Daroussin wide_waddnstr(WINDOW *w, const cchar_t *s, int n)
247aae38d10SBaptiste Daroussin {
248aae38d10SBaptiste Daroussin int rc = OK;
249aae38d10SBaptiste Daroussin
250aae38d10SBaptiste Daroussin while (n-- > 0)
251aae38d10SBaptiste Daroussin {
252aae38d10SBaptiste Daroussin if ((rc = wadd_wch(w, s)) != OK)
253aae38d10SBaptiste Daroussin break;
254aae38d10SBaptiste Daroussin ++s;
255aae38d10SBaptiste Daroussin }
256aae38d10SBaptiste Daroussin return rc;
257aae38d10SBaptiste Daroussin }
258aae38d10SBaptiste Daroussin
259aae38d10SBaptiste Daroussin /* insert like winsnstr, but using cchar_t* rather than char*
260aae38d10SBaptiste Daroussin *
261aae38d10SBaptiste Daroussin * X/Open Curses has no close equivalent; inserts are done only with wchar_t
262aae38d10SBaptiste Daroussin * strings.
263aae38d10SBaptiste Daroussin */
264aae38d10SBaptiste Daroussin static int
wide_winsnstr(WINDOW * w,const cchar_t * s,int n)265aae38d10SBaptiste Daroussin wide_winsnstr(WINDOW *w, const cchar_t *s, int n)
2664a1a9510SRong-En Fan {
2674a1a9510SRong-En Fan int code = ERR;
2684a1a9510SRong-En Fan
2694a1a9510SRong-En Fan while (n-- > 0)
2704a1a9510SRong-En Fan {
271*21817992SBaptiste Daroussin int y, x;
272*21817992SBaptiste Daroussin
2734a1a9510SRong-En Fan getyx(w, y, x);
2744a1a9510SRong-En Fan if ((code = wins_wch(w, s++)) != OK)
2754a1a9510SRong-En Fan break;
2764a1a9510SRong-En Fan if ((code = wmove(w, y, x + 1)) != OK)
2774a1a9510SRong-En Fan break;
2784a1a9510SRong-En Fan }
2794a1a9510SRong-En Fan return code;
2804a1a9510SRong-En Fan }
2814a1a9510SRong-En Fan
282aae38d10SBaptiste Daroussin /* retrieve like winnstr, but using cchar_t*, rather than char*.
283aae38d10SBaptiste Daroussin *
284aae38d10SBaptiste Daroussin * X/Open Curses' closest equivalent, win_wchnstr(), is inconsistent with
285aae38d10SBaptiste Daroussin * winnstr(), since it returns OK rather than the number of items transferred.
2864a1a9510SRong-En Fan */
2874a1a9510SRong-En Fan static int
wide_winnstr(WINDOW * w,cchar_t * s,int n)288aae38d10SBaptiste Daroussin wide_winnstr(WINDOW *w, cchar_t *s, int n)
2894a1a9510SRong-En Fan {
2905ca44d1cSRong-En Fan int x;
2915ca44d1cSRong-En Fan
2924a1a9510SRong-En Fan win_wchnstr(w, s, n);
2935ca44d1cSRong-En Fan /*
2945ca44d1cSRong-En Fan * This function is used to extract the text only from the window.
2955ca44d1cSRong-En Fan * Strip attributes and color from the string so they will not be added
2965ca44d1cSRong-En Fan * back when copying the string to the window.
2975ca44d1cSRong-En Fan */
2985ca44d1cSRong-En Fan for (x = 0; x < n; ++x)
2995ca44d1cSRong-En Fan {
3005ca44d1cSRong-En Fan RemAttr(s[x], A_ATTRIBUTES);
3015ca44d1cSRong-En Fan SetPair(s[x], 0);
3025ca44d1cSRong-En Fan }
3034a1a9510SRong-En Fan return n;
3044a1a9510SRong-En Fan }
3054a1a9510SRong-En Fan
3064a1a9510SRong-En Fan /*
3074a1a9510SRong-En Fan * Returns the column of the base of the given cell.
3084a1a9510SRong-En Fan */
3094a1a9510SRong-En Fan static int
cell_base(WINDOW * win,int y,int x)3104a1a9510SRong-En Fan cell_base(WINDOW *win, int y, int x)
3114a1a9510SRong-En Fan {
3124a1a9510SRong-En Fan int result = x;
3134a1a9510SRong-En Fan
3144a1a9510SRong-En Fan while (LEGALYX(win, y, x))
3154a1a9510SRong-En Fan {
3164a1a9510SRong-En Fan cchar_t *data = &(win->_line[y].text[x]);
3174a1a9510SRong-En Fan
3184a1a9510SRong-En Fan if (isWidecBase(CHDEREF(data)) || !isWidecExt(CHDEREF(data)))
3194a1a9510SRong-En Fan {
3204a1a9510SRong-En Fan result = x;
3214a1a9510SRong-En Fan break;
3224a1a9510SRong-En Fan }
3234a1a9510SRong-En Fan --x;
3244a1a9510SRong-En Fan }
3254a1a9510SRong-En Fan return result;
3264a1a9510SRong-En Fan }
3274a1a9510SRong-En Fan
3284a1a9510SRong-En Fan /*
3294a1a9510SRong-En Fan * Returns the number of columns needed for the given cell in a window.
3304a1a9510SRong-En Fan */
3314a1a9510SRong-En Fan static int
cell_width(WINDOW * win,int y,int x)3324a1a9510SRong-En Fan cell_width(WINDOW *win, int y, int x)
3334a1a9510SRong-En Fan {
3344a1a9510SRong-En Fan int result = 1;
3354a1a9510SRong-En Fan
3364a1a9510SRong-En Fan if (LEGALYX(win, y, x))
3374a1a9510SRong-En Fan {
3384a1a9510SRong-En Fan cchar_t *data = &(win->_line[y].text[x]);
3394a1a9510SRong-En Fan
3404a1a9510SRong-En Fan if (isWidecExt(CHDEREF(data)))
3414a1a9510SRong-En Fan {
3424a1a9510SRong-En Fan /* recur, providing the number of columns to the next character */
3434a1a9510SRong-En Fan result = cell_width(win, y, x - 1);
3444a1a9510SRong-En Fan }
3454a1a9510SRong-En Fan else
3464a1a9510SRong-En Fan {
3474a1a9510SRong-En Fan result = wcwidth(CharOf(CHDEREF(data)));
3484a1a9510SRong-En Fan }
3494a1a9510SRong-En Fan }
3504a1a9510SRong-En Fan return result;
3514a1a9510SRong-En Fan }
3524a1a9510SRong-En Fan
3534a1a9510SRong-En Fan /*
3544a1a9510SRong-En Fan * There is no wide-character function such as wdel_wch(), so we must find
3554a1a9510SRong-En Fan * all of the cells that comprise a multi-column character and delete them
3564a1a9510SRong-En Fan * one-by-one.
3574a1a9510SRong-En Fan */
3584a1a9510SRong-En Fan static void
delete_char(FORM * form)3594a1a9510SRong-En Fan delete_char(FORM *form)
3604a1a9510SRong-En Fan {
3614a1a9510SRong-En Fan int cells = cell_width(form->w, form->currow, form->curcol);
3624a1a9510SRong-En Fan
3634a1a9510SRong-En Fan form->curcol = cell_base(form->w, form->currow, form->curcol);
3644a1a9510SRong-En Fan wmove(form->w, form->currow, form->curcol);
3654a1a9510SRong-En Fan while (cells-- > 0)
3664a1a9510SRong-En Fan {
3674a1a9510SRong-En Fan wdelch(form->w);
3684a1a9510SRong-En Fan }
3694a1a9510SRong-En Fan }
3704a1a9510SRong-En Fan #define DeleteChar(form) delete_char(form)
3714a1a9510SRong-En Fan #else
3724a1a9510SRong-En Fan #define DeleteChar(form) \
3734a1a9510SRong-En Fan wmove((form)->w, (form)->currow, (form)->curcol), \
3744a1a9510SRong-En Fan wdelch((form)->w)
3754a1a9510SRong-En Fan #endif
3764a1a9510SRong-En Fan
3770e3d5408SPeter Wemm /*---------------------------------------------------------------------------
3780e3d5408SPeter Wemm | Facility : libnform
3790e3d5408SPeter Wemm | Function : static char *Get_Start_Of_Data(char * buf, int blen)
3800e3d5408SPeter Wemm |
3810e3d5408SPeter Wemm | Description : Return pointer to first non-blank position in buffer.
3820e3d5408SPeter Wemm | If buffer is empty return pointer to buffer itself.
3830e3d5408SPeter Wemm |
3840e3d5408SPeter Wemm | Return Values : Pointer to first non-blank position in buffer
3850e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
3864a1a9510SRong-En Fan NCURSES_INLINE static FIELD_CELL *
Get_Start_Of_Data(FIELD_CELL * buf,int blen)3874a1a9510SRong-En Fan Get_Start_Of_Data(FIELD_CELL *buf, int blen)
3880e3d5408SPeter Wemm {
3894a1a9510SRong-En Fan FIELD_CELL *p = buf;
3904a1a9510SRong-En Fan FIELD_CELL *end = &buf[blen];
3910e3d5408SPeter Wemm
3920e3d5408SPeter Wemm assert(buf && blen >= 0);
3934a1a9510SRong-En Fan while ((p < end) && ISBLANK(*p))
3940e3d5408SPeter Wemm p++;
3950e3d5408SPeter Wemm return ((p == end) ? buf : p);
3960e3d5408SPeter Wemm }
3970e3d5408SPeter Wemm
3980e3d5408SPeter Wemm /*---------------------------------------------------------------------------
3990e3d5408SPeter Wemm | Facility : libnform
4000e3d5408SPeter Wemm | Function : static char *After_End_Of_Data(char * buf, int blen)
4010e3d5408SPeter Wemm |
4020e3d5408SPeter Wemm | Description : Return pointer after last non-blank position in buffer.
4030e3d5408SPeter Wemm | If buffer is empty, return pointer to buffer itself.
4040e3d5408SPeter Wemm |
4050e3d5408SPeter Wemm | Return Values : Pointer to position after last non-blank position in
4060e3d5408SPeter Wemm | buffer.
4070e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
4084a1a9510SRong-En Fan NCURSES_INLINE static FIELD_CELL *
After_End_Of_Data(FIELD_CELL * buf,int blen)4094a1a9510SRong-En Fan After_End_Of_Data(FIELD_CELL *buf, int blen)
4100e3d5408SPeter Wemm {
4114a1a9510SRong-En Fan FIELD_CELL *p = &buf[blen];
4120e3d5408SPeter Wemm
4130e3d5408SPeter Wemm assert(buf && blen >= 0);
4144a1a9510SRong-En Fan while ((p > buf) && ISBLANK(p[-1]))
4150e3d5408SPeter Wemm p--;
4160e3d5408SPeter Wemm return (p);
4170e3d5408SPeter Wemm }
4180e3d5408SPeter Wemm
4190e3d5408SPeter Wemm /*---------------------------------------------------------------------------
4200e3d5408SPeter Wemm | Facility : libnform
4210e3d5408SPeter Wemm | Function : static char *Get_First_Whitespace_Character(
4220e3d5408SPeter Wemm | char * buf, int blen)
4230e3d5408SPeter Wemm |
4240e3d5408SPeter Wemm | Description : Position to the first whitespace character.
4250e3d5408SPeter Wemm |
4260e3d5408SPeter Wemm | Return Values : Pointer to first whitespace character in buffer.
4270e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
4284a1a9510SRong-En Fan NCURSES_INLINE static FIELD_CELL *
Get_First_Whitespace_Character(FIELD_CELL * buf,int blen)4294a1a9510SRong-En Fan Get_First_Whitespace_Character(FIELD_CELL *buf, int blen)
4300e3d5408SPeter Wemm {
4314a1a9510SRong-En Fan FIELD_CELL *p = buf;
4324a1a9510SRong-En Fan FIELD_CELL *end = &p[blen];
4330e3d5408SPeter Wemm
4340e3d5408SPeter Wemm assert(buf && blen >= 0);
4354a1a9510SRong-En Fan while ((p < end) && !ISBLANK(*p))
4360e3d5408SPeter Wemm p++;
4370e3d5408SPeter Wemm return ((p == end) ? buf : p);
4380e3d5408SPeter Wemm }
4390e3d5408SPeter Wemm
4400e3d5408SPeter Wemm /*---------------------------------------------------------------------------
4410e3d5408SPeter Wemm | Facility : libnform
4420e3d5408SPeter Wemm | Function : static char *After_Last_Whitespace_Character(
4430e3d5408SPeter Wemm | char * buf, int blen)
4440e3d5408SPeter Wemm |
4450e3d5408SPeter Wemm | Description : Get the position after the last whitespace character.
4460e3d5408SPeter Wemm |
4470e3d5408SPeter Wemm | Return Values : Pointer to position after last whitespace character in
4480e3d5408SPeter Wemm | buffer.
4490e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
4504a1a9510SRong-En Fan NCURSES_INLINE static FIELD_CELL *
After_Last_Whitespace_Character(FIELD_CELL * buf,int blen)4514a1a9510SRong-En Fan After_Last_Whitespace_Character(FIELD_CELL *buf, int blen)
4520e3d5408SPeter Wemm {
4534a1a9510SRong-En Fan FIELD_CELL *p = &buf[blen];
4540e3d5408SPeter Wemm
4550e3d5408SPeter Wemm assert(buf && blen >= 0);
4564a1a9510SRong-En Fan while ((p > buf) && !ISBLANK(p[-1]))
4570e3d5408SPeter Wemm p--;
4580e3d5408SPeter Wemm return (p);
4590e3d5408SPeter Wemm }
4600e3d5408SPeter Wemm
4610e3d5408SPeter Wemm /* Set this to 1 to use the div_t version. This is a good idea if your
4620e3d5408SPeter Wemm compiler has an intrinsic div() support. Unfortunately GNU-C has it
4630e3d5408SPeter Wemm not yet.
4640e3d5408SPeter Wemm N.B.: This only works if form->curcol follows immediately form->currow
4650e3d5408SPeter Wemm and both are of type int.
4660e3d5408SPeter Wemm */
4670e3d5408SPeter Wemm #define USE_DIV_T (0)
4680e3d5408SPeter Wemm
4690e3d5408SPeter Wemm /*---------------------------------------------------------------------------
4700e3d5408SPeter Wemm | Facility : libnform
4710e3d5408SPeter Wemm | Function : static void Adjust_Cursor_Position(
4720e3d5408SPeter Wemm | FORM * form, const char * pos)
4730e3d5408SPeter Wemm |
4740e3d5408SPeter Wemm | Description : Set current row and column of the form to values
4750e3d5408SPeter Wemm | corresponding to the buffer position.
4760e3d5408SPeter Wemm |
4770e3d5408SPeter Wemm | Return Values : -
4780e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
4794a1a9510SRong-En Fan NCURSES_INLINE static void
Adjust_Cursor_Position(FORM * form,const FIELD_CELL * pos)4804a1a9510SRong-En Fan Adjust_Cursor_Position(FORM *form, const FIELD_CELL *pos)
4810e3d5408SPeter Wemm {
4820e3d5408SPeter Wemm FIELD *field;
4830e3d5408SPeter Wemm int idx;
4840e3d5408SPeter Wemm
4850e3d5408SPeter Wemm field = form->current;
4860e3d5408SPeter Wemm assert(pos >= field->buf && field->dcols > 0);
4870e3d5408SPeter Wemm idx = (int)(pos - field->buf);
4880e3d5408SPeter Wemm #if USE_DIV_T
4890e3d5408SPeter Wemm *((div_t *) & (form->currow)) = div(idx, field->dcols);
4900e3d5408SPeter Wemm #else
4910e3d5408SPeter Wemm form->currow = idx / field->dcols;
4920e3d5408SPeter Wemm form->curcol = idx - field->cols * form->currow;
4930e3d5408SPeter Wemm #endif
4940e3d5408SPeter Wemm if (field->drows < form->currow)
4950e3d5408SPeter Wemm form->currow = 0;
4960e3d5408SPeter Wemm }
4970e3d5408SPeter Wemm
4980e3d5408SPeter Wemm /*---------------------------------------------------------------------------
4990e3d5408SPeter Wemm | Facility : libnform
5000e3d5408SPeter Wemm | Function : static void Buffer_To_Window(
5010e3d5408SPeter Wemm | const FIELD * field,
5020e3d5408SPeter Wemm | WINDOW * win)
5030e3d5408SPeter Wemm |
5044a1a9510SRong-En Fan | Description : Copy the buffer to the window. If it is a multi-line
5050e3d5408SPeter Wemm | field, the buffer is split to the lines of the
5060e3d5408SPeter Wemm | window without any editing.
5070e3d5408SPeter Wemm |
5080e3d5408SPeter Wemm | Return Values : -
5090e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
5104a1a9510SRong-En Fan static void
Buffer_To_Window(const FIELD * field,WINDOW * win)5114a1a9510SRong-En Fan Buffer_To_Window(const FIELD *field, WINDOW *win)
5120e3d5408SPeter Wemm {
5130e3d5408SPeter Wemm int width, height;
5144a1a9510SRong-En Fan int y, x;
5150e3d5408SPeter Wemm int row;
5164a1a9510SRong-En Fan FIELD_CELL *pBuffer;
5170e3d5408SPeter Wemm
5180e3d5408SPeter Wemm assert(win && field);
5190e3d5408SPeter Wemm
5204a1a9510SRong-En Fan getyx(win, y, x);
5210e3d5408SPeter Wemm width = getmaxx(win);
5220e3d5408SPeter Wemm height = getmaxy(win);
5230e3d5408SPeter Wemm
5240e3d5408SPeter Wemm for (row = 0, pBuffer = field->buf;
5250e3d5408SPeter Wemm row < height;
5260e3d5408SPeter Wemm row++, pBuffer += width)
5270e3d5408SPeter Wemm {
528*21817992SBaptiste Daroussin int len;
529*21817992SBaptiste Daroussin
5300e3d5408SPeter Wemm if ((len = (int)(After_End_Of_Data(pBuffer, width) - pBuffer)) > 0)
5310e3d5408SPeter Wemm {
5320e3d5408SPeter Wemm wmove(win, row, 0);
5334a1a9510SRong-En Fan myADDNSTR(win, pBuffer, len);
5340e3d5408SPeter Wemm }
5350e3d5408SPeter Wemm }
5364a1a9510SRong-En Fan wmove(win, y, x);
5370e3d5408SPeter Wemm }
5380e3d5408SPeter Wemm
5390e3d5408SPeter Wemm /*---------------------------------------------------------------------------
5400e3d5408SPeter Wemm | Facility : libnform
54106bfebdeSXin LI | Function : void _nc_get_fieldbuffer(
5420e3d5408SPeter Wemm | WINDOW * win,
54306bfebdeSXin LI | FIELD * field,
54406bfebdeSXin LI | FIELD_CELL * buf)
5450e3d5408SPeter Wemm |
5460e3d5408SPeter Wemm | Description : Copy the content of the window into the buffer.
5470e3d5408SPeter Wemm | The multiple lines of a window are simply
5480e3d5408SPeter Wemm | concatenated into the buffer. Pad characters in
5490e3d5408SPeter Wemm | the window will be replaced by blanks in the buffer.
5500e3d5408SPeter Wemm |
5510e3d5408SPeter Wemm | Return Values : -
5520e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
5537a656419SBaptiste Daroussin FORM_EXPORT(void)
_nc_get_fieldbuffer(FORM * form,FIELD * field,FIELD_CELL * buf)55406bfebdeSXin LI _nc_get_fieldbuffer(FORM *form, FIELD *field, FIELD_CELL *buf)
5550e3d5408SPeter Wemm {
5560e3d5408SPeter Wemm int pad;
5570e3d5408SPeter Wemm int len = 0;
5584a1a9510SRong-En Fan FIELD_CELL *p;
5590e3d5408SPeter Wemm int row, height;
56006bfebdeSXin LI WINDOW *win;
5610e3d5408SPeter Wemm
56206bfebdeSXin LI assert(form && field && buf);
56306bfebdeSXin LI
56406bfebdeSXin LI win = form->w;
56506bfebdeSXin LI assert(win);
5660e3d5408SPeter Wemm
5670e3d5408SPeter Wemm pad = field->pad;
56806bfebdeSXin LI p = buf;
5690e3d5408SPeter Wemm height = getmaxy(win);
5700e3d5408SPeter Wemm
5710e3d5408SPeter Wemm for (row = 0; (row < height) && (row < field->drows); row++)
5720e3d5408SPeter Wemm {
5730e3d5408SPeter Wemm wmove(win, row, 0);
5744a1a9510SRong-En Fan len += myINNSTR(win, p + len, field->dcols);
5750e3d5408SPeter Wemm }
5764a1a9510SRong-En Fan p[len] = myZEROS;
5770e3d5408SPeter Wemm
5780e3d5408SPeter Wemm /* replace visual padding character by blanks in buffer */
5790e3d5408SPeter Wemm if (pad != C_BLANK)
5800e3d5408SPeter Wemm {
5810e3d5408SPeter Wemm int i;
5824a1a9510SRong-En Fan
5830e3d5408SPeter Wemm for (i = 0; i < len; i++, p++)
5840e3d5408SPeter Wemm {
5854a1a9510SRong-En Fan if ((unsigned long)CharOf(*p) == ChCharOf(pad)
5864a1a9510SRong-En Fan #if USE_WIDEC_SUPPORT
5874a1a9510SRong-En Fan && p->chars[1] == 0
5884a1a9510SRong-En Fan #endif
5894a1a9510SRong-En Fan )
5904a1a9510SRong-En Fan *p = myBLANK;
5910e3d5408SPeter Wemm }
5920e3d5408SPeter Wemm }
5930e3d5408SPeter Wemm }
5940e3d5408SPeter Wemm
5950e3d5408SPeter Wemm /*---------------------------------------------------------------------------
5960e3d5408SPeter Wemm | Facility : libnform
59706bfebdeSXin LI | Function : static void Window_To_Buffer(
59806bfebdeSXin LI | FORM * form,
59906bfebdeSXin LI | FIELD * field)
60006bfebdeSXin LI |
60106bfebdeSXin LI | Description : Copy the content of the window into the buffer.
60206bfebdeSXin LI | The multiple lines of a window are simply
60306bfebdeSXin LI | concatenated into the buffer. Pad characters in
60406bfebdeSXin LI | the window will be replaced by blanks in the buffer.
60506bfebdeSXin LI |
60606bfebdeSXin LI | Return Values : -
60706bfebdeSXin LI +--------------------------------------------------------------------------*/
60806bfebdeSXin LI static void
Window_To_Buffer(FORM * form,FIELD * field)60906bfebdeSXin LI Window_To_Buffer(FORM *form, FIELD *field)
61006bfebdeSXin LI {
61106bfebdeSXin LI _nc_get_fieldbuffer(form, field, field->buf);
61206bfebdeSXin LI }
61306bfebdeSXin LI
61406bfebdeSXin LI /*---------------------------------------------------------------------------
61506bfebdeSXin LI | Facility : libnform
6160e3d5408SPeter Wemm | Function : static void Synchronize_Buffer(FORM * form)
6170e3d5408SPeter Wemm |
6180e3d5408SPeter Wemm | Description : If there was a change, copy the content of the
6190e3d5408SPeter Wemm | window into the buffer, so the buffer is synchronized
6200e3d5408SPeter Wemm | with the windows content. We have to indicate that the
6210e3d5408SPeter Wemm | buffer needs validation due to the change.
6220e3d5408SPeter Wemm |
6230e3d5408SPeter Wemm | Return Values : -
6240e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
6254a1a9510SRong-En Fan NCURSES_INLINE static void
Synchronize_Buffer(FORM * form)6264a1a9510SRong-En Fan Synchronize_Buffer(FORM *form)
6270e3d5408SPeter Wemm {
6280e3d5408SPeter Wemm if (form->status & _WINDOW_MODIFIED)
6290e3d5408SPeter Wemm {
63073f0a83dSXin LI ClrStatus(form, _WINDOW_MODIFIED);
63173f0a83dSXin LI SetStatus(form, _FCHECK_REQUIRED);
63206bfebdeSXin LI Window_To_Buffer(form, form->current);
6330e3d5408SPeter Wemm wmove(form->w, form->currow, form->curcol);
6340e3d5408SPeter Wemm }
6350e3d5408SPeter Wemm }
6360e3d5408SPeter Wemm
6370e3d5408SPeter Wemm /*---------------------------------------------------------------------------
6380e3d5408SPeter Wemm | Facility : libnform
6390e3d5408SPeter Wemm | Function : static bool Field_Grown( FIELD *field, int amount)
6400e3d5408SPeter Wemm |
6410e3d5408SPeter Wemm | Description : This function is called for growable dynamic fields
6420e3d5408SPeter Wemm | only. It has to increase the buffers and to allocate
6430e3d5408SPeter Wemm | a new window for this field.
6440e3d5408SPeter Wemm | This function has the side effect to set a new
6450e3d5408SPeter Wemm | field-buffer pointer, the dcols and drows values
6460e3d5408SPeter Wemm | as well as a new current Window for the field.
6470e3d5408SPeter Wemm |
6480e3d5408SPeter Wemm | Return Values : TRUE - field successfully increased
6490e3d5408SPeter Wemm | FALSE - there was some error
6500e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
6514a1a9510SRong-En Fan static bool
Field_Grown(FIELD * field,int amount)6524a1a9510SRong-En Fan Field_Grown(FIELD *field, int amount)
6530e3d5408SPeter Wemm {
6540e3d5408SPeter Wemm bool result = FALSE;
6550e3d5408SPeter Wemm
6560e3d5408SPeter Wemm if (field && Growable(field))
6570e3d5408SPeter Wemm {
6580e3d5408SPeter Wemm bool single_line_field = Single_Line_Field(field);
6590e3d5408SPeter Wemm int old_buflen = Buffer_Length(field);
6600e3d5408SPeter Wemm int new_buflen;
6610e3d5408SPeter Wemm int old_dcols = field->dcols;
6620e3d5408SPeter Wemm int old_drows = field->drows;
6634a1a9510SRong-En Fan FIELD_CELL *oldbuf = field->buf;
6644a1a9510SRong-En Fan FIELD_CELL *newbuf;
6650e3d5408SPeter Wemm
6660e3d5408SPeter Wemm int growth;
6670e3d5408SPeter Wemm FORM *form = field->form;
6680e3d5408SPeter Wemm bool need_visual_update = ((form != (FORM *)0) &&
6690e3d5408SPeter Wemm (form->status & _POSTED) &&
6700e3d5408SPeter Wemm (form->current == field));
6710e3d5408SPeter Wemm
6720e3d5408SPeter Wemm if (need_visual_update)
6730e3d5408SPeter Wemm Synchronize_Buffer(form);
6740e3d5408SPeter Wemm
6750e3d5408SPeter Wemm if (single_line_field)
6760e3d5408SPeter Wemm {
6770e3d5408SPeter Wemm growth = field->cols * amount;
6780e3d5408SPeter Wemm if (field->maxgrow)
6790e3d5408SPeter Wemm growth = Minimum(field->maxgrow - field->dcols, growth);
6800e3d5408SPeter Wemm field->dcols += growth;
6810e3d5408SPeter Wemm if (field->dcols == field->maxgrow)
68273f0a83dSXin LI ClrStatus(field, _MAY_GROW);
6830e3d5408SPeter Wemm }
6840e3d5408SPeter Wemm else
6850e3d5408SPeter Wemm {
6860e3d5408SPeter Wemm growth = (field->rows + field->nrow) * amount;
6870e3d5408SPeter Wemm if (field->maxgrow)
6880e3d5408SPeter Wemm growth = Minimum(field->maxgrow - field->drows, growth);
6890e3d5408SPeter Wemm field->drows += growth;
6900e3d5408SPeter Wemm if (field->drows == field->maxgrow)
69173f0a83dSXin LI ClrStatus(field, _MAY_GROW);
6920e3d5408SPeter Wemm }
6930e3d5408SPeter Wemm /* drows, dcols changed, so we get really the new buffer length */
6940e3d5408SPeter Wemm new_buflen = Buffer_Length(field);
6954a1a9510SRong-En Fan newbuf = (FIELD_CELL *)malloc(Total_Buffer_Size(field));
6960e3d5408SPeter Wemm if (!newbuf)
6974a1a9510SRong-En Fan {
6984a1a9510SRong-En Fan /* restore to previous state */
6990e3d5408SPeter Wemm field->dcols = old_dcols;
7000e3d5408SPeter Wemm field->drows = old_drows;
7010e3d5408SPeter Wemm if ((single_line_field && (field->dcols != field->maxgrow)) ||
7020e3d5408SPeter Wemm (!single_line_field && (field->drows != field->maxgrow)))
70373f0a83dSXin LI SetStatus(field, _MAY_GROW);
7040e3d5408SPeter Wemm }
7050e3d5408SPeter Wemm else
7064a1a9510SRong-En Fan {
7074a1a9510SRong-En Fan /* Copy all the buffers. This is the reason why we can't just use
7084a1a9510SRong-En Fan * realloc().
7090e3d5408SPeter Wemm */
7104a1a9510SRong-En Fan int i, j;
7114a1a9510SRong-En Fan
7124a1a9510SRong-En Fan result = TRUE; /* allow sharing of recovery on failure */
7130e3d5408SPeter Wemm
71406bfebdeSXin LI T((T_CREATE("fieldcell %p"), (void *)newbuf));
7150e3d5408SPeter Wemm field->buf = newbuf;
7160e3d5408SPeter Wemm for (i = 0; i <= field->nbuf; i++)
7170e3d5408SPeter Wemm {
718*21817992SBaptiste Daroussin FIELD_CELL *new_bp = Address_Of_Nth_Buffer(field, i);
719*21817992SBaptiste Daroussin FIELD_CELL *old_bp = oldbuf + i * (1 + old_buflen);
720*21817992SBaptiste Daroussin
7214a1a9510SRong-En Fan for (j = 0; j < old_buflen; ++j)
7224a1a9510SRong-En Fan new_bp[j] = old_bp[j];
7234a1a9510SRong-En Fan while (j < new_buflen)
7244a1a9510SRong-En Fan new_bp[j++] = myBLANK;
7254a1a9510SRong-En Fan new_bp[new_buflen] = myZEROS;
7260e3d5408SPeter Wemm }
7270e3d5408SPeter Wemm
728d8977eafSRong-En Fan #if USE_WIDEC_SUPPORT && NCURSES_EXT_FUNCS
7294a1a9510SRong-En Fan if (wresize(field->working, 1, Buffer_Length(field) + 1) == ERR)
7304a1a9510SRong-En Fan result = FALSE;
7314a1a9510SRong-En Fan #endif
7324a1a9510SRong-En Fan
7334a1a9510SRong-En Fan if (need_visual_update && result)
7340e3d5408SPeter Wemm {
7350e3d5408SPeter Wemm WINDOW *new_window = newpad(field->drows, field->dcols);
7364a1a9510SRong-En Fan
7374a1a9510SRong-En Fan if (new_window != 0)
7384a1a9510SRong-En Fan {
7390e3d5408SPeter Wemm assert(form != (FORM *)0);
7407a69bbfbSPeter Wemm if (form->w)
7410e3d5408SPeter Wemm delwin(form->w);
7420e3d5408SPeter Wemm form->w = new_window;
7430e3d5408SPeter Wemm Set_Field_Window_Attributes(field, form->w);
7440e3d5408SPeter Wemm werase(form->w);
7450e3d5408SPeter Wemm Buffer_To_Window(field, form->w);
7460e3d5408SPeter Wemm untouchwin(form->w);
7470e3d5408SPeter Wemm wmove(form->w, form->currow, form->curcol);
7480e3d5408SPeter Wemm }
7494a1a9510SRong-En Fan else
7504a1a9510SRong-En Fan result = FALSE;
7514a1a9510SRong-En Fan }
7520e3d5408SPeter Wemm
7534a1a9510SRong-En Fan if (result)
7544a1a9510SRong-En Fan {
7550e3d5408SPeter Wemm free(oldbuf);
7560e3d5408SPeter Wemm /* reflect changes in linked fields */
7570e3d5408SPeter Wemm if (field != field->link)
7580e3d5408SPeter Wemm {
7590e3d5408SPeter Wemm FIELD *linked_field;
7604a1a9510SRong-En Fan
7610e3d5408SPeter Wemm for (linked_field = field->link;
7620e3d5408SPeter Wemm linked_field != field;
7630e3d5408SPeter Wemm linked_field = linked_field->link)
7640e3d5408SPeter Wemm {
7650e3d5408SPeter Wemm linked_field->buf = field->buf;
7660e3d5408SPeter Wemm linked_field->drows = field->drows;
7670e3d5408SPeter Wemm linked_field->dcols = field->dcols;
7680e3d5408SPeter Wemm }
7690e3d5408SPeter Wemm }
7704a1a9510SRong-En Fan }
7714a1a9510SRong-En Fan else
7724a1a9510SRong-En Fan {
7734a1a9510SRong-En Fan /* restore old state */
7744a1a9510SRong-En Fan field->dcols = old_dcols;
7754a1a9510SRong-En Fan field->drows = old_drows;
7764a1a9510SRong-En Fan field->buf = oldbuf;
7774a1a9510SRong-En Fan if ((single_line_field &&
7784a1a9510SRong-En Fan (field->dcols != field->maxgrow)) ||
7794a1a9510SRong-En Fan (!single_line_field &&
7804a1a9510SRong-En Fan (field->drows != field->maxgrow)))
78173f0a83dSXin LI SetStatus(field, _MAY_GROW);
7824a1a9510SRong-En Fan free(newbuf);
7834a1a9510SRong-En Fan }
7840e3d5408SPeter Wemm }
7850e3d5408SPeter Wemm }
7860e3d5408SPeter Wemm return (result);
7870e3d5408SPeter Wemm }
7880e3d5408SPeter Wemm
7895ca44d1cSRong-En Fan #ifdef NCURSES_MOUSE_VERSION
7905ca44d1cSRong-En Fan /*---------------------------------------------------------------------------
7915ca44d1cSRong-En Fan | Facility : libnform
7925ca44d1cSRong-En Fan | Function : int Field_encloses(FIELD *field, int ry, int rx)
7935ca44d1cSRong-En Fan |
7945ca44d1cSRong-En Fan | Description : Check if the given coordinates lie within the given field.
7955ca44d1cSRong-En Fan |
7965ca44d1cSRong-En Fan | Return Values : E_OK - success
7975ca44d1cSRong-En Fan | E_BAD_ARGUMENT - invalid form pointer
7985ca44d1cSRong-En Fan | E_SYSTEM_ERROR - form has no current field or
7995ca44d1cSRong-En Fan | field-window
8005ca44d1cSRong-En Fan +--------------------------------------------------------------------------*/
8015ca44d1cSRong-En Fan static int
Field_encloses(FIELD * field,int ry,int rx)8025ca44d1cSRong-En Fan Field_encloses(FIELD *field, int ry, int rx)
8035ca44d1cSRong-En Fan {
80406bfebdeSXin LI T((T_CALLED("Field_encloses(%p)"), (void *)field));
8055ca44d1cSRong-En Fan if (field != 0
8065ca44d1cSRong-En Fan && field->frow <= ry
8075ca44d1cSRong-En Fan && (field->frow + field->rows) > ry
8085ca44d1cSRong-En Fan && field->fcol <= rx
8095ca44d1cSRong-En Fan && (field->fcol + field->cols) > rx)
8105ca44d1cSRong-En Fan {
8115ca44d1cSRong-En Fan RETURN(E_OK);
8125ca44d1cSRong-En Fan }
8135ca44d1cSRong-En Fan RETURN(E_INVALID_FIELD);
8145ca44d1cSRong-En Fan }
8155ca44d1cSRong-En Fan #endif
8165ca44d1cSRong-En Fan
8170e3d5408SPeter Wemm /*---------------------------------------------------------------------------
8180e3d5408SPeter Wemm | Facility : libnform
8190e3d5408SPeter Wemm | Function : int _nc_Position_Form_Cursor(FORM * form)
8200e3d5408SPeter Wemm |
8210e3d5408SPeter Wemm | Description : Position the cursor in the window for the current
8220e3d5408SPeter Wemm | field to be in sync. with the currow and curcol
8230e3d5408SPeter Wemm | values.
8240e3d5408SPeter Wemm |
8250e3d5408SPeter Wemm | Return Values : E_OK - success
8260e3d5408SPeter Wemm | E_BAD_ARGUMENT - invalid form pointer
8270e3d5408SPeter Wemm | E_SYSTEM_ERROR - form has no current field or
8280e3d5408SPeter Wemm | field-window
8290e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
8307a656419SBaptiste Daroussin FORM_EXPORT(int)
_nc_Position_Form_Cursor(FORM * form)8310e3d5408SPeter Wemm _nc_Position_Form_Cursor(FORM *form)
8320e3d5408SPeter Wemm {
8330e3d5408SPeter Wemm FIELD *field;
8340e3d5408SPeter Wemm WINDOW *formwin;
8350e3d5408SPeter Wemm
8360e3d5408SPeter Wemm if (!form)
8370e3d5408SPeter Wemm return (E_BAD_ARGUMENT);
8380e3d5408SPeter Wemm
8390e3d5408SPeter Wemm if (!form->w || !form->current)
8400e3d5408SPeter Wemm return (E_SYSTEM_ERROR);
8410e3d5408SPeter Wemm
8420e3d5408SPeter Wemm field = form->current;
8430e3d5408SPeter Wemm formwin = Get_Form_Window(form);
8440e3d5408SPeter Wemm
8450e3d5408SPeter Wemm wmove(form->w, form->currow, form->curcol);
8460e3d5408SPeter Wemm if (Has_Invisible_Parts(field))
8470e3d5408SPeter Wemm {
8480e3d5408SPeter Wemm /* in this case fieldwin isn't derived from formwin, so we have
8490e3d5408SPeter Wemm to move the cursor in formwin by hand... */
8500e3d5408SPeter Wemm wmove(formwin,
8510e3d5408SPeter Wemm field->frow + form->currow - form->toprow,
8520e3d5408SPeter Wemm field->fcol + form->curcol - form->begincol);
8530e3d5408SPeter Wemm wcursyncup(formwin);
8540e3d5408SPeter Wemm }
8550e3d5408SPeter Wemm else
8560e3d5408SPeter Wemm wcursyncup(form->w);
8570e3d5408SPeter Wemm return (E_OK);
8580e3d5408SPeter Wemm }
8590e3d5408SPeter Wemm
8600e3d5408SPeter Wemm /*---------------------------------------------------------------------------
8610e3d5408SPeter Wemm | Facility : libnform
8620e3d5408SPeter Wemm | Function : int _nc_Refresh_Current_Field(FORM * form)
8630e3d5408SPeter Wemm |
8647a656419SBaptiste Daroussin | Description : Propagate the changes in the field's window to the
8650e3d5408SPeter Wemm | window of the form.
8660e3d5408SPeter Wemm |
8670e3d5408SPeter Wemm | Return Values : E_OK - on success
8680e3d5408SPeter Wemm | E_BAD_ARGUMENT - invalid form pointer
8690e3d5408SPeter Wemm | E_SYSTEM_ERROR - general error
8700e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
871aae38d10SBaptiste Daroussin static bool move_after_insert = TRUE;
8727a656419SBaptiste Daroussin FORM_EXPORT(int)
_nc_Refresh_Current_Field(FORM * form)8730e3d5408SPeter Wemm _nc_Refresh_Current_Field(FORM *form)
8740e3d5408SPeter Wemm {
8750e3d5408SPeter Wemm WINDOW *formwin;
8760e3d5408SPeter Wemm FIELD *field;
877aae38d10SBaptiste Daroussin bool is_public;
8780e3d5408SPeter Wemm
87906bfebdeSXin LI T((T_CALLED("_nc_Refresh_Current_Field(%p)"), (void *)form));
8804a1a9510SRong-En Fan
8810e3d5408SPeter Wemm if (!form)
8820e3d5408SPeter Wemm RETURN(E_BAD_ARGUMENT);
8830e3d5408SPeter Wemm
8840e3d5408SPeter Wemm if (!form->w || !form->current)
8850e3d5408SPeter Wemm RETURN(E_SYSTEM_ERROR);
8860e3d5408SPeter Wemm
8870e3d5408SPeter Wemm field = form->current;
8880e3d5408SPeter Wemm formwin = Get_Form_Window(form);
8890e3d5408SPeter Wemm
890aae38d10SBaptiste Daroussin is_public = Field_Has_Option(field, O_PUBLIC);
891aae38d10SBaptiste Daroussin
8920e3d5408SPeter Wemm if (Is_Scroll_Field(field))
8930e3d5408SPeter Wemm {
8940e3d5408SPeter Wemm /* Again, in this case the fieldwin isn't derived from formwin,
8950e3d5408SPeter Wemm so we have to perform a copy operation. */
8960e3d5408SPeter Wemm if (Single_Line_Field(field))
8974a1a9510SRong-En Fan {
8984a1a9510SRong-En Fan /* horizontal scrolling */
8990e3d5408SPeter Wemm if (form->curcol < form->begincol)
9000e3d5408SPeter Wemm form->begincol = form->curcol;
9010e3d5408SPeter Wemm else
9020e3d5408SPeter Wemm {
9030e3d5408SPeter Wemm if (form->curcol >= (form->begincol + field->cols))
904aae38d10SBaptiste Daroussin form->begincol = form->curcol - field->cols
905aae38d10SBaptiste Daroussin + (move_after_insert ? 1 : 0);
9060e3d5408SPeter Wemm }
907aae38d10SBaptiste Daroussin if (is_public)
9080e3d5408SPeter Wemm copywin(form->w,
9090e3d5408SPeter Wemm formwin,
9100e3d5408SPeter Wemm 0,
9110e3d5408SPeter Wemm form->begincol,
9120e3d5408SPeter Wemm field->frow,
9130e3d5408SPeter Wemm field->fcol,
9140e3d5408SPeter Wemm field->frow,
9150e3d5408SPeter Wemm field->cols + field->fcol - 1,
9160e3d5408SPeter Wemm 0);
9170e3d5408SPeter Wemm }
9180e3d5408SPeter Wemm else
9194a1a9510SRong-En Fan {
9204a1a9510SRong-En Fan /* A multi-line, i.e. vertical scrolling field */
921*21817992SBaptiste Daroussin int first_modified_row, first_unmodified_row;
9220e3d5408SPeter Wemm
9230e3d5408SPeter Wemm if (field->drows > field->rows)
9240e3d5408SPeter Wemm {
925*21817992SBaptiste Daroussin int row_after_bottom = form->toprow + field->rows;
926*21817992SBaptiste Daroussin
9270e3d5408SPeter Wemm if (form->currow < form->toprow)
9280e3d5408SPeter Wemm {
9290e3d5408SPeter Wemm form->toprow = form->currow;
93073f0a83dSXin LI SetStatus(field, _NEWTOP);
9310e3d5408SPeter Wemm }
9320e3d5408SPeter Wemm if (form->currow >= row_after_bottom)
9330e3d5408SPeter Wemm {
9340e3d5408SPeter Wemm form->toprow = form->currow - field->rows + 1;
93573f0a83dSXin LI SetStatus(field, _NEWTOP);
9360e3d5408SPeter Wemm }
9370e3d5408SPeter Wemm if (field->status & _NEWTOP)
9384a1a9510SRong-En Fan {
9394a1a9510SRong-En Fan /* means we have to copy whole range */
9400e3d5408SPeter Wemm first_modified_row = form->toprow;
9410e3d5408SPeter Wemm first_unmodified_row = first_modified_row + field->rows;
94273f0a83dSXin LI ClrStatus(field, _NEWTOP);
9430e3d5408SPeter Wemm }
9440e3d5408SPeter Wemm else
9454a1a9510SRong-En Fan {
9464a1a9510SRong-En Fan /* we try to optimize : finding the range of touched
9470e3d5408SPeter Wemm lines */
9480e3d5408SPeter Wemm first_modified_row = form->toprow;
9490e3d5408SPeter Wemm while (first_modified_row < row_after_bottom)
9500e3d5408SPeter Wemm {
9510e3d5408SPeter Wemm if (is_linetouched(form->w, first_modified_row))
9520e3d5408SPeter Wemm break;
9530e3d5408SPeter Wemm first_modified_row++;
9540e3d5408SPeter Wemm }
9550e3d5408SPeter Wemm first_unmodified_row = first_modified_row;
9560e3d5408SPeter Wemm while (first_unmodified_row < row_after_bottom)
9570e3d5408SPeter Wemm {
9580e3d5408SPeter Wemm if (!is_linetouched(form->w, first_unmodified_row))
9590e3d5408SPeter Wemm break;
9600e3d5408SPeter Wemm first_unmodified_row++;
9610e3d5408SPeter Wemm }
9620e3d5408SPeter Wemm }
9630e3d5408SPeter Wemm }
9640e3d5408SPeter Wemm else
9650e3d5408SPeter Wemm {
9660e3d5408SPeter Wemm first_modified_row = form->toprow;
9670e3d5408SPeter Wemm first_unmodified_row = first_modified_row + field->rows;
9680e3d5408SPeter Wemm }
969aae38d10SBaptiste Daroussin if (first_unmodified_row != first_modified_row && is_public)
9700e3d5408SPeter Wemm copywin(form->w,
9710e3d5408SPeter Wemm formwin,
9720e3d5408SPeter Wemm first_modified_row,
9730e3d5408SPeter Wemm 0,
9740e3d5408SPeter Wemm field->frow + first_modified_row - form->toprow,
9750e3d5408SPeter Wemm field->fcol,
9760e3d5408SPeter Wemm field->frow + first_unmodified_row - form->toprow - 1,
9770e3d5408SPeter Wemm field->cols + field->fcol - 1,
9780e3d5408SPeter Wemm 0);
9790e3d5408SPeter Wemm }
980aae38d10SBaptiste Daroussin if (is_public)
9810e3d5408SPeter Wemm wsyncup(formwin);
9820e3d5408SPeter Wemm }
9830e3d5408SPeter Wemm else
9844a1a9510SRong-En Fan {
9854a1a9510SRong-En Fan /* if the field-window is simply a derived window, i.e. contains no
9864a1a9510SRong-En Fan * invisible parts, the whole thing is trivial
9870e3d5408SPeter Wemm */
988aae38d10SBaptiste Daroussin if (is_public)
9890e3d5408SPeter Wemm wsyncup(form->w);
9900e3d5408SPeter Wemm }
9910e3d5408SPeter Wemm untouchwin(form->w);
9924a1a9510SRong-En Fan returnCode(_nc_Position_Form_Cursor(form));
9930e3d5408SPeter Wemm }
9940e3d5408SPeter Wemm
9950e3d5408SPeter Wemm /*---------------------------------------------------------------------------
9960e3d5408SPeter Wemm | Facility : libnform
9970e3d5408SPeter Wemm | Function : static void Perform_Justification(
9980e3d5408SPeter Wemm | FIELD * field,
9990e3d5408SPeter Wemm | WINDOW * win)
10000e3d5408SPeter Wemm |
10010e3d5408SPeter Wemm | Description : Output field with requested justification
10020e3d5408SPeter Wemm |
10030e3d5408SPeter Wemm | Return Values : -
10040e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
10054a1a9510SRong-En Fan static void
Perform_Justification(FIELD * field,WINDOW * win)10064a1a9510SRong-En Fan Perform_Justification(FIELD *field, WINDOW *win)
10070e3d5408SPeter Wemm {
10084a1a9510SRong-En Fan FIELD_CELL *bp;
10090e3d5408SPeter Wemm int len;
10100e3d5408SPeter Wemm
1011aae38d10SBaptiste Daroussin bp = (Field_Has_Option(field, O_NO_LEFT_STRIP)
1012aae38d10SBaptiste Daroussin ? field->buf
1013aae38d10SBaptiste Daroussin : Get_Start_Of_Data(field->buf, Buffer_Length(field)));
10140e3d5408SPeter Wemm len = (int)(After_End_Of_Data(field->buf, Buffer_Length(field)) - bp);
10150e3d5408SPeter Wemm
10160e3d5408SPeter Wemm if (len > 0)
10170e3d5408SPeter Wemm {
1018*21817992SBaptiste Daroussin int col = 0;
1019*21817992SBaptiste Daroussin
1020aae38d10SBaptiste Daroussin assert(win && (field->drows == 1));
10210e3d5408SPeter Wemm
1022aae38d10SBaptiste Daroussin if (field->cols - len >= 0)
10230e3d5408SPeter Wemm switch (field->just)
10240e3d5408SPeter Wemm {
10250e3d5408SPeter Wemm case JUSTIFY_LEFT:
10260e3d5408SPeter Wemm break;
10270e3d5408SPeter Wemm case JUSTIFY_CENTER:
10280e3d5408SPeter Wemm col = (field->cols - len) / 2;
10290e3d5408SPeter Wemm break;
10300e3d5408SPeter Wemm case JUSTIFY_RIGHT:
10310e3d5408SPeter Wemm col = field->cols - len;
10320e3d5408SPeter Wemm break;
10330e3d5408SPeter Wemm default:
10340e3d5408SPeter Wemm break;
10350e3d5408SPeter Wemm }
10360e3d5408SPeter Wemm
10370e3d5408SPeter Wemm wmove(win, 0, col);
10384a1a9510SRong-En Fan myADDNSTR(win, bp, len);
10390e3d5408SPeter Wemm }
10400e3d5408SPeter Wemm }
10410e3d5408SPeter Wemm
10420e3d5408SPeter Wemm /*---------------------------------------------------------------------------
10430e3d5408SPeter Wemm | Facility : libnform
10440e3d5408SPeter Wemm | Function : static void Undo_Justification(
10450e3d5408SPeter Wemm | FIELD * field,
10460e3d5408SPeter Wemm | WINDOW * win)
10470e3d5408SPeter Wemm |
10480e3d5408SPeter Wemm | Description : Display field without any justification, i.e.
10490e3d5408SPeter Wemm | left justified
10500e3d5408SPeter Wemm |
10510e3d5408SPeter Wemm | Return Values : -
10520e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
10534a1a9510SRong-En Fan static void
Undo_Justification(FIELD * field,WINDOW * win)10544a1a9510SRong-En Fan Undo_Justification(FIELD *field, WINDOW *win)
10550e3d5408SPeter Wemm {
10564a1a9510SRong-En Fan FIELD_CELL *bp;
1057aae38d10SBaptiste Daroussin int y, x;
10580e3d5408SPeter Wemm int len;
10590e3d5408SPeter Wemm
1060aae38d10SBaptiste Daroussin getyx(win, y, x);
1061aae38d10SBaptiste Daroussin
1062aae38d10SBaptiste Daroussin bp = (Field_Has_Option(field, O_NO_LEFT_STRIP)
1063aae38d10SBaptiste Daroussin ? field->buf
1064aae38d10SBaptiste Daroussin : Get_Start_Of_Data(field->buf, Buffer_Length(field)));
10650e3d5408SPeter Wemm len = (int)(After_End_Of_Data(field->buf, Buffer_Length(field)) - bp);
10660e3d5408SPeter Wemm
10670e3d5408SPeter Wemm if (len > 0)
10680e3d5408SPeter Wemm {
10690e3d5408SPeter Wemm assert(win);
10700e3d5408SPeter Wemm wmove(win, 0, 0);
10714a1a9510SRong-En Fan myADDNSTR(win, bp, len);
10720e3d5408SPeter Wemm }
1073aae38d10SBaptiste Daroussin wmove(win, y, x);
10740e3d5408SPeter Wemm }
10750e3d5408SPeter Wemm
10760e3d5408SPeter Wemm /*---------------------------------------------------------------------------
10770e3d5408SPeter Wemm | Facility : libnform
107806bfebdeSXin LI | Function : static bool Check_Char(FORM *form,
107906bfebdeSXin LI | FIELD *field,
10800e3d5408SPeter Wemm | FIELDTYPE * typ,
10810e3d5408SPeter Wemm | int ch,
10820e3d5408SPeter Wemm | TypeArgument *argp)
10830e3d5408SPeter Wemm |
10840e3d5408SPeter Wemm | Description : Perform a single character check for character ch
10850e3d5408SPeter Wemm | according to the fieldtype instance.
10860e3d5408SPeter Wemm |
10870e3d5408SPeter Wemm | Return Values : TRUE - Character is valid
10880e3d5408SPeter Wemm | FALSE - Character is invalid
10890e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
10904a1a9510SRong-En Fan static bool
Check_Char(FORM * form,FIELD * field,FIELDTYPE * typ,int ch,TypeArgument * argp)109106bfebdeSXin LI Check_Char(FORM *form,
109206bfebdeSXin LI FIELD *field,
109306bfebdeSXin LI FIELDTYPE *typ,
109406bfebdeSXin LI int ch,
109506bfebdeSXin LI TypeArgument *argp)
10960e3d5408SPeter Wemm {
10970e3d5408SPeter Wemm if (typ)
10980e3d5408SPeter Wemm {
10990e3d5408SPeter Wemm if (typ->status & _LINKED_TYPE)
11000e3d5408SPeter Wemm {
11010e3d5408SPeter Wemm assert(argp);
11020e3d5408SPeter Wemm return (
110306bfebdeSXin LI Check_Char(form, field, typ->left, ch, argp->left) ||
110406bfebdeSXin LI Check_Char(form, field, typ->right, ch, argp->right));
11050e3d5408SPeter Wemm }
11060e3d5408SPeter Wemm else
11070e3d5408SPeter Wemm {
110806bfebdeSXin LI #if NCURSES_INTEROP_FUNCS
110906bfebdeSXin LI if (typ->charcheck.occheck)
111006bfebdeSXin LI {
111106bfebdeSXin LI if (typ->status & _GENERIC)
111206bfebdeSXin LI return typ->charcheck.gccheck(ch, form, field, (void *)argp);
111306bfebdeSXin LI else
111406bfebdeSXin LI return typ->charcheck.occheck(ch, (void *)argp);
111506bfebdeSXin LI }
111606bfebdeSXin LI #else
11170e3d5408SPeter Wemm if (typ->ccheck)
11180e3d5408SPeter Wemm return typ->ccheck(ch, (void *)argp);
111906bfebdeSXin LI #endif
11200e3d5408SPeter Wemm }
11210e3d5408SPeter Wemm }
11224a1a9510SRong-En Fan return (!iscntrl(UChar(ch)) ? TRUE : FALSE);
11230e3d5408SPeter Wemm }
11240e3d5408SPeter Wemm
11250e3d5408SPeter Wemm /*---------------------------------------------------------------------------
11260e3d5408SPeter Wemm | Facility : libnform
11270e3d5408SPeter Wemm | Function : static int Display_Or_Erase_Field(
11280e3d5408SPeter Wemm | FIELD * field,
11290e3d5408SPeter Wemm | bool bEraseFlag)
11300e3d5408SPeter Wemm |
11310e3d5408SPeter Wemm | Description : Create a subwindow for the field and display the
11320e3d5408SPeter Wemm | buffer contents (apply justification if required)
11330e3d5408SPeter Wemm | or simply erase the field.
11340e3d5408SPeter Wemm |
11350e3d5408SPeter Wemm | Return Values : E_OK - on success
11360e3d5408SPeter Wemm | E_SYSTEM_ERROR - some error (typical no memory)
11370e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
11384a1a9510SRong-En Fan static int
Display_Or_Erase_Field(FIELD * field,bool bEraseFlag)11394a1a9510SRong-En Fan Display_Or_Erase_Field(FIELD *field, bool bEraseFlag)
11400e3d5408SPeter Wemm {
11410e3d5408SPeter Wemm WINDOW *win;
11420e3d5408SPeter Wemm WINDOW *fwin;
11430e3d5408SPeter Wemm
11440e3d5408SPeter Wemm if (!field)
11450e3d5408SPeter Wemm return E_SYSTEM_ERROR;
11460e3d5408SPeter Wemm
11470e3d5408SPeter Wemm fwin = Get_Form_Window(field->form);
11480e3d5408SPeter Wemm win = derwin(fwin,
11490e3d5408SPeter Wemm field->rows, field->cols, field->frow, field->fcol);
11500e3d5408SPeter Wemm
11510e3d5408SPeter Wemm if (!win)
11520e3d5408SPeter Wemm return E_SYSTEM_ERROR;
11530e3d5408SPeter Wemm else
11540e3d5408SPeter Wemm {
1155aae38d10SBaptiste Daroussin if (Field_Has_Option(field, O_VISIBLE))
115606bfebdeSXin LI {
11570e3d5408SPeter Wemm Set_Field_Window_Attributes(field, win);
115806bfebdeSXin LI }
11590e3d5408SPeter Wemm else
116006bfebdeSXin LI {
116173f0a83dSXin LI (void)wattrset(win, (int)WINDOW_ATTRS(fwin));
116206bfebdeSXin LI }
11630e3d5408SPeter Wemm werase(win);
11640e3d5408SPeter Wemm }
11650e3d5408SPeter Wemm
11660e3d5408SPeter Wemm if (!bEraseFlag)
11670e3d5408SPeter Wemm {
1168aae38d10SBaptiste Daroussin if (Field_Has_Option(field, O_PUBLIC))
11690e3d5408SPeter Wemm {
11700e3d5408SPeter Wemm if (Justification_Allowed(field))
11710e3d5408SPeter Wemm Perform_Justification(field, win);
11720e3d5408SPeter Wemm else
11730e3d5408SPeter Wemm Buffer_To_Window(field, win);
11740e3d5408SPeter Wemm }
117573f0a83dSXin LI ClrStatus(field, _NEWTOP);
11760e3d5408SPeter Wemm }
11770e3d5408SPeter Wemm wsyncup(win);
11780e3d5408SPeter Wemm delwin(win);
11790e3d5408SPeter Wemm return E_OK;
11800e3d5408SPeter Wemm }
11810e3d5408SPeter Wemm
11820e3d5408SPeter Wemm /* Macros to preset the bEraseFlag */
11830e3d5408SPeter Wemm #define Display_Field(field) Display_Or_Erase_Field(field,FALSE)
11840e3d5408SPeter Wemm #define Erase_Field(field) Display_Or_Erase_Field(field,TRUE)
11850e3d5408SPeter Wemm
11860e3d5408SPeter Wemm /*---------------------------------------------------------------------------
11870e3d5408SPeter Wemm | Facility : libnform
11880e3d5408SPeter Wemm | Function : static int Synchronize_Field(FIELD * field)
11890e3d5408SPeter Wemm |
11900e3d5408SPeter Wemm | Description : Synchronize the windows content with the value in
11910e3d5408SPeter Wemm | the buffer.
11920e3d5408SPeter Wemm |
11930e3d5408SPeter Wemm | Return Values : E_OK - success
11940e3d5408SPeter Wemm | E_BAD_ARGUMENT - invalid field pointer
11950e3d5408SPeter Wemm | E_SYSTEM_ERROR - some severe basic error
11960e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
11974a1a9510SRong-En Fan static int
Synchronize_Field(FIELD * field)11984a1a9510SRong-En Fan Synchronize_Field(FIELD *field)
11990e3d5408SPeter Wemm {
12000e3d5408SPeter Wemm FORM *form;
12010e3d5408SPeter Wemm int res = E_OK;
12020e3d5408SPeter Wemm
12030e3d5408SPeter Wemm if (!field)
12040e3d5408SPeter Wemm return (E_BAD_ARGUMENT);
12050e3d5408SPeter Wemm
12060e3d5408SPeter Wemm if (((form = field->form) != (FORM *)0)
12070e3d5408SPeter Wemm && Field_Really_Appears(field))
12080e3d5408SPeter Wemm {
12090e3d5408SPeter Wemm if (field == form->current)
12100e3d5408SPeter Wemm {
12110e3d5408SPeter Wemm form->currow = form->curcol = form->toprow = form->begincol = 0;
12120e3d5408SPeter Wemm werase(form->w);
12130e3d5408SPeter Wemm
1214aae38d10SBaptiste Daroussin if ((Field_Has_Option(field, O_PUBLIC)) && Justification_Allowed(field))
12150e3d5408SPeter Wemm Undo_Justification(field, form->w);
12160e3d5408SPeter Wemm else
12170e3d5408SPeter Wemm Buffer_To_Window(field, form->w);
12180e3d5408SPeter Wemm
121973f0a83dSXin LI SetStatus(field, _NEWTOP);
12200e3d5408SPeter Wemm res = _nc_Refresh_Current_Field(form);
12210e3d5408SPeter Wemm }
12220e3d5408SPeter Wemm else
12230e3d5408SPeter Wemm res = Display_Field(field);
12240e3d5408SPeter Wemm }
122573f0a83dSXin LI SetStatus(field, _CHANGED);
12260e3d5408SPeter Wemm return (res);
12270e3d5408SPeter Wemm }
12280e3d5408SPeter Wemm
12290e3d5408SPeter Wemm /*---------------------------------------------------------------------------
12300e3d5408SPeter Wemm | Facility : libnform
12310e3d5408SPeter Wemm | Function : static int Synchronize_Linked_Fields(FIELD * field)
12320e3d5408SPeter Wemm |
12330e3d5408SPeter Wemm | Description : Propagate the Synchronize_Field function to all linked
12340e3d5408SPeter Wemm | fields. The first error that occurs in the sequence
12350e3d5408SPeter Wemm | of updates is the return value.
12360e3d5408SPeter Wemm |
12370e3d5408SPeter Wemm | Return Values : E_OK - success
12380e3d5408SPeter Wemm | E_BAD_ARGUMENT - invalid field pointer
12390e3d5408SPeter Wemm | E_SYSTEM_ERROR - some severe basic error
12400e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
12414a1a9510SRong-En Fan static int
Synchronize_Linked_Fields(FIELD * field)12424a1a9510SRong-En Fan Synchronize_Linked_Fields(FIELD *field)
12430e3d5408SPeter Wemm {
12440e3d5408SPeter Wemm FIELD *linked_field;
12450e3d5408SPeter Wemm int res = E_OK;
12460e3d5408SPeter Wemm
12470e3d5408SPeter Wemm if (!field)
12480e3d5408SPeter Wemm return (E_BAD_ARGUMENT);
12490e3d5408SPeter Wemm
12500e3d5408SPeter Wemm if (!field->link)
12510e3d5408SPeter Wemm return (E_SYSTEM_ERROR);
12520e3d5408SPeter Wemm
12530e3d5408SPeter Wemm for (linked_field = field->link;
125473f0a83dSXin LI (linked_field != field) && (linked_field != 0);
12550e3d5408SPeter Wemm linked_field = linked_field->link)
12560e3d5408SPeter Wemm {
1257*21817992SBaptiste Daroussin int syncres;
1258*21817992SBaptiste Daroussin
12590e3d5408SPeter Wemm if (((syncres = Synchronize_Field(linked_field)) != E_OK) &&
12600e3d5408SPeter Wemm (res == E_OK))
12610e3d5408SPeter Wemm res = syncres;
12620e3d5408SPeter Wemm }
12630e3d5408SPeter Wemm return (res);
12640e3d5408SPeter Wemm }
12650e3d5408SPeter Wemm
12660e3d5408SPeter Wemm /*---------------------------------------------------------------------------
12670e3d5408SPeter Wemm | Facility : libnform
12680e3d5408SPeter Wemm | Function : int _nc_Synchronize_Attributes(FIELD * field)
12690e3d5408SPeter Wemm |
12707a656419SBaptiste Daroussin | Description : If a field's visual attributes have changed, this
12710e3d5408SPeter Wemm | routine is called to propagate those changes to the
12720e3d5408SPeter Wemm | screen.
12730e3d5408SPeter Wemm |
12740e3d5408SPeter Wemm | Return Values : E_OK - success
12750e3d5408SPeter Wemm | E_BAD_ARGUMENT - invalid field pointer
12760e3d5408SPeter Wemm | E_SYSTEM_ERROR - some severe basic error
12770e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
12787a656419SBaptiste Daroussin FORM_EXPORT(int)
_nc_Synchronize_Attributes(FIELD * field)12797a69bbfbSPeter Wemm _nc_Synchronize_Attributes(FIELD *field)
12800e3d5408SPeter Wemm {
12810e3d5408SPeter Wemm FORM *form;
12820e3d5408SPeter Wemm int res = E_OK;
12830e3d5408SPeter Wemm
128406bfebdeSXin LI T((T_CALLED("_nc_Synchronize_Attributes(%p)"), (void *)field));
12850e3d5408SPeter Wemm
12864a1a9510SRong-En Fan if (!field)
12874a1a9510SRong-En Fan returnCode(E_BAD_ARGUMENT);
12884a1a9510SRong-En Fan
12894a1a9510SRong-En Fan CHECKPOS(field->form);
12900e3d5408SPeter Wemm if (((form = field->form) != (FORM *)0)
12910e3d5408SPeter Wemm && Field_Really_Appears(field))
12920e3d5408SPeter Wemm {
12930e3d5408SPeter Wemm if (form->current == field)
12940e3d5408SPeter Wemm {
12950e3d5408SPeter Wemm Synchronize_Buffer(form);
12960e3d5408SPeter Wemm Set_Field_Window_Attributes(field, form->w);
12970e3d5408SPeter Wemm werase(form->w);
12984a1a9510SRong-En Fan wmove(form->w, form->currow, form->curcol);
12994a1a9510SRong-En Fan
1300aae38d10SBaptiste Daroussin if (Field_Has_Option(field, O_PUBLIC))
13010e3d5408SPeter Wemm {
13020e3d5408SPeter Wemm if (Justification_Allowed(field))
13030e3d5408SPeter Wemm Undo_Justification(field, form->w);
13040e3d5408SPeter Wemm else
13050e3d5408SPeter Wemm Buffer_To_Window(field, form->w);
13060e3d5408SPeter Wemm }
13070e3d5408SPeter Wemm else
13080e3d5408SPeter Wemm {
1309*21817992SBaptiste Daroussin WINDOW *formwin = Get_Form_Window(form);
1310*21817992SBaptiste Daroussin
13110e3d5408SPeter Wemm copywin(form->w, formwin,
13120e3d5408SPeter Wemm 0, 0,
13130e3d5408SPeter Wemm field->frow, field->fcol,
1314aae38d10SBaptiste Daroussin field->frow + field->rows - 1,
1315aae38d10SBaptiste Daroussin field->fcol + field->cols - 1, 0);
13160e3d5408SPeter Wemm wsyncup(formwin);
13170e3d5408SPeter Wemm Buffer_To_Window(field, form->w);
131873f0a83dSXin LI SetStatus(field, _NEWTOP); /* fake refresh to paint all */
13190e3d5408SPeter Wemm _nc_Refresh_Current_Field(form);
13200e3d5408SPeter Wemm }
13210e3d5408SPeter Wemm }
13220e3d5408SPeter Wemm else
13230e3d5408SPeter Wemm {
13240e3d5408SPeter Wemm res = Display_Field(field);
13250e3d5408SPeter Wemm }
13260e3d5408SPeter Wemm }
13274a1a9510SRong-En Fan CHECKPOS(form);
13284a1a9510SRong-En Fan returnCode(res);
13290e3d5408SPeter Wemm }
13300e3d5408SPeter Wemm
13310e3d5408SPeter Wemm /*---------------------------------------------------------------------------
13320e3d5408SPeter Wemm | Facility : libnform
13330e3d5408SPeter Wemm | Function : int _nc_Synchronize_Options(FIELD * field,
13340e3d5408SPeter Wemm | Field_Options newopts)
13350e3d5408SPeter Wemm |
13367a656419SBaptiste Daroussin | Description : If a field's options have changed, this routine is
13370e3d5408SPeter Wemm | called to propagate these changes to the screen and
13384a1a9510SRong-En Fan | to really change the behavior of the field.
13390e3d5408SPeter Wemm |
13400e3d5408SPeter Wemm | Return Values : E_OK - success
13410e3d5408SPeter Wemm | E_BAD_ARGUMENT - invalid field pointer
13424a1a9510SRong-En Fan | E_CURRENT - field is the current one
13430e3d5408SPeter Wemm | E_SYSTEM_ERROR - some severe basic error
13440e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
13457a656419SBaptiste Daroussin FORM_EXPORT(int)
_nc_Synchronize_Options(FIELD * field,Field_Options newopts)13464a1a9510SRong-En Fan _nc_Synchronize_Options(FIELD *field, Field_Options newopts)
13470e3d5408SPeter Wemm {
13480e3d5408SPeter Wemm Field_Options oldopts;
13490e3d5408SPeter Wemm Field_Options changed_opts;
13500e3d5408SPeter Wemm FORM *form;
13510e3d5408SPeter Wemm int res = E_OK;
13520e3d5408SPeter Wemm
135306bfebdeSXin LI T((T_CALLED("_nc_Synchronize_Options(%p,%#x)"), (void *)field, newopts));
13544a1a9510SRong-En Fan
13550e3d5408SPeter Wemm if (!field)
13564a1a9510SRong-En Fan returnCode(E_BAD_ARGUMENT);
13570e3d5408SPeter Wemm
13580e3d5408SPeter Wemm oldopts = field->opts;
13590e3d5408SPeter Wemm changed_opts = oldopts ^ newopts;
13600e3d5408SPeter Wemm field->opts = newopts;
13610e3d5408SPeter Wemm form = field->form;
13620e3d5408SPeter Wemm
13630e3d5408SPeter Wemm if (form)
13640e3d5408SPeter Wemm {
136506bfebdeSXin LI if (form->status & _POSTED)
136606bfebdeSXin LI {
13670e3d5408SPeter Wemm if (form->current == field)
13680e3d5408SPeter Wemm {
13690e3d5408SPeter Wemm field->opts = oldopts;
13704a1a9510SRong-En Fan returnCode(E_CURRENT);
13710e3d5408SPeter Wemm }
137273f0a83dSXin LI if (form->curpage == field->page)
13730e3d5408SPeter Wemm {
137473f0a83dSXin LI if ((unsigned)changed_opts & O_VISIBLE)
13750e3d5408SPeter Wemm {
137673f0a83dSXin LI if ((unsigned)newopts & O_VISIBLE)
13770e3d5408SPeter Wemm res = Display_Field(field);
13780e3d5408SPeter Wemm else
13790e3d5408SPeter Wemm res = Erase_Field(field);
13800e3d5408SPeter Wemm }
13810e3d5408SPeter Wemm else
13820e3d5408SPeter Wemm {
138373f0a83dSXin LI if (((unsigned)changed_opts & O_PUBLIC) &&
138473f0a83dSXin LI ((unsigned)newopts & O_VISIBLE))
13850e3d5408SPeter Wemm res = Display_Field(field);
13860e3d5408SPeter Wemm }
13870e3d5408SPeter Wemm }
13880e3d5408SPeter Wemm }
13890e3d5408SPeter Wemm }
13900e3d5408SPeter Wemm
139173f0a83dSXin LI if ((unsigned)changed_opts & O_STATIC)
13920e3d5408SPeter Wemm {
13930e3d5408SPeter Wemm bool single_line_field = Single_Line_Field(field);
13940e3d5408SPeter Wemm int res2 = E_OK;
13950e3d5408SPeter Wemm
139673f0a83dSXin LI if ((unsigned)newopts & O_STATIC)
13974a1a9510SRong-En Fan {
13984a1a9510SRong-En Fan /* the field becomes now static */
139973f0a83dSXin LI ClrStatus(field, _MAY_GROW);
14000e3d5408SPeter Wemm /* if actually we have no hidden columns, justification may
14010e3d5408SPeter Wemm occur again */
14020e3d5408SPeter Wemm if (single_line_field &&
14030e3d5408SPeter Wemm (field->cols == field->dcols) &&
14040e3d5408SPeter Wemm (field->just != NO_JUSTIFICATION) &&
14050e3d5408SPeter Wemm Field_Really_Appears(field))
14060e3d5408SPeter Wemm {
14070e3d5408SPeter Wemm res2 = Display_Field(field);
14080e3d5408SPeter Wemm }
14090e3d5408SPeter Wemm }
14100e3d5408SPeter Wemm else
14114a1a9510SRong-En Fan {
14124a1a9510SRong-En Fan /* field is no longer static */
14130e3d5408SPeter Wemm if ((field->maxgrow == 0) ||
14140e3d5408SPeter Wemm (single_line_field && (field->dcols < field->maxgrow)) ||
14150e3d5408SPeter Wemm (!single_line_field && (field->drows < field->maxgrow)))
14160e3d5408SPeter Wemm {
141773f0a83dSXin LI SetStatus(field, _MAY_GROW);
14184a1a9510SRong-En Fan /* a field with justification now changes its behavior,
14190e3d5408SPeter Wemm so we must redisplay it */
14200e3d5408SPeter Wemm if (single_line_field &&
14210e3d5408SPeter Wemm (field->just != NO_JUSTIFICATION) &&
14220e3d5408SPeter Wemm Field_Really_Appears(field))
14230e3d5408SPeter Wemm {
14240e3d5408SPeter Wemm res2 = Display_Field(field);
14250e3d5408SPeter Wemm }
14260e3d5408SPeter Wemm }
14270e3d5408SPeter Wemm }
14280e3d5408SPeter Wemm if (res2 != E_OK)
14290e3d5408SPeter Wemm res = res2;
14300e3d5408SPeter Wemm }
14310e3d5408SPeter Wemm
14324a1a9510SRong-En Fan returnCode(res);
14330e3d5408SPeter Wemm }
14340e3d5408SPeter Wemm
1435aae38d10SBaptiste Daroussin /*
1436aae38d10SBaptiste Daroussin * Removes the focus from the current field of the form.
1437aae38d10SBaptiste Daroussin */
1438aae38d10SBaptiste Daroussin void
_nc_Unset_Current_Field(FORM * form)1439aae38d10SBaptiste Daroussin _nc_Unset_Current_Field(FORM *form)
1440aae38d10SBaptiste Daroussin {
1441aae38d10SBaptiste Daroussin FIELD *field = form->current;
1442aae38d10SBaptiste Daroussin
1443aae38d10SBaptiste Daroussin _nc_Refresh_Current_Field(form);
1444aae38d10SBaptiste Daroussin if (Field_Has_Option(field, O_PUBLIC))
1445aae38d10SBaptiste Daroussin {
1446aae38d10SBaptiste Daroussin if (field->drows > field->rows)
1447aae38d10SBaptiste Daroussin {
1448aae38d10SBaptiste Daroussin if (form->toprow == 0)
1449aae38d10SBaptiste Daroussin ClrStatus(field, _NEWTOP);
1450aae38d10SBaptiste Daroussin else
1451aae38d10SBaptiste Daroussin SetStatus(field, _NEWTOP);
1452aae38d10SBaptiste Daroussin }
1453aae38d10SBaptiste Daroussin else
1454aae38d10SBaptiste Daroussin {
1455aae38d10SBaptiste Daroussin if (Justification_Allowed(field))
1456aae38d10SBaptiste Daroussin {
1457aae38d10SBaptiste Daroussin Window_To_Buffer(form, field);
1458aae38d10SBaptiste Daroussin werase(form->w);
1459aae38d10SBaptiste Daroussin Perform_Justification(field, form->w);
1460aae38d10SBaptiste Daroussin if (Field_Has_Option(field, O_DYNAMIC_JUSTIFY) &&
1461aae38d10SBaptiste Daroussin (form->w->_parent == 0))
1462aae38d10SBaptiste Daroussin {
1463aae38d10SBaptiste Daroussin copywin(form->w,
1464aae38d10SBaptiste Daroussin Get_Form_Window(form),
1465aae38d10SBaptiste Daroussin 0,
1466aae38d10SBaptiste Daroussin 0,
1467aae38d10SBaptiste Daroussin field->frow,
1468aae38d10SBaptiste Daroussin field->fcol,
1469aae38d10SBaptiste Daroussin field->frow,
1470aae38d10SBaptiste Daroussin field->cols + field->fcol - 1,
1471aae38d10SBaptiste Daroussin 0);
1472aae38d10SBaptiste Daroussin wsyncup(Get_Form_Window(form));
1473aae38d10SBaptiste Daroussin }
1474aae38d10SBaptiste Daroussin else
1475aae38d10SBaptiste Daroussin {
1476aae38d10SBaptiste Daroussin wsyncup(form->w);
1477aae38d10SBaptiste Daroussin }
1478aae38d10SBaptiste Daroussin }
1479aae38d10SBaptiste Daroussin }
1480aae38d10SBaptiste Daroussin }
1481aae38d10SBaptiste Daroussin delwin(form->w);
1482aae38d10SBaptiste Daroussin form->w = (WINDOW *)0;
1483aae38d10SBaptiste Daroussin form->current = 0;
1484aae38d10SBaptiste Daroussin }
1485aae38d10SBaptiste Daroussin
14860e3d5408SPeter Wemm /*---------------------------------------------------------------------------
14870e3d5408SPeter Wemm | Facility : libnform
14880e3d5408SPeter Wemm | Function : int _nc_Set_Current_Field(FORM * form,
14890e3d5408SPeter Wemm | FIELD * newfield)
14900e3d5408SPeter Wemm |
14910e3d5408SPeter Wemm | Description : Make the newfield the new current field.
14920e3d5408SPeter Wemm |
14930e3d5408SPeter Wemm | Return Values : E_OK - success
14940e3d5408SPeter Wemm | E_BAD_ARGUMENT - invalid form or field pointer
14950e3d5408SPeter Wemm | E_SYSTEM_ERROR - some severe basic error
14964a1a9510SRong-En Fan | E_NOT_CONNECTED - no fields are connected to the form
14970e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
14987a656419SBaptiste Daroussin FORM_EXPORT(int)
_nc_Set_Current_Field(FORM * form,FIELD * newfield)14994a1a9510SRong-En Fan _nc_Set_Current_Field(FORM *form, FIELD *newfield)
15000e3d5408SPeter Wemm {
15010e3d5408SPeter Wemm FIELD *field;
15020e3d5408SPeter Wemm WINDOW *new_window;
15030e3d5408SPeter Wemm
150406bfebdeSXin LI T((T_CALLED("_nc_Set_Current_Field(%p,%p)"), (void *)form, (void *)newfield));
15054a1a9510SRong-En Fan
1506aae38d10SBaptiste Daroussin if (!form || !newfield || (newfield->form != form))
15074a1a9510SRong-En Fan returnCode(E_BAD_ARGUMENT);
15080e3d5408SPeter Wemm
15090e3d5408SPeter Wemm if ((form->status & _IN_DRIVER))
15104a1a9510SRong-En Fan returnCode(E_BAD_STATE);
15110e3d5408SPeter Wemm
15120e3d5408SPeter Wemm if (!(form->field))
15134a1a9510SRong-En Fan returnCode(E_NOT_CONNECTED);
15140e3d5408SPeter Wemm
15150e3d5408SPeter Wemm field = form->current;
15160e3d5408SPeter Wemm
15170e3d5408SPeter Wemm if ((field != newfield) ||
15180e3d5408SPeter Wemm !(form->status & _POSTED))
15190e3d5408SPeter Wemm {
1520aae38d10SBaptiste Daroussin if (field && (form->w) &&
1521aae38d10SBaptiste Daroussin (Field_Has_Option(field, O_VISIBLE)) &&
15220e3d5408SPeter Wemm (field->form->curpage == field->page))
1523aae38d10SBaptiste Daroussin _nc_Unset_Current_Field(form);
15240e3d5408SPeter Wemm
15250e3d5408SPeter Wemm field = newfield;
15260e3d5408SPeter Wemm
15270e3d5408SPeter Wemm if (Has_Invisible_Parts(field))
15280e3d5408SPeter Wemm new_window = newpad(field->drows, field->dcols);
15290e3d5408SPeter Wemm else
15300e3d5408SPeter Wemm new_window = derwin(Get_Form_Window(form),
15310e3d5408SPeter Wemm field->rows, field->cols, field->frow, field->fcol);
15320e3d5408SPeter Wemm
15330e3d5408SPeter Wemm if (!new_window)
15344a1a9510SRong-En Fan returnCode(E_SYSTEM_ERROR);
15350e3d5408SPeter Wemm
15360e3d5408SPeter Wemm form->current = field;
15377a69bbfbSPeter Wemm
15387a69bbfbSPeter Wemm if (form->w)
15397a69bbfbSPeter Wemm delwin(form->w);
15400e3d5408SPeter Wemm form->w = new_window;
15417a69bbfbSPeter Wemm
154273f0a83dSXin LI ClrStatus(form, _WINDOW_MODIFIED);
15430e3d5408SPeter Wemm Set_Field_Window_Attributes(field, form->w);
15440e3d5408SPeter Wemm
15450e3d5408SPeter Wemm if (Has_Invisible_Parts(field))
15460e3d5408SPeter Wemm {
15470e3d5408SPeter Wemm werase(form->w);
15480e3d5408SPeter Wemm Buffer_To_Window(field, form->w);
15490e3d5408SPeter Wemm }
15500e3d5408SPeter Wemm else
15510e3d5408SPeter Wemm {
15520e3d5408SPeter Wemm if (Justification_Allowed(field))
15530e3d5408SPeter Wemm {
15540e3d5408SPeter Wemm werase(form->w);
15550e3d5408SPeter Wemm Undo_Justification(field, form->w);
15560e3d5408SPeter Wemm wsyncup(form->w);
15570e3d5408SPeter Wemm }
15580e3d5408SPeter Wemm }
15590e3d5408SPeter Wemm
15600e3d5408SPeter Wemm untouchwin(form->w);
15610e3d5408SPeter Wemm }
15620e3d5408SPeter Wemm
15630e3d5408SPeter Wemm form->currow = form->curcol = form->toprow = form->begincol = 0;
15644a1a9510SRong-En Fan returnCode(E_OK);
15650e3d5408SPeter Wemm }
15664a1a9510SRong-En Fan
15670e3d5408SPeter Wemm /*----------------------------------------------------------------------------
15680e3d5408SPeter Wemm Intra-Field Navigation routines
15690e3d5408SPeter Wemm --------------------------------------------------------------------------*/
15700e3d5408SPeter Wemm
15710e3d5408SPeter Wemm /*---------------------------------------------------------------------------
15720e3d5408SPeter Wemm | Facility : libnform
15730e3d5408SPeter Wemm | Function : static int IFN_Next_Character(FORM * form)
15740e3d5408SPeter Wemm |
15754a1a9510SRong-En Fan | Description : Move to the next character in the field. In a multi-line
15760e3d5408SPeter Wemm | field this wraps at the end of the line.
15770e3d5408SPeter Wemm |
15780e3d5408SPeter Wemm | Return Values : E_OK - success
15790e3d5408SPeter Wemm | E_REQUEST_DENIED - at the rightmost position
15800e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
15814a1a9510SRong-En Fan static int
IFN_Next_Character(FORM * form)15824a1a9510SRong-En Fan IFN_Next_Character(FORM *form)
15830e3d5408SPeter Wemm {
15840e3d5408SPeter Wemm FIELD *field = form->current;
15854a1a9510SRong-En Fan int step = myWCWIDTH(form->w, form->currow, form->curcol);
15860e3d5408SPeter Wemm
158706bfebdeSXin LI T((T_CALLED("IFN_Next_Character(%p)"), (void *)form));
15884a1a9510SRong-En Fan if ((form->curcol += step) == field->dcols)
15890e3d5408SPeter Wemm {
15900e3d5408SPeter Wemm if ((++(form->currow)) == field->drows)
15910e3d5408SPeter Wemm {
15920e3d5408SPeter Wemm #if GROW_IF_NAVIGATE
15934a1a9510SRong-En Fan if (!Single_Line_Field(field) && Field_Grown(field, 1))
15944a1a9510SRong-En Fan {
15950e3d5408SPeter Wemm form->curcol = 0;
15964a1a9510SRong-En Fan returnCode(E_OK);
15970e3d5408SPeter Wemm }
15980e3d5408SPeter Wemm #endif
15990e3d5408SPeter Wemm form->currow--;
16000e3d5408SPeter Wemm #if GROW_IF_NAVIGATE
16010e3d5408SPeter Wemm if (Single_Line_Field(field) && Field_Grown(field, 1))
16024a1a9510SRong-En Fan returnCode(E_OK);
16030e3d5408SPeter Wemm #endif
16044a1a9510SRong-En Fan form->curcol -= step;
16054a1a9510SRong-En Fan returnCode(E_REQUEST_DENIED);
16060e3d5408SPeter Wemm }
16070e3d5408SPeter Wemm form->curcol = 0;
16080e3d5408SPeter Wemm }
16094a1a9510SRong-En Fan returnCode(E_OK);
16100e3d5408SPeter Wemm }
16110e3d5408SPeter Wemm
16120e3d5408SPeter Wemm /*---------------------------------------------------------------------------
16130e3d5408SPeter Wemm | Facility : libnform
16140e3d5408SPeter Wemm | Function : static int IFN_Previous_Character(FORM * form)
16150e3d5408SPeter Wemm |
16160e3d5408SPeter Wemm | Description : Move to the previous character in the field. In a
16174a1a9510SRong-En Fan | multi-line field this wraps and the beginning of the
16180e3d5408SPeter Wemm | line.
16190e3d5408SPeter Wemm |
16200e3d5408SPeter Wemm | Return Values : E_OK - success
16210e3d5408SPeter Wemm | E_REQUEST_DENIED - at the leftmost position
16220e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
16234a1a9510SRong-En Fan static int
IFN_Previous_Character(FORM * form)16244a1a9510SRong-En Fan IFN_Previous_Character(FORM *form)
16250e3d5408SPeter Wemm {
16264a1a9510SRong-En Fan int amount = myWCWIDTH(form->w, form->currow, form->curcol - 1);
16274a1a9510SRong-En Fan int oldcol = form->curcol;
16284a1a9510SRong-En Fan
162906bfebdeSXin LI T((T_CALLED("IFN_Previous_Character(%p)"), (void *)form));
16304a1a9510SRong-En Fan if ((form->curcol -= amount) < 0)
16310e3d5408SPeter Wemm {
16320e3d5408SPeter Wemm if ((--(form->currow)) < 0)
16330e3d5408SPeter Wemm {
16340e3d5408SPeter Wemm form->currow++;
16354a1a9510SRong-En Fan form->curcol = oldcol;
16364a1a9510SRong-En Fan returnCode(E_REQUEST_DENIED);
16370e3d5408SPeter Wemm }
16380e3d5408SPeter Wemm form->curcol = form->current->dcols - 1;
16390e3d5408SPeter Wemm }
16404a1a9510SRong-En Fan returnCode(E_OK);
16410e3d5408SPeter Wemm }
16420e3d5408SPeter Wemm
16430e3d5408SPeter Wemm /*---------------------------------------------------------------------------
16440e3d5408SPeter Wemm | Facility : libnform
16450e3d5408SPeter Wemm | Function : static int IFN_Next_Line(FORM * form)
16460e3d5408SPeter Wemm |
16470e3d5408SPeter Wemm | Description : Move to the beginning of the next line in the field
16480e3d5408SPeter Wemm |
16490e3d5408SPeter Wemm | Return Values : E_OK - success
16500e3d5408SPeter Wemm | E_REQUEST_DENIED - at the last line
16510e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
16524a1a9510SRong-En Fan static int
IFN_Next_Line(FORM * form)16534a1a9510SRong-En Fan IFN_Next_Line(FORM *form)
16540e3d5408SPeter Wemm {
16550e3d5408SPeter Wemm FIELD *field = form->current;
16560e3d5408SPeter Wemm
165706bfebdeSXin LI T((T_CALLED("IFN_Next_Line(%p)"), (void *)form));
16580e3d5408SPeter Wemm if ((++(form->currow)) == field->drows)
16590e3d5408SPeter Wemm {
16600e3d5408SPeter Wemm #if GROW_IF_NAVIGATE
16610e3d5408SPeter Wemm if (!Single_Line_Field(field) && Field_Grown(field, 1))
16624a1a9510SRong-En Fan returnCode(E_OK);
16630e3d5408SPeter Wemm #endif
16640e3d5408SPeter Wemm form->currow--;
16654a1a9510SRong-En Fan returnCode(E_REQUEST_DENIED);
16660e3d5408SPeter Wemm }
16670e3d5408SPeter Wemm form->curcol = 0;
16684a1a9510SRong-En Fan returnCode(E_OK);
16690e3d5408SPeter Wemm }
16700e3d5408SPeter Wemm
16710e3d5408SPeter Wemm /*---------------------------------------------------------------------------
16720e3d5408SPeter Wemm | Facility : libnform
16730e3d5408SPeter Wemm | Function : static int IFN_Previous_Line(FORM * form)
16740e3d5408SPeter Wemm |
16750e3d5408SPeter Wemm | Description : Move to the beginning of the previous line in the field
16760e3d5408SPeter Wemm |
16770e3d5408SPeter Wemm | Return Values : E_OK - success
16780e3d5408SPeter Wemm | E_REQUEST_DENIED - at the first line
16790e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
16804a1a9510SRong-En Fan static int
IFN_Previous_Line(FORM * form)16814a1a9510SRong-En Fan IFN_Previous_Line(FORM *form)
16820e3d5408SPeter Wemm {
168306bfebdeSXin LI T((T_CALLED("IFN_Previous_Line(%p)"), (void *)form));
16840e3d5408SPeter Wemm if ((--(form->currow)) < 0)
16850e3d5408SPeter Wemm {
16860e3d5408SPeter Wemm form->currow++;
16874a1a9510SRong-En Fan returnCode(E_REQUEST_DENIED);
16880e3d5408SPeter Wemm }
16890e3d5408SPeter Wemm form->curcol = 0;
16904a1a9510SRong-En Fan returnCode(E_OK);
16910e3d5408SPeter Wemm }
16920e3d5408SPeter Wemm
16930e3d5408SPeter Wemm /*---------------------------------------------------------------------------
16940e3d5408SPeter Wemm | Facility : libnform
16950e3d5408SPeter Wemm | Function : static int IFN_Next_Word(FORM * form)
16960e3d5408SPeter Wemm |
16970e3d5408SPeter Wemm | Description : Move to the beginning of the next word in the field.
16980e3d5408SPeter Wemm |
16990e3d5408SPeter Wemm | Return Values : E_OK - success
17000e3d5408SPeter Wemm | E_REQUEST_DENIED - there is no next word
17010e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
17024a1a9510SRong-En Fan static int
IFN_Next_Word(FORM * form)17034a1a9510SRong-En Fan IFN_Next_Word(FORM *form)
17040e3d5408SPeter Wemm {
17050e3d5408SPeter Wemm FIELD *field = form->current;
17064a1a9510SRong-En Fan FIELD_CELL *bp = Address_Of_Current_Position_In_Buffer(form);
17074a1a9510SRong-En Fan FIELD_CELL *s;
17084a1a9510SRong-En Fan FIELD_CELL *t;
17094a1a9510SRong-En Fan
171006bfebdeSXin LI T((T_CALLED("IFN_Next_Word(%p)"), (void *)form));
17110e3d5408SPeter Wemm
17120e3d5408SPeter Wemm /* We really need access to the data, so we have to synchronize */
17130e3d5408SPeter Wemm Synchronize_Buffer(form);
17140e3d5408SPeter Wemm
17150e3d5408SPeter Wemm /* Go to the first whitespace after the current position (including
17164a1a9510SRong-En Fan current position). This is then the starting point to look for the
17170e3d5408SPeter Wemm next non-blank data */
17180e3d5408SPeter Wemm s = Get_First_Whitespace_Character(bp, Buffer_Length(field) -
17190e3d5408SPeter Wemm (int)(bp - field->buf));
17200e3d5408SPeter Wemm
17210e3d5408SPeter Wemm /* Find the start of the next word */
17220e3d5408SPeter Wemm t = Get_Start_Of_Data(s, Buffer_Length(field) -
17230e3d5408SPeter Wemm (int)(s - field->buf));
17240e3d5408SPeter Wemm #if !FRIENDLY_PREV_NEXT_WORD
17250e3d5408SPeter Wemm if (s == t)
17264a1a9510SRong-En Fan returnCode(E_REQUEST_DENIED);
17270e3d5408SPeter Wemm else
17280e3d5408SPeter Wemm #endif
17290e3d5408SPeter Wemm {
17300e3d5408SPeter Wemm Adjust_Cursor_Position(form, t);
17314a1a9510SRong-En Fan returnCode(E_OK);
17320e3d5408SPeter Wemm }
17330e3d5408SPeter Wemm }
17340e3d5408SPeter Wemm
17350e3d5408SPeter Wemm /*---------------------------------------------------------------------------
17360e3d5408SPeter Wemm | Facility : libnform
17370e3d5408SPeter Wemm | Function : static int IFN_Previous_Word(FORM * form)
17380e3d5408SPeter Wemm |
17390e3d5408SPeter Wemm | Description : Move to the beginning of the previous word in the field.
17400e3d5408SPeter Wemm |
17410e3d5408SPeter Wemm | Return Values : E_OK - success
17420e3d5408SPeter Wemm | E_REQUEST_DENIED - there is no previous word
17430e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
17444a1a9510SRong-En Fan static int
IFN_Previous_Word(FORM * form)17454a1a9510SRong-En Fan IFN_Previous_Word(FORM *form)
17460e3d5408SPeter Wemm {
17470e3d5408SPeter Wemm FIELD *field = form->current;
17484a1a9510SRong-En Fan FIELD_CELL *bp = Address_Of_Current_Position_In_Buffer(form);
17494a1a9510SRong-En Fan FIELD_CELL *s;
17504a1a9510SRong-En Fan FIELD_CELL *t;
17510e3d5408SPeter Wemm bool again = FALSE;
17520e3d5408SPeter Wemm
175306bfebdeSXin LI T((T_CALLED("IFN_Previous_Word(%p)"), (void *)form));
17544a1a9510SRong-En Fan
17550e3d5408SPeter Wemm /* We really need access to the data, so we have to synchronize */
17560e3d5408SPeter Wemm Synchronize_Buffer(form);
17570e3d5408SPeter Wemm
17580e3d5408SPeter Wemm s = After_End_Of_Data(field->buf, (int)(bp - field->buf));
17590e3d5408SPeter Wemm /* s points now right after the last non-blank in the buffer before bp.
17600e3d5408SPeter Wemm If bp was in a word, s equals bp. In this case we must find the last
17610e3d5408SPeter Wemm whitespace in the buffer before bp and repeat the game to really find
17620e3d5408SPeter Wemm the previous word! */
17630e3d5408SPeter Wemm if (s == bp)
17640e3d5408SPeter Wemm again = TRUE;
17650e3d5408SPeter Wemm
17660e3d5408SPeter Wemm /* And next call now goes backward to look for the last whitespace
17670e3d5408SPeter Wemm before that, pointing right after this, so it points to the begin
17680e3d5408SPeter Wemm of the previous word.
17690e3d5408SPeter Wemm */
17700e3d5408SPeter Wemm t = After_Last_Whitespace_Character(field->buf, (int)(s - field->buf));
17710e3d5408SPeter Wemm #if !FRIENDLY_PREV_NEXT_WORD
17720e3d5408SPeter Wemm if (s == t)
17734a1a9510SRong-En Fan returnCode(E_REQUEST_DENIED);
17740e3d5408SPeter Wemm #endif
17750e3d5408SPeter Wemm if (again)
17764a1a9510SRong-En Fan {
17774a1a9510SRong-En Fan /* and do it again, replacing bp by t */
17780e3d5408SPeter Wemm s = After_End_Of_Data(field->buf, (int)(t - field->buf));
17790e3d5408SPeter Wemm t = After_Last_Whitespace_Character(field->buf, (int)(s - field->buf));
17800e3d5408SPeter Wemm #if !FRIENDLY_PREV_NEXT_WORD
17810e3d5408SPeter Wemm if (s == t)
17824a1a9510SRong-En Fan returnCode(E_REQUEST_DENIED);
17830e3d5408SPeter Wemm #endif
17840e3d5408SPeter Wemm }
17850e3d5408SPeter Wemm Adjust_Cursor_Position(form, t);
17864a1a9510SRong-En Fan returnCode(E_OK);
17870e3d5408SPeter Wemm }
17880e3d5408SPeter Wemm
17890e3d5408SPeter Wemm /*---------------------------------------------------------------------------
17900e3d5408SPeter Wemm | Facility : libnform
17910e3d5408SPeter Wemm | Function : static int IFN_Beginning_Of_Field(FORM * form)
17920e3d5408SPeter Wemm |
17930e3d5408SPeter Wemm | Description : Place the cursor at the first non-pad character in
17940e3d5408SPeter Wemm | the field.
17950e3d5408SPeter Wemm |
17960e3d5408SPeter Wemm | Return Values : E_OK - success
17970e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
17984a1a9510SRong-En Fan static int
IFN_Beginning_Of_Field(FORM * form)17994a1a9510SRong-En Fan IFN_Beginning_Of_Field(FORM *form)
18000e3d5408SPeter Wemm {
18010e3d5408SPeter Wemm FIELD *field = form->current;
18020e3d5408SPeter Wemm
180306bfebdeSXin LI T((T_CALLED("IFN_Beginning_Of_Field(%p)"), (void *)form));
18040e3d5408SPeter Wemm Synchronize_Buffer(form);
18050e3d5408SPeter Wemm Adjust_Cursor_Position(form,
18060e3d5408SPeter Wemm Get_Start_Of_Data(field->buf, Buffer_Length(field)));
18074a1a9510SRong-En Fan returnCode(E_OK);
18080e3d5408SPeter Wemm }
18090e3d5408SPeter Wemm
18100e3d5408SPeter Wemm /*---------------------------------------------------------------------------
18110e3d5408SPeter Wemm | Facility : libnform
18120e3d5408SPeter Wemm | Function : static int IFN_End_Of_Field(FORM * form)
18130e3d5408SPeter Wemm |
18140e3d5408SPeter Wemm | Description : Place the cursor after the last non-pad character in
18150e3d5408SPeter Wemm | the field. If the field occupies the last position in
18164a1a9510SRong-En Fan | the buffer, the cursor is positioned on the last
18170e3d5408SPeter Wemm | character.
18180e3d5408SPeter Wemm |
18190e3d5408SPeter Wemm | Return Values : E_OK - success
18200e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
18214a1a9510SRong-En Fan static int
IFN_End_Of_Field(FORM * form)18224a1a9510SRong-En Fan IFN_End_Of_Field(FORM *form)
18230e3d5408SPeter Wemm {
18240e3d5408SPeter Wemm FIELD *field = form->current;
18254a1a9510SRong-En Fan FIELD_CELL *pos;
18260e3d5408SPeter Wemm
182706bfebdeSXin LI T((T_CALLED("IFN_End_Of_Field(%p)"), (void *)form));
18280e3d5408SPeter Wemm Synchronize_Buffer(form);
18290e3d5408SPeter Wemm pos = After_End_Of_Data(field->buf, Buffer_Length(field));
18300e3d5408SPeter Wemm if (pos == (field->buf + Buffer_Length(field)))
18310e3d5408SPeter Wemm pos--;
18320e3d5408SPeter Wemm Adjust_Cursor_Position(form, pos);
18334a1a9510SRong-En Fan returnCode(E_OK);
18340e3d5408SPeter Wemm }
18350e3d5408SPeter Wemm
18360e3d5408SPeter Wemm /*---------------------------------------------------------------------------
18370e3d5408SPeter Wemm | Facility : libnform
18380e3d5408SPeter Wemm | Function : static int IFN_Beginning_Of_Line(FORM * form)
18390e3d5408SPeter Wemm |
18400e3d5408SPeter Wemm | Description : Place the cursor on the first non-pad character in
18410e3d5408SPeter Wemm | the current line of the field.
18420e3d5408SPeter Wemm |
18430e3d5408SPeter Wemm | Return Values : E_OK - success
18440e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
18454a1a9510SRong-En Fan static int
IFN_Beginning_Of_Line(FORM * form)18464a1a9510SRong-En Fan IFN_Beginning_Of_Line(FORM *form)
18470e3d5408SPeter Wemm {
18480e3d5408SPeter Wemm FIELD *field = form->current;
18490e3d5408SPeter Wemm
185006bfebdeSXin LI T((T_CALLED("IFN_Beginning_Of_Line(%p)"), (void *)form));
18510e3d5408SPeter Wemm Synchronize_Buffer(form);
18520e3d5408SPeter Wemm Adjust_Cursor_Position(form,
18530e3d5408SPeter Wemm Get_Start_Of_Data(Address_Of_Current_Row_In_Buffer(form),
18540e3d5408SPeter Wemm field->dcols));
18554a1a9510SRong-En Fan returnCode(E_OK);
18560e3d5408SPeter Wemm }
18570e3d5408SPeter Wemm
18580e3d5408SPeter Wemm /*---------------------------------------------------------------------------
18590e3d5408SPeter Wemm | Facility : libnform
18600e3d5408SPeter Wemm | Function : static int IFN_End_Of_Line(FORM * form)
18610e3d5408SPeter Wemm |
18620e3d5408SPeter Wemm | Description : Place the cursor after the last non-pad character in the
18630e3d5408SPeter Wemm | current line of the field. If the field occupies the
18640e3d5408SPeter Wemm | last column in the line, the cursor is positioned on the
18650e3d5408SPeter Wemm | last character of the line.
18660e3d5408SPeter Wemm |
18670e3d5408SPeter Wemm | Return Values : E_OK - success
18680e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
18694a1a9510SRong-En Fan static int
IFN_End_Of_Line(FORM * form)18704a1a9510SRong-En Fan IFN_End_Of_Line(FORM *form)
18710e3d5408SPeter Wemm {
18720e3d5408SPeter Wemm FIELD *field = form->current;
18734a1a9510SRong-En Fan FIELD_CELL *pos;
18744a1a9510SRong-En Fan FIELD_CELL *bp;
18750e3d5408SPeter Wemm
187606bfebdeSXin LI T((T_CALLED("IFN_End_Of_Line(%p)"), (void *)form));
18770e3d5408SPeter Wemm Synchronize_Buffer(form);
18780e3d5408SPeter Wemm bp = Address_Of_Current_Row_In_Buffer(form);
18790e3d5408SPeter Wemm pos = After_End_Of_Data(bp, field->dcols);
18800e3d5408SPeter Wemm if (pos == (bp + field->dcols))
18810e3d5408SPeter Wemm pos--;
18820e3d5408SPeter Wemm Adjust_Cursor_Position(form, pos);
18834a1a9510SRong-En Fan returnCode(E_OK);
18840e3d5408SPeter Wemm }
18850e3d5408SPeter Wemm
18860e3d5408SPeter Wemm /*---------------------------------------------------------------------------
18870e3d5408SPeter Wemm | Facility : libnform
18880e3d5408SPeter Wemm | Function : static int IFN_Left_Character(FORM * form)
18890e3d5408SPeter Wemm |
18900e3d5408SPeter Wemm | Description : Move one character to the left in the current line.
18910e3d5408SPeter Wemm | This doesn't cycle.
18920e3d5408SPeter Wemm |
18930e3d5408SPeter Wemm | Return Values : E_OK - success
18940e3d5408SPeter Wemm | E_REQUEST_DENIED - already in first column
18950e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
18964a1a9510SRong-En Fan static int
IFN_Left_Character(FORM * form)18974a1a9510SRong-En Fan IFN_Left_Character(FORM *form)
18980e3d5408SPeter Wemm {
18994a1a9510SRong-En Fan int amount = myWCWIDTH(form->w, form->currow, form->curcol - 1);
19004a1a9510SRong-En Fan int oldcol = form->curcol;
19014a1a9510SRong-En Fan
190206bfebdeSXin LI T((T_CALLED("IFN_Left_Character(%p)"), (void *)form));
19034a1a9510SRong-En Fan if ((form->curcol -= amount) < 0)
19040e3d5408SPeter Wemm {
19054a1a9510SRong-En Fan form->curcol = oldcol;
19064a1a9510SRong-En Fan returnCode(E_REQUEST_DENIED);
19070e3d5408SPeter Wemm }
19084a1a9510SRong-En Fan returnCode(E_OK);
19090e3d5408SPeter Wemm }
19100e3d5408SPeter Wemm
19110e3d5408SPeter Wemm /*---------------------------------------------------------------------------
19120e3d5408SPeter Wemm | Facility : libnform
19130e3d5408SPeter Wemm | Function : static int IFN_Right_Character(FORM * form)
19140e3d5408SPeter Wemm |
19150e3d5408SPeter Wemm | Description : Move one character to the right in the current line.
19160e3d5408SPeter Wemm | This doesn't cycle.
19170e3d5408SPeter Wemm |
19180e3d5408SPeter Wemm | Return Values : E_OK - success
19190e3d5408SPeter Wemm | E_REQUEST_DENIED - already in last column
19200e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
19214a1a9510SRong-En Fan static int
IFN_Right_Character(FORM * form)19224a1a9510SRong-En Fan IFN_Right_Character(FORM *form)
19230e3d5408SPeter Wemm {
19244a1a9510SRong-En Fan int amount = myWCWIDTH(form->w, form->currow, form->curcol);
19254a1a9510SRong-En Fan int oldcol = form->curcol;
19264a1a9510SRong-En Fan
192706bfebdeSXin LI T((T_CALLED("IFN_Right_Character(%p)"), (void *)form));
19284a1a9510SRong-En Fan if ((form->curcol += amount) >= form->current->dcols)
19290e3d5408SPeter Wemm {
19300e3d5408SPeter Wemm #if GROW_IF_NAVIGATE
19310e3d5408SPeter Wemm FIELD *field = form->current;
19324a1a9510SRong-En Fan
19330e3d5408SPeter Wemm if (Single_Line_Field(field) && Field_Grown(field, 1))
19344a1a9510SRong-En Fan returnCode(E_OK);
19350e3d5408SPeter Wemm #endif
19364a1a9510SRong-En Fan form->curcol = oldcol;
19374a1a9510SRong-En Fan returnCode(E_REQUEST_DENIED);
19380e3d5408SPeter Wemm }
19394a1a9510SRong-En Fan returnCode(E_OK);
19400e3d5408SPeter Wemm }
19410e3d5408SPeter Wemm
19420e3d5408SPeter Wemm /*---------------------------------------------------------------------------
19430e3d5408SPeter Wemm | Facility : libnform
19440e3d5408SPeter Wemm | Function : static int IFN_Up_Character(FORM * form)
19450e3d5408SPeter Wemm |
19460e3d5408SPeter Wemm | Description : Move one line up. This doesn't cycle through the lines
19470e3d5408SPeter Wemm | of the field.
19480e3d5408SPeter Wemm |
19490e3d5408SPeter Wemm | Return Values : E_OK - success
19500e3d5408SPeter Wemm | E_REQUEST_DENIED - already in last column
19510e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
19524a1a9510SRong-En Fan static int
IFN_Up_Character(FORM * form)19534a1a9510SRong-En Fan IFN_Up_Character(FORM *form)
19540e3d5408SPeter Wemm {
195506bfebdeSXin LI T((T_CALLED("IFN_Up_Character(%p)"), (void *)form));
19560e3d5408SPeter Wemm if ((--(form->currow)) < 0)
19570e3d5408SPeter Wemm {
19580e3d5408SPeter Wemm form->currow++;
19594a1a9510SRong-En Fan returnCode(E_REQUEST_DENIED);
19600e3d5408SPeter Wemm }
19614a1a9510SRong-En Fan returnCode(E_OK);
19620e3d5408SPeter Wemm }
19630e3d5408SPeter Wemm
19640e3d5408SPeter Wemm /*---------------------------------------------------------------------------
19650e3d5408SPeter Wemm | Facility : libnform
19660e3d5408SPeter Wemm | Function : static int IFN_Down_Character(FORM * form)
19670e3d5408SPeter Wemm |
19680e3d5408SPeter Wemm | Description : Move one line down. This doesn't cycle through the
19690e3d5408SPeter Wemm | lines of the field.
19700e3d5408SPeter Wemm |
19710e3d5408SPeter Wemm | Return Values : E_OK - success
19720e3d5408SPeter Wemm | E_REQUEST_DENIED - already in last column
19730e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
19744a1a9510SRong-En Fan static int
IFN_Down_Character(FORM * form)19754a1a9510SRong-En Fan IFN_Down_Character(FORM *form)
19760e3d5408SPeter Wemm {
19770e3d5408SPeter Wemm FIELD *field = form->current;
19780e3d5408SPeter Wemm
197906bfebdeSXin LI T((T_CALLED("IFN_Down_Character(%p)"), (void *)form));
19800e3d5408SPeter Wemm if ((++(form->currow)) == field->drows)
19810e3d5408SPeter Wemm {
19820e3d5408SPeter Wemm #if GROW_IF_NAVIGATE
19830e3d5408SPeter Wemm if (!Single_Line_Field(field) && Field_Grown(field, 1))
19844a1a9510SRong-En Fan returnCode(E_OK);
19850e3d5408SPeter Wemm #endif
19860e3d5408SPeter Wemm --(form->currow);
19874a1a9510SRong-En Fan returnCode(E_REQUEST_DENIED);
19880e3d5408SPeter Wemm }
19894a1a9510SRong-En Fan returnCode(E_OK);
19900e3d5408SPeter Wemm }
19910e3d5408SPeter Wemm /*----------------------------------------------------------------------------
19920e3d5408SPeter Wemm END of Intra-Field Navigation routines
19930e3d5408SPeter Wemm --------------------------------------------------------------------------*/
19944a1a9510SRong-En Fan
19950e3d5408SPeter Wemm /*----------------------------------------------------------------------------
19960e3d5408SPeter Wemm Vertical scrolling helper routines
19970e3d5408SPeter Wemm --------------------------------------------------------------------------*/
19980e3d5408SPeter Wemm
19990e3d5408SPeter Wemm /*---------------------------------------------------------------------------
20000e3d5408SPeter Wemm | Facility : libnform
20014a1a9510SRong-En Fan | Function : static int VSC_Generic(FORM *form, int nlines)
20020e3d5408SPeter Wemm |
20034a1a9510SRong-En Fan | Description : Scroll multi-line field forward (nlines>0) or
20044a1a9510SRong-En Fan | backward (nlines<0) this many lines.
20050e3d5408SPeter Wemm |
20060e3d5408SPeter Wemm | Return Values : E_OK - success
20070e3d5408SPeter Wemm | E_REQUEST_DENIED - can't scroll
20080e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
20094a1a9510SRong-En Fan static int
VSC_Generic(FORM * form,int nlines)20104a1a9510SRong-En Fan VSC_Generic(FORM *form, int nlines)
20110e3d5408SPeter Wemm {
20120e3d5408SPeter Wemm FIELD *field = form->current;
20130e3d5408SPeter Wemm int res = E_REQUEST_DENIED;
20144a1a9510SRong-En Fan int rows_to_go = (nlines > 0 ? nlines : -nlines);
20150e3d5408SPeter Wemm
20164a1a9510SRong-En Fan if (nlines > 0)
20170e3d5408SPeter Wemm {
20180e3d5408SPeter Wemm if ((rows_to_go + form->toprow) > (field->drows - field->rows))
20190e3d5408SPeter Wemm rows_to_go = (field->drows - field->rows - form->toprow);
20200e3d5408SPeter Wemm
20210e3d5408SPeter Wemm if (rows_to_go > 0)
20220e3d5408SPeter Wemm {
20230e3d5408SPeter Wemm form->currow += rows_to_go;
20240e3d5408SPeter Wemm form->toprow += rows_to_go;
20250e3d5408SPeter Wemm res = E_OK;
20260e3d5408SPeter Wemm }
20270e3d5408SPeter Wemm }
20280e3d5408SPeter Wemm else
20290e3d5408SPeter Wemm {
20300e3d5408SPeter Wemm if (rows_to_go > form->toprow)
20310e3d5408SPeter Wemm rows_to_go = form->toprow;
20320e3d5408SPeter Wemm
20330e3d5408SPeter Wemm if (rows_to_go > 0)
20340e3d5408SPeter Wemm {
20350e3d5408SPeter Wemm form->currow -= rows_to_go;
20360e3d5408SPeter Wemm form->toprow -= rows_to_go;
20370e3d5408SPeter Wemm res = E_OK;
20380e3d5408SPeter Wemm }
20390e3d5408SPeter Wemm }
20400e3d5408SPeter Wemm return (res);
20410e3d5408SPeter Wemm }
20420e3d5408SPeter Wemm /*----------------------------------------------------------------------------
20430e3d5408SPeter Wemm End of Vertical scrolling helper routines
20440e3d5408SPeter Wemm --------------------------------------------------------------------------*/
20454a1a9510SRong-En Fan
20460e3d5408SPeter Wemm /*----------------------------------------------------------------------------
20470e3d5408SPeter Wemm Vertical scrolling routines
20480e3d5408SPeter Wemm --------------------------------------------------------------------------*/
20490e3d5408SPeter Wemm
20500e3d5408SPeter Wemm /*---------------------------------------------------------------------------
20510e3d5408SPeter Wemm | Facility : libnform
20520e3d5408SPeter Wemm | Function : static int Vertical_Scrolling(
20530e3d5408SPeter Wemm | int (* const fct) (FORM *),
20540e3d5408SPeter Wemm | FORM * form)
20550e3d5408SPeter Wemm |
20560e3d5408SPeter Wemm | Description : Performs the generic vertical scrolling routines.
20570e3d5408SPeter Wemm | This has to check for a multi-line field and to set
20584a1a9510SRong-En Fan | the _NEWTOP flag if scrolling really occurred.
20590e3d5408SPeter Wemm |
20600e3d5408SPeter Wemm | Return Values : Propagated error code from low-level driver calls
20610e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
20624a1a9510SRong-En Fan static int
Vertical_Scrolling(int (* const fct)(FORM *),FORM * form)20634a1a9510SRong-En Fan Vertical_Scrolling(int (*const fct) (FORM *), FORM *form)
20640e3d5408SPeter Wemm {
20650e3d5408SPeter Wemm int res = E_REQUEST_DENIED;
20660e3d5408SPeter Wemm
20670e3d5408SPeter Wemm if (!Single_Line_Field(form->current))
20680e3d5408SPeter Wemm {
20690e3d5408SPeter Wemm res = fct(form);
20700e3d5408SPeter Wemm if (res == E_OK)
2071aae38d10SBaptiste Daroussin SetStatus(form->current, _NEWTOP);
20720e3d5408SPeter Wemm }
20730e3d5408SPeter Wemm return (res);
20740e3d5408SPeter Wemm }
20750e3d5408SPeter Wemm
20760e3d5408SPeter Wemm /*---------------------------------------------------------------------------
20770e3d5408SPeter Wemm | Facility : libnform
20780e3d5408SPeter Wemm | Function : static int VSC_Scroll_Line_Forward(FORM * form)
20790e3d5408SPeter Wemm |
20800e3d5408SPeter Wemm | Description : Scroll multi-line field forward a line
20810e3d5408SPeter Wemm |
20820e3d5408SPeter Wemm | Return Values : E_OK - success
20830e3d5408SPeter Wemm | E_REQUEST_DENIED - no data ahead
20840e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
20854a1a9510SRong-En Fan static int
VSC_Scroll_Line_Forward(FORM * form)20864a1a9510SRong-En Fan VSC_Scroll_Line_Forward(FORM *form)
20870e3d5408SPeter Wemm {
208806bfebdeSXin LI T((T_CALLED("VSC_Scroll_Line_Forward(%p)"), (void *)form));
20894a1a9510SRong-En Fan returnCode(VSC_Generic(form, 1));
20900e3d5408SPeter Wemm }
20910e3d5408SPeter Wemm
20920e3d5408SPeter Wemm /*---------------------------------------------------------------------------
20930e3d5408SPeter Wemm | Facility : libnform
20940e3d5408SPeter Wemm | Function : static int VSC_Scroll_Line_Backward(FORM * form)
20950e3d5408SPeter Wemm |
20960e3d5408SPeter Wemm | Description : Scroll multi-line field backward a line
20970e3d5408SPeter Wemm |
20980e3d5408SPeter Wemm | Return Values : E_OK - success
20990e3d5408SPeter Wemm | E_REQUEST_DENIED - no data behind
21000e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
21014a1a9510SRong-En Fan static int
VSC_Scroll_Line_Backward(FORM * form)21024a1a9510SRong-En Fan VSC_Scroll_Line_Backward(FORM *form)
21030e3d5408SPeter Wemm {
210406bfebdeSXin LI T((T_CALLED("VSC_Scroll_Line_Backward(%p)"), (void *)form));
21054a1a9510SRong-En Fan returnCode(VSC_Generic(form, -1));
21060e3d5408SPeter Wemm }
21070e3d5408SPeter Wemm
21080e3d5408SPeter Wemm /*---------------------------------------------------------------------------
21090e3d5408SPeter Wemm | Facility : libnform
21100e3d5408SPeter Wemm | Function : static int VSC_Scroll_Page_Forward(FORM * form)
21110e3d5408SPeter Wemm |
21120e3d5408SPeter Wemm | Description : Scroll a multi-line field forward a page
21130e3d5408SPeter Wemm |
21140e3d5408SPeter Wemm | Return Values : E_OK - success
21150e3d5408SPeter Wemm | E_REQUEST_DENIED - no data ahead
21160e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
21174a1a9510SRong-En Fan static int
VSC_Scroll_Page_Forward(FORM * form)21184a1a9510SRong-En Fan VSC_Scroll_Page_Forward(FORM *form)
21190e3d5408SPeter Wemm {
212006bfebdeSXin LI T((T_CALLED("VSC_Scroll_Page_Forward(%p)"), (void *)form));
21214a1a9510SRong-En Fan returnCode(VSC_Generic(form, form->current->rows));
21220e3d5408SPeter Wemm }
21230e3d5408SPeter Wemm
21240e3d5408SPeter Wemm /*---------------------------------------------------------------------------
21250e3d5408SPeter Wemm | Facility : libnform
21260e3d5408SPeter Wemm | Function : static int VSC_Scroll_Half_Page_Forward(FORM * form)
21270e3d5408SPeter Wemm |
21280e3d5408SPeter Wemm | Description : Scroll a multi-line field forward half a page
21290e3d5408SPeter Wemm |
21300e3d5408SPeter Wemm | Return Values : E_OK - success
21310e3d5408SPeter Wemm | E_REQUEST_DENIED - no data ahead
21320e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
21334a1a9510SRong-En Fan static int
VSC_Scroll_Half_Page_Forward(FORM * form)21344a1a9510SRong-En Fan VSC_Scroll_Half_Page_Forward(FORM *form)
21350e3d5408SPeter Wemm {
213606bfebdeSXin LI T((T_CALLED("VSC_Scroll_Half_Page_Forward(%p)"), (void *)form));
21374a1a9510SRong-En Fan returnCode(VSC_Generic(form, (form->current->rows + 1) / 2));
21380e3d5408SPeter Wemm }
21390e3d5408SPeter Wemm
21400e3d5408SPeter Wemm /*---------------------------------------------------------------------------
21410e3d5408SPeter Wemm | Facility : libnform
21420e3d5408SPeter Wemm | Function : static int VSC_Scroll_Page_Backward(FORM * form)
21430e3d5408SPeter Wemm |
21440e3d5408SPeter Wemm | Description : Scroll a multi-line field backward a page
21450e3d5408SPeter Wemm |
21460e3d5408SPeter Wemm | Return Values : E_OK - success
21470e3d5408SPeter Wemm | E_REQUEST_DENIED - no data behind
21480e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
21494a1a9510SRong-En Fan static int
VSC_Scroll_Page_Backward(FORM * form)21504a1a9510SRong-En Fan VSC_Scroll_Page_Backward(FORM *form)
21510e3d5408SPeter Wemm {
215206bfebdeSXin LI T((T_CALLED("VSC_Scroll_Page_Backward(%p)"), (void *)form));
21534a1a9510SRong-En Fan returnCode(VSC_Generic(form, -(form->current->rows)));
21540e3d5408SPeter Wemm }
21550e3d5408SPeter Wemm
21560e3d5408SPeter Wemm /*---------------------------------------------------------------------------
21570e3d5408SPeter Wemm | Facility : libnform
21580e3d5408SPeter Wemm | Function : static int VSC_Scroll_Half_Page_Backward(FORM * form)
21590e3d5408SPeter Wemm |
21600e3d5408SPeter Wemm | Description : Scroll a multi-line field backward half a page
21610e3d5408SPeter Wemm |
21620e3d5408SPeter Wemm | Return Values : E_OK - success
21630e3d5408SPeter Wemm | E_REQUEST_DENIED - no data behind
21640e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
21654a1a9510SRong-En Fan static int
VSC_Scroll_Half_Page_Backward(FORM * form)21664a1a9510SRong-En Fan VSC_Scroll_Half_Page_Backward(FORM *form)
21670e3d5408SPeter Wemm {
216806bfebdeSXin LI T((T_CALLED("VSC_Scroll_Half_Page_Backward(%p)"), (void *)form));
21694a1a9510SRong-En Fan returnCode(VSC_Generic(form, -((form->current->rows + 1) / 2)));
21700e3d5408SPeter Wemm }
21710e3d5408SPeter Wemm /*----------------------------------------------------------------------------
21720e3d5408SPeter Wemm End of Vertical scrolling routines
21730e3d5408SPeter Wemm --------------------------------------------------------------------------*/
21744a1a9510SRong-En Fan
21750e3d5408SPeter Wemm /*----------------------------------------------------------------------------
21760e3d5408SPeter Wemm Horizontal scrolling helper routines
21770e3d5408SPeter Wemm --------------------------------------------------------------------------*/
21780e3d5408SPeter Wemm
21790e3d5408SPeter Wemm /*---------------------------------------------------------------------------
21800e3d5408SPeter Wemm | Facility : libnform
21814a1a9510SRong-En Fan | Function : static int HSC_Generic(FORM *form, int ncolumns)
21820e3d5408SPeter Wemm |
21834a1a9510SRong-En Fan | Description : Scroll single-line field forward (ncolumns>0) or
21844a1a9510SRong-En Fan | backward (ncolumns<0) this many columns.
21850e3d5408SPeter Wemm |
21860e3d5408SPeter Wemm | Return Values : E_OK - success
21870e3d5408SPeter Wemm | E_REQUEST_DENIED - can't scroll
21880e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
21894a1a9510SRong-En Fan static int
HSC_Generic(FORM * form,int ncolumns)21904a1a9510SRong-En Fan HSC_Generic(FORM *form, int ncolumns)
21910e3d5408SPeter Wemm {
21920e3d5408SPeter Wemm FIELD *field = form->current;
21930e3d5408SPeter Wemm int res = E_REQUEST_DENIED;
21944a1a9510SRong-En Fan int cols_to_go = (ncolumns > 0 ? ncolumns : -ncolumns);
21950e3d5408SPeter Wemm
21964a1a9510SRong-En Fan if (ncolumns > 0)
21970e3d5408SPeter Wemm {
21980e3d5408SPeter Wemm if ((cols_to_go + form->begincol) > (field->dcols - field->cols))
21990e3d5408SPeter Wemm cols_to_go = field->dcols - field->cols - form->begincol;
22000e3d5408SPeter Wemm
22010e3d5408SPeter Wemm if (cols_to_go > 0)
22020e3d5408SPeter Wemm {
22030e3d5408SPeter Wemm form->curcol += cols_to_go;
22040e3d5408SPeter Wemm form->begincol += cols_to_go;
22050e3d5408SPeter Wemm res = E_OK;
22060e3d5408SPeter Wemm }
22070e3d5408SPeter Wemm }
22080e3d5408SPeter Wemm else
22090e3d5408SPeter Wemm {
22100e3d5408SPeter Wemm if (cols_to_go > form->begincol)
22110e3d5408SPeter Wemm cols_to_go = form->begincol;
22120e3d5408SPeter Wemm
22130e3d5408SPeter Wemm if (cols_to_go > 0)
22140e3d5408SPeter Wemm {
22150e3d5408SPeter Wemm form->curcol -= cols_to_go;
22160e3d5408SPeter Wemm form->begincol -= cols_to_go;
22170e3d5408SPeter Wemm res = E_OK;
22180e3d5408SPeter Wemm }
22190e3d5408SPeter Wemm }
22200e3d5408SPeter Wemm return (res);
22210e3d5408SPeter Wemm }
22220e3d5408SPeter Wemm /*----------------------------------------------------------------------------
22230e3d5408SPeter Wemm End of Horizontal scrolling helper routines
22240e3d5408SPeter Wemm --------------------------------------------------------------------------*/
22254a1a9510SRong-En Fan
22260e3d5408SPeter Wemm /*----------------------------------------------------------------------------
22270e3d5408SPeter Wemm Horizontal scrolling routines
22280e3d5408SPeter Wemm --------------------------------------------------------------------------*/
22290e3d5408SPeter Wemm
22300e3d5408SPeter Wemm /*---------------------------------------------------------------------------
22310e3d5408SPeter Wemm | Facility : libnform
22320e3d5408SPeter Wemm | Function : static int Horizontal_Scrolling(
22330e3d5408SPeter Wemm | int (* const fct) (FORM *),
22340e3d5408SPeter Wemm | FORM * form)
22350e3d5408SPeter Wemm |
22360e3d5408SPeter Wemm | Description : Performs the generic horizontal scrolling routines.
22370e3d5408SPeter Wemm | This has to check for a single-line field.
22380e3d5408SPeter Wemm |
22390e3d5408SPeter Wemm | Return Values : Propagated error code from low-level driver calls
22400e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
22414a1a9510SRong-En Fan static int
Horizontal_Scrolling(int (* const fct)(FORM *),FORM * form)22424a1a9510SRong-En Fan Horizontal_Scrolling(int (*const fct) (FORM *), FORM *form)
22430e3d5408SPeter Wemm {
22440e3d5408SPeter Wemm if (Single_Line_Field(form->current))
22450e3d5408SPeter Wemm return fct(form);
22460e3d5408SPeter Wemm else
22470e3d5408SPeter Wemm return (E_REQUEST_DENIED);
22480e3d5408SPeter Wemm }
22490e3d5408SPeter Wemm
22500e3d5408SPeter Wemm /*---------------------------------------------------------------------------
22510e3d5408SPeter Wemm | Facility : libnform
22520e3d5408SPeter Wemm | Function : static int HSC_Scroll_Char_Forward(FORM * form)
22530e3d5408SPeter Wemm |
22540e3d5408SPeter Wemm | Description : Scroll single-line field forward a character
22550e3d5408SPeter Wemm |
22560e3d5408SPeter Wemm | Return Values : E_OK - success
22570e3d5408SPeter Wemm | E_REQUEST_DENIED - no data ahead
22580e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
22594a1a9510SRong-En Fan static int
HSC_Scroll_Char_Forward(FORM * form)22604a1a9510SRong-En Fan HSC_Scroll_Char_Forward(FORM *form)
22610e3d5408SPeter Wemm {
226206bfebdeSXin LI T((T_CALLED("HSC_Scroll_Char_Forward(%p)"), (void *)form));
22634a1a9510SRong-En Fan returnCode(HSC_Generic(form, 1));
22640e3d5408SPeter Wemm }
22650e3d5408SPeter Wemm
22660e3d5408SPeter Wemm /*---------------------------------------------------------------------------
22670e3d5408SPeter Wemm | Facility : libnform
22680e3d5408SPeter Wemm | Function : static int HSC_Scroll_Char_Backward(FORM * form)
22690e3d5408SPeter Wemm |
22700e3d5408SPeter Wemm | Description : Scroll single-line field backward a character
22710e3d5408SPeter Wemm |
22720e3d5408SPeter Wemm | Return Values : E_OK - success
22730e3d5408SPeter Wemm | E_REQUEST_DENIED - no data behind
22740e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
22754a1a9510SRong-En Fan static int
HSC_Scroll_Char_Backward(FORM * form)22764a1a9510SRong-En Fan HSC_Scroll_Char_Backward(FORM *form)
22770e3d5408SPeter Wemm {
227806bfebdeSXin LI T((T_CALLED("HSC_Scroll_Char_Backward(%p)"), (void *)form));
22794a1a9510SRong-En Fan returnCode(HSC_Generic(form, -1));
22800e3d5408SPeter Wemm }
22810e3d5408SPeter Wemm
22820e3d5408SPeter Wemm /*---------------------------------------------------------------------------
22830e3d5408SPeter Wemm | Facility : libnform
22840e3d5408SPeter Wemm | Function : static int HSC_Horizontal_Line_Forward(FORM* form)
22850e3d5408SPeter Wemm |
22860e3d5408SPeter Wemm | Description : Scroll single-line field forward a line
22870e3d5408SPeter Wemm |
22880e3d5408SPeter Wemm | Return Values : E_OK - success
22890e3d5408SPeter Wemm | E_REQUEST_DENIED - no data ahead
22900e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
22914a1a9510SRong-En Fan static int
HSC_Horizontal_Line_Forward(FORM * form)22924a1a9510SRong-En Fan HSC_Horizontal_Line_Forward(FORM *form)
22930e3d5408SPeter Wemm {
229406bfebdeSXin LI T((T_CALLED("HSC_Horizontal_Line_Forward(%p)"), (void *)form));
22954a1a9510SRong-En Fan returnCode(HSC_Generic(form, form->current->cols));
22960e3d5408SPeter Wemm }
22970e3d5408SPeter Wemm
22980e3d5408SPeter Wemm /*---------------------------------------------------------------------------
22990e3d5408SPeter Wemm | Facility : libnform
23000e3d5408SPeter Wemm | Function : static int HSC_Horizontal_Half_Line_Forward(FORM* form)
23010e3d5408SPeter Wemm |
23020e3d5408SPeter Wemm | Description : Scroll single-line field forward half a line
23030e3d5408SPeter Wemm |
23040e3d5408SPeter Wemm | Return Values : E_OK - success
23050e3d5408SPeter Wemm | E_REQUEST_DENIED - no data ahead
23060e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
23074a1a9510SRong-En Fan static int
HSC_Horizontal_Half_Line_Forward(FORM * form)23084a1a9510SRong-En Fan HSC_Horizontal_Half_Line_Forward(FORM *form)
23090e3d5408SPeter Wemm {
231006bfebdeSXin LI T((T_CALLED("HSC_Horizontal_Half_Line_Forward(%p)"), (void *)form));
23114a1a9510SRong-En Fan returnCode(HSC_Generic(form, (form->current->cols + 1) / 2));
23120e3d5408SPeter Wemm }
23130e3d5408SPeter Wemm
23140e3d5408SPeter Wemm /*---------------------------------------------------------------------------
23150e3d5408SPeter Wemm | Facility : libnform
23160e3d5408SPeter Wemm | Function : static int HSC_Horizontal_Line_Backward(FORM* form)
23170e3d5408SPeter Wemm |
23180e3d5408SPeter Wemm | Description : Scroll single-line field backward a line
23190e3d5408SPeter Wemm |
23200e3d5408SPeter Wemm | Return Values : E_OK - success
23210e3d5408SPeter Wemm | E_REQUEST_DENIED - no data behind
23220e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
23234a1a9510SRong-En Fan static int
HSC_Horizontal_Line_Backward(FORM * form)23244a1a9510SRong-En Fan HSC_Horizontal_Line_Backward(FORM *form)
23250e3d5408SPeter Wemm {
232606bfebdeSXin LI T((T_CALLED("HSC_Horizontal_Line_Backward(%p)"), (void *)form));
23274a1a9510SRong-En Fan returnCode(HSC_Generic(form, -(form->current->cols)));
23280e3d5408SPeter Wemm }
23290e3d5408SPeter Wemm
23300e3d5408SPeter Wemm /*---------------------------------------------------------------------------
23310e3d5408SPeter Wemm | Facility : libnform
23320e3d5408SPeter Wemm | Function : static int HSC_Horizontal_Half_Line_Backward(FORM* form)
23330e3d5408SPeter Wemm |
23340e3d5408SPeter Wemm | Description : Scroll single-line field backward half a line
23350e3d5408SPeter Wemm |
23360e3d5408SPeter Wemm | Return Values : E_OK - success
23370e3d5408SPeter Wemm | E_REQUEST_DENIED - no data behind
23380e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
23394a1a9510SRong-En Fan static int
HSC_Horizontal_Half_Line_Backward(FORM * form)23404a1a9510SRong-En Fan HSC_Horizontal_Half_Line_Backward(FORM *form)
23410e3d5408SPeter Wemm {
234206bfebdeSXin LI T((T_CALLED("HSC_Horizontal_Half_Line_Backward(%p)"), (void *)form));
23434a1a9510SRong-En Fan returnCode(HSC_Generic(form, -((form->current->cols + 1) / 2)));
23440e3d5408SPeter Wemm }
23450e3d5408SPeter Wemm
23460e3d5408SPeter Wemm /*----------------------------------------------------------------------------
23470e3d5408SPeter Wemm End of Horizontal scrolling routines
23480e3d5408SPeter Wemm --------------------------------------------------------------------------*/
23494a1a9510SRong-En Fan
23500e3d5408SPeter Wemm /*----------------------------------------------------------------------------
23510e3d5408SPeter Wemm Helper routines for Field Editing
23520e3d5408SPeter Wemm --------------------------------------------------------------------------*/
23530e3d5408SPeter Wemm
23540e3d5408SPeter Wemm /*---------------------------------------------------------------------------
23550e3d5408SPeter Wemm | Facility : libnform
23560e3d5408SPeter Wemm | Function : static bool Is_There_Room_For_A_Line(FORM * form)
23570e3d5408SPeter Wemm |
23580e3d5408SPeter Wemm | Description : Check whether or not there is enough room in the
23590e3d5408SPeter Wemm | buffer to enter a whole line.
23600e3d5408SPeter Wemm |
23610e3d5408SPeter Wemm | Return Values : TRUE - there is enough space
23620e3d5408SPeter Wemm | FALSE - there is not enough space
23630e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
23644a1a9510SRong-En Fan NCURSES_INLINE static bool
Is_There_Room_For_A_Line(FORM * form)23654a1a9510SRong-En Fan Is_There_Room_For_A_Line(FORM *form)
23660e3d5408SPeter Wemm {
23670e3d5408SPeter Wemm FIELD *field = form->current;
23684a1a9510SRong-En Fan FIELD_CELL *begin_of_last_line, *s;
23690e3d5408SPeter Wemm
23700e3d5408SPeter Wemm Synchronize_Buffer(form);
23710e3d5408SPeter Wemm begin_of_last_line = Address_Of_Row_In_Buffer(field, (field->drows - 1));
23720e3d5408SPeter Wemm s = After_End_Of_Data(begin_of_last_line, field->dcols);
23730e3d5408SPeter Wemm return ((s == begin_of_last_line) ? TRUE : FALSE);
23740e3d5408SPeter Wemm }
23750e3d5408SPeter Wemm
23760e3d5408SPeter Wemm /*---------------------------------------------------------------------------
23770e3d5408SPeter Wemm | Facility : libnform
23780e3d5408SPeter Wemm | Function : static bool Is_There_Room_For_A_Char_In_Line(FORM * form)
23790e3d5408SPeter Wemm |
23800e3d5408SPeter Wemm | Description : Checks whether or not there is room for a new character
23810e3d5408SPeter Wemm | in the current line.
23820e3d5408SPeter Wemm |
23830e3d5408SPeter Wemm | Return Values : TRUE - there is room
23840e3d5408SPeter Wemm | FALSE - there is not enough room (line full)
23850e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
23864a1a9510SRong-En Fan NCURSES_INLINE static bool
Is_There_Room_For_A_Char_In_Line(FORM * form)23874a1a9510SRong-En Fan Is_There_Room_For_A_Char_In_Line(FORM *form)
23880e3d5408SPeter Wemm {
23890e3d5408SPeter Wemm int last_char_in_line;
23900e3d5408SPeter Wemm
23910e3d5408SPeter Wemm wmove(form->w, form->currow, form->current->dcols - 1);
23920e3d5408SPeter Wemm last_char_in_line = (int)(winch(form->w) & A_CHARTEXT);
23930e3d5408SPeter Wemm wmove(form->w, form->currow, form->curcol);
23940e3d5408SPeter Wemm return (((last_char_in_line == form->current->pad) ||
23950e3d5408SPeter Wemm is_blank(last_char_in_line)) ? TRUE : FALSE);
23960e3d5408SPeter Wemm }
23970e3d5408SPeter Wemm
23980e3d5408SPeter Wemm #define There_Is_No_Room_For_A_Char_In_Line(f) \
23990e3d5408SPeter Wemm !Is_There_Room_For_A_Char_In_Line(f)
24000e3d5408SPeter Wemm
24010e3d5408SPeter Wemm /*---------------------------------------------------------------------------
24020e3d5408SPeter Wemm | Facility : libnform
24030e3d5408SPeter Wemm | Function : static int Insert_String(
24040e3d5408SPeter Wemm | FORM * form,
24050e3d5408SPeter Wemm | int row,
24060e3d5408SPeter Wemm | char *txt,
24070e3d5408SPeter Wemm | int len )
24080e3d5408SPeter Wemm |
24090e3d5408SPeter Wemm | Description : Insert the 'len' characters beginning at pointer 'txt'
24100e3d5408SPeter Wemm | into the 'row' of the 'form'. The insertion occurs
24110e3d5408SPeter Wemm | on the beginning of the row, all other characters are
24120e3d5408SPeter Wemm | moved to the right. After the text a pad character will
24130e3d5408SPeter Wemm | be inserted to separate the text from the rest. If
24140e3d5408SPeter Wemm | necessary the insertion moves characters on the next
24150e3d5408SPeter Wemm | line to make place for the requested insertion string.
24160e3d5408SPeter Wemm |
24170e3d5408SPeter Wemm | Return Values : E_OK - success
24180e3d5408SPeter Wemm | E_REQUEST_DENIED -
24190e3d5408SPeter Wemm | E_SYSTEM_ERROR - system error
24200e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
24214a1a9510SRong-En Fan static int
Insert_String(FORM * form,int row,FIELD_CELL * txt,int len)24224a1a9510SRong-En Fan Insert_String(FORM *form, int row, FIELD_CELL *txt, int len)
24230e3d5408SPeter Wemm {
24240e3d5408SPeter Wemm FIELD *field = form->current;
24254a1a9510SRong-En Fan FIELD_CELL *bp = Address_Of_Row_In_Buffer(field, row);
24260e3d5408SPeter Wemm int datalen = (int)(After_End_Of_Data(bp, field->dcols) - bp);
24270e3d5408SPeter Wemm int freelen = field->dcols - datalen;
24280e3d5408SPeter Wemm int requiredlen = len + 1;
24290e3d5408SPeter Wemm int result = E_REQUEST_DENIED;
24300e3d5408SPeter Wemm
24310e3d5408SPeter Wemm if (freelen >= requiredlen)
24320e3d5408SPeter Wemm {
24330e3d5408SPeter Wemm wmove(form->w, row, 0);
24344a1a9510SRong-En Fan myINSNSTR(form->w, txt, len);
24350e3d5408SPeter Wemm wmove(form->w, row, len);
24364a1a9510SRong-En Fan myINSNSTR(form->w, &myBLANK, 1);
2437*21817992SBaptiste Daroussin result = E_OK;
24380e3d5408SPeter Wemm }
24390e3d5408SPeter Wemm else
24404a1a9510SRong-En Fan {
24414a1a9510SRong-En Fan /* we have to move characters on the next line. If we are on the
24420e3d5408SPeter Wemm last line this may work, if the field is growable */
24430e3d5408SPeter Wemm if ((row == (field->drows - 1)) && Growable(field))
24440e3d5408SPeter Wemm {
24450e3d5408SPeter Wemm if (!Field_Grown(field, 1))
24460e3d5408SPeter Wemm return (E_SYSTEM_ERROR);
24470e3d5408SPeter Wemm /* !!!Side-Effect : might be changed due to growth!!! */
24480e3d5408SPeter Wemm bp = Address_Of_Row_In_Buffer(field, row);
24490e3d5408SPeter Wemm }
24500e3d5408SPeter Wemm
24510e3d5408SPeter Wemm if (row < (field->drows - 1))
24520e3d5408SPeter Wemm {
2453*21817992SBaptiste Daroussin FIELD_CELL *split;
2454*21817992SBaptiste Daroussin
24554a1a9510SRong-En Fan split =
24564a1a9510SRong-En Fan After_Last_Whitespace_Character(bp,
24574a1a9510SRong-En Fan (int)(Get_Start_Of_Data(bp
24584a1a9510SRong-En Fan + field->dcols
24594a1a9510SRong-En Fan - requiredlen,
24604a1a9510SRong-En Fan requiredlen)
24614a1a9510SRong-En Fan - bp));
24620e3d5408SPeter Wemm /* split points now to the first character of the portion of the
24630e3d5408SPeter Wemm line that must be moved to the next line */
24640e3d5408SPeter Wemm datalen = (int)(split - bp); /* + freelen has to stay on this line */
24650e3d5408SPeter Wemm freelen = field->dcols - (datalen + freelen); /* for the next line */
24660e3d5408SPeter Wemm
24670e3d5408SPeter Wemm if ((result = Insert_String(form, row + 1, split, freelen)) == E_OK)
24680e3d5408SPeter Wemm {
24690e3d5408SPeter Wemm wmove(form->w, row, datalen);
24700e3d5408SPeter Wemm wclrtoeol(form->w);
24710e3d5408SPeter Wemm wmove(form->w, row, 0);
24724a1a9510SRong-En Fan myINSNSTR(form->w, txt, len);
24730e3d5408SPeter Wemm wmove(form->w, row, len);
24744a1a9510SRong-En Fan myINSNSTR(form->w, &myBLANK, 1);
24750e3d5408SPeter Wemm return E_OK;
24760e3d5408SPeter Wemm }
24770e3d5408SPeter Wemm }
24780e3d5408SPeter Wemm }
2479*21817992SBaptiste Daroussin return (result);
24800e3d5408SPeter Wemm }
24810e3d5408SPeter Wemm
24820e3d5408SPeter Wemm /*---------------------------------------------------------------------------
24830e3d5408SPeter Wemm | Facility : libnform
24840e3d5408SPeter Wemm | Function : static int Wrapping_Not_Necessary_Or_Wrapping_Ok(
24850e3d5408SPeter Wemm | FORM * form)
24860e3d5408SPeter Wemm |
24870e3d5408SPeter Wemm | Description : If a character has been entered into a field, it may
24880e3d5408SPeter Wemm | be that wrapping has to occur. This routine checks
24890e3d5408SPeter Wemm | whether or not wrapping is required and if so, performs
24900e3d5408SPeter Wemm | the wrapping.
24910e3d5408SPeter Wemm |
24920e3d5408SPeter Wemm | Return Values : E_OK - no wrapping required or wrapping
24934a1a9510SRong-En Fan | was successful
24940e3d5408SPeter Wemm | E_REQUEST_DENIED -
24950e3d5408SPeter Wemm | E_SYSTEM_ERROR - some system error
24960e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
24974a1a9510SRong-En Fan static int
Wrapping_Not_Necessary_Or_Wrapping_Ok(FORM * form)24984a1a9510SRong-En Fan Wrapping_Not_Necessary_Or_Wrapping_Ok(FORM *form)
24990e3d5408SPeter Wemm {
25000e3d5408SPeter Wemm FIELD *field = form->current;
25010e3d5408SPeter Wemm int result = E_REQUEST_DENIED;
25020e3d5408SPeter Wemm bool Last_Row = ((field->drows - 1) == form->currow);
25030e3d5408SPeter Wemm
2504aae38d10SBaptiste Daroussin if ((Field_Has_Option(field, O_WRAP)) && /* wrapping wanted */
25050e3d5408SPeter Wemm (!Single_Line_Field(field)) && /* must be multi-line */
25060e3d5408SPeter Wemm (There_Is_No_Room_For_A_Char_In_Line(form)) && /* line is full */
25070e3d5408SPeter Wemm (!Last_Row || Growable(field))) /* there are more lines */
25080e3d5408SPeter Wemm {
25094a1a9510SRong-En Fan FIELD_CELL *bp;
25104a1a9510SRong-En Fan FIELD_CELL *split;
25110e3d5408SPeter Wemm int chars_to_be_wrapped;
25120e3d5408SPeter Wemm int chars_to_remain_on_line;
25134a1a9510SRong-En Fan
25140e3d5408SPeter Wemm if (Last_Row)
25154a1a9510SRong-En Fan {
25164a1a9510SRong-En Fan /* the above logic already ensures, that in this case the field
25170e3d5408SPeter Wemm is growable */
25180e3d5408SPeter Wemm if (!Field_Grown(field, 1))
25190e3d5408SPeter Wemm return E_SYSTEM_ERROR;
25200e3d5408SPeter Wemm }
25210e3d5408SPeter Wemm bp = Address_Of_Current_Row_In_Buffer(form);
252206bfebdeSXin LI Window_To_Buffer(form, field);
25230e3d5408SPeter Wemm split = After_Last_Whitespace_Character(bp, field->dcols);
25240e3d5408SPeter Wemm /* split points to the first character of the sequence to be brought
25250e3d5408SPeter Wemm on the next line */
25260e3d5408SPeter Wemm chars_to_remain_on_line = (int)(split - bp);
25270e3d5408SPeter Wemm chars_to_be_wrapped = field->dcols - chars_to_remain_on_line;
25280e3d5408SPeter Wemm if (chars_to_remain_on_line > 0)
25290e3d5408SPeter Wemm {
25300e3d5408SPeter Wemm if ((result = Insert_String(form, form->currow + 1, split,
25310e3d5408SPeter Wemm chars_to_be_wrapped)) == E_OK)
25320e3d5408SPeter Wemm {
25330e3d5408SPeter Wemm wmove(form->w, form->currow, chars_to_remain_on_line);
25340e3d5408SPeter Wemm wclrtoeol(form->w);
25350e3d5408SPeter Wemm if (form->curcol >= chars_to_remain_on_line)
25360e3d5408SPeter Wemm {
25370e3d5408SPeter Wemm form->currow++;
25380e3d5408SPeter Wemm form->curcol -= chars_to_remain_on_line;
25390e3d5408SPeter Wemm }
25400e3d5408SPeter Wemm return E_OK;
25410e3d5408SPeter Wemm }
25420e3d5408SPeter Wemm }
25430e3d5408SPeter Wemm else
25440e3d5408SPeter Wemm return E_OK;
25450e3d5408SPeter Wemm if (result != E_OK)
25460e3d5408SPeter Wemm {
25474a1a9510SRong-En Fan DeleteChar(form);
254806bfebdeSXin LI Window_To_Buffer(form, field);
25490e3d5408SPeter Wemm result = E_REQUEST_DENIED;
25500e3d5408SPeter Wemm }
25510e3d5408SPeter Wemm }
25520e3d5408SPeter Wemm else
25530e3d5408SPeter Wemm result = E_OK; /* wrapping was not necessary */
25540e3d5408SPeter Wemm return (result);
25550e3d5408SPeter Wemm }
25564a1a9510SRong-En Fan
25570e3d5408SPeter Wemm /*----------------------------------------------------------------------------
25580e3d5408SPeter Wemm Field Editing routines
25590e3d5408SPeter Wemm --------------------------------------------------------------------------*/
25600e3d5408SPeter Wemm
25610e3d5408SPeter Wemm /*---------------------------------------------------------------------------
25620e3d5408SPeter Wemm | Facility : libnform
25630e3d5408SPeter Wemm | Function : static int Field_Editing(
25640e3d5408SPeter Wemm | int (* const fct) (FORM *),
25650e3d5408SPeter Wemm | FORM * form)
25660e3d5408SPeter Wemm |
25670e3d5408SPeter Wemm | Description : Generic routine for field editing requests. The driver
25680e3d5408SPeter Wemm | routines are only called for editable fields, the
25694a1a9510SRong-En Fan | _WINDOW_MODIFIED flag is set if editing occurred.
25700e3d5408SPeter Wemm | This is somewhat special due to the overload semantics
25710e3d5408SPeter Wemm | of the NEW_LINE and DEL_PREV requests.
25720e3d5408SPeter Wemm |
25730e3d5408SPeter Wemm | Return Values : Error code from low level drivers.
25740e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
25754a1a9510SRong-En Fan static int
Field_Editing(int (* const fct)(FORM *),FORM * form)25764a1a9510SRong-En Fan Field_Editing(int (*const fct) (FORM *), FORM *form)
25770e3d5408SPeter Wemm {
25780e3d5408SPeter Wemm int res = E_REQUEST_DENIED;
25790e3d5408SPeter Wemm
25800e3d5408SPeter Wemm /* We have to deal here with the specific case of the overloaded
25814a1a9510SRong-En Fan behavior of New_Line and Delete_Previous requests.
25820e3d5408SPeter Wemm They may end up in navigational requests if we are on the first
25830e3d5408SPeter Wemm character in a field. But navigation is also allowed on non-
25840e3d5408SPeter Wemm editable fields.
25850e3d5408SPeter Wemm */
25860e3d5408SPeter Wemm if ((fct == FE_Delete_Previous) &&
258773f0a83dSXin LI ((unsigned)form->opts & O_BS_OVERLOAD) &&
25880e3d5408SPeter Wemm First_Position_In_Current_Field(form))
25890e3d5408SPeter Wemm {
25900e3d5408SPeter Wemm res = Inter_Field_Navigation(FN_Previous_Field, form);
25910e3d5408SPeter Wemm }
25920e3d5408SPeter Wemm else
25930e3d5408SPeter Wemm {
25940e3d5408SPeter Wemm if (fct == FE_New_Line)
25950e3d5408SPeter Wemm {
259673f0a83dSXin LI if (((unsigned)form->opts & O_NL_OVERLOAD) &&
25970e3d5408SPeter Wemm First_Position_In_Current_Field(form))
25980e3d5408SPeter Wemm {
25990e3d5408SPeter Wemm res = Inter_Field_Navigation(FN_Next_Field, form);
26000e3d5408SPeter Wemm }
26010e3d5408SPeter Wemm else
26020e3d5408SPeter Wemm /* FE_New_Line deals itself with the _WINDOW_MODIFIED flag */
26030e3d5408SPeter Wemm res = fct(form);
26040e3d5408SPeter Wemm }
26050e3d5408SPeter Wemm else
26060e3d5408SPeter Wemm {
26070e3d5408SPeter Wemm /* From now on, everything must be editable */
260873f0a83dSXin LI if ((unsigned)form->current->opts & O_EDIT)
26090e3d5408SPeter Wemm {
26100e3d5408SPeter Wemm res = fct(form);
26110e3d5408SPeter Wemm if (res == E_OK)
261273f0a83dSXin LI SetStatus(form, _WINDOW_MODIFIED);
26130e3d5408SPeter Wemm }
26140e3d5408SPeter Wemm }
26150e3d5408SPeter Wemm }
26160e3d5408SPeter Wemm return res;
26170e3d5408SPeter Wemm }
26180e3d5408SPeter Wemm
26190e3d5408SPeter Wemm /*---------------------------------------------------------------------------
26200e3d5408SPeter Wemm | Facility : libnform
26210e3d5408SPeter Wemm | Function : static int FE_New_Line(FORM * form)
26220e3d5408SPeter Wemm |
26230e3d5408SPeter Wemm | Description : Perform a new line request. This is rather complex
26240e3d5408SPeter Wemm | compared to other routines in this code due to the
26250e3d5408SPeter Wemm | rather difficult to understand description in the
26260e3d5408SPeter Wemm | manuals.
26270e3d5408SPeter Wemm |
26280e3d5408SPeter Wemm | Return Values : E_OK - success
26290e3d5408SPeter Wemm | E_REQUEST_DENIED - new line not allowed
26300e3d5408SPeter Wemm | E_SYSTEM_ERROR - system error
26310e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
26324a1a9510SRong-En Fan static int
FE_New_Line(FORM * form)26334a1a9510SRong-En Fan FE_New_Line(FORM *form)
26340e3d5408SPeter Wemm {
26350e3d5408SPeter Wemm FIELD *field = form->current;
26364a1a9510SRong-En Fan FIELD_CELL *bp, *t;
26370e3d5408SPeter Wemm bool Last_Row = ((field->drows - 1) == form->currow);
26380e3d5408SPeter Wemm
263906bfebdeSXin LI T((T_CALLED("FE_New_Line(%p)"), (void *)form));
26400e3d5408SPeter Wemm if (form->status & _OVLMODE)
26410e3d5408SPeter Wemm {
26420e3d5408SPeter Wemm if (Last_Row &&
26430e3d5408SPeter Wemm (!(Growable(field) && !Single_Line_Field(field))))
26440e3d5408SPeter Wemm {
264573f0a83dSXin LI if (!((unsigned)form->opts & O_NL_OVERLOAD))
26464a1a9510SRong-En Fan returnCode(E_REQUEST_DENIED);
26474a1a9510SRong-En Fan wmove(form->w, form->currow, form->curcol);
26480e3d5408SPeter Wemm wclrtoeol(form->w);
26490e3d5408SPeter Wemm /* we have to set this here, although it is also
26500e3d5408SPeter Wemm handled in the generic routine. The reason is,
26510e3d5408SPeter Wemm that FN_Next_Field may fail, but the form is
26520e3d5408SPeter Wemm definitively changed */
265373f0a83dSXin LI SetStatus(form, _WINDOW_MODIFIED);
26544a1a9510SRong-En Fan returnCode(Inter_Field_Navigation(FN_Next_Field, form));
26550e3d5408SPeter Wemm }
26560e3d5408SPeter Wemm else
26570e3d5408SPeter Wemm {
26580e3d5408SPeter Wemm if (Last_Row && !Field_Grown(field, 1))
26594a1a9510SRong-En Fan {
26604a1a9510SRong-En Fan /* N.B.: due to the logic in the 'if', LastRow==TRUE
26610e3d5408SPeter Wemm means here that the field is growable and not
26620e3d5408SPeter Wemm a single-line field */
26634a1a9510SRong-En Fan returnCode(E_SYSTEM_ERROR);
26640e3d5408SPeter Wemm }
26654a1a9510SRong-En Fan wmove(form->w, form->currow, form->curcol);
26660e3d5408SPeter Wemm wclrtoeol(form->w);
26670e3d5408SPeter Wemm form->currow++;
26680e3d5408SPeter Wemm form->curcol = 0;
266973f0a83dSXin LI SetStatus(form, _WINDOW_MODIFIED);
26704a1a9510SRong-En Fan returnCode(E_OK);
26710e3d5408SPeter Wemm }
26720e3d5408SPeter Wemm }
26730e3d5408SPeter Wemm else
26744a1a9510SRong-En Fan {
26754a1a9510SRong-En Fan /* Insert Mode */
26760e3d5408SPeter Wemm if (Last_Row &&
26770e3d5408SPeter Wemm !(Growable(field) && !Single_Line_Field(field)))
26780e3d5408SPeter Wemm {
267973f0a83dSXin LI if (!((unsigned)form->opts & O_NL_OVERLOAD))
26804a1a9510SRong-En Fan returnCode(E_REQUEST_DENIED);
26814a1a9510SRong-En Fan returnCode(Inter_Field_Navigation(FN_Next_Field, form));
26820e3d5408SPeter Wemm }
26830e3d5408SPeter Wemm else
26840e3d5408SPeter Wemm {
26850e3d5408SPeter Wemm bool May_Do_It = !Last_Row && Is_There_Room_For_A_Line(form);
26860e3d5408SPeter Wemm
26870e3d5408SPeter Wemm if (!(May_Do_It || Growable(field)))
26884a1a9510SRong-En Fan returnCode(E_REQUEST_DENIED);
26890e3d5408SPeter Wemm if (!May_Do_It && !Field_Grown(field, 1))
26904a1a9510SRong-En Fan returnCode(E_SYSTEM_ERROR);
26910e3d5408SPeter Wemm
26920e3d5408SPeter Wemm bp = Address_Of_Current_Position_In_Buffer(form);
26930e3d5408SPeter Wemm t = After_End_Of_Data(bp, field->dcols - form->curcol);
26944a1a9510SRong-En Fan wmove(form->w, form->currow, form->curcol);
26950e3d5408SPeter Wemm wclrtoeol(form->w);
26960e3d5408SPeter Wemm form->currow++;
26970e3d5408SPeter Wemm form->curcol = 0;
26980e3d5408SPeter Wemm wmove(form->w, form->currow, form->curcol);
26990e3d5408SPeter Wemm winsertln(form->w);
27004a1a9510SRong-En Fan myADDNSTR(form->w, bp, (int)(t - bp));
270173f0a83dSXin LI SetStatus(form, _WINDOW_MODIFIED);
27024a1a9510SRong-En Fan returnCode(E_OK);
27030e3d5408SPeter Wemm }
27040e3d5408SPeter Wemm }
27050e3d5408SPeter Wemm }
27060e3d5408SPeter Wemm
27070e3d5408SPeter Wemm /*---------------------------------------------------------------------------
27080e3d5408SPeter Wemm | Facility : libnform
27090e3d5408SPeter Wemm | Function : static int FE_Insert_Character(FORM * form)
27100e3d5408SPeter Wemm |
27110e3d5408SPeter Wemm | Description : Insert blank character at the cursor position
27120e3d5408SPeter Wemm |
27130e3d5408SPeter Wemm | Return Values : E_OK
27140e3d5408SPeter Wemm | E_REQUEST_DENIED
27150e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
27164a1a9510SRong-En Fan static int
FE_Insert_Character(FORM * form)27174a1a9510SRong-En Fan FE_Insert_Character(FORM *form)
27180e3d5408SPeter Wemm {
27190e3d5408SPeter Wemm FIELD *field = form->current;
27200e3d5408SPeter Wemm int result = E_REQUEST_DENIED;
27210e3d5408SPeter Wemm
272206bfebdeSXin LI T((T_CALLED("FE_Insert_Character(%p)"), (void *)form));
272306bfebdeSXin LI if (Check_Char(form, field, field->type, (int)C_BLANK,
272406bfebdeSXin LI (TypeArgument *)(field->arg)))
27250e3d5408SPeter Wemm {
27260e3d5408SPeter Wemm bool There_Is_Room = Is_There_Room_For_A_Char_In_Line(form);
27270e3d5408SPeter Wemm
27280e3d5408SPeter Wemm if (There_Is_Room ||
27290e3d5408SPeter Wemm ((Single_Line_Field(field) && Growable(field))))
27300e3d5408SPeter Wemm {
27310e3d5408SPeter Wemm if (!There_Is_Room && !Field_Grown(field, 1))
27320e3d5408SPeter Wemm result = E_SYSTEM_ERROR;
27330e3d5408SPeter Wemm else
27340e3d5408SPeter Wemm {
27350e3d5408SPeter Wemm winsch(form->w, (chtype)C_BLANK);
27360e3d5408SPeter Wemm result = Wrapping_Not_Necessary_Or_Wrapping_Ok(form);
27370e3d5408SPeter Wemm }
27380e3d5408SPeter Wemm }
27390e3d5408SPeter Wemm }
27404a1a9510SRong-En Fan returnCode(result);
27410e3d5408SPeter Wemm }
27420e3d5408SPeter Wemm
27430e3d5408SPeter Wemm /*---------------------------------------------------------------------------
27440e3d5408SPeter Wemm | Facility : libnform
27450e3d5408SPeter Wemm | Function : static int FE_Insert_Line(FORM * form)
27460e3d5408SPeter Wemm |
27470e3d5408SPeter Wemm | Description : Insert a blank line at the cursor position
27480e3d5408SPeter Wemm |
27490e3d5408SPeter Wemm | Return Values : E_OK - success
27500e3d5408SPeter Wemm | E_REQUEST_DENIED - line can not be inserted
27510e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
27524a1a9510SRong-En Fan static int
FE_Insert_Line(FORM * form)27534a1a9510SRong-En Fan FE_Insert_Line(FORM *form)
27540e3d5408SPeter Wemm {
27550e3d5408SPeter Wemm FIELD *field = form->current;
27560e3d5408SPeter Wemm int result = E_REQUEST_DENIED;
27570e3d5408SPeter Wemm
275806bfebdeSXin LI T((T_CALLED("FE_Insert_Line(%p)"), (void *)form));
275906bfebdeSXin LI if (Check_Char(form, field,
276006bfebdeSXin LI field->type, (int)C_BLANK, (TypeArgument *)(field->arg)))
27610e3d5408SPeter Wemm {
27620e3d5408SPeter Wemm bool Maybe_Done = (form->currow != (field->drows - 1)) &&
27630e3d5408SPeter Wemm Is_There_Room_For_A_Line(form);
27640e3d5408SPeter Wemm
27650e3d5408SPeter Wemm if (!Single_Line_Field(field) &&
27660e3d5408SPeter Wemm (Maybe_Done || Growable(field)))
27670e3d5408SPeter Wemm {
27680e3d5408SPeter Wemm if (!Maybe_Done && !Field_Grown(field, 1))
27690e3d5408SPeter Wemm result = E_SYSTEM_ERROR;
27700e3d5408SPeter Wemm else
27710e3d5408SPeter Wemm {
27720e3d5408SPeter Wemm form->curcol = 0;
27730e3d5408SPeter Wemm winsertln(form->w);
27740e3d5408SPeter Wemm result = E_OK;
27750e3d5408SPeter Wemm }
27760e3d5408SPeter Wemm }
27770e3d5408SPeter Wemm }
27784a1a9510SRong-En Fan returnCode(result);
27790e3d5408SPeter Wemm }
27800e3d5408SPeter Wemm
27810e3d5408SPeter Wemm /*---------------------------------------------------------------------------
27820e3d5408SPeter Wemm | Facility : libnform
27830e3d5408SPeter Wemm | Function : static int FE_Delete_Character(FORM * form)
27840e3d5408SPeter Wemm |
27850e3d5408SPeter Wemm | Description : Delete character at the cursor position
27860e3d5408SPeter Wemm |
27870e3d5408SPeter Wemm | Return Values : E_OK - success
27880e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
27894a1a9510SRong-En Fan static int
FE_Delete_Character(FORM * form)27904a1a9510SRong-En Fan FE_Delete_Character(FORM *form)
27910e3d5408SPeter Wemm {
279206bfebdeSXin LI T((T_CALLED("FE_Delete_Character(%p)"), (void *)form));
27934a1a9510SRong-En Fan DeleteChar(form);
27944a1a9510SRong-En Fan returnCode(E_OK);
27950e3d5408SPeter Wemm }
27960e3d5408SPeter Wemm
27970e3d5408SPeter Wemm /*---------------------------------------------------------------------------
27980e3d5408SPeter Wemm | Facility : libnform
27990e3d5408SPeter Wemm | Function : static int FE_Delete_Previous(FORM * form)
28000e3d5408SPeter Wemm |
28010e3d5408SPeter Wemm | Description : Delete character before cursor. Again this is a rather
28020e3d5408SPeter Wemm | difficult piece compared to others due to the overloading
28030e3d5408SPeter Wemm | semantics of backspace.
28040e3d5408SPeter Wemm | N.B.: The case of overloaded BS on first field position
28050e3d5408SPeter Wemm | is already handled in the generic routine.
28060e3d5408SPeter Wemm |
28070e3d5408SPeter Wemm | Return Values : E_OK - success
28080e3d5408SPeter Wemm | E_REQUEST_DENIED - Character can't be deleted
28090e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
28104a1a9510SRong-En Fan static int
FE_Delete_Previous(FORM * form)28114a1a9510SRong-En Fan FE_Delete_Previous(FORM *form)
28120e3d5408SPeter Wemm {
28130e3d5408SPeter Wemm FIELD *field = form->current;
28140e3d5408SPeter Wemm
281506bfebdeSXin LI T((T_CALLED("FE_Delete_Previous(%p)"), (void *)form));
28160e3d5408SPeter Wemm if (First_Position_In_Current_Field(form))
28174a1a9510SRong-En Fan returnCode(E_REQUEST_DENIED);
28180e3d5408SPeter Wemm
28190e3d5408SPeter Wemm if ((--(form->curcol)) < 0)
28200e3d5408SPeter Wemm {
28214a1a9510SRong-En Fan FIELD_CELL *this_line, *prev_line, *prev_end, *this_end;
28224a1a9510SRong-En Fan int this_row = form->currow;
28230e3d5408SPeter Wemm
28240e3d5408SPeter Wemm form->curcol++;
28250e3d5408SPeter Wemm if (form->status & _OVLMODE)
28264a1a9510SRong-En Fan returnCode(E_REQUEST_DENIED);
28270e3d5408SPeter Wemm
28280e3d5408SPeter Wemm prev_line = Address_Of_Row_In_Buffer(field, (form->currow - 1));
28290e3d5408SPeter Wemm this_line = Address_Of_Row_In_Buffer(field, (form->currow));
28300e3d5408SPeter Wemm Synchronize_Buffer(form);
28310e3d5408SPeter Wemm prev_end = After_End_Of_Data(prev_line, field->dcols);
28320e3d5408SPeter Wemm this_end = After_End_Of_Data(this_line, field->dcols);
28330e3d5408SPeter Wemm if ((int)(this_end - this_line) >
28340e3d5408SPeter Wemm (field->cols - (int)(prev_end - prev_line)))
28354a1a9510SRong-En Fan returnCode(E_REQUEST_DENIED);
28364a1a9510SRong-En Fan wmove(form->w, form->currow, form->curcol);
28370e3d5408SPeter Wemm wdeleteln(form->w);
28380e3d5408SPeter Wemm Adjust_Cursor_Position(form, prev_end);
28394a1a9510SRong-En Fan /*
28404a1a9510SRong-En Fan * If we did not really move to the previous line, help the user a
28414a1a9510SRong-En Fan * little. It is however a little inconsistent. Normally, when
28424a1a9510SRong-En Fan * backspacing around the point where text wraps to a new line in a
28434a1a9510SRong-En Fan * multi-line form, we absorb one keystroke for the wrapping point. That
28444a1a9510SRong-En Fan * is consistent with SVr4 forms. However, SVr4 does not allow typing
28454a1a9510SRong-En Fan * into the last column of the field, and requires the user to enter a
28464a1a9510SRong-En Fan * newline to move to the next line. Therefore it can consistently eat
28474a1a9510SRong-En Fan * that keystroke. Since ncurses allows the last column, it wraps
28484a1a9510SRong-En Fan * automatically (given the proper options). But we cannot eat the
28494a1a9510SRong-En Fan * keystroke to back over the wrapping point, since that would put the
28504a1a9510SRong-En Fan * cursor past the end of the form field. In this case, just delete the
28514a1a9510SRong-En Fan * character at the end of the field.
28524a1a9510SRong-En Fan */
28534a1a9510SRong-En Fan if (form->currow == this_row && this_row > 0)
28544a1a9510SRong-En Fan {
28554a1a9510SRong-En Fan form->currow -= 1;
28564a1a9510SRong-En Fan form->curcol = field->dcols - 1;
28574a1a9510SRong-En Fan DeleteChar(form);
28580e3d5408SPeter Wemm }
28590e3d5408SPeter Wemm else
28600e3d5408SPeter Wemm {
28610e3d5408SPeter Wemm wmove(form->w, form->currow, form->curcol);
28624a1a9510SRong-En Fan myADDNSTR(form->w, this_line, (int)(this_end - this_line));
28630e3d5408SPeter Wemm }
28644a1a9510SRong-En Fan }
28654a1a9510SRong-En Fan else
28664a1a9510SRong-En Fan {
28674a1a9510SRong-En Fan DeleteChar(form);
28684a1a9510SRong-En Fan }
28694a1a9510SRong-En Fan returnCode(E_OK);
28700e3d5408SPeter Wemm }
28710e3d5408SPeter Wemm
28720e3d5408SPeter Wemm /*---------------------------------------------------------------------------
28730e3d5408SPeter Wemm | Facility : libnform
28740e3d5408SPeter Wemm | Function : static int FE_Delete_Line(FORM * form)
28750e3d5408SPeter Wemm |
28760e3d5408SPeter Wemm | Description : Delete line at cursor position.
28770e3d5408SPeter Wemm |
28780e3d5408SPeter Wemm | Return Values : E_OK - success
28790e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
28804a1a9510SRong-En Fan static int
FE_Delete_Line(FORM * form)28814a1a9510SRong-En Fan FE_Delete_Line(FORM *form)
28820e3d5408SPeter Wemm {
288306bfebdeSXin LI T((T_CALLED("FE_Delete_Line(%p)"), (void *)form));
28840e3d5408SPeter Wemm form->curcol = 0;
28850e3d5408SPeter Wemm wdeleteln(form->w);
28864a1a9510SRong-En Fan returnCode(E_OK);
28870e3d5408SPeter Wemm }
28880e3d5408SPeter Wemm
28890e3d5408SPeter Wemm /*---------------------------------------------------------------------------
28900e3d5408SPeter Wemm | Facility : libnform
28910e3d5408SPeter Wemm | Function : static int FE_Delete_Word(FORM * form)
28920e3d5408SPeter Wemm |
28930e3d5408SPeter Wemm | Description : Delete word at cursor position
28940e3d5408SPeter Wemm |
28950e3d5408SPeter Wemm | Return Values : E_OK - success
28960e3d5408SPeter Wemm | E_REQUEST_DENIED - failure
28970e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
28984a1a9510SRong-En Fan static int
FE_Delete_Word(FORM * form)28994a1a9510SRong-En Fan FE_Delete_Word(FORM *form)
29000e3d5408SPeter Wemm {
29010e3d5408SPeter Wemm FIELD *field = form->current;
29024a1a9510SRong-En Fan FIELD_CELL *bp = Address_Of_Current_Row_In_Buffer(form);
29034a1a9510SRong-En Fan FIELD_CELL *ep = bp + field->dcols;
29044a1a9510SRong-En Fan FIELD_CELL *cp = bp + form->curcol;
29054a1a9510SRong-En Fan FIELD_CELL *s;
29060e3d5408SPeter Wemm
290706bfebdeSXin LI T((T_CALLED("FE_Delete_Word(%p)"), (void *)form));
29080e3d5408SPeter Wemm Synchronize_Buffer(form);
29094a1a9510SRong-En Fan if (ISBLANK(*cp))
29104a1a9510SRong-En Fan returnCode(E_REQUEST_DENIED); /* not in word */
29110e3d5408SPeter Wemm
29120e3d5408SPeter Wemm /* move cursor to begin of word and erase to end of screen-line */
29130e3d5408SPeter Wemm Adjust_Cursor_Position(form,
29140e3d5408SPeter Wemm After_Last_Whitespace_Character(bp, form->curcol));
29150e3d5408SPeter Wemm wmove(form->w, form->currow, form->curcol);
29160e3d5408SPeter Wemm wclrtoeol(form->w);
29170e3d5408SPeter Wemm
29180e3d5408SPeter Wemm /* skip over word in buffer */
29190e3d5408SPeter Wemm s = Get_First_Whitespace_Character(cp, (int)(ep - cp));
29200e3d5408SPeter Wemm /* to begin of next word */
29210e3d5408SPeter Wemm s = Get_Start_Of_Data(s, (int)(ep - s));
29224a1a9510SRong-En Fan if ((s != cp) && !ISBLANK(*s))
29230e3d5408SPeter Wemm {
29240e3d5408SPeter Wemm /* copy remaining line to window */
29254a1a9510SRong-En Fan myADDNSTR(form->w, s, (int)(s - After_End_Of_Data(s, (int)(ep - s))));
29260e3d5408SPeter Wemm }
29274a1a9510SRong-En Fan returnCode(E_OK);
29280e3d5408SPeter Wemm }
29290e3d5408SPeter Wemm
29300e3d5408SPeter Wemm /*---------------------------------------------------------------------------
29310e3d5408SPeter Wemm | Facility : libnform
29320e3d5408SPeter Wemm | Function : static int FE_Clear_To_End_Of_Line(FORM * form)
29330e3d5408SPeter Wemm |
29340e3d5408SPeter Wemm | Description : Clear to end of current line.
29350e3d5408SPeter Wemm |
29360e3d5408SPeter Wemm | Return Values : E_OK - success
29370e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
29384a1a9510SRong-En Fan static int
FE_Clear_To_End_Of_Line(FORM * form)29394a1a9510SRong-En Fan FE_Clear_To_End_Of_Line(FORM *form)
29400e3d5408SPeter Wemm {
294106bfebdeSXin LI T((T_CALLED("FE_Clear_To_End_Of_Line(%p)"), (void *)form));
29424a1a9510SRong-En Fan wmove(form->w, form->currow, form->curcol);
29430e3d5408SPeter Wemm wclrtoeol(form->w);
29444a1a9510SRong-En Fan returnCode(E_OK);
29450e3d5408SPeter Wemm }
29460e3d5408SPeter Wemm
29470e3d5408SPeter Wemm /*---------------------------------------------------------------------------
29480e3d5408SPeter Wemm | Facility : libnform
29494a1a9510SRong-En Fan | Function : static int FE_Clear_To_End_Of_Field(FORM * form)
29500e3d5408SPeter Wemm |
29514a1a9510SRong-En Fan | Description : Clear to end of field.
29520e3d5408SPeter Wemm |
29530e3d5408SPeter Wemm | Return Values : E_OK - success
29540e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
29554a1a9510SRong-En Fan static int
FE_Clear_To_End_Of_Field(FORM * form)29564a1a9510SRong-En Fan FE_Clear_To_End_Of_Field(FORM *form)
29570e3d5408SPeter Wemm {
295806bfebdeSXin LI T((T_CALLED("FE_Clear_To_End_Of_Field(%p)"), (void *)form));
29594a1a9510SRong-En Fan wmove(form->w, form->currow, form->curcol);
29600e3d5408SPeter Wemm wclrtobot(form->w);
29614a1a9510SRong-En Fan returnCode(E_OK);
29620e3d5408SPeter Wemm }
29630e3d5408SPeter Wemm
29640e3d5408SPeter Wemm /*---------------------------------------------------------------------------
29650e3d5408SPeter Wemm | Facility : libnform
29660e3d5408SPeter Wemm | Function : static int FE_Clear_Field(FORM * form)
29670e3d5408SPeter Wemm |
29680e3d5408SPeter Wemm | Description : Clear entire field.
29690e3d5408SPeter Wemm |
29700e3d5408SPeter Wemm | Return Values : E_OK - success
29710e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
29724a1a9510SRong-En Fan static int
FE_Clear_Field(FORM * form)29734a1a9510SRong-En Fan FE_Clear_Field(FORM *form)
29740e3d5408SPeter Wemm {
297506bfebdeSXin LI T((T_CALLED("FE_Clear_Field(%p)"), (void *)form));
29760e3d5408SPeter Wemm form->currow = form->curcol = 0;
29770e3d5408SPeter Wemm werase(form->w);
29784a1a9510SRong-En Fan returnCode(E_OK);
29790e3d5408SPeter Wemm }
29800e3d5408SPeter Wemm /*----------------------------------------------------------------------------
29810e3d5408SPeter Wemm END of Field Editing routines
29820e3d5408SPeter Wemm --------------------------------------------------------------------------*/
29834a1a9510SRong-En Fan
29840e3d5408SPeter Wemm /*----------------------------------------------------------------------------
29850e3d5408SPeter Wemm Edit Mode routines
29860e3d5408SPeter Wemm --------------------------------------------------------------------------*/
29870e3d5408SPeter Wemm
29880e3d5408SPeter Wemm /*---------------------------------------------------------------------------
29890e3d5408SPeter Wemm | Facility : libnform
29900e3d5408SPeter Wemm | Function : static int EM_Overlay_Mode(FORM * form)
29910e3d5408SPeter Wemm |
29920e3d5408SPeter Wemm | Description : Switch to overlay mode.
29930e3d5408SPeter Wemm |
29940e3d5408SPeter Wemm | Return Values : E_OK - success
29950e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
29964a1a9510SRong-En Fan static int
EM_Overlay_Mode(FORM * form)29974a1a9510SRong-En Fan EM_Overlay_Mode(FORM *form)
29980e3d5408SPeter Wemm {
299906bfebdeSXin LI T((T_CALLED("EM_Overlay_Mode(%p)"), (void *)form));
300073f0a83dSXin LI SetStatus(form, _OVLMODE);
30014a1a9510SRong-En Fan returnCode(E_OK);
30020e3d5408SPeter Wemm }
30030e3d5408SPeter Wemm
30040e3d5408SPeter Wemm /*---------------------------------------------------------------------------
30050e3d5408SPeter Wemm | Facility : libnform
30060e3d5408SPeter Wemm | Function : static int EM_Insert_Mode(FORM * form)
30070e3d5408SPeter Wemm |
30080e3d5408SPeter Wemm | Description : Switch to insert mode
30090e3d5408SPeter Wemm |
30100e3d5408SPeter Wemm | Return Values : E_OK - success
30110e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
30124a1a9510SRong-En Fan static int
EM_Insert_Mode(FORM * form)30134a1a9510SRong-En Fan EM_Insert_Mode(FORM *form)
30140e3d5408SPeter Wemm {
301506bfebdeSXin LI T((T_CALLED("EM_Insert_Mode(%p)"), (void *)form));
301673f0a83dSXin LI ClrStatus(form, _OVLMODE);
30174a1a9510SRong-En Fan returnCode(E_OK);
30180e3d5408SPeter Wemm }
30190e3d5408SPeter Wemm
30200e3d5408SPeter Wemm /*----------------------------------------------------------------------------
30210e3d5408SPeter Wemm END of Edit Mode routines
30220e3d5408SPeter Wemm --------------------------------------------------------------------------*/
30234a1a9510SRong-En Fan
30240e3d5408SPeter Wemm /*----------------------------------------------------------------------------
30250e3d5408SPeter Wemm Helper routines for Choice Requests
30260e3d5408SPeter Wemm --------------------------------------------------------------------------*/
30270e3d5408SPeter Wemm
30280e3d5408SPeter Wemm /*---------------------------------------------------------------------------
30290e3d5408SPeter Wemm | Facility : libnform
303006bfebdeSXin LI | Function : static bool Next_Choice(FORM * form,
30310e3d5408SPeter Wemm | FIELDTYPE * typ,
30320e3d5408SPeter Wemm | FIELD * field,
30330e3d5408SPeter Wemm | TypeArgument *argp)
30340e3d5408SPeter Wemm |
30350e3d5408SPeter Wemm | Description : Get the next field choice. For linked types this is
30360e3d5408SPeter Wemm | done recursively.
30370e3d5408SPeter Wemm |
30380e3d5408SPeter Wemm | Return Values : TRUE - next choice successfully retrieved
30390e3d5408SPeter Wemm | FALSE - couldn't retrieve next choice
30400e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
30414a1a9510SRong-En Fan static bool
Next_Choice(FORM * form,FIELDTYPE * typ,FIELD * field,TypeArgument * argp)304206bfebdeSXin LI Next_Choice(FORM *form, FIELDTYPE *typ, FIELD *field, TypeArgument *argp)
30430e3d5408SPeter Wemm {
30440e3d5408SPeter Wemm if (!typ || !(typ->status & _HAS_CHOICE))
30450e3d5408SPeter Wemm return FALSE;
30460e3d5408SPeter Wemm
30470e3d5408SPeter Wemm if (typ->status & _LINKED_TYPE)
30480e3d5408SPeter Wemm {
30490e3d5408SPeter Wemm assert(argp);
30500e3d5408SPeter Wemm return (
305106bfebdeSXin LI Next_Choice(form, typ->left, field, argp->left) ||
305206bfebdeSXin LI Next_Choice(form, typ->right, field, argp->right));
30530e3d5408SPeter Wemm }
30540e3d5408SPeter Wemm else
30550e3d5408SPeter Wemm {
305606bfebdeSXin LI #if NCURSES_INTEROP_FUNCS
305706bfebdeSXin LI assert(typ->enum_next.onext);
305806bfebdeSXin LI if (typ->status & _GENERIC)
305906bfebdeSXin LI return typ->enum_next.gnext(form, field, (void *)argp);
306006bfebdeSXin LI else
306106bfebdeSXin LI return typ->enum_next.onext(field, (void *)argp);
306206bfebdeSXin LI #else
30630e3d5408SPeter Wemm assert(typ->next);
30640e3d5408SPeter Wemm return typ->next(field, (void *)argp);
306506bfebdeSXin LI #endif
30660e3d5408SPeter Wemm }
30670e3d5408SPeter Wemm }
30680e3d5408SPeter Wemm
30690e3d5408SPeter Wemm /*---------------------------------------------------------------------------
30700e3d5408SPeter Wemm | Facility : libnform
307106bfebdeSXin LI | Function : static bool Previous_Choice(FORM * form,
30720e3d5408SPeter Wemm | FIELDTYPE * typ,
30730e3d5408SPeter Wemm | FIELD * field,
30740e3d5408SPeter Wemm | TypeArgument *argp)
30750e3d5408SPeter Wemm |
30760e3d5408SPeter Wemm | Description : Get the previous field choice. For linked types this
30770e3d5408SPeter Wemm | is done recursively.
30780e3d5408SPeter Wemm |
30790e3d5408SPeter Wemm | Return Values : TRUE - previous choice successfully retrieved
30800e3d5408SPeter Wemm | FALSE - couldn't retrieve previous choice
30810e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
30824a1a9510SRong-En Fan static bool
Previous_Choice(FORM * form,FIELDTYPE * typ,FIELD * field,TypeArgument * argp)308306bfebdeSXin LI Previous_Choice(FORM *form, FIELDTYPE *typ, FIELD *field, TypeArgument *argp)
30840e3d5408SPeter Wemm {
30850e3d5408SPeter Wemm if (!typ || !(typ->status & _HAS_CHOICE))
30860e3d5408SPeter Wemm return FALSE;
30870e3d5408SPeter Wemm
30880e3d5408SPeter Wemm if (typ->status & _LINKED_TYPE)
30890e3d5408SPeter Wemm {
30900e3d5408SPeter Wemm assert(argp);
30910e3d5408SPeter Wemm return (
309206bfebdeSXin LI Previous_Choice(form, typ->left, field, argp->left) ||
309306bfebdeSXin LI Previous_Choice(form, typ->right, field, argp->right));
30940e3d5408SPeter Wemm }
30950e3d5408SPeter Wemm else
30960e3d5408SPeter Wemm {
309706bfebdeSXin LI #if NCURSES_INTEROP_FUNCS
309806bfebdeSXin LI assert(typ->enum_prev.oprev);
309906bfebdeSXin LI if (typ->status & _GENERIC)
310006bfebdeSXin LI return typ->enum_prev.gprev(form, field, (void *)argp);
310106bfebdeSXin LI else
310206bfebdeSXin LI return typ->enum_prev.oprev(field, (void *)argp);
310306bfebdeSXin LI #else
31040e3d5408SPeter Wemm assert(typ->prev);
31050e3d5408SPeter Wemm return typ->prev(field, (void *)argp);
310606bfebdeSXin LI #endif
31070e3d5408SPeter Wemm }
31080e3d5408SPeter Wemm }
31090e3d5408SPeter Wemm /*----------------------------------------------------------------------------
31100e3d5408SPeter Wemm End of Helper routines for Choice Requests
31110e3d5408SPeter Wemm --------------------------------------------------------------------------*/
31124a1a9510SRong-En Fan
31130e3d5408SPeter Wemm /*----------------------------------------------------------------------------
31140e3d5408SPeter Wemm Routines for Choice Requests
31150e3d5408SPeter Wemm --------------------------------------------------------------------------*/
31160e3d5408SPeter Wemm
31170e3d5408SPeter Wemm /*---------------------------------------------------------------------------
31180e3d5408SPeter Wemm | Facility : libnform
31190e3d5408SPeter Wemm | Function : static int CR_Next_Choice(FORM * form)
31200e3d5408SPeter Wemm |
31210e3d5408SPeter Wemm | Description : Get the next field choice.
31220e3d5408SPeter Wemm |
31230e3d5408SPeter Wemm | Return Values : E_OK - success
31240e3d5408SPeter Wemm | E_REQUEST_DENIED - next choice couldn't be retrieved
31250e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
31264a1a9510SRong-En Fan static int
CR_Next_Choice(FORM * form)31274a1a9510SRong-En Fan CR_Next_Choice(FORM *form)
31280e3d5408SPeter Wemm {
31290e3d5408SPeter Wemm FIELD *field = form->current;
31304a1a9510SRong-En Fan
313106bfebdeSXin LI T((T_CALLED("CR_Next_Choice(%p)"), (void *)form));
31320e3d5408SPeter Wemm Synchronize_Buffer(form);
313306bfebdeSXin LI returnCode((Next_Choice(form, field->type, field, (TypeArgument *)(field->arg)))
31344a1a9510SRong-En Fan ? E_OK
31354a1a9510SRong-En Fan : E_REQUEST_DENIED);
31360e3d5408SPeter Wemm }
31370e3d5408SPeter Wemm
31380e3d5408SPeter Wemm /*---------------------------------------------------------------------------
31390e3d5408SPeter Wemm | Facility : libnform
31400e3d5408SPeter Wemm | Function : static int CR_Previous_Choice(FORM * form)
31410e3d5408SPeter Wemm |
31420e3d5408SPeter Wemm | Description : Get the previous field choice.
31430e3d5408SPeter Wemm |
31440e3d5408SPeter Wemm | Return Values : E_OK - success
31450e3d5408SPeter Wemm | E_REQUEST_DENIED - prev. choice couldn't be retrieved
31460e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
31474a1a9510SRong-En Fan static int
CR_Previous_Choice(FORM * form)31484a1a9510SRong-En Fan CR_Previous_Choice(FORM *form)
31490e3d5408SPeter Wemm {
31500e3d5408SPeter Wemm FIELD *field = form->current;
31514a1a9510SRong-En Fan
315206bfebdeSXin LI T((T_CALLED("CR_Previous_Choice(%p)"), (void *)form));
31530e3d5408SPeter Wemm Synchronize_Buffer(form);
315406bfebdeSXin LI returnCode((Previous_Choice(form, field->type, field, (TypeArgument *)(field->arg)))
31554a1a9510SRong-En Fan ? E_OK
31564a1a9510SRong-En Fan : E_REQUEST_DENIED);
31570e3d5408SPeter Wemm }
31580e3d5408SPeter Wemm /*----------------------------------------------------------------------------
31590e3d5408SPeter Wemm End of Routines for Choice Requests
31600e3d5408SPeter Wemm --------------------------------------------------------------------------*/
31614a1a9510SRong-En Fan
31620e3d5408SPeter Wemm /*----------------------------------------------------------------------------
31630e3d5408SPeter Wemm Helper routines for Field Validations.
31640e3d5408SPeter Wemm --------------------------------------------------------------------------*/
31650e3d5408SPeter Wemm
31660e3d5408SPeter Wemm /*---------------------------------------------------------------------------
31670e3d5408SPeter Wemm | Facility : libnform
316806bfebdeSXin LI | Function : static bool Check_Field(FORM* form,
31690e3d5408SPeter Wemm | FIELDTYPE * typ,
31700e3d5408SPeter Wemm | FIELD * field,
31710e3d5408SPeter Wemm | TypeArgument * argp)
31720e3d5408SPeter Wemm |
31730e3d5408SPeter Wemm | Description : Check the field according to its fieldtype and its
31740e3d5408SPeter Wemm | actual arguments. For linked fieldtypes this is done
31750e3d5408SPeter Wemm | recursively.
31760e3d5408SPeter Wemm |
31770e3d5408SPeter Wemm | Return Values : TRUE - field is valid
31780e3d5408SPeter Wemm | FALSE - field is invalid.
31790e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
31804a1a9510SRong-En Fan static bool
Check_Field(FORM * form,FIELDTYPE * typ,FIELD * field,TypeArgument * argp)318106bfebdeSXin LI Check_Field(FORM *form, FIELDTYPE *typ, FIELD *field, TypeArgument *argp)
31820e3d5408SPeter Wemm {
31830e3d5408SPeter Wemm if (typ)
31840e3d5408SPeter Wemm {
3185aae38d10SBaptiste Daroussin if (Field_Has_Option(field, O_NULLOK))
31860e3d5408SPeter Wemm {
31874a1a9510SRong-En Fan FIELD_CELL *bp = field->buf;
31884a1a9510SRong-En Fan
31890e3d5408SPeter Wemm assert(bp);
31904a1a9510SRong-En Fan while (ISBLANK(*bp))
31914a1a9510SRong-En Fan {
31924a1a9510SRong-En Fan bp++;
31934a1a9510SRong-En Fan }
31944a1a9510SRong-En Fan if (CharOf(*bp) == 0)
31950e3d5408SPeter Wemm return TRUE;
31960e3d5408SPeter Wemm }
31970e3d5408SPeter Wemm
31980e3d5408SPeter Wemm if (typ->status & _LINKED_TYPE)
31990e3d5408SPeter Wemm {
32000e3d5408SPeter Wemm assert(argp);
32010e3d5408SPeter Wemm return (
320206bfebdeSXin LI Check_Field(form, typ->left, field, argp->left) ||
320306bfebdeSXin LI Check_Field(form, typ->right, field, argp->right));
32040e3d5408SPeter Wemm }
32050e3d5408SPeter Wemm else
32060e3d5408SPeter Wemm {
320706bfebdeSXin LI #if NCURSES_INTEROP_FUNCS
320806bfebdeSXin LI if (typ->fieldcheck.ofcheck)
320906bfebdeSXin LI {
321006bfebdeSXin LI if (typ->status & _GENERIC)
321106bfebdeSXin LI return typ->fieldcheck.gfcheck(form, field, (void *)argp);
321206bfebdeSXin LI else
321306bfebdeSXin LI return typ->fieldcheck.ofcheck(field, (void *)argp);
321406bfebdeSXin LI }
321506bfebdeSXin LI #else
32160e3d5408SPeter Wemm if (typ->fcheck)
32170e3d5408SPeter Wemm return typ->fcheck(field, (void *)argp);
321806bfebdeSXin LI #endif
32190e3d5408SPeter Wemm }
32200e3d5408SPeter Wemm }
32210e3d5408SPeter Wemm return TRUE;
32220e3d5408SPeter Wemm }
32230e3d5408SPeter Wemm
32240e3d5408SPeter Wemm /*---------------------------------------------------------------------------
32250e3d5408SPeter Wemm | Facility : libnform
32260e3d5408SPeter Wemm | Function : bool _nc_Internal_Validation(FORM * form )
32270e3d5408SPeter Wemm |
32280e3d5408SPeter Wemm | Description : Validate the current field of the form.
32290e3d5408SPeter Wemm |
32300e3d5408SPeter Wemm | Return Values : TRUE - field is valid
32310e3d5408SPeter Wemm | FALSE - field is invalid
32320e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
32337a656419SBaptiste Daroussin FORM_EXPORT(bool)
_nc_Internal_Validation(FORM * form)32340e3d5408SPeter Wemm _nc_Internal_Validation(FORM *form)
32350e3d5408SPeter Wemm {
32360e3d5408SPeter Wemm FIELD *field;
32370e3d5408SPeter Wemm
32380e3d5408SPeter Wemm field = form->current;
32390e3d5408SPeter Wemm
32400e3d5408SPeter Wemm Synchronize_Buffer(form);
32410e3d5408SPeter Wemm if ((form->status & _FCHECK_REQUIRED) ||
3242aae38d10SBaptiste Daroussin (!(Field_Has_Option(field, O_PASSOK))))
32430e3d5408SPeter Wemm {
324406bfebdeSXin LI if (!Check_Field(form, field->type, field, (TypeArgument *)(field->arg)))
32450e3d5408SPeter Wemm return FALSE;
324673f0a83dSXin LI ClrStatus(form, _FCHECK_REQUIRED);
324773f0a83dSXin LI SetStatus(field, _CHANGED);
32480e3d5408SPeter Wemm Synchronize_Linked_Fields(field);
32490e3d5408SPeter Wemm }
32500e3d5408SPeter Wemm return TRUE;
32510e3d5408SPeter Wemm }
32520e3d5408SPeter Wemm /*----------------------------------------------------------------------------
32530e3d5408SPeter Wemm End of Helper routines for Field Validations.
32540e3d5408SPeter Wemm --------------------------------------------------------------------------*/
32554a1a9510SRong-En Fan
32560e3d5408SPeter Wemm /*----------------------------------------------------------------------------
32570e3d5408SPeter Wemm Routines for Field Validation.
32580e3d5408SPeter Wemm --------------------------------------------------------------------------*/
32590e3d5408SPeter Wemm
32600e3d5408SPeter Wemm /*---------------------------------------------------------------------------
32610e3d5408SPeter Wemm | Facility : libnform
32620e3d5408SPeter Wemm | Function : static int FV_Validation(FORM * form)
32630e3d5408SPeter Wemm |
32640e3d5408SPeter Wemm | Description : Validate the current field of the form.
32650e3d5408SPeter Wemm |
32660e3d5408SPeter Wemm | Return Values : E_OK - field valid
32670e3d5408SPeter Wemm | E_INVALID_FIELD - field not valid
32680e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
32694a1a9510SRong-En Fan static int
FV_Validation(FORM * form)32704a1a9510SRong-En Fan FV_Validation(FORM *form)
32710e3d5408SPeter Wemm {
327206bfebdeSXin LI T((T_CALLED("FV_Validation(%p)"), (void *)form));
32730e3d5408SPeter Wemm if (_nc_Internal_Validation(form))
32744a1a9510SRong-En Fan returnCode(E_OK);
32750e3d5408SPeter Wemm else
32764a1a9510SRong-En Fan returnCode(E_INVALID_FIELD);
32770e3d5408SPeter Wemm }
32780e3d5408SPeter Wemm /*----------------------------------------------------------------------------
32790e3d5408SPeter Wemm End of routines for Field Validation.
32800e3d5408SPeter Wemm --------------------------------------------------------------------------*/
32814a1a9510SRong-En Fan
32820e3d5408SPeter Wemm /*----------------------------------------------------------------------------
32830e3d5408SPeter Wemm Helper routines for Inter-Field Navigation
32840e3d5408SPeter Wemm --------------------------------------------------------------------------*/
32850e3d5408SPeter Wemm
32860e3d5408SPeter Wemm /*---------------------------------------------------------------------------
32870e3d5408SPeter Wemm | Facility : libnform
32880e3d5408SPeter Wemm | Function : static FIELD *Next_Field_On_Page(FIELD * field)
32890e3d5408SPeter Wemm |
32900e3d5408SPeter Wemm | Description : Get the next field after the given field on the current
32910e3d5408SPeter Wemm | page. The order of fields is the one defined by the
32927a656419SBaptiste Daroussin | field's array. Only visible and active fields are
32930e3d5408SPeter Wemm | counted.
32940e3d5408SPeter Wemm |
32950e3d5408SPeter Wemm | Return Values : Pointer to the next field.
32960e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
32974a1a9510SRong-En Fan NCURSES_INLINE static FIELD *
Next_Field_On_Page(FIELD * field)32984a1a9510SRong-En Fan Next_Field_On_Page(FIELD *field)
32990e3d5408SPeter Wemm {
33000e3d5408SPeter Wemm FORM *form = field->form;
33010e3d5408SPeter Wemm FIELD **field_on_page = &form->field[field->index];
33020e3d5408SPeter Wemm FIELD **first_on_page = &form->field[form->page[form->curpage].pmin];
33030e3d5408SPeter Wemm FIELD **last_on_page = &form->field[form->page[form->curpage].pmax];
33040e3d5408SPeter Wemm
33050e3d5408SPeter Wemm do
33060e3d5408SPeter Wemm {
33070e3d5408SPeter Wemm field_on_page =
33080e3d5408SPeter Wemm (field_on_page == last_on_page) ? first_on_page : field_on_page + 1;
33090e3d5408SPeter Wemm if (Field_Is_Selectable(*field_on_page))
33100e3d5408SPeter Wemm break;
33114a1a9510SRong-En Fan }
33124a1a9510SRong-En Fan while (field != (*field_on_page));
33130e3d5408SPeter Wemm return (*field_on_page);
33140e3d5408SPeter Wemm }
33150e3d5408SPeter Wemm
33160e3d5408SPeter Wemm /*---------------------------------------------------------------------------
33170e3d5408SPeter Wemm | Facility : libnform
33180e3d5408SPeter Wemm | Function : FIELD* _nc_First_Active_Field(FORM * form)
33190e3d5408SPeter Wemm |
33200e3d5408SPeter Wemm | Description : Get the first active field on the current page,
33210e3d5408SPeter Wemm | if there are such. If there are none, get the first
33220e3d5408SPeter Wemm | visible field on the page. If there are also none,
33230e3d5408SPeter Wemm | we return the first field on page and hope the best.
33240e3d5408SPeter Wemm |
33250e3d5408SPeter Wemm | Return Values : Pointer to calculated field.
33260e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
33277a656419SBaptiste Daroussin FORM_EXPORT(FIELD *)
_nc_First_Active_Field(FORM * form)33280e3d5408SPeter Wemm _nc_First_Active_Field(FORM *form)
33290e3d5408SPeter Wemm {
33300e3d5408SPeter Wemm FIELD **last_on_page = &form->field[form->page[form->curpage].pmax];
33310e3d5408SPeter Wemm FIELD *proposed = Next_Field_On_Page(*last_on_page);
33320e3d5408SPeter Wemm
33330e3d5408SPeter Wemm if (proposed == *last_on_page)
33344a1a9510SRong-En Fan {
33354a1a9510SRong-En Fan /* there might be the special situation, where there is no
33360e3d5408SPeter Wemm active and visible field on the current page. We then select
33370e3d5408SPeter Wemm the first visible field on this readonly page
33380e3d5408SPeter Wemm */
33390e3d5408SPeter Wemm if (Field_Is_Not_Selectable(proposed))
33400e3d5408SPeter Wemm {
33410e3d5408SPeter Wemm FIELD **field = &form->field[proposed->index];
33420e3d5408SPeter Wemm FIELD **first = &form->field[form->page[form->curpage].pmin];
33430e3d5408SPeter Wemm
33440e3d5408SPeter Wemm do
33450e3d5408SPeter Wemm {
33460e3d5408SPeter Wemm field = (field == last_on_page) ? first : field + 1;
3347aae38d10SBaptiste Daroussin if (Field_Has_Option(*field, O_VISIBLE))
33480e3d5408SPeter Wemm break;
33494a1a9510SRong-En Fan }
33504a1a9510SRong-En Fan while (proposed != (*field));
33510e3d5408SPeter Wemm
33520e3d5408SPeter Wemm proposed = *field;
33530e3d5408SPeter Wemm
335473f0a83dSXin LI if ((proposed == *last_on_page) &&
335573f0a83dSXin LI !((unsigned)proposed->opts & O_VISIBLE))
33564a1a9510SRong-En Fan {
33574a1a9510SRong-En Fan /* This means, there is also no visible field on the page.
33580e3d5408SPeter Wemm So we propose the first one and hope the very best...
33590e3d5408SPeter Wemm Some very clever user has designed a readonly and invisible
33600e3d5408SPeter Wemm page on this form.
33610e3d5408SPeter Wemm */
33620e3d5408SPeter Wemm proposed = *first;
33630e3d5408SPeter Wemm }
33640e3d5408SPeter Wemm }
33650e3d5408SPeter Wemm }
33660e3d5408SPeter Wemm return (proposed);
33670e3d5408SPeter Wemm }
33680e3d5408SPeter Wemm
33690e3d5408SPeter Wemm /*---------------------------------------------------------------------------
33700e3d5408SPeter Wemm | Facility : libnform
33710e3d5408SPeter Wemm | Function : static FIELD *Previous_Field_On_Page(FIELD * field)
33720e3d5408SPeter Wemm |
33730e3d5408SPeter Wemm | Description : Get the previous field before the given field on the
33740e3d5408SPeter Wemm | current page. The order of fields is the one defined by
33757a656419SBaptiste Daroussin | the field's array. Only visible and active fields are
33760e3d5408SPeter Wemm | counted.
33770e3d5408SPeter Wemm |
33780e3d5408SPeter Wemm | Return Values : Pointer to the previous field.
33790e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
33804a1a9510SRong-En Fan NCURSES_INLINE static FIELD *
Previous_Field_On_Page(FIELD * field)33814a1a9510SRong-En Fan Previous_Field_On_Page(FIELD *field)
33820e3d5408SPeter Wemm {
33830e3d5408SPeter Wemm FORM *form = field->form;
33840e3d5408SPeter Wemm FIELD **field_on_page = &form->field[field->index];
33850e3d5408SPeter Wemm FIELD **first_on_page = &form->field[form->page[form->curpage].pmin];
33860e3d5408SPeter Wemm FIELD **last_on_page = &form->field[form->page[form->curpage].pmax];
33870e3d5408SPeter Wemm
33880e3d5408SPeter Wemm do
33890e3d5408SPeter Wemm {
33900e3d5408SPeter Wemm field_on_page =
33910e3d5408SPeter Wemm (field_on_page == first_on_page) ? last_on_page : field_on_page - 1;
33920e3d5408SPeter Wemm if (Field_Is_Selectable(*field_on_page))
33930e3d5408SPeter Wemm break;
33944a1a9510SRong-En Fan }
33954a1a9510SRong-En Fan while (field != (*field_on_page));
33960e3d5408SPeter Wemm
33970e3d5408SPeter Wemm return (*field_on_page);
33980e3d5408SPeter Wemm }
33990e3d5408SPeter Wemm
34000e3d5408SPeter Wemm /*---------------------------------------------------------------------------
34010e3d5408SPeter Wemm | Facility : libnform
34020e3d5408SPeter Wemm | Function : static FIELD *Sorted_Next_Field(FIELD * field)
34030e3d5408SPeter Wemm |
34040e3d5408SPeter Wemm | Description : Get the next field after the given field on the current
34050e3d5408SPeter Wemm | page. The order of fields is the one defined by the
34060e3d5408SPeter Wemm | (row,column) geometry, rows are major.
34070e3d5408SPeter Wemm |
34080e3d5408SPeter Wemm | Return Values : Pointer to the next field.
34090e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
34104a1a9510SRong-En Fan NCURSES_INLINE static FIELD *
Sorted_Next_Field(FIELD * field)34114a1a9510SRong-En Fan Sorted_Next_Field(FIELD *field)
34120e3d5408SPeter Wemm {
34130e3d5408SPeter Wemm FIELD *field_on_page = field;
34140e3d5408SPeter Wemm
34150e3d5408SPeter Wemm do
34160e3d5408SPeter Wemm {
34170e3d5408SPeter Wemm field_on_page = field_on_page->snext;
34180e3d5408SPeter Wemm if (Field_Is_Selectable(field_on_page))
34190e3d5408SPeter Wemm break;
34204a1a9510SRong-En Fan }
34214a1a9510SRong-En Fan while (field_on_page != field);
34220e3d5408SPeter Wemm
34230e3d5408SPeter Wemm return (field_on_page);
34240e3d5408SPeter Wemm }
34250e3d5408SPeter Wemm
34260e3d5408SPeter Wemm /*---------------------------------------------------------------------------
34270e3d5408SPeter Wemm | Facility : libnform
34280e3d5408SPeter Wemm | Function : static FIELD *Sorted_Previous_Field(FIELD * field)
34290e3d5408SPeter Wemm |
34300e3d5408SPeter Wemm | Description : Get the previous field before the given field on the
34310e3d5408SPeter Wemm | current page. The order of fields is the one defined
34320e3d5408SPeter Wemm | by the (row,column) geometry, rows are major.
34330e3d5408SPeter Wemm |
34340e3d5408SPeter Wemm | Return Values : Pointer to the previous field.
34350e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
34364a1a9510SRong-En Fan NCURSES_INLINE static FIELD *
Sorted_Previous_Field(FIELD * field)34374a1a9510SRong-En Fan Sorted_Previous_Field(FIELD *field)
34380e3d5408SPeter Wemm {
34390e3d5408SPeter Wemm FIELD *field_on_page = field;
34400e3d5408SPeter Wemm
34410e3d5408SPeter Wemm do
34420e3d5408SPeter Wemm {
34430e3d5408SPeter Wemm field_on_page = field_on_page->sprev;
34440e3d5408SPeter Wemm if (Field_Is_Selectable(field_on_page))
34450e3d5408SPeter Wemm break;
34464a1a9510SRong-En Fan }
34474a1a9510SRong-En Fan while (field_on_page != field);
34480e3d5408SPeter Wemm
34490e3d5408SPeter Wemm return (field_on_page);
34500e3d5408SPeter Wemm }
34510e3d5408SPeter Wemm
34520e3d5408SPeter Wemm /*---------------------------------------------------------------------------
34530e3d5408SPeter Wemm | Facility : libnform
34544a1a9510SRong-En Fan | Function : static FIELD *Left_Neighbor_Field(FIELD * field)
34550e3d5408SPeter Wemm |
34564a1a9510SRong-En Fan | Description : Get the left neighbor of the field on the same line
34570e3d5408SPeter Wemm | and the same page. Cycles through the line.
34580e3d5408SPeter Wemm |
34594a1a9510SRong-En Fan | Return Values : Pointer to left neighbor field.
34600e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
34614a1a9510SRong-En Fan NCURSES_INLINE static FIELD *
Left_Neighbor_Field(FIELD * field)34624a1a9510SRong-En Fan Left_Neighbor_Field(FIELD *field)
34630e3d5408SPeter Wemm {
34640e3d5408SPeter Wemm FIELD *field_on_page = field;
34650e3d5408SPeter Wemm
34664a1a9510SRong-En Fan /* For a field that has really a left neighbor, the while clause
34670e3d5408SPeter Wemm immediately fails and the loop is left, positioned at the right
34684a1a9510SRong-En Fan neighbor. Otherwise we cycle backwards through the sorted field list
34690e3d5408SPeter Wemm until we enter the same line (from the right end).
34700e3d5408SPeter Wemm */
34710e3d5408SPeter Wemm do
34720e3d5408SPeter Wemm {
34730e3d5408SPeter Wemm field_on_page = Sorted_Previous_Field(field_on_page);
34744a1a9510SRong-En Fan }
34754a1a9510SRong-En Fan while (field_on_page->frow != field->frow);
34760e3d5408SPeter Wemm
34770e3d5408SPeter Wemm return (field_on_page);
34780e3d5408SPeter Wemm }
34790e3d5408SPeter Wemm
34800e3d5408SPeter Wemm /*---------------------------------------------------------------------------
34810e3d5408SPeter Wemm | Facility : libnform
34824a1a9510SRong-En Fan | Function : static FIELD *Right_Neighbor_Field(FIELD * field)
34830e3d5408SPeter Wemm |
34844a1a9510SRong-En Fan | Description : Get the right neighbor of the field on the same line
34850e3d5408SPeter Wemm | and the same page.
34860e3d5408SPeter Wemm |
34874a1a9510SRong-En Fan | Return Values : Pointer to right neighbor field.
34880e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
34894a1a9510SRong-En Fan NCURSES_INLINE static FIELD *
Right_Neighbor_Field(FIELD * field)34904a1a9510SRong-En Fan Right_Neighbor_Field(FIELD *field)
34910e3d5408SPeter Wemm {
34920e3d5408SPeter Wemm FIELD *field_on_page = field;
34930e3d5408SPeter Wemm
34944a1a9510SRong-En Fan /* See the comments on Left_Neighbor_Field to understand how it works */
34950e3d5408SPeter Wemm do
34960e3d5408SPeter Wemm {
34970e3d5408SPeter Wemm field_on_page = Sorted_Next_Field(field_on_page);
34984a1a9510SRong-En Fan }
34994a1a9510SRong-En Fan while (field_on_page->frow != field->frow);
35000e3d5408SPeter Wemm
35010e3d5408SPeter Wemm return (field_on_page);
35020e3d5408SPeter Wemm }
35030e3d5408SPeter Wemm
35040e3d5408SPeter Wemm /*---------------------------------------------------------------------------
35050e3d5408SPeter Wemm | Facility : libnform
35064a1a9510SRong-En Fan | Function : static FIELD *Upper_Neighbor_Field(FIELD * field)
35070e3d5408SPeter Wemm |
35080e3d5408SPeter Wemm | Description : Because of the row-major nature of sorting the fields,
35097a656419SBaptiste Daroussin | it is more difficult to define what the upper neighbor
35100e3d5408SPeter Wemm | field really means. We define that it must be on a
35110e3d5408SPeter Wemm | 'previous' line (cyclic order!) and is the rightmost
35127a656419SBaptiste Daroussin | field lying on the left side of the given field. If
35130e3d5408SPeter Wemm | this set is empty, we take the first field on the line.
35140e3d5408SPeter Wemm |
35154a1a9510SRong-En Fan | Return Values : Pointer to the upper neighbor field.
35160e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
35174a1a9510SRong-En Fan static FIELD *
Upper_Neighbor_Field(FIELD * field)35184a1a9510SRong-En Fan Upper_Neighbor_Field(FIELD *field)
35190e3d5408SPeter Wemm {
35200e3d5408SPeter Wemm FIELD *field_on_page = field;
35210e3d5408SPeter Wemm int frow = field->frow;
35220e3d5408SPeter Wemm int fcol = field->fcol;
35230e3d5408SPeter Wemm
35240e3d5408SPeter Wemm /* Walk back to the 'previous' line. The second term in the while clause
35250e3d5408SPeter Wemm just guarantees that we stop if we cycled through the line because
35260e3d5408SPeter Wemm there might be no 'previous' line if the page has just one line.
35270e3d5408SPeter Wemm */
35280e3d5408SPeter Wemm do
35290e3d5408SPeter Wemm {
35300e3d5408SPeter Wemm field_on_page = Sorted_Previous_Field(field_on_page);
35314a1a9510SRong-En Fan }
35324a1a9510SRong-En Fan while (field_on_page->frow == frow && field_on_page->fcol != fcol);
35330e3d5408SPeter Wemm
35340e3d5408SPeter Wemm if (field_on_page->frow != frow)
35354a1a9510SRong-En Fan {
35364a1a9510SRong-En Fan /* We really found a 'previous' line. We are positioned at the
35370e3d5408SPeter Wemm rightmost field on this line */
35380e3d5408SPeter Wemm frow = field_on_page->frow;
35390e3d5408SPeter Wemm
35400e3d5408SPeter Wemm /* We walk to the left as long as we are really right of the
35410e3d5408SPeter Wemm field. */
35420e3d5408SPeter Wemm while (field_on_page->frow == frow && field_on_page->fcol > fcol)
35430e3d5408SPeter Wemm field_on_page = Sorted_Previous_Field(field_on_page);
35440e3d5408SPeter Wemm
35450e3d5408SPeter Wemm /* If we wrapped, just go to the right which is the first field on
35460e3d5408SPeter Wemm the row */
35470e3d5408SPeter Wemm if (field_on_page->frow != frow)
35480e3d5408SPeter Wemm field_on_page = Sorted_Next_Field(field_on_page);
35490e3d5408SPeter Wemm }
35500e3d5408SPeter Wemm
35510e3d5408SPeter Wemm return (field_on_page);
35520e3d5408SPeter Wemm }
35530e3d5408SPeter Wemm
35540e3d5408SPeter Wemm /*---------------------------------------------------------------------------
35550e3d5408SPeter Wemm | Facility : libnform
35564a1a9510SRong-En Fan | Function : static FIELD *Down_Neighbor_Field(FIELD * field)
35570e3d5408SPeter Wemm |
35580e3d5408SPeter Wemm | Description : Because of the row-major nature of sorting the fields,
3559*21817992SBaptiste Daroussin | it is more difficult to define what the down neighbor
35600e3d5408SPeter Wemm | field really means. We define that it must be on a
35610e3d5408SPeter Wemm | 'next' line (cyclic order!) and is the leftmost
35620e3d5408SPeter Wemm | field laying on the right side of the given field. If
35630e3d5408SPeter Wemm | this set is empty, we take the last field on the line.
35640e3d5408SPeter Wemm |
35654a1a9510SRong-En Fan | Return Values : Pointer to the upper neighbor field.
35660e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
35674a1a9510SRong-En Fan static FIELD *
Down_Neighbor_Field(FIELD * field)35684a1a9510SRong-En Fan Down_Neighbor_Field(FIELD *field)
35690e3d5408SPeter Wemm {
35700e3d5408SPeter Wemm FIELD *field_on_page = field;
35710e3d5408SPeter Wemm int frow = field->frow;
35720e3d5408SPeter Wemm int fcol = field->fcol;
35730e3d5408SPeter Wemm
35740e3d5408SPeter Wemm /* Walk forward to the 'next' line. The second term in the while clause
35750e3d5408SPeter Wemm just guarantees that we stop if we cycled through the line because
35760e3d5408SPeter Wemm there might be no 'next' line if the page has just one line.
35770e3d5408SPeter Wemm */
35780e3d5408SPeter Wemm do
35790e3d5408SPeter Wemm {
35800e3d5408SPeter Wemm field_on_page = Sorted_Next_Field(field_on_page);
35814a1a9510SRong-En Fan }
35824a1a9510SRong-En Fan while (field_on_page->frow == frow && field_on_page->fcol != fcol);
35830e3d5408SPeter Wemm
35840e3d5408SPeter Wemm if (field_on_page->frow != frow)
35854a1a9510SRong-En Fan {
35864a1a9510SRong-En Fan /* We really found a 'next' line. We are positioned at the rightmost
35870e3d5408SPeter Wemm field on this line */
35880e3d5408SPeter Wemm frow = field_on_page->frow;
35890e3d5408SPeter Wemm
35900e3d5408SPeter Wemm /* We walk to the right as long as we are really left of the
35910e3d5408SPeter Wemm field. */
35920e3d5408SPeter Wemm while (field_on_page->frow == frow && field_on_page->fcol < fcol)
35930e3d5408SPeter Wemm field_on_page = Sorted_Next_Field(field_on_page);
35940e3d5408SPeter Wemm
35950e3d5408SPeter Wemm /* If we wrapped, just go to the left which is the last field on
35960e3d5408SPeter Wemm the row */
35970e3d5408SPeter Wemm if (field_on_page->frow != frow)
35980e3d5408SPeter Wemm field_on_page = Sorted_Previous_Field(field_on_page);
35990e3d5408SPeter Wemm }
36000e3d5408SPeter Wemm
36010e3d5408SPeter Wemm return (field_on_page);
36020e3d5408SPeter Wemm }
36034a1a9510SRong-En Fan
36040e3d5408SPeter Wemm /*----------------------------------------------------------------------------
36050e3d5408SPeter Wemm Inter-Field Navigation routines
36060e3d5408SPeter Wemm --------------------------------------------------------------------------*/
36070e3d5408SPeter Wemm
36080e3d5408SPeter Wemm /*---------------------------------------------------------------------------
36090e3d5408SPeter Wemm | Facility : libnform
36100e3d5408SPeter Wemm | Function : static int Inter_Field_Navigation(
36110e3d5408SPeter Wemm | int (* const fct) (FORM *),
36120e3d5408SPeter Wemm | FORM * form)
36130e3d5408SPeter Wemm |
36144a1a9510SRong-En Fan | Description : Generic behavior for changing the current field, the
36150e3d5408SPeter Wemm | field is left and a new field is entered. So the field
36160e3d5408SPeter Wemm | must be validated and the field init/term hooks must
36170e3d5408SPeter Wemm | be called.
36180e3d5408SPeter Wemm |
36190e3d5408SPeter Wemm | Return Values : E_OK - success
36200e3d5408SPeter Wemm | E_INVALID_FIELD - field is invalid
36210e3d5408SPeter Wemm | some other - error from subordinate call
36220e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
36234a1a9510SRong-En Fan static int
Inter_Field_Navigation(int (* const fct)(FORM *),FORM * form)36244a1a9510SRong-En Fan Inter_Field_Navigation(int (*const fct) (FORM *), FORM *form)
36250e3d5408SPeter Wemm {
36260e3d5408SPeter Wemm int res;
36270e3d5408SPeter Wemm
36280e3d5408SPeter Wemm if (!_nc_Internal_Validation(form))
36290e3d5408SPeter Wemm res = E_INVALID_FIELD;
36300e3d5408SPeter Wemm else
36310e3d5408SPeter Wemm {
36320e3d5408SPeter Wemm Call_Hook(form, fieldterm);
36330e3d5408SPeter Wemm res = fct(form);
36340e3d5408SPeter Wemm Call_Hook(form, fieldinit);
36350e3d5408SPeter Wemm }
36360e3d5408SPeter Wemm return res;
36370e3d5408SPeter Wemm }
36380e3d5408SPeter Wemm
36390e3d5408SPeter Wemm /*---------------------------------------------------------------------------
36400e3d5408SPeter Wemm | Facility : libnform
36410e3d5408SPeter Wemm | Function : static int FN_Next_Field(FORM * form)
36420e3d5408SPeter Wemm |
36430e3d5408SPeter Wemm | Description : Move to the next field on the current page of the form
36440e3d5408SPeter Wemm |
36450e3d5408SPeter Wemm | Return Values : E_OK - success
36460e3d5408SPeter Wemm | != E_OK - error from subordinate call
36470e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
36484a1a9510SRong-En Fan static int
FN_Next_Field(FORM * form)36494a1a9510SRong-En Fan FN_Next_Field(FORM *form)
36500e3d5408SPeter Wemm {
365106bfebdeSXin LI T((T_CALLED("FN_Next_Field(%p)"), (void *)form));
36524a1a9510SRong-En Fan returnCode(_nc_Set_Current_Field(form,
36534a1a9510SRong-En Fan Next_Field_On_Page(form->current)));
36540e3d5408SPeter Wemm }
36550e3d5408SPeter Wemm
36560e3d5408SPeter Wemm /*---------------------------------------------------------------------------
36570e3d5408SPeter Wemm | Facility : libnform
36580e3d5408SPeter Wemm | Function : static int FN_Previous_Field(FORM * form)
36590e3d5408SPeter Wemm |
36600e3d5408SPeter Wemm | Description : Move to the previous field on the current page of the
36610e3d5408SPeter Wemm | form
36620e3d5408SPeter Wemm |
36630e3d5408SPeter Wemm | Return Values : E_OK - success
36640e3d5408SPeter Wemm | != E_OK - error from subordinate call
36650e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
36664a1a9510SRong-En Fan static int
FN_Previous_Field(FORM * form)36674a1a9510SRong-En Fan FN_Previous_Field(FORM *form)
36680e3d5408SPeter Wemm {
366906bfebdeSXin LI T((T_CALLED("FN_Previous_Field(%p)"), (void *)form));
36704a1a9510SRong-En Fan returnCode(_nc_Set_Current_Field(form,
36714a1a9510SRong-En Fan Previous_Field_On_Page(form->current)));
36720e3d5408SPeter Wemm }
36730e3d5408SPeter Wemm
36740e3d5408SPeter Wemm /*---------------------------------------------------------------------------
36750e3d5408SPeter Wemm | Facility : libnform
36760e3d5408SPeter Wemm | Function : static int FN_First_Field(FORM * form)
36770e3d5408SPeter Wemm |
36780e3d5408SPeter Wemm | Description : Move to the first field on the current page of the form
36790e3d5408SPeter Wemm |
36800e3d5408SPeter Wemm | Return Values : E_OK - success
36810e3d5408SPeter Wemm | != E_OK - error from subordinate call
36820e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
36834a1a9510SRong-En Fan static int
FN_First_Field(FORM * form)36844a1a9510SRong-En Fan FN_First_Field(FORM *form)
36850e3d5408SPeter Wemm {
368606bfebdeSXin LI T((T_CALLED("FN_First_Field(%p)"), (void *)form));
36874a1a9510SRong-En Fan returnCode(_nc_Set_Current_Field(form,
36884a1a9510SRong-En Fan Next_Field_On_Page(form->field[form->page[form->curpage].pmax])));
36890e3d5408SPeter Wemm }
36900e3d5408SPeter Wemm
36910e3d5408SPeter Wemm /*---------------------------------------------------------------------------
36920e3d5408SPeter Wemm | Facility : libnform
36930e3d5408SPeter Wemm | Function : static int FN_Last_Field(FORM * form)
36940e3d5408SPeter Wemm |
36950e3d5408SPeter Wemm | Description : Move to the last field on the current page of the form
36960e3d5408SPeter Wemm |
36970e3d5408SPeter Wemm | Return Values : E_OK - success
36980e3d5408SPeter Wemm | != E_OK - error from subordinate call
36990e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
37004a1a9510SRong-En Fan static int
FN_Last_Field(FORM * form)37014a1a9510SRong-En Fan FN_Last_Field(FORM *form)
37020e3d5408SPeter Wemm {
370306bfebdeSXin LI T((T_CALLED("FN_Last_Field(%p)"), (void *)form));
37044a1a9510SRong-En Fan returnCode(
37050e3d5408SPeter Wemm _nc_Set_Current_Field(form,
37064a1a9510SRong-En Fan Previous_Field_On_Page(form->field[form->page[form->curpage].pmin])));
37070e3d5408SPeter Wemm }
37080e3d5408SPeter Wemm
37090e3d5408SPeter Wemm /*---------------------------------------------------------------------------
37100e3d5408SPeter Wemm | Facility : libnform
37110e3d5408SPeter Wemm | Function : static int FN_Sorted_Next_Field(FORM * form)
37120e3d5408SPeter Wemm |
37130e3d5408SPeter Wemm | Description : Move to the sorted next field on the current page
37140e3d5408SPeter Wemm | of the form.
37150e3d5408SPeter Wemm |
37160e3d5408SPeter Wemm | Return Values : E_OK - success
37170e3d5408SPeter Wemm | != E_OK - error from subordinate call
37180e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
37194a1a9510SRong-En Fan static int
FN_Sorted_Next_Field(FORM * form)37204a1a9510SRong-En Fan FN_Sorted_Next_Field(FORM *form)
37210e3d5408SPeter Wemm {
372206bfebdeSXin LI T((T_CALLED("FN_Sorted_Next_Field(%p)"), (void *)form));
37234a1a9510SRong-En Fan returnCode(_nc_Set_Current_Field(form,
37244a1a9510SRong-En Fan Sorted_Next_Field(form->current)));
37250e3d5408SPeter Wemm }
37260e3d5408SPeter Wemm
37270e3d5408SPeter Wemm /*---------------------------------------------------------------------------
37280e3d5408SPeter Wemm | Facility : libnform
37290e3d5408SPeter Wemm | Function : static int FN_Sorted_Previous_Field(FORM * form)
37300e3d5408SPeter Wemm |
37310e3d5408SPeter Wemm | Description : Move to the sorted previous field on the current page
37320e3d5408SPeter Wemm | of the form.
37330e3d5408SPeter Wemm |
37340e3d5408SPeter Wemm | Return Values : E_OK - success
37350e3d5408SPeter Wemm | != E_OK - error from subordinate call
37360e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
37374a1a9510SRong-En Fan static int
FN_Sorted_Previous_Field(FORM * form)37384a1a9510SRong-En Fan FN_Sorted_Previous_Field(FORM *form)
37390e3d5408SPeter Wemm {
374006bfebdeSXin LI T((T_CALLED("FN_Sorted_Previous_Field(%p)"), (void *)form));
37414a1a9510SRong-En Fan returnCode(_nc_Set_Current_Field(form,
37424a1a9510SRong-En Fan Sorted_Previous_Field(form->current)));
37430e3d5408SPeter Wemm }
37440e3d5408SPeter Wemm
37450e3d5408SPeter Wemm /*---------------------------------------------------------------------------
37460e3d5408SPeter Wemm | Facility : libnform
37470e3d5408SPeter Wemm | Function : static int FN_Sorted_First_Field(FORM * form)
37480e3d5408SPeter Wemm |
37490e3d5408SPeter Wemm | Description : Move to the sorted first field on the current page
37500e3d5408SPeter Wemm | of the form.
37510e3d5408SPeter Wemm |
37520e3d5408SPeter Wemm | Return Values : E_OK - success
37530e3d5408SPeter Wemm | != E_OK - error from subordinate call
37540e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
37554a1a9510SRong-En Fan static int
FN_Sorted_First_Field(FORM * form)37564a1a9510SRong-En Fan FN_Sorted_First_Field(FORM *form)
37570e3d5408SPeter Wemm {
375806bfebdeSXin LI T((T_CALLED("FN_Sorted_First_Field(%p)"), (void *)form));
37594a1a9510SRong-En Fan returnCode(_nc_Set_Current_Field(form,
37604a1a9510SRong-En Fan Sorted_Next_Field(form->field[form->page[form->curpage].smax])));
37610e3d5408SPeter Wemm }
37620e3d5408SPeter Wemm
37630e3d5408SPeter Wemm /*---------------------------------------------------------------------------
37640e3d5408SPeter Wemm | Facility : libnform
37650e3d5408SPeter Wemm | Function : static int FN_Sorted_Last_Field(FORM * form)
37660e3d5408SPeter Wemm |
37670e3d5408SPeter Wemm | Description : Move to the sorted last field on the current page
37680e3d5408SPeter Wemm | of the form.
37690e3d5408SPeter Wemm |
37700e3d5408SPeter Wemm | Return Values : E_OK - success
37710e3d5408SPeter Wemm | != E_OK - error from subordinate call
37720e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
37734a1a9510SRong-En Fan static int
FN_Sorted_Last_Field(FORM * form)37744a1a9510SRong-En Fan FN_Sorted_Last_Field(FORM *form)
37750e3d5408SPeter Wemm {
377606bfebdeSXin LI T((T_CALLED("FN_Sorted_Last_Field(%p)"), (void *)form));
37774a1a9510SRong-En Fan returnCode(_nc_Set_Current_Field(form,
37784a1a9510SRong-En Fan Sorted_Previous_Field(form->field[form->page[form->curpage].smin])));
37790e3d5408SPeter Wemm }
37800e3d5408SPeter Wemm
37810e3d5408SPeter Wemm /*---------------------------------------------------------------------------
37820e3d5408SPeter Wemm | Facility : libnform
37830e3d5408SPeter Wemm | Function : static int FN_Left_Field(FORM * form)
37840e3d5408SPeter Wemm |
37850e3d5408SPeter Wemm | Description : Get the field on the left of the current field on the
37860e3d5408SPeter Wemm | same line and the same page. Cycles through the line.
37870e3d5408SPeter Wemm |
37880e3d5408SPeter Wemm | Return Values : E_OK - success
37890e3d5408SPeter Wemm | != E_OK - error from subordinate call
37900e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
37914a1a9510SRong-En Fan static int
FN_Left_Field(FORM * form)37924a1a9510SRong-En Fan FN_Left_Field(FORM *form)
37930e3d5408SPeter Wemm {
379406bfebdeSXin LI T((T_CALLED("FN_Left_Field(%p)"), (void *)form));
37954a1a9510SRong-En Fan returnCode(_nc_Set_Current_Field(form,
37964a1a9510SRong-En Fan Left_Neighbor_Field(form->current)));
37970e3d5408SPeter Wemm }
37980e3d5408SPeter Wemm
37990e3d5408SPeter Wemm /*---------------------------------------------------------------------------
38000e3d5408SPeter Wemm | Facility : libnform
38010e3d5408SPeter Wemm | Function : static int FN_Right_Field(FORM * form)
38020e3d5408SPeter Wemm |
38030e3d5408SPeter Wemm | Description : Get the field on the right of the current field on the
38040e3d5408SPeter Wemm | same line and the same page. Cycles through the line.
38050e3d5408SPeter Wemm |
38060e3d5408SPeter Wemm | Return Values : E_OK - success
38070e3d5408SPeter Wemm | != E_OK - error from subordinate call
38080e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
38094a1a9510SRong-En Fan static int
FN_Right_Field(FORM * form)38104a1a9510SRong-En Fan FN_Right_Field(FORM *form)
38110e3d5408SPeter Wemm {
381206bfebdeSXin LI T((T_CALLED("FN_Right_Field(%p)"), (void *)form));
38134a1a9510SRong-En Fan returnCode(_nc_Set_Current_Field(form,
38144a1a9510SRong-En Fan Right_Neighbor_Field(form->current)));
38150e3d5408SPeter Wemm }
38160e3d5408SPeter Wemm
38170e3d5408SPeter Wemm /*---------------------------------------------------------------------------
38180e3d5408SPeter Wemm | Facility : libnform
38190e3d5408SPeter Wemm | Function : static int FN_Up_Field(FORM * form)
38200e3d5408SPeter Wemm |
38214a1a9510SRong-En Fan | Description : Get the upper neighbor of the current field. This
38220e3d5408SPeter Wemm | cycles through the page. See the comments of the
38234a1a9510SRong-En Fan | Upper_Neighbor_Field function to understand how
38240e3d5408SPeter Wemm | 'upper' is defined.
38250e3d5408SPeter Wemm |
38260e3d5408SPeter Wemm | Return Values : E_OK - success
38270e3d5408SPeter Wemm | != E_OK - error from subordinate call
38280e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
38294a1a9510SRong-En Fan static int
FN_Up_Field(FORM * form)38304a1a9510SRong-En Fan FN_Up_Field(FORM *form)
38310e3d5408SPeter Wemm {
383206bfebdeSXin LI T((T_CALLED("FN_Up_Field(%p)"), (void *)form));
38334a1a9510SRong-En Fan returnCode(_nc_Set_Current_Field(form,
38344a1a9510SRong-En Fan Upper_Neighbor_Field(form->current)));
38350e3d5408SPeter Wemm }
38360e3d5408SPeter Wemm
38370e3d5408SPeter Wemm /*---------------------------------------------------------------------------
38380e3d5408SPeter Wemm | Facility : libnform
38390e3d5408SPeter Wemm | Function : static int FN_Down_Field(FORM * form)
38400e3d5408SPeter Wemm |
38414a1a9510SRong-En Fan | Description : Get the down neighbor of the current field. This
38420e3d5408SPeter Wemm | cycles through the page. See the comments of the
38434a1a9510SRong-En Fan | Down_Neighbor_Field function to understand how
38440e3d5408SPeter Wemm | 'down' is defined.
38450e3d5408SPeter Wemm |
38460e3d5408SPeter Wemm | Return Values : E_OK - success
38470e3d5408SPeter Wemm | != E_OK - error from subordinate call
38480e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
38494a1a9510SRong-En Fan static int
FN_Down_Field(FORM * form)38504a1a9510SRong-En Fan FN_Down_Field(FORM *form)
38510e3d5408SPeter Wemm {
385206bfebdeSXin LI T((T_CALLED("FN_Down_Field(%p)"), (void *)form));
38534a1a9510SRong-En Fan returnCode(_nc_Set_Current_Field(form,
38544a1a9510SRong-En Fan Down_Neighbor_Field(form->current)));
38550e3d5408SPeter Wemm }
38560e3d5408SPeter Wemm /*----------------------------------------------------------------------------
38570e3d5408SPeter Wemm END of Field Navigation routines
38580e3d5408SPeter Wemm --------------------------------------------------------------------------*/
38594a1a9510SRong-En Fan
38600e3d5408SPeter Wemm /*----------------------------------------------------------------------------
38610e3d5408SPeter Wemm Helper routines for Page Navigation
38620e3d5408SPeter Wemm --------------------------------------------------------------------------*/
38630e3d5408SPeter Wemm
38640e3d5408SPeter Wemm /*---------------------------------------------------------------------------
38650e3d5408SPeter Wemm | Facility : libnform
38660e3d5408SPeter Wemm | Function : int _nc_Set_Form_Page(FORM * form,
38670e3d5408SPeter Wemm | int page,
38680e3d5408SPeter Wemm | FIELD * field)
38690e3d5408SPeter Wemm |
38704a1a9510SRong-En Fan | Description : Make the given page number the current page and make
38710e3d5408SPeter Wemm | the given field the current field on the page. If
38720e3d5408SPeter Wemm | for the field NULL is given, make the first field on
38730e3d5408SPeter Wemm | the page the current field. The routine acts only
38740e3d5408SPeter Wemm | if the requested page is not the current page.
38750e3d5408SPeter Wemm |
38760e3d5408SPeter Wemm | Return Values : E_OK - success
38770e3d5408SPeter Wemm | != E_OK - error from subordinate call
38784a1a9510SRong-En Fan | E_BAD_ARGUMENT - invalid field pointer
38794a1a9510SRong-En Fan | E_SYSTEM_ERROR - some severe basic error
38800e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
38817a656419SBaptiste Daroussin FORM_EXPORT(int)
_nc_Set_Form_Page(FORM * form,int page,FIELD * field)38824a1a9510SRong-En Fan _nc_Set_Form_Page(FORM *form, int page, FIELD *field)
38830e3d5408SPeter Wemm {
38840e3d5408SPeter Wemm int res = E_OK;
38850e3d5408SPeter Wemm
38860e3d5408SPeter Wemm if ((form->curpage != page))
38870e3d5408SPeter Wemm {
38880e3d5408SPeter Wemm FIELD *last_field, *field_on_page;
38890e3d5408SPeter Wemm
38900e3d5408SPeter Wemm werase(Get_Form_Window(form));
389173f0a83dSXin LI form->curpage = (short)page;
38920e3d5408SPeter Wemm last_field = field_on_page = form->field[form->page[page].smin];
38930e3d5408SPeter Wemm do
38940e3d5408SPeter Wemm {
389573f0a83dSXin LI if ((unsigned)field_on_page->opts & O_VISIBLE)
38960e3d5408SPeter Wemm if ((res = Display_Field(field_on_page)) != E_OK)
38970e3d5408SPeter Wemm return (res);
38980e3d5408SPeter Wemm field_on_page = field_on_page->snext;
38994a1a9510SRong-En Fan }
39004a1a9510SRong-En Fan while (field_on_page != last_field);
39010e3d5408SPeter Wemm
39020e3d5408SPeter Wemm if (field)
39030e3d5408SPeter Wemm res = _nc_Set_Current_Field(form, field);
39040e3d5408SPeter Wemm else
39050e3d5408SPeter Wemm /* N.B.: we don't encapsulate this by Inter_Field_Navigation(),
39060e3d5408SPeter Wemm because this is already executed in a page navigation
39070e3d5408SPeter Wemm context that contains field navigation
39080e3d5408SPeter Wemm */
39090e3d5408SPeter Wemm res = FN_First_Field(form);
39100e3d5408SPeter Wemm }
39110e3d5408SPeter Wemm return (res);
39120e3d5408SPeter Wemm }
39130e3d5408SPeter Wemm
39140e3d5408SPeter Wemm /*---------------------------------------------------------------------------
39150e3d5408SPeter Wemm | Facility : libnform
39160e3d5408SPeter Wemm | Function : static int Next_Page_Number(const FORM * form)
39170e3d5408SPeter Wemm |
39180e3d5408SPeter Wemm | Description : Calculate the page number following the current page
39190e3d5408SPeter Wemm | number. This cycles if the highest page number is
39200e3d5408SPeter Wemm | reached.
39210e3d5408SPeter Wemm |
39220e3d5408SPeter Wemm | Return Values : The next page number
39230e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
39244a1a9510SRong-En Fan NCURSES_INLINE static int
Next_Page_Number(const FORM * form)39254a1a9510SRong-En Fan Next_Page_Number(const FORM *form)
39260e3d5408SPeter Wemm {
39270e3d5408SPeter Wemm return (form->curpage + 1) % form->maxpage;
39280e3d5408SPeter Wemm }
39290e3d5408SPeter Wemm
39300e3d5408SPeter Wemm /*---------------------------------------------------------------------------
39310e3d5408SPeter Wemm | Facility : libnform
39320e3d5408SPeter Wemm | Function : static int Previous_Page_Number(const FORM * form)
39330e3d5408SPeter Wemm |
39340e3d5408SPeter Wemm | Description : Calculate the page number before the current page
39350e3d5408SPeter Wemm | number. This cycles if the first page number is
39360e3d5408SPeter Wemm | reached.
39370e3d5408SPeter Wemm |
39380e3d5408SPeter Wemm | Return Values : The previous page number
39390e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
39404a1a9510SRong-En Fan NCURSES_INLINE static int
Previous_Page_Number(const FORM * form)39414a1a9510SRong-En Fan Previous_Page_Number(const FORM *form)
39420e3d5408SPeter Wemm {
39430e3d5408SPeter Wemm return (form->curpage != 0 ? form->curpage - 1 : form->maxpage - 1);
39440e3d5408SPeter Wemm }
39454a1a9510SRong-En Fan
39460e3d5408SPeter Wemm /*----------------------------------------------------------------------------
39470e3d5408SPeter Wemm Page Navigation routines
39480e3d5408SPeter Wemm --------------------------------------------------------------------------*/
39490e3d5408SPeter Wemm
39500e3d5408SPeter Wemm /*---------------------------------------------------------------------------
39510e3d5408SPeter Wemm | Facility : libnform
39520e3d5408SPeter Wemm | Function : static int Page_Navigation(
39530e3d5408SPeter Wemm | int (* const fct) (FORM *),
39540e3d5408SPeter Wemm | FORM * form)
39550e3d5408SPeter Wemm |
39564a1a9510SRong-En Fan | Description : Generic behavior for changing a page. This means
39570e3d5408SPeter Wemm | that the field is left and a new field is entered.
39580e3d5408SPeter Wemm | So the field must be validated and the field init/term
39590e3d5408SPeter Wemm | hooks must be called. Because also the page is changed,
39607a656419SBaptiste Daroussin | the form's init/term hooks must be called also.
39610e3d5408SPeter Wemm |
39620e3d5408SPeter Wemm | Return Values : E_OK - success
39630e3d5408SPeter Wemm | E_INVALID_FIELD - field is invalid
39640e3d5408SPeter Wemm | some other - error from subordinate call
39650e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
39664a1a9510SRong-En Fan static int
Page_Navigation(int (* const fct)(FORM *),FORM * form)39674a1a9510SRong-En Fan Page_Navigation(int (*const fct) (FORM *), FORM *form)
39680e3d5408SPeter Wemm {
39690e3d5408SPeter Wemm int res;
39700e3d5408SPeter Wemm
39710e3d5408SPeter Wemm if (!_nc_Internal_Validation(form))
39720e3d5408SPeter Wemm res = E_INVALID_FIELD;
39730e3d5408SPeter Wemm else
39740e3d5408SPeter Wemm {
39750e3d5408SPeter Wemm Call_Hook(form, fieldterm);
39760e3d5408SPeter Wemm Call_Hook(form, formterm);
39770e3d5408SPeter Wemm res = fct(form);
39780e3d5408SPeter Wemm Call_Hook(form, forminit);
39790e3d5408SPeter Wemm Call_Hook(form, fieldinit);
39800e3d5408SPeter Wemm }
39810e3d5408SPeter Wemm return res;
39820e3d5408SPeter Wemm }
39830e3d5408SPeter Wemm
39840e3d5408SPeter Wemm /*---------------------------------------------------------------------------
39850e3d5408SPeter Wemm | Facility : libnform
39860e3d5408SPeter Wemm | Function : static int PN_Next_Page(FORM * form)
39870e3d5408SPeter Wemm |
39880e3d5408SPeter Wemm | Description : Move to the next page of the form
39890e3d5408SPeter Wemm |
39900e3d5408SPeter Wemm | Return Values : E_OK - success
39910e3d5408SPeter Wemm | != E_OK - error from subordinate call
39920e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
39934a1a9510SRong-En Fan static int
PN_Next_Page(FORM * form)39944a1a9510SRong-En Fan PN_Next_Page(FORM *form)
39950e3d5408SPeter Wemm {
399606bfebdeSXin LI T((T_CALLED("PN_Next_Page(%p)"), (void *)form));
39974a1a9510SRong-En Fan returnCode(_nc_Set_Form_Page(form, Next_Page_Number(form), (FIELD *)0));
39980e3d5408SPeter Wemm }
39990e3d5408SPeter Wemm
40000e3d5408SPeter Wemm /*---------------------------------------------------------------------------
40010e3d5408SPeter Wemm | Facility : libnform
40020e3d5408SPeter Wemm | Function : static int PN_Previous_Page(FORM * form)
40030e3d5408SPeter Wemm |
40040e3d5408SPeter Wemm | Description : Move to the previous page of the form
40050e3d5408SPeter Wemm |
40060e3d5408SPeter Wemm | Return Values : E_OK - success
40070e3d5408SPeter Wemm | != E_OK - error from subordinate call
40080e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
40094a1a9510SRong-En Fan static int
PN_Previous_Page(FORM * form)40104a1a9510SRong-En Fan PN_Previous_Page(FORM *form)
40110e3d5408SPeter Wemm {
401206bfebdeSXin LI T((T_CALLED("PN_Previous_Page(%p)"), (void *)form));
40134a1a9510SRong-En Fan returnCode(_nc_Set_Form_Page(form, Previous_Page_Number(form), (FIELD *)0));
40140e3d5408SPeter Wemm }
40150e3d5408SPeter Wemm
40160e3d5408SPeter Wemm /*---------------------------------------------------------------------------
40170e3d5408SPeter Wemm | Facility : libnform
40180e3d5408SPeter Wemm | Function : static int PN_First_Page(FORM * form)
40190e3d5408SPeter Wemm |
40200e3d5408SPeter Wemm | Description : Move to the first page of the form
40210e3d5408SPeter Wemm |
40220e3d5408SPeter Wemm | Return Values : E_OK - success
40230e3d5408SPeter Wemm | != E_OK - error from subordinate call
40240e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
40254a1a9510SRong-En Fan static int
PN_First_Page(FORM * form)40264a1a9510SRong-En Fan PN_First_Page(FORM *form)
40270e3d5408SPeter Wemm {
402806bfebdeSXin LI T((T_CALLED("PN_First_Page(%p)"), (void *)form));
40294a1a9510SRong-En Fan returnCode(_nc_Set_Form_Page(form, 0, (FIELD *)0));
40300e3d5408SPeter Wemm }
40310e3d5408SPeter Wemm
40320e3d5408SPeter Wemm /*---------------------------------------------------------------------------
40330e3d5408SPeter Wemm | Facility : libnform
40340e3d5408SPeter Wemm | Function : static int PN_Last_Page(FORM * form)
40350e3d5408SPeter Wemm |
40360e3d5408SPeter Wemm | Description : Move to the last page of the form
40370e3d5408SPeter Wemm |
40380e3d5408SPeter Wemm | Return Values : E_OK - success
40390e3d5408SPeter Wemm | != E_OK - error from subordinate call
40400e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
40414a1a9510SRong-En Fan static int
PN_Last_Page(FORM * form)40424a1a9510SRong-En Fan PN_Last_Page(FORM *form)
40430e3d5408SPeter Wemm {
404406bfebdeSXin LI T((T_CALLED("PN_Last_Page(%p)"), (void *)form));
40454a1a9510SRong-En Fan returnCode(_nc_Set_Form_Page(form, form->maxpage - 1, (FIELD *)0));
40460e3d5408SPeter Wemm }
40474a1a9510SRong-En Fan
40480e3d5408SPeter Wemm /*----------------------------------------------------------------------------
40490e3d5408SPeter Wemm END of Field Navigation routines
40500e3d5408SPeter Wemm --------------------------------------------------------------------------*/
40514a1a9510SRong-En Fan
40520e3d5408SPeter Wemm /*----------------------------------------------------------------------------
40530e3d5408SPeter Wemm Helper routines for the core form driver.
40540e3d5408SPeter Wemm --------------------------------------------------------------------------*/
40550e3d5408SPeter Wemm
405673f0a83dSXin LI # if USE_WIDEC_SUPPORT
405773f0a83dSXin LI /*---------------------------------------------------------------------------
405873f0a83dSXin LI | Facility : libnform
405973f0a83dSXin LI | Function : static int Data_Entry_w(FORM * form, wchar_t c)
406073f0a83dSXin LI |
406173f0a83dSXin LI | Description : Enter the wide character c into at the current
406273f0a83dSXin LI | position of the current field of the form.
406373f0a83dSXin LI |
406473f0a83dSXin LI | Return Values : E_OK - success
406573f0a83dSXin LI | E_REQUEST_DENIED - driver could not process the request
406673f0a83dSXin LI | E_SYSTEM_ERROR -
406773f0a83dSXin LI +--------------------------------------------------------------------------*/
406873f0a83dSXin LI static int
Data_Entry_w(FORM * form,wchar_t c)406973f0a83dSXin LI Data_Entry_w(FORM *form, wchar_t c)
407073f0a83dSXin LI {
407173f0a83dSXin LI FIELD *field = form->current;
407273f0a83dSXin LI int result = E_REQUEST_DENIED;
407373f0a83dSXin LI
407473f0a83dSXin LI T((T_CALLED("Data_Entry(%p,%s)"), (void *)form, _tracechtype((chtype)c)));
4075aae38d10SBaptiste Daroussin if ((Field_Has_Option(field, O_EDIT))
407673f0a83dSXin LI #if FIX_FORM_INACTIVE_BUG
4077aae38d10SBaptiste Daroussin && (Field_Has_Option(field, O_ACTIVE))
407873f0a83dSXin LI #endif
407973f0a83dSXin LI )
408073f0a83dSXin LI {
408173f0a83dSXin LI wchar_t given[2];
408273f0a83dSXin LI cchar_t temp_ch;
408373f0a83dSXin LI
408473f0a83dSXin LI given[0] = c;
4085aae38d10SBaptiste Daroussin given[1] = 0;
408673f0a83dSXin LI setcchar(&temp_ch, given, 0, 0, (void *)0);
4087aae38d10SBaptiste Daroussin if ((Field_Has_Option(field, O_BLANK)) &&
408873f0a83dSXin LI First_Position_In_Current_Field(form) &&
408973f0a83dSXin LI !(form->status & _FCHECK_REQUIRED) &&
409073f0a83dSXin LI !(form->status & _WINDOW_MODIFIED))
409173f0a83dSXin LI werase(form->w);
409273f0a83dSXin LI
409373f0a83dSXin LI if (form->status & _OVLMODE)
409473f0a83dSXin LI {
409573f0a83dSXin LI wadd_wch(form->w, &temp_ch);
409673f0a83dSXin LI }
409773f0a83dSXin LI else
409873f0a83dSXin LI /* no _OVLMODE */
409973f0a83dSXin LI {
410073f0a83dSXin LI bool There_Is_Room = Is_There_Room_For_A_Char_In_Line(form);
410173f0a83dSXin LI
410273f0a83dSXin LI if (!(There_Is_Room ||
410373f0a83dSXin LI ((Single_Line_Field(field) && Growable(field)))))
410473f0a83dSXin LI RETURN(E_REQUEST_DENIED);
410573f0a83dSXin LI
410673f0a83dSXin LI if (!There_Is_Room && !Field_Grown(field, 1))
410773f0a83dSXin LI RETURN(E_SYSTEM_ERROR);
410873f0a83dSXin LI
410973f0a83dSXin LI wins_wch(form->w, &temp_ch);
411073f0a83dSXin LI }
411173f0a83dSXin LI
411273f0a83dSXin LI if ((result = Wrapping_Not_Necessary_Or_Wrapping_Ok(form)) == E_OK)
411373f0a83dSXin LI {
411473f0a83dSXin LI bool End_Of_Field = (((field->drows - 1) == form->currow) &&
411573f0a83dSXin LI ((field->dcols - 1) == form->curcol));
411673f0a83dSXin LI
411773f0a83dSXin LI form->status |= _WINDOW_MODIFIED;
4118aae38d10SBaptiste Daroussin if (End_Of_Field && !Growable(field) && (Field_Has_Option(field, O_AUTOSKIP)))
411973f0a83dSXin LI result = Inter_Field_Navigation(FN_Next_Field, form);
412073f0a83dSXin LI else
412173f0a83dSXin LI {
412273f0a83dSXin LI if (End_Of_Field && Growable(field) && !Field_Grown(field, 1))
412373f0a83dSXin LI result = E_SYSTEM_ERROR;
412473f0a83dSXin LI else
412573f0a83dSXin LI {
412673f0a83dSXin LI /*
412773f0a83dSXin LI * We have just added a byte to the form field. It may have
412873f0a83dSXin LI * been part of a multibyte character. If it was, the
412973f0a83dSXin LI * addch_used field is nonzero and we should not try to move
413073f0a83dSXin LI * to a new column.
413173f0a83dSXin LI */
413273f0a83dSXin LI if (WINDOW_EXT(form->w, addch_used) == 0)
413373f0a83dSXin LI IFN_Next_Character(form);
413473f0a83dSXin LI
413573f0a83dSXin LI result = E_OK;
413673f0a83dSXin LI }
413773f0a83dSXin LI }
413873f0a83dSXin LI }
413973f0a83dSXin LI }
414073f0a83dSXin LI RETURN(result);
414173f0a83dSXin LI }
414273f0a83dSXin LI # endif
414373f0a83dSXin LI
41440e3d5408SPeter Wemm /*---------------------------------------------------------------------------
41450e3d5408SPeter Wemm | Facility : libnform
41460e3d5408SPeter Wemm | Function : static int Data_Entry(FORM * form,int c)
41470e3d5408SPeter Wemm |
41480e3d5408SPeter Wemm | Description : Enter character c into at the current position of the
41490e3d5408SPeter Wemm | current field of the form.
41500e3d5408SPeter Wemm |
41514a1a9510SRong-En Fan | Return Values : E_OK - success
41524a1a9510SRong-En Fan | E_REQUEST_DENIED - driver could not process the request
41530e3d5408SPeter Wemm | E_SYSTEM_ERROR -
41540e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
41554a1a9510SRong-En Fan static int
Data_Entry(FORM * form,int c)41564a1a9510SRong-En Fan Data_Entry(FORM *form, int c)
41570e3d5408SPeter Wemm {
41580e3d5408SPeter Wemm FIELD *field = form->current;
41590e3d5408SPeter Wemm int result = E_REQUEST_DENIED;
41600e3d5408SPeter Wemm
416106bfebdeSXin LI T((T_CALLED("Data_Entry(%p,%s)"), (void *)form, _tracechtype((chtype)c)));
4162aae38d10SBaptiste Daroussin if ((Field_Has_Option(field, O_EDIT))
41630e3d5408SPeter Wemm #if FIX_FORM_INACTIVE_BUG
4164aae38d10SBaptiste Daroussin && (Field_Has_Option(field, O_ACTIVE))
41650e3d5408SPeter Wemm #endif
41660e3d5408SPeter Wemm )
41670e3d5408SPeter Wemm {
4168aae38d10SBaptiste Daroussin if ((Field_Has_Option(field, O_BLANK)) &&
41690e3d5408SPeter Wemm First_Position_In_Current_Field(form) &&
41700e3d5408SPeter Wemm !(form->status & _FCHECK_REQUIRED) &&
41710e3d5408SPeter Wemm !(form->status & _WINDOW_MODIFIED))
41720e3d5408SPeter Wemm werase(form->w);
41730e3d5408SPeter Wemm
41740e3d5408SPeter Wemm if (form->status & _OVLMODE)
41750e3d5408SPeter Wemm {
41760e3d5408SPeter Wemm waddch(form->w, (chtype)c);
41770e3d5408SPeter Wemm }
41784a1a9510SRong-En Fan else
41794a1a9510SRong-En Fan /* no _OVLMODE */
41800e3d5408SPeter Wemm {
41810e3d5408SPeter Wemm bool There_Is_Room = Is_There_Room_For_A_Char_In_Line(form);
41820e3d5408SPeter Wemm
41830e3d5408SPeter Wemm if (!(There_Is_Room ||
41840e3d5408SPeter Wemm ((Single_Line_Field(field) && Growable(field)))))
41854a1a9510SRong-En Fan RETURN(E_REQUEST_DENIED);
41860e3d5408SPeter Wemm
41870e3d5408SPeter Wemm if (!There_Is_Room && !Field_Grown(field, 1))
41884a1a9510SRong-En Fan RETURN(E_SYSTEM_ERROR);
41890e3d5408SPeter Wemm
41900e3d5408SPeter Wemm winsch(form->w, (chtype)c);
41910e3d5408SPeter Wemm }
41920e3d5408SPeter Wemm
41930e3d5408SPeter Wemm if ((result = Wrapping_Not_Necessary_Or_Wrapping_Ok(form)) == E_OK)
41940e3d5408SPeter Wemm {
41950e3d5408SPeter Wemm bool End_Of_Field = (((field->drows - 1) == form->currow) &&
41960e3d5408SPeter Wemm ((field->dcols - 1) == form->curcol));
41974a1a9510SRong-En Fan
4198aae38d10SBaptiste Daroussin if (Field_Has_Option(field, O_EDGE_INSERT_STAY))
4199aae38d10SBaptiste Daroussin move_after_insert = !!(form->curcol
4200aae38d10SBaptiste Daroussin - form->begincol
4201aae38d10SBaptiste Daroussin - field->cols
4202aae38d10SBaptiste Daroussin + 1);
4203aae38d10SBaptiste Daroussin
420473f0a83dSXin LI SetStatus(form, _WINDOW_MODIFIED);
4205aae38d10SBaptiste Daroussin if (End_Of_Field && !Growable(field) && (Field_Has_Option(field, O_AUTOSKIP)))
42060e3d5408SPeter Wemm result = Inter_Field_Navigation(FN_Next_Field, form);
42070e3d5408SPeter Wemm else
42080e3d5408SPeter Wemm {
42090e3d5408SPeter Wemm if (End_Of_Field && Growable(field) && !Field_Grown(field, 1))
42100e3d5408SPeter Wemm result = E_SYSTEM_ERROR;
42110e3d5408SPeter Wemm else
42120e3d5408SPeter Wemm {
42134a1a9510SRong-En Fan #if USE_WIDEC_SUPPORT
42144a1a9510SRong-En Fan /*
42154a1a9510SRong-En Fan * We have just added a byte to the form field. It may have
42164a1a9510SRong-En Fan * been part of a multibyte character. If it was, the
42174a1a9510SRong-En Fan * addch_used field is nonzero and we should not try to move
42184a1a9510SRong-En Fan * to a new column.
42194a1a9510SRong-En Fan */
42204a1a9510SRong-En Fan if (WINDOW_EXT(form->w, addch_used) == 0)
42210e3d5408SPeter Wemm IFN_Next_Character(form);
42224a1a9510SRong-En Fan #else
42234a1a9510SRong-En Fan IFN_Next_Character(form);
42244a1a9510SRong-En Fan #endif
42250e3d5408SPeter Wemm result = E_OK;
42260e3d5408SPeter Wemm }
42270e3d5408SPeter Wemm }
42280e3d5408SPeter Wemm }
42290e3d5408SPeter Wemm }
42304a1a9510SRong-En Fan RETURN(result);
42310e3d5408SPeter Wemm }
42324a1a9510SRong-En Fan
42330e3d5408SPeter Wemm /* Structure to describe the binding of a request code to a function.
42340e3d5408SPeter Wemm The member keycode codes the request value as well as the generic
42350e3d5408SPeter Wemm routine to use for the request. The code for the generic routine
42360e3d5408SPeter Wemm is coded in the upper 16 Bits while the request code is coded in
42370e3d5408SPeter Wemm the lower 16 bits.
42380e3d5408SPeter Wemm
42390e3d5408SPeter Wemm In terms of C++ you might think of a request as a class with a
42400e3d5408SPeter Wemm virtual method "perform". The different types of request are
42410e3d5408SPeter Wemm derived from this base class and overload (or not) the base class
42420e3d5408SPeter Wemm implementation of perform.
42430e3d5408SPeter Wemm */
42444a1a9510SRong-En Fan typedef struct
42454a1a9510SRong-En Fan {
42460e3d5408SPeter Wemm int keycode; /* must be at least 32 bit: hi:mode, lo: key */
42470e3d5408SPeter Wemm int (*cmd) (FORM *); /* low level driver routine for this key */
42484a1a9510SRong-En Fan }
42494a1a9510SRong-En Fan Binding_Info;
42500e3d5408SPeter Wemm
42510e3d5408SPeter Wemm /* You may see this is the class-id of the request type class */
42520e3d5408SPeter Wemm #define ID_PN (0x00000000) /* Page navigation */
42530e3d5408SPeter Wemm #define ID_FN (0x00010000) /* Inter-Field navigation */
42540e3d5408SPeter Wemm #define ID_IFN (0x00020000) /* Intra-Field navigation */
42550e3d5408SPeter Wemm #define ID_VSC (0x00030000) /* Vertical Scrolling */
42560e3d5408SPeter Wemm #define ID_HSC (0x00040000) /* Horizontal Scrolling */
42570e3d5408SPeter Wemm #define ID_FE (0x00050000) /* Field Editing */
42580e3d5408SPeter Wemm #define ID_EM (0x00060000) /* Edit Mode */
42590e3d5408SPeter Wemm #define ID_FV (0x00070000) /* Field Validation */
42600e3d5408SPeter Wemm #define ID_CH (0x00080000) /* Choice */
42610e3d5408SPeter Wemm #define ID_Mask (0xffff0000)
42620e3d5408SPeter Wemm #define Key_Mask (0x0000ffff)
42630e3d5408SPeter Wemm #define ID_Shft (16)
42640e3d5408SPeter Wemm
42650e3d5408SPeter Wemm /* This array holds all the Binding Infos */
42664a1a9510SRong-En Fan /* *INDENT-OFF* */
42670e3d5408SPeter Wemm static const Binding_Info bindings[MAX_FORM_COMMAND - MIN_FORM_COMMAND + 1] =
42680e3d5408SPeter Wemm {
42690e3d5408SPeter Wemm { REQ_NEXT_PAGE |ID_PN ,PN_Next_Page},
42700e3d5408SPeter Wemm { REQ_PREV_PAGE |ID_PN ,PN_Previous_Page},
42710e3d5408SPeter Wemm { REQ_FIRST_PAGE |ID_PN ,PN_First_Page},
42720e3d5408SPeter Wemm { REQ_LAST_PAGE |ID_PN ,PN_Last_Page},
42730e3d5408SPeter Wemm
42740e3d5408SPeter Wemm { REQ_NEXT_FIELD |ID_FN ,FN_Next_Field},
42750e3d5408SPeter Wemm { REQ_PREV_FIELD |ID_FN ,FN_Previous_Field},
42760e3d5408SPeter Wemm { REQ_FIRST_FIELD |ID_FN ,FN_First_Field},
42770e3d5408SPeter Wemm { REQ_LAST_FIELD |ID_FN ,FN_Last_Field},
42780e3d5408SPeter Wemm { REQ_SNEXT_FIELD |ID_FN ,FN_Sorted_Next_Field},
42790e3d5408SPeter Wemm { REQ_SPREV_FIELD |ID_FN ,FN_Sorted_Previous_Field},
42800e3d5408SPeter Wemm { REQ_SFIRST_FIELD |ID_FN ,FN_Sorted_First_Field},
42810e3d5408SPeter Wemm { REQ_SLAST_FIELD |ID_FN ,FN_Sorted_Last_Field},
42820e3d5408SPeter Wemm { REQ_LEFT_FIELD |ID_FN ,FN_Left_Field},
42830e3d5408SPeter Wemm { REQ_RIGHT_FIELD |ID_FN ,FN_Right_Field},
42840e3d5408SPeter Wemm { REQ_UP_FIELD |ID_FN ,FN_Up_Field},
42850e3d5408SPeter Wemm { REQ_DOWN_FIELD |ID_FN ,FN_Down_Field},
42860e3d5408SPeter Wemm
42870e3d5408SPeter Wemm { REQ_NEXT_CHAR |ID_IFN ,IFN_Next_Character},
42880e3d5408SPeter Wemm { REQ_PREV_CHAR |ID_IFN ,IFN_Previous_Character},
42890e3d5408SPeter Wemm { REQ_NEXT_LINE |ID_IFN ,IFN_Next_Line},
42900e3d5408SPeter Wemm { REQ_PREV_LINE |ID_IFN ,IFN_Previous_Line},
42910e3d5408SPeter Wemm { REQ_NEXT_WORD |ID_IFN ,IFN_Next_Word},
42920e3d5408SPeter Wemm { REQ_PREV_WORD |ID_IFN ,IFN_Previous_Word},
42930e3d5408SPeter Wemm { REQ_BEG_FIELD |ID_IFN ,IFN_Beginning_Of_Field},
42940e3d5408SPeter Wemm { REQ_END_FIELD |ID_IFN ,IFN_End_Of_Field},
42950e3d5408SPeter Wemm { REQ_BEG_LINE |ID_IFN ,IFN_Beginning_Of_Line},
42960e3d5408SPeter Wemm { REQ_END_LINE |ID_IFN ,IFN_End_Of_Line},
42970e3d5408SPeter Wemm { REQ_LEFT_CHAR |ID_IFN ,IFN_Left_Character},
42980e3d5408SPeter Wemm { REQ_RIGHT_CHAR |ID_IFN ,IFN_Right_Character},
42990e3d5408SPeter Wemm { REQ_UP_CHAR |ID_IFN ,IFN_Up_Character},
43000e3d5408SPeter Wemm { REQ_DOWN_CHAR |ID_IFN ,IFN_Down_Character},
43010e3d5408SPeter Wemm
43020e3d5408SPeter Wemm { REQ_NEW_LINE |ID_FE ,FE_New_Line},
43030e3d5408SPeter Wemm { REQ_INS_CHAR |ID_FE ,FE_Insert_Character},
43040e3d5408SPeter Wemm { REQ_INS_LINE |ID_FE ,FE_Insert_Line},
43050e3d5408SPeter Wemm { REQ_DEL_CHAR |ID_FE ,FE_Delete_Character},
43060e3d5408SPeter Wemm { REQ_DEL_PREV |ID_FE ,FE_Delete_Previous},
43070e3d5408SPeter Wemm { REQ_DEL_LINE |ID_FE ,FE_Delete_Line},
43080e3d5408SPeter Wemm { REQ_DEL_WORD |ID_FE ,FE_Delete_Word},
43090e3d5408SPeter Wemm { REQ_CLR_EOL |ID_FE ,FE_Clear_To_End_Of_Line},
43104a1a9510SRong-En Fan { REQ_CLR_EOF |ID_FE ,FE_Clear_To_End_Of_Field},
43110e3d5408SPeter Wemm { REQ_CLR_FIELD |ID_FE ,FE_Clear_Field},
43120e3d5408SPeter Wemm
43130e3d5408SPeter Wemm { REQ_OVL_MODE |ID_EM ,EM_Overlay_Mode},
43140e3d5408SPeter Wemm { REQ_INS_MODE |ID_EM ,EM_Insert_Mode},
43150e3d5408SPeter Wemm
43160e3d5408SPeter Wemm { REQ_SCR_FLINE |ID_VSC ,VSC_Scroll_Line_Forward},
43170e3d5408SPeter Wemm { REQ_SCR_BLINE |ID_VSC ,VSC_Scroll_Line_Backward},
43180e3d5408SPeter Wemm { REQ_SCR_FPAGE |ID_VSC ,VSC_Scroll_Page_Forward},
43190e3d5408SPeter Wemm { REQ_SCR_BPAGE |ID_VSC ,VSC_Scroll_Page_Backward},
43200e3d5408SPeter Wemm { REQ_SCR_FHPAGE |ID_VSC ,VSC_Scroll_Half_Page_Forward},
43210e3d5408SPeter Wemm { REQ_SCR_BHPAGE |ID_VSC ,VSC_Scroll_Half_Page_Backward},
43220e3d5408SPeter Wemm
43230e3d5408SPeter Wemm { REQ_SCR_FCHAR |ID_HSC ,HSC_Scroll_Char_Forward},
43240e3d5408SPeter Wemm { REQ_SCR_BCHAR |ID_HSC ,HSC_Scroll_Char_Backward},
43250e3d5408SPeter Wemm { REQ_SCR_HFLINE |ID_HSC ,HSC_Horizontal_Line_Forward},
43260e3d5408SPeter Wemm { REQ_SCR_HBLINE |ID_HSC ,HSC_Horizontal_Line_Backward},
43270e3d5408SPeter Wemm { REQ_SCR_HFHALF |ID_HSC ,HSC_Horizontal_Half_Line_Forward},
43280e3d5408SPeter Wemm { REQ_SCR_HBHALF |ID_HSC ,HSC_Horizontal_Half_Line_Backward},
43290e3d5408SPeter Wemm
43300e3d5408SPeter Wemm { REQ_VALIDATION |ID_FV ,FV_Validation},
43310e3d5408SPeter Wemm
43320e3d5408SPeter Wemm { REQ_NEXT_CHOICE |ID_CH ,CR_Next_Choice},
43330e3d5408SPeter Wemm { REQ_PREV_CHOICE |ID_CH ,CR_Previous_Choice}
43340e3d5408SPeter Wemm };
43354a1a9510SRong-En Fan /* *INDENT-ON* */
43360e3d5408SPeter Wemm
43370e3d5408SPeter Wemm /*---------------------------------------------------------------------------
43380e3d5408SPeter Wemm | Facility : libnform
43390e3d5408SPeter Wemm | Function : int form_driver(FORM * form,int c)
43400e3d5408SPeter Wemm |
43410e3d5408SPeter Wemm | Description : This is the workhorse of the forms system. It checks
43420e3d5408SPeter Wemm | to determine whether the character c is a request or
43430e3d5408SPeter Wemm | data. If it is a request, the form driver executes
43440e3d5408SPeter Wemm | the request and returns the result. If it is data
43450e3d5408SPeter Wemm | (printable character), it enters the data into the
43460e3d5408SPeter Wemm | current position in the current field. If it is not
43470e3d5408SPeter Wemm | recognized, the form driver assumes it is an application
43480e3d5408SPeter Wemm | defined command and returns E_UNKNOWN_COMMAND.
43490e3d5408SPeter Wemm | Application defined command should be defined relative
43500e3d5408SPeter Wemm | to MAX_FORM_COMMAND, the maximum value of a request.
43510e3d5408SPeter Wemm |
43520e3d5408SPeter Wemm | Return Values : E_OK - success
43530e3d5408SPeter Wemm | E_SYSTEM_ERROR - system error
43540e3d5408SPeter Wemm | E_BAD_ARGUMENT - an argument is incorrect
43550e3d5408SPeter Wemm | E_NOT_POSTED - form is not posted
43560e3d5408SPeter Wemm | E_INVALID_FIELD - field contents are invalid
43570e3d5408SPeter Wemm | E_BAD_STATE - called from inside a hook routine
43580e3d5408SPeter Wemm | E_REQUEST_DENIED - request failed
43594a1a9510SRong-En Fan | E_NOT_CONNECTED - no fields are connected to the form
43600e3d5408SPeter Wemm | E_UNKNOWN_COMMAND - command not known
43610e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
43627a656419SBaptiste Daroussin FORM_EXPORT(int)
form_driver(FORM * form,int c)43637a69bbfbSPeter Wemm form_driver(FORM *form, int c)
43640e3d5408SPeter Wemm {
43650e3d5408SPeter Wemm const Binding_Info *BI = (Binding_Info *)0;
43660e3d5408SPeter Wemm int res = E_UNKNOWN_COMMAND;
43670e3d5408SPeter Wemm
4368aae38d10SBaptiste Daroussin move_after_insert = TRUE;
4369aae38d10SBaptiste Daroussin
437006bfebdeSXin LI T((T_CALLED("form_driver(%p,%d)"), (void *)form, c));
43714a1a9510SRong-En Fan
43720e3d5408SPeter Wemm if (!form)
43730e3d5408SPeter Wemm RETURN(E_BAD_ARGUMENT);
43740e3d5408SPeter Wemm
4375aae38d10SBaptiste Daroussin if (!(form->field) || !(form->current))
43760e3d5408SPeter Wemm RETURN(E_NOT_CONNECTED);
43770e3d5408SPeter Wemm
43780e3d5408SPeter Wemm assert(form->page);
43790e3d5408SPeter Wemm
43800e3d5408SPeter Wemm if (c == FIRST_ACTIVE_MAGIC)
43810e3d5408SPeter Wemm {
43820e3d5408SPeter Wemm form->current = _nc_First_Active_Field(form);
43834a1a9510SRong-En Fan RETURN(E_OK);
43840e3d5408SPeter Wemm }
43850e3d5408SPeter Wemm
43860e3d5408SPeter Wemm assert(form->current &&
43870e3d5408SPeter Wemm form->current->buf &&
43880e3d5408SPeter Wemm (form->current->form == form)
43890e3d5408SPeter Wemm );
43900e3d5408SPeter Wemm
43910e3d5408SPeter Wemm if (form->status & _IN_DRIVER)
43920e3d5408SPeter Wemm RETURN(E_BAD_STATE);
43930e3d5408SPeter Wemm
43940e3d5408SPeter Wemm if (!(form->status & _POSTED))
43950e3d5408SPeter Wemm RETURN(E_NOT_POSTED);
43960e3d5408SPeter Wemm
43970e3d5408SPeter Wemm if ((c >= MIN_FORM_COMMAND && c <= MAX_FORM_COMMAND) &&
43980e3d5408SPeter Wemm ((bindings[c - MIN_FORM_COMMAND].keycode & Key_Mask) == c))
439973f0a83dSXin LI {
440073f0a83dSXin LI TR(TRACE_CALLS, ("form_request %s", form_request_name(c)));
44010e3d5408SPeter Wemm BI = &(bindings[c - MIN_FORM_COMMAND]);
440273f0a83dSXin LI }
44030e3d5408SPeter Wemm
44040e3d5408SPeter Wemm if (BI)
44050e3d5408SPeter Wemm {
44060e3d5408SPeter Wemm typedef int (*Generic_Method) (int (*const) (FORM *), FORM *);
44070e3d5408SPeter Wemm static const Generic_Method Generic_Methods[] =
44080e3d5408SPeter Wemm {
44090e3d5408SPeter Wemm Page_Navigation, /* overloaded to call field&form hooks */
44100e3d5408SPeter Wemm Inter_Field_Navigation, /* overloaded to call field hooks */
44110e3d5408SPeter Wemm NULL, /* Intra-Field is generic */
44120e3d5408SPeter Wemm Vertical_Scrolling, /* Overloaded to check multi-line */
44130e3d5408SPeter Wemm Horizontal_Scrolling, /* Overloaded to check single-line */
44140e3d5408SPeter Wemm Field_Editing, /* Overloaded to mark modification */
44150e3d5408SPeter Wemm NULL, /* Edit Mode is generic */
44160e3d5408SPeter Wemm NULL, /* Field Validation is generic */
44170e3d5408SPeter Wemm NULL /* Choice Request is generic */
44180e3d5408SPeter Wemm };
44190e3d5408SPeter Wemm size_t nMethods = (sizeof(Generic_Methods) / sizeof(Generic_Methods[0]));
442073f0a83dSXin LI size_t method = (size_t)((BI->keycode >> ID_Shft) & 0xffff); /* see ID_Mask */
44210e3d5408SPeter Wemm
44220e3d5408SPeter Wemm if ((method >= nMethods) || !(BI->cmd))
44230e3d5408SPeter Wemm res = E_SYSTEM_ERROR;
44240e3d5408SPeter Wemm else
44250e3d5408SPeter Wemm {
44260e3d5408SPeter Wemm Generic_Method fct = Generic_Methods[method];
44274a1a9510SRong-En Fan
44280e3d5408SPeter Wemm if (fct)
442973f0a83dSXin LI {
44300e3d5408SPeter Wemm res = fct(BI->cmd, form);
443173f0a83dSXin LI }
44320e3d5408SPeter Wemm else
443373f0a83dSXin LI {
44340e3d5408SPeter Wemm res = (BI->cmd) (form);
44350e3d5408SPeter Wemm }
44360e3d5408SPeter Wemm }
443773f0a83dSXin LI }
44385ca44d1cSRong-En Fan #ifdef NCURSES_MOUSE_VERSION
44395ca44d1cSRong-En Fan else if (KEY_MOUSE == c)
44405ca44d1cSRong-En Fan {
44415ca44d1cSRong-En Fan MEVENT event;
444206bfebdeSXin LI WINDOW *win = form->win ? form->win : StdScreen(Get_Form_Screen(form));
44435ca44d1cSRong-En Fan WINDOW *sub = form->sub ? form->sub : win;
44445ca44d1cSRong-En Fan
44455ca44d1cSRong-En Fan getmouse(&event);
44465ca44d1cSRong-En Fan if ((event.bstate & (BUTTON1_CLICKED |
44475ca44d1cSRong-En Fan BUTTON1_DOUBLE_CLICKED |
44485ca44d1cSRong-En Fan BUTTON1_TRIPLE_CLICKED))
44495ca44d1cSRong-En Fan && wenclose(win, event.y, event.x))
44505ca44d1cSRong-En Fan { /* we react only if the click was in the userwin, that means
44515ca44d1cSRong-En Fan * inside the form display area or at the decoration window.
44525ca44d1cSRong-En Fan */
44535ca44d1cSRong-En Fan int ry = event.y, rx = event.x; /* screen coordinates */
44545ca44d1cSRong-En Fan
44555ca44d1cSRong-En Fan res = E_REQUEST_DENIED;
44565ca44d1cSRong-En Fan if (mouse_trafo(&ry, &rx, FALSE))
44575ca44d1cSRong-En Fan { /* rx, ry are now "curses" coordinates */
44585ca44d1cSRong-En Fan if (ry < sub->_begy)
44595ca44d1cSRong-En Fan { /* we clicked above the display region; this is
44605ca44d1cSRong-En Fan * interpreted as "scroll up" request
44615ca44d1cSRong-En Fan */
44625ca44d1cSRong-En Fan if (event.bstate & BUTTON1_CLICKED)
44635ca44d1cSRong-En Fan res = form_driver(form, REQ_PREV_FIELD);
44645ca44d1cSRong-En Fan else if (event.bstate & BUTTON1_DOUBLE_CLICKED)
44655ca44d1cSRong-En Fan res = form_driver(form, REQ_PREV_PAGE);
44665ca44d1cSRong-En Fan else if (event.bstate & BUTTON1_TRIPLE_CLICKED)
44675ca44d1cSRong-En Fan res = form_driver(form, REQ_FIRST_FIELD);
44685ca44d1cSRong-En Fan }
44695ca44d1cSRong-En Fan else if (ry > sub->_begy + sub->_maxy)
44705ca44d1cSRong-En Fan { /* we clicked below the display region; this is
44715ca44d1cSRong-En Fan * interpreted as "scroll down" request
44725ca44d1cSRong-En Fan */
44735ca44d1cSRong-En Fan if (event.bstate & BUTTON1_CLICKED)
44745ca44d1cSRong-En Fan res = form_driver(form, REQ_NEXT_FIELD);
44755ca44d1cSRong-En Fan else if (event.bstate & BUTTON1_DOUBLE_CLICKED)
44765ca44d1cSRong-En Fan res = form_driver(form, REQ_NEXT_PAGE);
44775ca44d1cSRong-En Fan else if (event.bstate & BUTTON1_TRIPLE_CLICKED)
44785ca44d1cSRong-En Fan res = form_driver(form, REQ_LAST_FIELD);
44795ca44d1cSRong-En Fan }
44805ca44d1cSRong-En Fan else if (wenclose(sub, event.y, event.x))
44815ca44d1cSRong-En Fan { /* Inside the area we try to find the hit item */
44825ca44d1cSRong-En Fan ry = event.y;
44835ca44d1cSRong-En Fan rx = event.x;
44845ca44d1cSRong-En Fan if (wmouse_trafo(sub, &ry, &rx, FALSE))
44855ca44d1cSRong-En Fan {
44865ca44d1cSRong-En Fan int min_field = form->page[form->curpage].pmin;
44875ca44d1cSRong-En Fan int max_field = form->page[form->curpage].pmax;
4488*21817992SBaptiste Daroussin int i;
44895ca44d1cSRong-En Fan
44905ca44d1cSRong-En Fan for (i = min_field; i <= max_field; ++i)
44915ca44d1cSRong-En Fan {
44925ca44d1cSRong-En Fan FIELD *field = form->field[i];
44935ca44d1cSRong-En Fan
44945ca44d1cSRong-En Fan if (Field_Is_Selectable(field)
44955ca44d1cSRong-En Fan && Field_encloses(field, ry, rx) == E_OK)
44965ca44d1cSRong-En Fan {
44975ca44d1cSRong-En Fan res = _nc_Set_Current_Field(form, field);
44985ca44d1cSRong-En Fan if (res == E_OK)
44995ca44d1cSRong-En Fan res = _nc_Position_Form_Cursor(form);
45005ca44d1cSRong-En Fan if (res == E_OK
45015ca44d1cSRong-En Fan && (event.bstate & BUTTON1_DOUBLE_CLICKED))
45025ca44d1cSRong-En Fan res = E_UNKNOWN_COMMAND;
45035ca44d1cSRong-En Fan break;
45045ca44d1cSRong-En Fan }
45055ca44d1cSRong-En Fan }
45065ca44d1cSRong-En Fan }
45075ca44d1cSRong-En Fan }
45085ca44d1cSRong-En Fan }
45095ca44d1cSRong-En Fan }
45105ca44d1cSRong-En Fan else
45115ca44d1cSRong-En Fan res = E_REQUEST_DENIED;
45125ca44d1cSRong-En Fan }
45135ca44d1cSRong-En Fan #endif /* NCURSES_MOUSE_VERSION */
45144a1a9510SRong-En Fan else if (!(c & (~(int)MAX_REGULAR_CHARACTER)))
45150e3d5408SPeter Wemm {
45164a1a9510SRong-En Fan /*
45174a1a9510SRong-En Fan * If we're using 8-bit characters, iscntrl+isprint cover the whole set.
45184a1a9510SRong-En Fan * But with multibyte characters, there is a third possibility, i.e.,
45194a1a9510SRong-En Fan * parts of characters that build up into printable characters which are
45204a1a9510SRong-En Fan * not considered printable.
45214a1a9510SRong-En Fan *
45224a1a9510SRong-En Fan * FIXME: the wide-character branch should also use Check_Char().
45234a1a9510SRong-En Fan */
45244a1a9510SRong-En Fan #if USE_WIDEC_SUPPORT
45254a1a9510SRong-En Fan if (!iscntrl(UChar(c)))
45264a1a9510SRong-En Fan #else
45274a1a9510SRong-En Fan if (isprint(UChar(c)) &&
452806bfebdeSXin LI Check_Char(form, form->current, form->current->type, c,
45290e3d5408SPeter Wemm (TypeArgument *)(form->current->arg)))
45304a1a9510SRong-En Fan #endif
45310e3d5408SPeter Wemm res = Data_Entry(form, c);
45320e3d5408SPeter Wemm }
45330e3d5408SPeter Wemm _nc_Refresh_Current_Field(form);
45340e3d5408SPeter Wemm RETURN(res);
45350e3d5408SPeter Wemm }
45364a1a9510SRong-En Fan
453773f0a83dSXin LI # if USE_WIDEC_SUPPORT
453873f0a83dSXin LI /*---------------------------------------------------------------------------
453973f0a83dSXin LI | Facility : libnform
454073f0a83dSXin LI | Function : int form_driver_w(FORM * form,int type,wchar_t c)
454173f0a83dSXin LI |
454273f0a83dSXin LI | Description : This is the workhorse of the forms system.
454373f0a83dSXin LI |
454473f0a83dSXin LI | Input is either a key code (request) or a wide char
454573f0a83dSXin LI | returned by e.g. get_wch (). The type must be passed
454673f0a83dSXin LI | as well,so that we are able to determine whether the char
454773f0a83dSXin LI | is a multibyte char or a request.
454873f0a83dSXin LI
454973f0a83dSXin LI | If it is a request, the form driver executes
455073f0a83dSXin LI | the request and returns the result. If it is data
455173f0a83dSXin LI | (printable character), it enters the data into the
455273f0a83dSXin LI | current position in the current field. If it is not
455373f0a83dSXin LI | recognized, the form driver assumes it is an application
455473f0a83dSXin LI | defined command and returns E_UNKNOWN_COMMAND.
455573f0a83dSXin LI | Application defined command should be defined relative
455673f0a83dSXin LI | to MAX_FORM_COMMAND, the maximum value of a request.
455773f0a83dSXin LI |
455873f0a83dSXin LI | Return Values : E_OK - success
455973f0a83dSXin LI | E_SYSTEM_ERROR - system error
456073f0a83dSXin LI | E_BAD_ARGUMENT - an argument is incorrect
456173f0a83dSXin LI | E_NOT_POSTED - form is not posted
456273f0a83dSXin LI | E_INVALID_FIELD - field contents are invalid
456373f0a83dSXin LI | E_BAD_STATE - called from inside a hook routine
456473f0a83dSXin LI | E_REQUEST_DENIED - request failed
456573f0a83dSXin LI | E_NOT_CONNECTED - no fields are connected to the form
456673f0a83dSXin LI | E_UNKNOWN_COMMAND - command not known
456773f0a83dSXin LI +--------------------------------------------------------------------------*/
45687a656419SBaptiste Daroussin FORM_EXPORT(int)
form_driver_w(FORM * form,int type,wchar_t c)456973f0a83dSXin LI form_driver_w(FORM *form, int type, wchar_t c)
457073f0a83dSXin LI {
457173f0a83dSXin LI const Binding_Info *BI = (Binding_Info *)0;
457273f0a83dSXin LI int res = E_UNKNOWN_COMMAND;
457373f0a83dSXin LI
457473f0a83dSXin LI T((T_CALLED("form_driver(%p,%d)"), (void *)form, (int)c));
457573f0a83dSXin LI
457673f0a83dSXin LI if (!form)
457773f0a83dSXin LI RETURN(E_BAD_ARGUMENT);
457873f0a83dSXin LI
457973f0a83dSXin LI if (!(form->field))
458073f0a83dSXin LI RETURN(E_NOT_CONNECTED);
458173f0a83dSXin LI
458273f0a83dSXin LI assert(form->page);
458373f0a83dSXin LI
4584fd13916cSXin LI if (c == (wchar_t)FIRST_ACTIVE_MAGIC)
458573f0a83dSXin LI {
458673f0a83dSXin LI form->current = _nc_First_Active_Field(form);
458773f0a83dSXin LI RETURN(E_OK);
458873f0a83dSXin LI }
458973f0a83dSXin LI
459073f0a83dSXin LI assert(form->current &&
459173f0a83dSXin LI form->current->buf &&
459273f0a83dSXin LI (form->current->form == form)
459373f0a83dSXin LI );
459473f0a83dSXin LI
459573f0a83dSXin LI if (form->status & _IN_DRIVER)
459673f0a83dSXin LI RETURN(E_BAD_STATE);
459773f0a83dSXin LI
459873f0a83dSXin LI if (!(form->status & _POSTED))
459973f0a83dSXin LI RETURN(E_NOT_POSTED);
460073f0a83dSXin LI
460173f0a83dSXin LI /* check if this is a keycode or a (wide) char */
460273f0a83dSXin LI if (type == KEY_CODE_YES)
460373f0a83dSXin LI {
460473f0a83dSXin LI if ((c >= MIN_FORM_COMMAND && c <= MAX_FORM_COMMAND) &&
460573f0a83dSXin LI ((bindings[c - MIN_FORM_COMMAND].keycode & Key_Mask) == c))
460673f0a83dSXin LI BI = &(bindings[c - MIN_FORM_COMMAND]);
460773f0a83dSXin LI }
460873f0a83dSXin LI
460973f0a83dSXin LI if (BI)
461073f0a83dSXin LI {
461173f0a83dSXin LI typedef int (*Generic_Method) (int (*const) (FORM *), FORM *);
461273f0a83dSXin LI static const Generic_Method Generic_Methods[] =
461373f0a83dSXin LI {
461473f0a83dSXin LI Page_Navigation, /* overloaded to call field&form hooks */
461573f0a83dSXin LI Inter_Field_Navigation, /* overloaded to call field hooks */
461673f0a83dSXin LI NULL, /* Intra-Field is generic */
461773f0a83dSXin LI Vertical_Scrolling, /* Overloaded to check multi-line */
461873f0a83dSXin LI Horizontal_Scrolling, /* Overloaded to check single-line */
461973f0a83dSXin LI Field_Editing, /* Overloaded to mark modification */
462073f0a83dSXin LI NULL, /* Edit Mode is generic */
462173f0a83dSXin LI NULL, /* Field Validation is generic */
462273f0a83dSXin LI NULL /* Choice Request is generic */
462373f0a83dSXin LI };
462473f0a83dSXin LI size_t nMethods = (sizeof(Generic_Methods) / sizeof(Generic_Methods[0]));
462573f0a83dSXin LI size_t method = (size_t)(BI->keycode >> ID_Shft) & 0xffff; /* see ID_Mask */
462673f0a83dSXin LI
462773f0a83dSXin LI if ((method >= nMethods) || !(BI->cmd))
462873f0a83dSXin LI res = E_SYSTEM_ERROR;
462973f0a83dSXin LI else
463073f0a83dSXin LI {
463173f0a83dSXin LI Generic_Method fct = Generic_Methods[method];
463273f0a83dSXin LI
463373f0a83dSXin LI if (fct)
463473f0a83dSXin LI res = fct(BI->cmd, form);
463573f0a83dSXin LI else
463673f0a83dSXin LI res = (BI->cmd) (form);
463773f0a83dSXin LI }
463873f0a83dSXin LI }
463973f0a83dSXin LI #ifdef NCURSES_MOUSE_VERSION
464073f0a83dSXin LI else if (KEY_MOUSE == c)
464173f0a83dSXin LI {
464273f0a83dSXin LI MEVENT event;
464373f0a83dSXin LI WINDOW *win = form->win ? form->win : StdScreen(Get_Form_Screen(form));
464473f0a83dSXin LI WINDOW *sub = form->sub ? form->sub : win;
464573f0a83dSXin LI
464673f0a83dSXin LI getmouse(&event);
464773f0a83dSXin LI if ((event.bstate & (BUTTON1_CLICKED |
464873f0a83dSXin LI BUTTON1_DOUBLE_CLICKED |
464973f0a83dSXin LI BUTTON1_TRIPLE_CLICKED))
465073f0a83dSXin LI && wenclose(win, event.y, event.x))
465173f0a83dSXin LI { /* we react only if the click was in the userwin, that means
465273f0a83dSXin LI * inside the form display area or at the decoration window.
465373f0a83dSXin LI */
465473f0a83dSXin LI int ry = event.y, rx = event.x; /* screen coordinates */
465573f0a83dSXin LI
465673f0a83dSXin LI res = E_REQUEST_DENIED;
465773f0a83dSXin LI if (mouse_trafo(&ry, &rx, FALSE))
465873f0a83dSXin LI { /* rx, ry are now "curses" coordinates */
465973f0a83dSXin LI if (ry < sub->_begy)
466073f0a83dSXin LI { /* we clicked above the display region; this is
466173f0a83dSXin LI * interpreted as "scroll up" request
466273f0a83dSXin LI */
466373f0a83dSXin LI if (event.bstate & BUTTON1_CLICKED)
466473f0a83dSXin LI res = form_driver(form, REQ_PREV_FIELD);
466573f0a83dSXin LI else if (event.bstate & BUTTON1_DOUBLE_CLICKED)
466673f0a83dSXin LI res = form_driver(form, REQ_PREV_PAGE);
466773f0a83dSXin LI else if (event.bstate & BUTTON1_TRIPLE_CLICKED)
466873f0a83dSXin LI res = form_driver(form, REQ_FIRST_FIELD);
466973f0a83dSXin LI }
467073f0a83dSXin LI else if (ry > sub->_begy + sub->_maxy)
467173f0a83dSXin LI { /* we clicked below the display region; this is
467273f0a83dSXin LI * interpreted as "scroll down" request
467373f0a83dSXin LI */
467473f0a83dSXin LI if (event.bstate & BUTTON1_CLICKED)
467573f0a83dSXin LI res = form_driver(form, REQ_NEXT_FIELD);
467673f0a83dSXin LI else if (event.bstate & BUTTON1_DOUBLE_CLICKED)
467773f0a83dSXin LI res = form_driver(form, REQ_NEXT_PAGE);
467873f0a83dSXin LI else if (event.bstate & BUTTON1_TRIPLE_CLICKED)
467973f0a83dSXin LI res = form_driver(form, REQ_LAST_FIELD);
468073f0a83dSXin LI }
468173f0a83dSXin LI else if (wenclose(sub, event.y, event.x))
468273f0a83dSXin LI { /* Inside the area we try to find the hit item */
468373f0a83dSXin LI ry = event.y;
468473f0a83dSXin LI rx = event.x;
468573f0a83dSXin LI if (wmouse_trafo(sub, &ry, &rx, FALSE))
468673f0a83dSXin LI {
468773f0a83dSXin LI int min_field = form->page[form->curpage].pmin;
468873f0a83dSXin LI int max_field = form->page[form->curpage].pmax;
4689*21817992SBaptiste Daroussin int i;
469073f0a83dSXin LI
469173f0a83dSXin LI for (i = min_field; i <= max_field; ++i)
469273f0a83dSXin LI {
469373f0a83dSXin LI FIELD *field = form->field[i];
469473f0a83dSXin LI
469573f0a83dSXin LI if (Field_Is_Selectable(field)
469673f0a83dSXin LI && Field_encloses(field, ry, rx) == E_OK)
469773f0a83dSXin LI {
469873f0a83dSXin LI res = _nc_Set_Current_Field(form, field);
469973f0a83dSXin LI if (res == E_OK)
470073f0a83dSXin LI res = _nc_Position_Form_Cursor(form);
470173f0a83dSXin LI if (res == E_OK
470273f0a83dSXin LI && (event.bstate & BUTTON1_DOUBLE_CLICKED))
470373f0a83dSXin LI res = E_UNKNOWN_COMMAND;
470473f0a83dSXin LI break;
470573f0a83dSXin LI }
470673f0a83dSXin LI }
470773f0a83dSXin LI }
470873f0a83dSXin LI }
470973f0a83dSXin LI }
471073f0a83dSXin LI }
471173f0a83dSXin LI else
471273f0a83dSXin LI res = E_REQUEST_DENIED;
471373f0a83dSXin LI }
471473f0a83dSXin LI #endif /* NCURSES_MOUSE_VERSION */
471573f0a83dSXin LI else if (type == OK)
471673f0a83dSXin LI {
471773f0a83dSXin LI res = Data_Entry_w(form, c);
471873f0a83dSXin LI }
471973f0a83dSXin LI
472073f0a83dSXin LI _nc_Refresh_Current_Field(form);
472173f0a83dSXin LI RETURN(res);
472273f0a83dSXin LI }
472373f0a83dSXin LI # endif /* USE_WIDEC_SUPPORT */
472473f0a83dSXin LI
47250e3d5408SPeter Wemm /*----------------------------------------------------------------------------
47260e3d5408SPeter Wemm Field-Buffer manipulation routines.
47274a1a9510SRong-En Fan The effects of setting a buffer are tightly coupled to the core of the form
47280e3d5408SPeter Wemm driver logic. This is especially true in the case of growable fields.
47294a1a9510SRong-En Fan So I don't separate this into a separate module.
47300e3d5408SPeter Wemm --------------------------------------------------------------------------*/
47310e3d5408SPeter Wemm
47320e3d5408SPeter Wemm /*---------------------------------------------------------------------------
47330e3d5408SPeter Wemm | Facility : libnform
47340e3d5408SPeter Wemm | Function : int set_field_buffer(FIELD *field,
47350e3d5408SPeter Wemm | int buffer, char *value)
47360e3d5408SPeter Wemm |
47370e3d5408SPeter Wemm | Description : Set the given buffer of the field to the given value.
47380e3d5408SPeter Wemm | Buffer 0 stores the displayed content of the field.
47390e3d5408SPeter Wemm | For dynamic fields this may grow the fieldbuffers if
47400e3d5408SPeter Wemm | the length of the value exceeds the current buffer
47410e3d5408SPeter Wemm | length. For buffer 0 only printable values are allowed.
47427a656419SBaptiste Daroussin | For static fields, the value must not be zero terminated.
47437a656419SBaptiste Daroussin | It is copied up to the length of the buffer.
47440e3d5408SPeter Wemm |
47450e3d5408SPeter Wemm | Return Values : E_OK - success
47460e3d5408SPeter Wemm | E_BAD_ARGUMENT - invalid argument
47470e3d5408SPeter Wemm | E_SYSTEM_ERROR - system error
47480e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
47497a656419SBaptiste Daroussin FORM_EXPORT(int)
set_field_buffer(FIELD * field,int buffer,const char * value)47504a1a9510SRong-En Fan set_field_buffer(FIELD *field, int buffer, const char *value)
47510e3d5408SPeter Wemm {
47524a1a9510SRong-En Fan FIELD_CELL *p;
47530e3d5408SPeter Wemm int res = E_OK;
475473f0a83dSXin LI int i;
475573f0a83dSXin LI int len;
47560e3d5408SPeter Wemm
47574a1a9510SRong-En Fan #if USE_WIDEC_SUPPORT
47584a1a9510SRong-En Fan FIELD_CELL *widevalue = 0;
47594a1a9510SRong-En Fan #endif
47604a1a9510SRong-En Fan
476106bfebdeSXin LI T((T_CALLED("set_field_buffer(%p,%d,%s)"), (void *)field, buffer, _nc_visbuf(value)));
47624a1a9510SRong-En Fan
47630e3d5408SPeter Wemm if (!field || !value || ((buffer < 0) || (buffer > field->nbuf)))
47640e3d5408SPeter Wemm RETURN(E_BAD_ARGUMENT);
47650e3d5408SPeter Wemm
47660e3d5408SPeter Wemm len = Buffer_Length(field);
47670e3d5408SPeter Wemm
47680e3d5408SPeter Wemm if (Growable(field))
47690e3d5408SPeter Wemm {
47700e3d5408SPeter Wemm /* for a growable field we must assume zero terminated strings, because
47710e3d5408SPeter Wemm somehow we have to detect the length of what should be copied.
47720e3d5408SPeter Wemm */
477373f0a83dSXin LI int vlen = (int)strlen(value);
47744a1a9510SRong-En Fan
47750e3d5408SPeter Wemm if (vlen > len)
47760e3d5408SPeter Wemm {
47770e3d5408SPeter Wemm if (!Field_Grown(field,
47784a1a9510SRong-En Fan (int)(1 + (vlen - len) / ((field->rows + field->nrow)
47794a1a9510SRong-En Fan * field->cols))))
47800e3d5408SPeter Wemm RETURN(E_SYSTEM_ERROR);
47810e3d5408SPeter Wemm
478206bfebdeSXin LI #if !USE_WIDEC_SUPPORT
47830e3d5408SPeter Wemm len = vlen;
478406bfebdeSXin LI #endif
47850e3d5408SPeter Wemm }
47860e3d5408SPeter Wemm }
47870e3d5408SPeter Wemm
47880e3d5408SPeter Wemm p = Address_Of_Nth_Buffer(field, buffer);
47890e3d5408SPeter Wemm
47904a1a9510SRong-En Fan #if USE_WIDEC_SUPPORT
47914a1a9510SRong-En Fan /*
47924a1a9510SRong-En Fan * Use addstr's logic for converting a string to an array of cchar_t's.
47934a1a9510SRong-En Fan * There should be a better way, but this handles nonspacing characters
47944a1a9510SRong-En Fan * and other special cases that we really do not want to handle here.
47954a1a9510SRong-En Fan */
47965d08fb1fSRong-En Fan #if NCURSES_EXT_FUNCS
479706bfebdeSXin LI if (wresize(field->working, 1, Buffer_Length(field) + 1) == ERR)
47985d08fb1fSRong-En Fan #endif
47995d08fb1fSRong-En Fan {
48005d08fb1fSRong-En Fan delwin(field->working);
480106bfebdeSXin LI field->working = newpad(1, Buffer_Length(field) + 1);
48025d08fb1fSRong-En Fan }
480306bfebdeSXin LI len = Buffer_Length(field);
48044a1a9510SRong-En Fan wclear(field->working);
480506bfebdeSXin LI (void)mvwaddstr(field->working, 0, 0, value);
48064a1a9510SRong-En Fan
48075ca44d1cSRong-En Fan if ((widevalue = typeCalloc(FIELD_CELL, len + 1)) == 0)
48080e3d5408SPeter Wemm {
48094a1a9510SRong-En Fan RETURN(E_SYSTEM_ERROR);
48100e3d5408SPeter Wemm }
48110e3d5408SPeter Wemm else
48124a1a9510SRong-En Fan {
481373f0a83dSXin LI for (i = 0; i < field->drows; ++i)
48145d08fb1fSRong-En Fan {
481573f0a83dSXin LI (void)mvwin_wchnstr(field->working, 0, (int)i * field->dcols,
481673f0a83dSXin LI widevalue + ((int)i * field->dcols),
48175d08fb1fSRong-En Fan field->dcols);
48185d08fb1fSRong-En Fan }
48194a1a9510SRong-En Fan for (i = 0; i < len; ++i)
48204a1a9510SRong-En Fan {
48214a1a9510SRong-En Fan if (CharEq(myZEROS, widevalue[i]))
48224a1a9510SRong-En Fan {
48234a1a9510SRong-En Fan while (i < len)
48244a1a9510SRong-En Fan p[i++] = myBLANK;
48254a1a9510SRong-En Fan break;
48260e3d5408SPeter Wemm }
48274a1a9510SRong-En Fan p[i] = widevalue[i];
48284a1a9510SRong-En Fan }
48294a1a9510SRong-En Fan free(widevalue);
48304a1a9510SRong-En Fan }
48314a1a9510SRong-En Fan #else
48324a1a9510SRong-En Fan for (i = 0; i < len; ++i)
48334a1a9510SRong-En Fan {
48344a1a9510SRong-En Fan if (value[i] == '\0')
48354a1a9510SRong-En Fan {
48364a1a9510SRong-En Fan while (i < len)
48374a1a9510SRong-En Fan p[i++] = myBLANK;
48384a1a9510SRong-En Fan break;
48394a1a9510SRong-En Fan }
48404a1a9510SRong-En Fan p[i] = value[i];
48414a1a9510SRong-En Fan }
48424a1a9510SRong-En Fan #endif
48430e3d5408SPeter Wemm
48440e3d5408SPeter Wemm if (buffer == 0)
48450e3d5408SPeter Wemm {
48460e3d5408SPeter Wemm int syncres;
48474a1a9510SRong-En Fan
48480e3d5408SPeter Wemm if (((syncres = Synchronize_Field(field)) != E_OK) &&
48490e3d5408SPeter Wemm (res == E_OK))
48500e3d5408SPeter Wemm res = syncres;
48510e3d5408SPeter Wemm if (((syncres = Synchronize_Linked_Fields(field)) != E_OK) &&
48520e3d5408SPeter Wemm (res == E_OK))
48530e3d5408SPeter Wemm res = syncres;
48540e3d5408SPeter Wemm }
48550e3d5408SPeter Wemm RETURN(res);
48560e3d5408SPeter Wemm }
48570e3d5408SPeter Wemm
48580e3d5408SPeter Wemm /*---------------------------------------------------------------------------
48590e3d5408SPeter Wemm | Facility : libnform
48600e3d5408SPeter Wemm | Function : char *field_buffer(const FIELD *field,int buffer)
48610e3d5408SPeter Wemm |
48620e3d5408SPeter Wemm | Description : Return the address of the buffer for the field.
48630e3d5408SPeter Wemm |
48640e3d5408SPeter Wemm | Return Values : Pointer to buffer or NULL if arguments were invalid.
48650e3d5408SPeter Wemm +--------------------------------------------------------------------------*/
48667a656419SBaptiste Daroussin FORM_EXPORT(char *)
field_buffer(const FIELD * field,int buffer)48677a69bbfbSPeter Wemm field_buffer(const FIELD *field, int buffer)
48680e3d5408SPeter Wemm {
48694a1a9510SRong-En Fan char *result = 0;
48704a1a9510SRong-En Fan
487106bfebdeSXin LI T((T_CALLED("field_buffer(%p,%d)"), (const void *)field, buffer));
48724a1a9510SRong-En Fan
48730e3d5408SPeter Wemm if (field && (buffer >= 0) && (buffer <= field->nbuf))
48744a1a9510SRong-En Fan {
48754a1a9510SRong-En Fan #if USE_WIDEC_SUPPORT
48764a1a9510SRong-En Fan FIELD_CELL *data = Address_Of_Nth_Buffer(field, buffer);
487773f0a83dSXin LI size_t need = 0;
48784a1a9510SRong-En Fan int size = Buffer_Length(field);
48794a1a9510SRong-En Fan int n;
48804a1a9510SRong-En Fan
48814a1a9510SRong-En Fan /* determine the number of bytes needed to store the expanded string */
48824a1a9510SRong-En Fan for (n = 0; n < size; ++n)
48834a1a9510SRong-En Fan {
488406bfebdeSXin LI if (!isWidecExt(data[n]) && data[n].chars[0] != L'\0')
48854a1a9510SRong-En Fan {
48864a1a9510SRong-En Fan mbstate_t state;
48874a1a9510SRong-En Fan size_t next;
48884a1a9510SRong-En Fan
48894a1a9510SRong-En Fan init_mb(state);
48904a1a9510SRong-En Fan next = _nc_wcrtomb(0, data[n].chars[0], &state);
489173f0a83dSXin LI if (next > 0)
48924a1a9510SRong-En Fan need += next;
48930e3d5408SPeter Wemm }
48944a1a9510SRong-En Fan }
48954a1a9510SRong-En Fan
48964a1a9510SRong-En Fan /* allocate a place to store the expanded string */
48974a1a9510SRong-En Fan if (field->expanded[buffer] != 0)
48984a1a9510SRong-En Fan free(field->expanded[buffer]);
48994a1a9510SRong-En Fan field->expanded[buffer] = typeMalloc(char, need + 1);
49004a1a9510SRong-En Fan
490106bfebdeSXin LI /*
490206bfebdeSXin LI * Expand the multibyte data.
490306bfebdeSXin LI *
490406bfebdeSXin LI * It may also be multi-column data. In that case, the data for a row
490506bfebdeSXin LI * may be null-padded to align to the dcols/drows layout (or it may
490606bfebdeSXin LI * contain embedded wide-character extensions). Change the null-padding
490706bfebdeSXin LI * to blanks as needed.
490806bfebdeSXin LI */
49094a1a9510SRong-En Fan if ((result = field->expanded[buffer]) != 0)
49104a1a9510SRong-En Fan {
49114a1a9510SRong-En Fan wclear(field->working);
491206bfebdeSXin LI wmove(field->working, 0, 0);
491306bfebdeSXin LI for (n = 0; n < size; ++n)
491406bfebdeSXin LI {
491506bfebdeSXin LI if (!isWidecExt(data[n]) && data[n].chars[0] != L'\0')
491606bfebdeSXin LI wadd_wch(field->working, &data[n]);
491706bfebdeSXin LI }
491806bfebdeSXin LI wmove(field->working, 0, 0);
491906bfebdeSXin LI winnstr(field->working, result, (int)need);
49204a1a9510SRong-En Fan }
49214a1a9510SRong-En Fan #else
49224a1a9510SRong-En Fan result = Address_Of_Nth_Buffer(field, buffer);
49234a1a9510SRong-En Fan #endif
49244a1a9510SRong-En Fan }
49254a1a9510SRong-En Fan returnPtr(result);
49264a1a9510SRong-En Fan }
49274a1a9510SRong-En Fan
49284a1a9510SRong-En Fan #if USE_WIDEC_SUPPORT
49294a1a9510SRong-En Fan
49304a1a9510SRong-En Fan /*---------------------------------------------------------------------------
49314a1a9510SRong-En Fan | Convert a multibyte string to a wide-character string. The result must be
49324a1a9510SRong-En Fan | freed by the caller.
49334a1a9510SRong-En Fan +--------------------------------------------------------------------------*/
49347a656419SBaptiste Daroussin FORM_EXPORT(wchar_t *)
_nc_Widen_String(char * source,int * lengthp)49354a1a9510SRong-En Fan _nc_Widen_String(char *source, int *lengthp)
49364a1a9510SRong-En Fan {
49374a1a9510SRong-En Fan wchar_t *result = 0;
49384a1a9510SRong-En Fan wchar_t wch;
49394a1a9510SRong-En Fan size_t given = strlen(source);
49404a1a9510SRong-En Fan size_t tries;
49414a1a9510SRong-En Fan int pass;
49424a1a9510SRong-En Fan int status;
49434a1a9510SRong-En Fan
494406bfebdeSXin LI #ifndef state_unused
49454a1a9510SRong-En Fan mbstate_t state;
49464a1a9510SRong-En Fan #endif
49474a1a9510SRong-En Fan
49484a1a9510SRong-En Fan for (pass = 0; pass < 2; ++pass)
49494a1a9510SRong-En Fan {
49504a1a9510SRong-En Fan unsigned need = 0;
49514a1a9510SRong-En Fan size_t passed = 0;
49524a1a9510SRong-En Fan
49534a1a9510SRong-En Fan while (passed < given)
49544a1a9510SRong-En Fan {
49554a1a9510SRong-En Fan bool found = FALSE;
49564a1a9510SRong-En Fan
49574a1a9510SRong-En Fan for (tries = 1, status = 0; tries <= (given - passed); ++tries)
49584a1a9510SRong-En Fan {
49594a1a9510SRong-En Fan int save = source[passed + tries];
49604a1a9510SRong-En Fan
49614a1a9510SRong-En Fan source[passed + tries] = 0;
49624a1a9510SRong-En Fan reset_mbytes(state);
496306bfebdeSXin LI status = check_mbytes(wch, source + passed, tries, state);
496406bfebdeSXin LI source[passed + tries] = (char)save;
49654a1a9510SRong-En Fan
49664a1a9510SRong-En Fan if (status > 0)
49674a1a9510SRong-En Fan {
49684a1a9510SRong-En Fan found = TRUE;
49694a1a9510SRong-En Fan break;
49704a1a9510SRong-En Fan }
49714a1a9510SRong-En Fan }
49724a1a9510SRong-En Fan if (found)
49734a1a9510SRong-En Fan {
49744a1a9510SRong-En Fan if (pass)
49754a1a9510SRong-En Fan {
49764a1a9510SRong-En Fan result[need] = wch;
49774a1a9510SRong-En Fan }
497873f0a83dSXin LI passed += (size_t)status;
49794a1a9510SRong-En Fan ++need;
49804a1a9510SRong-En Fan }
49814a1a9510SRong-En Fan else
49824a1a9510SRong-En Fan {
49834a1a9510SRong-En Fan if (pass)
49844a1a9510SRong-En Fan {
4985aae38d10SBaptiste Daroussin result[need] = (wchar_t)source[passed];
49864a1a9510SRong-En Fan }
49874a1a9510SRong-En Fan ++need;
49884a1a9510SRong-En Fan ++passed;
49894a1a9510SRong-En Fan }
49904a1a9510SRong-En Fan }
49914a1a9510SRong-En Fan
49924a1a9510SRong-En Fan if (!pass)
49934a1a9510SRong-En Fan {
49944a1a9510SRong-En Fan if (!need)
49954a1a9510SRong-En Fan break;
49964a1a9510SRong-En Fan result = typeCalloc(wchar_t, need);
49974a1a9510SRong-En Fan
499873f0a83dSXin LI *lengthp = (int)need;
49994a1a9510SRong-En Fan if (result == 0)
50004a1a9510SRong-En Fan break;
50014a1a9510SRong-En Fan }
50024a1a9510SRong-En Fan }
50034a1a9510SRong-En Fan
50044a1a9510SRong-En Fan return result;
50054a1a9510SRong-En Fan }
50064a1a9510SRong-En Fan #endif
50070e3d5408SPeter Wemm
50080e3d5408SPeter Wemm /* frm_driver.c ends here */
5009