kscreensaver.cpp

00001 /* This file is part of the KDE libraries
00002 
00003     Copyright (c) 2001  Martin R. Jones <mjones@kde.org>
00004 
00005     This library is free software; you can redistribute it and/or
00006     modify it under the terms of the GNU Library General Public
00007     License as published by the Free Software Foundation; either
00008     version 2 of the License, or (at your option) any later version.
00009 
00010     This library is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013     Library General Public License for more details.
00014 
00015     You should have received a copy of the GNU Library General Public License
00016     along with this library; see the file COPYING.LIB.  If not, write to
00017     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018     Boston, MA 02110-1301, USA.
00019 */
00020 
00021 #include <qpainter.h>
00022 #include <qtimer.h>
00023 #include <kapplication.h>
00024 #include "kscreensaver.h"
00025 #ifdef Q_WS_X11
00026 #include <X11/Xlib.h>
00027 #else
00028 typedef WId Window;
00029 #endif
00030 
00031 #undef KeyPress
00032 #undef KeyRelease
00033 
00034 //-----------------------------------------------------------------------------
00035 
00036 class KScreenSaverPrivate
00037 {
00038 public:
00039     QWidget *owner;
00040 };
00041 
00042 KScreenSaver::KScreenSaver( WId id ) : QWidget()
00043 {
00044     Window root;
00045     int ai;
00046     unsigned int au;
00047     unsigned int w = 0;
00048     unsigned int h = 0;
00049 
00050     d = new KScreenSaverPrivate;
00051     d->owner = find( id );
00052     if ( d->owner )
00053     installEventFilter( this );
00054 
00055     if ( id )
00056     {
00057 #ifdef Q_WS_X11 //FIXME
00058         XGetGeometry(qt_xdisplay(), (Drawable)id, &root, &ai, &ai,
00059             &w, &h, &au, &au); 
00060 #endif
00061 
00062         create( id, false, true );
00063     }
00064 
00065     if ( w == 0 ) w = 600;
00066     if ( h == 0 ) h = 420;
00067     resize( w, h );
00068     KApplication::sendPostedEvents();
00069     show();
00070 }
00071 
00072 KScreenSaver::~KScreenSaver()
00073 {
00074     destroy( false, false );
00075     delete d;
00076 }
00077 
00078 void KScreenSaver::embed( QWidget *w )
00079 {
00080     KApplication::sendPostedEvents();
00081 #ifdef Q_WS_X11 //FIXME
00082     XReparentWindow(qt_xdisplay(), w->winId(), winId(), 0, 0);
00083 #endif
00084     w->setGeometry( 0, 0, width(), height() );
00085     KApplication::sendPostedEvents();
00086 }
00087 
00088 bool KScreenSaver::eventFilter( QObject *o, QEvent *e )
00089 {
00090     // make sure events get to the original window owner
00091     if ( d->owner && o == this ) {
00092     QApplication::sendEvent( d->owner, e );
00093     return false;
00094     }
00095 
00096     return QWidget::eventFilter( o, e );
00097 }
00098 
00099 //============================================================================
00100 
00101 class KBlankEffectPrivate
00102 {
00103 public:
00104     KBlankEffect::BlankEffect currentEffect;
00105     int effectProgress;
00106     QTimer *timer;
00107     QWidget *widget;
00108 };
00109 
00110 KBlankEffect::BlankEffect KBlankEffect::effects[] = {
00111     &KBlankEffect::blankNormal,
00112     &KBlankEffect::blankSweepRight,
00113     &KBlankEffect::blankSweepDown,
00114     &KBlankEffect::blankBlocks
00115 };
00116 
00117 KBlankEffect::KBlankEffect( QObject *parent ) : QObject( parent )
00118 {
00119     d = new KBlankEffectPrivate;
00120     d->currentEffect = &KBlankEffect::blankNormal;
00121     d->effectProgress = 0;
00122     d->timer = new QTimer( this );
00123     connect( d->timer, SIGNAL(timeout()), this, SLOT(timeout()) );
00124 }
00125 
00126 
00127 KBlankEffect::~KBlankEffect()
00128 {
00129     delete d;
00130 }
00131 
00132 void KBlankEffect::finished()
00133 {
00134     d->timer->stop();
00135     d->effectProgress = 0;
00136     emit doneBlank();
00137 }
00138 
00139 
00140 void KBlankEffect::blank( QWidget *w, Effect effect )
00141 {
00142     if ( !w ) {
00143         emit doneBlank();
00144         return;
00145     }
00146 
00147     if ( effect == Random )
00148         effect = (Effect)(kapp->random() % MaximumEffects);
00149 
00150     d->effectProgress = 0;
00151     d->widget = w;
00152     d->currentEffect = effects[ (int)effect ];
00153     d->timer->start( 10 );
00154 }
00155 
00156 void KBlankEffect::timeout()
00157 {
00158     (this->*d->currentEffect)();
00159 }
00160 
00161 void KBlankEffect::blankNormal()
00162 {
00163     QPainter p( d->widget );
00164     p.fillRect( 0, 0, d->widget->width(), d->widget->height(), black );
00165     finished();
00166 }
00167 
00168 
00169 void KBlankEffect::blankSweepRight()
00170 {
00171     QPainter p( d->widget );
00172     p.fillRect( d->effectProgress, 0, 50, d->widget->height(), black );
00173     kapp->flushX();
00174     d->effectProgress += 50;
00175     if ( d->effectProgress >= d->widget->width() )
00176         finished();
00177 }
00178 
00179 
00180 void KBlankEffect::blankSweepDown()
00181 {
00182     QPainter p( d->widget );
00183     p.fillRect( 0, d->effectProgress, d->widget->width(), 50, black );
00184     kapp->flushX();
00185     d->effectProgress += 50;
00186     if ( d->effectProgress >= d->widget->height() )
00187         finished();
00188 }
00189 
00190 
00191 void KBlankEffect::blankBlocks()
00192 {
00193     static int *block = 0;
00194 
00195     int bx = (d->widget->width()+63)/64;
00196     int by = (d->widget->height()+63)/64;
00197 
00198     if ( !d->effectProgress ) {
00199         block = new int [ bx*by ];
00200 
00201         for ( int i = 0; i < bx*by; i++ )
00202             block[i] = i;
00203         for ( int i = 0; i < bx*by; i++ ) {
00204             int swap = kapp->random()%(bx*by);
00205             int tmp = block[i];
00206             block[i] = block[swap];
00207             block[swap] = tmp;
00208         }
00209     }
00210 
00211     QPainter p( d->widget );
00212 
00213     // erase a couple of blocks at a time, otherwise it looks too slow
00214     for ( int i = 0; i < 2 && d->effectProgress < bx*by; i++ ) {
00215         int x = block[d->effectProgress]%bx;
00216         int y = block[d->effectProgress]/bx;
00217         p.fillRect( x*64, y*64, 64, 64, black );
00218         d->effectProgress++;
00219     }
00220 
00221     kapp->flushX();
00222 
00223     if ( d->effectProgress >= bx*by ) {
00224         delete[] block;
00225         finished();
00226     }
00227 }
00228 
00229 #include "kscreensaver.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys