1 /* $NetBSD: line.c,v 1.17 2021/09/06 07:03:50 rin 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.17 2021/09/06 07:03:50 rin 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
hline(chtype ch,int count)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
mvhline(int y,int x,chtype ch,int count)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
mvwhline(WINDOW * win,int y,int x,chtype ch,int count)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
whline(WINDOW * win,chtype ch,int count)87 whline(WINDOW *win, chtype ch, int count)
88 {
89 #ifndef HAVE_WCHAR
90 int ocury, ocurx, n, i;
91
92 n = min(count, win->maxx - win->curx);
93 ocury = win->cury;
94 ocurx = win->curx;
95
96 if (!(ch & __CHARTEXT))
97 ch |= ACS_HLINE;
98 for (i = 0; i < n; i++)
99 mvwaddch(win, ocury, ocurx + i, ch);
100
101 wmove(win, ocury, ocurx);
102 return OK;
103 #else
104 cchar_t cch;
105
106 __cursesi_chtype_to_cchar(ch, &cch);
107 return whline_set(win, &cch, count);
108 #endif
109 }
110
111 /*
112 * vline --
113 * Draw a vertical line of character ch on stdscr.
114 */
115 int
vline(chtype ch,int count)116 vline(chtype ch, int count)
117 {
118
119 return wvline(stdscr, ch, count);
120 }
121
122 /*
123 * mvvline --
124 * Move to the given location an draw a vertical line of character ch.
125 */
126 int
mvvline(int y,int x,chtype ch,int count)127 mvvline(int y, int x, chtype ch, int count)
128 {
129
130 return mvwvline(stdscr, y, x, ch, count);
131 }
132
133 /*
134 * mvwvline --
135 * Move to the given location and draw a vertical line of character ch
136 * on the given window.
137 */
138 int
mvwvline(WINDOW * win,int y,int x,chtype ch,int count)139 mvwvline(WINDOW *win, int y, int x, chtype ch, int count)
140 {
141
142 if (wmove(win, y, x) == ERR)
143 return ERR;
144
145 return wvline(win, ch, count);
146 }
147
148 /*
149 * wvline --
150 * Draw a vertical line of character ch in the given window moving
151 * towards the bottom of the screen. At most count characters are drawn
152 * or until the edge of the screen, whichever comes first.
153 */
154 int
wvline(WINDOW * win,chtype ch,int count)155 wvline(WINDOW *win, chtype ch, int count)
156 {
157 #ifndef HAVE_WCHAR
158 int ocury, ocurx, n, i;
159
160 n = min(count, win->maxy - win->cury);
161 ocury = win->cury;
162 ocurx = win->curx;
163
164 if (!(ch & __CHARTEXT))
165 ch |= ACS_VLINE;
166 for (i = 0; i < n; i++)
167 mvwaddch(win, ocury + i, ocurx, ch);
168
169 wmove(win, ocury, ocurx);
170 return OK;
171 #else
172 cchar_t cch;
173
174 __cursesi_chtype_to_cchar(ch, &cch);
175 return wvline_set(win, &cch, count);
176 #endif
177 }
178
hline_set(const cchar_t * wch,int n)179 int hline_set(const cchar_t *wch, int n)
180 {
181 #ifndef HAVE_WCHAR
182 return ERR;
183 #else
184 return whline_set( stdscr, wch, n );
185 #endif /* HAVE_WCHAR */
186 }
187
mvhline_set(int y,int x,const cchar_t * wch,int n)188 int mvhline_set(int y, int x, const cchar_t *wch, int n)
189 {
190 #ifndef HAVE_WCHAR
191 return ERR;
192 #else
193 return mvwhline_set( stdscr, y, x, wch, n );
194 #endif /* HAVE_WCHAR */
195 }
196
mvwhline_set(WINDOW * win,int y,int x,const cchar_t * wch,int n)197 int mvwhline_set(WINDOW *win, int y, int x, const cchar_t *wch, int n)
198 {
199 #ifndef HAVE_WCHAR
200 return ERR;
201 #else
202 if ( wmove( win, y , x ) == ERR )
203 return ERR;
204
205 return whline_set( win, wch, n );
206 #endif /* HAVE_WCHAR */
207 }
208
whline_set(WINDOW * win,const cchar_t * wch,int n)209 int whline_set(WINDOW *win, const cchar_t *wch, int n)
210 {
211 #ifndef HAVE_WCHAR
212 return ERR;
213 #else
214 int ocury, ocurx, wcn, i, cw;
215 cchar_t cc;
216
217 cc = *wch;
218 if (!cc.vals[0]) {
219 cc.vals[0] = WACS_HLINE->vals[0];
220 cc.attributes |= WACS_HLINE->attributes;
221 }
222
223 cw = wcwidth(cc.vals[0]);
224 if (cw <= 0)
225 cw = 1;
226 if ( ( win->maxx - win->curx ) < cw )
227 return ERR;
228 wcn = min( n, ( win->maxx - win->curx ) / cw );
229 __CTRACE(__CTRACE_LINE, "whline_set: line of %d\n", wcn);
230 ocury = win->cury;
231 ocurx = win->curx;
232
233 for (i = 0; i < wcn; i++ ) {
234 __CTRACE(__CTRACE_LINE, "whline_set: (%d,%d)\n",
235 ocury, ocurx + i * cw);
236 mvwadd_wch(win, ocury, ocurx + i * cw, &cc);
237 }
238
239 wmove(win, ocury, ocurx);
240 __sync(win);
241 return OK;
242 #endif /* HAVE_WCHAR */
243 }
244
vline_set(const cchar_t * wch,int n)245 int vline_set(const cchar_t *wch, int n)
246 {
247 #ifndef HAVE_WCHAR
248 return ERR;
249 #else
250 return wvline_set(stdscr, wch, n);
251 #endif /* HAVE_WCHAR */
252 }
253
mvvline_set(int y,int x,const cchar_t * wch,int n)254 int mvvline_set(int y, int x, const cchar_t *wch, int n)
255 {
256 #ifndef HAVE_WCHAR
257 return ERR;
258 #else
259 return mvwvline_set(stdscr, y, x, wch, n);
260 #endif /* HAVE_WCHAR */
261 }
262
mvwvline_set(WINDOW * win,int y,int x,const cchar_t * wch,int n)263 int mvwvline_set(WINDOW *win, int y, int x, const cchar_t *wch, int n)
264 {
265 #ifndef HAVE_WCHAR
266 return ERR;
267 #else
268 if (wmove(win, y, x) == ERR)
269 return ERR;
270
271 return wvline_set(win, wch, n);
272 #endif /* HAVE_WCHAR */
273 }
274
wvline_set(WINDOW * win,const cchar_t * wch,int n)275 int wvline_set(WINDOW *win, const cchar_t *wch, int n)
276 {
277 #ifndef HAVE_WCHAR
278 return ERR;
279 #else
280 int ocury, ocurx, wcn, i;
281 cchar_t cc;
282
283 wcn = min(n, win->maxy - win->cury);
284 __CTRACE(__CTRACE_LINE, "wvline_set: line of %d\n", wcn);
285 ocury = win->cury;
286 ocurx = win->curx;
287
288 cc = *wch;
289 if (!cc.vals[0]) {
290 cc.vals[0] = WACS_VLINE->vals[0];
291 cc.attributes |= WACS_VLINE->attributes;
292 }
293 for (i = 0; i < wcn; i++) {
294 mvwadd_wch(win, ocury + i, ocurx, &cc);
295 __CTRACE(__CTRACE_LINE, "wvline_set: (%d,%d)\n",
296 ocury + i, ocurx);
297 }
298
299 wmove(win, ocury, ocurx);
300 __sync(win);
301 return OK;
302 #endif /* HAVE_WCHAR */
303 }
304