1 // -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
2 // Texture.cc for Blackbox - an X11 Window manager
3 // Copyright (c) 2001 - 2005 Sean 'Shaleh' Perry <shaleh@debian.org>
4 // Copyright (c) 1997 - 2000, 2002 - 2005
5 // Bradley T Hughes <bhughes at trolltech.com>
7 // Permission is hereby granted, free of charge, to any person obtaining a
8 // copy of this software and associated documentation files (the "Software"),
9 // to deal in the Software without restriction, including without limitation
10 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 // and/or sell copies of the Software, and to permit persons to whom the
12 // Software is furnished to do so, subject to the following conditions:
14 // The above copyright notice and this permission notice shall be included in
15 // all copies or substantial portions of the Software.
17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 // DEALINGS IN THE SOFTWARE.
28 #include "Resource.hh"
36 void bt::Texture::setColor1(const bt::Color
&new_color
) {
39 unsigned char r
, g
, b
, rr
, gg
, bb
;
44 // calculate the light color
54 lc
.setRGB(rr
, gg
, bb
);
56 // calculate the shadow color
57 rr
= (r
>> 2) + (r
>> 1);
58 gg
= (g
>> 2) + (g
>> 1);
59 bb
= (b
>> 2) + (b
>> 1);
66 sc
.setRGB(rr
, gg
, bb
);
70 void bt::Texture::setDescription(const std::string
&d
) {
72 if (descr
.find("parentrelative") != std::string::npos
) {
73 setTexture(bt::Texture::Parent_Relative
);
77 if (descr
.find("gradient") != std::string::npos
) {
78 addTexture(bt::Texture::Gradient
);
79 if (descr
.find("crossdiagonal") != std::string::npos
)
80 addTexture(bt::Texture::CrossDiagonal
);
81 else if (descr
.find("rectangle") != std::string::npos
)
82 addTexture(bt::Texture::Rectangle
);
83 else if (descr
.find("pyramid") != std::string::npos
)
84 addTexture(bt::Texture::Pyramid
);
85 else if (descr
.find("pipecross") != std::string::npos
)
86 addTexture(bt::Texture::PipeCross
);
87 else if (descr
.find("elliptic") != std::string::npos
)
88 addTexture(bt::Texture::Elliptic
);
89 else if (descr
.find("horizontal") != std::string::npos
)
90 addTexture(bt::Texture::Horizontal
);
91 else if (descr
.find("vertical") != std::string::npos
)
92 addTexture(bt::Texture::Vertical
);
94 addTexture(bt::Texture::Diagonal
);
96 addTexture(bt::Texture::Solid
);
99 if (descr
.find("sunken") != std::string::npos
)
100 addTexture(bt::Texture::Sunken
);
101 else if (descr
.find("flat") != std::string::npos
)
102 addTexture(bt::Texture::Flat
);
104 addTexture(bt::Texture::Raised
);
106 if (descr
.find("interlaced") != std::string::npos
)
107 addTexture(bt::Texture::Interlaced
);
109 if (descr
.find("border") != std::string::npos
)
110 addTexture(bt::Texture::Border
);
115 bt::Texture
& bt::Texture::operator=(const bt::Texture
&tt
) {
130 bt::Texture
bt::textureResource(const Display
&display
,
132 const bt::Resource
&resource
,
133 const std::string
&name
,
134 const std::string
&className
,
135 const std::string
&defaultColor
)
139 std::string description
= resource
.read(name
+ ".appearance",
140 className
+ ".Appearance",
143 if (description
.empty()) {
144 // no such texture, use the default color in a flat solid texture
145 texture
.setDescription("flat solid");
146 texture
.setColor1(Color::namedColor(display
, screen
, defaultColor
));
150 texture
.setDescription(description
);
152 if ((texture
.texture() & bt::Texture::Gradient
)
153 || (texture
.texture() & bt::Texture::Interlaced
)) {
154 std::string color1
, color2
;
155 color1
= resource
.read(name
+ ".color1",
156 className
+ ".Color1",
157 resource
.read(name
+ ".color",
158 className
+ ".Color",
160 color2
= resource
.read(name
+ ".color2",
161 className
+ ".Color2",
162 resource
.read(name
+ ".colorTo",
163 className
+ ".ColorTo",
165 texture
.setColor1(Color::namedColor(display
, screen
, color1
));
166 texture
.setColor2(Color::namedColor(display
, screen
, color2
));
169 color1
= resource
.read(name
+ ".backgroundColor",
170 className
+ ".BackgroundColor",
171 resource
.read(name
+ ".color",
172 className
+ ".Color",
174 texture
.setColor1(Color::namedColor(display
, screen
, color1
));
177 if (texture
.texture() & bt::Texture::Border
) {
179 Color::namedColor(display
, screen
,
180 resource
.read(name
+ ".borderColor",
181 className
+ ".BorderColor",
183 texture
.setBorderColor(borderColor
);
185 const std::string bstr
=
186 resource
.read(name
+ ".borderWidth", className
+ ".BorderWidth", "1");
187 unsigned int bw
= static_cast<unsigned int>(strtoul(bstr
.c_str(), 0, 0));
188 texture
.setBorderWidth(bw
);
195 bt::Texture
bt::textureResource(const Display
&display
,
197 const Resource
&resource
,
198 const std::string
&name
,
199 const std::string
&className
,
200 const Texture
&defaultTexture
)
202 std::string description
= resource
.read(name
+ ".appearance",
203 className
+ ".Appearance",
206 if (description
.empty()) {
207 // no such texture, return the default
208 return defaultTexture
;
210 return textureResource(display
, screen
, resource
, name
, className
);
214 void bt::drawTexture(unsigned int screen
,
215 const Texture
&texture
,
220 Pen
pen(screen
, texture
.color1());
222 if ((texture
.texture() & Texture::Gradient
) && pixmap
) {
223 XCopyArea(pen
.XDisplay(), pixmap
, drawable
, pen
.gc(),
224 urect
.x() - trect
.x(), urect
.y() - trect
.y(),
225 urect
.width(), urect
.height(), urect
.x(), urect
.y());
227 } else if (!(texture
.texture() & Texture::Solid
)) {
228 XClearArea(pen
.XDisplay(), drawable
,
229 urect
.x(), urect
.y(), urect
.width(), urect
.height(), False
);
230 return; // might be Parent_Relative or empty
233 XFillRectangle(pen
.XDisplay(), drawable
, pen
.gc(),
234 urect
.x(), urect
.y(), urect
.width(), urect
.height());
236 int bw
= static_cast<int>(texture
.borderWidth());
237 if (texture
.texture() & bt::Texture::Border
&&
238 (trect
.left() == urect
.left() || trect
.right() == urect
.right() ||
239 trect
.top() == urect
.top() || trect
.bottom() == urect
.bottom())) {
240 Pen
penborder(screen
, texture
.borderColor());
241 penborder
.setLineWidth(bw
);
242 XDrawRectangle(pen
.XDisplay(), drawable
, penborder
.gc(),
243 trect
.x() + bw
/ 2, trect
.y() + bw
/ 2,
244 trect
.width() - bw
, trect
.height() - bw
);
247 if (texture
.texture() & bt::Texture::Interlaced
) {
248 Pen
peninterlace(screen
, texture
.color2());
249 int begin
= trect
.top() + bw
;
250 while (begin
< urect
.top()) begin
+= 2;
251 int end
= std::min(trect
.bottom() - bw
, urect
.bottom());
253 for (int i
= begin
; i
<= end
; i
+= 2)
254 XDrawLine(pen
.XDisplay(), drawable
, peninterlace
.gc(),
255 std::max(trect
.left() + bw
, urect
.left()), i
,
256 std::min(trect
.right() - bw
, urect
.right()), i
);
259 if ((trect
.left() + bw
>= urect
.left() ||
260 trect
.right() - bw
<= urect
.right() ||
261 trect
.top() + bw
>= urect
.top() ||
262 trect
.bottom() - bw
<= urect
.bottom())) {
264 Pen
penlight(screen
, texture
.lightColor());
265 Pen
penshadow(screen
, texture
.shadowColor());
267 if (texture
.texture() & bt::Texture::Raised
) {
268 XDrawLine(pen
.XDisplay(), drawable
, penshadow
.gc(),
269 trect
.left() + bw
, trect
.bottom() - bw
,
270 trect
.right() - bw
, trect
.bottom() - bw
);
271 XDrawLine(pen
.XDisplay(), drawable
, penshadow
.gc(),
272 trect
.right() - bw
, trect
.bottom() - bw
,
273 trect
.right() - bw
, trect
.top() + bw
);
275 XDrawLine(pen
.XDisplay(), drawable
, penlight
.gc(),
276 trect
.left() + bw
, trect
.top() + bw
,
277 trect
.right() - bw
, trect
.top() + bw
);
278 XDrawLine(pen
.XDisplay(), drawable
, penlight
.gc(),
279 trect
.left() + bw
, trect
.bottom() - bw
,
280 trect
.left() + bw
, trect
.top() + bw
);
281 } else if (texture
.texture() & bt::Texture::Sunken
) {
282 XDrawLine(pen
.XDisplay(), drawable
, penlight
.gc(),
283 trect
.left() + bw
, trect
.bottom() - bw
,
284 trect
.right() - bw
, trect
.bottom() - bw
);
285 XDrawLine(pen
.XDisplay(), drawable
, penlight
.gc(),
286 trect
.right() - bw
, trect
.bottom() - bw
,
287 trect
.right() - bw
, trect
.top() + bw
);
289 XDrawLine(pen
.XDisplay(), drawable
, penshadow
.gc(),
290 trect
.left() + bw
, trect
.top() + bw
,
291 trect
.right() - bw
, trect
.top() + bw
);
292 XDrawLine(pen
.XDisplay(), drawable
, penshadow
.gc(),
293 trect
.left() + bw
, trect
.bottom() - bw
,
294 trect
.left() + bw
, trect
.top() + bw
);