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