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