blob: 4d553e2ea73c98947085f4a5fe02a0bab6057ecd [file] [log] [blame]
Amit Daniel Kachhape6a01f52011-07-20 11:45:59 +05301/****************************************************************************
2 * Copyright (c) 2005-2007,2008 Free Software Foundation, Inc. *
3 * *
4 * Permission is hereby granted, free of charge, to any person obtaining a *
5 * copy of this software and associated documentation files (the *
6 * "Software"), to deal in the Software without restriction, including *
7 * without limitation the rights to use, copy, modify, merge, publish, *
8 * distribute, distribute with modifications, sublicense, and/or sell *
9 * copies of the Software, and to permit persons to whom the Software is *
10 * furnished to do so, subject to the following conditions: *
11 * *
12 * The above copyright notice and this permission notice shall be included *
13 * in all copies or substantial portions of the Software. *
14 * *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS *
16 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. *
18 * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR *
21 * THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
22 * *
23 * Except as contained in this notice, the name(s) of the above copyright *
24 * holders shall not be used in advertising or otherwise to promote the *
25 * sale, use or other dealings in this Software without prior written *
26 * authorization. *
27 ****************************************************************************/
28/*
29 * $Id: demo_menus.c,v 1.28 2008/08/23 20:31:54 tom Exp $
30 *
31 * Demonstrate a variety of functions from the menu library.
32 * Thomas Dickey - 2005/4/9
33 */
34/*
35item_description -
36item_init -
37item_opts -
38item_opts_off -
39item_opts_on -
40item_term -
41item_userptr -
42item_visible -
43menu_back -
44menu_fore -
45menu_format -
46menu_grey -
47menu_init -
48menu_opts -
49menu_pad -
50menu_request_by_name -
51menu_request_name -
52menu_sub -
53menu_term -
54menu_userptr -
55set_current_item -
56set_item_init -
57set_item_opts -
58set_item_term -
59set_item_userptr -
60set_menu_grey -
61set_menu_init -
62set_menu_items -
63set_menu_opts -
64set_menu_pad -
65set_menu_pattern -
66set_menu_spacing -
67set_menu_term -
68set_menu_userptr -
69set_top_row -
70top_row -
71*/
72
73#include <test.priv.h>
74
75#if USE_LIBMENU
76
77#include <menu.h>
78
79#include <sys/types.h>
80#include <sys/stat.h>
81
82#ifdef NCURSES_VERSION
83#ifdef TRACE
84static unsigned save_trace = TRACE_ORDINARY | TRACE_CALLS;
85extern unsigned _nc_tracing;
86static MENU *mpTrace;
87#endif
88#else
89#undef TRACE
90#endif
91
92typedef enum {
93 eBanner = -1
94 ,eFile
95 ,eSelect
96#ifdef TRACE
97 ,eTrace
98#endif
99 ,eMAX
100} MenuNo;
101
102#define okMenuNo(n) (((n) > eBanner) && ((n) < eMAX))
103
104#define MENU_Y 1
105
106static MENU *mpBanner;
107static MENU *mpFile;
108static MENU *mpSelect;
109
110static bool loaded_file = FALSE;
111
112#if !HAVE_STRDUP
113#define strdup my_strdup
114static char *
115strdup(char *s)
116{
117 char *p = typeMalloc(char, strlen(s) + 1);
118 if (p)
119 strcpy(p, s);
120 return (p);
121}
122#endif /* not HAVE_STRDUP */
123
124/* Common function to allow ^T to toggle trace-mode in the middle of a test
125 * so that trace-files can be made smaller.
126 */
127static int
128wGetchar(WINDOW *win)
129{
130 int c;
131#ifdef TRACE
132 while ((c = wgetch(win)) == CTRL('T')) {
133 if (_nc_tracing) {
134 save_trace = _nc_tracing;
135 Trace(("TOGGLE-TRACING OFF"));
136 _nc_tracing = 0;
137 } else {
138 _nc_tracing = save_trace;
139 }
140 trace(_nc_tracing);
141 if (_nc_tracing)
142 Trace(("TOGGLE-TRACING ON"));
143 }
144#else
145 c = wgetch(win);
146#endif
147 return c;
148}
149#define Getchar() wGetchar(stdscr)
150
151static int
152menu_virtualize(int c)
153{
154 int result;
155
156 if (c == '\n' || c == KEY_EXIT)
157 result = (MAX_COMMAND + 1);
158 else if (c == 'u')
159 result = (REQ_SCR_ULINE);
160 else if (c == 'd')
161 result = (REQ_SCR_DLINE);
162 else if (c == 'b' || c == KEY_NPAGE)
163 result = (REQ_SCR_UPAGE);
164 else if (c == 'f' || c == KEY_PPAGE)
165 result = (REQ_SCR_DPAGE);
166 else if (c == 'l' || c == KEY_LEFT || c == KEY_BTAB)
167 result = (REQ_LEFT_ITEM);
168 else if (c == 'n' || c == KEY_DOWN)
169 result = (REQ_NEXT_ITEM);
170 else if (c == 'p' || c == KEY_UP)
171 result = (REQ_PREV_ITEM);
172 else if (c == 'r' || c == KEY_RIGHT || c == '\t')
173 result = (REQ_RIGHT_ITEM);
174 else if (c == ' ')
175 result = (REQ_TOGGLE_ITEM);
176 else {
177 if (c != KEY_MOUSE)
178 beep();
179 result = (c);
180 }
181 return result;
182}
183
184static int
185menu_getc(MENU * m)
186{
187 return wGetchar(menu_win(m));
188}
189
190static int
191menu_offset(MenuNo number)
192{
193 int result = 0;
194
195 if (okMenuNo(number)) {
196 int spc_desc, spc_rows, spc_cols;
197
198#ifdef NCURSES_VERSION
199 menu_spacing(mpBanner, &spc_desc, &spc_rows, &spc_cols);
200#else
201 spc_rows = 0;
202#endif
203
204 /* FIXME: MENU.itemlen seems the only way to get actual width of items */
205 result = (number - (eBanner + 1)) * (mpBanner->itemlen + spc_rows);
206 }
207 return result;
208}
209
210static MENU *
211menu_create(ITEM ** items, int count, int ncols, MenuNo number)
212{
213 MENU *result;
214 WINDOW *menuwin;
215 int mrows, mcols;
216 int y = okMenuNo(number) ? MENU_Y : 0;
217 int x = menu_offset(number);
218 int margin = (y == MENU_Y) ? 1 : 0;
219 int maxcol = (ncols + x) < COLS ? ncols : (COLS - x - 1);
220 int maxrow = (count + 1) / ncols;
221
222 if ((maxrow + y) >= (LINES - 4))
223 maxrow = LINES - 4 - y;
224
225 result = new_menu(items);
226
227 if (has_colors()) {
228 set_menu_fore(result, COLOR_PAIR(1));
229 set_menu_back(result, COLOR_PAIR(2));
230 }
231
232 set_menu_format(result, maxrow, maxcol);
233 scale_menu(result, &mrows, &mcols);
234
235 if (mcols + (2 * margin + x) >= COLS)
236 mcols = COLS - (2 * margin + x);
237
238#ifdef TRACE
239 if (number == eTrace)
240 menu_opts_off(result, O_ONEVALUE);
241 else
242 menu_opts_on(result, O_ONEVALUE);
243#endif
244
245 menuwin = newwin(mrows + (2 * margin), mcols + (2 * margin), y, x);
246 set_menu_win(result, menuwin);
247 keypad(menuwin, TRUE);
248 if (margin)
249 box(menuwin, 0, 0);
250
251 set_menu_sub(result, derwin(menuwin, mrows, mcols, margin, margin));
252
253 post_menu(result);
254
255 return result;
256}
257
258static void
259menu_destroy(MENU * m)
260{
261 int count;
262
263 Trace(("menu_destroy %p", m));
264 if (m != 0) {
265 ITEM **items = menu_items(m);
266 const char *blob = 0;
267
268 count = item_count(m);
269 Trace(("menu_destroy %p count %d", m, count));
270 if ((count > 0) && (m == mpSelect)) {
271 blob = item_name(*items);
272 }
273
274 unpost_menu(m);
275 free_menu(m);
276
277 /* free the extra data allocated in build_select_menu() */
278 if ((count > 0) && (m == mpSelect)) {
279 if (blob && loaded_file) {
280 Trace(("freeing blob %p", blob));
281 free((char *) blob);
282 }
283 free(items);
284 }
285#ifdef TRACE
286 if ((count > 0) && (m == mpTrace)) {
287 ITEM **ip = items;
288 while (*ip)
289 free(*ip++);
290 }
291#endif
292 }
293}
294
295/* force the given menu to appear */
296static void
297menu_display(MENU * m)
298{
299 touchwin(menu_win(m));
300 wrefresh(menu_win(m));
301}
302
303/*****************************************************************************/
304
305static void
306build_file_menu(MenuNo number)
307{
308 static CONST_MENUS char *labels[] =
309 {
310 "Exit",
311 (char *) 0
312 };
313 static ITEM *items[SIZEOF(labels)];
314
315 ITEM **ip = items;
316 CONST_MENUS char **ap;
317
318 for (ap = labels; *ap; ap++)
319 *ip++ = new_item(*ap, "");
320 *ip = (ITEM *) 0;
321
322 mpFile = menu_create(items, SIZEOF(labels) - 1, 1, number);
323}
324
325static int
326perform_file_menu(int cmd)
327{
328 return menu_driver(mpFile, cmd);
329}
330
331/*****************************************************************************/
332
333static void
334build_select_menu(MenuNo number, char *filename)
335{
336 static CONST_MENUS char *labels[] =
337 {
338 "Lions",
339 "Tigers",
340 "Bears",
341 "(Oh my!)",
342 "Newts",
343 "Platypi",
344 "Lemurs",
345 "(Oh really?!)",
346 "Leopards",
347 "Panthers",
348 "Pumas",
349 "Lions, Tigers, Bears, (Oh my!), Newts, Platypi, Lemurs",
350 "Lions, Tigers, Bears, (Oh my!), Newts, Platypi, Lemurs, Lions, Tigers, Bears, (Oh my!), Newts, Platypi, Lemurs",
351 (char *) 0
352 };
353 static ITEM **items;
354
355 ITEM **ip;
356 CONST_MENUS char **ap = 0;
357 CONST_MENUS char **myList = 0;
358 unsigned count = 0;
359
360 if (filename != 0) {
361 struct stat sb;
362 if (stat(filename, &sb) == 0
363 && (sb.st_mode & S_IFMT) == S_IFREG
364 && sb.st_size != 0) {
365 size_t size = (size_t) sb.st_size;
366 unsigned j, k;
367 char *blob = typeMalloc(char, size + 1);
368 CONST_MENUS char **list = typeCalloc(CONST_MENUS char *, size + 1);
369
370 items = typeCalloc(ITEM *, size + 1);
371 Trace(("build_select_menu blob=%p, items=%p", blob, items));
372 if (blob != 0 && list != 0) {
373 FILE *fp = fopen(filename, "r");
374 if (fp != 0) {
375 if (fread(blob, sizeof(char), size, fp) == size) {
376 bool mark = TRUE;
377 for (j = k = 0; j < size; ++j) {
378 if (mark) {
379 list[k++] = blob + j;
380 mark = FALSE;
381 }
382 if (blob[j] == '\n') {
383 blob[j] = '\0';
384 if (k > 0 && *list[k - 1] == '\0')
385 --k;
386 mark = TRUE;
387 } else if (blob[j] == '\t') {
388 blob[j] = ' '; /* menu items are printable */
389 }
390 }
391 list[k] = 0;
392 count = k;
393 ap = myList = list;
394 }
395 fclose(fp);
396 }
397 loaded_file = TRUE;
398 }
399 }
400 }
401 if (ap == 0) {
402 count = SIZEOF(labels) - 1;
403 items = typeCalloc(ITEM *, count + 1);
404 ap = labels;
405 }
406
407 ip = items;
408 while (*ap != 0)
409 *ip++ = new_item(*ap++, "");
410 *ip = 0;
411
412 mpSelect = menu_create(items, (int) count, 1, number);
413 if (myList != 0)
414 free(myList);
415}
416
417static int
418perform_select_menu(int cmd)
419{
420 return menu_driver(mpSelect, cmd);
421}
422
423/*****************************************************************************/
424
425#ifdef TRACE
426#define T_TBL(name) { #name, name }
427static struct {
428 const char *name;
429 unsigned mask;
430} t_tbl[] = {
431
432 T_TBL(TRACE_DISABLE),
433 T_TBL(TRACE_TIMES),
434 T_TBL(TRACE_TPUTS),
435 T_TBL(TRACE_UPDATE),
436 T_TBL(TRACE_MOVE),
437 T_TBL(TRACE_CHARPUT),
438 T_TBL(TRACE_ORDINARY),
439 T_TBL(TRACE_CALLS),
440 T_TBL(TRACE_VIRTPUT),
441 T_TBL(TRACE_IEVENT),
442 T_TBL(TRACE_BITS),
443 T_TBL(TRACE_ICALLS),
444 T_TBL(TRACE_CCALLS),
445 T_TBL(TRACE_DATABASE),
446 T_TBL(TRACE_ATTRS),
447 T_TBL(TRACE_MAXIMUM),
448 {
449 (char *) 0, 0
450 }
451};
452
453static void
454build_trace_menu(MenuNo number)
455{
456 static ITEM *items[SIZEOF(t_tbl)];
457
458 ITEM **ip = items;
459 int n;
460
461 for (n = 0; t_tbl[n].name != 0; n++)
462 *ip++ = new_item(t_tbl[n].name, "");
463 *ip = (ITEM *) 0;
464
465 mpTrace = menu_create(items, SIZEOF(t_tbl) - 1, 2, number);
466}
467
468static char *
469tracetrace(unsigned tlevel)
470{
471 static char *buf;
472 int n;
473
474 if (buf == 0) {
475 size_t need = 12;
476 for (n = 0; t_tbl[n].name != 0; n++)
477 need += strlen(t_tbl[n].name) + 2;
478 buf = typeMalloc(char, need);
479 }
480 sprintf(buf, "0x%02x = {", tlevel);
481 if (tlevel == 0) {
482 sprintf(buf + strlen(buf), "%s, ", t_tbl[0].name);
483 } else {
484 for (n = 1; t_tbl[n].name != 0; n++)
485 if ((tlevel & t_tbl[n].mask) == t_tbl[n].mask) {
486 strcat(buf, t_tbl[n].name);
487 strcat(buf, ", ");
488 }
489 }
490 if (buf[strlen(buf) - 2] == ',')
491 buf[strlen(buf) - 2] = '\0';
492 return (strcat(buf, "}"));
493}
494
495/* fake a dynamically reconfigurable menu using the 0th entry to deselect
496 * the others
497 */
498static bool
499update_trace_menu(MENU * m)
500{
501 ITEM **items;
502 ITEM *i, **p;
503 bool changed = FALSE;
504
505 items = menu_items(m);
506 i = current_item(m);
507 if (i == items[0]) {
508 if (item_value(i)) {
509 for (p = items + 1; *p != 0; p++)
510 if (item_value(*p)) {
511 set_item_value(*p, FALSE);
512 changed = TRUE;
513 }
514 }
515 }
516 return changed;
517}
518
519static int
520perform_trace_menu(int cmd)
521/* interactively set the trace level */
522{
523 ITEM **ip;
524 unsigned newtrace;
525 int result;
526
527 for (ip = menu_items(mpTrace); *ip; ip++) {
528 unsigned mask = t_tbl[item_index(*ip)].mask;
529 if (mask == 0)
530 set_item_value(*ip, _nc_tracing == 0);
531 else if ((mask & _nc_tracing) == mask)
532 set_item_value(*ip, TRUE);
533 }
534
535 result = menu_driver(mpTrace, cmd);
536
537 if (result == E_OK) {
538 if (update_trace_menu(mpTrace) || cmd == REQ_TOGGLE_ITEM) {
539 newtrace = 0;
540 for (ip = menu_items(mpTrace); *ip; ip++) {
541 if (item_value(*ip))
542 newtrace |= t_tbl[item_index(*ip)].mask;
543 }
544 trace(newtrace);
545 Trace(("trace level interactively set to %s", tracetrace(_nc_tracing)));
546
547 (void) mvprintw(LINES - 2, 0,
548 "Trace level is %s\n", tracetrace(_nc_tracing));
549 refresh();
550 }
551 }
552 return result;
553}
554#endif /* TRACE */
555
556/*****************************************************************************/
557
558static int
559menu_number(void)
560{
561 return item_index(current_item(mpBanner)) - (eBanner + 1);
562}
563
564static MENU *
565current_menu(void)
566{
567 MENU *result;
568
569 switch (menu_number()) {
570 case eFile:
571 result = mpFile;
572 break;
573 case eSelect:
574 result = mpSelect;
575 break;
576#ifdef TRACE
577 case eTrace:
578 result = mpTrace;
579 break;
580#endif
581 default:
582 result = 0;
583 break;
584 }
585 return result;
586}
587
588static void
589build_menus(char *filename)
590{
591 static CONST_MENUS char *labels[] =
592 {
593 "File",
594 "Select",
595#ifdef TRACE
596 "Trace",
597#endif
598 (char *) 0
599 };
600 static ITEM *items[SIZEOF(labels)];
601
602 ITEM **ip = items;
603 CONST_MENUS char **ap;
604
605 for (ap = labels; *ap; ap++)
606 *ip++ = new_item(*ap, "");
607 *ip = (ITEM *) 0;
608
609 mpBanner = menu_create(items, SIZEOF(labels) - 1, SIZEOF(labels) - 1, eBanner);
610 set_menu_mark(mpBanner, ">");
611
612 build_file_menu(eFile);
613 build_select_menu(eSelect, filename);
614#ifdef TRACE
615 build_trace_menu(eTrace);
616#endif
617}
618
619static int
620move_menu(MENU * menu, MENU * current, int by_y, int by_x)
621{
622 WINDOW *top_win = menu_win(menu);
623 WINDOW *sub_win = menu_sub(menu);
624 int y0, x0;
625 int y1, x1;
626 int result;
627
628 getbegyx(top_win, y0, x0);
629 y0 += by_y;
630 x0 += by_x;
631
632 getbegyx(sub_win, y1, x1);
633 y1 += by_y;
634 x1 += by_x;
635
636 if ((result = mvwin(top_win, y0, x0)) != ERR) {
637#if defined(NCURSES_VERSION_PATCH) && (NCURSES_VERSION_PATCH < 20060218)
638 sub_win->_begy = y1;
639 sub_win->_begx = x1;
640#else
641 mvwin(sub_win, y1, x1);
642#endif
643 if (menu == current) {
644 touchwin(top_win);
645 wnoutrefresh(top_win);
646 }
647 }
648 return result;
649}
650
651/*
652 * Move the menus around on the screen, to test mvwin().
653 */
654static void
655move_menus(MENU * current, int by_y, int by_x)
656{
657 if (move_menu(mpBanner, current, by_y, by_x) != ERR) {
658 erase();
659 wnoutrefresh(stdscr);
660 move_menu(mpFile, current, by_y, by_x);
661 move_menu(mpSelect, current, by_y, by_x);
662#ifdef TRACE
663 move_menu(mpTrace, current, by_y, by_x);
664#endif
665 doupdate();
666 }
667}
668
669static void
670show_status(int ch, MENU * menu)
671{
672 move(LINES - 1, 0);
673 printw("key %s, menu %d, mark %s, match %s",
674 keyname(ch),
675 menu_number(),
676 menu_mark(menu),
677 menu_pattern(menu));
678 clrtoeol();
679 refresh();
680}
681
682static void
683perform_menus(void)
684{
685 MENU *this_menu;
686 MENU *last_menu = mpFile;
687 int code = E_UNKNOWN_COMMAND;
688 int cmd;
689 int ch = ERR;
690
691#ifdef NCURSES_MOUSE_VERSION
692 mousemask(ALL_MOUSE_EVENTS, (mmask_t *) 0);
693#endif
694
695 menu_display(last_menu);
696
697 for (;;) {
698
699 if (ch != ERR)
700 show_status(ch, last_menu);
701
702 ch = menu_getc(mpBanner);
703
704 /*
705 * Provide for moving the menu around in the screen using shifted
706 * cursor keys.
707 */
708 switch (ch) {
709 case KEY_SF:
710 move_menus(last_menu, 1, 0);
711 continue;
712 case KEY_SR:
713 move_menus(last_menu, -1, 0);
714 continue;
715 case KEY_SLEFT:
716 move_menus(last_menu, 0, -1);
717 continue;
718 case KEY_SRIGHT:
719 move_menus(last_menu, 0, 1);
720 continue;
721 }
722 cmd = menu_virtualize(ch);
723
724 switch (cmd) {
725 /*
726 * The banner menu acts solely to select one of the other menus.
727 * Move between its items, wrapping at the left/right limits.
728 */
729 case REQ_LEFT_ITEM:
730 case REQ_RIGHT_ITEM:
731 code = menu_driver(mpBanner, cmd);
732 if (code == E_REQUEST_DENIED) {
733 if (menu_number() > 0)
734 code = menu_driver(mpBanner, REQ_FIRST_ITEM);
735 else
736 code = menu_driver(mpBanner, REQ_LAST_ITEM);
737 }
738 break;
739 default:
740 switch (menu_number()) {
741 case eFile:
742 code = perform_file_menu(cmd);
743 break;
744 case eSelect:
745 code = perform_select_menu(cmd);
746 break;
747#ifdef TRACE
748 case eTrace:
749 code = perform_trace_menu(cmd);
750 break;
751#endif
752 }
753
754 if ((code == E_REQUEST_DENIED) && (cmd == KEY_MOUSE)) {
755 code = menu_driver(mpBanner, cmd);
756 }
757
758 break;
759 }
760
761 if (code == E_OK) {
762 this_menu = current_menu();
763 if (this_menu != last_menu) {
764 move(1, 0);
765 clrtobot();
766 box(menu_win(this_menu), 0, 0);
767 refresh();
768
769 /* force the current menu to appear */
770 menu_display(this_menu);
771
772 last_menu = this_menu;
773 }
774 }
775 wrefresh(menu_win(last_menu));
776 if (code == E_UNKNOWN_COMMAND
777 || code == E_NOT_POSTED) {
778 if (menu_number() == eFile)
779 break;
780 beep();
781 }
782 if (code == E_REQUEST_DENIED)
783 beep();
784 continue;
785 }
786
787#ifdef NCURSES_MOUSE_VERSION
788 mousemask(0, (mmask_t *) 0);
789#endif
790}
791
792static void
793destroy_menus(void)
794{
795 menu_destroy(mpFile);
796 menu_destroy(mpSelect);
797#ifdef TRACE
798 menu_destroy(mpTrace);
799#endif
800 menu_destroy(mpBanner);
801}
802
803#if HAVE_RIPOFFLINE
804static int
805rip_footer(WINDOW *win, int cols)
806{
807 wbkgd(win, A_REVERSE);
808 werase(win);
809 wmove(win, 0, 0);
810 wprintw(win, "footer: %d columns", cols);
811 wnoutrefresh(win);
812 return OK;
813}
814
815static int
816rip_header(WINDOW *win, int cols)
817{
818 wbkgd(win, A_REVERSE);
819 werase(win);
820 wmove(win, 0, 0);
821 wprintw(win, "header: %d columns", cols);
822 wnoutrefresh(win);
823 return OK;
824}
825#endif /* HAVE_RIPOFFLINE */
826
827static void
828usage(void)
829{
830 static const char *const tbl[] =
831 {
832 "Usage: demo_menus [options]"
833 ,""
834 ,"Options:"
835#if HAVE_RIPOFFLINE
836 ," -f rip-off footer line (can repeat)"
837 ," -h rip-off header line (can repeat)"
838#endif
839#ifdef TRACE
840 ," -t mask specify default trace-level (may toggle with ^T)"
841#endif
842 };
843 size_t n;
844 for (n = 0; n < SIZEOF(tbl); n++)
845 fprintf(stderr, "%s\n", tbl[n]);
846 ExitProgram(EXIT_FAILURE);
847}
848
849int
850main(int argc, char *argv[])
851{
852 int c;
853
854 setlocale(LC_ALL, "");
855
856 while ((c = getopt(argc, argv, "a:de:fhmp:s:t:")) != -1) {
857 switch (c) {
858#if HAVE_RIPOFFLINE
859 case 'f':
860 ripoffline(-1, rip_footer);
861 break;
862 case 'h':
863 ripoffline(1, rip_header);
864 break;
865#endif /* HAVE_RIPOFFLINE */
866#ifdef TRACE
867 case 't':
868 trace(strtoul(optarg, 0, 0));
869 break;
870#endif
871 default:
872 usage();
873 }
874 }
875
876 initscr();
877 noraw();
878 cbreak();
879 noecho();
880
881 if (has_colors()) {
882 start_color();
883 init_pair(1, COLOR_RED, COLOR_BLACK);
884 init_pair(2, COLOR_BLUE, COLOR_WHITE);
885 }
886 build_menus(argc > 1 ? argv[1] : 0);
887 perform_menus();
888 destroy_menus();
889
890 endwin();
891 ExitProgram(EXIT_SUCCESS);
892}
893#else
894int
895main(void)
896{
897 printf("This program requires the curses menu library\n");
898 ExitProgram(EXIT_FAILURE);
899}
900#endif