Source Code (Use browser search to find items of interest.)
Class Index
kdesktop'KBackgroundManager (./kdebase/kdesktop/bgmanager.h:96)
class KBackgroundManager
: public QObject,
virtual public KBackgroundIface
{
Q_OBJECT
public:
KBackgroundManager(QWidget *desktop, KWinModule* kwinModule);
~KBackgroundManager();
void configure();
void changeDesktop(int desk);
void setCommon(int);
void setExport(int);
void setDocking(int);
private slots:
void slotImageDone(int desk);
void slotWallpaperDropped(QString wallpaper, int mode);
void slotUnDocked();
void slotCommon(bool);
void slotExport(bool);
void slotTimeout();
void slotChangeWallpaper();
void slotChangeDesktop(int);
void slotDesktopNumberChanged(int);
private:
void applyCommon(bool common);
void applyDocking(bool dock);
void applyExport(bool _export);
void applyCache(bool limit, int size);
int realDesktop();
int effectiveDesktop();
void renderBackground(int desk);
void exportBackground(int pixmap, int desk);
int pixmapSize(QPixmap *pm);
int cacheSize();
void removeCache(int desk);
bool freeCache(int size);
void addCache(KPixmap *pm, int hash, int desk);
void setPixmap(KPixmap *pm, int hash, int desk);
bool m_bExport, m_bCommon, m_bDock;
bool m_bLimitCache, m_bInit;
int m_CacheLimit, m_X, m_Y;
int m_Serial, m_Hash, m_Current;
KConfig *m_pConfig;
QWidget *m_pDesktop;
KBackgroundDockWidget *m_pDockWidget;
QTimer *m_pTimer;
QVector<KBackgroundRenderer> m_Renderer;
QVector<KBackgroundCacheEntry> m_Cache;
KWinModule *m_pKwinmodule;
KPixmapServer *m_pPixmapServer;
};
kdesktop'KBackgroundManager::KBackgroundManager() (./kdebase/kdesktop/bgmanager.cc:199)
KBackgroundManager::KBackgroundManager(QWidget *desktop, KWinModule* kwinModule)
: DCOPObject("KBackgroundIface")
{
if (desktop == 0L)
m_pDesktop = QApplication::desktop();
else
m_pDesktop = desktop;
m_X = m_pDesktop->width();
m_Y = m_pDesktop->height();
// We need kwin for this, but startkde starts kwin after us
int nod = KWin::numberOfDesktops();
m_Renderer.resize(nod ? nod : 1);
m_Cache.resize(m_Renderer.size());
m_Serial = 0; m_Hash = 0;
m_pConfig = KGlobal::config();
m_bDock = m_bExport = m_bCommon = m_bInit = false;
m_pKwinmodule = kwinModule;
m_pPixmapServer = new KPixmapServer();
for (unsigned i=0; i<m_Renderer.size(); i++) {
m_Cache.insert(i, new KBackgroundCacheEntry);
m_Cache[i]->pixmap = 0L;
m_Cache[i]->hash = 0;
m_Cache[i]->exp_from = -1;
m_Renderer.insert (i, new KBackgroundRenderer(i));
connect(m_Renderer[i], SIGNAL(imageDone(int)), SLOT(slotImageDone(int)));
}
m_pDockWidget = new KBackgroundDockWidget();
connect(m_pDockWidget, SIGNAL(wallpaperDropped(QString,int)),
SLOT(slotWallpaperDropped(QString,int)));
connect(m_pDockWidget, SIGNAL(changeWallpaper()), SLOT(slotChangeWallpaper()));
connect(m_pDockWidget, SIGNAL(unDocked()), SLOT(slotUnDocked()));
connect(m_pDockWidget, SIGNAL(exportChanged(bool)), SLOT(slotExport(bool)));
connect(m_pDockWidget, SIGNAL(commonChanged(bool)), SLOT(slotCommon(bool)));
configure();
m_pTimer = new QTimer(this);
connect(m_pTimer, SIGNAL(timeout()), SLOT(slotTimeout()));
m_pTimer->start(5000, true); // Init after 5 secs
connect(m_pKwinmodule, SIGNAL(desktopChange(int)), SLOT(slotChangeDesktop(int)));
connect(m_pKwinmodule, SIGNAL(desktopNumberChange(int)), SLOT(slotDesktopNumberChanged(int)));
}
kdesktop'KBackgroundManager::~KBackgroundManager() (./kdebase/kdesktop/bgmanager.cc:249)
KBackgroundManager::~KBackgroundManager()
{
for (unsigned i=0; i<m_Renderer.size(); i++)
delete m_Renderer[i];
delete m_pConfig;
delete m_pPixmapServer;
delete m_pDockWidget;
delete m_pTimer;
if (m_bExport)
return;
for (unsigned i=0; i<m_Cache.size(); i++)
if (m_Cache[i]->pixmap) delete m_Cache[i]->pixmap;
}
kdesktop'KBackgroundManager::applyDocking() (./kdebase/kdesktop/bgmanager.cc:267)
void KBackgroundManager::applyDocking(bool dock)
{
if (dock == m_bDock)
return;
m_bDock = dock;
if (m_bDock && m_bInit)
m_pDockWidget->show();
else
m_pDockWidget->hide();
}
kdesktop'KBackgroundManager::applyExport() (./kdebase/kdesktop/bgmanager.cc:280)
void KBackgroundManager::applyExport(bool exp)
{
if (exp == m_bExport)
return;
// If export mode changed from true -> false, remove all shared pixmaps.
// If it changed false -> true force a redraw because the current screen
// image might not have an associated pixmap in the cache.
if (!exp) {
for (unsigned i=0; i<m_Cache.size(); i++)
removeCache(i);
} else
m_Hash = 0;
m_bExport = exp;
m_pDockWidget->setExport(m_bExport);
}
kdesktop'KBackgroundManager::applyCommon() (./kdebase/kdesktop/bgmanager.cc:299)
void KBackgroundManager::applyCommon(bool common)
{
if (common == m_bCommon)
return;
m_bCommon = common;
// If common changed from false -> true, remove all cache entries, except
// at index 0 if exports are on.
if (m_bCommon) {
if (!m_bExport)
removeCache(0);
for (unsigned i=1; i<m_Cache.size(); i++)
removeCache(i);
}
m_pDockWidget->setCommon(m_bCommon);
}
kdesktop'KBackgroundManager::applyCache() (./kdebase/kdesktop/bgmanager.cc:318)
void KBackgroundManager::applyCache(bool limit, int size)
{
m_bLimitCache = limit;
m_CacheLimit = size;
freeCache(0);
}
/*
* Call this when the configuration has changed.
*/
kdesktop'KBackgroundManager::configure() (./kdebase/kdesktop/bgmanager.cc:329)
void KBackgroundManager::configure()
{
// Read individual settings
KBackgroundRenderer *r;
for (unsigned i=0; i<m_Renderer.size(); i++) {
r = m_Renderer[i];
int ohash = r->hash();
r->load(i);
if ((r->hash() != ohash))
removeCache(i);
}
// Global settings
m_pConfig->reparseConfiguration();
m_pConfig->setGroup("Background Common");
applyDocking(m_pConfig->readBoolEntry("Dock", _defDock));
applyExport(m_pConfig->readBoolEntry("Export", _defExport));
applyCommon(m_pConfig->readBoolEntry("CommonDesktop", _defCommon));
bool limit = m_pConfig->readBoolEntry("LimitCache", _defLimitCache);
int size = m_pConfig->readNumEntry("CacheSize", _defCacheSize) * 1024;
applyCache(limit, size);
// Repaint desktop
changeDesktop(0);
}
kdesktop'KBackgroundManager::realDesktop() (./kdebase/kdesktop/bgmanager.cc:358)
int KBackgroundManager::realDesktop()
{
int desk = m_pKwinmodule->currentDesktop();
if (desk) desk--;
return desk;
}
kdesktop'KBackgroundManager::effectiveDesktop() (./kdebase/kdesktop/bgmanager.cc:366)
int KBackgroundManager::effectiveDesktop()
{
return m_bCommon ? 0 : realDesktop();
}
/*
* Auxiliary slot because dcop functions cannot be slots currently (unfortunately).
*/
kdesktop'KBackgroundManager::slotChangeDesktop() (./kdebase/kdesktop/bgmanager.cc:375)
void KBackgroundManager::slotChangeDesktop(int desk)
{
changeDesktop(desk);
}
/*
* Number of desktops changed
*/
kdesktop'KBackgroundManager::slotDesktopNumberChanged() (./kdebase/kdesktop/bgmanager.cc:383)
void KBackgroundManager::slotDesktopNumberChanged(int num)
{
if (m_Renderer.size() == (unsigned) num)
return;
if (m_Renderer.size() > (unsigned) num) {
for (unsigned i=num; i<m_Renderer.size(); i++) {
if (m_Renderer[i]->isActive())
m_Renderer[i]->stop();
delete m_Renderer[i];
removeCache(i);
}
for (unsigned i=num; i<m_Renderer.size(); i++)
delete m_Cache[i];
m_Renderer.resize(num);
m_Cache.resize(num);
} else { // allocate new renderers and caches
int oldsz = m_Renderer.size();
m_Renderer.resize(num);
m_Cache.resize(num);
for (int i=oldsz; i<num; i++) {
m_Cache.insert(i, new KBackgroundCacheEntry);
m_Cache[i]->pixmap = 0L;
m_Cache[i]->hash = 0;
m_Cache[i]->exp_from = -1;
m_Renderer.insert(i, new KBackgroundRenderer(i));
connect(m_Renderer[i], SIGNAL(imageDone(int)), SLOT(slotImageDone(int)));
}
}
}
/*
* Call this when the desktop has been changed.
* Desk is in KWM convention: [1..desks], instead of [0..desks-1].
* 0 repaints the current desktop.
* This method is DCOP exported.
*/
kdesktop'KBackgroundManager::changeDesktop() (./kdebase/kdesktop/bgmanager.cc:420)
void KBackgroundManager::changeDesktop(int desk)
{
if (desk == 0)
desk = realDesktop();
else
desk--;
// Lazy initialisation of # of desktops
if ((unsigned) desk >= m_Renderer.size())
slotDesktopNumberChanged(KWin::numberOfDesktops());
int edesk = effectiveDesktop();
m_Serial++;
// If the background is the same: do nothing
if (m_Hash == m_Renderer[edesk]->hash()) {
exportBackground(m_Current, desk);
return;
}
// If we have the background already rendered: set it
for (unsigned i=0; i<m_Cache.size(); i++) {
if (!m_Cache[i]->pixmap)
continue;
if (m_Cache[i]->hash != m_Renderer[edesk]->hash())
continue;
setPixmap(m_Cache[i]->pixmap, m_Cache[i]->hash, i);
m_Cache[i]->atime = m_Serial;
exportBackground(i, desk);
return;
}
// Do we have this or an indentical config already running?
for (unsigned i=0; i<m_Renderer.size(); i++) {
if ((m_Renderer[i]->hash() == m_Renderer[edesk]->hash()) &&
(m_Renderer[i]->isActive()))
return;
}
renderBackground(edesk);
}
/*
* Share a desktop pixmap.
*/
kdesktop'KBackgroundManager::exportBackground() (./kdebase/kdesktop/bgmanager.cc:466)
void KBackgroundManager::exportBackground(int pixmap, int desk)
{
if (!m_bExport || (m_Cache[desk]->exp_from == pixmap))
return;
m_Cache[desk]->exp_from = pixmap;
m_pPixmapServer->add(QString("DESKTOP%1").arg(desk+1),
m_Cache[pixmap]->pixmap);
KIPC::sendMessageAll(KIPC::BackgroundChanged);
}
/*
* Paint the pixmap to the root window.
*/
kdesktop'KBackgroundManager::setPixmap() (./kdebase/kdesktop/bgmanager.cc:481)
void KBackgroundManager::setPixmap(KPixmap *pm, int hash, int desk)
{
m_pDesktop->setBackgroundPixmap(*pm);
m_Hash = hash;
m_Current = desk;
}
/*
* Start the render of a desktop background.
*/
kdesktop'KBackgroundManager::renderBackground() (./kdebase/kdesktop/bgmanager.cc:492)
void KBackgroundManager::renderBackground(int desk)
{
KBackgroundRenderer *r = m_Renderer[desk];
if (r->isActive()) {
qDebug("renderer %d already active", desk);
return;
}
// Allow tiles!
r->setTile(true);
r->start();
}
/*
* This slot is called when a renderer is done.
*/
kdesktop'KBackgroundManager::slotImageDone() (./kdebase/kdesktop/bgmanager.cc:509)
void KBackgroundManager::slotImageDone(int desk)
{
KPixmap *pm = new KPixmap();
KBackgroundRenderer *r = m_Renderer[desk];
// Convert with correct color conversion
if (QPixmap::defaultDepth() < 15)
pm->convertFromImage(*r->image(), KPixmap::LowColor);
else
pm->convertFromImage(*r->image());
r->cleanup();
// If current: paint it
bool current = (r->hash() == m_Renderer[effectiveDesktop()]->hash());
if (current)
setPixmap(pm, r->hash(), desk);
if (m_bExport || !m_bCommon)
addCache(pm, r->hash(), desk);
if (current)
exportBackground(desk, realDesktop());
}
/*
* Size in bytes of a QPixmap. For use in the pixmap cache.
*/
kdesktop'KBackgroundManager::pixmapSize() (./kdebase/kdesktop/bgmanager.cc:535)
int KBackgroundManager::pixmapSize(QPixmap *pm)
{
return (pm->width() * pm->height()) * ((pm->depth() + 7) / 8);
}
/*
* Total size of the pixmap cache.
*/
kdesktop'KBackgroundManager::cacheSize() (./kdebase/kdesktop/bgmanager.cc:544)
int KBackgroundManager::cacheSize()
{
int total = 0;
for (unsigned i=0; i<m_Cache.size(); i++)
if (m_Cache[i]->pixmap)
total += pixmapSize(m_Cache[i]->pixmap);
return total;
}
/*
* Remove an entry from the pixmap cache.
*/
kdesktop'KBackgroundManager::removeCache() (./kdebase/kdesktop/bgmanager.cc:557)
void KBackgroundManager::removeCache(int desk)
{
if (m_bExport)
m_pPixmapServer->remove(QString("DESKTOP%1").arg(desk+1));
else
delete m_Cache[desk]->pixmap;
m_Cache[desk]->pixmap = 0L;
m_Cache[desk]->hash = 0;
m_Cache[desk]->exp_from = -1;
m_Cache[desk]->atime = 0;
// Remove cache entries pointing to the removed entry
for (unsigned i=0; i<m_Cache.size(); i++)
if (m_Cache[i]->exp_from == desk) {
assert(m_bExport);
m_Cache[i]->exp_from = -1;
m_pPixmapServer->remove(QString("DESKTOP%1").arg(i+1));
}
}
/*
* Try to free up to size bytes from the cache.
*/
kdesktop'KBackgroundManager::freeCache() (./kdebase/kdesktop/bgmanager.cc:581)
bool KBackgroundManager::freeCache(int size)
{
if (m_bExport || !m_bLimitCache)
return true;
// If it doesn't fit at all, return now.
if (size > m_CacheLimit)
return false;
// If cache is too full, purge it (LRU)
while (size+cacheSize() > m_CacheLimit) {
int j, min;
min = m_Serial+1; j = 0;
for (unsigned i=0; i<m_Cache.size(); i++)
if (m_Cache[i]->pixmap && (m_Cache[i]->atime < min)) {
min = m_Cache[i]->atime;
j = i;
}
removeCache(j);
}
return true;
}
/*
* Try to add a pixmap to the pixmap cache. We don't use QPixmapCache here
* because if we're exporting pixmaps, this needs special care.
*/
kdesktop'KBackgroundManager::addCache() (./kdebase/kdesktop/bgmanager.cc:609)
void KBackgroundManager::addCache(KPixmap *pm, int hash, int desk)
{
if (m_Cache[desk]->pixmap)
removeCache(desk);
if (m_bLimitCache && !m_bExport)
if (!freeCache(pixmapSize(pm))) {
// pixmap does not fit in cache
delete pm; return;
}
m_Cache[desk]->pixmap = pm;
m_Cache[desk]->hash = hash;
m_Cache[desk]->atime = m_Serial;
m_Cache[desk]->exp_from = -1;
exportBackground(desk, desk);
}
kdesktop'KBackgroundManager::slotChangeWallpaper() (./kdebase/kdesktop/bgmanager.cc:628)
void KBackgroundManager::slotChangeWallpaper()
{
KBackgroundRenderer *r = m_Renderer[effectiveDesktop()];
if (r->multiWallpaperMode() == KBackgroundSettings::NoMulti)
return;
r->changeWallpaper();
changeDesktop(0);
}
kdesktop'KBackgroundManager::slotWallpaperDropped() (./kdebase/kdesktop/bgmanager.cc:639)
void KBackgroundManager::slotWallpaperDropped(QString wallpaper, int mode)
{
KBackgroundRenderer *r = m_Renderer[effectiveDesktop()];
r->stop();
r->setWallpaperMode(mode);
r->setWallpaper(wallpaper);
r->writeSettings();
changeDesktop(0);
}
kdesktop'KBackgroundManager::slotUnDocked() (./kdebase/kdesktop/bgmanager.cc:651)
void KBackgroundManager::slotUnDocked()
{
setDocking(false);
}
kdesktop'KBackgroundManager::slotExport() (./kdebase/kdesktop/bgmanager.cc:657)
void KBackgroundManager::slotExport(bool _export)
{
setExport(_export);
}
kdesktop'KBackgroundManager::slotCommon() (./kdebase/kdesktop/bgmanager.cc:663)
void KBackgroundManager::slotCommon(bool common)
{
setCommon(common);
}
// DCOP exported
kdesktop'KBackgroundManager::setDocking() (./kdebase/kdesktop/bgmanager.cc:670)
void KBackgroundManager::setDocking(int dock)
{
applyDocking(dock);
m_pConfig->setGroup("Background Common");
m_pConfig->writeEntry("Dock", m_bDock);
m_pConfig->sync();
}
// DCOP exported
kdesktop'KBackgroundManager::setExport() (./kdebase/kdesktop/bgmanager.cc:680)
void KBackgroundManager::setExport(int _export)
{
applyExport(_export);
m_pConfig->setGroup("Background Common");
m_pConfig->writeEntry("Export", m_bExport);
m_pConfig->sync();
changeDesktop(0);
}
// DCOP exported
kdesktop'KBackgroundManager::setCommon() (./kdebase/kdesktop/bgmanager.cc:691)
void KBackgroundManager::setCommon(int common)
{
applyCommon(common);
m_pConfig->setGroup("Background Common");
m_pConfig->writeEntry("CommonDesktop", m_bCommon);
m_pConfig->sync();
changeDesktop(0);
}
/*
* Called every minute to check if we need to rerun a background program.
* or change a wallpaper.
*/
kdesktop'KBackgroundManager::slotTimeout() (./kdebase/kdesktop/bgmanager.cc:705)
void KBackgroundManager::slotTimeout()
{
// First time init. It's done this way because kdesktop starts before
// kicker and it needs the latter for docking. Hacky indeed....
if (!m_bInit) {
m_bInit = true;
if (m_bDock)
m_pDockWidget->show();
m_pTimer->start(60000);
return;
}
for (unsigned i=0; i<m_Renderer.size(); i++) {
KBackgroundRenderer *r = m_Renderer[i];
bool change = false;
if ((r->backgroundMode() == KBackgroundSettings::Program) &&
(m_Cache[i]->hash != 0) &&
(r->KBackgroundProgram::needUpdate())
) {
r->KBackgroundProgram::update();
change = true;
}
if (r->needWallpaperChange()) {
r->changeWallpaper();
change = true;
}
if (change)
r->start();
}
}