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