kde-workspace/kscreensaver/libkscreensaver/main.cpp
2014-11-13 19:30:51 +02:00

238 lines
5.6 KiB
C++

/* 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 "kscreensaver.h"
#include "kscreensaver_vroot.h"
#include <config-workspace.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <QDialog>
#include <QEvent>
#include <QKeyEvent>
#include <QSocketNotifier>
#include <klocale.h>
#include <kglobal.h>
#include <kdebug.h>
#include <kcmdlineargs.h>
#include <kicon.h>
#include <kapplication.h>
#include <kcrash.h>
#include <kaboutdata.h>
#ifdef Q_WS_X11
#include <QtGui/QX11Info>
#endif
static void crashHandler( int )
{
#ifdef SIGABRT
signal (SIGABRT, SIG_DFL);
#endif
abort();
}
extern "C" {
static int termPipe[2];
static void termHandler( int )
{
write( termPipe[1], "", 1 );
}
}
//----------------------------------------------------------------------------
class DemoWindow : public QWidget
{
public:
DemoWindow() : QWidget()
{
setFixedSize(600, 420);
}
protected:
virtual bool eventFilter( QObject *, QEvent *e )
{
if (e->type() == QEvent::KeyPress) {
keyPressEvent( (QKeyEvent *)e );
return true;
} else if( e->type() == QEvent::Close ) {
// In demo mode, screensaver's QWidget does create()
// with winId of the DemoWidget, which results in two QWidget's
// sharing the same winId and Qt delivering events only to one of them.
qApp->quit();
}
return false;
}
virtual void keyPressEvent(QKeyEvent *e)
{
if (e->text() == QLatin1String("q"))
{
qApp->quit();
}
}
virtual void closeEvent( QCloseEvent * )
{
qApp->quit();
}
};
//----------------------------------------------------------------------------
#if defined(Q_WS_QWS) || defined(Q_WS_MACX) || defined(Q_WS_WIN)
typedef WId Window;
#endif
#ifdef Q_WS_X11
extern "C" {
static int (*oldXErrorHandler)(Display *, XErrorEvent *);
static int xErrorHandler(Display *dpy, XErrorEvent *err)
{
if (getppid() == 1)
kFatal() << "Got X error after loss of parent process. Terminating.";
return oldXErrorHandler(dpy, err);
}
}
#endif
int kScreenSaverMain( int argc, char** argv, KScreenSaverInterface& screenSaverInterface )
{
KLocale::setMainCatalog("libkscreensaver");
KCmdLineArgs::init(argc, argv, screenSaverInterface.aboutData());
KCmdLineOptions options;
options.add("setup", ki18n("Setup screen saver"));
options.add("window-id wid", ki18n("Run in the specified XWindow"));
options.add("root", ki18n("Run in the root XWindow"));
options.add("demo", ki18n("Start screen saver in demo mode"), "default");
KCmdLineArgs::addCmdLineOptions(options);
KApplication app;
// Set a useful default icon.
app.setWindowIcon(KIcon("preferences-desktop-screensaver"));
// Disable session management so screensaver windows don't get restored on login (bug#314859)
app.disableSessionManagement();
if (!pipe(termPipe))
{
#ifndef Q_WS_WIN
struct sigaction sa;
sa.sa_handler = termHandler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sigaction(SIGTERM, &sa, 0);
#endif
QSocketNotifier *sn = new QSocketNotifier(termPipe[0], QSocketNotifier::Read, &app);
QObject::connect(sn, SIGNAL(activated(int)), &app, SLOT(quit()));
}
#ifdef Q_WS_X11
oldXErrorHandler = XSetErrorHandler(xErrorHandler);
#endif
KCrash::setCrashHandler( crashHandler );
KGlobal::locale()->insertCatalog("klock");
KGlobal::locale()->insertCatalog("kscreensaver");
DemoWindow *demoWidget = 0;
Window saveWin = 0;
KScreenSaver *target;
KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
if (args->isSet("setup"))
{
QDialog *dlg = screenSaverInterface.setup();
args->clear();
dlg->exec();
delete dlg;
return 0;
}
if (args->isSet("window-id"))
{
#ifdef Q_WS_WIN
saveWin = (HWND)(args->getOption("window-id").toULong());
#else
saveWin = args->getOption("window-id").toInt();
#endif
}
#ifdef Q_WS_X11 //FIXME
if (args->isSet("root"))
{
QX11Info inf;
saveWin = RootWindow(QX11Info::display(), inf.screen());
}
#endif
if (args->isSet("demo"))
{
saveWin = 0;
}
if (saveWin == 0)
{
demoWidget = new DemoWindow();
demoWidget->setAttribute(Qt::WA_NoSystemBackground);
demoWidget->setAttribute(Qt::WA_PaintOnScreen);
demoWidget->show();
app.processEvents();
saveWin = demoWidget->winId();
}
target = screenSaverInterface.create( saveWin );
target->setAttribute(Qt::WA_PaintOnScreen);
target->show();
if (demoWidget)
{
target->installEventFilter( demoWidget );
}
args->clear();
app.exec();
delete target;
delete demoWidget;
return 0;
}