File indexing completed on 2024-05-12 05:34:32

0001 /*
0002     this file is part of the oxygen gtk engine
0003     SPDX-FileCopyrightText: 2010 Hugo Pereira Da Costa <hugo.pereira@free.fr>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 #include "oxygenbackgroundhintengine.h"
0009 #include "config.h"
0010 
0011 #include <iostream>
0012 
0013 #ifdef GDK_WINDOWING_X11
0014 #include <X11/Xlib.h>
0015 #include <X11/Xatom.h>
0016 #endif
0017 
0018 namespace Oxygen
0019 {
0020 
0021     //_________________________________________________________
0022     BackgroundHintEngine::BackgroundHintEngine( Animations* animations ):
0023         BaseEngine( animations ),
0024         _useBackgroundGradient( true )
0025     {
0026 
0027         // create background gradient atom
0028         #ifdef GDK_WINDOWING_X11
0029         GdkDisplay *display( gdk_display_get_default () );
0030         if( display )
0031         {
0032 
0033             _backgroundGradientAtom = XInternAtom( GDK_DISPLAY_XDISPLAY( display ), "_KDE_OXYGEN_BACKGROUND_GRADIENT", False);
0034             _backgroundPixmapAtom = XInternAtom( GDK_DISPLAY_XDISPLAY( display ), "_KDE_OXYGEN_BACKGROUND_PIXMAP", False);
0035 
0036         } else {
0037 
0038             _backgroundGradientAtom = None;
0039             _backgroundPixmapAtom = None;
0040 
0041         }
0042         #endif
0043     }
0044 
0045     //_________________________________________________________
0046     bool BackgroundHintEngine::registerWidget( GtkWidget* widget, BackgroundHints hints )
0047     {
0048 
0049         // check enable state
0050         if( !enabled() ) return false;
0051 
0052         #ifdef GDK_WINDOWING_X11
0053 
0054         // get associated top level widget
0055         GtkWidget* topLevel( gtk_widget_get_toplevel( widget ) );
0056         if( !topLevel ) return false;
0057 
0058         // check associated window
0059         GdkWindow* window( gtk_widget_get_window( topLevel ) );
0060         if( !window ) return false;
0061 
0062         const XID id( GDK_WINDOW_XID( window ) );
0063         if( !id ) return false;
0064 
0065         Data data( topLevel, id );
0066         if( contains( data ) ) return false;
0067 
0068         // set hint
0069         GdkDisplay *display( gtk_widget_get_display( topLevel ) );
0070         if( _useBackgroundGradient && display && _backgroundGradientAtom && (hints&BackgroundGradient) )
0071         {
0072             unsigned long uLongValue( true );
0073             XChangeProperty(
0074                 GDK_DISPLAY_XDISPLAY( display ), id, _backgroundGradientAtom, XA_CARDINAL, 32, PropModeReplace,
0075                 reinterpret_cast<const unsigned char *>(&uLongValue), 1 );
0076         }
0077 
0078         if( display && _backgroundPixmapAtom && (hints&BackgroundPixmap) )
0079         {
0080             unsigned long uLongValue( true );
0081             XChangeProperty(
0082                 GDK_DISPLAY_XDISPLAY( display ), id, _backgroundPixmapAtom, XA_CARDINAL, 32, PropModeReplace,
0083                 reinterpret_cast<const unsigned char *>(&uLongValue), 1 );
0084         }
0085 
0086         // register
0087         #if OXYGEN_DEBUG
0088         std::cerr << "Oxygen::BackgroundHintEngine::registerWidget - (" << topLevel << "," << id << ")" << std::endl;
0089         #endif
0090 
0091         // insert in set
0092         _data.insert( data );
0093 
0094         // call base class
0095         BaseEngine::registerWidget( topLevel );
0096         return true;
0097 
0098         #else
0099 
0100         return false;
0101 
0102         #endif
0103     }
0104 
0105     //_________________________________________________________
0106     void BackgroundHintEngine::unregisterWidget( GtkWidget* widget )
0107     {
0108 
0109         #ifdef GDK_WINDOWING_X11
0110         SameWidgetFTor ftor( widget );
0111         for( std::set<Data>::iterator iter = _data.begin(); iter != _data.end(); )
0112         {
0113 
0114             if( ftor( *iter ) )
0115             {
0116 
0117                 #if OXYGEN_DEBUG
0118                 std::cerr << "Oxygen::BackgroundHintEngine::unregisterWidget - (" << iter->_widget << "," << iter->_id << ")" << std::endl;
0119                 #endif
0120 
0121                 _data.erase( iter++ );
0122 
0123             } else ++iter;
0124 
0125         }
0126         #endif
0127 
0128     }
0129 
0130 
0131     //____________________________________________________________________
0132     bool BackgroundHintEngine::contains( GtkWidget* widget ) const
0133     {
0134 
0135         #ifdef GDK_WINDOWING_X11
0136         return std::find_if( _data.begin(), _data.end(), SameWidgetFTor( widget ) ) != _data.end();
0137         #else
0138         return false;
0139         #endif
0140 
0141     }
0142 
0143 }