]> ncurses.scripts.mit.edu Git - ncurses.git/blobdiff - form/frm_driver.c
ncurses 5.4
[ncurses.git] / form / frm_driver.c
index 51297e5a03c062c5b9dce6e4c149237fcc5ffd61..9de28eeabbd3aa8770d2bbfc6a9aa137cad8d35f 100644 (file)
@@ -1,24 +1,38 @@
-/*-----------------------------------------------------------------------------+
-|           The ncurses form library is  Copyright (C) 1995-1997               |
-|             by Juergen Pfeifer <Juergen.Pfeifer@T-Online.de>                 |
-|                          All Rights Reserved.                                |
-|                                                                              |
-| Permission to use, copy, modify, and distribute this software and its        |
-| documentation for any purpose and without fee is hereby granted, provided    |
-| that the above copyright notice appear in all copies and that both that      |
-| copyright notice and this permission notice appear in supporting             |
-| documentation, and that the name of the above listed copyright holder(s) not |
-| be used in advertising or publicity pertaining to distribution of the        |
-| software without specific, written prior permission.                         | 
-|                                                                              |
-| THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD TO  |
-| THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-  |
-| NESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR   |
-| ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RE- |
-| SULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, |
-| NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH    |
-| THE USE OR PERFORMANCE OF THIS SOFTWARE.                                     |
-+-----------------------------------------------------------------------------*/
+/****************************************************************************
+ * Copyright (c) 1998-2002,2003 Free Software Foundation, Inc.              *
+ *                                                                          *
+ * Permission is hereby granted, free of charge, to any person obtaining a  *
+ * copy of this software and associated documentation files (the            *
+ * "Software"), to deal in the Software without restriction, including      *
+ * without limitation the rights to use, copy, modify, merge, publish,      *
+ * distribute, distribute with modifications, sublicense, and/or sell       *
+ * copies of the Software, and to permit persons to whom the Software is    *
+ * furnished to do so, subject to the following conditions:                 *
+ *                                                                          *
+ * The above copyright notice and this permission notice shall be included  *
+ * in all copies or substantial portions of the Software.                   *
+ *                                                                          *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
+ *                                                                          *
+ * Except as contained in this notice, the name(s) of the above copyright   *
+ * holders shall not be used in advertising or otherwise to promote the     *
+ * sale, use or other dealings in this Software without prior written       *
+ * authorization.                                                           *
+ ****************************************************************************/
+
+/****************************************************************************
+ *   Author:  Juergen Pfeifer, 1995,1997                                    *
+ ****************************************************************************/
+
+#include "form.priv.h"
+
+MODULE_ID("$Id: frm_driver.c,v 1.45 2003/12/06 17:22:42 tom Exp $")
 
 /*----------------------------------------------------------------------------
   This is the core module of the form library. It contains the majority
@@ -28,7 +42,7 @@
   all the functions in this module depends on some others in the module,
   so it makes no sense to split them into separate files because they
   will always be linked together. The only acceptable concern is turnaround
-  time for this module, but now we have all Pentiums or Riscs, so what!
+  time for this module, but now we have all Pentiums or RISCs, so what!
 
   The driver routines are grouped into nine generic categories:
 
    c)   Intra-Field Navigation     ( all functions prefixed by IFN_ )
         The current position in the current field is changed. 
    d)   Vertical Scrolling         ( all functions prefixed by VSC_ )
-        Esseantially this is a specialization of Intra-Field navigation.
+        Essentially this is a specialization of Intra-Field navigation.
         It has to check for a multi-line field.
    e)   Horizontal Scrolling       ( all functions prefixed by HSC_ )
-        Esseantially this is a specialization of Intra-Field navigation.
+        Essentially this is a specialization of Intra-Field navigation.
         It has to check for a single-line field.
    f)   Field Editing              ( all functions prefixed by FE_ )
         The content of the current field is changed
   routines I omit them mostly.
   --------------------------------------------------------------------------*/
 
-#include "form.priv.h"
-
-MODULE_ID("$Id: frm_driver.c,v 1.20 1997/05/01 16:47:54 juergen Exp $")
-
 /*
 Some options that may effect compatibility in behavior to SVr4 forms,
-but they are here to allow a more intuitive and user friendly behaviour of
+but they are here to allow a more intuitive and user friendly behavior of
 our form implementation. This doesn't affect the API, so we feel it is
 uncritical.
 
-The initial implementation tries to stay very close with the behaviour
+The initial implementation tries to stay very close with the behavior
 of the original SVr4 implementation, although in some areas it is quite
 clear that this isn't the most appropriate way. As far as possible this
 sources will allow you to build a forms lib that behaves quite similar
@@ -81,10 +91,12 @@ to SVr4, but now and in the future we will give you better options.
 Perhaps at some time we will make this configurable at runtime.
 */
 
-/* Implement a more user-friendly previous/next word behaviour */
+/* Implement a more user-friendly previous/next word behavior */
 #define FRIENDLY_PREV_NEXT_WORD (1)
-/* Fix the wrong behaviour for forms with all fields inactive */
+/* Fix the wrong behavior for forms with all fields inactive */
 #define FIX_FORM_INACTIVE_BUG (1)
+/* Allow dynamic field growth also when navigating past the end */
+#define GROW_IF_NAVIGATE (1)
 
 /*----------------------------------------------------------------------------
   Forward references to some internally used static functions
@@ -138,7 +150,7 @@ static int FE_Delete_Previous(FORM *);
 #define Address_Of_Current_Position_In_Buffer(form) \
   Address_Of_Current_Position_In_Nth_Buffer(form,0)
 
-/* Logic to decide wether or not a field is actually a field with
+/* Logic to decide whether or not a field is actually a field with
    vertical or horizontal scrolling */
 #define Is_Scroll_Field(field)          \
    (((field)->drows > (field)->rows) || \
@@ -163,10 +175,8 @@ static int FE_Delete_Previous(FORM *);
 
 /* Macro to set the attributes for a fields window */
 #define Set_Field_Window_Attributes(field,win) \
-{\
-   wbkgdset((win),(chtype)((field)->pad | (field)->back)); \
-   wattrset((win),(field)->fore); \
-}
+(  wbkgdset((win),(chtype)((field)->pad | (field)->back)), \
+   wattrset((win),(field)->fore) )
 
 /* Logic to decide whether or not a field really appears on the form */
 #define Field_Really_Appears(field)         \
@@ -180,13 +190,6 @@ static int FE_Delete_Previous(FORM *);
 #define First_Position_In_Current_Field(form) \
   (((form)->currow==0) && ((form)->curcol==0))
 
-/* This are the field options required to be a selectable field in field
-   navigation requests */
-#define O_SELECTABLE (O_ACTIVE | O_VISIBLE)
-
-/* Logic to determine whether or not a field is selectable */
-#define Field_Is_Selectable(f)     (((f)->opts & O_SELECTABLE)==O_SELECTABLE)
-#define Field_Is_Not_Selectable(f) (((f)->opts & O_SELECTABLE)!=O_SELECTABLE)
 
 #define Minimum(a,b) (((a)<=(b)) ? (a) : (b))
 #define Maximum(a,b) (((a)>=(b)) ? (a) : (b))
@@ -313,7 +316,7 @@ INLINE static void Adjust_Cursor_Position(FORM * form, const char * pos)
 |                                      const FIELD  * field,
 |                                      WINDOW * win)
 |   
-|   Description   :  Copy the buffer to the window. If its a multiline
+|   Description   :  Copy the buffer to the window. If it is a multi-line
 |                    field, the buffer is split to the lines of the
 |                    window without any editing.
 |
@@ -514,7 +517,8 @@ static bool Field_Grown(FIELD * field, int amount)
                  return FALSE;
                }
              assert(form!=(FORM *)0);
-             delwin(form->w);
+             if (form->w)
+               delwin(form->w);
              form->w = new_window;
              Set_Field_Window_Attributes(field,form->w);
              werase(form->w);
@@ -545,9 +549,9 @@ static bool Field_Grown(FIELD * field, int amount)
 
 /*---------------------------------------------------------------------------
 |   Facility      :  libnform  
-|   Function      :  static int Position_Form_Cursor(FORM * form)
+|   Function      :  int _nc_Position_Form_Cursor(FORM * form)
 |   
-|   Description   :  Position the currsor in the window for the current
+|   Description   :  Position the cursor in the window for the current
 |                    field to be in sync. with the currow and curcol 
 |                    values.
 |
@@ -556,7 +560,8 @@ static bool Field_Grown(FIELD * field, int amount)
 |                    E_SYSTEM_ERROR    - form has no current field or
 |                                        field-window
 +--------------------------------------------------------------------------*/
