background.c revision 1.34 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