00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
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 <kwin.h>
00024
#include <kdebug.h>
00025
#include <netwm.h>
00026
#include <dcopclient.h>
00027
00028
#include <ksharedpixmap.h>
00029
#include <krootpixmap.h>
00030
00031
class KRootPixmapData
00032 {
00033
public:
00034
QWidget *toplevel;
00035
KWinModule *kwin;
00036 };
00037
00038
00039 KRootPixmap::KRootPixmap(
QWidget *widget,
const char *name )
00040 :
QObject(widget, name ? name : "
KRootPixmap" ), m_pWidget(widget)
00041 {
00042 init();
00043 }
00044
00045 KRootPixmap::KRootPixmap(
QWidget *widget,
QObject *parent,
const char *name )
00046 :
QObject( parent, name ? name : "
KRootPixmap" ), m_pWidget(widget)
00047 {
00048 init();
00049 }
00050
00051
void KRootPixmap::init()
00052 {
00053 d =
new KRootPixmapData;
00054 m_Fade = 0;
00055 m_pPixmap =
new KSharedPixmap;
00056 m_pTimer =
new QTimer(
this );
00057 m_bInit =
false;
00058 m_bActive =
false;
00059 m_bCustomPaint =
false;
00060
00061 connect(kapp, SIGNAL(backgroundChanged(
int)), SLOT(slotBackgroundChanged(
int)));
00062 connect(m_pPixmap, SIGNAL(done(
bool)), SLOT(slotDone(
bool)));
00063 connect(m_pTimer, SIGNAL(timeout()), SLOT(
repaint()));
00064
00065 d->kwin =
new KWinModule(
this );
00066 connect( d->kwin, SIGNAL(currentDesktopChanged(
int)), SLOT(desktopChanged(
int)) );
00067
00068 d->toplevel = m_pWidget->topLevelWidget();
00069 d->toplevel->installEventFilter(
this);
00070 m_pWidget->installEventFilter(
this);
00071 }
00072
00073 KRootPixmap::~KRootPixmap()
00074 {
00075
delete m_pPixmap;
00076
delete d;
00077 }
00078
00079
00080 int KRootPixmap::currentDesktop()
const
00081
{
00082 NETRootInfo rinfo( qt_xdisplay(), NET::CurrentDesktop );
00083 rinfo.activate();
00084
return rinfo.currentDesktop();
00085 }
00086
00087
00088 void KRootPixmap::start()
00089 {
00090
if (m_bActive)
00091
return;
00092
00093 m_bActive =
true;
00094
if ( !
isAvailable() )
00095 {
00096
00097
enableExports();
00098
return;
00099 }
00100
if (m_bInit)
00101
repaint(
true);
00102 }
00103
00104
00105 void KRootPixmap::stop()
00106 {
00107 m_bActive =
false;
00108 m_pTimer->stop();
00109 }
00110
00111
00112 void KRootPixmap::setFadeEffect(
double fade,
const QColor &color)
00113 {
00114
if (fade < 0)
00115 m_Fade = 0;
00116
else if (fade > 1)
00117 m_Fade = 1;
00118
else
00119 m_Fade = fade;
00120 m_FadeColor = color;
00121
00122
if ( m_bActive && m_bInit )
repaint(
true);
00123 }
00124
00125
00126 bool KRootPixmap::eventFilter(
QObject *,
QEvent *event)
00127 {
00128
00129
if (!m_bInit && ((event->type() == QEvent::Show) || (event->type() == QEvent::Paint)))
00130 {
00131 m_bInit =
true;
00132 m_Desk =
currentDesktop();
00133 }
00134
00135
if (!m_bActive)
00136
return false;
00137
00138
switch (event->type())
00139 {
00140
case QEvent::Resize:
00141
case QEvent::Move:
00142 m_pTimer->start(100,
true);
00143
break;
00144
00145
case QEvent::Paint:
00146 m_pTimer->start(0,
true);
00147
break;
00148
00149
case QEvent::Reparent:
00150 d->toplevel->removeEventFilter(
this);
00151 d->toplevel = m_pWidget->topLevelWidget();
00152 d->toplevel->installEventFilter(
this);
00153
break;
00154
00155
default:
00156
break;
00157 }
00158
00159
return false;
00160 }
00161
00162
void KRootPixmap::desktopChanged(
int desk )
00163 {
00164
if( !m_pWidget->isVisible())
00165
return;
00166
QWidget* widget = m_pWidget->topLevelWidget();
00167
if( !widget->testWFlags( WX11BypassWM )
00168 && !KWin::windowInfo( widget->winId(), NET::WMDesktop ).isOnCurrentDesktop())
00169
return;
00170
repaint(
true);
00171 }
00172
00173 void KRootPixmap::repaint()
00174 {
00175
repaint(
false);
00176 }
00177
00178
00179 void KRootPixmap::repaint(
bool force)
00180 {
00181
QPoint p1 = m_pWidget->mapToGlobal(m_pWidget->rect().topLeft());
00182
QPoint p2 = m_pWidget->mapToGlobal(m_pWidget->rect().bottomRight());
00183
if (!force && (m_Rect ==
QRect(p1, p2)))
00184
return;
00185
00186
00187
00188
00189
00190
if ((p1 == m_Rect.topLeft()) && (m_pWidget->width() < m_Rect.width()) &&
00191 (m_pWidget->height() < m_Rect.height())
00192 )
00193 {
00194 m_Rect = QRect(p1, p2);
00195
updateBackground( m_pPixmap );
00196
return;
00197 }
00198 m_Rect = QRect(p1, p2);
00199 m_Desk =
currentDesktop();
00200
00201
00202 m_pPixmap->loadFromShared(
pixmapName(m_Desk), m_Rect);
00203 }
00204
00205 bool KRootPixmap::isAvailable()
const
00206
{
00207
return m_pPixmap->isAvailable(
pixmapName(m_Desk));
00208 }
00209
00210 QString KRootPixmap::pixmapName(
int desk) {
00211
QString pattern =
QString(
"DESKTOP%1");
00212
int screen_number = DefaultScreen(qt_xdisplay());
00213
if (screen_number) {
00214 pattern = QString(
"SCREEN%1-DESKTOP").arg(screen_number) +
"%1";
00215 }
00216
return pattern.arg( desk );
00217 }
00218
00219
00220 void KRootPixmap::enableExports()
00221 {
00222
kdDebug(270) <<
k_lineinfo <<
"activating background exports.\n";
00223
DCOPClient *client = kapp->dcopClient();
00224
if (!client->
isAttached())
00225 client->
attach();
00226
QByteArray data;
00227
QDataStream args( data, IO_WriteOnly );
00228 args << 1;
00229
00230
QCString appname(
"kdesktop" );
00231
int screen_number = DefaultScreen(qt_xdisplay());
00232
if ( screen_number )
00233 appname.sprintf(
"kdesktop-screen-%d", screen_number );
00234
00235 client->
send( appname,
"KBackgroundIface",
"setExport(int)", data );
00236 }
00237
00238
00239
void KRootPixmap::slotDone(
bool success)
00240 {
00241
if (!success)
00242 {
00243
kdWarning(270) <<
k_lineinfo <<
"loading of desktop background failed.\n";
00244
return;
00245 }
00246
00247
00248
00249
if ( m_bActive )
00250
updateBackground( m_pPixmap );
00251 }
00252
00253 void KRootPixmap::updateBackground( KSharedPixmap *spm )
00254 {
00255
QPixmap pm = *spm;
00256
00257
if (m_Fade > 1e-6)
00258 {
00259
KPixmapIO io;
00260
QImage img = io.
convertToImage(pm);
00261 img = KImageEffect::fade(img, m_Fade, m_FadeColor);
00262 pm = io.
convertToPixmap(img);
00263 }
00264
00265
if ( !m_bCustomPaint )
00266 m_pWidget->setBackgroundPixmap( pm );
00267
else {
00268 emit
backgroundUpdated( pm );
00269 }
00270 }
00271
00272
00273
void KRootPixmap::slotBackgroundChanged(
int desk)
00274 {
00275
if (!m_bInit || !m_bActive)
00276
return;
00277
00278
if (desk == m_Desk)
00279
repaint(
true);
00280 }
00281
00282
#include "krootpixmap.moc"
00283
#endif