1 #include <cdk_int.h>
2 
3 /*
4  * $Author: tom $
5  * $Date: 2016/11/20 20:13:16 $
6  * $Revision: 1.142 $
7  */
8 
9 /*
10  * Declare file local prototypes.
11  */
12 static void CDKTemplateCallBack (CDKTEMPLATE *widget, chtype input);
13 static void drawCDKTemplateField (CDKTEMPLATE *widget);
14 static void adjustCDKTemplateCursor (CDKTEMPLATE *widget, int direction);
15 
16 #define isPlateChar(c) ((c) != 0 && strchr ("#ACcMXz", c) != 0)
17 
18 DeclareCDKObjects (TEMPLATE, Template, setCdk, String);
19 
20 /*
21  * This creates a cdktemplate widget.
22  */
newCDKTemplate(CDKSCREEN * cdkscreen,int xplace,int yplace,const char * title,const char * label,const char * plate,const char * Overlay,boolean Box,boolean shadow)23 CDKTEMPLATE *newCDKTemplate (CDKSCREEN *cdkscreen,
24 			     int xplace,
25 			     int yplace,
26 			     const char *title,
27 			     const char *label,
28 			     const char *plate,
29 			     const char *Overlay,
30 			     boolean Box,
31 			     boolean shadow)
32 {
33    /* *INDENT-EQLS* */
34    CDKTEMPLATE *cdktemplate     = 0;
35    int parentWidth              = getmaxx (cdkscreen->window);
36    int parentHeight             = getmaxy (cdkscreen->window);
37    int boxWidth                 = 0;
38    int boxHeight                = Box ? 3 : 1;
39    int xpos                     = xplace;
40    int ypos                     = yplace;
41    int horizontalAdjust, oldWidth;
42    int fieldWidth               = 0;
43    int plateLen                 = 0;
44    int junk                     = 0;
45 
46    if (plate == 0
47        || (cdktemplate = newCDKObject (CDKTEMPLATE, &my_funcs)) == 0)
48         return (0);
49 
50    setCDKTemplateBox (cdktemplate, Box);
51 
52    fieldWidth = (int)strlen (plate) + 2 * BorderOf (cdktemplate);
53 
54    /* *INDENT-EQLS* Set some basic values of the cdktemplate field. */
55    cdktemplate->label     = 0;
56    cdktemplate->labelLen  = 0;
57    cdktemplate->labelWin  = 0;
58 
59    /* Translate the char * label to a chtype * */
60    if (label != 0)
61    {
62       cdktemplate->label = char2Chtype (label, &cdktemplate->labelLen, &junk);
63    }
64 
65    /* Translate the char * Overlay to a chtype * */
66    if (Overlay != 0)
67    {
68       cdktemplate->overlay = char2Chtype (Overlay, &cdktemplate->overlayLen, &junk);
69       cdktemplate->fieldAttr = cdktemplate->overlay[0] & A_ATTRIBUTES;
70    }
71    else
72    {
73       /* *INDENT-EQLS* */
74       cdktemplate->overlay      = 0;
75       cdktemplate->overlayLen   = 0;
76       cdktemplate->fieldAttr    = A_NORMAL;
77    }
78 
79    /* Set the box width. */
80    boxWidth = fieldWidth + cdktemplate->labelLen + 2 * BorderOf (cdktemplate);
81 
82    oldWidth = boxWidth;
83    boxWidth = setCdkTitle (ObjOf (cdktemplate), title, boxWidth);
84    horizontalAdjust = (boxWidth - oldWidth) / 2;
85 
86    boxHeight += TitleLinesOf (cdktemplate);
87 
88    /*
89     * Make sure we didn't extend beyond the dimensions of the window.
90     */
91    /* *INDENT-EQLS* */
92    boxWidth   = MINIMUM (boxWidth, parentWidth);
93    boxHeight  = MINIMUM (boxHeight, parentHeight);
94    fieldWidth = MINIMUM (fieldWidth,
95 			 boxWidth   - cdktemplate->labelLen - 2 * BorderOf (cdktemplate));
96 
97    /* Rejustify the x and y positions if we need to. */
98    alignxy (cdkscreen->window, &xpos, &ypos, boxWidth, boxHeight);
99 
100    /* Make the cdktemplate window */
101    cdktemplate->win = newwin (boxHeight, boxWidth, ypos, xpos);
102 
103    /* Is the cdktemplate window null?? */
104    if (cdktemplate->win == 0)
105    {
106       destroyCDKObject (cdktemplate);
107       return (0);
108    }
109    keypad (cdktemplate->win, TRUE);
110 
111    /* Make the label window. */
112    if (cdktemplate->label != 0)
113    {
114       cdktemplate->labelWin = subwin (cdktemplate->win,
115 				      1, cdktemplate->labelLen,
116 				      (ypos +
117 				       TitleLinesOf (cdktemplate) +
118 				       BorderOf (cdktemplate)),
119 				      (xpos +
120 				       horizontalAdjust +
121 				       BorderOf (cdktemplate)));
122    }
123 
124    /* Make the field window. */
125    cdktemplate->fieldWin = subwin (cdktemplate->win,
126 				   1, fieldWidth,
127 				   (ypos +
128 				    TitleLinesOf (cdktemplate) +
129 				    BorderOf (cdktemplate)),
130 				   (xpos +
131 				    cdktemplate->labelLen +
132 				    horizontalAdjust +
133 				    BorderOf (cdktemplate)));
134    keypad (cdktemplate->fieldWin, TRUE);
135 
136    /* Set up the info field. */
137    cdktemplate->plateLen = (int)strlen (plate);
138    cdktemplate->info = typeCallocN (char, cdktemplate->plateLen + 2);
139    if (cdktemplate->info == 0)
140    {
141       destroyCDKObject (cdktemplate);
142       return (0);
143    }
144 
145    /* Copy the plate to the cdktemplate. */
146    plateLen = (int)strlen (plate);
147    cdktemplate->plate = typeMallocN (char, plateLen + 3);
148    if (cdktemplate->plate == 0)
149    {
150       destroyCDKObject (cdktemplate);
151       return (0);
152    }
153    strcpy (cdktemplate->plate, plate);
154 
155    /* *INDENT-EQLS* Set up the rest of the structure */
156    ScreenOf (cdktemplate)               = cdkscreen;
157    cdktemplate->parent                  = cdkscreen->window;
158    cdktemplate->shadowWin               = 0;
159    cdktemplate->fieldWidth              = fieldWidth;
160    cdktemplate->boxHeight               = boxHeight;
161    cdktemplate->boxWidth                = boxWidth;
162    cdktemplate->platePos                = 0;
163    cdktemplate->screenPos               = 0;
164    cdktemplate->infoPos                 = 0;
165    initExitType (cdktemplate);
166    cdktemplate->min                     = 0;
167    ObjOf (cdktemplate)->inputWindow     = cdktemplate->win;
168    ObjOf (cdktemplate)->acceptsFocus    = TRUE;
169    cdktemplate->shadow                  = shadow;
170    cdktemplate->callbackfn              = CDKTemplateCallBack;
171 
172    /* Do we need to create a shadow??? */
173    if (shadow)
174    {
175       cdktemplate->shadowWin = newwin (boxHeight, boxWidth, ypos + 1, xpos + 1);
176    }
177 
178    registerCDKObject (cdkscreen, vTEMPLATE, cdktemplate);
179 
180    return cdktemplate;
181 }
182 
183 /*
184  * This actually manages the cdktemplate widget...
185  */
activateCDKTemplate(CDKTEMPLATE * cdktemplate,chtype * actions)186 char *activateCDKTemplate (CDKTEMPLATE *cdktemplate, chtype *actions)
187 {
188    chtype input = 0;
189    boolean functionKey;
190    char *ret = 0;
191 
192    /* Draw the object. */
193    drawCDKTemplate (cdktemplate, ObjOf (cdktemplate)->box);
194 
195    if (actions == 0)
196    {
197       for (;;)
198       {
199 	 input = (chtype)getchCDKObject (ObjOf (cdktemplate), &functionKey);
200 
201 	 /* Inject the character into the widget. */
202 	 ret = injectCDKTemplate (cdktemplate, input);
203 	 if (cdktemplate->exitType != vEARLY_EXIT)
204 	 {
205 	    return ret;
206 	 }
207       }
208    }
209    else
210    {
211       int length = chlen (actions);
212       int x = 0;
213 
214       /* Inject each character one at a time. */
215       for (x = 0; x < length; x++)
216       {
217 	 ret = injectCDKTemplate (cdktemplate, actions[x]);
218 	 if (cdktemplate->exitType != vEARLY_EXIT)
219 	 {
220 	    return ret;
221 	 }
222       }
223    }
224 
225    /* Set the exit type and return. */
226    setExitType (cdktemplate, 0);
227    return ret;
228 }
229 
230 /*
231  * This injects a character into the widget.
232  */
_injectCDKTemplate(CDKOBJS * object,chtype input)233 static int _injectCDKTemplate (CDKOBJS *object, chtype input)
234 {
235    CDKTEMPLATE *widget = (CDKTEMPLATE *)object;
236    int ppReturn = 1;
237    char *ret = unknownString;
238    bool complete = FALSE;
239 
240    /* Set the exit type and return. */
241    setExitType (widget, 0);
242 
243    /* Move the cursor. */
244    drawCDKTemplateField (widget);
245 
246    /* Check if there is a pre-process function to be called. */
247    if (PreProcessFuncOf (widget) != 0)
248    {
249       ppReturn = PreProcessFuncOf (widget) (vTEMPLATE,
250 					    widget,
251 					    PreProcessDataOf (widget),
252 					    input);
253    }
254 
255    /* Should we continue? */
256    if (ppReturn != 0)
257    {
258       /* Check a predefined binding...  */
259       if (checkCDKObjectBind (vTEMPLATE, widget, input) != 0)
260       {
261 	 checkEarlyExit (widget);
262 	 complete = TRUE;
263       }
264       else
265       {
266 	 switch (input)
267 	 {
268 	 case CDK_ERASE:
269 	    if (strlen (widget->info) != 0)
270 	    {
271 	       cleanCDKTemplate (widget);
272 	       drawCDKTemplateField (widget);
273 	    }
274 	    break;
275 
276 	 case CDK_CUT:
277 	    if ((int)strlen (widget->info) != 0)
278 	    {
279 	       freeChar (GPasteBuffer);
280 	       GPasteBuffer = copyChar (widget->info);
281 	       cleanCDKTemplate (widget);
282 	       drawCDKTemplateField (widget);
283 	    }
284 	    else
285 	    {
286 	       Beep ();
287 	    }
288 	    break;
289 
290 	 case CDK_COPY:
291 	    if ((int)strlen (widget->info) != 0)
292 	    {
293 	       freeChar (GPasteBuffer);
294 	       GPasteBuffer = copyChar (widget->info);
295 	    }
296 	    else
297 	    {
298 	       Beep ();
299 	    }
300 	    break;
301 
302 	 case CDK_PASTE:
303 	    if (GPasteBuffer != 0)
304 	    {
305 	       int length, x;
306 
307 	       cleanCDKTemplate (widget);
308 
309 	       /* Start inserting each character one at a time. */
310 	       length = (int)strlen (GPasteBuffer);
311 	       for (x = 0; x < length; x++)
312 	       {
313 		  (widget->callbackfn) (widget, (chtype)GPasteBuffer[x]);
314 	       }
315 	       drawCDKTemplateField (widget);
316 	    }
317 	    else
318 	    {
319 	       Beep ();
320 	    }
321 	    break;
322 
323 	 case KEY_TAB:
324 	 case KEY_ENTER:
325 	    if ((int)strlen (widget->info) < (int)widget->min)
326 	    {
327 	       Beep ();
328 	    }
329 	    else
330 	    {
331 	       setExitType (widget, input);
332 	       ret = widget->info;
333 	       complete = TRUE;
334 	    }
335 	    break;
336 
337 	 case KEY_ESC:
338 	    setExitType (widget, input);
339 	    complete = TRUE;
340 	    break;
341 
342 	 case KEY_ERROR:
343 	    setExitType (widget, input);
344 	    complete = TRUE;
345 	    break;
346 
347 	 case CDK_REFRESH:
348 	    eraseCDKScreen (ScreenOf (widget));
349 	    refreshCDKScreen (ScreenOf (widget));
350 	    break;
351 
352 	 default:
353 	    (widget->callbackfn) (widget, input);
354 	    break;
355 	 }
356       }
357 
358       /* Should we call a post-process? */
359       if (!complete && (PostProcessFuncOf (widget) != 0))
360       {
361 	 PostProcessFuncOf (widget) (vTEMPLATE,
362 				     widget,
363 				     PostProcessDataOf (widget),
364 				     input);
365       }
366    }
367 
368    if (!complete)
369    {
370       setExitType (widget, 0);
371    }
372 
373    ResultOf (widget).valueString = ret;
374    return (ret != unknownString);
375 }
376 
377 /*
378  * Return true if the given string matches the template (may be incomplete).
379  */
validTemplate(CDKTEMPLATE * cdktemplate,char * input)380 static boolean validTemplate (CDKTEMPLATE *cdktemplate, char *input)
381 {
382    int pp, ip;
383    const char *plate = cdktemplate->plate;
384 
385    for (pp = 0, ip = 0; input[ip] != '\0' && plate[pp] != '\0'; ++ip, ++pp)
386    {
387       int newchar = input[ip];
388 
389       while (plate[pp] != '\0' && !isPlateChar (plate[pp]))
390       {
391 	 ++pp;
392       }
393       if (plate[pp] == 0)
394       {
395 	 return FALSE;
396       }
397 
398       /* check if the input matches the plate */
399       if (isdigit (CharOf (newchar)) &&
400 	  (plate[pp] == 'A' ||
401 	   plate[pp] == 'C' ||
402 	   plate[pp] == 'c'))
403       {
404 	 return FALSE;
405       }
406       if (!isdigit (CharOf (newchar)) &&
407 	  plate[pp] == '#')
408       {
409 	 return FALSE;
410       }
411 
412       /* Do we need to convert the case??? */
413       if (plate[pp] == 'C' ||
414 	  plate[pp] == 'X')
415       {
416 	 newchar = toupper (newchar);
417       }
418       else if (plate[pp] == 'c' ||
419 	       plate[pp] == 'x')
420       {
421 	 newchar = tolower (newchar);
422       }
423       input[ip] = (char)newchar;
424    }
425    return TRUE;
426 }
427 
428 /*
429  * This is the standard callback proc for the cdktemplate.
430  */
CDKTemplateCallBack(CDKTEMPLATE * cdktemplate,chtype input)431 static void CDKTemplateCallBack (CDKTEMPLATE *cdktemplate, chtype input)
432 {
433    boolean failed = FALSE;
434    boolean change = FALSE;
435    boolean moveby = FALSE;
436    int amount = 0;
437    size_t mark = (size_t) cdktemplate->infoPos;
438    size_t have = strlen (cdktemplate->info);
439 
440    if (input == KEY_LEFT)
441    {
442       if (mark != 0)
443       {
444 	 moveby = TRUE;
445 	 amount = -1;
446       }
447       else
448       {
449 	 failed = TRUE;
450       }
451    }
452    else if (input == KEY_RIGHT)
453    {
454       if (cdktemplate->info[mark] != '\0')
455       {
456 	 moveby = TRUE;
457 	 amount = 1;
458       }
459       else
460       {
461 	 failed = TRUE;
462       }
463    }
464    else
465    {
466       char *test = (char *)malloc (have + 2);
467 
468       if (test != 0)
469       {
470 	 strcpy (test, cdktemplate->info);
471 
472 	 if (input == KEY_BACKSPACE)
473 	 {
474 	    if (mark != 0)
475 	    {
476 	       strcpy (test + mark - 1, cdktemplate->info + mark);
477 	       change = TRUE;
478 	       amount = -1;
479 	    }
480 	    else
481 	    {
482 	       failed = TRUE;
483 	    }
484 	 }
485 	 else if (input == KEY_DC)
486 	 {
487 	    if (test[mark] != '\0')
488 	    {
489 	       strcpy (test + mark, cdktemplate->info + mark + 1);
490 	       change = TRUE;
491 	       amount = 0;
492 	    }
493 	    else
494 	    {
495 	       failed = TRUE;
496 	    }
497 	 }
498 	 else if (isChar (input) &&
499 		  cdktemplate->platePos < cdktemplate->fieldWidth)
500 	 {
501 	    test[mark] = (char)(input);
502 	    strcpy (test + mark + 1, cdktemplate->info + mark + 1);
503 	    change = TRUE;
504 	    amount = 1;
505 	 }
506 	 else
507 	 {
508 	    failed = TRUE;
509 	 }
510 
511 	 if (change)
512 	 {
513 	    if (validTemplate (cdktemplate, test))
514 	    {
515 	       strcpy (cdktemplate->info, test);
516 	       drawCDKTemplateField (cdktemplate);
517 	    }
518 	    else
519 	    {
520 	       failed = TRUE;
521 	    }
522 	 }
523 
524 	 free (test);
525       }
526    }
527 
528    if (failed)
529    {
530       Beep ();
531    }
532    else if (change || moveby)
533    {
534       cdktemplate->infoPos += amount;
535       cdktemplate->platePos += amount;
536       cdktemplate->screenPos += amount;
537 
538       adjustCDKTemplateCursor (cdktemplate, amount);
539    }
540 }
541 
542 /*
543  * Return a mixture of the plate-overlay and field-info.
544  */
mixCDKTemplate(CDKTEMPLATE * cdktemplate)545 char *mixCDKTemplate (CDKTEMPLATE *cdktemplate)
546 {
547    char *mixedString = 0;
548 
549    if (cdktemplate->info != 0 && cdktemplate->info[0] != '\0')
550    {
551       mixedString = typeCallocN (char, cdktemplate->plateLen + 3);
552 
553       if (mixedString != 0)
554       {
555 	 int infoPos = 0;
556 	 int platePos = 0;
557 
558 	 while (platePos < cdktemplate->plateLen)
559 	 {
560 	    mixedString[platePos] = (char)(isPlateChar (cdktemplate->plate[platePos])
561 					   ? cdktemplate->info[infoPos++]
562 					   : cdktemplate->plate[platePos]);
563 	    platePos++;
564 	 }
565       }
566    }
567 
568    return mixedString;
569 }
570 
571 /*
572  * Return the field-info from the mixed string.
573  */
unmixCDKTemplate(CDKTEMPLATE * cdktemplate,const char * info)574 char *unmixCDKTemplate (CDKTEMPLATE *cdktemplate, const char *info)
575 {
576    /* *INDENT-EQLS* */
577    int infolen          = (int)strlen (info);
578    char *unmixedString  = typeCallocN (char, infolen + 2);
579 
580    if (unmixedString != 0)
581    {
582       int pos = 0;
583       int x = 0;
584 
585       while (pos < infolen)
586       {
587 	 if (isPlateChar (cdktemplate->plate[pos]))
588 	 {
589 	    unmixedString[x++] = info[pos++];
590 	 }
591 	 else
592 	 {
593 	    pos++;
594 	 }
595       }
596    }
597 
598    return unmixedString;
599 }
600 
601 /*
602  * Move the cdktemplate field to the given location.
603  */
_moveCDKTemplate(CDKOBJS * object,int xplace,int yplace,boolean relative,boolean refresh_flag)604 static void _moveCDKTemplate (CDKOBJS *object,
605 			      int xplace,
606 			      int yplace,
607 			      boolean relative,
608 			      boolean refresh_flag)
609 {
610    CDKTEMPLATE *cdktemplate = (CDKTEMPLATE *)object;
611    /* *INDENT-EQLS* */
612    int currentX = getbegx (cdktemplate->win);
613    int currentY = getbegy (cdktemplate->win);
614    int xpos     = xplace;
615    int ypos     = yplace;
616    int xdiff    = 0;
617    int ydiff    = 0;
618 
619    /*
620     * If this is a relative move, then we will adjust where we want
621     * to move to.
622     */
623    if (relative)
624    {
625       xpos = getbegx (cdktemplate->win) + xplace;
626       ypos = getbegy (cdktemplate->win) + yplace;
627    }
628 
629    /* Adjust the window if we need to. */
630    alignxy (WindowOf (cdktemplate), &xpos, &ypos, cdktemplate->boxWidth, cdktemplate->boxHeight);
631 
632    /* Get the difference. */
633    xdiff = currentX - xpos;
634    ydiff = currentY - ypos;
635 
636    /* Move the window to the new location. */
637    moveCursesWindow (cdktemplate->win, -xdiff, -ydiff);
638    moveCursesWindow (cdktemplate->labelWin, -xdiff, -ydiff);
639    moveCursesWindow (cdktemplate->fieldWin, -xdiff, -ydiff);
640    moveCursesWindow (cdktemplate->shadowWin, -xdiff, -ydiff);
641 
642    /* Touch the windows so they 'move'. */
643    refreshCDKWindow (WindowOf (cdktemplate));
644 
645    /* Redraw the window, if they asked for it. */
646    if (refresh_flag)
647    {
648       drawCDKTemplate (cdktemplate, ObjOf (cdktemplate)->box);
649    }
650 }
651 
652 /*
653  * Draw the template widget.
654  */
_drawCDKTemplate(CDKOBJS * object,boolean Box)655 static void _drawCDKTemplate (CDKOBJS *object, boolean Box)
656 {
657    CDKTEMPLATE *cdktemplate = (CDKTEMPLATE *)object;
658 
659    /* Do we need to draw the shadow. */
660    if (cdktemplate->shadowWin != 0)
661    {
662       drawShadow (cdktemplate->shadowWin);
663    }
664 
665    /* Box it if needed */
666    if (Box)
667    {
668       drawObjBox (cdktemplate->win, ObjOf (cdktemplate));
669    }
670 
671    drawCdkTitle (cdktemplate->win, object);
672 
673    wrefresh (cdktemplate->win);
674 
675    drawCDKTemplateField (cdktemplate);
676 }
677 
678 /*
679  * Draw the cdktemplate field.
680  */
drawCDKTemplateField(CDKTEMPLATE * cdktemplate)681 static void drawCDKTemplateField (CDKTEMPLATE *cdktemplate)
682 {
683    /* *INDENT-EQLS* */
684    chtype fieldColor    = 0;
685    int infolen          = (int)strlen (cdktemplate->info);
686 
687    /* Draw in the label and the cdktemplate object. */
688    if (cdktemplate->labelWin != 0)
689    {
690       writeChtype (cdktemplate->labelWin, 0, 0,
691 		   cdktemplate->label,
692 		   HORIZONTAL, 0,
693 		   cdktemplate->labelLen);
694       wrefresh (cdktemplate->labelWin);
695    }
696 
697    /* Draw in the cdktemplate... */
698    if (cdktemplate->overlay != 0)
699    {
700       writeChtype (cdktemplate->fieldWin, 0, 0,
701 		   cdktemplate->overlay,
702 		   HORIZONTAL, 0,
703 		   cdktemplate->overlayLen);
704 
705       /* Adjust the cursor. */
706       if (infolen != 0)
707       {
708 	 int pos = 0;
709 	 int x = 0;
710 	 for (x = 0; x < cdktemplate->fieldWidth; x++)
711 	 {
712 	    if (isPlateChar (cdktemplate->plate[x]) && pos < infolen)
713 	    {
714 	       fieldColor = cdktemplate->overlay[x] & A_ATTRIBUTES;
715 	       (void)mvwaddch (cdktemplate->fieldWin,
716 			       0, x,
717 			       CharOf (cdktemplate->info[pos++]) | fieldColor);
718 	    }
719 	 }
720 	 wmove (cdktemplate->fieldWin, 0, cdktemplate->screenPos);
721       }
722       else
723       {
724 	 adjustCDKTemplateCursor (cdktemplate, +1);
725       }
726       wrefresh (cdktemplate->fieldWin);
727    }
728 }
729 
730 /*
731  * Adjust the cursor for the cdktemplate.
732  */
adjustCDKTemplateCursor(CDKTEMPLATE * cdktemplate,int direction)733 static void adjustCDKTemplateCursor (CDKTEMPLATE *cdktemplate, int direction)
734 {
735    while (!isPlateChar (cdktemplate->plate[cdktemplate->platePos])
736 	  && cdktemplate->platePos < cdktemplate->fieldWidth)
737    {
738       cdktemplate->platePos += direction;
739       cdktemplate->screenPos += direction;
740    }
741    wmove (cdktemplate->fieldWin, 0, cdktemplate->screenPos);
742    wrefresh (cdktemplate->fieldWin);
743 }
744 
745 /*
746  * Set the background attribute of the widget.
747  */
_setBKattrTemplate(CDKOBJS * object,chtype attrib)748 static void _setBKattrTemplate (CDKOBJS *object, chtype attrib)
749 {
750    if (object != 0)
751    {
752       CDKTEMPLATE *widget = (CDKTEMPLATE *)object;
753 
754       wbkgd (widget->win, attrib);
755       wbkgd (widget->fieldWin, attrib);
756       if (widget->labelWin != 0)
757       {
758 	 wbkgd (widget->labelWin, attrib);
759       }
760    }
761 }
762 
763 /*
764  * Destroy this widget.
765  */
_destroyCDKTemplate(CDKOBJS * object)766 static void _destroyCDKTemplate (CDKOBJS *object)
767 {
768    if (object != 0)
769    {
770       CDKTEMPLATE *cdktemplate = (CDKTEMPLATE *)object;
771 
772       cleanCdkTitle (object);
773       freeChtype (cdktemplate->label);
774       freeChtype (cdktemplate->overlay);
775       freeChar (cdktemplate->plate);
776       freeChar (cdktemplate->info);
777 
778       /* Delete the windows. */
779       deleteCursesWindow (cdktemplate->fieldWin);
780       deleteCursesWindow (cdktemplate->labelWin);
781       deleteCursesWindow (cdktemplate->shadowWin);
782       deleteCursesWindow (cdktemplate->win);
783 
784       /* Clean the key bindings. */
785       cleanCDKObjectBindings (vTEMPLATE, cdktemplate);
786 
787       unregisterCDKObject (vTEMPLATE, cdktemplate);
788    }
789 }
790 
791 /*
792  * Erase the widget.
793  */
_eraseCDKTemplate(CDKOBJS * object)794 static void _eraseCDKTemplate (CDKOBJS *object)
795 {
796    if (validCDKObject (object))
797    {
798       CDKTEMPLATE *cdktemplate = (CDKTEMPLATE *)object;
799 
800       eraseCursesWindow (cdktemplate->fieldWin);
801       eraseCursesWindow (cdktemplate->labelWin);
802       eraseCursesWindow (cdktemplate->win);
803       eraseCursesWindow (cdktemplate->shadowWin);
804    }
805 }
806 
807 /*
808  * Set the value given to the cdktemplate.
809  */
setCDKTemplate(CDKTEMPLATE * cdktemplate,const char * newValue,boolean Box)810 void setCDKTemplate (CDKTEMPLATE *cdktemplate, const char *newValue, boolean Box)
811 {
812    setCDKTemplateValue (cdktemplate, newValue);
813    setCDKTemplateBox (cdktemplate, Box);
814 }
815 
816 /*
817  * Set the value given to the cdktemplate.
818  */
setCDKTemplateValue(CDKTEMPLATE * cdktemplate,const char * newValue)819 void setCDKTemplateValue (CDKTEMPLATE *cdktemplate, const char *newValue)
820 {
821    /* *INDENT-EQLS* */
822    int len              = 0;
823    int copychars        = 0;
824    int x;
825 
826    cleanCDKTemplate (cdktemplate);
827 
828    /* Just to be sure, if let's make sure the new value isn't null. */
829    if (newValue == 0)
830    {
831       return;
832    }
833 
834    /* Determine how many characters we need to copy. */
835    len = (int)strlen (newValue);
836    copychars = MINIMUM (len, cdktemplate->fieldWidth);
837 
838    /* OK, erase the old value, and copy in the new value. */
839    cdktemplate->info[0] = '\0';
840    strncpy (cdktemplate->info, newValue, (size_t) copychars);
841 
842    /* Use the function which handles the input of the characters. */
843    for (x = 0; x < len; x++)
844    {
845       (cdktemplate->callbackfn) (cdktemplate, (chtype)newValue[x]);
846    }
847 }
getCDKTemplateValue(CDKTEMPLATE * cdktemplate)848 char *getCDKTemplateValue (CDKTEMPLATE *cdktemplate)
849 {
850    return cdktemplate->info;
851 }
852 
853 /*
854  * Set the minimum number of characters to enter into the widget.
855  */
setCDKTemplateMin(CDKTEMPLATE * cdktemplate,int min)856 void setCDKTemplateMin (CDKTEMPLATE *cdktemplate, int min)
857 {
858    if (min >= 0)
859    {
860       cdktemplate->min = min;
861    }
862 }
getCDKTemplateMin(CDKTEMPLATE * cdktemplate)863 int getCDKTemplateMin (CDKTEMPLATE *cdktemplate)
864 {
865    return cdktemplate->min;
866 }
867 
868 /*
869  * Set the box attribute of the cdktemplate widget.
870  */
setCDKTemplateBox(CDKTEMPLATE * cdktemplate,boolean Box)871 void setCDKTemplateBox (CDKTEMPLATE *cdktemplate, boolean Box)
872 {
873    ObjOf (cdktemplate)->box = Box;
874    ObjOf (cdktemplate)->borderSize = Box ? 1 : 0;
875 }
getCDKTemplateBox(CDKTEMPLATE * cdktemplate)876 boolean getCDKTemplateBox (CDKTEMPLATE *cdktemplate)
877 {
878    return ObjOf (cdktemplate)->box;
879 }
880 
881 /*
882  * Erase the information in the cdktemplate widget.
883  */
cleanCDKTemplate(CDKTEMPLATE * cdktemplate)884 void cleanCDKTemplate (CDKTEMPLATE *cdktemplate)
885 {
886    if (cdktemplate->fieldWidth > 0)
887       memset (cdktemplate->info, 0, (size_t) cdktemplate->fieldWidth);
888 
889    /* *INDENT-EQLS* */
890    cdktemplate->screenPos = 0;
891    cdktemplate->infoPos   = 0;
892    cdktemplate->platePos  = 0;
893 }
894 
895 /*
896  * Set the callback function for the widget.
897  */
setCDKTemplateCB(CDKTEMPLATE * cdktemplate,TEMPLATECB callback)898 void setCDKTemplateCB (CDKTEMPLATE *cdktemplate, TEMPLATECB callback)
899 {
900    cdktemplate->callbackfn = callback;
901 }
902 
_focusCDKTemplate(CDKOBJS * object)903 static void _focusCDKTemplate (CDKOBJS *object)
904 {
905    CDKTEMPLATE *widget = (CDKTEMPLATE *)object;
906 
907    drawCDKTemplate (widget, ObjOf (widget)->box);
908 }
909 
_unfocusCDKTemplate(CDKOBJS * object)910 static void _unfocusCDKTemplate (CDKOBJS *object)
911 {
912    CDKTEMPLATE *widget = (CDKTEMPLATE *)object;
913 
914    drawCDKTemplate (widget, ObjOf (widget)->box);
915 }
916 
917 dummyRefreshData (Template)
918 
919 dummySaveData (Template)
920