aboutsummaryrefslogtreecommitdiff
path: root/src/FbTk/FbWindow.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/FbTk/FbWindow.cc')
-rw-r--r--src/FbTk/FbWindow.cc115
1 files changed, 100 insertions, 15 deletions
diff --git a/src/FbTk/FbWindow.cc b/src/FbTk/FbWindow.cc
index 416671c..1b4f77f 100644
--- a/src/FbTk/FbWindow.cc
+++ b/src/FbTk/FbWindow.cc
@@ -46,7 +46,7 @@ namespace FbTk {
46 46
47FbWindow::FbWindow():FbDrawable(), m_parent(0), m_screen_num(0), m_window(0), m_x(0), m_y(0), 47FbWindow::FbWindow():FbDrawable(), m_parent(0), m_screen_num(0), m_window(0), m_x(0), m_y(0),
48 m_width(0), m_height(0), m_border_width(0), m_depth(0), m_destroy(true), 48 m_width(0), m_height(0), m_border_width(0), m_depth(0), m_destroy(true),
49 m_buffer_pm(0){ 49 m_lastbg_pm(0){
50 50
51} 51}
52 52
@@ -57,7 +57,7 @@ FbWindow::FbWindow(const FbWindow& the_copy):FbDrawable(),
57 m_width(the_copy.width()), m_height(the_copy.height()), 57 m_width(the_copy.width()), m_height(the_copy.height()),
58 m_border_width(the_copy.borderWidth()), 58 m_border_width(the_copy.borderWidth()),
59 m_depth(the_copy.depth()), m_destroy(true), 59 m_depth(the_copy.depth()), m_destroy(true),
60 m_buffer_pm(0) { 60 m_lastbg_pm(0) {
61 the_copy.m_window = 0; 61 the_copy.m_window = 0;
62} 62}
63 63
@@ -73,7 +73,9 @@ FbWindow::FbWindow(int screen_num,
73 m_parent(0), 73 m_parent(0),
74 m_screen_num(screen_num), 74 m_screen_num(screen_num),
75 m_destroy(true), 75 m_destroy(true),
76 m_buffer_pm(0) { 76 m_lastbg_color_set(false),
77 m_lastbg_color(0),
78 m_lastbg_pm(0) {
77 79
78 create(RootWindow(display(), screen_num), 80 create(RootWindow(display(), screen_num),
79 x, y, width, height, eventmask, 81 x, y, width, height, eventmask,
@@ -89,7 +91,9 @@ FbWindow::FbWindow(const FbWindow &parent,
89 m_parent(&parent), 91 m_parent(&parent),
90 m_screen_num(parent.screenNumber()), 92 m_screen_num(parent.screenNumber()),
91 m_destroy(true), 93 m_destroy(true),
92 m_buffer_pm(0) { 94 m_lastbg_color_set(false),
95 m_lastbg_color(0x42),
96 m_lastbg_pm(0) {
93 97
94 create(parent.window(), x, y, width, height, eventmask, 98 create(parent.window(), x, y, width, height, eventmask,
95 override_redirect, save_unders, depth, class_type); 99 override_redirect, save_unders, depth, class_type);
@@ -105,7 +109,7 @@ FbWindow::FbWindow(Window client):FbDrawable(), m_parent(0),
105 m_border_width(0), 109 m_border_width(0),
106 m_depth(0), 110 m_depth(0),
107 m_destroy(false), // don't destroy this window 111 m_destroy(false), // don't destroy this window
108 m_buffer_pm(0) { 112 m_lastbg_pm(0) {
109 113
110 setNew(client); 114 setNew(client);
111} 115}
@@ -124,13 +128,90 @@ FbWindow::~FbWindow() {
124 } 128 }
125} 129}
126 130
127
128void FbWindow::setBackgroundColor(const FbTk::Color &bg_color) { 131void FbWindow::setBackgroundColor(const FbTk::Color &bg_color) {
129 XSetWindowBackground(display(), m_window, bg_color.pixel()); 132 if (bg_color.isAllocated()) {
133 m_lastbg_color = bg_color.pixel();
134 m_lastbg_color_set = true;
135 m_lastbg_pm = None;
136 } else {
137 m_lastbg_color_set = false;
138 }
139
140 updateBackground(false);
130} 141}
131 142
132void FbWindow::setBackgroundPixmap(Pixmap bg_pixmap) { 143void FbWindow::setBackgroundPixmap(Pixmap bg_pixmap) {
133 XSetWindowBackgroundPixmap(display(), m_window, bg_pixmap); 144 m_lastbg_pm = bg_pixmap;
145 if (bg_pixmap != None)
146 m_lastbg_color_set = false;
147
148 updateBackground(false);
149}
150
151void FbWindow::updateBackground(bool only_if_alpha) {
152 Pixmap newbg = m_lastbg_pm;
153 unsigned char alpha = 255;
154 bool free_newbg = false;
155
156 if (m_transparent.get() != 0)
157 alpha = m_transparent->alpha();
158
159 if (only_if_alpha && alpha == 255)
160 return;
161
162
163 if (alpha != 255 && m_lastbg_pm != ParentRelative) {
164 // update source and destination if needed
165 Pixmap root = FbPixmap::getRootPixmap(screenNumber());
166 if (m_transparent->source() != root)
167 m_transparent->setSource(root, screenNumber());
168
169 newbg = XCreatePixmap(display(), window(), width(), height(), depth());
170 free_newbg = true;
171 GC gc = XCreateGC(display(), window(), 0, 0);
172
173 if (m_lastbg_pm == None && m_lastbg_color_set) {
174 XSetForeground(display(), gc, m_lastbg_color);
175 XFillRectangle(display(), newbg, gc, 0, 0, width(), height());
176 } else {
177 // copy from window if no color and no bg...
178 XCopyArea(display(), (m_lastbg_pm == None)?drawable():m_lastbg_pm, newbg, gc,
179 0, 0,
180 width(), height(),
181 0, 0);
182 }
183 XFreeGC(display(), gc);
184 m_transparent->setDest(newbg, screenNumber());
185
186 // get root position
187
188 const FbWindow *root_parent = parent();
189 // our position in parent ("root")
190 int root_x = x() + borderWidth(), root_y = y() + borderWidth();
191 if (root_parent != 0) {
192 root_x += root_parent->x() + root_parent->borderWidth();
193 root_y += root_parent->y() + root_parent->borderWidth();
194 while (root_parent->parent() != 0) {
195 root_parent = root_parent->parent();
196 root_x += root_parent->x() + root_parent->borderWidth();
197 root_y += root_parent->y() + root_parent->borderWidth();
198 }
199 }
200
201 // render background image from root pos to our window
202 m_transparent->render(root_x, root_y,
203 0, 0,
204 width(), height());
205 m_transparent->freeDest(); // it's only temporary, don't leave it hanging around
206 }
207
208 if (newbg != None)
209 XSetWindowBackgroundPixmap(display(), m_window, newbg);
210 else if (m_lastbg_color_set)
211 XSetWindowBackground(display(), m_window, m_lastbg_color);
212
213 if (free_newbg)
214 XFreePixmap(display(), newbg);
134} 215}
135 216
136void FbWindow::setBorderColor(const FbTk::Color &border_color) { 217void FbWindow::setBorderColor(const FbTk::Color &border_color) {
@@ -168,6 +249,13 @@ void FbWindow::updateTransparent(int the_x, int the_y, unsigned int the_width, u
168 if (width() == 0 || height() == 0) 249 if (width() == 0 || height() == 0)
169 return; 250 return;
170 251
252 if ((the_width == 0 && the_height == 0 || the_width == width() && the_height == height()) &&
253 the_x <= 0 && the_y <= 0) {
254 // do the whole thing
255 updateBackground(true);
256 return;
257 }
258
171 if (the_width == 0 || the_height == 0) { 259 if (the_width == 0 || the_height == 0) {
172 the_width = width(); 260 the_width = width();
173 the_height = height(); 261 the_height = height();
@@ -183,14 +271,9 @@ void FbWindow::updateTransparent(int the_x, int the_y, unsigned int the_width, u
183 if (m_transparent->source() != root) 271 if (m_transparent->source() != root)
184 m_transparent->setSource(root, screenNumber()); 272 m_transparent->setSource(root, screenNumber());
185 273
186 if (m_buffer_pm) { 274 if (m_transparent->dest() != window())
187 if (m_transparent->dest() != m_buffer_pm) {
188 m_transparent->setDest(m_buffer_pm, screenNumber());
189 }
190 } else if (m_transparent->dest() != window())
191 m_transparent->setDest(window(), screenNumber()); 275 m_transparent->setDest(window(), screenNumber());
192 276
193
194 // get root position 277 // get root position
195 278
196 const FbWindow *root_parent = parent(); 279 const FbWindow *root_parent = parent();
@@ -414,9 +497,11 @@ void FbWindow::setOpaque(unsigned char alpha) {
414#endif // HAVE_XRENDER 497#endif // HAVE_XRENDER
415} 498}
416 499
500/*
417void FbWindow::setBufferPixmap(Pixmap pm) { 501void FbWindow::setBufferPixmap(Pixmap pm) {
418 m_buffer_pm = pm; 502 m_lastbg_pm = pm;
419} 503}
504*/
420 505
421void FbWindow::updateGeometry() { 506void FbWindow::updateGeometry() {
422 if (m_window == 0) 507 if (m_window == 0)