• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /****************************************************************************
2  * Copyright 2020,2022 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.14 2022/12/10 23:59:13 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
Quit(int ch)66 Quit(int ch)
67 {
68     return (ch == ERR || ch == 'q' || ch == QUIT || ch == ESCAPE);
69 }
70 
71 static int
Remainder(WINDOW * txtwin)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
ShowPrompt(WINDOW * txtwin,int limit)82 ShowPrompt(WINDOW *txtwin, int limit)
83 {
84     wchgat(txtwin, limit, WA_REVERSE, 0, NULL);
85     wnoutrefresh(txtwin);
86 }
87 
88 static void
MovePrompt(WINDOW * txtwin,int limit,int y,int x)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
ShowFlavor(WINDOW * strwin,WINDOW * txtwin,int flavor,int limit)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
recursive_test(int level,char ** argv,WINDOW * strwin)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 static void
usage(int ok)359 usage(int ok)
360 {
361     static const char *msg[] =
362     {
363 	"Usage: test_get_wstr [options] [file1 [...]]"
364 	,""
365 	,USAGE_COMMON
366     };
367     size_t n;
368 
369     for (n = 0; n < SIZEOF(msg); n++)
370 	fprintf(stderr, "%s\n", msg[n]);
371 
372     ExitProgram(ok ? EXIT_SUCCESS : EXIT_FAILURE);
373 }
374 /* *INDENT-OFF* */
VERSION_COMMON()375 VERSION_COMMON()
376 /* *INDENT-ON* */
377 
378 int
379 main(int argc, char *argv[])
380 {
381     WINDOW *chrbox;
382     WINDOW *strwin;
383     int ch;
384 
385     while ((ch = getopt(argc, argv, OPTS_COMMON)) != -1) {
386 	switch (ch) {
387 	case OPTS_VERSION:
388 	    show_version(argv);
389 	    ExitProgram(EXIT_SUCCESS);
390 	default:
391 	    usage(ch == OPTS_USAGE);
392 	    /* NOTREACHED */
393 	}
394     }
395 
396     setlocale(LC_ALL, "");
397 
398     if (optind + 1 > argc)
399 	usage(FALSE);
400 
401     initscr();
402 
403     chrbox = derwin(stdscr, BASE_Y, COLS, 0, 0);
404     box(chrbox, 0, 0);
405     wnoutrefresh(chrbox);
406 
407     strwin = derwin(chrbox, 4, COLS - 2, 1, 1);
408 
409     recursive_test(optind, argv, strwin);
410 
411     endwin();
412     ExitProgram(EXIT_SUCCESS);
413 }
414 #else
415 int
main(void)416 main(void)
417 {
418     printf("This program requires the wide-ncurses library\n");
419     ExitProgram(EXIT_FAILURE);
420 }
421 #endif
422 #else
423 int
main(void)424 main(void)
425 {
426     printf("This program requires the curses chgat function\n");
427     ExitProgram(EXIT_FAILURE);
428 }
429 #endif
430