1 /* $NetBSD: line.c,v 1.6 2010/02/23 19:48:26 drochner 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.6 2010/02/23 19:48:26 drochner 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 return whline(stdscr, ch, count); 50 } 51 52 /* 53 * mvhline -- 54 * Move to location (y, x) and draw a horizontal line of character c 55 * on stdscr. 56 */ 57 int 58 mvhline(int y, int x, chtype ch, int count) 59 { 60 return mvwhline(stdscr, y, x, ch, count); 61 } 62 63 /* 64 * mvwhline -- 65 * Move to location (y, x) and draw a horizontal line of character c 66 * in the given window. 67 */ 68 int 69 mvwhline(WINDOW *win, int y, int x, chtype ch, int count) 70 { 71 if (wmove(win, y, x) == ERR) 72 return ERR; 73 74 return whline(win, ch, count); 75 } 76 77 /* 78 * whline -- 79 * Draw a horizontal line of character c in the given window moving 80 * towards the rightmost column. At most count characters are drawn 81 * or until the edge of the screen, whichever comes first. 82 */ 83 int 84 whline(WINDOW *win, chtype ch, int count) 85 { 86 #ifndef HAVE_WCHAR 87 int ocurx, n, i; 88 89 n = min(count, win->maxx - win->curx); 90 ocurx = win->curx; 91 92 if (!(ch & __CHARTEXT)) 93 ch |= ACS_HLINE; 94 for (i = 0; i < n; i++) 95 mvwaddch(win, win->cury, ocurx + i, ch); 96 97 wmove(win, win->cury, ocurx); 98 return OK; 99 #else 100 cchar_t cch, *cchp; 101 102 if (ch & __CHARTEXT) { 103 __cursesi_chtype_to_cchar(ch, &cch); 104 cchp = & cch; 105 } else 106 cchp = WACS_HLINE; 107 108 return whline_set(win, cchp, count); 109 #endif 110 } 111 112 /* 113 * vline -- 114 * Draw a vertical line of character ch on stdscr. 115 */ 116 int 117 vline(chtype ch, int count) 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 return mvwvline(stdscr, y, x, ch, count); 130 } 131 132 /* 133 * mvwvline -- 134 * Move to the given location and draw a vertical line of character ch 135 * on the given window. 136 */ 137 int 138 mvwvline(WINDOW *win, int y, int x, chtype ch, int count) 139 { 140 if (wmove(win, y, x) == ERR) 141 return ERR; 142 143 return wvline(win, ch, count); 144 } 145 146 /* 147 * wvline -- 148 * Draw a vertical line of character ch in the given window moving 149 * towards the bottom of the screen. At most count characters are drawn 150 * or until the edge of the screen, whichever comes first. 151 */ 152 int 153 wvline(WINDOW *win, chtype ch, int count) 154 { 155 #ifndef HAVE_WCHAR 156 int ocury, ocurx, n, i; 157 158 n = min(count, win->maxy - win->cury); 159 ocury = win->cury; 160 ocurx = win->curx; 161 162 if (!(ch & __CHARTEXT)) 163 ch |= ACS_VLINE; 164 for (i = 0; i < n; i++) 165 mvwaddch(win, ocury + i, ocurx, ch); 166 167 wmove(win, ocury, ocurx); 168 return OK; 169 #else 170 cchar_t cch, *cchp; 171 172 if (ch & __CHARTEXT) { 173 __cursesi_chtype_to_cchar(ch, &cch); 174 cchp = & cch; 175 } else 176 cchp = WACS_VLINE; 177 178 return wvline_set(win, cchp, count); 179 #endif 180 } 181 182 int hline_set(const cchar_t *wch, int n) 183 { 184 #ifndef HAVE_WCHAR 185 return ERR; 186 #else 187 return whline_set( stdscr, wch, n ); 188 #endif /* HAVE_WCHAR */ 189 } 190 191 int mvhline_set(int y, int x, const cchar_t *wch, int n) 192 { 193 #ifndef HAVE_WCHAR 194 return ERR; 195 #else 196 return mvwhline_set( stdscr, y, x, wch, n ); 197 #endif /* HAVE_WCHAR */ 198 } 199 200 int mvwhline_set(WINDOW *win, int y, int x, const cchar_t *wch, int n) 201 { 202 #ifndef HAVE_WCHAR 203 return ERR; 204 #else 205 if ( wmove( win, y , x ) == ERR ) 206 return ERR; 207 208 return whline_set( win, wch, n ); 209 #endif /* HAVE_WCHAR */ 210 } 211 212 int whline_set(WINDOW *win, const cchar_t *wch, int n) 213 { 214 #ifndef HAVE_WCHAR 215 return ERR; 216 #else 217 int ocurx, wcn, i, cw; 218 cchar_t cc; 219 220 cw = wcwidth( wch->vals[ 0 ]); 221 if (cw < 0) 222 cw = 1; 223 if ( ( win->maxx - win->curx ) < cw ) 224 return ERR; 225 wcn = min( n, ( win->maxx - win->curx ) / cw ); 226 #ifdef DEBUG 227 __CTRACE(__CTRACE_LINE, "whline_set: line of %d\n", wcn); 228 #endif /* DEBUG */ 229 ocurx = win->curx; 230 231 memcpy( &cc, wch, sizeof( cchar_t )); 232 if (!(wch->vals[ 0 ])) 233 cc.vals[ 0 ] |= WACS_HLINE->vals[0]; 234 for (i = 0; i < wcn; i++ ) { 235 #ifdef DEBUG 236 __CTRACE(__CTRACE_LINE, "whline_set: (%d,%d)\n", 237 win->cury, ocurx + i * cw); 238 #endif /* DEBUG */ 239 mvwadd_wch(win, win->cury, ocurx + i * cw, &cc); 240 } 241 242 wmove(win, win->cury, ocurx); 243 return OK; 244 #endif /* HAVE_WCHAR */ 245 } 246 247 int vline_set(const cchar_t *wch, int n) 248 { 249 #ifndef HAVE_WCHAR 250 return ERR; 251 #else 252 return wvline_set( stdscr, wch, n ); 253 #endif /* HAVE_WCHAR */ 254 } 255 256 int mvvline_set(int y, int x, const cchar_t *wch, int n) 257 { 258 #ifndef HAVE_WCHAR 259 return ERR; 260 #else 261 return mvwvline_set( stdscr, y, x, wch, n ); 262 #endif /* HAVE_WCHAR */ 263 } 264 265 int mvwvline_set(WINDOW *win, int y, int x, const cchar_t *wch, int n) 266 { 267 #ifndef HAVE_WCHAR 268 return ERR; 269 #else 270 if ( wmove( win, y, x ) == ERR ) 271 return ERR; 272 273 return wvline_set( win, wch, n ); 274 #endif /* HAVE_WCHAR */ 275 } 276 277 int wvline_set(WINDOW *win, const cchar_t *wch, int n) 278 { 279 #ifndef HAVE_WCHAR 280 return ERR; 281 #else 282 int ocury, ocurx, wcn, i; 283 cchar_t cc; 284 285 wcn = min( n, win->maxy - win->cury); 286 #ifdef DEBUG 287 __CTRACE(__CTRACE_LINE, "wvline_set: line of %d\n", wcn); 288 #endif /* DEBUG */ 289 ocury = win->cury; 290 ocurx = win->curx; 291 292 memcpy( &cc, wch, sizeof( cchar_t )); 293 if (!(wch->vals[ 0 ])) 294 cc.vals[ 0 ] |= WACS_VLINE->vals[0]; 295 for (i = 0; i < wcn; i++) { 296 mvwadd_wch(win, ocury + i, ocurx, &cc); 297 #ifdef DEBUG 298 __CTRACE(__CTRACE_LINE, "wvline_set: (%d,%d)\n", 299 ocury + i, ocurx); 300 #endif /* DEBUG */ 301 } 302 wmove(win, ocury, ocurx); 303 return OK; 304 #endif /* HAVE_WCHAR */ 305 } 306