kdeui Library API Documentation

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