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