1 /* $NetBSD: background.c,v 1.13 2007/09/19 22:13:14 jdc Exp $ */ 2 3 /*- 4 * Copyright (c) 2000 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Julian Coleman. 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. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the NetBSD 21 * Foundation, Inc. and its contributors. 22 * 4. Neither the name of The NetBSD Foundation nor the names of its 23 * contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 */ 38 39 #include <sys/cdefs.h> 40 #ifndef lint 41 __RCSID("$NetBSD: background.c,v 1.13 2007/09/19 22:13:14 jdc Exp $"); 42 #endif /* not lint */ 43 44 #include <stdlib.h> 45 #include "curses.h" 46 #include "curses_private.h" 47 48 /* 49 * bkgdset 50 * Set new background attributes on stdscr. 51 */ 52 void 53 bkgdset(chtype ch) 54 { 55 wbkgdset(stdscr, ch); 56 } 57 58 /* 59 * bkgd -- 60 * Set new background and new background attributes on stdscr. 61 */ 62 int 63 bkgd(chtype ch) 64 { 65 return(wbkgd(stdscr, ch)); 66 } 67 68 /* 69 * wbkgdset 70 * Set new background attributes. 71 */ 72 void 73 wbkgdset(WINDOW *win, chtype ch) 74 { 75 #ifdef DEBUG 76 __CTRACE(__CTRACE_ATTR, "wbkgdset: (%p), '%s', %08x\n", 77 win, unctrl(ch & +__CHARTEXT), ch & __ATTRIBUTES); 78 #endif 79 80 /* Background character. */ 81 if (ch & __CHARTEXT) 82 win->bch = (wchar_t) ch & __CHARTEXT; 83 84 /* Background attributes (check colour). */ 85 if (__using_color && !(ch & __COLOR)) 86 ch |= __default_color; 87 win->battr = (attr_t) ch & __ATTRIBUTES; 88 } 89 90 /* 91 * wbkgd -- 92 * Set new background and new background attributes. 93 */ 94 int 95 wbkgd(WINDOW *win, chtype ch) 96 { 97 int y, x; 98 99 #ifdef DEBUG 100 __CTRACE(__CTRACE_ATTR, "wbkgd: (%p), '%s', %08x\n", 101 win, unctrl(ch & +__CHARTEXT), ch & __ATTRIBUTES); 102 #endif 103 104 /* Background attributes (check colour). */ 105 if (__using_color && !(ch & __COLOR)) 106 ch |= __default_color; 107 108 win->battr = (attr_t) ch & __ATTRIBUTES; 109 wbkgdset(win, ch); 110 for (y = 0; y < win->maxy; y++) 111 for (x = 0; x < win->maxx; x++) { 112 /* Copy character if space */ 113 if (ch & A_CHARTEXT && win->lines[y]->line[x].ch == ' ') 114 win->lines[y]->line[x].ch = ch & __CHARTEXT; 115 /* Merge attributes */ 116 if (win->lines[y]->line[x].attr & __ALTCHARSET) 117 win->lines[y]->line[x].attr = 118 (ch & __ATTRIBUTES) | __ALTCHARSET; 119 else 120 win->lines[y]->line[x].attr = 121 ch & __ATTRIBUTES; 122 #ifdef HAVE_WCHAR 123 SET_WCOL(win->lines[y]->line[x], 1); 124 #endif 125 } 126 __touchwin(win); 127 return(OK); 128 } 129 130 /* 131 * getbkgd -- 132 * Get current background attributes. 133 */ 134 chtype 135 getbkgd(WINDOW *win) 136 { 137 attr_t battr; 138 139 /* Background attributes (check colour). */ 140 battr = win->battr & A_ATTRIBUTES; 141 if (__using_color && ((battr & __COLOR) == __default_color)) 142 battr &= ~__default_color; 143 144 return ((chtype) ((win->bch & A_CHARTEXT) | battr)); 145 } 146 147 int bkgrnd(const cchar_t *wch) 148 { 149 #ifndef HAVE_WCHAR 150 return ERR; 151 #else 152 return wbkgrnd( stdscr, wch ); 153 #endif /* HAVE_WCHAR */ 154 } 155 156 void bkgrndset(const cchar_t *wch) 157 { 158 #ifdef HAVE_WCHAR 159 wbkgrndset( stdscr, wch ); 160 #endif /* HAVE_WCHAR */ 161 } 162 163 int getbkgrnd(cchar_t *wch) 164 { 165 #ifndef HAVE_WCHAR 166 return ERR; 167 #else 168 return wgetbkgrnd( stdscr, wch ); 169 #endif /* HAVE_WCHAR */ 170 } 171 172 int wbkgrnd(WINDOW *win, const cchar_t *wch) 173 { 174 #ifndef HAVE_WCHAR 175 return ERR; 176 #else 177 /* int y, x, i; */ 178 attr_t battr; 179 /* nschar_t *np, *tnp, *pnp; */ 180 181 #ifdef DEBUG 182 __CTRACE(__CTRACE_ATTR, "wbkgrnd: (%p), '%s', %x\n", 183 win, (const char *) wunctrl(wch), wch->attributes); 184 #endif 185 186 /* ignore multi-column characters */ 187 if ( !wch->elements || wcwidth( wch->vals[ 0 ]) > 1 ) 188 return ERR; 189 190 /* Background attributes (check colour). */ 191 battr = wch->attributes & WA_ATTRIBUTES; 192 if (__using_color && !( battr & __COLOR)) 193 battr |= __default_color; 194 195 win->battr = battr; 196 wbkgrndset(win, wch); 197 __touchwin(win); 198 return OK; 199 #endif /* HAVE_WCHAR */ 200 } 201 202 void wbkgrndset(WINDOW *win, const cchar_t *wch) 203 { 204 #ifdef HAVE_WCHAR 205 attr_t battr; 206 nschar_t *np, *tnp; 207 int i; 208 209 #ifdef DEBUG 210 __CTRACE(__CTRACE_ATTR, "wbkgrndset: (%p), '%s', %x\n", 211 win, (const char *) wunctrl(wch), wch->attributes); 212 #endif 213 214 /* ignore multi-column characters */ 215 if ( !wch->elements || wcwidth( wch->vals[ 0 ]) > 1 ) 216 return; 217 218 /* Background character. */ 219 tnp = np = win->bnsp; 220 if ( wcwidth( wch->vals[ 0 ])) 221 win->bch = wch->vals[ 0 ]; 222 else { 223 if ( !np ) { 224 np = (nschar_t *)malloc(sizeof(nschar_t)); 225 if (!np) 226 return; 227 np->next = NULL; 228 win->bnsp = np; 229 } 230 np->ch = wch->vals[ 0 ]; 231 tnp = np; 232 np = np->next; 233 } 234 /* add non-spacing characters */ 235 if ( wch->elements > 1 ) { 236 for ( i = 1; i < wch->elements; i++ ) { 237 if ( !np ) { 238 np = (nschar_t *)malloc(sizeof(nschar_t)); 239 if (!np) 240 return; 241 np->next = NULL; 242 if ( tnp ) 243 tnp->next = np; 244 else 245 win->bnsp = np; 246 } 247 np->ch = wch->vals[ i ]; 248 tnp = np; 249 np = np->next; 250 } 251 } 252 /* clear the old non-spacing characters */ 253 while ( np ) { 254 tnp = np->next; 255 free( np ); 256 np = tnp; 257 } 258 259 /* Background attributes (check colour). */ 260 battr = wch->attributes & WA_ATTRIBUTES; 261 if (__using_color && !( battr & __COLOR)) 262 battr |= __default_color; 263 win->battr = battr; 264 SET_BGWCOL((*win), 1); 265 #endif /* HAVE_WCHAR */ 266 } 267 268 int wgetbkgrnd(WINDOW *win, cchar_t *wch) 269 { 270 #ifndef HAVE_WCHAR 271 return ERR; 272 #else 273 nschar_t *np; 274 275 /* Background attributes (check colour). */ 276 wch->attributes = win->battr & WA_ATTRIBUTES; 277 if (__using_color && (( wch->attributes & __COLOR ) 278 == __default_color)) 279 wch->attributes &= ~__default_color; 280 wch->vals[ 0 ] = win->bch; 281 wch->elements = 1; 282 np = win->bnsp; 283 if (np) { 284 while ( np && wch->elements < CURSES_CCHAR_MAX ) { 285 wch->vals[ wch->elements++ ] = np->ch; 286 np = np->next; 287 } 288 } 289 290 return OK; 291 #endif /* HAVE_WCHAR */ 292 } 293