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
