1 /****************************************************************************
2 * Copyright (c) 2007-2010,2014 Free Software Foundation, Inc. *
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: *
12 * The above copyright notice and this permission notice shall be included *
13 * in all copies or substantial portions of the Software. *
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. *
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 *
27 ****************************************************************************/
29 * $Id: demo_panels.c,v 1.38 2014/08/02 17:24:07 tom Exp $
31 * Demonstrate a variety of functions from the panel library.
34 #include <test.priv.h>
43 typedef void (*InitPanel
) (void);
44 typedef void (*FillPanel
) (PANEL
*);
46 static bool use_colors
= FALSE
;
47 static bool unboxed
= FALSE
;
72 WINDOW
*result
= stdscr
;
74 wmove(result
, LINES
- 1, 0);
87 saywhat(NCURSES_CONST
char *text
)
89 WINDOW
*win
= statusline();
90 if (text
!= 0 && *text
!= '\0') {
94 waddstr(win
, "press any key to continue");
98 show_position(NCURSES_CONST
char *text
,
99 NCURSES_CONST
char *also
,
104 WINDOW
*win
= statusline();
106 wprintw(win
, "%s for panel %d now %d,%d%s", text
, which
, ypos
, xpos
, also
);
107 wmove(stdscr
, ypos
, xpos
);
111 get_position(NCURSES_CONST
char *text
,
112 NCURSES_CONST
char *also
,
121 getyx(stdscr
, y1
, x1
);
124 show_position(text
, also
, which
, y1
, x1
);
127 if (fscanf(log_in
, "%c%d,%d\n", &cmd
, &y1
, &x1
) == 3) {
131 (void) wgetch(stdscr
);
147 switch (wgetch(stdscr
)) {
164 if (y1
< getmaxy(stdscr
)) {
178 if (x1
< getmaxx(stdscr
)) {
187 wmove(stdscr
, y1
, x1
);
193 fprintf(log_out
, "%c%d,%d\n",
203 mkpanel(short color
, int rows
, int cols
, int tly
, int tlx
)
207 char *userdata
= typeMalloc(char, 3);
209 if ((win
= newwin(rows
, cols
, tly
, tlx
)) != 0) {
211 if ((pan
= new_panel(win
)) == 0) {
213 } else if (use_colors
) {
214 short fg
= (short) ((color
== COLOR_BLUE
)
219 init_pair(color
, fg
, bg
);
220 wbkgdset(win
, (chtype
) (COLOR_PAIR(color
) | ' '));
221 } else if (!unboxed
) {
222 wbkgdset(win
, A_BOLD
| ' ');
225 sprintf(userdata
, "p%d", color
% 8);
226 set_panel_userptr(pan
, (NCURSES_CONST
void *) userdata
);
231 my_remove_panel(PANEL
** pans
, int which
)
233 if (pans
[which
] != 0) {
234 PANEL
*pan
= pans
[which
];
235 WINDOW
*win
= panel_window(pan
);
236 char *user
= (char *) panel_userptr(pan
);
247 #define MIN(a,b) ((a) < (b) ? (a) : (b))
248 #define ABS(a) ((a) < 0 ? -(a) : (a))
251 my_create_panel(PANEL
** pans
, int which
, FillPanel myFill
)
255 short pair
= (short) which
;
256 short fg
= (short) ((pair
== COLOR_BLUE
) ? COLOR_WHITE
: COLOR_BLACK
);
260 init_pair(pair
, fg
, bg
);
262 /* remove the old panel, if any */
263 my_remove_panel(pans
, which
);
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) {
274 sprintf(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) {
282 int tly
= MIN(y0
, y1
);
283 int tlx
= MIN(x0
, x1
);
284 pan
= mkpanel(pair
, ABS(y1
- y0
) + 1, ABS(x1
- x0
) + 1, tly
, tlx
);
289 wmove(stdscr
, y1
, x1
);
295 my_move_panel(PANEL
** pans
, int which
, bool continuous
)
297 if (pans
[which
] != 0) {
301 WINDOW
*win
= panel_window(pans
[which
]);
304 getbegyx(win
, y0
, x0
);
305 sprintf(also
, " (start %d,%d)", y0
, x0
);
306 wmove(stdscr
, y0
, x0
);
307 while ((code
= get_position("Move panel", also
, which
, &x1
, &y1
)) == 0) {
309 move_panel(pans
[which
], y1
, x1
);
314 move_panel(pans
[which
], y1
, x1
);
320 my_resize_panel(PANEL
** pans
, int which
, FillPanel myFill
)
322 if (pans
[which
] != 0) {
326 WINDOW
*win
= panel_window(pans
[which
]);
329 getbegyx(win
, y0
, x0
);
330 sprintf(also
, " (start %d,%d)", y0
, x0
);
331 wmove(stdscr
, y0
, x0
);
332 while ((code
= get_position("Resize panel",
333 also
, which
, &x1
, &y1
)) == 0) {
337 WINDOW
*next
= newwin(ABS(y1
- y0
) + 1,
344 wbkgdset(next
, (chtype
) (COLOR_PAIR(which
) | ' '));
345 } else if (!unboxed
) {
346 wbkgdset(next
, A_BOLD
| ' ');
348 replace_panel(pans
[which
], next
);
361 for (y
= 0; y
< LINES
- 1; y
++) {
362 for (x
= 0; x
< COLS
; x
++)
363 wprintw(stdscr
, "%d", (y
+ x
) % 10);
368 fill_panel(PANEL
* pan
)
370 WINDOW
*win
= panel_window(pan
);
371 const char *userptr
= (const char *) panel_userptr(pan
);
372 int num
= (userptr
&& *userptr
) ? userptr
[1] : '?';
376 wprintw(win
, "-pan%c-", num
);
379 for (y
= 2; y
< getmaxy(win
) - 1; y
++) {
380 for (x
= 1; x
< getmaxx(win
) - 1; x
++) {
382 waddch(win
, UChar(num
));
388 fill_unboxed(PANEL
* pan
)
390 WINDOW
*win
= panel_window(pan
);
391 const char *userptr
= (const char *) panel_userptr(pan
);
392 int num
= (userptr
&& *userptr
) ? userptr
[1] : '?';
395 for (y
= 0; y
< getmaxy(win
); y
++) {
396 for (x
= 0; x
< getmaxx(win
); x
++) {
398 waddch(win
, UChar(num
));
403 #if USE_WIDEC_SUPPORT
405 make_fullwidth_digit(cchar_t
*target
, int digit
)
409 source
[0] = (wchar_t) (digit
+ 0xff10);
411 setcchar(target
, source
, A_NORMAL
, 0, 0);
415 init_wide_panel(void)
420 for (digit
= 0; digit
< 10; ++digit
)
421 make_fullwidth_digit(&temp
[digit
], digit
);
426 digit
= (y
+ x
/ 2) % 10;
427 } while (add_wch(&temp
[digit
]) != ERR
);
431 fill_wide_panel(PANEL
* pan
)
433 WINDOW
*win
= panel_window(pan
);
434 int num
= ((const char *) panel_userptr(pan
))[1];
438 wprintw(win
, "-pan%c-", num
);
441 for (y
= 2; y
< getmaxy(win
) - 1; y
++) {
442 for (x
= 1; x
< getmaxx(win
) - 1; x
++) {
444 waddch(win
, UChar(num
));
453 which_panel(PANEL
* px
[MAX_PANELS
+ 1], PANEL
* pan
)
458 for (j
= 1; j
<= MAX_PANELS
; ++j
) {
468 show_panels(PANEL
* px
[MAX_PANELS
+ 1])
470 static const char *help
[] =
473 "Commands are letter/digit pairs. Digits are the panel number.",
475 " b - put the panel on the bottom of the stack",
476 " c - create the panel",
477 " d - delete the panel",
478 " h - hide the panel",
479 " m - move the panel (M for continuous move)",
480 " r - resize the panel",
481 " s - show the panel",
482 " b - put the panel on the top of the stack"
490 } table
[MAX_PANELS
+ 1];
496 memset(table
, 0, sizeof(table
));
497 for (j
= 1; j
<= MAX_PANELS
; ++j
) {
498 table
[j
].valid
= (px
[j
] != 0);
499 if (table
[j
].valid
) {
500 table
[j
].hidden
= panel_hidden(px
[j
]);
501 table
[j
].above
= panel_above(px
[j
]);
502 table
[j
].below
= panel_below(px
[j
]);
506 if ((win
= newwin(LINES
- 1, COLS
, 0, 0)) != 0) {
508 if ((pan
= new_panel(win
)) != 0) {
510 MvWPrintw(win
, 0, 0, "Panels:\n");
511 for (j
= 1; j
<= MAX_PANELS
; ++j
) {
512 if (table
[j
].valid
) {
513 wprintw(win
, " %d:", j
);
514 if (table
[j
].hidden
) {
515 waddstr(win
, " hidden");
517 if (table
[j
].above
) {
518 wprintw(win
, " above %d",
519 which_panel(px
, table
[j
].above
));
521 if (table
[j
].below
) {
522 wprintw(win
, "%s below %d",
523 table
[j
].above
? "," : "",
524 which_panel(px
, table
[j
].below
));
530 for (j
= 0; j
< (int) SIZEOF(help
); ++j
) {
531 if (wprintw(win
, "%s\n", help
[j
]) == ERR
)
542 #define wrapper(func) \
543 static int my_##func(PANEL *pan) \
552 wrapper(bottom_panel
)
559 do_panel(PANEL
* px
[MAX_PANELS
+ 1],
560 NCURSES_CONST
char *cmd
,
563 int which
= cmd
[1] - '0';
565 if (which
< 1 || which
> MAX_PANELS
) {
577 my_bottom_panel(px
[which
]);
580 my_create_panel(px
, which
, myFill
);
583 my_remove_panel(px
, which
);
586 my_hide_panel(px
[which
]);
589 my_move_panel(px
, which
, FALSE
);
592 my_move_panel(px
, which
, TRUE
);
595 my_resize_panel(px
, which
, myFill
);
598 my_show_panel(px
[which
]);
601 my_top_panel(px
[which
]);
609 return isalpha(UChar(ch
)) && strchr("bcdhmMrst", ch
) != 0;
615 return isdigit(UChar(ch
)) && (ch
>= '1') && (ch
- '0' <= MAX_PANELS
);
619 * A command consists of one or more letter/digit pairs separated by a space.
620 * Digits are limited to 1..MAX_PANELS.
622 * End the command with a newline. Reject other characters.
625 get_command(PANEL
* px
[MAX_PANELS
+ 1], char *buffer
, int limit
)
632 getyx(stdscr
, y0
, x0
);
634 waddstr(win
, "Command:");
635 buffer
[length
= 0] = '\0';
638 if (fgets(buffer
, limit
- 3, log_in
) != 0) {
639 length
= (int) strlen(buffer
);
640 while (length
> 0 && isspace(UChar(buffer
[length
- 1])))
641 buffer
[--length
] = '\0';
642 waddstr(win
, buffer
);
651 if (ch
== ERR
|| ch
== QUIT
|| ch
== ESCAPE
) {
654 } else if (ch
== CTRL('L')) {
656 } else if (ch
== '\n' || ch
== KEY_ENTER
) {
658 } else if (ch
== '?') {
660 } else if (length
+ 3 < limit
) {
663 } else if (ok_letter(UChar(ch
))) {
664 if (isalpha(UChar(c0
))) {
666 } else if (isdigit(UChar(c0
))) {
667 wprintw(win
, " %c", ch
);
668 buffer
[length
++] = ' ';
669 buffer
[length
++] = (char) (c0
= ch
);
671 wprintw(win
, "%c", ch
);
672 buffer
[length
++] = (char) (c0
= ch
);
674 } else if (ok_digit(ch
)) {
675 if (isalpha(UChar(c0
))) {
676 wprintw(win
, "%c", ch
);
677 buffer
[length
++] = (char) (c0
= ch
);
681 } else if (ch
== ' ') {
682 if (isdigit(UChar(c0
))) {
683 wprintw(win
, "%c", ch
);
684 buffer
[length
++] = (char) (c0
= ch
);
697 wmove(stdscr
, y0
, x0
);
699 buffer
[length
] = '\0';
700 if (log_out
&& length
) {
701 fprintf(log_out
, "%s\n", buffer
);
703 return (length
!= 0);
707 demo_panels(InitPanel myInit
, FillPanel myFill
)
710 PANEL
*px
[MAX_PANELS
+ 1];
713 scrollok(stdscr
, FALSE
); /* we don't want stdscr to scroll! */
717 memset(px
, 0, sizeof(px
));
719 while (get_command(px
, buffer
, sizeof(buffer
))) {
720 int limit
= (int) strlen(buffer
);
721 for (itmp
= 0; itmp
< limit
; itmp
+= 3) {
722 do_panel(px
, buffer
+ itmp
, myFill
);
727 for (itmp
= 1; itmp
<= MAX_PANELS
; ++itmp
) {
728 my_remove_panel(px
, itmp
);
736 static const char *const tbl
[] =
738 "Usage: demo_panels [options]"
741 ," -i file read commands from file"
742 ," -o file record commands in file"
743 ," -m do not use colors"
744 #if USE_WIDEC_SUPPORT
745 ," -w use wide-characters in panels and background"
747 ," -x do not enclose panels in boxes"
750 for (n
= 0; n
< SIZEOF(tbl
); n
++)
751 fprintf(stderr
, "%s\n", tbl
[n
]);
752 ExitProgram(EXIT_FAILURE
);
756 main(int argc
, char *argv
[])
759 bool monochrome
= FALSE
;
760 InitPanel myInit
= init_panel
;
761 FillPanel myFill
= fill_panel
;
763 setlocale(LC_ALL
, "");
765 while ((c
= getopt(argc
, argv
, "i:o:mwx")) != -1) {
768 log_in
= fopen(optarg
, "r");
771 log_out
= fopen(optarg
, "w");
776 #if USE_WIDEC_SUPPORT
778 myInit
= init_wide_panel
;
779 myFill
= fill_wide_panel
;
790 myFill
= fill_unboxed
;
795 keypad(stdscr
, TRUE
);
797 use_colors
= monochrome
? FALSE
: has_colors();
801 demo_panels(myInit
, myFill
);
807 ExitProgram(EXIT_SUCCESS
);
813 printf("This program requires the curses panel library\n");
814 ExitProgram(EXIT_FAILURE
);