From c08c2664c94db67ded2a9891a18b626bf12d9e1a Mon Sep 17 00:00:00 2001 From: tpearson Date: Fri, 19 Aug 2011 21:57:10 +0000 Subject: [PATCH] Add krootbacking interface to kdeartwork git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdeartwork@1248132 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- kscreensaver/Makefile.am | 2 +- kscreensaver/krootbacking/Makefile.am | 10 + kscreensaver/krootbacking/krootbacking.cpp | 262 +++++++++++++++++++++ kscreensaver/krootbacking/krootbacking.h | 177 ++++++++++++++ kscreensaver/krootbacking/main.cpp | 73 ++++++ 5 files changed, 523 insertions(+), 1 deletion(-) create mode 100644 kscreensaver/krootbacking/Makefile.am create mode 100644 kscreensaver/krootbacking/krootbacking.cpp create mode 100644 kscreensaver/krootbacking/krootbacking.h create mode 100644 kscreensaver/krootbacking/main.cpp diff --git a/kscreensaver/Makefile.am b/kscreensaver/Makefile.am index f374ce3b..dbd2f867 100644 --- a/kscreensaver/Makefile.am +++ b/kscreensaver/Makefile.am @@ -6,7 +6,7 @@ if COMPILE_X11_KSAVERS XSAVERS_SUBDIR = xsavers endif -SUBDIRS = kdesavers kpartsaver $(KXSCONFIG_SUBDIR) $(XSAVERS_SUBDIR) +SUBDIRS = kdesavers kpartsaver krootbacking $(KXSCONFIG_SUBDIR) $(XSAVERS_SUBDIR) messages: $(EXTRACTRC) kdesavers/*.ui > rc.cpp diff --git a/kscreensaver/krootbacking/Makefile.am b/kscreensaver/krootbacking/Makefile.am new file mode 100644 index 00000000..ade1cc8f --- /dev/null +++ b/kscreensaver/krootbacking/Makefile.am @@ -0,0 +1,10 @@ +INCLUDES = $(all_includes) + +bin_PROGRAMS = krootbacking + +krootbacking_SOURCES = main.cpp krootbacking.cpp +krootbacking_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) -module $(LIB_QT) $(LIB_KDECORE) $(LIB_KDEUI) + +METASOURCES = AUTO + +noinst_HEADERS = krootbacking.h diff --git a/kscreensaver/krootbacking/krootbacking.cpp b/kscreensaver/krootbacking/krootbacking.cpp new file mode 100644 index 00000000..4a4d5543 --- /dev/null +++ b/kscreensaver/krootbacking/krootbacking.cpp @@ -0,0 +1,262 @@ +/*************************************************************************** + * Copyright (C) 2011 by Timothy Pearson * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +static TQString wallpaperForDesktop(int desktop) +{ + return DCOPRef("kdesktop", "KBackgroundIface").call("currentWallpaper", desktop); +} + +class KRootBackingData +{ +public: + TQWidget *toplevel; +#ifdef Q_WS_X11 + KWinModule *kwin; +#endif +}; + + +KRootBacking::KRootBacking() + : TQObject(KApplication::desktop(), "KRootBacking" ), m_Desk(0), m_timeout(0) +{ + init(); +} + +void KRootBacking::init() +{ + d = new KRootBackingData; + m_Fade = 0; + m_pPixmap = new KSharedPixmap; //ordinary KPixmap on win32 + m_pTimer = new TQTimer( this ); + m_bInit = false; + m_bActive = false; + + connect(kapp, TQT_SIGNAL(backgroundChanged(int)), TQT_SLOT(slotBackgroundChanged(int))); + connect(m_pTimer, TQT_SIGNAL(timeout()), TQT_SLOT(tqrepaint())); +#ifdef Q_WS_X11 + connect(m_pPixmap, TQT_SIGNAL(done(bool)), TQT_SLOT(slotDone(bool))); + + d->kwin = new KWinModule( this ); +#endif + + m_bInit = true; +} + +KRootBacking::~KRootBacking() +{ + delete m_pPixmap; + delete d; +} + + +int KRootBacking::currentDesktop() const +{ +#ifdef Q_WS_X11 + NETRootInfo rinfo( qt_xdisplay(), NET::CurrentDesktop ); + rinfo.activate(); + return rinfo.currentDesktop(); +#endif +} + + +void KRootBacking::start() +{ + if (m_bActive) + return; + + m_bActive = true; + if ( !isAvailable() ) + { + // We should get a KIPC message when the shared pixmap is available... + enableExports(); + if (m_timeout < 50) { + TQTimer::singleShot( 100, this, SLOT(show()) ); // ...but it doesn't always work! + m_timeout++; + return; + } + } + if (m_bInit) { + tqrepaint(true); + } +} + + +void KRootBacking::stop() +{ + m_bActive = false; + m_pTimer->stop(); +} + + +void KRootBacking::setFadeEffect(double fade, const TQColor &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 ) tqrepaint(true); +} + +void KRootBacking::tqrepaint() +{ + tqrepaint(false); +} + + +void KRootBacking::tqrepaint(bool force) +{ + TQWidget* desktopWidget = KApplication::desktop(); + TQPoint p1 = desktopWidget->mapToGlobal(desktopWidget->rect().topLeft()); + TQPoint p2 = desktopWidget->mapToGlobal(desktopWidget->rect().bottomRight()); + if (!force && (m_Rect == TQRect(p1, p2))) + return; + + m_Rect = TQRect(p1, p2); +#ifdef Q_WS_X11 + 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 KRootBacking::isAvailable() const +{ +// #ifdef Q_WS_X11 +// return m_pPixmap->isAvailable(pixmapName(m_Desk)); +// #else + return m_pPixmap->isNull(); +// #endif +} + +TQString KRootBacking::pixmapName(int desk) { + TQString pattern = TQString("DESKTOP%1"); +#ifdef Q_WS_X11 + int screen_number = DefaultScreen(qt_xdisplay()); + if (screen_number) { + pattern = TQString("SCREEN%1-DESKTOP").arg(screen_number) + "%1"; + } +#endif + return pattern.arg( desk ); +} + + +void KRootBacking::enableExports() +{ +#ifdef Q_WS_X11 + kdDebug(270) << k_lineinfo << "activating background exports.\n"; + DCOPClient *client = kapp->dcopClient(); + if (!client->isAttached()) + client->attach(); + TQByteArray data; + TQDataStream args( data, IO_WriteOnly ); + args << 1; + + TQCString 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 KRootBacking::slotDone(bool success) +{ + if (!success) + { + kdWarning(270) << k_lineinfo << "loading of desktop background failed.\n"; + if (m_timeout < 50) { + TQTimer::singleShot( 100, this, SLOT(show()) ); + m_timeout++; + 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 KRootBacking::updateBackground( KSharedPixmap *spm ) +{ + TQPixmap pm = *spm; + + if (m_Fade > 1e-6) + { + KPixmapIO io; + TQImage img = io.convertToImage(pm); + img = KImageEffect::fade(img, m_Fade, m_FadeColor); + pm = io.convertToPixmap(img); + } + + TQString filename = getenv("USER"); + filename.prepend("/tmp/kde-"); + filename.append("/krootbacking.png"); + pm.save(filename, "PNG"); + printf("%s\n\r", filename.ascii()); fflush(stdout); + exit(0); +} + + +void KRootBacking::slotBackgroundChanged(int desk) +{ + if (!m_bInit || !m_bActive) + return; + + if (desk == m_Desk) + tqrepaint(true); +} + +// #include "krootpixmap.moc" + diff --git a/kscreensaver/krootbacking/krootbacking.h b/kscreensaver/krootbacking/krootbacking.h new file mode 100644 index 00000000..532ea8f8 --- /dev/null +++ b/kscreensaver/krootbacking/krootbacking.h @@ -0,0 +1,177 @@ +/*************************************************************************** + * Copyright (C) 2011 by Timothy Pearson * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + + +#ifndef KROOTBACKING_H +#define KROOTBACKING_H + +#include +#include +#include + +#ifndef Q_WS_QWS //FIXME + +class TQRect; +class TQWidget; +class TQTimer; +class KSharedPixmap; +class KRootBackingData; + +/** + * Gets the current full shared desktop pixmap and feeds it to xscreensaver + * + * @author Timothy Pearson + */ +class KRootBacking: public TQObject +{ + Q_OBJECT + +public: + /** + * Constructs a KRootBacking. + */ + KRootBacking(); + + /** + * Destructs the object. + */ + virtual ~KRootBacking(); + + /** + * Checks if pseudo-transparency is available. + * @return @p true if transparency is available, @p false otherwise. + */ + bool isAvailable() const; + + /** + * Returns true if the KRootBacking is active. + */ + bool isActive() const { return m_bActive; } + + /** + * Returns the number of the current desktop. + */ + int currentDesktop() const; + +#ifndef KDE_NO_COMPAT + /** + * Deprecated, use isAvailable() instead. + * @deprecated + */ + KDE_DEPRECATED bool checkAvailable(bool) { return isAvailable(); } +#endif + + /** @since 3.2 + * @return the fade color. + */ + const TQColor &color() const { return m_FadeColor; } + + /** @since 3.2 + * @return the color opacity. + */ + double opacity() const { return m_Fade; } + +public slots: + /** + * Starts background handling. + */ + virtual void start(); + + /** + * Stops background handling. + */ + virtual void stop(); + + /** + * Sets the fade effect. + * + * This effect will fade the background to the + * specified color. + * @param opacity A value between 0 and 1, indicating the opacity + * of the color. A value of 0 will not change the image, a value of 1 + * will use the fade color unchanged. + * @param color The color to fade to. + */ + void setFadeEffect(double opacity, const TQColor &color); + + /** + * Repaints the widget background. Normally, you shouldn't need this + * as it is handled automatically. + * + * @param force Force a tqrepaint, even if the contents did not change. + */ + void tqrepaint( bool force ); + + /** + * Repaints the widget background. Normally, you shouldn't need this + * as it is handled automatically. This is equivalent to calling + * tqrepaint( false ). + */ + void tqrepaint(); + + /** + * Asks KDesktop to export the desktop background as a KSharedPixmap. + * This method uses DCOP to call KBackgroundIface/setExport(int). + */ + void enableExports(); + + /** + * Returns the name of the shared pixmap (only needed for low level access) + */ + static TQString pixmapName(int desk); +signals: + /** + * Emitted when the background needs updating and custom painting + * (see setCustomPainting(bool) ) is enabled. + * + * @param pm A pixmap containing the new background. + */ + void backgroundUpdated( const TQPixmap &pm ); + +protected: + /** + * Called when the pixmap has been updated. The default implementation + * applies the fade effect, then sets the target's background, or emits + * backgroundUpdated(const TQPixmap &) depending on the painting mode. + */ + virtual void updateBackground( KSharedPixmap * ); + +private slots: + void slotBackgroundChanged(int); + void slotDone(bool); + +private: + bool m_bActive, m_bInit; + int m_Desk; + int m_timeout; + + double m_Fade; + TQColor m_FadeColor; + + TQRect m_Rect; + TQTimer *m_pTimer; + KSharedPixmap *m_pPixmap; + KRootBackingData *d; + + void init(); +}; + +#endif // ! Q_WS_QWS + +#endif // KROOTBACKING_H \ No newline at end of file diff --git a/kscreensaver/krootbacking/main.cpp b/kscreensaver/krootbacking/main.cpp new file mode 100644 index 00000000..6b35a51a --- /dev/null +++ b/kscreensaver/krootbacking/main.cpp @@ -0,0 +1,73 @@ +/*************************************************************************** + * Copyright (C) 2011 by Timothy Pearson * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include "krootbacking.h" + +bool argb_visual = false; + +static const char description[] = + I18N_NOOP("A program to grab the current TDE desktop backrounds for xscreensaver"); + +static const char version[] = "0.1"; + +static KCmdLineOptions options[] = +{ + KCmdLineLastOption +}; + +int main(int argc, char **argv) +{ + KAboutData about("krootbacking", I18N_NOOP("krootbacking"), version, description, + KAboutData::License_GPL, "(C) 2011 Timothy Pearson", 0, 0, "kb9vqf@pearsoncomputing.net"); + about.addAuthor( "Timothy Pearson", 0, "kb9vqf@pearsoncomputing.net" ); + KCmdLineArgs::init(argc, argv, &about); + KCmdLineArgs::addCmdLineOptions( options ); + + KApplication app; + + // no session.. just start up normally + KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); + + /// @todo do something with the command line args here + args->clear(); + + TQObject* mainWin = new KRootBacking(); + TQTimer *timer = new QTimer( mainWin ); + TQObject::connect( timer, SIGNAL(timeout()), mainWin, SLOT(start()) ); + timer->start( 100, TRUE ); // 100ms single shot timer + + app.exec(); + + delete timer; + delete mainWin; +} +