| # kdeui Library API Documentation
Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Namespaces | Source Files

# krootpixmap.cpp

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

This file is part of the documentation for kdeui Library Version 3.4.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat Jun 11 20:20:22 2005 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003