#include <cdk_int.h>

/*
 * $Author: tom $
 * $Date: 2004/08/31 23:25:19 $
 * $Revision: 1.203 $
 */

/*
 * Declare file local prototypes.
 */
static void CDKEntryCallBack (CDKENTRY *entry, chtype character);
static void drawCDKEntryField (CDKENTRY *entry);

DeclareCDKObjects(ENTRY, Entry, setCdk, String);

/*
 * This creates a pointer to an entry widget.
 */
CDKENTRY *newCDKEntry (CDKSCREEN *cdkscreen, int xplace, int yplace, char *title, char *label, chtype fieldAttr, chtype filler, EDisplayType dispType, int fWidth, int min, int max, boolean Box, boolean shadow)
{
   CDKENTRY *entry	= 0;
   int parentWidth	= getmaxx(cdkscreen->window);
   int parentHeight	= getmaxy(cdkscreen->window);
   int fieldWidth	= fWidth;
   int boxWidth		= 0;
   int boxHeight;
   int xpos		= xplace;
   int ypos		= yplace;
   int junk		= 0;
   int horizontalAdjust, oldWidth;

   if ((entry = newCDKObject(CDKENTRY, &my_funcs)) == 0)
      return (0);

   setCDKEntryBox (entry, Box);
   boxHeight		= (BorderOf(entry) * 2) + 1;

  /*
   * 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(entry);

   /* Set some basic values of the entry field. */
   entry->label		= 0;
   entry->labelLen	= 0;
   entry->labelWin	= 0;

   /* Translate the label char *pointer to a chtype pointer. */
   if (label != 0)
   {
      entry->label = char2Chtype (label, &entry->labelLen, &junk);
      boxWidth += entry->labelLen;
   }

   oldWidth = boxWidth;
   boxWidth = setCdkTitle(ObjOf(entry), title, boxWidth);
   horizontalAdjust = (boxWidth - oldWidth) / 2;

   boxHeight += TitleLinesOf(entry);

  /*
   * Make sure we didn't extend beyond the dimensions of the window.
   */
   boxWidth = (boxWidth > parentWidth ? parentWidth : boxWidth);
   boxHeight = (boxHeight > parentHeight ? parentHeight : boxHeight);
   fieldWidth = MINIMUM(fieldWidth, boxWidth - entry->labelLen - 2 * BorderOf(entry));

   /* Rejustify the x and y positions if we need to. */
   alignxy (cdkscreen->window, &xpos, &ypos, boxWidth, boxHeight);

   /* Make the label window. */
   entry->win = subwin (cdkscreen->window, boxHeight, boxWidth, ypos, xpos);

   /* Is the window null? */
   if (entry->win == 0)
   {
      destroyCDKObject (entry);
      return (0);
   }
   keypad (entry->win, TRUE);

   /* Make the field window. */
   entry->fieldWin = subwin (entry->win, 1, fieldWidth,
				ypos + TitleLinesOf(entry) + BorderOf(entry),
				xpos + entry->labelLen + horizontalAdjust + BorderOf(entry));
   keypad (entry->fieldWin, TRUE);

   /* Make the label win, if we need to. */
   if (label != 0)
   {
      entry->labelWin = subwin (entry->win, 1, entry->labelLen,
					ypos + TitleLinesOf(entry) + BorderOf(entry),
					xpos + horizontalAdjust + BorderOf(entry));
   }

   /* Make room for the info char * pointer. */
   entry->info		= typeMallocN(char, max + 3);
   cleanChar (entry->info, max + 3, '\0');
   entry->infoWidth	= max + 3;

   /* Set up the rest of the structure. */
   ScreenOf(entry)		= cdkscreen;
   entry->parent		= cdkscreen->window;
   entry->shadowWin		= 0;
   entry->fieldAttr		= fieldAttr;
   entry->fieldWidth		= fieldWidth;
   entry->filler		= filler;
   entry->hidden		= filler;
   ObjOf(entry)->inputWindow    = entry->fieldWin;
   ObjOf(entry)->acceptsFocus   = TRUE;
   ReturnOf(entry)              = NULL;
   entry->shadow		= shadow;
   entry->screenCol		= 0;
   entry->leftChar		= 0;
   entry->min			= min;
   entry->max			= max;
   entry->boxWidth		= boxWidth;
   entry->boxHeight		= boxHeight;
   initExitType(entry);
   entry->dispType		= dispType;
   entry->callbackfn		= CDKEntryCallBack;

   /* Do we want a shadow? */
   if (shadow)
   {
      entry->shadowWin = subwin (cdkscreen->window, boxHeight, boxWidth, ypos+1, xpos+1);
   }

   /* Clean the key bindings. */
   cleanCDKObjectBindings (vENTRY, entry);

   /* Register this baby. */
   registerCDKObject (cdkscreen, vENTRY, entry);

   /* Return the pointer to the structure. */
   return (entry);
}

