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