news download themes documentation links










FbWindow.cc

00001 // FbWindow.cc for FbTk - fluxbox toolkit
00002 // Copyright (c) 2002-2003 Henrik Kinnunen (fluxgen at users.sourceforge.net)
00003 //
00004 // Permission is hereby granted, free of charge, to any person obtaining a
00005 // copy of this software and associated documentation files (the "Software"),
00006 // to deal in the Software without restriction, including without limitation
00007 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
00008 // and/or sell copies of the Software, and to permit persons to whom the
00009 // Software is furnished to do so, subject to the following conditions:
00010 //
00011 // The above copyright notice and this permission notice shall be included in
00012 // all copies or substantial portions of the Software.
00013 //
00014 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00015 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00016 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
00017 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00018 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
00019 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
00020 // DEALINGS IN THE SOFTWARE.
00021 
00022 // $Id: FbWindow.cc,v 1.30 2004/01/08 22:04:39 fluxgen Exp $
00023 
00024 #include "FbWindow.hh"
00025 
00026 #include "EventManager.hh"
00027 #include "Color.hh"
00028 #include "App.hh"
00029 #include "Transparent.hh"
00030 
00031 #ifdef HAVE_CONFIG_H
00032 #include "config.h"
00033 #endif // HAVE_CONFIG_H
00034 
00035 #include <X11/Xatom.h>
00036 
00037 #include <cassert>
00038 
00039 namespace FbTk {
00040 
00041 namespace {
00042 Pixmap getRootPixmap(int screen_num) {
00043     Pixmap root_pm = 0;
00044     // get root pixmap for transparency
00045     Display *disp = FbTk::App::instance()->display();
00046     Atom real_type;
00047     int real_format;
00048     unsigned long items_read, items_left;
00049     unsigned int *data;
00050     if (XGetWindowProperty(disp, RootWindow(disp, screen_num), 
00051                            XInternAtom(disp, "_XROOTPMAP_ID", false),
00052                            0L, 1L, 
00053                            false, XA_PIXMAP, &real_type,
00054                            &real_format, &items_read, &items_left, 
00055                            (unsigned char **) &data) == Success && 
00056         items_read) { 
00057         root_pm = (Pixmap) (*data);                  
00058         XFree(data);
00059     }
00060 
00061     return root_pm; 
00062 }
00063 
00064 }; // end anonymous namespace
00065 
00066 Display *FbWindow::s_display = 0;
00067 
00068 FbWindow::FbWindow():m_parent(0), m_screen_num(0), m_window(0), m_x(0), m_y(0), 
00069                      m_width(0), m_height(0), m_border_width(0), m_depth(0), m_destroy(true),
00070                      m_buffer_pm(0) {
00071 
00072     if (s_display == 0)
00073         s_display = App::instance()->display();
00074 }
00075 
00076 FbWindow::FbWindow(const FbWindow& the_copy):m_parent(the_copy.parent()), 
00077                                              m_screen_num(the_copy.screenNumber()), m_window(the_copy.window()), 
00078                                              m_x(the_copy.x()), m_y(the_copy.y()), 
00079                                              m_width(the_copy.width()), m_height(the_copy.height()),
00080                                              m_border_width(the_copy.borderWidth()), 
00081                                              m_depth(the_copy.depth()), m_destroy(true),
00082                                              m_buffer_pm(0) {
00083     if (s_display == 0)
00084         s_display = App::instance()->display();
00085 
00086     the_copy.m_window = 0;
00087 }
00088 
00089 FbWindow::FbWindow(int screen_num,
00090                    int x, int y, 
00091                    unsigned int width, unsigned int height, 
00092                    long eventmask, 
00093                    bool override_redirect,
00094                    int depth,
00095                    int class_type):
00096     m_parent(0),
00097     m_screen_num(screen_num),
00098     m_destroy(true),
00099     m_buffer_pm(0) {
00100     
00101     create(RootWindow(FbTk::App::instance()->display(), screen_num), 
00102            x, y, width, height, eventmask,
00103            override_redirect, depth, class_type);
00104 };
00105 
00106 FbWindow::FbWindow(const FbWindow &parent,
00107                    int x, int y, unsigned int width, unsigned int height, 
00108                    long eventmask,
00109                    bool override_redirect, 
00110                    int depth, int class_type):
00111     m_parent(&parent),
00112     m_screen_num(parent.screenNumber()), 
00113     m_destroy(true),
00114     m_buffer_pm(0) { 
00115 
00116     create(parent.window(), x, y, width, height, eventmask, 
00117            override_redirect, depth, class_type);
00118     
00119     
00120 };
00121 
00122 FbWindow::FbWindow(Window client):m_parent(0), 
00123                                   m_screen_num(0),
00124                                   m_window(0),
00125                                   m_x(0), m_y(0),
00126                                   m_width(1), m_height(1),
00127                                   m_border_width(0),
00128                                   m_depth(0),
00129                                   m_destroy(false),  // don't destroy this window
00130                                   m_buffer_pm(0) {
00131 
00132     if (s_display == 0)
00133         s_display = App::instance()->display();
00134 
00135     setNew(client);
00136 }
00137 
00138 FbWindow::~FbWindow() {
00139 
00140     if (m_window != 0) {
00141         // so we don't get any dangling eventhandler for this window
00142         FbTk::EventManager::instance()->remove(m_window); 
00143         if (m_destroy)
00144             XDestroyWindow(s_display, m_window);     
00145     }
00146 }
00147 
00148 
00149 void FbWindow::setBackgroundColor(const FbTk::Color &bg_color) {
00150     XSetWindowBackground(s_display, m_window, bg_color.pixel());
00151 }
00152 
00153 void FbWindow::setBackgroundPixmap(Pixmap bg_pixmap) {
00154     XSetWindowBackgroundPixmap(s_display, m_window, bg_pixmap);
00155 }
00156 
00157 void FbWindow::setBorderColor(const FbTk::Color &border_color) {
00158     XSetWindowBorder(s_display, m_window, border_color.pixel());
00159 }
00160 
00161 void FbWindow::setBorderWidth(unsigned int size) {  
00162     XSetWindowBorderWidth(s_display, m_window, size);
00163     m_border_width = size;
00164 }
00165 
00166 void FbWindow::setName(const char *name) {
00167     XStoreName(s_display, m_window, name);
00168 }
00169 
00170 void FbWindow::setEventMask(long mask) {
00171     XSelectInput(s_display, m_window, mask);
00172 }
00173 
00174 void FbWindow::clear() {
00175     XClearWindow(s_display, m_window);
00176 }
00177 
00178 void FbWindow::clearArea(int x, int y, 
00179                          unsigned int width, unsigned int height, 
00180                          bool exposures) {
00181     XClearArea(s_display, window(), x, y, width, height, exposures);
00182 }
00183 
00184 void FbWindow::updateTransparent(int the_x, int the_y, unsigned int the_width, unsigned int the_height) {
00185 #ifdef HAVE_XRENDER
00186     if (width() == 0 || height() == 0)
00187         return;
00188 
00189     if (the_width == 0 || the_height == 0) {
00190         the_width = width();
00191         the_height = height();
00192     }
00193 
00194     if (the_x < 0 || the_y < 0) {
00195         the_x = 0;
00196         the_y = 0;
00197     }
00198 
00199     if (!m_transparent.get())
00200         return;
00201 
00202     // update source and destination if needed
00203     Pixmap root = getRootPixmap(screenNumber());
00204     if (m_transparent->source() != root)
00205         m_transparent->setSource(root, screenNumber());
00206 
00207     if (m_buffer_pm) {
00208         if (m_transparent->dest() != m_buffer_pm) {
00209             m_transparent->setDest(m_buffer_pm, screenNumber());
00210         }
00211     } else if (m_transparent->dest() != window())
00212         m_transparent->setDest(window(), screenNumber());
00213 
00214 
00215     // get root position
00216 
00217     const FbWindow *root_parent = parent();
00218     // our position in parent ("root")
00219     int root_x = x() + borderWidth(), root_y = y() + borderWidth();
00220     if (root_parent != 0) {
00221         root_x += root_parent->x() + root_parent->borderWidth();
00222         root_y += root_parent->y() + root_parent->borderWidth();
00223         while (root_parent->parent() != 0) {
00224             root_parent = root_parent->parent();
00225             root_x += root_parent->x() + root_parent->borderWidth();
00226             root_y += root_parent->y() + root_parent->borderWidth();
00227         }
00228 
00229     } // else toplevel window so we already have x, y set
00230 
00231     // render background image from root pos to our window
00232     m_transparent->render(root_x + the_x, root_y + the_y,
00233                           the_x, the_y,
00234                           the_width, the_height);
00235 #endif // HAVE_XRENDER
00236 }
00237 
00238 void FbWindow::setAlpha(unsigned char alpha) {
00239 #ifdef HAVE_XRENDER
00240     if (m_transparent.get() == 0 && alpha != 0) {
00241         m_transparent.reset(new Transparent(getRootPixmap(screenNumber()), window(), alpha, screenNumber()));
00242     } else if (alpha != 0 && alpha != m_transparent->alpha())
00243         m_transparent->setAlpha(alpha);
00244     else if (alpha == 0)
00245         m_transparent.reset(0); // destroy transparent object
00246 #endif // HAVE_XRENDER
00247 }
00248 
00249 
00250 FbWindow &FbWindow::operator = (const FbWindow &win) {
00251     m_parent = win.parent();
00252     m_screen_num = win.screenNumber();
00253     m_window = win.window();
00254     m_x = win.x();
00255     m_y = win.y();
00256     m_width = win.width();
00257     m_height = win.height();
00258     m_border_width = win.borderWidth();
00259     m_depth = win.depth();
00260     // take over this window
00261     win.m_window = 0;
00262     return *this;
00263 }
00264 
00265 FbWindow &FbWindow::operator = (Window win) {
00266     setNew(win);    
00267     return *this;
00268 }
00269 
00270 void FbWindow::setNew(Window win) {
00271     if (s_display == 0)
00272         s_display = App::instance()->display();
00273 
00274     if (m_window != 0 && m_destroy)
00275         XDestroyWindow(s_display, m_window);
00276 
00277     m_window = win;
00278 
00279     if (m_window != 0) {
00280         updateGeometry();
00281         XWindowAttributes attr;
00282         attr.screen = 0;
00283         //get screen number
00284         if (XGetWindowAttributes(s_display,
00285                                  m_window,
00286                                  &attr) != 0 && attr.screen != 0) {
00287             m_screen_num = XScreenNumberOfScreen(attr.screen);
00288             m_width = attr.width;
00289             m_height = attr.height ;
00290             m_x = attr.x;
00291             m_y = attr.y;
00292             m_depth = attr.depth;
00293             m_border_width = attr.border_width;
00294         }
00295         
00296     }
00297 }
00298 
00299 void FbWindow::show() {
00300     XMapWindow(s_display, m_window);
00301 }
00302 
00303 void FbWindow::showSubwindows() {
00304     XMapSubwindows(s_display, m_window);
00305 }
00306 
00307 void FbWindow::hide() {
00308     XUnmapWindow(s_display, m_window);
00309 }
00310 
00311 void FbWindow::lower() {
00312     XLowerWindow(s_display, window());
00313 }
00314 
00315 void FbWindow::raise() {
00316     XRaiseWindow(s_display, window());
00317 }
00318 
00319 void FbWindow::setInputFocus(int revert_to, int time) {
00320     XSetInputFocus(s_display, window(), revert_to, time);
00321 }
00322 
00323 void FbWindow::setCursor(Cursor cur) {
00324     XDefineCursor(s_display, window(), cur); 
00325 }
00326 
00327 void FbWindow::unsetCursor() {
00328     XUndefineCursor(s_display, window());
00329 }
00330 
00331 void FbWindow::reparent(const FbWindow &parent, int x, int y) {
00332     XReparentWindow(s_display, window(), parent.window(), x, y);
00333     m_parent = &parent;
00334     updateGeometry();
00335 }
00336 
00337 bool FbWindow::property(Atom property,
00338                         long long_offset, long long_length,
00339                         bool do_delete,
00340                         Atom req_type,
00341                         Atom *actual_type_return,
00342                         int *actual_format_return,
00343                         unsigned long *nitems_return,
00344                         unsigned long *bytes_after_return,
00345                         unsigned char **prop_return) const {
00346     if (XGetWindowProperty(s_display, window(), 
00347                            property, long_offset, long_length, do_delete, 
00348                            req_type, actual_type_return,
00349                            actual_format_return, nitems_return,
00350                            bytes_after_return, prop_return) == Success)
00351         return true;
00352 
00353     return false;
00354 }
00355 
00356 void FbWindow::changeProperty(Atom property, Atom type,
00357                               int format,
00358                               int mode,
00359                               unsigned char *data,
00360                               int nelements) {
00361     
00362     XChangeProperty(s_display, m_window, property, type,
00363                     format, mode, 
00364                     data, nelements);
00365 }
00366 
00367 int FbWindow::screenNumber() const {
00368     return m_screen_num;
00369 }
00370 
00371 long FbWindow::eventMask() const {
00372     XWindowAttributes attrib;
00373     if (XGetWindowAttributes(s_display, window(), 
00374                          &attrib) == Success) {
00375         return attrib.your_event_mask;
00376     }
00377     return 0;
00378 }
00379 
00380 void FbWindow::setBufferPixmap(Pixmap pm) {
00381     m_buffer_pm = pm;
00382 }
00383 
00384 void FbWindow::updateGeometry() {
00385     if (m_window == 0)
00386         return;
00387 
00388     Window root;
00389     unsigned int border_width, depth;
00390     XGetGeometry(s_display, m_window, &root, &m_x, &m_y,
00391                  (unsigned int *)&m_width, (unsigned int *)&m_height, 
00392                  &border_width, &depth);
00393     m_depth = depth;
00394 }
00395 
00396 void FbWindow::create(Window parent, int x, int y,
00397                       unsigned int width, unsigned int height, 
00398                       long eventmask, bool override_redirect,
00399                       int depth, int class_type) {
00400                      
00401 
00402     if (s_display == 0)
00403         s_display = FbTk::App::instance()->display();
00404 
00405     m_border_width = 0;
00406 
00407     long valmask = CWEventMask;
00408     XSetWindowAttributes values;
00409     values.event_mask = eventmask;
00410 
00411     if (override_redirect) {        
00412         valmask |= CWOverrideRedirect;
00413         values.override_redirect = True;
00414     }
00415 
00416     m_window = XCreateWindow(s_display, parent, x, y, width, height,
00417                              0, // border width  
00418                              depth, // depth
00419                              class_type, // class
00420                              CopyFromParent, // visual
00421                              valmask, // create mask
00422                              &values); // create atrribs
00423     
00424     assert(m_window);
00425 
00426     updateGeometry();
00427     FbWindow::setBackgroundColor(Color("gray", screenNumber()));
00428 }
00429 
00430 bool operator == (Window win, const FbWindow &fbwin) {
00431     return win == fbwin.window();
00432 }
00433 
00434 };

Fluxbox CVS-Jan-2003




      



Got comments about the page? Send them to webmaster.
If you have general Fluxbox related questions ask them on our irc channel or mailing lists.

Show Source








Designed by aLEczapKA