-static int Position_Form_Cursor(FORM * form)
+NCURSES_EXPORT(int)
+_nc_Position_Form_Cursor (FORM * form)
 {
   FIELD  *field;
   WINDOW *formwin;
@@ -587,7 +592,7 @@ static int Position_Form_Cursor(FORM * form)
 
 /*---------------------------------------------------------------------------
 |   Facility      :  libnform  
-|   Function      :  static int Refresh_Current_Field(FORM * form)
+|   Function      :  int _nc_Refresh_Current_Field(FORM * form)
 |   
 |   Description   :  Propagate the changes in the fields window to the
 |                    window of the form.
@@ -596,7 +601,8 @@ static int Position_Form_Cursor(FORM * form)
 |                    E_BAD_ARGUMENT    - invalid form pointer
 |                    E_SYSTEM_ERROR    - general error
 +--------------------------------------------------------------------------*/
-static int Refresh_Current_Field(FORM * form)
+NCURSES_EXPORT(int)
+_nc_Refresh_Current_Field (FORM * form)
 {
   WINDOW *formwin;
   FIELD  *field;
@@ -636,7 +642,7 @@ static int Refresh_Current_Field(FORM * form)
                      0);
            }
          else
-           { /* A multiline, i.e. vertical scrolling field */
+           { /* A multi-line, i.e. vertical scrolling field */
              int row_after_bottom,first_modified_row,first_unmodified_row;
 
              if (field->drows > field->rows)
@@ -703,7 +709,7 @@ static int Refresh_Current_Field(FORM * form)
        }
     }
   untouchwin(form->w);
-  return Position_Form_Cursor(form);
+  return _nc_Position_Form_Cursor(form);
 }
        
 /*---------------------------------------------------------------------------
@@ -805,7 +811,7 @@ static bool Check_Char(FIELDTYPE * typ, int ch, TypeArgument *argp)
            return typ->ccheck(ch,(void *)argp);
        }
     }
-  return isprint((unsigned char)ch);
+  return (isprint((unsigned char)ch) ? TRUE : FALSE);
 }
 
 /*---------------------------------------------------------------------------
@@ -824,18 +830,23 @@ static bool Check_Char(FIELDTYPE * typ, int ch, TypeArgument *argp)
 static int Display_Or_Erase_Field(FIELD * field, bool bEraseFlag)
 {
   WINDOW *win;
+  WINDOW *fwin;
 
   if (!field)
     return E_SYSTEM_ERROR;
 
-  win =  derwin(Get_Form_Window(field->form),
+  fwin = Get_Form_Window(field->form);
+  win  = derwin(fwin,
                field->rows,field->cols,field->frow,field->fcol);
 
   if (!win) 
     return E_SYSTEM_ERROR;
   else
     {
-      Set_Field_Window_Attributes(field,win);
+      if (field->opts & O_VISIBLE)
+       Set_Field_Window_Attributes(field,win);
+      else
+       wattrset(win,getattrs(fwin));
       werase(win);
     }
 
@@ -892,7 +903,7 @@ static int Synchronize_Field(FIELD * field)
            Buffer_To_Window( field, form->w );
          
          field->status |= _NEWTOP;
-         res = Refresh_Current_Field( form );
+         res = _nc_Refresh_Current_Field( form );
        }
       else
        res = Display_Field( field );
@@ -907,7 +918,7 @@ static int Synchronize_Field(FIELD * field)
 |   
 |   Description   :  Propagate the Synchronize_Field function to all linked
 |                    fields. The first error that occurs in the sequence
-|                    of updates is the returnvalue.
+|                    of updates is the return value.
 |
 |   Return Values :  E_OK                - success
 |                    E_BAD_ARGUMENT      - invalid field pointer 
@@ -938,7 +949,7 @@ static int Synchronize_Linked_Fields(FIELD * field)
 
 /*---------------------------------------------------------------------------
 |   Facility      :  libnform  
-|   Function      :  static int Synchronize_Attributes(FIELD * field)
+|   Function      :  int _nc_Synchronize_Attributes(FIELD * field)
 |   
 |   Description   :  If a fields visual attributes have changed, this
 |                    routine is called to propagate those changes to the
@@ -948,7 +959,8 @@ static int Synchronize_Linked_Fields(FIELD * field)
 |                    E_BAD_ARGUMENT   - invalid field pointer
 |                    E_SYSTEM_ERROR   - some severe basic error
 +--------------------------------------------------------------------------*/
-static int Synchronize_Attributes(FIELD * field)
+NCURSES_EXPORT(int)
+_nc_Synchronize_Attributes (FIELD * field)
 {
   FORM *form;
   int res = E_OK;
@@ -982,7 +994,7 @@ static int Synchronize_Attributes(FIELD * field)
              wsyncup(formwin);
              Buffer_To_Window(field,form->w);
              field->status |= _NEWTOP; /* fake refresh to paint all */
-             Refresh_Current_Field(form);
+             _nc_Refresh_Current_Field(form);
            }
        }
       else 
@@ -995,18 +1007,20 @@ static int Synchronize_Attributes(FIELD * field)
 
 /*---------------------------------------------------------------------------
 |   Facility      :  libnform  
-|   Function      :  static int Synchronize_Options(FIELD * field,
-|                                                   Field_Options newopts)
+|   Function      :  int _nc_Synchronize_Options(FIELD * field,
+|                                                Field_Options newopts)
 |   
 |   Description   :  If a fields options have changed, this routine is
 |                    called to propagate these changes to the screen and
-|                    to really change the behaviour of the field.
+|                    to really change the behavior of the field.
 |
 |   Return Values :  E_OK                - success
 |                    E_BAD_ARGUMENT      - invalid field pointer 
 |                    E_SYSTEM_ERROR      - some severe basic error
 +--------------------------------------------------------------------------*/
