xref: /minix3/lib/libcurses/get_wstr.c (revision 51ffecc181005cb45a40108612ee28d1daaeeb86)
1*51ffecc1SBen Gras /*   $NetBSD: get_wstr.c,v 1.3 2008/04/14 20:33:59 jdc Exp $ */
2*51ffecc1SBen Gras 
3*51ffecc1SBen Gras /*
4*51ffecc1SBen Gras  * Copyright (c) 2005 The NetBSD Foundation Inc.
5*51ffecc1SBen Gras  * All rights reserved.
6*51ffecc1SBen Gras  *
7*51ffecc1SBen Gras  * This code is derived from code donated to the NetBSD Foundation
8*51ffecc1SBen Gras  * by Ruibiao Qiu <ruibiao@arl.wustl.edu,ruibiao@gmail.com>.
9*51ffecc1SBen Gras  *
10*51ffecc1SBen Gras  *
11*51ffecc1SBen Gras  * Redistribution and use in source and binary forms, with or without
12*51ffecc1SBen Gras  * modification, are permitted provided that the following conditions
13*51ffecc1SBen Gras  * are met:
14*51ffecc1SBen Gras  * 1. Redistributions of source code must retain the above copyright
15*51ffecc1SBen Gras  *	notice, this list of conditions and the following disclaimer.
16*51ffecc1SBen Gras  * 2. Redistributions in binary form must reproduce the above copyright
17*51ffecc1SBen Gras  *	notice, this list of conditions and the following disclaimer in the
18*51ffecc1SBen Gras  *	documentation and/or other materials provided with the distribution.
19*51ffecc1SBen Gras  * 3. Neither the name of the NetBSD Foundation nor the names of its
20*51ffecc1SBen Gras  *	contributors may be used to endorse or promote products derived
21*51ffecc1SBen Gras  *	from this software without specific prior written permission.
22*51ffecc1SBen Gras  *
23*51ffecc1SBen Gras  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
24*51ffecc1SBen Gras  * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
25*51ffecc1SBen Gras  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
26*51ffecc1SBen Gras  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27*51ffecc1SBen Gras  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28*51ffecc1SBen Gras  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29*51ffecc1SBen Gras  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30*51ffecc1SBen Gras  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31*51ffecc1SBen Gras  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32*51ffecc1SBen Gras  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33*51ffecc1SBen Gras  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34*51ffecc1SBen Gras  * SUCH DAMAGE.
35*51ffecc1SBen Gras  */
36*51ffecc1SBen Gras 
37*51ffecc1SBen Gras #include <sys/cdefs.h>
38*51ffecc1SBen Gras #ifndef lint
39*51ffecc1SBen Gras __RCSID("$NetBSD: get_wstr.c,v 1.3 2008/04/14 20:33:59 jdc Exp $");
40*51ffecc1SBen Gras #endif						  /* not lint */
41*51ffecc1SBen Gras 
42*51ffecc1SBen Gras #include "curses.h"
43*51ffecc1SBen Gras #include "curses_private.h"
44*51ffecc1SBen Gras 
45*51ffecc1SBen Gras /* prototypes for private functions */
46*51ffecc1SBen Gras #ifdef HAVE_WCHAR
47*51ffecc1SBen Gras static int __wgetn_wstr(WINDOW *, wchar_t *, int);
48*51ffecc1SBen Gras #endif /* HAVE_WCHAR */
49*51ffecc1SBen Gras 
50*51ffecc1SBen Gras /*
51*51ffecc1SBen Gras  * getn_wstr --
52*51ffecc1SBen Gras  *	Get a string (of maximum n) characters from stdscr starting at
53*51ffecc1SBen Gras  *	(cury, curx).
54*51ffecc1SBen Gras  */
55*51ffecc1SBen Gras int
getn_wstr(wchar_t * wstr,int n)56*51ffecc1SBen Gras getn_wstr(wchar_t *wstr, int n)
57*51ffecc1SBen Gras {
58*51ffecc1SBen Gras #ifndef HAVE_WCHAR
59*51ffecc1SBen Gras 	return ERR;
60*51ffecc1SBen Gras #else
61*51ffecc1SBen Gras 	return wgetn_wstr(stdscr, wstr, n);
62*51ffecc1SBen Gras #endif /* HAVE_WCHAR */
63*51ffecc1SBen Gras }
64*51ffecc1SBen Gras 
65*51ffecc1SBen Gras /*
66*51ffecc1SBen Gras  * get_wstr --
67*51ffecc1SBen Gras  *	Get a string from stdscr starting at (cury, curx).
68*51ffecc1SBen Gras  */
69*51ffecc1SBen Gras __warn_references(get_wstr,
70*51ffecc1SBen Gras 	"warning: this program uses get_wstr(), which is unsafe.")
71*51ffecc1SBen Gras int
get_wstr(wchar_t * wstr)72*51ffecc1SBen Gras get_wstr(wchar_t *wstr)
73*51ffecc1SBen Gras {
74*51ffecc1SBen Gras #ifndef HAVE_WCHAR
75*51ffecc1SBen Gras 	return ERR;
76*51ffecc1SBen Gras #else
77*51ffecc1SBen Gras 	return wget_wstr(stdscr, wstr);
78*51ffecc1SBen Gras #endif /* HAVE_WCHAR */
79*51ffecc1SBen Gras }
80*51ffecc1SBen Gras 
81*51ffecc1SBen Gras /*
82*51ffecc1SBen Gras  * mvgetn_wstr --
83*51ffecc1SBen Gras  *  Get a string (of maximum n) characters from stdscr starting at (y, x).
84*51ffecc1SBen Gras  */
85*51ffecc1SBen Gras int
mvgetn_wstr(int y,int x,wchar_t * wstr,int n)86*51ffecc1SBen Gras mvgetn_wstr(int y, int x, wchar_t *wstr, int n)
87*51ffecc1SBen Gras {
88*51ffecc1SBen Gras #ifndef HAVE_WCHAR
89*51ffecc1SBen Gras 	return ERR;
90*51ffecc1SBen Gras #else
91*51ffecc1SBen Gras 	return mvwgetn_wstr(stdscr, y, x, wstr, n);
92*51ffecc1SBen Gras #endif /* HAVE_WCHAR */
93*51ffecc1SBen Gras }
94*51ffecc1SBen Gras 
95*51ffecc1SBen Gras /*
96*51ffecc1SBen Gras  * mvget_wstr --
97*51ffecc1SBen Gras  *	  Get a string from stdscr starting at (y, x).
98*51ffecc1SBen Gras  */
99*51ffecc1SBen Gras __warn_references(mvget_wstr,
100*51ffecc1SBen Gras 	"warning: this program uses mvget_wstr(), which is unsafe.")
101*51ffecc1SBen Gras int
mvget_wstr(int y,int x,wchar_t * wstr)102*51ffecc1SBen Gras mvget_wstr(int y, int x, wchar_t *wstr)
103*51ffecc1SBen Gras {
104*51ffecc1SBen Gras #ifndef HAVE_WCHAR
105*51ffecc1SBen Gras 	return ERR;
106*51ffecc1SBen Gras #else
107*51ffecc1SBen Gras 	return mvwget_wstr(stdscr, y, x, wstr);
108*51ffecc1SBen Gras #endif /* HAVE_WCHAR */
109*51ffecc1SBen Gras }
110*51ffecc1SBen Gras 
111*51ffecc1SBen Gras /*
112*51ffecc1SBen Gras  * mvwgetn_wstr --
113*51ffecc1SBen Gras  *  Get a string (of maximum n) characters from the given window starting
114*51ffecc1SBen Gras  *	at (y, x).
115*51ffecc1SBen Gras  */
116*51ffecc1SBen Gras int
mvwgetn_wstr(WINDOW * win,int y,int x,wchar_t * wstr,int n)117*51ffecc1SBen Gras mvwgetn_wstr(WINDOW *win, int y, int x, wchar_t *wstr, int n)
118*51ffecc1SBen Gras {
119*51ffecc1SBen Gras #ifndef HAVE_WCHAR
120*51ffecc1SBen Gras 	return ERR;
121*51ffecc1SBen Gras #else
122*51ffecc1SBen Gras 	if (wmove(win, y, x) == ERR)
123*51ffecc1SBen Gras 		return ERR;
124*51ffecc1SBen Gras 
125*51ffecc1SBen Gras 	return wgetn_wstr(win, wstr, n);
126*51ffecc1SBen Gras #endif /* HAVE_WCHAR */
127*51ffecc1SBen Gras }
128*51ffecc1SBen Gras 
129*51ffecc1SBen Gras /*
130*51ffecc1SBen Gras  * mvwget_wstr --
131*51ffecc1SBen Gras  *	  Get a string from the given window starting at (y, x).
132*51ffecc1SBen Gras  */
133*51ffecc1SBen Gras __warn_references(mvget_wstr,
134*51ffecc1SBen Gras 	"warning: this program uses mvget_wstr(), which is unsafe.")
135*51ffecc1SBen Gras int
mvwget_wstr(WINDOW * win,int y,int x,wchar_t * wstr)136*51ffecc1SBen Gras mvwget_wstr(WINDOW *win, int y, int x, wchar_t *wstr)
137*51ffecc1SBen Gras {
138*51ffecc1SBen Gras #ifndef HAVE_WCHAR
139*51ffecc1SBen Gras 	return ERR;
140*51ffecc1SBen Gras #else
141*51ffecc1SBen Gras 	if (wmove(win, y, x) == ERR)
142*51ffecc1SBen Gras 		return ERR;
143*51ffecc1SBen Gras 
144*51ffecc1SBen Gras 	return wget_wstr(win, wstr);
145*51ffecc1SBen Gras #endif /* HAVE_WCHAR */
146*51ffecc1SBen Gras }
147*51ffecc1SBen Gras 
148*51ffecc1SBen Gras /*
149*51ffecc1SBen Gras  * wget_wstr --
150*51ffecc1SBen Gras  *	Get a string starting at (cury, curx).
151*51ffecc1SBen Gras  */
152*51ffecc1SBen Gras __warn_references(wget_wstr,
153*51ffecc1SBen Gras 	"warning: this program uses wget_wstr(), which is unsafe.")
154*51ffecc1SBen Gras int
wget_wstr(WINDOW * win,wchar_t * wstr)155*51ffecc1SBen Gras wget_wstr(WINDOW *win, wchar_t *wstr)
156*51ffecc1SBen Gras {
157*51ffecc1SBen Gras #ifndef HAVE_WCHAR
158*51ffecc1SBen Gras 	return ERR;
159*51ffecc1SBen Gras #else
160*51ffecc1SBen Gras 	return __wgetn_wstr(win, wstr, -1);
161*51ffecc1SBen Gras #endif /* HAVE_WCHAR */
162*51ffecc1SBen Gras }
163*51ffecc1SBen Gras 
164*51ffecc1SBen Gras /*
165*51ffecc1SBen Gras  * wgetn_wstr --
166*51ffecc1SBen Gras  *	Get a string starting at (cury, curx).
167*51ffecc1SBen Gras  *	Note that n <  2 means that we return ERR (SUSv2 specification).
168*51ffecc1SBen Gras  */
169*51ffecc1SBen Gras int
wgetn_wstr(WINDOW * win,wchar_t * wstr,int n)170*51ffecc1SBen Gras wgetn_wstr(WINDOW *win, wchar_t *wstr, int n)
171*51ffecc1SBen Gras {
172*51ffecc1SBen Gras #ifndef HAVE_WCHAR
173*51ffecc1SBen Gras 	return ERR;
174*51ffecc1SBen Gras #else
175*51ffecc1SBen Gras 	if (n < 1)
176*51ffecc1SBen Gras 		return (ERR);
177*51ffecc1SBen Gras 	if (n == 1) {
178*51ffecc1SBen Gras 		wstr[0] = L'\0';
179*51ffecc1SBen Gras 		return (ERR);
180*51ffecc1SBen Gras 	}
181*51ffecc1SBen Gras 	return __wgetn_wstr(win, wstr, n);
182*51ffecc1SBen Gras #endif /* HAVE_WCHAR */
183*51ffecc1SBen Gras }
184*51ffecc1SBen Gras 
185*51ffecc1SBen Gras #ifdef HAVE_WCHAR
186*51ffecc1SBen Gras /*
187*51ffecc1SBen Gras  * __wgetn_wstr --
188*51ffecc1SBen Gras  *	The actual implementation.
189*51ffecc1SBen Gras  *	Note that we include a trailing L'\0' for safety, so str will contain
190*51ffecc1SBen Gras  *	at most n - 1 other characters.
191*51ffecc1SBen Gras  */
192*51ffecc1SBen Gras int
__wgetn_wstr(WINDOW * win,wchar_t * wstr,int n)193*51ffecc1SBen Gras __wgetn_wstr(WINDOW *win, wchar_t *wstr, int n)
194*51ffecc1SBen Gras {
195*51ffecc1SBen Gras 	wchar_t *ostr, ec, kc, sc[ 2 ];
196*51ffecc1SBen Gras 	int oldx, remain;
197*51ffecc1SBen Gras 	wint_t wc;
198*51ffecc1SBen Gras 	cchar_t cc;
199*51ffecc1SBen Gras 
200*51ffecc1SBen Gras 	ostr = wstr;
201*51ffecc1SBen Gras 	if ( erasewchar( &ec ) == ERR )
202*51ffecc1SBen Gras 		return ERR;
203*51ffecc1SBen Gras 	if ( killwchar( &kc ) == ERR )
204*51ffecc1SBen Gras 		return ERR;
205*51ffecc1SBen Gras 	sc[ 0 ] = ( wchar_t )btowc( ' ' );
206*51ffecc1SBen Gras 	sc[ 1 ] = L'\0';
207*51ffecc1SBen Gras 	setcchar( &cc, sc, win->wattr, 0, NULL );
208*51ffecc1SBen Gras 	oldx = win->curx;
209*51ffecc1SBen Gras 	remain = n - 1;
210*51ffecc1SBen Gras 
211*51ffecc1SBen Gras 	while (wget_wch(win, &wc) != ERR
212*51ffecc1SBen Gras 	       && wc != L'\n' && wc != L'\r') {
213*51ffecc1SBen Gras #ifdef DEBUG
214*51ffecc1SBen Gras 		__CTRACE(__CTRACE_INPUT,
215*51ffecc1SBen Gras 		    "__wgetn_wstr: win %p, char 0x%x, remain %d\n",
216*51ffecc1SBen Gras 		    win, wc, remain);
217*51ffecc1SBen Gras #endif
218*51ffecc1SBen Gras 		*wstr = wc;
219*51ffecc1SBen Gras 		touchline(win, win->cury, 1);
220*51ffecc1SBen Gras 		if (wc == ec || wc == KEY_BACKSPACE || wc == KEY_LEFT) {
221*51ffecc1SBen Gras 			*wstr = L'\0';
222*51ffecc1SBen Gras 			if (wstr != ostr) {
223*51ffecc1SBen Gras 				if ((wchar_t)wc == ec) {
224*51ffecc1SBen Gras 					mvwadd_wch(win, win->cury,
225*51ffecc1SBen Gras 						win->curx, &cc);
226*51ffecc1SBen Gras 					wmove(win, win->cury, win->curx - 1);
227*51ffecc1SBen Gras 				}
228*51ffecc1SBen Gras 				if (wc == KEY_BACKSPACE || wc == KEY_LEFT) {
229*51ffecc1SBen Gras 					/* getch() displays the key sequence */
230*51ffecc1SBen Gras 					mvwadd_wch(win, win->cury,
231*51ffecc1SBen Gras 						win->curx - 1, &cc);
232*51ffecc1SBen Gras 					mvwadd_wch(win, win->cury,
233*51ffecc1SBen Gras 						win->curx - 2, &cc);
234*51ffecc1SBen Gras 					wmove(win, win->cury, win->curx - 1);
235*51ffecc1SBen Gras 				}
236*51ffecc1SBen Gras 				wstr--;
237*51ffecc1SBen Gras 				if (n != -1) {
238*51ffecc1SBen Gras 					/* We're counting chars */
239*51ffecc1SBen Gras 					remain++;
240*51ffecc1SBen Gras 				}
241*51ffecc1SBen Gras 			} else { /* str == ostr */
242*51ffecc1SBen Gras 				if (wc == KEY_BACKSPACE || wc == KEY_LEFT)
243*51ffecc1SBen Gras 					/* getch() displays the other keys */
244*51ffecc1SBen Gras 					mvwadd_wch(win, win->cury,
245*51ffecc1SBen Gras 						win->curx - 1, &cc);
246*51ffecc1SBen Gras 				wmove(win, win->cury, oldx);
247*51ffecc1SBen Gras 			}
248*51ffecc1SBen Gras 		} else if (wc == kc) {
249*51ffecc1SBen Gras 			*wstr = L'\0';
250*51ffecc1SBen Gras 			if (wstr != ostr) {
251*51ffecc1SBen Gras 				/* getch() displays the kill character */
252*51ffecc1SBen Gras 				mvwadd_wch(win, win->cury, win->curx - 1, &cc);
253*51ffecc1SBen Gras 				/* Clear the characters from screen and str */
254*51ffecc1SBen Gras 				while (wstr != ostr) {
255*51ffecc1SBen Gras 					mvwadd_wch(win, win->cury,
256*51ffecc1SBen Gras 						win->curx - 1, &cc);
257*51ffecc1SBen Gras 					wmove(win, win->cury, win->curx - 1);
258*51ffecc1SBen Gras 					wstr--;
259*51ffecc1SBen Gras 					if (n != -1)
260*51ffecc1SBen Gras 						/* We're counting chars */
261*51ffecc1SBen Gras 						remain++;
262*51ffecc1SBen Gras 				}
263*51ffecc1SBen Gras 				mvwadd_wch(win, win->cury, win->curx - 1, &cc);
264*51ffecc1SBen Gras 				wmove(win, win->cury, win->curx - 1);
265*51ffecc1SBen Gras 			} else
266*51ffecc1SBen Gras 				/* getch() displays the kill character */
267*51ffecc1SBen Gras 				mvwadd_wch( win, win->cury, oldx, &cc );
268*51ffecc1SBen Gras 			wmove(win, win->cury, oldx);
269*51ffecc1SBen Gras 		} else if (wc >= KEY_MIN && wc <= KEY_MAX) {
270*51ffecc1SBen Gras 			/* get_wch() displays these characters */
271*51ffecc1SBen Gras 			mvwadd_wch( win, win->cury, win->curx - 1, &cc );
272*51ffecc1SBen Gras 			wmove(win, win->cury, win->curx - 1);
273*51ffecc1SBen Gras 		} else {
274*51ffecc1SBen Gras 			if (remain) {
275*51ffecc1SBen Gras 				wstr++;
276*51ffecc1SBen Gras 				remain--;
277*51ffecc1SBen Gras 			} else {
278*51ffecc1SBen Gras 				mvwadd_wch(win, win->cury, win->curx - 1, &cc);
279*51ffecc1SBen Gras 				wmove(win, win->cury, win->curx - 1);
280*51ffecc1SBen Gras 			}
281*51ffecc1SBen Gras 		}
282*51ffecc1SBen Gras 	}
283*51ffecc1SBen Gras 
284*51ffecc1SBen Gras 	if (wc == ERR) {
285*51ffecc1SBen Gras 		*wstr = L'\0';
286*51ffecc1SBen Gras 		return ERR;
287*51ffecc1SBen Gras 	}
288*51ffecc1SBen Gras 	*wstr = L'\0';
289*51ffecc1SBen Gras 	return OK;
290*51ffecc1SBen Gras }
291*51ffecc1SBen Gras #endif /* HAVE_WCHAR */
292