diff --git a/c++/Makefile.in b/c++/Makefile.in
new file mode 100644
index 0000000..96d5879
--- /dev/null
+++ b/c++/Makefile.in
@@ -0,0 +1,239 @@
+# $Id: Makefile.in,v 1.84 2007/04/28 15:29:12 tom Exp $
+##############################################################################
+# Copyright (c) 1998-2006,2007 Free Software Foundation, Inc.                #
+#                                                                            #
+# Permission is hereby granted, free of charge, to any person obtaining a    #
+# copy of this software and associated documentation files (the "Software"), #
+# to deal in the Software without restriction, including without limitation  #
+# the rights to use, copy, modify, merge, publish, distribute, distribute    #
+# with modifications, sublicense, and/or sell copies of the Software, and to #
+# permit persons to whom the Software is furnished to do so, subject to the  #
+# following conditions:                                                      #
+#                                                                            #
+# The above copyright notice and this permission notice shall be included in #
+# all copies or substantial portions of the Software.                        #
+#                                                                            #
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR #
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   #
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    #
+# THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER      #
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING    #
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER        #
+# DEALINGS IN THE SOFTWARE.                                                  #
+#                                                                            #
+# Except as contained in this notice, the name(s) of the above copyright     #
+# holders shall not be used in advertising or otherwise to promote the sale, #
+# use or other dealings in this Software without prior written               #
+# authorization.                                                             #
+##############################################################################
+#
+# Author: Thomas E. Dickey
+#
+#  Simple makefile for c++ window class demo
+
+# turn off _all_ suffix rules; we'll generate our own
+.SUFFIXES:
+
+SHELL		= /bin/sh
+
+CF_MFLAGS 	= @cf_cv_makeflags@
+@SET_MAKE@
+x		= @EXEEXT@
+o		= .@OBJEXT@
+
+MODEL		= ../@DFT_OBJ_SUBDIR@
+DESTDIR		= @DESTDIR@
+srcdir		= @srcdir@
+prefix		= @prefix@
+exec_prefix	= @exec_prefix@
+libdir		= @libdir@
+includedir	= @includedir@
+
+LIBTOOL		= @LIBTOOL_CXX@
+LIBTOOL_CLEAN	= @LIB_CLEAN@
+LIBTOOL_COMPILE	= @LIB_COMPILE@
+LIBTOOL_LINK	= @LIB_LINK@
+LIBTOOL_INSTALL	= @LIB_INSTALL@
+LIBTOOL_UNINSTALL = @LIB_UNINSTALL@
+
+INSTALL		= @INSTALL@
+INSTALL_LIB	= @INSTALL@ @INSTALL_LIB@
+INSTALL_DATA	= @INSTALL_DATA@
+
+AR		= @AR@
+AR_OPTS		= @AR_OPTS@
+
+CXX_AR		= @CXX_AR@
+CXX_AR_OPTS	= @CXX_AR_OPTS@
+RANLIB		= @LIB_PREP@
+
+CXX		= @CXX@
+CPP		= @CXXCPP@
+CXXFLAGS	= @CXXFLAGS@ @EXTRA_CXXFLAGS@
+CXXLIBS		= @CXXLIBS@
+
+INCDIR		= ../include
+CPPFLAGS	= -I../c++ -I$(INCDIR) -I$(srcdir) -DHAVE_CONFIG_H @CPPFLAGS@
+
+CC		= ${CXX}
+CCFLAGS		= $(CPPFLAGS) $(CXXFLAGS)
+
+CFLAGS_LIBTOOL	= $(CCFLAGS)
+CFLAGS_NORMAL	= $(CCFLAGS)
+CFLAGS_DEBUG	= $(CCFLAGS) @CXX_G_OPT@ -DTRACE
+CFLAGS_PROFILE	= $(CCFLAGS) -pg
+CFLAGS_SHARED	= $(CCFLAGS) @CC_SHARED_OPTS@
+
+CFLAGS_DEFAULT	= $(CFLAGS_@DFT_UPR_MODEL@)
+
+NCURSES_MAJOR	= @NCURSES_MAJOR@
+NCURSES_MINOR	= @NCURSES_MINOR@
+REL_VERSION     = @cf_cv_rel_version@
+ABI_VERSION	= @cf_cv_abi_version@
+
+LOCAL_LIBDIR	= @top_builddir@/lib
+
+LINK		= @LINK_PROGS@ $(LIBTOOL_LINK) @CXXLDFLAGS@
+SHLIB_DIRS	= -L../lib
+SHLIB_LIST	= $(SHLIB_DIRS) -lncurses@LIB_SUFFIX@ @SHLIB_LIST@
+
+LIBROOT		= ncurses++
+
+LIBNAME_LIBTOOL	= @LIB_PREFIX@$(LIBROOT)@LIB_SUFFIX@.la
+LIBNAME_NORMAL	= @LIB_PREFIX@$(LIBROOT)@LIB_SUFFIX@.a
+LIBNAME		= @LIB_PREFIX@$(LIBROOT)@CXX_LIB_SUFFIX@
+
+LINK_FLAGS	= @EXTRA_LDFLAGS@ -L../lib -l$(LIBROOT)@LIB_SUFFIX@
+
+LINK_LIBTOOL	= @EXTRA_LDFLAGS@ -L../lib ../lib/$(LIBNAME)
+LINK_NORMAL	= $(LINK_FLAGS)
+LINK_DEBUG	= $(LINK_FLAGS)
+LINK_PROFILE	= $(LINK_FLAGS)
+LINK_SHARED	= $(LINK_FLAGS)
+
+TEST_ARGS	= @LDFLAGS_STATIC@ @TEST_ARGS@ @LDFLAGS_SHARED@ 
+
+LDFLAGS		= $(TEST_ARGS) @LDFLAGS@ \
+	@LD_MODEL@ @LIBS@ @LOCAL_LDFLAGS@ $(CXXLIBS)
+
+LDFLAGS_LIBTOOL	= $(LDFLAGS) $(CFLAGS_LIBTOOL)
+LDFLAGS_NORMAL	= $(LDFLAGS) $(CFLAGS_NORMAL)
+LDFLAGS_DEBUG	= $(LDFLAGS) $(CFLAGS_DEBUG)
+LDFLAGS_PROFILE	= $(LDFLAGS) $(CFLAGS_PROFILE)
+LDFLAGS_SHARED	= $(LDFLAGS) $(CFLAGS_SHARED) @LD_SHARED_OPTS@
+
+LDFLAGS_DEFAULT	= $(LINK_@DFT_UPR_MODEL@) $(LDFLAGS_@DFT_UPR_MODEL@)
+
+AUTO_SRC	= \
+		etip.h
+
+all \
+libs ::		$(AUTO_SRC) ../lib/$(LIBNAME)
+
+all ::		demo$x
+
+sources :	$(AUTO_SRC)
+
+depend :
+
+tags:
+	ctags *.[h] *.cc
+
+# Build a conventional library for installing, since a shared library would
+# pull in all of the ncurses libraries (panel, menu, form, ncurses) as direct
+# dependencies.
+LIB_OBJS = \
+	$(MODEL)/cursesf$o \
+	$(MODEL)/cursesm$o \
+	$(MODEL)/cursesw$o \
+	$(MODEL)/cursespad$o \
+	$(MODEL)/cursesp$o \
+	$(MODEL)/cursslk$o \
+	$(MODEL)/cursesapp$o \
+	$(MODEL)/cursesmain$o
+
+../lib/$(LIBNAME_NORMAL) : $(LIB_OBJS)
+	$(CXX_AR) $(CXX_AR_OPTS) $@ $?
+	$(RANLIB) $@
+
+../lib/$(LIBNAME_LIBTOOL) : $(LIB_OBJS)
+	cd ../lib && $(LIBTOOL_LINK) $(CXX) $(CXXFLAGS) \
+		-o $(LIBNAME) $(LIB_OBJS:$o=.lo) \
+		-rpath $(INSTALL_PREFIX)$(libdir) \
+		-version-info $(NCURSES_MAJOR):$(NCURSES_MINOR) $(SHLIB_LIST)
+
+OBJS_DEMO = $(MODEL)/demo$o
+
+$(MODEL)/demo$o : $(srcdir)/demo.cc \
+	$(cursesf_h) $(cursesm_h) $(cursesapp_h)
+
+demo$x:	$(OBJS_DEMO) \
+	../lib/$(LIBNAME)  \
+	@TEST_DEPS@
+	@ECHO_LINK@ $(LINK) -o $@ $(OBJS_DEMO) $(LDFLAGS_DEFAULT)
+
+etip.h:	$(srcdir)/etip.h.in $(srcdir)/edit_cfg.sh
+	cp $(srcdir)/etip.h.in $@
+	sh $(srcdir)/edit_cfg.sh ../include/ncurses_cfg.h $@
+
+$(DESTDIR)$(libdir) :
+	sh $(srcdir)/../mkdirs.sh $@
+
+install \
+install.libs:: ../lib/$(LIBNAME) $(DESTDIR)$(libdir)
+	$(LIBTOOL_INSTALL) $(INSTALL_LIB) ../lib/$(LIBNAME) $(DESTDIR)$(libdir)/$(LIBNAME)
+
+uninstall \
+uninstall.libs::
+	-$(LIBTOOL_UNINSTALL) rm -f $(DESTDIR)$(libdir)/$(LIBNAME)
+
+mostlyclean ::
+	-rm -f core tags TAGS *~ *.bak *.i *.ii *.ln *.atac trace
+
+clean :: mostlyclean
+	-sh -c "if test -n '$x' ; then $(MAKE) clean x=''; fi"
+	-rm -rf $(MODEL)/SunWS_cache
+	-$(LIBTOOL_CLEAN) rm -f demo$x $(AUTO_SRC) ../lib/$(LIBNAME) $(LIB_OBJS) $(OBJS_DEMO)
+	-rm -rf .libs
+
+distclean :: clean
+	-rm -f Makefile
+
+realclean :: distclean
+
+###############################################################################
+
+cursesw_h	= $(srcdir)/cursesw.h \
+		  etip.h \
+		  $(INCDIR)/curses.h
+
+cursesp_h	= $(srcdir)/cursesp.h \
+		  $(cursesw_h) \
+		  $(INCDIR)/panel.h
+
+cursesf_h	= $(srcdir)/cursesf.h \
+		  $(cursesp_h) \
+		  $(INCDIR)/form.h
+
+cursesm_h	= $(srcdir)/cursesm.h \
+		  $(cursesp_h) \
+		  $(INCDIR)/menu.h
+
+cursslk_h	= $(srcdir)/cursslk.h \
+		  $(cursesw_h)
+
+cursesapp_h	= $(srcdir)/cursesapp.h \
+		  $(cursslk_h)
+
+$(INCDIR)/form.h :
+	cd ../form && $(MAKE) $@
+
+$(INCDIR)/menu.h :
+	cd ../menu && $(MAKE) $@
+
+$(INCDIR)/panel.h :
+	cd ../panel && $(MAKE) $@
+
+###############################################################################
+# The remainder of this file is automatically generated during configuration
+###############################################################################
diff --git a/c++/NEWS b/c++/NEWS
new file mode 100644
index 0000000..17488a4
--- /dev/null
+++ b/c++/NEWS
@@ -0,0 +1,71 @@
+-------------------------------------------------------------------------------
+-- Copyright (c) 1998,2006 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.                                                            --
+-------------------------------------------------------------------------------
+-- $Id: NEWS,v 1.4 2006/04/22 22:19:37 tom Exp $
+-------------------------------------------------------------------------------
+This is a log of changes that the ncurses C++ binding has gone
+through starting with the integration of menu and forms integration
+into the binding.
+
+990731  + Improve support for pads. A viewport window may now be added to
+          a pad. It will then be possible to use a builtin panning mechanism
+          to view the pad.
+
+970908	+ Improve NCursesWindow class: added additional methods to
+	  cover more ncurses functionality. Make refresh() and 
+	  noutrefresh() virtual members to allow different implementation
+	  in the NCursesPanel class.
+	+ CAUTION: changed order of parameters in vline() and hline() of
+	  NCursesWindow class.
+	+ Make refresh() in NCursesPanel non-static, it is now a
+	  reimplementation  of refresh() in the base class. Added 
+	  noutrefresh() to NCursesPanel.
+	+ Added NCursesForm and related classes to support libform
+	  functionality.
+	+ Moved most of configuration related stuff from cursesw.h to
+	  etip.h
+	+ Added NCursesApplication class to support easy configuration 
+	  of menu and forms related attributes as well as ripped of
+	  title lines and Soft-Label-Keys for an application.
+	+ Support of Auto-Cleanup for a menus fieldlist.
+	+ Change of return type for current_item() and operator[] for
+	  menus.
+	+ Enhanced demo.
+970502
+	+ Introduced the THROW and THROWS functions/macros to prepare
+	  a smoother transition to real exception handling.
+	+ Exception classes provided in etip.h
+	+ Added the NCursesMenu class to support libmenu functionality.
+	+ The inheritace relation between NCursesWindow and NCursesColorWindow
+	  was kind of brain damage. Monochrome is a special case of colored, so
+	  the relation should be just the opposite. This would allow all 
+	  derived classes like NCursesPanel, NCursesMenu or NCursesForm to 
+	  have colors.
+	  To resolve that design flaw I put the color functionality into the 
+	  NCursesWindow class and it can be switched on by the static member
+	  useColors(). NCursesColorWindow is still there for compatibility
+	  reasons.
diff --git a/c++/PROBLEMS b/c++/PROBLEMS
new file mode 100644
index 0000000..7f2a7df
--- /dev/null
+++ b/c++/PROBLEMS
@@ -0,0 +1,34 @@
+-------------------------------------------------------------------------------
+-- Copyright (c) 1998,2006 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.                                                            --
+-------------------------------------------------------------------------------
+-- $Id: PROBLEMS,v 1.3 2006/04/22 22:19:37 tom Exp $
+-------------------------------------------------------------------------------
+This is a list of open problems. This mainly lists known missing pieces
+and design flaws.
+
+1. Testing!!!
+2. Better demo program
diff --git a/c++/README-first b/c++/README-first
new file mode 100644
index 0000000..42487f5
--- /dev/null
+++ b/c++/README-first
@@ -0,0 +1,80 @@
+-------------------------------------------------------------------------------
+-- Copyright (c) 1998-2006,2007 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.                                                            --
+-------------------------------------------------------------------------------
+-- $Id: README-first,v 1.9 2007/01/27 18:27:09 tom Exp $
+-------------------------------------------------------------------------------
+                  C++ interface to ncurses routines
+-----------------------------------------------------------------------
+
+This directory contains the source code for several C++ classes which
+ease the use of writing ncurses-based programs.  The code was originally
+derived from the libg++ CursesWindow class, but rewritten for ncurses.
+
+The classes simplify the use of window specific functions by
+encapsulating them in the window object.  Function overloading is
+used in order to narrow the interface.  For example, you do not have the
+distinction between `printw' and `mvprintw' anymore.
+
+A second benefit is the removal of all #defines which are included in
+the curses.h file.  This is a steady cause of trouble because many
+common identifiers are used.  Instead now all #defines are inline
+functions, which also allows strict type checking of arguments.
+
+The next enhancement is color support. It was originally provided by a 
+derived class.  This caused some trouble if you think about Panels or
+Menus and Forms with colors.  We decided to put color support into the
+base class so that any derived class may use color support also.
+The implementation chosen here is directed to unrestricted use
+of mixes of color and monochrome windows.  The original NCursesColorWindow
+class is maintained for compatibility reasons.
+
+The last point to mention is the support of other packages that are
+distributed with the ncurses package:  the panels library, the menu library
+and the form library.  This support is provided by the NCursesPanel class,
+which is also derived from the NCursesWindow class and the NCursesMenu
+and NCursesForm classes which are derived from NCursesPanel.  This allows
+building interfaces with windows.
+
+Please see the example program for a quick introduction.
+
+Note that at this point, there is no documentation for these classes.
+Hopefully some will be written in the not too distant future.  For now,
+to find out how to use the classes, read the code and the example program.
+
+Suggestions for enhancements and contributions of code (and docs) are
+welcome.  Please let us know which functionality you miss.
+
+Original author:
+     Eric Newton         <newton@rocky.oswego.edu> for FSF's libg++
+
+Authors of first ncurses based release (NCursesWindow, NCursesPanel):
+     Ulrich Drepper      <drepper@ira.uka.de>
+ and Anatoly Ivasyuk     <anatoly@nick.csh.rit.edu>
+
+Authors of this release:
+     Juergen Pfeifer
+     Thomas E. Dickey
diff --git a/c++/cursesapp.cc b/c++/cursesapp.cc
new file mode 100644
index 0000000..ddab6fd
--- /dev/null
+++ b/c++/cursesapp.cc
@@ -0,0 +1,164 @@
+// * this is for making emacs happy: -*-Mode: C++;-*-
+/****************************************************************************
+ * Copyright (c) 1998-2007,2008 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, 1997                                          *
+ *      and: Thomas E. Dickey                                               *
+ ****************************************************************************/
+
+#include "internal.h"
+#include "cursesapp.h"
+
+MODULE_ID("$Id: cursesapp.cc,v 1.15 2008/08/16 17:15:35 tom Exp $")
+
+void
+NCursesApplication::init(bool bColors)
+{
+  if (bColors)
+    NCursesWindow::useColors();
+
+  if (Root_Window->colors() > 1) {
+    b_Colors = TRUE;
+    Root_Window->setcolor(1);
+    Root_Window->setpalette(COLOR_YELLOW,COLOR_BLUE);
+    Root_Window->setcolor(2);
+    Root_Window->setpalette(COLOR_CYAN,COLOR_BLUE);
+    Root_Window->setcolor(3);
+    Root_Window->setpalette(COLOR_BLACK,COLOR_BLUE);
+    Root_Window->setcolor(4);
+    Root_Window->setpalette(COLOR_BLACK,COLOR_CYAN);
+    Root_Window->setcolor(5);
+    Root_Window->setpalette(COLOR_BLUE,COLOR_YELLOW);
+    Root_Window->setcolor(6);
+    Root_Window->setpalette(COLOR_BLACK,COLOR_GREEN);
+  }
+  else
+    b_Colors = FALSE;
+
+  Root_Window->bkgd(' '|window_backgrounds());
+}
+
+NCursesApplication* NCursesApplication::theApp = 0;
+NCursesWindow* NCursesApplication::titleWindow = 0;
+NCursesApplication::SLK_Link* NCursesApplication::slk_stack = 0;
+
+NCursesApplication::~NCursesApplication()
+{
+  Soft_Label_Key_Set* S;
+
+  delete titleWindow;
+  titleWindow = 0;
+
+  while( (S=top()) ) {
+    pop();
+    delete S;
+  }
+
+  delete Root_Window;
+  Root_Window = 0;
+
+  ::endwin();
+}
+
+int NCursesApplication::rinit(NCursesWindow& w)
+{
+  titleWindow = &w;
+  return OK;
+}
+
+void NCursesApplication::push(Soft_Label_Key_Set& S)
+{
+  SLK_Link* L = new SLK_Link;
+  assert(L != 0);
+  L->prev = slk_stack;
+  L->SLKs = &S;
+  slk_stack = L;
+  if (Root_Window)
+    S.show();
+}
+
+bool NCursesApplication::pop()
+{
+  if (slk_stack) {
+    SLK_Link* L = slk_stack;
+    slk_stack = slk_stack->prev;
+    delete L;
+    if (Root_Window) {
+      Soft_Label_Key_Set* xx = top();
+      if (xx != 0)
+        xx->show();
+    }
+  }
+  return (slk_stack ? FALSE : TRUE);
+}
+
+Soft_Label_Key_Set* NCursesApplication::top() const
+{
+  if (slk_stack)
+    return slk_stack->SLKs;
+  else
+    return static_cast<Soft_Label_Key_Set*>(0);
+}
+
+int NCursesApplication::operator()(void)
+{
+  bool bColors = b_Colors;
+  Soft_Label_Key_Set* S = 0;
+
+  int ts = titlesize();
+  if (ts>0)
+    NCursesWindow::ripoffline(ts,rinit);
+  Soft_Label_Key_Set::Label_Layout fmt = useSLKs();
+  if (fmt!=Soft_Label_Key_Set::None) {
+    S = new Soft_Label_Key_Set(fmt);
+    assert(S != 0);
+    init_labels(*S);
+  }
+
+  Root_Window = new NCursesWindow(::stdscr);
+  init(bColors);
+
+  if (ts>0)
+    title();
+  if (fmt!=Soft_Label_Key_Set::None) {
+    push(*S);
+  }
+
+  return run();
+}
+
+NCursesApplication::NCursesApplication(bool bColors)
+  : b_Colors(bColors),
+    Root_Window(NULL)
+{
+  if (theApp)
+    THROW(new NCursesException("Application object already created."));
+  else
+    theApp = this;
+}
diff --git a/c++/cursesapp.h b/c++/cursesapp.h
new file mode 100644
index 0000000..7e995d2
--- /dev/null
+++ b/c++/cursesapp.h
@@ -0,0 +1,176 @@
+// * This makes emacs happy -*-Mode: C++;-*-
+/****************************************************************************
+ * Copyright (c) 1998-2003,2005 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, 1997                                          *
+ ****************************************************************************/
+
+// $Id: cursesapp.h,v 1.11 2005/05/28 21:57:44 tom Exp $
+
+#ifndef NCURSES_CURSESAPP_H_incl
+#define NCURSES_CURSESAPP_H_incl
+
+#include <cursslk.h>
+
+class NCURSES_IMPEXP NCursesApplication {
+public:
+  typedef struct _slk_link {          // This structure is used to maintain
+    struct _slk_link* prev;           // a stack of SLKs
+    Soft_Label_Key_Set* SLKs;
+  } SLK_Link;
+private:
+  static int rinit(NCursesWindow& w); // Internal Init function for title
+  static NCursesApplication* theApp;  // Global ref. to the application
+
+  static SLK_Link* slk_stack;
+
+protected:
+  static NCursesWindow* titleWindow;  // The Title Window (if any)
+
+  bool b_Colors;                      // Is this a color application?
+  NCursesWindow* Root_Window;         // This is the stdscr equiv.
+
+  // Initialization of attributes;
+  // Rewrite this in your derived class if you prefer other settings
+  virtual void init(bool bColors);
+
+  // The number of lines for the title window. Default is no title window
+  // You may rewrite this in your derived class
+  virtual int titlesize() const {
+    return 0;
+  }
+
+  // This method is called to put something into the title window initially
+  // You may rewrite this in your derived class
+  virtual void title() {
+  }
+
+  // The layout used for the Soft Label Keys. Default is to have no SLKs.
+  // You may rewrite this in your derived class
+  virtual Soft_Label_Key_Set::Label_Layout useSLKs() const {
+    return Soft_Label_Key_Set::None;
+  }
+
+  // This method is called to initialize the SLKs. Default is nothing.
+  // You may rewrite this in your derived class
+  virtual void init_labels(Soft_Label_Key_Set& S) const {
+  }
+
+  // Your derived class must implement this method. The return value must
+  // be the exit value of your application.
+  virtual int run() = 0;
+
+  // The constructor is protected, so you may use it in your derived
+  // class constructor. The argument tells whether or not you want colors.
+  NCursesApplication(bool wantColors = FALSE);
+
+  NCursesApplication& operator=(const NCursesApplication& rhs)
+  {
+    if (this != &rhs) {
+      *this = rhs;
+    }
+    return *this;
+  }
+
+  NCursesApplication(const NCursesApplication& rhs)
+    : b_Colors(rhs.b_Colors),
+      Root_Window(rhs.Root_Window)
+  {
+  }
+
+public:
+  virtual ~NCursesApplication();
+
+  // Get a pointer to the current application object
+  static NCursesApplication* getApplication() {
+    return theApp;
+  }
+
+  // This method runs the application and returns its exit value
+  int operator()(void);
+
+  // Process the commandline arguments. The default implementation simply
+  // ignores them. Your derived class may rewrite this.
+  virtual void handleArgs(int argc, char* argv[]) {
+  }
+
+  // Does this application use colors?
+  inline bool useColors() const {
+    return b_Colors;
+  }
+
+  // Push the Key Set S onto the SLK Stack. S then becomes the current set
+  // of Soft Labelled Keys.
+  void push(Soft_Label_Key_Set& S);
+
+  // Throw away the current set of SLKs and make the previous one the
+  // new current set.
+  bool pop();
+
+  // Retrieve the current set of Soft Labelled Keys.
+  Soft_Label_Key_Set* top() const;
+
+  // Attributes to use for menu and forms foregrounds
+  virtual chtype foregrounds() const {
+    return b_Colors ? COLOR_PAIR(1) : A_BOLD;
+  }
+
+  // Attributes to use for menu and forms backgrounds
+  virtual chtype backgrounds() const {
+    return b_Colors ? COLOR_PAIR(2) : A_NORMAL;
+  }
+
+  // Attributes to use for inactive (menu) elements
+  virtual chtype inactives() const {
+    return b_Colors ? (COLOR_PAIR(3)|A_DIM) : A_DIM;
+  }
+
+  // Attributes to use for (form) labels and SLKs
+  virtual chtype labels() const {
+    return b_Colors ? COLOR_PAIR(4) : A_NORMAL;
+  }
+
+  // Attributes to use for form backgrounds
+  virtual chtype dialog_backgrounds() const {
+    return b_Colors ? COLOR_PAIR(4) : A_NORMAL;
+  }
+
+  // Attributes to use as default for (form) window backgrounds
+  virtual chtype window_backgrounds() const {
+    return b_Colors ? COLOR_PAIR(5) : A_NORMAL;
+  }
+
+  // Attributes to use for the title window
+  virtual chtype screen_titles() const {
+    return b_Colors ? COLOR_PAIR(6) : A_BOLD;
+  }
+
+};
+ 
+#endif /* NCURSES_CURSESAPP_H_incl */
diff --git a/c++/cursesf.cc b/c++/cursesf.cc
new file mode 100644
index 0000000..aaf1202
--- /dev/null
+++ b/c++/cursesf.cc
@@ -0,0 +1,454 @@
+// * this is for making emacs happy: -*-Mode: C++;-*-
+/****************************************************************************
+ * Copyright (c) 1998-2003,2005 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, 1997                                          *
+ ****************************************************************************/
+
+#include "internal.h"
+#include "cursesf.h"
+#include "cursesapp.h"
+
+MODULE_ID("$Id: cursesf.cc,v 1.21 2005/08/13 18:09:06 tom Exp $")
+
+NCursesFormField::~NCursesFormField ()
+{
+  if (field)
+    OnError(::free_field (field));
+}
+
+/* Construct a FIELD* array from an array of NCursesFormField
+ * objects.
+ */
+FIELD**
+NCursesForm::mapFields(NCursesFormField* nfields[])
+{
+  int fieldCount = 0,lcv;
+  FIELD** old_fields;
+
+  assert(nfields != 0);
+
+  for (lcv=0; nfields[lcv]->field; ++lcv)
+    ++fieldCount;
+
+  FIELD** fields = new FIELD*[fieldCount + 1];
+
+  for (lcv=0;nfields[lcv]->field;++lcv) {
+    fields[lcv] = nfields[lcv]->field;
+  }
+  fields[lcv] = NULL;
+
+  my_fields = nfields;
+
+  if (form && (old_fields = ::form_fields(form))) {
+    ::set_form_fields(form, static_cast<FIELD**>(0));
+    delete[] old_fields;
+  }
+  return fields;
+}
+
+void NCursesForm::setDefaultAttributes()
+{
+  NCursesApplication* S = NCursesApplication::getApplication();
+
+  int n = count();
+  if (n > 0) {
+    for(int i=0; i<n; i++) {
+      NCursesFormField* f = (*this)[i];
+      if ((f->options() & (O_EDIT|O_ACTIVE))==(O_EDIT|O_ACTIVE)) {
+	if (S) {
+	  f->set_foreground(S->foregrounds());
+	  f->set_background(S->backgrounds());
+	}
+	f->set_pad_character('_');
+      }
+      else {
+	if (S)
+	  f->set_background(S->labels());
+      }
+    }
+  }
+
+  if (S) {
+    bkgd(' '|S->dialog_backgrounds());
+    if (sub)
+      sub->bkgd(' '|S->dialog_backgrounds());
+  }
+}
+
+void
+NCursesForm::InitForm(NCursesFormField* nfields[],
+		      bool with_frame,
+		      bool autoDelete_Fields)
+{
+  int mrows, mcols;
+
+  keypad(TRUE);
+  meta(TRUE);
+
+  b_framed = with_frame;
+  b_autoDelete = autoDelete_Fields;
+
+  form = static_cast<FORM*>(0);
+  form = ::new_form(mapFields(nfields));
+  if (!form)
+    OnError (E_SYSTEM_ERROR);
+
+  UserHook* hook = new UserHook;
+  hook->m_user   = NULL;
+  hook->m_back   = this;
+  hook->m_owner  = form;
+  ::set_form_userptr(form, reinterpret_cast<void*>(hook));
+
+  ::set_form_init  (form, _nc_xx_frm_init);
+  ::set_form_term  (form, _nc_xx_frm_term);
+  ::set_field_init (form, _nc_xx_fld_init);
+  ::set_field_term (form, _nc_xx_fld_term);
+
+  scale(mrows, mcols);
+  ::set_form_win(form, w);
+
+  if (with_frame) {
+    if ((mrows > height()-2) || (mcols > width()-2))
+      OnError(E_NO_ROOM);
+    sub = new NCursesWindow(*this,mrows,mcols,1,1,'r');
+    ::set_form_sub(form, sub->w);
+    b_sub_owner = TRUE;
+  }
+  else {
+    sub = static_cast<NCursesWindow*>(0);
+    b_sub_owner = FALSE;
+  }
+  options_on(O_NL_OVERLOAD);
+  setDefaultAttributes();
+}
+
+NCursesForm::~NCursesForm()
+{
+  UserHook* hook = reinterpret_cast<UserHook*>(::form_userptr(form));
+  delete hook;
+  if (b_sub_owner) {
+    delete sub;
+    ::set_form_sub(form, static_cast<WINDOW *>(0));
+  }
+  if (form) {
+    FIELD** fields = ::form_fields(form);
+    int cnt = count();
+
+    OnError(::set_form_fields(form, static_cast<FIELD**>(0)));
+
+    if (b_autoDelete) {
+      if (cnt>0) {
+	for (int i=0; i <= cnt; i++)
+	  delete my_fields[i];
+      }
+      delete[] my_fields;
+    }
+
+    ::free_form(form);
+    // It's essential to do this after free_form()
+    delete[] fields;
+  }
+}
+
+void
+NCursesForm::setSubWindow(NCursesWindow& nsub)
+{
+  if (!isDescendant(nsub))
+    OnError(E_SYSTEM_ERROR);
+  else {
+    if (b_sub_owner)
+      delete sub;
+    sub = &nsub;
+    ::set_form_sub(form,sub->w);
+  }
+}
+
+/* Internal hook functions. They will route the hook
+ * calls to virtual methods of the NCursesForm class,
+ * so in C++ providing a hook is done simply by
+ * implementing a virtual method in a derived class
+ */
+void
+_nc_xx_frm_init(FORM *f)
+{
+  NCursesForm::getHook(f)->On_Form_Init();
+}
+
+void
+_nc_xx_frm_term(FORM *f)
+{
+  NCursesForm::getHook(f)->On_Form_Termination();
+}
+
+void
+_nc_xx_fld_init(FORM *f)
+{
+  NCursesForm* F = NCursesForm::getHook(f);
+  F->On_Field_Init (*(F->current_field ()));
+}
+
+void
+_nc_xx_fld_term(FORM *f)
+{
+  NCursesForm* F = NCursesForm::getHook(f);
+  F->On_Field_Termination (*(F->current_field ()));
+}
+
+void
+NCursesForm::On_Form_Init()
+{
+}
+
+void
+NCursesForm::On_Form_Termination()
+{
+}
+
+void
+NCursesForm::On_Field_Init(NCursesFormField& field)
+{
+}
+
+void
+NCursesForm::On_Field_Termination(NCursesFormField& field)
+{
+}
+
+// call the form driver and do basic error checking.
+int
+NCursesForm::driver (int c)
+{
+  int res = ::form_driver (form, c);
+  switch (res) {
+  case E_OK:
+  case E_REQUEST_DENIED:
+  case E_INVALID_FIELD:
+  case E_UNKNOWN_COMMAND:
+    break;
+  default:
+    OnError (res);
+  }
+  return (res);
+}
+
+void NCursesForm::On_Request_Denied(int c) const
+{
+  ::beep();
+}
+
+void NCursesForm::On_Invalid_Field(int c) const
+{
+  ::beep();
+}
+
+void NCursesForm::On_Unknown_Command(int c) const
+{
+  ::beep();
+}
+
+static const int CMD_QUIT = MAX_COMMAND + 1;
+
+NCursesFormField*
+NCursesForm::operator()(void)
+{
+  int drvCmnd;
+  int err;
+  int c;
+
+  post();
+  show();
+  refresh();
+
+  while (((drvCmnd = virtualize((c=getKey()))) != CMD_QUIT)) {
+    switch((err=driver(drvCmnd))) {
+    case E_REQUEST_DENIED:
+      On_Request_Denied(c);
+      break;
+    case E_INVALID_FIELD:
+      On_Invalid_Field(c);
+      break;
+    case E_UNKNOWN_COMMAND:
+      On_Unknown_Command(c);
+      break;
+    case E_OK:
+      break;
+    default:
+      OnError(err);
+    }
+  }
+
+  unpost();
+  hide();
+  refresh();
+  return my_fields[::field_index (::current_field (form))];
+}
+
+// Provide a default key virtualization. Translate the keyboard
+// code c into a form request code.
+// The default implementation provides a hopefully straightforward
+// mapping for the most common keystrokes and form requests.
+int
+NCursesForm::virtualize(int c)
+{
+  switch(c) {
+
+  case KEY_HOME      : return(REQ_FIRST_FIELD);
+  case KEY_END       : return(REQ_LAST_FIELD);
+
+  case KEY_DOWN      : return(REQ_DOWN_CHAR);
+  case KEY_UP        : return(REQ_UP_CHAR);
+  case KEY_LEFT      : return(REQ_PREV_CHAR);
+  case KEY_RIGHT     : return(REQ_NEXT_CHAR);
+
+  case KEY_NPAGE     : return(REQ_NEXT_PAGE);
+  case KEY_PPAGE     : return(REQ_PREV_PAGE);
+
+  case KEY_BACKSPACE : return(REQ_DEL_PREV);
+  case KEY_ENTER     : return(REQ_NEW_LINE);
+  case KEY_CLEAR     : return(REQ_CLR_FIELD);
+
+  case CTRL('X')     : return(CMD_QUIT);        // eXit
+
+  case CTRL('F')     : return(REQ_NEXT_FIELD);  // Forward
+  case CTRL('B')     : return(REQ_PREV_FIELD);  // Backward
+  case CTRL('L')     : return(REQ_LEFT_FIELD);  // Left
+  case CTRL('R')     : return(REQ_RIGHT_FIELD); // Right
+  case CTRL('U')     : return(REQ_UP_FIELD);    // Up
+  case CTRL('D')     : return(REQ_DOWN_FIELD);  // Down
+
+  case CTRL('W')     : return(REQ_NEXT_WORD);
+  case CTRL('T')     : return(REQ_PREV_WORD);
+
+  case CTRL('A')     : return(REQ_BEG_FIELD);
+  case CTRL('E')     : return(REQ_END_FIELD);
+
+  case CTRL('I')     : return(REQ_INS_CHAR);
+  case CTRL('M')     :
+  case CTRL('J')     : return(REQ_NEW_LINE);
+  case CTRL('O')     : return(REQ_INS_LINE);
+  case CTRL('V')     : return(REQ_DEL_CHAR);
+  case CTRL('H')     : return(REQ_DEL_PREV);
+  case CTRL('Y')     : return(REQ_DEL_LINE);
+  case CTRL('G')     : return(REQ_DEL_WORD);
+  case CTRL('K')     : return(REQ_CLR_EOF);
+
+  case CTRL('N')     : return(REQ_NEXT_CHOICE);
+  case CTRL('P')     : return(REQ_PREV_CHOICE);
+
+  default:
+    return(c);
+  }
+}
+//
+// -------------------------------------------------------------------------
+// User Defined Fieldtypes
+// -------------------------------------------------------------------------
+//
+bool _nc_xx_fld_fcheck(FIELD *f, const void *u)
+{
+  NCursesFormField* F = reinterpret_cast<NCursesFormField*>(const_cast<void *>(u));
+  assert(F != 0);
+  UserDefinedFieldType* udf = reinterpret_cast<UserDefinedFieldType*>(F->fieldtype());
+  assert(udf != 0);
+  return udf->field_check(*F);
+}
+
+bool _nc_xx_fld_ccheck(int c, const void *u)
+{
+  NCursesFormField* F = reinterpret_cast<NCursesFormField*>(const_cast<void *>(u));
+  assert(F != 0);
+  UserDefinedFieldType* udf =
+    reinterpret_cast<UserDefinedFieldType*>(F->fieldtype());
+  assert(udf != 0);
+  return udf->char_check(c);
+}
+
+void* _nc_xx_fld_makearg(va_list* va)
+{
+  return va_arg(*va,NCursesFormField*);
+}
+
+FIELDTYPE* UserDefinedFieldType::generic_fieldtype =
+  ::new_fieldtype(_nc_xx_fld_fcheck,
+		  _nc_xx_fld_ccheck);
+
+FIELDTYPE* UserDefinedFieldType_With_Choice::generic_fieldtype_with_choice =
+  ::new_fieldtype(_nc_xx_fld_fcheck,
+		  _nc_xx_fld_ccheck);
+
+bool _nc_xx_next_choice(FIELD *f, const void *u)
+{
+  NCursesFormField* F = reinterpret_cast<NCursesFormField*>(const_cast<void *>(u));
+  assert(F != 0);
+  UserDefinedFieldType_With_Choice* udf =
+    reinterpret_cast<UserDefinedFieldType_With_Choice*>(F->fieldtype());
+  assert(udf != 0);
+  return udf->next(*F);
+}
+
+bool _nc_xx_prev_choice(FIELD *f, const void *u)
+{
+  NCursesFormField* F = reinterpret_cast<NCursesFormField*>(const_cast<void *>(u));
+  assert(F != 0);
+  UserDefinedFieldType_With_Choice* udf =
+    reinterpret_cast<UserDefinedFieldType_With_Choice*>(F->fieldtype());
+  assert(udf != 0);
+  return udf->previous(*F);
+}
+
+class UDF_Init
+{
+private:
+  int code;
+  static UDF_Init* I;
+
+public:
+  UDF_Init()
+    : code(0)
+  {
+    code = ::set_fieldtype_arg(UserDefinedFieldType::generic_fieldtype,
+			       _nc_xx_fld_makearg,
+			       NULL,
+			       NULL);
+    if (code==E_OK)
+      code = ::set_fieldtype_arg
+	(UserDefinedFieldType_With_Choice::generic_fieldtype_with_choice,
+	 _nc_xx_fld_makearg,
+	 NULL,
+	 NULL);
+    if (code==E_OK)
+      code = ::set_fieldtype_choice
+	(UserDefinedFieldType_With_Choice::generic_fieldtype_with_choice,
+	 _nc_xx_next_choice,
+	 _nc_xx_prev_choice);
+  }
+};
+
+UDF_Init* UDF_Init::I = new UDF_Init();
diff --git a/c++/cursesf.h b/c++/cursesf.h
new file mode 100644
index 0000000..70a30c3
--- /dev/null
+++ b/c++/cursesf.h
@@ -0,0 +1,967 @@
+// * This makes emacs happy -*-Mode: C++;-*-
+/****************************************************************************
+ * Copyright (c) 1998-2004,2005 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, 1997                                          *
+ ****************************************************************************/
+
+// $Id: cursesf.h,v 1.28 2005/08/13 18:08:24 tom Exp $
+
+#ifndef NCURSES_CURSESF_H_incl
+#define NCURSES_CURSESF_H_incl 1
+
+#include <cursesp.h>
+
+#ifndef __EXT_QNX
+#include <string.h>
+#endif
+
+extern "C" {
+#  include <form.h>
+}
+//
+// -------------------------------------------------------------------------
+// The abstract base class for buitin and user defined Fieldtypes.
+// -------------------------------------------------------------------------
+//
+class NCURSES_IMPEXP NCursesFormField; // forward declaration
+
+// Class to represent builtin field types as well as C++ written new
+// fieldtypes (see classes UserDefineFieldType...
+class NCURSES_IMPEXP NCursesFieldType
+{
+  friend class NCursesFormField;
+
+protected:
+  FIELDTYPE* fieldtype;
+
+  inline void OnError(int err) const THROWS(NCursesFormException) {
+    if (err!=E_OK)
+      THROW(new NCursesFormException (err));
+  }
+
+  NCursesFieldType(FIELDTYPE *f) : fieldtype(f) {
+  }
+
+  virtual ~NCursesFieldType() {}
+
+  // Set the fields f fieldtype to this one.
+  virtual void set(NCursesFormField& f) = 0;
+
+public:
+  NCursesFieldType()
+    : fieldtype(STATIC_CAST(FIELDTYPE*)(0))
+  {
+  }
+
+  NCursesFieldType& operator=(const NCursesFieldType& rhs)
+  {
+    if (this != &rhs) {
+      *this = rhs;
+    }
+    return *this;
+  }
+
+  NCursesFieldType(const NCursesFieldType& rhs)
+    : fieldtype(rhs.fieldtype)
+  {
+  }
+
+};
+
+//
+// -------------------------------------------------------------------------
+// The class representing a forms field, wrapping the lowlevel FIELD struct
+// -------------------------------------------------------------------------
+//
+class NCURSES_IMPEXP NCursesFormField
+{
+  friend class NCursesForm;
+
+protected:
+  FIELD *field;		     // lowlevel structure
+  NCursesFieldType* ftype;   // Associated field type
+
+  // Error handler
+  inline void OnError (int err) const THROWS(NCursesFormException) {
+    if (err != E_OK)
+      THROW(new NCursesFormException (err));
+  }
+
+public:
+  // Create a 'Null' field. Can be used to delimit a field list
+  NCursesFormField()
+    : field(STATIC_CAST(FIELD*)(0)),
+      ftype(STATIC_CAST(NCursesFieldType*)(0))
+  {
+  }
+
+  // Create a new field
+  NCursesFormField (int rows,
+		    int ncols,
+		    int first_row = 0,
+		    int first_col = 0,
+		    int offscreen_rows = 0,
+		    int additional_buffers = 0)
+    : field(0),
+      ftype(STATIC_CAST(NCursesFieldType*)(0))
+  {
+      field = ::new_field(rows, ncols, first_row, first_col,
+			  offscreen_rows, additional_buffers);
+      if (!field)
+	OnError(errno);
+  }
+
+  NCursesFormField& operator=(const NCursesFormField& rhs)
+  {
+    if (this != &rhs) {
+      *this = rhs;
+    }
+    return *this;
+  }
+
+  NCursesFormField(const NCursesFormField& rhs)
+    : field(rhs.field), ftype(rhs.ftype)
+  {
+  }
+
+  virtual ~NCursesFormField ();
+
+  // Duplicate the field at a new position
+  inline NCursesFormField* dup(int first_row, int first_col)
+  {
+    NCursesFormField* f = new NCursesFormField();
+    if (!f)
+      OnError(E_SYSTEM_ERROR);
+    else {
+      f->ftype = ftype;
+      f->field = ::dup_field(field,first_row,first_col);
+      if (!f->field)
+	OnError(errno);
+    }
+    return f;
+  }
+
+  // Link the field to a new location
+  inline NCursesFormField* link(int first_row, int first_col) {
+    NCursesFormField* f = new NCursesFormField();
+    if (!f)
+      OnError(E_SYSTEM_ERROR);
+    else {
+      f->ftype = ftype;
+      f->field = ::link_field(field,first_row,first_col);
+      if (!f->field)
+	OnError(errno);
+    }
+    return f;
+  }
+
+  // Get the lowlevel field representation
+  inline FIELD* get_field() const {
+    return field;
+  }
+
+  // Retrieve info about the field
+  inline void info(int& rows, int& ncols,
+		   int& first_row, int& first_col,
+		   int& offscreen_rows, int& additional_buffers) const {
+    OnError(::field_info(field, &rows, &ncols,
+			 &first_row, &first_col,
+			 &offscreen_rows, &additional_buffers));
+  }
+
+  // Retrieve info about the fields dynamic properties.
+  inline void dynamic_info(int& dynamic_rows, int& dynamic_cols,
+			   int& max_growth) const {
+    OnError(::dynamic_field_info(field, &dynamic_rows, &dynamic_cols,
+				 &max_growth));
+  }
+
+  // For a dynamic field you may set the maximum growth limit.
+  // A zero means unlimited growth.
+  inline void set_maximum_growth(int growth = 0) {
+    OnError(::set_max_field(field,growth));
+  }
+
+  // Move the field to a new position
+  inline void move(int row, int col) {
+    OnError(::move_field(field,row,col));
+  }
+
+  // Mark the field to start a new page
+  inline void new_page(bool pageFlag = FALSE) {
+    OnError(::set_new_page(field,pageFlag));
+  }
+
+  // Retrieve whether or not the field starts a new page.
+  inline bool is_new_page() const {
+    return ::new_page(field);
+  }
+
+  // Set the justification for the field
+  inline void set_justification(int just) {
+    OnError(::set_field_just(field,just));
+  }
+
+  // Retrieve the fields justification
+  inline int justification() const {
+    return ::field_just(field);
+  }
+  // Set the foreground attribute for the field
+  inline void set_foreground(chtype foreground) {
+    OnError(::set_field_fore(field,foreground));
+  }
+
+  // Retrieve the fields foreground attribute
+  inline chtype fore() const {
+    return ::field_fore(field);
+  }
+
+  // Set the background attribute for the field
+  inline void set_background(chtype background) {
+    OnError(::set_field_back(field,background));
+  }
+
+  // Retrieve the fields background attribute
+  inline chtype back() const {
+    return ::field_back(field);
+  }
+
+  // Set the padding character for the field
+  inline void set_pad_character(int padding) {
+    OnError(::set_field_pad(field, padding));
+  }
+
+  // Retrieve the fields padding character
+  inline int pad() const {
+    return ::field_pad(field);
+  }
+
+  // Switch on the fields options
+  inline void options_on (Field_Options opts) {
+    OnError (::field_opts_on (field, opts));
+  }
+
+  // Switch off the fields options
+  inline void options_off (Field_Options opts) {
+    OnError (::field_opts_off (field, opts));
+  }
+
+  // Retrieve the fields options
+  inline Field_Options options () const {
+    return ::field_opts (field);
+  }
+
+  // Set the fields options
+  inline void set_options (Field_Options opts) {
+    OnError (::set_field_opts (field, opts));
+  }
+
+  // Mark the field as changed
+  inline void set_changed(bool changeFlag = TRUE) {
+    OnError(::set_field_status(field,changeFlag));
+  }
+
+  // Test whether or not the field is marked as changed
+  inline bool changed() const {
+    return ::field_status(field);
+  }
+
+  // Return the index of the field in the field array of a form
+  // or -1 if the field is not associated to a form
+  inline int (index)() const {
+    return ::field_index(field);
+  }
+
+  // Store a value in a fields buffer. The default buffer is nr. 0
+  inline void set_value(const char *val, int buffer = 0) {
+    OnError(::set_field_buffer(field,buffer,val));
+  }
+
+  // Retrieve the value of a fields buffer. The default buffer is nr. 0
+  inline char* value(int buffer = 0) const {
+    return ::field_buffer(field,buffer);
+  }
+
+  // Set the validation type of the field.
+  inline void set_fieldtype(NCursesFieldType& f) {
+    ftype = &f;
+    f.set(*this); // A good friend may do that...
+  }
+
+  // Retrieve the validation type of the field.
+  inline NCursesFieldType* fieldtype() const {
+    return ftype;
+  }
+
+};
+
+  // This are the built-in hook functions in this C++ binding. In C++ we use
+  // virtual member functions (see below On_..._Init and On_..._Termination)
+  // to provide this functionality in an object oriented manner.
+extern "C" {
+  void _nc_xx_frm_init(FORM *);
+  void _nc_xx_frm_term(FORM *);
+  void _nc_xx_fld_init(FORM *);
+  void _nc_xx_fld_term(FORM *);
+}
+
+//
+// -------------------------------------------------------------------------
+// The class representing a form, wrapping the lowlevel FORM struct
+// -------------------------------------------------------------------------
+//
+class NCURSES_IMPEXP NCursesForm : public NCursesPanel
+{
+protected:
+  FORM* form;  // the lowlevel structure
+
+private:
+  NCursesWindow* sub;   // the subwindow object
+  bool b_sub_owner;     // is this our own subwindow?
+  bool b_framed;	// has the form a border?
+  bool b_autoDelete;    // Delete fields when deleting form?
+
+  NCursesFormField** my_fields; // The array of fields for this form
+
+  // This structure is used for the form's user data field to link the
+  // FORM* to the C++ object and to provide extra space for a user pointer.
+  typedef struct {
+    void*	       m_user;	    // the pointer for the user's data
+    const NCursesForm* m_back;      // backward pointer to C++ object
+    const FORM*	       m_owner;
+  } UserHook;
+
+  // Get the backward pointer to the C++ object from a FORM
+  static inline NCursesForm* getHook(const FORM *f) {
+    UserHook* hook = reinterpret_cast<UserHook*>(::form_userptr(f));
+    assert(hook != 0 && hook->m_owner==f);
+    return const_cast<NCursesForm*>(hook->m_back);
+  }
+
+  friend void _nc_xx_frm_init(FORM *);
+  friend void _nc_xx_frm_term(FORM *);
+  friend void _nc_xx_fld_init(FORM *);
+  friend void _nc_xx_fld_term(FORM *);
+
+  // Calculate FIELD* array for the menu
+  FIELD** mapFields(NCursesFormField* nfields[]);
+
+protected:
+  // internal routines
+  inline void set_user(void *user) {
+    UserHook* uptr = reinterpret_cast<UserHook*>(::form_userptr (form));
+    assert (uptr != 0 && uptr->m_back==this && uptr->m_owner==form);
+    uptr->m_user = user;
+  }
+
+  inline void *get_user() {
+    UserHook* uptr = reinterpret_cast<UserHook*>(::form_userptr (form));
+    assert (uptr != 0 && uptr->m_back==this && uptr->m_owner==form);
+    return uptr->m_user;
+  }
+
+  void InitForm (NCursesFormField* Fields[],
+		 bool with_frame,
+		 bool autoDeleteFields);
+
+  inline void OnError (int err) const THROWS(NCursesFormException) {
+    if (err != E_OK)
+      THROW(new NCursesFormException (err));
+  }
+
+  // this wraps the form_driver call.
+  virtual int driver (int c) ;
+
+  // 'Internal' constructor, builds an object without association to a
+  // field array.
+  NCursesForm( int  nlines,
+	       int  ncols,
+	       int  begin_y = 0,
+	       int  begin_x = 0)
+    : NCursesPanel(nlines, ncols, begin_y, begin_x),
+      form (STATIC_CAST(FORM*)(0)),
+      sub(0),
+      b_sub_owner(0),
+      b_framed(0),
+      b_autoDelete(0),
+      my_fields(0)
+  {
+  }
+
+public:
+  // Create form for the default panel.
+  NCursesForm (NCursesFormField* Fields[],
+	       bool with_frame=FALSE,	      // reserve space for a frame?
+	       bool autoDelete_Fields=FALSE)  // do automatic cleanup?
+    : NCursesPanel(),
+      form(0),
+      sub(0),
+      b_sub_owner(0),
+      b_framed(0),
+      b_autoDelete(0),
+      my_fields(0)
+  {
+    InitForm(Fields, with_frame, autoDelete_Fields);
+  }
+
+  // Create a form in a panel with the given position and size.
+  NCursesForm (NCursesFormField* Fields[],
+	       int  nlines,
+	       int  ncols,
+	       int  begin_y,
+	       int  begin_x,
+	       bool with_frame=FALSE,	     // reserve space for a frame?
+	       bool autoDelete_Fields=FALSE) // do automatic cleanup?
+    : NCursesPanel(nlines, ncols, begin_y, begin_x),
+      form(0),
+      sub(0),
+      b_sub_owner(0),
+      b_framed(0),
+      b_autoDelete(0),
+      my_fields(0)
+  {
+      InitForm(Fields, with_frame, autoDelete_Fields);
+  }
+
+  NCursesForm& operator=(const NCursesForm& rhs)
+  {
+    if (this != &rhs) {
+      *this = rhs;
+      NCursesPanel::operator=(rhs);
+    }
+    return *this;
+  }
+
+  NCursesForm(const NCursesForm& rhs)
+    : NCursesPanel(rhs),
+      form(rhs.form),
+      sub(rhs.sub),
+      b_sub_owner(rhs.b_sub_owner),
+      b_framed(rhs.b_framed),
+      b_autoDelete(rhs.b_autoDelete),
+      my_fields(rhs.my_fields)
+  {
+  }
+
+  virtual ~NCursesForm();
+
+  // Set the default attributes for the form
+  virtual void setDefaultAttributes();
+
+  // Retrieve current field of the form.
+  inline NCursesFormField* current_field() const {
+    return my_fields[::field_index(::current_field(form))];
+  }
+
+  // Set the forms subwindow
+  void setSubWindow(NCursesWindow& sub);
+
+  // Set these fields for the form
+  inline void setFields(NCursesFormField* Fields[]) {
+    OnError(::set_form_fields(form,mapFields(Fields)));
+  }
+
+  // Remove the form from the screen
+  inline void unpost (void) {
+    OnError (::unpost_form (form));
+  }
+
+  // Post the form to the screen if flag is true, unpost it otherwise
+  inline void post(bool flag = TRUE) {
+    OnError (flag ? ::post_form(form) : ::unpost_form (form));
+  }
+
+  // Decorations
+  inline void frame(const char *title=NULL, const char* btitle=NULL) {
+    if (b_framed)
+      NCursesPanel::frame(title,btitle);
+    else
+      OnError(E_SYSTEM_ERROR);
+  }
+
+  inline void boldframe(const char *title=NULL, const char* btitle=NULL) {
+    if (b_framed)
+      NCursesPanel::boldframe(title,btitle);
+    else
+      OnError(E_SYSTEM_ERROR);
+  }
+
+  inline void label(const char *topLabel, const char *bottomLabel) {
+    if (b_framed)
+      NCursesPanel::label(topLabel,bottomLabel);
+    else
+      OnError(E_SYSTEM_ERROR);
+  }
+
+  // -----
+  // Hooks
+  // -----
+
+  // Called after the form gets repositioned in its window.
+  // This is especially true if the form is posted.
+  virtual void On_Form_Init();
+
+  // Called before the form gets repositioned in its window.
+  // This is especially true if the form is unposted.
+  virtual void On_Form_Termination();
+
+  // Called after the field became the current field
+  virtual void On_Field_Init(NCursesFormField& field);
+
+  // Called before this field is left as current field.
+  virtual void On_Field_Termination(NCursesFormField& field);
+
+  // Calculate required window size for the form.
+  void scale(int& rows, int& ncols) const {
+    OnError(::scale_form(form,&rows,&ncols));
+  }
+
+  // Retrieve number of fields in the form.
+  int count() const {
+    return ::field_count(form);
+  }
+
+  // Make the page the current page of the form.
+  void set_page(int pageNum) {
+    OnError(::set_form_page(form, pageNum));
+  }
+
+  // Retrieve current page number
+  int page() const {
+    return ::form_page(form);
+  }
+
+  // Switch on the forms options
+  inline void options_on (Form_Options opts) {
+    OnError (::form_opts_on (form, opts));
+  }
+
+  // Switch off the forms options
+  inline void options_off (Form_Options opts) {
+    OnError (::form_opts_off (form, opts));
+  }
+
+  // Retrieve the forms options
+  inline Form_Options options () const {
+    return ::form_opts (form);
+  }
+
+  // Set the forms options
+  inline void set_options (Form_Options opts) {
+    OnError (::set_form_opts (form, opts));
+  }
+
+  // Are there more data in the current field after the data shown
+  inline bool data_ahead() const {
+    return ::data_ahead(form);
+  }
+
+  // Are there more data in the current field before the data shown
+  inline bool data_behind() const {
+    return ::data_behind(form);
+  }
+
+  // Position the cursor to the current field
+  inline void position_cursor () {
+    OnError (::pos_form_cursor (form));
+  }
+  // Set the current field
+  inline void set_current(NCursesFormField& F) {
+    OnError (::set_current_field(form, F.field));
+  }
+
+  // Provide a default key virtualization. Translate the keyboard
+  // code c into a form request code.
+  // The default implementation provides a hopefully straightforward
+  // mapping for the most common keystrokes and form requests.
+  virtual int virtualize(int c);
+
+  // Operators
+  inline NCursesFormField* operator[](int i) const {
+    if ( (i < 0) || (i >= ::field_count (form)) )
+      OnError (E_BAD_ARGUMENT);
+    return my_fields[i];
+  }
+
+  // Perform the menu's operation
+  // Return the field where you left the form.
+  virtual NCursesFormField* operator()(void);
+
+  // Exception handlers. The default is a Beep.
+  virtual void On_Request_Denied(int c) const;
+  virtual void On_Invalid_Field(int c) const;
+  virtual void On_Unknown_Command(int c) const;
+
+};
+
+//
+// -------------------------------------------------------------------------
+// This is the typical C++ typesafe way to allow to attach
+// user data to a field of a form. Its assumed that the user
+// data belongs to some class T. Use T as template argument
+// to create a UserField.
+// -------------------------------------------------------------------------
+template<class T> class NCURSES_IMPEXP NCursesUserField : public NCursesFormField
+{
+public:
+  NCursesUserField (int rows,
+		    int ncols,
+		    int first_row = 0,
+		    int first_col = 0,
+		    const T* p_UserData = STATIC_CAST(T*)(0),
+		    int offscreen_rows = 0,
+		    int additional_buffers = 0)
+    : NCursesFormField (rows, ncols,
+			first_row, first_col,
+			offscreen_rows, additional_buffers) {
+      if (field)
+	OnError(::set_field_userptr(field, STATIC_CAST(void *)(p_UserData)));
+  }
+
+  virtual ~NCursesUserField() {};
+
+  inline const T* UserData (void) const {
+    return reinterpret_cast<const T*>(::field_userptr (field));
+  }
+
+  inline virtual void setUserData(const T* p_UserData) {
+    if (field)
+      OnError (::set_field_userptr (field, STATIC_CAST(void *)(p_UserData)));
+  }
+};
+//
+// -------------------------------------------------------------------------
+// The same mechanism is used to attach user data to a form
+// -------------------------------------------------------------------------
+//
+template<class T> class NCURSES_IMPEXP NCursesUserForm : public NCursesForm
+{
+protected:
+  // 'Internal' constructor, builds an object without association to a
+  // field array.
+  NCursesUserForm( int  nlines,
+		   int  ncols,
+		   int  begin_y = 0,
+		   int  begin_x = 0,
+		   const T* p_UserData = STATIC_CAST(T*)(0))
+    : NCursesForm(nlines,ncols,begin_y,begin_x) {
+      if (form)
+	set_user (const_cast<void *>(p_UserData));
+  }
+
+public:
+  NCursesUserForm (NCursesFormField Fields[],
+		   const T* p_UserData = STATIC_CAST(T*)(0),
+		   bool with_frame=FALSE,
+		   bool autoDelete_Fields=FALSE)
+    : NCursesForm (Fields, with_frame, autoDelete_Fields) {
+      if (form)
+	set_user (const_cast<void *>(p_UserData));
+  };
+
+  NCursesUserForm (NCursesFormField Fields[],
+		   int nlines,
+		   int ncols,
+		   int begin_y = 0,
+		   int begin_x = 0,
+		   const T* p_UserData = STATIC_CAST(T*)(0),
+		   bool with_frame=FALSE,
+		   bool autoDelete_Fields=FALSE)
+    : NCursesForm (Fields, nlines, ncols, begin_y, begin_x,
+		   with_frame, autoDelete_Fields) {
+      if (form)
+	set_user (const_cast<void *>(p_UserData));
+  };
+
+  virtual ~NCursesUserForm() {
+  };
+
+  inline T* UserData (void) const {
+    return reinterpret_cast<T*>(get_user ());
+  };
+
+  inline virtual void setUserData (const T* p_UserData) {
+    if (form)
+      set_user (const_cast<void *>(p_UserData));
+  }
+
+};
+//
+// -------------------------------------------------------------------------
+// Builtin Fieldtypes
+// -------------------------------------------------------------------------
+//
+class NCURSES_IMPEXP Alpha_Field : public NCursesFieldType
+{
+private:
+  int min_field_width;
+
+  void set(NCursesFormField& f) {
+    OnError(::set_field_type(f.get_field(),fieldtype,min_field_width));
+  }
+
+public:
+  Alpha_Field(int width)
+    : NCursesFieldType(TYPE_ALPHA),
+      min_field_width(width) {
+  }
+};
+
+class NCURSES_IMPEXP Alphanumeric_Field : public NCursesFieldType
+{
+private:
+  int min_field_width;
+
+  void set(NCursesFormField& f) {
+    OnError(::set_field_type(f.get_field(),fieldtype,min_field_width));
+  }
+
+public:
+  Alphanumeric_Field(int width)
+    : NCursesFieldType(TYPE_ALNUM),
+      min_field_width(width) {
+  }
+};
+
+class NCURSES_IMPEXP Integer_Field : public NCursesFieldType
+{
+private:
+  int precision;
+  long lower_limit, upper_limit;
+
+  void set(NCursesFormField& f) {
+    OnError(::set_field_type(f.get_field(),fieldtype,
+			     precision,lower_limit,upper_limit));
+  }
+
+public:
+  Integer_Field(int prec, long low=0L, long high=0L)
+    : NCursesFieldType(TYPE_INTEGER),
+      precision(prec), lower_limit(low), upper_limit(high) {
+  }
+};
+
+class NCURSES_IMPEXP Numeric_Field : public NCursesFieldType
+{
+private:
+  int precision;
+  double lower_limit, upper_limit;
+
+  void set(NCursesFormField& f) {
+    OnError(::set_field_type(f.get_field(),fieldtype,
+			     precision,lower_limit,upper_limit));
+  }
+
+public:
+  Numeric_Field(int prec, double low=0.0, double high=0.0)
+    : NCursesFieldType(TYPE_NUMERIC),
+      precision(prec), lower_limit(low), upper_limit(high) {
+  }
+};
+
+class NCURSES_IMPEXP Regular_Expression_Field : public NCursesFieldType
+{
+private:
+  char* regex;
+
+  void set(NCursesFormField& f) {
+    OnError(::set_field_type(f.get_field(),fieldtype,regex));
+  }
+
+  void copy_regex(const char *source)
+  {
+    regex = new char[1 + ::strlen(source)];
+    (::strcpy)(regex, source);
+  }
+
+public:
+  Regular_Expression_Field(const char *expr)
+    : NCursesFieldType(TYPE_REGEXP),
+      regex(NULL)
+  {
+    copy_regex(expr);
+  }
+
+  Regular_Expression_Field& operator=(const Regular_Expression_Field& rhs)
+  {
+    if (this != &rhs) {
+      *this = rhs;
+      copy_regex(rhs.regex);
+      NCursesFieldType::operator=(rhs);
+    }
+    return *this;
+  }
+
+  Regular_Expression_Field(const Regular_Expression_Field& rhs)
+    : NCursesFieldType(rhs),
+      regex(NULL)
+  {
+    copy_regex(rhs.regex);
+  }
+
+  ~Regular_Expression_Field() {
+    delete[] regex;
+  }
+};
+
+class NCURSES_IMPEXP Enumeration_Field : public NCursesFieldType
+{
+private:
+  const char** list;
+  int case_sensitive;
+  int non_unique_matches;
+
+  void set(NCursesFormField& f) {
+    OnError(::set_field_type(f.get_field(),fieldtype,
+			     list,case_sensitive,non_unique_matches));
+  }
+public:
+  Enumeration_Field(const char* enums[],
+		    bool case_sens=FALSE,
+		    bool non_unique=FALSE)
+    : NCursesFieldType(TYPE_ENUM),
+      list(enums),
+      case_sensitive(case_sens ? -1 : 0),
+      non_unique_matches(non_unique ? -1 : 0) {
+  }
+
+  Enumeration_Field& operator=(const Enumeration_Field& rhs)
+  {
+    if (this != &rhs) {
+      *this = rhs;
+      NCursesFieldType::operator=(rhs);
+    }
+    return *this;
+  }
+
+  Enumeration_Field(const Enumeration_Field& rhs)
+    : NCursesFieldType(rhs),
+      list(rhs.list),
+      case_sensitive(rhs.case_sensitive),
+      non_unique_matches(rhs.non_unique_matches)
+  {
+  }
+};
+
+class NCURSES_IMPEXP IPV4_Address_Field : public NCursesFieldType
+{
+private:
+  void set(NCursesFormField& f) {
+    OnError(::set_field_type(f.get_field(),fieldtype));
+  }
+
+public:
+  IPV4_Address_Field() : NCursesFieldType(TYPE_IPV4) {
+  }
+};
+
+extern "C" {
+  bool _nc_xx_fld_fcheck(FIELD *, const void*);
+  bool _nc_xx_fld_ccheck(int c, const void *);
+  void* _nc_xx_fld_makearg(va_list*);
+}
+
+//
+// -------------------------------------------------------------------------
+// Abstract base class for User-Defined Fieldtypes
+// -------------------------------------------------------------------------
+//
+class NCURSES_IMPEXP UserDefinedFieldType : public NCursesFieldType
+{
+  friend class UDF_Init; // Internal helper to set up statics
+private:
+  // For all C++ defined fieldtypes we need only one generic lowlevel
+  // FIELDTYPE* element.
+  static FIELDTYPE* generic_fieldtype;
+
+protected:
+  // This are the functions required by the low level libforms functions
+  // to construct a fieldtype.
+  friend bool _nc_xx_fld_fcheck(FIELD *, const void*);
+  friend bool _nc_xx_fld_ccheck(int c, const void *);
+  friend void* _nc_xx_fld_makearg(va_list*);
+
+  void set(NCursesFormField& f) {
+    OnError(::set_field_type(f.get_field(),fieldtype,&f));
+  }
+
+protected:
+  // Redefine this function to do a field validation. The argument
+  // is a reference to the field you should validate.
+  virtual bool field_check(NCursesFormField& f) = 0;
+
+  // Redefine this function to do a character validation. The argument
+  // is the character to be validated.
+  virtual bool char_check (int c) = 0;
+
+public:
+  UserDefinedFieldType() : NCursesFieldType(generic_fieldtype) {
+  }
+};
+
+extern "C" {
+  bool _nc_xx_next_choice(FIELD*, const void *);
+  bool _nc_xx_prev_choice(FIELD*, const void *);
+}
+
+//
+// -------------------------------------------------------------------------
+// Abstract base class for User-Defined Fieldtypes with Choice functions
+// -------------------------------------------------------------------------
+//
+class NCURSES_IMPEXP UserDefinedFieldType_With_Choice : public UserDefinedFieldType
+{
+  friend class UDF_Init; // Internal helper to set up statics
+private:
+  // For all C++ defined fieldtypes with choice functions we need only one
+  // generic lowlevel FIELDTYPE* element.
+  static FIELDTYPE* generic_fieldtype_with_choice;
+
+  // This are the functions required by the low level libforms functions
+  // to construct a fieldtype with choice functions.
+  friend bool _nc_xx_next_choice(FIELD*, const void *);
+  friend bool _nc_xx_prev_choice(FIELD*, const void *);
+
+protected:
+  // Redefine this function to do the retrieval of the next choice value.
+  // The argument is a reference to the field tobe examined.
+  virtual bool next    (NCursesFormField& f) = 0;
+
+  // Redefine this function to do the retrieval of the previous choice value.
+  // The argument is a reference to the field tobe examined.
+  virtual bool previous(NCursesFormField& f) = 0;
+
+public:
+  UserDefinedFieldType_With_Choice() {
+    fieldtype = generic_fieldtype_with_choice;
+  }
+};
+
+#endif /* NCURSES_CURSESF_H_incl */
diff --git a/c++/cursesm.cc b/c++/cursesm.cc
new file mode 100644
index 0000000..c253a67
--- /dev/null
+++ b/c++/cursesm.cc
@@ -0,0 +1,407 @@
+// * this is for making emacs happy: -*-Mode: C++;-*-
+/****************************************************************************
+ * Copyright (c) 1998-2003,2005 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, 1997                                          *
+ ****************************************************************************/
+
+#include "internal.h"
+#include "cursesm.h"
+#include "cursesapp.h"
+
+MODULE_ID("$Id: cursesm.cc,v 1.22 2005/04/02 20:39:05 tom Exp $")
+
+NCursesMenuItem::~NCursesMenuItem()
+{
+  if (item)
+    OnError(::free_item(item));
+}
+
+bool
+NCursesMenuItem::action()
+{
+  return FALSE;
+}
+
+NCursesMenuCallbackItem::~NCursesMenuCallbackItem()
+{
+}
+
+bool
+NCursesMenuCallbackItem::action()
+{
+  if (p_fct)
+    return p_fct (*this);
+  else
+    return FALSE;
+}
+
+/* Internal hook functions. They will route the hook
+ * calls to virtual methods of the NCursesMenu class,
+ * so in C++ providing a hook is done simply by
+ * implementing a virtual method in a derived class
+ */
+void
+_nc_xx_mnu_init(MENU *m)
+{
+  NCursesMenu::getHook(m)->On_Menu_Init();
+}
+
+void
+_nc_xx_mnu_term(MENU *m)
+{
+  NCursesMenu::getHook(m)->On_Menu_Termination();
+}
+
+void
+_nc_xx_itm_init(MENU *m)
+{
+  NCursesMenu* M = NCursesMenu::getHook(m);
+  M->On_Item_Init (*(M->current_item ()));
+}
+
+void
+_nc_xx_itm_term(MENU *m)
+{
+  NCursesMenu* M = NCursesMenu::getHook(m);
+  M->On_Item_Termination (*(M->current_item ()));
+}
+
+/* Construct an ITEM* array from an array of NCursesMenuItem
+ * objects.
+ */
+ITEM**
+NCursesMenu::mapItems(NCursesMenuItem* nitems[])
+{
+  int itemCount = 0,lcv;
+
+  for (lcv=0; nitems[lcv]->item; ++lcv)
+    ++itemCount;
+
+  ITEM** itemArray = new ITEM*[itemCount + 1];
+
+  for (lcv=0;nitems[lcv]->item;++lcv) {
+    itemArray[lcv] = nitems[lcv]->item;
+  }
+  itemArray[lcv] = NULL;
+
+  my_items = nitems;
+
+  if (menu)
+    delete[] ::menu_items(menu);
+  return itemArray;
+}
+
+void
+NCursesMenu::InitMenu(NCursesMenuItem* nitems[],
+		      bool with_frame,
+		      bool autoDelete_Items)
+{
+  int mrows, mcols;
+
+  keypad(TRUE);
+  meta(TRUE);
+
+  b_framed = with_frame;
+  b_autoDelete = autoDelete_Items;
+
+  menu = static_cast<MENU*>(0);
+  menu = ::new_menu(mapItems(nitems));
+  if (!menu)
+    OnError (E_SYSTEM_ERROR);
+
+  UserHook* hook = new UserHook;
+  hook->m_user   = NULL;
+  hook->m_back   = this;
+  hook->m_owner  = menu;
+  ::set_menu_userptr(menu, static_cast<void*>(hook));
+
+  ::set_menu_init (menu, _nc_xx_mnu_init);
+  ::set_menu_term (menu, _nc_xx_mnu_term);
+  ::set_item_init (menu, _nc_xx_itm_init);
+  ::set_item_term (menu, _nc_xx_itm_term);
+
+  scale(mrows, mcols);
+  ::set_menu_win(menu, w);
+
+  if (with_frame) {
+    if ((mrows > height()-2) || (mcols > width()-2))
+      OnError(E_NO_ROOM);
+    sub = new NCursesWindow(*this,mrows,mcols,1,1,'r');
+    ::set_menu_sub(menu, sub->w);
+    b_sub_owner = TRUE;
+  }
+  else {
+    sub = static_cast<NCursesWindow*>(0);
+    b_sub_owner = FALSE;
+  }
+  setDefaultAttributes();
+}
+
+void
+NCursesMenu::setDefaultAttributes()
+{
+  NCursesApplication* S = NCursesApplication::getApplication();
+  if (S) {
+    ::set_menu_fore(menu, S->foregrounds());
+    ::set_menu_back(menu, S->backgrounds());
+    ::set_menu_grey(menu, S->inactives());
+  }
+}
+
+NCursesMenu::~NCursesMenu()
+{
+  UserHook* hook = reinterpret_cast<UserHook*>(::menu_userptr(menu));
+  delete hook;
+  if (b_sub_owner) {
+    delete sub;
+    ::set_menu_sub(menu, static_cast<WINDOW *>(0));
+  }
+  if (menu) {
+    ITEM** itms = ::menu_items(menu);
+    int cnt = count();
+
+    OnError(::set_menu_items(menu, static_cast<ITEM**>(0)));
+
+    if (b_autoDelete) {
+      if (cnt>0) {
+	for (int i=0; i <= cnt; i++)
+	  delete my_items[i];
+      }
+      delete[] my_items;
+    }
+
+    ::free_menu(menu);
+    // It's essential to do this after free_menu()
+    delete[] itms;
+  }
+}
+
+void
+NCursesMenu::setSubWindow(NCursesWindow& nsub)
+{
+  if (!isDescendant(nsub))
+    OnError(E_SYSTEM_ERROR);
+  else {
+    if (b_sub_owner)
+      delete sub;
+    sub = &nsub;
+    ::set_menu_sub(menu,sub->w);
+  }
+}
+
+bool
+NCursesMenu::set_pattern (const char *pat)
+{
+  int res = ::set_menu_pattern (menu, pat);
+  switch(res) {
+  case E_OK:
+    break;
+  case E_NO_MATCH:
+    return FALSE;
+  default:
+    OnError (res);
+  }
+  return TRUE;
+}
+
+// call the menu driver and do basic error checking.
+int
+NCursesMenu::driver (int c)
+{
+  int res = ::menu_driver (menu, c);
+  switch (res) {
+  case E_OK:
+  case E_REQUEST_DENIED:
+  case E_NOT_SELECTABLE:
+  case E_UNKNOWN_COMMAND:
+  case E_NO_MATCH:
+    break;
+  default:
+    OnError (res);
+  }
+  return (res);
+}
+
+static const int CMD_QUIT   = MAX_COMMAND + 1;
+static const int CMD_ACTION = MAX_COMMAND + 2;
+//
+// -------------------------------------------------------------------------
+// Provide a default key virtualization. Translate the keyboard
+// code c into a menu request code.
+// The default implementation provides a hopefully straightforward
+// mapping for the most common keystrokes and menu requests.
+// -------------------------------------------------------------------------
+int
+NCursesMenu::virtualize(int c)
+{
+  switch(c) {
+  case CTRL('X')     : return(CMD_QUIT);              // eXit
+
+  case KEY_DOWN      : return(REQ_DOWN_ITEM);
+  case CTRL('N')     : return(REQ_NEXT_ITEM);         // Next
+  case KEY_UP        : return(REQ_UP_ITEM);
+  case CTRL('P')     : return(REQ_PREV_ITEM);         // Previous
+
+  case CTRL('U')     : return(REQ_SCR_ULINE);         // Up
+  case CTRL('D')     : return(REQ_SCR_DLINE);         // Down
+  case CTRL('F')     : return(REQ_SCR_DPAGE);         // Forward
+  case CTRL('B')     : return(REQ_SCR_UPAGE);         // Backward
+
+  case CTRL('Y')     : return(REQ_CLEAR_PATTERN);
+  case CTRL('H')     : return(REQ_BACK_PATTERN);
+  case CTRL('A')     : return(REQ_NEXT_MATCH);
+  case CTRL('E')     : return(REQ_PREV_MATCH);
+  case CTRL('T')     : return(REQ_TOGGLE_ITEM);
+
+  case CTRL('J')     :
+  case CTRL('M')     : return(CMD_ACTION);
+
+  case KEY_HOME      : return(REQ_FIRST_ITEM);
+  case KEY_LEFT      : return(REQ_LEFT_ITEM);
+  case KEY_RIGHT     : return(REQ_RIGHT_ITEM);
+  case KEY_END       : return(REQ_LAST_ITEM);
+  case KEY_BACKSPACE : return(REQ_BACK_PATTERN);
+  case KEY_NPAGE     : return(REQ_SCR_DPAGE);
+  case KEY_PPAGE     : return(REQ_SCR_UPAGE);
+
+  default:
+    return(c);
+  }
+}
+
+NCursesMenuItem*
+NCursesMenu::operator()(void)
+{
+  int drvCmnd;
+  int err;
+  int c;
+  bool b_action = FALSE;
+
+  post();
+  show();
+  refresh();
+
+  while (!b_action && ((drvCmnd = virtualize((c=getKey()))) != CMD_QUIT)) {
+
+    switch((err=driver(drvCmnd))) {
+    case E_REQUEST_DENIED:
+      On_Request_Denied(c);
+      break;
+    case E_NOT_SELECTABLE:
+      On_Not_Selectable(c);
+      break;
+    case E_UNKNOWN_COMMAND:
+      if (drvCmnd == CMD_ACTION) {
+	if (options() & O_ONEVALUE) {
+	  NCursesMenuItem* itm = current_item();
+	  assert(itm != 0);
+	  if (itm->options() & O_SELECTABLE)
+	    {
+	      b_action = itm->action();
+	      refresh();
+	    }
+	  else
+	    On_Not_Selectable(c);
+	}
+	else {
+	  int n = count();
+	  for(int i=0; i<n; i++) {
+	    NCursesMenuItem* itm = my_items[i];
+	    if (itm->value()) {
+	      b_action |= itm->action();
+	      refresh();
+	    }
+	  }
+	}
+      } else
+	On_Unknown_Command(c);
+      break;
+    case E_NO_MATCH:
+      On_No_Match(c);
+      break;
+    case E_OK:
+      break;
+    default:
+      OnError(err);
+    }
+  }
+
+  unpost();
+  hide();
+  refresh();
+  if (options() & O_ONEVALUE)
+    return my_items[::item_index (::current_item (menu))];
+  else
+    return NULL;
+}
+
+void
+NCursesMenu::On_Menu_Init()
+{
+}
+
+void
+NCursesMenu::On_Menu_Termination()
+{
+}
+
+void
+NCursesMenu::On_Item_Init(NCursesMenuItem& item)
+{
+}
+
+void
+NCursesMenu::On_Item_Termination(NCursesMenuItem& item)
+{
+}
+
+void
+NCursesMenu::On_Request_Denied(int c) const
+{
+  ::beep();
+}
+
+void
+NCursesMenu::On_Not_Selectable(int c) const
+{
+  ::beep();
+}
+
+void
+NCursesMenu::On_No_Match(int c) const
+{
+  ::beep();
+}
+
+void
+NCursesMenu::On_Unknown_Command(int c) const
+{
+  ::beep();
+}
diff --git a/c++/cursesm.h b/c++/cursesm.h
new file mode 100644
index 0000000..d9c2273
--- /dev/null
+++ b/c++/cursesm.h
@@ -0,0 +1,672 @@
+// * This makes emacs happy -*-Mode: C++;-*-
+/****************************************************************************
+ * Copyright (c) 1998-2003,2005 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, 1997                                          *
+ ****************************************************************************/
+
+// $Id: cursesm.h,v 1.25 2005/08/13 18:10:36 tom Exp $
+
+#ifndef NCURSES_CURSESM_H_incl
+#define NCURSES_CURSESM_H_incl 1
+
+#include <cursesp.h>
+
+extern "C" {
+#  include <menu.h>
+}
+//
+// -------------------------------------------------------------------------
+// This wraps the ITEM type of <menu.h>
+// -------------------------------------------------------------------------
+//
+class NCURSES_IMPEXP NCursesMenuItem
+{
+  friend class NCursesMenu;
+
+protected:
+  ITEM *item;
+
+  inline void OnError (int err) const THROWS(NCursesMenuException) {
+    if (err != E_OK)
+      THROW(new NCursesMenuException (err));
+  }
+
+public:
+  NCursesMenuItem (const char* p_name     = NULL,
+		   const char* p_descript = NULL)
+    : item(0)
+  {
+    item = p_name ? ::new_item (p_name, p_descript) : STATIC_CAST(ITEM*)(0);
+    if (p_name && !item)
+      OnError (E_SYSTEM_ERROR);
+  }
+  // Create an item. If you pass both parameters as NULL, a delimiting
+  // item is constructed which can be used to terminate a list of
+  // NCursesMenu objects.
+
+  NCursesMenuItem& operator=(const NCursesMenuItem& rhs)
+  {
+    if (this != &rhs) {
+      *this = rhs;
+    }
+    return *this;
+  }
+
+  NCursesMenuItem(const NCursesMenuItem& rhs)
+    : item(0)
+  {
+  }
+
+  virtual ~NCursesMenuItem ();
+  // Release the items memory
+
+  inline const char* name () const {
+    return ::item_name (item);
+  }
+  // Name of the item
+
+  inline const char* description () const {
+    return ::item_description (item);
+  }
+  // Description of the item
+
+  inline int (index) (void) const {
+    return ::item_index (item);
+  }
+  // Index of the item in an item array (or -1)
+
+  inline void options_on (Item_Options opts) {
+    OnError (::item_opts_on (item, opts));
+  }
+  // Switch on the items options
+
+  inline void options_off (Item_Options opts) {
+    OnError (::item_opts_off (item, opts));
+  }
+  // Switch off the item's option
+
+  inline Item_Options options () const {
+    return ::item_opts (item);
+  }
+  // Retrieve the items options
+
+  inline void set_options (Item_Options opts) {
+    OnError (::set_item_opts (item, opts));
+  }
+  // Set the items options
+
+  inline void set_value (bool f) {
+    OnError (::set_item_value (item,f));
+  }
+  // Set/Reset the items selection state
+
+  inline bool value () const {
+    return ::item_value (item);
+  }
+  // Retrieve the items selection state
+
+  inline bool visible () const {
+    return ::item_visible (item);
+  }
+  // Retrieve visibility of the item
+
+  virtual bool action();
+  // Perform an action associated with this item; you may use this in an
+  // user supplied driver for a menu; you may derive from this class and
+  // overload action() to supply items with different actions.
+  // If an action returns true, the menu will be exited. The default action
+  // is to do nothing.
+};
+
+// Prototype for an items callback function.
+typedef bool ITEMCALLBACK(NCursesMenuItem&);
+
+// If you don't like to create a child class for individual items to
+// overload action(), you may use this class and provide a callback
+// function pointer for items.
+class NCURSES_IMPEXP NCursesMenuCallbackItem : public NCursesMenuItem
+{
+private:
+  ITEMCALLBACK* p_fct;
+
+public:
+  NCursesMenuCallbackItem(ITEMCALLBACK* fct       = NULL,
+			  const char* p_name      = NULL,
+			  const char* p_descript  = NULL )
+    : NCursesMenuItem (p_name, p_descript),
+      p_fct (fct) {
+  }
+
+  NCursesMenuCallbackItem& operator=(const NCursesMenuCallbackItem& rhs)
+  {
+    if (this != &rhs) {
+      *this = rhs;
+    }
+    return *this;
+  }
+
+  NCursesMenuCallbackItem(const NCursesMenuCallbackItem& rhs)
+    : NCursesMenuItem(rhs),
+      p_fct(0)
+  {
+  }
+
+  virtual ~NCursesMenuCallbackItem();
+
+  bool action();
+};
+
+  // This are the built-in hook functions in this C++ binding. In C++ we use
+  // virtual member functions (see below On_..._Init and On_..._Termination)
+  // to provide this functionality in an object oriented manner.
+extern "C" {
+  void _nc_xx_mnu_init(MENU *);
+  void _nc_xx_mnu_term(MENU *);
+  void _nc_xx_itm_init(MENU *);
+  void _nc_xx_itm_term(MENU *);
+}
+
+//
+// -------------------------------------------------------------------------
+// This wraps the MENU type of <menu.h>
+// -------------------------------------------------------------------------
+//
+class NCURSES_IMPEXP NCursesMenu : public NCursesPanel
+{
+protected:
+  MENU *menu;
+
+private:
+  NCursesWindow* sub;   // the subwindow object
+  bool b_sub_owner;     // is this our own subwindow?
+  bool b_framed;        // has the menu a border?
+  bool b_autoDelete;    // Delete items when deleting menu?
+
+  NCursesMenuItem** my_items; // The array of items for this menu
+
+  // This structure is used for the menu's user data field to link the
+  // MENU* to the C++ object and to provide extra space for a user pointer.
+  typedef struct {
+    void*              m_user;      // the pointer for the user's data
+    const NCursesMenu* m_back;      // backward pointer to C++ object
+    const MENU*        m_owner;
+  } UserHook;
+
+  // Get the backward pointer to the C++ object from a MENU
+  static inline NCursesMenu* getHook(const MENU *m) {
+    UserHook* hook = STATIC_CAST(UserHook*)(::menu_userptr(m));
+    assert(hook != 0 && hook->m_owner==m);
+    return const_cast<NCursesMenu*>(hook->m_back);
+  }
+
+  friend void _nc_xx_mnu_init(MENU *);
+  friend void _nc_xx_mnu_term(MENU *);
+  friend void _nc_xx_itm_init(MENU *);
+  friend void _nc_xx_itm_term(MENU *);
+
+  // Calculate ITEM* array for the menu
+  ITEM** mapItems(NCursesMenuItem* nitems[]);
+
+protected:
+  // internal routines
+  inline void set_user(void *user) {
+    UserHook* uptr = STATIC_CAST(UserHook*)(::menu_userptr (menu));
+    assert (uptr != 0 && uptr->m_back==this && uptr->m_owner==menu);
+    uptr->m_user = user;
+  }
+
+  inline void *get_user() {
+    UserHook* uptr = STATIC_CAST(UserHook*)(::menu_userptr (menu));
+    assert (uptr != 0 && uptr->m_back==this && uptr->m_owner==menu);
+    return uptr->m_user;
+  }
+
+  void InitMenu (NCursesMenuItem* menu[],
+		 bool with_frame,
+		 bool autoDeleteItems);
+
+  inline void OnError (int err) const THROWS(NCursesMenuException) {
+    if (err != E_OK)
+      THROW(new NCursesMenuException (this, err));
+  }
+
+  // this wraps the menu_driver call.
+  virtual int driver (int c) ;
+
+  // 'Internal' constructor to create a menu without association to
+  // an array of items.
+  NCursesMenu( int  nlines,
+	       int  ncols,
+	       int  begin_y = 0,
+	       int  begin_x = 0)
+    : NCursesPanel(nlines,ncols,begin_y,begin_x),
+      menu (STATIC_CAST(MENU*)(0)),
+      sub(0),
+      b_sub_owner(0),
+      b_framed(0),
+      b_autoDelete(0),
+      my_items(0)
+  {
+  }
+
+public:
+  // Make a full window size menu
+  NCursesMenu (NCursesMenuItem* Items[],
+	       bool with_frame=FALSE,        // Reserve space for a frame?
+	       bool autoDelete_Items=FALSE)  // Autocleanup of Items?
+    : NCursesPanel(),
+      menu(0),
+      sub(0),
+      b_sub_owner(0),
+      b_framed(0),
+      b_autoDelete(0),
+      my_items(0)
+  {
+      InitMenu(Items, with_frame, autoDelete_Items);
+  }
+
+  // Make a menu with a window of this size.
+  NCursesMenu (NCursesMenuItem* Items[],
+	       int  nlines,
+	       int  ncols,
+	       int  begin_y = 0,
+	       int  begin_x = 0,
+	       bool with_frame=FALSE,        // Reserve space for a frame?
+	       bool autoDelete_Items=FALSE)  // Autocleanup of Items?
+    : NCursesPanel(nlines, ncols, begin_y, begin_x),
+      menu(0),
+      sub(0),
+      b_sub_owner(0),
+      b_framed(0),
+      b_autoDelete(0),
+      my_items(0)
+  {
+      InitMenu(Items, with_frame, autoDelete_Items);
+  }
+
+  NCursesMenu& operator=(const NCursesMenu& rhs)
+  {
+    if (this != &rhs) {
+      *this = rhs;
+      NCursesPanel::operator=(rhs);
+    }
+    return *this;
+  }
+
+  NCursesMenu(const NCursesMenu& rhs)
+    : NCursesPanel(rhs),
+      menu(rhs.menu),
+      sub(rhs.sub),
+      b_sub_owner(rhs.b_sub_owner),
+      b_framed(rhs.b_framed),
+      b_autoDelete(rhs.b_autoDelete),
+      my_items(rhs.my_items)
+  {
+  }
+
+  virtual ~NCursesMenu ();
+
+  // Retrieve the menus subwindow
+  inline NCursesWindow& subWindow() const {
+    assert(sub!=NULL);
+    return *sub;
+  }
+
+  // Set the menus subwindow
+  void setSubWindow(NCursesWindow& sub);
+
+  // Set these items for the menu
+  inline void setItems(NCursesMenuItem* Items[]) {
+    OnError(::set_menu_items(menu,mapItems(Items)));
+  }
+
+  // Remove the menu from the screen
+  inline void unpost (void) {
+    OnError (::unpost_menu (menu));
+  }
+
+  // Post the menu to the screen if flag is true, unpost it otherwise
+  inline void post(bool flag = TRUE) {
+    flag ? OnError (::post_menu(menu)) : OnError (::unpost_menu (menu));
+  }
+
+  // Get the numer of rows and columns for this menu
+  inline void scale (int& mrows, int& mcols) const  {
+    OnError (::scale_menu (menu, &mrows, &mcols));
+  }
+
+  // Set the format of this menu
+  inline void set_format(int mrows, int mcols) {
+    OnError (::set_menu_format(menu, mrows, mcols));
+  }
+
+  // Get the format of this menu
+  inline void menu_format(int& rows,int& ncols) {
+    ::menu_format(menu,&rows,&ncols);
+  }
+
+  // Items of the menu
+  inline NCursesMenuItem* items() const {
+    return *my_items;
+  }
+
+  // Get the number of items in this menu
+  inline int count() const {
+    return ::item_count(menu);
+  }
+
+  // Get the current item (i.e. the one the cursor is located)
+  inline NCursesMenuItem* current_item() const {
+    return my_items[::item_index(::current_item(menu))];
+  }
+
+  // Get the marker string
+  inline const char* mark() const {
+    return ::menu_mark(menu);
+  }
+
+  // Set the marker string
+  inline void set_mark(const char *marker) {
+    OnError (::set_menu_mark (menu, marker));
+  }
+
+  // Get the name of the request code c
+  inline static const char* request_name(int c) {
+    return ::menu_request_name(c);
+  }
+
+  // Get the current pattern
+  inline char* pattern() const {
+    return ::menu_pattern(menu);
+  }
+
+  // true if there is a pattern match, false otherwise.
+  bool set_pattern (const char *pat);
+
+  // set the default attributes for the menu
+  // i.e. set fore, back and grey attribute
+  virtual void setDefaultAttributes();
+
+  // Get the menus background attributes
+  inline chtype back() const {
+    return ::menu_back(menu);
+  }
+
+  // Get the menus foreground attributes
+  inline chtype fore() const {
+    return ::menu_fore(menu);
+  }
+
+  // Get the menus grey attributes (used for unselectable items)
+  inline chtype grey() const {
+    return ::menu_grey(menu);
+  }
+
+  // Set the menus background attributes
+  inline chtype set_background(chtype a) {
+    return ::set_menu_back(menu,a);
+  }
+
+  // Set the menus foreground attributes
+  inline chtype set_foreground(chtype a) {
+    return ::set_menu_fore(menu,a);
+  }
+
+  // Set the menus grey attributes (used for unselectable items)
+  inline chtype set_grey(chtype a) {
+    return ::set_menu_grey(menu,a);
+  }
+
+  inline void options_on (Menu_Options opts) {
+    OnError (::menu_opts_on (menu,opts));
+  }
+
+  inline void options_off(Menu_Options opts) {
+    OnError (::menu_opts_off(menu,opts));
+  }
+
+  inline Menu_Options options() const {
+    return ::menu_opts(menu);
+  }
+
+  inline void set_options (Menu_Options opts) {
+    OnError (::set_menu_opts (menu,opts));
+  }
+
+  inline int pad() const {
+    return ::menu_pad(menu);
+  }
+
+  inline void set_pad (int padch) {
+    OnError (::set_menu_pad (menu, padch));
+  }
+
+  // Position the cursor to the current item
+  inline void position_cursor () const {
+    OnError (::pos_menu_cursor (menu));
+  }
+
+  // Set the current item
+  inline void set_current(NCursesMenuItem& I) {
+    OnError (::set_current_item(menu, I.item));
+  }
+
+  // Get the current top row of the menu
+  inline int top_row (void) const {
+    return ::top_row (menu);
+  }
+
+  // Set the current top row of the menu
+  inline void set_top_row (int row) {
+    OnError (::set_top_row (menu, row));
+  }
+
+  // spacing control
+  // Set the spacing for the menu
+  inline void setSpacing(int spc_description,
+			 int spc_rows,
+			 int spc_columns) {
+    OnError(::set_menu_spacing(menu,
+			       spc_description,
+			       spc_rows,
+			       spc_columns));
+  }
+
+  // Get the spacing info for the menu
+  inline void Spacing(int& spc_description,
+		      int& spc_rows,
+		      int& spc_columns) const {
+    OnError(::menu_spacing(menu,
+			   &spc_description,
+			   &spc_rows,
+			   &spc_columns));
+  }
+
+  // Decorations
+  inline void frame(const char *title=NULL, const char* btitle=NULL) {
+    if (b_framed)
+      NCursesPanel::frame(title,btitle);
+    else
+      OnError(E_SYSTEM_ERROR);
+  }
+
+  inline void boldframe(const char *title=NULL, const char* btitle=NULL) {
+    if (b_framed)
+      NCursesPanel::boldframe(title,btitle);
+    else
+      OnError(E_SYSTEM_ERROR);
+  }
+
+  inline void label(const char *topLabel, const char *bottomLabel) {
+    if (b_framed)
+      NCursesPanel::label(topLabel,bottomLabel);
+    else
+      OnError(E_SYSTEM_ERROR);
+  }
+
+  // -----
+  // Hooks
+  // -----
+
+  // Called after the menu gets repositioned in its window.
+  // This is especially true if the menu is posted.
+  virtual void On_Menu_Init();
+
+  // Called before the menu gets repositioned in its window.
+  // This is especially true if the menu is unposted.
+  virtual void On_Menu_Termination();
+
+  // Called after the item became the current item
+  virtual void On_Item_Init(NCursesMenuItem& item);
+
+  // Called before this item is left as current item.
+  virtual void On_Item_Termination(NCursesMenuItem& item);
+
+  // Provide a default key virtualization. Translate the keyboard
+  // code c into a menu request code.
+  // The default implementation provides a hopefully straightforward
+  // mapping for the most common keystrokes and menu requests.
+  virtual int virtualize(int c);
+
+
+  // Operators
+  inline NCursesMenuItem* operator[](int i) const {
+    if ( (i < 0) || (i >= ::item_count (menu)) )
+      OnError (E_BAD_ARGUMENT);
+    return (my_items[i]);
+  }
+
+  // Perform the menu's operation
+  // Return the item where you left the selection mark for a single
+  // selection menu, or NULL for a multivalued menu.
+  virtual NCursesMenuItem* operator()(void);
+
+  // --------------------
+  // Exception handlers
+  // Called by operator()
+  // --------------------
+
+  // Called if the request is denied
+  virtual void On_Request_Denied(int c) const;
+
+  // Called if the item is not selectable
+  virtual void On_Not_Selectable(int c) const;
+
+  // Called if pattern doesn't match
+  virtual void On_No_Match(int c) const;
+
+  // Called if the command is unknown
+  virtual void On_Unknown_Command(int c) const;
+
+};
+//
+// -------------------------------------------------------------------------
+// This is the typical C++ typesafe way to allow to attach
+// user data to an item of a menu. Its assumed that the user
+// data belongs to some class T. Use T as template argument
+// to create a UserItem.
+// -------------------------------------------------------------------------
+//
+template<class T> class NCURSES_IMPEXP NCursesUserItem : public NCursesMenuItem
+{
+public:
+  NCursesUserItem (const char* p_name,
+		   const char* p_descript = NULL,
+		   const T* p_UserData    = STATIC_CAST(T*)(0))
+    : NCursesMenuItem (p_name, p_descript) {
+      if (item)
+	OnError (::set_item_userptr (item, const_cast<void *>(reinterpret_cast<const void*>(p_UserData))));
+  }
+
+  virtual ~NCursesUserItem() {}
+
+  inline const T* UserData (void) const {
+    return reinterpret_cast<const T*>(::item_userptr (item));
+  };
+
+  inline virtual void setUserData(const T* p_UserData) {
+    if (item)
+      OnError (::set_item_userptr (item, const_cast<void *>(reinterpret_cast<const void *>(p_UserData))));
+  }
+};
+//
+// -------------------------------------------------------------------------
+// The same mechanism is used to attach user data to a menu
+// -------------------------------------------------------------------------
+//
+template<class T> class NCURSES_IMPEXP NCursesUserMenu : public NCursesMenu
+{
+protected:
+  NCursesUserMenu( int  nlines,
+		   int  ncols,
+		   int  begin_y = 0,
+		   int  begin_x = 0,
+		   const T* p_UserData = STATIC_CAST(T*)(0))
+    : NCursesMenu(nlines,ncols,begin_y,begin_x) {
+      if (menu)
+	set_user (const_cast<void *>(p_UserData));
+  }
+
+public:
+  NCursesUserMenu (NCursesMenuItem Items[],
+		   const T* p_UserData = STATIC_CAST(T*)(0),
+		   bool with_frame=FALSE,
+		   bool autoDelete_Items=FALSE)
+    : NCursesMenu (Items, with_frame, autoDelete_Items) {
+      if (menu)
+	set_user (const_cast<void *>(p_UserData));
+  };
+
+  NCursesUserMenu (NCursesMenuItem Items[],
+		   int nlines,
+		   int ncols,
+		   int begin_y = 0,
+		   int begin_x = 0,
+		   const T* p_UserData = STATIC_CAST(T*)(0),
+		   bool with_frame=FALSE)
+    : NCursesMenu (Items, nlines, ncols, begin_y, begin_x, with_frame) {
+      if (menu)
+	set_user (const_cast<void *>(p_UserData));
+  };
+
+  virtual ~NCursesUserMenu() {
+  };
+
+  inline T* UserData (void) const {
+    return reinterpret_cast<T*>(get_user ());
+  };
+
+  inline virtual void setUserData (const T* p_UserData) {
+    if (menu)
+      set_user (const_cast<void *>(p_UserData));
+  }
+};
+
+#endif /* NCURSES_CURSESM_H_incl */
diff --git a/c++/cursesmain.cc b/c++/cursesmain.cc
new file mode 100644
index 0000000..1f82d4a
--- /dev/null
+++ b/c++/cursesmain.cc
@@ -0,0 +1,93 @@
+// * this is for making emacs happy: -*-Mode: C++;-*-
+/****************************************************************************
+ * Copyright (c) 1998-2003,2007 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, 1997                                          *
+ ****************************************************************************/
+
+#include "internal.h"
+#include "cursesapp.h"
+
+#if CPP_HAS_TRY_CATCH && HAVE_IOSTREAM
+#include <iostream>
+#else
+#undef CPP_HAS_TRY_CATCH
+#define CPP_HAS_TRY_CATCH 0
+#endif
+
+MODULE_ID("$Id: cursesmain.cc,v 1.14 2007/04/07 17:10:11 tom Exp $")
+
+#if HAVE_LOCALE_H
+#include <locale.h>
+#else
+#define setlocale(name,string) /* nothing */
+#endif
+
+#if NO_LEAKS
+#include <nc_alloc.h>
+#endif
+
+/* This is the default implementation of main() for a NCursesApplication.
+ * You only have to instantiate a static NCursesApplication object in your
+ * main application source file and link this module with your application.
+ */
+int main(int argc, char* argv[])
+{
+  setlocale(LC_ALL, "");
+
+  NCursesApplication* A = NCursesApplication::getApplication();
+  if (!A)
+    return(1);
+  else {
+    int res;
+
+    A->handleArgs(argc,argv);
+    ::endwin();
+#if CPP_HAS_TRY_CATCH
+    try {
+      res = (*A)();
+      ::endwin();
+    }
+    catch(const NCursesException &e) {
+      ::endwin();
+      std::cerr << e.message << std::endl;
+      res = e.errorno;
+    }
+#else
+    res = (*A)();
+    ::endwin();
+#endif
+#if NO_LEAKS
+    delete A;
+    _nc_free_and_exit(res);
+#else
+    return(res);
+#endif
+  }
+}
diff --git a/c++/cursesp.cc b/c++/cursesp.cc
new file mode 100644
index 0000000..9c4eab6
--- /dev/null
+++ b/c++/cursesp.cc
@@ -0,0 +1,138 @@
+// * this is for making emacs happy: -*-Mode: C++;-*-
+/****************************************************************************
+ * Copyright (c) 1998-2003,2005 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, 1993, 1997                                    *
+ ****************************************************************************/
+
+#include "internal.h"
+#include "cursesp.h"
+
+MODULE_ID("$Id: cursesp.cc,v 1.25 2005/08/06 22:12:36 tom Exp $")
+
+NCursesPanel* NCursesPanel::dummy = static_cast<NCursesPanel*>(0);
+
+void NCursesPanel::init()
+{
+  p = ::new_panel(w);
+  if (!p)
+    OnError(ERR);
+
+  UserHook* hook = new UserHook;
+  hook->m_user  = NULL;
+  hook->m_back  = this;
+  hook->m_owner = p;
+  ::set_panel_userptr(p, reinterpret_cast<void *>(hook));
+}
+
+NCursesPanel::~NCursesPanel()
+{
+  UserHook* hook = UserPointer();
+  assert(hook != 0 && hook->m_back==this && hook->m_owner==p);
+  delete hook;
+  ::del_panel(p);
+  ::update_panels();
+}
+
+void
+NCursesPanel::redraw()
+{
+  PANEL *pan;
+
+  pan = ::panel_above(NULL);
+  while (pan) {
+    ::touchwin(panel_window(pan));
+    pan = ::panel_above(pan);
+  }
+  ::update_panels();
+  ::doupdate();
+}
+
+int
+NCursesPanel::refresh()
+{
+  ::update_panels();
+  return ::doupdate();
+}
+
+int
+NCursesPanel::noutrefresh()
+{
+  ::update_panels();
+  return OK;
+}
+
+void
+NCursesPanel::boldframe(const char *title, const char* btitle)
+{
+  standout();
+  frame(title, btitle);
+  standend();
+}
+
+void
+NCursesPanel::frame(const char *title,const char *btitle)
+{
+  int err = OK;
+  if (!title && !btitle) {
+    err = box();
+  }
+  else {
+    err = box();
+    if (err==OK)
+      label(title,btitle);
+  }
+  OnError(err);
+}
+
+void
+NCursesPanel::label(const char *tLabel, const char *bLabel)
+{
+  if (tLabel)
+    centertext(0,tLabel);
+  if (bLabel)
+    centertext(maxy(),bLabel);
+}
+
+void
+NCursesPanel::centertext(int row,const char *labelText)
+{
+  if (labelText) {
+    int x = (maxx() - ::strlen(labelText)) / 2;
+    if (x<0)
+      x=0;
+    OnError(addstr(row, x, labelText, width()));
+  }
+}
+
+int
+NCursesPanel::getKey(void)
+{
+  return getch();
+}
diff --git a/c++/cursesp.h b/c++/cursesp.h
new file mode 100644
index 0000000..9b63d6d
--- /dev/null
+++ b/c++/cursesp.h
@@ -0,0 +1,268 @@
+// * This makes emacs happy -*-Mode: C++;-*-
+/****************************************************************************
+ * Copyright (c) 1998-2007,2008 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, 1997                                          *
+ ****************************************************************************/
+
+#ifndef NCURSES_CURSESP_H_incl
+#define NCURSES_CURSESP_H_incl 1
+
+// $Id: cursesp.h,v 1.29 2008/08/16 17:20:23 tom Exp $
+
+#include <cursesw.h>
+
+extern "C" {
+#  include <panel.h>
+}
+
+class NCURSES_IMPEXP NCursesPanel
+  : public NCursesWindow
+{
+protected:
+  PANEL *p;
+  static NCursesPanel *dummy;
+
+private:
+  // This structure is used for the panel's user data field to link the
+  // PANEL* to the C++ object and to provide extra space for a user pointer.
+  typedef struct {
+    void*               m_user;      // the pointer for the user's data
+    const NCursesPanel* m_back;      // backward pointer to C++ object
+    const PANEL*        m_owner;     // the panel itself
+  } UserHook;
+
+  inline UserHook *UserPointer()
+  {
+    UserHook* uptr = reinterpret_cast<UserHook*>(
+                           const_cast<void *>(::panel_userptr (p)));
+    return uptr;
+  }
+
+  void init();                       // Initialize the panel object
+
+protected:
+  void set_user(void *user)
+  {
+    UserHook* uptr = UserPointer();
+    if (uptr != 0 && uptr->m_back==this && uptr->m_owner==p) {
+      uptr->m_user = user;
+    }
+  }
+  // Set the user pointer of the panel.
+
+  void *get_user()
+  {
+    UserHook* uptr = UserPointer();
+    void *result = 0;
+    if (uptr != 0 && uptr->m_back==this && uptr->m_owner==p)
+      result = uptr->m_user;
+    return result;
+  }
+
+  void OnError (int err) const THROWS(NCursesPanelException)
+  {
+    if (err==ERR)
+      THROW(new NCursesPanelException (this, err));
+  }
+  // If err is equal to the curses error indicator ERR, an error handler
+  // is called.
+
+  // Get a keystroke. Default implementation calls getch()
+  virtual int getKey(void);
+
+public:
+  NCursesPanel(int nlines,
+	       int ncols,
+	       int begin_y = 0,
+	       int begin_x = 0)
+    : NCursesWindow(nlines,ncols,begin_y,begin_x), p(0)
+  {
+    init();
+  }
+  // Create a panel with this size starting at the requested position.
+
+  NCursesPanel()
+    : NCursesWindow(::stdscr), p(0)
+  {
+    init();
+  }
+  // This constructor creates the default Panel associated with the
+  // ::stdscr window
+
+  NCursesPanel& operator=(const NCursesPanel& rhs)
+  {
+    if (this != &rhs) {
+      *this = rhs;
+      NCursesWindow::operator=(rhs);
+    }
+    return *this;
+  }
+
+  NCursesPanel(const NCursesPanel& rhs)
+    : NCursesWindow(rhs),
+      p(rhs.p)
+  {
+  }
+
+  virtual ~NCursesPanel();
+
+  // basic manipulation
+  inline void hide()
+  {
+    OnError (::hide_panel(p));
+  }
+  // Hide the panel. It stays in the stack but becomes invisible.
+
+  inline void show()
+  {
+    OnError (::show_panel(p));
+  }
+  // Show the panel, i.e. make it visible.
+
+  inline void top()
+  {
+    OnError (::top_panel(p));
+  }
+  // Make this panel the top panel in the stack.
+
+  inline void bottom()
+  {
+    OnError (::bottom_panel(p));
+  }
+  // Make this panel the bottom panel in the stack.
+  // N.B.: The panel associated with ::stdscr is always on the bottom. So
+  // actually bottom() makes the panel the first above ::stdscr.
+
+  virtual int mvwin(int y, int x)
+  {
+    OnError(::move_panel(p, y, x));
+    return OK;
+  }
+
+  inline bool hidden() const
+  {
+    return (::panel_hidden (p) ? TRUE : FALSE);
+  }
+  // Return TRUE if the panel is hidden, FALSE otherwise.
+
+/* The functions panel_above() and panel_below() are not reflected in
+   the NCursesPanel class. The reason for this is, that we cannot
+   assume that a panel retrieved by those operations is one wrapped
+   by a C++ class. Although this situation might be handled, we also
+   need a reverse mapping from PANEL to NCursesPanel which needs some
+   redesign of the low level stuff. At the moment, we define them in the
+   interface but they will always produce an error. */
+  inline NCursesPanel& above() const
+  {
+    OnError(ERR);
+    return *dummy;
+  }
+
+  inline NCursesPanel& below() const
+  {
+    OnError(ERR);
+    return *dummy;
+  }
+
+  // Those two are rewrites of the corresponding virtual members of
+  // NCursesWindow
+  virtual int refresh();
+  // Propagate all panel changes to the virtual screen and update the
+  // physical screen.
+
+  virtual int noutrefresh();
+  // Propagate all panel changes to the virtual screen.
+
+  static void redraw();
+  // Redraw all panels.
+
+  // decorations
+  virtual void frame(const char* title=NULL,
+		     const char* btitle=NULL);
+  // Put a frame around the panel and put the title centered in the top line
+  // and btitle in the bottom line.
+
+  virtual void boldframe(const char* title=NULL,
+			 const char* btitle=NULL);
+  // Same as frame(), but use highlighted attributes.
+
+  virtual void label(const char* topLabel,
+		     const char* bottomLabel);
+  // Put the title centered in the top line and btitle in the bottom line.
+
+  virtual void centertext(int row,const char* label);
+  // Put the label text centered in the specified row.
+};
+
+/* We use templates to provide a typesafe mechanism to associate
+ * user data with a panel. A NCursesUserPanel<T> is a panel
+ * associated with some user data of type T.
+ */
+template<class T> class NCursesUserPanel : public NCursesPanel
+{
+public:
+  NCursesUserPanel (int nlines,
+		    int ncols,
+		    int begin_y = 0,
+		    int begin_x = 0,
+		    const T* p_UserData = STATIC_CAST(T*)(0))
+    : NCursesPanel (nlines, ncols, begin_y, begin_x)
+  {
+      if (p)
+	set_user (const_cast<void *>(p_UserData));
+  };
+  // This creates an user panel of the requested size with associated
+  // user data pointed to by p_UserData.
+
+  NCursesUserPanel(const T* p_UserData = STATIC_CAST(T*)(0)) : NCursesPanel()
+  {
+    if (p)
+      set_user(const_cast<void *>(p_UserData));
+  };
+  // This creates an user panel associated with the ::stdscr and user data
+  // pointed to by p_UserData.
+
+  virtual ~NCursesUserPanel() {};
+
+  T* UserData (void) const
+  {
+    return reinterpret_cast<T*>(get_user ());
+  };
+  // Retrieve the user data associated with the panel.
+
+  virtual void setUserData (const T* p_UserData)
+  {
+    if (p)
+      set_user (const_cast<void *>(p_UserData));
+  }
+  // Associate the user panel with the user data pointed to by p_UserData.
+};
+
+#endif /* NCURSES_CURSESP_H_incl */
diff --git a/c++/cursespad.cc b/c++/cursespad.cc
new file mode 100644
index 0000000..28c58fa
--- /dev/null
+++ b/c++/cursespad.cc
@@ -0,0 +1,279 @@
+// * this is for making emacs happy: -*-Mode: C++;-*-
+/****************************************************************************
+ * Copyright (c) 1998-2007,2008 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, 1999                                          *
+ ****************************************************************************/
+
+#include "internal.h"
+
+#include <etip.h>
+#include <cursesw.h>
+
+MODULE_ID("$Id: cursespad.cc,v 1.13 2008/08/04 18:59:22 tom Exp $")
+
+NCursesPad::NCursesPad(int nlines, int ncols)
+  : NCursesWindow(),
+    viewWin(static_cast<NCursesWindow*>(0)),
+    viewSub(static_cast<NCursesWindow*>(0)),
+    h_gridsize(0), v_gridsize(0),
+    min_row(0), min_col(0)
+{
+  w = ::newpad(nlines, ncols);
+  if (static_cast<WINDOW*>(0) == w) {
+    count--;
+    err_handler("Cannot construct window");
+  }
+  alloced = TRUE;
+}
+
+
+int NCursesPad::driver (int key)
+{
+  // Default implementation
+  switch(key) {
+  case KEY_UP:
+    // =======
+    return REQ_PAD_UP;
+  case KEY_DOWN:
+    // =========
+    return REQ_PAD_DOWN;
+  case KEY_LEFT:
+    // =========
+    return REQ_PAD_LEFT;
+  case KEY_RIGHT:
+    // ==========
+    return REQ_PAD_RIGHT;
+  case KEY_EXIT:
+    // =========
+  case CTRL('X'):
+    // ==========
+    return REQ_PAD_EXIT;
+
+  default: return(key);
+  }
+}
+
+
+void NCursesPad::operator()(void)
+{
+  NCursesWindow* W = Win();
+
+  if (static_cast<NCursesWindow*>(0) != W) {
+    int Width  = W->width();
+    int Height = W->height();
+
+    int req = REQ_PAD_REFRESH;
+
+    W->keypad(TRUE);
+    W->meta(TRUE);
+    refresh();
+
+    do {
+      bool changed = FALSE;
+
+      switch (req) {
+      case REQ_PAD_REFRESH:
+	// ================
+	changed = TRUE;
+	break;
+      case REQ_PAD_LEFT:
+	// =============
+	if (min_col > 0) {
+	  changed = TRUE;
+	  if (min_col < h_gridsize)
+	    min_col = 0;
+	  else
+	    min_col -= h_gridsize;
+	}
+	else
+	  OnNavigationError(req);
+	break;
+      case REQ_PAD_RIGHT:
+	// ==============
+	if (min_col < (width() - Width - 1)) {
+	  changed = TRUE;
+	  if (min_col > (width() - Width - h_gridsize - 1))
+	    min_col = width() - Width - 1;
+	  else
+	    min_col += h_gridsize;
+	}
+	else
+	  OnNavigationError(req);
+	break;
+      case REQ_PAD_UP:
+	// ===========
+	if (min_row > 0) {
+	  changed = TRUE;
+	  if (min_row < v_gridsize)
+	    min_row = 0;
+	  else
+	    min_row -= v_gridsize;
+	}
+	else
+	  OnNavigationError(req);
+	break;
+      case REQ_PAD_DOWN:
+	// =============
+	if (min_row < (height() - Height - 1)) {
+	  changed = TRUE;
+	  if (min_row > (height() - Height - v_gridsize - 1))
+	    min_row = height() - Height - 1;
+	  else
+	    min_row += v_gridsize;
+	}
+	else
+	  OnNavigationError(req);
+	break;
+
+      default:
+	OnUnknownOperation(req);
+      }
+
+      if (changed) {
+	noutrefresh();
+	W->syncup();
+	OnOperation(req);
+	viewWin->refresh();
+      }
+    } while( (req=driver(W->getch())) != REQ_PAD_EXIT );
+  }
+}
+
+
+int NCursesPad::refresh()
+{
+  int res = noutrefresh();
+  if (res==OK && (static_cast<NCursesWindow*>(0) != viewWin)) {
+    res = (viewWin->refresh());
+  }
+  return(res);
+}
+
+int NCursesPad::noutrefresh()
+{
+  int res = OK;
+  NCursesWindow* W = Win();
+  if (static_cast<NCursesWindow*>(0) != W) {
+    int high = W->maxy();
+    int wide = W->maxx();
+    res = copywin(*W, min_row, min_col,
+		  0, 0, high, wide,
+		  FALSE);
+    if (res==OK) {
+      W->syncup();
+      res = viewWin->noutrefresh();
+    }
+  }
+  return (res);
+}
+
+void NCursesPad::setWindow(NCursesWindow& view,
+			   int v_grid NCURSES_PARAM_INIT(1),
+			   int h_grid NCURSES_PARAM_INIT(1))
+{
+  viewWin = &view;
+  min_row = min_col = 0;
+  if (h_grid <=0 || v_grid <= 0)
+    err_handler("Illegal Gridsize");
+  else {
+    h_gridsize = h_grid;
+    v_gridsize = v_grid;
+  }
+}
+
+void NCursesPad::setSubWindow(NCursesWindow& sub)
+{
+  if (static_cast<NCursesWindow*>(0) == viewWin)
+    err_handler("Pad has no viewport");
+  assert(viewWin != 0);
+  if (!viewWin->isDescendant(sub))
+    THROW(new NCursesException("NCursesFramePad", E_SYSTEM_ERROR));
+  viewSub = &sub;
+}
+
+void NCursesFramedPad::OnOperation(int pad_req)
+{
+  NCursesWindow* W = Win();
+  NCursesWindow* W2 = getWindow();
+
+  if ((static_cast<NCursesWindow*>(0) != W) && (static_cast<NCursesWindow*>(0) != W2)) {
+    int Width  = W->width();
+    int Height = W->height();
+    int i, row, col, h_len, v_len;
+
+    h_len = (Width*Width + width() - 1)/width();
+    if (h_len==0)
+      h_len = 1;
+    if (h_len > Width)
+      h_len = Width;
+
+    v_len = (Height*Height + height() - 1)/height();
+    if (v_len==0)
+      v_len = 1;
+    if (v_len > Height)
+      v_len = Height;
+
+    col  = (min_col * Width + width() - 1)  / width();
+    if (col + h_len > Width)
+      col = Width - h_len;
+
+    row  = (min_row * Height + height() - 1) / height();
+    if (row + v_len > Height)
+      row = Height - v_len;
+
+    W2->vline(1,Width+1,Height);
+    W2->attron(A_REVERSE);
+    if (v_len>=2) {
+      W2->addch(row+1,Width+1,ACS_UARROW);
+      for(i=2;i<v_len;i++)
+	W2->addch(row+i,Width+1,' ');
+      W2->addch(row+v_len,Width+1,ACS_DARROW);
+    }
+    else {
+      for(i=1;i<=v_len;i++)
+	W2->addch(row+i,Width+1,' ');
+    }
+    W2->attroff(A_REVERSE);
+
+    W2->hline(Height+1,1,Width);
+    W2->attron(A_REVERSE);
+    if (h_len >= 2) {
+      W2->addch(Height+1,col+1,ACS_LARROW);
+      for(i=2;i<h_len;i++)
+	W2->addch(Height+1,col+i,' ');
+      W2->addch(Height+1,col+h_len,ACS_RARROW);
+    }
+    else {
+      for(i=1;i<=h_len;i++)
+	W2->addch(Height+1,col+i,' ');
+    }
+    W2->attroff(A_REVERSE);
+  }
+}
diff --git a/c++/cursesw.cc b/c++/cursesw.cc
new file mode 100644
index 0000000..825d08d
--- /dev/null
+++ b/c++/cursesw.cc
@@ -0,0 +1,470 @@
+// * this is for making emacs happy: -*-Mode: C++;-*-
+/****************************************************************************
+ * Copyright (c) 2007 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.                                                           *
+ ****************************************************************************/
+
+/*
+ * Authors:
+ *	Thomas E. Dickey
+ *	Juergen Pfeifer
+ *
+ * The NCursesWindow class was originally based on a file written by
+ * Eric Newton, later modified by Ulrich Drepper and Anatoly Ivasyuk.
+ * However, aside from the compatible interface definition, no trace
+ * of the original code remains in this version: it consists only of
+ * changes introduced since 1995.
+ */
+
+#include "internal.h"
+#include "cursesw.h"
+
+MODULE_ID("$Id: cursesw.cc,v 1.49 2007/12/15 23:01:57 tom Exp $")
+
+#define COLORS_NEED_INITIALIZATION  -1
+#define COLORS_NOT_INITIALIZED       0
+#define COLORS_MONOCHROME            1
+#define COLORS_ARE_REALLY_THERE      2
+
+#define HaveColors() (colorInitialized == COLORS_ARE_REALLY_THERE)
+
+// declare static variables for the class
+long NCursesWindow::count = 0L;
+bool NCursesWindow::b_initialized = FALSE;
+
+int
+NCursesWindow::scanw(const char* fmt, ...)
+{
+    int result = ERR;
+
+    va_list args;
+    va_start(args, fmt);
+    result = ::vw_scanw (w, const_cast<NCURSES_CONST char *>(fmt), args);
+    va_end(args);
+
+    return result;
+}
+
+
+int
+NCursesWindow::scanw(int y, int x, const char* fmt, ...)
+{
+    int result = ERR;
+
+    if (::wmove(w, y, x) != ERR) {
+	va_list args;
+	va_start(args, fmt);
+	result = ::vw_scanw (w, const_cast<NCURSES_CONST char *>(fmt), args);
+	va_end(args);
+    }
+    return result;
+}
+
+
+int
+NCursesWindow::scanw(const char* fmt, va_list args)
+{
+    int result = ERR;
+
+    result = ::vw_scanw (w, const_cast<NCURSES_CONST char *>(fmt), args);
+
+    return result;
+}
+
+
+int
+NCursesWindow::scanw(int y, int x, const char* fmt, va_list args)
+{
+    int result = ERR;
+
+    if (::wmove(w, y, x) != ERR) {
+	result = ::vw_scanw (w, const_cast<NCURSES_CONST char *>(fmt), args);
+    }
+    return result;
+}
+
+
+int
+NCursesWindow::printw(const char * fmt, ...)
+{
+    va_list args;
+    va_start(args, fmt);
+    int result = ::vw_printw(w, fmt, args);
+    va_end(args);
+    return result;
+}
+
+
+int
+NCursesWindow::printw(int y, int x, const char * fmt, ...)
+{
+    va_list args;
+    va_start(args, fmt);
+    int result = ::wmove(w, y, x);
+    if (result == OK) {
+	result = ::vw_printw(w, fmt, args);
+    }
+    va_end(args);
+    return result;
+}
+
+
+int
+NCursesWindow::printw(const char * fmt, va_list args)
+{
+    int result = ::vw_printw(w, fmt, args);
+    return result;
+}
+
+
+int
+NCursesWindow::printw(int y, int x, const char * fmt, va_list args)
+{
+    int result = ::wmove(w, y, x);
+    if (result == OK) {
+	result = ::vw_printw(w, fmt, args);
+    }
+    return result;
+}
+
+
+void
+NCursesWindow::set_keyboard(void)
+{
+    keypad(TRUE);
+    meta(TRUE);
+}
+
+void
+NCursesWindow::err_handler(const char *msg) const THROWS(NCursesException)
+{
+  THROW(new NCursesException(msg));
+}
+
+void
+NCursesWindow::initialize()
+{
+    if (!b_initialized) {
+	::initscr();
+	b_initialized = TRUE;
+	if (colorInitialized == COLORS_NEED_INITIALIZATION) {
+	    colorInitialized = COLORS_NOT_INITIALIZED;
+	    useColors();
+	}
+	::noecho();
+	::cbreak();
+    }
+}
+
+void
+NCursesWindow::constructing()
+{
+    initialize();
+    ++count;
+}
+
+NCursesWindow::NCursesWindow()
+  : w(0), alloced(FALSE), par(0), subwins(0), sib(0)
+{
+    constructing();
+
+    w = static_cast<WINDOW *>(0);
+    set_keyboard();
+}
+
+NCursesWindow::NCursesWindow(int nlines, int ncols, int begin_y, int begin_x)
+  : w(0), alloced(TRUE), par(0), subwins(0), sib(0)
+{
+    constructing();
+
+    w = ::newwin(nlines, ncols, begin_y, begin_x);
+    if (w == 0) {
+	err_handler("Cannot construct window");
+    }
+    set_keyboard();
+}
+
+NCursesWindow::NCursesWindow(WINDOW* window)
+  : w(0), alloced(FALSE), par(0), subwins(0), sib(0)
+{
+    constructing();
+
+    // We used to use a reference on the "window" parameter, but we cannot do
+    // that with an opaque pointer (see NCURSES_OPAQUE).  If the parameter was
+    // "::stdscr", that is first set via the "constructing() call, and is null
+    // up to that point.  So we allow a null pointer here as meaning the "same"
+    // as "::stdscr".
+    w = window ? window : ::stdscr;
+    set_keyboard();
+}
+
+NCursesWindow::NCursesWindow(NCursesWindow& win, int ny, int nx,
+			     int begin_y, int begin_x, char absrel)
+  : w(0), alloced(TRUE), par(0), subwins(0), sib(0)
+{
+    constructing();
+    if (absrel == 'a') {	// absolute origin
+	begin_y -= win.begy();
+	begin_x -= win.begx();
+    }
+
+    // Link this window into its parent's list of subwindows.
+    // We use derwin(), since this also works for pads.
+    w = ::derwin(win.w, ny, nx, begin_y, begin_x);
+    if (w == 0) {
+	err_handler("Cannot construct subwindow");
+    }
+
+    par = &win;
+    sib = win.subwins;
+    win.subwins = this;
+}
+
+NCursesWindow::NCursesWindow(NCursesWindow& win,
+				bool do_box NCURSES_PARAM_INIT(TRUE))
+  : w(0), alloced(TRUE), par(0), subwins(0), sib(0)
+{
+    constructing();
+    int myHeight = win.height();
+    int myWidth  = win.width();
+    w = :: derwin(win.w, myHeight - 2, myWidth - 2, 1, 1);
+    if (w == 0) {
+	err_handler("Cannot construct subwindow");
+    }
+
+    par = &win;
+    sib = win.subwins;
+    win.subwins = this;
+    subwins = 0;
+
+    if (do_box) {
+	win.box();
+	win.touchwin();
+    }
+}
+
+NCursesWindow NCursesWindow::Clone()
+{
+    WINDOW *d = ::dupwin(w);
+    NCursesWindow W(d);
+    W.subwins = subwins;
+    W.sib = sib;
+    W.par = par;
+    W.alloced = alloced;
+    return W;
+}
+
+typedef int (*RIPOFFINIT)(NCursesWindow&);
+static RIPOFFINIT R_INIT[5];       // There can't be more
+static int r_init_idx   = 0;
+static RIPOFFINIT* prip = R_INIT;
+
+NCursesWindow::NCursesWindow(WINDOW *win, int ncols)
+  : w(0), alloced(FALSE), par(0), subwins(0), sib(0)
+{
+    initialize();
+    w = win;
+    assert((w->_maxx +1 ) == ncols);
+}
+
+int _nc_xx_ripoff_init(WINDOW *w, int ncols)
+{
+    int res = ERR;
+
+    RIPOFFINIT init = *prip++;
+    if (init) {
+	NCursesWindow* W = new NCursesWindow(w,ncols);
+	res = init(*W);
+    }
+    return res;
+}
+
+int NCursesWindow::ripoffline(int ripoff_lines,
+			      int (*init)(NCursesWindow& win))
+{
+    int code = ::_nc_ripoffline(ripoff_lines,_nc_xx_ripoff_init);
+    if (code == OK && init && ripoff_lines) {
+	R_INIT[r_init_idx++] = init;
+    }
+    return code;
+}
+
+bool
+NCursesWindow::isDescendant(NCursesWindow& win)
+{
+    bool result = FALSE;
+
+    for (NCursesWindow* p = subwins; p != NULL; p = p->sib) {
+	if (p == &win || p->isDescendant(win)) {
+	    result = TRUE;
+	    break;
+	}
+    }
+    return result;
+}
+
+void
+NCursesWindow::kill_subwindows()
+{
+    NCursesWindow* p = subwins;
+
+    subwins = 0;
+    while (p != 0) {
+	NCursesWindow* q = p->sib;
+	p->kill_subwindows();
+	if (p->alloced) {
+	    if (p->w != 0)
+		::delwin(p->w);
+	}
+	delete p;
+	p = q;
+    }
+}
+
+
+NCursesWindow::~NCursesWindow()
+{
+    kill_subwindows();
+
+    if (par != 0) {
+	// Remove this window from the parent's list of subwindows.
+	NCursesWindow * next = par->subwins;
+	NCursesWindow * prev = 0;
+	while (next != 0) {
+	    if (next == this) {
+		if (prev != 0) {
+		    prev->sib = next->sib;
+		} else {
+		    par->subwins = next->sib;
+		}
+		break;
+	    }
+	    prev = next;
+	    next = next->sib;
+	}
+    }
+
+    if (alloced && w != 0)
+	::delwin(w);
+
+    if (alloced) {
+	--count;
+	if (count == 0) {
+	    ::endwin();
+	} else if (count < 0) { // cannot happen!
+	    err_handler("Too many windows destroyed");
+	}
+    }
+}
+
+// ---------------------------------------------------------------------
+// Color stuff
+//
+int NCursesWindow::colorInitialized = COLORS_NOT_INITIALIZED;
+
+void
+NCursesWindow::useColors(void)
+{
+    if (colorInitialized == COLORS_NOT_INITIALIZED) {
+	if (b_initialized) {
+	    if (::has_colors()) {
+		::start_color();
+		colorInitialized = COLORS_ARE_REALLY_THERE;
+	    } else {
+		colorInitialized = COLORS_MONOCHROME;
+	    }
+	} else {
+	    colorInitialized = COLORS_NEED_INITIALIZATION;
+	}
+    }
+}
+
+short
+NCursesWindow::getPair() const
+{
+    return static_cast<short>(PAIR_NUMBER(getattrs(w)));
+}
+
+short
+NCursesWindow::getcolor(int getback) const
+{
+    short fore, back;
+
+    if (HaveColors()) {
+	if (::pair_content(getPair(), &fore, &back) == ERR)
+	    err_handler("Can't get color pair");
+    } else {
+	// Monochrome means white on black
+	back = COLOR_BLACK;
+	fore = COLOR_WHITE;
+    }
+    return getback ? back : fore;
+}
+
+int NCursesWindow::NumberOfColors()
+{
+    return (HaveColors()) ? COLORS : 1;
+}
+
+short
+NCursesWindow::getcolor() const
+{
+    return (HaveColors()) ? getPair() : 0;
+}
+
+int
+NCursesWindow::setpalette(short fore, short back, short pair)
+{
+    return (HaveColors()) ? ::init_pair(pair, fore, back) : OK;
+}
+
+int
+NCursesWindow::setpalette(short fore, short back)
+{
+    return setpalette(fore, back, getPair());
+}
+
+
+int
+NCursesWindow::setcolor(short pair)
+{
+    if (HaveColors()) {
+	if ((pair < 1) || (pair > COLOR_PAIRS))
+	    err_handler("Can't set color pair");
+
+	attroff(A_COLOR);
+	attrset(COLOR_PAIR(pair));
+    }
+    return OK;
+}
+
+#if HAVE_HAS_KEY
+bool NCursesWindow::has_mouse() const
+{
+    return ((::has_key(KEY_MOUSE) || ::_nc_has_mouse())
+	     ? TRUE : FALSE);
+}
+#endif
diff --git a/c++/cursesw.h b/c++/cursesw.h
new file mode 100644
index 0000000..b8e921a
--- /dev/null
+++ b/c++/cursesw.h
@@ -0,0 +1,1556 @@
+// * This makes emacs happy -*-Mode: C++;-*-
+// vile:cppmode
+/****************************************************************************
+ * Copyright (c) 1998-2007,2008 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.                                                           *
+ ****************************************************************************/
+
+#ifndef NCURSES_CURSESW_H_incl
+#define NCURSES_CURSESW_H_incl 1
+
+// $Id: cursesw.h,v 1.48 2008/01/19 21:09:10 tom Exp $
+
+#include <etip.h>
+
+extern "C" {
+#  include   <curses.h>
+}
+
+/* SCO 3.2v4 curses.h includes term.h, which defines lines as a macro.
+   Undefine it here, because NCursesWindow uses lines as a method.  */
+#undef lines
+
+/* "Convert" macros to inlines. We'll define it as another symbol to avoid
+ * conflict with library symbols.
+ */
+#undef UNDEF
+#define UNDEF(name) CUR_ ##name
+
+#ifdef addch
+inline int UNDEF(addch)(chtype ch)  { return addch(ch); }
+#undef addch
+#define addch UNDEF(addch)
+#endif
+
+#ifdef addchstr
+inline int UNDEF(addchstr)(chtype *at) { return addchstr(at); }
+#undef addchstr
+#define addchstr UNDEF(addchstr)
+#endif
+
+#ifdef addnstr
+inline int UNDEF(addnstr)(const char *str, int n)
+{ return addnstr(str, n); }
+#undef addnstr
+#define addnstr UNDEF(addnstr)
+#endif
+
+#ifdef addstr
+inline int UNDEF(addstr)(const char * str)  { return addstr(str); }
+#undef addstr
+#define addstr UNDEF(addstr)
+#endif
+
+#ifdef attroff
+inline int UNDEF(attroff)(chtype at) { return attroff(at); }
+#undef attroff
+#define attroff UNDEF(attroff)
+#endif
+
+#ifdef attron
+inline int UNDEF(attron)(chtype at) { return attron(at); }
+#undef attron
+#define attron UNDEF(attron)
+#endif
+
+#ifdef attrset
+inline chtype UNDEF(attrset)(chtype at) { return attrset(at); }
+#undef attrset
+#define attrset UNDEF(attrset)
+#endif
+
+#ifdef bkgd
+inline int UNDEF(bkgd)(chtype ch) { return bkgd(ch); }
+#undef bkgd
+#define bkgd UNDEF(bkgd)
+#endif
+
+#ifdef bkgdset
+inline void UNDEF(bkgdset)(chtype ch) { bkgdset(ch); }
+#undef bkgdset
+#define bkgdset UNDEF(bkgdset)
+#endif
+
+#ifdef border
+inline int UNDEF(border)(chtype ls, chtype rs, chtype ts, chtype bs, chtype tl, chtype tr, chtype bl, chtype br)
+{ return border(ls, rs, ts, bs, tl, tr, bl, br); }
+#undef border
+#define border UNDEF(border)
+#endif
+
+#ifdef box
+inline int UNDEF(box)(WINDOW *win, int v, int h) { return box(win, v, h); }
+#undef box
+#define box UNDEF(box)
+#endif
+
+#ifdef chgat
+inline int UNDEF(chgat)(int n, attr_t attr, short color, const void *opts) {
+  return chgat(n, attr, color, opts); }
+#undef chgat
+#define chgat UNDEF(chgat)
+#endif
+
+#ifdef clear
+inline int UNDEF(clear)()  { return clear(); }
+#undef clear
+#define clear UNDEF(clear)
+#endif
+
+#ifdef clearok
+inline int UNDEF(clearok)(WINDOW* win, bool bf)  { return clearok(win, bf); }
+#undef clearok
+#define clearok UNDEF(clearok)
+#else
+extern "C" NCURSES_IMPEXP int NCURSES_API clearok(WINDOW*, bool);
+#endif
+
+#ifdef clrtobot
+inline int UNDEF(clrtobot)()  { return clrtobot(); }
+#undef clrtobot
+#define clrtobot UNDEF(clrtobot)
+#endif
+
+#ifdef clrtoeol
+inline int UNDEF(clrtoeol)()  { return clrtoeol(); }
+#undef clrtoeol
+#define clrtoeol UNDEF(clrtoeol)
+#endif
+
+#ifdef color_set
+inline chtype UNDEF(color_set)(short p, void* opts) { return color_set(p, opts); }
+#undef color_set
+#define color_set UNDEF(color_set)
+#endif
+
+#ifdef crmode
+inline int UNDEF(crmode)(void) { return crmode(); }
+#undef crmode
+#define crmode UNDEF(crmode)
+#endif
+
+#ifdef delch
+inline int UNDEF(delch)()  { return delch(); }
+#undef delch
+#define delch UNDEF(delch)
+#endif
+
+#ifdef deleteln
+inline int UNDEF(deleteln)()  { return deleteln(); }
+#undef deleteln
+#define deleteln UNDEF(deleteln)
+#endif
+
+#ifdef echochar
+inline int UNDEF(echochar)(chtype ch)  { return echochar(ch); }
+#undef echochar
+#define echochar UNDEF(echochar)
+#endif
+
+#ifdef erase
+inline int UNDEF(erase)()  { return erase(); }
+#undef erase
+#define erase UNDEF(erase)
+#endif
+
+#ifdef fixterm
+inline int UNDEF(fixterm)(void) { return fixterm(); }
+#undef fixterm
+#define fixterm UNDEF(fixterm)
+#endif
+
+#ifdef flushok
+inline int UNDEF(flushok)(WINDOW* _win, bool _bf)  {
+  return flushok(_win, _bf); }
+#undef flushok
+#define flushok UNDEF(flushok)
+#else
+#define _no_flushok
+#endif
+
+#ifdef getattrs
+inline int UNDEF(getattrs)(WINDOW *win) { return getattrs(win); }
+#undef getattrs
+#define getattrs UNDEF(getattrs)
+#endif
+
+#ifdef getbegyx
+inline void UNDEF(getbegyx)(WINDOW* win, int& y, int& x) { getbegyx(win, y, x); }
+#undef getbegyx
+#define getbegyx UNDEF(getbegyx)
+#endif
+
+#ifdef getbkgd
+inline chtype UNDEF(getbkgd)(const WINDOW *win) { return getbkgd(win); }
+#undef getbkgd
+#define getbkgd UNDEF(getbkgd)
+#endif
+
+#ifdef getch
+inline int UNDEF(getch)()  { return getch(); }
+#undef getch
+#define getch UNDEF(getch)
+#endif
+
+#ifdef getmaxyx
+inline void UNDEF(getmaxyx)(WINDOW* win, int& y, int& x) { getmaxyx(win, y, x); }
+#undef getmaxyx
+#define getmaxyx UNDEF(getmaxyx)
+#endif
+
+#ifdef getnstr
+inline int UNDEF(getnstr)(char *_str, int n)  { return getnstr(_str, n); }
+#undef getnstr
+#define getnstr UNDEF(getnstr)
+#endif
+
+#ifdef getparyx
+inline void UNDEF(getparyx)(WINDOW* win, int& y, int& x) { getparyx(win, y, x); }
+#undef getparyx
+#define getparyx UNDEF(getparyx)
+#endif
+
+#ifdef getstr
+inline int UNDEF(getstr)(char *_str)  { return getstr(_str); }
+#undef getstr
+#define getstr UNDEF(getstr)
+#endif
+
+#ifdef getyx
+inline void UNDEF(getyx)(const WINDOW* win, int& y, int& x) {
+  getyx(win, y, x); }
+#undef getyx
+#define getyx UNDEF(getyx)
+#endif
+
+#ifdef hline
+inline int UNDEF(hline)(chtype ch, int n) { return hline(ch, n); }
+#undef hline
+#define hline UNDEF(hline)
+#endif
+
+#ifdef inch
+inline chtype UNDEF(inch)()  { return inch(); }
+#undef inch
+#define inch UNDEF(inch)
+#endif
+
+#ifdef inchstr
+inline int UNDEF(inchstr)(chtype *str)  { return inchstr(str); }
+#undef inchstr
+#define inchstr UNDEF(inchstr)
+#endif
+
+#ifdef innstr
+inline int UNDEF(innstr)(char *_str, int n)  { return innstr(_str, n); }
+#undef innstr
+#define innstr UNDEF(innstr)
+#endif
+
+#ifdef insch
+inline int UNDEF(insch)(chtype c)  { return insch(c); }
+#undef insch
+#define insch UNDEF(insch)
+#endif
+
+#ifdef insdelln
+inline int UNDEF(insdelln)(int n)  { return insdelln(n); }
+#undef insdelln
+#define insdelln UNDEF(insdelln)
+#endif
+
+#ifdef insertln
+inline int UNDEF(insertln)()  { return insertln(); }
+#undef insertln
+#define insertln UNDEF(insertln)
+#endif
+
+#ifdef insnstr
+inline int UNDEF(insnstr)(const char *_str, int n)  {
+  return insnstr(_str, n); }
+#undef insnstr
+#define insnstr UNDEF(insnstr)
+#endif
+
+#ifdef insstr
+inline int UNDEF(insstr)(const char *_str)  {
+  return insstr(_str); }
+#undef insstr
+#define insstr UNDEF(insstr)
+#endif
+
+#ifdef instr
+inline int UNDEF(instr)(char *_str)  { return instr(_str); }
+#undef instr
+#define instr UNDEF(instr)
+#endif
+
+#ifdef intrflush
+inline void UNDEF(intrflush)(WINDOW *win, bool bf) { intrflush(); }
+#undef intrflush
+#define intrflush UNDEF(intrflush)
+#endif
+
+#ifdef leaveok
+inline int UNDEF(leaveok)(WINDOW* win, bool bf)  { return leaveok(win, bf); }
+#undef leaveok
+#define leaveok UNDEF(leaveok)
+#else
+extern "C" NCURSES_IMPEXP int NCURSES_API leaveok(WINDOW* win, bool bf);
+#endif
+
+#ifdef move
+inline int UNDEF(move)(int x, int y)  { return move(x, y); }
+#undef move
+#define move UNDEF(move)
+#endif
+
+#ifdef mvaddch
+inline int UNDEF(mvaddch)(int y, int x, chtype ch)
+{ return mvaddch(y, x, ch); }
+#undef mvaddch
+#define mvaddch UNDEF(mvaddch)
+#endif
+
+#ifdef mvaddnstr
+inline int UNDEF(mvaddnstr)(int y, int x, const char *str, int n)
+{ return mvaddnstr(y, x, str, n); }
+#undef mvaddnstr
+#define mvaddnstr UNDEF(mvaddnstr)
+#endif
+
+#ifdef mvaddstr
+inline int UNDEF(mvaddstr)(int y, int x, const char * str)
+{ return mvaddstr(y, x, str); }
+#undef mvaddstr
+#define mvaddstr UNDEF(mvaddstr)
+#endif
+
+#ifdef mvchgat
+inline int UNDEF(mvchgat)(int y, int x, int n,
+			  attr_t attr, short color, const void *opts) {
+  return mvchgat(y, x, n, attr, color, opts); }
+#undef mvchgat
+#define mvchgat UNDEF(mvchgat)
+#endif
+
+#ifdef mvdelch
+inline int UNDEF(mvdelch)(int y, int x) { return mvdelch(y, x);}
+#undef mvdelch
+#define mvdelch UNDEF(mvdelch)
+#endif
+
+#ifdef mvgetch
+inline int UNDEF(mvgetch)(int y, int x) { return mvgetch(y, x);}
+#undef mvgetch
+#define mvgetch UNDEF(mvgetch)
+#endif
+
+#ifdef mvgetnstr
+inline int UNDEF(mvgetnstr)(int y, int x, char *str, int n) {
+  return mvgetnstr(y, x, str, n);}
+#undef mvgetnstr
+#define mvgetnstr UNDEF(mvgetnstr)
+#endif
+
+#ifdef mvgetstr
+inline int UNDEF(mvgetstr)(int y, int x, char *str) {return mvgetstr(y, x, str);}
+#undef mvgetstr
+#define mvgetstr UNDEF(mvgetstr)
+#endif
+
+#ifdef mvinch
+inline chtype UNDEF(mvinch)(int y, int x) { return mvinch(y, x);}
+#undef mvinch
+#define mvinch UNDEF(mvinch)
+#endif
+
+#ifdef mvinnstr
+inline int UNDEF(mvinnstr)(int y, int x, char *_str, int n) {
+  return mvinnstr(y, x, _str, n); }
+#undef mvinnstr
+#define mvinnstr UNDEF(mvinnstr)
+#endif
+
+#ifdef mvinsch
+inline int UNDEF(mvinsch)(int y, int x, chtype c)
+{ return mvinsch(y, x, c); }
+#undef mvinsch
+#define mvinsch UNDEF(mvinsch)
+#endif
+
+#ifdef mvinsnstr
+inline int UNDEF(mvinsnstr)(int y, int x, const char *_str, int n) {
+  return mvinsnstr(y, x, _str, n); }
+#undef mvinsnstr
+#define mvinsnstr UNDEF(mvinsnstr)
+#endif
+
+#ifdef mvinsstr
+inline int UNDEF(mvinsstr)(int y, int x, const char *_str)  {
+  return mvinsstr(y, x, _str); }
+#undef mvinsstr
+#define mvinsstr UNDEF(mvinsstr)
+#endif
+
+#ifdef mvwaddch
+inline int UNDEF(mvwaddch)(WINDOW *win, int y, int x, const chtype ch)
+{ return mvwaddch(win, y, x, ch); }
+#undef mvwaddch
+#define mvwaddch UNDEF(mvwaddch)
+#endif
+
+#ifdef mvwaddchnstr
+inline int UNDEF(mvwaddchnstr)(WINDOW *win, int y, int x, const chtype *str, int n)
+{ return mvwaddchnstr(win, y, x, str, n); }
+#undef mvwaddchnstr
+#define mvwaddchnstr UNDEF(mvwaddchnstr)
+#endif
+
+#ifdef mvwaddchstr
+inline int UNDEF(mvwaddchstr)(WINDOW *win, int y, int x, const chtype *str)
+{ return mvwaddchstr(win, y, x, str); }
+#undef mvwaddchstr
+#define mvwaddchstr UNDEF(mvwaddchstr)
+#endif
+
+#ifdef mvwaddnstr
+inline int UNDEF(mvwaddnstr)(WINDOW *win, int y, int x, const char *str, int n)
+{ return mvwaddnstr(win, y, x, str, n); }
+#undef mvwaddnstr
+#define mvwaddnstr UNDEF(mvwaddnstr)
+#endif
+
+#ifdef mvwaddstr
+inline int UNDEF(mvwaddstr)(WINDOW *win, int y, int x, const char * str)
+{ return mvwaddstr(win, y, x, str); }
+#undef mvwaddstr
+#define mvwaddstr UNDEF(mvwaddstr)
+#endif
+
+#ifdef mvwchgat
+inline int UNDEF(mvwchgat)(WINDOW *win, int y, int x, int n,
+			   attr_t attr, short color, const void *opts) {
+  return mvwchgat(win, y, x, n, attr, color, opts); }
+#undef mvwchgat
+#define mvwchgat UNDEF(mvwchgat)
+#endif
+
+#ifdef mvwdelch
+inline int UNDEF(mvwdelch)(WINDOW *win, int y, int x)
+{ return mvwdelch(win, y, x); }
+#undef mvwdelch
+#define mvwdelch UNDEF(mvwdelch)
+#endif
+
+#ifdef mvwgetch
+inline int UNDEF(mvwgetch)(WINDOW *win, int y, int x) { return mvwgetch(win, y, x);}
+#undef mvwgetch
+#define mvwgetch UNDEF(mvwgetch)
+#endif
+
+#ifdef mvwgetnstr
+inline int UNDEF(mvwgetnstr)(WINDOW *win, int y, int x, char *str, int n)
+{return mvwgetnstr(win, y, x, str, n);}
+#undef mvwgetnstr
+#define mvwgetnstr UNDEF(mvwgetnstr)
+#endif
+
+#ifdef mvwgetstr
+inline int UNDEF(mvwgetstr)(WINDOW *win, int y, int x, char *str)
+{return mvwgetstr(win, y, x, str);}
+#undef mvwgetstr
+#define mvwgetstr UNDEF(mvwgetstr)
+#endif
+
+#ifdef mvwhline
+inline int UNDEF(mvwhline)(WINDOW *win, int y, int x, chtype c, int n) {
+  return mvwhline(win, y, x, c, n); }
+#undef mvwhline
+#define mvwhline UNDEF(mvwhline)
+#endif
+
+#ifdef mvwinch
+inline chtype UNDEF(mvwinch)(WINDOW *win, int y, int x) {
+  return mvwinch(win, y, x);}
+#undef mvwinch
+#define mvwinch UNDEF(mvwinch)
+#endif
+
+#ifdef mvwinchnstr
+inline int UNDEF(mvwinchnstr)(WINDOW *win, int y, int x, chtype *str, int n)  { return mvwinchnstr(win, y, x, str, n); }
+#undef mvwinchnstr
+#define mvwinchnstr UNDEF(mvwinchnstr)
+#endif
+
+#ifdef mvwinchstr
+inline int UNDEF(mvwinchstr)(WINDOW *win, int y, int x, chtype *str)  { return mvwinchstr(win, y, x, str); }
+#undef mvwinchstr
+#define mvwinchstr UNDEF(mvwinchstr)
+#endif
+
+#ifdef mvwinnstr
+inline int UNDEF(mvwinnstr)(WINDOW *win, int y, int x, char *_str, int n) {
+  return mvwinnstr(win, y, x, _str, n); }
+#undef mvwinnstr
+#define mvwinnstr UNDEF(mvwinnstr)
+#endif
+
+#ifdef mvwinsch
+inline int UNDEF(mvwinsch)(WINDOW *win, int y, int x, chtype c)
+{ return mvwinsch(win, y, x, c); }
+#undef mvwinsch
+#define mvwinsch UNDEF(mvwinsch)
+#endif
+
+#ifdef mvwinsnstr
+inline int UNDEF(mvwinsnstr)(WINDOW *w, int y, int x, const char *_str, int n) {
+  return mvwinsnstr(w, y, x, _str, n); }
+#undef mvwinsnstr
+#define mvwinsnstr UNDEF(mvwinsnstr)
+#endif
+
+#ifdef mvwinsstr
+inline int UNDEF(mvwinsstr)(WINDOW *w, int y, int x,  const char *_str)  {
+  return mvwinsstr(w, y, x, _str); }
+#undef mvwinsstr
+#define mvwinsstr UNDEF(mvwinsstr)
+#endif
+
+#ifdef mvwvline
+inline int UNDEF(mvwvline)(WINDOW *win, int y, int x, chtype c, int n) {
+  return mvwvline(win, y, x, c, n); }
+#undef mvwvline
+#define mvwvline UNDEF(mvwvline)
+#endif
+
+#ifdef napms
+inline void UNDEF(napms)(unsigned long x) { napms(x); }
+#undef napms
+#define napms UNDEF(napms)
+#endif
+
+#ifdef nocrmode
+inline int UNDEF(nocrmode)(void) { return nocrmode(); }
+#undef nocrmode
+#define nocrmode UNDEF(nocrmode)
+#endif
+
+#ifdef nodelay
+inline void UNDEF(nodelay)() { nodelay(); }
+#undef nodelay
+#define nodelay UNDEF(nodelay)
+#endif
+
+#ifdef redrawwin
+inline int UNDEF(redrawwin)(WINDOW *win)  { return redrawwin(win); }
+#undef redrawwin
+#define redrawwin UNDEF(redrawwin)
+#endif
+
+#ifdef refresh
+inline int UNDEF(refresh)()  { return refresh(); }
+#undef refresh
+#define refresh UNDEF(refresh)
+#endif
+
+#ifdef resetterm
+inline int UNDEF(resetterm)(void) { return resetterm(); }
+#undef resetterm
+#define resetterm UNDEF(resetterm)
+#endif
+
+#ifdef saveterm
+inline int UNDEF(saveterm)(void) { return saveterm(); }
+#undef saveterm
+#define saveterm UNDEF(saveterm)
+#endif
+
+#ifdef scrl
+inline int UNDEF(scrl)(int l) { return scrl(l); }
+#undef scrl
+#define scrl UNDEF(scrl)
+#endif
+
+#ifdef scroll
+inline int UNDEF(scroll)(WINDOW *win) { return scroll(win); }
+#undef scroll
+#define scroll UNDEF(scroll)
+#endif
+
+#ifdef scrollok
+inline int UNDEF(scrollok)(WINDOW* win, bool bf)  { return scrollok(win, bf); }
+#undef scrollok
+#define scrollok UNDEF(scrollok)
+#else
+#if	defined(__NCURSES_H)
+extern "C" NCURSES_IMPEXP int NCURSES_API scrollok(WINDOW*, bool);
+#else
+extern "C" NCURSES_IMPEXP int NCURSES_API scrollok(WINDOW*, char);
+#endif
+#endif
+
+#ifdef setscrreg
+inline int UNDEF(setscrreg)(int t, int b) { return setscrreg(t, b); }
+#undef setscrreg
+#define setscrreg UNDEF(setscrreg)
+#endif
+
+#ifdef standend
+inline int UNDEF(standend)()  { return standend(); }
+#undef standend
+#define standend UNDEF(standend)
+#endif
+
+#ifdef standout
+inline int UNDEF(standout)()  { return standout(); }
+#undef standout
+#define standout UNDEF(standout)
+#endif
+
+#ifdef subpad
+inline WINDOW *UNDEF(subpad)(WINDOW *p, int l, int c, int y, int x)
+{ return derwin(p, l, c, y, x); }
+#undef subpad
+#define subpad UNDEF(subpad)
+#endif
+
+#ifdef timeout
+inline void UNDEF(timeout)(int delay) { timeout(delay); }
+#undef timeout
+#define timeout UNDEF(timeout)
+#endif
+
+#ifdef touchline
+inline int UNDEF(touchline)(WINDOW *win, int s, int c)
+{ return touchline(win, s, c); }
+#undef touchline
+#define touchline UNDEF(touchline)
+#endif
+
+#ifdef touchwin
+inline int UNDEF(touchwin)(WINDOW *win) { return touchwin(win); }
+#undef touchwin
+#define touchwin UNDEF(touchwin)
+#endif
+
+#ifdef untouchwin
+inline int UNDEF(untouchwin)(WINDOW *win) { return untouchwin(win); }
+#undef untouchwin
+#define untouchwin UNDEF(untouchwin)
+#endif
+
+#ifdef vline
+inline int UNDEF(vline)(chtype ch, int n) { return vline(ch, n); }
+#undef vline
+#define vline UNDEF(vline)
+#endif
+
+#ifdef waddchstr
+inline int UNDEF(waddchstr)(WINDOW *win, chtype *at) { return waddchstr(win, at); }
+#undef waddchstr
+#define waddchstr UNDEF(waddchstr)
+#endif
+
+#ifdef waddstr
+inline int UNDEF(waddstr)(WINDOW *win, char *str) { return waddstr(win, str); }
+#undef waddstr
+#define waddstr UNDEF(waddstr)
+#endif
+
+#ifdef wattroff
+inline int UNDEF(wattroff)(WINDOW *win, int att) { return wattroff(win, att); }
+#undef wattroff
+#define wattroff UNDEF(wattroff)
+#endif
+
+#ifdef wattrset
+inline int UNDEF(wattrset)(WINDOW *win, int att) { return wattrset(win, att); }
+#undef wattrset
+#define wattrset UNDEF(wattrset)
+#endif
+
+#ifdef winch
+inline chtype UNDEF(winch)(const WINDOW* win) { return winch(win); }
+#undef winch
+#define winch UNDEF(winch)
+#endif
+
+#ifdef winchnstr
+inline int UNDEF(winchnstr)(WINDOW *win, chtype *str, int n)  { return winchnstr(win, str, n); }
+#undef winchnstr
+#define winchnstr UNDEF(winchnstr)
+#endif
+
+#ifdef winchstr
+inline int UNDEF(winchstr)(WINDOW *win, chtype *str)  { return winchstr(win, str); }
+#undef winchstr
+#define winchstr UNDEF(winchstr)
+#endif
+
+#ifdef winsstr
+inline int UNDEF(winsstr)(WINDOW *w, const char *_str)  {
+  return winsstr(w, _str); }
+#undef winsstr
+#define winsstr UNDEF(winsstr)
+#endif
+
+#ifdef wstandend
+inline int UNDEF(wstandend)(WINDOW *win)  { return wstandend(win); }
+#undef wstandend
+#define wstandend UNDEF(wstandend)
+#endif
+
+#ifdef wstandout
+inline int UNDEF(wstandout)(WINDOW *win)  { return wstandout(win); }
+#undef wstandout
+#define wstandout UNDEF(wstandout)
+#endif
+
+/*
+ *
+ * C++ class for windows.
+ *
+ */
+
+extern "C" int     _nc_ripoffline(int, int (*init)(WINDOW*, int));
+extern "C" int     _nc_xx_ripoff_init(WINDOW *, int);
+extern "C" int     _nc_has_mouse(void);
+
+class NCURSES_IMPEXP NCursesWindow
+{
+  friend class NCursesMenu;
+  friend class NCursesForm;
+
+private:
+  static bool    b_initialized;
+  static void    initialize();
+  void           constructing();
+  friend int     _nc_xx_ripoff_init(WINDOW *, int);
+
+  void           set_keyboard();
+
+  short          getcolor(int getback) const;
+  short          getPair() const;
+
+  static int     setpalette(short fore, short back, short pair);
+  static int     colorInitialized;
+
+  // This private constructor is only used during the initialization
+  // of windows generated by ripoffline() calls.
+  NCursesWindow(WINDOW* win, int ncols);
+
+protected:
+  virtual void   err_handler(const char *) const THROWS(NCursesException);
+  // Signal an error with the given message text.
+
+  static long count;        // count of all active windows:
+  //   We rely on the c++ promise that
+  //   all otherwise uninitialized
+  //   static class vars are set to 0
+
+  WINDOW*        w;                // the curses WINDOW
+
+  bool           alloced;          // TRUE if we own the WINDOW
+
+  NCursesWindow* par;              // parent, if subwindow
+  NCursesWindow* subwins;          // head of subwindows list
+  NCursesWindow* sib;              // next subwindow of parent
+
+  void           kill_subwindows(); // disable all subwindows
+  // Destroy all subwindows.
+
+  /* Only for use by derived classes. They are then in charge to
+     fill the member variables correctly. */
+  NCursesWindow();
+
+public:
+  NCursesWindow(WINDOW* window);   // useful only for stdscr
+
+  NCursesWindow(int nlines,        // number of lines
+		int ncols,         // number of columns
+		int begin_y,       // line origin
+		int begin_x);      // col origin
+
+  NCursesWindow(NCursesWindow& par,// parent window
+		int nlines,        // number of lines
+		int ncols,         // number of columns
+		int begin_y,       // absolute or relative
+		int begin_x,       //   origins:
+		char absrel = 'a');// if `a', begin_y & begin_x are
+  // absolute screen pos, else if `r', they are relative to par origin
+
+  NCursesWindow(NCursesWindow& par,// parent window
+		bool do_box = TRUE);
+  // this is the very common case that we want to create the subwindow that
+  // is two lines and two columns smaller and begins at (1,1).
+  // We may automatically request the box around it.
+
+  NCursesWindow& operator=(const NCursesWindow& rhs)
+  {
+    if (this != &rhs)
+      *this = rhs;
+    return *this;
+  }
+
+  NCursesWindow(const NCursesWindow& rhs)
+    : w(rhs.w), alloced(rhs.alloced), par(rhs.par), subwins(rhs.subwins), sib(rhs.sib)
+  {
+  }
+
+  virtual ~NCursesWindow();
+
+  NCursesWindow Clone();
+  // Make an exact copy of the window.
+
+  // Initialization.
+  static void    useColors(void);
+  // Call this routine very early if you want to have colors.
+
+  static int ripoffline(int ripoff_lines,
+			int (*init)(NCursesWindow& win));
+  // This function is used to generate a window of ripped-of lines.
+  // If the argument is positive, lines are removed from the top, if it
+  // is negative lines are removed from the bottom. This enhances the
+  // lowlevel ripoffline() function because it uses the internal
+  // implementation that allows to remove more than just a single line.
+  // This function must be called before any other ncurses function. The
+  // creation of the window is deferred until ncurses gets initialized.
+  // The initialization function is then called.
+
+  // -------------------------------------------------------------------------
+  // terminal status
+  // -------------------------------------------------------------------------
+  int            lines() const { initialize(); return LINES; }
+  // Number of lines on terminal, *not* window
+
+  int            cols() const { initialize(); return COLS; }
+  // Number of cols  on terminal, *not* window
+
+  int            tabsize() const { initialize(); return TABSIZE; }
+  // Size of a tab on terminal, *not* window
+
+  static int     NumberOfColors();
+  // Number of available colors
+
+  int            colors() const { return NumberOfColors(); }
+  // Number of available colors
+
+  // -------------------------------------------------------------------------
+  // window status
+  // -------------------------------------------------------------------------
+  int            height() const { return maxy() + 1; }
+  // Number of lines in this window
+
+  int            width() const { return maxx() + 1; }
+  // Number of columns in this window
+
+  int            begx() const { return getbegx(w); }
+  // Column of top left corner relative to stdscr
+
+  int            begy() const { return getbegy(w); }
+  // Line of top left corner relative to stdscr
+
+  int            curx() const { return getcurx(w); }
+  // Column of top left corner relative to stdscr
+
+  int            cury() const { return getcury(w); }
+  // Line of top left corner relative to stdscr
+
+  int            maxx() const { return getmaxx(w) == ERR ? ERR : getmaxx(w)-1; }
+  // Largest x coord in window
+
+  int            maxy() const { return getmaxy(w) == ERR ? ERR : getmaxy(w)-1; }
+  // Largest y coord in window
+
+  short          getcolor() const;
+  // Actual color pair
+
+  short          foreground() const { return getcolor(0); }
+  // Actual foreground color
+
+  short          background() const { return getcolor(1); }
+  // Actual background color
+
+  int            setpalette(short fore, short back);
+  // Set color palette entry
+
+  int            setcolor(short pair);
+  // Set actually used palette entry
+
+  // -------------------------------------------------------------------------
+  // window positioning
+  // -------------------------------------------------------------------------
+  virtual int    mvwin(int begin_y, int begin_x) {
+    return ::mvwin(w, begin_y, begin_x); }
+  // Move window to new position with the new position as top left corner.
+  // This is virtual because it is redefined in NCursesPanel.
+
+  // -------------------------------------------------------------------------
+  // coordinate positioning
+  // -------------------------------------------------------------------------
+  int            move(int y, int x) { return ::wmove(w, y, x); }
+  // Move cursor the this position
+
+  void           getyx(int& y, int& x) const { ::getyx(w, y, x); }
+  // Get current position of the cursor
+
+  void           getbegyx(int& y, int& x) const { ::getbegyx(w, y, x); }
+  // Get beginning of the window
+
+  void           getmaxyx(int& y, int& x) const { ::getmaxyx(w, y, x); }
+  // Get size of the window
+
+  void           getparyx(int& y, int& x) const { ::getparyx(w, y, x); }
+  // Get parent's beginning of the window
+
+  int            mvcur(int oldrow, int oldcol, int newrow, int newcol) const {
+    return ::mvcur(oldrow, oldcol, newrow, newcol); }
+  // Perform lowlevel cursor motion that takes effect immediately.
+
+  // -------------------------------------------------------------------------
+  // input
+  // -------------------------------------------------------------------------
+  int            getch() { return ::wgetch(w); }
+  // Get a keystroke from the window.
+
+  int            getch(int y, int x) { return ::mvwgetch(w, y, x); }
+  // Move cursor to position and get a keystroke from the window
+
+  int            getstr(char* str, int n=-1) {
+    return ::wgetnstr(w, str, n); }
+  // Read a series of characters into str until a newline or carriage return
+  // is received. Read at most n characters. If n is negative, the limit is
+  // ignored.
+
+  int            getstr(int y, int x, char* str, int n=-1) {
+    return ::mvwgetnstr(w, y, x, str, n); }
+  // Move the cursor to the requested position and then perform the getstr()
+  // as described above.
+
+  int            instr(char *s, int n=-1) { return ::winnstr(w, s, n); }
+  // Get a string of characters from the window into the buffer s. Retrieve
+  // at most n characters, if n is negative retrieve all characters up to the
+  // end of the current line. Attributes are stripped from the characters.
+
+  int            instr(int y, int x, char *s, int n=-1) {
+    return ::mvwinnstr(w, y, x, s, n); }
+  // Move the cursor to the requested position and then perform the instr()
+  // as described above.
+
+  int            scanw(const char* fmt, ...)
+    // Perform a scanw function from the window.
+#if __GNUG__ >= 2
+    __attribute__ ((format (scanf, 2, 3)));
+#else
+  ;
+#endif
+
+  int            scanw(const char*, va_list);
+    // Perform a scanw function from the window.
+
+  int            scanw(int y, int x, const char* fmt, ...)
+    // Move the cursor to the requested position and then perform a scanw
+    // from the window.
+#if __GNUG__ >= 2
+    __attribute__ ((format (scanf, 4, 5)));
+#else
+  ;
+#endif
+
+  int            scanw(int y, int x, const char* fmt, va_list);
+    // Move the cursor to the requested position and then perform a scanw
+    // from the window.
+
+  // -------------------------------------------------------------------------
+  // output
+  // -------------------------------------------------------------------------
+  int            addch(const chtype ch) { return ::waddch(w, ch); }
+  // Put attributed character to the window.
+
+  int            addch(int y, int x, const chtype ch) {
+    return ::mvwaddch(w, y, x, ch); }
+  // Move cursor to the requested position and then put attributed character
+  // to the window.
+
+  int            echochar(const chtype ch) { return ::wechochar(w, ch); }
+  // Put attributed character to the window and refresh it immediately.
+
+  int            addstr(const char* str, int n=-1) {
+    return ::waddnstr(w, str, n); }
+  // Write the string str to the window, stop writing if the terminating
+  // NUL or the limit n is reached. If n is negative, it is ignored.
+
+  int            addstr(int y, int x, const char * str, int n=-1) {
+    return ::mvwaddnstr(w, y, x, str, n); }
+  // Move the cursor to the requested position and then perform the addchstr
+  // as described above.
+
+  int            addchstr(const chtype* str, int n=-1) {
+    return ::waddchnstr(w, str, n); }
+  // Write the string str to the window, stop writing if the terminating
+  // NUL or the limit n is reached. If n is negative, it is ignored.
+
+  int            addchstr(int y, int x, const chtype * str, int n=-1) {
+    return ::mvwaddchnstr(w, y, x, str, n); }
+  // Move the cursor to the requested position and then perform the addchstr
+  // as described above.
+
+  int            printw(const char* fmt, ...)
+    // Do a formatted print to the window.
+#if (__GNUG__ >= 2) && !defined(printf)
+    __attribute__ ((format (printf, 2, 3)));
+#else
+  ;
+#endif
+
+  int            printw(int y, int x, const char * fmt, ...)
+    // Move the cursor and then do a formatted print to the window.
+#if (__GNUG__ >= 2) && !defined(printf)
+    __attribute__ ((format (printf, 4, 5)));
+#else
+  ;
+#endif
+
+  int            printw(const char* fmt, va_list args);
+    // Do a formatted print to the window.
+
+  int            printw(int y, int x, const char * fmt, va_list args);
+    // Move the cursor and then do a formatted print to the window.
+
+  chtype         inch() const { return ::winch(w); }
+  // Retrieve attributed character under the current cursor position.
+
+  chtype         inch(int y, int x) { return ::mvwinch(w, y, x); }
+  // Move cursor to requested position and then retrieve attributed character
+  // at this position.
+
+  int            inchstr(chtype* str, int n=-1) {
+    return ::winchnstr(w, str, n); }
+  // Read the string str from the window, stop reading if the terminating
+  // NUL or the limit n is reached. If n is negative, it is ignored.
+
+  int            inchstr(int y, int x, chtype * str, int n=-1) {
+    return ::mvwinchnstr(w, y, x, str, n); }
+  // Move the cursor to the requested position and then perform the inchstr
+  // as described above.
+
+  int            insch(chtype ch) { return ::winsch(w, ch); }
+  // Insert attributed character into the window before current cursor
+  // position.
+
+  int            insch(int y, int x, chtype ch) {
+    return ::mvwinsch(w, y, x, ch); }
+  // Move cursor to requested position and then insert the attributed
+  // character before that position.
+
+  int            insertln() { return ::winsdelln(w, 1); }
+  // Insert an empty line above the current line.
+
+  int            insdelln(int n=1) { return ::winsdelln(w, n); }
+  // If n>0 insert that many lines above the current line. If n<0 delete
+  // that many lines beginning with the current line.
+
+  int            insstr(const char *s, int n=-1) {
+    return ::winsnstr(w, s, n); }
+  // Insert the string into the window before the current cursor position.
+  // Insert stops at end of string or when the limit n is reached. If n is
+  // negative, it is ignored.
+
+  int            insstr(int y, int x, const char *s, int n=-1) {
+    return ::mvwinsnstr(w, y, x, s, n); }
+  // Move the cursor to the requested position and then perform the insstr()
+  // as described above.
+
+  int            attron (chtype at) { return ::wattron (w, at); }
+  // Switch on the window attributes;
+
+  int            attroff(chtype at) { return ::wattroff(w, static_cast<int>(at)); }
+  // Switch off the window attributes;
+
+  int            attrset(chtype at) { return ::wattrset(w, static_cast<int>(at)); }
+  // Set the window attributes;
+
+  chtype         attrget() { return ::getattrs(w); }
+  // Get the window attributes;
+
+  int            color_set(short color_pair_number, void* opts=NULL) {
+    return ::wcolor_set(w, color_pair_number, opts); }
+  // Set the window color attribute;
+
+  int            chgat(int n, attr_t attr, short color, const void *opts=NULL) {
+    return ::wchgat(w, n, attr, color, opts); }
+  // Change the attributes of the next n characters in the current line. If
+  // n is negative or greater than the number of remaining characters in the
+  // line, the attributes will be changed up to the end of the line.
+
+  int            chgat(int y, int x,
+		       int n, attr_t attr, short color, const void *opts=NULL) {
+    return ::mvwchgat(w, y, x, n, attr, color, opts); }
+  // Move the cursor to the requested position and then perform chgat() as
+  // described above.
+
+  // -------------------------------------------------------------------------
+  // background
+  // -------------------------------------------------------------------------
+  chtype         getbkgd() const { return ::getbkgd(w); }
+  // Get current background setting.
+
+  int            bkgd(const chtype ch) { return ::wbkgd(w, ch); }
+  // Set the background property and apply it to the window.
+
+  void           bkgdset(chtype ch) { ::wbkgdset(w, ch); }
+  // Set the background property.
+
+  // -------------------------------------------------------------------------
+  // borders
+  // -------------------------------------------------------------------------
+  int            box(chtype vert=0, chtype  hor=0) {
+    return ::wborder(w, vert, vert, hor, hor, 0, 0, 0, 0); }
+  // Draw a box around the window with the given vertical and horizontal
+  // drawing characters. If you specify a zero as character, curses will try
+  // to find a "nice" character.
+
+  int            border(chtype left=0, chtype right=0,
+			chtype top =0, chtype bottom=0,
+			chtype top_left =0, chtype top_right=0,
+			chtype bottom_left =0, chtype bottom_right=0) {
+    return ::wborder(w, left, right, top, bottom, top_left, top_right,
+		     bottom_left, bottom_right); }
+  // Draw a border around the window with the given characters for the
+  // various parts of the border. If you pass zero for a character, curses
+  // will try to find "nice" characters.
+
+  // -------------------------------------------------------------------------
+  // lines and boxes
+  // -------------------------------------------------------------------------
+  int            hline(int len, chtype ch=0) { return ::whline(w, ch, len); }
+  // Draw a horizontal line of len characters with the given character. If
+  // you pass zero for the character, curses will try to find a "nice" one.
+
+  int            hline(int y, int x, int len, chtype ch=0) {
+    return ::mvwhline(w, y, x, ch, len); }
+  // Move the cursor to the requested position and then draw a horizontal line.
+
+  int            vline(int len, chtype ch=0) { return ::wvline(w, ch, len); }
+  // Draw a vertical line of len characters with the given character. If
+  // you pass zero for the character, curses will try to find a "nice" one.
+
+  int            vline(int y, int x, int len, chtype ch=0) {
+    return ::mvwvline(w, y, x, ch, len); }
+  // Move the cursor to the requested position and then draw a vertical line.
+
+  // -------------------------------------------------------------------------
+  // erasure
+  // -------------------------------------------------------------------------
+  int            erase() { return ::werase(w); }
+  // Erase the window.
+
+  int            clear() { return ::wclear(w); }
+  // Clear the window.
+
+  int            clearok(bool bf) { return ::clearok(w, bf); }
+  // Set/Reset the clear flag. If set, the next refresh() will clear the
+  // screen.
+
+  int            clrtobot() { return ::wclrtobot(w); }
+  // Clear to the end of the window.
+
+  int            clrtoeol() { return ::wclrtoeol(w); }
+  // Clear to the end of the line.
+
+  int            delch() { return ::wdelch(w); }
+  // Delete character under the cursor.
+
+  int            delch(int y, int x) { return ::mvwdelch(w, y, x); }
+  // Move cursor to requested position and delete the character under the
+  // cursor.
+
+  int            deleteln() { return ::winsdelln(w, -1); }
+  // Delete the current line.
+
+  // -------------------------------------------------------------------------
+  // screen control
+  // -------------------------------------------------------------------------
+  int            scroll(int amount=1) { return ::wscrl(w, amount); }
+  // Scroll amount lines. If amount is positive, scroll up, otherwise
+  // scroll down.
+
+  int            scrollok(bool bf) { return ::scrollok(w, bf); }
+  // If bf is TRUE, window scrolls if cursor is moved off the bottom
+  // edge of the window or a scrolling region, otherwise the cursor is left
+  // at the bottom line.
+
+  int            setscrreg(int from, int to) {
+    return ::wsetscrreg(w, from, to); }
+  // Define a soft scrolling region.
+
+  int            idlok(bool bf) { return ::idlok(w, bf); }
+  // If bf is TRUE, use insert/delete line hardware support if possible.
+  // Otherwise do it in software.
+
+  void           idcok(bool bf) { ::idcok(w, bf); }
+  // If bf is TRUE, use insert/delete character hardware support if possible.
+  // Otherwise do it in software.
+
+  int            touchline(int s, int c) { return ::touchline(w, s, c); }
+  // Mark the given lines as modified.
+
+  int            touchwin()   { return ::wtouchln(w, 0, height(), 1); }
+  // Mark the whole window as modified.
+
+  int            untouchwin() { return ::wtouchln(w, 0, height(), 0); }
+  // Mark the whole window as unmodified.
+
+  int            touchln(int s, int cnt, bool changed=TRUE) {
+    return ::wtouchln(w, s, cnt, static_cast<int>(changed ? 1 : 0)); }
+  // Mark cnt lines beginning from line s as changed or unchanged, depending
+  // on the value of the changed flag.
+
+  bool           is_linetouched(int line) const {
+    return (::is_linetouched(w, line) ? TRUE:FALSE); }
+  // Return TRUE if line is marked as changed, FALSE otherwise
+
+  bool           is_wintouched() const {
+    return (::is_wintouched(w) ? TRUE:FALSE); }
+  // Return TRUE if window is marked as changed, FALSE otherwise
+
+  int            leaveok(bool bf) { return ::leaveok(w, bf); }
+  // If bf is TRUE, curses will leave the cursor after an update whereever
+  // it is after the update.
+
+  int            redrawln(int from, int n) { return ::wredrawln(w, from, n); }
+  // Redraw n lines starting from the requested line
+
+  int            redrawwin() { return ::wredrawln(w, 0, height()); }
+  // Redraw the whole window
+
+  int            doupdate()  { return ::doupdate(); }
+  // Do all outputs to make the physical screen looking like the virtual one
+
+  void           syncdown()  { ::wsyncdown(w); }
+  // Propagate the changes down to all descendant windows
+
+  void           syncup()    { ::wsyncup(w); }
+  // Propagate the changes up in the hierarchy
+
+  void           cursyncup() { ::wcursyncup(w); }
+  // Position the cursor in all ancestor windows corresponding to our setting
+
+  int            syncok(bool bf) { return ::syncok(w, bf); }
+  // If called with bf=TRUE, syncup() is called whenever the window is changed
+
+#ifndef _no_flushok
+  int            flushok(bool bf) { return ::flushok(w, bf); }
+#endif
+
+  void           immedok(bool bf) { ::immedok(w, bf); }
+  // If called with bf=TRUE, any change in the window will cause an
+  // automatic immediate refresh()
+
+  int            intrflush(bool bf) { return ::intrflush(w, bf); }
+
+  int            keypad(bool bf) { return ::keypad(w, bf); }
+  // If called with bf=TRUE, the application will interpret function keys.
+
+  int            nodelay(bool bf) { return ::nodelay(w, bf); }
+
+  int            meta(bool bf) { return ::meta(w, bf); }
+  // If called with bf=TRUE, keys may generate 8-Bit characters. Otherwise
+  // 7-Bit characters are generated.
+
+  int            standout() { return ::wstandout(w); }
+  // Enable "standout" attributes
+
+  int            standend() { return ::wstandend(w); }
+  // Disable "standout" attributes
+
+  // -------------------------------------------------------------------------
+  // The next two are virtual, because we redefine them in the
+  // NCursesPanel class.
+  // -------------------------------------------------------------------------
+  virtual int    refresh() { return ::wrefresh(w); }
+  // Propagate the changes in this window to the virtual screen and call
+  // doupdate(). This is redefined in NCursesPanel.
+
+  virtual int    noutrefresh() { return ::wnoutrefresh(w); }
+  // Propagate the changes in this window to the virtual screen. This is
+  // redefined in NCursesPanel.
+
+  // -------------------------------------------------------------------------
+  // multiple window control
+  // -------------------------------------------------------------------------
+  int            overlay(NCursesWindow& win) {
+    return ::overlay(w, win.w); }
+  // Overlay this window over win.
+
+  int            overwrite(NCursesWindow& win) {
+    return ::overwrite(w, win.w); }
+  // Overwrite win with this window.
+
+  int            copywin(NCursesWindow& win,
+			 int sminrow, int smincol,
+			 int dminrow, int dmincol,
+			 int dmaxrow, int dmaxcol, bool overlaywin=TRUE) {
+    return ::copywin(w, win.w, sminrow, smincol, dminrow, dmincol,
+		     dmaxrow, dmaxcol, static_cast<int>(overlaywin ? 1 : 0)); }
+  // Overlay or overwrite the rectangle in win given by dminrow,dmincol,
+  // dmaxrow,dmaxcol with the rectangle in this window beginning at
+  // sminrow,smincol.
+
+  // -------------------------------------------------------------------------
+  // Extended functions
+  // -------------------------------------------------------------------------
+#if defined(NCURSES_EXT_FUNCS) && (NCURSES_EXT_FUNCS != 0)
+  int            wresize(int newLines, int newColumns) {
+    return ::wresize(w, newLines, newColumns); }
+#endif
+
+  // -------------------------------------------------------------------------
+  // Mouse related
+  // -------------------------------------------------------------------------
+  bool has_mouse() const;
+  // Return TRUE if terminal supports a mouse, FALSE otherwise
+
+  // -------------------------------------------------------------------------
+  // traversal support
+  // -------------------------------------------------------------------------
+  NCursesWindow*  child() { return subwins; }
+  // Get the first child window.
+
+  NCursesWindow*  sibling() { return sib; }
+  // Get the next child of my parent.
+
+  NCursesWindow*  parent() { return par; }
+  // Get my parent.
+
+  bool isDescendant(NCursesWindow& win);
+  // Return TRUE if win is a descendant of this.
+};
+
+// -------------------------------------------------------------------------
+// We leave this here for compatibility reasons.
+// -------------------------------------------------------------------------
+class NCURSES_IMPEXP NCursesColorWindow : public NCursesWindow
+{
+public:
+  NCursesColorWindow(WINDOW* &window)   // useful only for stdscr
+    : NCursesWindow(window) {
+      useColors(); }
+
+  NCursesColorWindow(int nlines,        // number of lines
+		     int ncols,         // number of columns
+		     int begin_y,       // line origin
+		     int begin_x)       // col origin
+    : NCursesWindow(nlines, ncols, begin_y, begin_x) {
+      useColors(); }
+
+  NCursesColorWindow(NCursesWindow& parentWin,// parent window
+		     int nlines,        // number of lines
+		     int ncols,         // number of columns
+		     int begin_y,       // absolute or relative
+		     int begin_x,       //   origins:
+		     char absrel = 'a') // if `a', by & bx are
+    : NCursesWindow(parentWin,
+		    nlines, ncols,	// absolute screen pos,
+		    begin_y, begin_x,   // else if `r', they are
+		    absrel ) {          // relative to par origin
+      useColors(); }
+};
+
+// These enum definitions really belong inside the NCursesPad class, but only
+// recent compilers support that feature.
+
+  typedef enum {
+    REQ_PAD_REFRESH = KEY_MAX + 1,
+    REQ_PAD_UP,
+    REQ_PAD_DOWN,
+    REQ_PAD_LEFT,
+    REQ_PAD_RIGHT,
+    REQ_PAD_EXIT
+  } Pad_Request;
+
+  const Pad_Request PAD_LOW  = REQ_PAD_REFRESH;   // lowest  op-code
+  const Pad_Request PAD_HIGH = REQ_PAD_EXIT;      // highest op-code
+
+// -------------------------------------------------------------------------
+// Pad Support. We allow an association of a pad with a "real" window
+// through which the pad may be viewed.
+// -------------------------------------------------------------------------
+class NCURSES_IMPEXP NCursesPad : public NCursesWindow
+{
+private:
+  NCursesWindow* viewWin;       // the "viewport" window
+  NCursesWindow* viewSub;       // the "viewport" subwindow
+
+  int h_gridsize, v_gridsize;
+
+protected:
+  int min_row, min_col;         // top left row/col of the pads display area
+
+  NCursesWindow* Win(void) const {
+    // Get the window into which the pad should be copied (if any)
+    return (viewSub?viewSub:(viewWin?viewWin:0));
+  }
+
+  NCursesWindow* getWindow(void) const {
+    return viewWin;
+  }
+
+  NCursesWindow* getSubWindow(void) const {
+    return viewSub;
+  }
+
+  virtual int driver (int key);      // Virtualize keystroke key
+  // The driver translates the keystroke c into an Pad_Request
+
+  virtual void OnUnknownOperation(int pad_req) {
+    ::beep();
+  }
+  // This is called if the driver returns an unknown op-code
+
+  virtual void OnNavigationError(int pad_req) {
+    ::beep();
+  }
+  // This is called if a navigation request couldn't be satisfied
+
+  virtual void OnOperation(int pad_req) {
+  };
+  // OnOperation is called if a Pad_Operation was executed and just before
+  // the refresh() operation is done.
+
+public:
+  NCursesPad(int nlines, int ncols);
+  // create a pad with the given size
+
+  NCursesPad& operator=(const NCursesPad& rhs)
+  {
+    if (this != &rhs) {
+      *this = rhs;
+      NCursesWindow::operator=(rhs);
+    }
+    return *this;
+  }
+
+  NCursesPad(const NCursesPad& rhs)
+    : NCursesWindow(rhs),
+      viewWin(rhs.viewWin),
+      viewSub(rhs.viewSub),
+      h_gridsize(rhs.h_gridsize),
+      v_gridsize(rhs.v_gridsize),
+      min_row(rhs.min_row),
+      min_col(rhs.min_col)
+  {
+  }
+
+  virtual ~NCursesPad() {}
+
+  int echochar(const chtype ch) { return ::pechochar(w, ch); }
+  // Put the attributed character onto the pad and immediately do a
+  // prefresh().
+
+  int refresh();
+  // If a viewport is defined the pad is displayed in this window, otherwise
+  // this is a noop.
+
+  int refresh(int pminrow, int pmincol,
+	      int sminrow, int smincol,
+	      int smaxrow, int smaxcol) {
+    return ::prefresh(w, pminrow, pmincol,
+		      sminrow, smincol, smaxrow, smaxcol);
+  }
+  // The coordinates sminrow,smincol,smaxrow,smaxcol describe a rectangle
+  // on the screen. <b>refresh</b> copies a rectangle of this size beginning
+  // with top left corner pminrow,pmincol onto the screen and calls doupdate().
+
+  int noutrefresh();
+  // If a viewport is defined the pad is displayed in this window, otherwise
+  // this is a noop.
+
+  int noutrefresh(int pminrow, int pmincol,
+		  int sminrow, int smincol,
+		  int smaxrow, int smaxcol) {
+    return ::pnoutrefresh(w, pminrow, pmincol,
+			  sminrow, smincol, smaxrow, smaxcol);
+  }
+  // Does the same as refresh() but without calling doupdate().
+
+  virtual void setWindow(NCursesWindow& view, int v_grid = 1, int h_grid = 1);
+  // Add the window "view" as viewing window to the pad.
+
+  virtual void setSubWindow(NCursesWindow& sub);
+  // Use the subwindow "sub" of the viewport window for the actual viewing.
+  // The full viewport window is usually used to provide some decorations
+  // like frames, titles etc.
+
+  virtual void operator() (void);
+  // Perform Pad's operation
+};
+
+// A FramedPad is constructed always with a viewport window. This viewport
+// will be framed (by a box() command) and the interior of the box is the
+// viewport subwindow. On the frame we display scrollbar sliders.
+class NCURSES_IMPEXP NCursesFramedPad : public NCursesPad
+{
+protected:
+  virtual void OnOperation(int pad_req);
+
+public:
+  NCursesFramedPad(NCursesWindow& win, int nlines, int ncols,
+		   int v_grid = 1, int h_grid = 1)
+    : NCursesPad(nlines, ncols) {
+    NCursesPad::setWindow(win, v_grid, h_grid);
+    NCursesPad::setSubWindow(*(new NCursesWindow(win)));
+  }
+  // Construct the FramedPad with the given Window win as viewport.
+
+  virtual ~NCursesFramedPad() {
+    delete getSubWindow();
+  }
+
+  void setWindow(NCursesWindow& view, int v_grid = 1, int h_grid = 1) {
+    err_handler("Operation not allowed");
+  }
+  // Disable this call; the viewport is already defined
+
+  void setSubWindow(NCursesWindow& sub) {
+    err_handler("Operation not allowed");
+  }
+  // Disable this call; the viewport subwindow is already defined
+
+};
+
+#endif /* NCURSES_CURSESW_H_incl */
diff --git a/c++/cursslk.cc b/c++/cursslk.cc
new file mode 100644
index 0000000..cfbc9da
--- /dev/null
+++ b/c++/cursslk.cc
@@ -0,0 +1,132 @@
+// * this is for making emacs happy: -*-Mode: C++;-*-
+/****************************************************************************
+ * Copyright (c) 1998-2003,2005 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, 1997                                          *
+ ****************************************************************************/
+
+#include "internal.h"
+#include "cursslk.h"
+#include "cursesapp.h"
+
+MODULE_ID("$Id: cursslk.cc,v 1.15 2005/08/06 22:12:36 tom Exp $")
+
+Soft_Label_Key_Set::Soft_Label_Key&
+  Soft_Label_Key_Set::Soft_Label_Key::operator=(char *text)
+{
+  delete[] label;
+  label = new char[1 + ::strlen(text)];
+  (::strcpy)(label,text);
+  return *this;
+}
+
+long Soft_Label_Key_Set::count      = 0L;
+int  Soft_Label_Key_Set::num_labels = 0;
+
+Soft_Label_Key_Set::Label_Layout
+  Soft_Label_Key_Set::format = None;
+
+void Soft_Label_Key_Set::init()
+{
+  slk_array = new Soft_Label_Key[num_labels];
+  for(int i=0; i < num_labels; i++) {
+    slk_array[i].num = i+1;
+  }
+  b_attrInit = FALSE;
+}
+
+Soft_Label_Key_Set::Soft_Label_Key_Set()
+  : b_attrInit(FALSE),
+    slk_array(NULL)
+{
+  if (format==None)
+    Error("No default SLK layout");
+  init();
+}
+
+Soft_Label_Key_Set::Soft_Label_Key_Set(Soft_Label_Key_Set::Label_Layout fmt)
+  : b_attrInit(FALSE),
+    slk_array(NULL)
+{
+  if (fmt==None)
+    Error("Invalid SLK Layout");
+  if (count++==0) {
+    format = fmt;
+    if (ERR == ::slk_init(static_cast<int>(fmt)))
+      Error("slk_init");
+    num_labels = (fmt>=PC_Style?12:8);
+  }
+  else if (fmt!=format)
+    Error("All SLKs must have same layout");
+  init();
+}
+
+Soft_Label_Key_Set::~Soft_Label_Key_Set() {
+  if (!::isendwin())
+    clear();
+  delete[] slk_array;
+  count--;
+}
+
+Soft_Label_Key_Set::Soft_Label_Key& Soft_Label_Key_Set::operator[](int i) {
+  if (i<1 || i>num_labels)
+    Error("Invalid Label index");
+  return slk_array[i-1];
+}
+
+void Soft_Label_Key_Set::activate_label(int i, bool bf) {
+  if (!b_attrInit) {
+    NCursesApplication* A = NCursesApplication::getApplication();
+    if (A) attrset(A->labels());
+    b_attrInit = TRUE;
+  }
+  Soft_Label_Key& K = (*this)[i];
+  if (ERR==::slk_set(K.num,bf?K.label:"",K.format))
+    Error("slk_set");
+  noutrefresh();
+}
+
+void Soft_Label_Key_Set::activate_labels(bool bf)
+{
+  if (!b_attrInit) {
+    NCursesApplication* A = NCursesApplication::getApplication();
+    if (A) attrset(A->labels());
+    b_attrInit = TRUE;
+  }
+  for(int i=1; i <= num_labels; i++) {
+    Soft_Label_Key& K = (*this)[i];
+    if (ERR==::slk_set(K.num,bf?K.label:"",K.format))
+      Error("slk_set");
+  }
+  if (bf)
+    restore();
+  else
+    clear();
+  noutrefresh();
+}
diff --git a/c++/cursslk.h b/c++/cursslk.h
new file mode 100644
index 0000000..091695e
--- /dev/null
+++ b/c++/cursslk.h
@@ -0,0 +1,238 @@
+// * this is for making emacs happy: -*-Mode: C++;-*-
+/****************************************************************************
+ * Copyright (c) 1998-2003,2005 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, 1997                                          *
+ ****************************************************************************/
+
+// $Id: cursslk.h,v 1.13 2005/05/28 21:58:18 tom Exp $
+
+#ifndef NCURSES_CURSSLK_H_incl
+#define NCURSES_CURSSLK_H_incl
+
+#include <cursesw.h>
+
+class NCURSES_IMPEXP Soft_Label_Key_Set {
+public:
+  // This inner class represents the attributes of a Soft Label Key (SLK)
+  class NCURSES_IMPEXP Soft_Label_Key {
+    friend class Soft_Label_Key_Set;
+  public:
+    typedef enum { Left=0, Center=1, Right=2 } Justification;
+
+  private:
+    char *label;           // The Text of the Label
+    Justification format;  // The Justification
+    int num;               // The number of the Label
+
+    Soft_Label_Key() : label(NULL), format(Left), num(-1) {
+    }
+
+    virtual ~Soft_Label_Key() {
+      delete[] label;
+    };
+
+  public:
+    // Set the text of the Label
+    Soft_Label_Key& operator=(char *text);
+
+    // Set the Justification of the Label
+    Soft_Label_Key& operator=(Justification just) {
+      format = just;
+      return *this;
+    }
+
+    // Retrieve the text of the label
+    inline char* operator()(void) const {
+      return label;
+    }
+
+    Soft_Label_Key& operator=(const Soft_Label_Key& rhs)
+    {
+      if (this != &rhs) {
+        *this = rhs;
+      }
+      return *this;
+    }
+
+    Soft_Label_Key(const Soft_Label_Key& rhs)
+      : label(NULL),
+        format(rhs.format),
+        num(rhs.num)
+    {
+      *this = rhs.label;
+    }
+  };
+
+public:
+  typedef enum {
+    None                = -1,
+    Three_Two_Three     = 0,
+    Four_Four           = 1,
+    PC_Style            = 2,
+    PC_Style_With_Index = 3
+  } Label_Layout;
+
+private:
+  static long NCURSES_IMPEXP count;               // Number of Key Sets
+  static Label_Layout NCURSES_IMPEXP  format;     // Layout of the Key Sets
+  static int  NCURSES_IMPEXP num_labels;          // Number Of Labels in Key Sets
+  bool NCURSES_IMPEXP b_attrInit;                 // Are attributes initialized
+
+  Soft_Label_Key *slk_array;       // The array of SLK's
+
+  // Init the Key Set
+  void init();
+
+  // Activate or Deactivate Label# i, Label counting starts with 1!
+  void activate_label(int i, bool bf=TRUE);
+
+  // Activate of Deactivate all Labels
+  void activate_labels(bool bf);
+
+protected:
+  inline void Error (const char* msg) const THROWS(NCursesException) {
+    THROW(new NCursesException (msg));
+  }
+
+  // Remove SLK's from screen
+  void clear() {
+    if (ERR==::slk_clear())
+      Error("slk_clear");
+  }
+
+  // Restore them
+  void restore() {
+    if (ERR==::slk_restore())
+      Error("slk_restore");
+  }
+
+public:
+
+  // Construct a Key Set, use the most comfortable layout as default.
+  // You must create a Soft_Label_Key_Set before you create any object of
+  // the NCursesWindow, NCursesPanel or derived classes. (Actually before
+  // ::initscr() is called).
+  Soft_Label_Key_Set(Label_Layout fmt);
+
+  // This constructor assumes, that you already constructed a Key Set
+  // with a layout by the constructor above. This layout will be reused.
+  NCURSES_IMPEXP Soft_Label_Key_Set();
+
+  Soft_Label_Key_Set& operator=(const Soft_Label_Key_Set& rhs)
+  {
+    if (this != &rhs) {
+      *this = rhs;
+      init();		// allocate a new slk_array[]
+    }
+    return *this;
+  }
+
+  Soft_Label_Key_Set(const Soft_Label_Key_Set& rhs)
+    : b_attrInit(rhs.b_attrInit),
+      slk_array(NULL)
+  {
+    init();		// allocate a new slk_array[]
+  }
+
+  virtual ~Soft_Label_Key_Set();
+
+  // Get Label# i. Label counting starts with 1!
+  NCURSES_IMPEXP Soft_Label_Key& operator[](int i);
+
+  // Retrieve number of Labels
+  inline int labels() const { return num_labels; }
+
+  // Refresh the SLK portion of the screen
+  inline void refresh() {
+    if (ERR==::slk_refresh())
+      Error("slk_refresh");
+  }
+
+  // Mark the SLK portion of the screen for refresh, defer actual refresh
+  // until next update call.
+  inline void noutrefresh() {
+    if (ERR==::slk_noutrefresh())
+      Error("slk_noutrefresh");
+  }
+
+  // Mark the whole SLK portion of the screen as modified
+  inline void touch() {
+    if (ERR==::slk_touch())
+      Error("slk_touch");
+  }
+
+  // Activate Label# i
+  inline void show(int i) {
+    activate_label(i,FALSE);
+    activate_label(i,TRUE);
+  }
+
+  // Hide Label# i
+  inline void hide(int i) {
+    activate_label(i,FALSE);
+  }
+
+  // Show all Labels
+  inline void show() {
+    activate_labels(FALSE);
+    activate_labels(TRUE);
+  }
+
+  // Hide all Labels
+  inline void hide() {
+    activate_labels(FALSE);
+  }
+
+  inline void attron(attr_t attrs) {
+    if (ERR==::slk_attron(attrs))
+      Error("slk_attron");
+  }
+
+  inline void attroff(attr_t attrs) {
+    if (ERR==::slk_attroff(attrs))
+      Error("slk_attroff");
+  }
+
+  inline void attrset(attr_t attrs) {
+    if (ERR==::slk_attrset(attrs))
+      Error("slk_attrset");
+  }
+
+  inline void color(short color_pair_number) {
+    if (ERR==::slk_color(color_pair_number))
+      Error("slk_color");
+  }
+
+  inline attr_t attr() const {
+    return ::slk_attr();
+  }
+};
+
+#endif /* NCURSES_CURSSLK_H_incl */
diff --git a/c++/demo.cc b/c++/demo.cc
new file mode 100644
index 0000000..ddd5f2b
--- /dev/null
+++ b/c++/demo.cc
@@ -0,0 +1,563 @@
+// * This makes emacs happy -*-Mode: C++;-*-
+/****************************************************************************
+ * Copyright (c) 1998-2007,2008 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.                                                           *
+ ****************************************************************************/
+
+/*
+ *   Silly demo program for the NCursesPanel class.
+ *
+ *   written by Anatoly Ivasyuk (anatoly@nick.csh.rit.edu)
+ *
+ *   Demo code for NCursesMenu and NCursesForm written by
+ *   Juergen Pfeifer
+ *
+ * $Id: demo.cc,v 1.38 2008/08/04 17:16:57 tom Exp $
+ */
+
+#include "internal.h"
+#include "cursesapp.h"
+#include "cursesm.h"
+#include "cursesf.h"
+
+extern "C" unsigned int sleep(unsigned int);
+
+#undef index // needed for NeXT
+
+//
+// -------------------------------------------------------------------------
+//
+class SillyDemo
+{
+  public:
+  void run(int sleeptime) {
+
+    NCursesPanel *mystd = new NCursesPanel();
+
+    //  Make a few small demo panels
+
+    NCursesPanel *u = new NCursesPanel(8, 20, 12, 4);
+    NCursesPanel *v = new NCursesPanel(8, 20, 10, 6);
+    NCursesPanel *w = new NCursesPanel(8, 20, 8, 8);
+    NCursesPanel *x = new NCursesPanel(8, 20, 6, 10);
+    NCursesPanel *y = new NCursesPanel(8, 20, 4, 12);
+    NCursesPanel *z = new NCursesPanel(8, 30, 2, 14);
+
+    //  Draw something on the main screen, so we can see what happens
+    //  when panels get moved or deleted.
+
+    mystd->box();
+    mystd->move(mystd->height()/2, 1);
+    mystd->hline(mystd->width()-2);
+    mystd->move(1, mystd->width()/2);
+    mystd->vline(mystd->height()-2);
+    mystd->addch(0, mystd->width()/2, ACS_TTEE);
+    mystd->addch(mystd->height()-1, mystd->width()/2, ACS_BTEE);
+    mystd->addch(mystd->height()/2, 0, ACS_LTEE);
+    mystd->addch(mystd->height()/2, mystd->width()-1, ACS_RTEE);
+    mystd->addch(mystd->height()/2, mystd->width()/2, ACS_PLUS);
+
+    //  Draw frames with titles around panels so that we can see where
+    //  the panels are located.
+    u->boldframe("Win U");
+    v->frame("Win V");
+    w->boldframe("Win W");
+    x->frame("Win X");
+    y->boldframe("Win Y");
+    z->frame("Win Z");
+    if (NCursesApplication::getApplication()->useColors()) {
+      u->bkgd(' '|COLOR_PAIR(1));
+      w->bkgd(' '|COLOR_PAIR(1));
+      y->bkgd(' '|COLOR_PAIR(1));
+      v->bkgd(' '|COLOR_PAIR(2));
+      x->bkgd(' '|COLOR_PAIR(2));
+      z->bkgd(' '|COLOR_PAIR(2));
+    }
+
+    //  A refresh to any valid panel updates all panels and refreshes
+    //  the screen.  Using mystd is just convenient - We know it's always
+    //  valid until the end of the program.
+
+    mystd->refresh();
+    sleep(sleeptime);
+
+    //  Show what happens when panels are deleted and moved.
+
+    sleep(sleeptime);
+    delete u;
+    mystd->refresh();
+
+    sleep(sleeptime);
+    delete z;
+    mystd->refresh();
+
+    sleep(sleeptime);
+    delete v;
+    mystd->refresh();
+
+    // show how it looks when a panel moves
+    sleep(sleeptime);
+    y->mvwin(5, 30);
+    mystd->refresh();
+
+    sleep(sleeptime);
+    delete y;
+    mystd->refresh();
+
+    // show how it looks when you raise a panel
+    sleep(sleeptime);
+    w->top();
+    mystd->refresh();
+
+    sleep(sleeptime);
+    delete w;
+    mystd->refresh();
+
+    sleep(sleeptime);
+    delete x;
+
+    mystd->clear();
+    mystd->refresh();
+
+    //  Don't forget to clean up the main screen.  Since this is the
+    //  last thing using NCursesWindow, this has the effect of
+    //  shutting down ncurses and restoring the terminal state.
+
+    sleep(sleeptime);
+    delete mystd;
+  }
+};
+
+class UserData
+{
+private:
+  int u;
+public:
+  UserData(int x) : u(x) {}
+  int sleeptime() const { return u; }
+};
+//
+// -------------------------------------------------------------------------
+//
+template<class T> class MyAction : public NCursesUserItem<T>
+{
+public:
+  MyAction (const char* p_name,
+            const T* p_UserData)
+    : NCursesUserItem<T>(p_name, static_cast<const char*>(0), p_UserData)
+  {}
+
+  virtual ~MyAction() {}
+
+  bool action() {
+    SillyDemo a;
+    a.run(NCursesUserItem<T>::UserData()->sleeptime());
+    return FALSE;
+  }
+};
+
+template class MyAction<UserData>;
+template class NCURSES_IMPEXP NCursesUserItem<UserData>;
+
+class QuitItem : public NCursesMenuItem
+{
+public:
+  QuitItem() : NCursesMenuItem("Quit") {
+  }
+
+  bool action() {
+    return TRUE;
+  }
+};
+//
+// -------------------------------------------------------------------------
+//
+class Label : public NCursesFormField
+{
+public:
+  Label(const char* title,
+        int row, int col)
+    : NCursesFormField(1, static_cast<int>(::strlen(title)), row, col) {
+      set_value(title);
+      options_off(O_EDIT|O_ACTIVE);
+  }
+};
+//
+// -------------------------------------------------------------------------
+//
+class MyFieldType : public UserDefinedFieldType
+{
+private:
+  int chk;
+protected:
+  bool field_check(NCursesFormField& f) {
+    return TRUE;
+  }
+  bool char_check(int c) {
+    return (c==chk?TRUE:FALSE);
+  }
+public:
+  MyFieldType(int x) : chk(x) {
+  }
+};
+//
+// -------------------------------------------------------------------------
+//
+class TestForm : public NCursesForm
+{
+private:
+  NCursesFormField** F;
+  MyFieldType* mft;
+  Integer_Field *ift;
+  Enumeration_Field *eft;
+
+  static const char *weekdays[];
+
+public:
+  TestForm()
+    : NCursesForm(13, 51, (lines() - 15)/2, (cols() - 53)/2),
+      F(0),
+      mft(0),
+      ift(0),
+      eft(0)
+  {
+
+    F     = new NCursesFormField*[10];
+    mft   = new MyFieldType('X');
+    ift   = new Integer_Field(0, 1, 10);
+    eft   = new Enumeration_Field(weekdays);
+
+    F[0]  = new Label("Demo Entry Form", 0, 16);
+    F[1]  = new Label("Weekday Enum", 2, 1);
+    F[2]  = new Label("Number(1-10)", 2, 21);
+    F[3]  = new Label("Only 'X'", 2, 35);
+    F[4]  = new Label("Multiline Field (Dynamic and Scrollable)", 5, 1);
+    F[5]  = new NCursesFormField(1, 18, 3, 1);
+    F[6]  = new NCursesFormField(1, 12, 3, 21);
+    F[7]  = new NCursesFormField(1, 12, 3, 35);
+    F[8]  = new NCursesFormField(4, 46, 6, 1, 2);
+    F[9]  = new NCursesFormField();
+
+    InitForm(F, TRUE, TRUE);
+    boldframe();
+
+    F[5]->set_fieldtype(*eft);
+    F[6]->set_fieldtype(*ift);
+
+    F[7]->set_fieldtype(*mft);
+    F[7]->set_maximum_growth(20); // max. 20 characters
+    F[7]->options_off(O_STATIC);  // make field dynamic
+
+    F[8]->set_maximum_growth(10); // max. 10 lines
+    F[8]->options_off(O_STATIC);  // make field dynamic
+  }
+
+  TestForm& operator=(const TestForm& rhs)
+  {
+    if (this != &rhs) {
+      *this = rhs;
+    }
+    return *this;
+  }
+
+  TestForm(const TestForm& rhs)
+    : NCursesForm(rhs), F(0), mft(0), ift(0), eft(0)
+  {
+  }
+
+  ~TestForm() {
+    delete mft;
+    delete ift;
+    delete eft;
+  }
+};
+
+const char* TestForm::weekdays[] = {
+    "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday",
+    "Friday", "Saturday", NULL };
+//
+// -------------------------------------------------------------------------
+//
+class FormAction : public NCursesMenuItem
+{
+public:
+  FormAction(const char *s) : NCursesMenuItem(s) {
+  }
+
+  bool action() {
+    TestForm F;
+    Soft_Label_Key_Set* S = new Soft_Label_Key_Set;
+    for(int i=1; i <= S->labels(); i++) {
+      char buf[8];
+      assert(i < 100);
+      ::sprintf(buf, "Frm%02d", i);
+      (*S)[i] = buf;                                      // Text
+      (*S)[i] = Soft_Label_Key_Set::Soft_Label_Key::Left; // Justification
+    }
+    NCursesApplication::getApplication()->push(*S);
+    F();
+    NCursesApplication::getApplication()->pop();
+    delete S;
+    return FALSE;
+  }
+};
+//
+// -------------------------------------------------------------------------
+//
+class PadAction : public NCursesMenuItem
+{
+public:
+  PadAction(const char* s) : NCursesMenuItem(s) {
+  }
+
+  bool action() {
+    const int GRIDSIZE = 3;
+    const int PADSIZE  = 200;
+    unsigned gridcount = 0;
+
+    NCursesPanel mystd;
+    NCursesPanel P(mystd.lines()-2, mystd.cols()-2, 1, 1);
+    NCursesFramedPad FP(P, PADSIZE, PADSIZE);
+
+    for (int i=0; i < PADSIZE; i++) {
+      for (int j=0; j < PADSIZE; j++) {
+        if (i % GRIDSIZE == 0 && j % GRIDSIZE == 0) {
+          if (i==0 || j==0)
+            FP.addch('+');
+          else
+            FP.addch(static_cast<chtype>('A' + (gridcount++ % 26)));
+        }
+        else if (i % GRIDSIZE == 0)
+          FP.addch('-');
+        else if (j % GRIDSIZE == 0)
+          FP.addch('|');
+        else
+          FP.addch(' ');
+      }
+    }
+
+    P.label("Pad Demo", NULL);
+    FP();
+    P.clear();
+    return FALSE;
+  }
+};
+
+//
+// -------------------------------------------------------------------------
+//
+class PassiveItem : public NCursesMenuItem
+{
+public:
+  PassiveItem(const char* text) : NCursesMenuItem(text) {
+    options_off(O_SELECTABLE);
+  }
+};
+
+//
+// -------------------------------------------------------------------------
+//
+class ScanAction : public NCursesMenuItem
+{
+public:
+  ScanAction(const char* s) : NCursesMenuItem(s) {
+  }
+
+  bool action() {
+    NCursesPanel *mystd = new NCursesPanel();
+
+    NCursesPanel *w = new NCursesPanel(mystd->lines() - 2, mystd->cols() - 2, 1, 1);
+    w->box();
+    w->refresh();
+
+    NCursesPanel *s = new NCursesPanel(w->lines() - 6, w->cols() - 6, 3, 3);
+    s->scrollok(TRUE);
+    ::echo();
+
+    s->printw("Enter decimal integers.  The running total will be shown\n");
+    int nvalue = -1;
+    int result = 0;
+    while (nvalue != 0) {
+      nvalue = 0;
+      s->scanw("%d", &nvalue);
+      if (nvalue != 0) {
+        s->printw("%d: ", result += nvalue);
+      }
+      s->refresh();
+    }
+    s->printw("\nPress any key to continue...");
+    s->getch();
+
+    delete s;
+    delete w;
+    delete mystd;
+    ::noecho();
+    return FALSE;
+  }
+};
+
+//
+// -------------------------------------------------------------------------
+//
+class MyMenu : public NCursesMenu
+{
+private:
+  NCursesPanel* P;
+  NCursesMenuItem** I;
+  UserData *u;
+  #define n_items 7
+
+public:
+  MyMenu ()
+    : NCursesMenu (n_items+2, 8, (lines()-10)/2, (cols()-10)/2),
+      P(0), I(0), u(0)
+  {
+    u = new UserData(1);
+    I = new NCursesMenuItem*[1+n_items];
+    I[0] = new PassiveItem("One");
+    I[1] = new PassiveItem("Two");
+    I[2] = new MyAction<UserData> ("Silly", u);
+    I[3] = new FormAction("Form");
+    I[4] = new PadAction("Pad");
+    I[5] = new ScanAction("Scan");
+    I[6] = new QuitItem();
+    I[7] = new NCursesMenuItem(); // Terminating empty item
+
+    InitMenu(I, TRUE, TRUE);
+
+    P = new NCursesPanel(1, n_items, LINES-1, 1);
+    boldframe("Demo", "Silly");
+    P->show();
+  }
+
+  MyMenu& operator=(const MyMenu& rhs)
+  {
+    if (this != &rhs) {
+      *this = rhs;
+    }
+    return *this;
+  }
+
+  MyMenu(const MyMenu& rhs)
+    : NCursesMenu(rhs), P(0), I(0), u(0)
+  {
+  }
+
+  ~MyMenu()
+  {
+    P->hide();
+    delete P;
+    delete u;
+  }
+
+  virtual void On_Menu_Init()
+  {
+    NCursesWindow W(::stdscr);
+    P->move(0, 0);
+    P->clrtoeol();
+    for(int i=1; i<=count(); i++)
+      P->addch('0' + i);
+    P->bkgd(W.getbkgd());
+    refresh();
+  }
+
+  virtual void On_Menu_Termination()
+  {
+    P->move(0, 0);
+    P->clrtoeol();
+    refresh();
+  }
+
+  virtual void On_Item_Init(NCursesMenuItem& item)
+  {
+    P->move(0, item.index());
+    P->attron(A_REVERSE);
+    P->printw("%1d", 1+item.index());
+    P->attroff(A_REVERSE);
+    refresh();
+  }
+
+  virtual void On_Item_Termination(NCursesMenuItem& item)
+  {
+    P->move(0, item.index());
+    P->attroff(A_REVERSE);
+    P->printw("%1d", 1+item.index());
+    refresh();
+  }
+};
+//
+// -------------------------------------------------------------------------
+//
+class TestApplication : public NCursesApplication
+{
+protected:
+  int titlesize() const { return 1; }
+  void title();
+  Soft_Label_Key_Set::Label_Layout useSLKs() const {
+    return Soft_Label_Key_Set::PC_Style_With_Index;
+  }
+  void init_labels(Soft_Label_Key_Set& S) const;
+
+public:
+  TestApplication() : NCursesApplication(TRUE) {
+  }
+
+  int run();
+};
+
+void TestApplication::init_labels(Soft_Label_Key_Set& S) const
+{
+  for(int i=1; i <= S.labels(); i++) {
+    char buf[8];
+    assert(i < 100);
+    ::sprintf(buf, "Key%02d", i);
+    S[i] = buf;                                      // Text
+    S[i] = Soft_Label_Key_Set::Soft_Label_Key::Left; // Justification
+  }
+}
+
+void TestApplication::title()
+{
+  const char * const titleText = "Simple C++ Binding Demo";
+  const int len = ::strlen(titleText);
+
+  titleWindow->bkgd(screen_titles());
+  titleWindow->addstr(0, (titleWindow->cols() - len)/2, titleText);
+  titleWindow->noutrefresh();
+}
+
+
+int TestApplication::run()
+{
+  MyMenu M;
+  M();
+  return 0;
+}
+
+//
+// -------------------------------------------------------------------------
+//
+static TestApplication *Demo = new TestApplication();
diff --git a/c++/edit_cfg.sh b/c++/edit_cfg.sh
new file mode 100755
index 0000000..73c31b2
--- /dev/null
+++ b/c++/edit_cfg.sh
@@ -0,0 +1,71 @@
+#!/bin/sh
+# $Id: edit_cfg.sh,v 1.17 2008/08/30 19:44:25 tom Exp $
+##############################################################################
+# Copyright (c) 1998-2007,2008 Free Software Foundation, Inc.                #
+#                                                                            #
+# Permission is hereby granted, free of charge, to any person obtaining a    #
+# copy of this software and associated documentation files (the "Software"), #
+# to deal in the Software without restriction, including without limitation  #
+# the rights to use, copy, modify, merge, publish, distribute, distribute    #
+# with modifications, sublicense, and/or sell copies of the Software, and to #
+# permit persons to whom the Software is furnished to do so, subject to the  #
+# following conditions:                                                      #
+#                                                                            #
+# The above copyright notice and this permission notice shall be included in #
+# all copies or substantial portions of the Software.                        #
+#                                                                            #
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR #
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   #
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    #
+# THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER      #
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING    #
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER        #
+# DEALINGS IN THE SOFTWARE.                                                  #
+#                                                                            #
+# Except as contained in this notice, the name(s) of the above copyright     #
+# holders shall not be used in advertising or otherwise to promote the sale, #
+# use or other dealings in this Software without prior written               #
+# authorization.                                                             #
+##############################################################################
+#
+# Author: Thomas E. Dickey 1997-on
+#
+# Edit the default value of the etip.h file based on the autoconf-generated
+# values:
+#
+#	$1 = ncurses_cfg.h
+#	$2 = etip.h
+#
+echo "substituting autoconf'd values from $1 into $2"
+for name in \
+	CPP_HAS_PARAM_INIT \
+	CPP_HAS_STATIC_CAST \
+	ETIP_NEEDS_MATH_EXCEPTION \
+	ETIP_NEEDS_MATH_H \
+	HAVE_BUILTIN_H \
+	HAVE_GPP_BUILTIN_H \
+	HAVE_GXX_BUILTIN_H \
+	HAVE_IOSTREAM \
+	HAVE_TYPEINFO \
+	HAVE_VALUES_H \
+	IOSTREAM_NAMESPACE
+do
+	rm -f $2.bak
+	mv $2 $2.bak
+	if ( grep "[ 	]$name[ 	]1" $1 2>&1 >/dev/null)
+	then
+		value=1
+		sed -e 's/define '$name'.*$/define '$name' 1/' $2.bak >$2
+	else
+		value=0
+		sed -e 's/define '$name'.*$/define '$name' 0/' $2.bak >$2
+	fi
+	if (cmp -s $2 $2.bak)
+	then
+		echo '... '$name $value
+		mv $2.bak $2
+	else
+		echo '... '$name $value
+		rm -f $2.bak
+	fi
+done
diff --git a/c++/etip.h.in b/c++/etip.h.in
new file mode 100644
index 0000000..20642a6
--- /dev/null
+++ b/c++/etip.h.in
@@ -0,0 +1,378 @@
+// * This makes emacs happy -*-Mode: C++;-*-
+/****************************************************************************
+ * Copyright (c) 1998-2007,2008 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, 1997                                          *
+ ****************************************************************************/
+
+// $Id: etip.h.in,v 1.37 2008/08/30 19:27:32 tom Exp $
+
+#ifndef NCURSES_ETIP_H_incl
+#define NCURSES_ETIP_H_incl 1
+
+// These are substituted at configure/build time
+#ifndef HAVE_BUILTIN_H
+#define HAVE_BUILTIN_H 0
+#endif
+
+#ifndef HAVE_GXX_BUILTIN_H
+#define HAVE_GXX_BUILTIN_H 0
+#endif
+
+#ifndef HAVE_GPP_BUILTIN_H
+#define HAVE_GPP_BUILTIN_H 0
+#endif
+
+#ifndef HAVE_IOSTREAM
+#define HAVE_IOSTREAM 0
+#endif
+
+#ifndef HAVE_TYPEINFO
+#define HAVE_TYPEINFO 0
+#endif
+
+#ifndef HAVE_VALUES_H
+#define HAVE_VALUES_H 0
+#endif
+
+#ifndef ETIP_NEEDS_MATH_H
+#define ETIP_NEEDS_MATH_H 0
+#endif
+
+#ifndef ETIP_NEEDS_MATH_EXCEPTION
+#define ETIP_NEEDS_MATH_EXCEPTION 0
+#endif
+
+#ifndef CPP_HAS_PARAM_INIT
+#define CPP_HAS_PARAM_INIT 0
+#endif
+
+#ifndef CPP_HAS_STATIC_CAST
+#define CPP_HAS_STATIC_CAST 0	// workaround for g++ 2.95.3
+#endif
+
+#ifndef IOSTREAM_NAMESPACE
+#define IOSTREAM_NAMESPACE 0
+#endif
+
+#ifdef __GNUG__
+#  if ((__GNUG__ <= 2) && (__GNUC_MINOR__ < 8))
+#    if HAVE_TYPEINFO
+#      include <typeinfo>
+#    endif
+#  endif
+#endif
+
+#if defined(__GNUG__)
+#  if HAVE_BUILTIN_H || HAVE_GXX_BUILTIN_H || HAVE_GPP_BUILTIN_H
+#    if ETIP_NEEDS_MATH_H
+#      if ETIP_NEEDS_MATH_EXCEPTION
+#        undef exception
+#        define exception math_exception
+#      endif
+#      include <math.h>
+#    endif
+#    undef exception
+#    define exception builtin_exception
+#    if HAVE_GPP_BUILTIN_H
+#     include <gpp/builtin.h>
+#    elif HAVE_GXX_BUILTIN_H
+#     include <g++/builtin.h>
+#    else
+#     include <builtin.h>
+#    endif
+#    undef exception
+#  endif
+#elif defined (__SUNPRO_CC)
+#  include <generic.h>
+#endif
+
+#include <ncurses_dll.h>
+
+extern "C" {
+#if HAVE_VALUES_H
+#  include <values.h>
+#endif
+
+#include <assert.h>
+#include <eti.h>
+#include <errno.h>
+}
+
+// Language features
+#if CPP_HAS_PARAM_INIT
+#define NCURSES_PARAM_INIT(value) = value
+#else
+#define NCURSES_PARAM_INIT(value) /*nothing*/
+#endif
+
+#if CPP_HAS_STATIC_CAST
+#define STATIC_CAST(s) static_cast<s>
+#else
+#define STATIC_CAST(s) (s)
+#endif
+
+// Forward Declarations
+class NCURSES_IMPEXP NCursesPanel;
+class NCURSES_IMPEXP NCursesMenu;
+class NCURSES_IMPEXP NCursesForm;
+
+class NCURSES_IMPEXP NCursesException
+{
+public:
+  const char *message;
+  int errorno;
+
+  NCursesException (const char* msg, int err)
+    : message(msg), errorno (err)
+    {};
+
+  NCursesException (const char* msg)
+    : message(msg), errorno (E_SYSTEM_ERROR)
+    {};
+
+  NCursesException& operator=(const NCursesException& rhs)
+  {
+    errorno = rhs.errorno;
+    return *this;
+  }
+
+  NCursesException(const NCursesException& rhs)
+    : message(rhs.message), errorno(rhs.errorno)
+  {
+  }
+
+  virtual const char *classname() const {
+    return "NCursesWindow";
+  }
+
+  virtual ~NCursesException()
+  {
+  }
+};
+
+class NCURSES_IMPEXP NCursesPanelException : public NCursesException
+{
+public:
+  const NCursesPanel* p;
+
+  NCursesPanelException (const char *msg, int err) :
+    NCursesException (msg, err),
+    p (NULL)
+    {};
+
+  NCursesPanelException (const NCursesPanel* panel,
+			 const char *msg,
+			 int err) :
+    NCursesException (msg, err),
+    p (panel)
+    {};
+
+  NCursesPanelException (int err) :
+    NCursesException ("panel library error", err),
+    p (NULL)
+    {};
+
+  NCursesPanelException (const NCursesPanel* panel,
+			 int err) :
+    NCursesException ("panel library error", err),
+    p (panel)
+    {};
+
+  NCursesPanelException& operator=(const NCursesPanelException& rhs)
+  {
+    if (this != &rhs) {
+      NCursesException::operator=(rhs);
+      p = rhs.p;
+    }
+    return *this;
+  }
+
+  NCursesPanelException(const NCursesPanelException& rhs)
+    : NCursesException(rhs), p(rhs.p)
+  {
+  }
+
+  virtual const char *classname() const {
+    return "NCursesPanel";
+  }
+
+  virtual ~NCursesPanelException()
+  {
+  }
+};
+
+class NCURSES_IMPEXP NCursesMenuException : public NCursesException
+{
+public:
+  const NCursesMenu* m;
+
+  NCursesMenuException (const char *msg, int err) :
+    NCursesException (msg, err),
+    m (NULL)
+    {};
+
+  NCursesMenuException (const NCursesMenu* menu,
+			const char *msg,
+			int err) :
+    NCursesException (msg, err),
+    m (menu)
+    {};
+
+  NCursesMenuException (int err) :
+    NCursesException ("menu library error", err),
+    m (NULL)
+    {};
+
+  NCursesMenuException (const NCursesMenu* menu,
+			int err) :
+    NCursesException ("menu library error", err),
+    m (menu)
+    {};
+
+  NCursesMenuException& operator=(const NCursesMenuException& rhs)
+  {
+    if (this != &rhs) {
+      NCursesException::operator=(rhs);
+      m = rhs.m;
+    }
+    return *this;
+  }
+
+  NCursesMenuException(const NCursesMenuException& rhs)
+    : NCursesException(rhs), m(rhs.m)
+  {
+  }
+
+  virtual const char *classname() const {
+    return "NCursesMenu";
+  }
+
+  virtual ~NCursesMenuException()
+  {
+  }
+};
+
+class NCURSES_IMPEXP NCursesFormException : public NCursesException
+{
+public:
+  const NCursesForm* f;
+
+  NCursesFormException (const char *msg, int err) :
+    NCursesException (msg, err),
+    f (NULL)
+    {};
+
+  NCursesFormException (const NCursesForm* form,
+			const char *msg,
+			int err) :
+    NCursesException (msg, err),
+    f (form)
+    {};
+
+  NCursesFormException (int err) :
+    NCursesException ("form library error", err),
+    f (NULL)
+    {};
+
+  NCursesFormException (const NCursesForm* form,
+			int err) :
+    NCursesException ("form library error", err),
+    f (form)
+    {};
+
+  NCursesFormException& operator=(const NCursesFormException& rhs)
+  {
+    if (this != &rhs) {
+      NCursesException::operator=(rhs);
+      f = rhs.f;
+    }
+    return *this;
+  }
+
+  NCursesFormException(const NCursesFormException& rhs)
+    : NCursesException(rhs), f(rhs.f)
+  {
+  }
+
+  virtual const char *classname() const {
+    return "NCursesForm";
+  }
+
+  virtual ~NCursesFormException()
+  {
+  }
+};
+
+#if !((defined(__GNUG__) && defined(__EXCEPTIONS)) || defined(__SUNPRO_CC))
+#  if HAVE_IOSTREAM
+#     include <iostream>
+#     if IOSTREAM_NAMESPACE
+using std::cerr;
+using std::endl;
+#     endif
+#  else
+#     include <iostream.h>
+#  endif
+   extern "C" void exit(int);
+#endif
+
+inline void THROW(const NCursesException *e) {
+#if defined(__GNUG__) && defined(__EXCEPTIONS)
+#  if ((__GNUG__ <= 2) && (__GNUC_MINOR__ < 8))
+      (*lib_error_handler)(e ? e->classname() : "", e ? e->message : "");
+#else
+#define CPP_HAS_TRY_CATCH 1
+#endif
+#elif defined(__SUNPRO_CC)
+#  if !defined(__SUNPRO_CC_COMPAT) || (__SUNPRO_CC_COMPAT < 5)
+  genericerror(1, ((e != 0) ? (char *)(e->message) : ""));
+#else
+#define CPP_HAS_TRY_CATCH 1
+#endif
+#else
+  if (e)
+    cerr << e->message << endl;
+  exit(0);
+#endif
+
+#ifndef CPP_HAS_TRY_CATCH
+#define CPP_HAS_TRY_CATCH 0
+#define NCURSES_CPP_TRY		/* nothing */
+#define NCURSES_CPP_CATCH(e)	if (false)
+#define THROWS(s)		/* nothing */
+#elif CPP_HAS_TRY_CATCH
+  throw *e;
+#define NCURSES_CPP_TRY		try
+#define NCURSES_CPP_CATCH(e)	catch(e)
+#define THROWS(s)		throw(s)
+#endif
+}
+
+#endif /* NCURSES_ETIP_H_incl */
diff --git a/c++/headers b/c++/headers
new file mode 100644
index 0000000..0be0311
--- /dev/null
+++ b/c++/headers
@@ -0,0 +1,40 @@
+# C++ headers
+# $Id: headers,v 1.3 2006/12/24 16:25:45 tom Exp $
+##############################################################################
+# Copyright (c) 1998,2006 Free Software Foundation, Inc.                     #
+#                                                                            #
+# Permission is hereby granted, free of charge, to any person obtaining a    #
+# copy of this software and associated documentation files (the "Software"), #
+# to deal in the Software without restriction, including without limitation  #
+# the rights to use, copy, modify, merge, publish, distribute, distribute    #
+# with modifications, sublicense, and/or sell copies of the Software, and to #
+# permit persons to whom the Software is furnished to do so, subject to the  #
+# following conditions:                                                      #
+#                                                                            #
+# The above copyright notice and this permission notice shall be included in #
+# all copies or substantial portions of the Software.                        #
+#                                                                            #
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR #
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   #
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    #
+# THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER      #
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING    #
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER        #
+# DEALINGS IN THE SOFTWARE.                                                  #
+#                                                                            #
+# Except as contained in this notice, the name(s) of the above copyright     #
+# holders shall not be used in advertising or otherwise to promote the sale, #
+# use or other dealings in this Software without prior written               #
+# authorization.                                                             #
+##############################################################################
+#
+# Author: Thomas E. Dickey <dickey@clark.net> 1997
+#
+$(srcdir)/cursesapp.h
+$(srcdir)/cursesf.h
+$(srcdir)/cursesm.h
+$(srcdir)/cursesp.h
+$(srcdir)/cursesw.h
+$(srcdir)/cursslk.h
+etip.h
+# vile:makemode
diff --git a/c++/internal.h b/c++/internal.h
new file mode 100644
index 0000000..3066e72
--- /dev/null
+++ b/c++/internal.h
@@ -0,0 +1,60 @@
+// * This makes emacs happy -*-Mode: C++;-*-
+/****************************************************************************
+ * Copyright (c) 1998-2007,2008 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, 1997                                          *
+ ****************************************************************************/
+
+// $Id: internal.h,v 1.16 2008/10/25 21:35:44 tom Exp $
+
+#ifndef NCURSES_CPLUS_INTERNAL_H
+#define NCURSES_CPLUS_INTERNAL_H 1
+
+#include <ncurses_cfg.h>
+
+#if USE_RCS_IDS
+#define MODULE_ID(id) static const char Ident[] = id;
+#else
+#define MODULE_ID(id) /*nothing*/
+#endif
+
+#ifndef _QNX_SOURCE
+#include <stdlib.h>
+#include <string.h>
+#endif
+
+#ifndef CTRL
+#define CTRL(x) ((x) & 0x1f)
+#endif
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+#endif /* NCURSES_CPLUS_INTERNAL_H */
diff --git a/c++/modules b/c++/modules
new file mode 100644
index 0000000..bc4fae5
--- /dev/null
+++ b/c++/modules
@@ -0,0 +1,45 @@
+# Program modules
+# $Id: modules,v 1.7 2006/12/24 00:53:08 tom Exp $
+##############################################################################
+# Copyright (c) 1998,2006 Free Software Foundation, Inc.                     #
+#                                                                            #
+# Permission is hereby granted, free of charge, to any person obtaining a    #
+# copy of this software and associated documentation files (the "Software"), #
+# to deal in the Software without restriction, including without limitation  #
+# the rights to use, copy, modify, merge, publish, distribute, distribute    #
+# with modifications, sublicense, and/or sell copies of the Software, and to #
+# permit persons to whom the Software is furnished to do so, subject to the  #
+# following conditions:                                                      #
+#                                                                            #
+# The above copyright notice and this permission notice shall be included in #
+# all copies or substantial portions of the Software.                        #
+#                                                                            #
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR #
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   #
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    #
+# THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER      #
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING    #
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER        #
+# DEALINGS IN THE SOFTWARE.                                                  #
+#                                                                            #
+# Except as contained in this notice, the name(s) of the above copyright     #
+# holders shall not be used in advertising or otherwise to promote the sale, #
+# use or other dealings in this Software without prior written               #
+# authorization.                                                             #
+##############################################################################
+#
+# Author: Thomas E. Dickey	1995-on
+#
+
+@ base
+cursesf		c++		$(srcdir)	$(cursesf_h) $(cursesapp_h)
+cursesm		c++		$(srcdir)	$(cursesm_h) $(cursesapp_h)
+cursesp		c++		$(srcdir)	$(cursesp_h)
+cursesw		c++		$(srcdir)	$(cursesw_h)
+cursespad	c++		$(srcdir)	$(cursesw_h)
+cursslk		c++		$(srcdir)	$(cursslk_h) $(cursesapp_h)
+cursesapp	c++		$(srcdir)	$(cursesapp_h)
+cursesmain	c++		$(srcdir)	$(cursesapp_h)
+demo		c++		$(srcdir)	$(cursesf_h) $(cursesm_h) $(cursesapp_h)
+
+# vile:makemode
