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 #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"
KDE Logo
This file is part of the documentation for kdeui Library Version 3.4.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Tue Apr 12 22:56:30 2005 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003