summaryrefslogtreecommitdiffstats
path: root/libkscreensaver
diff options
context:
space:
mode:
Diffstat (limited to 'libkscreensaver')
-rw-r--r--libkscreensaver/Makefile.am18
-rw-r--r--libkscreensaver/configure.in.in5
-rw-r--r--libkscreensaver/kscreensaver.cpp229
-rw-r--r--libkscreensaver/kscreensaver.h138
-rw-r--r--libkscreensaver/kscreensaver_vroot.h132
-rw-r--r--libkscreensaver/main.cpp163
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;
+}
+