1 1.19 blymn /* $NetBSD: line.c,v 1.19 2024/12/23 02:58:03 blymn Exp $ */ 2 1.1 blymn 3 1.1 blymn /*- 4 1.1 blymn * Copyright (c) 1998-1999 Brett Lymn 5 1.14 uwe * (blymn (at) baea.com.au, brett_lymn (at) yahoo.com.au) 6 1.1 blymn * All rights reserved. 7 1.1 blymn * 8 1.1 blymn * This code has been donated to The NetBSD Foundation by the Author. 9 1.1 blymn * 10 1.1 blymn * Redistribution and use in source and binary forms, with or without 11 1.1 blymn * modification, are permitted provided that the following conditions 12 1.1 blymn * are met: 13 1.1 blymn * 1. Redistributions of source code must retain the above copyright 14 1.1 blymn * notice, this list of conditions and the following disclaimer. 15 1.1 blymn * 2. The name of the author may not be used to endorse or promote products 16 1.3 wiz * derived from this software without specific prior written permission 17 1.1 blymn * 18 1.1 blymn * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 1.1 blymn * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 1.1 blymn * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 1.1 blymn * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 1.1 blymn * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 1.1 blymn * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 1.1 blymn * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 1.1 blymn * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 1.1 blymn * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 1.1 blymn * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 1.1 blymn * 29 1.1 blymn * 30 1.1 blymn */ 31 1.1 blymn 32 1.1 blymn #include <sys/cdefs.h> 33 1.1 blymn #ifndef lint 34 1.19 blymn __RCSID("$NetBSD: line.c,v 1.19 2024/12/23 02:58:03 blymn Exp $"); 35 1.1 blymn #endif /* not lint */ 36 1.1 blymn 37 1.5 blymn #include <string.h> 38 1.5 blymn 39 1.1 blymn #include "curses.h" 40 1.1 blymn #include "curses_private.h" 41 1.1 blymn 42 1.1 blymn /* 43 1.1 blymn * hline -- 44 1.5 blymn * Draw a horizontal line of character c on stdscr. 45 1.1 blymn */ 46 1.1 blymn int 47 1.1 blymn hline(chtype ch, int count) 48 1.1 blymn { 49 1.9 roy 50 1.1 blymn return whline(stdscr, ch, count); 51 1.1 blymn } 52 1.1 blymn 53 1.1 blymn /* 54 1.1 blymn * mvhline -- 55 1.5 blymn * Move to location (y, x) and draw a horizontal line of character c 56 1.5 blymn * on stdscr. 57 1.1 blymn */ 58 1.1 blymn int 59 1.1 blymn mvhline(int y, int x, chtype ch, int count) 60 1.1 blymn { 61 1.9 roy 62 1.1 blymn return mvwhline(stdscr, y, x, ch, count); 63 1.1 blymn } 64 1.1 blymn 65 1.1 blymn /* 66 1.1 blymn * mvwhline -- 67 1.5 blymn * Move to location (y, x) and draw a horizontal line of character c 68 1.5 blymn * in the given window. 69 1.1 blymn */ 70 1.1 blymn int 71 1.1 blymn mvwhline(WINDOW *win, int y, int x, chtype ch, int count) 72 1.1 blymn { 73 1.9 roy 74 1.11 blymn if (wmove(win, y, x) == ERR) 75 1.1 blymn return ERR; 76 1.1 blymn 77 1.1 blymn return whline(win, ch, count); 78 1.1 blymn } 79 1.1 blymn 80 1.1 blymn /* 81 1.1 blymn * whline -- 82 1.5 blymn * Draw a horizontal line of character c in the given window moving 83 1.5 blymn * towards the rightmost column. At most count characters are drawn 84 1.5 blymn * or until the edge of the screen, whichever comes first. 85 1.1 blymn */ 86 1.1 blymn int 87 1.1 blymn whline(WINDOW *win, chtype ch, int count) 88 1.1 blymn { 89 1.6 drochner #ifndef HAVE_WCHAR 90 1.19 blymn if (__predict_false(win == NULL)) 91 1.19 blymn return ERR; 92 1.19 blymn 93 1.13 uwe int ocury, ocurx, n, i; 94 1.1 blymn 95 1.1 blymn n = min(count, win->maxx - win->curx); 96 1.15 uwe ocury = win->cury; 97 1.1 blymn ocurx = win->curx; 98 1.4 blymn 99 1.2 jdc if (!(ch & __CHARTEXT)) 100 1.2 jdc ch |= ACS_HLINE; 101 1.1 blymn for (i = 0; i < n; i++) 102 1.13 uwe mvwaddch(win, ocury, ocurx + i, ch); 103 1.7 roy 104 1.13 uwe wmove(win, ocury, ocurx); 105 1.1 blymn return OK; 106 1.6 drochner #else 107 1.16 uwe cchar_t cch; 108 1.6 drochner 109 1.16 uwe __cursesi_chtype_to_cchar(ch, &cch); 110 1.16 uwe return whline_set(win, &cch, count); 111 1.6 drochner #endif 112 1.1 blymn } 113 1.1 blymn 114 1.1 blymn /* 115 1.1 blymn * vline -- 116 1.5 blymn * Draw a vertical line of character ch on stdscr. 117 1.1 blymn */ 118 1.1 blymn int 119 1.1 blymn vline(chtype ch, int count) 120 1.1 blymn { 121 1.9 roy 122 1.1 blymn return wvline(stdscr, ch, count); 123 1.1 blymn } 124 1.1 blymn 125 1.1 blymn /* 126 1.1 blymn * mvvline -- 127 1.18 rillig * Move to the given location and draw a vertical line of character ch. 128 1.1 blymn */ 129 1.1 blymn int 130 1.1 blymn mvvline(int y, int x, chtype ch, int count) 131 1.1 blymn { 132 1.9 roy 133 1.1 blymn return mvwvline(stdscr, y, x, ch, count); 134 1.1 blymn } 135 1.1 blymn 136 1.1 blymn /* 137 1.1 blymn * mvwvline -- 138 1.5 blymn * Move to the given location and draw a vertical line of character ch 139 1.5 blymn * on the given window. 140 1.1 blymn */ 141 1.1 blymn int 142 1.1 blymn mvwvline(WINDOW *win, int y, int x, chtype ch, int count) 143 1.1 blymn { 144 1.9 roy 145 1.11 blymn if (wmove(win, y, x) == ERR) 146 1.1 blymn return ERR; 147 1.1 blymn 148 1.1 blymn return wvline(win, ch, count); 149 1.1 blymn } 150 1.1 blymn 151 1.1 blymn /* 152 1.1 blymn * wvline -- 153 1.5 blymn * Draw a vertical line of character ch in the given window moving 154 1.5 blymn * towards the bottom of the screen. At most count characters are drawn 155 1.5 blymn * or until the edge of the screen, whichever comes first. 156 1.1 blymn */ 157 1.1 blymn int 158 1.1 blymn wvline(WINDOW *win, chtype ch, int count) 159 1.1 blymn { 160 1.6 drochner #ifndef HAVE_WCHAR 161 1.1 blymn int ocury, ocurx, n, i; 162 1.1 blymn 163 1.19 blymn if (__predict_false(win == NULL)) 164 1.19 blymn return ERR; 165 1.19 blymn 166 1.1 blymn n = min(count, win->maxy - win->cury); 167 1.1 blymn ocury = win->cury; 168 1.1 blymn ocurx = win->curx; 169 1.1 blymn 170 1.2 jdc if (!(ch & __CHARTEXT)) 171 1.2 jdc ch |= ACS_VLINE; 172 1.1 blymn for (i = 0; i < n; i++) 173 1.1 blymn mvwaddch(win, ocury + i, ocurx, ch); 174 1.1 blymn 175 1.11 blymn wmove(win, ocury, ocurx); 176 1.1 blymn return OK; 177 1.6 drochner #else 178 1.16 uwe cchar_t cch; 179 1.6 drochner 180 1.16 uwe __cursesi_chtype_to_cchar(ch, &cch); 181 1.16 uwe return wvline_set(win, &cch, count); 182 1.6 drochner #endif 183 1.1 blymn } 184 1.5 blymn 185 1.5 blymn int hline_set(const cchar_t *wch, int n) 186 1.5 blymn { 187 1.5 blymn #ifndef HAVE_WCHAR 188 1.5 blymn return ERR; 189 1.5 blymn #else 190 1.5 blymn return whline_set( stdscr, wch, n ); 191 1.5 blymn #endif /* HAVE_WCHAR */ 192 1.5 blymn } 193 1.5 blymn 194 1.5 blymn int mvhline_set(int y, int x, const cchar_t *wch, int n) 195 1.5 blymn { 196 1.5 blymn #ifndef HAVE_WCHAR 197 1.5 blymn return ERR; 198 1.5 blymn #else 199 1.5 blymn return mvwhline_set( stdscr, y, x, wch, n ); 200 1.5 blymn #endif /* HAVE_WCHAR */ 201 1.5 blymn } 202 1.5 blymn 203 1.5 blymn int mvwhline_set(WINDOW *win, int y, int x, const cchar_t *wch, int n) 204 1.5 blymn { 205 1.5 blymn #ifndef HAVE_WCHAR 206 1.5 blymn return ERR; 207 1.5 blymn #else 208 1.11 blymn if ( wmove( win, y , x ) == ERR ) 209 1.5 blymn return ERR; 210 1.5 blymn 211 1.5 blymn return whline_set( win, wch, n ); 212 1.5 blymn #endif /* HAVE_WCHAR */ 213 1.5 blymn } 214 1.5 blymn 215 1.5 blymn int whline_set(WINDOW *win, const cchar_t *wch, int n) 216 1.5 blymn { 217 1.5 blymn #ifndef HAVE_WCHAR 218 1.5 blymn return ERR; 219 1.5 blymn #else 220 1.12 uwe int ocury, ocurx, wcn, i, cw; 221 1.5 blymn cchar_t cc; 222 1.5 blymn 223 1.19 blymn if (__predict_false(win == NULL)) 224 1.19 blymn return ERR; 225 1.19 blymn 226 1.16 uwe cc = *wch; 227 1.16 uwe if (!cc.vals[0]) { 228 1.16 uwe cc.vals[0] = WACS_HLINE->vals[0]; 229 1.16 uwe cc.attributes |= WACS_HLINE->attributes; 230 1.16 uwe } 231 1.16 uwe 232 1.16 uwe cw = wcwidth(cc.vals[0]); 233 1.16 uwe if (cw <= 0) 234 1.6 drochner cw = 1; 235 1.5 blymn if ( ( win->maxx - win->curx ) < cw ) 236 1.5 blymn return ERR; 237 1.5 blymn wcn = min( n, ( win->maxx - win->curx ) / cw ); 238 1.5 blymn __CTRACE(__CTRACE_LINE, "whline_set: line of %d\n", wcn); 239 1.12 uwe ocury = win->cury; 240 1.5 blymn ocurx = win->curx; 241 1.5 blymn 242 1.5 blymn for (i = 0; i < wcn; i++ ) { 243 1.5 blymn __CTRACE(__CTRACE_LINE, "whline_set: (%d,%d)\n", 244 1.12 uwe ocury, ocurx + i * cw); 245 1.12 uwe mvwadd_wch(win, ocury, ocurx + i * cw, &cc); 246 1.5 blymn } 247 1.7 roy 248 1.12 uwe wmove(win, ocury, ocurx); 249 1.8 roy __sync(win); 250 1.5 blymn return OK; 251 1.5 blymn #endif /* HAVE_WCHAR */ 252 1.5 blymn } 253 1.5 blymn 254 1.5 blymn int vline_set(const cchar_t *wch, int n) 255 1.5 blymn { 256 1.5 blymn #ifndef HAVE_WCHAR 257 1.5 blymn return ERR; 258 1.5 blymn #else 259 1.9 roy return wvline_set(stdscr, wch, n); 260 1.5 blymn #endif /* HAVE_WCHAR */ 261 1.5 blymn } 262 1.5 blymn 263 1.5 blymn int mvvline_set(int y, int x, const cchar_t *wch, int n) 264 1.5 blymn { 265 1.5 blymn #ifndef HAVE_WCHAR 266 1.5 blymn return ERR; 267 1.5 blymn #else 268 1.9 roy return mvwvline_set(stdscr, y, x, wch, n); 269 1.5 blymn #endif /* HAVE_WCHAR */ 270 1.5 blymn } 271 1.5 blymn 272 1.5 blymn int mvwvline_set(WINDOW *win, int y, int x, const cchar_t *wch, int n) 273 1.5 blymn { 274 1.5 blymn #ifndef HAVE_WCHAR 275 1.5 blymn return ERR; 276 1.5 blymn #else 277 1.11 blymn if (wmove(win, y, x) == ERR) 278 1.5 blymn return ERR; 279 1.5 blymn 280 1.9 roy return wvline_set(win, wch, n); 281 1.5 blymn #endif /* HAVE_WCHAR */ 282 1.5 blymn } 283 1.5 blymn 284 1.5 blymn int wvline_set(WINDOW *win, const cchar_t *wch, int n) 285 1.5 blymn { 286 1.5 blymn #ifndef HAVE_WCHAR 287 1.5 blymn return ERR; 288 1.5 blymn #else 289 1.5 blymn int ocury, ocurx, wcn, i; 290 1.5 blymn cchar_t cc; 291 1.5 blymn 292 1.19 blymn if (__predict_false(win == NULL)) 293 1.19 blymn return ERR; 294 1.19 blymn 295 1.9 roy wcn = min(n, win->maxy - win->cury); 296 1.5 blymn __CTRACE(__CTRACE_LINE, "wvline_set: line of %d\n", wcn); 297 1.5 blymn ocury = win->cury; 298 1.5 blymn ocurx = win->curx; 299 1.5 blymn 300 1.16 uwe cc = *wch; 301 1.16 uwe if (!cc.vals[0]) { 302 1.16 uwe cc.vals[0] = WACS_VLINE->vals[0]; 303 1.16 uwe cc.attributes |= WACS_VLINE->attributes; 304 1.16 uwe } 305 1.5 blymn for (i = 0; i < wcn; i++) { 306 1.5 blymn mvwadd_wch(win, ocury + i, ocurx, &cc); 307 1.5 blymn __CTRACE(__CTRACE_LINE, "wvline_set: (%d,%d)\n", 308 1.5 blymn ocury + i, ocurx); 309 1.5 blymn } 310 1.8 roy 311 1.11 blymn wmove(win, ocury, ocurx); 312 1.8 roy __sync(win); 313 1.5 blymn return OK; 314 1.5 blymn #endif /* HAVE_WCHAR */ 315 1.5 blymn } 316