xref: /netbsd/lib/libcurses/inwstr.c (revision 6550d01e)
1 /*   $NetBSD: inwstr.c,v 1.3 2009/07/22 16:57:15 roy Exp $ */
2 
3 /*
4  * Copyright (c) 2005 The NetBSD Foundation Inc.
5  * All rights reserved.
6  *
7  * This code is derived from code donated to the NetBSD Foundation
8  * by Ruibiao Qiu <ruibiao@arl.wustl.edu,ruibiao@gmail.com>.
9  *
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *	notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *	notice, this list of conditions and the following disclaimer in the
18  *	documentation and/or other materials provided with the distribution.
19  * 3. Neither the name of the NetBSD Foundation nor the names of its
20  *	contributors may be used to endorse or promote products derived
21  *	from this software without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
24  * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
25  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
26  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34  * SUCH DAMAGE.
35  */
36 
37 #include <sys/cdefs.h>
38 #ifndef lint
39 __RCSID("$NetBSD: inwstr.c,v 1.3 2009/07/22 16:57:15 roy Exp $");
40 #endif						  /* not lint */
41 
42 #include "curses.h"
43 #include "curses_private.h"
44 
45 /*
46  * inwstr, innwstr --
47  *	Return a string of wide characters at cursor position from stdscr.
48  */
49 __warn_references(inwstr,
50 	"warning: this program uses inwstr(), which is unsafe.")
51 int
52 inwstr(wchar_t *wstr)
53 {
54 #ifndef HAVE_WCHAR
55 	return ERR;
56 #else
57 	return winwstr(stdscr, wstr);
58 #endif /* HAVE_WCHAR */
59 }
60 
61 int
62 innwstr(wchar_t *wstr, int n)
63 {
64 #ifndef HAVE_WCHAR
65 	return ERR;
66 #else
67 	return winnwstr(stdscr, wstr, n);
68 #endif /* HAVE_WCHAR */
69 }
70 
71 /*
72  * mvinwstr, mvinnwstr --
73  *  Return a string of wide characters at position (y, x) from stdscr.
74  */
75 __warn_references(mvinwstr,
76 	"warning: this program uses mvinwstr(), which is unsafe.")
77 int
78 mvinwstr(int y, int x, wchar_t *wstr)
79 {
80 #ifndef HAVE_WCHAR
81 	return ERR;
82 #else
83 	return mvwinwstr(stdscr, y, x, wstr);
84 #endif /* HAVE_WCHAR */
85 }
86 
87 int
88 mvinnwstr(int y, int x, wchar_t *wstr, int n)
89 {
90 #ifndef HAVE_WCHAR
91 	return ERR;
92 #else
93 	return mvwinnwstr(stdscr, y, x, wstr, n);
94 #endif /* HAVE_WCHAR */
95 }
96 
97 /*
98  * mvwinwstr, mvwinnwstr --
99  *  Return an array wide characters at position (y, x) from the given window.
100  */
101 __warn_references(mvwinwstr,
102 	"warning: this program uses mvwinwstr(), which is unsafe.")
103 int
104 mvwinwstr(WINDOW *win, int y, int x, wchar_t *wstr)
105 {
106 #ifndef HAVE_WCHAR
107 	return ERR;
108 #else
109 	if (wmove(win, y, x) == ERR)
110 		return ERR;
111 
112 	return winwstr(win, wstr);
113 #endif /* HAVE_WCHAR */
114 }
115 
116 int
117 mvwinnwstr(WINDOW *win, int y, int x, wchar_t *wstr, int n)
118 {
119 #ifndef HAVE_WCHAR
120 	return ERR;
121 #else
122 	if (wmove(win, y, x) == ERR)
123 		return ERR;
124 
125 	return winnwstr(win, wstr, n);
126 #endif /* HAVE_WCHAR */
127 }
128 
129 /*
130  * winwstr, winnwstr --
131  *	Return a string of wide characters at cursor position.
132  */
133 __warn_references(winwstr,
134 	"warning: this program uses winwstr(), which is unsafe.")
135 int
136 winwstr(WINDOW *win, wchar_t *wstr)
137 {
138 #ifndef HAVE_WCHAR
139 	return ERR;
140 #else
141 
142 	return winnwstr(win, wstr, -1);
143 #endif /* HAVE_WCHAR */
144 }
145 
146 /*
147  * - winnwstr() returns the number of characters copied only of if it is
148  *   called with n >= 0 (ie, as in_wchnstr(), mvin_wchnstr(), mvwin_wchnstr()
149  *   or win_wchnstr()).  If N < 0, it returns `OK'.
150  * - SUSv2/xcurses doesn't document whether the trailing NUL is included
151  *   in the length count or not.  For safety's sake it _is_ included.
152  * - This implementation does not (yet) support multi-byte characters
153  *   strings.
154  */
155 int
156 winnwstr(WINDOW *win, wchar_t *wstr, int n)
157 {
158 #ifndef HAVE_WCHAR
159 	return ERR;
160 #else
161 	__LDATA	*start;
162 	int x, cw, cnt;
163 	wchar_t *wcp;
164 
165 	if (wstr == NULL)
166 		return ERR;
167 
168 	start = &win->alines[win->cury]->line[win->curx];
169 	x = win->curx;
170 	cw = WCOL( *start );
171 	if (cw < 0) {
172 		start += cw;
173 		x += cw;
174 	}
175     cnt = 0;
176 	wcp = wstr;
177 	/* (n - 1) to leave room for the trailing 0 element */
178 	while ((x < win->maxx) && ((n < 0) || ((n > 1) && (cnt < n - 1)))) {
179 		cw = WCOL( *start );
180 		*wcp = start->ch;
181 		wcp++;
182 		cnt++;
183 		x += cw;
184 		if ( x < win->maxx )
185 			start += cw;
186 	}
187 	*wcp = L'\0';
188 
189 	if (n < 0)
190 		return OK;
191 	else
192 		return cnt;
193 #endif /* HAVE_WCHAR */
194 }
195