#include <cdk_int.h>

/*
 * $Author: tom $
 * $Date: 2016/11/20 20:55:23 $
 * $Revision: 1.169 $
 */

/*
 * Declare file local prototypes.
 */
static void CDKMentryCallBack (CDKMENTRY *mentry, chtype character);

DeclareCDKObjects (MENTRY, Mentry, setCdk, String);

/*
 * This creates a pointer to a multiple line entry widget.
 */
CDKMENTRY *newCDKMentry (CDKSCREEN *cdkscreen,
			 int xplace,
			 int yplace,
			 const char *title,
			 const char *label,
			 chtype fieldAttr,
			 chtype filler,
			 EDisplayType dispType,
			 int fWidth,
			 int fRows,
			 int logicalRows,
			 int min,
			 boolean Box,
			 boolean shadow)
{
   /* *INDENT-EQLS* */
   CDKMENTRY *mentry    = 0;
   int parentWidth      = getmaxx (cdkscreen->window);
   int parentHeight     = getmaxy (cdkscreen->window);
   int fieldWidth       = fWidth;
   int fieldRows        = fRows;
   int boxWidth         = 0;
   int boxHeight        = 0;
   int horizontalAdjust, oldWidth;
   int xpos             = xplace;
   int ypos             = yplace;
   int junk;

   if ((mentry = newCDKObject (CDKMENTRY, &my_funcs)) == 0)
        return (0);

   setCDKMentryBox (mentry, Box);

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

   /*
    * If the fieldRows is a negative value, the fieldRows will
    * be ROWS-fieldRows, otherwise, the fieldRows will be the
    * given height.
    */
   fieldRows = setWidgetDimension (parentWidth, fieldRows, 0);
   boxHeight = fieldRows + 2;

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

   /* We need to translate the char * label to a chtype * */
   if (label != 0)
   {
      mentry->label = char2Chtype (label, &mentry->labelLen, &junk);
   }
   boxWidth = mentry->labelLen + fieldWidth + 2;

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

   boxHeight += TitleLinesOf (mentry);

   /*
    * Make sure we didn't extend beyond the parent window.
    */
   boxWidth = (boxWidth > parentWidth ? parentWidth : boxWidth);
   boxHeight = (boxHeight > parentHeight ? parentHeight : boxHeight);
   fieldWidth = (fieldWidth > (boxWidth - mentry->labelLen - 2)
		 ? (boxWidth - mentry->labelLen - 2)
		 : fieldWidth);
   fieldRows = (fieldRows > (boxHeight - TitleLinesOf (mentry) - 2)
		? (boxHeight - TitleLinesOf (mentry) - 2)
		: fieldRows);

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

   /* Make the label window. */
   mentry->win = newwin (boxHeight, boxWidth, ypos, xpos);

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

   /* Create the label window. */
   if (mentry->label != 0)
   {
      mentry->labelWin = subwin (mentry->win, fieldRows,
				 mentry->labelLen + 2,
				 ypos + TitleLinesOf (mentry) + 1,
				 xpos + horizontalAdjust + 1);
   }

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

   /* Turn on the keypad. */
   keypad (mentry->fieldWin, TRUE);
   keypad (mentry->win, TRUE);

   /* *INDENT-EQLS* Set up the rest of the structure. */
   mentry->parent       = cdkscreen->window;
   mentry->totalWidth   = (fieldWidth * logicalRows) + 1;

   /* Create the info char * pointer. */
   mentry->info = typeMallocN (char, mentry->totalWidth + 3);
   cleanChar (mentry->info, mentry->totalWidth + 3, '\0');

   /* *INDENT-EQLS* Set up the rest of the widget information. */
   ScreenOf (mentry)            = cdkscreen;
   mentry->shadowWin            = 0;
   mentry->fieldAttr            = fieldAttr;
   mentry->fieldWidth           = fieldWidth;
   mentry->rows                 = fieldRows;
   mentry->boxHeight            = boxHeight;
   mentry->boxWidth             = boxWidth;
   mentry->filler               = filler;
   mentry->hidden               = filler;
   ObjOf (mentry)->inputWindow  = mentry->win;
   ObjOf (mentry)->acceptsFocus = TRUE;
   mentry->currentRow           = 0;
   mentry->currentCol           = 0;
   mentry->topRow               = 0;
   mentry->shadow               = shadow;
   mentry->dispType             = dispType;
   mentry->min                  = min;
   mentry->logicalRows          = logicalRows;
   initExitType (mentry);
   mentry->callbackfn           = CDKMentryCallBack;

   /* Do we need to create a shadow. */
   if (shadow)
   {
      mentry->shadowWin = newwin (boxHeight, boxWidth, ypos + 1, xpos + 1);
   }

   /* Register this baby. */
   registerCDKObject (cdkscreen, vMENTRY, mentry);

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

/*
 * This actually manages the mentry widget...
 */
char *activateCDKMentry (CDKMENTRY *mentry, chtype *actions)
{
   chtype input = 0;
   boolean functionKey;
   char *ret = 0;

   /* Draw the mentry widget. */
   drawCDKMentry (mentry, ObjOf (mentry)->box);

   if (actions == 0)
   {
      for (;;)
      {
	 input = (chtype)getchCDKObject (ObjOf (mentry), &functionKey);

	 /* Inject this character into the widget. */
	 ret = injectCDKMentry (mentry, input);
	 if (mentry->exitType != vEARLY_EXIT)
	 {
	    return ret;
	 }
      }
   }
   else
   {
      int length = chlen (actions);
      int x;

      /* Inject each character one at a time. */
      for (x = 0; x < length; x++)
      {
	 ret = injectCDKMentry (mentry, actions[x]);
	 if (mentry->exitType != vEARLY_EXIT)
	 {
	    return ret;
	 }
      }
   }

   /* Set the exit type and exit. */
   setExitType (mentry, 0);
   return 0;
}

static bool setTopRow (CDKMENTRY *widget, int row)
{
   if (widget->topRow != row)
   {
      widget->topRow = row;
      return TRUE;
   }
   return FALSE;
}

static bool setCurPos (CDKMENTRY *widget, int row, int col)
{
   if (widget->currentRow != row ||
       widget->currentCol != col)
   {
      widget->currentRow = row;
      widget->currentCol = col;
      return TRUE;
   }
   return FALSE;
}

static bool handle_KEY_LEFT (CDKMENTRY *mentry, bool *moved, bool *redraw)
{
   bool result = TRUE;

   if (mentry->currentCol != 0)
   {
      *moved = setCurPos (mentry,
			  mentry->currentRow,
			  mentry->currentCol - 1);
   }
   else if (mentry->currentRow == 0)
   {
      if (mentry->topRow != 0)
      {
	 *moved = setCurPos (mentry,
			     mentry->currentRow,
			     mentry->fieldWidth - 1);
	 *redraw = setTopRow (mentry, mentry->topRow - 1);
      }
   }
   else
   {
      *moved = setCurPos (mentry,
			  mentry->currentRow - 1,
			  mentry->fieldWidth - 1);
   }

   if (!*moved && !*redraw)
   {
      Beep ();
      result = FALSE;
   }
   return result;
}

static int getCursorPos (CDKMENTRY *mentry)
{
   return (((mentry->currentRow + mentry->topRow) * mentry->fieldWidth) +
	   mentry->currentCol);
}

/*
 * This injects a character into the widget.
 */
static int _injectCDKMentry (CDKOBJS *object, chtype input)
{
   CDKMENTRY *widget = (CDKMENTRY *)object;
   /* *INDENT-EQLS */
   int cursorPos = getCursorPos (widget);
   int ppReturn = 1;
   char *ret = unknownString;
   bool complete = FALSE;

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

   /* Refresh the field. */
   drawCDKMentryField (widget);

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

   /* Should we continue? */
   if (ppReturn != 0)
   {
      /* Check for a key binding... */
      if (checkCDKObjectBind (vMENTRY, widget, input) != 0)
      {
	 checkEarlyExit (widget);
	 complete = TRUE;
      }
      else
      {
	 bool moved = FALSE;
	 bool redraw = FALSE;
	 int infoLength = (int)strlen (widget->info);
	 int fieldCharacters;

	 switch (input)
	 {
	 case KEY_HOME:
	    moved = setCurPos (widget, 0, 0);
	    redraw = setTopRow (widget, 0);
	    break;

	 case KEY_END:
	    fieldCharacters = widget->rows * widget->fieldWidth;
	    if (infoLength < fieldCharacters)
	    {
	       redraw = setTopRow (widget, 0);
	       moved = setCurPos (widget,
				  infoLength / widget->fieldWidth,
				  infoLength % widget->fieldWidth);
	    }
	    else
	    {
	       redraw = setTopRow (widget,
				   (infoLength / widget->fieldWidth) -
				   widget->rows + 1);
	       moved = setCurPos (widget,
				  widget->rows - 1,
				  infoLength % widget->fieldWidth);
	    }
	    break;

	 case KEY_LEFT:
	    handle_KEY_LEFT (widget, &moved, &redraw);
	    break;

	 case KEY_RIGHT:
	    if (widget->currentCol < (widget->fieldWidth - 1))
	    {
	       if ((getCursorPos (widget) + 1) <= infoLength)
	       {
		  moved = setCurPos (widget,
				     widget->currentRow,
				     widget->currentCol + 1);
	       }
	    }
	    else if (widget->currentRow == widget->rows - 1)
	    {
	       if ((widget->topRow + widget->currentRow + 1) <= widget->logicalRows)
	       {
		  moved = setCurPos (widget, widget->currentRow, 0);
		  redraw = setTopRow (widget, widget->topRow + 1);
	       }
	    }
	    else
	    {
	       moved = setCurPos (widget, widget->currentRow + 1, 0);
	    }
	    if (!moved && !redraw)
	       Beep ();
	    break;

	 case KEY_DOWN:
	    if (widget->currentRow != (widget->rows - 1))
	    {
	       if ((getCursorPos (widget) + widget->fieldWidth + 1)
		   <= infoLength)
	       {
		  moved = setCurPos (widget, widget->currentRow + 1, widget->currentCol);
	       }
	    }
	    else if (widget->topRow < widget->logicalRows - widget->rows)
	    {
	       if (((widget->topRow + widget->currentRow + 1) *
		    widget->fieldWidth) <= infoLength)
	       {
		  redraw = setTopRow (widget, widget->topRow + 1);
	       }
	    }
	    if (!moved && !redraw)
	       Beep ();
	    break;

	 case KEY_UP:
	    if (widget->currentRow != 0)
	    {
	       moved = setCurPos (widget, widget->currentRow - 1, widget->currentCol);
	    }
	    else if (widget->topRow != 0)
	    {
	       redraw = setTopRow (widget, widget->topRow - 1);
	    }
	    if (!moved && !redraw)
	       Beep ();
	    break;

	 case KEY_BACKSPACE:
	 case KEY_DC:
	    if (widget->dispType == vVIEWONLY)
	    {
	       Beep ();
	    }
	    else if (infoLength == 0)
	    {
	       Beep ();
	    }
	    else if (input == KEY_DC
		     || handle_KEY_LEFT (widget, &moved, &redraw))
	    {
	       cursorPos = getCursorPos (widget);
	       if (widget->info[cursorPos] != '\0')
	       {
		  int x;

		  for (x = cursorPos; x < infoLength; x++)
		  {
		     widget->info[x] = widget->info[x + 1];
		  }
		  widget->info[--infoLength] = '\0';

		  drawCDKMentryField (widget);
	       }
	       else
	       {
		  Beep ();
	       }
	    }
	    break;

	 case CDK_TRANSPOSE:
	    if (cursorPos >= infoLength - 1)
	    {
	       Beep ();
	    }
	    else
	    {
	       char holder = widget->info[cursorPos];
	       widget->info[cursorPos] = widget->info[cursorPos + 1];
	       widget->info[cursorPos + 1] = holder;
	       drawCDKMentryField (widget);
	    }
	    break;

	 case CDK_ERASE:
	    if (infoLength != 0)
	    {
	       cleanCDKMentry (widget);
	       drawCDKMentryField (widget);
	    }
	    break;

	 case CDK_CUT:
	    if (infoLength == 0)
	    {
	       Beep ();
	    }
	    else
	    {
	       freeChar (GPasteBuffer);
	       GPasteBuffer = copyChar (widget->info);
	       cleanCDKMentry (widget);
	       drawCDKMentryField (widget);
	    }
	    break;

	 case CDK_COPY:
	    if (infoLength == 0)
	    {
	       Beep ();
	    }
	    else
	    {
	       freeChar (GPasteBuffer);
	       GPasteBuffer = copyChar (widget->info);
	    }
	    break;

	 case CDK_PASTE:
	    if (GPasteBuffer == 0)
	    {
	       Beep ();
	    }
	    else
	    {
	       setCDKMentryValue (widget, GPasteBuffer);
	       drawCDKMentry (widget, ObjOf (widget)->box);
	    }
	    break;

	 case KEY_TAB:
	 case KEY_ENTER:
	    if (infoLength < widget->min + 1)
	    {
	       Beep ();
	    }
	    else
	    {
	       setExitType (widget, input);
	       ret = (widget->info);
	       complete = TRUE;
	    }
	    break;

	 case KEY_ERROR:
	    setExitType (widget, input);
	    complete = TRUE;
	    break;

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

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

	 default:
	    if (widget->dispType == vVIEWONLY
		|| infoLength >= widget->totalWidth)
	    {
	       Beep ();
	    }
	    else
	    {
	       (widget->callbackfn) (widget, input);
	    }
	    break;
	 }

	 if (redraw)
	 {
	    drawCDKMentryField (widget);
	 }
	 else if (moved)
	 {
	    wmove (widget->fieldWin, widget->currentRow, widget->currentCol);
	    wrefresh (widget->fieldWin);
	 }
      }

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

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

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

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

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

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

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

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

   /* Redraw the window, if they asked for it. */
   if (refresh_flag)
   {
      drawCDKMentry (mentry, ObjOf (mentry)->box);
   }
}

/*
 * This function redraws the multiple line entry field.
 */
void drawCDKMentryField (CDKMENTRY *mentry)
{
   /* *INDENT-EQLS* */
   int currchar         = (mentry->fieldWidth * mentry->topRow);
   int length           = 0;
   int lastpos          = 0;
   int x, y;

   /* Check the value of info. */
   if (mentry->info == 0)
   {
      return;
   }

   drawCdkTitle (mentry->win, ObjOf (mentry));

   wrefresh (mentry->win);

   /* The information isn't null, redraw the field. */
   length = (int)strlen (mentry->info);
   lastpos = ((chtype)mentry->info[length] == (chtype)mentry->filler
	      ? length - 1
	      : length);

   /* Set background color and attributes of the entry field */
   wbkgd (mentry->fieldWin, mentry->fieldAttr);

   /* Start redrawing the fields. */
   for (x = 0; x < mentry->rows; x++)
   {
      for (y = 0; y < mentry->fieldWidth; y++)
      {
	 if (currchar < lastpos)
	 {
	    if (isHiddenDisplayType (mentry->dispType))
	    {
	       (void)mvwaddch (mentry->fieldWin, x, y, mentry->hidden | mentry->fieldAttr);
	    }
	    else
	    {
	       (void)mvwaddch (mentry->fieldWin, x, y,
			       CharOf (mentry->info[currchar++]) | mentry->fieldAttr);
	    }
	 }
	 else
	 {
	    (void)mvwhline (mentry->fieldWin, x, y, mentry->filler |
			    mentry->fieldAttr, mentry->fieldWidth - y);
	    break;
	 }
      }
   }

   /* Refresh the screen. */
   wmove (mentry->fieldWin, mentry->currentRow, mentry->currentCol);
   wrefresh (mentry->fieldWin);
}

/*
 * This is a generic character parser for the mentry field. It is used as a
 * callback function, so any personal modifications can be made by creating
 * a new function and calling that one the mentry activation.
 */
static void CDKMentryCallBack (CDKMENTRY *mentry, chtype character)
{
   /* *INDENT-EQLS* */
   int cursorPos  = getCursorPos (mentry);
   int infoLength = (int)strlen (mentry->info);
   char newchar   = (char)filterByDisplayType (mentry->dispType, character);

   if (newchar == ERR)
   {
      Beep ();
   }
   else
   {
      int x;

      for (x = infoLength + 1; x > cursorPos; x--)
      {
	 mentry->info[x] = mentry->info[x - 1];
      }
      mentry->info[cursorPos] = newchar;
      mentry->currentCol++;

      drawCDKMentryField (mentry);

      /* Have we gone out of bounds. */
      if (mentry->currentCol >= mentry->fieldWidth)
      {
	 /* Update the row and col values. */
	 mentry->currentCol = 0;
	 mentry->currentRow++;

	 /*
	  * If we have gone outside of the visual boundaries, we
	  * need to scroll the window.
	  */
	 if (mentry->currentRow == mentry->rows)
	 {
	    /* We have to redraw the screen. */
	    mentry->currentRow--;
	    mentry->topRow++;
	    drawCDKMentryField (mentry);
	 }
	 wmove (mentry->fieldWin, mentry->currentRow, mentry->currentCol);
	 wrefresh (mentry->fieldWin);
      }
   }
}

/*
 * This function draws the multiple line entry field.
 */
static void _drawCDKMentry (CDKOBJS *object, boolean Box)
{
   CDKMENTRY *mentry = (CDKMENTRY *)object;

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

   /* Do we need to draw in the shadow??? */
   if (mentry->shadowWin != 0)
   {
      drawShadow (mentry->shadowWin);
   }

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

   /* Draw the mentry field. */
   drawCDKMentryField (mentry);
}

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

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

/*
 * This function erases the multiple line entry field from the screen.
 */
static void _eraseCDKMentry (CDKOBJS *object)
{
   if (validCDKObject (object))
   {
      CDKMENTRY *mentry = (CDKMENTRY *)object;

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

/*
 * This function destroys a multiple line entry field widget.
 */
static void _destroyCDKMentry (CDKOBJS *object)
{
   if (object != 0)
   {
      CDKMENTRY *mentry = (CDKMENTRY *)object;

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

      /* Clean up the windows. */
      deleteCursesWindow (mentry->fieldWin);
      deleteCursesWindow (mentry->labelWin);
      deleteCursesWindow (mentry->shadowWin);
      deleteCursesWindow (mentry->win);

      /* Clean the key bindings. */
      cleanCDKObjectBindings (vMENTRY, mentry);

      /* Unregister this object. */
      unregisterCDKObject (vMENTRY, mentry);
   }
}

/*
 * This sets multiple attributes of the widget.
 */
void setCDKMentry (CDKMENTRY *mentry, const char *value, int min, boolean Box)
{
   setCDKMentryValue (mentry, value);
   setCDKMentryMin (mentry, min);
   setCDKMentryBox (mentry, Box);
}

/*
 * This removes the old information in the entry field and keeps the
 * new information given.
 */
void setCDKMentryValue (CDKMENTRY *mentry, const char *newValue)
{
   /* *INDENT-EQLS* */
   int fieldCharacters  = mentry->rows * mentry->fieldWidth;
   int len              = 0;
   int copychars        = 0;

   /* 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 (mentry->info, mentry->totalWidth, '\0');
      return;
   }

   /* Determine how many characters we need to copy. */
   len = (int)strlen (newValue);
   copychars = (len < mentry->totalWidth ? len : mentry->totalWidth);

   /* OK, erase the old value, and copy in the new value. */
   cleanChar (mentry->info, mentry->totalWidth, '\0');
   strncpy (mentry->info, newValue, (size_t) copychars);

   /* Set the cursor/row info. */
   if (len < fieldCharacters)
   {
      mentry->topRow = 0;
      mentry->currentRow = len / mentry->fieldWidth;
      mentry->currentCol = len % mentry->fieldWidth;
   }
   else
   {
      /* *INDENT-EQLS* */
      int rowsUsed              = len / mentry->fieldWidth;
      mentry->topRow            = rowsUsed - mentry->rows + 1;
      mentry->currentRow        = mentry->rows - 1;
      mentry->currentCol        = len % mentry->fieldWidth;
   }

   /* Redraw the widget. */
   drawCDKMentryField (mentry);
}
char *getCDKMentryValue (CDKMENTRY *mentry)
{
   return mentry->info;
}

/*
 * This sets the filler character to use when drawing the widget.
 */
void setCDKMentryFillerChar (CDKMENTRY *mentry, chtype filler)
{
   mentry->filler = filler;
}
chtype getCDKMentryFillerChar (CDKMENTRY *mentry)
{
   return mentry->filler;
}

/*
 * This sets the character to use when a hidden character type is used.
 */
void setCDKMentryHiddenChar (CDKMENTRY *mentry, chtype character)
{
   mentry->hidden = character;
}
chtype getCDKMentryHiddenChar (CDKMENTRY *mentry)
{
   return mentry->hidden;
}

/*
 * This sets the minimum length of the widget.
 */
void setCDKMentryMin (CDKMENTRY *mentry, int min)
{
   mentry->min = min;
}
int getCDKMentryMin (CDKMENTRY *mentry)
{
   return mentry->min;
}

/*
 * This sets the widgets box attribute.
 */
void setCDKMentryBox (CDKMENTRY *mentry, boolean Box)
{
   ObjOf (mentry)->box = Box;
   ObjOf (mentry)->borderSize = Box ? 1 : 0;
}
boolean getCDKMentryBox (CDKMENTRY *mentry)
{
   return ObjOf (mentry)->box;
}

/*
 * This erases the information in the multiple line entry widget.
 */
void cleanCDKMentry (CDKMENTRY *mentry)
{
   cleanChar (mentry->info, mentry->totalWidth, '\0');
   /* *INDENT-EQLS* */
   mentry->currentRow   = 0;
   mentry->currentCol   = 0;
   mentry->topRow       = 0;
}

/*
 * This sets the callback function.
 */
void setCDKMentryCB (CDKMENTRY *mentry, MENTRYCB callback)
{
   mentry->callbackfn = callback;
}

static void _focusCDKMentry (CDKOBJS *object)
{
   CDKMENTRY *mentry = (CDKMENTRY *)object;

   wmove (mentry->fieldWin, 0, mentry->currentCol);
   wrefresh (mentry->fieldWin);
}

static void _unfocusCDKMentry (CDKOBJS *object)
{
   CDKMENTRY *mentry = (CDKMENTRY *)object;

   wrefresh (mentry->fieldWin);
}

dummyRefreshData (Mentry)

dummySaveData (Mentry)