/*
 * This means you want to use the given entry field. It takes input
 * from the keyboard, and when its done, it fills the entry info
 * element of the structure with what was typed.
 */
char *activateCDKEntry (CDKENTRY *entry, chtype *actions)
{
   chtype input = 0;
   char *ret	= 0;

   /* Draw the widget. */
   drawCDKEntry (entry, ObjOf(entry)->box);

   /* Check if 'actions' is null. */
   if (actions == 0)
   {
      for (;;)
      {
	 /* Get the input. */
	 input = getcCDKObject (ObjOf(entry));

	 /* Inject the character into the widget. */
	 ret = injectCDKEntry (entry, input);
	 if (entry->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 = injectCDKEntry (entry, actions[x]);
	 if (entry->exitType != vEARLY_EXIT)
	 {
	    return ret;
	 }
      }
   }

   /* Make sure we return the correct info. */
   if (entry->exitType == vNORMAL)
   {
      return entry->info;
   }
   else
   {
      return 0;
   }
}

/*
 * This injects a single character into the widget.
 */
static int _injectCDKEntry (CDKOBJS *object, chtype input)
{
   CDKENTRY *entry = (CDKENTRY *)object;
   int ppReturn = 1;
   int temp, x, charCount, stringLen;
   char holder;
   char *ret = unknownString;
   bool complete = FALSE;

   /* Set the exit type. */
   setExitType(entry, 0);

   /* Refresh the entry field. */
   drawCDKEntryField (entry);

   /* Check if there is a pre-process function to be called. */
   if (PreProcessFuncOf(entry) != 0)
   {
      /* Call the pre-process function. */
      ppReturn = PreProcessFuncOf(entry) (vENTRY, entry, PreProcessDataOf(entry), input);
   }

   /* Should we continue? */
   if (ppReturn != 0)
   {
      /* Check a predefined binding... */
      if (checkCDKObjectBind (vENTRY, entry, input) != 0)
      {
	 checkEarlyExit(entry);
	 complete = TRUE;
      }
      else
      {
	 switch (input)
	 {
	    case KEY_UP : case KEY_DOWN :
		 Beep();
		 break;

	    case KEY_HOME :
		 entry->leftChar = 0;
		 entry->screenCol = 0;
		 drawCDKEntryField (entry);
		 break;

	    case CDK_TRANSPOSE :
		 stringLen = (int)strlen (entry->info);
		 temp = entry->leftChar + entry->screenCol;
		 if (temp >= stringLen-1)
		 {
		    Beep();
		 }
		 else
		 {
		    holder = entry->info[temp];
		    entry->info[temp] = entry->info[temp + 1];
		    entry->info[temp + 1] = holder;
		    drawCDKEntryField (entry);
		 }
		 break;

	    case KEY_END :
		 stringLen = (int)strlen (entry->info);
		 if (stringLen >= entry->fieldWidth)
		 {
		    charCount = (int)(entry->fieldWidth * .8);
		    entry->leftChar = stringLen - charCount;
		    entry->screenCol = charCount;
		 }
		 else
		 {
		    entry->leftChar = 0;
		    entry->screenCol = stringLen;
		 }
		 drawCDKEntryField (entry);
		 break;

	    case KEY_LEFT :
		 if (entry->screenCol == 0)
		 {
		    if (entry->leftChar == 0)
		    {
		       Beep();
		    }
		    else
		    {
		       /* Scroll left.	*/
		       entry->leftChar--;
		       drawCDKEntryField (entry);
		    }
		 }
		 else
		 {
		    wmove (entry->fieldWin, 0, --entry->screenCol);
		    wrefresh (entry->fieldWin);
		 }
		 break;

	    case KEY_RIGHT :
		 if (entry->screenCol == entry->fieldWidth-1)
		 {
		    temp = (int)strlen (entry->info);
		    if ((entry->leftChar + entry->screenCol + 1) == temp)
		    {
		       Beep();
		    }
		    else
		    {
		       /* Scroll to the right. */
		       entry->leftChar++;
		       drawCDKEntryField (entry);
		    }
		 }
		 else
		 {
		    /* Move right. */
		    temp = (int)strlen (entry->info);
		    if ((entry->leftChar + entry->screenCol) == temp)
		    {
		       Beep();
		    }
		    else
		    {
		       wmove (entry->fieldWin, 0, ++entry->screenCol);
		    }
		    wrefresh (entry->fieldWin);
		 }
		 break;

	    case KEY_BACKSPACE : case KEY_DC :
		 if (entry->dispType == vVIEWONLY)
		 {
		    Beep();
		 }
		 else
		 {
		    /* Get the length of the widget information. */
		    int infoLength = (int)strlen (entry->info);
		    if ((entry->leftChar + entry->screenCol) < infoLength)
		    {
		       /* We are deleting from inside the string. */
		       int currPos = entry->screenCol + entry->leftChar;
		       for (x=currPos; x < infoLength; x++)
		       {
			  entry->info[x] = entry->info[x + 1];
		       }
		       entry->info[infoLength] = '\0';

		       /* Update the widget. */
		       drawCDKEntryField (entry);
		    }
		    else
		    {
		       /* We are deleting from the end of the string. */
		       if (infoLength > 0)
		       {
			  /* Update the character pointer. */
			  entry->info[infoLength-1] = '\0';
			  infoLength--;

			  /* Adjust the cursor. */
			  if (entry->screenCol > 0)
			  {
			     entry->screenCol--;
			  }

			  /*
			   * If we deleted the last character on the
			   * screen and the information has scrolled,
			   * adjust the entry field to show the info.
			   */
			   if (entry->leftChar > 0 && entry->screenCol == 1)
			   {
			      if (infoLength < entry->fieldWidth-1)
			      {
				 entry->leftChar = 0;
				 entry->screenCol = infoLength;
			      }
			      else
			      {
				 entry->leftChar -= (entry->fieldWidth-3);
				 entry->screenCol = entry->fieldWidth-2;
			      }
			   }

			  /* Update the widget. */
			  drawCDKEntryField (entry);
		       }
		       else
		       {
			  Beep();
		       }
		    }
		 }
		 break;

	    case KEY_ESC :
		 setExitType(entry, input);
		 complete = TRUE;
		 break;

	    case CDK_ERASE :
		 if ((int)strlen(entry->info) != 0)
		 {
		    cleanCDKEntry (entry);
		    drawCDKEntryField (entry);
		 }
		 break;

	    case CDK_CUT:
		 if ((int)strlen(entry->info) != 0)
		 {
		    freeChar (GPasteBuffer);
		    GPasteBuffer = copyChar (entry->info);
		    cleanCDKEntry (entry);
		    drawCDKEntryField (entry);
		 }
		 else
		 {
		    Beep();
		 }
		 break;

	    case CDK_COPY:
		 if ((int)strlen(entry->info) != 0)
		 {
		    freeChar (GPasteBuffer);
		    GPasteBuffer = copyChar (entry->info);
		 }
		 else
		 {
		    Beep();
		 }
		 break;

	    case CDK_PASTE:
		 if (GPasteBuffer != 0)
		 {
		    setCDKEntryValue (entry, GPasteBuffer);
		    drawCDKEntryField (entry);
		 }
		 else
		 {
		    Beep();
		 }
		 break;

	    case KEY_TAB : case KEY_ENTER :
		 if ((int)strlen (entry->info) >= entry->min)
		 {
		    setExitType(entry, input);
		    ret = (entry->info);
		    complete = TRUE;
		 }
		 else
		 {
		    Beep();
		 }
		 break;

	    case CDK_REFRESH :
		 eraseCDKScreen (ScreenOf(entry));
		 refreshCDKScreen (ScreenOf(entry));
		 break;

	    default :
		 (entry->callbackfn)(entry, input);
		 break;
	 }
      }

      /* Should we do a post-process? */
      if (!complete && (PostProcessFuncOf(entry) != 0))
      {
	 PostProcessFuncOf(entry) (vENTRY, entry, PostProcessDataOf(entry), input);
      }
   }

   if (!complete) {
      setExitType(entry, 0);
   }

   ResultOf(entry).valueString = ret;
   return (ret != unknownString);
}

/*
 * This moves the entry field to the given location.
 */
static void _moveCDKEntry (CDKOBJS *object, int xplace, int yplace, boolean relative, boolean refresh_flag)
{
   CDKENTRY *entry = (CDKENTRY *)object;
   int currentX = getbegx(entry->win);
   int currentY = getbegy(entry->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(entry->win) + xplace;
      ypos = getbegy(entry->win) + yplace;
   }

   /* Adjust the window if we need to. */
   alignxy (WindowOf(entry), &xpos, &ypos, entry->boxWidth, entry->boxHeight);

   /* Get the difference. */
   xdiff = currentX - xpos;
   ydiff = currentY - ypos;

   /* Move the window to the new location. */
   moveCursesWindow(entry->win, -xdiff, -ydiff);
   moveCursesWindow(entry->fieldWin, -xdiff, -ydiff);
   moveCursesWindow(entry->labelWin, -xdiff, -ydiff);
   moveCursesWindow(entry->shadowWin, -xdiff, -ydiff);

   /* Touch the windows so they 'move'. */
   refreshCDKWindow (WindowOf(entry));

   /* Redraw the window, if they asked for it. */
   if (refresh_flag)
   {
      touchwin (entry->win);
      touchwin (entry->labelWin);
      touchwin (entry->fieldWin);
      drawCDKEntry (entry, ObjOf(entry)->box);
   }
}

/*
 * 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
 * a new function and calling the activation with its name.
 */
static void CDKEntryCallBack (CDKENTRY *entry, chtype character)
{
   int plainchar = CharOf(character);
   unsigned temp, x;

   /* Start checking the input. */
   if (!isChar(character))
   {
      Beep();
   }
   else if ((entry->dispType == vINT ||
	entry->dispType ==vHINT) &&
	!isdigit(CharOf(plainchar)))
   {
      Beep();
   }
   else if ((entry->dispType == vCHAR ||
		entry->dispType == vUCHAR ||
		entry->dispType == vLCHAR ||
		entry->dispType == vUHCHAR ||
		entry->dispType == vLHCHAR) &&
		isdigit(CharOf(plainchar)))
   {
      Beep();
   }
   else if (entry->dispType == vVIEWONLY)
   {
      Beep();
   }
   else if ((int)strlen (entry->info) == entry->max)
   {
      Beep();
   }
   else
   {
      /* We will make any adjustments to the case of the character. */
      if ((entry->dispType == vUCHAR ||
	     entry->dispType == vUHCHAR ||
	     entry->dispType == vUMIXED ||
	     entry->dispType == vUHMIXED)
	     && !isdigit(CharOf(plainchar)))
      {
	 plainchar = toupper (plainchar);
      }
      else if ((entry->dispType == vLCHAR ||
		     entry->dispType == vLHCHAR ||
		     entry->dispType == vLMIXED ||
		     entry->dispType == vLHMIXED) &&
		     !isdigit(CharOf(plainchar)))
      {
	 plainchar = tolower (plainchar);
      }

      /* Update the screen and pointer. */
      if (entry->screenCol != entry->fieldWidth-1)
      {
	 /* Update the character pointer. */
	 temp = strlen (entry->info);
	 for (x=temp; (int) x > entry->screenCol + entry->leftChar; x--)
	 {
	    entry->info[x] = entry->info[x-1];
	 }
	 entry->info[entry->screenCol + entry->leftChar] = plainchar;
	 entry->screenCol++;
      }
      else
      {
	 /* Update the character pointer. */
	 temp = strlen (entry->info);
	 entry->info[temp]     = plainchar;
	 entry->info[temp + 1] = '\0';
	 /* Do not update the pointer if it's the last character */
	 if ((int)(temp + 1) < entry->max)
	     entry->leftChar++;
      }

      /* Update the entry field. */
      drawCDKEntryField (entry);
   }
}

/*
 * This erases the information in the entry field
 * and redraws a clean and empty entry field.
 */
void cleanCDKEntry (CDKENTRY *entry)
{
   int width = entry->fieldWidth;

   /* Erase the information in the character pointer. */
   cleanChar (entry->info, entry->infoWidth, '\0');

   /* Clean the entry screen field. */
   mvwhline(entry->fieldWin, 0, 0, entry->filler, width);

   /* Reset some variables. */
   entry->screenCol	= 0;
   entry->leftChar	= 0;

   /* Refresh the entry field. */
   wrefresh (entry->fieldWin);
}

/*
 * This draws the entry field.
 */
static void _drawCDKEntry (CDKOBJS *object, boolean Box)
{
   CDKENTRY *entry = (CDKENTRY *)object;

   /* Did we ask for a shadow? */
   if (entry->shadowWin != 0)
   {
      drawShadow (entry->shadowWin);
   }

   /* Box the widget if asked. */
   if (Box)
   {
      drawObjBox (entry->win, ObjOf(entry));
   }

   drawCdkTitle (entry->win, object);

   /* Refresh the window. */
   refreshCDKWindow (entry->win);

   /* Draw in the label to the widget. */
   if (entry->labelWin != 0)
   {
      writeChtype (entry->labelWin, 0, 0, entry->label, HORIZONTAL, 0, entry->labelLen);
      refreshCDKWindow (entry->labelWin);
   }

   /* Redraw the entry field. */
   drawCDKEntryField (entry);
}

/*
 * This redraws the entry field.
 */
static void drawCDKEntryField (CDKENTRY *entry)
{
   int infoLength	= 0;
   int x		= 0;

   /* Draw in the filler characters.*/
   mvwhline(entry->fieldWin, 0, x, entry->filler, entry->fieldWidth);

   /* If there is information in the field. Then draw it in. */
   if (entry->info != 0)
   {
      infoLength = (int)strlen (entry->info);

      /* Redraw the field. */
      if (entry->dispType == vHINT ||
		entry->dispType == vHCHAR ||
		entry->dispType == vHMIXED ||
		entry->dispType == vUHCHAR ||
		entry->dispType == vLHCHAR ||
		entry->dispType == vUHMIXED ||
		entry->dispType == vLHMIXED)
      {
	 for (x=entry->leftChar; x < infoLength; x++)
	 {
	    mvwaddch (entry->fieldWin, 0, x - entry->leftChar, entry->hidden);
	 }
      }
      else
      {
	 for (x=entry->leftChar; x < infoLength; x++)
	 {
	    mvwaddch (entry->fieldWin, 0, x - entry->leftChar, CharOf(entry->info[x]) | entry->fieldAttr);
	 }
      }
      wmove (entry->fieldWin, 0, entry->screenCol);
   }

   /* Refresh the field. */
   refreshCDKWindow (entry->fieldWin);
}

/*
 * This erases an entry widget from the screen.
 */
static void _eraseCDKEntry (CDKOBJS *object)
{
   if (validCDKObject (object))
   {
      CDKENTRY *entry = (CDKENTRY *)object;

      eraseCursesWindow (entry->fieldWin);
      eraseCursesWindow (entry->labelWin);
      eraseCursesWindow (entry->win);
      eraseCursesWindow (entry->shadowWin);
   }
}

/*
 * This destroys an entry widget.
 */
static void _destroyCDKEntry (CDKOBJS *object)
{
   if (object != 0)
   {
      CDKENTRY *entry = (CDKENTRY *)object;

      cleanCdkTitle (object);
      freeChtype (entry->label);
      freeChar (entry->info);

      /* Delete the windows. */
      deleteCursesWindow (entry->fieldWin);
      deleteCursesWindow (entry->labelWin);
      deleteCursesWindow (entry->shadowWin);
      deleteCursesWindow (entry->win);

      /* Unregister this object. */
      unregisterCDKObject (vENTRY, entry);
   }
}

/*
 * This sets specific attributes of the entry field.
 */
void setCDKEntry (CDKENTRY *entry, char *value, int min, int max, boolean Box GCC_UNUSED)
{
   setCDKEntryValue (entry, value);
   setCDKEntryMin (entry, min);
   setCDKEntryMax (entry, max);
}

/*
 * This removes the old information in the entry field and keeps the
 * new information given.
 */
void setCDKEntryValue (CDKENTRY *entry, char *newValue)
{
   int copychars	= 0;
   int stringLen	= 0;
   int charCount	= 0;

   /* If the pointer sent in is the same pointer as before, do nothing. */
   if (entry->info == newValue)
   {
      return;
   }

   /* Just to be sure, if lets make sure the new value isn't null. */
   if (newValue == 0)
   {
      /* Then we want to just erase the old value. */
      cleanChar (entry->info, entry->infoWidth, '\0');

      /* Set the pointers back to zero. */
      entry->leftChar = 0;
      entry->screenCol = 0;
      return;
   }

   /* Determine how many characters we need to copy. */
   copychars = MINIMUM ((int)strlen(newValue), entry->max);

   /* OK, erase the old value, and copy in the new value. */
   cleanChar (entry->info, entry->max, '\0');
   strncpy (entry->info, newValue, (unsigned) copychars);
   stringLen = (int)strlen (entry->info);

   /* Now determine the values of leftChar and screenCol. */
   if (stringLen >= entry->fieldWidth)
   {
      charCount		= (int)(entry->fieldWidth * .8);
      entry->leftChar	= stringLen - charCount;
      entry->screenCol	= charCount;
   }
   else
   {
      entry->leftChar = 0;
      entry->screenCol = stringLen;
   }
}
char *getCDKEntryValue (CDKENTRY *entry)
{
   return entry->info;
}

/*
 * This sets the maximum length of the string that will be accepted.
 */
void setCDKEntryMax (CDKENTRY *entry, int max)
{
   entry->max = max;
}
int getCDKEntryMax (CDKENTRY *entry)
{
   return entry->max;
}

/*
 * This sets the minimum length of the string that will
 * be accepted.
 */
void setCDKEntryMin (CDKENTRY *entry, int min)
{
   entry->min = min;
}
int getCDKEntryMin (CDKENTRY *entry)
{
   return entry->min;
}

/*
 * This sets the filler character to be used in the entry field.
 */
void setCDKEntryFillerChar (CDKENTRY *entry, chtype fillerCharacter)
{
   entry->filler = fillerCharacter;
}
chtype getCDKEntryFillerChar (CDKENTRY *entry)
{
   return entry->filler;
}

/*
 * This sets the character to use when a hidden type is used.
 */
void setCDKEntryHiddenChar (CDKENTRY *entry, chtype hiddenCharacter)
{
   entry->hidden = hiddenCharacter;
}
chtype getCDKEntryHiddenChar (CDKENTRY *entry)
{
   return entry->hidden;
}

/*
 * This sets the widgets box attribute.
 */
void setCDKEntryBox (CDKENTRY *entry, boolean Box)
{
   ObjOf(entry)->box = Box;
   ObjOf(entry)->borderSize = Box ? 1 : 0;
}
boolean getCDKEntryBox (CDKENTRY *entry)
{
   return ObjOf(entry)->box;
}

/*
 * This sets the background attribute of the widget.
 */
static void _setBKattrEntry (CDKOBJS *object, chtype attrib)
{
   if (object != 0)
   {
      CDKENTRY *widget = (CDKENTRY *)object;

      wbkgd (widget->win, attrib);
      wbkgd (widget->fieldWin, attrib);
      if (widget->labelWin != 0)
      {
	 wbkgd (widget->labelWin, attrib);
      }
   }
}

/*
 * This sets the attribute of the entry field.
 */
void setCDKEntryHighlight (CDKENTRY *entry, chtype highlight, boolean cursor)
{
   wbkgd (entry->fieldWin, highlight);
   entry->fieldAttr = highlight;
   curs_set (cursor);
   /*
    *  FIXME -  if (cursor) { move the cursor to this widget }
    */
}

/*
 * This sets the entry field callback function.
 */
void setCDKEntryCB (CDKENTRY *entry, ENTRYCB callback)
{
   entry->callbackfn = callback;
}

static void _focusCDKEntry(CDKOBJS *object)
{
   CDKENTRY *entry = (CDKENTRY *)object;

   wmove (entry->fieldWin, 0, entry->screenCol);
   wrefresh (entry->fieldWin);
}

static void _unfocusCDKEntry(CDKOBJS *object)
{
   CDKENTRY *entry = (CDKENTRY *)object;

   drawCDKEntry (entry, ObjOf(entry)->box);
   wrefresh (entry->fieldWin);
}

#if 0
static void _refreshDataCDKEntry(CDKOBJS *object)
{
   CDKENTRY *entry = (CDKENTRY *)object;

   if (ReturnOf(entry))
   {
      switch (DataTypeOf(entry))
      {
      default:
      case DataTypeString:
	 strcpy(entry->info, (char *)ReturnOf(entry));
	 break;
      case DataTypeInt:
	 sprintf(entry->info, "%d", *((int*)ReturnOf(entry)));
	 break;
      case DataTypeFloat:
	 sprintf(entry->info, "%g", *((float*)ReturnOf(entry)));
	 break;
      case DataTypeDouble:
	 sprintf(entry->info, "%g", *((double*)ReturnOf(entry)));
	 break;
      }
      entry->screenCol = strlen(entry->info);
      drawCDKEntryField(entry);
   }
}

static void _saveDataCDKEntry(CDKOBJS *object)
{
   CDKENTRY *entry = (CDKENTRY *)object;

   if (ReturnOf(entry))
   {
      switch (DataTypeOf(entry))
      {
      default:
      case DataTypeString:
	 strcpy((char *)ReturnOf(entry), entry->info);
	 break;
      case DataTypeInt:
	 *((int*)ReturnOf(entry)) = atoi(entry->info);
	 break;
      case DataTypeFloat:
	 *((float*)ReturnOf(entry)) = atof(entry->info);
	 break;
      case DataTypeDouble:
	 *((double*)ReturnOf(entry)) = atof(entry->info);
	 break;
      }
   }
}
#else
dummyRefreshData(Entry)
dummySaveData(Entry)
#endif


syntax highlighted by Code2HTML, v. 0.9.1