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