ncurses 6.2 - patch 20200301
[ncurses.git] / test / test_get_wstr.c
1 /****************************************************************************
2  * Copyright 2020 Thomas E. Dickey                                          *
3  * Copyright 2007-2011,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: test_get_wstr.c,v 1.12 2020/02/02 23:34:34 tom Exp $
31  *
32  * Author: Thomas E Dickey
33  *
34  * Demonstrate the get_wstr functions from the curses library.
35
36        int get_wstr(wint_t *wstr);
37        int getn_wstr(wint_t *wstr, int n);
38        int wget_wstr(WINDOW *win, wint_t *wstr);
39        int wgetn_wstr(WINDOW *win, wint_t *wstr, int n);
40        int mvget_wstr(int y, int x, wint_t *wstr);
41        int mvgetn_wstr(int y, int x, wint_t *wstr, int n);
42        int mvwget_wstr(WINDOW *win, int y, int x, wint_t *wstr);
43        int mvwgetn_wstr(WINDOW *win, int y, int x, wint_t *wstr, int n);
44  */
45
46 #include <test.priv.h>
47 #include <popup_msg.h>
48
49 #if HAVE_CHGAT
50 /* NetBSD curses wchgat */
51
52 #if USE_WIDEC_SUPPORT
53
54 #define BASE_Y 6
55 #define MAX_COLS 1024
56
57 typedef enum {
58     eGetStr = 0,
59     eGetNStr,
60     eMvGetStr,
61     eMvGetNStr,
62     eMaxFlavor
63 } Flavors;
64
65 static bool
66 Quit(int ch)
67 {
68     return (ch == ERR || ch == 'q' || ch == QUIT || ch == ESCAPE);
69 }
70
71 static int
72 Remainder(WINDOW *txtwin)
73 {
74     int result = getmaxx(txtwin) - getcurx(txtwin);
75     return (result > 0) ? result : 0;
76 }
77
78 /*
79  * Show a highlighted line in the place where input will happen.
80  */
81 static void
82 ShowPrompt(WINDOW *txtwin, int limit)
83 {
84     wchgat(txtwin, limit, WA_REVERSE, 0, NULL);
85     wnoutrefresh(txtwin);
86 }
87
88 static void
89 MovePrompt(WINDOW *txtwin, int limit, int y, int x)
90 {
91     wchgat(txtwin, Remainder(txtwin), WA_NORMAL, 0, NULL);
92     wmove(txtwin, y, x);
93     ShowPrompt(txtwin, limit);
94 }
95
96 static int
97 ShowFlavor(WINDOW *strwin, WINDOW *txtwin, int flavor, int limit)
98 {
99     const char *name = "?";
100     bool limited = FALSE;
101     bool wins = (txtwin != stdscr);
102     int result;
103
104     switch (flavor) {
105     case eGetStr:
106         name = wins ? "wget_wstr" : "get_wstr";
107         break;
108     case eGetNStr:
109         limited = TRUE;
110         name = wins ? "wgetn_wstr" : "getn_wstr";
111         break;
112     case eMvGetStr:
113         name = wins ? "mvwget_wstr" : "mvget_wstr";
114         break;
115     case eMvGetNStr:
116         limited = TRUE;
117         name = wins ? "mvwgetn_wstr" : "mvgetn_wstr";
118         break;
119     case eMaxFlavor:
120         break;
121     }
122
123     wmove(strwin, 0, 0);
124     werase(strwin);
125
126     if (limited) {
127         wprintw(strwin, "%s(%d):", name, limit);
128     } else {
129         wprintw(strwin, "%s:", name);
130     }
131     result = limited ? limit : Remainder(txtwin);
132     ShowPrompt(txtwin, result);
133
134     wnoutrefresh(strwin);
135     return result;
136 }
137
138 static int
139 recursive_test(int level, char **argv, WINDOW *strwin)
140 {
141     static const char *help[] =
142     {
143         "Commands:",
144         "  q,^Q,ESC       - quit this program",
145         "  ^Q,ESC         - quit help-screen",
146         "",
147         "  p,<Up>         - move beginning of prompt one up row",
148         "  j,<Down>       - move beginning of prompt one down row",
149         "  h,<Left>       - move beginning of prompt one left column",
150         "  l,<Right>      - move beginning of prompt one right column",
151         "",
152         "  -              - reduce getnstr buffer-size one column",
153         "  +              - increase getnstr buffer-size one column",
154         "  :              - prompt for input-text",
155         "",
156         "  <              - scroll \"left\" through getstr-functions",
157         "  >              - scroll \"right\" through getstr-functions",
158         "",
159         "  w              - recur to subwindow",
160         "  ?,<F1>         - show help-screen",
161         0
162     };
163     WINDOW *txtbox = 0;
164     WINDOW *txtwin = 0;
165     FILE *fp;
166     int ch;
167     int rc;
168     int txt_x = 0, txt_y = 0;
169     int base_y;
170     int flavor = 0;
171     int limit = getmaxx(strwin) - 5;
172     int actual;
173     wint_t buffer[MAX_COLS];
174
175     if (argv[level] == 0) {
176         beep();
177         return FALSE;
178     }
179
180     if (level > 1) {
181         txtbox = newwin(LINES - BASE_Y, COLS - level, BASE_Y, level);
182         box(txtbox, 0, 0);
183         wnoutrefresh(txtbox);
184
185         txtwin = derwin(txtbox,
186                         getmaxy(txtbox) - 2,
187                         getmaxx(txtbox) - 2,
188                         1, 1);
189         base_y = 0;
190     } else {
191         txtwin = stdscr;
192         base_y = BASE_Y;
193     }
194
195     keypad(txtwin, TRUE);       /* enable keyboard mapping */
196     (void) cbreak();            /* take input chars one at a time, no wait for \n */
197     (void) noecho();            /* don't echo input */
198
199     txt_y = base_y;
200     txt_x = 0;
201     wmove(txtwin, txt_y, txt_x);
202
203     if ((fp = fopen(argv[level], "r")) != 0) {
204         while ((ch = fgetc(fp)) != EOF) {
205             if (waddch(txtwin, UChar(ch)) != OK) {
206                 break;
207             }
208         }
209         fclose(fp);
210     } else {
211         wprintw(txtwin, "Cannot open:\n%s", argv[1]);
212     }
213
214     wmove(txtwin, txt_y, txt_x);
215     actual = ShowFlavor(strwin, txtwin, flavor, limit);
216     while (!Quit(ch = mvwgetch(txtwin, txt_y, txt_x))) {
217         switch (ch) {
218         case KEY_DOWN:
219         case 'j':
220             if (txt_y < getmaxy(txtwin) - 1) {
221                 MovePrompt(txtwin, actual, ++txt_y, txt_x);
222             } else {
223                 beep();
224             }
225             break;
226         case KEY_UP:
227         case 'k':
228             if (txt_y > base_y) {
229                 MovePrompt(txtwin, actual, --txt_y, txt_x);
230             } else {
231                 beep();
232             }
233             break;
234         case KEY_LEFT:
235         case 'h':
236             if (txt_x > 0) {
237                 MovePrompt(txtwin, actual, txt_y, --txt_x);
238             } else {
239                 beep();
240             }
241             break;
242         case KEY_RIGHT:
243         case 'l':
244             if (txt_x < getmaxx(txtwin) - 1) {
245                 MovePrompt(txtwin, actual, txt_y, ++txt_x);
246             } else {
247                 beep();
248             }
249             break;
250
251         case 'w':
252             recursive_test(level + 1, argv, strwin);
253             if (txtbox != 0) {
254                 touchwin(txtbox);
255                 wnoutrefresh(txtbox);
256             } else {
257                 touchwin(txtwin);
258                 wnoutrefresh(txtwin);
259             }
260             break;
261
262         case '-':
263             if (limit > 0) {
264                 actual = ShowFlavor(strwin, txtwin, flavor, --limit);
265                 MovePrompt(txtwin, actual, txt_y, txt_x);
266             } else {
267                 beep();
268             }
269             break;
270
271         case '+':
272             actual = ShowFlavor(strwin, txtwin, flavor, ++limit);
273             MovePrompt(txtwin, actual, txt_y, txt_x);
274             break;
275
276         case '<':
277             if (flavor > 0) {
278                 actual = ShowFlavor(strwin, txtwin, --flavor, limit);
279                 MovePrompt(txtwin, actual, txt_y, txt_x);
280             } else {
281                 beep();
282             }
283             break;
284
285         case '>':
286             if (flavor + 1 < eMaxFlavor) {
287                 actual = ShowFlavor(strwin, txtwin, ++flavor, limit);
288                 MovePrompt(txtwin, actual, txt_y, txt_x);
289             } else {
290                 beep();
291             }
292             break;
293
294         case ':':
295             actual = ShowFlavor(strwin, txtwin, flavor, limit);
296             *buffer = '\0';
297             rc = ERR;
298             echo();
299             (void) wattrset(txtwin, A_REVERSE);
300             switch (flavor) {
301             case eGetStr:
302                 if (txtwin != stdscr) {
303                     wmove(txtwin, txt_y, txt_x);
304                     rc = wget_wstr(txtwin, buffer);
305                 } else {
306                     move(txt_y, txt_x);
307                     rc = get_wstr(buffer);
308                 }
309                 break;
310             case eGetNStr:
311                 if (txtwin != stdscr) {
312                     wmove(txtwin, txt_y, txt_x);
313                     rc = wgetn_wstr(txtwin, buffer, limit);
314                 } else {
315                     move(txt_y, txt_x);
316                     rc = getn_wstr(buffer, limit);
317                 }
318                 break;
319             case eMvGetStr:
320                 if (txtwin != stdscr) {
321                     rc = mvwget_wstr(txtwin, txt_y, txt_x, buffer);
322                 } else {
323                     rc = mvget_wstr(txt_y, txt_x, buffer);
324                 }
325                 break;
326             case eMvGetNStr:
327                 if (txtwin != stdscr) {
328                     rc = mvwgetn_wstr(txtwin, txt_y, txt_x, buffer, limit);
329                 } else {
330                     rc = mvgetn_wstr(txt_y, txt_x, buffer, limit);
331                 }
332                 break;
333             case eMaxFlavor:
334                 break;
335             }
336             noecho();
337             (void) wattrset(txtwin, A_NORMAL);
338             wprintw(strwin, "%s:", (rc == OK) ? "OK" : "ERR");
339             (void) waddwstr(strwin, (wchar_t *) buffer);
340             wnoutrefresh(strwin);
341             break;
342         case HELP_KEY_1:
343             popup_msg(stdscr, help);
344             break;
345         default:
346             beep();
347             break;
348         }
349         doupdate();
350     }
351     if (level > 1) {
352         delwin(txtwin);
353         delwin(txtbox);
354     }
355     return TRUE;
356 }
357
358 int
359 main(int argc, char *argv[])
360 {
361     WINDOW *chrbox;
362     WINDOW *strwin;
363
364     setlocale(LC_ALL, "");
365
366     if (argc < 2) {
367         fprintf(stderr, "usage: %s file\n", argv[0]);
368         return EXIT_FAILURE;
369     }
370
371     initscr();
372
373     chrbox = derwin(stdscr, BASE_Y, COLS, 0, 0);
374     box(chrbox, 0, 0);
375     wnoutrefresh(chrbox);
376
377     strwin = derwin(chrbox, 4, COLS - 2, 1, 1);
378
379     recursive_test(1, argv, strwin);
380
381     endwin();
382     ExitProgram(EXIT_SUCCESS);
383 }
384 #else
385 int
386 main(void)
387 {
388     printf("This program requires the wide-ncurses library\n");
389     ExitProgram(EXIT_FAILURE);
390 }
391 #endif
392 #else
393 int
394 main(void)
395 {
396     printf("This program requires the curses chgat function\n");
397     ExitProgram(EXIT_FAILURE);
398 }
399 #endif