00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <tqwidget.h>
00013 #include <tqtimer.h>
00014 #include <tqrect.h>
00015 #include <tqimage.h>
00016
00017 #include <tdeapplication.h>
00018 #include <kimageeffect.h>
00019 #include <kpixmapio.h>
00020 #include <twinmodule.h>
00021 #include <twin.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 TQString wallpaperForDesktop(int desktop)
00032 {
00033 return DCOPRef("kdesktop", "KBackgroundIface").call("currentWallpaper", desktop);
00034 }
00035
00036 class KRootPixmapData
00037 {
00038 public:
00039 TQWidget *toplevel;
00040 #ifdef Q_WS_X11
00041 KWinModule *twin;
00042 #endif
00043 };
00044
00045
00046 KRootPixmap::KRootPixmap( TQWidget *widget, const char *name )
00047 : TQObject(widget, name ? name : "KRootPixmap" ), m_Desk(0), m_pWidget(widget)
00048 {
00049 init();
00050 }
00051
00052 KRootPixmap::KRootPixmap( TQWidget *widget, TQObject *parent, const char *name )
00053 : TQObject( 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_BlurRadius = 0;
00063 m_BlurSigma = 0;
00064 m_pPixmap = new TDESharedPixmap;
00065 m_pTimer = new TQTimer( this );
00066 m_bInit = false;
00067 m_bActive = false;
00068 m_bCustomPaint = false;
00069
00070 connect(kapp, TQT_SIGNAL(backgroundChanged(int)), TQT_SLOT(slotBackgroundChanged(int)));
00071 connect(m_pTimer, TQT_SIGNAL(timeout()), TQT_SLOT(repaint()));
00072 #ifdef Q_WS_X11
00073 connect(m_pPixmap, TQT_SIGNAL(done(bool)), TQT_SLOT(slotDone(bool)));
00074
00075 d->twin = new KWinModule( this );
00076 connect(d->twin, TQT_SIGNAL(windowChanged(WId, unsigned int)), TQT_SLOT(desktopChanged(WId, unsigned int)));
00077 connect(d->twin, TQT_SIGNAL(currentDesktopChanged(int)), TQT_SLOT(desktopChanged(int)));
00078 #endif
00079
00080 d->toplevel = m_pWidget->topLevelWidget();
00081 d->toplevel->installEventFilter(this);
00082 m_pWidget->installEventFilter(this);
00083 }
00084
00085 KRootPixmap::~KRootPixmap()
00086 {
00087 delete m_pPixmap;
00088 delete d;
00089 }
00090
00091
00092 int KRootPixmap::currentDesktop() const
00093 {
00094 #ifdef Q_WS_X11
00095 NETRootInfo rinfo( tqt_xdisplay(), NET::CurrentDesktop );
00096 rinfo.activate();
00097 return rinfo.currentDesktop();
00098 #else
00099
00100 return TQApplication::desktop()->screenNumber(m_pWidget);
00101 #endif
00102 }
00103
00104
00105 void KRootPixmap::start()
00106 {
00107 if (m_bActive)
00108 return;
00109
00110 m_bActive = true;
00111 if ( !isAvailable() )
00112 {
00113
00114 enableExports();
00115 return;
00116 }
00117 if (m_bInit)
00118 repaint(true);
00119 }
00120
00121
00122 void KRootPixmap::stop()
00123 {
00124 m_bActive = false;
00125 m_pTimer->stop();
00126 }
00127
00128
00129 void KRootPixmap::setFadeEffect(double fade, const TQColor &color)
00130 {
00131 if (fade < 0)
00132 m_Fade = 0;
00133 else if (fade > 1)
00134 m_Fade = 1;
00135 else
00136 m_Fade = fade;
00137 m_FadeColor = color;
00138
00139 if ( m_bActive && m_bInit ) repaint(true);
00140 }
00141
00142 void KRootPixmap::setBlurEffect(double radius, double sigma)
00143 {
00144 m_BlurRadius = radius;
00145 m_BlurSigma = sigma;
00146 }
00147
00148 bool KRootPixmap::eventFilter(TQObject *, TQEvent *event)
00149 {
00150
00151 if (!m_bInit && ((event->type() == TQEvent::Show) || (event->type() == TQEvent::Paint)))
00152 {
00153 m_bInit = true;
00154 m_Desk = currentDesktop();
00155 }
00156
00157 if (!m_bActive)
00158 return false;
00159
00160 switch (event->type())
00161 {
00162 case TQEvent::Resize:
00163 case TQEvent::Move:
00164 m_pTimer->start(100, true);
00165 break;
00166
00167 case TQEvent::Paint:
00168 m_pTimer->start(0, true);
00169 break;
00170
00171 case TQEvent::Reparent:
00172 d->toplevel->removeEventFilter(this);
00173 d->toplevel = m_pWidget->topLevelWidget();
00174 d->toplevel->installEventFilter(this);
00175 break;
00176
00177 default:
00178 break;
00179 }
00180
00181 return false;
00182 }
00183
00184 void KRootPixmap::desktopChanged(int desktop)
00185 {
00186 if (wallpaperForDesktop(m_Desk) == wallpaperForDesktop(desktop) &&
00187 !wallpaperForDesktop(m_Desk).isNull())
00188 return;
00189
00190 #ifdef Q_WS_X11
00191 if (KWin::windowInfo(m_pWidget->topLevelWidget()->winId()).desktop() == NET::OnAllDesktops &&
00192 pixmapName(m_Desk) != pixmapName(desktop))
00193 #endif
00194 repaint(true);
00195 }
00196
00197 void KRootPixmap::desktopChanged( WId window, unsigned int properties )
00198 {
00199 #ifdef Q_WS_X11
00200 if( !(properties & NET::WMDesktop) ||
00201 (window != m_pWidget->topLevelWidget()->winId()))
00202 return;
00203 #endif
00204
00205 kdDebug() << k_funcinfo << endl;
00206 repaint(true);
00207 }
00208
00209 void KRootPixmap::repaint()
00210 {
00211 repaint(false);
00212 }
00213
00214
00215 void KRootPixmap::repaint(bool force)
00216 {
00217 TQPoint p1 = m_pWidget->mapToGlobal(m_pWidget->rect().topLeft());
00218 TQPoint p2 = m_pWidget->mapToGlobal(m_pWidget->rect().bottomRight());
00219 if (!force && (m_Rect == TQRect(p1, p2)))
00220 return;
00221
00222
00223
00224
00225
00226 if ((p1 == m_Rect.topLeft()) && (m_pWidget->width() < m_Rect.width()) &&
00227 (m_pWidget->height() < m_Rect.height())
00228 )
00229 {
00230 m_Rect = TQRect(p1, p2);
00231 updateBackground( m_pPixmap );
00232 return;
00233 }
00234 m_Rect = TQRect(p1, p2);
00235 #ifdef Q_WS_X11
00236 m_Desk = KWin::windowInfo(m_pWidget->topLevelWidget()->winId()).desktop();
00237 if ((m_Desk == NET::OnAllDesktops) || (m_Desk == 0)) {
00238 m_Desk = currentDesktop();
00239 }
00240
00241
00242 m_pPixmap->loadFromShared(pixmapName(m_Desk), m_Rect);
00243 #else
00244 m_Desk = currentDesktop();
00245
00246
00247 m_pPixmap->load( pixmapName(m_Desk) );
00248 if (!m_pPixmap->isNull()) {
00249 m_pPixmap->resize( m_Rect.size() );
00250 slotDone(true);
00251 }
00252 #endif
00253 }
00254
00255 bool KRootPixmap::isAvailable() const
00256 {
00257 #ifdef Q_WS_X11
00258 return m_pPixmap->isAvailable(pixmapName(m_Desk));
00259 #else
00260 return m_pPixmap->isNull();
00261 #endif
00262 }
00263
00264 TQString KRootPixmap::pixmapName(int desk) {
00265 TQString pattern = TQString("DESKTOP%1");
00266 #ifdef Q_WS_X11
00267 int screen_number = DefaultScreen(tqt_xdisplay());
00268 if (screen_number) {
00269 pattern = TQString("SCREEN%1-DESKTOP").arg(screen_number) + "%1";
00270 }
00271 #endif
00272 return pattern.arg( desk );
00273 }
00274
00275
00276 void KRootPixmap::enableExports()
00277 {
00278 #ifdef Q_WS_X11
00279 kdDebug(270) << k_lineinfo << "activating background exports.\n";
00280 DCOPClient *client = kapp->dcopClient();
00281 if (!client->isAttached())
00282 client->attach();
00283 TQByteArray data;
00284 TQDataStream args( data, IO_WriteOnly );
00285 args << 1;
00286
00287 TQCString appname( "kdesktop" );
00288 int screen_number = DefaultScreen(tqt_xdisplay());
00289 if ( screen_number )
00290 appname.sprintf("kdesktop-screen-%d", screen_number );
00291
00292 client->send( appname, "KBackgroundIface", "setExport(int)", data );
00293 #endif
00294 }
00295
00296
00297 void KRootPixmap::slotDone(bool success)
00298 {
00299 if (!success)
00300 {
00301 kdWarning(270) << k_lineinfo << "loading of desktop background failed.\n";
00302 return;
00303 }
00304
00305
00306
00307 if ( m_bActive )
00308 updateBackground( m_pPixmap );
00309 }
00310
00311 void KRootPixmap::updateBackground( TDESharedPixmap *spm )
00312 {
00313 TQPixmap pm = *spm;
00314
00315 if (m_Fade > 1e-6)
00316 {
00317 KPixmapIO io;
00318 TQImage img = io.convertToImage(pm);
00319 img = KImageEffect::fade(img, m_Fade, m_FadeColor);
00320 pm = io.convertToPixmap(img);
00321 }
00322
00323 if ((m_BlurRadius > 1e-6) || (m_BlurSigma > 1e-6))
00324 {
00325 KPixmapIO io;
00326 TQImage img = io.convertToImage(pm);
00327 img = KImageEffect::blur(img, m_BlurRadius, m_BlurSigma);
00328 pm = io.convertToPixmap(img);
00329 }
00330
00331 if ( !m_bCustomPaint )
00332 m_pWidget->setBackgroundPixmap( pm );
00333 else {
00334 emit backgroundUpdated( pm );
00335 }
00336 }
00337
00338
00339 void KRootPixmap::slotBackgroundChanged(int desk)
00340 {
00341 if (!m_bInit || !m_bActive)
00342 return;
00343
00344 if (desk == m_Desk)
00345 repaint(true);
00346 }
00347
00348 #include "krootpixmap.moc"