00001
00002
00003
00004
00005
00006
00007
00008
00009
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;
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
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
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
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;
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
00216
00217
00218
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
00234 m_pPixmap->
loadFromShared(
pixmapName(m_Desk), m_Rect);
00235
#else
00236
m_Desk =
currentDesktop();
00237
00238
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
00298
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"