blob: 2a788fce8dfae64332a5fa0737f67aaccc9fb2f2 [file] [log] [blame]
Steve Kondikae271bc2015-11-15 02:50:53 +01001/****************************************************************************
micky3879b9f5e72025-07-08 18:04:53 -04002 * Copyright 2020,2022 Thomas E. Dickey *
3 * Copyright 2007-2011,2017 Free Software Foundation, Inc. *
Steve Kondikae271bc2015-11-15 02:50:53 +01004 * *
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/*
micky3879b9f5e72025-07-08 18:04:53 -040030 * $Id: test_get_wstr.c,v 1.14 2022/12/10 23:59:13 tom Exp $
Steve Kondikae271bc2015-11-15 02:50:53 +010031 *
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>
micky3879b9f5e72025-07-08 18:04:53 -040047#include <popup_msg.h>
Steve Kondikae271bc2015-11-15 02:50:53 +010048
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
57typedef enum {
58 eGetStr = 0,
59 eGetNStr,
60 eMvGetStr,
61 eMvGetNStr,
62 eMaxFlavor
63} Flavors;
64
65static bool
66Quit(int ch)
67{
68 return (ch == ERR || ch == 'q' || ch == QUIT || ch == ESCAPE);
69}
70
71static int
72Remainder(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 */
81static void
82ShowPrompt(WINDOW *txtwin, int limit)
83{
micky3879b9f5e72025-07-08 18:04:53 -040084 wchgat(txtwin, limit, WA_REVERSE, 0, NULL);
Steve Kondikae271bc2015-11-15 02:50:53 +010085 wnoutrefresh(txtwin);
86}
87
88static void
89MovePrompt(WINDOW *txtwin, int limit, int y, int x)
90{
micky3879b9f5e72025-07-08 18:04:53 -040091 wchgat(txtwin, Remainder(txtwin), WA_NORMAL, 0, NULL);
Steve Kondikae271bc2015-11-15 02:50:53 +010092 wmove(txtwin, y, x);
93 ShowPrompt(txtwin, limit);
94}
95
96static int
97ShowFlavor(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
138static int
micky3879b9f5e72025-07-08 18:04:53 -0400139recursive_test(int level, char **argv, WINDOW *strwin)
Steve Kondikae271bc2015-11-15 02:50:53 +0100140{
micky3879b9f5e72025-07-08 18:04:53 -0400141 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 };
Steve Kondikae271bc2015-11-15 02:50:53 +0100163 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':
micky3879b9f5e72025-07-08 18:04:53 -0400252 recursive_test(level + 1, argv, strwin);
Steve Kondikae271bc2015-11-15 02:50:53 +0100253 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);
micky3879b9f5e72025-07-08 18:04:53 -0400338 wprintw(strwin, "%s:", (rc == OK) ? "OK" : "ERR");
Steve Kondikae271bc2015-11-15 02:50:53 +0100339 (void) waddwstr(strwin, (wchar_t *) buffer);
340 wnoutrefresh(strwin);
341 break;
micky3879b9f5e72025-07-08 18:04:53 -0400342 case HELP_KEY_1:
343 popup_msg(stdscr, help);
344 break;
Steve Kondikae271bc2015-11-15 02:50:53 +0100345 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
micky3879b9f5e72025-07-08 18:04:53 -0400358static void
359usage(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* */
375VERSION_COMMON()
376/* *INDENT-ON* */
377
Steve Kondikae271bc2015-11-15 02:50:53 +0100378int
379main(int argc, char *argv[])
380{
381 WINDOW *chrbox;
382 WINDOW *strwin;
micky3879b9f5e72025-07-08 18:04:53 -0400383 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 }
Steve Kondikae271bc2015-11-15 02:50:53 +0100395
396 setlocale(LC_ALL, "");
397
micky3879b9f5e72025-07-08 18:04:53 -0400398 if (optind + 1 > argc)
399 usage(FALSE);
Steve Kondikae271bc2015-11-15 02:50:53 +0100400
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
micky3879b9f5e72025-07-08 18:04:53 -0400409 recursive_test(optind, argv, strwin);
Steve Kondikae271bc2015-11-15 02:50:53 +0100410
411 endwin();
412 ExitProgram(EXIT_SUCCESS);
413}
414#else
415int
416main(void)
417{
418 printf("This program requires the wide-ncurses library\n");
419 ExitProgram(EXIT_FAILURE);
420}
421#endif
422#else
423int
424main(void)
425{
426 printf("This program requires the curses chgat function\n");
427 ExitProgram(EXIT_FAILURE);
428}
429#endif