ncurses 6.2 - patch 20210619
[ncurses.git] / test / redraw.c
1 /****************************************************************************
2  * Copyright 2020,2021 Thomas E. Dickey                                     *
3  * Copyright 2006-2012,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: redraw.c,v 1.13 2021/06/17 21:26:02 tom Exp $
31  *
32  * Demonstrate the redrawwin() and wredrawln() functions.
33  * Thomas Dickey - 2006/11/4
34  */
35
36 #include <test.priv.h>
37 #include <popup_msg.h>
38
39 static void
40 trash(int beg_x, int max_x, int cur_x)
41 {
42     int x;
43
44     for (x = cur_x; x > beg_x; --x) {
45         putchar('\b');
46     }
47     for (x = beg_x; x < max_x; ++x) {
48         if (x < cur_x)
49             putchar('<');
50         else if (x == cur_x)
51             putchar('=');
52         else if (x > cur_x)
53             putchar('>');
54     }
55     for (x = max_x; x > cur_x; --x) {
56         putchar('\b');
57     }
58     fflush(stdout);
59 }
60
61 static void
62 test_redraw(WINDOW *win)
63 {
64     static const char *help[] =
65     {
66         "Commands:",
67         "  ^Q/ESC/q   - quit",
68         "  w          - recur in a new window",
69         "  !          - overwrite current line using stdio outside curses.",
70 #ifdef NCURSES_VERSION
71         "  @          - run \"date\" command, to put its output on screen.",
72 #endif
73         "  ^L         - call redrawwin() for current window.",
74         "  ^W         - call wredrawln() for current line/current window.",
75         "  arrow-keys - move cursor on the screen",
76         "",
77         "Other control characters are added to the screen in printable form.",
78         "Other printable characters are added to the screen as is.",
79         0
80     };
81
82     WINDOW *win1;
83     WINDOW *win2;
84     bool done = FALSE;
85     int max_y, max_x;
86     int beg_y, beg_x;
87
88     assert(win != 0);
89
90     scrollok(win, TRUE);
91     keypad(win, TRUE);
92     getmaxyx(win, max_y, max_x);
93     getbegyx(win, beg_y, beg_x);
94
95     while (!done) {
96         int ch = wgetch(win);
97         int y, x;
98
99         getyx(win, y, x);
100         switch (ch) {
101         case 'q':
102             /* FALLTHRU */
103         case QUIT:
104         case ESCAPE:
105             done = TRUE;
106             break;
107         case 'w':
108             win1 = newwin(max_y, max_x,
109                           beg_y, beg_x);
110             win2 = newwin(max_y - 2, max_x - 2,
111                           beg_y + 1, beg_x + 1);
112             box(win1, 0, 0);
113             wrefresh(win1);
114
115             test_redraw(win2);
116
117             delwin(win2);
118             delwin(win1);
119
120             touchwin(win);
121             break;
122
123         case '!':
124             /*
125              * redrawwin() and wredrawln() do not take into account the
126              * possibility that the cursor may have moved.  That makes them
127              * cumbersome for using with a shell command.  So we simply
128              * trash the current line of the window using backspace/overwrite.
129              */
130             trash(beg_x, max_x, x + beg_x);
131             break;
132
133 #ifdef NCURSES_VERSION
134         case '@':
135             /*
136              * For a shell command, we can work around the problem noted above
137              * using mvcur().  It is ifdef'd for NCURSES, since X/Open does
138              * not define the case where the old location is unknown.
139              */
140             IGNORE_RC(system("date"));
141             mvcur(-1, -1, y, x);
142             break;
143 #endif
144
145         case CTRL('W'):
146             redrawwin(win);
147             break;
148
149         case CTRL('L'):
150             wredrawln(win, y, 1);
151             break;
152
153         case KEY_UP:
154             if (y > 0)
155                 wmove(win, y - 1, x);
156             break;
157
158         case KEY_DOWN:
159             if (y < max_y)
160                 wmove(win, y + 1, x);
161             break;
162
163         case KEY_LEFT:
164             if (x > 0)
165                 wmove(win, y, x - 1);
166             break;
167
168         case KEY_RIGHT:
169             if (x < max_x)
170                 wmove(win, y, x + 1);
171             break;
172
173         case HELP_KEY_1:
174             popup_msg(win, help);
175             break;
176
177         default:
178             if (ch > KEY_MIN) {
179                 waddstr(win, keyname(ch));
180                 waddch(win, '\n');
181             } else {
182                 waddstr(win, unctrl(UChar(ch)));
183             }
184             break;
185         }
186         wnoutrefresh(win);
187         doupdate();
188     }
189 }
190
191 static void
192 usage(void)
193 {
194     static const char *tbl[] =
195     {
196         "Usage: redraw [options]"
197         ,""
198         ,"Options:"
199         ,"  -e      use stderr (default stdout)"
200         ,"  -n      do not initialize terminal"
201     };
202     unsigned n;
203     for (n = 0; n < SIZEOF(tbl); ++n)
204         fprintf(stderr, "%s\n", tbl[n]);
205     ExitProgram(EXIT_FAILURE);
206 }
207
208 int
209 main(int argc GCC_UNUSED, char *argv[]GCC_UNUSED)
210 {
211     int ch;
212     bool no_init = FALSE;
213     FILE *my_fp = stdout;
214
215     while ((ch = getopt(argc, argv, "en")) != -1) {
216         switch (ch) {
217         case 'e':
218             my_fp = stderr;
219             break;
220         case 'n':
221             no_init = TRUE;
222             break;
223         default:
224             usage();
225             break;
226         }
227     }
228     if (optind < argc)
229         usage();
230
231     if (no_init) {
232         START_TRACE();
233     } else {
234         newterm((char *) 0, my_fp, stdin);
235     }
236
237     raw();
238     noecho();
239     test_redraw(stdscr);
240     endwin();
241     ExitProgram(EXIT_SUCCESS);
242 }