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