summaryrefslogtreecommitdiffstats
path: root/kdeui/krootpixmap.cpp
diff options
context:
space:
mode:
authortoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
committertoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
commitce4a32fe52ef09d8f5ff1dd22c001110902b60a2 (patch)
tree5ac38a06f3dde268dc7927dc155896926aaf7012 /kdeui/krootpixmap.cpp
downloadtdelibs-ce4a32fe52ef09d8f5ff1dd22c001110902b60a2.tar.gz
tdelibs-ce4a32fe52ef09d8f5ff1dd22c001110902b60a2.zip
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdelibs@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kdeui/krootpixmap.cpp')
-rw-r--r--kdeui/krootpixmap.cpp332
1 files changed, 332 insertions, 0 deletions
diff --git a/kdeui/krootpixmap.cpp b/kdeui/krootpixmap.cpp
new file mode 100644
index 000000000..5f9591b5b
--- /dev/null
+++ b/kdeui/krootpixmap.cpp
@@ -0,0 +1,332 @@
+/* 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"