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