1 1.34 blymn /* $NetBSD: background.c,v 1.34 2024/12/23 02:58:03 blymn Exp $ */ 2 1.1 jdc 3 1.1 jdc /*- 4 1.1 jdc * Copyright (c) 2000 The NetBSD Foundation, Inc. 5 1.1 jdc * All rights reserved. 6 1.1 jdc * 7 1.1 jdc * This code is derived from software contributed to The NetBSD Foundation 8 1.1 jdc * by Julian Coleman. 9 1.1 jdc * 10 1.1 jdc * Redistribution and use in source and binary forms, with or without 11 1.1 jdc * modification, are permitted provided that the following conditions 12 1.1 jdc * are met: 13 1.1 jdc * 1. Redistributions of source code must retain the above copyright 14 1.1 jdc * notice, this list of conditions and the following disclaimer. 15 1.1 jdc * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 jdc * notice, this list of conditions and the following disclaimer in the 17 1.1 jdc * documentation and/or other materials provided with the distribution. 18 1.1 jdc * 19 1.1 jdc * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 1.1 jdc * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 1.1 jdc * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 1.1 jdc * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 1.1 jdc * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 1.1 jdc * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 1.1 jdc * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 1.1 jdc * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 1.1 jdc * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 1.1 jdc * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 1.1 jdc * POSSIBILITY OF SUCH DAMAGE. 30 1.1 jdc */ 31 1.6 blymn 32 1.6 blymn #include <sys/cdefs.h> 33 1.6 blymn #ifndef lint 34 1.34 blymn __RCSID("$NetBSD: background.c,v 1.34 2024/12/23 02:58:03 blymn Exp $"); 35 1.6 blymn #endif /* not lint */ 36 1.1 jdc 37 1.11 blymn #include <stdlib.h> 38 1.1 jdc #include "curses.h" 39 1.1 jdc #include "curses_private.h" 40 1.1 jdc 41 1.1 jdc /* 42 1.4 jdc * bkgdset 43 1.4 jdc * Set new background attributes on stdscr. 44 1.4 jdc */ 45 1.4 jdc void 46 1.4 jdc bkgdset(chtype ch) 47 1.4 jdc { 48 1.4 jdc wbkgdset(stdscr, ch); 49 1.4 jdc } 50 1.4 jdc 51 1.4 jdc /* 52 1.4 jdc * bkgd -- 53 1.19 uwe * Set new background attributes on stdscr and apply them to its 54 1.19 uwe * contents. 55 1.4 jdc */ 56 1.4 jdc int 57 1.4 jdc bkgd(chtype ch) 58 1.4 jdc { 59 1.4 jdc return(wbkgd(stdscr, ch)); 60 1.4 jdc } 61 1.4 jdc 62 1.4 jdc /* 63 1.1 jdc * wbkgdset 64 1.19 uwe * Set new background attributes on the specified window. 65 1.1 jdc */ 66 1.1 jdc void 67 1.3 blymn wbkgdset(WINDOW *win, chtype ch) 68 1.1 jdc { 69 1.10 jdc __CTRACE(__CTRACE_ATTR, "wbkgdset: (%p), '%s', %08x\n", 70 1.18 uwe win, unctrl(ch & __CHARTEXT), ch & __ATTRIBUTES); 71 1.7 jdc 72 1.34 blymn if (__predict_false(win == NULL)) 73 1.34 blymn return; 74 1.34 blymn 75 1.7 jdc /* Background character. */ 76 1.5 jdc if (ch & __CHARTEXT) 77 1.5 jdc win->bch = (wchar_t) ch & __CHARTEXT; 78 1.7 jdc 79 1.7 jdc /* Background attributes (check colour). */ 80 1.7 jdc if (__using_color && !(ch & __COLOR)) 81 1.7 jdc ch |= __default_color; 82 1.5 jdc win->battr = (attr_t) ch & __ATTRIBUTES; 83 1.1 jdc } 84 1.1 jdc 85 1.1 jdc /* 86 1.1 jdc * wbkgd -- 87 1.19 uwe * Set new background attributes on the specified window and 88 1.19 uwe * apply them to its contents. 89 1.1 jdc */ 90 1.1 jdc int 91 1.3 blymn wbkgd(WINDOW *win, chtype ch) 92 1.1 jdc { 93 1.25 uwe int y, x; 94 1.5 jdc 95 1.10 jdc __CTRACE(__CTRACE_ATTR, "wbkgd: (%p), '%s', %08x\n", 96 1.18 uwe win, unctrl(ch & __CHARTEXT), ch & __ATTRIBUTES); 97 1.34 blymn 98 1.34 blymn if (__predict_false(win == NULL)) 99 1.34 blymn return ERR; 100 1.34 blymn 101 1.20 uwe wbkgdset(win, ch); 102 1.7 jdc 103 1.25 uwe for (y = 0; y < win->maxy; y++) { 104 1.5 jdc for (x = 0; x < win->maxx; x++) { 105 1.25 uwe __LDATA *cp = &win->alines[y]->line[x]; 106 1.25 uwe 107 1.25 uwe /* Update/switch background characters */ 108 1.31 blymn if (cp->cflags & CA_BACKGROUND) 109 1.25 uwe cp->ch = win->bch; 110 1.25 uwe 111 1.25 uwe /* Update/merge attributes */ 112 1.25 uwe cp->attr = win->battr | (cp->attr & __ALTCHARSET); 113 1.13 jdc #ifdef HAVE_WCHAR 114 1.28 blymn cp->wcols = 1; 115 1.13 jdc #endif 116 1.5 jdc } 117 1.25 uwe } 118 1.29 blymn __touchwin(win, 1); 119 1.25 uwe return OK; 120 1.1 jdc } 121 1.1 jdc 122 1.1 jdc /* 123 1.1 jdc * getbkgd -- 124 1.1 jdc * Get current background attributes. 125 1.11 blymn */ 126 1.1 jdc chtype 127 1.3 blymn getbkgd(WINDOW *win) 128 1.1 jdc { 129 1.7 jdc attr_t battr; 130 1.7 jdc 131 1.34 blymn if (__predict_false(win == NULL)) 132 1.34 blymn return ERR; 133 1.34 blymn 134 1.7 jdc /* Background attributes (check colour). */ 135 1.7 jdc battr = win->battr & A_ATTRIBUTES; 136 1.7 jdc if (__using_color && ((battr & __COLOR) == __default_color)) 137 1.23 uwe battr &= ~__COLOR; 138 1.7 jdc 139 1.7 jdc return ((chtype) ((win->bch & A_CHARTEXT) | battr)); 140 1.1 jdc } 141 1.11 blymn 142 1.21 uwe 143 1.21 uwe #ifdef HAVE_WCHAR 144 1.21 uwe 145 1.21 uwe void 146 1.21 uwe bkgrndset(const cchar_t *wch) 147 1.11 blymn { 148 1.22 uwe wbkgrndset(stdscr, wch); 149 1.11 blymn } 150 1.11 blymn 151 1.21 uwe 152 1.21 uwe int 153 1.22 uwe bkgrnd(const cchar_t *wch) 154 1.11 blymn { 155 1.22 uwe return wbkgrnd(stdscr, wch); 156 1.11 blymn } 157 1.11 blymn 158 1.21 uwe 159 1.21 uwe int 160 1.22 uwe getbkgrnd(cchar_t *wch) 161 1.11 blymn { 162 1.22 uwe return wgetbkgrnd(stdscr, wch); 163 1.11 blymn } 164 1.11 blymn 165 1.21 uwe 166 1.21 uwe void 167 1.21 uwe wbkgrndset(WINDOW *win, const cchar_t *wch) 168 1.11 blymn { 169 1.11 blymn attr_t battr; 170 1.11 blymn nschar_t *np, *tnp; 171 1.30 blymn int i, wy, wx; 172 1.30 blymn __LDATA obkgrnd, nbkgrnd; 173 1.30 blymn __LINE *wlp; 174 1.11 blymn 175 1.11 blymn __CTRACE(__CTRACE_ATTR, "wbkgrndset: (%p), '%s', %x\n", 176 1.27 rin win, (const char *)wunctrl(wch), wch->attributes); 177 1.11 blymn 178 1.34 blymn if (__predict_false(win == NULL)) 179 1.34 blymn return; 180 1.34 blymn 181 1.11 blymn /* ignore multi-column characters */ 182 1.17 roy if (!wch->elements || wcwidth(wch->vals[0]) > 1) 183 1.11 blymn return; 184 1.11 blymn 185 1.30 blymn /* get a copy of the old background, we will need it. */ 186 1.30 blymn obkgrnd.ch = win->bch; 187 1.30 blymn obkgrnd.attr = win->battr; 188 1.33 blymn obkgrnd.cflags = CA_BACKGROUND; 189 1.30 blymn obkgrnd.wcols = win->wcols; 190 1.30 blymn obkgrnd.nsp = NULL; 191 1.30 blymn _cursesi_copy_nsp(win->bnsp, &obkgrnd); 192 1.30 blymn 193 1.11 blymn /* Background character. */ 194 1.11 blymn tnp = np = win->bnsp; 195 1.17 roy if (wcwidth( wch->vals[0])) 196 1.17 roy win->bch = wch->vals[0]; 197 1.11 blymn else { 198 1.17 roy if (!np) { 199 1.16 christos np = malloc(sizeof(nschar_t)); 200 1.11 blymn if (!np) 201 1.11 blymn return; 202 1.11 blymn np->next = NULL; 203 1.11 blymn win->bnsp = np; 204 1.11 blymn } 205 1.17 roy np->ch = wch->vals[0]; 206 1.11 blymn tnp = np; 207 1.11 blymn np = np->next; 208 1.11 blymn } 209 1.11 blymn /* add non-spacing characters */ 210 1.17 roy if (wch->elements > 1) { 211 1.17 roy for (i = 1; i < wch->elements; i++) { 212 1.11 blymn if ( !np ) { 213 1.16 christos np = malloc(sizeof(nschar_t)); 214 1.11 blymn if (!np) 215 1.11 blymn return; 216 1.11 blymn np->next = NULL; 217 1.17 roy if (tnp) 218 1.11 blymn tnp->next = np; 219 1.11 blymn else 220 1.11 blymn win->bnsp = np; 221 1.11 blymn } 222 1.17 roy np->ch = wch->vals[i]; 223 1.11 blymn tnp = np; 224 1.11 blymn np = np->next; 225 1.11 blymn } 226 1.11 blymn } 227 1.11 blymn /* clear the old non-spacing characters */ 228 1.30 blymn __cursesi_free_nsp(np); 229 1.11 blymn 230 1.11 blymn /* Background attributes (check colour). */ 231 1.11 blymn battr = wch->attributes & WA_ATTRIBUTES; 232 1.11 blymn if (__using_color && !( battr & __COLOR)) 233 1.11 blymn battr |= __default_color; 234 1.11 blymn win->battr = battr; 235 1.28 blymn win->wcols = 1; 236 1.30 blymn 237 1.30 blymn nbkgrnd.ch = win->bch; 238 1.30 blymn nbkgrnd.attr = win->battr; 239 1.33 blymn nbkgrnd.cflags = CA_BACKGROUND; 240 1.30 blymn nbkgrnd.wcols = win->wcols; 241 1.30 blymn nbkgrnd.nsp = NULL; 242 1.30 blymn _cursesi_copy_nsp(win->bnsp, &nbkgrnd); 243 1.30 blymn 244 1.31 blymn /* if the background is already this char then skip updating */ 245 1.31 blymn if (_cursesi_celleq(&obkgrnd, &nbkgrnd)) 246 1.31 blymn return; 247 1.31 blymn 248 1.31 blymn /* 249 1.31 blymn * Now do the dirty work of updating all the locations 250 1.31 blymn * that have the old background character with the new. 251 1.31 blymn */ 252 1.31 blymn 253 1.30 blymn for (wy = 0; wy < win->maxy; wy++) { 254 1.30 blymn wlp = win->alines[wy]; 255 1.30 blymn for (wx = 0; wx < win->maxx; wx++) { 256 1.31 blymn if (wlp->line[wx].cflags & CA_BACKGROUND) { 257 1.30 blymn _cursesi_copy_wchar(&nbkgrnd, &wlp->line[wx]); 258 1.30 blymn } 259 1.30 blymn } 260 1.30 blymn } 261 1.32 blymn __touchwin(win, 0); 262 1.30 blymn 263 1.11 blymn } 264 1.11 blymn 265 1.21 uwe 266 1.21 uwe int 267 1.22 uwe wbkgrnd(WINDOW *win, const cchar_t *wch) 268 1.22 uwe { 269 1.22 uwe __CTRACE(__CTRACE_ATTR, "wbkgrnd: (%p), '%s', %x\n", 270 1.27 rin win, (const char *)wunctrl(wch), wch->attributes); 271 1.22 uwe 272 1.34 blymn if (__predict_false(win == NULL)) 273 1.34 blymn return ERR; 274 1.34 blymn 275 1.22 uwe /* ignore multi-column characters */ 276 1.22 uwe if (!wch->elements || wcwidth( wch->vals[ 0 ]) > 1) 277 1.22 uwe return ERR; 278 1.22 uwe 279 1.22 uwe wbkgrndset(win, wch); 280 1.29 blymn __touchwin(win, 1); 281 1.22 uwe return OK; 282 1.22 uwe } 283 1.22 uwe 284 1.22 uwe 285 1.22 uwe int 286 1.21 uwe wgetbkgrnd(WINDOW *win, cchar_t *wch) 287 1.11 blymn { 288 1.11 blymn nschar_t *np; 289 1.11 blymn 290 1.34 blymn if (__predict_false(win == NULL)) 291 1.34 blymn return ERR; 292 1.34 blymn 293 1.11 blymn /* Background attributes (check colour). */ 294 1.11 blymn wch->attributes = win->battr & WA_ATTRIBUTES; 295 1.23 uwe if (__using_color && ((wch->attributes & __COLOR) == __default_color)) 296 1.23 uwe wch->attributes &= ~__COLOR; 297 1.17 roy wch->vals[0] = win->bch; 298 1.11 blymn wch->elements = 1; 299 1.11 blymn np = win->bnsp; 300 1.11 blymn if (np) { 301 1.17 roy while (np && wch->elements < CURSES_CCHAR_MAX) { 302 1.17 roy wch->vals[wch->elements++] = np->ch; 303 1.11 blymn np = np->next; 304 1.11 blymn } 305 1.11 blymn } 306 1.11 blymn 307 1.11 blymn return OK; 308 1.11 blymn } 309 1.21 uwe 310 1.21 uwe #else /* !HAVE_WCHAR */ 311 1.21 uwe 312 1.21 uwe void 313 1.21 uwe bkgrndset(const cchar_t *wch) 314 1.21 uwe { 315 1.21 uwe return; 316 1.21 uwe } 317 1.21 uwe 318 1.21 uwe int 319 1.22 uwe bkgrnd(const cchar_t *wch) 320 1.21 uwe { 321 1.21 uwe return ERR; 322 1.21 uwe } 323 1.21 uwe 324 1.21 uwe 325 1.21 uwe int 326 1.22 uwe getbkgrnd(cchar_t *wch) 327 1.21 uwe { 328 1.21 uwe return ERR; 329 1.21 uwe } 330 1.21 uwe 331 1.21 uwe 332 1.21 uwe void 333 1.21 uwe wbkgrndset(WINDOW *win, const cchar_t *wch) 334 1.21 uwe { 335 1.21 uwe return; 336 1.21 uwe } 337 1.21 uwe 338 1.21 uwe 339 1.21 uwe int 340 1.22 uwe wbkgrnd(WINDOW *win, const cchar_t *wch) 341 1.22 uwe { 342 1.22 uwe return ERR; 343 1.22 uwe } 344 1.22 uwe 345 1.22 uwe 346 1.22 uwe int 347 1.21 uwe wgetbkgrnd(WINDOW *win, cchar_t *wch) 348 1.21 uwe { 349 1.21 uwe return ERR; 350 1.21 uwe } 351 1.21 uwe 352 1.21 uwe #endif /* !HAVE_WCHAR */ 353