1*6348e3f3Sblymn /* $NetBSD: background.c,v 1.34 2024/12/23 02:58:03 blymn Exp $ */ 292d0751bSjdc 392d0751bSjdc /*- 492d0751bSjdc * Copyright (c) 2000 The NetBSD Foundation, Inc. 592d0751bSjdc * All rights reserved. 692d0751bSjdc * 792d0751bSjdc * This code is derived from software contributed to The NetBSD Foundation 892d0751bSjdc * by Julian Coleman. 992d0751bSjdc * 1092d0751bSjdc * Redistribution and use in source and binary forms, with or without 1192d0751bSjdc * modification, are permitted provided that the following conditions 1292d0751bSjdc * are met: 1392d0751bSjdc * 1. Redistributions of source code must retain the above copyright 1492d0751bSjdc * notice, this list of conditions and the following disclaimer. 1592d0751bSjdc * 2. Redistributions in binary form must reproduce the above copyright 1692d0751bSjdc * notice, this list of conditions and the following disclaimer in the 1792d0751bSjdc * documentation and/or other materials provided with the distribution. 1892d0751bSjdc * 1992d0751bSjdc * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 2092d0751bSjdc * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 2192d0751bSjdc * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 2292d0751bSjdc * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 2392d0751bSjdc * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2492d0751bSjdc * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2592d0751bSjdc * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2692d0751bSjdc * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2792d0751bSjdc * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 2892d0751bSjdc * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 2992d0751bSjdc * POSSIBILITY OF SUCH DAMAGE. 3092d0751bSjdc */ 3192d0751bSjdc 3266cab71cSblymn #include <sys/cdefs.h> 3366cab71cSblymn #ifndef lint 34*6348e3f3Sblymn __RCSID("$NetBSD: background.c,v 1.34 2024/12/23 02:58:03 blymn Exp $"); 3566cab71cSblymn #endif /* not lint */ 3666cab71cSblymn 37e124de36Sblymn #include <stdlib.h> 3892d0751bSjdc #include "curses.h" 3992d0751bSjdc #include "curses_private.h" 4092d0751bSjdc 4192d0751bSjdc /* 42032680bbSjdc * bkgdset 43032680bbSjdc * Set new background attributes on stdscr. 44032680bbSjdc */ 45032680bbSjdc void 46032680bbSjdc bkgdset(chtype ch) 47032680bbSjdc { 48032680bbSjdc wbkgdset(stdscr, ch); 49032680bbSjdc } 50032680bbSjdc 51032680bbSjdc /* 52032680bbSjdc * bkgd -- 5314d02454Suwe * Set new background attributes on stdscr and apply them to its 5414d02454Suwe * contents. 55032680bbSjdc */ 56032680bbSjdc int 57032680bbSjdc bkgd(chtype ch) 58032680bbSjdc { 59032680bbSjdc return(wbkgd(stdscr, ch)); 60032680bbSjdc } 61032680bbSjdc 62032680bbSjdc /* 6392d0751bSjdc * wbkgdset 6414d02454Suwe * Set new background attributes on the specified window. 6592d0751bSjdc */ 6692d0751bSjdc void 67aaf74682Sblymn wbkgdset(WINDOW *win, chtype ch) 6892d0751bSjdc { 691f221324Sjdc __CTRACE(__CTRACE_ATTR, "wbkgdset: (%p), '%s', %08x\n", 703f33c7bdSuwe win, unctrl(ch & __CHARTEXT), ch & __ATTRIBUTES); 714eb3ef3dSjdc 72*6348e3f3Sblymn if (__predict_false(win == NULL)) 73*6348e3f3Sblymn return; 74*6348e3f3Sblymn 754eb3ef3dSjdc /* Background character. */ 764eb3ef3dSjdc if (ch & __CHARTEXT) 774eb3ef3dSjdc win->bch = (wchar_t) ch & __CHARTEXT; 784eb3ef3dSjdc 794eb3ef3dSjdc /* Background attributes (check colour). */ 804eb3ef3dSjdc if (__using_color && !(ch & __COLOR)) 814eb3ef3dSjdc ch |= __default_color; 824eb3ef3dSjdc win->battr = (attr_t) ch & __ATTRIBUTES; 8392d0751bSjdc } 8492d0751bSjdc 8592d0751bSjdc /* 8692d0751bSjdc * wbkgd -- 8714d02454Suwe * Set new background attributes on the specified window and 8814d02454Suwe * apply them to its contents. 8992d0751bSjdc */ 9092d0751bSjdc int 91aaf74682Sblymn wbkgd(WINDOW *win, chtype ch) 9292d0751bSjdc { 9331355762Sjdc int y, x; 9431355762Sjdc 951f221324Sjdc __CTRACE(__CTRACE_ATTR, "wbkgd: (%p), '%s', %08x\n", 963f33c7bdSuwe win, unctrl(ch & __CHARTEXT), ch & __ATTRIBUTES); 97*6348e3f3Sblymn 98*6348e3f3Sblymn if (__predict_false(win == NULL)) 99*6348e3f3Sblymn return ERR; 100*6348e3f3Sblymn 10192d0751bSjdc wbkgdset(win, ch); 102ee4af76dSuwe 103ce63d7aaSuwe for (y = 0; y < win->maxy; y++) { 10431355762Sjdc for (x = 0; x < win->maxx; x++) { 105ce63d7aaSuwe __LDATA *cp = &win->alines[y]->line[x]; 106ce63d7aaSuwe 107ce63d7aaSuwe /* Update/switch background characters */ 108a7d2c216Sblymn if (cp->cflags & CA_BACKGROUND) 109ce63d7aaSuwe cp->ch = win->bch; 110ce63d7aaSuwe 111ce63d7aaSuwe /* Update/merge attributes */ 112ce63d7aaSuwe cp->attr = win->battr | (cp->attr & __ALTCHARSET); 113fe324c36Sjdc #ifdef HAVE_WCHAR 114f1942931Sblymn cp->wcols = 1; 115fe324c36Sjdc #endif 11631355762Sjdc } 117ce63d7aaSuwe } 118301bf8ccSblymn __touchwin(win, 1); 119ce63d7aaSuwe return OK; 12092d0751bSjdc } 12192d0751bSjdc 12292d0751bSjdc /* 12392d0751bSjdc * getbkgd -- 12492d0751bSjdc * Get current background attributes. 12592d0751bSjdc */ 12692d0751bSjdc chtype 127aaf74682Sblymn getbkgd(WINDOW *win) 12892d0751bSjdc { 1294eb3ef3dSjdc attr_t battr; 1304eb3ef3dSjdc 131*6348e3f3Sblymn if (__predict_false(win == NULL)) 132*6348e3f3Sblymn return ERR; 133*6348e3f3Sblymn 1344eb3ef3dSjdc /* Background attributes (check colour). */ 1354eb3ef3dSjdc battr = win->battr & A_ATTRIBUTES; 1364eb3ef3dSjdc if (__using_color && ((battr & __COLOR) == __default_color)) 13776bb9929Suwe battr &= ~__COLOR; 1384eb3ef3dSjdc 1394eb3ef3dSjdc return ((chtype) ((win->bch & A_CHARTEXT) | battr)); 14092d0751bSjdc } 141e124de36Sblymn 142e124de36Sblymn 143e124de36Sblymn #ifdef HAVE_WCHAR 1445fc07779Suwe 1455fc07779Suwe void 1465fc07779Suwe bkgrndset(const cchar_t *wch) 1475fc07779Suwe { 148e124de36Sblymn wbkgrndset(stdscr, wch); 149e124de36Sblymn } 150e124de36Sblymn 1515fc07779Suwe 1525fc07779Suwe int 1530b616789Suwe bkgrnd(const cchar_t *wch) 154e124de36Sblymn { 1550b616789Suwe return wbkgrnd(stdscr, wch); 156e124de36Sblymn } 157e124de36Sblymn 1585fc07779Suwe 1595fc07779Suwe int 1600b616789Suwe getbkgrnd(cchar_t *wch) 161e124de36Sblymn { 1620b616789Suwe return wgetbkgrnd(stdscr, wch); 163e124de36Sblymn } 164e124de36Sblymn 1655fc07779Suwe 1665fc07779Suwe void 1675fc07779Suwe wbkgrndset(WINDOW *win, const cchar_t *wch) 168e124de36Sblymn { 169e124de36Sblymn attr_t battr; 170e124de36Sblymn nschar_t *np, *tnp; 17188123910Sblymn int i, wy, wx; 17288123910Sblymn __LDATA obkgrnd, nbkgrnd; 17388123910Sblymn __LINE *wlp; 174e124de36Sblymn 175e124de36Sblymn __CTRACE(__CTRACE_ATTR, "wbkgrndset: (%p), '%s', %x\n", 176070937beSblymn win, (const char *)wunctrl(wch), wch->attributes); 177e124de36Sblymn 178*6348e3f3Sblymn if (__predict_false(win == NULL)) 179*6348e3f3Sblymn return; 180*6348e3f3Sblymn 181e124de36Sblymn /* ignore multi-column characters */ 182e124de36Sblymn if (!wch->elements || wcwidth(wch->vals[0]) > 1) 183e124de36Sblymn return; 184e124de36Sblymn 18588123910Sblymn /* get a copy of the old background, we will need it. */ 18688123910Sblymn obkgrnd.ch = win->bch; 18788123910Sblymn obkgrnd.attr = win->battr; 188ee6c5161Sblymn obkgrnd.cflags = CA_BACKGROUND; 18988123910Sblymn obkgrnd.wcols = win->wcols; 19088123910Sblymn obkgrnd.nsp = NULL; 19188123910Sblymn _cursesi_copy_nsp(win->bnsp, &obkgrnd); 19288123910Sblymn 193e124de36Sblymn /* Background character. */ 194e124de36Sblymn tnp = np = win->bnsp; 195e124de36Sblymn if (wcwidth( wch->vals[0])) 196e124de36Sblymn win->bch = wch->vals[0]; 197e124de36Sblymn else { 198e124de36Sblymn if (!np) { 1998a48cf66Schristos np = malloc(sizeof(nschar_t)); 200e124de36Sblymn if (!np) 201e124de36Sblymn return; 202e124de36Sblymn np->next = NULL; 203e124de36Sblymn win->bnsp = np; 204e124de36Sblymn } 205e124de36Sblymn np->ch = wch->vals[0]; 206e124de36Sblymn tnp = np; 207e124de36Sblymn np = np->next; 208e124de36Sblymn } 209e124de36Sblymn /* add non-spacing characters */ 210e124de36Sblymn if (wch->elements > 1) { 211e124de36Sblymn for (i = 1; i < wch->elements; i++) { 212e124de36Sblymn if ( !np ) { 2138a48cf66Schristos np = malloc(sizeof(nschar_t)); 214e124de36Sblymn if (!np) 215e124de36Sblymn return; 216e124de36Sblymn np->next = NULL; 217e124de36Sblymn if (tnp) 218e124de36Sblymn tnp->next = np; 219e124de36Sblymn else 220e124de36Sblymn win->bnsp = np; 221e124de36Sblymn } 222e124de36Sblymn np->ch = wch->vals[i]; 223e124de36Sblymn tnp = np; 224e124de36Sblymn np = np->next; 225e124de36Sblymn } 226e124de36Sblymn } 227e124de36Sblymn /* clear the old non-spacing characters */ 22888123910Sblymn __cursesi_free_nsp(np); 229e124de36Sblymn 230e124de36Sblymn /* Background attributes (check colour). */ 231e124de36Sblymn battr = wch->attributes & WA_ATTRIBUTES; 232e124de36Sblymn if (__using_color && !( battr & __COLOR)) 233e124de36Sblymn battr |= __default_color; 234e124de36Sblymn win->battr = battr; 235f1942931Sblymn win->wcols = 1; 23688123910Sblymn 237a7d2c216Sblymn nbkgrnd.ch = win->bch; 238a7d2c216Sblymn nbkgrnd.attr = win->battr; 239ee6c5161Sblymn nbkgrnd.cflags = CA_BACKGROUND; 240a7d2c216Sblymn nbkgrnd.wcols = win->wcols; 241a7d2c216Sblymn nbkgrnd.nsp = NULL; 242a7d2c216Sblymn _cursesi_copy_nsp(win->bnsp, &nbkgrnd); 243a7d2c216Sblymn 244a7d2c216Sblymn /* if the background is already this char then skip updating */ 245a7d2c216Sblymn if (_cursesi_celleq(&obkgrnd, &nbkgrnd)) 246a7d2c216Sblymn return; 247a7d2c216Sblymn 24888123910Sblymn /* 24988123910Sblymn * Now do the dirty work of updating all the locations 25088123910Sblymn * that have the old background character with the new. 25188123910Sblymn */ 25288123910Sblymn 25388123910Sblymn for (wy = 0; wy < win->maxy; wy++) { 25488123910Sblymn wlp = win->alines[wy]; 25588123910Sblymn for (wx = 0; wx < win->maxx; wx++) { 256a7d2c216Sblymn if (wlp->line[wx].cflags & CA_BACKGROUND) { 25788123910Sblymn _cursesi_copy_wchar(&nbkgrnd, &wlp->line[wx]); 25888123910Sblymn } 25988123910Sblymn } 26088123910Sblymn } 261080c30e8Sblymn __touchwin(win, 0); 26288123910Sblymn 263e124de36Sblymn } 264e124de36Sblymn 2655fc07779Suwe 2665fc07779Suwe int 2670b616789Suwe wbkgrnd(WINDOW *win, const cchar_t *wch) 2680b616789Suwe { 2690b616789Suwe __CTRACE(__CTRACE_ATTR, "wbkgrnd: (%p), '%s', %x\n", 2700b616789Suwe win, (const char *)wunctrl(wch), wch->attributes); 2710b616789Suwe 272*6348e3f3Sblymn if (__predict_false(win == NULL)) 273*6348e3f3Sblymn return ERR; 274*6348e3f3Sblymn 2750b616789Suwe /* ignore multi-column characters */ 2760b616789Suwe if (!wch->elements || wcwidth( wch->vals[ 0 ]) > 1) 2770b616789Suwe return ERR; 2780b616789Suwe 2790b616789Suwe wbkgrndset(win, wch); 280301bf8ccSblymn __touchwin(win, 1); 2810b616789Suwe return OK; 2820b616789Suwe } 2830b616789Suwe 2840b616789Suwe 2850b616789Suwe int 2865fc07779Suwe wgetbkgrnd(WINDOW *win, cchar_t *wch) 287e124de36Sblymn { 288e124de36Sblymn nschar_t *np; 289e124de36Sblymn 290*6348e3f3Sblymn if (__predict_false(win == NULL)) 291*6348e3f3Sblymn return ERR; 292*6348e3f3Sblymn 293e124de36Sblymn /* Background attributes (check colour). */ 294e124de36Sblymn wch->attributes = win->battr & WA_ATTRIBUTES; 29576bb9929Suwe if (__using_color && ((wch->attributes & __COLOR) == __default_color)) 29676bb9929Suwe wch->attributes &= ~__COLOR; 297e124de36Sblymn wch->vals[0] = win->bch; 298e124de36Sblymn wch->elements = 1; 299e124de36Sblymn np = win->bnsp; 300e124de36Sblymn if (np) { 301e124de36Sblymn while (np && wch->elements < CURSES_CCHAR_MAX) { 302e124de36Sblymn wch->vals[wch->elements++] = np->ch; 303e124de36Sblymn np = np->next; 304e124de36Sblymn } 305e124de36Sblymn } 306e124de36Sblymn 307e124de36Sblymn return OK; 308e124de36Sblymn } 3095fc07779Suwe 3105fc07779Suwe #else /* !HAVE_WCHAR */ 3115fc07779Suwe 3125fc07779Suwe void 3135fc07779Suwe bkgrndset(const cchar_t *wch) 3145fc07779Suwe { 3155fc07779Suwe return; 3165fc07779Suwe } 3175fc07779Suwe 3185fc07779Suwe int 3190b616789Suwe bkgrnd(const cchar_t *wch) 3205fc07779Suwe { 3215fc07779Suwe return ERR; 3225fc07779Suwe } 3235fc07779Suwe 3245fc07779Suwe 3255fc07779Suwe int 3260b616789Suwe getbkgrnd(cchar_t *wch) 3275fc07779Suwe { 3285fc07779Suwe return ERR; 3295fc07779Suwe } 3305fc07779Suwe 3315fc07779Suwe 3325fc07779Suwe void 3335fc07779Suwe wbkgrndset(WINDOW *win, const cchar_t *wch) 3345fc07779Suwe { 3355fc07779Suwe return; 3365fc07779Suwe } 3375fc07779Suwe 3385fc07779Suwe 3395fc07779Suwe int 3400b616789Suwe wbkgrnd(WINDOW *win, const cchar_t *wch) 3410b616789Suwe { 3420b616789Suwe return ERR; 3430b616789Suwe } 3440b616789Suwe 3450b616789Suwe 3460b616789Suwe int 3475fc07779Suwe wgetbkgrnd(WINDOW *win, cchar_t *wch) 3485fc07779Suwe { 3495fc07779Suwe return ERR; 3505fc07779Suwe } 3515fc07779Suwe 3525fc07779Suwe #endif /* !HAVE_WCHAR */ 353