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