diff options
-rw-r--r-- | kcontrol/background/CMakeLists.txt | 2 | ||||
-rw-r--r-- | kcontrol/background/KCrossBGRender.cc | 361 | ||||
-rw-r--r-- | kcontrol/background/KCrossBGRender.h | 76 | ||||
-rw-r--r-- | kcontrol/background/bgdefaults.h | 1 | ||||
-rw-r--r-- | kcontrol/background/bgdialog.cpp | 18 | ||||
-rw-r--r-- | kcontrol/background/bgdialog.h | 1 | ||||
-rw-r--r-- | kcontrol/background/bgdialog_ui.ui | 11 | ||||
-rw-r--r-- | kcontrol/background/bgrender.cpp | 8 | ||||
-rw-r--r-- | kcontrol/background/bgrender.h | 5 | ||||
-rw-r--r-- | kcontrol/background/bgsettings.cpp | 14 | ||||
-rw-r--r-- | kcontrol/background/bgsettings.h | 10 | ||||
-rw-r--r-- | kcontrol/background/crossfade.h | 56 | ||||
-rw-r--r-- | kdesktop/bgmanager.cc | 104 | ||||
-rw-r--r-- | kdesktop/bgmanager.h | 17 | ||||
-rw-r--r-- | tdm/kfrontend/krootimage.h | 1 |
15 files changed, 658 insertions, 27 deletions
diff --git a/kcontrol/background/CMakeLists.txt b/kcontrol/background/CMakeLists.txt index 7996f58a6..0d04bd10d 100644 --- a/kcontrol/background/CMakeLists.txt +++ b/kcontrol/background/CMakeLists.txt @@ -29,7 +29,7 @@ if( BUILD_KCONTROL OR BUILD_KDESKTOP OR BUILD_TDM ) ##### bgnd (static) ############################# tde_add_library( bgnd STATIC_PIC AUTOMOC - SOURCES bgrender.cpp bgsettings.cpp + SOURCES bgrender.cpp bgsettings.cpp KCrossBGRender.cc LINK ${LIBART_LIBRARIES} ) diff --git a/kcontrol/background/KCrossBGRender.cc b/kcontrol/background/KCrossBGRender.cc new file mode 100644 index 000000000..3158e5699 --- /dev/null +++ b/kcontrol/background/KCrossBGRender.cc @@ -0,0 +1,361 @@ +/* + * Copyright (C) 2008 Danilo Cesar Lemes de Paula <danilo@mandriva.com> + * Copyright (C) 2008 Gustavo Boiko <boiko@mandriva.com> + * Mandriva Conectiva + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License version 2 as published by the Free Software Foundation. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <tqdom.h> +#include <tqfile.h> + +#include <kdebug.h> + +#include "KCrossBGRender.h" +#include <tqapplication.h> +#include <kimageeffect.h> + + +KCrossBGRender::KCrossBGRender(int desk, int screen, bool drawBackgroundPerScreen, TDEConfig *config): KBackgroundRenderer(desk,screen,drawBackgroundPerScreen,config) +{ + useCrossEfect = false; + if ( wallpaperList()[0].endsWith("xml",false) ) { + initCrossFade(wallpaperList()[0]); + } +} + + +void KCrossBGRender::initCrossFade(TQString xmlFile) +{ + useCrossEfect = true; + if (xmlFile.isEmpty()){ + useCrossEfect = false; + return; + } + secs = 0; + timeList.empty(); + + // read the XMLfile + TQDomDocument xmldoc = TQDomDocument(xmlFile); + TQFile file( xmlFile ); + if ( !file.open( IO_ReadOnly ) ) { + useCrossEfect = false; + return; + } + if ( !xmldoc.setContent( &file ) ) { + useCrossEfect = false; + file.close(); + return; + } + file.close(); + + TQDomElement docElem = xmldoc.documentElement(); + TQDomNode n = docElem.firstChild(); + while( !n.isNull() ) { + TQDomElement e = n.toElement(); // try to convert the node to an element. + if( !e.isNull() ) { + if (e.tagName() == "starttime") { + createStartTime(e); + } else if (e.tagName() == "transition") { + createTransition(e); + } else if (e.tagName() == "static") { + createStatic(e); + } + } + n = n.nextSibling(); + } + + // Setting "now" state + setCurrentEvent(true); + pix = getCurrentPixmap(); + + useCrossEfect = true; +} + + +KCrossBGRender::~KCrossBGRender(){ +} + +TQPixmap KCrossBGRender::pixmap() { + fixEnabled(); + if (!useCrossEfect){ + TQPixmap p = KBackgroundRenderer::pixmap(); + kdDebug() << "Inherited " << p.size() << endl; + if (p.width() == 0 && p.height() == 0){ + p.convertFromImage(image()); + } + return p; + } + + return pix; +} + +bool KCrossBGRender::needWallpaperChange(){ + if (!useCrossEfect) { + return KBackgroundRenderer::needWallpaperChange(); + } + + bool forceChange = setCurrentEvent(); // If we change the current state + if (forceChange){ // do not matter what hapens + actualPhase = 0; // we need to change background + return true; + } + + // Return false if it's not a transition + if (!current.transition) { + return false; + } + + double timeLeft, timeTotal; + TQTime now = TQTime::currentTime(); + + timeLeft = now.secsTo(current.etime); + if (timeLeft < 0) { + timeLeft += 86400; // before midnight + } + timeTotal = current.stime.secsTo(current.etime); + if (timeTotal < 0) { + timeTotal += 86400; + } + + double passed = timeTotal - timeLeft; + double timeCell = timeTotal/60; //Time cell size + + //kdDebug() << "\ntimeleft:" << timeLeft << " timeTotal:" << timeTotal + // << "\npassed:" << passed << " timeCell:" << timeCell + // << "\nactualPhase: " << actualPhase << endl; + + int aux = passed/timeCell; + if(actualPhase != aux){ + //kdDebug() << "needWallpaperChange() => returned true" << endl; + actualPhase = passed/timeCell; + return true; + } + + //kdDebug() << "needWallpaperChange() => returned false" << endl; + return false; +} + +/* + * This method change the enabledEffect flag to TRUE of FALSE, according + * with multiWallpaperMode and FileName (it needs to be a XML) + */ +void KCrossBGRender::fixEnabled(){ + + + TQString w = wallpaperList()[0]; + useCrossEfect = false; + if(multiWallpaperMode() == Random || multiWallpaperMode() == InOrder){ + + if ( w != xmlFileName ){ + // New XML File + xmlFileName = w; + if (w.endsWith("xml",false)){ + initCrossFade(wallpaperList()[0]); + //useCrossEfect = true; + }else{ + // Not, it's not a xml file + useCrossEfect = false; + } + }else if (w.endsWith("xml",false)){ + //xmlFile doesn't change + //but it's there + useCrossEfect = true; + }else{ + // it's not a XML file + useCrossEfect = false; + } + } +} + +void KCrossBGRender::changeWallpaper(bool init){ + + + + fixEnabled(); + + if (!useCrossEfect){ + KBackgroundRenderer::changeWallpaper(init); + return; + } + + pix = getCurrentPixmap(); + + +} + + +bool KCrossBGRender::setCurrentEvent(bool init){ + TQTime now = TQTime::currentTime(); + + + //Verify if is need to change + if (!(init || now <= current.stime || now >= current.etime )) { + return false; + } + + TQValueList<KBGCrossEvent>::iterator it; + for ( it = timeList.begin(); it != timeList.end(); ++it ){ + + // Look for time + if ( ((*it).stime <= now && now <= (*it).etime) || //normal situation + ((*it).etime <= (*it).stime && (now >= (*it).stime || + now <= (*it).etime) ) ) + { + current = *it; + actualPhase = 0; + + //kdDebug() << "Cur: " << current.stime << "< now <" << current.etime << endl; + return true; + } + } +} + +TQPixmap KCrossBGRender::getCurrentPixmap() +{ + float alpha; + TQPixmap ret; + TQImage tmp; + TQImage p1; + if (!tmp.load(current.pix1)) + return TQPixmap(); + + // scale the pixmap to fit in the screen + //p1 = TQPixmap(QApplication::desktop()->screenGeometry().size()); + //TQPainter p(&p1); + //p.drawPixmap(p1.rect(), tmp); + // + p1 = tmp.smoothScale(TQApplication::desktop()->screenGeometry().size()); + + if (current.transition){ + TQTime now = TQTime::currentTime(); + double timeLeft,timeTotal; + + TQImage p2; + + if (!tmp.load(current.pix2) ) + return NULL; + + p2 = tmp.smoothScale(TQApplication::desktop()->screenGeometry().size()); + //TQPainter p(&p2); + //p.drawPixmap(p2.rect(), tmp); + + timeLeft = now.secsTo(current.etime); + if (timeLeft < 0) + timeLeft += 86400; + timeTotal = current.stime.secsTo(current.etime); + if (timeTotal < 0) + timeTotal += 86400; + + alpha = (timeTotal - timeLeft)/timeTotal; + + //ret = crossFade(p2,p1,alpha); + tmp = KImageEffect::blend(p2,p1,alpha); + ret.convertFromImage(tmp); + return ret; + }else{ + ret.convertFromImage(p1); + return ret; + } + + +} + +void KCrossBGRender::createStartTime(TQDomElement docElem) +{ + int hour; + int minutes; + + TQDomNode n = docElem.firstChild(); + while( !n.isNull() ) { + TQDomElement e = n.toElement(); + if( !e.isNull() ) { + if (e.tagName() == "hour"){ + hour = e.text().toInt(); + }else if ( e.tagName() == "minute" ){ + minutes = e.text().toInt(); + } + + } + + n = n.nextSibling(); + } + secs = hour*60*60 + minutes*60; +} +void KCrossBGRender::createTransition(TQDomElement docElem) +{ + int duration; + TQString from; + TQString to; + + TQDomNode n = docElem.firstChild(); + while( !n.isNull() ) { + TQDomElement e = n.toElement(); + if( !e.isNull() ) { + if (e.tagName() == "duration"){ + duration = e.text().toFloat(); + }else if ( e.tagName() == "from" ){ + from = e.text(); + } + else if ( e.tagName() == "to" ){ + to = e.text(); + } + + } + n = n.nextSibling(); + } + TQTime startTime(0,0,0); + startTime = startTime.addSecs(secs); + TQTime endTime(0,0,0); + endTime = endTime.addSecs(secs+duration); + + secs += duration; + + KBGCrossEvent l = {true, from, to, startTime,endTime}; + + timeList.append(l); + +} +void KCrossBGRender::createStatic(TQDomElement docElem) +{ + int duration; + TQString file; + + TQDomNode n = docElem.firstChild(); + while( !n.isNull() ) { + TQDomElement e = n.toElement(); + if( !e.isNull() ) { + if (e.tagName() == "duration"){ + duration = e.text().toFloat(); + }else if ( e.tagName() == "file" ){ + file = e.text(); + } + + } + n = n.nextSibling(); + } + + TQTime startTime(0,0,0); + startTime = startTime.addSecs(secs); + TQTime endTime(0,0,0); + endTime = endTime.addSecs(secs+duration); + + secs += duration; + + KBGCrossEvent l = {false, file, NULL, startTime,endTime}; + timeList.append(l); +} + +#include "KCrossBGRender.moc" diff --git a/kcontrol/background/KCrossBGRender.h b/kcontrol/background/KCrossBGRender.h new file mode 100644 index 000000000..f3c2f0931 --- /dev/null +++ b/kcontrol/background/KCrossBGRender.h @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2008 Danilo Cesar Lemes de Paula <danilo@mandriva.com> + * Copyright (C) 2008 Gustavo Boiko <boiko@mandriva.com> + * Mandriva Conectiva + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License version 2 as published by the Free Software Foundation. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. +*/ + +#ifndef __KCROSSBGRENDER_H__ +#define __KCROSSBGRENDER_H__ + + +#include <tqvaluelist.h> +#include <tqpixmap.h> +#include <tqvaluelist.h> +#include <tqdatetime.h> + +#include "bgrender.h" + +class TQDomElement; + +typedef struct crossEvent{ + bool transition; + TQString pix1; + TQString pix2; + TQTime stime; //start time + TQTime etime; //end time +} KBGCrossEvent; + + +class KCrossBGRender: public KBackgroundRenderer{ + +TQ_OBJECT + +public: + KCrossBGRender(int desk, int screen, bool drawBackgroundPerScreen, TDEConfig *config=0); + ~KCrossBGRender(); + + bool needWallpaperChange(); + void changeWallpaper(bool init=false); + TQPixmap pixmap(); + bool usingCrossXml(){return useCrossEfect;}; + + +private: + TQPixmap pix; + int secs; + TQString xmlFileName; + bool useCrossEfect; + + int actualPhase; + + void createStartTime(TQDomElement e); + void createTransition(TQDomElement e); + void createStatic(TQDomElement e); + bool setCurrentEvent(bool init = false); + void initCrossFade(TQString xml); + void fixEnabled(); + TQPixmap getCurrentPixmap(); + KBGCrossEvent current; + TQValueList<KBGCrossEvent> timeList; +}; + +#endif // __KCROSSBGRENDER_H__ diff --git a/kcontrol/background/bgdefaults.h b/kcontrol/background/bgdefaults.h index 8a0f2912e..d64c6e546 100644 --- a/kcontrol/background/bgdefaults.h +++ b/kcontrol/background/bgdefaults.h @@ -34,5 +34,6 @@ #define _defBlendMode KBackgroundSettings::NoBlending #define _defBlendBalance 100 #define _defReverseBlending false +#define _defCrossFadeBg false #endif // __BGDefaults_h_Included__ diff --git a/kcontrol/background/bgdialog.cpp b/kcontrol/background/bgdialog.cpp index 9c0cd5e1b..c221a50fe 100644 --- a/kcontrol/background/bgdialog.cpp +++ b/kcontrol/background/bgdialog.cpp @@ -174,6 +174,10 @@ BGDialog::BGDialog(TQWidget* parent, TDEConfig* _config, bool _multidesktop) connect(m_cbBlendReverse, TQT_SIGNAL(toggled(bool)), TQT_SLOT(slotBlendReverse(bool))); + // Crossfading background + connect(m_cbCrossFadeBg, TQT_SIGNAL(toggled(bool)), + TQT_SLOT(slotCrossFadeBg(bool))); + // advanced options connect(m_buttonAdvanced, TQT_SIGNAL(clicked()), TQT_SLOT(slotAdvanced())); @@ -304,6 +308,7 @@ void BGDialog::makeReadOnly() m_cbBlendReverse->setEnabled( false ); m_buttonAdvanced->setEnabled( false ); m_buttonGetNew->setEnabled( false ); + m_cbCrossFadeBg->setEnabled( false ); } void BGDialog::load( bool useDefaults ) @@ -781,6 +786,8 @@ void BGDialog::updateUI() m_cbBlendReverse->setChecked(r->reverseBlending()); m_sliderBlend->setValue( r->blendBalance() / 10 ); + m_cbCrossFadeBg->setChecked(r->crossFadeBg()); + m_comboBlend->blockSignals(false); m_sliderBlend->blockSignals(false); @@ -1295,6 +1302,17 @@ void BGDialog::slotBlendReverse(bool b) eRenderer()->start(true); } +void BGDialog::slotCrossFadeBg(bool b) +{ + if (b == eRenderer()->crossFadeBg()) + return; + emit changed(true); + + eRenderer()->stop(); + eRenderer()->setCrossFadeBg(b); + eRenderer()->start(true); +} + void BGDialog::desktopResized() { for (unsigned i = 0; i < m_renderer.size(); ++i) diff --git a/kcontrol/background/bgdialog.h b/kcontrol/background/bgdialog.h index 08dfe13be..6b33d8999 100644 --- a/kcontrol/background/bgdialog.h +++ b/kcontrol/background/bgdialog.h @@ -80,6 +80,7 @@ protected slots: void slotBlendReverse(bool b); void desktopResized(); void setBlendingEnabled(bool); + void slotCrossFadeBg(bool); protected: void getEScreen(); diff --git a/kcontrol/background/bgdialog_ui.ui b/kcontrol/background/bgdialog_ui.ui index 3960b4009..f35e19f78 100644 --- a/kcontrol/background/bgdialog_ui.ui +++ b/kcontrol/background/bgdialog_ui.ui @@ -376,6 +376,17 @@ </ul></qt></string> </property> </widget> + <widget class="TQCheckBox" row="8" column="1"> + <property name="name"> + <cstring>m_cbCrossFadeBg</cstring> + </property> + <property name="text"> + <string>Cross-fading background</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Enables a smooth fading effect when changing background image.</string> + </property> + </widget> <widget class="TQComboBox" row="5" column="1"> <property name="name"> <cstring>m_comboBlend</cstring> diff --git a/kcontrol/background/bgrender.cpp b/kcontrol/background/bgrender.cpp index f6db68f70..5e9e4b82f 100644 --- a/kcontrol/background/bgrender.cpp +++ b/kcontrol/background/bgrender.cpp @@ -10,6 +10,8 @@ #include <config.h> +#include "KCrossBGRender.h" + #include <time.h> #include <stdlib.h> #include <utime.h> @@ -1061,7 +1063,7 @@ KVirtualBGRenderer::~KVirtualBGRenderer() } -KBackgroundRenderer * KVirtualBGRenderer::renderer(unsigned screen) +KCrossBGRender * KVirtualBGRenderer::renderer(unsigned screen) { return m_renderer[screen]; } @@ -1220,7 +1222,7 @@ void KVirtualBGRenderer::initRenderers() for (unsigned i=0; i<m_numRenderers; ++i) { int eScreen = m_bCommonScreen ? 0 : i; - KBackgroundRenderer * r = new KBackgroundRenderer( m_desk, eScreen, m_bDrawBackgroundPerScreen, m_pConfig ); + KCrossBGRender *r = new KCrossBGRender(m_desk, eScreen, m_bDrawBackgroundPerScreen, m_pConfig); m_renderer.insert( i, r ); r->setSize(renderSize(i)); connect( r, TQT_SIGNAL(imageDone(int,int)), this, TQT_SLOT(screenDone(int,int)) ); @@ -1250,7 +1252,7 @@ void KVirtualBGRenderer::screenDone(int _desk, int _screen) Q_UNUSED(_desk); Q_UNUSED(_screen); - const KBackgroundRenderer * sender = dynamic_cast<const KBackgroundRenderer*>(this->sender()); + const KCrossBGRender * sender = dynamic_cast<const KCrossBGRender*>(this->sender()); int screen = m_renderer.find(sender); if (screen == -1) //?? diff --git a/kcontrol/background/bgrender.h b/kcontrol/background/bgrender.h index 56317013f..5ab1cc6c3 100644 --- a/kcontrol/background/bgrender.h +++ b/kcontrol/background/bgrender.h @@ -28,6 +28,7 @@ class TDEProcess; class KTempFile; class KShellProcess; class TDEStandardDirs; +class KCrossBGRender; /** * This class renders a desktop background to a TQImage. The operation is @@ -127,7 +128,7 @@ public: KVirtualBGRenderer(int desk, TDEConfig *config=0l); ~KVirtualBGRenderer(); - KBackgroundRenderer * renderer(unsigned screen); + KCrossBGRender * renderer(unsigned screen); unsigned numRenderers() const { return m_numRenderers; } TQPixmap pixmap(); @@ -173,7 +174,7 @@ private: TQSize m_size; TQMemArray<bool> m_bFinished; - TQPtrVector<KBackgroundRenderer> m_renderer; + TQPtrVector<KCrossBGRender> m_renderer; TQPixmap *m_pPixmap; }; diff --git a/kcontrol/background/bgsettings.cpp b/kcontrol/background/bgsettings.cpp index d36d7f140..f29eeacf4 100644 --- a/kcontrol/background/bgsettings.cpp +++ b/kcontrol/background/bgsettings.cpp @@ -437,6 +437,7 @@ KBackgroundSettings::KBackgroundSettings(int desk, int screen, bool drawBackgrou defBlendMode = _defBlendMode; defBlendBalance = _defBlendBalance; defReverseBlending = _defReverseBlending; + defCrossFadeBg = _defCrossFadeBg; m_MinOptimizationDepth = _defMinOptimizationDepth; m_bShm = _defShm; @@ -537,6 +538,7 @@ void KBackgroundSettings::copyConfig(const KBackgroundSettings *settings) m_BlendMode = settings->m_BlendMode; m_BlendBalance = settings->m_BlendBalance; m_ReverseBlending = settings->m_ReverseBlending; + m_CrossFadeBg = settings->m_CrossFadeBg; m_MinOptimizationDepth = settings->m_MinOptimizationDepth; m_bShm = settings->m_bShm; m_MultiMode = settings->m_MultiMode; @@ -633,6 +635,15 @@ void KBackgroundSettings::setReverseBlending(bool value) } +void KBackgroundSettings::setCrossFadeBg(bool value) +{ + if (m_CrossFadeBg == value) + return; + dirty = hashdirty = true; + m_CrossFadeBg = value; +} + + void KBackgroundSettings::setWallpaper(TQString wallpaper) { dirty = hashdirty = true; @@ -774,6 +785,8 @@ void KBackgroundSettings::readSettings(bool reparse) m_ReverseBlending = m_pConfig->readBoolEntry( "ReverseBlending", defReverseBlending); + m_CrossFadeBg = m_pConfig->readBoolEntry( "CrossFadeBg", defCrossFadeBg); + // Multiple wallpaper config m_WallpaperList = m_pConfig->readPathListEntry("WallpaperList"); @@ -834,6 +847,7 @@ void KBackgroundSettings::writeSettings() m_pConfig->writeEntry("BlendMode", m_BlMRevMap[m_BlendMode]); m_pConfig->writeEntry("BlendBalance", m_BlendBalance); m_pConfig->writeEntry("ReverseBlending", m_ReverseBlending); + m_pConfig->writeEntry("CrossFadeBg", m_CrossFadeBg); m_pConfig->writeEntry("MinOptimizationDepth", m_MinOptimizationDepth); m_pConfig->writeEntry("UseSHM", m_bShm); diff --git a/kcontrol/background/bgsettings.h b/kcontrol/background/bgsettings.h index 0e16a87e9..a49873af2 100644 --- a/kcontrol/background/bgsettings.h +++ b/kcontrol/background/bgsettings.h @@ -8,8 +8,8 @@ * Public License. See the file "COPYING.LIB" for the exact licensing terms. */ -#ifndef __BGSettings_h_Included__ -#define __BGSettings_h_Included__ +#ifndef __BGSETTINGS_H__ +#define __BGSETTINGS_H__ #include <tqstringlist.h> @@ -198,6 +198,9 @@ public: void setReverseBlending(bool value); bool reverseBlending() const { return m_ReverseBlending; } + void setCrossFadeBg(bool value); + bool crossFadeBg() const { return m_CrossFadeBg; } + void setBlendBalance(int value); int blendBalance() const { return m_BlendBalance; } @@ -273,6 +276,7 @@ private: int m_BlendMode, defBlendMode; int m_BlendBalance, defBlendBalance; bool m_ReverseBlending, defReverseBlending; + bool m_CrossFadeBg, defCrossFadeBg; int m_MinOptimizationDepth; bool m_bShm; bool m_bDrawBackgroundPerScreen; @@ -369,4 +373,4 @@ private: }; -#endif // __BGSettings_h_Included__ +#endif // __BGSETTINGS_H__ diff --git a/kcontrol/background/crossfade.h b/kcontrol/background/crossfade.h new file mode 100644 index 000000000..dba34a3b4 --- /dev/null +++ b/kcontrol/background/crossfade.h @@ -0,0 +1,56 @@ +/* vi: ts=8 sts=4 sw=4 + * kate: space-indent on; tab-width 8; indent-width 4; indent-mode cstyle; + * + * This file is part of the KDE project, module kdesktop. + * Copyright (C) 1999,2000 Geert Jansen <jansen@kde.org> + * + * You can Freely distribute this program under the GNU General Public + * License. See the file "COPYING" for the exact licensing terms. + */ + +#ifndef __CROSSFADE_H__ +#define __CROSSFADE_H__ + +#include <tqtimer.h> +#include <tqpainter.h> +#include <tqpixmap.h> +#include <X11/X.h> +#include <X11/Xlib.h> +#include <X11/Xatom.h> +#include <X11/extensions/Xrender.h> +#include <kdebug.h> +#include <unistd.h> + + + +inline TQPixmap crossFade(const TQPixmap &pix1, const TQPixmap &pix2, double r_alpha, + bool sync = false){ + + TQPixmap pix = TQPixmap(1,1,8); + int mw,mh; + mw = pix1.width(); + mh = pix1.height(); + + int alpha = 0xffff * (1-r_alpha); + + XRenderColor clr = { 0, 0, 0, alpha }; + XRenderPictureAttributes pa; + pa.repeat = True; + Picture pic = XRenderCreatePicture(pix.x11Display(), pix.handle(), + XRenderFindStandardFormat (pix.x11Display(), PictStandardA8), + CPRepeat, &pa); + XRenderFillRectangle(pix.x11Display(), PictOpSrc, pic, + &clr, 0, 0, 1, 1); + TQPixmap dst(pix1); + dst.detach(); + XRenderComposite(pix.x11Display(), PictOpOver, pix2.x11RenderHandle(), + pic, dst.x11RenderHandle(),0,0, 0,0, 0,0, mw,mh); + + if (sync) { + XSync(pix.x11Display(), false); + } + XRenderFreePicture(pix.x11Display(), pic); + return dst; +} + +#endif // __CROSSFADE_H__ diff --git a/kdesktop/bgmanager.cc b/kdesktop/bgmanager.cc index ddb95c9e7..32f774357 100644 --- a/kdesktop/bgmanager.cc +++ b/kdesktop/bgmanager.cc @@ -16,10 +16,15 @@ #include "bgsettings.h" #include "kdesktopapp.h" +#include "KCrossBGRender.h" +#include "crossfade.h" + #include <assert.h> #include <tqtimer.h> #include <tqscrollview.h> +#include <tqpainter.h> +#include <tqdesktopwidget.h> #include <kiconloader.h> #include <tdeconfig.h> @@ -34,6 +39,8 @@ #include <X11/X.h> #include <X11/Xlib.h> #include <X11/Xatom.h> +#include <X11/extensions/Xrender.h> +#include <unistd.h> #ifndef None #define None 0L @@ -47,7 +54,7 @@ #include "pixmapserver.h" -template class TQPtrVector<KBackgroundRenderer>; +template class TQPtrVector<KCrossBGRender>; template class TQPtrVector<KBackgroundCacheEntry>; template class TQMemArray<int>; @@ -108,6 +115,12 @@ KBackgroundManager::KBackgroundManager(TQWidget *desktop, KWinModule* twinModule connect(m_pTimer, TQT_SIGNAL(timeout()), TQT_SLOT(slotTimeout())); m_pTimer->start( 60000 ); + /*CrossFade's config*/ + m_crossTimer = new TQTimer(this); + connect(m_crossTimer, TQT_SIGNAL(timeout()), TQT_SLOT(slotCrossFadeTimeout())); + /*Ends here*/ + + connect(m_pKwinmodule, TQT_SIGNAL(currentDesktopChanged(int)), TQT_SLOT(slotChangeDesktop(int))); connect(m_pKwinmodule, TQT_SIGNAL(numberOfDesktopsChanged(int)), @@ -577,6 +590,36 @@ void KBackgroundManager::renderBackground(int desk) /* + * This slot is called when the Timeout is executed + */ +void KBackgroundManager::slotCrossFadeTimeout() +{ + KVirtualBGRenderer *r = m_Renderer[fadeDesk]; + if (crossInit) { + mBenchmark.start(); + } + + if (mAlpha <= 0.0 || mBenchmark.elapsed() > 300 ) { + bool do_cleanup = true; + mAlpha = 1; + m_crossTimer->stop(); + KPixmap pixm(mNextScreen); + setPixmap(&pixm, r->hash(), fadeDesk); + return; + } + // Reset Timer + mBenchmark.start(); + + TQPixmap dst = crossFade(*mOldScreen, mNextScreen, mAlpha, crossInit); + KPixmap pixm(dst); + setPixmap(&pixm, r->hash(), fadeDesk); + + mAlpha -=0.03; + crossInit = false; +} + + +/* * This slot is called when a renderer is done. */ void KBackgroundManager::slotImageDone(int desk) @@ -592,18 +635,49 @@ void KBackgroundManager::slotImageDone(int desk) KPixmap *pm = new KPixmap(); KVirtualBGRenderer *r = m_Renderer[desk]; bool do_cleanup = true; + fadeDesk = desk; + mAlpha = 1.0; + int width,height; + *pm = r->pixmap(); // If current: paint it bool current = (r->hash() == m_Renderer[effectiveDesktop()]->hash()); if (current) { - //KPixmap * viewport_background = new KPixmap(TQPixmap(pm->width()*s.width(), pm->height()*s.height())); - //printf("slotImageDone(): x: %d y: %d\n", viewport_background->size().width(), viewport_background->size().height()); - //setPixmap(viewport_background, r->hash(), desk); - //delete viewport_background; - - setPixmap(pm, r->hash(), desk); + //START + if (m_Renderer[effectiveDesktop()]->renderer(0)->crossFadeBg() && !m_Renderer[effectiveDesktop()]->renderer(0)->usingCrossXml()){ + int mode = m_Renderer[effectiveDesktop()]->renderer(0)->wallpaperMode(); + width = TQApplication::desktop()->screenGeometry().width(); + height = TQApplication::desktop()->screenGeometry().height(); + + if (mode == KBackgroundSettings::NoWallpaper || mode == KBackgroundSettings::Tiled || mode == KBackgroundSettings::CenterTiled ){ + mNextScreen = TQPixmap(width,height); + TQPainter p (&mNextScreen); + p.drawTiledPixmap(0,0,width,height,*pm); + } else { + mNextScreen = TQPixmap(*pm); + } + + if (m_pDesktop){ + mOldScreen = const_cast<TQPixmap *>( m_pDesktop->backgroundPixmap() ); + }else{ + mOldScreen = const_cast<TQPixmap *>( + TQApplication::desktop()->screen()->backgroundPixmap() ); + } + + //TODO Find a way to discover if CrossFade effect needs to run + if (mOldScreen){ + crossInit = true; + m_crossTimer->start(70); + } else{ + setPixmap(pm, r->hash(), desk); + } + }else{ + setPixmap(pm, r->hash(), desk); + } + //ENDS HERE */ + if (!m_bBgInitDone) { m_bBgInitDone = true; @@ -801,7 +875,7 @@ int KBackgroundManager::validateDesk(int desk) TQString KBackgroundManager::currentWallpaper(int desk) { //TODO Is the behaviour of this function appropriate for multiple screens? - KBackgroundRenderer *r = m_Renderer[validateDesk(desk)]->renderer(0); + KCrossBGRender *r = m_Renderer[validateDesk(desk)]->renderer(0); return r->currentWallpaper(); } @@ -818,7 +892,7 @@ void KBackgroundManager::changeWallpaper() // DCOP exported void KBackgroundManager::setExport(int _export) { - kdDebug() << "KBackgroundManager enabling exports.\n"; +// kdDebug() << "KBackgroundManager enabling exports.\n"; applyExport(_export); slotChangeDesktop(0); } @@ -843,7 +917,7 @@ void KBackgroundManager::setWallpaper(TQString wallpaper, int mode) //TODO Is the behaviour of this function appropriate for multiple screens? for (unsigned i=0; i < m_Renderer[effectiveDesktop()]->numRenderers(); ++i) { - KBackgroundRenderer *r = m_Renderer[effectiveDesktop()]->renderer(i); + KCrossBGRender *r = m_Renderer[effectiveDesktop()]->renderer(i); r->stop(); r->setWallpaperMode(mode); r->setMultiWallpaperMode(KBackgroundSettings::NoMulti); @@ -856,7 +930,7 @@ void KBackgroundManager::setWallpaper(TQString wallpaper, int mode) void KBackgroundManager::setWallpaper(TQString wallpaper) { //TODO Is the behaviour of this function appropriate for multiple screens? - KBackgroundRenderer *r = m_Renderer[effectiveDesktop()]->renderer(0); + KCrossBGRender *r = m_Renderer[effectiveDesktop()]->renderer(0); int mode = r->wallpaperMode(); if (mode == KBackgroundSettings::NoWallpaper) mode = KBackgroundSettings::Tiled; @@ -869,7 +943,7 @@ void KBackgroundManager::setWallpaper(TQString wallpaper) TQStringList KBackgroundManager::wallpaperFiles(int desk) { //TODO Is the behaviour of this function appropriate for multiple screens? - KBackgroundRenderer *r = m_Renderer[validateDesk(desk)]->renderer(0); + KCrossBGRender *r = m_Renderer[validateDesk(desk)]->renderer(0); return r->wallpaperFiles(); } @@ -880,7 +954,7 @@ TQStringList KBackgroundManager::wallpaperFiles(int desk) TQStringList KBackgroundManager::wallpaperList(int desk) { //TODO Is the behaviour of this function appropriate for multiple screens? - KBackgroundRenderer *r = m_Renderer[validateDesk(desk)]->renderer(0);; + KCrossBGRender *r = m_Renderer[validateDesk(desk)]->renderer(0);; return r->wallpaperList(); } @@ -907,7 +981,7 @@ void KBackgroundManager::setWallpaper(int desk, TQString wallpaper, int mode) //TODO Is the behaviour of this function appropriate for multiple screens? for (unsigned i=0; i < m_Renderer[sdesk]->numRenderers(); ++i) { - KBackgroundRenderer *r = m_Renderer[sdesk]->renderer(i); + KCrossBGRender *r = m_Renderer[sdesk]->renderer(i); setCommon(false); // Force each desktop to have it's own wallpaper @@ -974,7 +1048,7 @@ void KBackgroundManager::setColor(const TQColor & c, bool isColorA) //TODO Is the behaviour of this function appropriate for multiple screens? for (unsigned i=0; i < m_Renderer[effectiveDesktop()]->numRenderers(); ++i) { - KBackgroundRenderer *r = m_Renderer[effectiveDesktop()]->renderer(i); + KCrossBGRender *r = m_Renderer[effectiveDesktop()]->renderer(i); r->stop(); if (isColorA) diff --git a/kdesktop/bgmanager.h b/kdesktop/bgmanager.h index 2d29278f7..71ca6c1bb 100644 --- a/kdesktop/bgmanager.h +++ b/kdesktop/bgmanager.h @@ -7,12 +7,13 @@ * License. See the file "COPYING" for the exact licensing terms. */ -#ifndef __BGManager_h_Included__ -#define __BGManager_h_Included__ +#ifndef __BGMANAGER_H__ +#define __BGMANAGER_H__ #include <tqstring.h> #include <tqptrvector.h> +#include <tqdatetime.h> #include <KBackgroundIface.h> #if defined(Q_WS_X11) && defined(HAVE_XRENDER) && TQT_VERSION >= 0x030300 @@ -89,6 +90,7 @@ private slots: void desktopResized(); void clearRoot(); void saveImages(); + void slotCrossFadeTimeout(); void slotCmBackgroundChanged(bool); private: @@ -131,6 +133,15 @@ private: KPixmapServer *m_pPixmapServer; unsigned long m_xrootpmap; + + /*CrossFade vars*/ + TQTimer * m_crossTimer; + double mAlpha; + TQPixmap mNextScreen; + TQPixmap * mOldScreen; + int fadeDesk; + TQTime mBenchmark; + bool crossInit; }; -#endif // __BGManager_h_Included__ +#endif // __BGMANAGER_H__ diff --git a/tdm/kfrontend/krootimage.h b/tdm/kfrontend/krootimage.h index b10480986..e002ce230 100644 --- a/tdm/kfrontend/krootimage.h +++ b/tdm/kfrontend/krootimage.h @@ -27,6 +27,7 @@ Boston, MA 02110-1301, USA. #include <tqtimer.h> #include <bgrender.h> +#include <KCrossBGRender.h> class MyApplication : public TDEApplication |