SVN_SILENT made messages (.desktop file)
[kdeartwork.git] / kscreensaver / kdesavers / science.cpp
blob653cba7d785c61349e25cbf6dd223366018aeacc
1 //-----------------------------------------------------------------------------
2 //
3 // kscience - screen saver for KDE
4 //
5 // Copyright (c) Rene Beutler 1998
6 //
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <math.h>
11 #include <sys/types.h>
12 #include <time.h>
14 #include <qpainter.h>
15 #include <qcolormap.h>
16 #include <qpixmap.h>
17 #include <qlabel.h>
18 #include <qlistwidget.h>
19 #include <qcheckbox.h>
20 #include <qslider.h>
21 #include <qlayout.h>
22 #include <QPaintEvent>
24 #include <kapplication.h>
25 #include <kglobal.h>
26 #include <kmessagebox.h>
27 #include <klocale.h>
28 #include <kconfig.h>
29 #include <kstandarddirs.h>
30 #include <krandomsequence.h>
32 #include "science.h"
33 #include "science.moc"
35 #if defined Q_WS_X11 && !defined K_WS_QTONLY
36 #include <X11/Xlib.h>
37 #include <X11/Xutil.h>
38 #endif
40 #define SCI_DEFAULT_MODE 0
41 #define SCI_DEFAULT_MOVEX 6
42 #define SCI_DEFAULT_MOVEY 8
43 #define SCI_DEFAULT_SIZE 15
44 #define SCI_DEFAULT_INTENSITY 4
45 #define SCI_DEFAULT_SPEED 70
46 #define SCI_DEFAULT_INVERSE false
47 #define SCI_DEFAULT_GRAVITY false
48 #define SCI_DEFAULT_HIDE false
49 #define SCI_MAX_SPEED 100
50 #define SCI_MAX_MOVE 20
52 #undef Below
55 // libkscreensaver interface
56 class KScienceSaverInterface : public KScreenSaverInterface
60 public:
61 virtual KAboutData* aboutData() {
62 return new KAboutData( "kscience.kss", 0, ki18n( "Science Screen Saver" ), "2.2.0", ki18n( "Science Screen Saver" ) );
66 virtual KScreenSaver* create( WId id )
68 return new KScienceSaver( id );
71 virtual QDialog* setup()
73 return new KScienceSetup();
77 int main( int argc, char *argv[] )
79 KScienceSaverInterface kss;
80 return kScreenSaverMain( argc, argv, kss );
83 static struct {
84 QString name;
85 bool inverseEnable;
86 } modeInfo[MAX_MODES];
88 enum { MODE_WHIRL=0, MODE_CURVATURE, MODE_SPHERE, MODE_WAVE, MODE_EXPONENTIAL, MODE_CONTRACTION };
90 void initModeInfo()
92 modeInfo[MODE_WHIRL].name = i18n( "Whirl" );
93 modeInfo[MODE_WHIRL].inverseEnable = true;
95 modeInfo[MODE_SPHERE].name = i18n( "Sphere" );
96 modeInfo[MODE_SPHERE].inverseEnable = true;
98 modeInfo[MODE_EXPONENTIAL].name = i18n( "Exponential" );
99 modeInfo[MODE_EXPONENTIAL].inverseEnable = false;
101 modeInfo[MODE_CONTRACTION].name = i18n( "Contraction" );
102 modeInfo[MODE_CONTRACTION].inverseEnable = false;
104 modeInfo[MODE_WAVE].name = i18n( "Wave" );
105 modeInfo[MODE_WAVE].inverseEnable = false;
107 modeInfo[MODE_CURVATURE].name = i18n( "Curvature" );
108 modeInfo[MODE_CURVATURE].inverseEnable = true;
111 //-----------------------------------------------------------------------------
112 // KPreviewWidget
115 KPreviewWidget::KPreviewWidget( QWidget *parent ) :
116 QWidget ( parent ) { }
118 void KPreviewWidget::paintEvent( QPaintEvent *event )
120 if( saver != 0 )
121 saver->do_refresh( event->rect() );
124 void KPreviewWidget::notifySaver( KScienceSaver *s )
126 saver = s;
129 //-----------------------------------------------------------------------------
130 // Screen Saver
133 struct KScienceData
135 T32bit **offset;
136 XImage *buffer;
137 XImage *xRootWin;
138 GC gc;
141 KScienceSaver::KScienceSaver( WId id, bool s, bool gP )
142 : KScreenSaver( id )
144 setAttribute( Qt::WA_NoSystemBackground );
146 d = new KScienceData;
147 d->gc = XCreateGC(QX11Info::display(), id, 0, 0);
148 d->xRootWin = 0;
149 d->buffer = 0;
151 moveOn = true;
152 grabPixmap = gP;
153 setup = s;
155 vx = vy = 0.0;
156 readSettings();
158 if( !grabPixmap )
160 grabRootWindow();
161 initialize();
162 do_refresh( QRect ( 0, 0, width(), height() ) );
165 connect( &timer, SIGNAL( timeout() ), SLOT( slotTimeout() ) );
166 timer.start( SCI_MAX_SPEED - speed[mode] );
169 KScienceSaver::~KScienceSaver()
171 timer.stop();
172 releaseLens();
173 if ( d->xRootWin )
174 XDestroyImage( d->xRootWin );
175 XFreeGC(QX11Info::display(), d->gc );
176 delete d;
179 void KScienceSaver::myAssert( bool term, const char *eMsg )
181 if( !term ) {
182 fprintf(stderr, "Error in KScreensaver - mode Science: %s\n", eMsg);
183 releaseLens();
184 exit(-1);
188 void KScienceSaver::initialize()
190 KRandomSequence rnd;
191 initLens();
192 signed int ws = (signed int) (width() - diam);
193 signed int hs = (signed int) (height() - diam);
195 x = (ws > 0) ? (rnd.getDouble() * ws ) : 0.0;
196 y = (hs > 0) ? (rnd.getDouble() * hs ) : 0.0;
198 xcoord = (int) x;
199 ycoord = (int) y;
201 switch( bpp ) {
202 case 1 : applyLens = &KScienceSaver::applyLens8bpp; break;
203 case 2 : applyLens = &KScienceSaver::applyLens16bpp; break;
204 case 3 : applyLens = &KScienceSaver::applyLens24bpp; break;
205 case 4 : applyLens = &KScienceSaver::applyLens32bpp; break;
206 default: myAssert( false, "unsupported colordepth "\
207 "(only 8, 16, 24, 32 bpp supported)" );
211 void KScienceSaver::initWhirlLens()
213 double dx, dy, r, phi, intens;
214 T32bit *off;
215 T32bit xo, yo;
217 intens = double( intensity[mode] + 1) / 5.0;
218 if( inverse[mode] )
219 intens = -intens;
221 for(int y = side-1; y >= 0; y--)
223 dy = y - origin;
224 off = d->offset[y] = (T32bit *) malloc(sizeof(T32bit) * side);
225 myAssert( off != 0, "too few memory" );
226 for(int x = side-1; x >= 0; x--)
228 dx = x - origin;
229 r = sqrt( dx*dx + dy*dy );
231 if( r < radius )
233 if ( dx == 0.0 )
234 phi = (dy > 0.0) ? M_PI_2 :-(M_PI_2);
235 else
236 phi = atan2( dy, dx );
237 phi += intens * ( radius - r ) / ( r+7.0 );
238 xo = (T32bit) ( origin + r*cos( phi ) - x );
239 yo = (T32bit) ( origin + r*sin( phi ) - y );
240 off[x] = xo*bpp + yo*imgnext;
242 else
243 if( hideBG[mode] )
244 off[x] = (border-y)*imgnext + (border-x)*bpp;
245 else
246 off[x] = 0;
251 void KScienceSaver::initSphereLens()
253 double dx, dy, r, xr, yr, phi, intens;
254 T32bit *off;
255 T32bit xo, yo;
257 intens = 1.0 - double( intensity[mode] ) / 20.0;
259 if( inverse[mode] )
260 intens = -intens;
262 for(int y = side-1; y >= 0; y--)
264 dy = y - origin;
265 off = d->offset[y] = (T32bit *) malloc(sizeof(T32bit) * side);
266 myAssert( off != 0, "too few memory" );
267 for(int x = side-1; x >= 0; x--)
269 dx = x - origin;
270 r = sqrt( dx*dx + dy*dy );
272 if( r < radius )
274 xr = (double) radius*cos(asin(dy/radius));
275 yr = (double) radius*cos(asin(dx/radius));
276 phi = (xr != 0.0) ? asin(dx/xr) : 0.0;
277 xo = (T32bit) (origin + intens*2.0*phi*xr / M_PI - x);
278 phi = (yr != 0.0) ? asin(dy/yr) : 0.0;
279 yo = (T32bit) (origin + intens*2.0*phi*yr / M_PI - y);
280 off[x] = xo*bpp + yo*imgnext;
282 else
283 if( hideBG[mode] )
284 off[x] = (border-y)*imgnext + (border-x)*bpp;
285 else
286 off[x] = 0;
291 void KScienceSaver::initExponentialLens()
293 double dx, dy, r, rnew, f, intens;
294 T32bit *off;
295 T32bit xo, yo;
297 if( mode == MODE_EXPONENTIAL )
298 intens = - (0.1 + 0.8 * double( intensity[mode] + 2) / 10.0);
299 else
300 intens = 0.9 - 0.8 * double( intensity[mode] ) / 10.0;
302 for(int y = side-1; y >= 0; y--)
304 dy = y - origin;
305 off = d->offset[y] = (T32bit *) malloc(sizeof(T32bit) * side);
306 myAssert( off != 0, "too few memory" );
307 for(int x = side-1; x >= 0; x--)
309 dx = x - origin;
310 r = sqrt( dx*dx + dy*dy );
312 if( r < radius )
314 if( r == 0.0 )
315 f = 0.0;
316 else
318 rnew = radius*(pow(r, intens) / pow(radius, intens));
319 f = double ((int)rnew % radius) / r;
321 xo = (T32bit) ( origin + f*dx - x );
322 yo = (T32bit) ( origin + f*dy - y );
323 off[x] = xo*bpp + yo*imgnext;
325 else
326 if( hideBG[mode] )
327 off[x] = (border-y)*imgnext + (border-x)*bpp;
328 else
329 off[x] = 0;
334 void KScienceSaver::initCurvatureLens()
336 double dx, dy, r, f, intens;
337 T32bit *off;
338 T32bit xo, yo;
340 intens = (double) radius*intensity[mode] / 20.0;
341 if( inverse[mode] ) intens = -intens;
343 for(int y = side-1; y >= 0; y--)
345 dy = y - origin;
346 off = d->offset[y] = (T32bit *) malloc(sizeof(T32bit) * side);
347 myAssert( off != 0, "too few memory" );
348 for(int x = side-1; x >= 0; x--)
350 dx = x - origin;
351 r = sqrt( dx*dx + dy*dy );
353 if( r < radius )
355 if( r == 0.0 )
356 f = 0.0;
357 else
358 f = (r - intens * sin(M_PI * r/(double)radius)) / r;
359 xo = (T32bit) ( origin + f*dx - x );
360 yo = (T32bit) ( origin + f*dy - y );
361 off[x] = xo*bpp + yo*imgnext;
363 else
364 if( hideBG[mode] )
365 off[x] = (border-y)*imgnext + (border-x)*bpp;
366 else
367 off[x] = 0;
372 void KScienceSaver::initWaveLens()
374 double dx, dy, r, rnew, f, intens, k;
375 T32bit *off;
376 T32bit xo, yo;
378 intens = (double) intensity[mode] + 1.0;
379 k = (intensity[mode] % 2) ? -12.0 : 12.0;
381 for(int y = side-1; y >= 0; y--)
383 dy = y - origin;
384 off = d->offset[y] = (T32bit *) malloc(sizeof(T32bit) * side);
385 myAssert( off != 0, "too few memory" );
386 for(int x = side-1; x >= 0; x--)
388 dx = x - origin;
389 r = sqrt( dx*dx + dy*dy );
391 if( r < radius )
393 if( r == 0.0 )
394 f = 0.0;
395 else
397 rnew = r - k * sin( M_PI * intens * r/(double)radius);
398 f = double ((int)rnew % radius) / r;
400 xo = (T32bit) ( origin + f*dx - x );
401 yo = (T32bit) ( origin + f*dy - y );
402 off[x] = xo*bpp + yo*imgnext;
404 else
405 if( hideBG[mode] )
406 off[x] = (border-y)*imgnext + (border-x)*bpp;
407 else
408 off[x] = 0;
413 void KScienceSaver::initLens()
415 int min = (width() < height()) ? width() : height();
416 border = 1 + SCI_MAX_MOVE;
418 radius = (size[mode] * min) / 100;
419 if( radius<<1 == min ) radius--;
420 diam = radius << 1;
421 myAssert( diam < min, "assertion violated: diam < min" );
422 origin = radius + border;
423 side = origin << 1;
425 d->buffer = XSubImage( d->xRootWin, 0, 0, side, side );
426 myAssert( d->buffer != 0, "cannot allocate pixmap" );
428 d->offset = (T32bit **) malloc( sizeof(T32bit *) * side );
429 myAssert( d->offset != 0, "too few memory" );
431 switch( mode ) {
432 case MODE_WHIRL: initWhirlLens(); break;
433 case MODE_SPHERE: initSphereLens(); break;
434 case MODE_EXPONENTIAL:
435 case MODE_CONTRACTION: initExponentialLens(); break;
436 case MODE_CURVATURE: initCurvatureLens(); break;
437 case MODE_WAVE: initWaveLens(); break;
438 default: myAssert( false, "internal error (wrong mode in initLens() )" );
442 void KScienceSaver::releaseLens()
444 if( d->offset != 0 ) {
445 for(int i=0; i<side; i++)
446 if( d->offset[i] != 0 ) free( d->offset[i] );
447 free( d->offset );
448 d->offset = 0;
450 if( d->buffer != 0 ) {
451 XDestroyImage( d->buffer );
452 d->buffer = 0;
456 void KScienceSaver::setMode( int m )
458 timer.stop();
460 releaseLens();
461 int old = mode;
462 mode = m;
463 vx = copysign( moveX[mode], vx );
464 vy = copysign( moveY[mode], vy );
465 int dm = diam;
466 initLens();
467 if( hideBG[old] ^ hideBG[m] )
468 do_refresh( QRect( 0, 0, width(), height() ) );
469 else
470 if( diam < dm )
472 do_refresh( QRect( (int) x+diam, (int) y, dm-diam, diam ) );
473 do_refresh( QRect( (int) x, (int) y+diam, dm, dm-diam ) );
476 timer.start( SCI_MAX_SPEED - speed[mode] );
479 void KScienceSaver::setMoveX( int s )
481 timer.stop();
483 moveX[mode] = s;
484 vx = copysign( moveX[mode], vx );
486 timer.start( SCI_MAX_SPEED - speed[mode] );
489 void KScienceSaver::setMoveY( int s )
491 timer.stop();
493 moveY[mode] = s;
494 vy = copysign( moveY[mode], vy );
496 timer.start( SCI_MAX_SPEED - speed[mode] );
499 void KScienceSaver::setMove( bool s )
501 moveOn = s;
504 void KScienceSaver::setSize( int s )
506 timer.stop();
508 releaseLens();
509 int dm = diam;
510 size[mode] = s;
511 initLens();
512 if( diam < dm )
514 do_refresh( QRect( (int) x+diam, (int) y, dm-diam, diam ) );
515 do_refresh( QRect( (int) x, (int) y+diam, dm, dm-diam ) );
518 timer.start( SCI_MAX_SPEED - speed[mode] );
521 void KScienceSaver::setSpeed( int s )
523 speed[mode] = s;
525 timer.start( SCI_MAX_SPEED - speed[mode] );
528 void KScienceSaver::setIntensity( int i )
530 timer.stop();
532 releaseLens();
533 intensity[mode] = i;
534 initLens();
536 timer.start( SCI_MAX_SPEED - speed[mode]);
539 void KScienceSaver::setInverse( bool b )
541 timer.stop();
543 releaseLens();
544 inverse[mode] = b;
545 initLens();
547 timer.start( SCI_MAX_SPEED - speed[mode]);
550 void KScienceSaver::setGravity( bool b )
552 timer.stop();
554 releaseLens();
555 gravity[mode] = b;
556 vy = copysign( moveY[mode], vy );
557 initLens();
559 timer.start( SCI_MAX_SPEED - speed[mode]);
562 void KScienceSaver::setHideBG( bool b )
564 timer.stop();
566 releaseLens();
567 hideBG[mode] = b;
568 initLens();
569 do_refresh( QRect( 0, 0, width(), height() ) );
571 timer.start( SCI_MAX_SPEED - speed[mode]);
574 void KScienceSaver::readSettings()
576 KConfigGroup group = KGlobal::config()->group("Settings");
577 QString sMode;
579 mode = group.readEntry( "ModeNr", SCI_DEFAULT_MODE );
581 for(int i=0; i < MAX_MODES; i++)
583 sMode.setNum( i );
584 group = KGlobal::config()->group( "Mode" + sMode );
585 moveX[i] = group.readEntry( "MoveX", SCI_DEFAULT_MOVEX);
586 moveY[i] = group.readEntry( "MoveY", SCI_DEFAULT_MOVEY);
587 size[i] = group.readEntry( "Size", SCI_DEFAULT_SIZE);
588 speed[i] = group.readEntry( "Speed", SCI_DEFAULT_SPEED);
589 intensity[i] = group.readEntry( "Intensity", SCI_DEFAULT_INTENSITY);
590 inverse[i] = group.readEntry( "Inverse", SCI_DEFAULT_INVERSE);
591 gravity[i] = group.readEntry( "Gravity", SCI_DEFAULT_GRAVITY);
592 hideBG[i] = group.readEntry( "HideBG", SCI_DEFAULT_HIDE);
595 vx = copysign( moveX[mode], vx );
596 vy = copysign( moveY[mode], vy );
599 void KScienceSaver::do_refresh( const QRect & origRect )
601 if( grabPixmap )
602 return;
603 QRect rect(origRect.normalized());
605 if( hideBG[mode] )
607 XSetWindowBackground( QX11Info::display(), winId(), QColormap::instance().pixel(Qt::black) );
608 XClearArea( QX11Info::display(), winId(), rect.left(), rect.top(),
609 rect.width(), rect.height(), false );
611 else
613 myAssert( d->xRootWin != 0, "root window not grabbed" );
614 XPutImage( QX11Info::display(), winId(), d->gc, d->xRootWin,
615 rect.left(), rect.top(),
616 rect.left(), rect.top(),
617 rect.width(), rect.height() );
621 void KScienceSaver::slotTimeout()
623 if( grabPixmap ) {
624 if( !QWidget::find(winId())->isActiveWindow() )
625 return;
626 grabPreviewWidget();
627 grabPixmap = false;
628 initialize();
629 if( hideBG[mode] )
630 do_refresh( QRect ( 0, 0, width(), height() ) );
633 signed int oldx = xcoord, oldy = ycoord;
635 if( gravity[mode] ) {
636 double h = double(y+1.0) / double(height()-diam);
637 if( h > 1.0 ) h = 1.0;
638 vy = sqrt( h ) * ( (vy > 0.0) ? moveY[mode] : -moveY[mode] );
640 myAssert( abs((int)rint(vy)) <= border, "assertion violated: vy <= border" );
642 if( moveOn )
644 x += vx;
645 y += vy;
648 if( x <= 0.0 ) {
649 vx = -vx;
650 x = 0.0;
652 if( int(x) + diam >= width()) {
653 vx = -vx;
654 myAssert( width()-diam > 0, "assertion violated: width-diam > 0" );
655 x = (double) (width() - diam - 1);
657 if( y <= 0.0 ) {
658 vy = -vy;
659 y = 0.0;
661 if( int(y) + diam >= height() ) {
662 vy = -vy;
663 myAssert( height() - diam > 0, "assertion violated: height-diam > 0" );
664 y = (double) (height() - diam - 1);
667 xcoord = (int) x ;
668 ycoord = (int) y ;
669 signed int dx = (signed int) xcoord - oldx;
670 signed int dy = (signed int) ycoord - oldy;
671 signed int xs, ys, xd, yd, w, h;
673 if( dx > 0 ) {
674 w = diam+dx;
675 xd = oldx;
676 xs = border-dx;
677 if( dy > 0 ) {
678 h = diam+dy;
679 yd = oldy;
680 ys = border-dy;
682 else {
683 h = diam-dy;
684 yd = ycoord;
685 ys = border;
688 else {
689 w = diam-dx;
690 xd = xcoord;
691 xs = border;
692 if( dy > 0 ) {
693 h = diam+dy;
694 yd = oldy;
695 ys = border-dy;
696 } else {
697 h = diam-dy;
698 yd = ycoord;
699 ys = border;
703 if( xd + w >= width() ) w = width() - xd - 1;
704 if( yd + h >= height() ) h = height() - yd - 1;
706 //printf("%d: (dx: %3d, dy: %3d), diam: %3d, (xc: %3d, yc: %3d), (xs: %3d, ys: %3d), (xd: %3d, yd: %3d), (w: %3d, h: %3d)\n", mode, dx, dy, diam, xcoord, ycoord, xs, ys, xd, yd, w, h);
707 myAssert( dx <= border && dy <=border, "assertion violated: dx or dy <= border");
708 myAssert( xcoord >= 0 && ycoord >= 0, "assertion violated: xcoord, ycoord >= 0 ");
709 myAssert( xd+w < width(), "assertion violated: xd+w < width" );
710 myAssert( yd+h < height(), "assertion violated: yd+h < height" );
712 if( hideBG[mode] )
713 blackPixel( xcoord, ycoord );
714 (this->*applyLens)(xs, ys, xd, yd, w, h);
715 XPutImage( QX11Info::display(), winId(), d->gc, d->buffer, 0, 0, xd, yd, w, h );
716 if( hideBG[mode] )
717 blackPixelUndo( xcoord, ycoord );
720 void KScienceSaver::grabRootWindow()
722 Display *dsp = QX11Info::display();
723 Window rootwin = RootWindow( dsp, QX11Info::appScreen() );
725 // grab contents of root window
726 if( d->xRootWin )
727 XDestroyImage( d->xRootWin );
729 d->xRootWin = XGetImage( dsp, rootwin, 0, 0, width(),
730 height(), AllPlanes, ZPixmap);
731 myAssert( d->xRootWin, "unable to grab root window\n" );
733 imgnext = d->xRootWin->bytes_per_line;
734 bpp = ( d->xRootWin->bits_per_pixel ) >> 3;
737 void KScienceSaver::grabPreviewWidget()
739 myAssert( QWidget::find(winId())->isActiveWindow(), "cannot grab preview widget: dialog not active()" );
741 if( d->xRootWin )
742 XDestroyImage( d->xRootWin );
744 Display *dsp = QX11Info::display();
745 d->xRootWin = XGetImage( dsp, winId(), 0, 0, width(), height(), AllPlanes, ZPixmap);
746 myAssert( d->xRootWin, "unable to grab preview window\n" );
748 imgnext = d->xRootWin->bytes_per_line;
749 bpp = ( d->xRootWin->bits_per_pixel ) >> 3;
752 void KScienceSaver::blackPixel( int x, int y )
754 unsigned char black = (char) BlackPixel( QX11Info::display(), QX11Info::appScreen() );
755 unsigned int adr = x*bpp + y*imgnext;
757 for(int i=0; i<bpp; i++) {
758 blackRestore[i] = d->xRootWin->data[adr];
759 d->xRootWin->data[adr++] = black;
763 void KScienceSaver::blackPixelUndo( int x, int y )
765 unsigned int adr = x*bpp + y*imgnext;
766 for(int i=0; i<bpp; i++)
767 d->xRootWin->data[adr++] = blackRestore[i];
770 // hm....
772 void KScienceSaver::applyLens8bpp(int xs, int ys, int xd, int yd, int w, int h)
774 T32bit *off;
775 char *img1, *img2, *data;
776 signed int ix, iy, datanext = d->buffer->bytes_per_line - w;
778 img1 = d->xRootWin->data + xd + yd*imgnext;
779 data = d->buffer->data;
780 for(iy = ys; iy < ys+h; iy++)
782 off = d->offset[iy] + xs;
783 img2 = img1;
784 for(ix = w; ix > 0; ix--)
785 *data++ = img2++[*off++];
786 img1 += imgnext;
787 data += datanext;
792 void KScienceSaver::applyLens16bpp(int xs, int ys, int xd, int yd, int w, int h)
794 T32bit *off;
795 char *img1, *img2, *data;
796 int ix, iy, datanext = d->buffer->bytes_per_line - (w << 1);
798 img1 = d->xRootWin->data + (xd << 1) + yd*imgnext;
799 data = d->buffer->data;
800 for(iy = ys; iy < ys+h; iy++)
802 off = d->offset[iy] + xs;
803 img2 = img1;
804 for(ix = w; ix > 0; ix--) {
805 *data++ = img2++[*off];
806 *data++ = img2++[*off++];
808 img1 += imgnext;
809 data += datanext;
813 void KScienceSaver::applyLens24bpp(int xs, int ys, int xd, int yd, int w, int h)
815 T32bit *off;
816 char *img1, *img2, *data;
817 signed int ix, iy, datanext = d->buffer->bytes_per_line - 3*w;
819 img1 = d->xRootWin->data + 3*xd + yd*imgnext;
820 data = d->buffer->data;
821 for(iy = ys; iy < ys+h; iy++)
823 off = d->offset[iy] + xs;
824 img2 = img1;
825 for(ix = w; ix > 0; ix--) {
826 *data++ = img2++[*off];
827 *data++ = img2++[*off];
828 *data++ = img2++[*off++];
830 img1 += imgnext;
831 data += datanext;
835 void KScienceSaver::applyLens32bpp(int xs, int ys, int xd, int yd, int w, int h)
837 T32bit *off;
838 char *img1, *img2, *data;
839 signed int ix, iy, datanext = d->buffer->bytes_per_line - (w << 2);
841 img1 = d->xRootWin->data + (xd << 2) + yd*imgnext;
842 data = d->buffer->data;
843 for(iy = ys; iy < ys+h; iy++)
845 off = d->offset[iy] + xs;
846 img2 = img1;
847 for(ix = w; ix > 0; ix--) {
848 *data++ = img2++[*off];
849 *data++ = img2++[*off];
850 *data++ = img2++[*off];
851 *data++ = img2++[*off++];
853 img1 += imgnext;
854 data += datanext;
859 //-----------------------------------------------------------------------------
861 KScienceSetup::KScienceSetup( QWidget *parent )
862 : KDialog( parent)
863 , saver( 0 )
865 setCaption(i18n( "Setup Science Screen Saver" ));
866 setModal(true);
867 setButtons(Ok|Cancel|Help);
868 setDefaultButton(Ok);
869 showButtonSeparator(true);
870 readSettings();
871 initModeInfo();
873 QWidget *main = new QWidget(this);
874 setMainWidget(main);
876 QHBoxLayout *lt = new QHBoxLayout( main );
877 lt->setSpacing( spacingHint() );
878 QVBoxLayout *ltm = new QVBoxLayout;
879 lt->addLayout( ltm );
880 QVBoxLayout *ltc = new QVBoxLayout;
881 lt->addLayout( ltc );
883 // mode
884 QLabel *label = new QLabel( i18n("Mode:"), main );
885 ltm->addWidget( label );
887 QListWidget *c = new QListWidget( main );
888 for(int i = 0; i<MAX_MODES; i++)
889 c->addItem( modeInfo[i].name );
890 c->setCurrentRow( mode );
891 c->setFixedHeight( 5 * c->fontMetrics().height() );
892 connect( c, SIGNAL( currentRowChanged( int ) ), SLOT( slotMode( int ) ) );
893 ltm->addWidget( c );
895 // inverse
896 QCheckBox *cbox = checkInverse = new QCheckBox( i18n("Inverse"), main );
897 cbox->setEnabled( modeInfo[mode].inverseEnable );
898 cbox->setChecked( inverse[mode] );
899 connect( cbox, SIGNAL( clicked() ), SLOT( slotInverse() ) );
900 ltm->addWidget( cbox );
902 // gravity
903 cbox = checkGravity = new QCheckBox( i18n("Gravity"), main );
904 cbox->setChecked( gravity[mode] );
905 connect( cbox, SIGNAL( clicked() ), SLOT( slotGravity() ) );
906 ltm->addWidget( cbox );
908 // hide background
909 cbox = checkHideBG = new QCheckBox( i18n("Hide background"), main );
910 cbox->setChecked( hideBG[mode] );
911 connect( cbox, SIGNAL( clicked() ), SLOT( slotHideBG() ) );
912 ltm->addWidget( cbox );
913 ltm->addStretch();
915 // size
916 label = new QLabel( i18n("Size:"), main );
917 ltc->addWidget( label );
919 slideSize = new QSlider(Qt::Horizontal, main );
920 slideSize->setMinimum(9);
921 slideSize->setMaximum(50);
922 slideSize->setPageStep(5);
923 slideSize->setValue(size[mode]);
924 slideSize->setMinimumSize( 90, 20 );
925 slideSize->setTickPosition(QSlider::TicksBelow);
926 slideSize->setTickInterval(5);
927 connect( slideSize, SIGNAL( sliderMoved( int ) ),
928 SLOT( slotSize( int ) ) );
929 connect( slideSize, SIGNAL( sliderPressed() ),
930 SLOT( slotSliderPressed() ) );
931 connect( slideSize, SIGNAL( sliderReleased() ),
932 SLOT( slotSliderReleased() ) );
934 ltc->addWidget( slideSize );
936 // intensity
937 label = new QLabel( i18n("Intensity:"), main );
938 ltc->addWidget( label );
940 slideIntensity = new QSlider(Qt::Horizontal, main );
941 slideIntensity->setMinimum(0);
942 slideIntensity->setMaximum(10);
943 slideIntensity->setPageStep(1);
944 slideIntensity->setValue(intensity[mode]);
945 slideIntensity->setMinimumSize( 90, 20 );
946 slideIntensity->setTickPosition(QSlider::TicksBelow);
947 slideIntensity->setTickInterval(1);
948 connect( slideIntensity, SIGNAL( sliderMoved( int ) ),
949 SLOT( slotIntensity( int )) );
950 connect( slideIntensity, SIGNAL( sliderPressed() ),
951 SLOT( slotSliderPressed() ) );
952 connect( slideIntensity, SIGNAL( sliderReleased() ),
953 SLOT( slotSliderReleased() ) );
954 ltc->addWidget( slideIntensity );
956 // speed
957 label = new QLabel( i18n("Speed:"), main );
958 ltc->addWidget( label );
960 slideSpeed = new QSlider(Qt::Horizontal, main );
961 slideSpeed->setMinimum(0);
962 slideSpeed->setMaximum(SCI_MAX_SPEED);
963 slideSpeed->setPageStep(10);
964 slideSpeed->setValue(speed[mode]);
965 slideSpeed->setMinimumSize( 90, 20 );
966 slideSpeed->setTickPosition(QSlider::TicksBelow);
967 slideSpeed->setTickInterval(10);
968 connect( slideSpeed, SIGNAL( sliderMoved( int ) ),
969 SLOT( slotSpeed( int ) ) );
970 ltc->addWidget( slideSpeed );
972 // motion
973 label = new QLabel( i18n("Motion:"), main );
974 ltc->addWidget( label );
976 QHBoxLayout *ltcm = new QHBoxLayout;
977 ltc->addLayout( ltcm );
979 slideMoveX = new QSlider(Qt::Horizontal, main );
980 slideMoveX->setMinimum(0);
981 slideMoveX->setMaximum(SCI_MAX_MOVE);
982 slideMoveX->setPageStep(5);
983 slideMoveX->setValue(moveX[mode]);
984 slideMoveX->setMinimumSize( 40, 20 );
985 slideMoveX->setTickPosition(QSlider::TicksBelow);
986 slideMoveX->setTickInterval(5);
987 connect( slideMoveX, SIGNAL( sliderMoved( int ) ),
988 SLOT( slotMoveX( int ) ) );
989 ltcm->addWidget( slideMoveX );
991 slideMoveY = new QSlider(Qt::Horizontal, main );
992 slideMoveY->setMinimum(0);
993 slideMoveY->setMaximum(SCI_MAX_MOVE);
994 slideMoveY->setPageStep(5);
995 slideMoveY->setValue(moveY[mode]);
996 slideMoveY->setMinimumSize( 40, 20 );
997 slideMoveY->setTickPosition(QSlider::TicksBelow);
998 slideMoveY->setTickInterval(5);
999 connect( slideMoveY, SIGNAL( sliderMoved( int ) ),
1000 SLOT( slotMoveY( int ) ) );
1001 ltcm->addWidget( slideMoveY );
1003 ltc->addStretch();
1005 // preview
1006 preview = new KPreviewWidget( main );
1007 preview->setFixedSize( 220, 170 );
1008 QPixmap p( KStandardDirs::locate("data", "kscreensaver/pics/kscience.png") );
1009 QPalette palette;
1010 if( p.isNull() ) {
1011 palette.setColor( preview->backgroundRole(), Qt::black );
1012 } else {
1013 palette.setBrush( preview->backgroundRole(), QBrush( p ) );
1015 preview->setPalette( palette );
1016 preview->show(); // otherwise saver does not get correct size
1017 lt->addWidget( preview );
1019 // let the preview window display before creating the saver
1020 kapp->processEvents();
1022 saver = new KScienceSaver( preview->winId(), true, !p.isNull() );
1023 preview->notifySaver( saver );
1024 connect(this,SIGNAL(okClicked()),SLOT(slotOk()));
1025 connect(this,SIGNAL(helpClicked()),SLOT(slotHelp()));
1028 KScienceSetup::~KScienceSetup()
1030 delete saver; // be sure to delete this first
1033 void KScienceSetup::updateSettings()
1035 // update dialog
1036 slideMoveX ->setValue( moveX[mode] );
1037 slideMoveY ->setValue( moveY[mode] );
1038 slideSize ->setValue( size[mode] );
1039 slideSpeed ->setValue( speed[mode] );
1040 slideIntensity->setValue( intensity[mode] );
1041 checkInverse ->setEnabled( modeInfo[mode].inverseEnable );
1042 checkInverse ->setChecked( inverse[mode] );
1043 checkGravity ->setChecked( gravity[mode] );
1044 checkHideBG ->setChecked( hideBG[mode] );
1047 // read settings from config file
1048 void KScienceSetup::readSettings()
1050 KConfigGroup group = KGlobal::config()->group("Settings");
1051 QString sMode;
1053 mode = group.readEntry( "ModeNr", SCI_DEFAULT_MODE );
1055 for(int i=0; i < MAX_MODES; i++)
1057 sMode.setNum( i );
1058 group = KGlobal::config()->group( "Mode" + sMode );
1059 moveX[i] = group.readEntry( "MoveX", SCI_DEFAULT_MOVEX);
1060 moveY[i] = group.readEntry( "MoveY", SCI_DEFAULT_MOVEY);
1061 size[i] = group.readEntry( "Size", SCI_DEFAULT_SIZE);
1062 speed[i] = group.readEntry( "Speed", SCI_DEFAULT_SPEED);
1063 intensity[i] = group.readEntry( "Intensity", SCI_DEFAULT_INTENSITY);
1064 inverse[i] = group.readEntry( "Inverse", SCI_DEFAULT_INVERSE);
1065 gravity[i] = group.readEntry( "Gravity", SCI_DEFAULT_GRAVITY);
1066 hideBG[i] = group.readEntry( "HideBG", SCI_DEFAULT_HIDE);
1070 void KScienceSetup::slotMode( int m )
1072 mode = m;
1074 if( saver )
1075 saver->setMode( mode );
1077 updateSettings();
1080 void KScienceSetup::slotInverse( )
1082 inverse[mode] = checkInverse->isChecked();
1084 if( saver )
1085 saver->setInverse( inverse[mode] );
1088 void KScienceSetup::slotGravity( )
1090 gravity[mode] = checkGravity->isChecked();
1092 if( saver )
1093 saver->setGravity( gravity[mode] );
1096 void KScienceSetup::slotHideBG( )
1098 hideBG[mode] = checkHideBG->isChecked();
1100 if( saver )
1101 saver->setHideBG( hideBG[mode] );
1104 void KScienceSetup::slotMoveX( int x )
1106 moveX[mode] = x;
1108 if( saver )
1109 saver->setMoveX( x );
1112 void KScienceSetup::slotMoveY( int y )
1114 moveY[mode] = y;
1116 if( saver )
1117 saver->setMoveY( y );
1120 void KScienceSetup::slotSize( int s )
1122 size[mode] = s;
1124 if( saver )
1125 saver->setSize( s );
1128 void KScienceSetup::slotSpeed( int s )
1130 speed[mode] = s;
1132 if( saver )
1133 saver->setSpeed( s );
1136 void KScienceSetup::slotIntensity( int i )
1138 intensity[mode] = i;
1140 if( saver )
1141 saver->setIntensity( i );
1144 void KScienceSetup::slotSliderPressed()
1146 if( saver )
1147 saver->setMove( false );
1150 void KScienceSetup::slotSliderReleased()
1152 if( saver )
1153 saver->setMove( true );
1156 // Ok pressed - save settings and exit
1157 void KScienceSetup::slotOk()
1159 KConfigGroup group = KGlobal::config()->group("Settings");
1160 QString sSize, sSpeed, sIntensity, sMode;
1162 group.writeEntry( "ModeNr", mode );
1164 for(int i=0; i<MAX_MODES; i++)
1166 sMode.setNum( i );
1167 group = KGlobal::config()->group("Mode" + sMode );
1168 group.writeEntry( "MoveX", moveX[i] );
1169 group.writeEntry( "MoveY", moveY[i] );
1170 group.writeEntry( "Size", size[i] );
1171 group.writeEntry( "Speed", speed[i] );
1172 group.writeEntry( "Intensity", intensity[i] );
1173 group.writeEntry( "Inverse", inverse[i] );
1174 group.writeEntry( "Gravity", gravity[i] );
1175 group.writeEntry( "HideBG", hideBG[i] );
1178 group.sync();
1180 accept();
1183 void KScienceSetup::slotHelp()
1185 QString about = i18n("Science Version 0.26.5\n\nWritten by Rene Beutler (1998)\nrbeutler@g26.ethz.ch");
1186 KMessageBox::about(this,
1187 about);