• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /****************************************************************************
2  * Copyright 2018-2020,2022 Thomas E. Dickey                                *
3  * Copyright 2003-2016,2017 Free Software Foundation, Inc.                  *
4  *                                                                          *
5  * Permission is hereby granted, free of charge, to any person obtaining a  *
6  * copy of this software and associated documentation files (the            *
7  * "Software"), to deal in the Software without restriction, including      *
8  * without limitation the rights to use, copy, modify, merge, publish,      *
9  * distribute, distribute with modifications, sublicense, and/or sell       *
10  * copies of the Software, and to permit persons to whom the Software is    *
11  * furnished to do so, subject to the following conditions:                 *
12  *                                                                          *
13  * The above copyright notice and this permission notice shall be included  *
14  * in all copies or substantial portions of the Software.                   *
15  *                                                                          *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
17  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
19  * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
20  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
21  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
22  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
23  *                                                                          *
24  * Except as contained in this notice, the name(s) of the above copyright   *
25  * holders shall not be used in advertising or otherwise to promote the     *
26  * sale, use or other dealings in this Software without prior written       *
27  * authorization.                                                           *
28  ****************************************************************************/
29 /*
30  * $Id: demo_panels.c,v 1.48 2022/12/04 00:40:11 tom Exp $
31  *
32  * Demonstrate a variety of functions from the panel library.
33  */
34 
35 #include <test.priv.h>
36 
37 #if USE_LIBPANEL
38 
39 #include <panel.h>
40 
41 #define LAST_POS '@'
42 #define TEMP_POS '>'
43 
44 typedef void (*InitPanel) (void);
45 typedef void (*FillPanel) (PANEL *);
46 
47 static bool use_colors = FALSE;
48 static bool unboxed = FALSE;
49 static FILE *log_in;
50 static FILE *log_out;
51 
52 static void
close_input(void)53 close_input(void)
54 {
55     if (log_in != 0) {
56 	fclose(log_in);
57 	log_in = 0;
58     }
59 }
60 
61 static void
close_output(void)62 close_output(void)
63 {
64     if (log_out != 0) {
65 	fclose(log_out);
66 	log_out = 0;
67     }
68 }
69 
70 static WINDOW *
statusline(void)71 statusline(void)
72 {
73     WINDOW *result = stdscr;
74 
75     wmove(result, LINES - 1, 0);
76     wclrtoeol(result);
77     return result;
78 }
79 
80 static void
pflush(void)81 pflush(void)
82 {
83     update_panels();
84     doupdate();
85 }
86 
87 static void
saywhat(NCURSES_CONST char * text)88 saywhat(NCURSES_CONST char *text)
89 {
90     WINDOW *win = statusline();
91     if (text != 0 && *text != '\0') {
92 	waddstr(win, text);
93 	waddstr(win, "; ");
94     }
95     waddstr(win, "press any key to continue");
96 }
97 
98 static void
show_position(NCURSES_CONST char * text,NCURSES_CONST char * also,int which,int ypos,int xpos)99 show_position(NCURSES_CONST char *text,
100 	      NCURSES_CONST char *also,
101 	      int which,
102 	      int ypos,
103 	      int xpos)
104 {
105     WINDOW *win = statusline();
106 
107     wprintw(win, "%s for panel %d now %d,%d%s", text, which, ypos, xpos, also);
108     wmove(stdscr, ypos, xpos);
109 }
110 
111 static int
get_position(NCURSES_CONST char * text,NCURSES_CONST char * also,int which,int * xpos,int * ypos)112 get_position(NCURSES_CONST char *text,
113 	     NCURSES_CONST char *also,
114 	     int which,
115 	     int *xpos,
116 	     int *ypos)
117 {
118     int result = 0;
119     int x1, y1;
120     char cmd;
121 
122     getyx(stdscr, y1, x1);
123     (void) statusline();
124 
125     show_position(text, also, which, y1, x1);
126 
127     if (log_in != 0) {
128 	if (fscanf(log_in, "%c%d,%d\n", &cmd, &y1, &x1) == 3) {
129 	    switch (cmd) {
130 	    case LAST_POS:
131 		result = 1;
132 		(void) wgetch(stdscr);
133 		break;
134 	    case TEMP_POS:
135 		result = 0;
136 		wrefresh(stdscr);
137 		napms(100);
138 		break;
139 	    default:
140 		result = -1;
141 		break;
142 	    }
143 	} else {
144 	    result = -1;
145 	}
146     } else {
147 
148 	switch (wgetch(stdscr)) {
149 	case QUIT:
150 	case ESCAPE:
151 	case ERR:
152 	    result = -1;
153 	    break;
154 	case ' ':
155 	    result = 1;
156 	    break;
157 	case KEY_UP:
158 	    if (y1 > 0) {
159 		--y1;
160 	    } else {
161 		beep();
162 	    }
163 	    break;
164 	case KEY_DOWN:
165 	    if (y1 < getmaxy(stdscr)) {
166 		++y1;
167 	    } else {
168 		beep();
169 	    }
170 	    break;
171 	case KEY_LEFT:
172 	    if (x1 > 0) {
173 		--x1;
174 	    } else {
175 		beep();
176 	    }
177 	    break;
178 	case KEY_RIGHT:
179 	    if (x1 < getmaxx(stdscr)) {
180 		++x1;
181 	    } else {
182 		beep();
183 	    }
184 	    break;
185 	}
186     }
187 
188     wmove(stdscr, y1, x1);
189     *ypos = y1;
190     *xpos = x1;
191 
192     if (result >= 0) {
193 	if (log_out)
194 	    fprintf(log_out, "%c%d,%d\n",
195 		    ((result > 0)
196 		     ? LAST_POS
197 		     : TEMP_POS),
198 		    y1, x1);
199     }
200     return result;
201 }
202 
203 static PANEL *
mkpanel(short color,int rows,int cols,int tly,int tlx)204 mkpanel(short color, int rows, int cols, int tly, int tlx)
205 {
206     WINDOW *win;
207     PANEL *pan = 0;
208     char *userdata = typeMalloc(char, 6);
209 
210     if ((win = newwin(rows, cols, tly, tlx)) != 0) {
211 	keypad(win, TRUE);
212 	if ((pan = new_panel(win)) == 0) {
213 	    delwin(win);
214 	} else if (use_colors) {
215 	    short fg = (short) ((color == COLOR_BLUE)
216 				? COLOR_WHITE
217 				: COLOR_BLACK);
218 	    short bg = color;
219 
220 	    init_pair(color, fg, bg);
221 	    wbkgdset(win, (chtype) (COLOR_PAIR(color) | ' '));
222 	} else if (!unboxed) {
223 	    wbkgdset(win, A_BOLD | ' ');
224 	}
225     }
226     _nc_SPRINTF(userdata, _nc_SLIMIT(4) "p%d", color % 8);
227     set_panel_userptr(pan, (NCURSES_CONST void *) userdata);
228     return pan;
229 }
230 
231 static void
my_remove_panel(PANEL ** pans,int which)232 my_remove_panel(PANEL **pans, int which)
233 {
234     if (pans[which] != 0) {
235 	PANEL *pan = pans[which];
236 	WINDOW *win = panel_window(pan);
237 	char *user = (char *) panel_userptr(pan);
238 
239 	free(user);
240 	del_panel(pan);
241 	delwin(win);
242 
243 	pans[which] = 0;
244     }
245 }
246 
247 #undef MIN
248 #define MIN(a,b) ((a) < (b) ? (a) : (b))
249 #define ABS(a)   ((a) < 0 ? -(a) : (a))
250 
251 static void
my_create_panel(PANEL ** pans,int which,FillPanel myFill)252 my_create_panel(PANEL **pans, int which, FillPanel myFill)
253 {
254     int code;
255     short pair = (short) which;
256     short fg = (short) ((pair == COLOR_BLUE) ? COLOR_WHITE : COLOR_BLACK);
257     short bg = pair;
258     int x0, y0, x1, y1;
259 
260     init_pair(pair, fg, bg);
261 
262     /* remove the old panel, if any */
263     my_remove_panel(pans, which);
264 
265     /* get the position of one corner */
266     wmove(stdscr, getmaxy(stdscr) / 2, getmaxx(stdscr) / 2);
267     getyx(stdscr, y0, x0);
268     while ((code = get_position("First corner", "", which, &x0, &y0)) == 0) {
269 	;
270     }
271 
272     if (code > 0) {
273 	char also[80];
274 	_nc_SPRINTF(also, _nc_SLIMIT(sizeof(also)) " (first %d,%d)", y0, x0);
275 	/* get the position of the opposite corner */
276 	while ((code = get_position("Opposite corner",
277 				    also, which, &x1, &y1)) == 0) {
278 	    ;
279 	}
280 
281 	if (code > 0) {
282 	    int tly = MIN(y0, y1);
283 	    int tlx = MIN(x0, x1);
284 	    PANEL *pan = mkpanel(pair,
285 				 ABS(y1 - y0) + 1,
286 				 ABS(x1 - x0) + 1,
287 				 tly, tlx);
288 	    /* finish */
289 	    myFill(pan);
290 	    pans[which] = pan;
291 	    pflush();
292 	    wmove(stdscr, y1, x1);
293 	}
294     }
295 }
296 
297 static void
my_move_panel(PANEL ** pans,int which,bool continuous)298 my_move_panel(PANEL **pans, int which, bool continuous)
299 {
300     if (pans[which] != 0) {
301 	int code;
302 	int y0, x0;
303 	int y1, x1;
304 	WINDOW *win = panel_window(pans[which]);
305 	char also[80];
306 
307 	getbegyx(win, y0, x0);
308 	_nc_SPRINTF(also, _nc_SLIMIT(sizeof(also)) " (start %d,%d)", y0, x0);
309 	wmove(stdscr, y0, x0);
310 	while ((code = get_position("Move panel", also, which, &x1, &y1)) == 0) {
311 	    if (continuous) {
312 		move_panel(pans[which], y1, x1);
313 		pflush();
314 	    }
315 	}
316 	if (code > 0) {
317 	    move_panel(pans[which], y1, x1);
318 	}
319     }
320 }
321 
322 static void
my_resize_panel(PANEL ** pans,int which,FillPanel myFill)323 my_resize_panel(PANEL **pans, int which, FillPanel myFill)
324 {
325     if (pans[which] != 0) {
326 	int code;
327 	int y0, x0;
328 	int y1, x1;
329 	WINDOW *win = panel_window(pans[which]);
330 	char also[80];
331 
332 	getbegyx(win, y0, x0);
333 	_nc_SPRINTF(also, _nc_SLIMIT(sizeof(also)) " (start %d,%d)", y0, x0);
334 	wmove(stdscr, y0, x0);
335 	while ((code = get_position("Resize panel",
336 				    also, which, &x1, &y1)) == 0) {
337 	    ;
338 	}
339 	if (code > 0) {
340 	    WINDOW *next = newwin(ABS(y1 - y0) + 1,
341 				  ABS(x1 - x0) + 1,
342 				  MIN(y0, y1),
343 				  MIN(x0, x1));
344 	    if (next != 0) {
345 		keypad(next, TRUE);
346 		if (use_colors) {
347 		    wbkgdset(next, (chtype) (COLOR_PAIR(which) | ' '));
348 		} else if (!unboxed) {
349 		    wbkgdset(next, A_BOLD | ' ');
350 		}
351 		replace_panel(pans[which], next);
352 		myFill(pans[which]);
353 		delwin(win);
354 	    }
355 	}
356     }
357 }
358 
359 static void
init_panel(void)360 init_panel(void)
361 {
362     register int y, x;
363 
364     for (y = 0; y < LINES - 1; y++) {
365 	for (x = 0; x < COLS; x++)
366 	    wprintw(stdscr, "%d", (y + x) % 10);
367     }
368 }
369 
370 static void
fill_panel(PANEL * pan)371 fill_panel(PANEL *pan)
372 {
373     WINDOW *win = panel_window(pan);
374     const char *userptr = (const char *) panel_userptr(pan);
375     int num = (userptr && *userptr) ? userptr[1] : '?';
376     int y, x;
377 
378     wmove(win, 1, 1);
379     wprintw(win, "-pan%c-", num);
380     wclrtoeol(win);
381     box(win, 0, 0);
382     for (y = 2; y < getmaxy(win) - 1; y++) {
383 	for (x = 1; x < getmaxx(win) - 1; x++) {
384 	    wmove(win, y, x);
385 	    waddch(win, UChar(num));
386 	}
387     }
388 }
389 
390 static void
fill_unboxed(PANEL * pan)391 fill_unboxed(PANEL *pan)
392 {
393     WINDOW *win = panel_window(pan);
394     const char *userptr = (const char *) panel_userptr(pan);
395     int num = (userptr && *userptr) ? userptr[1] : '?';
396     int y, x;
397 
398     for (y = 0; y < getmaxy(win); y++) {
399 	for (x = 0; x < getmaxx(win); x++) {
400 	    wmove(win, y, x);
401 	    waddch(win, UChar(num));
402 	}
403     }
404 }
405 
406 #if USE_WIDEC_SUPPORT
407 static void
make_fullwidth_digit(cchar_t * target,int digit)408 make_fullwidth_digit(cchar_t *target, int digit)
409 {
410     wchar_t source[2];
411 
412     source[0] = (wchar_t) (digit + 0xff10);
413     source[1] = 0;
414     setcchar(target, source, A_NORMAL, 0, 0);
415 }
416 
417 static void
init_wide_panel(void)418 init_wide_panel(void)
419 {
420     int digit;
421     cchar_t temp[10];
422 
423     for (digit = 0; digit < 10; ++digit)
424 	make_fullwidth_digit(&temp[digit], digit);
425 
426     do {
427 	int y, x;
428 	getyx(stdscr, y, x);
429 	digit = (y + x / 2) % 10;
430     } while (add_wch(&temp[digit]) != ERR);
431 }
432 
433 static void
fill_wide_panel(PANEL * pan)434 fill_wide_panel(PANEL *pan)
435 {
436     WINDOW *win = panel_window(pan);
437     int num = ((const char *) panel_userptr(pan))[1];
438     int y, x;
439 
440     wmove(win, 1, 1);
441     wprintw(win, "-pan%c-", num);
442     wclrtoeol(win);
443     box(win, 0, 0);
444     for (y = 2; y < getmaxy(win) - 1; y++) {
445 	for (x = 1; x < getmaxx(win) - 1; x++) {
446 	    wmove(win, y, x);
447 	    waddch(win, UChar(num));
448 	}
449     }
450 }
451 #endif
452 
453 #define MAX_PANELS 5
454 
455 static int
which_panel(PANEL * px[MAX_PANELS+1],PANEL * pan)456 which_panel(PANEL *px[MAX_PANELS + 1], PANEL *pan)
457 {
458     int result = 0;
459     int j;
460 
461     for (j = 1; j <= MAX_PANELS; ++j) {
462 	if (px[j] == pan) {
463 	    result = j;
464 	    break;
465 	}
466     }
467     return result;
468 }
469 
470 static void
show_help(WINDOW * win)471 show_help(WINDOW *win)
472 {
473     static const char *help[] =
474     {
475 	"",
476 	"Commands are letter/digit pairs.  Digits are the panel number.",
477 	"",
478 	"  b - put the panel on the bottom of the stack",
479 	"  c - create the panel",
480 	"  d - delete the panel",
481 	"  h - hide the panel",
482 	"  m - move the panel (M for continuous move)",
483 	"  r - resize the panel",
484 	"  s - show the panel",
485 	"  t - put the panel on the top of the stack"
486     };
487     int j;
488 
489     for (j = 0; j < (int) SIZEOF(help); ++j) {
490 	if (wprintw(win, "%s\n", help[j]) == ERR)
491 	    break;
492     }
493 }
494 
495 static void
show_panels(PANEL * px[MAX_PANELS+1])496 show_panels(PANEL *px[MAX_PANELS + 1])
497 {
498     struct {
499 	bool valid;
500 	bool hidden;
501 	PANEL *above;
502 	PANEL *below;
503     } table[MAX_PANELS + 1];
504 
505     WINDOW *win;
506     int j;
507 
508     memset(table, 0, sizeof(table));
509     for (j = 1; j <= MAX_PANELS; ++j) {
510 	table[j].valid = (px[j] != 0);
511 	if (table[j].valid) {
512 	    table[j].hidden = panel_hidden(px[j]);
513 	    table[j].above = panel_above(px[j]);
514 	    table[j].below = panel_below(px[j]);
515 	}
516     }
517 
518     if ((win = newwin(LINES - 1, COLS, 0, 0)) != 0) {
519 	PANEL *pan;
520 
521 	keypad(win, TRUE);
522 	if ((pan = new_panel(win)) != 0) {
523 	    werase(win);
524 	    MvWPrintw(win, 0, 0, "Panels:\n");
525 	    for (j = 1; j <= MAX_PANELS; ++j) {
526 		if (table[j].valid) {
527 		    wprintw(win, " %d:", j);
528 		    if (table[j].hidden) {
529 			waddstr(win, " hidden");
530 		    } else {
531 			if (table[j].above) {
532 			    wprintw(win, " above %d",
533 				    which_panel(px, table[j].above));
534 			}
535 			if (table[j].below) {
536 			    wprintw(win, "%s below %d",
537 				    table[j].above ? "," : "",
538 				    which_panel(px, table[j].below));
539 			}
540 		    }
541 		    waddch(win, '\n');
542 		}
543 	    }
544 	    show_help(win);
545 	    wgetch(win);
546 	    del_panel(pan);
547 	    pflush();
548 	}
549 	delwin(win);
550     }
551 }
552 
553 #define wrapper(func) \
554 static int my_##func(PANEL *pan) \
555 { \
556     int code = ERR; \
557     if (pan != 0) { \
558 	code = func(pan); \
559     } \
560     return code; \
561 }
562 /* *INDENT-OFF* */
563 wrapper(bottom_panel)
wrapper(hide_panel)564 wrapper(hide_panel)
565 wrapper(show_panel)
566 wrapper(top_panel)
567 /* *INDENT-ON* */
568 
569 static void
570 do_panel(PANEL *px[MAX_PANELS + 1],
571 	 NCURSES_CONST char *cmd,
572 	 FillPanel myFill)
573 {
574     int which = cmd[1] - '0';
575 
576     if (which < 1 || which > MAX_PANELS) {
577 	beep();
578 	return;
579     }
580 
581     if (log_in != 0) {
582 	pflush();
583     }
584 
585     saywhat(cmd);
586     switch (*cmd) {
587     case 'b':
588 	my_bottom_panel(px[which]);
589 	break;
590     case 'c':
591 	my_create_panel(px, which, myFill);
592 	break;
593     case 'd':
594 	my_remove_panel(px, which);
595 	break;
596     case 'h':
597 	my_hide_panel(px[which]);
598 	break;
599     case 'm':
600 	my_move_panel(px, which, FALSE);
601 	break;
602     case 'M':
603 	my_move_panel(px, which, TRUE);
604 	break;
605     case 'r':
606 	my_resize_panel(px, which, myFill);
607 	break;
608     case 's':
609 	my_show_panel(px[which]);
610 	break;
611     case 't':
612 	my_top_panel(px[which]);
613 	break;
614     }
615 }
616 
617 static bool
ok_letter(int ch)618 ok_letter(int ch)
619 {
620     return isalpha(UChar(ch)) && strchr("bcdhmMrst", ch) != 0;
621 }
622 
623 static bool
ok_digit(int ch)624 ok_digit(int ch)
625 {
626     return isdigit(UChar(ch)) && (ch >= '1') && (ch - '0' <= MAX_PANELS);
627 }
628 
629 /*
630  * A command consists of one or more letter/digit pairs separated by a space.
631  * Digits are limited to 1..MAX_PANELS.
632  *
633  * End the command with a newline.  Reject other characters.
634  */
635 static bool
get_command(PANEL * px[MAX_PANELS+1],char * buffer,int limit)636 get_command(PANEL *px[MAX_PANELS + 1], char *buffer, int limit)
637 {
638     int length = 0;
639     int y0, x0;
640     WINDOW *win;
641 
642     getyx(stdscr, y0, x0);
643     win = statusline();
644     waddstr(win, "Command:");
645     buffer[length = 0] = '\0';
646 
647     if (log_in != 0) {
648 	if (fgets(buffer, limit - 3, log_in) != 0) {
649 	    length = (int) strlen(buffer);
650 	    while (length > 0 && isspace(UChar(buffer[length - 1])))
651 		buffer[--length] = '\0';
652 	    waddstr(win, buffer);
653 	} else {
654 	    close_input();
655 	}
656 	(void) wgetch(win);
657     } else {
658 	int c0 = 0;
659 	for (;;) {
660 	    int ch = wgetch(win);
661 	    if (ch == ERR || ch == QUIT || ch == ESCAPE) {
662 		buffer[0] = '\0';
663 		break;
664 	    } else if (ch == CTRL('L')) {
665 		wrefresh(curscr);
666 	    } else if (ch == '\n' || ch == KEY_ENTER) {
667 		break;
668 	    } else if (ch == HELP_KEY_1) {
669 		show_panels(px);
670 	    } else if (length + 3 < limit) {
671 		if (ch >= KEY_MIN) {
672 		    beep();
673 		} else if (ok_letter(UChar(ch))) {
674 		    if (isalpha(UChar(c0))) {
675 			beep();
676 		    } else if (isdigit(UChar(c0))) {
677 			wprintw(win, " %c", ch);
678 			buffer[length++] = ' ';
679 			buffer[length++] = (char) (c0 = ch);
680 		    } else {
681 			wprintw(win, "%c", ch);
682 			buffer[length++] = (char) (c0 = ch);
683 		    }
684 		} else if (ok_digit(ch)) {
685 		    if (isalpha(UChar(c0))) {
686 			wprintw(win, "%c", ch);
687 			buffer[length++] = (char) (c0 = ch);
688 		    } else {
689 			beep();
690 		    }
691 		} else if (ch == ' ') {
692 		    if (isdigit(UChar(c0))) {
693 			wprintw(win, "%c", ch);
694 			buffer[length++] = (char) (c0 = ch);
695 		    } else {
696 			beep();
697 		    }
698 		} else {
699 		    beep();
700 		}
701 	    } else {
702 		beep();
703 	    }
704 	}
705     }
706 
707     wmove(stdscr, y0, x0);
708 
709     buffer[length] = '\0';
710     if (log_out && length) {
711 	fprintf(log_out, "%s\n", buffer);
712     }
713     return (length != 0);
714 }
715 
716 static void
demo_panels(InitPanel myInit,FillPanel myFill)717 demo_panels(InitPanel myInit, FillPanel myFill)
718 {
719     int itmp;
720     PANEL *px[MAX_PANELS + 1];
721     char buffer[BUFSIZ];
722 
723     scrollok(stdscr, FALSE);	/* we don't want stdscr to scroll! */
724     refresh();
725 
726     myInit();
727     memset(px, 0, sizeof(px));
728 
729     while (get_command(px, buffer, sizeof(buffer))) {
730 	int limit = (int) strlen(buffer);
731 	for (itmp = 0; itmp < limit; itmp += 3) {
732 	    do_panel(px, buffer + itmp, myFill);
733 	}
734 	pflush();
735     }
736 #if NO_LEAKS
737     for (itmp = 1; itmp <= MAX_PANELS; ++itmp) {
738 	my_remove_panel(px, itmp);
739     }
740 #endif
741 }
742 
743 static void
usage(int ok)744 usage(int ok)
745 {
746     static const char *const tbl[] =
747     {
748 	"Usage: demo_panels [options]"
749 	,""
750 	,USAGE_COMMON
751 	,"Options:"
752 	," -i file  read commands from file"
753 	," -o file  record commands in file"
754 	," -m       do not use colors"
755 #if USE_WIDEC_SUPPORT
756 	," -w       use wide-characters in panels and background"
757 #endif
758 	," -x       do not enclose panels in boxes"
759     };
760     size_t n;
761     for (n = 0; n < SIZEOF(tbl); n++)
762 	fprintf(stderr, "%s\n", tbl[n]);
763     ExitProgram(ok ? EXIT_SUCCESS : EXIT_FAILURE);
764 }
765 /* *INDENT-OFF* */
VERSION_COMMON()766 VERSION_COMMON()
767 /* *INDENT-ON* */
768 
769 int
770 main(int argc, char *argv[])
771 {
772     int ch;
773     bool monochrome = FALSE;
774     InitPanel myInit = init_panel;
775     FillPanel myFill = fill_panel;
776 
777     setlocale(LC_ALL, "");
778 
779     while ((ch = getopt(argc, argv, OPTS_COMMON "i:o:mwx")) != -1) {
780 	switch (ch) {
781 	case 'i':
782 	    log_in = fopen(optarg, "r");
783 	    break;
784 	case 'o':
785 	    log_out = fopen(optarg, "w");
786 	    break;
787 	case 'm':
788 	    monochrome = TRUE;
789 	    break;
790 #if USE_WIDEC_SUPPORT
791 	case 'w':
792 	    myInit = init_wide_panel;
793 	    myFill = fill_wide_panel;
794 	    break;
795 #endif
796 	case 'x':
797 	    unboxed = TRUE;
798 	    break;
799 	case OPTS_VERSION:
800 	    show_version(argv);
801 	    ExitProgram(EXIT_SUCCESS);
802 	default:
803 	    usage(ch == OPTS_USAGE);
804 	    /* NOTREACHED */
805 	}
806     }
807     if (unboxed)
808 	myFill = fill_unboxed;
809 
810     initscr();
811     cbreak();
812     noecho();
813     keypad(stdscr, TRUE);
814 
815     use_colors = monochrome ? FALSE : has_colors();
816     if (use_colors)
817 	start_color();
818 
819     demo_panels(myInit, myFill);
820     endwin();
821 
822     close_input();
823     close_output();
824 
825     ExitProgram(EXIT_SUCCESS);
826 }
827 #else
828 int
main(void)829 main(void)
830 {
831     printf("This program requires the curses panel library\n");
832     ExitProgram(EXIT_FAILURE);
833 }
834 #endif
835