ncurses 6.2 - patch 20200301
[ncurses.git] / test / redraw.c
1 /****************************************************************************
2  * Copyright 2020 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.11 2020/02/02 23:34:34 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 ch, y, x;
86     int max_y, max_x;
87     int beg_y, beg_x;
88
89     assert(win != 0);
90
91     scrollok(win, TRUE);
92     keypad(win, TRUE);
93     getmaxyx(win, max_y, max_x);
94     getbegyx(win, beg_y, beg_x);
95     while (!done) {
96         ch = wgetch(win);
97         getyx(win, y, x);
98         switch (ch) {
99         case 'q':
100             /* FALLTHRU */
101         case QUIT:
102         case ESCAPE:
103             done = TRUE;
104             break;
105         case 'w':
106             win1 = newwin(max_y, max_x,
107                           beg_y, beg_x);
108             win2 = newwin(max_y - 2, max_x - 2,
109                           beg_y + 1, beg_x + 1);
110             box(win1, 0, 0);
111             wrefresh(win1);
112
113             test_redraw(win2);
114
115             delwin(win2);
116             delwin(win1);
117
118             touchwin(win);
119             break;
120
121         case '!':
122             /*
123              * redrawwin() and wredrawln() do not take into account the
124              * possibility that the cursor may have moved.  That makes them
125              * cumbersome for using with a shell command.  So we simply
126              * trash the current line of the window using backspace/overwrite.
127              */
128             trash(beg_x, max_x, x + beg_x);
129             break;
130
131 #ifdef NCURSES_VERSION
132         case '@':
133             /*
134              * For a shell command, we can work around the problem noted above
135              * using mvcur().  It is ifdef'd for NCURSES, since X/Open does
136              * not define the case where the old location is unknown. 
137              */
138             IGNORE_RC(system("date"));
139             mvcur(-1, -1, y, x);
140             break;
141 #endif
142
143         case CTRL('W'):
144             redrawwin(win);
145             break;
146
147         case CTRL('L'):
148             wredrawln(win, y, 1);
149             break;
150
151         case KEY_UP:
152             if (y > 0)
153                 wmove(win, y - 1, x);
154             break;
155
156         case KEY_DOWN:
157             if (y < max_y)
158                 wmove(win, y + 1, x);
159             break;
160
161         case KEY_LEFT:
162             if (x > 0)
163                 wmove(win, y, x - 1);
164             break;
165
166         case KEY_RIGHT:
167             if (x < max_x)
168                 wmove(win, y, x + 1);
169             break;
170
171         case HELP_KEY_1:
172             popup_msg(win, help);
173             break;
174
175         default:
176             if (ch > KEY_MIN) {
177                 waddstr(win, keyname(ch));
178                 waddch(win, '\n');
179             } else {
180                 waddstr(win, unctrl(UChar(ch)));
181             }
182             break;
183         }
184         wnoutrefresh(win);
185         doupdate();
186     }
187 }
188
189 static void
190 usage(void)
191 {
192     static const char *tbl[] =
193     {
194         "Usage: redraw [options]"
195         ,""
196         ,"Options:"
197         ,"  -e      use stderr (default stdout)"
198         ,"  -n      do not initialize terminal"
199     };
200     unsigned n;
201     for (n = 0; n < SIZEOF(tbl); ++n)
202         fprintf(stderr, "%s\n", tbl[n]);
203     ExitProgram(EXIT_FAILURE);
204 }
205
206 int
207 main(int argc GCC_UNUSED, char *argv[]GCC_UNUSED)
208 {
209     int ch;
210     bool no_init = FALSE;
211     FILE *my_fp = stdout;
212
213     while ((ch = getopt(argc, argv, "en")) != -1) {
214         switch (ch) {
215         case 'e':
216             my_fp = stderr;
217             break;
218         case 'n':
219             no_init = TRUE;
220             break;
221         default:
222             usage();
223             break;
224         }
225     }
226     if (optind < argc)
227         usage();
228
229     if (no_init) {
230         START_TRACE();
231     } else {
232         newterm((char *) 0, my_fp, stdin);
233     }
234
235     raw();
236     noecho();
237     test_redraw(stdscr);
238     endwin();
239     ExitProgram(EXIT_SUCCESS);
240 }