diff options
Diffstat (limited to 'libkscreensaver')
-rw-r--r-- | libkscreensaver/Makefile.am | 18 | ||||
-rw-r--r-- | libkscreensaver/configure.in.in | 5 | ||||
-rw-r--r-- | libkscreensaver/kscreensaver.cpp | 229 | ||||
-rw-r--r-- | libkscreensaver/kscreensaver.h | 138 | ||||
-rw-r--r-- | libkscreensaver/kscreensaver_vroot.h | 132 | ||||
-rw-r--r-- | libkscreensaver/main.cpp | 163 |
6 files changed, 685 insertions, 0 deletions
diff --git a/libkscreensaver/Makefile.am b/libkscreensaver/Makefile.am new file mode 100644 index 000000000..b0cff55ab --- /dev/null +++ b/libkscreensaver/Makefile.am @@ -0,0 +1,18 @@ +lib_LTLIBRARIES = libkscreensaver.la +libkscreensaver_la_SOURCES = main.cpp kscreensaver.cpp +libkscreensaver_la_LIBADD = $(LIB_KIO) +if undefined_symbols_allowed +libkscreensaver_la_LDFLAGS = $(all_libraries) $(KDE_RPATH) -version-info 6:0:2 +else +libkscreensaver_la_LDFLAGS = $(all_libraries) -static +endif + +include_HEADERS = kscreensaver.h kscreensaver_vroot.h + +INCLUDES = $(all_includes) +METASOURCES = AUTO + +messages: + $(XGETTEXT) *.cpp *.h -o $(podir)/libkscreensaver.pot + +include $(top_srcdir)/admin/Doxyfile.am diff --git a/libkscreensaver/configure.in.in b/libkscreensaver/configure.in.in new file mode 100644 index 000000000..1777b1e98 --- /dev/null +++ b/libkscreensaver/configure.in.in @@ -0,0 +1,5 @@ +case $host in + *cygwin*) undefined_symbols_in_shared_libs_allowed=no;; + *) undefined_symbols_in_shared_libs_allowed=yes;; +esac +AM_CONDITIONAL(undefined_symbols_allowed, test "$undefined_symbols_in_shared_libs_allowed" = yes) diff --git a/libkscreensaver/kscreensaver.cpp b/libkscreensaver/kscreensaver.cpp new file mode 100644 index 000000000..f56b31dc9 --- /dev/null +++ b/libkscreensaver/kscreensaver.cpp @@ -0,0 +1,229 @@ +/* This file is part of the KDE libraries + + Copyright (c) 2001 Martin R. Jones <mjones@kde.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include <qpainter.h> +#include <qtimer.h> +#include <kapplication.h> +#include "kscreensaver.h" +#ifdef Q_WS_X11 +#include <X11/Xlib.h> +#else +typedef WId Window; +#endif + +#undef KeyPress +#undef KeyRelease + +//----------------------------------------------------------------------------- + +class KScreenSaverPrivate +{ +public: + QWidget *owner; +}; + +KScreenSaver::KScreenSaver( WId id ) : QWidget() +{ + Window root; + int ai; + unsigned int au; + unsigned int w = 0; + unsigned int h = 0; + + d = new KScreenSaverPrivate; + d->owner = find( id ); + if ( d->owner ) + installEventFilter( this ); + + if ( id ) + { +#ifdef Q_WS_X11 //FIXME + XGetGeometry(qt_xdisplay(), (Drawable)id, &root, &ai, &ai, + &w, &h, &au, &au); +#endif + + create( id, false, true ); + } + + if ( w == 0 ) w = 600; + if ( h == 0 ) h = 420; + resize( w, h ); + KApplication::sendPostedEvents(); + show(); +} + +KScreenSaver::~KScreenSaver() +{ + destroy( false, false ); + delete d; +} + +void KScreenSaver::embed( QWidget *w ) +{ + KApplication::sendPostedEvents(); +#ifdef Q_WS_X11 //FIXME + XReparentWindow(qt_xdisplay(), w->winId(), winId(), 0, 0); +#endif + w->setGeometry( 0, 0, width(), height() ); + KApplication::sendPostedEvents(); +} + +bool KScreenSaver::eventFilter( QObject *o, QEvent *e ) +{ + // make sure events get to the original window owner + if ( d->owner && o == this ) { + QApplication::sendEvent( d->owner, e ); + return false; + } + + return QWidget::eventFilter( o, e ); +} + +//============================================================================ + +class KBlankEffectPrivate +{ +public: + KBlankEffect::BlankEffect currentEffect; + int effectProgress; + QTimer *timer; + QWidget *widget; +}; + +KBlankEffect::BlankEffect KBlankEffect::effects[] = { + &KBlankEffect::blankNormal, + &KBlankEffect::blankSweepRight, + &KBlankEffect::blankSweepDown, + &KBlankEffect::blankBlocks +}; + +KBlankEffect::KBlankEffect( QObject *parent ) : QObject( parent ) +{ + d = new KBlankEffectPrivate; + d->currentEffect = &KBlankEffect::blankNormal; + d->effectProgress = 0; + d->timer = new QTimer( this ); + connect( d->timer, SIGNAL(timeout()), this, SLOT(timeout()) ); +} + + +KBlankEffect::~KBlankEffect() +{ + delete d; +} + +void KBlankEffect::finished() +{ + d->timer->stop(); + d->effectProgress = 0; + emit doneBlank(); +} + + +void KBlankEffect::blank( QWidget *w, Effect effect ) +{ + if ( !w ) { + emit doneBlank(); + return; + } + + if ( effect == Random ) + effect = (Effect)(kapp->random() % MaximumEffects); + + d->effectProgress = 0; + d->widget = w; + d->currentEffect = effects[ (int)effect ]; + d->timer->start( 10 ); +} + +void KBlankEffect::timeout() +{ + (this->*d->currentEffect)(); +} + +void KBlankEffect::blankNormal() +{ + QPainter p( d->widget ); + p.fillRect( 0, 0, d->widget->width(), d->widget->height(), black ); + finished(); +} + + +void KBlankEffect::blankSweepRight() +{ + QPainter p( d->widget ); + p.fillRect( d->effectProgress, 0, 50, d->widget->height(), black ); + kapp->flushX(); + d->effectProgress += 50; + if ( d->effectProgress >= d->widget->width() ) + finished(); +} + + +void KBlankEffect::blankSweepDown() +{ + QPainter p( d->widget ); + p.fillRect( 0, d->effectProgress, d->widget->width(), 50, black ); + kapp->flushX(); + d->effectProgress += 50; + if ( d->effectProgress >= d->widget->height() ) + finished(); +} + + +void KBlankEffect::blankBlocks() +{ + static int *block = 0; + + int bx = (d->widget->width()+63)/64; + int by = (d->widget->height()+63)/64; + + if ( !d->effectProgress ) { + block = new int [ bx*by ]; + + for ( int i = 0; i < bx*by; i++ ) + block[i] = i; + for ( int i = 0; i < bx*by; i++ ) { + int swap = kapp->random()%(bx*by); + int tmp = block[i]; + block[i] = block[swap]; + block[swap] = tmp; + } + } + + QPainter p( d->widget ); + + // erase a couple of blocks at a time, otherwise it looks too slow + for ( int i = 0; i < 2 && d->effectProgress < bx*by; i++ ) { + int x = block[d->effectProgress]%bx; + int y = block[d->effectProgress]/bx; + p.fillRect( x*64, y*64, 64, 64, black ); + d->effectProgress++; + } + + kapp->flushX(); + + if ( d->effectProgress >= bx*by ) { + delete[] block; + finished(); + } +} + +#include "kscreensaver.moc" diff --git a/libkscreensaver/kscreensaver.h b/libkscreensaver/kscreensaver.h new file mode 100644 index 000000000..3150300f4 --- /dev/null +++ b/libkscreensaver/kscreensaver.h @@ -0,0 +1,138 @@ +/* This file is part of the KDE libraries + + Copyright (c) 2001 Martin R. Jones <mjones@kde.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef KSCREENSAVER_H +#define KSCREENSAVER_H + +#include <qwidget.h> + +#include <kdelibs_export.h> + +class QTimer; +class KScreenSaverPrivate; +class KBlankEffectPrivate; + +/** +* Provides a QWidget for a screensaver to draw into. +* +* You should derive from this widget and implement your screensaver's +* functionality. To use libkss, provide the following constants and +* functions: +* +* extern "C" +* { +* const char *kss_applicationName = "yourappname"; +* const char *kss_description = I18N_NOOP( "Your screensaver" ); +* const char *kss_version = "1.0"; +* +* KScreenSaver *kss_create( WId d ) +* { +* // return your KScreenSaver derived screensaver +* } +* +* QDialog *kss_setup() +* { +* // return your modal setup dialog +* } +* } +* +* @short Provides a QWidget for a screensaver to draw into. +* @author Martin R. Jones <mjones@kde.org> +*/ +class KDE_EXPORT KScreenSaver : public QWidget +{ + Q_OBJECT +public: + /** + * @param id The winId() of the widget to draw the screensaver into. + */ + KScreenSaver( WId id=0 ); + ~KScreenSaver(); + +protected: + /** + * You cannot create a new widget with this widget as parent, since this + * widget may not be owned by your application. In order to create + * widgets with a KScreenSaver as parent, create the widget with no parent, + * call embed(), and then show() the widget. + * + * @param widget The widget to embed in the screensaver widget. + */ + void embed( QWidget *widget ); + + bool eventFilter( QObject *o, QEvent * ); + +private: + KScreenSaverPrivate *d; +}; + + +/** +* +* Blanks a widget using various effects. +* +* @short Blanks a widget using various effects. +* @author Martin R. Jones <mjones@kde.org> +*/ +class KBlankEffect : public QObject +{ + Q_OBJECT +public: + KBlankEffect( QObject *parent=0 ); + ~KBlankEffect(); + + enum Effect { Random=-1, Blank=0, SweepRight, SweepDown, Blocks, + MaximumEffects }; + + /** + * Blank a widget using the specified effect. + * Some blanking effects take some time, so you should connect to + * doneBlank() to know when the blanking is complete. + * + * @param w The widget to blank. + * @param effect The type of effect to use. + */ + void blank( QWidget *w, Effect effect=Random ); + + typedef void (KBlankEffect::*BlankEffect)(); + +signals: + /** + * emitted when a blanking effect has completed. + */ + void doneBlank(); + +protected slots: + void timeout(); + +protected: + void finished(); + + void blankNormal(); + void blankSweepRight(); + void blankSweepDown(); + void blankBlocks(); + +protected: + static BlankEffect effects[]; + KBlankEffectPrivate *d; +}; +#endif + diff --git a/libkscreensaver/kscreensaver_vroot.h b/libkscreensaver/kscreensaver_vroot.h new file mode 100644 index 000000000..62ac73889 --- /dev/null +++ b/libkscreensaver/kscreensaver_vroot.h @@ -0,0 +1,132 @@ +/*****************************************************************************/ +/** Copyright 1991 by Andreas Stolcke **/ +/** Copyright 1990 by Solbourne Computer Inc. **/ +/** Longmont, Colorado **/ +/** **/ +/** All Rights Reserved **/ +/** **/ +/** Permission to use, copy, modify, and distribute this software and **/ +/** its documentation for any purpose and without fee is hereby **/ +/** granted, provided that the above copyright notice appear in all **/ +/** copies and that both that copyright notice and this permis- **/ +/** sion notice appear in supporting documentation, and that the **/ +/** name of Solbourne not be used in advertising **/ +/** in publicity pertaining to distribution of the software without **/ +/** specific, written prior permission. **/ +/** **/ +/** ANDREAS STOLCKE AND SOLBOURNE COMPUTER INC. DISCLAIMS ALL WARRANTIES **/ +/** WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF **/ +/** MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL ANDREAS STOLCKE **/ +/** OR SOLBOURNE BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL **/ +/** DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA **/ +/** OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER **/ +/** TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE **/ +/** OR PERFORMANCE OF THIS SOFTWARE. **/ +/*****************************************************************************/ +/* + * vroot.h -- Virtual Root Window handling header file + * + * This header file redefines the X11 macros RootWindow and DefaultRootWindow, + * making them look for a virtual root window as provided by certain `virtual' + * window managers like swm and tvtwm. If none is found, the ordinary root + * window is returned, thus retaining backward compatibility with standard + * window managers. + * The function implementing the virtual root lookup remembers the result of + * its last invocation to avoid overhead in the case of repeated calls + * on the same display and screen arguments. + * The lookup code itself is taken from Tom LaStrange's ssetroot program. + * + * Most simple root window changing X programs can be converted to using + * virtual roots by just including + * + * #include <X11/vroot.h> + * + * after all the X11 header files. It has been tested on such popular + * X clients as xphoon, xfroot, xloadimage, and xaqua. + * It also works with the core clients xprop, xwininfo, xwd, and editres + * (and is necessary to get those clients working under tvtwm). + * It does NOT work with xsetroot; get the xsetroot replacement included in + * the tvtwm distribution instead. + * + * Andreas Stolcke <stolcke@ICSI.Berkeley.EDU>, 9/7/90 + * - replaced all NULL's with properly cast 0's, 5/6/91 + * - free children list (suggested by Mark Martin <mmm@cetia.fr>), 5/16/91 + * - include X11/Xlib.h and support RootWindowOfScreen, too 9/17/91 + */ + +#ifndef _VROOT_H_ +#define _VROOT_H_ + +#if !defined(lint) && !defined(SABER) +static const char vroot_rcsid[] = "#Id: vroot.h,v 1.4 1991/09/30 19:23:16 stolcke Exp stolcke #"; +#endif + +#include <qwidget.h> +#ifdef Q_WS_X11 +#include <X11/X.h> +#include <X11/Xatom.h> +#include <X11/Xlib.h> + +static Window +#if defined(__STDC__) || defined(__cplusplus) /* ANSIfication added by jwz, to avoid superfluous warnings. */ +VirtualRootWindowOfScreen(Screen *screen) +#else /* !__STDC__ */ +VirtualRootWindowOfScreen(screen) Screen *screen; +#endif /* !__STDC__ */ +{ + static Screen *save_screen = (Screen *)0; + static Window root = (Window)0; + + if (screen != save_screen) { + Display *dpy = DisplayOfScreen(screen); + Atom __SWM_VROOT = None; + uint i; + Window rootReturn, parentReturn, *children; + unsigned int numChildren; + + root = RootWindowOfScreen(screen); + + /* go look for a virtual root */ + __SWM_VROOT = XInternAtom(dpy, "__SWM_VROOT", False); + if (XQueryTree(dpy, root, &rootReturn, &parentReturn, + &children, &numChildren)) { + for (i = 0; i < numChildren; i++) { + Atom actual_type; + int actual_format; + unsigned long nitems, bytesafter; + unsigned char *newRoot = 0; + + if (XGetWindowProperty(dpy, children[i], + __SWM_VROOT, 0, 1, False, XA_WINDOW, + &actual_type, &actual_format, + &nitems, &bytesafter, + &newRoot) == Success + && newRoot) + { + void *tmpRoot = (void *) newRoot; + root = *(Window*) tmpRoot; + XFree( (char*) newRoot ); + break; + } + } + if (children) + XFree((char *)children); + } + + save_screen = screen; + } + + return root; +} + +#undef RootWindowOfScreen +#define RootWindowOfScreen(s) VirtualRootWindowOfScreen(s) + +#undef RootWindow +#define RootWindow(dpy,screen) VirtualRootWindowOfScreen(ScreenOfDisplay(dpy,screen)) + +#undef DefaultRootWindow +#define DefaultRootWindow(dpy) VirtualRootWindowOfScreen(DefaultScreenOfDisplay(dpy)) +#endif + +#endif /* _VROOT_H_ */ diff --git a/libkscreensaver/main.cpp b/libkscreensaver/main.cpp new file mode 100644 index 000000000..caa9278ff --- /dev/null +++ b/libkscreensaver/main.cpp @@ -0,0 +1,163 @@ +/* This file is part of the KDE libraries + + Copyright (c) 2001 Martin R. Jones <mjones@kde.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + 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., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ +#include <config.h> + +#include <stdlib.h> +#include <stdio.h> +#include <signal.h> + +#include <qdialog.h> +#include <klocale.h> +#include <kglobal.h> +#include <kdebug.h> +#include <kcmdlineargs.h> +#include <kapplication.h> +#include <kcrash.h> + +#include "kscreensaver.h" +#include "kscreensaver_vroot.h" + +extern "C" +{ + extern const char *kss_applicationName; + extern const char *kss_description; + extern const char *kss_version; + KScreenSaver *kss_create( WId d ); + QDialog *kss_setup(); +} + +static const KCmdLineOptions options[] = +{ + { "setup", I18N_NOOP("Setup screen saver"), 0 }, + { "window-id wid", I18N_NOOP("Run in the specified XWindow"), 0 }, + { "root", I18N_NOOP("Run in the root XWindow"), 0 }, + { "demo", I18N_NOOP("Start screen saver in demo mode"), "default"}, + KCmdLineLastOption +}; + +static void crashHandler( int ) +{ +#ifdef SIGABRT + signal (SIGABRT, SIG_DFL); +#endif + abort(); +} + +//---------------------------------------------------------------------------- + +class DemoWindow : public QWidget +{ +public: + DemoWindow() : QWidget() + { + setFixedSize(600, 420); + } + +protected: + virtual void keyPressEvent(QKeyEvent *e) + { + if (e->ascii() == 'q') + { + kapp->quit(); + } + } + + virtual void closeEvent( QCloseEvent * ) + { + kapp->quit(); + } +}; + + +//---------------------------------------------------------------------------- +#if defined(Q_WS_QWS) || defined(Q_WS_MACX) +typedef WId Window; +#endif + +KDE_EXPORT int main(int argc, char *argv[]) +{ + KLocale::setMainCatalogue("libkscreensaver"); + KCmdLineArgs::init(argc, argv, kss_applicationName, kss_description, kss_version); + + KCmdLineArgs::addCmdLineOptions(options); + + KApplication app; + + KCrash::setCrashHandler( crashHandler ); + KGlobal::locale()->insertCatalogue("klock"); + KGlobal::locale()->insertCatalogue("kscreensaver"); + + DemoWindow *demoWidget = 0; + Window saveWin = 0; + KScreenSaver *target; + + KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); + + if (args->isSet("setup")) + { + QDialog *dlg = kss_setup(); + args->clear(); + dlg->exec(); + delete dlg; + exit(0); + } + + if (args->isSet("window-id")) + { + saveWin = atol(args->getOption("window-id")); + } + +#ifdef Q_WS_X11 //FIXME + if (args->isSet("root")) + { + saveWin = RootWindow(qt_xdisplay(), qt_xscreen()); + } +#endif + + if (args->isSet("demo")) + { + saveWin = 0; + } + + if (saveWin == 0) + { + demoWidget = new DemoWindow(); + demoWidget->setBackgroundMode(QWidget::NoBackground); + saveWin = demoWidget->winId(); + app.setMainWidget(demoWidget); + app.processEvents(); + } + + target = kss_create( saveWin ); + + if ( demoWidget ) + { + demoWidget->setFixedSize( 600, 420 ); + demoWidget->show(); + } + args->clear(); + app.exec(); + + delete target; + delete demoWidget; + + return 0; +} + |