1 /*
2 * this file is part of the oxygen gtk engine
3 * Copyright (c) 2010 Hugo Pereira Da Costa <hugo.pereira@free.fr>
4 *
5 * This  library is free  software; you can  redistribute it and/or
6 * modify it  under  the terms  of the  GNU Lesser  General  Public
7 * License  as published  by the Free  Software  Foundation; either
8 * version 2 of the License, or(at your option ) any later version.
9 *
10 * This library is distributed  in the hope that it will be useful,
11 * but  WITHOUT ANY WARRANTY; without even  the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License  along  with  this library;  if not,  write to  the Free
17 * Software Foundation, Inc., 51  Franklin St, Fifth Floor, Boston,
18 * MA 02110-1301, USA.
19 */
20 
21 #include "oxygenbackgroundhintengine.h"
22 #include "config.h"
23 
24 #include <iostream>
25 
26 #ifdef GDK_WINDOWING_X11
27 #include <X11/Xlib.h>
28 #include <X11/Xatom.h>
29 #endif
30 
31 namespace Oxygen
32 {
33 
34     //_________________________________________________________
BackgroundHintEngine(Animations * animations)35     BackgroundHintEngine::BackgroundHintEngine( Animations* animations ):
36         BaseEngine( animations ),
37         _useBackgroundGradient( true )
38     {
39 
40         // create background gradient atom
41         #ifdef GDK_WINDOWING_X11
42         GdkDisplay *display( gdk_display_get_default () );
43         if( display )
44         {
45 
46             _backgroundGradientAtom = XInternAtom( GDK_DISPLAY_XDISPLAY( display ), "_KDE_OXYGEN_BACKGROUND_GRADIENT", False);
47             _backgroundPixmapAtom = XInternAtom( GDK_DISPLAY_XDISPLAY( display ), "_KDE_OXYGEN_BACKGROUND_PIXMAP", False);
48 
49         } else {
50 
51             _backgroundGradientAtom = None;
52             _backgroundPixmapAtom = None;
53 
54         }
55         #endif
56     }
57 
58     //_________________________________________________________
registerWidget(GtkWidget * widget,BackgroundHints hints)59     bool BackgroundHintEngine::registerWidget( GtkWidget* widget, BackgroundHints hints )
60     {
61 
62         // check enable state
63         if( !enabled() ) return false;
64 
65         #ifdef GDK_WINDOWING_X11
66 
67         // get associated top level widget
68         GtkWidget* topLevel( gtk_widget_get_toplevel( widget ) );
69         if( !topLevel ) return false;
70 
71         // check associated window
72         GdkWindow* window( gtk_widget_get_window( topLevel ) );
73         if( !window ) return false;
74 
75         const XID id( GDK_WINDOW_XID( window ) );
76         if( !id ) return false;
77 
78         Data data( topLevel, id );
79         if( contains( data ) ) return false;
80 
81         // set hint
82         GdkDisplay *display( gtk_widget_get_display( topLevel ) );
83         if( _useBackgroundGradient && display && _backgroundGradientAtom && (hints&BackgroundGradient) )
84         {
85             unsigned long uLongValue( true );
86             XChangeProperty(
87                 GDK_DISPLAY_XDISPLAY( display ), id, _backgroundGradientAtom, XA_CARDINAL, 32, PropModeReplace,
88                 reinterpret_cast<const unsigned char *>(&uLongValue), 1 );
89         }
90 
91         if( display && _backgroundPixmapAtom && (hints&BackgroundPixmap) )
92         {
93             unsigned long uLongValue( true );
94             XChangeProperty(
95                 GDK_DISPLAY_XDISPLAY( display ), id, _backgroundPixmapAtom, XA_CARDINAL, 32, PropModeReplace,
96                 reinterpret_cast<const unsigned char *>(&uLongValue), 1 );
97         }
98 
99         // register
100         #if OXYGEN_DEBUG
101         std::cerr << "Oxygen::BackgroundHintEngine::registerWidget - (" << topLevel << "," << id << ")" << std::endl;
102         #endif
103 
104         // insert in set
105         _data.insert( data );
106 
107         // call base class
108         BaseEngine::registerWidget( topLevel );
109         return true;
110 
111         #else
112 
113         return false;
114 
115         #endif
116     }
117 
118     //_________________________________________________________
unregisterWidget(GtkWidget * widget)119     void BackgroundHintEngine::unregisterWidget( GtkWidget* widget )
120     {
121 
122         #ifdef GDK_WINDOWING_X11
123         SameWidgetFTor ftor( widget );
124         for( std::set<Data>::iterator iter = _data.begin(); iter != _data.end(); )
125         {
126 
127             if( ftor( *iter ) )
128             {
129 
130                 #if OXYGEN_DEBUG
131                 std::cerr << "Oxygen::BackgroundHintEngine::unregisterWidget - (" << iter->_widget << "," << iter->_id << ")" << std::endl;
132                 #endif
133 
134                 _data.erase( iter++ );
135 
136             } else ++iter;
137 
138         }
139         #endif
140 
141     }
142 
143 
144     //____________________________________________________________________
contains(GtkWidget * widget) const145     bool BackgroundHintEngine::contains( GtkWidget* widget ) const
146     {
147 
148         #ifdef GDK_WINDOWING_X11
149         return std::find_if( _data.begin(), _data.end(), SameWidgetFTor( widget ) ) != _data.end();
150         #else
151         return false;
152         #endif
153 
154     }
155 
156 }
157