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
#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
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
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;
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
00204
00205
00206
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
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
00267
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