-static int Synchronize_Options(FIELD *field, Field_Options newopts)
+NCURSES_EXPORT(int)
+_nc_Synchronize_Options
+(FIELD *field, Field_Options newopts)
 {
   Field_Options oldopts;
   Field_Options changed_opts;
@@ -1036,9 +1050,9 @@ static int Synchronize_Options(FIELD *field, Field_Options newopts)
              if (changed_opts & O_VISIBLE)
                {
                  if (newopts & O_VISIBLE)
-                   res = Erase_Field(field);
-                 else
                    res = Display_Field(field);
+                 else
+                   res = Erase_Field(field);
                }
              else
                {
@@ -1075,7 +1089,7 @@ static int Synchronize_Options(FIELD *field, Field_Options newopts)
              (!single_line_field && (field->drows < field->maxgrow)))
            {
              field->status |= _MAY_GROW;
-             /* a field with justification now changes its behaviour,
+             /* a field with justification now changes its behavior,
                 so we must redisplay it */
              if (single_line_field                 &&
                  (field->just != NO_JUSTIFICATION) &&
@@ -1094,9 +1108,8 @@ static int Synchronize_Options(FIELD *field, Field_Options newopts)
 
 /*---------------------------------------------------------------------------
 |   Facility      :  libnform  
-|   Function      :  static int Set_Current_Field(
-|                                                 FORM  * form,
-|                                                 FIELD * newfield)
+|   Function      :  int _nc_Set_Current_Field(FORM  * form,
+|                                              FIELD * newfield)
 |   
 |   Description   :  Make the newfield the new current field.
 |
@@ -1104,7 +1117,9 @@ static int Synchronize_Options(FIELD *field, Field_Options newopts)
 |                    E_BAD_ARGUMENT      - invalid form or field pointer 
 |                    E_SYSTEM_ERROR      - some severe basic error
 +--------------------------------------------------------------------------*/
-static int Set_Current_Field(FORM  *form, FIELD *newfield)
+NCURSES_EXPORT(int)
+_nc_Set_Current_Field
+(FORM  *form, FIELD *newfield)
 {
   FIELD  *field;
   WINDOW *new_window;
@@ -1127,7 +1142,7 @@ static int Set_Current_Field(FORM  *form, FIELD *newfield)
          (field->opts & O_VISIBLE) &&
          (field->form->curpage == field->page))
        {
-         Refresh_Current_Field(form);
+         _nc_Refresh_Current_Field(form);
          if (field->opts & O_PUBLIC)
            {
              if (field->drows > field->rows)
@@ -1149,6 +1164,7 @@ static int Set_Current_Field(FORM  *form, FIELD *newfield)
                }
            }
          delwin(form->w);
+         form->w = (WINDOW *)0;
        }
       
       field = newfield;
@@ -1163,7 +1179,11 @@ static int Set_Current_Field(FORM  *form, FIELD *newfield)
        return(E_SYSTEM_ERROR);
 
       form->current = field;
+
+      if (form->w)
+       delwin(form->w);
       form->w       = new_window;
+
       form->status &= ~_WINDOW_MODIFIED;
       Set_Field_Window_Attributes(field,form->w);
 
@@ -1197,8 +1217,8 @@ static int Set_Current_Field(FORM  *form, FIELD *newfield)
 |   Facility      :  libnform  
 |   Function      :  static int IFN_Next_Character(FORM * form)
 |   
-|   Description   :  Move to the next character in the field. In a multiline
-|                    field this wraps and the end of the line.
+|   Description   :  Move to the next character in the field. In a multi-line
+|                    field this wraps at the end of the line.
 |
 |   Return Values :  E_OK                - success
 |                    E_REQUEST_DENIED    - at the rightmost position
@@ -1211,7 +1231,17 @@ static int IFN_Next_Character(FORM * form)
     {
       if ((++(form->currow))==field->drows)
        {
+#if GROW_IF_NAVIGATE
+         if (!Single_Line_Field(field) && Field_Grown(field,1)) {
+           form->curcol = 0;
+           return(E_OK);
+         }
+#endif
          form->currow--;
+#if GROW_IF_NAVIGATE
+         if (Single_Line_Field(field) && Field_Grown(field,1))
+           return(E_OK);
+#endif
          form->curcol--;
          return(E_REQUEST_DENIED);
        }
@@ -1225,7 +1255,7 @@ static int IFN_Next_Character(FORM * form)
 |   Function      :  static int IFN_Previous_Character(FORM * form)
 |   
 |   Description   :  Move to the previous character in the field. In a 
-|                    multiline field this wraps and the beginning of the 
+|                    multi-line field this wraps and the beginning of the 
 |                    line.
 |
 |   Return Values :  E_OK                - success
@@ -1261,6 +1291,10 @@ static int IFN_Next_Line(FORM * form)
 
   if ((++(form->currow))==field->drows)
     {
+#if GROW_IF_NAVIGATE
+      if (!Single_Line_Field(field) && Field_Grown(field,1))
+       return(E_OK);
+#endif
       form->currow--;
       return(E_REQUEST_DENIED);
     }
@@ -1308,7 +1342,7 @@ static int IFN_Next_Word(FORM * form)
   Synchronize_Buffer(form);
 
   /* Go to the first whitespace after the current position (including
-     current position). This is then the startpoint to look for the
+     current position). This is then the starting point to look for the
     next non-blank data */
   s = Get_First_Whitespace_Character(bp,Buffer_Length(field) -
                                     (int)(bp - field->buf));
@@ -1402,7 +1436,7 @@ static int IFN_Beginning_Of_Field(FORM * form)
 |   
 |   Description   :  Place the cursor after the last non-pad character in
 |                    the field. If the field occupies the last position in
-|                    the buffer, the cursos is positioned on the last 
+|                    the buffer, the cursor is positioned on the last 
 |                    character.
 |
 |   Return Values :  E_OK              - success
@@ -1500,6 +1534,11 @@ static int IFN_Right_Character(FORM * form)
 {
   if ( (++(form->curcol)) == form->current->dcols )
     {
+#if GROW_IF_NAVIGATE
+      FIELD *field = form->current;
+      if (Single_Line_Field(field) && Field_Grown(field,1))
+       return(E_OK);
+#endif
       --(form->curcol);
       return(E_REQUEST_DENIED);
     }
@@ -1542,6 +1581,10 @@ static int IFN_Down_Character(FORM * form)
 
   if ( (++(form->currow)) == field->drows )
     {
+#if GROW_IF_NAVIGATE
+      if (!Single_Line_Field(field) && Field_Grown(field,1))
+       return(E_OK);
+#endif
       --(form->currow);
       return(E_REQUEST_DENIED);
     }
@@ -1613,7 +1656,7 @@ static int VSC_Generic(FORM *form, int lines)
 |   
 |   Description   :  Performs the generic vertical scrolling routines. 
 |                    This has to check for a multi-line field and to set
-|                    the _NEWTOP flag if scrolling really occured.
+|                    the _NEWTOP flag if scrolling really occurred.
 |
 |   Return Values :  Propagated error code from low-level driver calls
 +--------------------------------------------------------------------------*/
@@ -2013,7 +2056,7 @@ static int Insert_String(FORM *form, int row, char *txt, int len)
 |                    the wrapping.
 |
 |   Return Values :  E_OK              - no wrapping required or wrapping
-|                                        was successfull
+|                                        was successful
 |                    E_REQUEST_DENIED  -
 |                    E_SYSTEM_ERROR    - some system error
 +--------------------------------------------------------------------------*/
@@ -2025,7 +2068,7 @@ static int Wrapping_Not_Necessary_Or_Wrapping_Ok(FORM * form)
 
   if ( (field->opts & O_WRAP)                     &&  /* wrapping wanted     */
       (!Single_Line_Field(field))                 &&  /* must be multi-line  */
-      (There_Is_No_Room_For_A_Char_In_Line(form)) &&  /* line id full        */
+      (There_Is_No_Room_For_A_Char_In_Line(form)) &&  /* line is full        */
       (!Last_Row || Growable(field))               )  /* there are more lines*/
     {
       char *bp;
@@ -2060,6 +2103,8 @@ static int Wrapping_Not_Necessary_Or_Wrapping_Ok(FORM * form)
              return E_OK;
            }
        }
+      else
+       return E_OK;
       if (result!=E_OK)
        {
          wmove(form->w,form->currow,form->curcol);
@@ -2085,7 +2130,7 @@ static int Wrapping_Not_Necessary_Or_Wrapping_Ok(FORM * form)
 |   
 |   Description   :  Generic routine for field editing requests. The driver
 |                    routines are only called for editable fields, the
-|                    _WINDOW_MODIFIED flag is set if editing occured.
+|                    _WINDOW_MODIFIED flag is set if editing occurred.
 |                    This is somewhat special due to the overload semantics
 |                    of the NEW_LINE and DEL_PREV requests.
 |
@@ -2096,7 +2141,7 @@ static int Field_Editing(int (* const fct) (FORM *), FORM * form)
   int res = E_REQUEST_DENIED;
 
   /* We have to deal here with the specific case of the overloaded 
-     behaviour of New_Line and Delete_Previous requests.
+     behavior of New_Line and Delete_Previous requests.
      They may end up in navigational requests if we are on the first
      character in a field. But navigation is also allowed on non-
      editable fields.
@@ -2160,6 +2205,7 @@ static int FE_New_Line(FORM * form)
        {
          if (!(form->opts & O_NL_OVERLOAD))
            return(E_REQUEST_DENIED);
+         wmove(form->w,form->currow,form->curcol);
          wclrtoeol(form->w);
          /* we have to set this here, although it is also
             handled in the generic routine. The reason is,
@@ -2176,6 +2222,7 @@ static int FE_New_Line(FORM * form)
                 a single-line field */
              return(E_SYSTEM_ERROR);
            }
+         wmove(form->w,form->currow,form->curcol);
          wclrtoeol(form->w);
          form->currow++;
          form->curcol = 0;
@@ -2203,6 +2250,7 @@ static int FE_New_Line(FORM * form)
          
          bp= Address_Of_Current_Position_In_Buffer(form);
          t = After_End_Of_Data(bp,field->dcols - form->curcol);
+         wmove(form->w,form->currow,form->curcol);
          wclrtoeol(form->w);
          form->currow++;
          form->curcol=0;
@@ -2293,6 +2341,7 @@ static int FE_Insert_Line(FORM * form)
 +--------------------------------------------------------------------------*/
 static int FE_Delete_Character(FORM * form)
 {
+  wmove(form->w,form->currow,form->curcol);
   wdelch(form->w);
   return E_OK;
 }
@@ -2333,6 +2382,7 @@ static int FE_Delete_Previous(FORM * form)
       if ((int)(this_end-this_line) > 
          (field->cols-(int)(prev_end-prev_line))) 
        return E_REQUEST_DENIED;
+      wmove(form->w,form->currow,form->curcol);
       wdeleteln(form->w);
       Adjust_Cursor_Position(form,prev_end);
       wmove(form->w,form->currow,form->curcol);
@@ -2410,20 +2460,22 @@ static int FE_Delete_Word(FORM * form)
 +--------------------------------------------------------------------------*/
 static int FE_Clear_To_End_Of_Line(FORM * form)
 {
+  wmove(form->w,form->currow,form->curcol);
   wclrtoeol(form->w);
   return E_OK;
 }
 
 /*---------------------------------------------------------------------------
 |   Facility      :  libnform  
-|   Function      :  static int FE_Clear_To_End_Of_Form(FORM * form)
+|   Function      :  static int FE_Clear_To_End_Of_Field(FORM * form)
 |   
-|   Description   :  Clear to end of form.
+|   Description   :  Clear to end of field.
 |
 |   Return Values :  E_OK   - success
 +--------------------------------------------------------------------------*/
-static int FE_Clear_To_End_Of_Form(FORM * form)
+static int FE_Clear_To_End_Of_Field(FORM * form)
 {
+  wmove(form->w,form->currow,form->curcol);
   wclrtobot(form->w);
   return E_OK;
 }
@@ -2644,14 +2696,15 @@ static bool Check_Field(FIELDTYPE *typ, FIELD *field, TypeArgument *argp)
 
 /*---------------------------------------------------------------------------
 |   Facility      :  libnform  
-|   Function      :  static bool Internal_Validation(FORM * form )
+|   Function      :  bool _nc_Internal_Validation(FORM * form )
 |   
 |   Description   :  Validate the current field of the form.  
 |
 |   Return Values :  TRUE  - field is valid
 |                    FALSE - field is invalid
 +--------------------------------------------------------------------------*/
-static bool Internal_Validation(FORM *form)
+NCURSES_EXPORT(bool)
+_nc_Internal_Validation (FORM *form)
 {
   FIELD *field;
 
@@ -2688,7 +2741,7 @@ static bool Internal_Validation(FORM *form)
 +--------------------------------------------------------------------------*/
 static int FV_Validation(FORM * form)
 {
-  if (Internal_Validation(form))
+  if (_nc_Internal_Validation(form))
     return E_OK;
   else
     return E_INVALID_FIELD;
@@ -2731,7 +2784,7 @@ INLINE static FIELD *Next_Field_On_Page(FIELD * field)
 
 /*---------------------------------------------------------------------------
 |   Facility      :  libnform  
-|   Function      :  static FIELD * First_Active_Field(FORM * form)
+|   Function      :  FIELD* _nc_First_Active_Field(FORM * form)
 |   
 |   Description   :  Get the first active field on the current page,
 |                    if there are such. If there are none, get the first
@@ -2740,7 +2793,8 @@ INLINE static FIELD *Next_Field_On_Page(FIELD * field)
 |
 |   Return Values :  Pointer to calculated field.
 +--------------------------------------------------------------------------*/
-static FIELD * First_Active_Field(FORM * form)
+NCURSES_EXPORT(FIELD*)
+_nc_First_Active_Field (FORM * form)
 {
   FIELD **last_on_page = &form->field[form->page[form->curpage].pmax];
   FIELD *proposed = Next_Field_On_Page(*last_on_page);
@@ -2856,20 +2910,20 @@ INLINE static FIELD *Sorted_Previous_Field(FIELD * field)
 
 /*---------------------------------------------------------------------------
 |   Facility      :  libnform  
-|   Function      :  static FIELD *Left_Neighbour_Field(FIELD * field)
+|   Function      :  static FIELD *Left_Neighbor_Field(FIELD * field)
 |   
-|   Description   :  Get the left neighbour of the field on the same line
+|   Description   :  Get the left neighbor of the field on the same line
 |                    and the same page. Cycles through the line.
 |
-|   Return Values :  Pointer to left neighbour field.
+|   Return Values :  Pointer to left neighbor field.
 +--------------------------------------------------------------------------*/
-INLINE static FIELD *Left_Neighbour_Field(FIELD * field)
+INLINE static FIELD *Left_Neighbor_Field(FIELD * field)
 {
   FIELD *field_on_page = field;
 
-  /* For a field that has really a left neighbour, the while clause
+  /* For a field that has really a left neighbor, the while clause
      immediately fails and the loop is left, positioned at the right
-     neighbour. Otherwise we cycle backwards through the sorted fieldlist
+     neighbor. Otherwise we cycle backwards through the sorted field list
      until we enter the same line (from the right end).
   */
   do
@@ -2882,18 +2936,18 @@ INLINE static FIELD *Left_Neighbour_Field(FIELD * field)
 
 /*---------------------------------------------------------------------------
 |   Facility      :  libnform  
-|   Function      :  static FIELD *Right_Neighbour_Field(FIELD * field)
+|   Function      :  static FIELD *Right_Neighbor_Field(FIELD * field)
 |   
-|   Description   :  Get the right neighbour of the field on the same line
+|   Description   :  Get the right neighbor of the field on the same line
 |                    and the same page.
 |
-|   Return Values :  Pointer to right neighbour field.
+|   Return Values :  Pointer to right neighbor field.
 +--------------------------------------------------------------------------*/
-INLINE static FIELD *Right_Neighbour_Field(FIELD * field)
+INLINE static FIELD *Right_Neighbor_Field(FIELD * field)
 {
   FIELD *field_on_page = field;
 
-  /* See the comments on Left_Neighbour_Field to understand how it works */
+  /* See the comments on Left_Neighbor_Field to understand how it works */
   do
     {
       field_on_page = Sorted_Next_Field(field_on_page);
@@ -2904,18 +2958,18 @@ INLINE static FIELD *Right_Neighbour_Field(FIELD * field)
 
 /*---------------------------------------------------------------------------
 |   Facility      :  libnform  
-|   Function      :  static FIELD *Upper_Neighbour_Field(FIELD * field)
+|   Function      :  static FIELD *Upper_Neighbor_Field(FIELD * field)
 |   
 |   Description   :  Because of the row-major nature of sorting the fields,
-|                    its more difficult to define whats the upper neighbour
+|                    it is more difficult to define whats the upper neighbor
 |                    field really means. We define that it must be on a
 |                    'previous' line (cyclic order!) and is the rightmost
 |                    field laying on the left side of the given field. If
 |                    this set is empty, we take the first field on the line.
 |
-|   Return Values :  Pointer to the upper neighbour field.
+|   Return Values :  Pointer to the upper neighbor field.
 +--------------------------------------------------------------------------*/
-static FIELD *Upper_Neighbour_Field(FIELD * field)
+static FIELD *Upper_Neighbor_Field(FIELD * field)
 {
   FIELD *field_on_page = field;
   int frow = field->frow;
@@ -2951,18 +3005,18 @@ static FIELD *Upper_Neighbour_Field(FIELD * field)
 
 /*---------------------------------------------------------------------------
 |   Facility      :  libnform  
-|   Function      :  static FIELD *Down_Neighbour_Field(FIELD * field)
+|   Function      :  static FIELD *Down_Neighbor_Field(FIELD * field)
 |   
 |   Description   :  Because of the row-major nature of sorting the fields,
-|                    its more difficult to define whats the down neighbour
+|                    its more difficult to define whats the down neighbor
 |                    field really means. We define that it must be on a
 |                    'next' line (cyclic order!) and is the leftmost
 |                    field laying on the right side of the given field. If
 |                    this set is empty, we take the last field on the line.
 |
-|   Return Values :  Pointer to the upper neighbour field.
+|   Return Values :  Pointer to the upper neighbor field.
 +--------------------------------------------------------------------------*/
-static FIELD *Down_Neighbour_Field(FIELD * field)
+static FIELD *Down_Neighbor_Field(FIELD * field)
 {
   FIELD *field_on_page = field;
   int frow = field->frow;
@@ -3006,7 +3060,7 @@ static FIELD *Down_Neighbour_Field(FIELD * field)
 |                                           int (* const fct) (FORM *),
 |                                           FORM * form)
 |   
-|   Description   :  Generic behaviour for changing the current field, the
+|   Description   :  Generic behavior for changing the current field, the
 |                    field is left and a new field is entered. So the field
 |                    must be validated and the field init/term hooks must
 |                    be called.
@@ -3019,7 +3073,7 @@ static int Inter_Field_Navigation(int (* const fct) (FORM *),FORM *form)
 {
   int res;
 
-  if (!Internal_Validation(form)) 
+  if (!_nc_Internal_Validation(form)) 
     res = E_INVALID_FIELD;
   else
     {
@@ -3041,8 +3095,8 @@ static int Inter_Field_Navigation(int (* const fct) (FORM *),FORM *form)
 +--------------------------------------------------------------------------*/
 static int FN_Next_Field(FORM * form)
 {
-  return Set_Current_Field(form,
-                          Next_Field_On_Page(form->current));
+  return _nc_Set_Current_Field(form,
+                              Next_Field_On_Page(form->current));
 }
 
 /*---------------------------------------------------------------------------
@@ -3057,8 +3111,8 @@ static int FN_Next_Field(FORM * form)
 +--------------------------------------------------------------------------*/
 static int FN_Previous_Field(FORM * form)
 {
-  return Set_Current_Field(form,
-                          Previous_Field_On_Page(form->current));
+  return _nc_Set_Current_Field(form,
+                              Previous_Field_On_Page(form->current));
 }
 
 /*---------------------------------------------------------------------------
@@ -3072,9 +3126,8 @@ static int FN_Previous_Field(FORM * form)
 +--------------------------------------------------------------------------*/
 static int FN_First_Field(FORM * form)
 {
-  return 
-    Set_Current_Field(form,
-       Next_Field_On_Page(form->field[form->page[form->curpage].pmax]));
+  return _nc_Set_Current_Field(form,
+      Next_Field_On_Page(form->field[form->page[form->curpage].pmax]));
 }
 
 /*---------------------------------------------------------------------------
@@ -3089,7 +3142,7 @@ static int FN_First_Field(FORM * form)
 static int FN_Last_Field(FORM * form)
 {
   return 
-    Set_Current_Field(form,
+    _nc_Set_Current_Field(form,
        Previous_Field_On_Page(form->field[form->page[form->curpage].pmin]));
 }
 
@@ -3105,8 +3158,8 @@ static int FN_Last_Field(FORM * form)
 +--------------------------------------------------------------------------*/
 static int FN_Sorted_Next_Field(FORM * form)
 {
-  return Set_Current_Field(form,
-                          Sorted_Next_Field(form->current));
+  return _nc_Set_Current_Field(form,
+                              Sorted_Next_Field(form->current));
 }
 
 /*---------------------------------------------------------------------------
@@ -3121,8 +3174,8 @@ static int FN_Sorted_Next_Field(FORM * form)
 +--------------------------------------------------------------------------*/
 static int FN_Sorted_Previous_Field(FORM * form)
 {
-  return Set_Current_Field(form,
-                          Sorted_Previous_Field(form->current));
+  return _nc_Set_Current_Field(form,
+                              Sorted_Previous_Field(form->current));
 }
 
 /*---------------------------------------------------------------------------
@@ -3137,8 +3190,8 @@ static int FN_Sorted_Previous_Field(FORM * form)
 +--------------------------------------------------------------------------*/
 static int FN_Sorted_First_Field(FORM * form)
 {
-  return Set_Current_Field(form,
-           Sorted_Next_Field(form->field[form->page[form->curpage].smax]));
+  return _nc_Set_Current_Field(form,
+             Sorted_Next_Field(form->field[form->page[form->curpage].smax]));
 }
 
 /*---------------------------------------------------------------------------
@@ -3153,7 +3206,7 @@ static int FN_Sorted_First_Field(FORM * form)
 +--------------------------------------------------------------------------*/
 static int FN_Sorted_Last_Field(FORM * form)
 {
-  return Set_Current_Field(form,
+  return _nc_Set_Current_Field(form,
           Sorted_Previous_Field(form->field[form->page[form->curpage].smin]));
 }
 
@@ -3169,8 +3222,8 @@ static int FN_Sorted_Last_Field(FORM * form)
 +--------------------------------------------------------------------------*/
 static int FN_Left_Field(FORM * form)
 {
-  return Set_Current_Field(form,
-                          Left_Neighbour_Field(form->current));
+  return _nc_Set_Current_Field(form,
+                              Left_Neighbor_Field(form->current));
 }
 
 /*---------------------------------------------------------------------------
@@ -3185,17 +3238,17 @@ static int FN_Left_Field(FORM * form)
 +--------------------------------------------------------------------------*/
 static int FN_Right_Field(FORM * form)
 {
-  return Set_Current_Field(form,
-                          Right_Neighbour_Field(form->current));
+  return _nc_Set_Current_Field(form,
+                              Right_Neighbor_Field(form->current));
 }
 
 /*---------------------------------------------------------------------------
 |   Facility      :  libnform  
 |   Function      :  static int FN_Up_Field(FORM * form)
 |   
-|   Description   :  Get the upper neighbour of the current field. This
+|   Description   :  Get the upper neighbor of the current field. This
 |                    cycles through the page. See the comments of the
-|                    Upper_Neighbour_Field function to understand how
+|                    Upper_Neighbor_Field function to understand how
 |                    'upper' is defined. 
 |
 |   Return Values :  E_OK            - success
@@ -3203,17 +3256,17 @@ static int FN_Right_Field(FORM * form)
 +--------------------------------------------------------------------------*/
 static int FN_Up_Field(FORM * form)
 {
-  return Set_Current_Field(form,
-                          Upper_Neighbour_Field(form->current));
+  return _nc_Set_Current_Field(form,
+                              Upper_Neighbor_Field(form->current));
 }
 
 /*---------------------------------------------------------------------------
 |   Facility      :  libnform  
 |   Function      :  static int FN_Down_Field(FORM * form)
 |   
-|   Description   :  Get the down neighbour of the current field. This
+|   Description   :  Get the down neighbor of the current field. This
 |                    cycles through the page. See the comments of the
-|                    Down_Neighbour_Field function to understand how
+|                    Down_Neighbor_Field function to understand how
 |                    'down' is defined. 
 |
 |   Return Values :  E_OK            - success
@@ -3221,8 +3274,8 @@ static int FN_Up_Field(FORM * form)
 +--------------------------------------------------------------------------*/
 static int FN_Down_Field(FORM * form)
 {
-  return Set_Current_Field(form,
-                          Down_Neighbour_Field(form->current));
+  return _nc_Set_Current_Field(form,
+                              Down_Neighbor_Field(form->current));
 }
 /*----------------------------------------------------------------------------
   END of Field Navigation routines 
@@ -3234,11 +3287,11 @@ static int FN_Down_Field(FORM * form)
 
 /*---------------------------------------------------------------------------
 |   Facility      :  libnform  
-|   Function      :  static int Set_Form_Page(FORM * form,
-|                                             int page,
-|                                             FIELD * field)
+|   Function      :  int _nc_Set_Form_Page(FORM * form,
+|                                          int page,
+|                                          FIELD * field)
 |   
-|   Description   :  Make the given page nr. the current page and make
+|   Description   :  Make the given page number the current page and make
 |                    the given field the current field on the page. If
 |                    for the field NULL is given, make the first field on
 |                    the page the current field. The routine acts only
@@ -3247,7 +3300,9 @@ static int FN_Down_Field(FORM * form)
 |   Return Values :  E_OK                - success
 |                    != E_OK             - error from subordinate call
 +--------------------------------------------------------------------------*/
-static int Set_Form_Page(FORM * form, int page, FIELD * field)
+NCURSES_EXPORT(int)
+_nc_Set_Form_Page
+(FORM * form, int page, FIELD * field)
 {
   int res = E_OK;
 
@@ -3267,7 +3322,7 @@ static int Set_Form_Page(FORM * form, int page, FIELD * field)
        } while(field_on_page != last_field);
 
       if (field)
-       res = Set_Current_Field(form,field);
+       res = _nc_Set_Current_Field(form,field);
       else
        /* N.B.: we don't encapsulate this by Inter_Field_Navigation(),
           because this is already executed in a page navigation
@@ -3318,7 +3373,7 @@ INLINE static int Previous_Page_Number(const FORM * form)
 |                                               int (* const fct) (FORM *),
 |                                               FORM * form)
 |   
-|   Description   :  Generic behaviour for changing a page. This means
+|   Description   :  Generic behavior for changing a page. This means
 |                    that the field is left and a new field is entered.
 |                    So the field must be validated and the field init/term
 |                    hooks must be called. Because also the page is changed,
@@ -3332,7 +3387,7 @@ static int Page_Navigation(int (* const fct) (FORM *), FORM * form)
 {
   int res;
 
-  if (!Internal_Validation(form)) 
+  if (!_nc_Internal_Validation(form)) 
     res = E_INVALID_FIELD;
   else
     {
@@ -3356,7 +3411,7 @@ static int Page_Navigation(int (* const fct) (FORM *), FORM * form)
 +--------------------------------------------------------------------------*/
 static int PN_Next_Page(FORM * form)
 { 
-  return Set_Form_Page(form,Next_Page_Number(form),(FIELD *)0);
+  return _nc_Set_Form_Page(form,Next_Page_Number(form),(FIELD *)0);
 }
 
 /*---------------------------------------------------------------------------
@@ -3370,7 +3425,7 @@ static int PN_Next_Page(FORM * form)
 +--------------------------------------------------------------------------*/
 static int PN_Previous_Page(FORM * form)
 {
-  return Set_Form_Page(form,Previous_Page_Number(form),(FIELD *)0);
+  return _nc_Set_Form_Page(form,Previous_Page_Number(form),(FIELD *)0);
 }
 
 /*---------------------------------------------------------------------------
@@ -3384,7 +3439,7 @@ static int PN_Previous_Page(FORM * form)
 +--------------------------------------------------------------------------*/
 static int PN_First_Page(FORM * form)
 {
-  return Set_Form_Page(form,0,(FIELD *)0);
+  return _nc_Set_Form_Page(form,0,(FIELD *)0);
 }
 
 /*---------------------------------------------------------------------------
@@ -3398,7 +3453,7 @@ static int PN_First_Page(FORM * form)
 +--------------------------------------------------------------------------*/
 static int PN_Last_Page(FORM * form)
 {
-  return Set_Form_Page(form,form->maxpage-1,(FIELD *)0);
+  return _nc_Set_Form_Page(form,form->maxpage-1,(FIELD *)0);
 }
 /*----------------------------------------------------------------------------
   END of Field Navigation routines 
@@ -3423,7 +3478,6 @@ static int Data_Entry(FORM * form, int c)
 {
   FIELD  *field = form->current;
   int result = E_REQUEST_DENIED;
-  bool End_Of_Field;
 
   if ( (field->opts & O_EDIT) 
 #if FIX_FORM_INACTIVE_BUG
@@ -3457,9 +3511,9 @@ static int Data_Entry(FORM * form, int c)
 
       if ((result=Wrapping_Not_Necessary_Or_Wrapping_Ok(form))==E_OK)
        {
+         bool End_Of_Field= (((field->drows-1)==form->currow) &&
+                             ((field->dcols-1)==form->curcol));
          form->status |= _WINDOW_MODIFIED;
-         End_Of_Field= (((field->drows-1)==form->currow) &&
-                        ((field->dcols-1)==form->curcol));
          if (End_Of_Field && !Growable(field) && (field->opts & O_AUTOSKIP))
            result = Inter_Field_Navigation(FN_Next_Field,form);
          else
@@ -3551,7 +3605,7 @@ static const Binding_Info bindings[MAX_FORM_COMMAND - MIN_FORM_COMMAND + 1] =
   { REQ_DEL_LINE     |ID_FE  ,FE_Delete_Line},
   { REQ_DEL_WORD     |ID_FE  ,FE_Delete_Word},
   { REQ_CLR_EOL      |ID_FE  ,FE_Clear_To_End_Of_Line},
-  { REQ_CLR_EOF      |ID_FE  ,FE_Clear_To_End_Of_Form},
+  { REQ_CLR_EOF      |ID_FE  ,FE_Clear_To_End_Of_Field},
   { REQ_CLR_FIELD    |ID_FE  ,FE_Clear_Field},
   
   { REQ_OVL_MODE     |ID_EM  ,EM_Overlay_Mode},
@@ -3601,7 +3655,8 @@ static const Binding_Info bindings[MAX_FORM_COMMAND - MIN_FORM_COMMAND + 1] =
 |                    E_REQUEST_DENIED  - request failed
 |                    E_UNKNOWN_COMMAND - command not known
 +--------------------------------------------------------------------------*/
-int form_driver(FORM * form, int  c)
+NCURSES_EXPORT(int)
+form_driver (FORM * form, int  c)
 {
   const Binding_Info* BI = (Binding_Info *)0;
   int res = E_UNKNOWN_COMMAND;
@@ -3616,7 +3671,7 @@ int form_driver(FORM * form, int  c)
   
   if (c==FIRST_ACTIVE_MAGIC)
     {
-      form->current = First_Active_Field(form);
+      form->current = _nc_First_Active_Field(form);
       return E_OK;
     }
   
@@ -3650,10 +3705,10 @@ int form_driver(FORM * form, int  c)
          NULL,                    /* Field Validation is generic         */
          NULL                     /* Choice Request is generic           */
        };
-      int nMethods = (sizeof(Generic_Methods)/sizeof(Generic_Methods[0]));
-      int method   = ((BI->keycode & ID_Mask) >> ID_Shft) & 0xffff;
+      size_t nMethods = (sizeof(Generic_Methods)/sizeof(Generic_Methods[0]));
+      size_t method   = ((BI->keycode & ID_Mask) >> ID_Shft) & 0xffff;
       
-      if ( (method < 0) || (method >= nMethods) || !(BI->cmd) )
+      if ( (method >= nMethods) || !(BI->cmd) )
        res = E_SYSTEM_ERROR;
       else
        {
@@ -3672,274 +3727,15 @@ int form_driver(FORM * form, int  c)
                     (TypeArgument *)(form->current->arg)))
        res = Data_Entry(form,c);
     }
-  Refresh_Current_Field(form);
+  _nc_Refresh_Current_Field(form);
   RETURN(res);
 }
 \f
-/*---------------------------------------------------------------------------
-|   Facility      :  libnform  
-|   Function      :  int post_form(FORM * form)
-|   
-|   Description   :  Writes the form into its associated subwindow.
-|
-|   Return Values :  E_OK              - success
-|                    E_BAD_ARGUMENT    - invalid form pointer
-|                    E_POSTED          - form already posted
-|                    E_NOT_CONNECTED   - no fields connected to form
-|                    E_NO_ROOM         - form doesn't fit into subwindow
-|                    E_SYSTEM_ERROR    - system error
-+--------------------------------------------------------------------------*/
-int post_form(FORM * form)
-{
-  WINDOW *formwin;
-  int err;
-  int page;
-
-  if (!form)
-    RETURN(E_BAD_ARGUMENT);
-
-  if (form->status & _POSTED)   
-    RETURN(E_POSTED);
-
-  if (!(form->field))
-    RETURN(E_NOT_CONNECTED);
-  
-  formwin = Get_Form_Window(form);
-  if ((form->cols > getmaxx(formwin)) || (form->rows > getmaxy(formwin))) 
-    RETURN(E_NO_ROOM);
-
-  /* reset form->curpage to an invald value. This forces Set_Form_Page
-     to do the page initialization which is required by post_form.
-  */
-  page = form->curpage;
-  form->curpage = -1;
-  if ((err = Set_Form_Page(form,page,form->current))!=E_OK)
-    RETURN(err);
-
-  form->status |= _POSTED;
-
-  Call_Hook(form,forminit);
-  Call_Hook(form,fieldinit);
-
-  Refresh_Current_Field(form);
-  RETURN(E_OK);
-}
-
-/*---------------------------------------------------------------------------
-|   Facility      :  libnform  
-|   Function      :  int unpost_form(FORM * form)
-|   
-|   Description   :  Erase form from its associated subwindow.
-|
-|   Return Values :  E_OK            - success
-|                    E_BAD_ARGUMENT  - invalid form pointer
-|                    E_NOT_POSTED    - form isn't posted
-|                    E_BAD_STATE     - called from a hook routine
-+--------------------------------------------------------------------------*/
-int unpost_form(FORM * form)
-{
-  if (!form)
-    RETURN(E_BAD_ARGUMENT);
-
-  if (!(form->status & _POSTED)) 
-    RETURN(E_NOT_POSTED);
-
-  if (form->status & _IN_DRIVER) 
-    RETURN(E_BAD_STATE);
-
-  Call_Hook(form,fieldterm);
-  Call_Hook(form,formterm);
-
-  werase(Get_Form_Window(form));
-  delwin(form->w);
-  form->w = (WINDOW *)0;
-  form->status &= ~_POSTED;
-  RETURN(E_OK);
-}
-
-/*---------------------------------------------------------------------------
-|   Facility      :  libnform  
-|   Function      :  int pos_form_cursor(FORM * form)
-|   
-|   Description   :  Moves the form window cursor to the location required
-|                    by the form driver to resume form processing. This may
-|                    be needed after the application calls a curses library
-|                    I/O routine that modifies the cursor position.
-|
-|   Return Values :  E_OK                      - Success
-|                    E_SYSTEM_ERROR            - System error.
-|                    E_BAD_ARGUMENT            - Invalid form pointer
-|                    E_NOT_POSTED              - Form is not posted
-+--------------------------------------------------------------------------*/
-int pos_form_cursor(FORM * form)
-{
-  int res;
-
-  if (!form)
-   res = E_BAD_ARGUMENT;
-  else
-    {
-      if (!(form->status & _POSTED))
-        res = E_NOT_POSTED;
-      else
-       res = Position_Form_Cursor(form);
-    }
-  RETURN(res);
-}
-
-/*---------------------------------------------------------------------------
-|   Facility      :  libnform  
-|   Function      :  int set_current_field(FORM  * form,FIELD * field)
-|   
-|   Description   :  Set the current field of the form to the specified one.
-|
-|   Return Values :  E_OK              - success
-|                    E_BAD_ARGUMENT    - invalid form or field pointer
-|                    E_REQUEST_DENIED  - field not selectable
-|                    E_BAD_STATE       - called from a hook routine
-|                    E_INVALID_FIELD   - current field can't be left
-|                    E_SYSTEM_ERROR    - system error
-+--------------------------------------------------------------------------*/
-int set_current_field(FORM  * form, FIELD * field)
-{
-  int err = E_OK;
-
-  if ( !form || !field )
-    RETURN(E_BAD_ARGUMENT);
-
-  if ( (form != field->form) || Field_Is_Not_Selectable(field) )
-    RETURN(E_REQUEST_DENIED);
-
-  if (!(form->status & _POSTED))
-    {
-      form->current = field;
-      form->curpage = field->page;
-  }
-  else
-    {
-      if (form->status & _IN_DRIVER) 
-       err = E_BAD_STATE;
-      else
-       {
-         if (form->current != field)
-           {
-             if (!Internal_Validation(form)) 
-              err = E_INVALID_FIELD;
-             else
-               {
-                 Call_Hook(form,fieldterm);
-                 if (field->page != form->curpage)
-                   {
-                     Call_Hook(form,formterm);
-                     err = Set_Form_Page(form,field->page,field);
-                     Call_Hook(form,forminit);
-                   } 
-                 else 
-                   {
-                     err = Set_Current_Field(form,field);
-                   }
-                 Call_Hook(form,fieldinit);
-                 Refresh_Current_Field(form);
-               }
-           }
-       }
-    }
-  RETURN(err);
-}
-
-/*---------------------------------------------------------------------------
-|   Facility      :  libnform  
-|   Function      :  FIELD *current_field(const FORM * form)
-|   
-|   Description   :  Return the current field.
-|
-|   Return Values :  Pointer to the current field.
-+--------------------------------------------------------------------------*/
-FIELD *current_field(const FORM * form)
-{
-  return Normalize_Form(form)->current;
-}
-
-/*---------------------------------------------------------------------------
-|   Facility      :  libnform  
-|   Function      :  int field_index(const FIELD * field)
-|   
-|   Description   :  Return the index of the field in the field-array of
-|                    the form.
-|
-|   Return Values :  >= 0   : field index
-|                    -1     : fieldpointer invalid or field not connected
-+--------------------------------------------------------------------------*/
-int field_index(const FIELD * field)
-{
-  return ( (field && field->form) ? field->index : -1 );
-}
-
-/*---------------------------------------------------------------------------
-|   Facility      :  libnform  
-|   Function      :  int set_form_page(FORM * form,int  page)
-|   
-|   Description   :  Set the page number of the form.
-|
-|   Return Values :  E_OK              - success
-|                    E_BAD_ARGUMENT    - invalid form pointer or page number
-|                    E_BAD_STATE       - called from a hook routine
-|                    E_INVALID_FIELD   - current field can't be left
-|                    E_SYSTEM_ERROR    - system error
-+--------------------------------------------------------------------------*/
-int set_form_page(FORM * form, int page)
-{
-  int err = E_OK;
-
-  if ( !form || (page<0) || (page>=form->maxpage) )
-    RETURN(E_BAD_ARGUMENT);
-
-  if (!(form->status & _POSTED))
-    {
-      form->curpage = page;
-      form->current = First_Active_Field(form);
-  }
-  else
-    {
-      if (form->status & _IN_DRIVER) 
-       err = E_BAD_STATE;
-      else
-       {
-         if (form->curpage != page)
-           {
-             if (!Internal_Validation(form)) 
-               err = E_INVALID_FIELD;
-             else
-               {
-                 Call_Hook(form,fieldterm);
-                 Call_Hook(form,formterm);
-                 err = Set_Form_Page(form,page,(FIELD *)0);
-                 Call_Hook(form,forminit);
-                 Call_Hook(form,fieldinit);
-                 Refresh_Current_Field(form);
-               }
-           }
-       }
-    }
-  RETURN(err);
-}
-
-/*---------------------------------------------------------------------------
-|   Facility      :  libnform  
-|   Function      :  int form_page(const FORM * form)
-|   
-|   Description   :  Return the current page of the form.
-|
-|   Return Values :  >= 0  : current page number
-|                    -1    : invalid form pointer
-+--------------------------------------------------------------------------*/
-int form_page(const FORM * form)
-{
-  return Normalize_Form(form)->curpage;
-}
-\f
 /*----------------------------------------------------------------------------
-  Field-Buffer manipulation routines
+  Field-Buffer manipulation routines.
+  The effects of setting a buffer is tightly coupled to the core of the form
+  driver logic. This is especially true in the case of growable fields.
+  So I don't separate this into an own module. 
   --------------------------------------------------------------------------*/
 
 /*---------------------------------------------------------------------------
@@ -3959,7 +3755,9 @@ int form_page(const FORM * form)
 |                    E_BAD_ARGUMENT  - invalid argument
 |                    E_SYSTEM_ERROR  - system error
 +--------------------------------------------------------------------------*/
-int set_field_buffer(FIELD * field, int buffer, const char * value)
+NCURSES_EXPORT(int)
+set_field_buffer
+(FIELD * field, int buffer, const char * value)
 {
   char *s, *p;
   int res = E_OK;
@@ -3994,14 +3792,14 @@ int set_field_buffer(FIELD * field, int buffer, const char * value)
                           (int)(1 + (vlen-len)/((field->rows+field->nrow)*field->cols))))
            RETURN(E_SYSTEM_ERROR);
 
-         /* in this case we also have to check, wether or not the remaining
+         /* in this case we also have to check, whether or not the remaining
             characters in value are also printable for buffer 0. */
          if (buffer==0)
            {
              unsigned int i;
          
              for(i=len; i<vlen; i++)
-               if (!isprint(value[i]))
+               if (!isprint((unsigned char)value[i]))
                  RETURN(E_BAD_ARGUMENT);
            }
          len = vlen;
@@ -4011,19 +3809,24 @@ int set_field_buffer(FIELD * field, int buffer, const char * value)
   p   = Address_Of_Nth_Buffer(field,buffer);
 
 #if HAVE_MEMCCPY
-  s = memccpy(p,value,0,len);
+  s = (char *) memccpy(p, value, 0, len);
 #else
   for(s=(char *)value; *s && (s < (value+len)); s++)
     p[s-value] = *s;
   if (s < (value+len))
-    p[s-value] = *s++; 
+    {
+      p[s-value] = *s++;
+      s = p + (s-value);
+    }
   else 
     s=(char *)0;
 #endif
 
   if (s) 
     { /* this means, value was null terminated and not greater than the
-        buffer. We have to pad with blanks */
+        buffer. We have to pad with blanks. Please note that due to memccpy
+        logic s points after the terminating null. */
+      s--; /* now we point to the terminator. */
       assert(len >= (unsigned int)(s-p));
       if (len > (unsigned int)(s-p))
        memset(s,C_BLANK,len-(unsigned int)(s-p));
@@ -4050,258 +3853,13 @@ int set_field_buffer(FIELD * field, int buffer, const char * value)
 |
 |   Return Values :  Pointer to buffer or NULL if arguments were invalid.
 +--------------------------------------------------------------------------*/
-char *field_buffer(const FIELD * field, int  buffer)
+NCURSES_EXPORT(char *)
+field_buffer (const FIELD * field, int  buffer)
 {
   if (field && (buffer >= 0) && (buffer <= field->nbuf))
     return Address_Of_Nth_Buffer(field,buffer);
   else
     return (char *)0;
 }
-\f
-/*----------------------------------------------------------------------------
-  Field-Options manipulation routines
-  --------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------
-|   Facility      :  libnform  
-|   Function      :  int set_field_opts(FIELD *field, Field_Options opts)
-|   
-|   Description   :  Turns on the named options for this field and turns
-|                    off all the remaining options.
-|
-|   Return Values :  E_OK            - success
-|                    E_CURRENT       - the field is the current field
-|                    E_BAD_ARGUMENT  - invalid options
-|                    E_SYSTEM_ERROR  - system error
-+--------------------------------------------------------------------------*/
-int set_field_opts(FIELD * field, Field_Options opts)
-{
-  int res = E_BAD_ARGUMENT;
-  if (!(opts & ~ALL_FIELD_OPTS))
-    res = Synchronize_Options( Normalize_Field(field), opts );
-  RETURN(res);
-}
-
-/*---------------------------------------------------------------------------
-|   Facility      :  libnform  
-|   Function      :  Field_Options field_opts(const FIELD *field)
-|   
-|   Description   :  Retrieve the fields options.
-|
-|   Return Values :  The options.
-+--------------------------------------------------------------------------*/
-Field_Options field_opts(const FIELD * field)
-{
-  return ALL_FIELD_OPTS & Normalize_Field( field )->opts;
-}
-
-/*---------------------------------------------------------------------------
-|   Facility      :  libnform  
-|   Function      :  int field_opts_on(FIELD *field, Field_Options opts)
-|   
-|   Description   :  Turns on the named options for this field and all the 
-|                    remaining options are unchanged.
-|
-|   Return Values :  E_OK            - success
-|                    E_CURRENT       - the field is the current field
-|                    E_BAD_ARGUMENT  - invalid options
-|                    E_SYSTEM_ERROR  - system error
-+--------------------------------------------------------------------------*/
-int field_opts_on(FIELD * field, Field_Options opts)
-{
-  int res = E_BAD_ARGUMENT;
-
-  if (!(opts & ~ALL_FIELD_OPTS))
-    {
-      Normalize_Field( field );
-      res = Synchronize_Options( field, field->opts | opts );
-    }
-  RETURN(res);
-}
-
-/*---------------------------------------------------------------------------
-|   Facility      :  libnform  
-|   Function      :  int field_opts_off(FIELD *field, Field_Options opts)
-|   
-|   Description   :  Turns off the named options for this field and all the 
-|                    remaining options are unchanged.
-|
-|   Return Values :  E_OK            - success
-|                    E_CURRENT       - the field is the current field
-|                    E_BAD_ARGUMENT  - invalid options
-|                    E_SYSTEM_ERROR  - system error
-+--------------------------------------------------------------------------*/
-int field_opts_off(FIELD  * field, Field_Options opts)
-{
-  int res = E_BAD_ARGUMENT;
-
-  if (!(opts & ~ALL_FIELD_OPTS))
-    {
-      Normalize_Field( field );
-      res = Synchronize_Options( field, field->opts & ~opts );
-    }
-  RETURN(res);
-}      
-\f
-/*----------------------------------------------------------------------------
-  Field-Attribute manipulation routines
-  --------------------------------------------------------------------------*/
-/* "Template" macro to generate a function to set a fields attribute */
-#define GEN_FIELD_ATTR_SET_FCT( name ) \
-int set_field_ ## name (FIELD * field, chtype attr)\
-{\
-   int res = E_BAD_ARGUMENT;\
-   if ( attr==A_NORMAL || ((attr & A_ATTRIBUTES)==attr) )\
-     {\
-       Normalize_Field( field );\
-       if ((field -> name) != attr)\
-         {\
-           field -> name = attr;\
-           res = Synchronize_Attributes( field );\
-         }\
-       else\
-        res = E_OK;\
-     }\
-   RETURN(res);\
-}
-
-/* "Template" macro to generate a function to get a fields attribute */
-#define GEN_FIELD_ATTR_GET_FCT( name ) \
-chtype field_ ## name (const FIELD * field)\
-{\
-   return ( A_ATTRIBUTES & (Normalize_Field( field ) -> name) );\
-}
-
-/*---------------------------------------------------------------------------
-|   Facility      :  libnform  
-|   Function      :  int set_field_fore(FIELD *field, chtype attr)
-|   
-|   Description   :  Sets the foreground of the field used to display the
-|                    field contents.
-|
-|   Return Values :  E_OK             - success
-|                    E_BAD_ARGUMENT   - invalid attributes
-|                    E_SYSTEM_ERROR   - system error
-+--------------------------------------------------------------------------*/
-GEN_FIELD_ATTR_SET_FCT( fore )
-
-/*---------------------------------------------------------------------------
-|   Facility      :  libnform  
-|   Function      :  chtype field_fore(const FIELD *)
-|   
-|   Description   :  Retrieve fields foreground attribute
-|
-|   Return Values :  The foreground attribute
-+--------------------------------------------------------------------------*/
-GEN_FIELD_ATTR_GET_FCT( fore )
-
-/*---------------------------------------------------------------------------
-|   Facility      :  libnform  
-|   Function      :  int set_field_back(FIELD *field, chtype attr)
-|   
-|   Description   :  Sets the background of the field used to display the
-|                    fields extend.
-|
-|   Return Values :  E_OK             - success
-|                    E_BAD_ARGUMENT   - invalid attributes
-|                    E_SYSTEM_ERROR   - system error
-+--------------------------------------------------------------------------*/
-GEN_FIELD_ATTR_SET_FCT( back )
-
-/*---------------------------------------------------------------------------
-|   Facility      :  libnform
-|   Function      :  chtype field_back(const 
-|   
-|   Description   :  Retrieve fields background attribute
-|
-|   Return Values :  The background attribute
-+--------------------------------------------------------------------------*/
-GEN_FIELD_ATTR_GET_FCT( back )
-
-/*---------------------------------------------------------------------------
-|   Facility      :  libnform  
-|   Function      :  int set_field_pad(FIELD *field, int ch)
-|   
-|   Description   :  Set the pad character used to fill the field. This must
-|                    be a printable character.
-|
-|   Return Values :  E_OK           - success
-|                    E_BAD_ARGUMENT - invalid field pointer or pad character
-|                    E_SYSTEM_ERROR - system error
-+--------------------------------------------------------------------------*/
-int set_field_pad(FIELD  * field, int ch)
-{
-  int res = E_BAD_ARGUMENT;
-
-  Normalize_Field( field );
-  if (isprint((unsigned char)ch))
-    {
-      if (field->pad != ch)
-       {
-         field->pad = ch;
-         res = Synchronize_Attributes( field );
-       }
-      else
-       res = E_OK;
-    }
-  RETURN(res);
-}
-
-/*---------------------------------------------------------------------------
-|   Facility      :  libnform  
-|   Function      :  int field_pad(const FIELD *field)
-|   
-|   Description   :  Retrieve the fields pad character.
-|
-|   Return Values :  The pad character.
-+--------------------------------------------------------------------------*/
-int field_pad(const FIELD * field)
-{
-  return Normalize_Field( field )->pad;
-}
-\f
-/*---------------------------------------------------------------------------
-|   Facility      :  libnform  
-|   Function      :  int set_field_just(FIELD *field, int just)
-|   
-|   Description   :  Set the fields type of justification.
-|
-|   Return Values :  E_OK            - success
-|                    E_BAD_ARGUMENT  - one of the arguments was incorrect
-|                    E_SYSTEM_ERROR  - system error
-+--------------------------------------------------------------------------*/
-int set_field_just(FIELD * field, int just)
-{
-  int res = E_BAD_ARGUMENT;
-
-  if ((just==NO_JUSTIFICATION)  ||
-      (just==JUSTIFY_LEFT)     ||
-      (just==JUSTIFY_CENTER)   ||
-      (just==JUSTIFY_RIGHT)    )
-    {
-      Normalize_Field( field );
-      if (field->just != just)
-       {
-         field->just = just;
-         res = Synchronize_Attributes( field );
-       }
-      else
-       res = E_OK;
-    }
-  RETURN(res);
-}
-
-/*---------------------------------------------------------------------------
-|   Facility      :  libnform  
-|   Function      :  int field_just( const FIELD *field )
-|   
-|   Description   :  Retrieve the fields type of justification
-|
-|   Return Values :  The justification type.
-+--------------------------------------------------------------------------*/
-int field_just(const FIELD * field)
-{
-  return Normalize_Field( field )->just;
-}
 
 /* frm_driver.c ends here */