From 93a10f6233c59e45acc1c15aa91829c851c0cadf Mon Sep 17 00:00:00 2001 From: fluxgen <fluxgen> Date: Mon, 4 Aug 2003 12:44:43 +0000 Subject: added transparent option and fixed copy constructor --- src/FbTk/FbWindow.cc | 143 ++++++++++++++++++++++++++++++++++++++++++++++----- 1 file 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 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: FbWindow.cc,v 1.22 2003/07/02 05:17:30 fluxgen Exp $ +// $Id: FbWindow.cc,v 1.23 2003/08/04 12:44:43 fluxgen Exp $ #include "FbWindow.hh" -#include "EventManager.hh" +#include "EventManager.hh" #include "Color.hh" #include "App.hh" +#include "Transparent.hh" + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif // HAVE_CONFIG_H + +#include <X11/Xatom.h> #include <cassert> namespace FbTk { +namespace { +Pixmap getRootPixmap(int screen_num) { + Pixmap root_pm = 0; + // get root pixmap for transparency + Display *disp = FbTk::App::instance()->display(); + Atom real_type; + int real_format; + unsigned long items_read, items_left; + unsigned int *data; + if (XGetWindowProperty(disp, RootWindow(disp, screen_num), + XInternAtom(disp, "_XROOTPMAP_ID", false), + 0L, 1L, + false, XA_PIXMAP, &real_type, + &real_format, &items_read, &items_left, + (unsigned char **) &data) == Success && + items_read) { + root_pm = (Pixmap) (*data); + XFree(data); + } + + return root_pm; +} + +}; // end anonymous namespace + Display *FbWindow::s_display = 0; 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), s_display = App::instance()->display(); } +FbWindow::FbWindow(const FbWindow& the_copy):m_parent(the_copy.parent()), + m_screen_num(the_copy.screenNumber()), m_window(the_copy.window()), + m_x(the_copy.x()), m_y(the_copy.y()), + m_width(the_copy.width()), m_height(the_copy.height()), + m_border_width(the_copy.borderWidth()), + m_depth(the_copy.depth()), m_destroy(true) { + if (s_display == 0) + s_display = App::instance()->display(); + + the_copy.m_window = 0; +} + FbWindow::FbWindow(int screen_num, int x, int y, unsigned int width, unsigned int height, @@ -98,6 +142,7 @@ void FbWindow::setBackgroundPixmap(Pixmap bg_pixmap) { void FbWindow::setBorderColor(const FbTk::Color &border_color) { XSetWindowBorder(s_display, m_window, border_color.pixel()); } + void FbWindow::setBorderWidth(unsigned int size) { XSetWindowBorderWidth(s_display, m_window, size); m_border_width = size; @@ -121,6 +166,82 @@ void FbWindow::clearArea(int x, int y, XClearArea(s_display, window(), x, y, width, height, exposures); } +void FbWindow::updateTransparent(int the_x, int the_y, unsigned int the_width, unsigned int the_height) { +#ifdef HAVE_XRENDER + if (width() == 0 || height() == 0) + return; + + if (the_width == 0 || the_height == 0) { + the_width = width(); + the_height = height(); + } + + if (the_x < 0 || the_y < 0) { + the_x = 0; + the_y = 0; + } + + if (!m_transparent.get()) + return; + + // update source and destination if needed + Pixmap root = getRootPixmap(screenNumber()); + if (m_transparent->source() != root) + m_transparent->setSource(root, screenNumber()); + + if (m_transparent->dest() != window()) + m_transparent->setDest(window(), screenNumber()); + + // get root position + + const FbWindow *root_parent = parent(); + // our position in parent ("root") + int root_x = x() + borderWidth(), root_y = y() + borderWidth(); + if (root_parent != 0) { + root_x += root_parent->x() + root_parent->borderWidth(); + root_y += root_parent->y() + root_parent->borderWidth(); + while (root_parent->parent() != 0) { + root_parent = root_parent->parent(); + root_x += root_parent->x() + root_parent->borderWidth(); + root_y += root_parent->y() + root_parent->borderWidth(); + } + + } // else toplevel window so we already have x, y set + + // render background image from root pos to our window + m_transparent->render(root_x + the_x, root_y + the_y, + the_x, the_y, + the_width, the_height); +#endif // HAVE_XRENDER +} + +void FbWindow::setAlpha(unsigned char alpha) { +#ifdef HAVE_XRENDER + if (m_transparent.get() == 0 && alpha != 0) { + m_transparent.reset(new Transparent(getRootPixmap(screenNumber()), window(), alpha, screenNumber())); + } else if (alpha != 0 && alpha != m_transparent->alpha()) + m_transparent->setAlpha(alpha); + else if (alpha == 0) + m_transparent.reset(0); // destroy transparent object +#endif // HAVE_XRENDER +} + + +FbWindow &FbWindow::operator = (const FbWindow &win) { + m_parent = win.parent(); + m_screen_num = win.screenNumber(); + m_window = win.window(); + m_x = win.x(); + m_y = win.y(); + m_width = win.width(); + m_height = win.height(); + m_border_width = win.borderWidth(); + m_depth = win.depth(); + // take over this window + win.m_window = 0; + return *this; +} + FbWindow &FbWindow::operator = (Window win) { setNew(win); return *this; @@ -208,14 +329,14 @@ bool FbWindow::property(Atom property, unsigned long *nitems_return, unsigned long *bytes_after_return, unsigned char **prop_return) const { - if (XGetWindowProperty(s_display, window(), - property, long_offset, long_length, do_delete, - req_type, actual_type_return, - actual_format_return, nitems_return, - bytes_after_return, prop_return) == Success) - return true; - - return false; + if (XGetWindowProperty(s_display, window(), + property, long_offset, long_length, do_delete, + req_type, actual_type_return, + actual_format_return, nitems_return, + bytes_after_return, prop_return) == Success) + return true; + + return false; } void FbWindow::changeProperty(Atom property, Atom type, @@ -254,8 +375,6 @@ void FbWindow::create(Window parent, int x, int y, if (s_display == 0) s_display = FbTk::App::instance()->display(); - assert(s_display); - m_border_width = 0; long valmask = CWEventMask; -- cgit v0.11.2