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 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->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 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 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 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 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 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 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 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 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 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 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 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 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