diff options
-rw-r--r-- | src/FbTk/FbWindow.cc | 143 |
1 files changed, 131 insertions, 12 deletions
diff --git a/src/FbTk/FbWindow.cc b/src/FbTk/FbWindow.cc index 509dd6c..5d64728 100644 --- a/src/FbTk/FbWindow.cc +++ b/src/FbTk/FbWindow.cc | |||
@@ -19,18 +19,50 @@ | |||
19 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | 19 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
20 | // DEALINGS IN THE SOFTWARE. | 20 | // DEALINGS IN THE SOFTWARE. |
21 | 21 | ||
22 | // $Id: FbWindow.cc,v 1.22 2003/07/02 05:17:30 fluxgen Exp $ | 22 | // $Id: FbWindow.cc,v 1.23 2003/08/04 12:44:43 fluxgen Exp $ |
23 | 23 | ||
24 | #include "FbWindow.hh" | 24 | #include "FbWindow.hh" |
25 | #include "EventManager.hh" | ||
26 | 25 | ||
26 | #include "EventManager.hh" | ||
27 | #include "Color.hh" | 27 | #include "Color.hh" |
28 | #include "App.hh" | 28 | #include "App.hh" |
29 | #include "Transparent.hh" | ||
30 | |||
31 | #ifdef HAVE_CONFIG_H | ||
32 | #include "config.h" | ||
33 | #endif // HAVE_CONFIG_H | ||
34 | |||
35 | #include <X11/Xatom.h> | ||
29 | 36 | ||
30 | #include <cassert> | 37 | #include <cassert> |
31 | 38 | ||
32 | namespace FbTk { | 39 | namespace FbTk { |
33 | 40 | ||
41 | namespace { | ||
42 | Pixmap getRootPixmap(int screen_num) { | ||
43 | Pixmap root_pm = 0; | ||
44 | // get root pixmap for transparency | ||
45 | Display *disp = FbTk::App::instance()->display(); | ||
46 | Atom real_type; | ||
47 | int real_format; | ||
48 | unsigned long items_read, items_left; | ||
49 | unsigned int *data; | ||
50 | if (XGetWindowProperty(disp, RootWindow(disp, screen_num), | ||
51 | XInternAtom(disp, "_XROOTPMAP_ID", false), | ||
52 | 0L, 1L, | ||
53 | false, XA_PIXMAP, &real_type, | ||
54 | &real_format, &items_read, &items_left, | ||
55 | (unsigned char **) &data) == Success && | ||
56 | items_read) { | ||
57 | root_pm = (Pixmap) (*data); | ||
58 | XFree(data); | ||
59 | } | ||
60 | |||
61 | return root_pm; | ||
62 | } | ||
63 | |||
64 | }; // end anonymous namespace | ||
65 | |||
34 | Display *FbWindow::s_display = 0; | 66 | Display *FbWindow::s_display = 0; |
35 | 67 | ||
36 | FbWindow::FbWindow():m_parent(0), m_screen_num(0), m_window(0), m_x(0), m_y(0), | 68 | FbWindow::FbWindow():m_parent(0), m_screen_num(0), m_window(0), m_x(0), m_y(0), |
@@ -40,6 +72,18 @@ FbWindow::FbWindow():m_parent(0), m_screen_num(0), m_window(0), m_x(0), m_y(0), | |||
40 | s_display = App::instance()->display(); | 72 | s_display = App::instance()->display(); |
41 | } | 73 | } |
42 | 74 | ||
75 | FbWindow::FbWindow(const FbWindow& the_copy):m_parent(the_copy.parent()), | ||
76 | m_screen_num(the_copy.screenNumber()), m_window(the_copy.window()), | ||
77 | m_x(the_copy.x()), m_y(the_copy.y()), | ||
78 | m_width(the_copy.width()), m_height(the_copy.height()), | ||
79 | m_border_width(the_copy.borderWidth()), | ||
80 | m_depth(the_copy.depth()), m_destroy(true) { | ||
81 | if (s_display == 0) | ||
82 | s_display = App::instance()->display(); | ||
83 | |||
84 | the_copy.m_window = 0; | ||
85 | } | ||
86 | |||
43 | FbWindow::FbWindow(int screen_num, | 87 | FbWindow::FbWindow(int screen_num, |
44 | int x, int y, | 88 | int x, int y, |
45 | unsigned int width, unsigned int height, | 89 | unsigned int width, unsigned int height, |
@@ -98,6 +142,7 @@ void FbWindow::setBackgroundPixmap(Pixmap bg_pixmap) { | |||
98 | void FbWindow::setBorderColor(const FbTk::Color &border_color) { | 142 | void FbWindow::setBorderColor(const FbTk::Color &border_color) { |
99 | XSetWindowBorder(s_display, m_window, border_color.pixel()); | 143 | XSetWindowBorder(s_display, m_window, border_color.pixel()); |
100 | } | 144 | } |
145 | |||
101 | void FbWindow::setBorderWidth(unsigned int size) { | 146 | void FbWindow::setBorderWidth(unsigned int size) { |
102 | XSetWindowBorderWidth(s_display, m_window, size); | 147 | XSetWindowBorderWidth(s_display, m_window, size); |
103 | m_border_width = size; | 148 | m_border_width = size; |
@@ -121,6 +166,82 @@ void FbWindow::clearArea(int x, int y, | |||
121 | XClearArea(s_display, window(), x, y, width, height, exposures); | 166 | XClearArea(s_display, window(), x, y, width, height, exposures); |
122 | } | 167 | } |
123 | 168 | ||
169 | void FbWindow::updateTransparent(int the_x, int the_y, unsigned int the_width, unsigned int the_height) { | ||
170 | #ifdef HAVE_XRENDER | ||
171 | if (width() == 0 || height() == 0) | ||
172 | return; | ||
173 | |||
174 | if (the_width == 0 || the_height == 0) { | ||
175 | the_width = width(); | ||
176 | the_height = height(); | ||
177 | } | ||
178 | |||
179 | if (the_x < 0 || the_y < 0) { | ||
180 | the_x = 0; | ||
181 | the_y = 0; | ||
182 | } | ||
183 | |||
184 | if (!m_transparent.get()) | ||
185 | return; | ||
186 | |||
187 | // update source and destination if needed | ||
188 | Pixmap root = getRootPixmap(screenNumber()); | ||
189 | if (m_transparent->source() != root) | ||
190 | m_transparent->setSource(root, screenNumber()); | ||
191 | |||
192 | if (m_transparent->dest() != window()) | ||
193 | m_transparent->setDest(window(), screenNumber()); | ||
194 | |||
195 | // get root position | ||
196 | |||
197 | const FbWindow *root_parent = parent(); | ||
198 | // our position in parent ("root") | ||
199 | int root_x = x() + borderWidth(), root_y = y() + borderWidth(); | ||
200 | if (root_parent != 0) { | ||
201 | root_x += root_parent->x() + root_parent->borderWidth(); | ||
202 | root_y += root_parent->y() + root_parent->borderWidth(); | ||
203 | while (root_parent->parent() != 0) { | ||
204 | root_parent = root_parent->parent(); | ||
205 | root_x += root_parent->x() + root_parent->borderWidth(); | ||
206 | root_y += root_parent->y() + root_parent->borderWidth(); | ||
207 | } | ||
208 | |||
209 | } // else toplevel window so we already have x, y set | ||
210 | |||
211 | // render background image from root pos to our window | ||
212 | m_transparent->render(root_x + the_x, root_y + the_y, | ||
213 | the_x, the_y, | ||
214 | the_width, the_height); | ||
215 | #endif // HAVE_XRENDER | ||
216 | } | ||
217 | |||
218 | void FbWindow::setAlpha(unsigned char alpha) { | ||
219 | #ifdef HAVE_XRENDER | ||
220 | if (m_transparent.get() == 0 && alpha != 0) { | ||
221 | m_transparent.reset(new Transparent(getRootPixmap(screenNumber()), window(), alpha, screenNumber())); | ||
222 | } else if (alpha != 0 && alpha != m_transparent->alpha()) | ||
223 | m_transparent->setAlpha(alpha); | ||
224 | else if (alpha == 0) | ||
225 | m_transparent.reset(0); // destroy transparent object | ||
226 | #endif // HAVE_XRENDER | ||
227 | } | ||
228 | |||
229 | |||
230 | FbWindow &FbWindow::operator = (const FbWindow &win) { | ||
231 | m_parent = win.parent(); | ||
232 | m_screen_num = win.screenNumber(); | ||
233 | m_window = win.window(); | ||
234 | m_x = win.x(); | ||
235 | m_y = win.y(); | ||
236 | m_width = win.width(); | ||
237 | m_height = win.height(); | ||
238 | m_border_width = win.borderWidth(); | ||
239 | m_depth = win.depth(); | ||
240 | // take over this window | ||
241 | win.m_window = 0; | ||
242 | return *this; | ||
243 | } | ||
244 | |||
124 | FbWindow &FbWindow::operator = (Window win) { | 245 | FbWindow &FbWindow::operator = (Window win) { |
125 | setNew(win); | 246 | setNew(win); |
126 | return *this; | 247 | return *this; |
@@ -208,14 +329,14 @@ bool FbWindow::property(Atom property, | |||
208 | unsigned long *nitems_return, | 329 | unsigned long *nitems_return, |
209 | unsigned long *bytes_after_return, | 330 | unsigned long *bytes_after_return, |
210 | unsigned char **prop_return) const { | 331 | unsigned char **prop_return) const { |
211 | if (XGetWindowProperty(s_display, window(), | 332 | if (XGetWindowProperty(s_display, window(), |
212 | property, long_offset, long_length, do_delete, | 333 | property, long_offset, long_length, do_delete, |
213 | req_type, actual_type_return, | 334 | req_type, actual_type_return, |
214 | actual_format_return, nitems_return, | 335 | actual_format_return, nitems_return, |
215 | bytes_after_return, prop_return) == Success) | 336 | bytes_after_return, prop_return) == Success) |
216 | return true; | 337 | return true; |
217 | 338 | ||
218 | return false; | 339 | return false; |
219 | } | 340 | } |
220 | 341 | ||
221 | void FbWindow::changeProperty(Atom property, Atom type, | 342 | void FbWindow::changeProperty(Atom property, Atom type, |
@@ -254,8 +375,6 @@ void FbWindow::create(Window parent, int x, int y, | |||
254 | if (s_display == 0) | 375 | if (s_display == 0) |
255 | s_display = FbTk::App::instance()->display(); | 376 | s_display = FbTk::App::instance()->display(); |
256 | 377 | ||
257 | assert(s_display); | ||
258 | |||
259 | m_border_width = 0; | 378 | m_border_width = 0; |
260 | 379 | ||
261 | long valmask = CWEventMask; | 380 | long valmask = CWEventMask; |