diff --git a/ncurses/base/lib_addch.c b/ncurses/base/lib_addch.c
new file mode 100644
index 0000000..20a97a0
--- /dev/null
+++ b/ncurses/base/lib_addch.c
@@ -0,0 +1,548 @@
+/****************************************************************************
+ * Copyright (c) 1998-2006,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.                                                           *
+ ****************************************************************************/
+
+/*
+**	lib_addch.c
+**
+**	The routine waddch().
+**
+*/
+
+#include <curses.priv.h>
+#include <ctype.h>
+
+MODULE_ID("$Id: lib_addch.c,v 1.113 2008/08/16 19:20:04 tom Exp $")
+
+static const NCURSES_CH_T blankchar = NewChar(BLANK_TEXT);
+
+/*
+ * Ugly microtweaking alert.  Everything from here to end of module is
+ * likely to be speed-critical -- profiling data sure says it is!
+ * Most of the important screen-painting functions are shells around
+ * waddch().  So we make every effort to reduce function-call overhead
+ * by inlining stuff, even at the cost of making wrapped copies for
+ * export.  Also we supply some internal versions that don't call the
+ * window sync hook, for use by string-put functions.
+ */
+
+/* Return bit mask for clearing color pair number if given ch has color */
+#define COLOR_MASK(ch) (~(attr_t)((ch) & A_COLOR ? A_COLOR : 0))
+
+static NCURSES_INLINE NCURSES_CH_T
+render_char(WINDOW *win, NCURSES_CH_T ch)
+/* compute a rendition of the given char correct for the current context */
+{
+    attr_t a = WINDOW_ATTRS(win);
+    int pair = GetPair(ch);
+
+    if (ISBLANK(ch)
+	&& AttrOf(ch) == A_NORMAL
+	&& pair == 0) {
+	/* color/pair in attrs has precedence over bkgrnd */
+	ch = win->_nc_bkgd;
+	SetAttr(ch, a | AttrOf(win->_nc_bkgd));
+	if ((pair = GET_WINDOW_PAIR(win)) == 0)
+	    pair = GetPair(win->_nc_bkgd);
+	SetPair(ch, pair);
+    } else {
+	/* color in attrs has precedence over bkgrnd */
+	a |= AttrOf(win->_nc_bkgd) & COLOR_MASK(a);
+	/* color in ch has precedence */
+	if (pair == 0) {
+	    if ((pair = GET_WINDOW_PAIR(win)) == 0)
+		pair = GetPair(win->_nc_bkgd);
+	}
+#if 0
+	if (pair > 255) {
+	    NCURSES_CH_T fixme = ch;
+	    SetPair(fixme, pair);
+	}
+#endif
+	AddAttr(ch, (a & COLOR_MASK(AttrOf(ch))));
+	SetPair(ch, pair);
+    }
+
+    TR(TRACE_VIRTPUT,
+       ("render_char bkg %s (%d), attrs %s (%d) -> ch %s (%d)",
+	_tracech_t2(1, CHREF(win->_nc_bkgd)),
+	GetPair(win->_nc_bkgd),
+	_traceattr(WINDOW_ATTRS(win)),
+	GET_WINDOW_PAIR(win),
+	_tracech_t2(3, CHREF(ch)),
+	GetPair(ch)));
+
+    return (ch);
+}
+
+NCURSES_EXPORT(NCURSES_CH_T)
+_nc_render(WINDOW *win, NCURSES_CH_T ch)
+/* make render_char() visible while still allowing us to inline it below */
+{
+    return render_char(win, ch);
+}
+
+/* check if position is legal; if not, return error */
+#ifndef NDEBUG			/* treat this like an assertion */
+#define CHECK_POSITION(win, x, y) \
+	if (y > win->_maxy \
+	 || x > win->_maxx \
+	 || y < 0 \
+	 || x < 0) { \
+		TR(TRACE_VIRTPUT, ("Alert! Win=%p _curx = %d, _cury = %d " \
+				   "(_maxx = %d, _maxy = %d)", win, x, y, \
+				   win->_maxx, win->_maxy)); \
+		return(ERR); \
+	}
+#else
+#define CHECK_POSITION(win, x, y)	/* nothing */
+#endif
+
+static bool
+newline_forces_scroll(WINDOW *win, NCURSES_SIZE_T * ypos)
+{
+    bool result = FALSE;
+
+    if (*ypos >= win->_regtop && *ypos == win->_regbottom) {
+	*ypos = win->_regbottom;
+	result = TRUE;
+    } else {
+	*ypos += 1;
+    }
+    return result;
+}
+
+/*
+ * The _WRAPPED flag is useful only for telling an application that we've just
+ * wrapped the cursor.  We don't do anything with this flag except set it when
+ * wrapping, and clear it whenever we move the cursor.  If we try to wrap at
+ * the lower-right corner of a window, we cannot move the cursor (since that
+ * wouldn't be legal).  So we return an error (which is what SVr4 does). 
+ * Unlike SVr4, we can successfully add a character to the lower-right corner
+ * (Solaris 2.6 does this also, however).
+ */
+static int
+wrap_to_next_line(WINDOW *win)
+{
+    win->_flags |= _WRAPPED;
+    if (newline_forces_scroll(win, &(win->_cury))) {
+	win->_curx = win->_maxx;
+	if (!win->_scroll)
+	    return (ERR);
+	scroll(win);
+    }
+    win->_curx = 0;
+    return (OK);
+}
+
+#if USE_WIDEC_SUPPORT
+static int waddch_literal(WINDOW *, NCURSES_CH_T);
+/*
+ * Fill the given number of cells with blanks using the current background
+ * rendition.  This saves/restores the current x-position.
+ */
+static void
+fill_cells(WINDOW *win, int count)
+{
+    NCURSES_CH_T blank = blankchar;
+    int save_x = win->_curx;
+    int save_y = win->_cury;
+
+    while (count-- > 0) {
+	if (waddch_literal(win, blank) == ERR)
+	    break;
+    }
+    win->_curx = save_x;
+    win->_cury = save_y;
+}
+#endif
+
+/*
+ * Build up the bytes for a multibyte character, returning the length when
+ * complete (a positive number), -1 for error and -2 for incomplete.
+ */
+#if USE_WIDEC_SUPPORT
+NCURSES_EXPORT(int)
+_nc_build_wch(WINDOW *win, ARG_CH_T ch)
+{
+    char *buffer = WINDOW_EXT(win, addch_work);
+    int len;
+    int x = win->_curx;
+    int y = win->_cury;
+    mbstate_t state;
+    wchar_t result;
+
+    if ((WINDOW_EXT(win, addch_used) != 0) &&
+	(WINDOW_EXT(win, addch_x) != x ||
+	 WINDOW_EXT(win, addch_y) != y)) {
+	/* discard the incomplete multibyte character */
+	WINDOW_EXT(win, addch_used) = 0;
+	TR(TRACE_VIRTPUT,
+	   ("Alert discarded multibyte on move (%d,%d) -> (%d,%d)",
+	    WINDOW_EXT(win, addch_y), WINDOW_EXT(win, addch_x),
+	    y, x));
+    }
+    WINDOW_EXT(win, addch_x) = x;
+    WINDOW_EXT(win, addch_y) = y;
+
+    init_mb(state);
+    buffer[WINDOW_EXT(win, addch_used)] = (char) CharOf(CHDEREF(ch));
+    WINDOW_EXT(win, addch_used) += 1;
+    buffer[WINDOW_EXT(win, addch_used)] = '\0';
+    if ((len = mbrtowc(&result,
+		       buffer,
+		       WINDOW_EXT(win, addch_used), &state)) > 0) {
+	attr_t attrs = AttrOf(CHDEREF(ch));
+	if_EXT_COLORS(int pair = GetPair(CHDEREF(ch)));
+	SetChar(CHDEREF(ch), result, attrs);
+	if_EXT_COLORS(SetPair(CHDEREF(ch), pair));
+	WINDOW_EXT(win, addch_used) = 0;
+    } else if (len == -1) {
+	/*
+	 * An error occurred.  We could either discard everything,
+	 * or assume that the error was in the previous input.
+	 * Try the latter.
+	 */
+	TR(TRACE_VIRTPUT, ("Alert! mbrtowc returns error"));
+	/* handle this with unctrl() */
+	WINDOW_EXT(win, addch_used) = 0;
+    }
+    return len;
+}
+#endif /* USE_WIDEC_SUPPORT */
+
+static
+#if !USE_WIDEC_SUPPORT		/* cannot be inline if it is recursive */
+NCURSES_INLINE
+#endif
+int
+waddch_literal(WINDOW *win, NCURSES_CH_T ch)
+{
+    int x;
+    int y;
+    struct ldat *line;
+
+    x = win->_curx;
+    y = win->_cury;
+
+    CHECK_POSITION(win, x, y);
+
+    ch = render_char(win, ch);
+
+    line = win->_line + y;
+
+    CHANGED_CELL(line, x);
+
+    /*
+     * Build up multibyte characters until we have a wide-character.
+     */
+    if_WIDEC({
+	if (WINDOW_EXT(win, addch_used) != 0 || !Charable(ch)) {
+	    int len = _nc_build_wch(win, CHREF(ch));
+
+	    if (len >= -1) {
+		/* handle EILSEQ */
+		if (is8bits(CharOf(ch))) {
+		    const char *s = unctrl((chtype) CharOf(ch));
+		    if (s[1] != 0) {
+			return waddstr(win, s);
+		    }
+		}
+		if (len == -1)
+		    return waddch(win, ' ');
+	    } else {
+		return OK;
+	    }
+	}
+    });
+
+    /*
+     * Non-spacing characters are added to the current cell.
+     *
+     * Spacing characters that are wider than one column require some display
+     * adjustments.
+     */
+    if_WIDEC({
+	int len = wcwidth(CharOf(ch));
+	int i;
+	int j;
+	wchar_t *chars;
+
+	if (len == 0) {		/* non-spacing */
+	    if ((x > 0 && y >= 0)
+		|| (win->_maxx >= 0 && win->_cury >= 1)) {
+		if (x > 0 && y >= 0)
+		    chars = (win->_line[y].text[x - 1].chars);
+		else
+		    chars = (win->_line[y - 1].text[win->_maxx].chars);
+		for (i = 0; i < CCHARW_MAX; ++i) {
+		    if (chars[i] == 0) {
+			TR(TRACE_VIRTPUT,
+			   ("added non-spacing %d: %x",
+			    x, (int) CharOf(ch)));
+			chars[i] = CharOf(ch);
+			break;
+		    }
+		}
+	    }
+	    goto testwrapping;
+	} else if (len > 1) {	/* multi-column characters */
+	    /*
+	     * Check if the character will fit on the current line.  If it does
+	     * not fit, fill in the remainder of the line with blanks.  and
+	     * move to the next line.
+	     */
+	    if (len > win->_maxx + 1) {
+		TR(TRACE_VIRTPUT, ("character will not fit"));
+		return ERR;
+	    } else if (x + len > win->_maxx + 1) {
+		int count = win->_maxx + 1 - x;
+		TR(TRACE_VIRTPUT, ("fill %d remaining cells", count));
+		fill_cells(win, count);
+		if (wrap_to_next_line(win) == ERR)
+		    return ERR;
+		x = win->_curx;
+		y = win->_cury;
+	    }
+	    /*
+	     * Check for cells which are orphaned by adding this character, set
+	     * those to blanks.
+	     *
+	     * FIXME: this actually could fill j-i cells, more complicated to
+	     * setup though.
+	     */
+	    for (i = 0; i < len; ++i) {
+		if (isWidecBase(win->_line[y].text[x + i])) {
+		    break;
+		} else if (isWidecExt(win->_line[y].text[x + i])) {
+		    for (j = i; x + j <= win->_maxx; ++j) {
+			if (!isWidecExt(win->_line[y].text[x + j])) {
+			    TR(TRACE_VIRTPUT, ("fill %d orphan cells", j));
+			    fill_cells(win, j);
+			    break;
+			}
+		    }
+		    break;
+		}
+	    }
+	    /*
+	     * Finally, add the cells for this character.
+	     */
+	    for (i = 0; i < len; ++i) {
+		NCURSES_CH_T value = ch;
+		SetWidecExt(value, i);
+		TR(TRACE_VIRTPUT, ("multicolumn %d:%d (%d,%d)",
+				   i + 1, len,
+				   win->_begy + y, win->_begx + x));
+		line->text[x] = value;
+		CHANGED_CELL(line, x);
+		++x;
+	    }
+	    goto testwrapping;
+	}
+    });
+
+    /*
+     * Single-column characters.
+     */
+    line->text[x++] = ch;
+    /*
+     * This label is used only for wide-characters.
+     */
+    if_WIDEC(
+  testwrapping:
+    );
+
+    TR(TRACE_VIRTPUT, ("cell (%ld, %ld..%d) = %s",
+		       (long) win->_cury, (long) win->_curx, x - 1,
+		       _tracech_t(CHREF(ch))));
+
+    if (x > win->_maxx) {
+	return wrap_to_next_line(win);
+    }
+    win->_curx = x;
+    return OK;
+}
+
+static NCURSES_INLINE int
+waddch_nosync(WINDOW *win, const NCURSES_CH_T ch)
+/* the workhorse function -- add a character to the given window */
+{
+    NCURSES_SIZE_T x, y;
+    chtype t = CharOf(ch);
+    const char *s = unctrl(t);
+
+    /*
+     * If we are using the alternate character set, forget about locale.
+     * Otherwise, if unctrl() returns a single-character or the locale
+     * claims the code is printable, treat it that way.
+     */
+    if ((AttrOf(ch) & A_ALTCHARSET)
+	|| (
+#if USE_WIDEC_SUPPORT
+	       (SP != 0 && SP->_legacy_coding) &&
+#endif
+	       s[1] == 0
+	)
+	|| (
+	       isprint(t)
+#if USE_WIDEC_SUPPORT
+	       || ((SP == 0 || !SP->_legacy_coding) &&
+		   (WINDOW_EXT(win, addch_used)
+		    || !_nc_is_charable(CharOf(ch))))
+#endif
+	))
+	return waddch_literal(win, ch);
+
+    /*
+     * Handle carriage control and other codes that are not printable, or are
+     * known to expand to more than one character according to unctrl().
+     */
+    x = win->_curx;
+    y = win->_cury;
+
+    switch (t) {
+    case '\t':
+	x += (TABSIZE - (x % TABSIZE));
+
+	/*
+	 * Space-fill the tab on the bottom line so that we'll get the
+	 * "correct" cursor position.
+	 */
+	if ((!win->_scroll && (y == win->_regbottom))
+	    || (x <= win->_maxx)) {
+	    NCURSES_CH_T blank = blankchar;
+	    AddAttr(blank, AttrOf(ch));
+	    while (win->_curx < x) {
+		if (waddch_literal(win, blank) == ERR)
+		    return (ERR);
+	    }
+	    break;
+	} else {
+	    wclrtoeol(win);
+	    win->_flags |= _WRAPPED;
+	    if (newline_forces_scroll(win, &y)) {
+		x = win->_maxx;
+		if (win->_scroll) {
+		    scroll(win);
+		    x = 0;
+		}
+	    } else {
+		x = 0;
+	    }
+	}
+	break;
+    case '\n':
+	wclrtoeol(win);
+	if (newline_forces_scroll(win, &y)) {
+	    if (win->_scroll)
+		scroll(win);
+	    else
+		return (ERR);
+	}
+	/* FALLTHRU */
+    case '\r':
+	x = 0;
+	win->_flags &= ~_WRAPPED;
+	break;
+    case '\b':
+	if (x == 0)
+	    return (OK);
+	x--;
+	win->_flags &= ~_WRAPPED;
+	break;
+    default:
+	while (*s) {
+	    NCURSES_CH_T sch;
+	    SetChar(sch, *s++, AttrOf(ch));
+	    if_EXT_COLORS(SetPair(sch, GetPair(ch)));
+	    if (waddch_literal(win, sch) == ERR)
+		return ERR;
+	}
+	return (OK);
+    }
+
+    win->_curx = x;
+    win->_cury = y;
+
+    return (OK);
+}
+
+NCURSES_EXPORT(int)
+_nc_waddch_nosync(WINDOW *win, const NCURSES_CH_T c)
+/* export copy of waddch_nosync() so the string-put functions can use it */
+{
+    return (waddch_nosync(win, c));
+}
+
+/*
+ * The versions below call _nc_synchook().  We wanted to avoid this in the
+ * version exported for string puts; they'll call _nc_synchook once at end
+ * of run.
+ */
+
+/* These are actual entry points */
+
+NCURSES_EXPORT(int)
+waddch(WINDOW *win, const chtype ch)
+{
+    int code = ERR;
+    NCURSES_CH_T wch;
+    SetChar2(wch, ch);
+
+    TR(TRACE_VIRTPUT | TRACE_CCALLS, (T_CALLED("waddch(%p, %s)"), win,
+				      _tracechtype(ch)));
+
+    if (win && (waddch_nosync(win, wch) != ERR)) {
+	_nc_synchook(win);
+	code = OK;
+    }
+
+    TR(TRACE_VIRTPUT | TRACE_CCALLS, (T_RETURN("%d"), code));
+    return (code);
+}
+
+NCURSES_EXPORT(int)
+wechochar(WINDOW *win, const chtype ch)
+{
+    int code = ERR;
+    NCURSES_CH_T wch;
+    SetChar2(wch, ch);
+
+    TR(TRACE_VIRTPUT | TRACE_CCALLS, (T_CALLED("wechochar(%p, %s)"), win,
+				      _tracechtype(ch)));
+
+    if (win && (waddch_nosync(win, wch) != ERR)) {
+	bool save_immed = win->_immed;
+	win->_immed = TRUE;
+	_nc_synchook(win);
+	win->_immed = save_immed;
+	code = OK;
+    }
+    TR(TRACE_VIRTPUT | TRACE_CCALLS, (T_RETURN("%d"), code));
+    return (code);
+}
