63b7f586a714e22cbed41163d0cecdc5983b001c
[ncurses.git] / test / test_opaque.c
1 /****************************************************************************
2  * Copyright (c) 2007 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: test_opaque.c,v 1.4 2007/08/18 17:51:51 tom Exp $
30  *
31  * Author: Thomas E Dickey
32  *
33  * Demonstrate the opaque functions from the curses library.
34
35        WINDOW * wgetparent (const WINDOW *);
36        bool is_cleared(const WINDOW *win);
37        bool is_idcok(const WINDOW *win);
38        bool is_idlok(const WINDOW *win);
39        bool is_immedok(const WINDOW *win);
40        bool is_keypad(const WINDOW *win);
41        bool is_leaveok(const WINDOW *win);
42        bool is_nodelay(const WINDOW *win);
43        bool is_notimeout(const WINDOW *win);
44        bool is_scrollok(const WINDOW *win);
45        bool is_syncok(const WINDOW *win);
46        int wgetscrreg (const WINDOW *, int *, int *);
47  */
48
49 #include <test.priv.h>
50
51 #define BASE_Y 6
52 #define MAX_COLS 1024
53
54 static bool
55 Quit(int ch)
56 {
57     return (ch == 'q' || ch == QUIT || ch == ESCAPE);
58 }
59
60 typedef bool(*BoolOpaque) (WINDOW *, int);
61
62 static bool
63 test_opaque_cleared(WINDOW *win, int mode)
64 {
65     if (mode >= 0) {
66         if (mode)
67             wclear(win);
68     }
69     return is_cleared(win);
70 }
71
72 static bool
73 test_opaque_idcok(WINDOW *win, int mode)
74 {
75     if (mode >= 0) {
76         idcok(win, mode);
77     }
78     return is_idcok(win);
79 }
80
81 static bool
82 test_opaque_idlok(WINDOW *win, int mode)
83 {
84     if (mode >= 0) {
85         idlok(win, mode);
86     }
87     return is_idlok(win);
88 }
89
90 static bool
91 test_opaque_immedok(WINDOW *win, int mode)
92 {
93     if (mode >= 0) {
94         immedok(win, mode);
95     }
96     return is_immedok(win);
97 }
98
99 static bool
100 test_opaque_keypad(WINDOW *win, int mode)
101 {
102     if (mode >= 0) {
103         keypad(win, mode);
104     }
105     return is_keypad(win);
106 }
107
108 static bool
109 test_opaque_leaveok(WINDOW *win, int mode)
110 {
111     if (mode >= 0) {
112         leaveok(win, mode);
113     }
114     return is_leaveok(win);
115 }
116
117 static bool
118 test_opaque_nodelay(WINDOW *win, int mode)
119 {
120     if (mode >= 0) {
121         nodelay(win, mode);
122     }
123     return is_nodelay(win);
124 }
125
126 static bool
127 test_opaque_notimeout(WINDOW *win, int mode)
128 {
129     if (mode >= 0) {
130         notimeout(win, mode);
131     }
132     return is_notimeout(win);
133 }
134
135 static bool
136 test_opaque_scrollok(WINDOW *win, int mode)
137 {
138     if (mode >= 0) {
139         scrollok(win, mode);
140     }
141     return is_scrollok(win);
142 }
143
144 static bool
145 test_opaque_syncok(WINDOW *win, int mode)
146 {
147     if (mode >= 0) {
148         syncok(win, mode);
149     }
150     return is_syncok(win);
151 }
152
153 static int
154 status_y(WINDOW *stswin, int cell)
155 {
156     return (cell % getmaxy(stswin));
157 }
158
159 static int
160 status_x(WINDOW *stswin, int cell)
161 {
162     return (15 * (cell / getmaxy(stswin)));
163 }
164
165 static void
166 to_keyword(WINDOW *stswin, int cell)
167 {
168     wmove(stswin, status_y(stswin, cell), status_x(stswin, cell));
169 }
170
171 static void
172 to_result(WINDOW *stswin, int cell, bool before)
173 {
174     int y = status_y(stswin, cell);
175     int x = status_x(stswin, cell) + 11;
176     if (!before)
177         ++x;
178     wmove(stswin, y, x);
179 }
180
181 static void
182 show_keyword(WINDOW *stswin, int cell, int active, const char *name)
183 {
184     to_keyword(stswin, cell);
185     if (active == cell)
186         wstandout(stswin);
187     wprintw(stswin, "%s:", name);
188     if (active == cell)
189         wstandend(stswin);
190 }
191 /* *INDENT-OFF* */
192 static struct {
193     const char *name;
194     BoolOpaque func;
195 } bool_funcs[] = {
196     { "cleared",   test_opaque_cleared },
197     { "idcok",     test_opaque_idcok },
198     { "idlok",     test_opaque_idlok },
199     { "immedok",   test_opaque_immedok },
200     { "keypad",    test_opaque_keypad },
201     { "leaveok",   test_opaque_leaveok },
202     { "nodelay",   test_opaque_nodelay },
203     { "notimeout", test_opaque_notimeout },
204     { "scrollok",  test_opaque_scrollok },
205     { "syncok",    test_opaque_syncok }
206 };
207 /* *INDENT-ON* */
208
209 /*
210  * Display and/or allow update for the properties accessed in the opaque
211  * window.  Some may change state after refreshing the window, so we
212  * distinguish between them using the 'before' parameter.
213  */
214 static int
215 show_opaque(WINDOW *stswin, WINDOW *txtwin, bool before, int active)
216 {
217     int n;
218     int top, bottom;
219
220     if (before) {
221         werase(stswin);
222     }
223     for (n = 0; n < (int) SIZEOF(bool_funcs); ++n) {
224         show_keyword(stswin, n, active, bool_funcs[n].name);
225
226         to_result(stswin, n, before);
227         wprintw(stswin, "%c", bool_funcs[n].func(txtwin, -1) ? 'T' : 'F');
228     }
229
230     show_keyword(stswin, n, active, "wgetparent");
231     to_result(stswin, n, TRUE);
232     wprintw(stswin, "%p", wgetparent(txtwin));
233
234     ++n;
235     show_keyword(stswin, n, active, "wgetscrreg");
236     to_result(stswin, n, TRUE);
237     if (wgetscrreg(txtwin, &top, &bottom) == OK)
238         wprintw(stswin, "%d,%d", top, bottom);
239
240     wnoutrefresh(stswin);
241     return active;
242 }
243
244 static int
245 test_opaque(int level, char **argv, WINDOW *stswin)
246 {
247     WINDOW *txtbox = 0;
248     WINDOW *txtwin = 0;
249     FILE *fp;
250     int ch;
251     int txt_x = 0, txt_y = 0;
252     int base_y;
253     bool in_status = FALSE;
254     int active = 0;
255
256     if (argv[level] == 0) {
257         beep();
258         return FALSE;
259     }
260
261     if (level > 1) {
262         txtbox = newwin(LINES - BASE_Y, COLS - level, BASE_Y, level);
263         box(txtbox, 0, 0);
264         wnoutrefresh(txtbox);
265
266         txtwin = derwin(txtbox,
267                         getmaxy(txtbox) - 2,
268                         getmaxx(txtbox) - 2,
269                         1, 1);
270         base_y = 0;
271     } else {
272         txtwin = stdscr;
273         base_y = BASE_Y;
274     }
275
276     keypad(txtwin, TRUE);       /* enable keyboard mapping */
277     (void) cbreak();            /* take input chars one at a time, no wait for \n */
278     (void) noecho();            /* don't echo input */
279
280     txt_y = base_y;
281     txt_x = 0;
282     wmove(txtwin, txt_y, txt_x);
283
284     if ((fp = fopen(argv[level], "r")) != 0) {
285         while ((ch = fgetc(fp)) != EOF) {
286             if (waddch(txtwin, UChar(ch)) != OK) {
287                 break;
288             }
289         }
290         fclose(fp);
291     } else {
292         wprintw(txtwin, "Cannot open:\n%s", argv[1]);
293     }
294
295     for (;;) {
296         if (in_status) {
297             to_keyword(stswin, active);
298
299             ch = wgetch(stswin);
300             show_opaque(stswin, txtwin, TRUE, active);
301             if (Quit(ch))
302                 break;
303
304             switch (ch) {
305             case '\t':
306                 in_status = FALSE;
307                 break;
308             case KEY_DOWN:
309             case 'j':
310                 if (active < (int) SIZEOF(bool_funcs) - 1)
311                     active++;
312                 else
313                     beep();
314                 break;
315             case KEY_UP:
316             case 'k':
317                 if (active > 0)
318                     active--;
319                 else
320                     beep();
321                 break;
322             case ' ':
323                 bool_funcs[active].func(txtwin,
324                                                                          !bool_funcs[active].func(txtwin, -1));
325                 break;
326             default:
327                 beep();
328                 break;
329             }
330             show_opaque(stswin, txtwin, FALSE, in_status ? active : -1);
331         } else {
332             ch = mvwgetch(txtwin, txt_y, txt_x);
333             show_opaque(stswin, txtwin, TRUE, -1);
334             if (Quit(ch))
335                 break;
336
337             switch (ch) {
338             case '\t':
339                 in_status = TRUE;
340                 break;
341             case KEY_DOWN:
342             case 'j':
343                 if (txt_y < getmaxy(txtwin) - 1)
344                     txt_y++;
345                 else
346                     beep();
347                 break;
348             case KEY_UP:
349             case 'k':
350                 if (txt_y > base_y)
351                     txt_y--;
352                 else
353                     beep();
354                 break;
355             case KEY_LEFT:
356             case 'h':
357                 if (txt_x > 0)
358                     txt_x--;
359                 else
360                     beep();
361                 break;
362             case KEY_RIGHT:
363             case 'l':
364                 if (txt_x < getmaxx(txtwin) - 1)
365                     txt_x++;
366                 else
367                     beep();
368                 break;
369             case 'w':
370                 test_opaque(level + 1, argv, stswin);
371                 if (txtbox != 0) {
372                     touchwin(txtbox);
373                     wnoutrefresh(txtbox);
374                 } else {
375                     touchwin(txtwin);
376                     wnoutrefresh(txtwin);
377                 }
378                 break;
379             default:
380                 beep();
381                 napms(100);
382                 break;
383             }
384
385             show_opaque(stswin, txtwin, FALSE, -1);
386         }
387     }
388     if (level > 1) {
389         delwin(txtwin);
390         delwin(txtbox);
391     }
392     return TRUE;
393 }
394
395 int
396 main(int argc, char *argv[])
397 {
398     WINDOW *stsbox;
399     WINDOW *stswin;
400
401     setlocale(LC_ALL, "");
402
403     if (argc < 2) {
404         fprintf(stderr, "usage: %s file\n", argv[0]);
405         return EXIT_FAILURE;
406     }
407
408     initscr();
409
410     stsbox = derwin(stdscr, BASE_Y, COLS, 0, 0);
411     box(stsbox, 0, 0);
412     wnoutrefresh(stsbox);
413
414     stswin = derwin(stsbox, BASE_Y - 2, COLS - 2, 1, 1);
415     keypad(stswin, TRUE);
416
417     test_opaque(1, argv, stswin);
418
419     endwin();
420     ExitProgram(EXIT_SUCCESS);
421 }