1 /* $Id: traverse_ex.c,v 1.26 2017/12/09 19:03:36 tom Exp $ */
2 
3 #include <cdk_test.h>
4 
5 #ifdef HAVE_XCURSES
6 char *XCursesProgramName = "entry_ex";
7 #endif
8 
9 #define NumElements(a) ((sizeof a)/(sizeof a[0]))
10 
11 #define MY_MAX 3
12 
13 static CDKOBJS *all_objects[MY_MAX];
14 
15 static const char *yes_no[] =
16 {
17    "Yes", "NO"
18 };
19 static const char *months[] =
20 {
21    "Jan", "Feb", "Mar", "Apr", "May", "Jun",
22    "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
23 };
24 static const char *choices[] =
25 {
26    "[ ]", "[*]"
27 };
28 
29 /*
30  * Exercise all widgets except
31  *	CDKMENU
32  * 	CDKTRAVERSE
33  * The names in parentheses do not accept input, so they will never have
34  * focus for traversal.  The names with leading "*" have some limitation
35  * that makes them not useful in traversal.
36  */
37 /* *INDENT-OFF* */
38 static const struct
39 {
40    const char *name;
41    EObjectType type;
42 }
43 menu_table[] =
44 {
45    { "(CDKGRAPH)",	vGRAPH },	/* no traversal (not active) */
46    { "(CDKHISTOGRAM)",	vHISTOGRAM },	/* no traversal (not active) */
47    { "(CDKLABEL)",	vLABEL },	/* no traversal (not active) */
48    { "(CDKMARQUEE)",	vMARQUEE },	/* hangs (leaves trash) */
49    { "*CDKVIEWER",	vVIEWER },	/* traversal out-only on OK */
50    { "CDKALPHALIST",	vALPHALIST },
51    { "CDKBUTTON",	vBUTTON },
52    { "CDKBUTTONBOX",	vBUTTONBOX },
53    { "CDKCALENDAR",	vCALENDAR },
54    { "CDKDIALOG",	vDIALOG },
55    { "CDKDSCALE",	vDSCALE },
56    { "CDKENTRY",	vENTRY },
57    { "CDKFSCALE",	vFSCALE },
58    { "CDKFSELECT",	vFSELECT },
59    { "CDKFSLIDER",	vFSLIDER },
60    { "CDKITEMLIST",	vITEMLIST },
61    { "CDKMATRIX",	vMATRIX },
62    { "CDKMENTRY",	vMENTRY },
63    { "CDKRADIO",	vRADIO },
64    { "CDKSCALE",	vSCALE },
65    { "CDKSCROLL",	vSCROLL },
66    { "CDKSELECTION",	vSELECTION },
67    { "CDKSLIDER",	vSLIDER },
68    { "CDKSWINDOW",	vSWINDOW },
69    { "CDKTEMPLATE",	vTEMPLATE },
70    { "CDKUSCALE",	vUSCALE },
71    { "CDKUSLIDER",	vUSLIDER },
72 };
73 /* *INDENT-ON* */
74 
make_alphalist(CDKSCREEN * cdkscreen,int x,int y)75 static CDKOBJS *make_alphalist (CDKSCREEN *cdkscreen, int x, int y)
76 {
77    CDKALPHALIST *widget = newCDKAlphalist (cdkscreen,
78 					   x, y, 10, 15,
79 					   "AlphaList",
80 					   "->",
81 					   (CDK_CSTRING *)months,
82 					   NumElements (months),
83 					   '_', A_REVERSE,
84 					   TRUE, FALSE);
85    return ObjPtr (widget);
86 }
87 
make_button(CDKSCREEN * cdkscreen,int x,int y)88 static CDKOBJS *make_button (CDKSCREEN *cdkscreen, int x, int y)
89 {
90    CDKBUTTON *widget = newCDKButton (cdkscreen, x, y,
91 				     "A Button!", NULL,
92 				     TRUE, FALSE);
93    return ObjPtr (widget);
94 }
95 
make_buttonbox(CDKSCREEN * cdkscreen,int x,int y)96 static CDKOBJS *make_buttonbox (CDKSCREEN *cdkscreen, int x, int y)
97 {
98    CDKBUTTONBOX *widget = newCDKButtonbox (cdkscreen, x, y,
99 					   10, 16,
100 					   "ButtonBox", 6, 2,
101 					   (CDK_CSTRING2)months,
102 					   NumElements (months),
103 					   A_REVERSE,
104 					   TRUE, FALSE);
105    return ObjPtr (widget);
106 }
107 
make_calendar(CDKSCREEN * cdkscreen,int x,int y)108 static CDKOBJS *make_calendar (CDKSCREEN *cdkscreen, int x, int y)
109 {
110    CDKCALENDAR *widget = newCDKCalendar (cdkscreen, x, y,
111 					 "Calendar", 25, 1, 2000,
112 					 COLOR_PAIR (16) | A_BOLD,
113 					 COLOR_PAIR (24) | A_BOLD,
114 					 COLOR_PAIR (32) | A_BOLD,
115 					 COLOR_PAIR (40) | A_REVERSE,
116 					 TRUE,
117 					 FALSE);
118    return ObjPtr (widget);
119 }
120 
make_dialog(CDKSCREEN * cdkscreen,int x,int y)121 static CDKOBJS *make_dialog (CDKSCREEN *cdkscreen, int x, int y)
122 {
123    static const char *message[] =
124    {
125       "This is a simple dialog box"
126       ,"Is it simple enough?"
127    };
128 
129    CDKDIALOG *widget = newCDKDialog (cdkscreen, x, y,
130 				     (CDK_CSTRING2)message, NumElements (message),
131 				     (CDK_CSTRING2)yes_no, NumElements (yes_no),
132 				     COLOR_PAIR (2) | A_REVERSE,
133 				     TRUE,
134 				     TRUE, FALSE);
135    return ObjPtr (widget);
136 }
137 
make_dscale(CDKSCREEN * cdkscreen,int x,int y)138 static CDKOBJS *make_dscale (CDKSCREEN *cdkscreen, int x, int y)
139 {
140    CDKDSCALE *widget = newCDKDScale (cdkscreen, x, y,
141 				     "DScale", "Value", A_NORMAL,
142 				     15,
143 				     0.0, 0.0, 100.0,
144 				     1.0, (1.0 * 2.), 1,
145 				     TRUE,
146 				     FALSE);
147    return ObjPtr (widget);
148 }
149 
make_entry(CDKSCREEN * cdkscreen,int x,int y)150 static CDKOBJS *make_entry (CDKSCREEN *cdkscreen, int x, int y)
151 {
152    CDKENTRY *widget = newCDKEntry (cdkscreen, x, y,
153 				   NULL, "Entry: ", A_NORMAL,
154 				   '.', vMIXED, 40, 0, 256, TRUE, FALSE);
155    return ObjPtr (widget);
156 }
157 
make_fscale(CDKSCREEN * cdkscreen,int x,int y)158 static CDKOBJS *make_fscale (CDKSCREEN *cdkscreen, int x, int y)
159 {
160    CDKFSCALE *widget = newCDKFScale (cdkscreen, x, y,
161 				     "FScale", "Value", A_NORMAL,
162 				     15,
163 				     0.0, 0.0, 100.0,
164 				     1.0, (1.0 * 2.), 1,
165 				     TRUE,
166 				     FALSE);
167    return ObjPtr (widget);
168 }
169 
make_fslider(CDKSCREEN * cdkscreen,int x,int y)170 static CDKOBJS *make_fslider (CDKSCREEN *cdkscreen, int x, int y)
171 {
172    float low = -32;
173    float high = 64;
174    float inc = (float)0.1;
175    CDKFSLIDER *widget = newCDKFSlider (cdkscreen,
176 				       x,
177 				       y,
178 				       "FSlider", "Label",
179 				       A_REVERSE | COLOR_PAIR (29) | ' ',
180 				       20,
181 				       low, low, high, inc, (inc * 2),
182 				       3,
183 				       TRUE,
184 				       FALSE);
185    /* selection = activateCDKSlider (widget, 0); */
186    return ObjPtr (widget);
187 }
188 
make_fselect(CDKSCREEN * cdkscreen,int x,int y)189 static CDKOBJS *make_fselect (CDKSCREEN *cdkscreen, int x, int y)
190 {
191    CDKFSELECT *widget = newCDKFselect (cdkscreen,
192 				       x,
193 				       y,
194 				       15,
195 				       25,
196 				       "FSelect", "->", A_NORMAL, '_', A_REVERSE,
197 				       "</5>", "</48>", "</N>", "</N>",
198 				       TRUE,
199 				       FALSE);
200    return ObjPtr (widget);
201 }
202 
make_graph(CDKSCREEN * cdkscreen,int x,int y)203 static CDKOBJS *make_graph (CDKSCREEN *cdkscreen, int x, int y)
204 {
205    static int values[] =
206    {
207       10, 15, 20, 25, 30, 35, 40, 45, 50, 55
208    };
209    static const char *graphChars = "0123456789";
210    CDKGRAPH *widget = newCDKGraph (cdkscreen, x, y,
211 				   10, 25,
212 				   "title", "X-axis", "Y-axis");
213    setCDKGraph (widget, values, NumElements (values), graphChars, TRUE, vPLOT);
214    return ObjPtr (widget);
215 }
216 
make_histogram(CDKSCREEN * cdkscreen,int x,int y)217 static CDKOBJS *make_histogram (CDKSCREEN *cdkscreen, int x, int y)
218 {
219    CDKHISTOGRAM *widget = newCDKHistogram (cdkscreen,
220 					   x,
221 					   y,
222 					   1,
223 					   20,
224 					   HORIZONTAL, "Histogram",
225 					   TRUE,
226 					   FALSE);
227    setCDKHistogram (widget, vPERCENT, CENTER, A_BOLD, 0, 10, 6, ' ' |
228 		    A_REVERSE, TRUE);
229    return ObjPtr (widget);
230 }
231 
make_itemlist(CDKSCREEN * cdkscreen,int x,int y)232 static CDKOBJS *make_itemlist (CDKSCREEN *cdkscreen, int x, int y)
233 {
234    CDKITEMLIST *widget = newCDKItemlist (cdkscreen, x, y,
235 					 NULL, "Month ",
236 					 (CDK_CSTRING2)months,
237 					 NumElements (months),
238 					 1, TRUE, FALSE);
239    return ObjPtr (widget);
240 }
241 
make_label(CDKSCREEN * cdkscreen,int x,int y)242 static CDKOBJS *make_label (CDKSCREEN *cdkscreen, int x, int y)
243 {
244    static const char *message[] =
245    {
246       "This is a simple label."
247       ,"Is it simple enough?"
248    };
249    CDKLABEL *widget = newCDKLabel (cdkscreen,
250 				   x,
251 				   y,
252 				   (CDK_CSTRING2)message, NumElements (message),
253 				   TRUE,
254 				   TRUE);
255    return ObjPtr (widget);
256 }
257 
make_marquee(CDKSCREEN * cdkscreen,int x,int y)258 static CDKOBJS *make_marquee (CDKSCREEN *cdkscreen, int x, int y)
259 {
260    CDKMARQUEE *widget = newCDKMarquee (cdkscreen,
261 				       x,
262 				       y,
263 				       30,
264 				       TRUE,
265 				       TRUE);
266    activateCDKMarquee (widget, "This is a message", 5, 3, TRUE);
267    destroyCDKMarquee (widget);
268    return 0;
269 }
270 
make_matrix(CDKSCREEN * cdkscreen,int x,int y)271 static CDKOBJS *make_matrix (CDKSCREEN *cdkscreen, int x, int y)
272 {
273 #define NUMROWS 8
274 #define NUMCOLS 5
275 
276    CDKMATRIX *widget;
277    const char *coltitle[NUMCOLS + 1];
278    const char *rowtitle[NUMROWS + 1];
279    char temp[80];
280    int cols = NUMCOLS;
281    int colwidth[NUMCOLS + 1];
282    int coltypes[NUMCOLS + 1];
283    int maxwidth = 0;
284    int n;
285    int rows = NUMROWS;
286    int vcols = 3;
287    int vrows = 3;
288 
289    for (n = 0; n <= NUMROWS; ++n)
290    {
291       sprintf (temp, "row%d", n);
292       rowtitle[n] = copyChar (temp);
293    }
294    for (n = 0; n <= NUMCOLS; ++n)
295    {
296       sprintf (temp, "col%d", n);
297       coltitle[n] = copyChar (temp);
298       colwidth[n] = (int)strlen (temp);
299       coltypes[n] = vUCHAR;
300       if (colwidth[n] > maxwidth)
301 	 maxwidth = colwidth[n];
302    }
303 
304    widget = newCDKMatrix (cdkscreen,
305 			  x,
306 			  y,
307 			  rows, cols, vrows, vcols,
308 			  "Matrix", (CDK_CSTRING2)rowtitle, (CDK_CSTRING2)coltitle,
309 			  colwidth, coltypes,
310 			  -1, -1, '.',
311 			  COL, TRUE,
312 			  TRUE,
313 			  FALSE);
314    return ObjPtr (widget);
315 }
316 
make_mentry(CDKSCREEN * cdkscreen,int x,int y)317 static CDKOBJS *make_mentry (CDKSCREEN *cdkscreen, int x, int y)
318 {
319    CDKMENTRY *widget = newCDKMentry (cdkscreen,
320 				     x,
321 				     y,
322 				     "MEntry", "Label", A_BOLD, '.', vMIXED,
323 				     20,
324 				     5,
325 				     20,
326 				     0,
327 				     TRUE,
328 				     FALSE);
329    return ObjPtr (widget);
330 }
331 
make_radio(CDKSCREEN * cdkscreen,int x,int y)332 static CDKOBJS *make_radio (CDKSCREEN *cdkscreen, int x, int y)
333 {
334    CDKRADIO *widget = newCDKRadio (cdkscreen,
335 				   x,
336 				   y,
337 				   RIGHT,
338 				   10,
339 				   20,
340 				   "Radio",
341 				   (CDK_CSTRING2)months, NumElements (months),
342 				   '#' | A_REVERSE, 1,
343 				   A_REVERSE,
344 				   TRUE,
345 				   FALSE);
346    return ObjPtr (widget);
347 }
348 
make_scale(CDKSCREEN * cdkscreen,int x,int y)349 static CDKOBJS *make_scale (CDKSCREEN *cdkscreen, int x, int y)
350 {
351    int low = 2;
352    int high = 25;
353    int inc = 1;
354    CDKSCALE *widget = newCDKScale (cdkscreen,
355 				   x,
356 				   y,
357 				   "Scale", "Label", A_NORMAL,
358 				   5,
359 				   low, low, high,
360 				   inc, (inc * 2),
361 				   TRUE,
362 				   FALSE);
363    return ObjPtr (widget);
364 }
365 
make_scroll(CDKSCREEN * cdkscreen,int x,int y)366 static CDKOBJS *make_scroll (CDKSCREEN *cdkscreen, int x, int y)
367 {
368    CDKSCROLL *widget = newCDKScroll (cdkscreen,
369 				     x,
370 				     y,
371 				     RIGHT,
372 				     10,
373 				     20,
374 				     "Scroll",
375 				     (CDK_CSTRING2)months, NumElements (months),
376 				     TRUE,
377 				     A_REVERSE,
378 				     TRUE,
379 				     FALSE);
380    return ObjPtr (widget);
381 }
382 
make_slider(CDKSCREEN * cdkscreen,int x,int y)383 static CDKOBJS *make_slider (CDKSCREEN *cdkscreen, int x, int y)
384 {
385    int low = 2;
386    int high = 25;
387    int inc = 1;
388    CDKSLIDER *widget = newCDKSlider (cdkscreen,
389 				     x,
390 				     y,
391 				     "Slider", "Label",
392 				     A_REVERSE | COLOR_PAIR (29) | ' ',
393 				     20,
394 				     low, low, high, inc, (inc * 2),
395 				     TRUE,
396 				     FALSE);
397    /* selection = activateCDKSlider (widget, 0); */
398    return ObjPtr (widget);
399 }
400 
make_selection(CDKSCREEN * cdkscreen,int x,int y)401 static CDKOBJS *make_selection (CDKSCREEN *cdkscreen, int x, int y)
402 {
403    CDKSELECTION *widget = newCDKSelection (cdkscreen, x, y,
404 					   NONE, 8, 20, "Selection",
405 					   (CDK_CSTRING2)months,
406 					   NumElements (months),
407 					   (CDK_CSTRING2)choices,
408 					   NumElements (choices),
409 					   A_REVERSE, TRUE, FALSE);
410    return ObjPtr (widget);
411 }
412 
make_swindow(CDKSCREEN * cdkscreen,int x,int y)413 static CDKOBJS *make_swindow (CDKSCREEN *cdkscreen, int x, int y)
414 {
415    CDKSWINDOW *widget = newCDKSwindow (cdkscreen,
416 				       x,
417 				       y,
418 				       6,
419 				       25,
420 				       "SWindow", 100,
421 				       TRUE,
422 				       FALSE);
423    int n;
424    for (n = 0; n < 30; ++n)
425    {
426       char temp[80];
427       sprintf (temp, "Line %d", n);
428       addCDKSwindow (widget, temp, BOTTOM);
429    }
430    activateCDKSwindow (widget, 0);
431    return ObjPtr (widget);
432 }
433 
make_template(CDKSCREEN * cdkscreen,int x,int y)434 static CDKOBJS *make_template (CDKSCREEN *cdkscreen, int x, int y)
435 {
436    const char *Overlay = "</B/6>(___)<!6> </5>___-____";
437    const char *plate = "(###) ###-####";
438    CDKTEMPLATE *widget = newCDKTemplate (cdkscreen,
439 					 x,
440 					 y,
441 					 "Template", "Label",
442 					 plate, Overlay,
443 					 TRUE,
444 					 FALSE);
445    activateCDKTemplate (widget, 0);
446    return ObjPtr (widget);
447 }
448 
make_uscale(CDKSCREEN * cdkscreen,int x,int y)449 static CDKOBJS *make_uscale (CDKSCREEN *cdkscreen, int x, int y)
450 {
451    unsigned low = 0;
452    unsigned high = 65535;
453    unsigned inc = 1;
454    CDKUSCALE *widget = newCDKUScale (cdkscreen,
455 				     x,
456 				     y,
457 				     "UScale", "Label", A_NORMAL,
458 				     5,
459 				     low, low, high,
460 				     inc, (inc * 32),
461 				     TRUE,
462 				     FALSE);
463    return ObjPtr (widget);
464 }
465 
make_uslider(CDKSCREEN * cdkscreen,int x,int y)466 static CDKOBJS *make_uslider (CDKSCREEN *cdkscreen, int x, int y)
467 {
468    unsigned low = 0;
469    unsigned high = 65535;
470    unsigned inc = 1;
471    CDKUSLIDER *widget = newCDKUSlider (cdkscreen,
472 				       x,
473 				       y,
474 				       "USlider", "Label",
475 				       A_REVERSE | COLOR_PAIR (29) | ' ',
476 				       20,
477 				       low, low, high, inc, (inc * 32),
478 				       TRUE,
479 				       FALSE);
480    /* selection = activateCDKSlider (widget, 0); */
481    return ObjPtr (widget);
482 }
483 
make_viewer(CDKSCREEN * cdkscreen,int x,int y)484 static CDKOBJS *make_viewer (CDKSCREEN *cdkscreen, int x, int y)
485 {
486    static const char *button[1] =
487    {
488       "Ok"
489    };
490    CDKVIEWER *widget = newCDKViewer (cdkscreen,
491 				     x,
492 				     y,
493 				     10,
494 				     20,
495 				     (CDK_CSTRING2)button, 1, A_REVERSE,
496 				     TRUE,
497 				     FALSE);
498    setCDKViewer (widget, "Viewer",
499 		 (CDK_CSTRING2)months, NumElements (months),
500 		 A_REVERSE, FALSE, TRUE, TRUE);
501    activateCDKViewer (widget, 0);
502    return ObjPtr (widget);
503 }
504 
rebind_esc(CDKOBJS * obj)505 static void rebind_esc (CDKOBJS *obj)
506 {
507    bindCDKObject (ObjTypeOf (obj), obj, KEY_F (1), getcCDKBind, (void *)KEY_ESC);
508 }
509 
make_any(CDKSCREEN * cdkscreen,int menu,EObjectType type)510 static void make_any (CDKSCREEN *cdkscreen, int menu, EObjectType type)
511 {
512    CDKOBJS *(*func) (CDKSCREEN *, int, int) = 0;
513    CDKOBJS *prior = 0;
514    int x;
515    int y;
516 
517    /* setup positions, staggered a little */
518    switch (menu)
519    {
520    case 0:
521       x = LEFT;
522       y = 2;
523       break;
524    case 1:
525       x = CENTER;
526       y = 4;
527       break;
528    case 2:
529       x = RIGHT;
530       y = 6;
531       break;
532    default:
533       beep ();
534       return;
535    }
536 
537    /* find the function to make a widget of the given type */
538    switch (type)
539    {
540    case vALPHALIST:
541       func = make_alphalist;
542       break;
543    case vBUTTON:
544       func = make_button;
545       break;
546    case vBUTTONBOX:
547       func = make_buttonbox;
548       break;
549    case vCALENDAR:
550       func = make_calendar;
551       break;
552    case vDIALOG:
553       func = make_dialog;
554       break;
555    case vDSCALE:
556       func = make_dscale;
557       break;
558    case vENTRY:
559       func = make_entry;
560       break;
561    case vFSCALE:
562       func = make_fscale;
563       break;
564    case vFSELECT:
565       func = make_fselect;
566       break;
567    case vFSLIDER:
568       func = make_fslider;
569       break;
570    case vGRAPH:
571       func = make_graph;
572       break;
573    case vHISTOGRAM:
574       func = make_histogram;
575       break;
576    case vITEMLIST:
577       func = make_itemlist;
578       break;
579    case vLABEL:
580       func = make_label;
581       break;
582    case vMARQUEE:
583       func = make_marquee;
584       break;
585    case vMATRIX:
586       func = make_matrix;
587       break;
588    case vMENTRY:
589       func = make_mentry;
590       break;
591    case vRADIO:
592       func = make_radio;
593       break;
594    case vSCALE:
595       func = make_scale;
596       break;
597    case vSCROLL:
598       func = make_scroll;
599       break;
600    case vSELECTION:
601       func = make_selection;
602       break;
603    case vSLIDER:
604       func = make_slider;
605       break;
606    case vSWINDOW:
607       func = make_swindow;
608       break;
609    case vTEMPLATE:
610       func = make_template;
611       break;
612    case vUSCALE:
613       func = make_uscale;
614       break;
615    case vUSLIDER:
616       func = make_uslider;
617       break;
618    case vVIEWER:
619       func = make_viewer;
620       break;
621    case vMENU:
622    case vTRAVERSE:
623    case vNULL:
624       if (type > 0)
625 	 beep ();
626       return;
627    }
628 
629    /* erase the old widget */
630    if ((prior = all_objects[menu]) != 0)
631    {
632       EraseObj (prior);
633       _destroyCDKObject (prior);
634       all_objects[menu] = 0;
635    }
636 
637    /* create the new widget */
638    if (func != 0)
639    {
640       CDKOBJS *widget = func (cdkscreen, x, y);
641       if (widget != 0)
642       {
643 	 all_objects[menu] = widget;
644 	 rebind_esc (widget);
645       }
646       else
647 	 flash ();
648    }
649    else
650    {
651       beep ();
652    }
653 }
654 
655 /*
656  * Whenever we get a menu selection, create the selected widget.
657  */
preHandler(EObjectType cdktype GCC_UNUSED,void * object,void * clientData GCC_UNUSED,chtype input GCC_UNUSED)658 static int preHandler (EObjectType cdktype GCC_UNUSED, void *object,
659 		       void *clientData GCC_UNUSED,
660 		       chtype input GCC_UNUSED)
661 {
662    int mp, sp;
663    CDKSCREEN *screen;
664    WINDOW *window;
665 
666    switch (input)
667    {
668    case KEY_ENTER:
669       getCDKMenuCurrentItem ((CDKMENU *)object, &mp, &sp);
670 
671       screen = ScreenOf ((CDKMENU *)object);
672       window = screen->window;
673       mvwprintw (window, getmaxy (window) - 1, 0, "selection %d/%d", mp, sp);
674       clrtoeol ();
675       refresh ();
676       if (sp >= 0 && sp < (int)NumElements (menu_table))
677 	 make_any (screen, mp, menu_table[sp].type);
678       break;
679    }
680    return 1;
681 }
682 
683 /*
684  * This demonstrates the Cdk widget-traversal.
685  */
main(int argc GCC_UNUSED,char ** argv GCC_UNUSED)686 int main (int argc GCC_UNUSED, char **argv GCC_UNUSED)
687 {
688    unsigned j, k;
689 
690    /* Declare local variables. */
691    CDKSCREEN *cdkscreen = NULL;
692    CDKMENU *menu = NULL;
693    const char *mesg[3];
694    static const char *menulist[MAX_MENU_ITEMS][MAX_SUB_ITEMS] =
695    {
696       {"Left"},
697       {"Center"},
698       {"Right"},
699    };
700    static int submenusize[] =
701    {
702       NumElements (menu_table) + 1,
703       NumElements (menu_table) + 1,
704       NumElements (menu_table) + 1
705    };
706    static int menuloc[] =
707    {LEFT, LEFT, RIGHT};
708 
709    for (j = 0; j < MY_MAX; ++j)
710    {
711       for (k = 0; k < NumElements (menu_table); ++k)
712       {
713 	 menulist[j][k + 1] = menu_table[k].name;
714       }
715    }
716 
717    cdkscreen = initCDKScreen (NULL);
718 
719    /* Start CDK colors. */
720    initCDKColor ();
721 
722 
723    menu = newCDKMenu (cdkscreen, menulist, MY_MAX, submenusize, menuloc,
724 		      TOP, A_UNDERLINE, A_REVERSE);
725    if (menu == 0)
726    {
727       destroyCDKScreen (cdkscreen);
728       endCDK ();
729 
730       printf ("? Cannot create menus\n");
731       ExitProgram (EXIT_FAILURE);
732    }
733    rebind_esc (ObjOf (menu));
734 
735    setCDKMenuPreProcess (menu, preHandler, 0);
736 
737    /* setup the initial display */
738    make_any (cdkscreen, 0, vENTRY);
739 #if MY_MAX > 1
740    make_any (cdkscreen, 1, vITEMLIST);
741 #if MY_MAX > 2
742    make_any (cdkscreen, 2, vSELECTION);
743 #endif
744 #endif
745 
746    /* Draw the screen. */
747    refreshCDKScreen (cdkscreen);
748 
749    /* Traverse the screen */
750    traverseCDKScreen (cdkscreen);
751 
752    mesg[0] = "Done";
753    mesg[1] = "";
754    mesg[2] = "<C>Press any key to continue.";
755    popupLabel (cdkscreen, (CDK_CSTRING2)mesg, 3);
756 
757    /* Clean up and exit. */
758    for (j = 0; j < MY_MAX; ++j)
759    {
760       if (all_objects[j] != 0)
761 	 _destroyCDKObject (all_objects[j]);
762    }
763    destroyCDKMenu (menu);
764    destroyCDKScreen (cdkscreen);
765    endCDK ();
766 
767    ExitProgram (EXIT_SUCCESS);
768 }
769