diff options
Diffstat (limited to 'src/FbTk/FbWindow.cc')
-rw-r--r-- | src/FbTk/FbWindow.cc | 115 |
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 | ||
47 | FbWindow::FbWindow():FbDrawable(), m_parent(0), m_screen_num(0), m_window(0), m_x(0), m_y(0), | 47 | FbWindow::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 | |||
128 | void FbWindow::setBackgroundColor(const FbTk::Color &bg_color) { | 131 | void 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 | ||
132 | void FbWindow::setBackgroundPixmap(Pixmap bg_pixmap) { | 143 | void 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 | |||
151 | void 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 | ||
136 | void FbWindow::setBorderColor(const FbTk::Color &border_color) { | 217 | void 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 | /* | ||
417 | void FbWindow::setBufferPixmap(Pixmap pm) { | 501 | void FbWindow::setBufferPixmap(Pixmap pm) { |
418 | m_buffer_pm = pm; | 502 | m_lastbg_pm = pm; |
419 | } | 503 | } |
504 | */ | ||
420 | 505 | ||
421 | void FbWindow::updateGeometry() { | 506 | void FbWindow::updateGeometry() { |
422 | if (m_window == 0) | 507 | if (m_window == 0) |