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