1 /* $NetBSD: background.c,v 1.25 2018/11/19 20:37:04 uwe 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.25 2018/11/19 20:37:04 uwe 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 attributes on stdscr and apply them to its 54 * contents. 55 */ 56 int 57 bkgd(chtype ch) 58 { 59 return(wbkgd(stdscr, ch)); 60 } 61 62 /* 63 * wbkgdset 64 * Set new background attributes on the specified window. 65 */ 66 void 67 wbkgdset(WINDOW *win, chtype ch) 68 { 69 #ifdef DEBUG 70 __CTRACE(__CTRACE_ATTR, "wbkgdset: (%p), '%s', %08x\n", 71 win, unctrl(ch & __CHARTEXT), ch & __ATTRIBUTES); 72 #endif 73 74 /* Background character. */ 75 if (ch & __CHARTEXT) 76 win->bch = (wchar_t) ch & __CHARTEXT; 77 78 /* Background attributes (check colour). */ 79 if (__using_color && !(ch & __COLOR)) 80 ch |= __default_color; 81 win->battr = (attr_t) ch & __ATTRIBUTES; 82 } 83 84 /* 85 * wbkgd -- 86 * Set new background attributes on the specified window and 87 * apply them to its contents. 88 */ 89 int 90 wbkgd(WINDOW *win, chtype ch) 91 { 92 chtype obch; 93 int y, x; 94 95 #ifdef DEBUG 96 __CTRACE(__CTRACE_ATTR, "wbkgd: (%p), '%s', %08x\n", 97 win, unctrl(ch & __CHARTEXT), ch & __ATTRIBUTES); 98 #endif 99 obch = win->bch; 100 wbkgdset(win, ch); 101 102 for (y = 0; y < win->maxy; y++) { 103 for (x = 0; x < win->maxx; x++) { 104 __LDATA *cp = &win->alines[y]->line[x]; 105 106 /* Update/switch background characters */ 107 if (cp->ch == obch) 108 cp->ch = win->bch; 109 110 /* Update/merge attributes */ 111 cp->attr = win->battr | (cp->attr & __ALTCHARSET); 112 #ifdef HAVE_WCHAR 113 SET_WCOL(*cp, 1); 114 #endif 115 } 116 } 117 __touchwin(win); 118 return OK; 119 } 120 121 /* 122 * getbkgd -- 123 * Get current background attributes. 124 */ 125 chtype 126 getbkgd(WINDOW *win) 127 { 128 attr_t battr; 129 130 /* Background attributes (check colour). */ 131 battr = win->battr & A_ATTRIBUTES; 132 if (__using_color && ((battr & __COLOR) == __default_color)) 133 battr &= ~__COLOR; 134 135 return ((chtype) ((win->bch & A_CHARTEXT) | battr)); 136 } 137 138 139 #ifdef HAVE_WCHAR 140 141 void 142 bkgrndset(const cchar_t *wch) 143 { 144 wbkgrndset(stdscr, wch); 145 } 146 147 148 int 149 bkgrnd(const cchar_t *wch) 150 { 151 return wbkgrnd(stdscr, wch); 152 } 153 154 155 int 156 getbkgrnd(cchar_t *wch) 157 { 158 return wgetbkgrnd(stdscr, wch); 159 } 160 161 162 void 163 wbkgrndset(WINDOW *win, const cchar_t *wch) 164 { 165 attr_t battr; 166 nschar_t *np, *tnp; 167 int i; 168 169 #ifdef DEBUG 170 __CTRACE(__CTRACE_ATTR, "wbkgrndset: (%p), '%s', %x\n", 171 win, (const char *) wunctrl(wch), wch->attributes); 172 #endif 173 174 /* ignore multi-column characters */ 175 if (!wch->elements || wcwidth(wch->vals[0]) > 1) 176 return; 177 178 /* Background character. */ 179 tnp = np = win->bnsp; 180 if (wcwidth( wch->vals[0])) 181 win->bch = wch->vals[0]; 182 else { 183 if (!np) { 184 np = malloc(sizeof(nschar_t)); 185 if (!np) 186 return; 187 np->next = NULL; 188 win->bnsp = np; 189 } 190 np->ch = wch->vals[0]; 191 tnp = np; 192 np = np->next; 193 } 194 /* add non-spacing characters */ 195 if (wch->elements > 1) { 196 for (i = 1; i < wch->elements; i++) { 197 if ( !np ) { 198 np = malloc(sizeof(nschar_t)); 199 if (!np) 200 return; 201 np->next = NULL; 202 if (tnp) 203 tnp->next = np; 204 else 205 win->bnsp = np; 206 } 207 np->ch = wch->vals[i]; 208 tnp = np; 209 np = np->next; 210 } 211 } 212 /* clear the old non-spacing characters */ 213 while (np) { 214 tnp = np->next; 215 free(np); 216 np = tnp; 217 } 218 219 /* Background attributes (check colour). */ 220 battr = wch->attributes & WA_ATTRIBUTES; 221 if (__using_color && !( battr & __COLOR)) 222 battr |= __default_color; 223 win->battr = battr; 224 SET_BGWCOL((*win), 1); 225 } 226 227 228 int 229 wbkgrnd(WINDOW *win, const cchar_t *wch) 230 { 231 #ifdef DEBUG 232 __CTRACE(__CTRACE_ATTR, "wbkgrnd: (%p), '%s', %x\n", 233 win, (const char *) wunctrl(wch), wch->attributes); 234 #endif 235 236 /* ignore multi-column characters */ 237 if (!wch->elements || wcwidth( wch->vals[ 0 ]) > 1) 238 return ERR; 239 240 wbkgrndset(win, wch); 241 __touchwin(win); 242 return OK; 243 } 244 245 246 int 247 wgetbkgrnd(WINDOW *win, cchar_t *wch) 248 { 249 nschar_t *np; 250 251 /* Background attributes (check colour). */ 252 wch->attributes = win->battr & WA_ATTRIBUTES; 253 if (__using_color && ((wch->attributes & __COLOR) == __default_color)) 254 wch->attributes &= ~__COLOR; 255 wch->vals[0] = win->bch; 256 wch->elements = 1; 257 np = win->bnsp; 258 if (np) { 259 while (np && wch->elements < CURSES_CCHAR_MAX) { 260 wch->vals[wch->elements++] = np->ch; 261 np = np->next; 262 } 263 } 264 265 return OK; 266 } 267 268 #else /* !HAVE_WCHAR */ 269 270 void 271 bkgrndset(const cchar_t *wch) 272 { 273 return; 274 } 275 276 int 277 bkgrnd(const cchar_t *wch) 278 { 279 return ERR; 280 } 281 282 283 int 284 getbkgrnd(cchar_t *wch) 285 { 286 return ERR; 287 } 288 289 290 void 291 wbkgrndset(WINDOW *win, const cchar_t *wch) 292 { 293 return; 294 } 295 296 297 int 298 wbkgrnd(WINDOW *win, const cchar_t *wch) 299 { 300 return ERR; 301 } 302 303 304 int 305 wgetbkgrnd(WINDOW *win, cchar_t *wch) 306 { 307 return ERR; 308 } 309 310 #endif /* !HAVE_WCHAR */ 311