CDK changes:

Exclude the following source files: alphalist.c, button.c, calendar.c,
cdk_compat.{c,h}, cdk_params.c, cdk_test.h, debug.c, dialog.c, {d,f}scale.{c,h},
fslider.{c,h}, gen-scale.{c,h}, get_index.c, get_string.c, graph.c, histogram.c,
marquee.c, matrix.c, menu.c, popup_dialog.c, position.c, radio.c, scale.{c,h},
swindow.c, template.c, u{scale,slider}.{c,h}, view_{file,info}.c, and viewer.c.

binding.c utilizes libtermkey for universal input.

cdk.h does not #include matrix.h, viewer.h, and any headers labeled
"Generated headers" due to their machine-dependence, except for slider.h. It
also #defines "boolean" as "CDKboolean" on Windows platforms since the former is
already a typedef.

cdk_config.h no longer defines HAVE_SETLOCALE since Textadept handles locale
settings, no longer defines HAVE_NCURSES_H and NCURSES since Textadept supports
multiple curses implementations (not just ncurses), and conditionally enables
HAVE_GRP_H, HAVE_LSTAT, and HAVE_PWD_H definitions on *nix platforms since
Windows does not have them.

cdk_util.h #defines "Beep" as "CDKBeep" on Windows platforms since Windows
already defines Beep.

The "baseName" and "dirName" functions in cdk.c recognize Window's '\'
directory separator.

Deactivated the "deleteFileCB" function in fselect.c.

Removed some of CDK's initial screen handling code.

cdk.c has some basic UTF-8 handling functions and draw.c, entry.c, and
itemlist.c use them for UTF-8 drawing and character handling. (Note: mentry.c
cannot handle UTF-8.)

Added generated include/slider.h and slider.c, which came from:
  ./gen-scale.sh SLIDER Slider Int int include/gen-slider.h > include/slider.h
  ./gen-scale.sh SLIDER Slider Int int gen-slider.c > slider.c

diff --git a/binding.c b/binding.c
index c217870..fbb12f1 100644
--- a/binding.c
+++ b/binding.c
@@ -1,4 +1,6 @@
 #include <cdk_int.h>
