add more spacing
[personal-kdebase.git] / workspace / kdm / kfrontend / krootimage.cpp
blob88cdafcd9bb4ab15d33afa41e8e90d41c2d51241
1 /*
3 Copyright (C) 1999 Matthias Hoelzer-Kluepfel <hoelzer@kde.org>
4 Copyright (C) 2002,2004 Oswald Buddenhagen <ossi@kde.org>
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; see the file COPYING. If not, write to
18 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 Boston, MA 02110-1301, USA.
23 #include "krootimage.h"
25 #include <bgdefaults.h>
27 #include <kcmdlineargs.h>
28 #include <kconfiggroup.h>
29 #include <kdebug.h>
30 #include <kcomponentdata.h>
31 #include <klocale.h>
33 #include <QDesktopWidget>
34 #include <QFile>
35 #include <QHash>
36 #include <QPainter>
37 #include <QX11Info>
39 #include <X11/Xlib.h>
41 #include <stdlib.h>
43 KVirtualBGRenderer::KVirtualBGRenderer( const KSharedConfigPtr &config )
45 m_pPixmap = 0;
46 m_numRenderers = 0;
47 m_scaleX = 1;
48 m_scaleY = 1;
50 m_pConfig = config;
52 initRenderers();
53 m_size = QApplication::desktop()->size();
56 KVirtualBGRenderer::~KVirtualBGRenderer()
58 for (int i=0; i<m_numRenderers; ++i)
59 delete m_renderer[i];
61 delete m_pPixmap;
64 KBackgroundRenderer *
65 KVirtualBGRenderer::renderer( unsigned screen )
67 return m_renderer[screen];
70 QPixmap
71 KVirtualBGRenderer::pixmap()
73 if (m_numRenderers == 1)
74 return m_renderer[0]->pixmap();
76 return *m_pPixmap;
79 bool
80 KVirtualBGRenderer::needProgramUpdate()
82 for (int i = 0; i < m_numRenderers; i++)
83 if (m_renderer[i]->backgroundMode() == KBackgroundSettings::Program &&
84 m_renderer[i]->KBackgroundProgram::needUpdate())
85 return true;
86 return false;
89 void
90 KVirtualBGRenderer::programUpdate()
92 for (int i = 0; i < m_numRenderers; i++)
93 if (m_renderer[i]->backgroundMode() == KBackgroundSettings::Program &&
94 m_renderer[i]->KBackgroundProgram::needUpdate())
95 m_renderer[i]->KBackgroundProgram::update();
98 bool
99 KVirtualBGRenderer::needWallpaperChange()
101 for (int i = 0; i < m_numRenderers; i++)
102 if (m_renderer[i]->needWallpaperChange())
103 return true;
104 return false;
107 void
108 KVirtualBGRenderer::changeWallpaper()
110 for (int i = 0; i < m_numRenderers; i++)
111 m_renderer[i]->changeWallpaper();
114 void
115 KVirtualBGRenderer::desktopResized()
117 m_size = QApplication::desktop()->size();
119 if (m_pPixmap) {
120 delete m_pPixmap;
121 m_pPixmap = new QPixmap( m_size );
122 m_pPixmap->fill( Qt::black );
125 for (int i = 0; i < m_numRenderers; i++)
126 m_renderer[i]->desktopResized();
130 QSize
131 KVirtualBGRenderer::renderSize( int screen )
133 return m_bDrawBackgroundPerScreen ?
134 QApplication::desktop()->screenGeometry( screen ).size() :
135 QApplication::desktop()->size();
139 void
140 KVirtualBGRenderer::initRenderers()
142 KConfigGroup cg( m_pConfig, "Background Common" );
143 // Same config for each screen?
144 // FIXME: Could use same renderer for identically-sized screens.
145 m_bCommonScreen = cg.readEntry( "CommonScreen", _defCommonScreen );
146 // Do not split one big image over all screens?
147 m_bDrawBackgroundPerScreen =
148 cg.readEntry( "DrawBackgroundPerScreen_0", _defDrawBackgroundPerScreen );
150 m_numRenderers = m_bDrawBackgroundPerScreen ? QApplication::desktop()->numScreens() : 1;
152 m_bFinished.resize( m_numRenderers );
153 m_bFinished.fill( false );
155 if (m_numRenderers == m_renderer.size())
156 return;
158 qDeleteAll(m_renderer);
159 m_renderer.resize( m_numRenderers );
160 for (int i = 0; i < m_numRenderers; i++) {
161 int eScreen = m_bCommonScreen ? 0 : i;
162 KBackgroundRenderer *r = new KBackgroundRenderer( eScreen, m_bDrawBackgroundPerScreen, m_pConfig );
163 m_renderer.insert( i, r );
164 r->setSize( renderSize( i ) );
165 connect( r, SIGNAL(imageDone( int )), SLOT(screenDone( int )) );
169 void
170 KVirtualBGRenderer::load( bool reparseConfig )
172 initRenderers();
174 for (int i = 0; i < m_numRenderers; i++) {
175 int eScreen = m_bCommonScreen ? 0 : i;
176 m_renderer[i]->load( eScreen, m_bDrawBackgroundPerScreen, reparseConfig );
180 void
181 KVirtualBGRenderer::screenDone( int screen )
183 m_bFinished[screen] = true;
185 if (m_pPixmap) {
186 // There's more than one renderer, so we are drawing each output to our own pixmap
188 QRect overallGeometry;
189 for (int i = 0; i < QApplication::desktop()->numScreens(); i++)
190 overallGeometry |= QApplication::desktop()->screenGeometry( i );
192 QPoint drawPos =
193 QApplication::desktop()->screenGeometry( screen ).topLeft() -
194 overallGeometry.topLeft();
195 drawPos.setX( int(drawPos.x() * m_scaleX) );
196 drawPos.setY( int(drawPos.y() * m_scaleY) );
198 QPixmap source = m_renderer[screen]->pixmap();
199 QSize renderSize = this->renderSize( screen );
200 renderSize.setWidth( int(renderSize.width() * m_scaleX) );
201 renderSize.setHeight( int(renderSize.height() * m_scaleY) );
203 QPainter p( m_pPixmap );
205 if (renderSize == source.size())
206 p.drawPixmap( drawPos, source );
207 else
208 p.drawTiledPixmap( drawPos.x(), drawPos.y(),
209 renderSize.width(), renderSize.height(), source );
211 p.end();
214 for (int i = 0; i < m_bFinished.size(); i++)
215 if (!m_bFinished[i])
216 return;
218 emit imageDone();
221 void
222 KVirtualBGRenderer::start()
224 delete m_pPixmap;
225 m_pPixmap = 0;
227 if (m_numRenderers > 1) {
228 m_pPixmap = new QPixmap( m_size );
229 // If are screen sizes do not properly tile the overall virtual screen
230 // size, then we want the untiled parts to be black for use in desktop
231 // previews, etc
232 m_pPixmap->fill( Qt::black );
235 m_bFinished.fill( false );
236 for (int i = 0; i < m_numRenderers; i++)
237 m_renderer[i]->start();
241 void KVirtualBGRenderer::stop()
243 for (int i = 0; i < m_numRenderers; i++)
244 m_renderer[i]->stop();
248 void KVirtualBGRenderer::cleanup()
250 m_bFinished.fill( false );
252 for (int i = 0; i < m_numRenderers; i++)
253 m_renderer[i]->cleanup();
255 delete m_pPixmap;
256 m_pPixmap = 0l;
259 void KVirtualBGRenderer::saveCacheFile()
261 for (int i = 0; i < m_numRenderers; i++)
262 m_renderer[i]->saveCacheFile();
265 void KVirtualBGRenderer::enableTiling( bool enable )
267 for (int i = 0; i < m_numRenderers; i++)
268 m_renderer[i]->enableTiling( enable );
272 MyApplication::MyApplication( const char *conf, int argc, char **argv )
273 : QApplication( argc, argv )
274 , renderer( KSharedConfig::openConfig( QFile::decodeName( conf ) ) )
276 connect( &timer, SIGNAL(timeout()), SLOT(slotTimeout()) );
277 connect( &renderer, SIGNAL(imageDone()), this, SLOT(renderDone()) );
278 renderer.enableTiling( true ); // optimize
279 renderer.changeWallpaper(); // cannot do it when we're killed, so do it now
280 timer.start( 60000 );
281 renderer.start();
285 void
286 MyApplication::renderDone()
288 QPalette palette;
289 palette.setBrush( desktop()->backgroundRole(), QBrush( renderer.pixmap() ) );
290 desktop()->setPalette( palette );
291 desktop()->setAutoFillBackground( true );
292 desktop()->setAttribute( Qt::WA_PaintOnScreen );
293 desktop()->show();
294 desktop()->repaint();
296 renderer.saveCacheFile();
297 renderer.cleanup();
298 for (unsigned i = 0; i < renderer.numRenderers(); ++i) {
299 KBackgroundRenderer *r = renderer.renderer( i );
300 if (r->backgroundMode() == KBackgroundSettings::Program ||
301 (r->multiWallpaperMode() != KBackgroundSettings::NoMulti &&
302 r->multiWallpaperMode() != KBackgroundSettings::NoMultiRandom))
303 return;
305 quit();
308 void
309 MyApplication::slotTimeout()
311 bool change = false;
313 if (renderer.needProgramUpdate()) {
314 renderer.programUpdate();
315 change = true;
318 if (renderer.needWallpaperChange()) {
319 renderer.changeWallpaper();
320 change = true;
323 if (change)
324 renderer.start();
328 main( int argc, char *argv[] )
330 KCmdLineArgs::init( argc, argv, "krootimage", "kdmgreet",
331 ki18n("KRootImage"), QByteArray(),
332 ki18n("Fancy desktop background for kdm") );
334 KCmdLineOptions options;
335 options.add( "+config", ki18n("Name of the configuration file") );
336 KCmdLineArgs::addCmdLineOptions( options );
338 KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
339 if (!args->count())
340 args->usage();
341 KComponentData inst( KCmdLineArgs::aboutData() );
342 MyApplication app( args->arg( 0 ).toLocal8Bit(),
343 KCmdLineArgs::qtArgc(), KCmdLineArgs::qtArgv() );
344 args->clear();
346 app.exec();
347 app.flush();
349 // Keep color resources after termination
350 XSetCloseDownMode( QX11Info::display(), RetainTemporary );
352 return 0;
355 #include "krootimage.moc"