1 /* $NetBSD: line.c,v 1.16 2020/07/01 02:57:01 uwe 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.16 2020/07/01 02:57:01 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->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 #ifdef DEBUG 230 __CTRACE(__CTRACE_LINE, "whline_set: line of %d\n", wcn); 231 #endif /* DEBUG */ 232 ocury = win->cury; 233 ocurx = win->curx; 234 235 for (i = 0; i < wcn; i++ ) { 236 #ifdef DEBUG 237 __CTRACE(__CTRACE_LINE, "whline_set: (%d,%d)\n", 238 ocury, ocurx + i * cw); 239 #endif /* DEBUG */ 240 mvwadd_wch(win, ocury, ocurx + i * cw, &cc); 241 } 242 243 wmove(win, ocury, ocurx); 244 __sync(win); 245 return OK; 246 #endif /* HAVE_WCHAR */ 247 } 248 249 int vline_set(const cchar_t *wch, int n) 250 { 251 #ifndef HAVE_WCHAR 252 return ERR; 253 #else 254 return wvline_set(stdscr, wch, n); 255 #endif /* HAVE_WCHAR */ 256 } 257 258 int mvvline_set(int y, int x, const cchar_t *wch, int n) 259 { 260 #ifndef HAVE_WCHAR 261 return ERR; 262 #else 263 return mvwvline_set(stdscr, y, x, wch, n); 264 #endif /* HAVE_WCHAR */ 265 } 266 267 int mvwvline_set(WINDOW *win, int y, int x, const cchar_t *wch, int n) 268 { 269 #ifndef HAVE_WCHAR 270 return ERR; 271 #else 272 if (wmove(win, y, x) == ERR) 273 return ERR; 274 275 return wvline_set(win, wch, n); 276 #endif /* HAVE_WCHAR */ 277 } 278 279 int wvline_set(WINDOW *win, const cchar_t *wch, int n) 280 { 281 #ifndef HAVE_WCHAR 282 return ERR; 283 #else 284 int ocury, ocurx, wcn, i; 285 cchar_t cc; 286 287 wcn = min(n, win->maxy - win->cury); 288 #ifdef DEBUG 289 __CTRACE(__CTRACE_LINE, "wvline_set: line of %d\n", wcn); 290 #endif /* DEBUG */ 291 ocury = win->cury; 292 ocurx = win->curx; 293 294 cc = *wch; 295 if (!cc.vals[0]) { 296 cc.vals[0] = WACS_VLINE->vals[0]; 297 cc.attributes |= WACS_VLINE->attributes; 298 } 299 for (i = 0; i < wcn; i++) { 300 mvwadd_wch(win, ocury + i, ocurx, &cc); 301 #ifdef DEBUG 302 __CTRACE(__CTRACE_LINE, "wvline_set: (%d,%d)\n", 303 ocury + i, ocurx); 304 #endif /* DEBUG */ 305 } 306 307 wmove(win, ocury, ocurx); 308 __sync(win); 309 return OK; 310 #endif /* HAVE_WCHAR */ 311 } 312