kdeui Library API Documentation

krootpixmap.cpp

00001 /* vi: ts=8 sts=4 sw=4
00002  *
00003  * $Id: krootpixmap.cpp,v 1.23.2.3 2004/05/24 10:57:23 waba Exp $
00004  *
00005  * This file is part of the KDE project, module kdeui.
00006  * Copyright (C) 1999,2000 Geert Jansen <jansen@kde.org>
00007  *
00008  * You can Freely distribute this program under the GNU Library
00009  * General Public License. See the file "COPYING.LIB" for the exact
00010  * licensing terms.
00011  */
00012 
00013 #include <qwidget.h>
00014 #include <qtimer.h>
00015 #include <qrect.h>
00016 #include <qimage.h>
00017 
00018 #ifndef Q_WS_QWS //FIXME
00019 #include <kapplication.h>
00020 #include <kimageeffect.h>
00021 #include <kpixmapio.h>
00022 #include <kwinmodule.h>
00023 #include <kwin.h>
00024 #include <kdebug.h>
00025 #include <netwm.h>
00026 #include <dcopclient.h>
00027 
00028 #include <ksharedpixmap.h>
00029 #include <krootpixmap.h>
00030 
00031 class KRootPixmapData
00032 {
00033 public:
00034     QWidget *toplevel;
00035     KWinModule *kwin;
00036 };
00037 
00038 
00039 KRootPixmap::KRootPixmap( QWidget *widget, const char *name )
00040     : QObject(widget, name ? name : "KRootPixmap" ), m_pWidget(widget)
00041 {
00042     init();
00043 }
00044 
00045 KRootPixmap::KRootPixmap( QWidget *widget, QObject *parent, const char *name )
00046     : QObject( parent, name ? name : "KRootPixmap" ), m_pWidget(widget)
00047 {
00048     init();
00049 }
00050 
00051 void KRootPixmap::init()
00052 {
00053     d = new KRootPixmapData;
00054     m_Fade = 0;
00055     m_pPixmap = new KSharedPixmap;
00056     m_pTimer = new QTimer( this );
00057     m_bInit = false;
00058     m_bActive = false;
00059     m_bCustomPaint = false;
00060 
00061     connect(kapp, SIGNAL(backgroundChanged(int)), SLOT(slotBackgroundChanged(int)));
00062     connect(m_pPixmap, SIGNAL(done(bool)), SLOT(slotDone(bool)));
00063     connect(m_pTimer, SIGNAL(timeout()), SLOT(repaint()));
00064 
00065     d->kwin = new KWinModule( this );
00066     connect( d->kwin, SIGNAL(currentDesktopChanged(int)), SLOT(desktopChanged(int)) );
00067 
00068     d->toplevel = m_pWidget->topLevelWidget();
00069     d->toplevel->installEventFilter(this);
00070     m_pWidget->installEventFilter(this);
00071 }
00072 
00073 KRootPixmap::~KRootPixmap()
00074 {
00075     delete m_pPixmap;
00076     delete d;
00077 }
00078 
00079 
00080 int KRootPixmap::currentDesktop() const
00081 {
00082     NETRootInfo rinfo( qt_xdisplay(), NET::CurrentDesktop );
00083     rinfo.activate();
00084     return rinfo.currentDesktop();
00085 }
00086 
00087 
00088 void KRootPixmap::start()
00089 {
00090     if (m_bActive)
00091     return;
00092 
00093     m_bActive = true;
00094     if ( !isAvailable() )
00095     {
00096     // We will get a KIPC message when the shared pixmap is available.
00097     enableExports();
00098     return;
00099     }
00100     if (m_bInit)
00101     repaint(true);
00102 }
00103 
00104 
00105 void KRootPixmap::stop()
00106 {
00107     m_bActive = false;
00108     m_pTimer->stop();
00109 }
00110 
00111 
00112 void KRootPixmap::setFadeEffect(double fade, const QColor &color)
00113 {
00114     if (fade < 0)
00115     m_Fade = 0;
00116     else if (fade > 1)
00117     m_Fade = 1;
00118     else
00119     m_Fade = fade;
00120     m_FadeColor = color;
00121 
00122     if ( m_bActive && m_bInit ) repaint(true);
00123 }
00124 
00125 
00126 bool KRootPixmap::eventFilter(QObject *, QEvent *event)
00127 {
00128     // Initialise after the first show or paint event on the managed widget.
00129     if (!m_bInit && ((event->type() == QEvent::Show) || (event->type() == QEvent::Paint)))
00130     {
00131     m_bInit = true;
00132     m_Desk = currentDesktop();
00133     }
00134 
00135     if (!m_bActive)
00136     return false;
00137 
00138     switch (event->type())
00139     {
00140     case QEvent::Resize:
00141     case QEvent::Move:
00142     m_pTimer->start(100, true);
00143     break;
00144 
00145     case QEvent::Paint:
00146     m_pTimer->start(0, true);
00147     break;
00148 
00149     case QEvent::Reparent:
00150         d->toplevel->removeEventFilter(this);
00151         d->toplevel = m_pWidget->topLevelWidget();
00152         d->toplevel->installEventFilter(this);
00153         break;
00154 
00155     default:
00156     break;
00157     }
00158 
00159     return false; // always continue processing
00160 }
00161 
00162 void KRootPixmap::desktopChanged( int desk )
00163 {
00164     if( !m_pWidget->isVisible())
00165         return; // not visible, no need to update
00166     QWidget* widget = m_pWidget->topLevelWidget();
00167     if( !widget->testWFlags( WX11BypassWM )
00168         && !KWin::windowInfo( widget->winId(), NET::WMDesktop ).isOnCurrentDesktop())
00169         return; // not on current desktop -> not visible, no need to update
00170     repaint(true);
00171 }
00172 
00173 void KRootPixmap::repaint()
00174 {
00175     repaint(false);
00176 }
00177 
00178 
00179 void KRootPixmap::repaint(bool force)
00180 {
00181     QPoint p1 = m_pWidget->mapToGlobal(m_pWidget->rect().topLeft());
00182     QPoint p2 = m_pWidget->mapToGlobal(m_pWidget->rect().bottomRight());
00183     if (!force && (m_Rect == QRect(p1, p2)))
00184     return;
00185 
00186     // Due to northwest bit gravity, we don't need to do anything if the
00187     // bottom right corner of the widget is moved inward.
00188     // That said, konsole clears the background when it is resized, so
00189     // we have to reset the background pixmap.
00190     if ((p1 == m_Rect.topLeft()) && (m_pWidget->width() < m_Rect.width()) &&
00191     (m_pWidget->height() < m_Rect.height())
00192        )
00193     {
00194         m_Rect = QRect(p1, p2);
00195     updateBackground( m_pPixmap );
00196     return;
00197     }
00198     m_Rect = QRect(p1, p2);
00199     m_Desk = currentDesktop();
00200 
00201     // KSharedPixmap will correctly generate a tile for us.
00202     m_pPixmap->loadFromShared(pixmapName(m_Desk), m_Rect);
00203 }
00204 
00205 bool KRootPixmap::isAvailable() const
00206 {
00207     return m_pPixmap->isAvailable(pixmapName(m_Desk));
00208 }
00209 
00210 QString KRootPixmap::pixmapName(int desk) {
00211     QString pattern = QString("DESKTOP%1");
00212     int screen_number = DefaultScreen(qt_xdisplay());
00213     if (screen_number) {
00214         pattern = QString("SCREEN%1-DESKTOP").arg(screen_number) + "%1";
00215     }
00216     return pattern.arg( desk );
00217 }
00218 
00219 
00220 void KRootPixmap::enableExports()
00221 {
00222     kdDebug(270) << k_lineinfo << "activating background exports.\n";
00223     DCOPClient *client = kapp->dcopClient();
00224     if (!client->isAttached())
00225     client->attach();
00226     QByteArray data;
00227     QDataStream args( data, IO_WriteOnly );
00228     args << 1;
00229 
00230     QCString appname( "kdesktop" );
00231     int screen_number = DefaultScreen(qt_xdisplay());
00232     if ( screen_number )
00233         appname.sprintf("kdesktop-screen-%d", screen_number );
00234 
00235     client->send( appname, "KBackgroundIface", "setExport(int)", data );
00236 }
00237 
00238 
00239 void KRootPixmap::slotDone(bool success)
00240 {
00241     if (!success)
00242     {
00243     kdWarning(270) << k_lineinfo << "loading of desktop background failed.\n";
00244     return;
00245     }
00246 
00247     // We need to test active as the pixmap might become available
00248     // after the widget has been destroyed.
00249     if ( m_bActive )
00250     updateBackground( m_pPixmap );
00251 }
00252 
00253 void KRootPixmap::updateBackground( KSharedPixmap *spm )
00254 {
00255     QPixmap pm = *spm;
00256 
00257     if (m_Fade > 1e-6)
00258     {
00259     KPixmapIO io;
00260     QImage img = io.convertToImage(pm);
00261     img = KImageEffect::fade(img, m_Fade, m_FadeColor);
00262     pm = io.convertToPixmap(img);
00263     }
00264 
00265     if ( !m_bCustomPaint )
00266     m_pWidget->setBackgroundPixmap( pm );
00267     else {
00268     emit backgroundUpdated( pm );
00269     }
00270 }
00271 
00272 
00273 void KRootPixmap::slotBackgroundChanged(int desk)
00274 {
00275     if (!m_bInit || !m_bActive)
00276     return;
00277 
00278     if (desk == m_Desk)
00279     repaint(true);
00280 }
00281 
00282 #include "krootpixmap.moc"
00283 #endif
KDE Logo
This file is part of the documentation for kdeui Library Version 3.2.3.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Aug 4 05:24:00 2004 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2003