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