1 /* Public Domain Curses */
2 
3 #include <curspriv.h>
4 
5 RCSID("$Id: bkgd.c,v 1.39 2008/07/13 16:08:18 wmcbrine Exp $")
6 
7 /*man-start**************************************************************
8 
9   Name:                                                         bkgd
10 
11   Synopsis:
12         int bkgd(chtype ch);
13         void bkgdset(chtype ch);
14         chtype getbkgd(WINDOW *win);
15         int wbkgd(WINDOW *win, chtype ch);
16         void wbkgdset(WINDOW *win, chtype ch);
17 
18         int bkgrnd(const cchar_t *wch);
19         void bkgrndset(const cchar_t *wch);
20         int getbkgrnd(cchar_t *wch);
21         int wbkgrnd(WINDOW *win, const cchar_t *wch);
22         void wbkgrndset(WINDOW *win, const cchar_t *wch);
23         int wgetbkgrnd(WINDOW *win, cchar_t *wch);
24 
25   Description:
26         bkgdset() and wbkgdset() manipulate the background of a window.
27         The background is a chtype consisting of any combination of
28         attributes and a character; it is combined with each chtype
29         added or inserted to the window by waddch() or winsch(). Only
30         the attribute part is used to set the background of non-blank
31         characters, while both character and attributes are used for
32         blank positions.
33 
34         bkgd() and wbkgd() not only change the background, but apply it
35         immediately to every cell in the window.
36 
37         The attributes that are defined with the attrset()/attron() set
38         of functions take precedence over the background attributes if
39         there is a conflict (e.g., different color pairs).
40 
41   Return Value:
42         bkgd() and wbkgd() return OK, unless the window is NULL, in
43         which case they return ERR.
44 
45   Portability                                X/Open    BSD    SYS V
46         bkgd                                    Y       -      4.0
47         bkgdset                                 Y       -      4.0
48         getbkgd                                 Y
49         wbkgd                                   Y       -      4.0
50         wbkgdset                                Y       -      4.0
51         bkgrnd                                  Y
52         bkgrndset                               Y
53         getbkgrnd                               Y
54         wbkgrnd                                 Y
55         wbkgrndset                              Y
56         wgetbkgrnd                              Y
57 
58 **man-end****************************************************************/
59 
wbkgd(WINDOW * win,chtype ch)60 int wbkgd(WINDOW *win, chtype ch)
61 {
62     int x, y;
63     chtype oldcolr, oldch, newcolr, newch, colr, attr;
64     chtype oldattr = 0, newattr = 0;
65     chtype *winptr;
66 
67     PDC_LOG(("wbkgd() - called\n"));
68 
69     if (!win)
70         return ERR;
71 
72     if (win->_bkgd == ch)
73         return OK;
74 
75     oldcolr = win->_bkgd & A_COLOR;
76     if (oldcolr)
77         oldattr = (win->_bkgd & A_ATTRIBUTES) ^ oldcolr;
78 
79     oldch = win->_bkgd & A_CHARTEXT;
80 
81     wbkgdset(win, ch);
82 
83     newcolr = win->_bkgd & A_COLOR;
84     if (newcolr)
85         newattr = (win->_bkgd & A_ATTRIBUTES) ^ newcolr;
86 
87     newch = win->_bkgd & A_CHARTEXT;
88 
89     /* what follows is what seems to occur in the System V
90        implementation of this routine */
91 
92     for (y = 0; y < win->_maxy; y++)
93     {
94         for (x = 0; x < win->_maxx; x++)
95         {
96             winptr = win->_y[y] + x;
97 
98             ch = *winptr;
99 
100             /* determine the colors and attributes of the character read
101                from the window */
102 
103             colr = ch & A_COLOR;
104             attr = ch & (A_ATTRIBUTES ^ A_COLOR);
105 
106             /* if the color is the same as the old background color,
107                then make it the new background color, otherwise leave it */
108 
109             if (colr == oldcolr)
110                 colr = newcolr;
111 
112             /* remove any attributes (non color) from the character that
113                were part of the old background, then combine the
114                remaining ones with the new background */
115 
116             attr ^= oldattr;
117             attr |= newattr;
118 
119             /* change character if it is there because it was the old
120                background character */
121 
122             ch &= A_CHARTEXT;
123             if (ch == oldch)
124                 ch = newch;
125 
126             ch |= (attr | colr);
127 
128             *winptr = ch;
129 
130         }
131     }
132 
133     touchwin(win);
134     PDC_sync(win);
135     return OK;
136 }
137 
bkgd(chtype ch)138 int bkgd(chtype ch)
139 {
140     PDC_LOG(("bkgd() - called\n"));
141 
142     return wbkgd(stdscr, ch);
143 }
144 
wbkgdset(WINDOW * win,chtype ch)145 void wbkgdset(WINDOW *win, chtype ch)
146 {
147     PDC_LOG(("wbkgdset() - called\n"));
148 
149     if (win)
150     {
151         if (!(ch & A_CHARTEXT))
152             ch |= ' ';
153 
154         win->_bkgd = ch;
155     }
156 }
157 
bkgdset(chtype ch)158 void bkgdset(chtype ch)
159 {
160     PDC_LOG(("bkgdset() - called\n"));
161 
162     wbkgdset(stdscr, ch);
163 }
164 
getbkgd(WINDOW * win)165 chtype getbkgd(WINDOW *win)
166 {
167     PDC_LOG(("getbkgd() - called\n"));
168 
169     return win ? win->_bkgd : (chtype)ERR;
170 }
171 
172 #ifdef PDC_WIDE
wbkgrnd(WINDOW * win,const cchar_t * wch)173 int wbkgrnd(WINDOW *win, const cchar_t *wch)
174 {
175     PDC_LOG(("wbkgrnd() - called\n"));
176 
177     return wch ? wbkgd(win, *wch) : ERR;
178 }
179 
bkgrnd(const cchar_t * wch)180 int bkgrnd(const cchar_t *wch)
181 {
182     PDC_LOG(("bkgrnd() - called\n"));
183 
184     return wbkgrnd(stdscr, wch);
185 }
186 
wbkgrndset(WINDOW * win,const cchar_t * wch)187 void wbkgrndset(WINDOW *win, const cchar_t *wch)
188 {
189     PDC_LOG(("wbkgdset() - called\n"));
190 
191     if (wch)
192         wbkgdset(win, *wch);
193 }
194 
bkgrndset(const cchar_t * wch)195 void bkgrndset(const cchar_t *wch)
196 {
197     PDC_LOG(("bkgrndset() - called\n"));
198 
199     wbkgrndset(stdscr, wch);
200 }
201 
wgetbkgrnd(WINDOW * win,cchar_t * wch)202 int wgetbkgrnd(WINDOW *win, cchar_t *wch)
203 {
204     PDC_LOG(("wgetbkgrnd() - called\n"));
205 
206     if (!win || !wch)
207         return ERR;
208 
209     *wch = win->_bkgd;
210 
211     return OK;
212 }
213 
getbkgrnd(cchar_t * wch)214 int getbkgrnd(cchar_t *wch)
215 {
216     PDC_LOG(("getbkgrnd() - called\n"));
217 
218     return wgetbkgrnd(stdscr, wch);
219 }
220 #endif
221