+#include "termkey.h"
+extern TermKey *ta_tk;
 
 /*
  * $Author: tom $
@@ -167,7 +169,50 @@ int getcCDKObject (CDKOBJS *obj)
 {
    EObjectType cdktype = ObjTypeOf (obj);
    CDKOBJS *test = bindableObject (&cdktype, obj);
-   int result = wgetch (InputWindowOf (obj));
+   int result = ERR;
+   TermKeyKey key;
+   int keysyms[] = {0,KEY_BACKSPACE,KEY_TAB,KEY_ENTER,KEY_ESC,0,KEY_BACKSPACE,KEY_UP,KEY_DOWN,KEY_LEFT,KEY_RIGHT,0,0,KEY_IC,KEY_DC,0,KEY_PPAGE,KEY_NPAGE,KEY_HOME,KEY_END};
+   TermKeyResult res;
+retry:
+   res = termkey_waitkey(ta_tk, &key);
+   switch (res)
+   {
+   case TERMKEY_RES_KEY:
+      switch (key.type)
+      {
+      case TERMKEY_TYPE_UNICODE:
+         result = key.code.codepoint;
+         if ((key.modifiers & TERMKEY_KEYMOD_CTRL) &&
+             ((result >= 'a' && result <= 'z') || (result >= 'A' && result <= 'Z')))
+         {
+            result = (result & ~0x60);
+            key.modifiers &= ~TERMKEY_KEYMOD_CTRL;
+         }
+         break;
+      case TERMKEY_TYPE_FUNCTION:
+         result = KEY_F(key.code.number);
+         break;
+      case TERMKEY_TYPE_KEYSYM:
+         result = keysyms[key.code.sym];
+         if (key.code.sym == TERMKEY_SYM_TAB && key.modifiers & TERMKEY_KEYMOD_SHIFT)
+            result = KEY_BTAB;
+         break;
+      case TERMKEY_TYPE_UNKNOWN_CSI:
+      case TERMKEY_TYPE_MOUSE:
+         goto retry;
+      default:
+         result = ERR;
+      }
+      break;
+   case TERMKEY_RES_EOF:
+   case TERMKEY_RES_ERROR:
+      result = ERR;
+      break;
+   case TERMKEY_RES_NONE:
+   case TERMKEY_RES_AGAIN:
+      result = 0;
+      break;
+   }
 
    if (result >= 0
        && test != 0
diff --git a/cdk.c b/cdk.c
index c446e34..211c74d 100644
--- a/cdk.c
+++ b/cdk.c
@@ -493,6 +493,34 @@ static unsigned decodeAttribute (char *string,
    return (from + (unsigned)(result - base));
 }
 
+unsigned int utf8charlen(unsigned char ch)
+{
+	if (ch < 0x80) {
+		return 1;
+	} else if (ch < 0x80 + 0x40 + 0x20) {
+		return 2;
+	} else if (ch < 0x80 + 0x40 + 0x20 + 0x10) {
+		return 3;
+	} else {
+		return 4;
+	}
+}
+
+size_t utf8strlen(const char *s)
+{
+	if (!s) return 0;
+	size_t i, len = strlen(s), utf8len = 0;
+	for (i = 0; i < len; i+=utf8charlen(CharOf(s[i]))) utf8len++;
+	return utf8len;
+}
+
+int utf8charpos(char *s, int pos)
+{
+	int i, len = (int)strlen(s), utf8len = 0;
+	for (i = 0; i < len; i+=utf8charlen(CharOf(s[i]))) if (utf8len++ >= pos) break;
+	return i;
+}
+
 /*
  * This function takes a character string, full of format markers
  * and translates them into a chtype * array. This is better suited
@@ -502,6 +529,7 @@ chtype *char2Chtype (const char *string, int *to, int *align)
 {
    chtype *result = 0;
    chtype mask;
+   char *s;
 
    (*to) = 0;
    *align = LEFT;
@@ -813,7 +841,7 @@ chtype *char2Chtype (const char *string, int *to, int *align)
 	    result[0] = attrib;
 	 }
       }
-      *to = used;
+      for (int from = 0; from < used; from+=utf8charlen(CharOf(result[from]))) (*to)++;
    }
    else
    {
@@ -1270,6 +1298,7 @@ int intlen (int value)
  */
 int CDKgetDirectoryContents (const char *directory, char ***list)
 {
+#if !_WIN32
    /* Declare local variables.  */
    struct dirent *dirStruct;
    int counter = 0;
@@ -1295,6 +1324,21 @@ int CDKgetDirectoryContents (const char *directory, char ***list)
 
    /* Close the directory.  */
    closedir (dp);
+#else
+  struct _finddata_t file;
+  int counter = 0;
+  unsigned used = 0;
+  char *glob = malloc(strlen(directory)+3);
+  strcpy(glob, directory);
+  strcpy(glob + strlen(directory), "/*");
+  intptr_t handle = _findfirst(glob, &file);
+  if (handle == -1) return 0;
+  do {
+    used = CDKallocStrings(list, file.name, (unsigned)counter++, used);
+  } while (_findnext(handle, &file) != -1);
+  free(glob);
+  _findclose(handle);
+#endif
 
    /* Sort the info.  */
    sortList ((CDK_CSTRING *)*list, counter);
@@ -1402,7 +1446,7 @@ char *baseName (char *pathname)
 	 for (x = pathLen - 1; x != 0; --x)
 	 {
 	    /* Find the last '/' in the pathname. */
-	    if (pathname[x] == '/')
+	    if (pathname[x] == '/' || pathname[x] == '\\')
 	    {
 	       strcpy (base, pathname + x + 1);
 	       break;
@@ -1428,7 +1472,7 @@ char *dirName (char *pathname)
        && (pathLen = strlen (pathname)) != 0)
    {
       size_t x = pathLen;
-      while ((dir[x] != '/') && (x > 0))
+      while ((dir[x] != '/' && dir[x] != '\\') && (x > 0))
       {
 	 dir[x--] = '\0';
       }
diff --git a/cdkscreen.c b/cdkscreen.c
index b768b6d..37a9100 100644
--- a/cdkscreen.c
+++ b/cdkscreen.c
@@ -180,24 +180,6 @@ CDKSCREEN *initCDKScreen (WINDOW *window)
    ALL_SCREENS *item;
    CDKSCREEN *screen = 0;
 
-   /* initialization, for the first time */
-   if (all_screens == 0 || stdscr == 0 || window == 0)
-   {
-      /* Set up basic curses settings. */
-#ifdef HAVE_SETLOCALE
-      setlocale (LC_ALL, "");
-#endif
-      /* Initialize curses after setting the locale, since curses depends
-       * on having a correct locale to reflect the terminal's encoding.
-       */
-      if (stdscr == 0 || window == 0)
-      {
-	 window = initscr ();
-      }
-      noecho ();
-      cbreak ();
-   }
-
    if ((item = typeMalloc (ALL_SCREENS)) != 0)
    {
       if ((screen = typeCalloc (CDKSCREEN)) != 0)
diff --git a/draw.c b/draw.c
index 0dc87d8..fc18586 100644
--- a/draw.c
+++ b/draw.c
@@ -349,23 +349,34 @@ void writeChtypeAttrib (WINDOW *window,
    int diff             = end - start;
    int display          = 0;
    int x                = 0;
+   char *s, *p;
+   attr_t current_attr;
+   short pair;
+   int charlen;
 
+   s = chtype2Char (string), p = s + start;
+   wattr_get (window, &current_attr, &pair, NULL); // save original attrs
+   wattr_set (window, (string[x] & ~A_CHARTEXT) | attr, pair, NULL); // set new attrs
    if (align == HORIZONTAL)
    {
       /* Draw the message on a horizontal axis. */
       display = MINIMUM (diff, getmaxx (window) - xpos);
-      for (x = 0; x < display; x++)
+      for (x = 0; x < display; x++, p+=charlen)
       {
-	 CDKmvwaddch (window, ypos, xpos + x, string[x + start], attr);
+         charlen = utf8charlen(*p);
+	 (void)mvwaddnstr (window, ypos, xpos + x, (const char *)p, charlen);
       }
    }
    else
    {
       /* Draw the message on a vertical axis. */
       display = MINIMUM (diff, getmaxy (window) - ypos);
-      for (x = 0; x < display; x++)
+      for (x = 0; x < display; x++, p+=charlen)
       {
-	 CDKmvwaddch (window, ypos + x, xpos, string[x + start], attr);
+         charlen = utf8charlen(*p);
+	 (void)mvwaddnstr (window, ypos + x, xpos, (const char *)p, charlen);
       }
    }
+   wattr_set (window, current_attr, pair, NULL); // restore original attrs
+   freeChar (s);
 }
diff --git a/entry.c b/entry.c
index 97b9418..1755774 100644
--- a/entry.c
+++ b/entry.c
@@ -221,13 +221,13 @@ static void setPositionToEnd (CDKENTRY *entry)
 {
    int stringLen;
 
-   stringLen = (int)strlen (entry->info);
+   stringLen = (int)utf8strlen (entry->info);
    if (stringLen >= entry->fieldWidth)
    {
       if (stringLen < entry->max)
       {
 	 int charCount = entry->fieldWidth - 1;
-	 entry->leftChar = stringLen - charCount;
+	 entry->leftChar = stringLen - charCount; // horizontal scrolling with UTF8 does not work
 	 entry->screenCol = charCount;
       }
       else
@@ -243,6 +243,8 @@ static void setPositionToEnd (CDKENTRY *entry)
    }
 }
 
+static inline int isUtf8CharPart(unsigned int ch) { return (ch >= 0x80) && (ch < 0xc0); }
+
 /*
  * This injects a single character into the widget.
  */
@@ -280,7 +282,7 @@ static int _injectCDKEntry (CDKOBJS *object, chtype input)
       else
       {
 	 int infoLength = (int)strlen (widget->info);
-	 int currPos = widget->screenCol + widget->leftChar;
+	 int currPos = utf8charpos (widget->info, widget->screenCol) + widget->leftChar;
 
 	 switch (input)
 	 {
@@ -328,6 +330,7 @@ static int _injectCDKEntry (CDKOBJS *object, chtype input)
 	    else
 	    {
 	       wmove (widget->fieldWin, 0, --widget->screenCol);
+	       drawCDKEntryField (widget);
 	    }
 	    break;
 
@@ -346,6 +349,7 @@ static int _injectCDKEntry (CDKOBJS *object, chtype input)
 	    {
 	       /* Move right. */
 	       wmove (widget->fieldWin, 0, ++widget->screenCol);
+	       drawCDKEntryField (widget);
 	    }
 	    break;
 
@@ -360,7 +364,10 @@ static int _injectCDKEntry (CDKOBJS *object, chtype input)
 	       bool success = FALSE;
 
 	       if (input == KEY_BACKSPACE)
+	       {
+		  while (currPos >= 1 && isUtf8CharPart(CharOf(widget->info[currPos - 1]))) currPos--;
 		  --currPos;
+	       }
 
 	       if (currPos >= 0 && infoLength > 0)
 	       {
@@ -368,14 +375,16 @@ static int _injectCDKEntry (CDKOBJS *object, chtype input)
 		  {
 		     int x;
 
+		     int len = utf8charlen(widget->info[currPos]);
 		     for (x = currPos; x < infoLength; x++)
 		     {
-			widget->info[x] = widget->info[x + 1];
+			widget->info[x] = widget->info[x + len];
 		     }
 		     success = TRUE;
 		  }
 		  else if (input == KEY_BACKSPACE)
 		  {
+		     while (infoLength >= 1 && isUtf8CharPart(CharOf(widget->info[infoLength - 1]))) infoLength--;
 		     widget->info[infoLength - 1] = '\0';
 		     success = TRUE;
 		  }
@@ -549,6 +558,23 @@ static void _moveCDKEntry (CDKOBJS *object,
    }
 }
 
+static void toutf8(int code, char *s, int *len) {
+  int b;
+  if (code < 0x80) *len = 1;
+  else if (code < 0x800) *len = 2;
+  else if (code < 0x10000) *len = 3;
+  else if (code < 0x200000) *len = 4;
+  else if (code < 0x4000000) *len = 5;
+  else *len = 6;
+  for (b = *len - 1; b > 0; b--) s[b] = 0x80 | (code & 0x3F), code >>= 6;
+  if (*len == 1) s[0] = code & 0x7F;
+  else if (*len == 2) s[0] = 0xC0 | (code & 0x1F);
+  else if (*len == 3) s[0] = 0xE0 | (code & 0x0F);
+  else if (*len == 4) s[0] = 0xF0 | (code & 0x07);
+  else if (*len == 5) s[0] = 0xF8 | (code & 0x03);
+  else if (*len == 6) s[0] = 0xFC | (code & 0x01);
+}
+
 /*
  * This is a generic character parser for the entry field. It is used as a
  * callback function, so any personal modifications can be made by creating
@@ -556,37 +582,41 @@ static void _moveCDKEntry (CDKOBJS *object,
  */
 static void CDKEntryCallBack (CDKENTRY *entry, chtype character)
 {
-   int plainchar = filterByDisplayType (entry->dispType, character);
+   int plainchar = character;
+   char utf8[6];
+   int len;
 
    if (plainchar == ERR ||
-       ((int)strlen (entry->info) >= entry->max))
+       ((int)utf8strlen (entry->info) >= entry->max))
    {
       Beep ();
    }
    else
    {
+      toutf8(plainchar, utf8, &len);
       /* Update the screen and pointer. */
       if (entry->screenCol != entry->fieldWidth - 1)
       {
 	 int x;
+	 int pos = utf8charpos (entry->info, entry->screenCol) + entry->leftChar;
 
-	 for (x = (int)strlen (entry->info);
-	      x > (entry->screenCol + entry->leftChar);
+	 for (x = (int)strlen (entry->info) + len - 1;
+	      x > pos + len - 1;
 	      x--)
 	 {
-	    entry->info[x] = entry->info[x - 1];
+	    entry->info[x] = entry->info[x - len];
 	 }
-	 entry->info[entry->screenCol + entry->leftChar] = (char)plainchar;
+	 strncpy(entry->info + pos, utf8, len);
 	 entry->screenCol++;
       }
       else
       {
 	 /* Update the character pointer. */
 	 size_t temp = strlen (entry->info);
-	 entry->info[temp] = (char)plainchar;
-	 entry->info[temp + 1] = '\0';
+	 strncpy(entry->info + temp, utf8, len);
+	 entry->info[temp + len] = '\0';
 	 /* Do not update the pointer if it's the last character */
-	 if ((int)(temp + 1) < entry->max)
+	 if ((int)(temp + len + 1) < entry->max)
 	    entry->leftChar++;
       }
 
@@ -656,6 +686,8 @@ static void _drawCDKEntry (CDKOBJS *object, boolean Box)
 static void drawCDKEntryField (CDKENTRY *entry)
 {
    int x = 0;
+   char *p;
+   int charlen;
 
    /* Set background color and attributes of the entry field */
    wbkgd (entry->fieldWin, entry->fieldAttr);
@@ -666,7 +698,7 @@ static void drawCDKEntryField (CDKENTRY *entry)
    /* If there is information in the field. Then draw it in. */
    if (entry->info != 0)
    {
-      int infoLength = (int)strlen (entry->info);
+      int infoLength = (int)utf8strlen (entry->info);
 
       /* Redraw the field. */
       if (isHiddenDisplayType (entry->dispType))
@@ -679,10 +711,12 @@ static void drawCDKEntryField (CDKENTRY *entry)
       }
       else
       {
-	 for (x = entry->leftChar; x < infoLength; x++)
+	 p = entry->info + entry->leftChar;
+	 for (x = entry->leftChar; x < infoLength; x++, p+=charlen)
 	 {
-	    (void)mvwaddch (entry->fieldWin, 0, x - entry->leftChar,
-			    CharOf (entry->info[x]) | entry->fieldAttr);
+	    charlen = utf8charlen(CharOf (*p));
+	    (void)mvwaddnstr (entry->fieldWin, 0, x - entry->leftChar,
+			    (const char *)p, charlen);
 	 }
       }
       wmove (entry->fieldWin, 0, entry->screenCol);
diff --git a/fselect.c b/fselect.c
index 571bf28..2e06ec7 100644
--- a/fselect.c
+++ b/fselect.c
@@ -415,7 +415,7 @@ static int _injectCDKFselect (CDKOBJS *object, chtype input)
    copyExitType (fselect, fselect->entryField);
 
    /* If we exited early, make sure we don't interpret it as a file. */
-   if (fselect->exitType == vEARLY_EXIT)
+   if (fselect->exitType == vEARLY_EXIT || fselect->exitType == vESCAPE_HIT)
    {
       return 0;
    }
@@ -1109,7 +1109,7 @@ static int displayFileInfoCB (EObjectType objectType GCC_UNUSED,
 
 static char *make_pathname (const char *directory, const char *filename)
 {
-   size_t need = strlen (filename) + 2;
+   size_t need = strlen (filename) + 3;
    bool root = (strcmp (directory, "/") == 0);
    char *result;
 
@@ -1322,6 +1322,7 @@ static int completeFilenameCB (EObjectType objectType GCC_UNUSED,
  */
 void deleteFileCB (EObjectType objectType GCC_UNUSED, void *object, void *clientData)
 {
+#if 0
    CDKSCROLL *fscroll = (CDKSCROLL *)object;
    CDKFSELECT *fselect = (CDKFSELECT *)clientData;
    const char *buttons[] =
@@ -1380,6 +1381,7 @@ void deleteFileCB (EObjectType objectType GCC_UNUSED, void *object, void *client
 
    /* Redraw the file selector. */
    drawCDKFselect (fselect, ObjOf (fselect)->box);
+#endif
 }
 
 /*
diff --git a/gen-scale.c b/gen-scale.c
index d459dc6..e69de29 100644
--- a/gen-scale.c
+++ b/gen-scale.c
@@ -1,816 +0,0 @@
-#include <cdk_int.h>
-
-/*
- * $Author: tom $
- * $Date: 2021/12/16 00:38:44 $
- * $Revision: 1.26 $
- */
-
-/*
- * Declare file local prototypes.
- */
-static void drawCDK<MIXED>Field (CDK<UPPER> * widget);
-
-DeclareCDKObjects (<UPPER>, <MIXED>, setCdk, <DTYPE>);
-
-/*
- * This function creates a widget.
- */
-CDK<UPPER> *newCDK<MIXED> (CDKSCREEN *cdkscreen,
-			   int xplace,
-			   int yplace,
-			   const char *title,
-			   const char *label,
-			   chtype fieldAttr,
-			   int fieldWidth,
-			   <CTYPE> start,
-			   <CTYPE> low,
-			   <CTYPE> high,
-			   <CTYPE> inc,
-			   <CTYPE> fastInc,
-#if <FLOAT>
-			   int digits,
-#endif <FLOAT>
-			   boolean Box,
-			   boolean shadow)
-{
-   /* *INDENT-EQLS* */
-   CDK<UPPER> *widget   = 0;
-   int parentWidth      = getmaxx (cdkscreen->window);
-   int parentHeight     = getmaxy (cdkscreen->window);
-   int boxHeight;
-   int boxWidth;
-   int horizontalAdjust, oldWidth;
-   int xpos             = xplace;
-   int ypos             = yplace;
-   int x, junk;
-   /* *INDENT-OFF* */
-   static const struct { int from; int to; } bindings[] = {
-		{ 'u',		KEY_UP },
-		{ 'U',		KEY_PPAGE },
-		{ CDK_BACKCHAR,	KEY_PPAGE },
-		{ CDK_FORCHAR,	KEY_NPAGE },
-		{ 'g',		KEY_HOME },
-		{ '^',		KEY_HOME },
-		{ 'G',		KEY_END },
-		{ '$',		KEY_END },
-   };
-   /* *INDENT-ON* */
-
-
-   if ((widget = newCDKObject (CDK<UPPER>, &my_funcs)) == 0)
-      return (0);
-
-   setCDK<MIXED>Box (widget, Box);
-
-   boxHeight = (BorderOf (widget) * 2) + 1;
-
-   /* Set some basic values of the widget's data field. */
-   widget->label = 0;
-   widget->labelLen = 0;
-   widget->labelWin = 0;
-
-   /*
-    * If the fieldWidth is a negative value, the fieldWidth will
-    * be COLS-fieldWidth, otherwise, the fieldWidth will be the
-    * given width.
-    */
-   fieldWidth = setWidgetDimension (parentWidth, fieldWidth, 0);
-   boxWidth = fieldWidth + 2 * BorderOf (widget);
-
-   /* Translate the label char *pointer to a chtype pointer. */
-   if (label != 0)
-   {
-      widget->label = char2Chtype (label, &widget->labelLen, &junk);
-      boxWidth = widget->labelLen + fieldWidth + 2;
-   }
-
-   oldWidth = boxWidth;
-   boxWidth = setCdkTitle (ObjOf (widget), title, boxWidth);
-   horizontalAdjust = (boxWidth - oldWidth) / 2;
-
-   boxHeight += TitleLinesOf (widget);
-
-   /*
-    * Make sure we didn't extend beyond the dimensions of the window.
-    */
-   boxWidth = (boxWidth > parentWidth ? parentWidth : boxWidth);
-   boxHeight = (boxHeight > parentHeight ? parentHeight : boxHeight);
-   fieldWidth = (fieldWidth > (boxWidth - widget->labelLen - 2 * BorderOf (widget))
-		 ? (boxWidth - widget->labelLen - 2 * BorderOf (widget))
-		 : fieldWidth);
-
-   /* Rejustify the x and y positions if we need to. */
-   alignxy (cdkscreen->window, &xpos, &ypos, boxWidth, boxHeight);
-
-   /* Make the widget's window. */
-   widget->win = newwin (boxHeight, boxWidth, ypos, xpos);
-
-   /* Is the main window null??? */
-   if (widget->win == 0)
-   {
-      destroyCDKObject (widget);
-      return (0);
-   }
-
-   /* Create the widget's label window. */
-   if (widget->label != 0)
-   {
-      widget->labelWin = subwin (widget->win,
-				 1, widget->labelLen,
-				 ypos + TitleLinesOf (widget) + BorderOf (widget),
-				 xpos + horizontalAdjust + BorderOf (widget));
-      if (widget->labelWin == 0)
-      {
-	 destroyCDKObject (widget);
-	 return (0);
-      }
-   }
-
-   /* Create the widget's data field window. */
-   widget->fieldWin = subwin (widget->win,
-			      1, fieldWidth,
-			      (ypos + TitleLinesOf (widget) + BorderOf (widget)),
-			      (xpos
-			       + widget->labelLen
-			       + horizontalAdjust
-			       + BorderOf (widget)));
-   if (widget->fieldWin == 0)
-   {
-      destroyCDKObject (widget);
-      return (0);
-   }
-   keypad (widget->fieldWin, TRUE);
-   keypad (widget->win, TRUE);
-
-   /* *INDENT-EQLS* Create the widget's data field. */
-   ScreenOf (widget)            = cdkscreen;
-   widget->parent               = cdkscreen->window;
-   widget->shadowWin            = 0;
-   widget->boxWidth             = boxWidth;
-   widget->boxHeight            = boxHeight;
-   widget->fieldWidth           = fieldWidth;
-   widget->fieldAttr            = (chtype)fieldAttr;
-   widget->current              = low;
-   widget->low                  = low;
-   widget->high                 = high;
-   widget->current              = start;
-   widget->inc                  = inc;
-   widget->fastinc              = fastInc;
-#if <FLOAT>
-   widget->digits               = digits;
-#endif <FLOAT>
-   initExitType (widget);
-   ObjOf (widget)->acceptsFocus = TRUE;
-   ObjOf (widget)->inputWindow  = widget->win;
-   widget->shadow               = shadow;
-
-   /* Do we want a shadow??? */
-   if (shadow)
-   {
-      widget->shadowWin = newwin (boxHeight, boxWidth, ypos + 1, xpos + 1);
-      if (widget->shadowWin == 0)
-      {
-	 destroyCDKObject (widget);
-	 return (0);
-      }
-   }
-
-   /* Setup the key bindings. */
-   for (x = 0; x < (int)SIZEOF (bindings); ++x)
-      bindCDKObject (v<UPPER>,
-		     widget,
-		     (chtype) bindings[x].from,
-		     getcCDKBind,
-		     (void *)(long)bindings[x].to);
-
-   registerCDKObject (cdkscreen, v<UPPER>, widget);
-
-   return (widget);
-}
-
-/*
- * This allows the person to use the widget's data field.
- */
-<CTYPE> activateCDK<MIXED> (CDK<UPPER> * widget, chtype *actions)
-{
-   <CTYPE> ret;
-
-   /* Draw the widget. */
-   drawCDK<MIXED> (widget, ObjOf (widget)->box);
-
-   if (actions == 0)
-   {
-      boolean functionKey;
-
-      for (;;)
-      {
-	 chtype input = (chtype) getchCDKObject (ObjOf (widget), &functionKey);
-
-	 /* Inject the character into the widget. */
-	 ret = (<CTYPE>) injectCDK<MIXED> (widget, input);
-	 if (widget->exitType != vEARLY_EXIT)
-	 {
-	    return ret;
-	 }
-      }
-   }
-   else
-   {
-      int length = chlen (actions);
-      int x = 0;
-
-      /* Inject each character one at a time. */
-      for (x = 0; x < length; x++)
-      {
-	 ret = (<CTYPE>) injectCDK<MIXED> (widget, actions[x]);
-	 if (widget->exitType != vEARLY_EXIT)
-	 {
-	    return ret;
-	 }
-      }
-   }
-
-   /* Set the exit type and return. */
-   setExitType (widget, 0);
-   return unknown<DTYPE>;
-}
-
-/*
- * Check if the value lies outside the low/high range.  If so, force it in.
- */
-static void limitCurrentValue (CDK<UPPER> * widget)
-{
-   if (widget->current < widget->low)
-   {
-      widget->current = widget->low;
-      Beep ();
-   }
-   else if (widget->current > widget->high)
-   {
-      widget->current = widget->high;
-      Beep ();
-   }
-}
-
-/*
- * Move the cursor to the given edit-position.
- */
-static int moveToEditPosition (CDK<UPPER> * widget, int newPosition)
-{
-   return wmove (widget->fieldWin, 0, widget->fieldWidth - newPosition - 1);
-}
-
-/*
- * Check if the cursor is on a valid edit-position.  This must be one of
- * the non-blank cells in the field.
- */
-static int validEditPosition (CDK<UPPER> * widget, int newPosition)
-{
-   chtype ch;
-   if (newPosition <= 0 || newPosition >= widget->fieldWidth)
-      return FALSE;
-   if (moveToEditPosition (widget, newPosition) == ERR)
-      return FALSE;
-   ch = winch (widget->fieldWin);
-   if (CharOf (ch) != ' ')
-      return TRUE;
-   if (newPosition > 1)
-   {
-      /* don't use recursion - only one level is wanted */
-      if (moveToEditPosition (widget, newPosition - 1) == ERR)
-	 return FALSE;
-      ch = winch (widget->fieldWin);
-      return CharOf (ch) != ' ';
-   }
-   return FALSE;
-}
-
-/*
- * Set the edit position.  Normally the cursor is one cell to the right of
- * the editable field.  Moving it left, over the field allows the user to
- * modify cells by typing in replacement characters for the field's value.
- */
-static void setEditPosition (CDK<UPPER> * widget, int newPosition)
-{
-   if (newPosition < 0)
-   {
-      Beep ();
-   }
-   else if (newPosition == 0)
-   {
-      widget->fieldEdit = newPosition;
-   }
-   else if (validEditPosition (widget, newPosition))
-   {
-      widget->fieldEdit = newPosition;
-   }
-   else
-   {
-      Beep ();
-   }
-}
-
-/*
- * Remove the character from the string at the given column, if it is blank.
- * Returns true if a change was made.
- */
-static bool removeChar (char *string, int col)
-{
-   bool result = FALSE;
-
-   if ((col >= 0) && (string[col] != ' '))
-   {
-      while (string[col] != '\0')
-      {
-	 string[col] = string[col + 1];
-	 ++col;
-      }
-      result = TRUE;
-   }
-   return result;
-}
-
-/*
- * Perform an editing function for the field.
- */
-static bool performEdit (CDK<UPPER> * widget, chtype input)
-{
-   bool result = FALSE;
-   int need = widget->fieldWidth;
-   char *temp = (char *)malloc ((size_t) need + 2);
-   char test;
-   int col = need - widget->fieldEdit - 1;
-#if <FLOAT>
-   double value;
-#define SCANF_FMT "%lg%c"
-#endif <FLOAT>
-#if <INT>
-   <CTYPE> value;
-#define SCANF_FMT "%<PRINT>%c"
-#endif <INT>
-
-   if (temp != 0)
-   {
-      bool modify = TRUE;
-      int base = 0;
-
-      wmove (widget->fieldWin, 0, base);
-      winnstr (widget->fieldWin, temp, need);
-      strcpy (temp + need, " ");
-      if (isChar (input))	/* replace the char at the cursor */
-      {
-	 temp[col] = (char) (input);
-      }
-      else if (input == KEY_BACKSPACE)	/* delete the char before the cursor */
-      {
-	 modify = removeChar (temp, col - 1);
-      }
-      else if (input == KEY_DC)	/* delete the char at the cursor */
-      {
-	 modify = removeChar (temp, col);
-      }
-      else
-      {
-	 modify = FALSE;
-      }
-      if (modify
-	  && sscanf (temp, SCANF_FMT, &value, &test) == 2
-	  && test == ' '
-	  && value >= widget->low
-	  && value <= widget->high)
-      {
-	 setCDK<MIXED>Value (widget, (<CTYPE>) value);
-	 result = TRUE;
-      }
-      free (temp);
-   }
-   return result;
-}
-
-#define Decrement(value,by) if (value - by < value) value -= by
-#define Increment(value,by) if (value + by > value) value += by
-
-/*
- * This function injects a single character into the widget.
- */
-static int _injectCDK<MIXED> (CDKOBJS *object, chtype input)
-{
-   CDK<UPPER> *widget = (CDK<UPPER> *) object;
-   int ppReturn = 1;
-   <CTYPE> ret = unknown<DTYPE>;
-   bool complete = FALSE;
-
-   /* Set the exit type. */
-   setExitType (widget, 0);
-
-   /* Draw the field. */
-   drawCDK<MIXED>Field (widget);
-
-   /* Check if there is a pre-process function to be called. */
-   if (PreProcessFuncOf (widget) != 0)
-   {
-      /* Call the pre-process function. */
-      ppReturn = PreProcessFuncOf (widget) (v<UPPER>,
-					    widget,
-					    PreProcessDataOf (widget),
-					    input);
-   }
-
-   /* Should we continue? */
-   if (ppReturn != 0)
-   {
-      /* Check for a key binding. */
-      if (checkCDKObjectBind (v<UPPER>, widget, input) != 0)
-      {
-	 checkEarlyExit (widget);
-	 complete = TRUE;
-      }
-      else
-      {
-	 switch (input)
-	 {
-	 case KEY_LEFT:
-	    setEditPosition (widget, widget->fieldEdit + 1);
-	    break;
-
-	 case KEY_RIGHT:
-	    setEditPosition (widget, widget->fieldEdit - 1);
-	    break;
-
-	 case KEY_DOWN:
-	    Decrement (widget->current, widget->inc);
-	    break;
-
-	 case KEY_UP:
-	    Increment (widget->current, widget->inc);
-	    break;
-
-	 case KEY_PPAGE:
-	    Increment (widget->current, widget->fastinc);
-	    break;
-
-	 case KEY_NPAGE:
-	    Decrement (widget->current, widget->fastinc);
-	    break;
-
-	 case KEY_HOME:
-	    widget->current = widget->low;
-	    break;
-
-	 case KEY_END:
-	    widget->current = widget->high;
-	    break;
-
-	 case KEY_TAB:
-	 case KEY_ENTER:
-	    setExitType (widget, input);
-	    ret = (widget->current);
-	    complete = TRUE;
-	    break;
-
-	 case KEY_ESC:
-	    setExitType (widget, input);
-	    complete = TRUE;
-	    break;
-
-	 case KEY_ERROR:
-	    setExitType (widget, input);
-	    complete = TRUE;
-	    break;
-
-	 case CDK_REFRESH:
-	    eraseCDKScreen (ScreenOf (widget));
-	    refreshCDKScreen (ScreenOf (widget));
-	    break;
-
-	 default:
-	    if (widget->fieldEdit)
-	    {
-	       if (!performEdit (widget, input))
-		  Beep ();
-	    }
-	    else
-	    {
-	       /*
-	        * The cursor is not within the editable text.  Interpret
-	        * input as commands.
-	        */
-	       switch (input)
-	       {
-	       case 'd':
-	       case '-':
-		  return _injectCDK<MIXED> (object, KEY_DOWN);
-	       case '+':
-		  return _injectCDK<MIXED> (object, KEY_UP);
-	       case 'D':
-		  return _injectCDK<MIXED> (object, KEY_NPAGE);
-	       case '0':
-		  return _injectCDK<MIXED> (object, KEY_HOME);
-	       default:
-		  Beep ();
-		  break;
-	       }
-	    }
-	    break;
-	 }
-      }
-      limitCurrentValue (widget);
-
-      /* Should we call a post-process? */
-      if (!complete && (PostProcessFuncOf (widget) != 0))
-      {
-	 PostProcessFuncOf (widget) (v<UPPER>,
-				     widget,
-				     PostProcessDataOf (widget),
-				     input);
-      }
-   }
-
-   if (!complete)
-   {
-      drawCDK<MIXED>Field (widget);
-      setExitType (widget, 0);
-   }
-
-   ResultOf (widget).value<DTYPE> = ret;
-   return (ret != unknown<DTYPE>);
-}
-
-/*
- * This moves the widget's data field to the given location.
- */
-static void _moveCDK<MIXED> (CDKOBJS *object,
-			     int xplace,
-			     int yplace,
-			     boolean relative,
-			     boolean refresh_flag)
-{
-   CDK<UPPER> *widget = (CDK<UPPER> *) object;
-   int currentX = getbegx (widget->win);
-   int currentY = getbegy (widget->win);
-   int xpos = xplace;
-   int ypos = yplace;
-   int xdiff = 0;
-   int ydiff = 0;
-
-   /*
-    * If this is a relative move, then we will adjust where we want
-    * to move to.
-    */
-   if (relative)
-   {
-      xpos = getbegx (widget->win) + xplace;
-      ypos = getbegy (widget->win) + yplace;
-   }
-
-   /* Adjust the window if we need to. */
-   alignxy (WindowOf (widget), &xpos, &ypos, widget->boxWidth, widget->boxHeight);
-
-   /* Get the difference. */
-   xdiff = currentX - xpos;
-   ydiff = currentY - ypos;
-
-   /* Move the window to the new location. */
-   moveCursesWindow (widget->win, -xdiff, -ydiff);
-   moveCursesWindow (widget->labelWin, -xdiff, -ydiff);
-   moveCursesWindow (widget->fieldWin, -xdiff, -ydiff);
-   moveCursesWindow (widget->shadowWin, -xdiff, -ydiff);
-
-   /* Touch the windows so they 'move'. */
-   refreshCDKWindow (WindowOf (widget));
-
-   /* Redraw the window, if they asked for it. */
-   if (refresh_flag)
-   {
-      drawCDK<MIXED> (widget, ObjOf (widget)->box);
-   }
-}
-
-/*
- * This function draws the widget.
- */
-static void _drawCDK<MIXED> (CDKOBJS *object, boolean Box)
-{
-   CDK<UPPER> *widget = (CDK<UPPER> *) object;
-
-   /* Draw the shadow. */
-   if (widget->shadowWin != 0)
-   {
-      drawShadow (widget->shadowWin);
-   }
-
-   /* Box the widget if asked. */
-   if (Box)
-   {
-      drawObjBox (widget->win, ObjOf (widget));
-   }
-
-   drawCdkTitle (widget->win, object);
-
-   /* Draw the label. */
-   if (widget->labelWin != 0)
-   {
-      writeChtype (widget->labelWin, 0, 0,
-		   widget->label,
-		   HORIZONTAL, 0,
-		   widget->labelLen);
-      wrefresh (widget->labelWin);
-   }
-   wrefresh (widget->win);
-
-   /* Draw the field window. */
-   drawCDK<MIXED>Field (widget);
-}
-
-/*
- * This draws the widget.
- */
-static void drawCDK<MIXED>Field (CDK<UPPER> * widget)
-{
-   char temp[256];
-
-   werase (widget->fieldWin);
-
-   /* Draw the value in the field. */
-#if <FLOAT>
-   {
-      char format[256];
-      int digits = MINIMUM (widget->digits, 30);
-      sprintf (format, "%%.%i<PRINT>", digits);
-      sprintf (temp, format, widget->current);
-   }
-#endif <FLOAT>
-#if <INT>
-   sprintf (temp, "%<PRINT>", widget->current);
-#endif <INT>
-   writeCharAttrib (widget->fieldWin,
-		    widget->fieldWidth - (int)strlen (temp) - 1,
-		    0,
-		    temp,
-		    widget->fieldAttr,
-		    HORIZONTAL,
-		    0,
-		    (int)strlen (temp));
-
-   moveToEditPosition (widget, widget->fieldEdit);
-   wrefresh (widget->fieldWin);
-}
-
-/*
- * This sets the background attribute of the widget.
- */
-static void _setBKattr<MIXED> (CDKOBJS *object, chtype attrib)
-{
-   if (object != 0)
-   {
-      CDK<UPPER> *widget = (CDK<UPPER> *) object;
-
-      wbkgd (widget->win, attrib);
-      wbkgd (widget->fieldWin, attrib);
-      if (widget->labelWin != 0)
-      {
-	 wbkgd (widget->labelWin, attrib);
-      }
-   }
-}
-
-/*
- * This function destroys the widget.
- */
-static void _destroyCDK<MIXED> (CDKOBJS *object)
-{
-   if (object != 0)
-   {
-      CDK<UPPER> *widget = (CDK<UPPER> *) object;
-
-      cleanCdkTitle (object);
-      freeChtype (widget->label);
-
-      /* Clean up the windows. */
-      deleteCursesWindow (widget->fieldWin);
-      deleteCursesWindow (widget->labelWin);
-      deleteCursesWindow (widget->shadowWin);
-      deleteCursesWindow (widget->win);
-
-      /* Clean the key bindings. */
-      cleanCDKObjectBindings (v<UPPER>, widget);
-
-      /* Unregister this object. */
-      unregisterCDKObject (v<UPPER>, widget);
-   }
-}
-
-/*
- * This function erases the widget from the screen.
- */
-static void _eraseCDK<MIXED> (CDKOBJS *object)
-{
-   if (validCDKObject (object))
-   {
-      CDK<UPPER> *widget = (CDK<UPPER> *) object;
-
-      eraseCursesWindow (widget->labelWin);
-      eraseCursesWindow (widget->fieldWin);
-      eraseCursesWindow (widget->win);
-      eraseCursesWindow (widget->shadowWin);
-   }
-}
-
-/*
- * This function sets the low/high/current values of the widget.
- */
-void setCDK<MIXED> (CDK<UPPER> * widget, <CTYPE> low, <CTYPE> high, <CTYPE> value, boolean Box)
-{
-   setCDK<MIXED>LowHigh (widget, low, high);
-   setCDK<MIXED>Value (widget, value);
-   setCDK<MIXED>Box (widget, Box);
-}
-
-/*
- * This sets the digits.
- */
-#if <FLOAT>
-void setCDK<MIXED>Digits (CDK<UPPER> * widget, int digits)
-{
-   widget->digits = MAXIMUM (0, digits);
-}
-
-int getCDK<MIXED>Digits (CDK<UPPER> * widget)
-{
-   return widget->digits;
-}
-#endif <FLOAT>
-
-/*
- * This sets the widget's value.
- */
-void setCDK<MIXED>Value (CDK<UPPER> * widget, <CTYPE> value)
-{
-   widget->current = value;
-   limitCurrentValue (widget);
-}
-<CTYPE> getCDK<MIXED>Value (CDK<UPPER> * widget)
-{
-   return widget->current;
-}
-
-/*
- * This function sets the low/high values of the widget.
- */
-void setCDK<MIXED>LowHigh (CDK<UPPER> * widget, <CTYPE> low, <CTYPE> high)
-{
-   /* Make sure the values aren't out of bounds. */
-   if (low <= high)
-   {
-      widget->low = low;
-      widget->high = high;
-   }
-   else
-   {
-      widget->low = high;
-      widget->high = low;
-   }
-
-   /* Make sure the user hasn't done something silly. */
-   limitCurrentValue (widget);
-}
-<CTYPE> getCDK<MIXED>LowValue (CDK<UPPER> * widget)
-{
-   return widget->low;
-}
-<CTYPE> getCDK<MIXED>HighValue (CDK<UPPER> * widget)
-{
-   return widget->high;
-}
-
-/*
- * This sets the widget's box attribute.
- */
-void setCDK<MIXED>Box (CDK<UPPER> * widget, boolean Box)
-{
-   ObjOf (widget)->box = Box;
-   ObjOf (widget)->borderSize = Box ? 1 : 0;
-}
-boolean getCDK<MIXED>Box (CDK<UPPER> * widget)
-{
-   return ObjOf (widget)->box;
-}
-
-static void _focusCDK<MIXED> (CDKOBJS *object)
-{
-   CDK<UPPER> *widget = (CDK<UPPER> *) object;
-
-   drawCDK<MIXED> (widget, ObjOf (widget)->box);
-}
-
-static void _unfocusCDK<MIXED> (CDKOBJS *object)
-{
-   CDK<UPPER> *widget = (CDK<UPPER> *) object;
-
-   drawCDK<MIXED> (widget, ObjOf (widget)->box);
-}
-
-dummyRefreshData (<MIXED>)
-
-dummySaveData (<MIXED>)
diff --git a/include/cdk.h b/include/cdk.h
index 737e272..7d1f339 100644
--- a/include/cdk.h
+++ b/include/cdk.h
@@ -73,6 +73,14 @@ extern "C" {
 #endif
 #ifdef HAVE_DIRENT_H
 #include <dirent.h>
+#else
+#include <windows.h>
+#include <io.h>
+#define mode_t unsigned int
+#define S_IFIFO _S_IFIFO
+#define S_IRUSR _S_IREAD
+#define S_IWUSR _S_IWRITE
+#define S_IXUSR 0
 #endif
 #include <time.h>
 #include <errno.h>
@@ -219,6 +227,10 @@ typedef enum {vFRONT, vBACK, vBOTH} EStripType;
  */
 typedef enum {vEARLY_EXIT, vESCAPE_HIT, vNORMAL, vNEVER_ACTIVATED, vERROR} EExitType;
 
+#if _WIN32
+#define boolean CDKboolean
+#endif
+
 /*
  * This defines a boolean type.
  */
@@ -293,7 +305,7 @@ void stopCDKDebug (FILE *fd);
 #include <itemlist.h>
 #include <label.h>
 #include <marquee.h>
-#include <matrix.h>
+//#include <matrix.h>
 #include <mentry.h>
 #include <menu.h>
 #include <radio.h>
@@ -301,21 +313,21 @@ void stopCDKDebug (FILE *fd);
 #include <selection.h>
 #include <swindow.h>
 #include <template.h>
-#include <viewer.h>
+//#include <viewer.h>
 #include <traverse.h>
 #include <button.h>
 
 /*
  * Generated headers:
  */
-#include <dscale.h>
-#include <fscale.h>
-#include <scale.h>
-#include <uscale.h>
-
-#include <fslider.h>
+//#include <dscale.h>
+//#include <fscale.h>
+//#include <scale.h>
+//#include <uscale.h>
+//
+//#include <fslider.h>
 #include <slider.h>
-#include <uslider.h>
+//#include <uslider.h>
 
 /*
  * Low-level object drawing
diff --git a/include/cdk_config.h b/include/cdk_config.h
new file mode 100644
index 0000000..917f5b1
--- /dev/null
+++ b/include/cdk_config.h
@@ -0,0 +1,69 @@
+/* include/cdk_config.h.  Generated automatically by configure.  */
+/*
+ * $Id: config.hin,v 1.2 2000/01/17 14:48:19 tom Exp $
+ */
+
+#ifndef CDK_CONFIG_H
+#define CDK_CONFIG_H 1
+
+
+#define CC_HAS_PROTOS 1
+#define CDK_CONST /*nothing*/
+#define CDK_CSTRING CDK_CONST char *
+#define CDK_CSTRING2 CDK_CONST char * CDK_CONST *
+#define CDK_PATCHDATE 20140118
+#define CDK_VERSION "5.0"
+#if !_WIN32
+#define HAVE_DIRENT_H 1
+#endif
+#define HAVE_GETBEGX 1
+#define HAVE_GETBEGY 1
+#define HAVE_GETCWD 1
+#define HAVE_GETLOGIN 1
+#define HAVE_GETMAXX 1
+#define HAVE_GETMAXY 1
+#if !_WIN32
+#define HAVE_GETOPT_H 1
+#define HAVE_GETOPT_HEADER 1
+#define HAVE_GRP_H 1
+#endif
+#define HAVE_INTTYPES_H 1
+#define HAVE_LIMITS_H 1
+#if !_WIN32
+#define HAVE_LSTAT 1
+#endif
+#define HAVE_MEMORY_H 1
+#define HAVE_MKTIME 1
+//#define HAVE_NCURSES_H 1
+#if !_WIN32
+#define HAVE_PWD_H 1
+#endif
+#define HAVE_SETLOCALE 1
+#define HAVE_SLEEP 1
+#define HAVE_START_COLOR 1
+#define HAVE_STDINT_H 1
+#define HAVE_STDLIB_H 1
+#define HAVE_STRDUP 1
+#define HAVE_STRERROR 1
+#define HAVE_STRINGS_H 1
+#define HAVE_STRING_H 1
+#define HAVE_SYS_STAT_H 1
+#define HAVE_SYS_TYPES_H 1
+#define HAVE_TERM_H 1
+#define HAVE_TYPE_CHTYPE 1
+#define HAVE_UNCTRL_H 1
+#if !_WIN32
+#define HAVE_UNISTD_H 1
+#endif
+#define MIXEDCASE_FILENAMES 1
+//#define NCURSES 1
+#define PACKAGE "cdk"
+#define STDC_HEADERS 1
+#define SYSTEM_NAME "linux-gnu"
+#define TYPE_CHTYPE_IS_SCALAR 1
+
+#if !defined(HAVE_LSTAT) && !defined(lstat)
+#define lstat(f,b) stat(f,b)
+#endif
+
+#endif /* CDK_CONFIG_H */
diff --git a/include/cdk_util.h b/include/cdk_util.h
index bae8a48..293131b 100644
--- a/include/cdk_util.h
+++ b/include/cdk_util.h
@@ -46,6 +46,10 @@ extern "C" {
  * use or other dealings in this Software without prior written authorization.
  */
 
+#if _WIN32
+#define Beep CDKBeep
+#endif
+
 /*
  * This beeps at the user. The standard curses beep() does not
  * flush the stream, so it will only beep until a force is made.
@@ -286,6 +290,14 @@ void cleanChtype (
 		int		/* length */,
 		chtype		/* character */);
 
+#define HAVE_CDKUTF8 1
+/* This takes the first byte of a UTF-8 character and returns the length of that character. */
+unsigned int utf8charlen(unsigned char /* char */);
+/* This returns the length of the UTF-8 string. */
+size_t utf8strlen(const char * /* string */);
+/** This returns the absolute position in a UTF-8 string of a character position. */
+int utf8charpos(char * /* string */, int /* pos */);
+
 /*
  * This takes a chtype pointer and returns a char pointer.
  */
diff --git a/include/cdk_version.h b/include/cdk_version.h
new file mode 100644
index 0000000..37b6098
--- /dev/null
+++ b/include/cdk_version.h
@@ -0,0 +1,56 @@
+/*
+ * $Id: cdk_version.hin,v 1.2 2012/03/20 22:10:36 tom Exp $
+ */
+
+#ifndef CDK_VERSION_H
+#define CDK_VERSION_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Copyright 2002,2012 Thomas E. Dickey
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgment:
+ * 	This product includes software developed by Thomas E. Dickey
+ * 	and contributors.
+ * 4. Neither the name of Thomas E. Dickey, nor the names of contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THOMAS E. DICKEY AND CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THOMAS E. DICKEY OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#define CDK_VERSION_MAJOR "5"
+#define CDK_VERSION_MINOR "0"
+#define CDK_VERSION_PATCH "20140118"
+
+/*
+ * Runtime to return the same version information.
+ */
+const char *CDKVersion (void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* CDK_VERSION_H */
diff --git a/include/gen-scale.h b/include/gen-scale.h
index 66bcb44..e69de29 100644
--- a/include/gen-scale.h
+++ b/include/gen-scale.h
@@ -1,227 +0,0 @@
-/*
- * $Id: gen-scale.h,v 1.9 2012/03/20 21:59:39 tom Exp $
- */
-
-#ifndef CDKINCLUDES
-#ifndef CDK<UPPER>_H
-#define CDK<UPPER>_H	1
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef CDK_H
-#define CDKINCLUDES
-#include <cdk.h>
-#undef CDKINCLUDES
-#include <binding.h>
-#include <cdkscreen.h>
-#include <cdk_objs.h>
-#endif
-
-/*
- * Copyright 2004,2012 Thomas E. Dickey
- *
- * 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.
- */
-
-/*
- * Define the CDK widget <MIXED> structure.
- */
-struct S<MIXED> {
-   CDKOBJS	obj;
-   WINDOW *	parent;
-   WINDOW *	win;
-   WINDOW *	shadowWin;
-   WINDOW *	fieldWin;
-   WINDOW *	labelWin;
-   int		titleAdj;
-   chtype *	label;
-   int		labelLen;
-   int		boxHeight;
-   int		boxWidth;
-   int		fieldWidth;
-   int		fieldEdit;	/* offset from right-margin of field */
-   chtype	fieldAttr;
-   <CTYPE>	low;
-   <CTYPE>	high;
-   <CTYPE>	inc;
-   <CTYPE>	fastinc;
-   <CTYPE>	current;
-#if <FLOAT>
-   int		digits;
-#endif <FLOAT>
-   EExitType	exitType;
-   boolean	shadow;
-};
-typedef struct S<MIXED> CDK<UPPER>;
-
-/*
- * This creates a new pointer to a CDK <CTYPE>-<MIXED> widget.
- */
-CDK<UPPER> *newCDK<MIXED> (
-		CDKSCREEN *	/* cdkscreen */,
-		int		/* xpos */,
-		int		/* ypos */,
-		const char *	/* title */,
-		const char *	/* label */,
-		chtype		/* fieldAttr */,
-		int		/* fieldWidth */,
-		<CTYPE>		/* start */,
-		<CTYPE>		/* low */,
-		<CTYPE>		/* high */,
-		<CTYPE>		/* inc */,
-		<CTYPE>		/* fastInc */,
-#if <FLOAT>
-		int		/* digits */,
-#endif <FLOAT>
-		boolean		/* Box */,
-		boolean		/* shadow */);
-
-/*
- * This activates the widget.
- */
-<CTYPE>	activateCDK<MIXED> (
-		CDK<UPPER> *	/* widget */,
-		chtype *	/* actions */);
-
-/*
- * This injects a single character into the widget.
- */
-#define injectCDK<MIXED>(obj,input) injectCDKObject(obj,input,<DTYPE>)
-
-/*
- * This sets various attributes of the widget.
- */
-void setCDK<MIXED> (
-		CDK<UPPER> *	/* widget */,
-		<CTYPE>		/* low */,
-		<CTYPE>		/* high */,
-		<CTYPE>		/* value */,
-		boolean		/* Box */);
-
-/*
- * These set/get the low and high values.
- */
-void setCDK<MIXED>LowHigh (
-		CDK<UPPER> *	/* widget */,
-		<CTYPE>		/* low */,
-		<CTYPE>		/* high */);
-
-<CTYPE>	getCDK<MIXED>LowValue (
-		CDK<UPPER> *	/* widget */);
-
-<CTYPE>	getCDK<MIXED>HighValue (
-		CDK<UPPER> *	/* widget */);
-
-/*
- * These set/get the digits.
- */
-#if <FLOAT>
-void setCDK<MIXED>Digits (
-		CDK<UPPER> *	/* widget */,
-		int		/* digits */);
-
-int getCDK<MIXED>Digits (
-		CDK<UPPER> *	/* widget */);
-#endif <FLOAT>
-
-/*
- * These set/get the current value.
- */
-void setCDK<MIXED>Value (
-		CDK<UPPER> *	/* widget */,
-		<CTYPE>		/* value */);
-
-<CTYPE>	getCDK<MIXED>Value (
-		CDK<UPPER> *	/* widget */);
-
-/*
- * This sets the box attribute of the widget.
- */
-void setCDK<MIXED>Box (
-		CDK<UPPER> *	/* widget */,
-		boolean		/* Box */);
-
-boolean getCDK<MIXED>Box (
-		CDK<UPPER> *	/* widget */);
-
-/*
- * These set the drawing characters of the widget.
- */
-#define setCDK<MIXED>ULChar(w,c)             setULCharOf(w,c)
-#define setCDK<MIXED>URChar(w,c)             setURCharOf(w,c)
-#define setCDK<MIXED>LLChar(w,c)             setLLCharOf(w,c)
-#define setCDK<MIXED>LRChar(w,c)             setLRCharOf(w,c)
-#define setCDK<MIXED>VerticalChar(w,c)       setVTCharOf(w,c)
-#define setCDK<MIXED>HorizontalChar(w,c)     setHZCharOf(w,c)
-#define setCDK<MIXED>BoxAttribute(w,c)       setBXAttrOf(w,c)
-
-/*
- * This sets the background color of the widget.
- */
-#define setCDK<MIXED>BackgroundColor(w,c) setCDKObjectBackgroundColor(ObjOf(w),c)
-
-/*
- * This sets the background attribute of the widget.
- */ 
-#define setCDK<MIXED>BackgroundAttrib(w,c) setBKAttrOf(w,c)
-
-/*
- * This draws the widget on the screen.
- */
-#define drawCDK<MIXED>(obj,Box) drawCDKObject(obj,Box)
-
-/*
- * This erases the widget from the screen.
- */
-#define eraseCDK<MIXED>(obj) eraseCDKObject(obj)
-
-/*
- * This moves the widget to the given location on the screen.
- */
-#define moveCDK<MIXED>(obj,xpos,ypos,relative,refresh) moveCDKObject(obj,xpos,ypos,relative,refresh)
-
-/*
- * This allows the user to interactively position the widget on the screen.
- */
-#define positionCDK<MIXED>(widget) positionCDKObject(ObjOf(widget),widget->win)
-
-/*
- * This destroys the widget and associated memory.
- */
-#define destroyCDK<MIXED>(obj) destroyCDKObject(obj)
-
-/*
- * These set the pre/post process callback functions.
- */
-#define setCDK<MIXED>PreProcess(w,f,d)  setCDKObjectPreProcess(ObjOf(w),f,d)
-#define setCDK<MIXED>PostProcess(w,f,d) setCDKObjectPostProcess(ObjOf(w),f,d)
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* CDK<UPPER>_H */
-#endif /* CDKINCLUDES */
diff --git a/include/slider.h b/include/slider.h
new file mode 100644
index 0000000..7fd0868
--- /dev/null
+++ b/include/slider.h
@@ -0,0 +1,213 @@
+/*
+ * $Id: gen-slider.h,v 1.9 2012/03/20 21:59:30 tom Exp $
+ */
+
+#ifndef CDKINCLUDES
+#ifndef CDKSLIDER_H
+#define CDKSLIDER_H	1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef CDK_H
+#define CDKINCLUDES
+#include <cdk.h>
+#undef CDKINCLUDES
+#include <binding.h>
+#include <cdkscreen.h>
+#include <cdk_objs.h>
+#endif
+
+/*
+ * Copyright 2004,2012 Thomas E. Dickey
+ *
+ * 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.
+ */
+
+/*
+ * Define the CDK widget Slider structure.
+ */
+struct SSlider {
+   CDKOBJS	obj;
+   WINDOW *	parent;
+   WINDOW *	win;
+   WINDOW *	shadowWin;
+   WINDOW *	fieldWin;
+   WINDOW *	labelWin;
+   int		titleAdj;
+   chtype *	label;
+   int		labelLen;
+   int		boxHeight;
+   int		boxWidth;
+   int		fieldWidth;
+   int		fieldEdit;	/* offset from right-margin of field */
+   chtype	filler;
+   int	low;
+   int	high;
+   int	inc;
+   int	fastinc;
+   int	current;
+   EExitType	exitType;
+   boolean	shadow;
+};
+typedef struct SSlider CDKSLIDER;
+
+/*
+ * This creates a new pointer to a CDK int-Slider widget.
+ */
+CDKSLIDER *newCDKSlider (
+		CDKSCREEN *	/* cdkscreen */,
+		int		/* xpos */,
+		int		/* ypos */,
+		const char *	/* title */,
+		const char *	/* label */,
+		chtype		/* fieldAttr */,
+		int		/* fieldWidth */,
+		int		/* start */,
+		int		/* low */,
+		int		/* high */,
+		int		/* inc */,
+		int		/* fastInc */,
+		boolean		/* Box */,
+		boolean		/* shadow */);
+
+/*
+ * This activates the widget.
+ */
+int activateCDKSlider (
+		CDKSLIDER *	/* widget */,
+		chtype *	/* actions */);
+
+/*
+ * This injects a single character into the widget.
+ */
+#define injectCDKSlider(obj,input) injectCDKObject(obj,input,Int)
+
+/*
+ * This sets various attributes of the widget.
+ */
+void setCDKSlider (
+		CDKSLIDER *	/* widget */,
+		int		/* low */,
+		int		/* high */,
+		int		/* value */,
+		boolean		/* Box */);
+
+/*
+ * These set/get the low and high values.
+ */
+void setCDKSliderLowHigh (
+		CDKSLIDER *	/* widget */,
+		int		/* low */,
+		int		/* high */);
+
+int getCDKSliderLowValue (
+		CDKSLIDER *	/* widget */);
+
+int getCDKSliderHighValue (
+		CDKSLIDER *	/* widget */);
+
+/*
+ * These set/get the digits.
+ */
+
+/*
+ * These set/get the current value.
+ */
+void setCDKSliderValue (
+		CDKSLIDER *	/* widget */,
+		int		/* value */);
+
+int getCDKSliderValue (
+		CDKSLIDER *	/* widget */);
+
+/*
+ * This sets the box attribute of the widget.
+ */
+void setCDKSliderBox (
+		CDKSLIDER *	/* widget */,
+		boolean		/* Box */);
+
+boolean getCDKSliderBox (
+		CDKSLIDER *	/* widget */);
+
+/*
+ * These set the drawing characters of the widget.
+ */
+#define setCDKSliderULChar(w,c)            setULCharOf(w,c)
+#define setCDKSliderURChar(w,c)            setURCharOf(w,c)
+#define setCDKSliderLLChar(w,c)            setLLCharOf(w,c)
+#define setCDKSliderLRChar(w,c)            setLRCharOf(w,c)
+#define setCDKSliderVerticalChar(w,c)      setVTCharOf(w,c)
+#define setCDKSliderHorizontalChar(w,c)    setHZCharOf(w,c)
+#define setCDKSliderBoxAttribute(w,c)      setBXAttrOf(w,c)
+
+/*
+ * This sets the background color of the widget.
+ */
+#define setCDKSliderBackgroundColor(w,c) setCDKObjectBackgroundColor(ObjOf(w),c)
+
+/*
+ * This sets the background attribute of the widget.
+ */ 
+#define setCDKSliderBackgroundAttrib(w,c) setBKAttrOf(w,c)
+
+/*
+ * This draws the widget on the screen.
+ */
+#define drawCDKSlider(obj,Box) drawCDKObject(obj,Box)
+
+/*
+ * This erases the widget from the screen.
+ */
+#define eraseCDKSlider(obj) eraseCDKObject(obj)
+
+/*
+ * This moves the widget to the given location on the screen.
+ */
+#define moveCDKSlider(obj,xpos,ypos,relative,refresh) moveCDKObject(obj,xpos,ypos,relative,refresh)
+
+/*
+ * This allows the user to interactively position the widget on the screen.
+ */
+#define positionCDKSlider(widget) positionCDKObject(ObjOf(widget),widget->win)
+
+/*
+ * This destroys the widget and associated memory.
+ */
+#define destroyCDKSlider(obj) destroyCDKObject(obj)
+
+/*
+ * These set the pre/post process callback functions.
+ */
+#define setCDKSliderPreProcess(w,f,d)  setCDKObjectPreProcess(ObjOf(w),f,d)
+#define setCDKSliderPostProcess(w,f,d) setCDKObjectPostProcess(ObjOf(w),f,d)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* CDKSLIDER_H */
+#endif /* CDKINCLUDES */
diff --git a/itemlist.c b/itemlist.c
index 099b993..b9c8403 100644
--- a/itemlist.c
+++ b/itemlist.c
@@ -448,6 +448,8 @@ void drawCDKItemlistField (CDKITEMLIST *itemlist, boolean highlight)
    int currentItem = itemlist->currentItem;
    int len;
    int x;
+   char *s, *p;
+   int charlen;
 
    /* Determine how much we have to draw. */
    len = MINIMUM (itemlist->itemLen[currentItem], itemlist->fieldWidth);
@@ -455,19 +457,25 @@ void drawCDKItemlistField (CDKITEMLIST *itemlist, boolean highlight)
    /* Erase the field window. */
    werase (itemlist->fieldWin);
 
+   s = chtype2Char (itemlist->item[currentItem]), p = s;
    /* Draw in the current item in the field. */
-   for (x = 0; x < len; x++)
+   for (x = 0; x < len; x++, p+=charlen)
    {
-      chtype c = itemlist->item[currentItem][x];
+      charlen = utf8charlen(*p);
 
       if (highlight)
       {
-	 c = CharOf (c) | A_REVERSE;
+	 wattron(itemlist->fieldWin, A_REVERSE);
       }
 
-      (void)mvwaddch (itemlist->fieldWin, 0,
+      (void)mvwaddnstr (itemlist->fieldWin, 0,
 		      x + itemlist->itemPos[currentItem],
-		      c);
+		      (const char *)p, charlen);
+
+      if (highlight)
+      {
+	 wattroff(itemlist->fieldWin, A_REVERSE);
+      }
    }
 
    /* Redraw the field window. */
diff --git a/matrix.c b/matrix.c
index 0cabe97..e69de29 100644
--- a/matrix.c
+++ b/matrix.c
@@ -1,1788 +0,0 @@
-#include <cdk_int.h>
-
-/*
- * $Author: tom $
- * $Date: 2021/12/16 01:09:14 $
- * $Revision: 1.200 $
- */
-
-/*
- * Declare file local prototypes.
- */
-static void highlightCDKMatrixCell (CDKMATRIX *matrix);
-static void CDKMatrixCallBack (CDKMATRIX *matrix, chtype input);
-static void drawCDKMatrixCell (CDKMATRIX *matrix,
-			       int srow, int scol,
-			       int vrow, int vcol,
-			       boolean Box);
-static void drawCurCDKMatrixCell (CDKMATRIX *matrix);
-static void drawEachCDKMatrixCell (CDKMATRIX *matrix);
-static void drawEachColTitle (CDKMATRIX *matrix);
-static void drawEachRowTitle (CDKMATRIX *matrix);
-static void drawOldCDKMatrixCell (CDKMATRIX *matrix);
-static void redrawTitles (CDKMATRIX *matrix, int row, int col);
-
-#define emptyString(s) ((s) == 0 || *(s) == '\0')
-
-#define CurMatrixCell(matrix) \
-	    MATRIX_CELL (matrix, matrix->crow, matrix->ccol)
-
-#define CurMatrixInfo(matrix) \
-	    MATRIX_INFO (matrix, \
-	    matrix->trow + matrix->crow - 1, \
-	    matrix->lcol + matrix->ccol - 1)
-
-DeclareCDKObjects (MATRIX, Matrix, setCdk, Int);
-
-#define WHOLE_BOX ACS_ULCORNER, ACS_URCORNER, ACS_LLCORNER, ACS_LRCORNER
-
-#define TOP_C_BOX ACS_ULCORNER, ACS_URCORNER, ACS_LTEE,     ACS_RTEE
-#define MID_C_BOX ACS_LTEE,     ACS_RTEE,     ACS_LTEE,     ACS_RTEE
-#define BOT_C_BOX ACS_LTEE,     ACS_RTEE,     ACS_LLCORNER, ACS_LRCORNER
-
-#define LFT_R_BOX ACS_ULCORNER, ACS_TTEE,     ACS_LLCORNER, ACS_BTEE
-#define MID_R_BOX ACS_TTEE,     ACS_TTEE,     ACS_BTEE,     ACS_BTEE
-#define RGT_R_BOX ACS_TTEE,     ACS_URCORNER, ACS_BTEE,     ACS_LRCORNER
-
-#define LFT_T_BOX ACS_ULCORNER, ACS_TTEE,     ACS_LTEE,     ACS_PLUS
-#define MID_T_BOX ACS_TTEE,     ACS_TTEE,     ACS_PLUS,     ACS_PLUS
-#define RGT_T_BOX ACS_TTEE,     ACS_URCORNER, ACS_PLUS,     ACS_RTEE
-
-#define LFT_M_BOX ACS_LTEE,     ACS_PLUS,     ACS_LTEE,     ACS_PLUS
-#define MID_M_BOX ACS_PLUS,     ACS_PLUS,     ACS_PLUS,     ACS_PLUS
-#define RGT_M_BOX ACS_PLUS,     ACS_RTEE,     ACS_PLUS,     ACS_RTEE
-
-#define LFT_B_BOX ACS_LTEE,     ACS_PLUS,     ACS_LLCORNER, ACS_BTEE
-#define MID_B_BOX ACS_PLUS,     ACS_PLUS,     ACS_BTEE,     ACS_BTEE
-#define RGT_B_BOX ACS_PLUS,     ACS_RTEE,     ACS_BTEE,     ACS_LRCORNER
-
-#define MyBox(cell,what,attr) attrbox(cell, what, ACS_HLINE, ACS_VLINE, attr)
-
-/*
- * This function creates the matrix widget.
- */
-CDKMATRIX *newCDKMatrix (CDKSCREEN *cdkscreen,
-			 int xplace,
-			 int yplace,
-			 int rows,
-			 int cols,
-			 int vrows,
-			 int vcols,
-			 const char *title,
-			 CDK_CSTRING2 rowtitles,
-			 CDK_CSTRING2 coltitles,
-			 int *colwidths,
-			 int *colvalues,
-			 int rspace,
-			 int cspace,
-			 chtype filler,
-			 int dominant,
-			 boolean Box,
-			 boolean boxCell,
-			 boolean shadow)
-{
-   /* *INDENT-EQLS* */
-   CDKMATRIX *matrix    = 0;
-   int parentWidth      = getmaxx (cdkscreen->window);
-   int parentHeight     = getmaxy (cdkscreen->window);
-   int boxHeight        = 0;
-   int boxWidth         = 0;
-   int xpos             = xplace;
-   int ypos             = yplace;
-   int maxWidth;
-   int maxRowTitleWidth = 0;
-   int rowSpace         = MAXIMUM (0, rspace);
-   int colSpace         = MAXIMUM (0, cspace);
-   int begx             = 0;
-   int begy             = 0;
-   int cellWidth        = 0;
-   char **temp          = 0;
-   int x, y;
-   int borderw          = 0;
-   bool have_rowtitles  = FALSE;
-   bool have_coltitles  = FALSE;
-   /* *INDENT-OFF* */
-   static const struct { int from; int to; } bindings[] = {
-      { CDK_FORCHAR,	KEY_NPAGE },
-      { CDK_BACKCHAR,	KEY_PPAGE },
-   };
-   /* *INDENT-ON* */
-
-   if ((matrix = newCDKObject (CDKMATRIX, &my_funcs)) == 0)
-   {
-      return (0);
-   }
-
-   setCDKMatrixBox (matrix, Box);
-   borderw = (ObjOf (matrix)->box) ? 1 : 0;
-
-   /* Make sure that the number of rows/cols/vrows/vcols is not zero. */
-   if (rows <= 0 || cols <= 0 || vrows <= 0 || vcols <= 0)
-   {
-      destroyCDKObject (matrix);
-      return (0);
-   }
-#if NEW_CDKMATRIX
-   matrix->cell = typeCallocN (WINDOW *, (rows + 1) * (cols + 1));
-   matrix->info = typeCallocN (char *, (rows + 1) * (cols + 1));
-#endif
-
-   /*
-    * Make sure the number of virtual cells is not larger than
-    * the physical size.
-    */
-   vrows = (vrows > rows ? rows : vrows);
-   vcols = (vcols > cols ? cols : vcols);
-
-   /* Set these early, since they are used in matrix index computations */
-   /* *INDENT-EQLS* */
-   matrix->rows        = rows;
-   matrix->cols        = cols;
-   /* columns */
-   matrix->colwidths   = typeCallocN (int, cols + 1);
-   matrix->colvalues   = typeCallocN (int, cols + 1);
-   matrix->coltitle    = typeCallocN (chtype *, cols + 1);
-   matrix->coltitleLen = typeCallocN (int, cols + 1);
-   matrix->coltitlePos = typeCallocN (int, cols + 1);
-   /* titles */
-   matrix->rowtitle    = typeCallocN (chtype *, rows + 1);
-   matrix->rowtitleLen = typeCallocN (int, rows + 1);
-   matrix->rowtitlePos = typeCallocN (int, rows + 1);
-
-   /*
-    * Count the number of lines in the title (see setCdkTitle).
-    */
-   temp = CDKsplitString (title, '\n');
-   TitleLinesOf (matrix) = (int)CDKcountStrings ((CDK_CSTRING2)temp);
-   CDKfreeStrings (temp);
-
-   /* Determine the height of the box. */
-   if (vrows == 1)
-   {
-      boxHeight = 6 + TitleLinesOf (matrix);
-   }
-   else
-   {
-      if (rowSpace == 0)
-      {
-	 boxHeight = (6 + TitleLinesOf (matrix) +
-		      ((vrows - 1) * 2));
-      }
-      else
-      {
-	 boxHeight = (3 + TitleLinesOf (matrix) +
-		      (vrows * 3) + ((vrows - 1) * (rowSpace - 1)));
-      }
-   }
-
-   /* Determine the maximum row title width */
-   for (x = 1; x <= rows; x++)
-   {
-      if (rowtitles && !emptyString (rowtitles[x]))	/*VR */
-	 have_rowtitles = TRUE;
-      matrix->rowtitle[x] = char2Chtype (rowtitles ? rowtitles[x] : 0,	/*VR */
-					 &matrix->rowtitleLen[x],
-					 &matrix->rowtitlePos[x]);
-      maxRowTitleWidth = MAXIMUM (maxRowTitleWidth, matrix->rowtitleLen[x]);
-   }
-
-   if (have_rowtitles)
-   {
-      matrix->maxrt = maxRowTitleWidth + 2;
-
-      /* We need to rejustify the row title cell info. */
-      for (x = 1; x <= rows; x++)
-      {
-	 matrix->rowtitlePos[x] = justifyString (matrix->maxrt,
-						 matrix->rowtitleLen[x],
-						 matrix->rowtitlePos[x]);
-      }
-   }
-   else
-   {
-      matrix->maxrt = 0;
-   }
-
-   /* Determine the width of the matrix. */
-   maxWidth = 2 + matrix->maxrt;
-   for (x = 1; x <= vcols; x++)
-   {
-      maxWidth += colwidths[x] + 2 + colSpace;
-   }
-   maxWidth -= (colSpace - 1);
-   boxWidth = MAXIMUM (maxWidth, boxWidth);
-
-   boxWidth = setCdkTitle (ObjOf (matrix), title, boxWidth);
-
-   /*
-    * Make sure the dimensions of the window didn't
-    * extend beyond the dimensions of the parent window.
-    */
-   boxWidth = (boxWidth > parentWidth ? parentWidth : boxWidth);
-   boxHeight = (boxHeight > parentHeight ? parentHeight : boxHeight);
-
-   /* Rejustify the x and y positions if we need to. */
-   alignxy (cdkscreen->window, &xpos, &ypos, boxWidth, boxHeight);
-
-   /* Make the pop-up window. */
-   matrix->win = newwin (boxHeight, boxWidth, ypos, xpos);
-
-   if (matrix->win == 0)
-   {
-      destroyCDKObject (matrix);
-      return (0);
-   }
-
-   /* Make the subwindows in the pop-up. */
-   begx = xpos;
-   begy = ypos + borderw + TitleLinesOf (matrix);
-
-   /* Make the 'empty' 0x0 cell. */
-   MATRIX_CELL (matrix, 0, 0) = subwin (matrix->win, 3, matrix->maxrt, begy, begx);
-   begx += matrix->maxrt + 1;
-
-   /* Copy the titles into the structure. */
-   for (x = 1; x <= cols; x++)
-   {
-      if (coltitles && !emptyString (coltitles[x]))	/*VR */
-	 have_coltitles = TRUE;
-      matrix->coltitle[x] = char2Chtype (coltitles ? coltitles[x] : 0,	/*VR */
-					 &matrix->coltitleLen[x],
-					 &matrix->coltitlePos[x]);
-      matrix->coltitlePos[x] = (BorderOf (matrix) +
-				justifyString (colwidths[x],
-					       matrix->coltitleLen[x],
-					       matrix->coltitlePos[x]));
-      matrix->colwidths[x] = colwidths[x];
-   }
-
-   if (have_coltitles)
-   {
-      /* Make the column titles. */
-      for (x = 1; x <= vcols; x++)
-      {
-	 cellWidth = colwidths[x] + 3;
-	 MATRIX_CELL (matrix, 0, x) = subwin (matrix->win,
-					      borderw,
-					      cellWidth,
-					      begy,
-					      begx);
-
-	 if (MATRIX_CELL (matrix, 0, x) == 0)
-	 {
-	    destroyCDKObject (matrix);
-	    return (0);
-	 }
-	 begx += cellWidth + colSpace - 1;
-      }
-      begy++;
-   }
-
-   /* Make the main cell body */
-   for (x = 1; x <= vrows; x++)
-   {
-      if (have_rowtitles)
-      {
-	 /* Make the row titles */
-	 MATRIX_CELL (matrix, x, 0) = subwin (matrix->win,
-					      3, matrix->maxrt,
-					      begy, xpos + borderw);
-
-	 if (MATRIX_CELL (matrix, x, 0) == 0)
-	 {
-	    destroyCDKObject (matrix);
-	    return (0);
-	 }
-      }
-
-      /* Set the start of the x position. */
-      begx = xpos + matrix->maxrt + borderw;
-
-      /* Make the cells */
-      for (y = 1; y <= vcols; y++)
-      {
-	 cellWidth = colwidths[y] + 3;
-	 MATRIX_CELL (matrix, x, y) = subwin (matrix->win,
-					      3, cellWidth,
-					      begy, begx);
-
-	 if (MATRIX_CELL (matrix, x, y) == 0)
-	 {
-	    destroyCDKObject (matrix);
-	    return (0);
-	 }
-	 begx += cellWidth + colSpace - 1;
-	 keypad (MATRIX_CELL (matrix, x, y), TRUE);
-      }
-      begy += rowSpace + 2;
-   }
-   keypad (matrix->win, TRUE);
-
-   /* *INDENT-EQLS* Keep the rest of the info. */
-   ScreenOf (matrix)            = cdkscreen;
-   ObjOf (matrix)->acceptsFocus = TRUE;
-   ObjOf (matrix)->inputWindow  = matrix->win;
-   matrix->parent               = cdkscreen->window;
-   matrix->vrows                = vrows;
-   matrix->vcols                = vcols;
-   matrix->boxWidth             = boxWidth;
-   matrix->boxHeight            = boxHeight;
-   matrix->rowSpace             = rowSpace;
-   matrix->colSpace             = colSpace;
-   matrix->filler               = filler;
-   matrix->dominant             = dominant;
-   matrix->row                  = 1;
-   matrix->col                  = 1;
-   matrix->crow                 = 1;
-   matrix->ccol                 = 1;
-   matrix->trow                 = 1;
-   matrix->lcol                 = 1;
-   matrix->oldcrow              = 1;
-   matrix->oldccol              = 1;
-   matrix->oldvrow              = 1;
-   matrix->oldvcol              = 1;
-   initExitType (matrix);
-   matrix->boxCell              = boxCell;
-   matrix->shadow               = shadow;
-   matrix->highlight            = A_REVERSE;
-   matrix->callbackfn           = CDKMatrixCallBack;
-
-   /* Make room for the cell information. */
-   for (x = 1; x <= rows; x++)
-   {
-      for (y = 1; y <= cols; y++)
-      {
-	 MATRIX_INFO (matrix, x, y) = typeCallocN (char, (colwidths[y] + 1));
-	 matrix->colvalues[y] = colvalues[y];
-	 matrix->colwidths[y] = colwidths[y];
-      }
-   }
-
-   /* Do we want a shadow??? */
-   if (shadow)
-   {
-      matrix->shadowWin = newwin (boxHeight, boxWidth, ypos + 1, xpos + 1);
-   }
-
-   /* Setup the key bindings. */
-   for (x = 0; x < (int)SIZEOF (bindings); ++x)
-      bindCDKObject (vMATRIX, matrix,
-		     (chtype)bindings[x].from,
-		     getcCDKBind,
-		     (void *)(long)bindings[x].to);
-
-   /* Register this baby. */
-   registerCDKObject (cdkscreen, vMATRIX, matrix);
-
-   /* Return the matrix pointer */
-   return (matrix);
-}
-
-/*
- * This activates the matrix.
- */
-int activateCDKMatrix (CDKMATRIX *matrix, chtype *actions)
-{
-   int ret;
-
-   /* Draw the matrix */
-   drawCDKMatrix (matrix, ObjOf (matrix)->box);
-
-   if (actions == 0)
-   {
-      boolean functionKey;
-
-      for (;;)
-      {
-	 chtype input;
-
-	 ObjOf (matrix)->inputWindow = CurMatrixCell (matrix);
-	 keypad (ObjOf (matrix)->inputWindow, TRUE);
-	 input = (chtype)getchCDKObject (ObjOf (matrix), &functionKey);
-
-	 /* Inject the character into the widget. */
-	 ret = injectCDKMatrix (matrix, input);
-	 if (matrix->exitType != vEARLY_EXIT)
-	 {
-	    return ret;
-	 }
-      }
-   }
-   else
-   {
-      int length = chlen (actions);
-      int x = 0;
-
-      /* Inject each character one at a time. */
-      for (x = 0; x < length; x++)
-      {
-	 ret = injectCDKMatrix (matrix, actions[x]);
-	 if (matrix->exitType != vEARLY_EXIT)
-	 {
-	    return ret;
-	 }
-      }
-   }
-
-   /* Set the exit type and exit. */
-   setExitType (matrix, 0);
-   return -1;
-}
-
-/*
- * This injects a single character into the matrix widget.
- */
-static int _injectCDKMatrix (CDKOBJS *object, chtype input)
-{
-   /* *INDENT-EQLS* */
-   CDKMATRIX *widget = (CDKMATRIX *)object;
-   int charcount     = (int)strlen (MATRIX_INFO (widget, widget->row, widget->col));
-   int ppReturn      = 1;
-   int ret           = unknownInt;
-   bool complete     = FALSE;
-
-   /* Set the exit type. */
-   setExitType (widget, 0);
-
-   /* Move the cursor to the correct position within the cell. */
-   if (widget->colwidths[widget->ccol] == 1)
-   {
-      wmove (CurMatrixCell (widget), 1, 1);
-   }
-   else
-   {
-      wmove (CurMatrixCell (widget),
-	     1,
-	     (int)strlen (MATRIX_INFO (widget, widget->row, widget->col)) + 1);
-   }
-
-   /* Put the focus on the current cell */
-   MyBox (CurMatrixCell (widget), WHOLE_BOX, A_BOLD);
-   wrefresh (CurMatrixCell (widget));
-   highlightCDKMatrixCell (widget);
-
-   /* Check if there is a pre-process function to be called. */
-   if (PreProcessFuncOf (widget) != 0)
-   {
-      /* Call the pre-process function. */
-      ppReturn = PreProcessFuncOf (widget) (vMATRIX,
-					    widget,
-					    PreProcessDataOf (widget),
-					    input);
-   }
-
-   /* Should we continue? */
-   if (ppReturn != 0)
-   {
-      /* *INDENT-EQLS* */
-      int refreshCells  = FALSE;
-      int movedCell     = FALSE;
-
-      /* Check the key bindings. */
-      if (checkCDKObjectBind (vMATRIX, widget, input) != 0)
-      {
-	 checkEarlyExit (widget);
-	 complete = TRUE;
-      }
-      else
-      {
-	 switch (input)
-	 {
-	 case CDK_TRANSPOSE:
-	    break;
-
-	 case KEY_HOME:
-	    break;
-
-	 case KEY_END:
-	    break;
-
-	 case KEY_BACKSPACE:
-	 case KEY_DC:
-	    if (widget->colvalues[widget->col] == vVIEWONLY || charcount <= 0)
-	    {
-	       Beep ();
-	    }
-	    else
-	    {
-	       charcount--;
-	       mvwdelch (CurMatrixCell (widget), 1, charcount + 1);
-	       mvwinsch (CurMatrixCell (widget), 1, charcount + 1, widget->filler);
-	       wrefresh (CurMatrixCell (widget));
-	       MATRIX_INFO (widget, widget->row, widget->col)[charcount] = '\0';
-	    }
-	    break;
-
-	 case KEY_RIGHT:
-	 case KEY_TAB:
-	    if (widget->ccol != widget->vcols)
-	    {
-	       /* We are moving to the right... */
-	       widget->col++;
-	       widget->ccol++;
-	       movedCell = TRUE;
-	    }
-	    else
-	    {
-	       /* We have to shift the columns to the right. */
-	       if (widget->col != widget->cols)
-	       {
-		  widget->lcol++;
-		  widget->col++;
-
-		  /* Redraw the column titles. */
-		  if (widget->rows > widget->vrows)
-		  {
-		     redrawTitles (widget, FALSE, TRUE);
-		  }
-		  refreshCells = TRUE;
-		  movedCell = TRUE;
-	       }
-	       else
-	       {
-		  /* We are at the far right column, we need  */
-		  /* shift down one row, if we can. */
-		  if (widget->row == widget->rows)
-		  {
-		     Beep ();
-		  }
-		  else
-		  {
-		     /* Set up the columns info. */
-		     widget->col = 1;
-		     widget->lcol = 1;
-		     widget->ccol = 1;
-
-		     /* Shift the rows... */
-		     if (widget->crow != widget->vrows)
-		     {
-			widget->row++;
-			widget->crow++;
-		     }
-		     else
-		     {
-			widget->row++;
-			widget->trow++;
-		     }
-		     redrawTitles (widget, TRUE, TRUE);
-		     refreshCells = TRUE;
-		     movedCell = TRUE;
-		  }
-	       }
-	    }
-	    break;
-
-	 case KEY_LEFT:
-	 case KEY_BTAB:
-	    if (widget->ccol != 1)
-	    {
-	       /* We are moving to the left... */
-	       widget->col--;
-	       widget->ccol--;
-	       movedCell = TRUE;
-	    }
-	    else
-	    {
-	       /* Are we at the far left??? */
-	       if (widget->lcol != 1)
-	       {
-		  widget->lcol--;
-		  widget->col--;
-
-		  /* Redraw the column titles. */
-		  if (widget->cols > widget->vcols)
-		  {
-		     redrawTitles (widget, FALSE, TRUE);
-		  }
-		  refreshCells = TRUE;
-		  movedCell = TRUE;
-	       }
-	       else
-	       {
-		  /* Shift up one line if we can... */
-		  if (widget->row == 1)
-		  {
-		     Beep ();
-		  }
-		  else
-		  {
-		     /* Set up the columns info. */
-		     widget->col = widget->cols;
-		     widget->lcol = widget->cols - widget->vcols + 1;
-		     widget->ccol = widget->vcols;
-
-		     /* Shift the rows... */
-		     if (widget->crow != 1)
-		     {
-			widget->row--;
-			widget->crow--;
-		     }
-		     else
-		     {
-			widget->row--;
-			widget->trow--;
-		     }
-		     redrawTitles (widget, TRUE, TRUE);
-		     refreshCells = TRUE;
-		     movedCell = TRUE;
-		  }
-	       }
-	    }
-	    break;
-
-	 case KEY_UP:
-	    if (widget->crow != 1)
-	    {
-	       widget->row--;
-	       widget->crow--;
-	       movedCell = TRUE;
-	    }
-	    else
-	    {
-	       if (widget->trow != 1)
-	       {
-		  widget->trow--;
-		  widget->row--;
-
-		  /* Redraw the row titles. */
-		  if (widget->rows > widget->vrows)
-		  {
-		     redrawTitles (widget, TRUE, FALSE);
-		  }
-		  refreshCells = TRUE;
-		  movedCell = TRUE;
-	       }
-	       else
-	       {
-		  Beep ();
-	       }
-	    }
-	    break;
-
-	 case KEY_DOWN:
-	    if (widget->crow != widget->vrows)
-	    {
-	       widget->row++;
-	       widget->crow++;
-	       movedCell = TRUE;
-	    }
-	    else
-	    {
-	       if ((widget->trow + widget->vrows - 1) != widget->rows)
-	       {
-		  widget->trow++;
-		  widget->row++;
-
-		  /* Redraw the titles. */
-		  if (widget->rows > widget->vrows)
-		  {
-		     redrawTitles (widget, TRUE, FALSE);
-		  }
-		  refreshCells = TRUE;
-		  movedCell = TRUE;
-	       }
-	       else
-	       {
-		  Beep ();
-	       }
-	    }
-	    break;
-
-	 case KEY_NPAGE:
-	    if (widget->rows > widget->vrows)
-	    {
-	       if ((widget->trow + ((widget->vrows - 1) * 2)) <= widget->rows)
-	       {
-		  widget->trow += widget->vrows - 1;
-		  widget->row += widget->vrows - 1;
-		  redrawTitles (widget, TRUE, FALSE);
-		  refreshCells = TRUE;
-		  movedCell = TRUE;
-	       }
-	       else
-	       {
-		  Beep ();
-	       }
-	    }
-	    else
-	    {
-	       Beep ();
-	    }
-	    break;
-
-	 case KEY_PPAGE:
-	    if (widget->rows > widget->vrows)
-	    {
-	       if ((widget->trow - ((widget->vrows - 1) * 2)) >= 1)
-	       {
-		  widget->trow -= widget->vrows - 1;
-		  widget->row -= widget->vrows - 1;
-		  redrawTitles (widget, TRUE, FALSE);
-		  refreshCells = TRUE;
-		  movedCell = TRUE;
-	       }
-	       else
-	       {
-		  Beep ();
-	       }
-	    }
-	    else
-	    {
-	       Beep ();
-	    }
-	    break;
-
-	 case CTRL ('G'):
-	    jumpToCell (widget, -1, -1);
-	    drawCDKMatrix (widget, ObjOf (widget)->box);
-	    break;
-
-	 case CDK_PASTE:
-	    if (GPasteBuffer == 0 ||
-		(int)strlen (GPasteBuffer) > widget->colwidths[widget->ccol])
-	    {
-	       Beep ();
-	    }
-	    else
-	    {
-	       strcpy (CurMatrixInfo (widget), GPasteBuffer);
-	       drawCurCDKMatrixCell (widget);
-	    }
-	    break;
-
-	 case CDK_COPY:
-	    freeChar (GPasteBuffer);
-	    GPasteBuffer = copyChar (CurMatrixInfo (widget));
-	    break;
-
-	 case CDK_CUT:
-	    freeChar (GPasteBuffer);
-	    GPasteBuffer = copyChar (CurMatrixInfo (widget));
-	    cleanCDKMatrixCell (widget,
-				widget->trow + widget->crow - 1,
-				widget->lcol + widget->ccol - 1);
-	    drawCurCDKMatrixCell (widget);
-	    break;
-
-	 case CDK_ERASE:
-	    cleanCDKMatrixCell (widget,
-				widget->trow + widget->crow - 1,
-				widget->lcol + widget->ccol - 1);
-	    drawCurCDKMatrixCell (widget);
-	    break;
-
-	 case KEY_ENTER:
-	    if (!widget->boxCell)
-	    {
-	       attrbox (MATRIX_CELL (widget, widget->oldcrow, widget->oldccol),
-			' ', ' ',
-			' ', ' ',
-			' ', ' ',
-			A_NORMAL);
-	    }
-	    else
-	    {
-	       drawOldCDKMatrixCell (widget);
-	    }
-	    wrefresh (CurMatrixCell (widget));
-	    setExitType (widget, input);
-	    ret = 1;
-	    complete = TRUE;
-	    break;
-
-	 case KEY_ERROR:
-	    setExitType (widget, input);
-	    complete = TRUE;
-	    break;
-
-	 case KEY_ESC:
-	    if (!widget->boxCell)
-	    {
-	       attrbox (MATRIX_CELL (widget, widget->oldcrow, widget->oldccol),
-			' ', ' ',
-			' ', ' ',
-			' ', ' ',
-			A_NORMAL);
-	    }
-	    else
-	    {
-	       drawOldCDKMatrixCell (widget);
-	    }
-	    wrefresh (CurMatrixCell (widget));
-	    setExitType (widget, input);
-	    complete = TRUE;
-	    break;
-
-	 case CDK_REFRESH:
-	    eraseCDKScreen (ScreenOf (widget));
-	    refreshCDKScreen (ScreenOf (widget));
-	    break;
-
-	 default:
-	    (widget->callbackfn) (widget, input);
-	    break;
-	 }
-      }
-
-      if (!complete)
-      {
-	 /* Did we change cells? */
-	 if (movedCell)
-	 {
-	    /* un-highlight the old box  */
-	    if (!widget->boxCell)
-	    {
-	       attrbox (MATRIX_CELL (widget, widget->oldcrow, widget->oldccol),
-			' ', ' ',
-			' ', ' ',
-			' ', ' ',
-			A_NORMAL);
-	    }
-	    else
-	    {
-	       drawOldCDKMatrixCell (widget);
-	    }
-	    wrefresh (MATRIX_CELL (widget, widget->oldcrow, widget->oldccol));
-
-	    /* Highlight the new cell. */
-	    MyBox (CurMatrixCell (widget), WHOLE_BOX, A_BOLD);
-	    wrefresh (CurMatrixCell (widget));
-	    highlightCDKMatrixCell (widget);
-	 }
-
-	 /* Redraw each cell. */
-	 if (refreshCells)
-	 {
-	    drawEachCDKMatrixCell (widget);
-
-	    /* Highlight the current cell. */
-	    MyBox (CurMatrixCell (widget), WHOLE_BOX, A_BOLD);
-	    wrefresh (CurMatrixCell (widget));
-	    highlightCDKMatrixCell (widget);
-	 }
-
-	 /* Move to the correct position in the cell. */
-	 if (refreshCells || movedCell)
-	 {
-	    if (widget->colwidths[widget->ccol] == 1)
-	    {
-	       wmove (CurMatrixCell (widget), 1, 1);
-	    }
-	    else
-	    {
-	       int infolen = (int)strlen (CurMatrixInfo (widget));
-	       wmove (CurMatrixCell (widget), 1, infolen + 1);
-	    }
-	    wrefresh (CurMatrixCell (widget));
-	 }
-
-	 /* Should we call a post-process? */
-	 if (PostProcessFuncOf (widget) != 0)
-	 {
-	    PostProcessFuncOf (widget) (vMATRIX,
-					widget,
-					PostProcessDataOf (widget),
-					input);
-	 }
-      }
-   }
-
-   if (!complete)
-   {
-      /* Set the variables we need. */
-      widget->oldcrow = widget->crow;
-      widget->oldccol = widget->ccol;
-      widget->oldvrow = widget->row;
-      widget->oldvcol = widget->col;
-
-      /* Set the exit type and exit. */
-      setExitType (widget, 0);
-   }
-
-   ResultOf (widget).valueInt = ret;
-   return (ret != unknownInt);
-}
-
-/*
- * This allows the programmer to define their own key mappings.
- */
-static void CDKMatrixCallBack (CDKMATRIX *matrix, chtype input)
-{
-   EDisplayType disptype = (EDisplayType) matrix->colvalues[matrix->col];
-   int plainchar = filterByDisplayType (disptype, input);
-   int charcount = (int)strlen (MATRIX_INFO (matrix, matrix->row, matrix->col));
-
-   if (plainchar == ERR)
-   {
-      Beep ();
-   }
-   else if (charcount == matrix->colwidths[matrix->col])
-   {
-      Beep ();
-   }
-   else
-   {
-      /* Update the screen. */
-      wmove (CurMatrixCell (matrix),
-	     1,
-	     (int)strlen (MATRIX_INFO (matrix, matrix->row, matrix->col)) + 1);
-      waddch (CurMatrixCell (matrix),
-	      (chtype)((isHiddenDisplayType (disptype))
-		       ? (int)matrix->filler
-		       : plainchar));
-      wrefresh (CurMatrixCell (matrix));
-
-      /* Update the character pointer. */
-      MATRIX_INFO (matrix, matrix->row, matrix->col)[charcount++] = (char)plainchar;
-      MATRIX_INFO (matrix, matrix->row, matrix->col)[charcount] = '\0';
-   }
-}
-
-/*
- * Highlight the new field.
- */
-static void highlightCDKMatrixCell (CDKMATRIX *matrix)
-{
-   /* *INDENT-EQLS* */
-   EDisplayType disptype = (EDisplayType) matrix->colvalues[matrix->col];
-   chtype highlight      = matrix->highlight;
-   int x                 = 0;
-   int infolen           = (int)strlen (MATRIX_INFO (matrix, matrix->row, matrix->col));
-
-   /*
-    * Given the dominance of the colors/attributes, we need to set the
-    * current cell attribute.
-    */
-   if (matrix->dominant == ROW)
-   {
-      highlight = matrix->rowtitle[matrix->crow][0] & A_ATTRIBUTES;
-   }
-   else if (matrix->dominant == COL)
-   {
-      highlight = matrix->coltitle[matrix->ccol][0] & A_ATTRIBUTES;
-   }
-
-   /* If the column is only one char. */
-   for (x = 1; x <= matrix->colwidths[matrix->ccol]; x++)
-   {
-      chtype ch = (((x <= infolen) && !isHiddenDisplayType (disptype))
-		   ? CharOf (MATRIX_INFO (matrix,
-					  matrix->row,
-					  matrix->col)[x - 1])
-		   : matrix->filler);
-
-      (void)mvwaddch (CurMatrixCell (matrix), 1, x, ch | highlight);
-   }
-   wmove (CurMatrixCell (matrix), 1, infolen + 1);
-   wrefresh (CurMatrixCell (matrix));
-}
-
-/*
- * This moves the matrix field to the given location.
- */
-static void _moveCDKMatrix (CDKOBJS *object,
-			    int xplace,
-			    int yplace,
-			    boolean relative,
-			    boolean refresh_flag)
-{
-   /* *INDENT-EQLS* */
-   CDKMATRIX *matrix = (CDKMATRIX *)object;
-   int currentX      = getbegx (matrix->win);
-   int currentY      = getbegy (matrix->win);
-   int xpos          = xplace;
-   int ypos          = yplace;
-   int xdiff         = 0;
-   int ydiff         = 0;
-   int x, y;
-
-   /*
-    * If this is a relative move, then we will adjust where we want
-    * to move to.
-    */
-   if (relative)
-   {
-      xpos = getbegx (matrix->win) + xplace;
-      ypos = getbegy (matrix->win) + yplace;
-   }
-
-   /* Adjust the window if we need to. */
-   alignxy (WindowOf (matrix), &xpos, &ypos, matrix->boxWidth, matrix->boxHeight);
-
-   /* Get the difference. */
-   xdiff = currentX - xpos;
-   ydiff = currentY - ypos;
-
-   /* Move the window to the new location. */
-   moveCursesWindow (matrix->win, -xdiff, -ydiff);
-
-   for (x = 0; x <= matrix->vrows; x++)
-   {
-      for (y = 0; y <= matrix->vcols; y++)
-      {
-	 moveCursesWindow (MATRIX_CELL (matrix, x, y), -xdiff, -ydiff);
-      }
-   }
-
-   moveCursesWindow (matrix->shadowWin, -xdiff, -ydiff);
-
-   /* Touch the windows so they 'move'. */
-   refreshCDKWindow (WindowOf (matrix));
-
-   /* Redraw the window, if they asked for it. */
-   if (refresh_flag)
-   {
-      drawCDKMatrix (matrix, ObjOf (matrix)->box);
-   }
-}
-
-/*
- * This draws a cell within a matrix.
- */
-static void drawCDKMatrixCell (CDKMATRIX *matrix,
-			       int row,
-			       int col,
-			       int vrow,
-			       int vcol,
-			       boolean Box)
-{
-   /* *INDENT-EQLS* */
-   WINDOW *cell         = MATRIX_CELL (matrix, row, col);
-   EDisplayType disptype = (EDisplayType) matrix->colvalues[matrix->col];
-   chtype highlight     = matrix->filler & A_ATTRIBUTES;
-   int rows             = matrix->vrows;
-   int cols             = matrix->vcols;
-   int infolen          = (int)strlen (MATRIX_INFO (matrix, vrow, vcol));
-   chtype attr          = A_NORMAL;
-   int x;
-
-   /*
-    * Given the dominance of the colors/attributes, we need to set the
-    * current cell attribute.
-    */
-   if (matrix->dominant == ROW)
-   {
-      highlight = matrix->rowtitle[row][0] & A_ATTRIBUTES;
-   }
-   else if (matrix->dominant == COL)
-   {
-      highlight = matrix->coltitle[col][0] & A_ATTRIBUTES;
-   }
-
-   /* Draw in the cell info. */
-   for (x = 1; x <= matrix->colwidths[col]; x++)
-   {
-      chtype ch = (((x <= infolen) && !isHiddenDisplayType (disptype))
-		   ? (CharOf (MATRIX_INFO (matrix, vrow, vcol)[x - 1]) | highlight)
-		   : matrix->filler);
-
-      (void)mvwaddch (cell, 1, x, ch | highlight);
-   }
-   wmove (cell, 1, infolen + 1);
-   wrefresh (cell);
-
-   /* Only draw the box iff the user asked for a box. */
-   if (!Box)
-   {
-      return;
-   }
-
-   /*
-    * If the value of the column spacing is greater than 0 then these
-    * are independent boxes.
-    */
-   if (matrix->colSpace != 0)
-   {
-      if (matrix->rowSpace != 0)
-      {
-	 MyBox (cell, WHOLE_BOX, attr);
-      }
-      else
-      {
-	 if (row == 1)
-	 {
-	    MyBox (cell, TOP_C_BOX, attr);
-	 }
-	 else if (row > 1 && row < rows)
-	 {
-	    MyBox (cell, MID_C_BOX, attr);
-	 }
-	 else if (row == rows)
-	 {
-	    MyBox (cell, BOT_C_BOX, attr);
-	 }
-      }
-   }
-   else if (matrix->rowSpace != 0)
-   {
-      if (col == 1)
-      {
-	 MyBox (cell, LFT_R_BOX, attr);
-      }
-      else if (col > 1 && col < cols)
-      {
-	 MyBox (cell, MID_R_BOX, attr);
-      }
-      else if (col == cols)
-      {
-	 MyBox (cell, RGT_R_BOX, attr);
-      }
-   }
-   else
-   {
-      if (row == 1)
-      {
-	 if (col == 1)
-	 {
-	    MyBox (cell, LFT_T_BOX, attr);	/* top left corner */
-	 }
-	 else if (col > 1 && col < cols)
-	 {
-	    MyBox (cell, MID_T_BOX, attr);	/* top middle */
-	 }
-	 else if (col == cols)
-	 {
-	    MyBox (cell, RGT_T_BOX, attr);	/* top right corner */
-	 }
-      }
-      else if (row > 1 && row < rows)
-      {
-	 if (col == 1)
-	 {
-	    MyBox (cell, LFT_M_BOX, attr);	/* middle left */
-	 }
-	 else if (col > 1 && col < cols)
-	 {
-	    MyBox (cell, MID_M_BOX, attr);	/* middle */
-	 }
-	 else if (col == cols)
-	 {
-	    MyBox (cell, RGT_M_BOX, attr);	/* middle right */
-	 }
-      }
-      else if (row == rows)
-      {
-	 if (col == 1)
-	 {
-	    MyBox (cell, LFT_B_BOX, attr);	/* bottom left corner */
-	 }
-	 else if (col > 1 && col < cols)
-	 {
-	    MyBox (cell, MID_B_BOX, attr);	/* bottom middle */
-	 }
-	 else if (col == cols)
-	 {
-	    MyBox (cell, RGT_B_BOX, attr);	/* bottom right corner */
-	 }
-      }
-   }
-
-   /* Highlight the current cell. */
-   MyBox (CurMatrixCell (matrix), WHOLE_BOX, A_BOLD);
-   wrefresh (CurMatrixCell (matrix));
-   highlightCDKMatrixCell (matrix);
-}
-
-static void drawEachColTitle (CDKMATRIX *matrix)
-{
-   int x;
-
-   for (x = 1; x <= matrix->vcols; x++)
-   {
-      if (MATRIX_CELL (matrix, 0, x))
-      {
-	 werase (MATRIX_CELL (matrix, 0, x));	/*VR */
-	 writeChtype (MATRIX_CELL (matrix, 0, x),
-		      matrix->coltitlePos[matrix->lcol + x - 1], 0,
-		      matrix->coltitle[matrix->lcol + x - 1],
-		      HORIZONTAL,
-		      0, matrix->coltitleLen[matrix->lcol + x - 1]);
-	 wrefresh (MATRIX_CELL (matrix, 0, x));
-      }
-   }
-}
-
-static void drawEachRowTitle (CDKMATRIX *matrix)
-{
-   int x;
-
-   for (x = 1; x <= matrix->vrows; x++)
-   {
-      if (MATRIX_CELL (matrix, x, 0))
-      {
-	 werase (MATRIX_CELL (matrix, x, 0));
-	 writeChtype (MATRIX_CELL (matrix, x, 0),
-		      matrix->rowtitlePos[matrix->trow + x - 1], 1,
-		      matrix->rowtitle[matrix->trow + x - 1],
-		      HORIZONTAL,
-		      0, matrix->rowtitleLen[matrix->trow + x - 1]);
-	 wrefresh (MATRIX_CELL (matrix, x, 0));
-      }
-   }
-}
-
-static void drawEachCDKMatrixCell (CDKMATRIX *matrix)
-{
-   int y, x;
-
-   /* Fill in the cells. */
-   for (x = 1; x <= matrix->vrows; x++)
-   {
-      for (y = 1; y <= matrix->vcols; y++)
-      {
-	 drawCDKMatrixCell (matrix, x, y,
-			    matrix->trow + x - 1,
-			    matrix->lcol + y - 1,
-			    matrix->boxCell);
-      }
-   }
-}
-
-static void drawCurCDKMatrixCell (CDKMATRIX *matrix)
-{
-   drawCDKMatrixCell (matrix,
-		      matrix->crow,
-		      matrix->ccol,
-		      matrix->row,
-		      matrix->col,
-		      matrix->boxCell);
-}
-
-static void drawOldCDKMatrixCell (CDKMATRIX *matrix)
-{
-   drawCDKMatrixCell (matrix,
-		      matrix->oldcrow,
-		      matrix->oldccol,
-		      matrix->oldvrow,
-		      matrix->oldvcol,
-		      matrix->boxCell);
-}
-
-/*
- * This function draws the matrix widget.
- */
-static void _drawCDKMatrix (CDKOBJS *object, boolean Box)
-{
-   CDKMATRIX *matrix = (CDKMATRIX *)object;
-
-   /* Did we ask for a shadow??? */
-   if (matrix->shadowWin != 0)
-   {
-      drawShadow (matrix->shadowWin);
-   }
-
-   /* Should we box the matrix??? */
-   if (Box)
-   {
-      drawObjBox (matrix->win, ObjOf (matrix));
-   }
-
-   drawCdkTitle (matrix->win, object);
-
-   wrefresh (matrix->win);
-
-   drawEachColTitle (matrix);
-   drawEachRowTitle (matrix);
-   drawEachCDKMatrixCell (matrix);
-
-   /* Highlight the current cell. */
-   MyBox (CurMatrixCell (matrix), WHOLE_BOX, A_BOLD);
-   wrefresh (CurMatrixCell (matrix));
-   highlightCDKMatrixCell (matrix);
-}
-
-/*
- * This function destroys the matrix widget.
- */
-static void _destroyCDKMatrix (CDKOBJS *object)
-{
-   if (object != 0)
-   {
-      CDKMATRIX *matrix = (CDKMATRIX *)object;
-      int x = 0;
-      int y = 0;
-
-      cleanCdkTitle (object);
-
-      /* Clear out the col titles. */
-      for (x = 1; x <= matrix->cols; x++)
-      {
-	 freeChtype (matrix->coltitle[x]);
-      }
-
-      /* Clear out the row titles. */
-      for (x = 1; x <= matrix->rows; x++)
-      {
-	 freeChtype (matrix->rowtitle[x]);
-      }
-
-      /* Clear out the matrix cells. */
-      for (x = 1; x <= matrix->rows; x++)
-      {
-	 for (y = 1; y <= matrix->cols; y++)
-	 {
-	    freeChar (MATRIX_INFO (matrix, x, y));
-	 }
-      }
-
-      /* Clear the matrix windows. */
-      deleteCursesWindow (MATRIX_CELL (matrix, 0, 0));
-      for (x = 1; x <= matrix->vrows; x++)
-      {
-	 deleteCursesWindow (MATRIX_CELL (matrix, x, 0));
-      }
-      for (x = 1; x <= matrix->vcols; x++)
-      {
-	 deleteCursesWindow (MATRIX_CELL (matrix, 0, x));
-      }
-      for (x = 1; x <= matrix->vrows; x++)
-      {
-	 for (y = 1; y <= matrix->vcols; y++)
-	 {
-	    deleteCursesWindow (MATRIX_CELL (matrix, x, y));
-	 }
-      }
-
-#if NEW_CDKMATRIX
-      freeChecked (matrix->cell);
-      freeChecked (matrix->info);
-#endif
-
-      freeChecked (matrix->colwidths);
-      freeChecked (matrix->colvalues);
-
-      freeChecked (matrix->coltitle);
-      freeChecked (matrix->coltitleLen);
-      freeChecked (matrix->coltitlePos);
-
-      freeChecked (matrix->rowtitle);
-      freeChecked (matrix->rowtitleLen);
-      freeChecked (matrix->rowtitlePos);
-
-      deleteCursesWindow (matrix->shadowWin);
-      deleteCursesWindow (matrix->win);
-
-      /* Clean the key bindings. */
-      cleanCDKObjectBindings (vMATRIX, matrix);
-
-      /* Unregister this object. */
-      unregisterCDKObject (vMATRIX, matrix);
-   }
-}
-
-/*
- * This function erases the matrix widget from the screen.
- */
-static void _eraseCDKMatrix (CDKOBJS *object)
-{
-   if (validCDKObject (object))
-   {
-      CDKMATRIX *matrix = (CDKMATRIX *)object;
-      int x = 0;
-      int y = 0;
-
-      /* Clear the matrix cells. */
-      eraseCursesWindow (MATRIX_CELL (matrix, 0, 0));
-      for (x = 1; x <= matrix->vrows; x++)
-      {
-	 eraseCursesWindow (MATRIX_CELL (matrix, x, 0));
-      }
-      for (x = 1; x <= matrix->vcols; x++)
-      {
-	 eraseCursesWindow (MATRIX_CELL (matrix, 0, x));
-      }
-      for (x = 1; x <= matrix->vrows; x++)
-      {
-	 for (y = 1; y <= matrix->vcols; y++)
-	 {
-	    eraseCursesWindow (MATRIX_CELL (matrix, x, y));
-	 }
-      }
-      eraseCursesWindow (matrix->shadowWin);
-      eraseCursesWindow (matrix->win);
-   }
-}
-
-/*
- * Set the callback-function.
- */
-void setCDKMatrixCB (CDKMATRIX *widget, MATRIXCB callback)
-{
-   widget->callbackfn = callback;
-}
-
-/*
- * This function sets the values of the matrix widget.
- */
-void setCDKMatrixCells (CDKMATRIX *matrix,
-			CDK_CSTRING2 info,
-			int rows,
-			int maxcols,
-			int *subSize)
-{
-   int x = 0;
-   int y = 0;
-
-   if (rows > matrix->rows)
-      rows = matrix->rows;
-
-   /* Copy in the new info. */
-   for (x = 1; x <= rows; x++)
-   {
-      for (y = 1; y <= matrix->cols; y++)
-      {
-	 if (x <= rows && y <= subSize[x])
-	 {
-	    const char *source = info[(x * maxcols) + y];
-
-	    /* Copy in the new information. */
-	    if (source != 0)
-	    {
-	       char *target = MATRIX_INFO (matrix, x, y);
-
-	       if (target == 0)	/* this should not happen... */
-	       {
-		  target = typeCallocN (char, matrix->colwidths[y] + 1);
-		  MATRIX_INFO (matrix, x, y) = target;
-	       }
-	       strncpy (MATRIX_INFO (matrix, x, y),
-			source,
-			(size_t)matrix->colwidths[y]);
-	    }
-	 }
-	 else
-	    cleanCDKMatrixCell (matrix, x, y);
-      }
-   }
-}
-
-/*
- * This sets the widget's box attribute.
- */
-void setCDKMatrixBox (CDKMATRIX *matrix, boolean Box)
-{
-   ObjOf (matrix)->box = Box;
-   ObjOf (matrix)->borderSize = Box ? 1 : 0;
-}
-boolean getCDKMatrixBox (CDKMATRIX *matrix)
-{
-   return ObjOf (matrix)->box;
-}
-
-/*
- * This cleans out the information cells in the matrix widget.
- */
-void cleanCDKMatrix (CDKMATRIX *matrix)
-{
-   int x = 0;
-   int y = 0;
-
-   for (x = 1; x <= matrix->rows; x++)
-   {
-      for (y = 1; y <= matrix->cols; y++)
-      {
-	 cleanCDKMatrixCell (matrix, x, y);
-      }
-   }
-}
-
-/*
- * This cleans one cell in the matrix widget.
- */
-void cleanCDKMatrixCell (CDKMATRIX *matrix, int row, int col)
-{
-   if (row > 0 && row <= matrix->rows &&
-       col > 0 && col <= matrix->cols)
-      cleanChar (MATRIX_INFO (matrix, row, col), matrix->colwidths[col], '\0');
-}
-
-/*
- * This allows us to hyper-warp to a cell.
- */
-int jumpToCell (CDKMATRIX *matrix, int row, int col)
-{
-   CDKSCALE *scale = 0;
-   int newRow = row;
-   int newCol = col;
-
-   /*
-    * Only create the row scale if needed.
-    */
-   if ((row == -1) || (row > matrix->rows))
-   {
-      /* Create the row scale widget. */
-      scale = newCDKScale (ScreenOf (matrix),
-			   CENTER, CENTER,
-			   "<C>Jump to which row.",
-			   "</5/B>Row: ", A_NORMAL, 5,
-			   1, 1, matrix->rows, 1, 1, TRUE, FALSE);
-
-      /* Activate the scale and get the row. */
-      newRow = activateCDKScale (scale, 0);
-      destroyCDKScale (scale);
-   }
-
-   /*
-    * Only create the column scale if needed.
-    */
-   if ((col == -1) || (col > matrix->cols))
-   {
-      /* Create the column scale widget. */
-      scale = newCDKScale (ScreenOf (matrix),
-			   CENTER, CENTER,
-			   "<C>Jump to which column",
-			   "</5/B>Col: ", A_NORMAL, 5,
-			   1, 1, matrix->cols, 1, 1, TRUE, FALSE);
-
-      /* Activate the scale and get the column. */
-      newCol = activateCDKScale (scale, 0);
-      destroyCDKScale (scale);
-   }
-
-   /* Hyper-warp.... */
-   if (newRow != matrix->row || newCol != matrix->col)
-   {
-      return (moveToCDKMatrixCell (matrix, newRow, newCol));
-   }
-   else
-   {
-      return 1;
-   }
-}
-
-/*
- * This allows us to move to a given cell.
- */
-int moveToCDKMatrixCell (CDKMATRIX *matrix, int newrow, int newcol)
-{
-   int rowShift = newrow - matrix->row;
-   int colShift = newcol - matrix->col;
-
-   /* Make sure we arent asking to move out of the matrix. */
-   if (newrow > matrix->rows ||
-       newcol > matrix->cols ||
-       newrow <= 0 ||
-       newcol <= 0)
-   {
-      return 0;
-   }
-
-   /* Did we move up/down???? */
-   if (rowShift > 0)
-   {
-      /* We are moving down. */
-      if (matrix->vrows == matrix->cols)
-      {
-	 matrix->trow = 1;
-	 matrix->crow = newrow;
-	 matrix->row = newrow;
-      }
-      else
-      {
-	 if ((rowShift + matrix->vrows) < matrix->rows)
-	 {
-	    /* Just shift down by rowShift... */
-	    matrix->trow += rowShift;
-	    matrix->crow = 1;
-	    matrix->row += rowShift;
-	 }
-	 else
-	 {
-	    /* We need to munge with the values... */
-	    matrix->trow = matrix->rows - matrix->vrows + 1;
-	    matrix->crow = ((rowShift + matrix->vrows) - matrix->rows) + 1;
-	    matrix->row = newrow;
-	 }
-      }
-   }
-   else if (rowShift < 0)
-   {
-      /* We are moving up. */
-      if (matrix->vrows == matrix->rows)
-      {
-	 matrix->trow = 1;
-	 matrix->row = newrow;
-	 matrix->crow = newrow;
-      }
-      else
-      {
-	 if ((rowShift + matrix->vrows) > 1)
-	 {
-	    /* Just shift up by rowShift... */
-	    matrix->trow += rowShift;
-	    matrix->row += rowShift;
-	    matrix->crow = 1;
-	 }
-	 else
-	 {
-	    /* We need to munge with the values... */
-	    matrix->trow = 1;
-	    matrix->crow = 1;
-	    matrix->row = 1;
-	 }
-      }
-   }
-
-   /* Did we move left/right ???? */
-   if (colShift > 0)
-   {
-      /* We are moving right. */
-      if (matrix->vcols == matrix->cols)
-      {
-	 matrix->lcol = 1;
-	 matrix->ccol = newcol;
-	 matrix->col = newcol;
-      }
-      else
-      {
-	 if ((colShift + matrix->vcols) < matrix->cols)
-	 {
-	    matrix->lcol += colShift;
-	    matrix->ccol = 1;
-	    matrix->col += colShift;
-	 }
-	 else
-	 {
-	    /* We need to munge with the values... */
-	    matrix->lcol = matrix->cols - matrix->vcols + 1;
-	    matrix->ccol = ((colShift + matrix->vcols) - matrix->cols) + 1;
-	    matrix->col = newcol;
-	 }
-      }
-   }
-   else if (colShift < 0)
-   {
-      /* We are moving left. */
-      if (matrix->vcols == matrix->cols)
-      {
-	 matrix->lcol = 1;
-	 matrix->col = newcol;
-	 matrix->ccol = newcol;
-      }
-      else
-      {
-	 if ((colShift + matrix->vcols) > 1)
-	 {
-	    /* Just shift left by colShift... */
-	    matrix->lcol += colShift;
-	    matrix->col += colShift;
-	    matrix->ccol = 1;
-	 }
-	 else
-	 {
-	    matrix->lcol = 1;
-	    matrix->col = 1;
-	    matrix->ccol = 1;
-	 }
-      }
-   }
-
-   /* Keep the 'old' values around for redrawing sake. */
-   matrix->oldcrow = matrix->crow;
-   matrix->oldccol = matrix->ccol;
-   matrix->oldvrow = matrix->row;
-   matrix->oldvcol = matrix->col;
-
-   /* Lets ... */
-   return 1;
-}
-
-/*
- * This redraws the titles indicated...
- */
-static void redrawTitles (CDKMATRIX *matrix, int rowTitles, int colTitles)
-{
-   /* Redraw the row titles. */
-   if (rowTitles)
-   {
-      drawEachRowTitle (matrix);
-   }
-
-   /* Redraw the column titles. */
-   if (colTitles)
-   {
-      drawEachColTitle (matrix);
-   }
-}
-
-/*
- * This sets the value of a matrix cell.
- */
-int setCDKMatrixCell (CDKMATRIX *matrix, int row, int col, const char *value)
-{
-   /* Make sure the row/col combination is within the matrix. */
-   if (row > matrix->rows || col > matrix->cols || row <= 0 || col <= 0)
-   {
-      return -1;
-   }
-
-   cleanCDKMatrixCell (matrix, row, col);
-   strncpy (MATRIX_INFO (matrix, row, col),
-	    value,
-	    (size_t)matrix->colwidths[col]);
-   return 1;
-}
-
-/*
- * This gets the value of a matrix cell.
- */
-char *getCDKMatrixCell (CDKMATRIX *matrix, int row, int col)
-{
-   /* Make sure the row/col combination is within the matrix. */
-   if (row > matrix->rows || col > matrix->cols || row <= 0 || col <= 0)
-   {
-      return 0;
-   }
-   return MATRIX_INFO (matrix, row, col);
-}
-
-/*
- * This returns the current row/col cell.
- */
-int getCDKMatrixCol (CDKMATRIX *matrix)
-{
-   return matrix->col;
-}
-int getCDKMatrixRow (CDKMATRIX *matrix)
-{
-   return matrix->row;
-}
-
-/*
- * This sets the background attribute of the widget.
- */
-static void _setBKattrMatrix (CDKOBJS *object, chtype attrib)
-{
-   if (object != 0)
-   {
-      CDKMATRIX *widget = (CDKMATRIX *)object;
-      int x, y;
-
-      wbkgd (widget->win, attrib);
-      for (x = 0; x <= widget->vrows; x++)
-      {
-	 for (y = 0; y <= widget->vcols; y++)
-	 {
-	    wbkgd (MATRIX_CELL (widget, x, y), attrib);
-	 }
-      }
-   }
-}
-
-static void _focusCDKMatrix (CDKOBJS *object)
-{
-   CDKMATRIX *widget = (CDKMATRIX *)object;
-
-   drawCDKMatrix (widget, ObjOf (widget)->box);
-}
-
-static void _unfocusCDKMatrix (CDKOBJS *object)
-{
-   CDKMATRIX *widget = (CDKMATRIX *)object;
-
-   drawCDKMatrix (widget, ObjOf (widget)->box);
-}
-
-dummyRefreshData (Matrix)
-
-dummySaveData (Matrix)
diff --git a/slider.c b/slider.c
new file mode 100644
index 0000000..bce688c
--- /dev/null
+++ b/slider.c
@@ -0,0 +1,830 @@
+#include <cdk_int.h>
+
+/*
+ * $Author: tom $
+ * $Date: 2021/12/16 00:42:01 $
+ * $Revision: 1.29 $
+ */
+
+/*
+ * Declare file local prototypes.
+ */
+static void drawCDKSliderField (CDKSLIDER *widget);
+static int formattedSize (CDKSLIDER *widget, int value);
+
+DeclareCDKObjects (SLIDER, Slider, setCdk, Int);
+
+/*
+ * This function creates a widget.
+ */
+CDKSLIDER *newCDKSlider (CDKSCREEN *cdkscreen,
+			   int xplace,
+			   int yplace,
+			   const char *title,
+			   const char *label,
+			   chtype filler,
+			   int fieldWidth,
+			   int start,
+			   int low,
+			   int high,
+			   int inc,
+			   int fastInc,
+			   boolean Box,
+			   boolean shadow)
+{
+   /* *INDENT-EQLS* */
+   CDKSLIDER *widget   = 0;
+   int parentWidth      = getmaxx (cdkscreen->window);
+   int parentHeight     = getmaxy (cdkscreen->window);
+   int boxHeight;
+   int boxWidth         = 0;
+   int horizontalAdjust, oldWidth;
+   int xpos             = xplace;
+   int ypos             = yplace;
+   int highValueLen;
+   int x, junk;
+   /* *INDENT-OFF* */
+   static const struct { int from; int to; } bindings[] = {
+		{ 'u',		KEY_UP },
+		{ 'U',		KEY_PPAGE },
+		{ CDK_BACKCHAR,	KEY_PPAGE },
+		{ CDK_FORCHAR,	KEY_NPAGE },
+		{ 'g',		KEY_HOME },
+		{ '^',		KEY_HOME },
+		{ 'G',		KEY_END },
+		{ '$',		KEY_END },
+   };
+   /* *INDENT-ON* */
+
+
+   if ((widget = newCDKObject (CDKSLIDER, &my_funcs)) == 0)
+      return (0);
+
+   setCDKSliderBox (widget, Box);
+   boxHeight = (BorderOf (widget) * 2) + 1;
+
+   /* *INDENT-EQLS* Set some basic values of the widget's data field. */
+   widget->label        = 0;
+   widget->labelLen     = 0;
+   widget->labelWin     = 0;
+   highValueLen         = MAXIMUM (formattedSize (widget, low),
+			           formattedSize (widget, high));
+
+   /*
+    * If the fieldWidth is a negative value, the fieldWidth will
+    * be COLS-fieldWidth, otherwise, the fieldWidth will be the
+    * given width.
+    */
+   fieldWidth = setWidgetDimension (parentWidth, fieldWidth, 0);
+
+   /* Translate the label char *pointer to a chtype pointer. */
+   if (label != 0)
+   {
+      widget->label = char2Chtype (label, &widget->labelLen, &junk);
+      boxWidth = widget->labelLen + fieldWidth + highValueLen + 2 * BorderOf (widget);
+   }
+   else
+   {
+      boxWidth = fieldWidth + highValueLen + 2 * BorderOf (widget);
+   }
+
+   oldWidth = boxWidth;
+   boxWidth = setCdkTitle (ObjOf (widget), title, boxWidth);
+   horizontalAdjust = (boxWidth - oldWidth) / 2;
+
+   boxHeight += TitleLinesOf (widget);
+
+   /*
+    * Make sure we didn't extend beyond the dimensions of the window.
+    */
+   boxWidth = (boxWidth > parentWidth ? parentWidth : boxWidth);
+   boxHeight = (boxHeight > parentHeight ? parentHeight : boxHeight);
+   fieldWidth = (fieldWidth > (boxWidth - widget->labelLen - highValueLen - 1)
+		 ? (boxWidth - widget->labelLen - highValueLen - 1)
+		 : fieldWidth);
+
+   /* Rejustify the x and y positions if we need to. */
+   alignxy (cdkscreen->window, &xpos, &ypos, boxWidth, boxHeight);
+
+   /* Make the widget's window. */
+   widget->win = newwin (boxHeight, boxWidth, ypos, xpos);
+
+   /* Is the main window null??? */
+   if (widget->win == 0)
+   {
+      destroyCDKObject (widget);
+      return (0);
+   }
+
+   /* Create the widget's label window. */
+   if (widget->label != 0)
+   {
+      widget->labelWin = subwin (widget->win,
+				 1, widget->labelLen,
+				 ypos + TitleLinesOf (widget) + BorderOf (widget),
+				 xpos + horizontalAdjust + BorderOf (widget));
+      if (widget->labelWin == 0)
+      {
+	 destroyCDKObject (widget);
+	 return (0);
+      }
+   }
+
+   /* Create the widget's data field window. */
+   widget->fieldWin = subwin (widget->win,
+			      1, fieldWidth + highValueLen - 1,
+			      (ypos + TitleLinesOf (widget) + BorderOf (widget)),
+			      (xpos
+			       + widget->labelLen
+			       + horizontalAdjust
+			       + BorderOf (widget)));
+   if (widget->fieldWin == 0)
+   {
+      destroyCDKObject (widget);
+      return (0);
+   }
+   keypad (widget->fieldWin, TRUE);
+   keypad (widget->win, TRUE);
+
+   /* *INDENT-EQLS* Create the widget's data field. */
+   ScreenOf (widget)            = cdkscreen;
+   widget->parent               = cdkscreen->window;
+   widget->shadowWin            = 0;
+   widget->boxWidth             = boxWidth;
+   widget->boxHeight            = boxHeight;
+   widget->fieldWidth           = fieldWidth - 1;
+   widget->filler               = filler;
+   widget->low                  = low;
+   widget->high                 = high;
+   widget->current              = start;
+   widget->inc                  = inc;
+   widget->fastinc              = fastInc;
+   initExitType (widget);
+   ObjOf (widget)->acceptsFocus = TRUE;
+   ObjOf (widget)->inputWindow  = widget->win;
+   widget->shadow               = shadow;
+
+   /* Set the start value. */
+   if (start < low)
+   {
+      widget->current = low;
+   }
+
+   /* Do we want a shadow??? */
+   if (shadow)
+   {
+      widget->shadowWin = newwin (boxHeight, boxWidth, ypos + 1, xpos + 1);
+      if (widget->shadowWin == 0)
+      {
+	 destroyCDKObject (widget);
+	 return (0);
+      }
+   }
+
+   /* Setup the key bindings. */
+   for (x = 0; x < (int)SIZEOF (bindings); ++x)
+      bindCDKObject (vSLIDER,
+		     widget,
+		     (chtype)bindings[x].from,
+		     getcCDKBind,
+		     (void *)(long)bindings[x].to);
+
+   registerCDKObject (cdkscreen, vSLIDER, widget);
+
+   return (widget);
+}
+
+/*
+ * This allows the person to use the widget's data field.
+ */
+int activateCDKSlider (CDKSLIDER *widget, chtype *actions)
+{
+   int ret;
+
+   /* Draw the widget. */
+   drawCDKSlider (widget, ObjOf (widget)->box);
+
+   if (actions == 0)
+   {
+      boolean functionKey;
+
+      for (;;)
+      {
+	 chtype input = (chtype)getchCDKObject (ObjOf (widget), &functionKey);
+
+	 /* Inject the character into the widget. */
+	 ret = (int)injectCDKSlider (widget, input);
+	 if (widget->exitType != vEARLY_EXIT)
+	 {
+	    return ret;
+	 }
+      }
+   }
+   else
+   {
+      int length = chlen (actions);
+      int x = 0;
+
+      /* Inject each character one at a time. */
+      for (x = 0; x < length; x++)
+      {
+	 ret = (int)injectCDKSlider (widget, actions[x]);
+	 if (widget->exitType != vEARLY_EXIT)
+	 {
+	    return ret;
+	 }
+      }
+   }
+
+   /* Set the exit type and return. */
+   setExitType (widget, 0);
+   return unknownInt;
+}
+
+/*
+ * Check if the value lies outside the low/high range.  If so, force it in.
+ */
+static void limitCurrentValue (CDKSLIDER *widget)
+{
+   if (widget->current < widget->low)
+   {
+      widget->current = widget->low;
+      Beep ();
+   }
+   else if (widget->current > widget->high)
+   {
+      widget->current = widget->high;
+      Beep ();
+   }
+}
+
+/*
+ * Move the cursor to the given edit-position.
+ */
+static int moveToEditPosition (CDKSLIDER *widget, int newPosition)
+{
+   return wmove (widget->fieldWin,
+		 0,
+		 widget->fieldWidth +
+		 formattedSize (widget, widget->current) -
+		 newPosition);
+}
+
+/*
+ * Check if the cursor is on a valid edit-position.  This must be one of
+ * the non-blank cells in the field.
+ */
+static int validEditPosition (CDKSLIDER *widget, int newPosition)
+{
+   chtype ch;
+   if (newPosition <= 0 || newPosition >= widget->fieldWidth)
+      return FALSE;
+   if (moveToEditPosition (widget, newPosition) == ERR)
+      return FALSE;
+   ch = winch (widget->fieldWin);
+   if (CharOf (ch) != ' ')
+      return TRUE;
+   if (newPosition > 1)
+   {
+      /* don't use recursion - only one level is wanted */
+      if (moveToEditPosition (widget, newPosition - 1) == ERR)
+	 return FALSE;
+      ch = winch (widget->fieldWin);
+      return CharOf (ch) != ' ';
+   }
+   return FALSE;
+}
+
+/*
+ * Set the edit position.  Normally the cursor is one cell to the right of
+ * the editable field.  Moving it left, over the field allows the user to
+ * modify cells by typing in replacement characters for the field's value.
+ */
+static void setEditPosition (CDKSLIDER *widget, int newPosition)
+{
+   if (newPosition < 0)
+   {
+      Beep ();
+   }
+   else if (newPosition == 0)
+   {
+      widget->fieldEdit = newPosition;
+   }
+   else if (validEditPosition (widget, newPosition))
+   {
+      widget->fieldEdit = newPosition;
+   }
+   else
+   {
+      Beep ();
+   }
+}
+
+/*
+ * Remove the character from the string at the given column, if it is blank.
+ * Returns true if a change was made.
+ */
+static bool removeChar (char *string, int col)
+{
+   bool result = FALSE;
+
+   if ((col >= 0) && (string[col] != ' '))
+   {
+      while (string[col] != '\0')
+      {
+	 string[col] = string[col + 1];
+	 ++col;
+      }
+      result = TRUE;
+   }
+   return result;
+}
+
+/*
+ * Perform an editing function for the field.
+ */
+static bool performEdit (CDKSLIDER *widget, chtype input)
+{
+   bool result = FALSE;
+   int base = widget->fieldWidth;
+   int need = formattedSize (widget, widget->current);
+   char *temp = (char *)malloc ((size_t) need + 5);
+   char *data = temp;
+   char test;
+   int col = need - widget->fieldEdit;
+   int value;
+#define SCANF_FMT "%d%c"
+
+   if (temp != 0)
+   {
+      bool modify = TRUE;
+      int adj = (col < 0) ? (-col) : 0;
+      if (adj)
+      {
+	 memset (temp, ' ', (size_t) adj);
+	 temp += adj;
+      }
+      wmove (widget->fieldWin, 0, base);
+      winnstr (widget->fieldWin, temp, need);
+      strcpy (temp + need, " ");
+      if (isChar (input))	/* replace the char at the cursor */
+      {
+	 temp[col] = (char)(input);
+      }
+      else if (input == KEY_BACKSPACE)	/* delete the char before the cursor */
+      {
+	 modify = removeChar (temp, col - 1);
+      }
+      else if (input == KEY_DC)	/* delete the char at the cursor */
+      {
+	 modify = removeChar (temp, col);
+      }
+      else
+      {
+	 modify = FALSE;
+      }
+      if (modify
+	  && sscanf (temp, SCANF_FMT, &value, &test) == 2
+	  && test == ' '
+	  && value >= widget->low
+	  && value <= widget->high)
+      {
+	 setCDKSliderValue (widget, (int)value);
+	 result = TRUE;
+      }
+      free (data);
+   }
+   return result;
+}
+
+#define Decrement(value,by) if (value - by < value) value -= by
+#define Increment(value,by) if (value + by > value) value += by
+
+/*
+ * This function injects a single character into the widget.
+ */
+static int _injectCDKSlider (CDKOBJS *object, chtype input)
+{
+   CDKSLIDER *widget = (CDKSLIDER *)object;
+   int ppReturn = 1;
+   int ret = unknownInt;
+   bool complete = FALSE;
+
+   /* Set the exit type. */
+   setExitType (widget, 0);
+
+   /* Draw the field. */
+   drawCDKSliderField (widget);
+
+   /* Check if there is a pre-process function to be called. */
+   if (PreProcessFuncOf (widget) != 0)
+   {
+      /* Call the pre-process function. */
+      ppReturn = PreProcessFuncOf (widget) (vSLIDER,
+					    widget,
+					    PreProcessDataOf (widget),
+					    input);
+   }
+
+   /* Should we continue? */
+   if (ppReturn != 0)
+   {
+      /* Check for a key binding. */
+      if (checkCDKObjectBind (vSLIDER, widget, input) != 0)
+      {
+	 checkEarlyExit (widget);
+	 complete = TRUE;
+      }
+      else
+      {
+	 switch (input)
+	 {
+	 case KEY_LEFT:
+	    setEditPosition (widget, widget->fieldEdit + 1);
+	    break;
+
+	 case KEY_RIGHT:
+	    setEditPosition (widget, widget->fieldEdit - 1);
+	    break;
+
+	 case KEY_DOWN:
+	    Decrement (widget->current, widget->inc);
+	    break;
+
+	 case KEY_UP:
+	    Increment (widget->current, widget->inc);
+	    break;
+
+	 case KEY_PPAGE:
+	    Increment (widget->current, widget->fastinc);
+	    break;
+
+	 case KEY_NPAGE:
+	    Decrement (widget->current, widget->fastinc);
+	    break;
+
+	 case KEY_HOME:
+	    widget->current = widget->low;
+	    break;
+
+	 case KEY_END:
+	    widget->current = widget->high;
+	    break;
+
+	 case KEY_TAB:
+	 case KEY_ENTER:
+	    setExitType (widget, input);
+	    ret = (widget->current);
+	    complete = TRUE;
+	    break;
+
+	 case KEY_ESC:
+	    setExitType (widget, input);
+	    complete = TRUE;
+	    break;
+
+	 case KEY_ERROR:
+	    setExitType (widget, input);
+	    complete = TRUE;
+	    break;
+
+	 case CDK_REFRESH:
+	    eraseCDKScreen (ScreenOf (widget));
+	    refreshCDKScreen (ScreenOf (widget));
+	    break;
+
+	 default:
+	    if (widget->fieldEdit)
+	    {
+	       if (!performEdit (widget, input))
+		  Beep ();
+	    }
+	    else
+	    {
+	       /*
+	        * The cursor is not within the editable text.  Interpret
+	        * input as commands.
+	        */
+	       switch (input)
+	       {
+	       case 'd':
+	       case '-':
+		  return _injectCDKSlider (object, KEY_DOWN);
+	       case '+':
+		  return _injectCDKSlider (object, KEY_UP);
+	       case 'D':
+		  return _injectCDKSlider (object, KEY_NPAGE);
+	       case '0':
+		  return _injectCDKSlider (object, KEY_HOME);
+	       default:
+		  Beep ();
+		  break;
+	       }
+	    }
+	    break;
+	 }
+      }
+      limitCurrentValue (widget);
+
+      /* Should we call a post-process? */
+      if (!complete && (PostProcessFuncOf (widget) != 0))
+      {
+	 PostProcessFuncOf (widget) (vSLIDER,
+				     widget,
+				     PostProcessDataOf (widget),
+				     input);
+      }
+   }
+
+   if (!complete)
+   {
+      drawCDKSliderField (widget);
+      setExitType (widget, 0);
+   }
+
+   ResultOf (widget).valueInt = ret;
+   return (ret != unknownInt);
+}
+
+/*
+ * This moves the widget's data field to the given location.
+ */
+static void _moveCDKSlider (CDKOBJS *object,
+			     int xplace,
+			     int yplace,
+			     boolean relative,
+			     boolean refresh_flag)
+{
+   /* *INDENT-EQLS* */
+   CDKSLIDER *widget = (CDKSLIDER *)object;
+   int currentX       = getbegx (widget->win);
+   int currentY       = getbegy (widget->win);
+   int xpos           = xplace;
+   int ypos           = yplace;
+   int xdiff          = 0;
+   int ydiff          = 0;
+
+   /*
+    * If this is a relative move, then we will adjust where we want
+    * to move to.
+    */
+   if (relative)
+   {
+      xpos = getbegx (widget->win) + xplace;
+      ypos = getbegy (widget->win) + yplace;
+   }
+
+   /* Adjust the window if we need to. */
+   alignxy (WindowOf (widget), &xpos, &ypos, widget->boxWidth, widget->boxHeight);
+
+   /* Get the difference. */
+   xdiff = currentX - xpos;
+   ydiff = currentY - ypos;
+
+   /* Move the window to the new location. */
+   moveCursesWindow (widget->win, -xdiff, -ydiff);
+   moveCursesWindow (widget->labelWin, -xdiff, -ydiff);
+   moveCursesWindow (widget->fieldWin, -xdiff, -ydiff);
+   moveCursesWindow (widget->shadowWin, -xdiff, -ydiff);
+
+   /* Touch the windows so they 'move'. */
+   refreshCDKWindow (WindowOf (widget));
+
+   /* Redraw the window, if they asked for it. */
+   if (refresh_flag)
+   {
+      drawCDKSlider (widget, ObjOf (widget)->box);
+   }
+}
+
+/*
+ * This function draws the widget.
+ */
+static void _drawCDKSlider (CDKOBJS *object, boolean Box)
+{
+   CDKSLIDER *widget = (CDKSLIDER *)object;
+
+   /* Draw the shadow. */
+   if (widget->shadowWin != 0)
+   {
+      drawShadow (widget->shadowWin);
+   }
+
+   /* Box the widget if asked. */
+   if (Box)
+   {
+      drawObjBox (widget->win, ObjOf (widget));
+   }
+
+   drawCdkTitle (widget->win, object);
+
+   /* Draw the label. */
+   if (widget->labelWin != 0)
+   {
+      writeChtype (widget->labelWin, 0, 0,
+		   widget->label,
+		   HORIZONTAL, 0,
+		   widget->labelLen);
+      wrefresh (widget->labelWin);
+   }
+   wrefresh (widget->win);
+
+   /* Draw the field window. */
+   drawCDKSliderField (widget);
+}
+
+/*
+ * This draws the widget.
+ */
+static void drawCDKSliderField (CDKSLIDER *widget)
+{
+   int fillerCharacters, x;
+   char temp[256];
+   double step = ((double)widget->fieldWidth /
+		  (double)(widget->high - widget->low));
+
+   /* Determine how many filler characters need to be drawn. */
+   fillerCharacters = (int)((widget->current - widget->low) * step);
+
+   werase (widget->fieldWin);
+
+   /* Add the character to the window. */
+   for (x = 0; x < fillerCharacters; x++)
+   {
+      (void)mvwaddch (widget->fieldWin, 0, x, widget->filler);
+   }
+
+   /* Draw the value in the field. */
+   sprintf (temp, "%d", widget->current);
+   writeCharAttrib (widget->fieldWin,
+		    widget->fieldWidth,
+		    0,
+		    temp,
+		    A_NORMAL,
+		    HORIZONTAL,
+		    0,
+		    (int)strlen (temp));
+
+   moveToEditPosition (widget, widget->fieldEdit);
+   wrefresh (widget->fieldWin);
+}
+
+/*
+ * This sets the background attribute of the widget.
+ */
+static void _setBKattrSlider (CDKOBJS *object, chtype attrib)
+{
+   if (object != 0)
+   {
+      CDKSLIDER *widget = (CDKSLIDER *)object;
+
+      /* Set the widgets background attribute. */
+      wbkgd (widget->win, attrib);
+      wbkgd (widget->fieldWin, attrib);
+      if (widget->labelWin != 0)
+      {
+	 wbkgd (widget->labelWin, attrib);
+      }
+   }
+}
+
+/*
+ * This function destroys the widget.
+ */
+static void _destroyCDKSlider (CDKOBJS *object)
+{
+   if (object != 0)
+   {
+      CDKSLIDER *widget = (CDKSLIDER *)object;
+
+      cleanCdkTitle (object);
+      freeChtype (widget->label);
+
+      /* Clean up the windows. */
+      deleteCursesWindow (widget->fieldWin);
+      deleteCursesWindow (widget->labelWin);
+      deleteCursesWindow (widget->shadowWin);
+      deleteCursesWindow (widget->win);
+
+      /* Clean the key bindings. */
+      cleanCDKObjectBindings (vSLIDER, widget);
+
+      /* Unregister this object. */
+      unregisterCDKObject (vSLIDER, widget);
+   }
+}
+
+/*
+ * This function erases the widget from the screen.
+ */
+static void _eraseCDKSlider (CDKOBJS *object)
+{
+   if (validCDKObject (object))
+   {
+      CDKSLIDER *widget = (CDKSLIDER *)object;
+
+      eraseCursesWindow (widget->labelWin);
+      eraseCursesWindow (widget->fieldWin);
+      eraseCursesWindow (widget->win);
+      eraseCursesWindow (widget->shadowWin);
+   }
+}
+
+static int formattedSize (CDKSLIDER *widget, int value)
+{
+   char temp[256];
+   (void)widget;
+   sprintf (temp, "%d", value);
+   return (int) strlen (temp);
+}
+
+/*
+ * This function sets the low/high/current values of the widget.
+ */
+void setCDKSlider (CDKSLIDER *widget,
+		    int low,
+		    int high,
+		    int value,
+		    boolean Box)
+{
+   setCDKSliderLowHigh (widget, low, high);
+   setCDKSliderValue (widget, value);
+   setCDKSliderBox (widget, Box);
+}
+
+/*
+ * This sets the digits.
+ */
+
+/*
+ * This sets the widget's value.
+ */
+void setCDKSliderValue (CDKSLIDER *widget, int value)
+{
+   widget->current = value;
+   limitCurrentValue (widget);
+}
+int getCDKSliderValue (CDKSLIDER *widget)
+{
+   return widget->current;
+}
+
+/*
+ * This function sets the low/high values of the widget.
+ */
+void setCDKSliderLowHigh (CDKSLIDER *widget, int low, int high)
+{
+   /* Make sure the values aren't out of bounds. */
+   if (low <= high)
+   {
+      widget->low = low;
+      widget->high = high;
+   }
+   else
+   {
+      widget->low = high;
+      widget->high = low;
+   }
+
+   /* Make sure the user hasn't done something silly. */
+   limitCurrentValue (widget);
+}
+int getCDKSliderLowValue (CDKSLIDER *widget)
+{
+   return widget->low;
+}
+int getCDKSliderHighValue (CDKSLIDER *widget)
+{
+   return widget->high;
+}
+
+/*
+ * This sets the widget's box attribute.
+ */
+void setCDKSliderBox (CDKSLIDER *widget, boolean Box)
+{
+   ObjOf (widget)->box = Box;
+   ObjOf (widget)->borderSize = Box ? 1 : 0;
+}
+boolean getCDKSliderBox (CDKSLIDER *widget)
+{
+   return ObjOf (widget)->box;
+}
+
+static void _focusCDKSlider (CDKOBJS *object)
+{
+   CDKSLIDER *widget = (CDKSLIDER *)object;
+
+   drawCDKSlider (widget, ObjOf (widget)->box);
+}
+
+static void _unfocusCDKSlider (CDKOBJS *object)
+{
+   CDKSLIDER *widget = (CDKSLIDER *)object;
+
+   drawCDKSlider (widget, ObjOf (widget)->box);
+}
+
+dummyRefreshData (Slider)
+
+dummySaveData (Slider)
diff --git a/view_info.c b/view_info.c
index fff430d..e69de29 100644
--- a/view_info.c
+++ b/view_info.c
@@ -1,44 +0,0 @@
-#include <cdk_int.h>
-
-/*
- * $Author: tom $
- * $Date: 2016/11/20 18:35:56 $
- * $Revision: 1.3 $
- */
-
-/*
- * This allows the user to view information.
- */
-int viewInfo (CDKSCREEN *screen,
-	      const char *title,
-	      CDK_CSTRING2 info,
-	      int count,
-	      CDK_CSTRING2 buttons,
-	      int buttonCount,
-	      boolean interpret)
-{
-   CDKVIEWER *viewer = 0;
-   int selected;
-
-   /* Create the file viewer to view the file selected. */
-   viewer = newCDKViewer (screen, CENTER, CENTER, -6, -16,
-			  buttons, buttonCount,
-			  A_REVERSE, TRUE, TRUE);
-
-   /* Set up the viewer title, and the contents to the widget. */
-   setCDKViewer (viewer, title, info, count, A_REVERSE, interpret, TRUE, TRUE);
-
-   /* Activate the viewer widget. */
-   selected = activateCDKViewer (viewer, 0);
-
-   /* Make sure they exited normally. */
-   if (viewer->exitType != vNORMAL)
-   {
-      destroyCDKViewer (viewer);
-      return (-1);
-   }
-
-   /* Clean up and return the button index selected. */
-   destroyCDKViewer (viewer);
-   return selected;
-}
diff --git a/viewer.c b/viewer.c
index c306602..e69de29 100644
--- a/viewer.c
+++ b/viewer.c
@@ -1,1305 +0,0 @@
-#include <cdk_int.h>
-
-/*
- * $Author: tom $
- * $Date: 2021/12/16 00:34:50 $
- * $Revision: 1.168 $
- */
-
-/*
- * Declare some local definitions.
- */
-#define		DOWN		0
-#define		UP		1
-
-/*
- * Declare file local prototypes.
- */
-static int createList (CDKVIEWER *swindow, int listSize);
-static int searchForWord (CDKVIEWER *viewer, char *pattern, int direction);
-static int jumpToLine (CDKVIEWER *viewer);
-static void popUpLabel (CDKVIEWER *viewer, CDK_CSTRING2 mesg);
-static void getAndStorePattern (CDKSCREEN *screen);
-static void drawCDKViewerButtons (CDKVIEWER *viewer);
-static void drawCDKViewerInfo (CDKVIEWER *viewer);
-
-/*
- * Declare file local variables.
- */
-static char *SearchPattern = 0;
-static int SearchDirection = DOWN;
-
-DeclareCDKObjects (VIEWER, Viewer, setCdk, Unknown);
-
-/*
- * This function creates a new viewer object.
- */
-CDKVIEWER *newCDKViewer (CDKSCREEN *cdkscreen,
-			 int xplace,
-			 int yplace,
-			 int height,
-			 int width,
-			 CDK_CSTRING2 buttons,
-			 int buttonCount,
-			 chtype buttonHighlight,
-			 boolean Box,
-			 boolean shadow)
-{
-   /* *INDENT-EQLS* */
-   CDKVIEWER *viewer = 0;
-   int parentWidth   = getmaxx (cdkscreen->window);
-   int parentHeight  = getmaxy (cdkscreen->window);
-   int boxWidth;
-   int boxHeight;
-   int xpos          = xplace;
-   int ypos          = yplace;
-   int buttonAdj     = 0;
-   int x             = 0;
-   /* *INDENT-OFF* */
-   static const struct { int from; int to; } bindings[] = {
-	    { CDK_BACKCHAR,	KEY_PPAGE },
-	    { 'b',		KEY_PPAGE },
-	    { 'B',		KEY_PPAGE },
-	    { CDK_FORCHAR,	KEY_NPAGE },
-	    { SPACE,		KEY_NPAGE },
-	    { 'f',		KEY_NPAGE },
-	    { 'F',		KEY_NPAGE },
-	    { '|',		KEY_HOME },
-	    { '$',		KEY_END },
-   };
-   /* *INDENT-ON* */
-
-
-   if ((viewer = newCDKObject (CDKVIEWER, &my_funcs)) == 0)
-        return (0);
-
-   setCDKViewerBox (viewer, Box);
-
-   boxHeight = setWidgetDimension (parentHeight, height, 0);
-   boxWidth = setWidgetDimension (parentWidth, width, 0);
-
-   /* Rejustify the x and y positions if we need to. */
-   alignxy (cdkscreen->window, &xpos, &ypos, boxWidth, boxHeight);
-
-   /* Make the viewer window. */
-   viewer->win = newwin (boxHeight, boxWidth, ypos, xpos);
-   if (viewer->win == 0)
-   {
-      destroyCDKObject (viewer);
-      return (0);
-   }
-
-   /* Turn the keypad on for the viewer. */
-   keypad (viewer->win, TRUE);
-
-   /* Create the buttons. */
-   viewer->buttonCount = buttonCount;
-   if (buttonCount > 0)
-   {
-      int buttonWidth = 0;
-      int buttonPos = 1;
-
-      if ((viewer->button = typeCallocN (chtype *, buttonCount + 1)) == 0
-	  || (viewer->buttonLen = typeCallocN (int, buttonCount + 1)) == 0
-	  || (viewer->buttonPos = typeCallocN (int, buttonCount + 1)) == 0)
-      {
-	 destroyCDKObject (viewer);
-	 return (0);
-      }
-      for (x = 0; x < buttonCount; x++)
-      {
-	 viewer->button[x] = char2Chtype (buttons[x], &viewer->buttonLen[x], &buttonAdj);
-	 buttonWidth += viewer->buttonLen[x] + 1;
-      }
-      buttonAdj = (int)((boxWidth - buttonWidth) / (buttonCount + 1));
-      buttonPos = 1 + buttonAdj;
-      for (x = 0; x < buttonCount; x++)
-      {
-	 viewer->buttonPos[x] = buttonPos;
-	 buttonPos += buttonAdj + viewer->buttonLen[x];
-      }
-   }
-
-   /* *INDENT-EQLS* Set the rest of the variables */
-   ScreenOf (viewer)            = cdkscreen;
-   viewer->parent               = cdkscreen->window;
-   viewer->shadowWin            = 0;
-   viewer->buttonHighlight      = buttonHighlight;
-   viewer->boxHeight            = boxHeight;
-   viewer->boxWidth             = boxWidth - 2;
-   viewer->viewSize             = height - 2;
-   ObjOf (viewer)->inputWindow  = viewer->win;
-   initExitType (viewer);
-   viewer->shadow               = shadow;
-   viewer->currentButton        = 0;
-   viewer->currentTop           = 0;
-   viewer->length               = 0;
-   viewer->leftChar             = 0;
-   viewer->maxLeftChar          = 0;
-   viewer->maxTopLine           = 0;
-   viewer->characters           = 0;
-   viewer->listSize             = -1;
-   viewer->showLineInfo         = 1;
-   viewer->exitType             = vEARLY_EXIT;
-
-   /* Do we need to create a shadow??? */
-   if (shadow)
-   {
-      viewer->shadowWin = newwin (boxHeight, boxWidth + 1, ypos + 1, xpos + 1);
-      if (viewer->shadowWin == 0)
-      {
-	 destroyCDKObject (viewer);
-	 return (0);
-      }
-   }
-
-   /* Setup the key bindings. */
-   for (x = 0; x < (int)SIZEOF (bindings); ++x)
-      bindCDKObject (vVIEWER,
-		     viewer,
-		     (chtype)bindings[x].from,
-		     getcCDKBind,
-		     (void *)(long)bindings[x].to);
-
-   registerCDKObject (cdkscreen, vVIEWER, viewer);
-
-   return (viewer);
-}
-
-/*
- * This function sets various attributes of the widget.
- */
-int setCDKViewer (CDKVIEWER *viewer,
-		  const char *title,
-		  CDK_CSTRING2 list,
-		  int listSize,
-		  chtype buttonHighlight,
-		  boolean attrInterp,
-		  boolean showLineInfo,
-		  boolean Box)
-{
-   setCDKViewerTitle (viewer, title);
-   setCDKViewerHighlight (viewer, buttonHighlight);
-   setCDKViewerInfoLine (viewer, showLineInfo);
-   setCDKViewerBox (viewer, Box);
-   return setCDKViewerInfo (viewer, list, listSize, attrInterp);
-}
-
-/*
- * This sets the title of the viewer. (A null title is allowed.
- * It just means that the viewer will not have a title when drawn.)
- */
-void setCDKViewerTitle (CDKVIEWER *viewer, const char *title)
-{
-   (void)setCdkTitle (ObjOf (viewer), title, -(viewer->boxWidth + 1));
-   viewer->titleAdj = TitleLinesOf (viewer);
-
-   /* Need to set viewer->viewSize. */
-   viewer->viewSize = viewer->boxHeight - (TitleLinesOf (viewer) + 1) - 2;
-}
-chtype **getCDKViewerTitle (CDKVIEWER *viewer)
-{
-   return TitleOf (viewer);
-}
-
-static void setupLine (CDKVIEWER *viewer, boolean interpret, const char
-		       *list, int x)
-{
-   /* Did they ask for attribute interpretation? */
-   if (interpret)
-   {
-      viewer->list[x] = char2Chtype (list, &viewer->listLen[x],
-				     &viewer->listPos[x]);
-      viewer->listPos[x] = justifyString (viewer->boxWidth,
-					  viewer->listLen[x],
-					  viewer->listPos[x]);
-   }
-   else
-   {
-      int len = (int)strlen (list);
-      int pass;
-      int y;
-      chtype *t = 0;
-
-      /*
-       * We must convert tabs and other nonprinting characters.  The curses
-       * library normally does this, but we are bypassing it by writing
-       * chtype's directly.
-       */
-      for (pass = 0; pass < 2; ++pass)
-      {
-	 len = 0;
-	 for (y = 0; list[y] != '\0'; ++y)
-	 {
-	    if (list[y] == '\t')
-	    {
-	       do
-	       {
-		  if (pass)
-		     t[len] = ' ';
-		  ++len;
-	       }
-	       while (len & 7);
-	    }
-	    else if (isprint (CharOf (list[y])))
-	    {
-	       if (pass)
-		  t[len] = CharOf (list[y]);
-	       ++len;
-	    }
-	    else
-	    {
-	       const char *s = unctrl ((chtype)list[y]);
-	       while (*s != 0)
-	       {
-		  if (pass)
-		     t[len] = CharOf (*s);
-		  ++len;
-		  ++s;
-	       }
-	    }
-	 }
-	 if (!pass)
-	 {
-	    viewer->list[x] = t = typeCallocN (chtype, len + 3);
-	    if (t == 0)
-	    {
-	       len = 0;
-	       break;
-	    }
-	 }
-      }
-      viewer->listLen[x] = len;
-      viewer->listPos[x] = 0;
-   }
-   viewer->widestLine = MAXIMUM (viewer->widestLine, viewer->listLen[x]);
-}
-
-static void freeLine (CDKVIEWER *viewer, int x)
-{
-   if (x < viewer->listSize)
-   {
-      freeChtype (viewer->list[x]);
-      viewer->list[x] = 0;
-   }
-}
-
-/*
- * This function sets the contents of the viewer.
- */
-int setCDKViewerInfo (CDKVIEWER *viewer, CDK_CSTRING2 list, int listSize, boolean interpret)
-{
-   /* *INDENT-EQLS* */
-   char filename[CDK_PATHMAX + 2];
-   int currentLine      = 0;
-   int x                = 0;
-   int viewerSize;
-
-   /*
-    * If the list-size is negative, count the length of the null-terminated
-    * list of strings.
-    */
-   if (listSize < 0)
-   {
-      listSize = (int)CDKcountStrings (list);
-   }
-
-   /* compute the size of the resulting display */
-   viewerSize = listSize;
-   if (list != 0 && interpret)
-   {
-      for (x = 0; x < listSize; ++x)
-      {
-	 if (list[x] == 0)
-	 {
-	    viewerSize = x;	/* oops - caller gave the wrong length */
-	    break;
-	 }
-	 if (checkForLink (list[x], filename) == 1)
-	 {
-	    char **fileContents = 0;
-	    int fileLen = CDKreadFile (filename, &fileContents);
-
-	    if (fileLen >= 0)
-	       viewerSize += (fileLen - 1);
-	    CDKfreeStrings (fileContents);
-	 }
-      }
-   }
-
-   /* Clean out the old viewer info. (if there is any) */
-   viewer->inProgress = TRUE;
-   cleanCDKViewer (viewer);
-   createList (viewer, viewerSize);
-
-   /* Keep some semi-permanent info. */
-   viewer->interpret = interpret;
-
-   /* Copy the information given. */
-   for (x = currentLine = 0; x < listSize && currentLine < viewerSize; x++)
-   {
-      if (list[x] == 0)
-      {
-	 viewer->list[currentLine] = 0;
-	 viewer->listLen[currentLine] = 0;
-	 viewer->listPos[currentLine] = 0;
-	 currentLine++;
-      }
-      else
-      {
-	 /* Check if we have a file link in this line. */
-	 if (checkForLink (list[x], filename) == 1)
-	 {
-	    /* We have a link, open the file. */
-	    char **fileContents = 0;
-	    int fileLen = 0;
-
-	    /* Open the file and put it into the viewer. */
-	    fileLen = CDKreadFile (filename, &fileContents);
-	    if (fileLen == -1)
-	    {
-#ifdef HAVE_START_COLOR
-#define FOPEN_FMT "<C></16>Link Failed: Could not open the file %s"
-#else
-#define FOPEN_FMT "<C></K>Link Failed: Could not open the file %s"
-#endif
-	       char *temp = (char *)malloc (80 + strlen (filename));
-	       sprintf (temp, FOPEN_FMT, filename);
-	       setupLine (viewer, TRUE, temp, currentLine++);
-	       free (temp);
-	    }
-	    else
-	    {
-	       int fileLine;
-
-	       /* For each line read, copy it into the viewer. */
-	       fileLen = MINIMUM (fileLen, (viewerSize - currentLine));
-	       for (fileLine = 0; fileLine < fileLen; fileLine++)
-	       {
-		  if (currentLine >= viewerSize)
-		     break;
-		  setupLine (viewer, FALSE, fileContents[fileLine], currentLine);
-		  viewer->characters += viewer->listLen[currentLine];
-		  currentLine++;
-	       }
-	       CDKfreeStrings (fileContents);
-	    }
-	 }
-	 else if (currentLine < viewerSize)
-	 {
-	    setupLine (viewer, viewer->interpret, list[x], currentLine);
-	    viewer->characters += viewer->listLen[currentLine];
-	    currentLine++;
-	 }
-      }
-   }
-
-   /*
-    * Determine how many characters we can shift to the right
-    * before all the items have been viewer off the screen.
-    */
-   if (viewer->widestLine > viewer->boxWidth)
-   {
-      viewer->maxLeftChar = (viewer->widestLine - viewer->boxWidth) + 1;
-   }
-   else
-   {
-      viewer->maxLeftChar = 0;
-   }
-
-   /* Set up the needed vars for the viewer list. */
-   viewer->inProgress = FALSE;
-   viewer->listSize = viewerSize;
-   if (viewer->listSize <= viewer->viewSize)
-   {
-      viewer->maxTopLine = 0;
-   }
-   else
-   {
-      viewer->maxTopLine = viewer->listSize - 1;
-   }
-   return viewer->listSize;
-}
-chtype **getCDKViewerInfo (CDKVIEWER *viewer, int *size)
-{
-   (*size) = viewer->listSize;
-   return viewer->list;
-}
-
-/*
- * This function sets the highlight type of the buttons.
- */
-void setCDKViewerHighlight (CDKVIEWER *viewer, chtype buttonHighlight)
-{
-   viewer->buttonHighlight = buttonHighlight;
-}
-chtype getCDKViewerHighlight (CDKVIEWER *viewer)
-{
-   return viewer->buttonHighlight;
-}
-
-/*
- * This sets whether or not you want to set the viewer info line.
- */
-void setCDKViewerInfoLine (CDKVIEWER *viewer, boolean showLineInfo)
-{
-   viewer->showLineInfo = showLineInfo;
-}
-boolean getCDKViewerInfoLine (CDKVIEWER *viewer)
-{
-   return viewer->showLineInfo;
-}
-
-/*
- * This sets the widgets box attribute.
- */
-void setCDKViewerBox (CDKVIEWER *viewer, boolean Box)
-{
-   ObjOf (viewer)->box = Box;
-   ObjOf (viewer)->borderSize = Box ? 1 : 0;
-}
-boolean getCDKViewerBox (CDKVIEWER *viewer)
-{
-   return ObjOf (viewer)->box;
-}
-
-/*
- * This removes all the lines inside the scrolling window.
- */
-void cleanCDKViewer (CDKVIEWER *viewer)
-{
-   int x;
-
-   /* Clean up the memory used ... */
-   for (x = 0; x < viewer->listSize; x++)
-   {
-      freeLine (viewer, x);
-   }
-
-   /* *INDENT-EQLS* Reset some variables. */
-   viewer->listSize    = 0;
-   viewer->maxLeftChar = 0;
-   viewer->widestLine  = 0;
-   viewer->currentTop  = 0;
-   viewer->maxTopLine  = 0;
-
-   /* Redraw the window. */
-   drawCDKViewer (viewer, ObjOf (viewer)->box);
-}
-
-static void PatternNotFound (CDKVIEWER *viewer, const char *pattern)
-{
-   if (pattern == 0)
-   {
-      PatternNotFound (viewer, "");
-   }
-   else
-   {
-      CDK_CSTRING tempInfo[2];
-      char *temp = (char *)malloc (80 + strlen (pattern));
-      tempInfo[0] = temp;
-      tempInfo[1] = 0;
-      sprintf (temp, "</U/5>Pattern '%s' not found.<!U!5>", pattern);
-      popUpLabel (viewer, tempInfo);
-      free (temp);
-   }
-}
-
-/*
- * This function actually controls the viewer...
- */
-int activateCDKViewer (CDKVIEWER *widget, chtype *actions GCC_UNUSED)
-{
-   char *fileInfo[10];
-   CDK_CSTRING tempInfo[2];
-   char temp[500];
-   boolean functionKey;
-   int x;
-
-   /* Create the information about the file stats. */
-   sprintf (temp, "</5>      </U>File Statistics<!U>     <!5>");
-   fileInfo[0] = copyChar (temp);
-   sprintf (temp, "</5>                          <!5>");
-   fileInfo[1] = copyChar (temp);
-   sprintf (temp, "</5/R>Character Count:<!R> %-4ld     <!5>", widget->characters);
-   fileInfo[2] = copyChar (temp);
-   sprintf (temp, "</5/R>Line Count     :<!R> %-4d     <!5>", widget->listSize);
-   fileInfo[3] = copyChar (temp);
-   sprintf (temp, "</5>                          <!5>");
-   fileInfo[4] = copyChar (temp);
-   sprintf (temp, "<C></5>Press Any Key To Continue.<!5>");
-   fileInfo[5] = copyChar (temp);
-   fileInfo[6] = 0;
-
-   tempInfo[0] = temp;
-   tempInfo[1] = 0;
-
-   /* Set the current button. */
-   widget->currentButton = 0;
-
-   /* Draw the widget list. */
-   drawCDKViewer (widget, ObjOf (widget)->box);
-
-   /* Do this until KEY_ENTER is hit. */
-   for (;;)
-   {
-      /* Reset the refresh flag. */
-      int REFRESH = FALSE;
-
-      chtype input = (chtype)getchCDKObject (ObjOf (widget), &functionKey);
-      if (!checkCDKObjectBind (vVIEWER, widget, input))
-      {
-	 switch (input)
-	 {
-	 case KEY_TAB:
-	    if (widget->buttonCount > 1)
-	    {
-	       if (widget->currentButton == (widget->buttonCount - 1))
-	       {
-		  widget->currentButton = 0;
-	       }
-	       else
-	       {
-		  widget->currentButton++;
-	       }
-
-	       /* Redraw the buttons. */
-	       drawCDKViewerButtons (widget);
-	    }
-	    break;
-
-	 case CDK_PREV:
-	    if (widget->buttonCount > 1)
-	    {
-	       if (widget->currentButton == 0)
-	       {
-		  widget->currentButton = widget->buttonCount - 1;
-	       }
-	       else
-	       {
-		  widget->currentButton--;
-	       }
-
-	       /* Redraw the buttons. */
-	       drawCDKViewerButtons (widget);
-	    }
-	    break;
-
-	 case KEY_UP:
-	    if (widget->currentTop > 0)
-	    {
-	       widget->currentTop--;
-	       REFRESH = TRUE;
-	    }
-	    else
-	    {
-	       Beep ();
-	    }
-	    break;
-
-	 case KEY_DOWN:
-	    if (widget->currentTop < widget->maxTopLine)
-	    {
-	       widget->currentTop++;
-	       REFRESH = TRUE;
-	    }
-	    else
-	    {
-	       Beep ();
-	    }
-	    break;
-
-	 case KEY_RIGHT:
-	    if (widget->leftChar < widget->maxLeftChar)
-	    {
-	       widget->leftChar++;
-	       REFRESH = TRUE;
-	    }
-	    else
-	    {
-	       Beep ();
-	    }
-	    break;
-
-	 case KEY_LEFT:
-	    if (widget->leftChar > 0)
-	    {
-	       widget->leftChar--;
-	       REFRESH = TRUE;
-	    }
-	    else
-	    {
-	       Beep ();
-	    }
-	    break;
-
-	 case KEY_PPAGE:
-	    if (widget->currentTop > 0)
-	    {
-	       if ((widget->currentTop - (widget->viewSize - 1)) > 0)
-	       {
-		  widget->currentTop = (widget->currentTop
-					- (widget->viewSize - 1));
-	       }
-	       else
-	       {
-		  widget->currentTop = 0;
-	       }
-	       REFRESH = TRUE;
-	    }
-	    else
-	    {
-	       Beep ();
-	    }
-	    break;
-
-	 case KEY_NPAGE:
-	    if (widget->currentTop < widget->maxTopLine)
-	    {
-	       if ((widget->currentTop + widget->viewSize) < widget->maxTopLine)
-	       {
-		  widget->currentTop = widget->currentTop +
-		     (widget->viewSize
-		      - 1);
-	       }
-	       else
-	       {
-		  widget->currentTop = widget->maxTopLine;
-	       }
-	       REFRESH = TRUE;
-	    }
-	    else
-	    {
-	       Beep ();
-	    }
-	    break;
-
-	 case KEY_HOME:
-	    widget->leftChar = 0;
-	    REFRESH = TRUE;
-	    break;
-
-	 case KEY_END:
-	    widget->leftChar = widget->maxLeftChar;
-	    REFRESH = TRUE;
-	    break;
-
-	 case 'g':
-	 case '1':
-	 case '<':
-	    widget->currentTop = 0;
-	    REFRESH = TRUE;
-	    break;
-
-	 case 'G':
-	 case '>':
-	    widget->currentTop = widget->maxTopLine;
-	    REFRESH = TRUE;
-	    break;
-
-	 case 'L':
-	    x = (int)((widget->listSize + widget->currentTop) / 2);
-	    if (x < widget->maxTopLine)
-	    {
-	       widget->currentTop = x;
-	       REFRESH = TRUE;
-	    }
-	    else
-	    {
-	       Beep ();
-	    }
-	    break;
-
-	 case 'l':
-	    x = (int)(widget->currentTop / 2);
-	    if (x >= 0)
-	    {
-	       widget->currentTop = x;
-	       REFRESH = TRUE;
-	    }
-	    else
-	    {
-	       Beep ();
-	    }
-	    break;
-
-	 case '?':
-	    SearchDirection = UP;
-	    getAndStorePattern (ScreenOf (widget));
-	    if (!searchForWord (widget, SearchPattern, SearchDirection))
-	    {
-	       PatternNotFound (widget, SearchPattern);
-	    }
-	    REFRESH = TRUE;
-	    break;
-
-	 case '/':
-	    SearchDirection = DOWN;
-	    getAndStorePattern (ScreenOf (widget));
-	    if (!searchForWord (widget, SearchPattern, SearchDirection))
-	    {
-	       PatternNotFound (widget, SearchPattern);
-	    }
-	    REFRESH = TRUE;
-	    break;
-
-	 case 'N':
-	 case 'n':
-	    if (SearchPattern == 0)
-	    {
-	       sprintf (temp, "</5>There is no pattern in the buffer.<!5>");
-	       popUpLabel (widget, tempInfo);
-	    }
-	    else if (!searchForWord (widget,
-				     SearchPattern,
-				     ((input == 'n')
-				      ? SearchDirection
-				      : !SearchDirection)))
-	    {
-	       PatternNotFound (widget, SearchPattern);
-	    }
-	    REFRESH = TRUE;
-	    break;
-
-	 case ':':
-	    widget->currentTop = jumpToLine (widget);
-	    REFRESH = TRUE;
-	    break;
-
-	 case 'i':
-	 case 's':
-	 case 'S':
-	    popUpLabel (widget, (CDK_CSTRING2)fileInfo);
-	    REFRESH = TRUE;
-	    break;
-
-	 case KEY_ESC:
-	    freeCharList (fileInfo, 6);
-	    setExitType (widget, input);
-	    return -1;
-
-	 case KEY_ERROR:
-	    freeCharList (fileInfo, 6);
-	    setExitType (widget, input);
-	    return -1;
-
-	 case KEY_ENTER:
-	    freeCharList (fileInfo, 6);
-	    setExitType (widget, input);
-	    return widget->currentButton;
-
-	 case CDK_REFRESH:
-	    eraseCDKScreen (ScreenOf (widget));
-	    refreshCDKScreen (ScreenOf (widget));
-	    break;
-
-	 default:
-	    Beep ();
-	    break;
-	 }
-      }
-
-      /* Do we need to redraw the screen??? */
-      if (REFRESH)
-      {
-	 drawCDKViewerInfo (widget);
-      }
-   }
-}
-
-/*
- * This searches the document looking for the given word.
- */
-static void getAndStorePattern (CDKSCREEN *screen)
-{
-   /* *INDENT-EQLS* */
-   CDKENTRY *getPattern = 0;
-   const char *temp     = 0;
-   char *list           = 0;
-
-   /* Check the direction. */
-   if (SearchDirection == UP)
-   {
-      temp = "</5>Search Up  : <!5>";
-   }
-   else
-   {
-      temp = "</5>Search Down: <!5>";
-   }
-
-   /* Pop up the entry field. */
-   getPattern = newCDKEntry (screen, CENTER, CENTER,
-			     0, temp,
-			     COLOR_PAIR (5) | A_BOLD,
-			     '.' | COLOR_PAIR (5) | A_BOLD,
-			     vMIXED, 10, 0, 256, TRUE, FALSE);
-
-   /* Is there an old search pattern? */
-   if (SearchPattern != 0)
-   {
-      setCDKEntry (getPattern, SearchPattern, getPattern->min,
-		   getPattern->max, ObjOf (getPattern)->box);
-   }
-   freeChar (SearchPattern);
-
-   /* Activate this baby. */
-   list = activateCDKEntry (getPattern, 0);
-
-   /* Save the list. */
-   if ((list != 0) && (strlen (list) != 0))
-   {
-      SearchPattern = copyChar (list);
-   }
-
-   /* Clean up. */
-   destroyCDKEntry (getPattern);
-}
-
-/*
- * This searches for a line containing the word and realigns the value on the
- * screen.
- */
-static int searchForWord (CDKVIEWER *viewer, char *pattern, int direction)
-{
-   int found = 0;
-   int plen;
-
-   /* If the pattern is empty then return. */
-   if (pattern != 0 && (plen = (int)strlen (pattern)) != 0)
-   {
-      int x, y, pos, len;
-
-      if (direction == DOWN)
-      {
-	 /* Start looking from 'here' down. */
-	 for (x = viewer->currentTop + 1; !found && (x < viewer->listSize);
-	      x++)
-	 {
-	    len = chlen (viewer->list[x]);
-	    for (y = pos = 0; y < len; y++)
-	    {
-	       int plainChar = CharOf (viewer->list[x][y]);
-
-	       if (CharOf (pattern[pos]) != plainChar)
-	       {
-		  y -= pos;
-		  pos = 0;
-	       }
-	       else if (++pos == plen)
-	       {
-		  viewer->currentTop = (x < viewer->maxTopLine ? x : viewer->maxTopLine);
-		  viewer->leftChar = (y < viewer->boxWidth ? 0 : viewer->maxLeftChar);
-		  found = 1;
-		  break;
-	       }
-
-	    }
-	 }
-      }
-      else
-      {
-	 /* Start looking from 'here' up. */
-	 for (x = viewer->currentTop - 1; !found && (x >= 0); x--)
-	 {
-	    len = chlen (viewer->list[x]);
-	    for (y = pos = 0; y < len; y++)
-	    {
-	       int plainChar = CharOf (viewer->list[x][y]);
-
-	       if (CharOf (pattern[pos]) != plainChar)
-	       {
-		  y -= pos;
-		  pos = 0;
-	       }
-	       else if (++pos == plen)
-	       {
-		  viewer->currentTop = x;
-		  viewer->leftChar = (y < viewer->boxWidth ? 0 : viewer->maxLeftChar);
-		  found = 1;
-		  break;
-	       }
-
-	    }
-	 }
-      }
-   }
-   return (found);
-}
-
-/*
- * This allows us to 'jump' to a given line in the file.
- */
-static int jumpToLine (CDKVIEWER *viewer)
-{
-   /* *INDENT-EQLS* */
-   int line           = 0;
-   CDKSCALE *newline  = newCDKScale (ScreenOf (viewer), CENTER, CENTER,
-				     "<C>Jump To Line", "</5>Line :", A_BOLD,
-				     intlen (viewer->listSize) + 1,
-				     viewer->currentTop + 1,
-				     0, viewer->maxTopLine + 1,
-				     1, 10, TRUE, TRUE);
-
-   line = activateCDKScale (newline, 0);
-   destroyCDKScale (newline);
-   return ((line - 1));
-}
-
-/*
- * This pops a little message up on the screen.
- */
-static void popUpLabel (CDKVIEWER *viewer, CDK_CSTRING2 mesg)
-{
-   CDKLABEL *label;
-   boolean functionKey;
-
-   /* Set up variables. */
-   label = newCDKLabel (ScreenOf (viewer), CENTER, CENTER,
-			(CDK_CSTRING2)mesg,
-			(int)CDKcountStrings (mesg),
-			TRUE, FALSE);
-
-   /* Draw the label and wait. */
-   drawCDKLabel (label, TRUE);
-   getchCDKObject (ObjOf (label), &functionKey);
-
-   /* Clean up. */
-   destroyCDKLabel (label);
-}
-
-/*
- * This moves the viewer field to the given location.
- */
-static void _moveCDKViewer (CDKOBJS *object, int xplace, int yplace, boolean
-			    relative, boolean refresh_flag)
-{
-   /* *INDENT-EQLS* */
-   CDKVIEWER *viewer = (CDKVIEWER *)object;
-   int currentX      = getbegx (viewer->win);
-   int currentY      = getbegy (viewer->win);
-   int xpos          = xplace;
-   int ypos          = yplace;
-   int xdiff         = 0;
-   int ydiff         = 0;
-
-   /*
-    * If this is a relative move, then we will adjust where we want
-    * to move to.
-    */
-   if (relative)
-   {
-      xpos = getbegx (viewer->win) + xplace;
-      ypos = getbegy (viewer->win) + yplace;
-   }
-
-   /* Adjust the window if we need to. */
-   alignxy (WindowOf (viewer), &xpos, &ypos, viewer->boxWidth, viewer->boxHeight);
-
-   /* Get the difference. */
-   xdiff = currentX - xpos;
-   ydiff = currentY - ypos;
-
-   /* Move the window to the new location. */
-   moveCursesWindow (viewer->win, -xdiff, -ydiff);
-   moveCursesWindow (viewer->shadowWin, -xdiff, -ydiff);
-
-   /* Touch the windows so they 'move'. */
-   refreshCDKWindow (WindowOf (viewer));
-
-   /* Redraw the window, if they asked for it. */
-   if (refresh_flag)
-   {
-      drawCDKViewer (viewer, ObjOf (viewer)->box);
-   }
-}
-
-/*
- * This function draws the viewer widget.
- */
-static void _drawCDKViewer (CDKOBJS *object, boolean Box)
-{
-   CDKVIEWER *viewer = (CDKVIEWER *)object;
-
-   /* Do we need to draw in the shadow??? */
-   if (viewer->shadowWin != 0)
-   {
-      drawShadow (viewer->shadowWin);
-   }
-
-   /* Box it if it was asked for. */
-   if (Box)
-   {
-      drawObjBox (viewer->win, ObjOf (viewer));
-      wrefresh (viewer->win);
-   }
-
-   /* Draw the info in the viewer. */
-   drawCDKViewerInfo (viewer);
-}
-
-/*
- * This redraws the viewer buttons.
- */
-static void drawCDKViewerButtons (CDKVIEWER *viewer)
-{
-   int x;
-
-   /* No buttons, no drawing. */
-   if (viewer->buttonCount == 0)
-   {
-      return;
-   }
-
-   /* Redraw the buttons. */
-   for (x = 0; x < viewer->buttonCount; x++)
-   {
-      writeChtype (viewer->win,
-		   viewer->buttonPos[x],
-		   viewer->boxHeight - 2,
-		   viewer->button[x],
-		   HORIZONTAL,
-		   0,
-		   viewer->buttonLen[x]);
-   }
-
-   /* Highlight the current button. */
-   for (x = 0; x < viewer->buttonLen[viewer->currentButton]; x++)
-   {
-      /* Strip the character of any extra attributes. */
-      chtype character = CharOf (viewer->button[viewer->currentButton][x]);
-
-      /* Add the character into the window. */
-      (void)mvwaddch (viewer->win,
-		      viewer->boxHeight - 2,
-		      viewer->buttonPos[viewer->currentButton] + x,
-		      character | viewer->buttonHighlight);
-   }
-
-   /* Refresh the window. */
-   wrefresh (viewer->win);
-}
-
-/*
- * This sets the background attribute of the widget.
- */
-static void _setBKattrViewer (CDKOBJS *object, chtype attrib)
-{
-   if (object != 0)
-   {
-      CDKVIEWER *widget = (CDKVIEWER *)object;
-
-      wbkgd (widget->win, attrib);
-   }
-}
-
-/*
- * Free any storage associated with the info-list.
- */
-static void destroyInfo (CDKVIEWER *viewer)
-{
-   CDKfreeChtypes (viewer->list);
-   freeChecked (viewer->listPos);
-   freeChecked (viewer->listLen);
-
-   viewer->list = 0;
-   viewer->listPos = 0;
-   viewer->listLen = 0;
-}
-
-/*
- * This function destroys the viewer widget.
- */
-static void _destroyCDKViewer (CDKOBJS *object)
-{
-   if (object != 0)
-   {
-      CDKVIEWER *viewer = (CDKVIEWER *)object;
-
-      destroyInfo (viewer);
-
-      cleanCdkTitle (object);
-      CDKfreeChtypes (viewer->button);
-      freeChecked (viewer->buttonLen);
-      freeChecked (viewer->buttonPos);
-
-      /* Clean up the windows. */
-      deleteCursesWindow (viewer->shadowWin);
-      deleteCursesWindow (viewer->win);
-
-      /* Clean the key bindings. */
-      cleanCDKObjectBindings (vVIEWER, viewer);
-
-      /* Unregister this object. */
-      unregisterCDKObject (vVIEWER, viewer);
-   }
-}
-
-/*
- * This function erases the viewer widget from the screen.
- */
-static void _eraseCDKViewer (CDKOBJS *object)
-{
-   if (validCDKObject (object))
-   {
-      CDKVIEWER *viewer = (CDKVIEWER *)object;
-
-      eraseCursesWindow (viewer->win);
-      eraseCursesWindow (viewer->shadowWin);
-   }
-}
-
-/*
- * This draws the viewer info lines.
- */
-static void drawCDKViewerInfo (CDKVIEWER *viewer)
-{
-   int listAdjust = 0;
-   int lastLine = 0;
-   int x;
-
-   /* Clear the window. */
-   werase (viewer->win);
-
-   drawCdkTitle (viewer->win, ObjOf (viewer));
-
-   /* Draw in the current line at the top. */
-   if (viewer->showLineInfo == TRUE)
-   {
-      char temp[256];
-
-      /* Set up the info line and draw it. */
-      if (viewer->inProgress)
-      {
-	 strcpy (temp, "processing...");
-      }
-      else if (viewer->listSize != 0)
-      {
-	 sprintf (temp, "%d/%d %2.0f%%",
-		  (viewer->currentTop + 1),
-		  viewer->listSize,
-		  ((float)(viewer->currentTop + 1)
-		   / (float)viewer->listSize) * 100);
-      }
-      else
-      {
-	 sprintf (temp, "%d/%d %2.0f%%", 0, 0, 0.0);
-      }
-
-      /*
-       * The listAdjust variable tells us if we have to shift down one line
-       * because the person asked for the line X of Y line at the top of the
-       * screen.  We only want to set this to 1 if they asked for the info line
-       * and there is no title, or if the two items overlap.
-       */
-      if (TitleLinesOf (viewer) == 0
-	  || TitlePosOf (viewer)[0] < ((int)strlen (temp) + 2))
-      {
-	 listAdjust = 1;
-      }
-      writeChar (viewer->win, 1, (listAdjust ? TitleLinesOf (viewer) : 0) + 1,
-		 temp, HORIZONTAL, 0, (int)strlen (temp));
-   }
-
-   /* Determine the last line to draw. */
-   lastLine = ((viewer->listSize <= viewer->viewSize)
-	       ? viewer->listSize
-	       : viewer->viewSize);
-   lastLine -= listAdjust;
-
-   /* Redraw the list. */
-   for (x = 0; x < lastLine; x++)
-   {
-      if (viewer->currentTop + x < viewer->listSize)
-      {
-	 int screenPos = viewer->listPos[viewer->currentTop + x] + 1 - viewer->leftChar;
-
-	 writeChtype (viewer->win,
-		      ((screenPos >= 0)
-		       ? screenPos
-		       : 1),
-		      x + TitleLinesOf (viewer) + listAdjust + 1,
-		      viewer->list[x + viewer->currentTop],
-		      HORIZONTAL,
-		      ((screenPos >= 0)
-		       ? 0
-		       : (viewer->leftChar
-			  - viewer->listPos[viewer->currentTop + x])),
-		      viewer->listLen[x + viewer->currentTop]);
-      }
-   }
-
-   /* Box it if we have to. */
-   if (ObjOf (viewer)->box)
-   {
-      drawObjBox (viewer->win, ObjOf (viewer));
-      wrefresh (viewer->win);
-   }
-
-   /* Draw the separation line. */
-   if (viewer->buttonCount > 0)
-   {
-      chtype boxattr = BXAttrOf (viewer);
-
-      for (x = 1; x <= viewer->boxWidth; x++)
-      {
-	 (void)mvwaddch (viewer->win, viewer->boxHeight - 3, x,
-			 HZCharOf (viewer) | boxattr);
-      }
-      (void)mvwaddch (viewer->win, viewer->boxHeight - 3, 0,
-		      ACS_LTEE | boxattr);
-      (void)mvwaddch (viewer->win, viewer->boxHeight - 3,
-		      getmaxx (viewer->win) - 1,
-		      ACS_RTEE | boxattr);
-   }
-
-   /* Draw the buttons. This will call refresh on the viewer win. */
-   drawCDKViewerButtons (viewer);
-}
-
-/*
- * The listSize may be negative, to assign no definite limit.
- */
-static int createList (CDKVIEWER *swindow, int listSize)
-{
-   int status = 0;
-
-   if (listSize >= 0)
-   {
-      chtype **newList = typeCallocN (chtype *, listSize + 1);
-      int *newPos = typeCallocN (int, listSize + 1);
-      int *newLen = typeCallocN (int, listSize + 1);
-
-      if (newList != 0
-	  && newPos != 0
-	  && newLen != 0)
-      {
-	 status = 1;
-	 destroyInfo (swindow);
-
-	 swindow->list = newList;
-	 swindow->listPos = newPos;
-	 swindow->listLen = newLen;
-      }
-      if (!status)
-      {
-	 CDKfreeChtypes (newList);
-	 freeChecked (newPos);
-	 freeChecked (newLen);
-      }
-   }
-   else
-   {
-      destroyInfo (swindow);
-   }
-   return status;
-}
-
-dummyInject (Viewer)
-
-dummyFocus (Viewer)
-
-dummyUnfocus (Viewer)
-
-dummyRefreshData (Viewer)
-
-dummySaveData (Viewer)
-- 
2.46.0

