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