kdeui Library API Documentation

krootpixmap.cpp

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