1 #include <cdk_int.h>
2 
3 /*
4  * $Author: tom $
5  * $Date: 2016/11/20 19:04:57 $
6  * $Revision: 1.224 $
7  */
8 
9 /*
10  * Declare file local prototypes.
11  */
12 static void CDKEntryCallBack (CDKENTRY *entry, chtype character);
13 static void drawCDKEntryField (CDKENTRY *entry);
14 
15 DeclareCDKObjects (ENTRY, Entry, setCdk, String);
16 
17 /*
18  * This creates a pointer to an entry widget.
19  */
newCDKEntry(CDKSCREEN * cdkscreen,int xplace,int yplace,const char * title,const char * label,chtype fieldAttr,chtype filler,EDisplayType dispType,int fWidth,int min,int max,boolean Box,boolean shadow)20 CDKENTRY *newCDKEntry (CDKSCREEN *cdkscreen,
21 		       int xplace,
22 		       int yplace,
23 		       const char *title,
24 		       const char *label,
25 		       chtype fieldAttr,
26 		       chtype filler,
27 		       EDisplayType dispType,
28 		       int fWidth,
29 		       int min,
30 		       int max,
31 		       boolean Box,
32 		       boolean shadow)
33 {
34    /* *INDENT-EQLS* */
35    CDKENTRY *entry      = 0;
36    int parentWidth      = getmaxx (cdkscreen->window);
37    int parentHeight     = getmaxy (cdkscreen->window);
38    int fieldWidth       = fWidth;
39    int boxWidth         = 0;
40    int boxHeight;
41    int xpos             = xplace;
42    int ypos             = yplace;
43    int junk             = 0;
44    int horizontalAdjust, oldWidth;
45 
46    if ((entry = newCDKObject (CDKENTRY, &my_funcs)) == 0)
47         return (0);
48 
49    setCDKEntryBox (entry, Box);
50    boxHeight = (BorderOf (entry) * 2) + 1;
51 
52    /*
53     * If the fieldWidth is a negative value, the fieldWidth will
54     * be COLS-fieldWidth, otherwise, the fieldWidth will be the
55     * given width.
56     */
57    fieldWidth = setWidgetDimension (parentWidth, fieldWidth, 0);
58    boxWidth = fieldWidth + 2 * BorderOf (entry);
59 
60    /* Set some basic values of the entry field. */
61    entry->label = 0;
62    entry->labelLen = 0;
63    entry->labelWin = 0;
64 
65    /* Translate the label char *pointer to a chtype pointer. */
66    if (label != 0)
67    {
68       entry->label = char2Chtype (label, &entry->labelLen, &junk);
69       boxWidth += entry->labelLen;
70    }
71 
72    oldWidth = boxWidth;
73    boxWidth = setCdkTitle (ObjOf (entry), title, boxWidth);
74    horizontalAdjust = (boxWidth - oldWidth) / 2;
75 
76    boxHeight += TitleLinesOf (entry);
77 
78    /*
79     * Make sure we didn't extend beyond the dimensions of the window.
80     */
81    boxWidth = MINIMUM (boxWidth, parentWidth);
82    boxHeight = MINIMUM (boxHeight, parentHeight);
83    fieldWidth = MINIMUM (fieldWidth,
84 			 boxWidth - entry->labelLen - 2 * BorderOf (entry));
85 
86    /* Rejustify the x and y positions if we need to. */
87    alignxy (cdkscreen->window, &xpos, &ypos, boxWidth, boxHeight);
88 
89    /* Make the label window. */
90    entry->win = newwin (boxHeight, boxWidth, ypos, xpos);
91    if (entry->win == 0)
92    {
93       destroyCDKObject (entry);
94       return (0);
95    }
96    keypad (entry->win, TRUE);
97 
98    /* Make the field window. */
99    entry->fieldWin = subwin (entry->win, 1, fieldWidth,
100 			     (ypos + TitleLinesOf (entry) + BorderOf (entry)),
101 			     (xpos + entry->labelLen
102 			      + horizontalAdjust
103 			      + BorderOf (entry)));
104    if (entry->fieldWin == 0)
105    {
106       destroyCDKObject (entry);
107       return (0);
108    }
109    keypad (entry->fieldWin, TRUE);
110 
111    /* Make the label win, if we need to. */
112    if (label != 0)
113    {
114       entry->labelWin = subwin (entry->win, 1, entry->labelLen,
115 				ypos + TitleLinesOf (entry) + BorderOf (entry),
116 				xpos + horizontalAdjust + BorderOf (entry));
117    }
118 
119    /* Make room for the info char * pointer. */
120    entry->info = typeMallocN (char, max + 3);
121    if (entry->info == 0)
122    {
123       destroyCDKObject (entry);
124       return (0);
125    }
126    cleanChar (entry->info, max + 3, '\0');
127    entry->infoWidth = max + 3;
128 
129    /* *INDENT-EQLS* Set up the rest of the structure. */
130    ScreenOf (entry)             = cdkscreen;
131    entry->parent                = cdkscreen->window;
132    entry->shadowWin             = 0;
133    entry->fieldAttr             = fieldAttr;
134    entry->fieldWidth            = fieldWidth;
135    entry->filler                = filler;
136    entry->hidden                = filler;
137    ObjOf (entry)->inputWindow   = entry->fieldWin;
138    ObjOf (entry)->acceptsFocus  = TRUE;
139    ReturnOf (entry)             = NULL;
140    entry->shadow                = shadow;
141    entry->screenCol             = 0;
142    entry->leftChar              = 0;
143    entry->min                   = min;
144    entry->max                   = max;
145    entry->boxWidth              = boxWidth;
146    entry->boxHeight             = boxHeight;
147    initExitType (entry);
148    entry->dispType              = dispType;
149    entry->callbackfn            = CDKEntryCallBack;
150 
151    /* Do we want a shadow? */
152    if (shadow)
153    {
154       entry->shadowWin = newwin (
155 				   boxHeight,
156 				   boxWidth,
157 				   ypos + 1,
158 				   xpos + 1);
159    }
160 
161    registerCDKObject (cdkscreen, vENTRY, entry);
162 
163    return (entry);
164 }
165 
166 /*
167  * This means you want to use the given entry field. It takes input
168  * from the keyboard, and when its done, it fills the entry info
169  * element of the structure with what was typed.
170  */
activateCDKEntry(CDKENTRY * entry,chtype * actions)171 char *activateCDKEntry (CDKENTRY *entry, chtype *actions)
172 {
173    chtype input = 0;
174    boolean functionKey;
175    char *ret = 0;
176 
177    /* Draw the widget. */
178    drawCDKEntry (entry, ObjOf (entry)->box);
179 
180    if (actions == 0)
181    {
182       for (;;)
183       {
184 	 input = (chtype)getchCDKObject (ObjOf (entry), &functionKey);
185 
186 	 /* Inject the character into the widget. */
187 	 ret = injectCDKEntry (entry, input);
188 	 if (entry->exitType != vEARLY_EXIT)
189 	 {
190 	    return ret;
191 	 }
192       }
193    }
194    else
195    {
196       int length = chlen (actions);
197       int x;
198 
199       /* Inject each character one at a time. */
200       for (x = 0; x < length; x++)
201       {
202 	 ret = injectCDKEntry (entry, actions[x]);
203 	 if (entry->exitType != vEARLY_EXIT)
204 	 {
205 	    return ret;
206 	 }
207       }
208    }
209 
210    /* Make sure we return the correct info. */
211    if (entry->exitType == vNORMAL)
212    {
213       return entry->info;
214    }
215    else
216    {
217       return 0;
218    }
219 }
220 
setPositionToEnd(CDKENTRY * entry)221 static void setPositionToEnd (CDKENTRY *entry)
222 {
223    int stringLen;
224 
225    stringLen = (int)utf8strlen (entry->info);
226    if (stringLen >= entry->fieldWidth)
227    {
228       if (stringLen < entry->max)
229       {
230 	 int charCount = entry->fieldWidth - 1;
231 	 entry->leftChar = stringLen - charCount; // horizontal scrolling with UTF8 does not work
232 	 entry->screenCol = charCount;
233       }
234       else
235       {
236 	 entry->leftChar = stringLen - entry->fieldWidth;
237 	 entry->screenCol = stringLen - 1;
238       }
239    }
240    else
241    {
242       entry->leftChar = 0;
243       entry->screenCol = stringLen;
244    }
245 }
246 
isUtf8CharPart(unsigned int ch)247 static inline int isUtf8CharPart(unsigned int ch) { return (ch >= 0x80) && (ch < 0xc0); }
248 
249 /*
250  * This injects a single character into the widget.
251  */
_injectCDKEntry(CDKOBJS * object,chtype input)252 static int _injectCDKEntry (CDKOBJS *object, chtype input)
253 {
254    CDKENTRY *widget = (CDKENTRY *)object;
255    int ppReturn = 1;
256    char *ret = unknownString;
257    bool complete = FALSE;
258 
259    /* Set the exit type. */
260    setExitType (widget, 0);
261 
262    /* Refresh the widget field. */
263    drawCDKEntryField (widget);
264 
265    /* Check if there is a pre-process function to be called. */
266    if (PreProcessFuncOf (widget) != 0)
267    {
268       ppReturn = PreProcessFuncOf (widget) (vENTRY,
269 					    widget,
270 					    PreProcessDataOf (widget),
271 					    input);
272    }
273 
274    /* Should we continue? */
275    if (ppReturn != 0)
276    {
277       /* Check a predefined binding... */
278       if (checkCDKObjectBind (vENTRY, widget, input) != 0)
279       {
280 	 checkEarlyExit (widget);
281 	 complete = TRUE;
282       }
283       else
284       {
285 	 int infoLength = (int)strlen (widget->info);
286 	 int currPos = utf8charpos (widget->info, widget->screenCol) + widget->leftChar;
287 
288 	 switch (input)
289 	 {
290 	 case KEY_UP:
291 	 case KEY_DOWN:
292 	    Beep ();
293 	    break;
294 
295 	 case KEY_HOME:
296 	    widget->leftChar = 0;
297 	    widget->screenCol = 0;
298 	    drawCDKEntryField (widget);
299 	    break;
300 
301 	 case CDK_TRANSPOSE:
302 	    if (currPos >= infoLength - 1)
303 	    {
304 	       Beep ();
305 	    }
306 	    else
307 	    {
308 	       char holder = widget->info[currPos];
309 	       widget->info[currPos] = widget->info[currPos + 1];
310 	       widget->info[currPos + 1] = holder;
311 	       drawCDKEntryField (widget);
312 	    }
313 	    break;
314 
315 	 case KEY_END:
316 	    setPositionToEnd (widget);
317 	    drawCDKEntryField (widget);
318 	    break;
319 
320 	 case KEY_LEFT:
321 	    if (currPos <= 0)
322 	    {
323 	       Beep ();
324 	    }
325 	    else if (widget->screenCol == 0)
326 	    {
327 	       /* Scroll left.  */
328 	       widget->leftChar--;
329 	       drawCDKEntryField (widget);
330 	    }
331 	    else
332 	    {
333 	       wmove (widget->fieldWin, 0, --widget->screenCol);
334 	       drawCDKEntryField (widget);
335 	    }
336 	    break;
337 
338 	 case KEY_RIGHT:
339 	    if (currPos >= infoLength)
340 	    {
341 	       Beep ();
342 	    }
343 	    else if (widget->screenCol == widget->fieldWidth - 1)
344 	    {
345 	       /* Scroll to the right. */
346 	       widget->leftChar++;
347 	       drawCDKEntryField (widget);
348 	    }
349 	    else
350 	    {
351 	       /* Move right. */
352 	       wmove (widget->fieldWin, 0, ++widget->screenCol);
353 	       drawCDKEntryField (widget);
354 	    }
355 	    break;
356 
357 	 case KEY_BACKSPACE:
358 	 case KEY_DC:
359 	    if (widget->dispType == vVIEWONLY)
360 	    {
361 	       Beep ();
362 	    }
363 	    else
364 	    {
365 	       bool success = FALSE;
366 
367 	       if (input == KEY_BACKSPACE)
368 	       {
369 		  while (currPos >= 1 && isUtf8CharPart(CharOf(widget->info[currPos - 1]))) currPos--;
370 		  --currPos;
371 	       }
372 
373 	       if (currPos >= 0 && infoLength > 0)
374 	       {
375 		  if (currPos < infoLength)
376 		  {
377 		     int x;
378 
379 		     int len = utf8charlen(widget->info[currPos]);
380 		     for (x = currPos; x < infoLength; x++)
381 		     {
382 			widget->info[x] = widget->info[x + len];
383 		     }
384 		     success = TRUE;
385 		  }
386 		  else if (input == KEY_BACKSPACE)
387 		  {
388 		     while (infoLength >= 1 && isUtf8CharPart(CharOf(widget->info[infoLength - 1]))) infoLength--;
389 		     widget->info[infoLength - 1] = '\0';
390 		     success = TRUE;
391 		  }
392 	       }
393 
394 	       if (success)
395 	       {
396 		  if (input == KEY_BACKSPACE)
397 		  {
398 		     if (widget->screenCol > 0)
399 			widget->screenCol--;
400 		     else
401 			widget->leftChar--;
402 		  }
403 
404 		  drawCDKEntryField (widget);
405 	       }
406 	       else
407 	       {
408 		  Beep ();
409 	       }
410 	    }
411 	    break;
412 
413 	 case KEY_ESC:
414 	    setExitType (widget, input);
415 	    complete = TRUE;
416 	    break;
417 
418 	 case CDK_ERASE:
419 	    if (infoLength != 0)
420 	    {
421 	       cleanCDKEntry (widget);
422 	       drawCDKEntryField (widget);
423 	    }
424 	    break;
425 
426 	 case CDK_CUT:
427 	    if (infoLength != 0)
428 	    {
429 	       freeChar (GPasteBuffer);
430 	       GPasteBuffer = copyChar (widget->info);
431 	       cleanCDKEntry (widget);
432 	       drawCDKEntryField (widget);
433 	    }
434 	    else
435 	    {
436 	       Beep ();
437 	    }
438 	    break;
439 
440 	 case CDK_COPY:
441 	    if (infoLength != 0)
442 	    {
443 	       freeChar (GPasteBuffer);
444 	       GPasteBuffer = copyChar (widget->info);
445 	    }
446 	    else
447 	    {
448 	       Beep ();
449 	    }
450 	    break;
451 
452 	 case CDK_PASTE:
453 	    if (GPasteBuffer != 0)
454 	    {
455 	       setCDKEntryValue (widget, GPasteBuffer);
456 	       drawCDKEntryField (widget);
457 	    }
458 	    else
459 	    {
460 	       Beep ();
461 	    }
462 	    break;
463 
464 	 case KEY_TAB:
465 	 case KEY_ENTER:
466 	    if (infoLength >= widget->min)
467 	    {
468 	       setExitType (widget, input);
469 	       ret = (widget->info);
470 	       complete = TRUE;
471 	    }
472 	    else
473 	    {
474 	       Beep ();
475 	    }
476 	    break;
477 
478 	 case KEY_ERROR:
479 	    setExitType (widget, input);
480 	    complete = TRUE;
481 	    break;
482 
483 	 case CDK_REFRESH:
484 	    eraseCDKScreen (ScreenOf (widget));
485 	    refreshCDKScreen (ScreenOf (widget));
486 	    break;
487 
488 	 default:
489 	    (widget->callbackfn) (widget, input);
490 	    break;
491 	 }
492       }
493 
494       /* Should we do a post-process? */
495       if (!complete && (PostProcessFuncOf (widget) != 0))
496       {
497 	 PostProcessFuncOf (widget) (vENTRY,
498 				     widget,
499 				     PostProcessDataOf (widget),
500 				     input);
501       }
502    }
503 
504    if (!complete)
505       setExitType (widget, 0);
506 
507    ResultOf (widget).valueString = ret;
508    return (ret != unknownString);
509 }
510 
511 /*
512  * This moves the entry field to the given location.
513  */
_moveCDKEntry(CDKOBJS * object,int xplace,int yplace,boolean relative,boolean refresh_flag)514 static void _moveCDKEntry (CDKOBJS *object,
515 			   int xplace,
516 			   int yplace,
517 			   boolean relative,
518 			   boolean refresh_flag)
519 {
520    /* *INDENT-EQLS* */
521    CDKENTRY *entry = (CDKENTRY *)object;
522    int currentX    = getbegx (entry->win);
523    int currentY    = getbegy (entry->win);
524    int xpos        = xplace;
525    int ypos        = yplace;
526    int xdiff       = 0;
527    int ydiff       = 0;
528 
529    /*
530     * If this is a relative move, then we will adjust where we want
531     * to move to.
532     */
533    if (relative)
534    {
535       xpos = getbegx (entry->win) + xplace;
536       ypos = getbegy (entry->win) + yplace;
537    }
538 
539    /* Adjust the window if we need to. */
540    alignxy (WindowOf (entry), &xpos, &ypos, entry->boxWidth, entry->boxHeight);
541 
542    /* Get the difference. */
543    xdiff = currentX - xpos;
544    ydiff = currentY - ypos;
545 
546    /* Move the window to the new location. */
547    moveCursesWindow (entry->win, -xdiff, -ydiff);
548    moveCursesWindow (entry->fieldWin, -xdiff, -ydiff);
549    moveCursesWindow (entry->labelWin, -xdiff, -ydiff);
550    moveCursesWindow (entry->shadowWin, -xdiff, -ydiff);
551 
552    /* Touch the windows so they 'move'. */
553    refreshCDKWindow (WindowOf (entry));
554 
555    /* Redraw the window, if they asked for it. */
556    if (refresh_flag)
557    {
558       drawCDKEntry (entry, ObjOf (entry)->box);
559    }
560 }
561 
toutf8(int code,char * s,int * len)562 static void toutf8(int code, char *s, int *len) {
563   int b;
564   if (code < 0x80) *len = 1;
565   else if (code < 0x800) *len = 2;
566   else if (code < 0x10000) *len = 3;
567   else if (code < 0x200000) *len = 4;
568   else if (code < 0x4000000) *len = 5;
569   else *len = 6;
570   for (b = *len - 1; b > 0; b--) s[b] = 0x80 | (code & 0x3F), code >>= 6;
571   if (*len == 1) s[0] = code & 0x7F;
572   else if (*len == 2) s[0] = 0xC0 | (code & 0x1F);
573   else if (*len == 3) s[0] = 0xE0 | (code & 0x0F);
574   else if (*len == 4) s[0] = 0xF0 | (code & 0x07);
575   else if (*len == 5) s[0] = 0xF8 | (code & 0x03);
576   else if (*len == 6) s[0] = 0xFC | (code & 0x01);
577 }
578 
579 /*
580  * This is a generic character parser for the entry field. It is used as a
581  * callback function, so any personal modifications can be made by creating
582  * a new function and calling the activation with its name.
583  */
CDKEntryCallBack(CDKENTRY * entry,chtype character)584 static void CDKEntryCallBack (CDKENTRY *entry, chtype character)
585 {
586    int plainchar = character;
587    char utf8[6];
588    int len;
589 
590    if (plainchar == ERR ||
591        ((int)utf8strlen (entry->info) >= entry->max))
592    {
593       Beep ();
594    }
595    else
596    {
597       toutf8(plainchar, utf8, &len);
598       /* Update the screen and pointer. */
599       if (entry->screenCol != entry->fieldWidth - 1)
600       {
601 	 int x;
602 	 int pos = utf8charpos (entry->info, entry->screenCol) + entry->leftChar;
603 
604 	 for (x = (int)strlen (entry->info) + len - 1;
605 	      x > pos + len - 1;
606 	      x--)
607 	 {
608 	    entry->info[x] = entry->info[x - len];
609 	 }
610 	 strncpy(entry->info + pos, utf8, len);
611 	 entry->screenCol++;
612       }
613       else
614       {
615 	 /* Update the character pointer. */
616 	 size_t temp = strlen (entry->info);
617 	 strncpy(entry->info + temp, utf8, len);
618 	 entry->info[temp + len] = '\0';
619 	 /* Do not update the pointer if it's the last character */
620 	 if ((int)(temp + len + 1) < entry->max)
621 	    entry->leftChar++;
622       }
623 
624       /* Update the entry field. */
625       drawCDKEntryField (entry);
626    }
627 }
628 
629 /*
630  * This erases the information in the entry field
631  * and redraws a clean and empty entry field.
632  */
cleanCDKEntry(CDKENTRY * entry)633 void cleanCDKEntry (CDKENTRY *entry)
634 {
635    int width = entry->fieldWidth;
636 
637    /* Erase the information in the character pointer. */
638    cleanChar (entry->info, entry->infoWidth, '\0');
639 
640    /* Clean the entry screen field. */
641    (void)mvwhline (entry->fieldWin, 0, 0, entry->filler, width);
642 
643    /* Reset some variables. */
644    entry->screenCol = 0;
645    entry->leftChar = 0;
646 
647    /* Refresh the entry field. */
648    wrefresh (entry->fieldWin);
649 }
650 
651 /*
652  * This draws the entry field.
653  */
_drawCDKEntry(CDKOBJS * object,boolean Box)654 static void _drawCDKEntry (CDKOBJS *object, boolean Box)
655 {
656    CDKENTRY *entry = (CDKENTRY *)object;
657 
658    /* Did we ask for a shadow? */
659    if (entry->shadowWin != 0)
660    {
661       drawShadow (entry->shadowWin);
662    }
663 
664    /* Box the widget if asked. */
665    if (Box)
666    {
667       drawObjBox (entry->win, ObjOf (entry));
668    }
669 
670    drawCdkTitle (entry->win, object);
671 
672    wrefresh (entry->win);
673 
674    /* Draw in the label to the widget. */
675    if (entry->labelWin != 0)
676    {
677       writeChtype (entry->labelWin, 0, 0, entry->label, HORIZONTAL, 0, entry->labelLen);
678       wrefresh (entry->labelWin);
679    }
680 
681    drawCDKEntryField (entry);
682 }
683 
684 /*
685  * This redraws the entry field.
686  */
drawCDKEntryField(CDKENTRY * entry)687 static void drawCDKEntryField (CDKENTRY *entry)
688 {
689    int x = 0;
690    char *p;
691    int charlen;
692 
693    /* Set background color and attributes of the entry field */
694    wbkgd (entry->fieldWin, entry->fieldAttr);
695 
696    /* Draw in the filler characters. */
697    (void)mvwhline (entry->fieldWin, 0, x, entry->filler | entry->fieldAttr, entry->fieldWidth);
698 
699    /* If there is information in the field. Then draw it in. */
700    if (entry->info != 0)
701    {
702       int infoLength = (int)utf8strlen (entry->info);
703 
704       /* Redraw the field. */
705       if (isHiddenDisplayType (entry->dispType))
706       {
707 	 for (x = entry->leftChar; x < infoLength; x++)
708 	 {
709 	    (void)mvwaddch (entry->fieldWin, 0, x - entry->leftChar,
710 			    entry->hidden | entry->fieldAttr);
711 	 }
712       }
713       else
714       {
715 	 p = entry->info + entry->leftChar;
716 	 for (x = entry->leftChar; x < infoLength; x++, p+=charlen)
717 	 {
718 	    charlen = utf8charlen(CharOf (*p));
719 	    (void)mvwaddnstr (entry->fieldWin, 0, x - entry->leftChar,
720 			    (const char *)p, charlen);
721 	 }
722       }
723       wmove (entry->fieldWin, 0, entry->screenCol);
724    }
725 
726    wrefresh (entry->fieldWin);
727 }
728 
729 /*
730  * This erases an entry widget from the screen.
731  */
_eraseCDKEntry(CDKOBJS * object)732 static void _eraseCDKEntry (CDKOBJS *object)
733 {
734    if (validCDKObject (object))
735    {
736       CDKENTRY *entry = (CDKENTRY *)object;
737 
738       eraseCursesWindow (entry->fieldWin);
739       eraseCursesWindow (entry->labelWin);
740       eraseCursesWindow (entry->win);
741       eraseCursesWindow (entry->shadowWin);
742    }
743 }
744 
745 /*
746  * This destroys an entry widget.
747  */
_destroyCDKEntry(CDKOBJS * object)748 static void _destroyCDKEntry (CDKOBJS *object)
749 {
750    if (object != 0)
751    {
752       CDKENTRY *entry = (CDKENTRY *)object;
753 
754       cleanCdkTitle (object);
755       freeChtype (entry->label);
756       freeChar (entry->info);
757 
758       /* Delete the windows. */
759       deleteCursesWindow (entry->fieldWin);
760       deleteCursesWindow (entry->labelWin);
761       deleteCursesWindow (entry->shadowWin);
762       deleteCursesWindow (entry->win);
763 
764       /* Clean the key bindings. */
765       cleanCDKObjectBindings (vENTRY, entry);
766 
767       /* Unregister this object. */
768       unregisterCDKObject (vENTRY, entry);
769    }
770 }
771 
772 /*
773  * This sets specific attributes of the entry field.
774  */
setCDKEntry(CDKENTRY * entry,const char * value,int min,int max,boolean Box GCC_UNUSED)775 void setCDKEntry (CDKENTRY *entry,
776 		  const char *value,
777 		  int min,
778 		  int max,
779 		  boolean Box GCC_UNUSED)
780 {
781    setCDKEntryValue (entry, value);
782    setCDKEntryMin (entry, min);
783    setCDKEntryMax (entry, max);
784 }
785 
786 /*
787  * This removes the old information in the entry field and keeps the
788  * new information given.
789  */
setCDKEntryValue(CDKENTRY * entry,const char * newValue)790 void setCDKEntryValue (CDKENTRY *entry, const char *newValue)
791 {
792    /* If the pointer sent in is the same pointer as before, do nothing. */
793    if (entry->info != newValue)
794    {
795       /* Just to be sure, if lets make sure the new value isn't null. */
796       if (newValue == 0)
797       {
798 	 /* Then we want to just erase the old value. */
799 	 cleanChar (entry->info, entry->infoWidth, '\0');
800 
801 	 /* Set the pointers back to zero. */
802 	 entry->leftChar = 0;
803 	 entry->screenCol = 0;
804       }
805       else
806       {
807 	 /* Determine how many characters we need to copy. */
808 	 int copychars = MINIMUM ((int)strlen (newValue), entry->max);
809 
810 	 /* OK, erase the old value, and copy in the new value. */
811 	 cleanChar (entry->info, entry->max, '\0');
812 	 strncpy (entry->info, newValue, (unsigned)copychars);
813 
814 	 setPositionToEnd (entry);
815       }
816    }
817 }
getCDKEntryValue(CDKENTRY * entry)818 char *getCDKEntryValue (CDKENTRY *entry)
819 {
820    return entry->info;
821 }
822 
823 /*
824  * This sets the maximum length of the string that will be accepted.
825  */
setCDKEntryMax(CDKENTRY * entry,int max)826 void setCDKEntryMax (CDKENTRY *entry, int max)
827 {
828    entry->max = max;
829 }
getCDKEntryMax(CDKENTRY * entry)830 int getCDKEntryMax (CDKENTRY *entry)
831 {
832    return entry->max;
833 }
834 
835 /*
836  * This sets the minimum length of the string that will
837  * be accepted.
838  */
setCDKEntryMin(CDKENTRY * entry,int min)839 void setCDKEntryMin (CDKENTRY *entry, int min)
840 {
841    entry->min = min;
842 }
getCDKEntryMin(CDKENTRY * entry)843 int getCDKEntryMin (CDKENTRY *entry)
844 {
845    return entry->min;
846 }
847 
848 /*
849  * This sets the filler character to be used in the entry field.
850  */
setCDKEntryFillerChar(CDKENTRY * entry,chtype fillerCharacter)851 void setCDKEntryFillerChar (CDKENTRY *entry, chtype fillerCharacter)
852 {
853    entry->filler = fillerCharacter;
854 }
getCDKEntryFillerChar(CDKENTRY * entry)855 chtype getCDKEntryFillerChar (CDKENTRY *entry)
856 {
857    return entry->filler;
858 }
859 
860 /*
861  * This sets the character to use when a hidden type is used.
862  */
setCDKEntryHiddenChar(CDKENTRY * entry,chtype hiddenCharacter)863 void setCDKEntryHiddenChar (CDKENTRY *entry, chtype hiddenCharacter)
864 {
865    entry->hidden = hiddenCharacter;
866 }
getCDKEntryHiddenChar(CDKENTRY * entry)867 chtype getCDKEntryHiddenChar (CDKENTRY *entry)
868 {
869    return entry->hidden;
870 }
871 
872 /*
873  * This sets the widgets box attribute.
874  */
setCDKEntryBox(CDKENTRY * entry,boolean Box)875 void setCDKEntryBox (CDKENTRY *entry, boolean Box)
876 {
877    ObjOf (entry)->box = Box;
878    ObjOf (entry)->borderSize = Box ? 1 : 0;
879 }
getCDKEntryBox(CDKENTRY * entry)880 boolean getCDKEntryBox (CDKENTRY *entry)
881 {
882    return ObjOf (entry)->box;
883 }
884 
885 /*
886  * This sets the background attribute of the widget.
887  */
_setBKattrEntry(CDKOBJS * object,chtype attrib)888 static void _setBKattrEntry (CDKOBJS *object, chtype attrib)
889 {
890    if (object != 0)
891    {
892       CDKENTRY *widget = (CDKENTRY *)object;
893 
894       wbkgd (widget->win, attrib);
895       wbkgd (widget->fieldWin, attrib);
896       if (widget->labelWin != 0)
897       {
898 	 wbkgd (widget->labelWin, attrib);
899       }
900    }
901 }
902 
903 /*
904  * This sets the attribute of the entry field.
905  */
setCDKEntryHighlight(CDKENTRY * entry,chtype highlight,boolean cursor)906 void setCDKEntryHighlight (CDKENTRY *entry, chtype highlight, boolean cursor)
907 {
908    wbkgd (entry->fieldWin, highlight);
909    entry->fieldAttr = highlight;
910    curs_set (cursor);
911    /*
912     *  FIXME -  if (cursor) { move the cursor to this widget }
913     */
914 }
915 
916 /*
917  * This sets the entry field callback function.
918  */
setCDKEntryCB(CDKENTRY * entry,ENTRYCB callback)919 void setCDKEntryCB (CDKENTRY *entry, ENTRYCB callback)
920 {
921    entry->callbackfn = callback;
922 }
923 
_focusCDKEntry(CDKOBJS * object)924 static void _focusCDKEntry (CDKOBJS *object)
925 {
926    CDKENTRY *entry = (CDKENTRY *)object;
927 
928    wmove (entry->fieldWin, 0, entry->screenCol);
929    wrefresh (entry->fieldWin);
930 }
931 
_unfocusCDKEntry(CDKOBJS * object)932 static void _unfocusCDKEntry (CDKOBJS *object)
933 {
934    CDKENTRY *entry = (CDKENTRY *)object;
935 
936    drawCDKEntry (entry, ObjOf (entry)->box);
937    wrefresh (entry->fieldWin);
938 }
939 
940 #if 0
941 static void _refreshDataCDKEntry (CDKOBJS *object)
942 {
943    CDKENTRY *entry = (CDKENTRY *)object;
944 
945    if (ReturnOf (entry))
946    {
947       switch (DataTypeOf (entry))
948       {
949       default:
950       case DataTypeString:
951 	 strcpy (entry->info, (char *)ReturnOf (entry));
952 	 break;
953       case DataTypeInt:
954 	 sprintf (entry->info, "%d", *((int *)ReturnOf (entry)));
955 	 break;
956       case DataTypeFloat:
957 	 sprintf (entry->info, "%g", *((float *)ReturnOf (entry)));
958 	 break;
959       case DataTypeDouble:
960 	 sprintf (entry->info, "%g", *((double *)ReturnOf (entry)));
961 	 break;
962       }
963       entry->screenCol = strlen (entry->info);
964       drawCDKEntryField (entry);
965    }
966 }
967 
968 static void _saveDataCDKEntry (CDKOBJS *object)
969 {
970    CDKENTRY *entry = (CDKENTRY *)object;
971 
972    if (ReturnOf (entry))
973    {
974       switch (DataTypeOf (entry))
975       {
976       default:
977       case DataTypeString:
978 	 strcpy ((char *)ReturnOf (entry), entry->info);
979 	 break;
980       case DataTypeInt:
981 	 *((int *)ReturnOf (entry)) = atoi (entry->info);
982 	 break;
983       case DataTypeFloat:
984 	 *((float *)ReturnOf (entry)) = atof (entry->info);
985 	 break;
986       case DataTypeDouble:
987 	 *((double *)ReturnOf (entry)) = atof (entry->info);
988 	 break;
989       }
990    }
991 }
992 #else
993 dummyRefreshData (Entry)
994 dummySaveData (Entry)
995 #endif
996