xref: /netbsd-src/lib/libcurses/line.c (revision 7330f729ccf0bd976a06f95fad452fe774fc7fd1)
1 /*	$NetBSD: line.c,v 1.11 2019/06/09 07:40:14 blymn Exp $	*/
2 
3 /*-
4  * Copyright (c) 1998-1999 Brett Lymn
5  *						 (blymn@baea.com.au, brett_lymn@yahoo.com.au)
6  * All rights reserved.
7  *
8  * This code has been donated to The NetBSD Foundation by the Author.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. The name of the author may not be used to endorse or promote products
16  *    derived from this software without specific prior written permission
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  *
29  *
30  */
31 
32 #include <sys/cdefs.h>
33 #ifndef lint
34 __RCSID("$NetBSD: line.c,v 1.11 2019/06/09 07:40:14 blymn Exp $");
35 #endif				/* not lint */
36 
37 #include <string.h>
38 
39 #include "curses.h"
40 #include "curses_private.h"
41 
42 /*
43  * hline --
44  *	Draw a horizontal line of character c on stdscr.
45  */
46 int
47 hline(chtype ch, int count)
48 {
49 
50 	return whline(stdscr, ch, count);
51 }
52 
53 /*
54  * mvhline --
55  *	Move to location (y, x) and draw a horizontal line of character c
56  *	on stdscr.
57  */
58 int
59 mvhline(int y, int x, chtype ch, int count)
60 {
61 
62 	return mvwhline(stdscr, y, x, ch, count);
63 }
64 
65 /*
66  * mvwhline --
67  *	Move to location (y, x) and draw a horizontal line of character c
68  *	in the given window.
69  */
70 int
71 mvwhline(WINDOW *win, int y, int x, chtype ch, int count)
72 {
73 
74 	if (wmove(win, y, x) == ERR)
75 		return ERR;
76 
77 	return whline(win, ch, count);
78 }
79 
80 /*
81  * whline --
82  *	Draw a horizontal line of character c in the given window moving
83  *	towards the rightmost column.  At most count characters are drawn
84  *	or until the edge of the screen, whichever comes first.
85  */
86 int
87 whline(WINDOW *win, chtype ch, int count)
88 {
89 #ifndef HAVE_WCHAR
90 	int ocurx, n, i;
91 
92 	n = min(count, win->maxx - win->curx);
93 	ocurx = win->curx;
94 
95 	if (!(ch & __CHARTEXT))
96 		ch |= ACS_HLINE;
97 	for (i = 0; i < n; i++)
98 		mvwaddch(win, win->cury, ocurx + i, ch);
99 
100 	wmove(win, win->cury, ocurx);
101 	return OK;
102 #else
103 	cchar_t cch, *cchp;
104 
105 	if (ch & __CHARTEXT) {
106 		__cursesi_chtype_to_cchar(ch, &cch);
107 		cchp = & cch;
108 	} else
109 		cchp = WACS_HLINE;
110 
111 	return whline_set(win, cchp, count);
112 #endif
113 }
114 
115 /*
116  * vline --
117  *	Draw a vertical line of character ch on stdscr.
118  */
119 int
120 vline(chtype ch, int count)
121 {
122 
123 	return wvline(stdscr, ch, count);
124 }
125 
126 /*
127  * mvvline --
128  *	Move to the given location an draw a vertical line of character ch.
129  */
130 int
131 mvvline(int y, int x, chtype ch, int count)
132 {
133 
134 	return mvwvline(stdscr, y, x, ch, count);
135 }
136 
137 /*
138  * mvwvline --
139  *	Move to the given location and draw a vertical line of character ch
140  *	on the given window.
141  */
142 int
143 mvwvline(WINDOW *win, int y, int x, chtype ch, int count)
144 {
145 
146 	if (wmove(win, y, x) == ERR)
147 		return ERR;
148 
149 	return wvline(win, ch, count);
150 }
151 
152 /*
153  * wvline --
154  *	Draw a vertical line of character ch in the given window moving
155  *	towards the bottom of the screen.  At most count characters are drawn
156  *	or until the edge of the screen, whichever comes first.
157  */
158 int
159 wvline(WINDOW *win, chtype ch, int count)
160 {
161 #ifndef HAVE_WCHAR
162 	int ocury, ocurx, n, i;
163 
164 	n = min(count, win->maxy - win->cury);
165 	ocury = win->cury;
166 	ocurx = win->curx;
167 
168 	if (!(ch & __CHARTEXT))
169 		ch |= ACS_VLINE;
170 	for (i = 0; i < n; i++)
171 		mvwaddch(win, ocury + i, ocurx, ch);
172 
173 	wmove(win, ocury, ocurx);
174 	return OK;
175 #else
176 	cchar_t cch, *cchp;
177 
178 	if (ch & __CHARTEXT) {
179 		__cursesi_chtype_to_cchar(ch, &cch);
180 		cchp = & cch;
181 	} else
182 		cchp = WACS_VLINE;
183 
184 	return wvline_set(win, cchp, count);
185 #endif
186 }
187 
188 int hline_set(const cchar_t *wch, int n)
189 {
190 #ifndef HAVE_WCHAR
191 	return ERR;
192 #else
193 	return whline_set( stdscr, wch, n );
194 #endif /* HAVE_WCHAR */
195 }
196 
197 int mvhline_set(int y, int x, const cchar_t *wch, int n)
198 {
199 #ifndef HAVE_WCHAR
200 	return ERR;
201 #else
202 	return mvwhline_set( stdscr, y, x, wch, n );
203 #endif /* HAVE_WCHAR */
204 }
205 
206 int mvwhline_set(WINDOW *win, int y, int x, const cchar_t *wch, int n)
207 {
208 #ifndef HAVE_WCHAR
209 	return ERR;
210 #else
211 	if ( wmove( win, y , x ) == ERR )
212 		return ERR;
213 
214 	return whline_set( win, wch, n );
215 #endif /* HAVE_WCHAR */
216 }
217 
218 int whline_set(WINDOW *win, const cchar_t *wch, int n)
219 {
220 #ifndef HAVE_WCHAR
221 	return ERR;
222 #else
223 	int ocurx, wcn, i, cw;
224 	cchar_t cc;
225 
226 	cw = wcwidth( wch->vals[ 0 ]);
227 	if (cw < 0)
228 		cw = 1;
229 	if ( ( win->maxx - win->curx ) < cw )
230 		return ERR;
231 	wcn = min( n, ( win->maxx - win->curx ) / cw );
232 #ifdef DEBUG
233 	__CTRACE(__CTRACE_LINE, "whline_set: line of %d\n", wcn);
234 #endif /* DEBUG */
235 	ocurx = win->curx;
236 
237 	memcpy( &cc, wch, sizeof( cchar_t ));
238 	if (!(wch->vals[ 0 ]))
239 		cc.vals[ 0 ] |= WACS_HLINE->vals[0];
240 	for (i = 0; i < wcn; i++ ) {
241 #ifdef DEBUG
242 		__CTRACE(__CTRACE_LINE, "whline_set: (%d,%d)\n",
243 		   win->cury, ocurx + i * cw);
244 #endif /* DEBUG */
245 		mvwadd_wch(win, win->cury, ocurx + i * cw, &cc);
246 	}
247 
248 	wmove(win, win->cury, ocurx);
249 	__sync(win);
250 	return OK;
251 #endif /* HAVE_WCHAR */
252 }
253 
254 int vline_set(const cchar_t *wch, int n)
255 {
256 #ifndef HAVE_WCHAR
257 	return ERR;
258 #else
259 	return wvline_set(stdscr, wch, n);
260 #endif /* HAVE_WCHAR */
261 }
262 
263 int mvvline_set(int y, int x, const cchar_t *wch, int n)
264 {
265 #ifndef HAVE_WCHAR
266 	return ERR;
267 #else
268 	return mvwvline_set(stdscr, y, x, wch, n);
269 #endif /* HAVE_WCHAR */
270 }
271 
272 int mvwvline_set(WINDOW *win, int y, int x, const cchar_t *wch, int n)
273 {
274 #ifndef HAVE_WCHAR
275 	return ERR;
276 #else
277 	if (wmove(win, y, x) == ERR)
278 		return ERR;
279 
280 	return wvline_set(win, wch, n);
281 #endif /* HAVE_WCHAR */
282 }
283 
284 int wvline_set(WINDOW *win, const cchar_t *wch, int n)
285 {
286 #ifndef HAVE_WCHAR
287 	return ERR;
288 #else
289 	int ocury, ocurx, wcn, i;
290 	cchar_t cc;
291 
292 	wcn = min(n, win->maxy - win->cury);
293 #ifdef DEBUG
294 	__CTRACE(__CTRACE_LINE, "wvline_set: line of %d\n", wcn);
295 #endif /* DEBUG */
296 	ocury = win->cury;
297 	ocurx = win->curx;
298 
299 	memcpy(&cc, wch, sizeof(cchar_t));
300 	if (!(wch->vals[0]))
301 		cc.vals[0] |= WACS_VLINE->vals[0];
302 	for (i = 0; i < wcn; i++) {
303 		mvwadd_wch(win, ocury + i, ocurx, &cc);
304 #ifdef DEBUG
305 		__CTRACE(__CTRACE_LINE, "wvline_set: (%d,%d)\n",
306 		    ocury + i, ocurx);
307 #endif /* DEBUG */
308 	}
309 
310 	wmove(win, ocury, ocurx);
311 	__sync(win);
312 	return OK;
313 #endif /* HAVE_WCHAR */
314 }
315