krootpixmap.cpp
/* vi: ts=8 sts=4 sw=4
*
*
* This file is part of the KDE project, module kdeui.
* Copyright (C) 1999,2000 Geert Jansen <jansen@kde.org>
*
* You can Freely distribute this program under the GNU Library
* General Public License. See the file "COPYING.LIB" for the exact
* licensing terms.
*/
#include <qwidget.h>
#include <qtimer.h>
#include <qrect.h>
#include <qimage.h>
#include <kapplication.h>
#include <kimageeffect.h>
#include <kpixmapio.h>
#include <kwinmodule.h>
#include <kwin.h>
#include <kdebug.h>
#include <netwm.h>
#include <dcopclient.h>
#include <dcopref.h>
#include <ksharedpixmap.h>
#include <krootpixmap.h>
static QString wallpaperForDesktop(int desktop)
{
return DCOPRef("kdesktop", "KBackgroundIface").call("currentWallpaper", desktop);
}
class KRootPixmapData
{
public:
QWidget *toplevel;
#ifdef Q_WS_X11
KWinModule *kwin;
#endif
};
KRootPixmap::KRootPixmap( QWidget *widget, const char *name )
: QObject(widget, name ? name : "KRootPixmap" ), m_Desk(0), m_pWidget(widget)
{
init();
}
KRootPixmap::KRootPixmap( QWidget *widget, QObject *parent, const char *name )
: QObject( parent, name ? name : "KRootPixmap" ), m_Desk(0), m_pWidget(widget)
{
init();
}
void KRootPixmap::init()
{
d = new KRootPixmapData;
m_Fade = 0;
m_pPixmap = new KSharedPixmap; //ordinary KPixmap on win32
m_pTimer = new QTimer( this );
m_bInit = false;
m_bActive = false;
m_bCustomPaint = false;
connect(kapp, SIGNAL(backgroundChanged(int)), SLOT(slotBackgroundChanged(int)));
connect(m_pTimer, SIGNAL(timeout()), SLOT(repaint()));
#ifdef Q_WS_X11
connect(m_pPixmap, SIGNAL(done(bool)), SLOT(slotDone(bool)));
d->kwin = new KWinModule( this );
connect(d->kwin, SIGNAL(windowChanged(WId, unsigned int)), SLOT(desktopChanged(WId, unsigned int)));
connect(d->kwin, SIGNAL(currentDesktopChanged(int)), SLOT(desktopChanged(int)));
#endif
d->toplevel = m_pWidget->topLevelWidget();
d->toplevel->installEventFilter(this);
m_pWidget->installEventFilter(this);
}
KRootPixmap::~KRootPixmap()
{
delete m_pPixmap;
delete d;
}
int KRootPixmap::currentDesktop() const
{
#ifdef Q_WS_X11
NETRootInfo rinfo( qt_xdisplay(), NET::CurrentDesktop );
rinfo.activate();
return rinfo.currentDesktop();
#else
//OK?
return QApplication::desktop()->screenNumber(m_pWidget);
#endif
}
void KRootPixmap::start()
{
if (m_bActive)
return;
m_bActive = true;
if ( !isAvailable() )
{
// We will get a KIPC message when the shared pixmap is available.
enableExports();
return;
}
if (m_bInit)
repaint(true);
}
void KRootPixmap::stop()
{
m_bActive = false;
m_pTimer->stop();
}
void KRootPixmap::setFadeEffect(double fade, const QColor &color)
{
if (fade < 0)
m_Fade = 0;
else if (fade > 1)
m_Fade = 1;
else
m_Fade = fade;
m_FadeColor = color;
if ( m_bActive && m_bInit ) repaint(true);
}
bool KRootPixmap::eventFilter(QObject *, QEvent *event)
{
// Initialise after the first show or paint event on the managed widget.
if (!m_bInit && ((event->type() == QEvent::Show) || (event->type() == QEvent::Paint)))
{
m_bInit = true;
m_Desk = currentDesktop();
}
if (!m_bActive)
return false;
switch (event->type())
{
case QEvent::Resize:
case QEvent::Move:
m_pTimer->start(100, true);
break;
case QEvent::Paint:
m_pTimer->start(0, true);
break;
case QEvent::Reparent:
d->toplevel->removeEventFilter(this);
d->toplevel = m_pWidget->topLevelWidget();
d->toplevel->installEventFilter(this);
break;
default:
break;
}
return false; // always continue processing
}
void KRootPixmap::desktopChanged(int desktop)
{
if (wallpaperForDesktop(m_Desk) == wallpaperForDesktop(desktop) &&
!wallpaperForDesktop(m_Desk).isNull())
return;
#ifdef Q_WS_X11
if (KWin::windowInfo(m_pWidget->topLevelWidget()->winId()).desktop() == NET::OnAllDesktops &&
pixmapName(m_Desk) != pixmapName(desktop))
#endif
repaint(true);
}
void KRootPixmap::desktopChanged( WId window, unsigned int properties )
{
#ifdef Q_WS_X11
if( !(properties & NET::WMDesktop) ||
(window != m_pWidget->topLevelWidget()->winId()))
return;
#endif
kdDebug() << k_funcinfo << endl;
repaint(true);
}
void KRootPixmap::repaint()
{
repaint(false);
}
void KRootPixmap::repaint(bool force)
{
QPoint p1 = m_pWidget->mapToGlobal(m_pWidget->rect().topLeft());
QPoint p2 = m_pWidget->mapToGlobal(m_pWidget->rect().bottomRight());
if (!force && (m_Rect == QRect(p1, p2)))
return;
// Due to northwest bit gravity, we don't need to do anything if the
// bottom right corner of the widget is moved inward.
// That said, konsole clears the background when it is resized, so
// we have to reset the background pixmap.
if ((p1 == m_Rect.topLeft()) && (m_pWidget->width() < m_Rect.width()) &&
(m_pWidget->height() < m_Rect.height())
)
{
m_Rect = QRect(p1, p2);
updateBackground( m_pPixmap );
return;
}
m_Rect = QRect(p1, p2);
#ifdef Q_WS_X11
m_Desk = KWin::windowInfo(m_pWidget->topLevelWidget()->winId()).desktop();
if (m_Desk == NET::OnAllDesktops)
m_Desk = currentDesktop();
// KSharedPixmap will correctly generate a tile for us.
m_pPixmap->loadFromShared(pixmapName(m_Desk), m_Rect);
#else
m_Desk = currentDesktop();
// !x11 note: tile is not generated!
// TODO: pixmapName() is a nonsense now!
m_pPixmap->load( pixmapName(m_Desk) );
if (!m_pPixmap->isNull()) {
m_pPixmap->resize( m_Rect.size() );
slotDone(true);
}
#endif
}
bool KRootPixmap::isAvailable() const
{
#ifdef Q_WS_X11
return m_pPixmap->isAvailable(pixmapName(m_Desk));
#else
return m_pPixmap->isNull();
#endif
}
QString KRootPixmap::pixmapName(int desk) {
QString pattern = QString("DESKTOP%1");
#ifdef Q_WS_X11
int screen_number = DefaultScreen(qt_xdisplay());
if (screen_number) {
pattern = QString("SCREEN%1-DESKTOP").arg(screen_number) + "%1";
}
#endif
return pattern.arg( desk );
}
void KRootPixmap::enableExports()
{
#ifdef Q_WS_X11
kdDebug(270) << k_lineinfo << "activating background exports.\n";
DCOPClient *client = kapp->dcopClient();
if (!client->isAttached())
client->attach();
QByteArray data;
QDataStream args( data, IO_WriteOnly );
args << 1;
QCString appname( "kdesktop" );
int screen_number = DefaultScreen(qt_xdisplay());
if ( screen_number )
appname.sprintf("kdesktop-screen-%d", screen_number );
client->send( appname, "KBackgroundIface", "setExport(int)", data );
#endif
}
void KRootPixmap::slotDone(bool success)
{
if (!success)
{
kdWarning(270) << k_lineinfo << "loading of desktop background failed.\n";
return;
}
// We need to test active as the pixmap might become available
// after the widget has been destroyed.
if ( m_bActive )
updateBackground( m_pPixmap );
}
void KRootPixmap::updateBackground( KSharedPixmap *spm )
{
QPixmap pm = *spm;
if (m_Fade > 1e-6)
{
KPixmapIO io;
QImage img = io.convertToImage(pm);
img = KImageEffect::fade(img, m_Fade, m_FadeColor);
pm = io.convertToPixmap(img);
}
if ( !m_bCustomPaint )
m_pWidget->setBackgroundPixmap( pm );
else {
emit backgroundUpdated( pm );
}
}
void KRootPixmap::slotBackgroundChanged(int desk)
{
if (!m_bInit || !m_bActive)
return;
if (desk == m_Desk)
repaint(true);
}
#include "krootpixmap.moc"
DCOPRef::call
DCOPReply call(const QCString &fun)
KRootPixmap::eventFilter
virtual bool eventFilter(QObject *, QEvent *)
Reimplemented to filter the events from the target widget and track its movements.
Definition: krootpixmap.cpp:141
KRootPixmap::currentDesktop
int currentDesktop() const
Returns the number of the current desktop.
Definition: krootpixmap.cpp:90
KRootPixmap::isAvailable
bool isAvailable() const
Checks if pseudo-transparency is available.
Definition: krootpixmap.cpp:247
KRootPixmap::KRootPixmap
KRootPixmap(QWidget *target, const char *name=0)
Constructs a KRootPixmap.
Definition: krootpixmap.cpp:46
DCOPClient::attach
bool attach()
DCOPRef
KRootPixmap::backgroundUpdated
void backgroundUpdated(const QPixmap &pm)
Emitted when the background needs updating and custom painting (see setCustomPainting(bool) ) is enab...
KRootPixmap::stop
virtual void stop()
Stops background handling.
Definition: krootpixmap.cpp:120
kdDebug
kdbgstream kdDebug(int area=0)
DCOPClient
KRootPixmap::repaint
void repaint()
Repaints the widget background.
Definition: krootpixmap.cpp:202
DCOPClient::send
bool send(const QCString &remApp, const QCString &remObj, const QCString &remFun, const QByteArray &data)
KWinModule
KRootPixmap::setFadeEffect
void setFadeEffect(double opacity, const QColor &color)
Sets the fade effect.
Definition: krootpixmap.cpp:127
kdWarning
kdbgstream kdWarning(int area=0)
KRootPixmap::color
const QColor & color() const
Definition: krootpixmap.h:106
KRootPixmap::enableExports
void enableExports()
Asks KDesktop to export the desktop background as a KSharedPixmap.
Definition: krootpixmap.cpp:268
KImageEffect::fade
static QImage & fade(QImage &image, float val, const QColor &color)
KPixmapIO::convertToImage
QImage convertToImage(const QPixmap &pixmap)
Convert a pixmap to an image.
Definition: kpixmapio.cpp:205
KPixmapIO::convertToPixmap
QPixmap convertToPixmap(const QImage &image)
Convert an image to a pixmap.
Definition: kpixmapio.cpp:187
KRootPixmap::~KRootPixmap
virtual ~KRootPixmap()
Destructs the object.
Definition: krootpixmap.cpp:83
DCOPClient::isAttached
bool isAttached() const
KWin::windowInfo
static WindowInfo windowInfo(WId win, unsigned long properties=0, unsigned long properties2=0)
endl
kndbgstream & endl(kndbgstream &s)
KPixmapIO
Fast QImage to/from QPixmap conversion.
Definition: kpixmapio.h:87
KRootPixmap::updateBackground
virtual void updateBackground(KSharedPixmap *)
Called when the pixmap has been updated.
Definition: krootpixmap.cpp:303
KRootPixmap::start
virtual void start()
Starts background handling.
Definition: krootpixmap.cpp:103
KRootPixmap::pixmapName
static QString pixmapName(int desk)
Returns the name of the shared pixmap (only needed for low level access)
Definition: krootpixmap.cpp:256

KDE Home | KDE Accessibility Home | Description of Access Keys