+
+/*----------------------------------------------------------------------------
+ Useful constants
+ --------------------------------------------------------------------------*/
+static FIELD_CELL myBLANK = BLANK;
+static FIELD_CELL myZEROS;
+
+#ifdef TRACE
+static void
+check_pos(FORM *form, int lineno)
+{
+ int y, x;
+
+ if (form && form->w)
+ {
+ getyx(form->w, y, x);
+ if (y != form->currow || x != form->curcol)
+ {
+ T(("CHECKPOS %s@%d have position %d,%d vs want %d,%d",
+ __FILE__, lineno,
+ y, x,
+ form->currow, form->curcol));
+ }
+ }
+}
+#define CHECKPOS(form) check_pos(form, __LINE__)
+#else
+#define CHECKPOS(form) /* nothing */
+#endif
+
+/*----------------------------------------------------------------------------
+ Wide-character special functions
+ --------------------------------------------------------------------------*/
+#if USE_WIDEC_SUPPORT
+/* like winsnstr */
+static int
+wins_wchnstr(WINDOW *w, cchar_t *s, int n)
+{
+ int code = ERR;
+ int y, x;
+
+ while (n-- > 0)
+ {
+ getyx(w, y, x);
+ if ((code = wins_wch(w, s++)) != OK)
+ break;
+ if ((code = wmove(w, y, x + 1)) != OK)
+ break;
+ }
+ return code;
+}
+
+/* win_wchnstr is inconsistent with winnstr, since it returns OK rather than
+ * the number of items transferred.
+ */
+static int
+fix_wchnstr(WINDOW *w, cchar_t *s, int n)
+{
+ int x;
+
+ win_wchnstr(w, s, n);
+ /*
+ * This function is used to extract the text only from the window.
+ * Strip attributes and color from the string so they will not be added
+ * back when copying the string to the window.
+ */
+ for (x = 0; x < n; ++x)
+ {
+ RemAttr(s[x], A_ATTRIBUTES);
+ SetPair(s[x], 0);
+ }
+ return n;
+}
+
+/*
+ * Returns the column of the base of the given cell.
+ */
+static int
+cell_base(WINDOW *win, int y, int x)
+{
+ int result = x;
+
+ while (LEGALYX(win, y, x))
+ {
+ cchar_t *data = &(win->_line[y].text[x]);
+
+ if (isWidecBase(CHDEREF(data)) || !isWidecExt(CHDEREF(data)))
+ {
+ result = x;
+ break;
+ }
+ --x;
+ }
+ return result;
+}
+
+/*
+ * Returns the number of columns needed for the given cell in a window.
+ */
+static int
+cell_width(WINDOW *win, int y, int x)
+{
+ int result = 1;
+
+ if (LEGALYX(win, y, x))
+ {
+ cchar_t *data = &(win->_line[y].text[x]);
+
+ if (isWidecExt(CHDEREF(data)))
+ {
+ /* recur, providing the number of columns to the next character */
+ result = cell_width(win, y, x - 1);
+ }
+ else
+ {
+ result = wcwidth(CharOf(CHDEREF(data)));
+ }
+ }
+ return result;
+}
+
+/*
+ * There is no wide-character function such as wdel_wch(), so we must find
+ * all of the cells that comprise a multi-column character and delete them
+ * one-by-one.
+ */
+static void
+delete_char(FORM *form)
+{
+ int cells = cell_width(form->w, form->currow, form->curcol);
+
+ form->curcol = cell_base(form->w, form->currow, form->curcol);
+ wmove(form->w, form->currow, form->curcol);
+ while (cells-- > 0)
+ {
+ wdelch(form->w);
+ }
+}
+#define DeleteChar(form) delete_char(form)
+#else
+#define DeleteChar(form) \
+ wmove((form)->w, (form)->currow, (form)->curcol), \
+ wdelch((form)->w)
+#endif
+