diff --git a/kcontrol/screensaver/CMakeLists.txt b/kcontrol/screensaver/CMakeLists.txt index e4dcc3a..c08c235 100644 --- a/kcontrol/screensaver/CMakeLists.txt +++ b/kcontrol/screensaver/CMakeLists.txt @@ -12,7 +12,7 @@ set(kcm_screensaver_PART_SRCS saverconfig.cpp kswidget.cpp) -set(kscreensaver_xml ${KDEBASE_WORKSPACE_SOURCE_DIR}/krunner/dbus/org.kde.screensaver.xml) +set(kscreensaver_xml ${KDEBASE_WORKSPACE_SOURCE_DIR}/ksmserver/screenlocker/dbus/org.kde.screensaver.xml) QT4_ADD_DBUS_INTERFACE( kcm_screensaver_PART_SRCS ${kscreensaver_xml} kscreensaver_interface ) diff --git a/kcontrol/screensaver/screensaver.ui b/kcontrol/screensaver/screensaver.ui index 0ad5cd8..6524e27 100644 --- a/kcontrol/screensaver/screensaver.ui +++ b/kcontrol/screensaver/screensaver.ui @@ -7,233 +7,283 @@ 0 0 - 745 - 579 + 801 + 733 - - - - - - - - - - Qt::Vertical - - - - 20 - 145 - - - - - - - - - 0 - 0 - + + + + + + 0 + 0 + + + + + + + + + Automatically start the screen saver after a period of inactivity. - - - 0 - 0 - + + Start a&utomatically after: - - - - - - - Qt::Vertical - - - - 20 - 145 - - - - - - - - - - Settings - - - - - - Automatically start the screen saver after a period of inactivity. - - - Start a&utomatically after: - - - - - - - - - - Qt::Horizontal - - - - 243 - 20 - - - - - - - - Prevent potential unauthorized use by requiring a password to stop the screen saver. - - - &Require password after: - - - - - - - The amount of time, after the screen saver has started, to ask for the unlock password. - - - - - - - Qt::Horizontal - - - - 243 - 20 - - - - - - - - Add widgets to your screensaver. - - - Allow widgets on screen saver - - - - - - - + + + + + Qt::Horizontal - - QSizePolicy::Fixed - - 13 + 243 20 - - + + + + Prevent potential unauthorized use by requiring a password to stop the screen saver. + - Configure Widgets... + &Require password after: - - + + + + The amount of time, after the screen saver has started, to ask for the unlock password. + + + + + Qt::Horizontal - 309 - 19 + 243 + 20 - - - - - - - Screen Saver - - - - - Qt::Horizontal + + + &Screen locker type: - - - 40 - 20 - + + mSimpleLockerRadio - + - - - false + + + S&imple locker - - Show a full screen preview of the screen saver. + + true + + + + + + + + &Desktop Widgets + + + + + + + false + + + Configure... + + + + + + + - &Test + S&creen saver - - + + false - - Configure the screen saver's options, if any. - - - &Setup... - - - - - - - Select the screen saver to use. + + + 0 + 1 + - - - 1 - - + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 16 + 20 + + + + + + + + Select the screen saver to use. + + + + 1 + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 145 + + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 5 + 20 + + + + + + + + false + + + Show a full screen preview of the screen saver. + + + &Test + + + + + + + false + + + Configure the screen saver's options, if any. + + + &Setup... + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 5 + 20 + + + + + + + + + + Qt::Vertical + + + + 20 + 145 + + + + + + + @@ -253,6 +303,50 @@
kpushbutton.h
+ + mEnabledCheckBox + mWaitEdit + mLockCheckBox + mWaitLockEdit + mSimpleLockerRadio + mPlasmaWidgetsRadio + mPlasmaSetup + mScreenSaverRadio + mSaverListView + - + + + mPlasmaWidgetsRadio + toggled(bool) + mPlasmaSetup + setEnabled(bool) + + + 175 + 147 + + + 283 + 147 + + + + + mScreenSaverRadio + toggled(bool) + mScreenSaverSettings + setEnabled(bool) + + + 163 + 176 + + + 485 + 512 + + + + diff --git a/kcontrol/screensaver/scrnsave.cpp b/kcontrol/screensaver/scrnsave.cpp index c0507d4..0125620 100644 --- a/kcontrol/screensaver/scrnsave.cpp +++ b/kcontrol/screensaver/scrnsave.cpp @@ -167,8 +167,8 @@ KScreenSaver::KScreenSaver(QWidget *parent, const QVariantList&) connect(mWaitLockEdit, SIGNAL(valueChanged(int)), this, SLOT(slotLockTimeoutChanged(int))); - mPlasmaCheckBox->setChecked(mPlasmaEnabled); - connect(mPlasmaCheckBox, SIGNAL(toggled(bool)), this, SLOT(slotEnablePlasma(bool))); + connect(mPlasmaWidgetsRadio, SIGNAL(toggled(bool)), this, SLOT(slotEnablePlasma(bool))); + connect(mScreenSaverRadio, SIGNAL(toggled(bool)), this, SLOT(slotEnableLegacyScreenSaver(bool))); mPlasmaSetup->setEnabled(mPlasmaEnabled); connect(mPlasmaSetup, SIGNAL(clicked()), this, SLOT(slotPlasmaSetup())); @@ -297,7 +297,18 @@ void KScreenSaver::readSettings() mLockTimeout = config.readEntry("LockGrace", 60000); mLock = config.readEntry("Lock", false); mSaver = config.readEntry("Saver"); - mPlasmaEnabled = config.readEntry("PlasmaEnabled", false); + + bool legacyScreenSaver = config.readEntry("LegacySaverEnabled", false); + mScreenSaverRadio->setChecked(legacyScreenSaver); + if (!legacyScreenSaver) { + mPlasmaEnabled = config.readEntry("PlasmaEnabled", false); + mPlasmaWidgetsRadio->setChecked(mPlasmaEnabled); + } else { + mPlasmaEnabled = false; + } + if (!legacyScreenSaver && !mPlasmaEnabled) { + mSimpleLockerRadio->setChecked(true); + } if (mTimeout < 60) mTimeout = 60; if (mLockTimeout < 0) mLockTimeout = 0; @@ -339,7 +350,7 @@ void KScreenSaver::defaults() slotLockTimeoutChanged( 60 ); slotLock( false ); mEnabledCheckBox->setChecked(false); - mPlasmaCheckBox->setChecked(false); + mSimpleLockerRadio->setChecked(true); mPlasmaSetup->setEnabled(false); updateValues(); @@ -361,6 +372,7 @@ void KScreenSaver::save() config.writeEntry("LockGrace", mLockTimeout); config.writeEntry("Lock", mLock); config.writeEntry("PlasmaEnabled", mPlasmaEnabled); + config.writeEntry("LegacySaverEnabled", mScreenSaverRadio->isChecked()); if ( !mSaver.isEmpty() ) config.writeEntry("Saver", mSaver); @@ -515,7 +527,7 @@ void KScreenSaver::slotPreviewExited() palette.setColor(mMonitor->backgroundRole(), Qt::black); mMonitor->setPalette(palette); mMonitor->setGeometry(mMonitorPreview->previewRect()); - mMonitor->show(); + mMonitor->setVisible(mScreenSaverRadio->isChecked()); // So that hacks can XSelectInput ButtonPressMask XSelectInput(QX11Info::display(), mMonitor->winId(), widgetEventMask ); @@ -557,6 +569,15 @@ void KScreenSaver::slotEnablePlasma(bool enable) emit changed(true); } +void KScreenSaver::slotEnableLegacyScreenSaver(bool enable) +{ + if (mMonitor) { + mMonitor->setVisible(enable); + } + mChanged = true; + emit changed(true); +} + void KScreenSaver::slotPlasmaSetup() { org::kde::screensaver kscreensaver("org.kde.screensaver", "/ScreenSaver", QDBusConnection::sessionBus()); diff --git a/kcontrol/screensaver/scrnsave.h b/kcontrol/screensaver/scrnsave.h index 7c8deba..202e14e 100644 --- a/kcontrol/screensaver/scrnsave.h +++ b/kcontrol/screensaver/scrnsave.h @@ -81,6 +81,7 @@ protected Q_SLOTS: void slotPreviewExited(); void findSavers(); void slotEnablePlasma(bool enable); + void slotEnableLegacyScreenSaver(bool enable); void slotPlasmaSetup(); protected: diff --git a/krunner/CMakeLists.txt b/krunner/CMakeLists.txt index 21eac6f..aa1e915 100644 --- a/krunner/CMakeLists.txt +++ b/krunner/CMakeLists.txt @@ -10,14 +10,8 @@ include_directories(${KDEBASE_WORKSPACE_SOURCE_DIR}/libs/ksysguard ${KDEBASE_WORKSPACE_SOURCE_DIR}/krunner/screensaver ${KDEBASE_WORKSPACE_SOURCE_DIR}/libs/kephal) -macro_bool_to_01(X11_Xscreensaver_FOUND HAVE_XSCREENSAVER) -macro_log_feature(HAVE_XSCREENSAVER "libxss" "XScreenSaver Library" "http://www.x.org/" FALSE "" "Needed to enable screensaver status check") -configure_file(config-xautolock.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-xautolock.h) - -set(krunner_KCFG_SRCS kcfg/krunnersettings.kcfgc kcfg/kscreensaversettings.kcfgc kcfg/klaunchsettings.kcfgc) +set(krunner_KCFG_SRCS kcfg/krunnersettings.kcfgc kcfg/klaunchsettings.kcfgc) set(krunner_dbusAppXML dbus/org.kde.krunner.App.xml) -set(screensaver_dbusXML dbus/org.freedesktop.ScreenSaver.xml) -set(kscreensaver_dbusXML dbus/org.kde.screensaver.xml) set(default_interface_SRCS @@ -62,14 +56,8 @@ if(NOT WIN32) set(krunner_SRCS ${krunner_SRCS} ksystemactivitydialog.cpp - startupid.cpp - screensaver/saverengine.cpp - screensaver/xautolock.cpp - screensaver/xautolock_diy.c - screensaver/xautolock_engine.c) - -qt4_add_dbus_adaptor(krunner_SRCS ${screensaver_dbusXML} saverengine.h SaverEngine) -qt4_add_dbus_adaptor(krunner_SRCS ${kscreensaver_dbusXML} saverengine.h SaverEngine kscreensaveradaptor KScreenSaverAdaptor) + startupid.cpp) + endif(NOT WIN32) kde4_add_kdeinit_executable(krunner ${krunner_SRCS}) @@ -88,14 +76,9 @@ if(X11_Xcursor_FOUND) target_link_libraries(kdeinit_krunner ${X11_Xcursor_LIB}) endif(X11_Xcursor_FOUND) -if(NOT WIN32) -add_subdirectory( lock ) -endif(NOT WIN32) - install(TARGETS kdeinit_krunner ${INSTALL_TARGETS_DEFAULT_ARGS} ) install(TARGETS krunner ${INSTALL_TARGETS_DEFAULT_ARGS} ) install(FILES krunner.desktop DESTINATION ${AUTOSTART_INSTALL_DIR}) -install(FILES kcfg/kscreensaversettings.kcfg DESTINATION ${KCFG_INSTALL_DIR}) install(FILES kcfg/klaunch.kcfg DESTINATION ${KCFG_INSTALL_DIR}) -install(FILES ${krunner_dbusAppXML} ${screensaver_dbusXML} ${kscreensaver_dbusXML} DESTINATION ${DBUS_INTERFACES_INSTALL_DIR} ) +install(FILES ${krunner_dbusAppXML} DESTINATION ${DBUS_INTERFACES_INSTALL_DIR} ) diff --git a/krunner/dbus/org.freedesktop.ScreenSaver.xml b/krunner/dbus/org.freedesktop.ScreenSaver.xml deleted file mode 100644 index 5efd943..0000000 --- a/krunner/dbus/org.freedesktop.ScreenSaver.xml +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/krunner/dbus/org.kde.screensaver.xml b/krunner/dbus/org.kde.screensaver.xml deleted file mode 100644 index e700b88..0000000 --- a/krunner/dbus/org.kde.screensaver.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/krunner/kcfg/kscreensaversettings.kcfg b/krunner/kcfg/kscreensaversettings.kcfg deleted file mode 100644 index c8f76f3..0000000 --- a/krunner/kcfg/kscreensaversettings.kcfg +++ /dev/null @@ -1,92 +0,0 @@ - - - kglobalsettings.h - - - - false - - Enables the screen saver. - - - 300 - - Sets the seconds after which the screen saver is started. - - - true - - Usually the screen saver is suspended when display power saving kicks in, - as nothing can be seen on the screen anyway, obviously. However, some screen savers - actually perform useful computations, so it is not desirable to suspend them. - - - 0 - - - - - 0 - - - - - 0 - - - - - 0 - - - - - false - - - - - 5000 - - - - - false - - - - - 600 - - - - - 19 - - - - - - - - - - - - - - - - - - - - false - - - - - diff --git a/krunner/kcfg/kscreensaversettings.kcfgc b/krunner/kcfg/kscreensaversettings.kcfgc deleted file mode 100644 index af9133d..0000000 --- a/krunner/kcfg/kscreensaversettings.kcfgc +++ /dev/null @@ -1,4 +0,0 @@ -File=kscreensaversettings.kcfg -ClassName=KScreenSaverSettings -Singleton=true -Mutators=true diff --git a/krunner/krunnerapp.cpp b/krunner/krunnerapp.cpp index eea6220..2eafa9f 100644 --- a/krunner/krunnerapp.cpp +++ b/krunner/krunnerapp.cpp @@ -146,17 +146,6 @@ void KRunnerApp::initialize() connect(a, SIGNAL(triggered(bool)), SLOT(switchUser())); } - //FIXME: lock/logout should be in the session management runner which also provides similar - // functions -#ifdef Q_WS_X11 - if (KAuthorized::authorize(QLatin1String("lock_screen"))) { - a = m_actionCollection->addAction(QLatin1String("Lock Session")); - a->setText(i18n("Lock Session")); - a->setGlobalShortcut(KShortcut(Qt::ALT+Qt::CTRL+Qt::Key_L)); - connect(a, SIGNAL(triggered(bool)), &m_saver, SLOT(Lock())); - } -#endif - //Setup the interface after we have set up the actions //TODO: if !KAuthorized::authorize("run_comand") (and !"switch_user" i suppose?) // then we probably don't need the interface at all. would be another place diff --git a/krunner/krunnerapp.h b/krunner/krunnerapp.h index 040198d..3ac1196 100644 --- a/krunner/krunnerapp.h +++ b/krunner/krunnerapp.h @@ -20,9 +20,6 @@ #define KRUNNERAPP_H #include -#ifdef Q_WS_X11 -#include "saverengine.h" -#endif class KActionCollection; class KDialog; @@ -49,9 +46,6 @@ public: KActionCollection* actionCollection(); virtual int newInstance(); -#ifdef Q_WS_X11 - SaverEngine& screensaver() { return m_saver; } -#endif public Q_SLOTS: // DBUS interface. if you change these methods, you MUST run: @@ -102,9 +96,6 @@ private: Plasma::RunnerManager *m_runnerManager; KActionCollection *m_actionCollection; -#ifdef Q_WS_X11 - SaverEngine m_saver; -#endif KRunnerDialog *m_interface; KSystemActivityDialog *m_tasks; StartupId *m_startupId; diff --git a/krunner/lock/CMakeLists.txt b/krunner/lock/CMakeLists.txt deleted file mode 100644 index cf9a67e..0000000 --- a/krunner/lock/CMakeLists.txt +++ /dev/null @@ -1,62 +0,0 @@ -include_directories( ${KDEBASE_WORKSPACE_SOURCE_DIR}/krunner ${KDEBASE_WORKSPACE_SOURCE_DIR}/kcheckpass ${KDEBASE_WORKSPACE_SOURCE_DIR}/libs/kdm ) - -########### next target ############### - -check_library_exists(Xxf86misc XF86MiscSetGrabKeysState "" HAVE_XF86MISCSETGRABKEYSSTATE) -if(WITH_OpenGL) -check_library_exists(GL glXChooseVisual "" HAVE_GLXCHOOSEVISUAL) -endif(WITH_OpenGL) - -configure_file(config-krunner-lock.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-krunner-lock.h) - -set(kscreenlocker_SRCS - lockprocess.cc - lockdlg.cc - autologout.cc - main.cc ) - -set(plasmaapp_dbusXML ../../plasma/screensaver/shell/org.kde.plasma-overlay.App.xml) -qt4_add_dbus_interface(kscreenlocker_SRCS ${plasmaapp_dbusXML} plasmaapp_interface) - -set(lockprocess_dbusXML org.kde.screenlocker.LockProcess.xml) -qt4_generate_dbus_interface(lockprocess.h ${lockprocess_dbusXML} OPTIONS -m) -qt4_add_dbus_adaptor(kscreenlocker_SRCS ${CMAKE_CURRENT_BINARY_DIR}/${lockprocess_dbusXML} lockprocess.h LockProcess) - -set(ksmserver_xml ${KDEBASE_WORKSPACE_SOURCE_DIR}/ksmserver/org.kde.KSMServerInterface.xml) -QT4_ADD_DBUS_INTERFACE(kscreenlocker_SRCS ${ksmserver_xml} ksmserver_interface) -set(kscreensaver_xml ${KDEBASE_WORKSPACE_SOURCE_DIR}/krunner/dbus/org.kde.screensaver.xml) -QT4_ADD_DBUS_INTERFACE(kscreenlocker_SRCS ${kscreensaver_xml} kscreensaver_interface) - - - -kde4_add_kcfg_files(kscreenlocker_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/../kcfg/kscreensaversettings.kcfgc) - - - -kde4_add_executable(kscreenlocker ${kscreenlocker_SRCS}) - -target_link_libraries(kscreenlocker kephal ${KDE4_KDEUI_LIBS} ${X11_LIBRARIES}) - -find_library(DL_LIBRARY dl) -if (DL_LIBRARY) - target_link_libraries(kscreenlocker ${DL_LIBRARY}) -endif(DL_LIBRARY) - -if (HAVE_XF86MISC) - target_link_libraries(kscreenlocker ${X11_Xxf86misc_LIB}) -endif (HAVE_XF86MISC) - -if(HAVE_GLXCHOOSEVISUAL) - target_link_libraries(kscreenlocker ${OPENGL_gl_LIBRARY}) -endif(HAVE_GLXCHOOSEVISUAL) - -install(TARGETS kscreenlocker DESTINATION ${LIBEXEC_INSTALL_DIR}) - -install_pam_service(kscreensaver) - - -########### install files ############### - - -install( FILES kscreenlocker.notifyrc DESTINATION ${DATA_INSTALL_DIR}/kscreenlocker ) - diff --git a/krunner/lock/autologout.cc b/krunner/lock/autologout.cc deleted file mode 100644 index c86e29a..0000000 --- a/krunner/lock/autologout.cc +++ /dev/null @@ -1,118 +0,0 @@ -//=========================================================================== -// -// This file is part of the KDE project -// -// Copyright 2004 Chris Howells - -#include "lockprocess.h" -#include "autologout.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define COUNTDOWN 30 - -AutoLogout::AutoLogout(LockProcess *parent) : QDialog(parent, Qt::X11BypassWindowManagerHint) -{ - QLabel *pixLabel = new QLabel( this ); - pixLabel->setObjectName( QLatin1String( "pixlabel" ) ); - pixLabel->setPixmap(DesktopIcon(QLatin1String( "application-exit" ))); - - QLabel *greetLabel = new QLabel(i18n("Automatic Log Out"), this); - QLabel *infoLabel = new QLabel(i18n("To prevent being logged out, resume using this session by moving the mouse or pressing a key."), this); - - mStatusLabel = new QLabel(QLatin1String( " " ), this); - mStatusLabel->setAlignment(Qt::AlignCenter); - - QLabel *mProgressLabel = new QLabel(i18n("Time Remaining:"), this); - mProgressRemaining = new QProgressBar(this); - mProgressRemaining->setTextVisible(false); - - frameLayout = new QGridLayout(this); - frameLayout->setSpacing(KDialog::spacingHint()); - frameLayout->setMargin(KDialog::marginHint() * 2); - frameLayout->addWidget(pixLabel, 0, 0, 3, 1, Qt::AlignCenter | Qt::AlignTop); - frameLayout->addWidget(greetLabel, 0, 1); - frameLayout->addWidget(mStatusLabel, 1, 1); - frameLayout->addWidget(infoLabel, 2, 1); - frameLayout->addWidget(mProgressLabel, 3, 1); - frameLayout->addWidget(mProgressRemaining, 4, 1); - - // get the time remaining in seconds for the status label - mRemaining = COUNTDOWN * 25; - - mProgressRemaining->setMaximum(COUNTDOWN * 25); - - updateInfo(mRemaining); - - mCountdownTimerId = startTimer(1000/25); - - connect(qApp, SIGNAL(activity()), SLOT(slotActivity())); -} - -AutoLogout::~AutoLogout() -{ - hide(); -} - -void AutoLogout::updateInfo(int timeout) -{ - mStatusLabel->setText(i18np("You will be automatically logged out in 1 second", - "You will be automatically logged out in %1 seconds", - timeout / 25) ); - mProgressRemaining->setValue(timeout); -} - -void AutoLogout::timerEvent(QTimerEvent *ev) -{ - if (ev->timerId() == mCountdownTimerId) - { - updateInfo(mRemaining); - --mRemaining; - if (mRemaining < 0) - { - killTimer(mCountdownTimerId); - logout(); - } - } -} - -void AutoLogout::slotActivity() -{ - if (mRemaining >= 0) - accept(); -} - -void AutoLogout::logout() -{ - QAbstractEventDispatcher::instance()->unregisterTimers(this); - org::kde::KSMServerInterface ksmserver(QLatin1String( "org.kde.ksmserver" ), QLatin1String( "/KSMServer" ), QDBusConnection::sessionBus()); - ksmserver.logout( 0, 0, 0 ); -} - -void AutoLogout::setVisible(bool visible) -{ - QDialog::setVisible(visible); - - if (visible) - QApplication::flush(); -} - -#include "autologout.moc" diff --git a/krunner/lock/autologout.h b/krunner/lock/autologout.h deleted file mode 100644 index 0c444050..0000000 --- a/krunner/lock/autologout.h +++ /dev/null @@ -1,46 +0,0 @@ -//=========================================================================== -// -// This file is part of the KDE project -// -// Copyright 1999 Martin R. Jones -// Copyright 2003 Oswald Buddenhagen -// Copyright 2004 Chris Howells - -#ifndef AUTOLOGOUT_H -#define AUTOLOGOUT_H - -#include - -class LockProcess; -class QGridLayout; -class QLabel; -class QDialog; -class QProgressBar; - -class AutoLogout : public QDialog -{ - Q_OBJECT - -public: - AutoLogout(LockProcess *parent); - ~AutoLogout(); - virtual void setVisible(bool visible); - -protected: - virtual void timerEvent(QTimerEvent *); - -private Q_SLOTS: - void slotActivity(); - -private: - void updateInfo(int); - QGridLayout *frameLayout; - QLabel *mStatusLabel; - int mCountdownTimerId; - int mRemaining; - QTimer countDownTimer; - QProgressBar *mProgressRemaining; - void logout(); -}; - -#endif // AUTOLOGOUT_H diff --git a/krunner/lock/config-krunner-lock.h.cmake b/krunner/lock/config-krunner-lock.h.cmake deleted file mode 100644 index 7bfdfd6..0000000 --- a/krunner/lock/config-krunner-lock.h.cmake +++ /dev/null @@ -1,2 +0,0 @@ -#cmakedefine HAVE_GLXCHOOSEVISUAL 1 -#cmakedefine HAVE_XF86MISCSETGRABKEYSSTATE 1 diff --git a/krunner/lock/kscreenlocker.notifyrc b/krunner/lock/kscreenlocker.notifyrc deleted file mode 100644 index c35f4c7..0000000 --- a/krunner/lock/kscreenlocker.notifyrc +++ /dev/null @@ -1,741 +0,0 @@ -[Global] -IconName=system-lock-screen -Comment=Screen Saver -Comment[ar]=حافظة الشاشة -Comment[ast]=Curiapantalles -Comment[bg]=Екранен предпазител -Comment[bs]=Čuvar ekrana -Comment[ca]=Estalvi de pantalla -Comment[ca@valencia]=Estalvi de pantalla -Comment[cs]=Šetřič obrazovky -Comment[da]=Pauseskærm -Comment[de]=Bildschirmschoner -Comment[el]=Προφύλαξη οθόνης -Comment[en_GB]=Screen Saver -Comment[es]=Salvapantallas -Comment[et]=Ekraanisäästja -Comment[eu]=Pantaila babeslea -Comment[fi]=Näytönsäästäjä -Comment[fr]=Écran de veille -Comment[ga]=Spárálaí Scáileáin -Comment[gu]=સ્ક્રીનક્રિન સેવર -Comment[he]=שומר מסך -Comment[hi]=स्क्रीन सेवर -Comment[hr]=Čuvar zaslona -Comment[hu]=Képernyővédő -Comment[ia]=Salvator de schermo -Comment[id]=Penyimpan Layar -Comment[is]=Skjáhvíla -Comment[it]=Salvaschermo -Comment[ja]=スクリーンセーバー -Comment[kk]=Экран сақтағышы -Comment[km]=ធាតុ​រក្សា​អេក្រង់​ -Comment[kn]=ತೆರೆ ರಕ್ಷಕ -Comment[ko]=화면 보호기 -Comment[lt]=Ekrano užsklanda -Comment[lv]=Ekrānsaudzētājs -Comment[nb]=Pauseskjerm -Comment[nds]=Pausschirm -Comment[nl]=Schermbeveiliging -Comment[nn]=Pause­skjerm -Comment[pa]=ਸਕਰੀਨ ਸੇਵਰ -Comment[pl]=Wygaszacz ekranu -Comment[pt]=Protector de Ecrã -Comment[pt_BR]=Protetor de tela -Comment[ro]=Protecție de ecran -Comment[ru]=Хранитель экрана -Comment[si]=තිර සුරැකුම -Comment[sk]=Šetrič obrazovky -Comment[sl]=Ohranjevalnik zaslona -Comment[sr]=Чувар екрана -Comment[sr@ijekavian]=Чувар екрана -Comment[sr@ijekavianlatin]=Čuvar ekrana -Comment[sr@latin]=Čuvar ekrana -Comment[sv]=Skärmsläckare -Comment[tg]=Пардаи экран -Comment[th]=โปรแกรมรักษาจอภาพ -Comment[tr]=Ekran Koruyucu -Comment[ug]=ئېكران قوغدىغۇچ -Comment[uk]=Зберігач екрана -Comment[wa]=Sipårgneu di waitroûle -Comment[x-test]=xxScreen Saverxx -Comment[zh_CN]=屏幕保护程序 -Comment[zh_TW]=螢幕保護程式 - -[Event/savingstarted] -Name=Screen saver started -Name[ar]=بدأت حافظة الشاشة -Name[ast]=Curiapantalles aniciáu -Name[bg]=Зареден е екранен предпазител -Name[bs]=Čuvar ekrana pokrenut -Name[ca]=S'ha iniciat l'estalvi de pantalla -Name[ca@valencia]=S'ha iniciat l'estalvi de pantalla -Name[cs]=Šetřič obrazovky spuštěn -Name[csb]=Zrëszony wëgaszôcz ekranu -Name[da]=Pauseskærm startet -Name[de]=Der Bildschirmschoner wurde gestartet. -Name[el]=Η προφύλαξη οθόνης ξεκίνησε -Name[en_GB]=Screen saver started -Name[eo]=Ekrankurtenon ŝaltis -Name[es]=Salvapantallas iniciado -Name[et]=Ekraanisäästja alustas tööd -Name[eu]=Pantaila babeslea abiarazita -Name[fi]=Näytönsäästäjä käynnistyi -Name[fr]=Écran de veille démarré -Name[fy]=Skermbefeiliging úteinsetten -Name[ga]=Tosaíodh an spárálaí scáileáin -Name[gl]=Iniciouse o protector de pantalla -Name[gu]=સ્ક્રિન સેવર શરૂ થયું -Name[he]=שומר המסך התחיל -Name[hi]=स्क्रीन सेवर चालू -Name[hr]=Zaštita zaslona pokrenuta -Name[hu]=A képernyővédő elindult -Name[ia]=Salvator de schermo startate -Name[id]=Penyimpan layar dijalankan -Name[is]=Skjásvæfa ræst -Name[it]=Salvaschermo avviato -Name[ja]=スクリーンセーバー開始 -Name[kk]=Экран сақтағышы ісін бастады -Name[km]=បាន​ចាប់ផ្ដើម​ធាតុរក្សា​អេក្រង់ -Name[kn]=ಸ್ಕ್ರೀನ್‌ ಸೇವರ್ ಪ್ರಾರಂಭಗೊಂಡಿದೆ -Name[ko]=화면 보호기 시작됨 -Name[lt]=Ekrano užsklanda paleista -Name[lv]=Ekrāna saudzētājs palaists -Name[mk]=Чуварот на екранот е стартуван -Name[ml]=സ്ക്രീന്‍ സേവര്‍ തുടങ്ങി -Name[nb]=Pauseskjerm startet -Name[nds]=Pausschirm opropen -Name[nl]=Schermbeveiliging gestart -Name[nn]=Pauseskjermen er starta -Name[pa]=ਸਕਰੀਨ-ਸੇਵਰ ਸ਼ੁਰੂ ਹੋਏ -Name[pl]=Wygaszacz ekranu uruchomiony -Name[pt]=O protector de ecrã foi iniciado -Name[pt_BR]=O protetor de tela foi iniciado -Name[ro]=Protecție de ecran pornită -Name[ru]=Хранитель экрана запущен -Name[si]=තිර සුරැකුම ආරම්ණ කරන ලදි -Name[sk]=Šetrič obrazovky spustený -Name[sl]=Zagon ohranjevalnika zaslona -Name[sr]=Чувар екрана покренут -Name[sr@ijekavian]=Чувар екрана покренут -Name[sr@ijekavianlatin]=Čuvar ekrana pokrenut -Name[sr@latin]=Čuvar ekrana pokrenut -Name[sv]=Skärmsläckare startad -Name[tg]=Пардаи экран сар шуд -Name[th]=โปรแกรมรักษาจอภาพเริ่มทำงานแล้ว -Name[tr]=Ekran koruyucu başlatıldı -Name[ug]=ئېكران قوغدىغۇچ باشلاندى -Name[uk]=Запущено зберігач екрана -Name[wa]=Sipårgneu di waitroûle enondé -Name[x-test]=xxScreen saver startedxx -Name[zh_CN]=屏幕保护程序已启动 -Name[zh_TW]=螢幕保護程式已啟動 -Comment=The screen saver has been started -Comment[ar]=بدأت حافظة الشاشة -Comment[ast]=Entamóse'l curiapantalles -Comment[bg]=Зареден е екранен предпазител -Comment[bs]=Pokrenut je čuvar ekrana -Comment[ca]=S'ha iniciat l'estalvi de pantalla -Comment[ca@valencia]=S'ha iniciat l'estalvi de pantalla -Comment[cs]=Šetřič obrazovky byl spuštěn -Comment[csb]=Wëgaszôcz ekranu òstôł zrëszony -Comment[da]=Pauseskærmen er blevet startet -Comment[de]=Der Bildschirmschoner wurde gestartet. -Comment[el]=Η προφύλαξη οθόνης έχει ξεκινήσει -Comment[en_GB]=The screen saver has been started -Comment[eo]=la Ekrankurteno lanĉiĝas -Comment[es]=Se ha iniciado el salvapantallas -Comment[et]=Ekraanisäästja alustas tööd -Comment[eu]=Pantaila babeslea abiarazi da -Comment[fi]=Näytönsäästäjä on käynnistynyt -Comment[fr]=L'écran de veille a été démarré -Comment[fy]=De skermbefeiliging is úteinsetten -Comment[ga]=Tosaíodh an spárálaí scáileáin -Comment[gl]=Iniciouse o protector de pantalla -Comment[gu]=સ્ક્રિન સેવર શરૂ કરાયેલ છે -Comment[he]=שומר מסך הופעל -Comment[hr]=Zaštita zaslona je pokrenuta -Comment[hu]=A képernyővédő elindult -Comment[ia]=Le salvator de schermo ha essite startate -Comment[id]=Penyimpan layar telah dijalankan -Comment[is]=Skjáhvílan hefur verið ræst -Comment[it]=Il salvaschermo è stato avviato -Comment[ja]=スクリーンセーバーが開始されました -Comment[kk]=Экран сақтағышы ісін бастады -Comment[km]=ធាតុ​រក្សាអេក្រង់​ត្រូវ​បាន​ចាប់ផ្ដើម -Comment[kn]=ಸ್ಕ್ರೀನ್‌ ಸೇವರನ್ನು ಪ್ರಾರಂಭಿಸಲಾಗಿದೆ -Comment[ko]=화면 보호기 시작됨 -Comment[lt]=Ekrano užsklanda buvo paleista -Comment[lv]=Ekrāna saudzētājs tika palaists -Comment[mk]=Чуварот на екранот беше стартуван -Comment[ml]=സ്ക്രീന്‍ സേവര്‍ തുടങ്ങിയിരിയ്ക്കുന്നു -Comment[nb]=Pauseskjermen er startet -Comment[nds]=De Pausschirm wöör opropen -Comment[nl]=De schermbeveiliging is gestart -Comment[nn]=Pauseskjermen er starta -Comment[pa]=ਸਕਰੀਨਸੇਵਰ ਸ਼ੁਰੂ ਕੀਤਾ ਜਾ ਚੁੱਕਿਆ ਹੈ -Comment[pl]=Wygaszacz ekranu został uruchomiony -Comment[pt]=O protector de ecrã foi iniciado -Comment[pt_BR]=O protetor de tela foi iniciado -Comment[ro]=Protecția de ecran a fost pornită -Comment[ru]=Хранитель экрана запущен -Comment[si]=තිර සුරැකුම ආරම්භ කර ඇත -Comment[sk]=Šetrič obrazovky bol spustený -Comment[sl]=Ohranjevalnik zaslona se je zagnal -Comment[sr]=Покренут је чувар екрана -Comment[sr@ijekavian]=Покренут је чувар екрана -Comment[sr@ijekavianlatin]=Pokrenut je čuvar ekrana -Comment[sr@latin]=Pokrenut je čuvar ekrana -Comment[sv]=Skärmsläckaren har startats -Comment[tg]=Ахлотдон холӣ карда шуд -Comment[th]=โปรแกรมรักษาจอภาพเริ่มการทำงานแล้ว -Comment[tr]=Ekran koruyucu başlatıldı -Comment[ug]=ئېكران قوغدىغۇچ باشلاندى -Comment[uk]=Запущено зберігач екрана -Comment[wa]=Li spårgneu di waitroûle a stî enondé -Comment[x-test]=xxThe screen saver has been startedxx -Comment[zh_CN]=屏幕保护程序已经启动 -Comment[zh_TW]=螢幕保護程式已被啟動 -Action=None - -[Event/locked] -Name=Screen locked -Name[ar]=قُقلت الشاشة -Name[ast]=Pantalla bloquiada -Name[bg]=Екранът е заключен -Name[bs]=Ekran zaključan -Name[ca]=S'ha bloquejat la pantalla -Name[ca@valencia]=S'ha bloquejat la pantalla -Name[cs]=Obrazovka uzamčena -Name[csb]=Zablokòwóny ekranu -Name[da]=Skærmen er låst -Name[de]=Bildschirm gesperrt -Name[el]=Οθόνη κλειδώθηκε -Name[en_GB]=Screen locked -Name[eo]=Ekranŝloso -Name[es]=Pantalla bloqueada -Name[et]=Ekraan on lukustatud -Name[eu]=Pantaila giltzatuta -Name[fi]=Näyttö lukittu -Name[fr]=Écran verrouillé -Name[fy]=Skerm beskoattele -Name[ga]=Tá an scáileán faoi ghlas -Name[gl]=A pantalla está trancada -Name[gu]=સ્ક્રિન તાળું મારેલ છે -Name[he]=מסך נעול -Name[hi]=स्क्रीन तालाबंद -Name[hr]=Zaslon zaključan -Name[hu]=A képernyő zárolt -Name[ia]=Schermo blocate -Name[id]=Layar dikunci -Name[is]=Skjár læstur -Name[it]=Schermo bloccato -Name[ja]=スクリーンロック -Name[kk]=Экран бұғатталды -Name[km]=បាន​ចាក់សោ​អេក្រង់​ -Name[kn]=ತೆರೆ ಲಾಕ್ ಆಗಿದೆ -Name[ko]=화면 잠김 -Name[lt]=Ekranas užrakintas -Name[lv]=Ekrāns slēgts -Name[mk]=Екранот е заклучен -Name[ml]=സ്ക്രീന്‍ പൂട്ടി -Name[nb]=Skjermen låst -Name[nds]=Schirm afslaten -Name[nl]=Scherm vergrendeld -Name[nn]=Skjermen er låst -Name[pa]=ਸਕਰੀਨ ਲਾਕ ਹੈ -Name[pl]=Ekran zablokowany -Name[pt]=Ecrã bloqueado -Name[pt_BR]=Tela bloqueada -Name[ro]=Ecran blocat -Name[ru]=Экран заблокирован -Name[si]=තිරය අගුලු දමන ලදි -Name[sk]=Obrazovka zamknutá -Name[sl]=Zaklep zaslona -Name[sr]=Екран закључан -Name[sr@ijekavian]=Екран закључан -Name[sr@ijekavianlatin]=Ekran zaključan -Name[sr@latin]=Ekran zaključan -Name[sv]=Skärm låst -Name[tg]=Пардаи экран қулф шуд -Name[th]=หน้าจอถูกล็อคอยู่ -Name[tr]=Ekran kilitlendi -Name[ug]=ئېكران قۇلۇپلاندى -Name[uk]=Екран заблоковано -Name[wa]=Waitroûle eclawêye -Name[x-test]=xxScreen lockedxx -Name[zh_CN]=屏幕已锁定 -Name[zh_TW]=螢幕已鎖定 -Comment=The screen has been locked -Comment[ar]=تمّ قفل الشاشة -Comment[ast]=Bloquióse la pantalla -Comment[bg]=Екранът е заключен -Comment[bs]=Ekran je upravo zaključan -Comment[ca]=S'ha bloquejat la pantalla -Comment[ca@valencia]=S'ha bloquejat la pantalla -Comment[cs]=Obrazovka byla uzamčena -Comment[csb]=Ekran òstôł zablokòwóny -Comment[da]=Skærmen er blevet låst -Comment[de]=Der Bildschirm wurde gesperrt. -Comment[el]=Η οθόνη έχει κλειδωθεί -Comment[en_GB]=The screen has been locked -Comment[eo]=La ekrano ŝlosiĝis -Comment[es]=Se ha bloqueado la pantalla -Comment[et]=Ekraan on lukustatud -Comment[eu]=Pantaila giltzatu egin da -Comment[fi]=Näyttö on lukittunut -Comment[fr]=L'écran a été verrouillé -Comment[fy]=It skerm is beskoattele -Comment[ga]=Cuireadh an scáileán faoi ghlas -Comment[gl]=A pantalla trancouse -Comment[gu]=સ્ક્રિનને તાળું મારવામાં આવ્યું છે -Comment[he]=המסך ננעל -Comment[hi]=स्क्रीन तालाबंद कर दिया गया है -Comment[hr]=Zaslon je zaključan -Comment[hu]=A képernyő zárolt -Comment[ia]=Le schermo ha essite blocate -Comment[id]=Layar telah dikunci -Comment[is]=Skjánum hefur verið læst -Comment[it]=Lo schermo è stato bloccato -Comment[ja]=スクリーンがロックされました -Comment[kk]=Экран бұғатталған -Comment[km]=អេក្រង់​ត្រូវ​បាន​ចាក់សោ -Comment[kn]=ಒಂದು ತೆರೆಯನ್ನು ಲಾಕ್‌ ಮಾಡಲಾಗಿದೆ -Comment[ko]=화면 잠김 -Comment[lt]=Ekranas buvo užrakintas -Comment[lv]=Ekrāns tika slēgts -Comment[mk]=Екранот беше заклучен -Comment[ml]=സ്ക്രീന്‍ പൂട്ടിയിരിയ്ക്കുന്നു -Comment[nb]=Skjermen er nå låst -Comment[nds]=De Schirm wöör afslaten -Comment[nl]=Het scherm is vergrendeld -Comment[nn]=Skjermen er låst -Comment[pa]=ਸਕਰੀਨ ਨੂੰ ਲਾਕ ਕੀਤਾ ਗਿਆ ਹੈ -Comment[pl]=Ekran został zablokowany -Comment[pt]=O ecrã foi bloqueado -Comment[pt_BR]=A tela foi bloqueada -Comment[ro]=Ecranul a fost blocat -Comment[ru]=Экран заблокирован -Comment[si]=තිරය අගුළු දමා ඇත -Comment[sk]=Obrazovka bola zamknutá -Comment[sl]=Zaslon je bil zaklenjen -Comment[sr]=Екран је управо закључан -Comment[sr@ijekavian]=Екран је управо закључан -Comment[sr@ijekavianlatin]=Ekran je upravo zaključan -Comment[sr@latin]=Ekran je upravo zaključan -Comment[sv]=Skärmen har låsts -Comment[tg]=Клавиша модификатора зафиксирована -Comment[th]=หน้าจอถูกล็อคอยู่ -Comment[tr]=Ekran kilitlendi -Comment[ug]=ئېكران قۇلۇپلانغان -Comment[uk]=Екран було заблоковано -Comment[wa]=Li waitroûle a stî eclawêye -Comment[x-test]=xxThe screen has been lockedxx -Comment[zh_CN]=屏幕已经被锁定 -Comment[zh_TW]=螢幕已被鎖定 -Action=None - -[Event/savingstopped] -Name=Screen saver exited -Name[ar]=خرجت حافظة الشاشة -Name[ast]=Finó'l curiapantalles -Name[bg]=Екранният предпазител е спрян -Name[bs]=Čuvar ekrana napušten -Name[ca]=S'ha sortit de l'estalvi de pantalla -Name[ca@valencia]=S'ha eixit de l'estalvi de pantalla -Name[cs]=Šetřič obrazovky ukončen -Name[csb]=Wëgaszôcz ekranu òstôł zakùńczony -Name[da]=Pauseskærm afslutter -Name[de]=Der Bildschirmschoner wurde beendet. -Name[el]=Η προφύλαξη οθόνης τερμάτισε -Name[en_GB]=Screen saver exited -Name[eo]=Ekrankurteno finiĝis -Name[es]=El salvapantallas ha terminado -Name[et]=Ekraanisäästja lõpetas töö -Name[eu]=Pantaila babeslea amaituta -Name[fi]=Näytönsäästäjä sulkeutui -Name[fr]=Écran de veille terminé -Name[fy]=Skermbefeiliging is der útgong -Name[ga]=Scoireadh ón spárálaí scáileáin -Name[gl]=O protector de pantalla saíu -Name[he]=שומר המסך הפסיק -Name[hi]=स्क्रीन सेवर बंद -Name[hr]=Zaštita zaslona završila -Name[hu]=A képernyővédő kilépett -Name[ia]=Salvator de schermo exite -Name[id]=Penyimpan layar keluar -Name[is]=Hætt í skjásvæfu -Name[it]=Salvaschermo terminato -Name[ja]=スクリーンセーバー終了 -Name[kk]=Экран сақтаушысы тоқтады -Name[km]=បាន​ចេញ​ពី​ធាតុរក្សាអេក្រង់​ -Name[kn]=ಸ್ಕ್ರೀನ್‌ ಸೇವರ್ ನಿರ್ಗಮಿಸಿದೆ -Name[ko]=화면 보호기 종료됨 -Name[lt]=Ekrano užsklanda išsijungė -Name[lv]=Ekrāna saudzētājs apturēts -Name[mk]=Чуварот на екранот излезе -Name[ml]=സ്ക്രീന്‍ സേവറില്‍ നിന്നും പുറത്തു് കടന്നിരിയ്ക്കുന്നു -Name[nb]=Pauseskjermen avsluttet -Name[nds]=Pausschirm utmaakt -Name[nl]=Schermbeveiliger geëindigd -Name[nn]=Pauseskjermen er avslutta -Name[pa]=ਸਕਰੀਨ ਸੇਵਰ ਬੰਦ -Name[pl]=Wygaszacz ekranu wyszedł -Name[pt]=O protector de ecrã terminou -Name[pt_BR]=O protetor de tela terminou -Name[ro]=Protecția de ecran a s-a terminat -Name[ru]=Хранитель экрана завершил работу -Name[si]=තිර සුරැකුම ඉවත් විය -Name[sk]=Šetrič obrazovky skončil -Name[sl]=Izhod iz ohranjevalnika zaslona -Name[sr]=Чувар екрана напуштен -Name[sr@ijekavian]=Чувар екрана напуштен -Name[sr@ijekavianlatin]=Čuvar ekrana napušten -Name[sr@latin]=Čuvar ekrana napušten -Name[sv]=Skärmsläckare avslutades -Name[tg]=Пардаи экран хомӯш шуд -Name[th]=โปรแกรมรักษาจอภาพจบการทำงานแล้ว -Name[tr]=Ekran koruyucudan çıkıldı -Name[ug]=ئېكران قوغدىغۇچ ئاخىرلاشتى -Name[uk]=Завершено роботу зберігача екрана -Name[wa]=Sipårgneu di waitroûle a cwité -Name[x-test]=xxScreen saver exitedxx -Name[zh_CN]=屏幕保护程序已退出 -Name[zh_TW]=螢幕保護程式已離開 -Comment=The screen saver has finished -Comment[ar]=حافظة الشاشة انتهت -Comment[ast]=Finó'l curiapantalles -Comment[bg]=Екранният предпазител е спрян -Comment[bs]=Čuvar ekrana se upravo okončao -Comment[ca]=L'estalvi de pantalla ha finalitzat -Comment[ca@valencia]=L'estalvi de pantalla ha finalitzat -Comment[cs]=Šetřič obrazovky byl ukončen -Comment[csb]=Wëgaszôcz ekranu òstôł zakùńczony -Comment[da]=Pauseskærmen er afsluttet -Comment[de]=Der Bildschirmschoner wurde beendet. -Comment[el]=Η προφύλαξη οθόνης έχει τελειώσει -Comment[en_GB]=The screen saver has finished -Comment[eo]=La ekrankurteno finiĝis -Comment[es]=El salvapantallas ha terminado -Comment[et]=Ekraanisäästja lõpetas töö -Comment[eu]=Pantaila babeslea amaitu da -Comment[fi]=Näytönsäästäjä on päättynyt -Comment[fr]=L'écran de veille a terminé -Comment[fy]=De skermbefeiliging is foltôge -Comment[ga]=Tá an spárálaí scáileán críochnaithe -Comment[gl]=O protector de pantalla rematou -Comment[gu]=સ્ક્રિન સેવર પૂર્ણ થયું છે -Comment[he]=שומר המסך הפסיק -Comment[hi]=स्क्रीन सेवर समाप्त हुआ -Comment[hr]=Zaštita zaslona je završila -Comment[hu]=A képernyővédő befejeződött -Comment[ia]=Le salvator de schermo ha finite -Comment[id]=Penyimpan layar telah selesai -Comment[is]=Skjáhvílan hefur lokið sér af -Comment[it]=Il salvaschermo si è concluso -Comment[ja]=スクリーンセーバーが終了しました -Comment[kk]=Экран сақтаушысы жұмысын тоқтатты -Comment[km]=បាន​បញ្ចប់​ធាតុ​រក្សា​អេក្រង់ -Comment[kn]=ತೆರೆ ರಕ್ಷಕ (ಸ್ಕ್ರೀನ್ ಸೇವರ್) ಅಂತ್ಯಗೊಂಡಿದೆ -Comment[ko]=화면 보호기 종료됨 -Comment[lt]=Ekrano užsklanda baigė darbą -Comment[lv]=Ekrāna saudzētājs tika apturēts -Comment[mk]=Чуварот на екранот заврши -Comment[ml]=സ്ക്രീന്‍ സേവര്‍ അവസാനിച്ചു -Comment[nb]=Pauseskjermen er ferdig -Comment[nds]=De Pausschirm wöör utmaakt -Comment[nl]=De schermbeveiliging is geëindigd -Comment[nn]=Pauseskjermen er ferdig -Comment[pa]=ਸਕਰੀਨ ਸੇਵਰ ਮੁਕੰਮਲ -Comment[pl]=Wygaszacz ekranu zakończył działanie -Comment[pt]=O protector de ecrã terminou -Comment[pt_BR]=O protetor de tela terminou -Comment[ro]=Protecția de ecran s-a încheiat -Comment[ru]=Хранитель экрана завершил работу -Comment[si]=තිරසුරැකුම අවසන් විය -Comment[sk]=Šetrič obrazovky bol ukončený -Comment[sl]=Ohranjevalnik zaslona se je zaključil -Comment[sr]=Чувар екрана се управо окончао -Comment[sr@ijekavian]=Чувар екрана се управо окончао -Comment[sr@ijekavianlatin]=Čuvar ekrana se upravo okončao -Comment[sr@latin]=Čuvar ekrana se upravo okončao -Comment[sv]=Skärmsläckaren har avslutats -Comment[th]=โปรแกรมรักษาจอภาพทำงานเสร็จสิ้นแล้ว -Comment[tr]=Ekran koruyucu bitti -Comment[ug]=ئېكران قوغدىغۇچ ئاخىرلاشتى -Comment[uk]=Роботу зберігача екрана завершено -Comment[wa]=Li spårgneu di waitroûle a cwité -Comment[x-test]=xxThe screen saver has finishedxx -Comment[zh_CN]=屏幕保护程序已运行完成 -Comment[zh_TW]=螢幕保護程式已完成 -Action=None - -[Event/unlocked] -Name=Screen unlocked -Name[ar]=فُكًَ قفل الشاشة -Name[ast]=Pantalla desbloquiada -Name[bg]=Екранът е отключен -Name[bs]=Ekran otključan -Name[ca]=Pantalla desbloquejada -Name[ca@valencia]=Pantalla desbloquejada -Name[cs]=Obrazovka odemknuta -Name[csb]=Ekran òdblokòwóny -Name[da]=Skærmen er låst op -Name[de]=Bildschirm freigegeben -Name[el]=Οθόνη ξεκλείδωτη -Name[en_GB]=Screen unlocked -Name[eo]=Ekrano malŝlosita -Name[es]=Pantalla desbloqueada -Name[et]=Ekraan on lahtilukustatud -Name[eu]=Pantaila desblokeatuta -Name[fi]=Näytön lukitus aukeni -Name[fr]=Écran déverrouillé -Name[fy]=Skerm ûntskoattele -Name[ga]=Scáileán díghlasáilte -Name[gl]=A pantalla desatrancouse -Name[gu]=સ્ક્રિનનું તાળું ખૂલેલ છે -Name[he]=המסך שוחרר -Name[hi]=स्क्रीन तालाबंद -Name[hr]=Zaslon otključan -Name[hu]=A képernyő feloldva -Name[ia]=Schermo disblocate -Name[id]=Layar tidak dikunci -Name[is]=Skjár aflæstur -Name[it]=Schermo sbloccato -Name[ja]=スクリーンロック解除 -Name[kk]=Экран бұғаты шешілді -Name[km]=បាន​​ដោះសោ​អេក្រង់ -Name[kn]=ತೆರೆಯನ್ನು ಅನ್ ಲಾಕ್ ಮಾಡಲಾಗಿದೆ -Name[ko]=화면 잠금 풀림 -Name[lt]=Ekranas atrakintas -Name[lv]=Ekrāns atslēgts -Name[mk]=Екранот е отклучен -Name[ml]=സ്ക്രീന്‍ തുറന്നു -Name[nb]=Skjermen låst opp -Name[nds]=Schirm opslaten -Name[nl]=Scherm ontgrendeld -Name[nn]=Skjermen er låst opp -Name[pa]=ਸਕਰੀਨ ਅਣ-ਲਾਕ ਹੈ -Name[pl]=Ekran odblokowany -Name[pt]=Ecrã desbloqueado -Name[pt_BR]=Tela desbloqueada -Name[ro]=Ecran deblocat -Name[ru]=Экран разблокирован -Name[si]=තිරය අගුළු හැරිනි -Name[sk]=Obrazovka odomknutá -Name[sl]=Odklep zaslona -Name[sr]=Екран откључан -Name[sr@ijekavian]=Екран откључан -Name[sr@ijekavianlatin]=Ekran otključan -Name[sr@latin]=Ekran otključan -Name[sv]=Skärm upplåst -Name[tg]=Экран кушода шуд -Name[th]=ปลดล็อคหน้าจอแล้ว -Name[tr]=Ekranın kilidi açıldı -Name[ug]=ئېكران قۇلۇپسىزلاندى -Name[uk]=Екран розблоковано -Name[wa]=Waitroûle dizeclawêye -Name[x-test]=xxScreen unlockedxx -Name[zh_CN]=屏幕已解锁 -Name[zh_TW]=螢幕已解除鎖定 -Comment=The screen has been unlocked -Comment[ar]=تم قفل الشاشة -Comment[ast]=Desbloquióse la pantalla -Comment[bg]=Екранът е отключен -Comment[bs]=Ekran je upravo otključan -Comment[ca]=S'ha desbloquejat la pantalla -Comment[ca@valencia]=S'ha desbloquejat la pantalla -Comment[cs]=Obrazovka byla odemknuta -Comment[csb]=Ekran òstôł òdblokòwóny -Comment[da]=Skærmen er blevet låst op -Comment[de]=Der Bildschirm wurde freigegeben. -Comment[el]=Η οθόνη έχει ξεκλειδωθεί -Comment[en_GB]=The screen has been unlocked -Comment[eo]=La ekrano malŝlosiĝis -Comment[es]=Se ha desbloqueado la pantalla -Comment[et]=Ekraan on lahtilukustatud -Comment[eu]=Pantaila desblokeatu da -Comment[fi]=Näytön lukitus on avautunut -Comment[fr]=L'écran a été déverrouillé -Comment[fy]=It skerm is ûntskoattele -Comment[ga]=Tá an scáileán díghlasáilte -Comment[gl]=A pantalla desatrancouse -Comment[he]=המסך שוחרר -Comment[hr]=Zaslon je otključan -Comment[hu]=A képernyő feloldva -Comment[ia]=Le schermo ha essite disblocate -Comment[id]=Layar telah tidak dikunci -Comment[is]=Skjánum hefur verið aflæst -Comment[it]=Lo schermo è stato sbloccato -Comment[ja]=スクリーンのロックが解除されました -Comment[kk]=Экраннан бұғаты шешілді -Comment[km]=ធាតុរក្សាអេក្រង់​ត្រូ​វបានដោះសោ -Comment[kn]=ತೆರೆಯನ್ನು ಅನ್ ಲಾಕ್ ಮಾಡಲಾಗಿದೆ -Comment[ko]=화면 잠금 풀림 -Comment[lt]=Ekranas buvo atrakintas -Comment[lv]=Ekrāns tika atslēgts -Comment[mk]=Екранот беше отклучен -Comment[ml]=സ്ക്രീന്‍ തുറന്നിരിയ്ക്കുന്നു -Comment[nb]=Skjermen er blitt låst opp -Comment[nds]=De Schirm wöör opslaten -Comment[nl]=Het scherm is ontgrendeld -Comment[nn]=Skjermen er låst opp -Comment[pa]=ਸਕਰੀਨ ਨੂੰ ਅਣ-ਲਾਕ ਕੀਤਾ ਗਿਆ -Comment[pl]=Ekran został odblokowany -Comment[pt]=O ecrã foi desbloqueado -Comment[pt_BR]=A tela foi desbloqueada -Comment[ro]=Ecranul a fost deblocat -Comment[ru]=Экран разблокирован -Comment[si]=තිරය අගුළු හැර ඇත -Comment[sk]=Obrazovka bola odomknutá -Comment[sl]=Zaslon je bil odklenjen -Comment[sr]=Екран је управо откључан -Comment[sr@ijekavian]=Екран је управо откључан -Comment[sr@ijekavianlatin]=Ekran je upravo otključan -Comment[sr@latin]=Ekran je upravo otključan -Comment[sv]=Skärmen har låsts upp -Comment[tg]=Клавиша модификатора зафиксирована -Comment[th]=หน้าจอถูกปลดล็อคแล้ว -Comment[tr]=Ekranın kilidi açıldı -Comment[ug]=ئېكران قۇلۇپسىزلانغان -Comment[uk]=Екран було розблоковано -Comment[wa]=Li waitroûle a stî dizeclawêye -Comment[x-test]=xxThe screen has been unlockedxx -Comment[zh_CN]=屏幕已经被解锁 -Comment[zh_TW]=螢幕已解除鎖定 -Action=None - -[Event/unlockfailed] -Name=Screen unlock failed -Name[ar]=فشل فك قفل الشاشة -Name[ast]=Nun pudo desbloquiase la pantalla -Name[bg]=Грешка при отключване на екрана -Name[bs]=Otključavanje ekrana neuspelo -Name[ca]=Ha fallat el desbloqueig de la pantalla -Name[ca@valencia]=Ha fallat el desbloqueig de la pantalla -Name[cs]=Odemknutí obrazovky selhalo -Name[csb]=Felënk òdblokòwaniô ekranu -Name[da]=Det mislykkedes at låse skærmen op -Name[de]=Entsperren des Bildschirms fehlgeschlagen -Name[el]=Το ξεκλείδωμα της οθόνης απέτυχε -Name[en_GB]=Screen unlock failed -Name[eo]=Malŝlositado de ekrano fiaskis -Name[es]=No se pudo desbloquear la pantalla -Name[et]=Ekraani lahtilukustamine nurjus -Name[eu]=Pantaila desblokeatzeak huts egin du -Name[fi]=Näytön lukinnan poisto epäonnistui -Name[fr]=Le déverrouillage de l'écran a échoué -Name[fy]=Skerm ûntskoatteling is mislearre -Name[ga]=Níorbh fhéidir an scáileán a dhíghlasáil -Name[gl]=Fallou o desbloqueo da pantalla -Name[gu]=સ્ક્રિનનું તાળું ખોલવામાં નિષ્ફળ -Name[he]=שיחרור המסך נכשל -Name[hi]=स्क्रीन ताला नहीं खुला -Name[hr]=Neuspjelo otključavanje zaslona -Name[hu]=Nem sikerült feloldani a képernyőt -Name[ia]=Disbloco de schermo falleva -Name[id]=Gagal membuka kunci -Name[is]=Aflæsing skjásins mistókst -Name[it]=Sblocco dello schermo non riuscito -Name[ja]=スクリーンのロック解除失敗 -Name[kk]=Экран бұғатын шешуі болмады -Name[km]=បាន​បរាជ័យ​ក្នុងការ​ដោះសោ​អេក្រង់ -Name[kn]=ತೆರೆಯನ್ನು ಅನ್ ಲಾಕ್ ಮಾಡುವುದು ವಿಫಲವಾಗಿದೆ -Name[ko]=화면 잠금 풀리지 않음 -Name[lt]=Ekrano atrakinimas nepavyko -Name[lv]=Neizdevās atslēgt ekrānu -Name[mk]=Не успеа отклучувањето на екранот -Name[ml]=സ്ക്രീന്‍ തുറക്കുന്നതില്‍ പരാജയപ്പെട്ടു -Name[nb]=Det lyktes ikke å låse opp skjermen -Name[nds]=Opsluten vun den Schirm fehlslaan -Name[nl]=Ontgrendelen van scherm is mislukt -Name[nn]=Klarte ikkje låsa opp skjermen -Name[pa]=ਸਕਰੀਨ ਖੋਲ੍ਹਣ ਲਈ ਫੇਲ੍ਹ -Name[pl]=Nieudane odblokowanie ekranu -Name[pt]=O desbloqueio do ecrã foi mal-sucedido -Name[pt_BR]=O bloqueio de tela falhou -Name[ro]=Deblocare ecranului a eșuat -Name[ru]=Не удалось разблокировать экран -Name[si]=තිරය අගුළු හැරීම අසාර්ථකයි -Name[sk]=Odomknutie obrazovky zlyhalo -Name[sl]=Spodletel odklep zaslona -Name[sr]=Откључавање екрана неуспело -Name[sr@ijekavian]=Откључавање екрана неуспјело -Name[sr@ijekavianlatin]=Otključavanje ekrana neuspjelo -Name[sr@latin]=Otključavanje ekrana neuspelo -Name[sv]=Upplåsning av skärm misslyckades -Name[tg]=Кушодани экран қатъ карда шуд -Name[th]=ล้มเหลวในการปลดล็อคหน้าจอ -Name[tr]=Ekran kilidi açılamadı -Name[ug]=ئېكران قۇلۇپسىزلاش مەغلۇپ بولدى -Name[uk]=Невдала спроба розблокування екрана -Name[wa]=Li dizeclawaedje del waitroûle a fwait berwete -Name[x-test]=xxScreen unlock failedxx -Name[zh_CN]=屏幕解锁失败 -Name[zh_TW]=螢幕解除鎖定失敗 -Comment=Failed attempt to unlock the screen -Comment[ar]=محاولة فاشلة لفك قفل الشاشة -Comment[ast]=Fallu al intentar desbloquiar la pantalla -Comment[bg]=Грешка при опит за отключване на екрана -Comment[bs]=Pokušaj otključavanja ekrana nije uspeo -Comment[ca]=L'intent de desbloquejar la pantalla ha fallat -Comment[ca@valencia]=L'intent de desbloquejar la pantalla ha fallat -Comment[cs]=Pokus o odemknutí obrazovky selhal -Comment[csb]=Felënk przëstãpù do òdblokòwaniô ekranu -Comment[da]=Mislykket forsøg på at låse skærmen op -Comment[de]=Das Entsperren des Bildschirms ist fehlgeschlagen. -Comment[el]=Αποτυχημένη προσπάθεια ξεκλειδώματος οθόνης -Comment[en_GB]=Failed attempt to unlock the screen -Comment[eo]=Provo de malŝlosi ekranon fiaskis -Comment[es]=Error al intentar desbloquear la pantalla -Comment[et]=Nurjunud katse ekraani lahti lukustada -Comment[eu]=Pantaila desblokeatzeko saiakerak huts egin du -Comment[fi]=Yritys näytön lukituksen poistamiseksi epäonnistui -Comment[fr]=Tentative infructueuse de déverrouiller l'écran -Comment[fy]=It is net slagge om it skerm te ûntskoatteljen -Comment[ga]=Theip ar iarracht an scáileán a dhíghlasáil -Comment[gl]=Fallou a tentativa de desbloquear a pantalla -Comment[he]=ניסיון כושל לשיחרור המסך -Comment[hr]=Propao je pokušaj otključavanja zaslona -Comment[hu]=Nem sikerült feloldani a képernyőt -Comment[ia]=Tentativa fallite de disblocar le schermo -Comment[id]=Gagal mencoba membuka kunci layar -Comment[is]=Tilraun til að aflæsa skjánum mistókst -Comment[it]=Tentanivo di sbloccare lo schermo non riuscito -Comment[ja]=スクリーンのロックを解除できませんでした -Comment[kk]=Экран бұғатын шешу әректі сәтсіз аяқталды -Comment[km]=បាន​បរាជ័យ​ក្នុង​ការ​ដោះសោ​អេក្រង់ -Comment[kn]=ತೆರೆಯನ್ನು ಅನ್ ಲಾಕ್ ಮಾಡುವ ವಿಫಲ ಯತ್ನ -Comment[ko]=화면 잠금 풀리지 않음 -Comment[lt]=Nepavyko bandymas atrakinti ekraną -Comment[lv]=Neizdevās atslēgt ekrānu -Comment[mk]=Не успеа обидот да се отклучи екранот -Comment[ml]=സ്ക്രീന്‍ തുറക്കാനുള്ള ശ്രമം പരാജയപ്പെട്ടിരിയ്ക്കുന്നു -Comment[nb]=Klarte ikke å låse opp skjermen -Comment[nds]=Opsluten vun den Schirm hett nich funkscheneert -Comment[nl]=Een mislukte poging om het scherm te ontgrendelen -Comment[nn]=Forsøket på å låsa opp skjermen var mislukka -Comment[pa]=ਸਕਰੀਨ ਅਣ-ਲਾਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਫੇਲ੍ਹ ਹੋਈ -Comment[pl]=Nieudana próba odblokowania ekranu -Comment[pt]=Falhou a tentativa de desbloquear o ecrã -Comment[pt_BR]=A tentativa de desbloquear a tela falhou -Comment[ro]=Încercare eșuată de a debloca ecranul -Comment[ru]=Не удалось разблокировать экран -Comment[si]=තිරය අගුළු හැරිමේ උත්සාහය අසාර්ථකයි -Comment[sk]=Neúspešný pokus o odomknutie obrazovky -Comment[sl]=Spodletel poskus odklepa zaslona -Comment[sr]=Покушај откључавања екрана није успео -Comment[sr@ijekavian]=Покушај откључавања екрана није успио -Comment[sr@ijekavianlatin]=Pokušaj otključavanja ekrana nije uspio -Comment[sr@latin]=Pokušaj otključavanja ekrana nije uspeo -Comment[sv]=Misslyckat försök att låsa upp skärmen -Comment[th]=ล้มเหลวในการพยายามปลดล็อคหน้าจอ -Comment[tr]=Ekran kilidini açma denemesi başarısız oldu -Comment[ug]=ئېكراننى قۇلۇپسىزلاندۇرالمىدى -Comment[uk]=Спроба розблокування екрана завершилася невдало -Comment[vi]=Mở khoá màn hình thất bại -Comment[wa]=Li saye di dizeclawaedje del waitroûle a fwait berwete -Comment[x-test]=xxFailed attempt to unlock the screenxx -Comment[zh_CN]=尝试解锁屏幕失败 -Comment[zh_TW]=螢幕解除鎖定失敗 -Action=None diff --git a/krunner/lock/lockdlg.cc b/krunner/lock/lockdlg.cc deleted file mode 100644 index 14a9b34..0000000 --- a/krunner/lock/lockdlg.cc +++ /dev/null @@ -1,667 +0,0 @@ -//=========================================================================== -// -// This file is part of the KDE project -// -// Copyright 1999 Martin R. Jones -// Copyright 2003 Chris Howells -// Copyright 2003 Oswald Buddenhagen - -#include // HAVE_PAM - -#include "lockprocess.h" -#include "lockdlg.h" - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -// #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include - -#ifndef AF_LOCAL -# define AF_LOCAL AF_UNIX -#endif - -#define PASSDLG_HIDE_TIMEOUT 10000 - -//=========================================================================== -// -// Simple dialog for entering a password. -// -PasswordDlg::PasswordDlg(LockProcess *parent, GreeterPluginHandle *plugin, const QString &text) - : KDialog(parent, Qt::X11BypassWindowManagerHint), - mPlugin( plugin ), - mCapsLocked(-1), - mUnlockingFailed(false), - sNot(0) -{ - QWidget* w = mainWidget(); - - QLabel *pixLabel = new QLabel( w ); - pixLabel->setPixmap(DesktopIcon(QLatin1String( "system-lock-screen" ))); - - KUser user; QString fullName=user.property(KUser::FullName).toString(); - QString greetString = text; - if (text.isEmpty()) { - greetString = fullName.isEmpty() ? - i18n("The session is locked
") : - i18n("The session was locked by %1
", fullName ); - } - QLabel *greetLabel = new QLabel(greetString, w); - - mStatusLabel = new QLabel( QLatin1String( " " ), w ); - mStatusLabel->setAlignment( Qt::AlignCenter ); - - greet = plugin->info->create(this, w, QString(), - KGreeterPlugin::Authenticate, - KGreeterPlugin::ExUnlock); - - KSeparator *sep = new KSeparator( Qt::Horizontal, w ); - - ok = new KPushButton( KGuiItem(i18n("Unl&ock"), QLatin1String( "object-unlocked" )), w ); - cancel = new KPushButton( KStandardGuiItem::cancel(), w ); - mNewSessButton = new KPushButton( KGuiItem(i18n("Sw&itch User..."), QLatin1String( "fork" )), w ); - - // Using keyboard layout component - KPluginFactory *kxkbFactory = KPluginLoader(QLatin1String( "keyboard_layout_widget" )).factory(); - QWidget *kxkbComponent = NULL; - if (kxkbFactory) { - kxkbComponent = kxkbFactory->create(this); - } - else { - kDebug() << "can't load keyboard layout widget library"; - } - - QHBoxLayout *layStatus = new QHBoxLayout(); - layStatus->addStretch(); - layStatus->addWidget( mStatusLabel ); - layStatus->addStretch(); - - if( kxkbComponent ) { - //TODO: without this the widget is off the parent area, but we need something better here - kxkbComponent->setFixedSize(48, 24); - layStatus->addWidget( kxkbComponent, 0, Qt::AlignRight ); - } - - QHBoxLayout *layButtons = new QHBoxLayout(); - layButtons->addWidget( mNewSessButton ); - layButtons->addStretch(); - layButtons->addWidget( ok ); - layButtons->addWidget( cancel ); - - frameLayout = new QGridLayout( w ); - frameLayout->setSpacing( KDialog::spacingHint() ); - frameLayout->setMargin( KDialog::marginHint() ); - frameLayout->addWidget( pixLabel, 0, 0, 3, 1, Qt::AlignTop ); - frameLayout->addWidget( greetLabel, 0, 1 ); - frameLayout->addWidget( greet->getWidgets().first(), 1, 1 ); - frameLayout->addLayout( layStatus, 2, 1 ); - frameLayout->addWidget( sep, 3, 0, 1, 2 ); - frameLayout->addLayout( layButtons, 4, 0, 1, 2 ); - - setButtons(None); - connect(cancel, SIGNAL(clicked()), SLOT(reject())); - connect(ok, SIGNAL(clicked()), SLOT(slotOK())); - connect(mNewSessButton, SIGNAL(clicked()), SLOT(slotSwitchUser())); - - if (!text.isEmpty() || !KDisplayManager().isSwitchable() || !KAuthorized::authorizeKAction(QLatin1String( "switch_user" ))) - mNewSessButton->hide(); - - installEventFilter(this); - - mFailedTimerId = 0; - mTimeoutTimerId = startTimer(PASSDLG_HIDE_TIMEOUT); - connect(qApp, SIGNAL(activity()), SLOT(slotActivity()) ); - - greet->start(); - - capsLocked(); -} - -PasswordDlg::~PasswordDlg() -{ - hide(); - delete greet; -} - -void PasswordDlg::updateLabel() -{ - if (mUnlockingFailed) - { - QPalette palette; - KColorScheme::adjustForeground(palette, KColorScheme::NormalText, QPalette::WindowText); - mStatusLabel->setPalette(palette); - mStatusLabel->setText(i18n("Unlocking failed")); - } - else - if (mCapsLocked) - { - QPalette palette = mStatusLabel->palette(); - KColorScheme::adjustForeground(palette, KColorScheme::NegativeText, QPalette::WindowText); - mStatusLabel->setPalette(palette); - mStatusLabel->setText(i18n("Warning: Caps Lock on")); - } - else - { - mStatusLabel->setText(QLatin1String( " " )); - } -} - -//--------------------------------------------------------------------------- -// -// Handle timer events. -// -void PasswordDlg::timerEvent(QTimerEvent *ev) -{ - if (ev->timerId() == mTimeoutTimerId) - { - done(TIMEOUT_CODE); - } - else if (ev->timerId() == mFailedTimerId) - { - killTimer(mFailedTimerId); - mFailedTimerId = 0; - // Show the normal password prompt. - mUnlockingFailed = false; - updateLabel(); - ok->setEnabled(true); - cancel->setEnabled(true); - mNewSessButton->setEnabled( true ); - greet->revive(); - greet->start(); - } -} - -bool PasswordDlg::eventFilter(QObject *, QEvent *ev) -{ - if (ev->type() == QEvent::KeyPress || ev->type() == QEvent::KeyRelease) - capsLocked(); - return false; -} - -void PasswordDlg::slotActivity() -{ - if (mTimeoutTimerId) { - killTimer(mTimeoutTimerId); - mTimeoutTimerId = startTimer(PASSDLG_HIDE_TIMEOUT); - } -} - -////// kckeckpass interface code - -int PasswordDlg::Reader (void *buf, int count) -{ - int ret, rlen; - - for (rlen = 0; rlen < count; ) { - dord: - ret = ::read (sFd, (void *)((char *)buf + rlen), count - rlen); - if (ret < 0) { - if (errno == EINTR) - goto dord; - if (errno == EAGAIN) - break; - return -1; - } - if (!ret) - break; - rlen += ret; - } - return rlen; -} - -bool PasswordDlg::GRead (void *buf, int count) -{ - return Reader (buf, count) == count; -} - -bool PasswordDlg::GWrite (const void *buf, int count) -{ - return ::write (sFd, buf, count) == count; -} - -bool PasswordDlg::GSendInt (int val) -{ - return GWrite (&val, sizeof(val)); -} - -bool PasswordDlg::GSendStr (const char *buf) -{ - int len = buf ? ::strlen (buf) + 1 : 0; - return GWrite (&len, sizeof(len)) && GWrite (buf, len); -} - -bool PasswordDlg::GSendArr (int len, const char *buf) -{ - return GWrite (&len, sizeof(len)) && GWrite (buf, len); -} - -bool PasswordDlg::GRecvInt (int *val) -{ - return GRead (val, sizeof(*val)); -} - -bool PasswordDlg::GRecvArr (char **ret) -{ - int len; - char *buf; - - if (!GRecvInt(&len)) - return false; - if (!len) { - *ret = 0; - return true; - } - if (!(buf = (char *)::malloc (len))) - return false; - *ret = buf; - if (GRead (buf, len)) { - return true; - } else { - ::free(buf); - *ret = 0; - return false; - } -} - -void PasswordDlg::reapVerify() -{ - sNot->setEnabled( false ); - sNot->deleteLater(); - sNot = 0; - ::close( sFd ); - int status; - while (::waitpid( sPid, &status, 0 ) < 0) - if (errno != EINTR) { // This should not happen ... - cantCheck(); - return; - } - if (WIFEXITED(status)) - switch (WEXITSTATUS(status)) { - case AuthOk: - greet->succeeded(); - accept(); - return; - case AuthBad: - greet->failed(); - mUnlockingFailed = true; - updateLabel(); - mFailedTimerId = startTimer(1500); - ok->setEnabled(false); - cancel->setEnabled(false); - mNewSessButton->setEnabled( false ); - KNotification::event( QLatin1String( "unlockfailed" ) ); - return; - case AuthAbort: - return; - } - cantCheck(); -} - -void PasswordDlg::handleVerify() -{ - int ret; - char *arr; - - if (GRecvInt( &ret )) { - switch (ret) { - case ConvGetBinary: - if (!GRecvArr( &arr )) - break; - greet->binaryPrompt( arr, false ); - if (arr) - ::free( arr ); - return; - case ConvGetNormal: - if (!GRecvArr( &arr )) - break; - greet->textPrompt( arr, true, false ); - if (arr) - ::free( arr ); - return; - case ConvGetHidden: - if (!GRecvArr( &arr )) - break; - greet->textPrompt( arr, false, false ); - if (arr) - ::free( arr ); - return; - case ConvPutInfo: - if (!GRecvArr( &arr )) - break; - if (!greet->textMessage( arr, false )) - static_cast< LockProcess* >(parent())->msgBox( this, QMessageBox::Information, QString::fromLocal8Bit( arr ) ); - ::free( arr ); - return; - case ConvPutError: - if (!GRecvArr( &arr )) - break; - if (!greet->textMessage( arr, true )) - static_cast< LockProcess* >(parent())->msgBox( this, QMessageBox::Warning, QString::fromLocal8Bit( arr ) ); - ::free( arr ); - return; - } - } - reapVerify(); -} - -////// greeter plugin callbacks - -void PasswordDlg::gplugReturnText( const char *text, int tag ) -{ - GSendStr( text ); - if (text) - GSendInt( tag ); -} - -void PasswordDlg::gplugReturnBinary( const char *data ) -{ - if (data) { - unsigned const char *up = (unsigned const char *)data; - int len = up[3] | (up[2] << 8) | (up[1] << 16) | (up[0] << 24); - if (!len) - GSendArr( 4, data ); - else - GSendArr( len, data ); - } else - GSendArr( 0, 0 ); -} - -void PasswordDlg::gplugSetUser( const QString & ) -{ - // ignore ... -} - -void PasswordDlg::cantCheck() -{ - greet->failed(); - static_cast< LockProcess* >(parent())->msgBox( this, QMessageBox::Critical, - i18n("Cannot unlock the session because the authentication system failed to work;\n" - "you must kill kscreenlocker (pid %1) manually.", getpid()) ); - greet->revive(); -} - -//--------------------------------------------------------------------------- -// -// Starts the kcheckpass process to check the user's password. -// -void PasswordDlg::gplugStart() -{ - int sfd[2]; - char fdbuf[16]; - - if (sNot) - return; - if (::socketpair(AF_LOCAL, SOCK_STREAM, 0, sfd)) { - cantCheck(); - return; - } - if ((sPid = ::fork()) < 0) { - ::close(sfd[0]); - ::close(sfd[1]); - cantCheck(); - return; - } - if (!sPid) { - ::close(sfd[0]); - sprintf(fdbuf, "%d", sfd[1]); - execlp(QFile::encodeName(KStandardDirs::findExe(QLatin1String( "kcheckpass" ))).data(), - "kcheckpass", - "-m", mPlugin->info->method, - "-S", fdbuf, - (char *)0); - _exit(20); - } - ::close(sfd[1]); - sFd = sfd[0]; - sNot = new QSocketNotifier(sFd, QSocketNotifier::Read, this); - connect(sNot, SIGNAL(activated(int)), SLOT(handleVerify())); -} - -void PasswordDlg::gplugChanged() -{ -} - -void PasswordDlg::gplugActivity() -{ - slotActivity(); -} - -void PasswordDlg::gplugMsgBox( QMessageBox::Icon type, const QString &text ) -{ - static_cast< LockProcess* >(parent())->msgBox( this, type, text ); -} - -bool PasswordDlg::gplugHasNode( const QString & ) -{ - return false; -} - -void PasswordDlg::slotOK() -{ - greet->next(); -} - - -void PasswordDlg::setVisible( bool visible ) -{ - QDialog::setVisible( visible ); - - if ( visible ) - QApplication::flush(); -} - -void PasswordDlg::slotStartNewSession() -{ - if (!KMessageBox::shouldBeShownContinue( QLatin1String( ":confirmNewSession" ) )) { - KDisplayManager().startReserve(); - return; - } - - killTimer(mTimeoutTimerId); - mTimeoutTimerId = 0; - - KDialog *dialog = new KDialog( this, Qt::X11BypassWindowManagerHint ); - dialog->setModal( true ); - dialog->setButtons( KDialog::Yes | KDialog::No ); - dialog->setButtonGuiItem( KDialog::Yes, KGuiItem(i18n("&Start New Session"), QLatin1String( "fork" )) ); - dialog->setButtonGuiItem( KDialog::No, KStandardGuiItem::cancel() ); - dialog->setDefaultButton( KDialog::Yes ); - dialog->setEscapeButton( KDialog::No ); - - bool dontAskAgain = false; - - KMessageBox::createKMessageBox( dialog, QMessageBox::Warning, - i18n("You have chosen to open another desktop session " - "instead of resuming the current one.\n" - "The current session will be hidden " - "and a new login screen will be displayed.\n" - "An F-key is assigned to each session; " - "F%1 is usually assigned to the first session, " - "F%2 to the second session and so on. " - "You can switch between sessions by pressing " - "Ctrl, Alt and the appropriate F-key at the same time. " - "Additionally, the KDE Panel and Desktop menus have " - "actions for switching between sessions.", - 7, 8), - QStringList(), - i18n("&Do not ask again"), &dontAskAgain, - KMessageBox::NoExec ); - - int ret = static_cast< LockProcess* >( parent())->execDialog( dialog ); - - delete dialog; - - if (ret == KDialog::Yes) { - if (dontAskAgain) - KMessageBox::saveDontShowAgainContinue( QLatin1String( ":confirmNewSession" ) ); - KDisplayManager().startReserve(); - } - - mTimeoutTimerId = startTimer(PASSDLG_HIDE_TIMEOUT); -} - -class LockListViewItem : public QTreeWidgetItem { -public: - LockListViewItem( QTreeWidget *parent, - const QString &sess, const QString &loc, int _vt ) - : QTreeWidgetItem( parent ) - , vt( _vt ) - { - setText( 0, sess ); - setText( 1, loc ); - } - - int vt; -}; - -void PasswordDlg::slotSwitchUser() -{ - int p = 0; - KDisplayManager dm; - - QDialog dialog( this, Qt::X11BypassWindowManagerHint ); - dialog.setModal( true ); - - QBoxLayout *hbox = new QHBoxLayout( &dialog ); - hbox->setSpacing( KDialog::spacingHint() ); - hbox->setMargin( KDialog::marginHint() ); - - QBoxLayout *vbox1 = new QVBoxLayout( ); - hbox->addItem( vbox1 ); - QBoxLayout *vbox2 = new QVBoxLayout( ); - hbox->addItem( vbox2 ); - - KPushButton *btn; - - SessList sess; - if (dm.localSessions( sess )) { - - lv = new QTreeWidget( &dialog ); - connect( lv, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)), SLOT(slotSessionActivated()) ); - connect( lv, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)), &dialog, SLOT(reject()) ); - lv->setAllColumnsShowFocus( true ); - lv->setHeaderLabels( QStringList() << i18n("Session") << i18n("Location") ); - lv->header()->setResizeMode( 0, QHeaderView::Stretch ); - lv->header()->setResizeMode( 1, QHeaderView::Stretch ); - QTreeWidgetItem *itm = 0; - QString user, loc; - int ns = 0; - for (SessList::ConstIterator it = sess.constBegin(); it != sess.constEnd(); ++it) { - KDisplayManager::sess2Str2( *it, user, loc ); - itm = new LockListViewItem( lv, user, loc, (*it).vt ); - if (!(*it).vt) - itm->setFlags( itm->flags() & ~Qt::ItemIsEnabled ); - if ((*it).self) { - lv->setCurrentItem( itm ); - itm->setSelected( true ); - } - ns++; - } - int fw = lv->frameWidth() * 2; - QSize hds( lv->header()->sizeHint() ); - lv->setMinimumWidth( fw + hds.width() + - (ns > 10 ? style()->pixelMetric(QStyle::PM_ScrollBarExtent) : 0 ) ); - int ih = lv->itemDelegate()->sizeHint( - QStyleOptionViewItem(), lv->model()->index( 0, 0 ) ).height(); - lv->setFixedHeight( fw + hds.height() + - ih * (ns < 6 ? 6 : ns > 10 ? 10 : ns) ); - lv->header()->adjustSize(); - vbox1->addWidget( lv ); - - btn = new KPushButton( KGuiItem(i18nc("session", "&Activate"), QLatin1String( "fork" )), &dialog ); - connect( btn, SIGNAL(clicked()), SLOT(slotSessionActivated()) ); - connect( btn, SIGNAL(clicked()), &dialog, SLOT(reject()) ); - vbox2->addWidget( btn ); - vbox2->addStretch( 2 ); - } - - if (KAuthorized::authorizeKAction(QLatin1String( "start_new_session" )) && (p = dm.numReserve()) >= 0) - { - btn = new KPushButton( KGuiItem(i18n("Start &New Session"), QLatin1String( "fork" )), &dialog ); - connect( btn, SIGNAL(clicked()), SLOT(slotStartNewSession()) ); - connect( btn, SIGNAL(clicked()), &dialog, SLOT(reject()) ); - if (!p) - btn->setEnabled( false ); - vbox2->addWidget( btn ); - vbox2->addStretch( 1 ); - } - - btn = new KPushButton( KStandardGuiItem::cancel(), &dialog ); - connect( btn, SIGNAL(clicked()), &dialog, SLOT(reject()) ); - vbox2->addWidget( btn ); - - static_cast< LockProcess* >(parent())->execDialog( &dialog ); -} - -void PasswordDlg::slotSessionActivated() -{ - LockListViewItem *itm = (LockListViewItem *)lv->currentItem(); - if (itm && itm->vt > 0) - KDisplayManager().switchVT( itm->vt ); -} - -void PasswordDlg::capsLocked() -{ - unsigned int lmask; - Window dummy1, dummy2; - int dummy3, dummy4, dummy5, dummy6; - XQueryPointer(QX11Info::display(), DefaultRootWindow( QX11Info::display() ), &dummy1, &dummy2, &dummy3, &dummy4, &dummy5, &dummy6, &lmask); - mCapsLocked = lmask & LockMask; - updateLabel(); -} - -#include "lockdlg.moc" diff --git a/krunner/lock/lockdlg.h b/krunner/lock/lockdlg.h deleted file mode 100644 index f25e55f..0000000 --- a/krunner/lock/lockdlg.h +++ /dev/null @@ -1,96 +0,0 @@ -//=========================================================================== -// -// This file is part of the KDE project -// -// Copyright 1999 Martin R. Jones -// Copyright 2003 Oswald Buddenhagen -// - -#ifndef __LOCKDLG_H__ -#define __LOCKDLG_H__ - -#include - -#include - -#include -#include -#include -#include -#include - -struct GreeterPluginHandle; -class LockProcess; -class QFrame; -class QGridLayout; -class QLabel; -class KPushButton; -class QSocketNotifier; -class QTreeWidget; - -//=========================================================================== -// -// Simple dialog for entering a password. -// It does not handle password validation. -// -class PasswordDlg : public KDialog, public KGreeterPluginHandler -{ - Q_OBJECT - -public: - PasswordDlg(LockProcess *parent, GreeterPluginHandle *plugin, const QString &text = QString()); - ~PasswordDlg(); - virtual void setVisible(bool visible); - - // from KGreetPluginHandler - virtual void gplugReturnText( const char *text, int tag ); - virtual void gplugReturnBinary( const char *data ); - virtual void gplugSetUser( const QString & ); - virtual void gplugStart(); - virtual void gplugChanged(); - virtual void gplugActivity(); - virtual void gplugMsgBox( QMessageBox::Icon type, const QString &text ); - virtual bool gplugHasNode( const QString &id ); - -protected: - virtual void timerEvent(QTimerEvent *); - virtual bool eventFilter(QObject *, QEvent *); - -private Q_SLOTS: - void slotSwitchUser(); - void slotSessionActivated(); - void slotStartNewSession(); - void slotOK(); - void slotActivity(); - void handleVerify(); - -private: - void capsLocked(); - void updateLabel(); - int Reader (void *buf, int count); - bool GRead (void *buf, int count); - bool GWrite (const void *buf, int count); - bool GSendInt (int val); - bool GSendStr (const char *buf); - bool GSendArr (int len, const char *buf); - bool GRecvInt (int *val); - bool GRecvArr (char **buf); - void reapVerify(); - void cantCheck(); - GreeterPluginHandle *mPlugin; - KGreeterPlugin *greet; - QFrame *frame; - QGridLayout *frameLayout; - QLabel *mStatusLabel; - KPushButton *mNewSessButton, *ok, *cancel; - int mFailedTimerId; - int mTimeoutTimerId; - int mCapsLocked; - bool mUnlockingFailed; - int sPid, sFd; - QSocketNotifier *sNot; - QTreeWidget *lv; -}; - -#endif - diff --git a/krunner/lock/lockprocess.cc b/krunner/lock/lockprocess.cc deleted file mode 100644 index 65c7f1d..0000000 --- a/krunner/lock/lockprocess.cc +++ /dev/null @@ -1,1808 +0,0 @@ -//=========================================================================== -// -// This file is part of the KDE project -// -// Copyright 1999 Martin R. Jones -// Copyright 2003 Oswald Buddenhagen -// Copyright 2008 Chani Armitage -// - -//krunner keeps running and checks user inactivity -//when it should show screensaver (and maybe lock the session), -//it starts kscreenlocker, who does all the locking and who -//actually starts the screensaver - -//It's done this way to prevent screen unlocking when krunner -//crashes - -#include "lockprocess.h" -#include "lockprocessadaptor.h" - -#include -#include -#include -#include "lockdlg.h" -#include "autologout.h" -#include "kscreensaversettings.h" - -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include // % operator for QString - -#include - -#include -#include -#include -#include -#ifdef HAVE_SETPRIORITY -#include -#include -#endif - -#include -#include -#include -#include - -#ifdef HAVE_DPMS -extern "C" { -#include -#ifndef Bool -#define Bool BOOL -#endif -#include - -#ifndef HAVE_DPMSINFO_PROTO -Status DPMSInfo ( Display *, CARD16 *, BOOL * ); -#endif -} -#endif - -#ifdef HAVE_XF86MISC -#include -#endif - -#ifdef HAVE_GLXCHOOSEVISUAL -#include -#endif - -#define LOCK_GRACE_DEFAULT 5000 -#define AUTOLOGOUT_DEFAULT 600 - -static Window gVRoot = 0; -static Window gVRootData = 0; -static Atom gXA_VROOT; -static Atom gXA_SCREENSAVER_VERSION; - -//#define CHECK_XSELECTINPUT -#ifdef CHECK_XSELECTINPUT -#include -static bool check_xselectinput = false; -extern "C" -int XSelectInput( Display* dpy, Window w, long e ) -{ - typedef int (*ptr)(Display*, Window, long); - static ptr fun = NULL; - if( fun == NULL ) - fun = (ptr)dlsym( RTLD_NEXT, "XSelectInput" ); - if( check_xselectinput && w == DefaultRootWindow( dpy )) - kDebug() << kBacktrace(); - return fun( dpy, w, e ); -} -#endif - -static QLatin1String s_overlayServiceName("org.kde.plasma-overlay"); - -//=========================================================================== -// -// Screen saver handling process. Handles screensaver window, -// starting screensaver hacks, and password entry.f -// -LockProcess::LockProcess(bool child, bool useBlankOnly) - : QWidget(0L, Qt::X11BypassWindowManagerHint), - mInitialLock(false), - mLocked(false), - mBusy(false), - mPlasmaDBus(0), - mServiceWatcher(0), - mSetupMode(false), - mOpenGLVisual(false), - child_saver(child), - mParent(0), - mUseBlankOnly(useBlankOnly), - mSuspended(false), - mVisibility(false), - mEventRecursed(false), - mRestoreXF86Lock(false), - mForbidden(false), - mAutoLogoutTimerId(0) -{ - setObjectName(QLatin1String( "save window" )); - setupSignals(); - - new LockProcessAdaptor(this); - QDBusConnection::sessionBus().registerService(QLatin1String( "org.kde.screenlocker" )); - QDBusConnection::sessionBus().registerObject(QLatin1String( "/LockProcess" ), this); - - kapp->installX11EventFilter(this); - - // Get root window size - XWindowAttributes rootAttr; - QX11Info info; - XGetWindowAttributes(QX11Info::display(), RootWindow(QX11Info::display(), - info.screen()), &rootAttr); - kapp->desktop(); // make Qt set its event mask on the root window first - XSelectInput( QX11Info::display(), QX11Info::appRootWindow(), - SubstructureNotifyMask | rootAttr.your_event_mask ); -#ifdef CHECK_XSELECTINPUT - check_xselectinput = true; -#endif - setGeometry(0, 0, rootAttr.width, rootAttr.height); - - // virtual root property - gXA_VROOT = XInternAtom (QX11Info::display(), "__SWM_VROOT", False); - gXA_SCREENSAVER_VERSION = XInternAtom (QX11Info::display(), "_SCREENSAVER_VERSION", False); - - connect(&mHackProc, SIGNAL(finished(int, QProcess::ExitStatus)), - SLOT(hackExited())); - - mSuspendTimer.setSingleShot(true); - connect(&mSuspendTimer, SIGNAL(timeout()), SLOT(suspend())); - - const QStringList dmopt = - QString::fromLatin1( ::getenv( "XDM_MANAGED" )).split(QLatin1Char(','), QString::SkipEmptyParts); - for (QStringList::ConstIterator it = dmopt.constBegin(); it != dmopt.constEnd(); ++it) - if ((*it).startsWith(QLatin1String( "method=" ))) - mMethod = (*it).mid(7); - - configure(); - -#ifdef HAVE_DPMS - if (mDPMSDepend) { - BOOL on; - CARD16 state; - DPMSInfo(QX11Info::display(), &state, &on); - if (on) - { - connect(&mCheckDPMS, SIGNAL(timeout()), SLOT(checkDPMSActive())); - // we can save CPU if we stop it as quickly as possible - // but we waste CPU if we check too often -> so take 10s - mCheckDPMS.start(10000); - } - } -#endif - - greetPlugin.library = 0; - - mSuppressUnlock.setSingleShot(true); - connect(&mSuppressUnlock, SIGNAL(timeout()), SLOT(deactivatePlasma())); - - // read the initial information about all toplevel windows - Window r, p; - Window* real; - unsigned nreal; - if( XQueryTree( x11Info().display(), x11Info().appRootWindow(), &r, &p, &real, &nreal ) - && real != NULL ) { - KXErrorHandler err; // ignore X errors here - for( unsigned i = 0; i < nreal; ++i ) { - XWindowAttributes winAttr; - if (XGetWindowAttributes(QX11Info::display(), real[ i ], &winAttr)) { - WindowInfo info; - info.window = real[ i ]; - info.viewable = ( winAttr.map_state == IsViewable ); - windowInfo.append( info ); // ordered bottom to top - } - } - XFree( real ); - } -} - -//--------------------------------------------------------------------------- -// -// Destructor - usual cleanups. -// -LockProcess::~LockProcess() -{ - if (greetPlugin.library) { - if (greetPlugin.info->done) - greetPlugin.info->done(); - greetPlugin.library->unload(); - } -} - -static int signal_pipe[2]; - -static void sigterm_handler(int) -{ - char tmp = 'T'; - ::write( signal_pipe[1], &tmp, 1); -} - -static void sighup_handler(int) -{ - char tmp = 'H'; - ::write( signal_pipe[1], &tmp, 1); -} - -static void sigusr1_handler(int) -{ - char tmp = '1'; - ::write(signal_pipe[1], &tmp, 1); -} - -void LockProcess::timerEvent(QTimerEvent *ev) -{ - if (ev->timerId() == mAutoLogoutTimerId) - { - AutoLogout autologout(this); - execDialog(&autologout); - } -} - -void LockProcess::setupSignals() -{ - struct sigaction act; - sigemptyset(&(act.sa_mask)); - act.sa_flags = 0; - // ignore SIGINT - act.sa_handler=SIG_IGN; - sigaction(SIGINT, &act, 0L); - // ignore SIGQUIT - //act.sa_handler=SIG_IGN; - sigaction(SIGQUIT, &act, 0L); - // exit cleanly on SIGTERM - act.sa_handler= sigterm_handler; - sigaction(SIGTERM, &act, 0L); - // SIGHUP forces lock - act.sa_handler= sighup_handler; - sigaction(SIGHUP, &act, 0L); - // SIGUSR1 simulates user activity - act.sa_handler= sigusr1_handler; - sigaction(SIGUSR1, &act, 0L); - - pipe(signal_pipe); - QSocketNotifier* notif = new QSocketNotifier(signal_pipe[0], QSocketNotifier::Read, this); - connect( notif, SIGNAL(activated(int)), SLOT(signalPipeSignal())); -} - - -void LockProcess::signalPipeSignal() -{ - char tmp; - ::read( signal_pipe[0], &tmp, 1); - if (tmp == 'T') { - quitSaver(); - } else if (tmp == '1') { - // In case SimulateUserActivity (SIGUSR1) is called during the dead-time (mBusy == true). - mInitialLock = true; - if (!mBusy && mDialogs.isEmpty()) { - mBusy = true; - quit(); - mBusy = false; - } - } else if (tmp == 'H') { - if( !mLocked ) - startLock(); - } -} - -//--------------------------------------------------------------------------- -bool LockProcess::lock(bool initial) -{ - if (startSaver()) { - // In case of a forced lock we don't react to events during - // the dead-time to give the screensaver some time to activate. - // That way we don't accidentally show the password dialog before - // the screensaver kicks in because the user moved the mouse after - // selecting "lock screen", that looks really untidy. - mBusy = true; - mInitialLock = initial; - if (startLock()) - { - QTimer::singleShot(1000, this, SLOT(slotDeadTimePassed())); - return true; - } - stopSaver(); - mBusy = false; - } - return false; -} -//--------------------------------------------------------------------------- -void LockProcess::slotDeadTimePassed() -{ - if (mInitialLock) - quit(); - mBusy = false; -} - -//--------------------------------------------------------------------------- -bool LockProcess::defaultSave() -{ - mLocked = false; - if (startSaver()) { - if (mLockGrace >= 0) - QTimer::singleShot(mLockGrace, this, SLOT(startLock())); - return true; - } - return false; -} - -bool LockProcess::startSetup() -{ - mPlasmaEnabled = true; //force it on in case the user didn't click apply yet - mLocked = false; - mSetupMode = true; - return startSaver(); - //plasma startup will handle the suppressunlock bit -} -//--------------------------------------------------------------------------- -bool LockProcess::dontLock() -{ - mLocked = false; - return startSaver(); -} - -//--------------------------------------------------------------------------- -void LockProcess::quitSaver() -{ - stopSaver(); - qApp->quit(); -} - -//--------------------------------------------------------------------------- -// -// Read and apply configuration. -// -void LockProcess::configure() -{ - // the configuration is stored in krunner's config file - if( KScreenSaverSettings::lock() ) { - mLockGrace = KScreenSaverSettings::lockGrace(); - if (mLockGrace < 0) - mLockGrace = 0; - else if (mLockGrace > 300000) - mLockGrace = 300000; // 5 minutes, keep the value sane - } else { - mLockGrace = -1; - } - - mAutoLogoutTimeout = KScreenSaverSettings::autoLogout() ? - KScreenSaverSettings::autoLogoutTimeout() : 0; - -#ifdef HAVE_DPMS - mDPMSDepend = KScreenSaverSettings::suspendWhenInvisible(); -#endif - - mPriority = KScreenSaverSettings::priority(); - if (mPriority < 0) mPriority = 0; - if (mPriority > 19) mPriority = 19; - - mSaver = KScreenSaverSettings::saver(); - if (mSaver.isEmpty() || mUseBlankOnly) { - mSaver = QLatin1String( "kblank.desktop" ); - } - - readSaver(); - - mPlasmaEnabled = KScreenSaverSettings::plasmaEnabled(); - - mSuppressUnlockTimeout = qMax(0, KScreenSaverSettings::timeout() * 1000); - mSuppressUnlockTimeout = qMax(mSuppressUnlockTimeout, 30 * 1000); //min. 30 secs FIXME is this a good idea? - - mPlugins = KScreenSaverSettings::pluginsUnlock(); - if (mPlugins.isEmpty()) { - mPlugins << QLatin1String( "classic" ) << QLatin1String( "generic" ); - } - mPluginOptions = KScreenSaverSettings::pluginOptions(); -} - -//--------------------------------------------------------------------------- -// -// Read the command line needed to run the screensaver given a .desktop file. -// -void LockProcess::readSaver() -{ - if (!mSaver.isEmpty()) - { - QString entryName = mSaver; - if( entryName.endsWith( QLatin1String( ".desktop" ) )) - entryName = entryName.left( entryName.length() - 8 ); // strip it - const KService::List offers = KServiceTypeTrader::self()->query( QLatin1String( "ScreenSaver" ), - QLatin1String( "DesktopEntryName == '" ) + entryName.toLower() + QLatin1Char( '\'' ) ); - if( offers.isEmpty() ) - { - kDebug(1204) << "Cannot find screesaver: " << mSaver; - return; - } - const QString file = KStandardDirs::locate("services", offers.first()->entryPath()); - - const bool opengl = KAuthorized::authorizeKAction(QLatin1String( "opengl_screensavers" )); - const bool manipulatescreen = KAuthorized::authorizeKAction(QLatin1String( "manipulatescreen_screensavers" )); - KDesktopFile config( file ); - KConfigGroup desktopGroup = config.desktopGroup(); - foreach (const QString &type, desktopGroup.readEntry("X-KDE-Type").split(QLatin1Char(';'))) { - if (type == QLatin1String("ManipulateScreen")) { - if (!manipulatescreen) { - kDebug(1204) << "Screensaver is type ManipulateScreen and ManipulateScreen is forbidden"; - mForbidden = true; - } - } else if (type == QLatin1String("OpenGL")) { - mOpenGLVisual = true; - if (!opengl) { - kDebug(1204) << "Screensaver is type OpenGL and OpenGL is forbidden"; - mForbidden = true; - } - } - } - - kDebug(1204) << "mForbidden: " << (mForbidden ? "true" : "false"); - - if (config.hasActionGroup(QLatin1String( "Root" ))) - { - mSaverExec = config.actionGroup(QLatin1String( "Root" )).readPathEntry("Exec", QString()); - } - } -} - -//--------------------------------------------------------------------------- -// -// Create a window to draw our screen saver on. -// -void LockProcess::createSaverWindow() -{ - Visual* visual = CopyFromParent; - int depth = CopyFromParent; - XSetWindowAttributes attrs; - int flags = CWOverrideRedirect; -#ifdef HAVE_GLXCHOOSEVISUAL -// this code is (partially) duplicated in kdebase/workspace/kcontrol/screensaver - if( mOpenGLVisual ) - { - static const int attribs[][ 15 ] = - { - #define R GLX_RED_SIZE - #define G GLX_GREEN_SIZE - #define B GLX_BLUE_SIZE - { GLX_RGBA, R, 8, G, 8, B, 8, GLX_DEPTH_SIZE, 8, GLX_DOUBLEBUFFER, GLX_STENCIL_SIZE, 1, None }, - { GLX_RGBA, R, 4, G, 4, B, 4, GLX_DEPTH_SIZE, 4, GLX_DOUBLEBUFFER, GLX_STENCIL_SIZE, 1, None }, - { GLX_RGBA, R, 8, G, 8, B, 8, GLX_DEPTH_SIZE, 8, GLX_DOUBLEBUFFER, None }, - { GLX_RGBA, R, 4, G, 4, B, 4, GLX_DEPTH_SIZE, 4, GLX_DOUBLEBUFFER, None }, - { GLX_RGBA, R, 8, G, 8, B, 8, GLX_DEPTH_SIZE, 8, GLX_STENCIL_SIZE, 1, None }, - { GLX_RGBA, R, 4, G, 4, B, 4, GLX_DEPTH_SIZE, 4, GLX_STENCIL_SIZE, 1, None }, - { GLX_RGBA, R, 8, G, 8, B, 8, GLX_DEPTH_SIZE, 8, None }, - { GLX_RGBA, R, 4, G, 4, B, 4, GLX_DEPTH_SIZE, 4, None }, - { GLX_RGBA, GLX_DEPTH_SIZE, 8, GLX_DOUBLEBUFFER, GLX_STENCIL_SIZE, 1, None }, - { GLX_RGBA, GLX_DEPTH_SIZE, 8, GLX_DOUBLEBUFFER, None }, - { GLX_RGBA, GLX_DEPTH_SIZE, 8, GLX_STENCIL_SIZE, 1, None }, - { GLX_RGBA, GLX_DEPTH_SIZE, 8, None } - #undef R - #undef G - #undef B - }; - for( unsigned int i = 0; - i < sizeof( attribs ) / sizeof( attribs[ 0 ] ); - ++i ) - { - if( XVisualInfo* info = glXChooseVisual( x11Info().display(), x11Info().screen(), const_cast(attribs[ i ]) )) - { - visual = info->visual; - depth = info->depth; - static Colormap colormap = 0; - if( colormap != 0 ) - XFreeColormap( x11Info().display(), colormap ); - colormap = XCreateColormap( x11Info().display(), RootWindow( x11Info().display(), x11Info().screen()), visual, AllocNone ); - attrs.colormap = colormap; - flags |= CWColormap; - XFree( info ); - break; - } - } - } -#endif - attrs.override_redirect = 1; - hide(); - Window w = XCreateWindow( x11Info().display(), RootWindow( x11Info().display(), x11Info().screen()), - x(), y(), width(), height(), 0, depth, InputOutput, visual, flags, &attrs ); - - create( w, false, true ); - - // Some xscreensaver hacks check for this property - const char *version = "KDE 4.0"; - XChangeProperty (QX11Info::display(), winId(), - gXA_SCREENSAVER_VERSION, XA_STRING, 8, PropModeReplace, - (unsigned char *) version, strlen(version)); - - - XSetWindowAttributes attr; - attr.event_mask = KeyPressMask | ButtonPressMask | PointerMotionMask | - VisibilityChangeMask | ExposureMask; - XChangeWindowAttributes(QX11Info::display(), winId(), - CWEventMask, &attr); - - // erase(); - - // set NoBackground so that the saver can capture the current - // screen state if necessary - setAttribute(Qt::WA_PaintOnScreen, true); - setAttribute(Qt::WA_NoSystemBackground, true); - setAttribute(Qt::WA_PaintOutsidePaintEvent, true); // for bitBlt in resume() - - setCursor( Qt::BlankCursor ); - - kDebug(1204) << "Saver window Id: " << winId(); -} - -//--------------------------------------------------------------------------- -// -// Hide the screensaver window -// -void LockProcess::hideSaverWindow() -{ - hide(); - lower(); - removeVRoot(winId()); - XDeleteProperty(QX11Info::display(), winId(), gXA_SCREENSAVER_VERSION); - if ( gVRoot ) { - unsigned long vroot_data[1] = { gVRootData }; - XChangeProperty(QX11Info::display(), gVRoot, gXA_VROOT, XA_WINDOW, 32, - PropModeReplace, (unsigned char *)vroot_data, 1); - gVRoot = 0; - } - XSync(QX11Info::display(), False); -} - -//--------------------------------------------------------------------------- -static int ignoreXError(Display *, XErrorEvent *) -{ - return 0; -} - -//--------------------------------------------------------------------------- -// -// Save the current virtual root window -// -void LockProcess::saveVRoot() -{ - Window rootReturn, parentReturn, *children; - unsigned int numChildren; - QX11Info info; - Window root = RootWindowOfScreen(ScreenOfDisplay(QX11Info::display(), info.screen())); - - gVRoot = 0; - gVRootData = 0; - - int (*oldHandler)(Display *, XErrorEvent *); - oldHandler = XSetErrorHandler(ignoreXError); - - if (XQueryTree(QX11Info::display(), root, &rootReturn, &parentReturn, - &children, &numChildren)) - { - for (unsigned int i = 0; i < numChildren; i++) - { - Atom actual_type; - int actual_format; - unsigned long nitems, bytesafter; - unsigned char *newRoot = 0; - - if ((XGetWindowProperty(QX11Info::display(), children[i], gXA_VROOT, 0, 1, - False, XA_WINDOW, &actual_type, &actual_format, &nitems, &bytesafter, - &newRoot) == Success) && newRoot) - { - gVRoot = children[i]; - Window *dummy = (Window*)newRoot; - gVRootData = *dummy; - XFree ((char*) newRoot); - break; - } - } - if (children) - { - XFree((char *)children); - } - } - - XSetErrorHandler(oldHandler); -} - -//--------------------------------------------------------------------------- -// -// Set the virtual root property -// -void LockProcess::setVRoot(Window win, Window vr) -{ - if (gVRoot) - removeVRoot(gVRoot); - - QX11Info info; - unsigned long rw = RootWindowOfScreen(ScreenOfDisplay(QX11Info::display(), info.screen())); - unsigned long vroot_data[1] = { vr }; - - Window rootReturn, parentReturn, *children; - unsigned int numChildren; - Window top = win; - while (1) { - if (!XQueryTree(QX11Info::display(), top , &rootReturn, &parentReturn, - &children, &numChildren)) - return; - if (children) - XFree((char *)children); - if (parentReturn == rw) { - break; - } else - top = parentReturn; - } - - XChangeProperty(QX11Info::display(), top, gXA_VROOT, XA_WINDOW, 32, - PropModeReplace, (unsigned char *)vroot_data, 1); -} - -//--------------------------------------------------------------------------- -// -// Remove the virtual root property -// -void LockProcess::removeVRoot(Window win) -{ - XDeleteProperty (QX11Info::display(), win, gXA_VROOT); -} - -//--------------------------------------------------------------------------- -// -// Grab the keyboard. Returns true on success -// -bool LockProcess::grabKeyboard() -{ - int rv = XGrabKeyboard( QX11Info::display(), QApplication::desktop()->winId(), - True, GrabModeAsync, GrabModeAsync, CurrentTime ); - - return (rv == GrabSuccess); -} - -#define GRABEVENTS ButtonPressMask | ButtonReleaseMask | PointerMotionMask | \ - EnterWindowMask | LeaveWindowMask - -//--------------------------------------------------------------------------- -// -// Grab the mouse. Returns true on success -// -bool LockProcess::grabMouse() -{ - int rv = XGrabPointer( QX11Info::display(), QApplication::desktop()->winId(), - True, GRABEVENTS, GrabModeAsync, GrabModeAsync, None, - QCursor(Qt::BlankCursor).handle(), CurrentTime ); - - return (rv == GrabSuccess); -} - -//--------------------------------------------------------------------------- -// -// Grab keyboard and mouse. Returns true on success. -// -bool LockProcess::grabInput() -{ - XSync(QX11Info::display(), False); - - if (!grabKeyboard()) - { - sleep(1); - if (!grabKeyboard()) - { - return false; - } - } - - if (!grabMouse()) - { - sleep(1); - if (!grabMouse()) - { - XUngrabKeyboard(QX11Info::display(), CurrentTime); - return false; - } - } - - lockXF86(); - - return true; -} - -//--------------------------------------------------------------------------- -// -// Release mouse an keyboard grab. -// -void LockProcess::ungrabInput() -{ - XUngrabKeyboard(QX11Info::display(), CurrentTime); - XUngrabPointer(QX11Info::display(), CurrentTime); - unlockXF86(); -} - -//--------------------------------------------------------------------------- -// -// Start the screen saver. -// -bool LockProcess::startSaver() -{ - if (!child_saver && !grabInput()) - { - kWarning(1204) << "LockProcess::startSaver() grabInput() failed!!!!" ; - return false; - } - mBusy = false; - - saveVRoot(); - - if (mParent) { - QSocketNotifier *notifier = new QSocketNotifier(mParent, QSocketNotifier::Read, this); - connect(notifier, SIGNAL( activated (int)), SLOT( quitSaver())); - } - if (mAutoLogoutTimeout && !mSetupMode) - mAutoLogoutTimerId = startTimer(mAutoLogoutTimeout * 1000); // in milliseconds - createSaverWindow(); - move(0, 0); - show(); - setCursor( Qt::BlankCursor ); - - raise(); - XSync(QX11Info::display(), False); - - setVRoot( winId(), winId() ); - startHack(); - startPlasma(); - KNotification::event( QLatin1String( "savingstarted" ) ); - return true; -} - -//--------------------------------------------------------------------------- -// -// Stop the screen saver. -// -void LockProcess::stopSaver() -{ - kDebug(1204) << "LockProcess: stopping saver"; - resume( true ); - stopPlasma(); - stopHack(); - hideSaverWindow(); - mVisibility = false; - if (!child_saver) { - if (mLocked) { - KDisplayManager().setLock( false ); - mLocked = false; - KNotification *u = new KNotification( QLatin1String( "unlocked" ) ); - u->sendEvent(); - } - ungrabInput(); - const char *out = "GOAWAY!"; - for (QList::ConstIterator it = child_sockets.constBegin(); it != child_sockets.constEnd(); ++it) - write(*it, out, sizeof(out)); - } - KNotification *s = new KNotification( QLatin1String( "savingstopped" ) ); - s->sendEvent(); -} - -// private static -QVariant LockProcess::getConf(void *ctx, const char *key, const QVariant &dflt) -{ - LockProcess *that = (LockProcess *)ctx; - QString fkey = QLatin1String( key ) % QLatin1Char( '=' ); - for (QStringList::ConstIterator it = that->mPluginOptions.constBegin(); - it != that->mPluginOptions.constEnd(); ++it) - if ((*it).startsWith( fkey )) - return (*it).mid( fkey.length() ); - return dflt; -} - -void LockProcess::cantLock( const QString &txt) -{ - msgBox( 0, QMessageBox::Critical, i18n("Will not lock the session, as unlocking would be impossible:\n") + txt ); -} - -#if 0 // placeholders for later -i18n("Cannot start kcheckpass."); -i18n("kcheckpass is unable to operate. Possibly it is not setuid root."); -#endif - -//--------------------------------------------------------------------------- -// -// Make the screen saver password protected. -// -bool LockProcess::startLock() -{ - if (loadGreetPlugin()) { - mLocked = true; - KDisplayManager().setLock(true); - lockPlasma(); - KNotification::event( QLatin1String( "locked" ) ); - return true; - } - return false; -} - -bool LockProcess::loadGreetPlugin() -{ - if (greetPlugin.library) { - //we were locked once before, so all the plugin loading's done already - //FIXME should I be unloading the plugin on unlock instead? - return true; - } - for (QStringList::ConstIterator it = mPlugins.constBegin(); it != mPlugins.constEnd(); ++it) { - GreeterPluginHandle plugin; - KLibrary *lib = new KLibrary( (*it)[0] == QLatin1Char( '/' ) ? *it : QLatin1String( "kgreet_" ) + *it ); - if (lib->fileName().isEmpty()) { - kWarning(1204) << "GreeterPlugin " << *it << " does not exist" ; - delete lib; - continue; - } - if (!lib->load()) { - kWarning(1204) << "Cannot load GreeterPlugin " << *it << " (" << lib->fileName() << ")" ; - delete lib; - continue; - } - plugin.library = lib; - plugin.info = (KGreeterPluginInfo *)lib->resolveSymbol( "kgreeterplugin_info" ); - if (!plugin.info ) { - kWarning(1204) << "GreeterPlugin " << *it << " (" << lib->fileName() << ") is no valid greet widget plugin" ; - lib->unload(); - delete lib; - continue; - } - if (plugin.info->method && !mMethod.isEmpty() && mMethod != QLatin1String( plugin.info->method )) { - kDebug(1204) << "GreeterPlugin " << *it << " (" << lib->fileName() << ") serves " << plugin.info->method << ", not " << mMethod; - lib->unload(); - delete lib; - continue; - } - if (!plugin.info->init( mMethod, getConf, this )) { - kDebug(1204) << "GreeterPlugin " << *it << " (" << lib->fileName() << ") refuses to serve " << mMethod; - lib->unload(); - delete lib; - continue; - } - kDebug(1204) << "GreeterPlugin " << *it << " (" << plugin.info->method << ", " << plugin.info->name << ") loaded"; - greetPlugin = plugin; - return true; - } - cantLock( i18n("No appropriate greeter plugin configured.") ); - return false; -} - -//--------------------------------------------------------------------------- -// - - -bool LockProcess::startHack() -{ - kDebug(1204) << "Starting hack:" << mSaverExec; - - if (mSaverExec.isEmpty() || mForbidden) - { - hackExited(); - return false; - } - - QHash keyMap; - keyMap.insert(QLatin1Char( 'w' ), QString::number(winId())); - mHackProc << KShell::splitArgs(KMacroExpander::expandMacrosShellQuote(mSaverExec, keyMap)); - - mHackProc.start(); - if (mHackProc.waitForStarted()) - { -#ifdef HAVE_SETPRIORITY - setpriority(PRIO_PROCESS, mHackProc.pid(), mPriority); -#endif - return true; - } - - hackExited(); - return false; -} - -//--------------------------------------------------------------------------- -// -void LockProcess::stopHack() -{ - if (mHackProc.state() != QProcess::NotRunning) - { - mHackProc.terminate(); - if (!mHackProc.waitForFinished(10000)) - { - mHackProc.kill(); - } - } -} - -//--------------------------------------------------------------------------- -// -void LockProcess::hackExited() -{ - // Hack exited while we're supposed to be saving the screen. - // Make sure the saver window is black. - XSetWindowBackground(QX11Info::display(), winId(), BlackPixel( QX11Info::display(), QX11Info::appScreen())); - XClearWindow(QX11Info::display(), winId()); -} - -bool LockProcess::startPlasma() -{ - if (!mPlasmaEnabled) { - return false; - } - - if (mSetupMode) { - mSuppressUnlock.start(mSuppressUnlockTimeout); - XChangeActivePointerGrab(QX11Info::display(), GRABEVENTS, - QCursor(Qt::ArrowCursor).handle(), CurrentTime); - } - - kDebug() << "looking for plasma-overlay"; - if (!mPlasmaDBus) { - //try to get it, in case it's already running somehow - //mPlasmaDBus = new QDBusInterface(s_overlayServiceName, "/MainApplication", QString(), - mPlasmaDBus = new org::kde::plasmaoverlay::App(s_overlayServiceName, QLatin1String( "/App" ), - QDBusConnection::sessionBus(), this); - //FIXME this might-already-be-running stuff seems really really Wrong. - } - - if (mPlasmaDBus->isValid()) { - kDebug() << "weird, plasma-overlay is already running"; - mPlasmaDBus->call(QDBus::NoBlock, QLatin1String( "setup" ), mSetupMode); - return true; - } - - kDebug () << "...not found" << "starting plasma-overlay"; - delete mPlasmaDBus; - mPlasmaDBus = 0; - - if (!mServiceWatcher) { - mServiceWatcher = new QDBusServiceWatcher(s_overlayServiceName, QDBusConnection::sessionBus(), - QDBusServiceWatcher::WatchForOwnerChange, this); - connect(mServiceWatcher, SIGNAL(serviceOwnerChanged(QString,QString,QString)), - this, SLOT(newService(QString,QString,QString))); - } - - KProcess *plasmaProc = new KProcess; - plasmaProc->setProgram(QLatin1String( "plasma-overlay" )); - if (mSetupMode) { - *plasmaProc << QLatin1String( "--setup" ); - } - - //make sure it goes away when it's done (and not before) - connect(plasmaProc, SIGNAL(finished(int,QProcess::ExitStatus)), plasmaProc, SLOT(deleteLater())); - - plasmaProc->start(); - kDebug() << "process begun"; - - //plasma gets 15 seconds to load, or we assume it failed - QTimer::singleShot(15 * 1000, this, SLOT(checkPlasma())); - return true; -} - -void LockProcess::checkPlasma() -{ - if (!mPlasmaEnabled) { - kDebug() << "You're Doing It Wrong!"; - return; - } - if (mPlasmaDBus && mPlasmaDBus->isValid()) { - //hooray, looks like it started ok - kDebug() << "success!"; - //...but just in case, make sure we're not waiting on it - mSetupMode = false; - return; - } - - kDebug() << "ohnoes. plasma = teh fail."; - disablePlasma(); -} - -bool LockProcess::isPlasmaValid() -{ - //FIXME I'm assuming that if it's valid, calls will succeed. so if that's not the case we'll - //need to change things so that plasma's disabled properly if it fails - //damn. isValid is not quite enough. a call may still fail, and then we need to bail. - if (!(mPlasmaEnabled && mPlasmaDBus)) { - return false; //no plasma, at least not yet - } - if (mPlasmaDBus->isValid()) { - return true; - } - //oh crap, it ran away on us. - disablePlasma(); - return false; -} - -void LockProcess::disablePlasma() -{ - kDebug(); - mPlasmaEnabled = false; - mSetupMode = false; - mSuppressUnlock.stop(); //FIXME we might need to start the lock timer ala deactivatePlasma() - //actually we could be lazy and just call deactivatePlasma() TODO check that this'll really work - delete mPlasmaDBus; - mPlasmaDBus=0; -} - -void LockProcess::stopPlasma() -{ - if (mPlasmaDBus && mPlasmaDBus->isValid()) { - mPlasmaDBus->call(QDBus::NoBlock, QLatin1String( "quit" )); - } else { - kDebug() << "cannot stop plasma-overlay"; - } -} - -void LockProcess::newService(QString name, QString oldOwner, QString newOwner) -{ - Q_UNUSED(name); - Q_UNUSED(oldOwner); - - if (mPlasmaDBus) { - if (newOwner.isEmpty()) { - kDebug() << "plasma ran away?"; - disablePlasma(); - } else { - kDebug() << "I'm confused!!"; - } - return; - } - - kDebug() << "plasma! yaay!"; - mPlasmaDBus = new org::kde::plasmaoverlay::App(s_overlayServiceName, QLatin1String( "/App" ), QDBusConnection::sessionBus(), this); - - //XXX this isn't actually used any more iirc - connect(mPlasmaDBus, SIGNAL(hidden()), SLOT(unSuppressUnlock())); - - if (!mDialogs.isEmpty()) { - //whoops, activation probably failed earlier - mPlasmaDBus->call(QDBus::NoBlock, QLatin1String( "setActive" ), true); - } -} - -void LockProcess::deactivatePlasma() -{ - if (isPlasmaValid()) { - mPlasmaDBus->call(QDBus::NoBlock, QLatin1String( "setActive" ), false); - } - if (!mLocked && mLockGrace >=0) { - QTimer::singleShot(mLockGrace, this, SLOT(startLock())); //this is only ok because any activity will quit - } -} - -void LockProcess::lockPlasma() -{ - if (isPlasmaValid()) { - mPlasmaDBus->call(QDBus::NoBlock, QLatin1String( "lock" )); - } -} - -void LockProcess::unSuppressUnlock() -{ - //note: suppressing unlock also now means suppressing quit-on-activity - //maybe some var renaming is in order. - mSuppressUnlock.stop(); -} - -void LockProcess::quit() -{ - mSuppressUnlock.stop(); - if (!mLocked || checkPass()) { - quitSaver(); - } -} - -void LockProcess::suspend() -{ - if( !mSuspended && mHackProc.state() == QProcess::Running ) - { - ::kill(mHackProc.pid(), SIGSTOP); - // We actually want to wait for the stopped hack's X commands - // having been handled, but that would require a custom - // protocol which would cause the hack to call XSync() and - // freeze itself. So just go to sleep and hope that the X - // server will have enough time ... - usleep(100000); - mSavedScreen = QPixmap::grabWindow( winId()); - mSnapshotTimer.setSingleShot(true); - mSnapshotTimer.start(1000); - } - mSuspended = true; -} - -void LockProcess::resume( bool force ) -{ - if( !force && (!mDialogs.isEmpty() || !mVisibility )) - return; // no resuming with dialog visible or when not visible - if( mSuspended && mHackProc.state() == QProcess::Running ) - { - QPainter p( this ); - if (!mSavedScreen.isNull()) - p.drawPixmap( 0, 0, mSavedScreen ); - else - p.fillRect( rect(), Qt::black ); - p.end(); - QApplication::syncX(); - mSavedScreen = QPixmap(); - ::kill(mHackProc.pid(), SIGCONT); - } - mSuspended = false; -} - -//--------------------------------------------------------------------------- -// -// Show the password dialog -// This is called only in the master process -// -bool LockProcess::checkPass() -{ - if (isPlasmaValid()) { - mPlasmaDBus->call(QDBus::NoBlock, QLatin1String( "setActive" ), true); - } - - PasswordDlg passDlg( this, &greetPlugin); - const int ret = execDialog( &passDlg ); - - if (isPlasmaValid()) { - if (ret == QDialog::Rejected) { - mSuppressUnlock.start(mSuppressUnlockTimeout); - } else if (ret == TIMEOUT_CODE) { - mPlasmaDBus->call(QDBus::NoBlock, QLatin1String( "setActive" ), false); - } - } - - XWindowAttributes rootAttr; - XGetWindowAttributes(QX11Info::display(), QX11Info::appRootWindow(), &rootAttr); - if(( rootAttr.your_event_mask & SubstructureNotifyMask ) == 0 ) - { - kWarning() << "ERROR: Something removed SubstructureNotifyMask from the root window!!!" ; - XSelectInput( QX11Info::display(), QX11Info::appRootWindow(), - SubstructureNotifyMask | rootAttr.your_event_mask ); - } - - return ret == QDialog::Accepted; -} - -bool LockProcess::checkPass(const QString &reason) -{ - if (! mLocked) { - //we were never locked... how can we unlock?! - //if anyone finds a use case for checking the password while unlocked, they'll have to load - //the greetplugin n'stuff - return false; - } - PasswordDlg passDlg(this, &greetPlugin, reason); - const int ret = execDialog( &passDlg ); -// kDebug() << ret; - - //FIXME do we need to copy&paste that SubstructureNotifyMask code above? - if (ret == QDialog::Accepted) { - //we don't quit on a custom checkpass, but we do unlock - //so that the user doesn't have to type their password twice - mLocked = false; - KDisplayManager().setLock(false); - KNotification::event( QLatin1String( "unlocked" ) ); - //FIXME while suppressUnlock *should* always be running, if it isn't - //(say if someone's doing things they shouldn't with dbus) then it won't get started by this - //which means that a successful unlock will never re-lock - //in fact, the next bit of activity would lead to the screensaver quitting. - //possible solutions: - //-treat this function like activity: quit if already unlocked, ensure suppress is started - //if we're locked and the dialog's rejected - //-return true if already unlocked, without doing anything, same as above if locked - //-let it quit, and tell people not to do such silly things :P - return true; - } - return false; -} - -static void fakeFocusIn( WId window ) -{ - // We have keyboard grab, so this application will - // get keyboard events even without having focus. - // Fake FocusIn to make Qt realize it has the active - // window, so that it will correctly show cursor in the dialog. - XEvent ev; - memset(&ev, 0, sizeof(ev)); - ev.xfocus.display = QX11Info::display(); - ev.xfocus.type = FocusIn; - ev.xfocus.window = window; - ev.xfocus.mode = NotifyNormal; - ev.xfocus.detail = NotifyAncestor; - XSendEvent( QX11Info::display(), window, False, NoEventMask, &ev ); -} - -bool LockProcess::eventFilter(QObject *o, QEvent *e) -{ - if (e->type() == QEvent::Resize) { - QWidget *w = static_cast(o); - mFrames.value(w)->resize(w->size()); - } - return false; -} - -int LockProcess::execDialog( QDialog *dlg ) -{ - - QFrame *winFrame = new QFrame( dlg ); - winFrame->setFrameStyle( QFrame::WinPanel | QFrame::Raised ); - winFrame->setLineWidth( 2 ); - winFrame->lower(); - mFrames.insert(dlg, winFrame); - dlg->installEventFilter(this); - - dlg->adjustSize(); - - int screen = Kephal::ScreenUtils::primaryScreenId(); - if (Kephal::ScreenUtils::numScreens() > 1) { - screen = Kephal::ScreenUtils::screenId(QCursor::pos()); - } - - const QRect screenRect = Kephal::ScreenUtils::screenGeometry(screen); - QRect rect = dlg->geometry(); - rect.moveCenter(screenRect.center()); - dlg->move(rect.topLeft()); - - if (mDialogs.isEmpty()) - { - if (mAutoLogoutTimerId) - killTimer(mAutoLogoutTimerId); - suspend(); - XChangeActivePointerGrab( QX11Info::display(), GRABEVENTS, - QCursor(Qt::ArrowCursor).handle(), CurrentTime); - } - mDialogs.prepend( dlg ); - fakeFocusIn( dlg->winId()); - const int rt = dlg->exec(); - const int pos = mDialogs.indexOf( dlg ); - if (pos != -1) - mDialogs.remove( pos ); - if( mDialogs.isEmpty() ) { - resume( false ); - if (mAutoLogoutTimerId) - mAutoLogoutTimerId = startTimer(mAutoLogoutTimeout * 1000); - } - updateFocus(); - - dlg->removeEventFilter(this); - mFrames.remove(dlg); - - return rt; -} - -void LockProcess::updateFocus() -{ - if (mDialogs.isEmpty()) { - if (mForeignInputWindows.isEmpty()) { - XChangeActivePointerGrab( QX11Info::display(), GRABEVENTS, - QCursor(Qt::BlankCursor).handle(), CurrentTime); - } else { - fakeFocusIn(mForeignInputWindows.first()); - } - } else { - fakeFocusIn(mDialogs.first()->winId()); - } -} - -//--------------------------------------------------------------------------- -// -// X11 Event. -// -bool LockProcess::x11Event(XEvent *event) -{ - if (mEventRecursed) - return false; - - bool ret = false; - switch (event->type) - { - case ButtonPress: - if (!mDialogs.isEmpty() && event->xbutton.window == event->xbutton.root) { - //kDebug() << "close" << mDialogs.first()->effectiveWinId(); - KDialog *dlg = qobject_cast(mDialogs.first()); - if (dlg) { - //kDebug() << "casting success"; - dlg->reject(); - } - break; - } - case KeyPress: - case MotionNotify: - if (mBusy || !mDialogs.isEmpty()) { - //kDebug() << "busy"; - //FIXME shouldn't we be resetting some timers? - break; - } - mBusy = true; - //something happened. do we quit, ask for a password or forward it to plasma? - //if we're supposed to be forwarding, we check that there's actually a plasma window up - //so that the user isn't trapped if plasma crashes or is slow to load. - //however, if plasma started in setup mode, we don't want to let anything happen until - //it has a chance to load. - //note: mSetupMode should end when we either get a winid or hit the checkPlasma timeout - if (mSuppressUnlock.isActive() && (mSetupMode || !mForeignInputWindows.isEmpty())) { - mSuppressUnlock.start(); //help, help, I'm being suppressed! - if (mAutoLogoutTimerId) { - killTimer(mAutoLogoutTimerId); - mAutoLogoutTimerId = startTimer(mAutoLogoutTimeout * 1000); - } - } else if (!mLocked) { - quitSaver(); - mBusy = false; - return true; //it's better not to forward any input while quitting, right? - } else { - if (event->type == KeyPress) { - // Bounce the keypress to the dialog - QByteArray chars; - chars.resize(513); - KeySym keysym; - XLookupString(&event->xkey, chars.data(), chars.size(), &keysym, 0); - switch (keysym) { - // These would cause immediate failure - case XK_Escape: - case XK_Return: - case XK_KP_Enter: - // These just make no sense - case XK_Tab: - case XK_space: - break; - default: - mEventQueue.enqueue(*event); - } - } - if (checkPass()) { - quitSaver(); - mBusy = false; - return true; //it's better not to forward any input while quitting, right? - } - } - mBusy = false; - ret = true; - break; - - case VisibilityNotify: - if( event->xvisibility.window == winId()) - { // mVisibility == false means the screensaver is not visible at all - // e.g. when switched to text console - // ...or when plasma's over it non-compositely? - // hey, this gives me free "suspend saver when plasma obscures it" - mVisibility = !(event->xvisibility.state == VisibilityFullyObscured); - if (!mVisibility) { - mSuspendTimer.start(2000); - kDebug(1204) << "fully obscured"; - } else { - kDebug(1204) << "not fully obscured"; - mSuspendTimer.stop(); - resume( false ); - } - if (mForeignWindows.isEmpty() && event->xvisibility.state != VisibilityUnobscured) { - kDebug(1204) << "no plasma; saver obscured"; - stayOnTop(); - } - } else if (!mForeignWindows.isEmpty() && event->xvisibility.window == mForeignWindows.last() && - event->xvisibility.state != VisibilityUnobscured) { - //FIXME now that we have several plasma winids this doesn't feel valid - //but I don't know what to do about it! - kDebug(1204) << "plasma obscured!"; - stayOnTop(); - } - break; - - case ConfigureNotify: // from SubstructureNotifyMask on the root window - if(event->xconfigure.event == QX11Info::appRootWindow()) { - int index = findWindowInfo( event->xconfigure.window ); - if( index >= 0 ) { - int index2 = event->xconfigure.above ? findWindowInfo( event->xconfigure.above ) : 0; - if( index2 < 0 ) - kDebug(1204) << "Unknown above for ConfigureNotify"; - else { // move just above the other window - if( index2 < index ) - ++index2; - windowInfo.move( index, index2 ); - } - } else - kDebug(1204) << "Unknown toplevel for ConfigureNotify"; - //kDebug() << "ConfigureNotify:"; - //the stacking order changed, so let's change the stacking order again to what we want - stayOnTop(); - } - break; - case MapNotify: // from SubstructureNotifyMask on the root window - if( event->xmap.event == QX11Info::appRootWindow()) { - kDebug(1204) << "MapNotify:" << event->xmap.window; - if (!mDialogs.isEmpty() && mDialogs.first()->winId() == event->xmap.window) - mVisibleDialogs.append(event->xmap.window); - int index = findWindowInfo( event->xmap.window ); - if( index >= 0 ) - windowInfo[ index ].viewable = true; - else - kDebug(1204) << "Unknown toplevel for MapNotify"; - KXErrorHandler err; // ignore X errors here - WindowType type = windowType(event->xmap.window); - if (type != IgnoreWindow) { - if (mForeignWindows.contains(event->xmap.window)) { - kDebug(1204) << "uhoh! duplicate!"; - } else { - //ordered youngest-on-top - mForeignWindows.prepend(event->xmap.window); - } - if (type & InputWindow) { - kDebug(1204) << "input window"; - if (mForeignInputWindows.contains(event->xmap.window)) { - kDebug(1204) << "uhoh! duplicate again"; //never happens - } else { - //ordered youngest-on-top - mForeignInputWindows.prepend(event->xmap.window); - fakeFocusIn(event->xmap.window); - } - mSetupMode = false; //no more waiting for plasma - } - } - stayOnTop(); - } - break; - case UnmapNotify: - if (event->xunmap.event == QX11Info::appRootWindow()) { - kDebug(1204) << "UnmapNotify:" << event->xunmap.window; - int index = findWindowInfo( event->xunmap.window ); - if( index >= 0 ) - windowInfo[ index ].viewable = false; - else - kDebug(1204) << "Unknown toplevel for MapNotify"; - mVisibleDialogs.removeAll(event->xunmap.window); - mForeignWindows.removeAll(event->xunmap.window); - if (mForeignInputWindows.removeAll(event->xunmap.window)) { - updateFocus(); - } - } - break; - case CreateNotify: - if (event->xcreatewindow.parent == QX11Info::appRootWindow()) { - kDebug(1204) << "CreateNotify:" << event->xcreatewindow.window; - int index = findWindowInfo( event->xcreatewindow.window ); - if( index >= 0 ) - kDebug(1204) << "Already existing toplevel for CreateNotify"; - else { - WindowInfo info; - info.window = event->xcreatewindow.window; - info.viewable = false; - windowInfo.append( info ); - } - } - break; - case DestroyNotify: - if (event->xdestroywindow.event == QX11Info::appRootWindow()) { - int index = findWindowInfo( event->xdestroywindow.window ); - if( index >= 0 ) - windowInfo.removeAt( index ); - else - kDebug(1204) << "Unknown toplevel for DestroyNotify"; - } - break; - case ReparentNotify: - if (event->xreparent.event == QX11Info::appRootWindow() && event->xreparent.parent != QX11Info::appRootWindow()) { - int index = findWindowInfo( event->xreparent.window ); - if( index >= 0 ) - windowInfo.removeAt( index ); - else - kDebug(1204) << "Unknown toplevel for ReparentNotify away"; - } else if (event->xreparent.parent == QX11Info::appRootWindow()) { - int index = findWindowInfo( event->xreparent.window ); - if( index >= 0 ) - kDebug(1204) << "Already existing toplevel for ReparentNotify"; - else { - WindowInfo info; - info.window = event->xreparent.window; - info.viewable = false; - windowInfo.append( info ); - } - } - break; - case CirculateNotify: - if (event->xcirculate.event == QX11Info::appRootWindow()) { - int index = findWindowInfo( event->xcirculate.window ); - if( index >= 0 ) { - windowInfo.move( index, event->xcirculate.place == PlaceOnTop ? windowInfo.size() - 1 : 0 ); - } else - kDebug(1204) << "Unknown toplevel for CirculateNotify"; - } - break; - } - - // We have grab with the grab window being the root window. - // This results in key events being sent to the root window, - // but they should be sent to the dialog if it's visible. - // It could be solved by setFocus() call, but that would mess - // the focus after this process exits. - // Qt seems to be quite hard to persuade to redirect the event, - // so let's simply dupe it with correct destination window, - // and ignore the original one. - if (!mDialogs.isEmpty()) { - if (event->type == KeyPress || event->type == KeyRelease) { - mEventQueue.enqueue(*event); - ret = true; - } - if (!mVisibleDialogs.isEmpty()) - while (!mEventQueue.isEmpty()) { - //kDebug() << "forward to dialog"; - XEvent ev2 = mEventQueue.dequeue(); - ev2.xkey.window = ev2.xkey.subwindow = mVisibleDialogs.last(); - mEventRecursed = true; - qApp->x11ProcessEvent( &ev2 ); - mEventRecursed = false; - } - } else { - mEventQueue.clear(); - if (!mForeignInputWindows.isEmpty()) { - //when there are no dialogs, forward some events to plasma - switch (event->type) { - case KeyPress: - case KeyRelease: - case ButtonPress: - case ButtonRelease: - case MotionNotify: { - //kDebug() << "forward to plasma"; - XEvent ev2 = *event; - Window root_return; - int x_return, y_return; - unsigned int width_return, height_return, border_width_return, depth_return; - WId targetWindow = 0; - //kDebug() << "root is" << winId(); - //kDebug() << "search window under pointer with" << mForeignInputWindows.size() << "windows"; - KXErrorHandler err; // ignore X errors - foreach(WId window, mForeignInputWindows) - { - if( XGetGeometry(QX11Info::display(), window, &root_return, - &x_return, &y_return, - &width_return, &height_return, - &border_width_return, &depth_return) - && - (event->xkey.x>=x_return && event->xkey.x<=x_return+(int)width_return) - && - (event->xkey.y>=y_return && event->xkey.y<=y_return+(int)height_return) ) - { - //kDebug() << "found window" << window; - targetWindow = window; - ev2.xkey.window = ev2.xkey.subwindow = targetWindow; - ev2.xkey.x = event->xkey.x - x_return; - ev2.xkey.y = event->xkey.y - y_return; - break; - } - } - XSendEvent(QX11Info::display(), targetWindow, False, NoEventMask, &ev2); - ret = true; - break; } - default: - break; - } - } - } - - return ret; -} - -LockProcess::WindowType LockProcess::windowType(WId id) -{ - Atom tag = XInternAtom(QX11Info::display(), "_KDE_SCREENSAVER_OVERRIDE", False); - Atom actualType; - int actualFormat; - unsigned long nitems, remaining; - unsigned char *data = 0; - Display *display = QX11Info::display(); - - int result = XGetWindowProperty(display, id, tag, 0, 1, False, tag, &actualType, - &actualFormat, &nitems, &remaining, &data); - - //kDebug() << (result == Success) << (actualType == tag); - WindowType type = IgnoreWindow; - if (result == Success && actualType == tag) { - if (nitems != 1 || actualFormat != 8) { - kDebug(1204) << "malformed property"; - } else { - kDebug(1204) << "i can haz plasma window?" << data[0]; - switch (data[0]) { - case 0: //FIXME magic numbers - type = SimpleWindow; - break; - case 1: - type = InputWindow; - break; - case 2: - type = DefaultWindow; - break; - } - } - } - if (data) { - XFree(data); - } - return type; -} - -void LockProcess::stayOnTop() -{ - // this restacking is written in a way so that - // if the stacking positions actually don't change, - // all restacking operations will be no-op, - // and no ConfigureNotify will be generated, - // thus avoiding possible infinite loops - QVector< Window > stack( mDialogs.count() + mForeignWindows.count() + 1 ); - int count = 0; - // dialogs first - foreach( QWidget* w, mDialogs ) - stack[ count++ ] = w->winId(); - // now the plasma stuff below the dialogs - foreach( WId w, mForeignWindows ) - stack[ count++ ] = w; - // finally, the saver window - stack[ count++ ] = winId(); - // We actually have to check the current stacking order. When an override-redirect - // window is shown or raised, it can get above the screensaver window and there's not - // much to do to prevent it (only the compositing manager can prevent that). This - // is detected by the screenlocker and handled here, but the contents of the window - // may remain visible, since some screensavers don't react to Expose events and - // don't repaint as necessary. Therefore, if a window is detected above any of the windows - // related to screenlocking, I don't see any better possibility than to completely - // erase the screenlocker window. - // It is important to first detect, then restack and then erase. - // Another catch here is that only viewable windows matter, but checking here whether - // a window is viewable is a race condition, since a window may map, paint and unmap - // before we reach this point, thus making this code fail to detect the need to do - // a repaint. Therefore we track all relevant X events about mapping state of toplevel - // windows (which ensures proper ordering) and here just consult the information. - bool needs_erase = false; - bool found_ours = false; - foreach( const WindowInfo& info, windowInfo ) { - if( stack.contains( info.window )) { - found_ours = true; - } else if( found_ours && info.viewable ) { - kDebug(1204) << "found foreign window above screensaver"; - needs_erase = true; - break; - } - } - // do the actual restacking if needed - XRaiseWindow( x11Info().display(), stack[ 0 ] ); - if( count > 1 ) - XRestackWindows( x11Info().display(), stack.data(), count ); - if( needs_erase ) { - // if the snapshot was taken recently it is possible that the rogue - // window was snapshotted at well. - if (mSnapshotTimer.isActive()) - mSavedScreen = QPixmap(); - QPainter p( this ); - if (!mSavedScreen.isNull()) - p.drawPixmap( 0, 0, mSavedScreen ); - else - p.fillRect( rect(), Qt::black ); - p.end(); - QApplication::syncX(); - } -} - -void LockProcess::checkDPMSActive() -{ -#ifdef HAVE_DPMS - BOOL on; - CARD16 state; - DPMSInfo(QX11Info::display(), &state, &on); - //kDebug() << "checkDPMSActive " << on << " " << state; - if (state == DPMSModeStandby || state == DPMSModeSuspend || state == DPMSModeOff) - suspend(); - else - resume( false ); -#endif -} - -#if defined(HAVE_XF86MISC) && defined(HAVE_XF86MISCSETGRABKEYSSTATE) -// see http://cvsweb.xfree86.org/cvsweb/xc/programs/Xserver/hw/xfree86/common/xf86Events.c#rev3.113 -// This allows enabling the "Allow{Deactivate/Closedown}Grabs" options in XF86Config, -// and kscreenlocker will still lock the session. -static enum { Unknown, Yes, No } can_do_xf86_lock = Unknown; -void LockProcess::lockXF86() -{ - if( can_do_xf86_lock == Unknown ) - { - int major, minor, dummy; - if( XF86MiscQueryExtension( QX11Info::display(), &dummy, &dummy ) - && XF86MiscQueryVersion( QX11Info::display(), &major, &minor ) - && (major > 0 || minor >= 5) ) - can_do_xf86_lock = Yes; - else - can_do_xf86_lock = No; - } - if( can_do_xf86_lock != Yes ) - return; - if( mRestoreXF86Lock ) - return; - if( XF86MiscSetGrabKeysState( QX11Info::display(), False ) != MiscExtGrabStateSuccess ) - return; - // success - mRestoreXF86Lock = true; -} - -void LockProcess::unlockXF86() -{ - if( can_do_xf86_lock != Yes ) - return; - if( !mRestoreXF86Lock ) - return; - XF86MiscSetGrabKeysState( QX11Info::display(), True ); - mRestoreXF86Lock = false; -} -#else -void LockProcess::lockXF86() -{ -} - -void LockProcess::unlockXF86() -{ -} -#endif - -void LockProcess::msgBox( QWidget *parent, QMessageBox::Icon type, const QString &txt ) -{ - QDialog box( parent, Qt::X11BypassWindowManagerHint ); - - QLabel *label1 = new QLabel( &box ); - label1->setPixmap( QMessageBox::standardIcon( type ) ); - QLabel *label2 = new QLabel( txt, &box ); - KPushButton *button = new KPushButton( KStandardGuiItem::ok(), &box ); - button->setDefault( true ); - button->setSizePolicy( QSizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred ) ); - connect( button, SIGNAL( clicked() ), &box, SLOT( accept() ) ); - - QGridLayout *grid = new QGridLayout( &box ); - grid->setSpacing( 10 ); - grid->addWidget( label1, 0, 0, Qt::AlignCenter ); - grid->addWidget( label2, 0, 1, Qt::AlignCenter ); - grid->addWidget( button, 1, 0, 1, 2, Qt::AlignCenter ); - - execDialog( &box ); -} - -int LockProcess::findWindowInfo( Window w ) -{ - for( int i = 0; - i < windowInfo.size(); - ++i ) - if( windowInfo[ i ].window == w ) - return i; - return -1; -} - -#include "lockprocess.moc" diff --git a/krunner/lock/lockprocess.h b/krunner/lock/lockprocess.h deleted file mode 100644 index 8b6d9a8..0000000 --- a/krunner/lock/lockprocess.h +++ /dev/null @@ -1,238 +0,0 @@ -//=========================================================================== -// -// This file is part of the KDE project -// -// Copyright 1999 Martin R. Jones -// Copyright 2003 Oswald Buddenhagen -// Copyright 2008 Chani Armitage -// - -#ifndef LOCKPROCESS_H -#define LOCKPROCESS_H - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "plasmaapp_interface.h" - -class KLibrary; - -struct KGreeterPluginInfo; - -struct GreeterPluginHandle { - KLibrary *library; - KGreeterPluginInfo *info; -}; - -const int TIMEOUT_CODE = 2; //from PasswordDlg - -class QDBusServiceWatcher; - -//=========================================================================== -// -// Screen saver handling process. Handles screensaver window, -// starting screensaver hacks, and password entry. -// -class LockProcess - : public QWidget -{ - Q_OBJECT - Q_CLASSINFO("D-Bus Interface", "org.kde.screenlocker.LockProcess") -public: - explicit LockProcess(bool child_saver = false, bool useBlankOnly = false); - ~LockProcess(); - - /** - * start the screensaver locked - */ - bool lock(bool initial = false); - - /** - * start the screensaver unlocked - */ - bool defaultSave(); - - /** - * start the screensaver in plasma setup mode - * if plasma is disabled this just acts like defaultSave - */ - bool startSetup(); - - /** - * start the screensaver unlocked, and *never* automatically lock it - */ - bool dontLock(); - - void setChildren(QList children) { child_sockets = children; } - void setParent(int fd) { mParent = fd; } - - void msgBox( QWidget *parent, QMessageBox::Icon type, const QString &txt ); - int execDialog( QDialog* dlg ); - -public Q_SLOTS: - void quitSaver(); - //dbus methods - /** - * bring up the password dialog with @param reason displayed instead of the usual "this session - * is locked" message. - * @return true if the password was entered correctly - * if this returns true, it will also unlock the screensaver without quitting. - * it will re-lock after the lock timeout in the settings - */ - Q_SCRIPTABLE bool checkPass(const QString &reason); - /** - * this will unlock and quit the screensaver, asking for a password first if necessary - */ - Q_SCRIPTABLE void quit(); - /** - * immediately lock the screen; it will now require a password to unlock. - */ - Q_SCRIPTABLE bool startLock(); - -protected: - virtual bool x11Event(XEvent *); - virtual void timerEvent(QTimerEvent *); - virtual bool eventFilter(QObject *o, QEvent *e); - -private Q_SLOTS: - void hackExited(); - void signalPipeSignal(); - void suspend(); - void checkDPMSActive(); - void slotDeadTimePassed(); - /** - * check that plasma started properly (used for timeout) - * and disable it if it failed - */ - void checkPlasma(); - /** - * a new dbus service has come in - */ - void newService(QString name, QString oldOwner, QString newOwner); - /** - * tell plasma we're in idle mode - */ - void deactivatePlasma(); - void lockPlasma(); - /** - * immediately un-suppress the password dialog - * FIXME need a better name - */ - void unSuppressUnlock(); - -private: - void configure(); - void readSaver(); - void createSaverWindow(); - void hideSaverWindow(); - void saveVRoot(); - void setVRoot(Window win, Window rw); - void removeVRoot(Window win); - bool grabKeyboard(); - bool grabMouse(); - bool grabInput(); - void ungrabInput(); - void cantLock(const QString &reason); - bool startSaver(); - void stopSaver(); - bool startHack(); - void stopHack(); - bool startPlasma(); - void stopPlasma(); - void setupSignals(); - /** - * exec the password dialog - * @return true iff the password was checked and is valid - */ - bool checkPass(); - /** - * returns true if plasma is up and the dbus interface is valid - */ - bool isPlasmaValid(); - /** - * give up on plasma, probably because it crashed. - * this does *not* tell plasma to quit. it just stops using it. - */ - void disablePlasma(); - /** - * give a fakefocusin to the right window - */ - void updateFocus(); - void stayOnTop(); - int findWindowInfo( Window window ); // returns index in windowInfo or -1 - void lockXF86(); - void unlockXF86(); - void resume( bool force ); - enum WindowType { IgnoreWindow = 0 /** regular window to be left below the saver */, - SimpleWindow = 1 /** simple popup that can't handle direct input */, - InputWindow = 2 /** annoying dialog that needs direct input */, - DefaultWindow = 6/** input window that's also the plasma view */ - }; - /** - * @return the type of window, based on its X property - */ - WindowType windowType(WId id); - - static QVariant getConf(void *ctx, const char *key, const QVariant &dflt); - bool loadGreetPlugin(); - - bool mInitialLock; - bool mLocked; - int mLockGrace; - int mPriority; - bool mBusy; - KProcess mHackProc; - org::kde::plasmaoverlay::App *mPlasmaDBus; - QDBusServiceWatcher *mServiceWatcher; - bool mPlasmaEnabled; - bool mSetupMode; - QString mSaverExec; - QString mSaver; - bool mOpenGLVisual; - bool child_saver; - QList child_sockets; - int mParent; - bool mUseBlankOnly; - bool mSuspended; - QTimer mSuspendTimer; - bool mVisibility; - bool mDPMSDepend; - QTimer mCheckDPMS; - QStack< QWidget* > mDialogs; - QHash< QWidget*, QWidget* > mFrames; - QList mVisibleDialogs; - QQueue mEventQueue; - bool mEventRecursed; - bool mRestoreXF86Lock; - bool mForbidden; - QStringList mPlugins, mPluginOptions; - QString mMethod; - GreeterPluginHandle greetPlugin; - QPixmap mSavedScreen; - QTimer mSnapshotTimer; - int mAutoLogoutTimerId; - int mAutoLogoutTimeout; - QTimer mSuppressUnlock; - int mSuppressUnlockTimeout; - QList mForeignWindows; - QList mForeignInputWindows; - struct WindowInfo - { - Window window; - bool viewable; - }; - QList windowInfo; -}; - -#endif - diff --git a/krunner/lock/main.cc b/krunner/lock/main.cc deleted file mode 100644 index 7b41024..0000000 --- a/krunner/lock/main.cc +++ /dev/null @@ -1,204 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 1999 David Faure - Copyright 2003 Oswald Buddenhagen - - 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 "lockprocess.h" -#include "main.h" -#include "kscreensaversettings.h" - -#include -#include -#include -#include -#include -#include -#include "kscreensaver_interface.h" - -#include - -#include -#include -#include - -#include -#include - -bool MyApp::x11EventFilter( XEvent *ev ) -{ - if (ev->type == XKeyPress || ev->type == ButtonPress) - emit activity(); - else if (ev->type == MotionNotify) { - time_t tick = time( 0 ); - if (tick != lastTick) { - lastTick = tick; - emit activity(); - } - } - return KApplication::x11EventFilter( ev ); -} - - -// ----------------------------------------------------------------------------- - -int main( int argc, char **argv ) -{ - KCmdLineArgs::init(argc, argv, "kscreenlocker", "krunner", ki18n("KDE Screen Locker"), - "2.0" , ki18n("Session Locker for KDE Workspace")); - - KCmdLineOptions options; - options.add("forcelock", ki18n("Force session locking")); - options.add("dontlock", ki18n("Only start screen saver")); - options.add("showunlock", ki18n("Immediately show the unlock dialog")); - options.add("blank", ki18n("Only use the blank screen saver")); - options.add("plasmasetup", ki18n("start with plasma unlocked for configuring")); - options.add("daemon", ki18n("Fork into the background after starting up")); - KCmdLineArgs::addCmdLineOptions( options ); - KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); - - bool daemonize = false; - int daemonPipe[2]; - char daemonBuf; - if (args->isSet("daemon")) { - daemonize = true; - if (pipe(daemonPipe)) - kFatal() << "pipe() failed"; - switch (fork()) { - case -1: - kFatal() << "fork() failed"; - case 0: - break; - default: - if (read(daemonPipe[0], &daemonBuf, 1) != 1) - _exit(1); - _exit(0); - } - } - - putenv(strdup("SESSION_MANAGER=")); - - //KApplication::disableAutoDcopRegistration(); - - int kdesktop_screen_number = 0; - int starting_screen = 0; - - bool child = false; - int parent_connection = 0; // socket to the parent saver - QList child_sockets; - - if (KGlobalSettings::isMultiHead()) - { - Display *dpy = XOpenDisplay(NULL); - if (! dpy) { - fprintf(stderr, - "%s: FATAL ERROR: could not open display '%s'\n", - argv[0], XDisplayName(NULL)); - exit(1); - } - - int number_of_screens = ScreenCount(dpy); - starting_screen = kdesktop_screen_number = DefaultScreen(dpy); - int pos; - QByteArray display_name = XDisplayString(dpy); - XCloseDisplay(dpy); - kDebug() << "screen " << number_of_screens << " " << kdesktop_screen_number << " " << display_name << " " << starting_screen; - dpy = 0; - - if ((pos = display_name.lastIndexOf('.')) != -1) - display_name.remove(pos, 10); - - QString env; - if (number_of_screens != 1) { - for (int i = 0; i < number_of_screens; i++) { - if (i != starting_screen) { - int fd[2]; - if (pipe(fd)) { - perror("pipe"); - break; - } - if (fork() == 0) { - child = true; - kdesktop_screen_number = i; - parent_connection = fd[0]; - // break here because we are the child process, we don't - // want to fork() anymore - break; - } else { - child_sockets.append(fd[1]); - } - } - } - - env.sprintf("DISPLAY=%s.%d", display_name.data(), - kdesktop_screen_number); - kDebug() << "env " << env; - - if (putenv(strdup(env.toLatin1().data()))) { - fprintf(stderr, - "%s: WARNING: unable to set DISPLAY environment variable\n", - argv[0]); - perror("putenv()"); - } - } - } - - MyApp app; - kDebug() << "app " << kdesktop_screen_number << " " << starting_screen << " " << child << " " << child_sockets.count() << " " << parent_connection; - app.disableSessionManagement(); - app.setQuitOnLastWindowClosed( false ); - KGlobal::locale()->insertCatalog(QLatin1String( "libkworkspace" )); - - LockProcess process(child, args->isSet("blank")); - if (!child) - process.setChildren(child_sockets); - else - process.setParent(parent_connection); - - bool rt; - bool sig = false; - if (!child && (args->isSet("forcelock"))) { - rt = process.lock(args->isSet("showunlock")); - sig = true; - } - else if( child || args->isSet( "dontlock" )) - rt = process.dontLock(); - else if (args->isSet("plasmasetup")) { - rt = process.startSetup(); - } - else - rt = process.defaultSave(); - if (!rt) - return 1; - - if( sig ) - { - org::kde::screensaver kscreensaver(QLatin1String( "org.kde.screensaver" ), QLatin1String( "/ScreenSaver" ), QDBusConnection::sessionBus()); - kscreensaver.saverLockReady(); - } - args->clear(); - if (daemonize) { - daemonBuf = 0; - write(daemonPipe[1], &daemonBuf, 1); - } - return app.exec(); -} - -#include "main.moc" - -#define KDM_NO_SHUTDOWN -#include diff --git a/krunner/lock/main.h b/krunner/lock/main.h deleted file mode 100644 index 8a60353..0000000 --- a/krunner/lock/main.h +++ /dev/null @@ -1,39 +0,0 @@ -/* This file is part of the KDE project - Copyright 2003 Oswald Buddenhagen - - 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 _MAIN_H -#define _MAIN_H - -#include - -#include - -class MyApp : public KApplication { - Q_OBJECT -public: - MyApp() : KApplication(), lastTick( 0 ) {} -protected: - bool x11EventFilter( XEvent * ); -Q_SIGNALS: - void activity(); -private: - time_t lastTick; -}; - -#endif diff --git a/krunner/main.cpp b/krunner/main.cpp index 84a547b..c3dd560 100644 --- a/krunner/main.cpp +++ b/krunner/main.cpp @@ -25,10 +25,8 @@ #include "krunnerapp.h" #ifdef Q_WS_X11 -#include "saverengine.h" #include "startupid.h" #endif -#include "kscreensaversettings.h" // contains screen saver config #include "klaunchsettings.h" // contains startup config #ifdef Q_WS_X11 diff --git a/krunner/screensaver/saverengine.cpp b/krunner/screensaver/saverengine.cpp deleted file mode 100644 index 4d90faa..0000000 --- a/krunner/screensaver/saverengine.cpp +++ /dev/null @@ -1,496 +0,0 @@ -//=========================================================================== -// -// This file is part of the KDE project -// -// Copyright 1999 Martin R. Jones -// - - -#include "saverengine.h" -#include "kscreensaversettings.h" -#include "screensaveradaptor.h" -#include "kscreensaveradaptor.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "xautolock_c.h" -extern xautolock_corner_t xautolock_corners[ 4 ]; - -//=========================================================================== -// -// Screen saver engine. Doesn't handle the actual screensaver window, -// starting screensaver hacks, or password entry. That's done by -// a newly started process. -// -SaverEngine::SaverEngine() - : QWidget() -{ - (void) new ScreenSaverAdaptor( this ); - QDBusConnection::sessionBus().registerService( QLatin1String( "org.freedesktop.ScreenSaver" ) ) ; - (void) new KScreenSaverAdaptor( this ); - QDBusConnection::sessionBus().registerService( QLatin1String( "org.kde.screensaver" ) ) ; - QDBusConnection::sessionBus().registerObject( QLatin1String( "/ScreenSaver" ), this ); - - // Save X screensaver parameters - XGetScreenSaver(QX11Info::display(), &mXTimeout, &mXInterval, - &mXBlanking, &mXExposures); - // And disable it. The internal X screensaver is not used at all, but we use its - // internal idle timer (and it is also used by DPMS support in X). This timer must not - // be altered by this code, since e.g. resetting the counter after activating our - // screensaver would prevent DPMS from activating. We use the timer merely to detect - // user activity. - XSetScreenSaver(QX11Info::display(), 0, mXInterval, mXBlanking, mXExposures); - - mState = Waiting; - mXAutoLock = 0; - mLockProcess = 0; - - m_nr_throttled = 0; - m_nr_inhibited = 0; - m_actived_time = -1; - - m_serviceWatcher = new QDBusServiceWatcher(this); - m_serviceWatcher->setConnection(QDBusConnection::sessionBus()); - m_serviceWatcher->setWatchMode(QDBusServiceWatcher::WatchForUnregistration); - connect(m_serviceWatcher, SIGNAL(serviceUnregistered(QString)), - this, SLOT(serviceUnregistered(QString))); - - // Also receive updates triggered through the DBus (from powerdevil) see Bug #177123 - QStringList modules; - QDBusInterface kdedInterface(QLatin1String( "org.kde.kded" ), QLatin1String( "/kded" ), QLatin1String( "org.kde.kded" )); - QDBusReply reply = kdedInterface.call(QLatin1String( "loadedModules" )); - - if (!reply.isValid()) { - return; - } - - modules = reply.value(); - - if (modules.contains(QLatin1String( "powerdevil" ))) { - if (!QDBusConnection::sessionBus().connect(QLatin1String( "org.kde.kded" ), QLatin1String( "/modules/powerdevil" ), QLatin1String( "org.kde.PowerDevil" ), - QLatin1String( "DPMSconfigUpdated" ), this, SLOT(configure()))) { - kDebug() << "error!"; - } - } - - // I make it a really random number to avoid - // some assumptions in clients, but just increase - // while gnome-ss creates a random number every time - m_next_cookie = KRandom::random() % 20000; - configure(); -} - -//--------------------------------------------------------------------------- -// -// Destructor - usual cleanups. -// -SaverEngine::~SaverEngine() -{ - delete mXAutoLock; - // Just let mLockProcess leak, so the saver is not killed - - // Restore X screensaver parameters - XSetScreenSaver(QX11Info::display(), mXTimeout, mXInterval, mXBlanking, - mXExposures); -} - -//--------------------------------------------------------------------------- - -void SaverEngine::Lock() -{ - if (mState == Waiting) - { - startLockProcess( ForceLock ); - } - else - { - // XXX race condition here - ::kill(mLockProcess->pid(), SIGHUP); - } -} - -void SaverEngine::processLockTransactions() -{ - QList::ConstIterator it = mLockTransactions.constBegin(), - end = mLockTransactions.constEnd(); - for ( ; it != end; ++it ) - { - QDBusConnection::sessionBus().send(*it); - } - mLockTransactions.clear(); -} - -void SaverEngine::saverLockReady() -{ - if( mState != Preparing ) - { - kDebug() << "Got unexpected saverLockReady()"; - return; - } - kDebug() << "Saver Lock Ready"; - processLockTransactions(); - if (m_nr_throttled) - ::kill(mLockProcess->pid(), SIGSTOP); -} - -void SaverEngine::SimulateUserActivity() -{ - XForceScreenSaver( QX11Info::display(), ScreenSaverReset ); - if ( mXAutoLock && mState == Waiting ) - { - mXAutoLock->resetTrigger(); - } - else if (mLockProcess) - { - ::kill(mLockProcess->pid(), SIGUSR1); - } -} - -//--------------------------------------------------------------------------- -bool SaverEngine::save() -{ - if (mState == Waiting) - { - return startLockProcess( DefaultLock ); - } - return false; -} - -bool SaverEngine::setupPlasma() -{ - if (mState == Waiting) - { - return startLockProcess( PlasmaSetup ); - } - return false; -} - -//--------------------------------------------------------------------------- -bool SaverEngine::quit() -{ - if (mState == Saving || mState == Preparing) - { - stopLockProcess(); - return true; - } - return false; -} - -//--------------------------------------------------------------------------- -bool SaverEngine::isEnabled() -{ - return mXAutoLock != 0; -} - -//--------------------------------------------------------------------------- -bool SaverEngine::enable( bool e, bool force ) -{ - if ( !force && e == isEnabled() ) - return true; - - // If we aren't in a suitable state, we will not reconfigure. - if (mState != Waiting) - return false; - - if (e) - { - if (!mXAutoLock) - { - mXAutoLock = new XAutoLock(); - connect(mXAutoLock, SIGNAL(timeout()), SLOT(idleTimeout())); - } - - int timeout = KScreenSaverSettings::timeout(); - mXAutoLock->setTimeout(timeout); - mXAutoLock->setDPMS(true); -#ifdef NOT_FREAKIN_UGLY - mXAutoLock->changeCornerLockStatus( mLockCornerTopLeft, mLockCornerTopRight, mLockCornerBottomLeft, mLockCornerBottomRight); -#else - xautolock_corners[0] = applyManualSettings(KScreenSaverSettings::actionTopLeft()); - xautolock_corners[1] = applyManualSettings(KScreenSaverSettings::actionTopRight()); - xautolock_corners[2] = applyManualSettings(KScreenSaverSettings::actionBottomLeft()); - xautolock_corners[3] = applyManualSettings(KScreenSaverSettings::actionBottomRight()); -#endif - - mXAutoLock->start(); - kDebug() << "Saver Engine started, timeout: " << timeout; - } - else - { - delete mXAutoLock; - mXAutoLock = 0; - kDebug() << "Saver Engine disabled"; - } - - return true; -} - -//--------------------------------------------------------------------------- -bool SaverEngine::isBlanked() -{ - return (mState != Waiting); -} - -//--------------------------------------------------------------------------- -// -// Read and apply configuration. -// -void SaverEngine::configure() -{ - // create a new config obj to ensure we read the latest options - KScreenSaverSettings::self()->readConfig(); - - enable( KScreenSaverSettings::screenSaverEnabled(), true ); -} - -//--------------------------------------------------------------------------- -// -// Start the screen saver. -// -bool SaverEngine::startLockProcess( LockType lock_type ) -{ - Q_ASSERT(mState == Waiting); - - kDebug() << "SaverEngine: starting saver"; - - QString path = KStandardDirs::findExe( QLatin1String( "kscreenlocker" ) ); - if( path.isEmpty()) - { - kDebug() << "Can't find kscreenlocker!"; - return false; - } - mLockProcess = new KProcess; // No parent, so it is not auto-deleted - connect(mLockProcess, SIGNAL(finished(int,QProcess::ExitStatus)), - SLOT(lockProcessExited())); - *mLockProcess << path; - switch( lock_type ) - { - case ForceLock: - *mLockProcess << QLatin1String( "--forcelock" ); - break; - case DontLock: - *mLockProcess << QLatin1String( "--dontlock" ); - break; - case PlasmaSetup: - *mLockProcess << QLatin1String( "--plasmasetup" ); - break; - default: - break; - } - - m_actived_time = time( 0 ); - mLockProcess->start(); - if (mLockProcess->waitForStarted() == false ) - { - kDebug() << "Failed to start kscreenlocker!"; - delete mLockProcess; - mLockProcess = 0; - m_actived_time = -1; - return false; - } - - if (mXAutoLock) - { - mXAutoLock->stop(); - } - - emit ActiveChanged(true); // DBus signal - mState = Preparing; - - // It takes a while for kscreenlocker to start and lock the screen. - // Therefore delay the DBus call until it tells krunner that the locking is in effect. - // This is done only for --forcelock . - if (lock_type == ForceLock && calledFromDBus()) { - mLockTransactions.append(message().createReply()); - setDelayedReply(true); - } - - return true; -} - -//--------------------------------------------------------------------------- -// -// Stop the screen saver. -// -void SaverEngine::stopLockProcess() -{ - Q_ASSERT(mState != Waiting); - kDebug() << "SaverEngine: stopping lock process"; - - mLockProcess->kill(); -} - -void SaverEngine::lockProcessExited() -{ - Q_ASSERT(mState != Waiting); - kDebug() << "SaverEngine: lock process exited"; - - delete mLockProcess; - mLockProcess = 0; - - if (mXAutoLock) - { - mXAutoLock->start(); - } - - processLockTransactions(); - emit ActiveChanged(false); // DBus signal - m_actived_time = -1; - mState = Waiting; -} - -//--------------------------------------------------------------------------- -// -// XAutoLock has detected the required idle time. -// -void SaverEngine::idleTimeout() -{ - if( mState != Waiting ) - return; // already saving - startLockProcess( DefaultLock ); -} - -xautolock_corner_t SaverEngine::applyManualSettings(int action) -{ - if (action == 0) - { - kDebug() << "no lock"; - return ca_nothing; - } - else if (action == 1) - { - kDebug() << "lock screen"; - return ca_forceLock; - } - else if (action == 2) - { - kDebug() << "prevent lock"; - return ca_dontLock; - } - else - { - kDebug() << "no lock nothing"; - return ca_nothing; - } -} - -uint SaverEngine::GetSessionIdleTime() -{ - return mXAutoLock ? mXAutoLock->idleTime() : 0; -} - -uint SaverEngine::GetActiveTime() -{ - if ( m_actived_time == -1 ) - return 0; - return time( 0 ) - m_actived_time; -} - -bool SaverEngine::GetActive() -{ - return ( mState != Waiting ); -} - -bool SaverEngine::SetActive(bool state) -{ - if ( state ) - return save(); - else - return quit(); -} - -uint SaverEngine::Inhibit(const QString &/*application_name*/, const QString &/*reason*/) -{ - ScreenSaverRequest sr; -// sr.appname = application_name; -// sr.reasongiven = reason; - sr.cookie = m_next_cookie++; - sr.dbusid = message().service(); - sr.type = ScreenSaverRequest::Inhibit; - m_requests.append( sr ); - m_serviceWatcher->addWatchedService(sr.dbusid); - m_nr_inhibited++; - if (KScreenSaverSettings::screenSaverEnabled()) - enable( false ); - return sr.cookie; -} - -void SaverEngine::UnInhibit(uint cookie) -{ - QMutableListIterator it( m_requests ); - while ( it.hasNext() ) - { - if ( it.next().cookie == cookie ) { - it.remove(); - if ( !--m_nr_inhibited ) - if (KScreenSaverSettings::screenSaverEnabled()) - enable( true ); - } - } -} - -uint SaverEngine::Throttle(const QString &/*application_name*/, const QString &/*reason*/) -{ - ScreenSaverRequest sr; -// sr.appname = application_name; -// sr.reasongiven = reason; - sr.cookie = m_next_cookie++; - sr.type = ScreenSaverRequest::Throttle; - sr.dbusid = message().service(); - m_requests.append( sr ); - m_serviceWatcher->addWatchedService(sr.dbusid); - m_nr_throttled++; - if (mLockProcess) - // XXX race condition here (locker may be not ready yet) - ::kill(mLockProcess->pid(), SIGSTOP); - return sr.cookie; -} - -void SaverEngine::UnThrottle(uint cookie) -{ - QMutableListIterator it( m_requests ); - while ( it.hasNext() ) - { - if ( it.next().cookie == cookie ) { - it.remove(); - if ( !--m_nr_throttled ) - if (mLockProcess) - ::kill(mLockProcess->pid(), SIGCONT); - } - } -} - -void SaverEngine::serviceUnregistered(const QString& name) -{ - m_serviceWatcher->removeWatchedService( name ); - QListIterator it( m_requests ); - while ( it.hasNext() ) - { - const ScreenSaverRequest &r = it.next(); - if ( r.dbusid == name ) - { - if ( r.type == ScreenSaverRequest::Throttle ) - UnThrottle( r.cookie ); - else - UnInhibit( r.cookie ); - } - } -} - -#include "saverengine.moc" - - diff --git a/krunner/screensaver/saverengine.h b/krunner/screensaver/saverengine.h deleted file mode 100644 index 3384d4a..0000000 --- a/krunner/screensaver/saverengine.h +++ /dev/null @@ -1,185 +0,0 @@ -//=========================================================================== -// -// This file is part of the KDE project -// -// Copyright 1999 Martin R. Jones -// - -#ifndef SAVERENGINE_H -#define SAVERENGINE_H - -#include -#include -#include -#include - -class QDBusServiceWatcher; -class KProcess; - -#include "xautolock.h" -#include "xautolock_c.h" - -class ScreenSaverRequest -{ -public: -// QString appname; -// QString reasongiven; - QString dbusid; - uint cookie; - enum { Inhibit,Throttle } type; -}; - -//=========================================================================== -/** - * Screen saver engine. Handles screensaver window, starting screensaver - * hacks, and password entry. - */ -class SaverEngine : public QWidget, protected QDBusContext -{ - Q_OBJECT - Q_CLASSINFO("D-Bus Interface", "org.freedesktop.ScreenSaver") - -public: - SaverEngine(); - ~SaverEngine(); - -public Q_SLOTS: - /** - * Lock the screen now even if the screensaver does not lock by default. - */ - void Lock(); - - /** - * Save the screen now. If the user has locking enabled, the screen is locked also. - */ - bool save(); - - /** - * Start the screensaver in plasma-setup mode. - * if plasma is not enabled, this just locks the screen. - */ - bool setupPlasma(); - - /** - * Quit the screensaver if it is running - */ - bool quit(); - - /** - * Simulate user activity - */ - void SimulateUserActivity(); - - /** - * Return true if the screensaver is enabled - */ - bool isEnabled(); - - /** - * Enable/disable the screensaver - * @return true if the action succeeded - */ - bool enable( bool e, bool force = false ); - - /** - * Return true if the screen is currently blanked - */ - bool isBlanked(); - - /** - * Read and apply configuration. - */ - void configure(); - - /** - * Called by krunner_lock when locking is in effect. - */ - void saverLockReady(); - - /** - * Request a change in the state of the screensaver. - * Set to TRUE to request that the screensaver activate. - * Active means that the screensaver has blanked the - * screen and may run a graphical theme. This does - * not necessary mean that the screen is locked. - */ - bool SetActive( bool state ); - - /// Returns the value of the current state of activity (See setActive) - bool GetActive(); - - /** - * Returns the number of seconds that the screensaver has - * been active. Returns zero if the screensaver is not active. - */ - uint GetActiveTime(); - - /** - * Returns the number of seconds that the session has - * been idle. Returns zero if the session is not idle. - */ - uint GetSessionIdleTime(); - - /** - * Request that saving the screen due to system idleness - * be blocked until UnInhibit is called or the - * calling process exits. - * The cookie is a random number used to identify the request - */ - uint Inhibit(const QString &application_name, const QString &reason_for_inhibit); - /// Cancel a previous call to Inhibit() identified by the cookie. - void UnInhibit(uint cookie); - - /** - * Request that running themes while the screensaver is active - * be blocked until UnThrottle is called or the - * calling process exits. - * The cookie is a random number used to identify the request - */ - uint Throttle(const QString &application_name, const QString &reason_for_inhibit); - /// Cancel a previous call to Throttle() identified by the cookie. - void UnThrottle(uint cookie); - -Q_SIGNALS: - // DBus signals - void ActiveChanged(bool state); - -protected Q_SLOTS: - void idleTimeout(); - void lockProcessExited(); - void serviceUnregistered(const QString&); - -protected: - enum LockType { DontLock, DefaultLock, ForceLock, PlasmaSetup }; - bool startLockProcess( LockType lock_type ); - void stopLockProcess(); - bool handleKeyPress(XKeyEvent *xke); - void processLockTransactions(); - xautolock_corner_t applyManualSettings(int); - -private: - enum State { Waiting, Preparing, Saving }; - - State mState; - XAutoLock *mXAutoLock; - KProcess *mLockProcess; - - // the original X screensaver parameters - int mXTimeout; - int mXInterval; - int mXBlanking; - int mXExposures; - - time_t m_actived_time; - QList m_requests; - QDBusServiceWatcher *m_serviceWatcher; - uint m_next_cookie; - - int m_nr_throttled; - int m_nr_inhibited; - - QList mLockTransactions; -}; - -#endif - diff --git a/krunner/screensaver/xautolock.cpp b/krunner/screensaver/xautolock.cpp deleted file mode 100644 index 7124215..0000000 --- a/krunner/screensaver/xautolock.cpp +++ /dev/null @@ -1,317 +0,0 @@ -//---------------------------------------------------------------------------- -// -// This file is part of the KDE project -// -// Copyright 1999 Martin R. Jones -// Copyright 2003 Lubos Lunak -// -// KDE screensaver engine -// - -#include - -#include "xautolock.h" -#include "xautolock_c.h" - -#include -#include - -#include -#include - -#include -#include - -#ifdef HAVE_DPMS -extern "C" { -#include -#ifndef Bool -#define Bool BOOL -#endif -#include - -#ifndef HAVE_DPMSINFO_PROTO -Status DPMSInfo ( Display *, CARD16 *, BOOL * ); -#endif -} -#endif - -#include - -xautolock_corner_t xautolock_corners[ 4 ]; - -static XAutoLock* self = NULL; - -extern "C" { -static int catchFalseAlarms(Display *, XErrorEvent *) -{ - return 0; -} -} - -//=========================================================================== -// -// Detect user inactivity. -// Named XAutoLock after the program that it is based on. -// -XAutoLock::XAutoLock() -{ - self = this; -#ifdef HAVE_XSCREENSAVER - mMitInfo = 0; - int dummy; - if (XScreenSaverQueryExtension( QX11Info::display(), &dummy, &dummy )) - { - mMitInfo = XScreenSaverAllocInfo(); - } - else -#endif - { - kapp->installX11EventFilter( this ); - int (*oldHandler)(Display *, XErrorEvent *); - oldHandler = XSetErrorHandler(catchFalseAlarms); - XSync(QX11Info::display(), False ); - xautolock_initDiy( QX11Info::display()); - XSync(QX11Info::display(), False ); - XSetErrorHandler(oldHandler); - } - - mTimeout = DEFAULT_TIMEOUT; - mDPMS = true; - resetTrigger(); - - mActive = false; - - mTimerId = startTimer( CHECK_INTERVAL ); - // This is an internal clock timer (in seconds), used instead of querying system time. - // It is incremented manually, preventing from problems with clock jumps. - // In other words, this is the 'now' time and the reference point for other times here. - mElapsed = 0; -} - -//--------------------------------------------------------------------------- -// -// Destructor. -// -XAutoLock::~XAutoLock() -{ - stop(); - self = NULL; -} - -//--------------------------------------------------------------------------- -// -// The time in seconds of continuous inactivity. -// -void XAutoLock::setTimeout(int t) -{ - mTimeout = t; -} - -void XAutoLock::setDPMS(bool s) -{ -#ifdef HAVE_DPMS - BOOL on; - CARD16 state; - DPMSInfo( QX11Info::display(), &state, &on ); - if (!on) - s = false; -#endif - mDPMS = s; -} - -//--------------------------------------------------------------------------- -// -// Start watching Activity -// -void XAutoLock::start() -{ - mActive = true; - resetTrigger(); -} - -//--------------------------------------------------------------------------- -// -// Stop watching Activity -// -void XAutoLock::stop() -{ - mActive = false; - resetTrigger(); -} - -//--------------------------------------------------------------------------- -// -// Reset the trigger time. -// -void XAutoLock::resetTrigger() -{ - // Time of the last user activity (used only when the internal XScreensaver - // idle counter is not available). - mLastReset = mElapsed; - // Time when screensaver should be activated. - mTrigger = mElapsed + mTimeout; -#ifdef HAVE_XSCREENSAVER - mLastIdle = 0; -#endif - // Do not reset the internal X screensaver here (no XForceScreenSaver()) -} - -//--------------------------------------------------------------------------- -// -// Move the trigger time in order to postpone (repeat) emitting of timeout(). -// -void XAutoLock::postpone() -{ - mTrigger = mElapsed + 60; // delay by 60sec -} - -//--------------------------------------------------------------------------- -// -// Set the remaining time to 't', if it's shorter than already set. -// -void XAutoLock::setTrigger( int t ) -{ - time_t newT = mElapsed + qMax(t, 0); - if (mTrigger > newT) - mTrigger = newT; -} - -//--------------------------------------------------------------------------- -// -// Process new windows and check the mouse. -// -void XAutoLock::timerEvent(QTimerEvent *ev) -{ - if (ev->timerId() != mTimerId) - { - return; - } - mElapsed += CHECK_INTERVAL / 1000; - -#ifdef HAVE_XSCREENSAVER - if (!mMitInfo) -#endif - { // only the diy way needs special X handler - XSync( QX11Info::display(), False ); - int (*oldHandler)(Display *, XErrorEvent *) = - XSetErrorHandler(catchFalseAlarms); - - xautolock_processQueue(); - - XSetErrorHandler(oldHandler); - } - -#ifdef HAVE_XSCREENSAVER - if (mMitInfo) - { - Display *d = QX11Info::display(); - // Check user idle time. If it is smaller than before, it is either - // clock jump or user activity, so reset the trigger time. Checking whether - // there is user inactivity timeout is done below using mTrigger and mElapsed. - XScreenSaverQueryInfo(d, DefaultRootWindow(d), mMitInfo); - if (mLastIdle < mMitInfo->idle) - mLastIdle = mMitInfo->idle; - else - resetTrigger(); - } -#endif /* HAVE_XSCREENSAVER */ - - // This needs to be after the above check, so it overrides it. - xautolock_queryPointer( QX11Info::display()); - - bool activate = false; - - // This is the test whether to activate screensaver. If we have reached the time - // and for the whole timeout period there was no activity (which would change mTrigger - // again), activate. - if (mElapsed >= mTrigger) - activate = true; - -#ifdef HAVE_DPMS - BOOL on; - CARD16 state; - CARD16 timeout1, timeout2, timeout3; - DPMSInfo( QX11Info::display(), &state, &on ); - DPMSGetTimeouts( QX11Info::display(), &timeout1, &timeout2, &timeout3 ); - - // kDebug() << "DPMSInfo " << state << on; - // If DPMS is active, it makes XScreenSaverQueryInfo() report idle time - // that is always smaller than DPMS timeout (X bug I guess). So if DPMS - // saving is active, simply always activate our saving too, otherwise - // this could prevent locking from working. - // X.Org 7.4: With this version activating DPMS resets the screensaver idle timer, - // so keep this. It probably makes sense to always do this anyway. - if(state == DPMSModeStandby || state == DPMSModeSuspend || state == DPMSModeOff) - activate = true; - // If we are DPMS-dependent and either DPMS is turned off completely or all - // three DPMS modes are turned off, don't activate (apps use this to turn off - // screensavers). - if(mDPMS && (!on || (timeout1 == 0 && timeout2 == 0 && timeout3 == 0 ))) { - activate = false; - resetTrigger(); - } -#endif - - // Do not check whether internal X screensaver is enabled or disabled, since we - // have disabled it ourselves. Some apps might try to disable it too to prevent - // screensavers, but then our logic breaks[*]. Those apps need to disable DPMS anyway, - // or they will still have problems, so the DPMS code above should be enough. - // Besides, I doubt other screensaver implementations check this either. - // [*] We can't run with X screensaver enabled, since then sooner or later - // the internal screensaver will activate instead of our screensaver and we cannot - // prevent its activation by resetting the idle counter since that would also - // reset DPMS saving. - - if(mActive && activate) - emit timeout(); -} - -bool XAutoLock::x11Event( XEvent* ev ) -{ - xautolock_processEvent( ev ); -// don't futher process key events that were received only because XAutoLock wants them - if( ev->type == KeyPress && !ev->xkey.send_event -#ifdef HAVE_XSCREENSAVER - && !mMitInfo -#endif - && !QWidget::find( ev->xkey.window )) - return true; - return false; -} - -bool XAutoLock::ignoreWindow( WId w ) -{ - if( w != QX11Info::appRootWindow() && QWidget::find( w )) - return true; - return false; -} - -time_t XAutoLock::idleTime() -{ -#ifdef HAVE_XSCREENSAVER - if (mMitInfo) - return mMitInfo->idle / 1000; -#endif - return mElapsed - mLastReset; -} - -extern "C" -void xautolock_resetTriggers() -{ - self->resetTrigger(); -} - -extern "C" -void xautolock_setTrigger( int t ) -{ - self->setTrigger( t ); -} - -extern "C" -int xautolock_ignoreWindow( Window w ) -{ - return self->ignoreWindow( w ); -} - -#include "xautolock.moc" diff --git a/krunner/screensaver/xautolock.h b/krunner/screensaver/xautolock.h deleted file mode 100644 index 3db3233..0000000 --- a/krunner/screensaver/xautolock.h +++ /dev/null @@ -1,91 +0,0 @@ -//=========================================================================== -// -// This file is part of the KDE project -// -// Copyright 1999 Martin R. Jones -// - -#ifndef __XAUTOLOCK_H__ -#define __XAUTOLOCK_H__ - -#include - -#include - -#include -#ifdef HAVE_XSCREENSAVER -# include -#endif -#include - -//=========================================================================== -// -// Detect user inactivity. -// Named XAutoLock after the program that it is based on. -// -class XAutoLock : public QWidget -{ - Q_OBJECT -public: - XAutoLock(); - ~XAutoLock(); - - //----------------------------------------------------------------------- - // - // The time in seconds of continuous inactivity. - // Need to call start() again afterwards. - // - void setTimeout(int t); - - void setDPMS(bool s); - - //----------------------------------------------------------------------- - // - // Start watching Activity - // - void start(); - - //----------------------------------------------------------------------- - // - // Stop watching Activity - // - void stop(); - - //----------------------------------------------------------------------- - // - // Should be called only from a slot connected to the timeout() signal. Will - // result in the timeout() signal being emitted again with a delay (i.e. postponed). - // - void postpone(); - - // internal - void resetTrigger(); - // internal - void setTrigger( int ); - // internal - bool ignoreWindow( WId ); - // internal - time_t idleTime(); - -Q_SIGNALS: - void timeout(); - -protected: - virtual void timerEvent(QTimerEvent *ev); - virtual bool x11Event( XEvent* ); - -protected: - int mTimerId; - int mTimeout; - time_t mTrigger; - bool mActive; - time_t mLastReset; - time_t mElapsed; - bool mDPMS; -#ifdef HAVE_XSCREENSAVER - XScreenSaverInfo *mMitInfo; - ulong mLastIdle; -#endif -}; - -#endif diff --git a/krunner/screensaver/xautolock_c.h b/krunner/screensaver/xautolock_c.h deleted file mode 100644 index 3b82f5c..0000000 --- a/krunner/screensaver/xautolock_c.h +++ /dev/null @@ -1,65 +0,0 @@ -/***************************************************************************** - * - * Authors: Michel Eyckmans (MCE) & Stefan De Troch (SDT) - * - * Content: This file is part of version 2.x of xautolock. It takes care - * of most OS dependencies, and defines the program's default - * settings. - * - * Please send bug reports etc. to eyckmans@imec.be. - * - * -------------------------------------------------------------------------- - * - * Copyright 1990,1992-1999,2001-2002 by Stefan De Troch and Michel Eyckmans. - * - * Versions 2.0 and above of xautolock are available under version 2 of the - * GNU GPL. Earlier versions are available under other conditions. For more - * information, see the License file. - * - *****************************************************************************/ - -#ifndef __xautolock_c_h -#define __xautolock_c_h - -#include -#ifdef __cplusplus -# include -#endif - -#define DEFAULT_TIMEOUT 600 - -#define CHECK_INTERVAL 5000 /* ms */ - -#define CREATION_DELAY 30 /* should be > 10 and - < min (45,(MIN_MINUTES*30)) */ -#define TIME_CHANGE_LIMIT 120 /* if the time changes by more - than x secs then we will - assume someone has changed - date or machine has suspended */ - -#define cornerSize 5 - -#define cornerDelay 5 - -#define cornerRedelay 5 - -typedef enum { ca_nothing, ca_dontLock, ca_forceLock } xautolock_corner_t; - -#ifdef __cplusplus -extern "C" -{ -#endif -void xautolock_processEvent( XEvent* ev ); -void xautolock_processQueue( void ); -void xautolock_queryPointer (Display* d); -void xautolock_initDiy (Display* d); -void xautolock_resetTriggers( void ); -void xautolock_setTrigger( int ); -int xautolock_ignoreWindow( Window ); -extern xautolock_corner_t xautolock_corners[ 4 ]; -#ifdef __cplusplus -} -#endif - - -#endif diff --git a/krunner/screensaver/xautolock_diy.c b/krunner/screensaver/xautolock_diy.c deleted file mode 100644 index b9df2f8..0000000 --- a/krunner/screensaver/xautolock_diy.c +++ /dev/null @@ -1,289 +0,0 @@ -/***************************************************************************** - * - * Authors: Michel Eyckmans (MCE) & Stefan De Troch (SDT) - * - * Content: This file is part of version 2.x of xautolock. It implements - * the stuff used when the program is not using a screen saver - * extension and thus has to use the good old "do it yourself" - * approach for detecting user activity. - * - * The basic idea is that we initially traverse the window tree, - * selecting SubstructureNotify on all windows and adding each - * window to a temporary list. About +- 30 seconds later, we - * scan this list, now asking for KeyPress events. The delay - * is needed in order to interfere as little as possible with - * the event propagation mechanism. Whenever a new window is - * created by an application, a similar process takes place. - * - * Please send bug reports etc. to eyckmans@imec.be. - * - * -------------------------------------------------------------------------- - * - * Copyright 1990,1992-1999,2001-2002 by Stefan De Troch and Michel Eyckmans. - * - * Versions 2.0 and above of xautolock are available under version 2 of the - * GNU GPL. Earlier versions are available under other conditions. For more - * information, see the License file. - * - *****************************************************************************/ - -#include -#include -#include - -#include "xautolock_c.h" - -static void selectEvents (Window window, Bool substructureOnly); - -/* - * Window queue management. - */ -typedef struct item -{ - Window window; - time_t creationtime; - struct item* next; -} xautolock_anItem, *xautolock_item; - -static struct -{ - Display* display; - struct item* head; - struct item* tail; -} queue; - -static void -addToQueue (Window window) -{ - xautolock_item newItem = malloc(sizeof(xautolock_anItem)); - - newItem->window = window; - newItem->creationtime = time (0); - newItem->next = 0; - - if (!queue.head) queue.head = newItem; - if ( queue.tail) queue.tail->next = newItem; - - queue.tail = newItem; -} - -static void -processQueue (time_t age) -{ - if (queue.head) - { - time_t now = time (0); - xautolock_item current = queue.head; - - while (current && current->creationtime + age < now) - { - selectEvents (current->window, False); - queue.head = current->next; - free (current); - current = queue.head; - } - - if (!queue.head) queue.tail = 0; - } -} - -/* - * Function for selecting all interesting events on a given - * (tree of) window(s). - */ -static void -selectEvents (Window window, Bool substructureOnly) -{ - Window root; /* root window of the window */ - Window parent; /* parent of the window */ - Window* children; /* children of the window */ - unsigned nofChildren = 0; /* number of children */ - unsigned i; /* loop counter */ - XWindowAttributes attribs; /* attributes of the window */ - - if( xautolock_ignoreWindow( window )) - return; - /* - * Start by querying the server about the root and parent windows. - */ - if (!XQueryTree (queue.display, window, &root, &parent, - &children, &nofChildren)) - { - return; - } - - if (nofChildren) (void) XFree ((char*) children); - - /* - * Build the appropriate event mask. The basic idea is that we don't - * want to interfere with the normal event propagation mechanism if - * we don't have to. - * - * On the root window, we need to ask for both substructureNotify - * and KeyPress events. On all other windows, we always need - * substructureNotify, but only need Keypress if some other client - * also asked for them, or if they are not being propagated up the - * window tree. - */ -#if 0 - if (substructureOnly) - { - (void) XSelectInput (queue.display, window, SubstructureNotifyMask); - } - else - { - if (parent == None) /* the *real* rootwindow */ - { - attribs.all_event_masks = - attribs.do_not_propagate_mask = KeyPressMask; - } - else if (!XGetWindowAttributes (queue.display, window, &attribs)) -#else - { - if (!XGetWindowAttributes (queue.display, window, &attribs)) -#endif - { - return; - } - -#if 0 - (void) XSelectInput (queue.display, window, - SubstructureNotifyMask - | ( ( attribs.all_event_masks - | attribs.do_not_propagate_mask) - & KeyPressMask)); -#else - { - int mask = SubstructureNotifyMask | attribs.your_event_mask; - if( !substructureOnly ) - { - mask |= ( ( attribs.all_event_masks - | attribs.do_not_propagate_mask) - & KeyPressMask ); - } - (void) XSelectInput (queue.display, window, mask ); - } -#endif - - } - - /* - * Now ask for the list of children again, since it might have changed - * in between the last time and us selecting SubstructureNotifyMask. - * - * There is a (very small) chance that we might process a subtree twice: - * child windows that have been created after our XSelectinput() has - * been processed but before we get to the XQueryTree() bit will be - * in this situation. This is harmless. It could be avoided by using - * XGrabServer(), but that'd be an impolite thing to do, and since it - * isn't required... - */ - if (!XQueryTree (queue.display, window, &root, &parent, - &children, &nofChildren)) - { - return; - } - - /* - * Now do the same thing for all children. - */ - for (i = 0; i < nofChildren; ++i) - { - selectEvents (children[i], substructureOnly); - } - - if (nofChildren) (void) XFree ((char*) children); -} - -#if 0 -/* - * Function for processing any events that have come in since - * last time. It is crucial that this function does not block - * in case nothing interesting happened. - */ -void -processEvents (void) -{ - while (XPending (queue.display)) - { - XEvent event; - - if (XCheckMaskEvent (queue.display, SubstructureNotifyMask, &event)) - { - if (event.type == CreateNotify) - { - addToQueue (event.xcreatewindow.window); - } - } - else - { - (void) XNextEvent (queue.display, &event); - } - - /* - * Reset the triggers if and only if the event is a - * KeyPress event *and* was not generated by XSendEvent(). - */ - if ( event.type == KeyPress - && !event.xany.send_event) - { - resetTriggers (); - } - } - - /* - * Check the window queue for entries that are older than - * CREATION_DELAY seconds. - */ - processQueue ((time_t) CREATION_DELAY); -} -#else -void xautolock_processEvent( XEvent* event ) -{ - if (event->type == CreateNotify) - { - addToQueue (event->xcreatewindow.window); - } - /* - * Reset the triggers if and only if the event is a - * KeyPress event *and* was not generated by XSendEvent(). - */ - if ( event->type == KeyPress - && !event->xany.send_event) - { - xautolock_resetTriggers (); - } -} - -void xautolock_processQueue() -{ - /* - * Check the window queue for entries that are older than - * CREATION_DELAY seconds. - */ - processQueue ((time_t) CREATION_DELAY); -} -#endif - - -/* - * Function for initialising the whole shebang. - */ -void -xautolock_initDiy (Display* d) -{ - int s; - - queue.display = d; - queue.tail = 0; - queue.head = 0; - - for (s = -1; ++s < ScreenCount (d); ) - { - Window root = RootWindowOfScreen (ScreenOfDisplay (d, s)); - addToQueue (root); -#if 0 - selectEvents (root, True); -#endif - } -} diff --git a/krunner/screensaver/xautolock_engine.c b/krunner/screensaver/xautolock_engine.c deleted file mode 100644 index d6d0cf5..0000000 --- a/krunner/screensaver/xautolock_engine.c +++ /dev/null @@ -1,137 +0,0 @@ -/***************************************************************************** - * - * Authors: Michel Eyckmans (MCE) & Stefan De Troch (SDT) - * - * Content: This file is part of version 2.x of xautolock. It implements - * the program's core functions. - * - * Please send bug reports etc. to eyckmans@imec.be. - * - * -------------------------------------------------------------------------- - * - * Copyright 1990,1992-1999,2001-2002 by Stefan De Troch and Michel Eyckmans. - * - * Versions 2.0 and above of xautolock are available under version 2 of the - * GNU GPL. Earlier versions are available under other conditions. For more - * information, see the License file. - * - *****************************************************************************/ - -#include "xautolock_c.h" - -/* - * Function for monitoring pointer movements. This implements the - * `corners' feature and as a side effect also tracks pointer - * related user activity. The latter actually is only needed when - * we're using the DIY mode of operations, but it's much simpler - * to do it unconditionally. - */ -void -xautolock_queryPointer (Display* d) -{ - Window dummyWin; /* as it says */ - int dummyInt; /* as it says */ - unsigned mask; /* modifier mask */ - int rootX; /* as it says */ - int rootY; /* as it says */ - int corner; /* corner index */ - int i; /* loop counter */ - static Window root; /* root window the pointer is on */ - static Screen* screen; /* screen the pointer is on */ - static unsigned prevMask = 0; /* as it says */ - static int prevRootX = -1; /* as it says */ - static int prevRootY = -1; /* as it says */ - static Bool firstCall = True; /* as it says */ - - /* - * Have a guess... - */ - if (firstCall) - { - firstCall = False; - root = DefaultRootWindow (d); - screen = ScreenOfDisplay (d, DefaultScreen (d)); - } - - /* - * Find out whether the pointer has moved. Using XQueryPointer for this - * is gross, but it also is the only way never to mess up propagation - * of pointer events. - */ - if (!XQueryPointer (d, root, &root, &dummyWin, &rootX, &rootY, - &dummyInt, &dummyInt, &mask)) - { - /* - * Pointer has moved to another screen, so let's find out which one. - */ - for (i = -1; ++i < ScreenCount (d); ) - { - if (root == RootWindow (d, i)) - { - screen = ScreenOfDisplay (d, i); - break; - } - } - } - - if ( rootX == prevRootX - && rootY == prevRootY - && mask == prevMask) - { - xautolock_corner_t* corners = xautolock_corners; - /* - * If the pointer has not moved since the previous call and - * is inside one of the 4 corners, we act according to the - * contents of the "corners" array. - * - * If rootX and rootY are less than zero, don't lock even if - * ca_forceLock is set in the upper-left corner. Why? 'cause - * on initial server startup, if (and only if) the pointer is - * never moved, XQueryPointer() can return values less than - * zero (only some servers, Openwindows 2.0 and 3.0 in - * particular). - */ - if ( (corner = 0, - rootX <= cornerSize && rootX >= 0 - && rootY <= cornerSize && rootY >= 0) - || (corner++, - rootX >= WidthOfScreen (screen) - cornerSize - 1 - && rootY <= cornerSize) - || (corner++, - rootX <= cornerSize - && rootY >= HeightOfScreen (screen) - cornerSize - 1) - || (corner++, - rootX >= WidthOfScreen (screen) - cornerSize - 1 - && rootY >= HeightOfScreen (screen) - cornerSize - 1)) - { - switch (corners[corner]) - { - case ca_forceLock: -#if 0 - xautolock_setTrigger( (useRedelay ? cornerRedelay : cornerDelay) - 1 ); -#else - xautolock_setTrigger( 0 ); -#endif - break; - - case ca_dontLock: - xautolock_resetTriggers (); - -#ifdef __GNUC__ - default: ; /* Makes gcc -Wall shut up. */ -#endif /* __GNUC__ */ - } - } - } - else - { -#if 0 - useRedelay = False; -#endif - prevRootX = rootX; - prevRootY = rootY; - prevMask = mask; - - xautolock_resetTriggers (); - } -} diff --git a/ksmserver/CMakeLists.txt b/ksmserver/CMakeLists.txt index 5f0fd34..a0cd920 100644 --- a/ksmserver/CMakeLists.txt +++ b/ksmserver/CMakeLists.txt @@ -11,6 +11,12 @@ include_directories( add_subdirectory( tests ) +if(NOT WIN32) + macro_optional_add_subdirectory( screenlocker ) + set(COMPILE_SCREEN_LOCKER 1) + set(SCREEN_LOCKER "screenlocker_static") +endif(NOT WIN32) + check_library_exists(ICE _IceTransNoListen "" HAVE__ICETRANSNOLISTEN) configure_file(config-ksmserver.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-ksmserver.h) @@ -54,7 +60,7 @@ qt4_add_dbus_adaptor( ksmserver_KDEINIT_SRCS org.kde.KSMServerInterface.xml serv kde4_add_kdeinit_executable( ksmserver ${ksmserver_KDEINIT_SRCS}) -target_link_libraries(kdeinit_ksmserver ${KDE4_PLASMA_LIBS} kworkspace +target_link_libraries(kdeinit_ksmserver ${SCREEN_LOCKER} ${KDE4_PLASMA_LIBS} kworkspace ${KDE4_KDEUI_LIBS} ${KDE4_KIO_LIBS} ${QIMAGEBLITZ_LIBRARIES} ${KDE4_SOLID_LIBS} ${X11_LIBRARIES} ${X11_Xrender_LIB} ${QT_QTDECLARATIVE_LIBRARY} ${KDECLARATIVE_LIBRARIES} ) diff --git a/ksmserver/config-ksmserver.h.cmake b/ksmserver/config-ksmserver.h.cmake index 933da35..4b60c8c 100644 --- a/ksmserver/config-ksmserver.h.cmake +++ b/ksmserver/config-ksmserver.h.cmake @@ -1,3 +1,4 @@ /* Define to 1 if you have the `_IceTransNoListen' function. */ #cmakedefine HAVE__ICETRANSNOLISTEN 1 +#cmakedefine COMPILE_SCREEN_LOCKER 1 diff --git a/ksmserver/main.cpp b/ksmserver/main.cpp index 430a61a..23f089d 100644 --- a/ksmserver/main.cpp +++ b/ksmserver/main.cpp @@ -246,6 +246,9 @@ extern "C" KDE_EXPORT int kdemain( int argc, char* argv[] ) options.add("w"); options.add("windowmanager ", ki18n("Starts 'wm' in case no other window manager is \nparticipating in the session. Default is 'kwin'")); options.add("nolocal", ki18n("Also allow remote connections")); +#if COMPILE_SCREEN_LOCKER + options.add("lockscreen", ki18n("Starts the screenlocker in locked mode")); +#endif KCmdLineArgs::addCmdLineOptions( options ); putenv((char*)"SESSION_MANAGER="); @@ -282,7 +285,11 @@ extern "C" KDE_EXPORT int kdemain( int argc, char* argv[] ) only_local = false; #endif - KSMServer *server = new KSMServer( wm, only_local); +#if COMPILE_SCREEN_LOCKER + KSMServer *server = new KSMServer( wm, only_local, args->isSet("lockscreen") ); +#else + KSMServer *server = new KSMServer( wm, only_local ); +#endif // for the KDE-already-running check in startkde KSelectionOwner kde_running( "_KDE_RUNNING", 0 ); diff --git a/ksmserver/screenlocker/CMakeLists.txt b/ksmserver/screenlocker/CMakeLists.txt new file mode 100644 index 0000000..d3dac2a --- /dev/null +++ b/ksmserver/screenlocker/CMakeLists.txt @@ -0,0 +1,34 @@ +# for dbus_add_activation_service +include(PkgConfigGetVar) + +add_definitions(-DKDE_DEFAULT_DEBUG_AREA=1223) +add_subdirectory(data) +add_subdirectory(greeter) + +# for dbus_add_activation_service +include(PkgConfigGetVar) + +include_directories(${KDEBASE_WORKSPACE_SOURCE_DIR}/libs/kworkspace) + +set(screensaver_dbusXML dbus/org.freedesktop.ScreenSaver.xml) +set(kscreensaver_dbusXML dbus/org.kde.screensaver.xml) +set(ksmserver_xml ${KDEBASE_WORKSPACE_SOURCE_DIR}/ksmserver/org.kde.KSMServerInterface.xml) + +set(ksld_SRCS + ksldapp.cpp + autologout.cpp + interface.cpp + lockwindow.cpp) +qt4_add_dbus_adaptor(ksld_SRCS ${screensaver_dbusXML} interface.h ScreenLocker::Interface) +qt4_add_dbus_adaptor(ksld_SRCS ${kscreensaver_dbusXML} interface.h ScreenLocker::Interface kscreensaveradaptor KScreenSaverAdaptor) +kde4_add_kcfg_files(ksld_SRCS kcfg/kscreensaversettings.kcfgc) +QT4_ADD_DBUS_INTERFACE(ksld_SRCS ${ksmserver_xml} ksmserver_interface) + +kde4_add_library(screenlocker_static STATIC ${ksld_SRCS}) + +target_link_libraries(screenlocker_static kworkspace kephal ${KDE4_KDEUI_LIBS} ${KDE4_KIDLETIME_LIBS} ${X11_LIBRARIES}) + +# Needed to compile on Arm target. +set_target_properties(screenlocker_static PROPERTIES COMPILE_FLAGS "-fPIC") + +install(FILES kscreenlocker.notifyrc DESTINATION ${DATA_INSTALL_DIR}/ksmserver/ksmserver.notifyrc) diff --git a/ksmserver/screenlocker/Messages.sh b/ksmserver/screenlocker/Messages.sh new file mode 100644 index 0000000..7857f3f --- /dev/null +++ b/ksmserver/screenlocker/Messages.sh @@ -0,0 +1,4 @@ +#!bin/sh +$EXTRACTRC kcfg/*.kcfg >> rc.cpp +# do not include subdirectory as it has an own Messages.sh +$XGETTEXT *.h *.cpp -o $podir/kscreenlocker.pot diff --git a/ksmserver/screenlocker/autologout.cpp b/ksmserver/screenlocker/autologout.cpp new file mode 100644 index 0000000..74fd958 --- /dev/null +++ b/ksmserver/screenlocker/autologout.cpp @@ -0,0 +1,118 @@ +//=========================================================================== +// +// This file is part of the KDE project +// +// Copyright 2004 Chris Howells + +#include "autologout.h" +#include "lockwindow.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define COUNTDOWN 30 + +AutoLogout::AutoLogout(ScreenLocker::LockWindow *parent) : QDialog(NULL, Qt::X11BypassWindowManagerHint) +{ + QLabel *pixLabel = new QLabel( this ); + pixLabel->setObjectName( QLatin1String( "pixlabel" ) ); + pixLabel->setPixmap(DesktopIcon(QLatin1String( "application-exit" ))); + + QLabel *greetLabel = new QLabel(i18n("Automatic Log Out"), this); + QLabel *infoLabel = new QLabel(i18n("To prevent being logged out, resume using this session by moving the mouse or pressing a key."), this); + + mStatusLabel = new QLabel(QLatin1String( " " ), this); + mStatusLabel->setAlignment(Qt::AlignCenter); + + QLabel *mProgressLabel = new QLabel(i18n("Time Remaining:"), this); + mProgressRemaining = new QProgressBar(this); + mProgressRemaining->setTextVisible(false); + + frameLayout = new QGridLayout(this); + frameLayout->setSpacing(KDialog::spacingHint()); + frameLayout->setMargin(KDialog::marginHint() * 2); + frameLayout->addWidget(pixLabel, 0, 0, 3, 1, Qt::AlignCenter | Qt::AlignTop); + frameLayout->addWidget(greetLabel, 0, 1); + frameLayout->addWidget(mStatusLabel, 1, 1); + frameLayout->addWidget(infoLabel, 2, 1); + frameLayout->addWidget(mProgressLabel, 3, 1); + frameLayout->addWidget(mProgressRemaining, 4, 1); + + // get the time remaining in seconds for the status label + mRemaining = COUNTDOWN * 25; + + mProgressRemaining->setMaximum(COUNTDOWN * 25); + + updateInfo(mRemaining); + + mCountdownTimerId = startTimer(1000/25); + + connect(parent, SIGNAL(userActivity()), SLOT(slotActivity())); +} + +AutoLogout::~AutoLogout() +{ + hide(); +} + +void AutoLogout::updateInfo(int timeout) +{ + mStatusLabel->setText(i18np("You will be automatically logged out in 1 second", + "You will be automatically logged out in %1 seconds", + timeout / 25) ); + mProgressRemaining->setValue(timeout); +} + +void AutoLogout::timerEvent(QTimerEvent *ev) +{ + if (ev->timerId() == mCountdownTimerId) + { + updateInfo(mRemaining); + --mRemaining; + if (mRemaining < 0) + { + killTimer(mCountdownTimerId); + logout(); + } + } +} + +void AutoLogout::slotActivity() +{ + if (mRemaining >= 0) + accept(); +} + +void AutoLogout::logout() +{ + QAbstractEventDispatcher::instance()->unregisterTimers(this); + org::kde::KSMServerInterface ksmserver(QLatin1String( "org.kde.ksmserver" ), QLatin1String( "/KSMServer" ), QDBusConnection::sessionBus()); + ksmserver.logout( 0, 0, 0 ); +} + +void AutoLogout::setVisible(bool visible) +{ + QDialog::setVisible(visible); + + if (visible) + QApplication::flush(); +} + +#include "autologout.moc" diff --git a/ksmserver/screenlocker/autologout.h b/ksmserver/screenlocker/autologout.h new file mode 100644 index 0000000..ea2693a --- /dev/null +++ b/ksmserver/screenlocker/autologout.h @@ -0,0 +1,53 @@ +//=========================================================================== +// +// This file is part of the KDE project +// +// Copyright 1999 Martin R. Jones +// Copyright 2003 Oswald Buddenhagen +// Copyright 2004 Chris Howells + +#ifndef AUTOLOGOUT_H +#define AUTOLOGOUT_H + +#include +#include +#include + +namespace ScreenLocker +{ +class LockWindow; +} + +class LockProcess; +class QGridLayout; +class QLabel; +class QDialog; +class QProgressBar; + +class AutoLogout : public QDialog +{ + Q_OBJECT + +public: + AutoLogout(ScreenLocker::LockWindow *parent); + ~AutoLogout(); + virtual void setVisible(bool visible); + +protected: + virtual void timerEvent(QTimerEvent *); + +private Q_SLOTS: + void slotActivity(); + +private: + void updateInfo(int); + QGridLayout *frameLayout; + QLabel *mStatusLabel; + int mCountdownTimerId; + int mRemaining; + QTimer countDownTimer; + QProgressBar *mProgressRemaining; + void logout(); +}; + +#endif // AUTOLOGOUT_H diff --git a/ksmserver/screenlocker/data/CMakeLists.txt b/ksmserver/screenlocker/data/CMakeLists.txt new file mode 100644 index 0000000..1177fc3 --- /dev/null +++ b/ksmserver/screenlocker/data/CMakeLists.txt @@ -0,0 +1,8 @@ +set( force_krunner_lock_shortcut_unreg_SRCS force_krunner_lock_shortcut_unreg.cpp ) + +kde4_add_executable( force_krunner_lock_shortcut_unreg ${force_krunner_lock_shortcut_unreg_SRCS} ) + +target_link_libraries( force_krunner_lock_shortcut_unreg ${QT_QTCORE_LIBRARY} ${QT_QTDBUS_LIBRARY} ) + +install( TARGETS force_krunner_lock_shortcut_unreg DESTINATION ${LIB_INSTALL_DIR}/kconf_update_bin/ ) +install( FILES kscreenlocker_locksession-shortcut.upd DESTINATION ${KCONF_UPDATE_INSTALL_DIR} ) diff --git a/ksmserver/screenlocker/data/force_krunner_lock_shortcut_unreg.cpp b/ksmserver/screenlocker/data/force_krunner_lock_shortcut_unreg.cpp new file mode 100644 index 0000000..14cff8f --- /dev/null +++ b/ksmserver/screenlocker/data/force_krunner_lock_shortcut_unreg.cpp @@ -0,0 +1,38 @@ +/******************************************************************** +KWin - the KDE window manager +This file is part of the KDE project. + +Copyright (C) 2011 Alex Merry + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*********************************************************************/ + +// see kscreenlocker_locksession-shortcut.upd + +#include + +int main( int argc, char* argv[] ) +{ + QDBusInterface accelIface("org.kde.kglobalaccel", "/kglobalaccel", "org.kde.KGlobalAccel"); + QStringList krunnerShortcutId; + krunnerShortcutId << QLatin1String("krunner") << QLatin1String("Lock Session") << "" << ""; + /* + QDBusReply > reply = accelIface.call("shortcut", krunnerShortcutId); + int shortcut = -1; + if (reply.isValid() && reply.value().size() == 1) { + shortcut = reply.value().at(0); + } + */ + accelIface.call(QDBus::NoBlock, "unRegister", krunnerShortcutId); +} diff --git a/ksmserver/screenlocker/data/kscreenlocker_locksession-shortcut.upd b/ksmserver/screenlocker/data/kscreenlocker_locksession-shortcut.upd new file mode 100644 index 0000000..cbc4d52 --- /dev/null +++ b/ksmserver/screenlocker/data/kscreenlocker_locksession-shortcut.upd @@ -0,0 +1,10 @@ +Id=4.9-locksession-shortcut +File=kglobalshortcutsrc +Group=krunner,kscreenlocker +Key=Lock Session + +# If this update script is run from within an existing KDE session +# (if the user updates the kde-workspace package while KDE is running) +# then we need to make sure the shortcut we just stole from krunner +# isn't written back to the file at logout +Script=force_krunner_lock_shortcut_unreg diff --git a/ksmserver/screenlocker/dbus/org.freedesktop.ScreenSaver.xml b/ksmserver/screenlocker/dbus/org.freedesktop.ScreenSaver.xml new file mode 100644 index 0000000..5efd943 --- /dev/null +++ b/ksmserver/screenlocker/dbus/org.freedesktop.ScreenSaver.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ksmserver/screenlocker/dbus/org.kde.screensaver.xml b/ksmserver/screenlocker/dbus/org.kde.screensaver.xml new file mode 100644 index 0000000..e700b88 --- /dev/null +++ b/ksmserver/screenlocker/dbus/org.kde.screensaver.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/ksmserver/screenlocker/greeter/CMakeLists.txt b/ksmserver/screenlocker/greeter/CMakeLists.txt new file mode 100644 index 0000000..36c633d --- /dev/null +++ b/ksmserver/screenlocker/greeter/CMakeLists.txt @@ -0,0 +1,24 @@ +include_directories( + ${CMAKE_CURRENT_BINARY_DIR} + ${KDEBASE_WORKSPACE_SOURCE_DIR}/kcheckpass + ${KDEBASE_WORKSPACE_SOURCE_DIR}/libs/kephal + ${KDEBASE_WORKSPACE_SOURCE_DIR}/libs/kdm + ${KDEBASE_WORKSPACE_SOURCE_DIR}/libs/kworkspace +) + +set(kscreenlocker_greet_SRCS + greeter.cpp + sessions.cpp + greeterapp.cpp + screensaverwindow.cpp + main.cpp ) + +kde4_add_kcfg_files(kscreenlocker_greet_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/../kcfg/kscreensaversettings.kcfgc) + +kde4_add_executable(kscreenlocker_greet ${kscreenlocker_greet_SRCS}) + +target_link_libraries(kscreenlocker_greet kephal kworkspace ${KDE4_KDEUI_LIBS} ${KDE4_SOLID_LIBS} ${QT_QTDECLARATIVE_LIBRARY} ${X11_LIBRARIES} ${KDE4_PLASMA_LIBS} ${KDE4_PLASMA_LIBS} ${KDECLARATIVE_LIBRARIES}) + +install(TARGETS kscreenlocker_greet DESTINATION ${LIBEXEC_INSTALL_DIR}) + +install(DIRECTORY themes/org.kde.passworddialog DESTINATION ${DATA_INSTALL_DIR}/ksmserver/screenlocker) \ No newline at end of file diff --git a/ksmserver/screenlocker/greeter/Messages.sh b/ksmserver/screenlocker/greeter/Messages.sh new file mode 100644 index 0000000..7f04e9f --- /dev/null +++ b/ksmserver/screenlocker/greeter/Messages.sh @@ -0,0 +1,2 @@ +#!bin/sh +$XGETTEXT `find . -name \*.qml -o -name \*.cc -o -name \*.cpp -o -name \*.h` -o $podir/kscreenlocker_greet.pot diff --git a/ksmserver/screenlocker/greeter/greeter.cpp b/ksmserver/screenlocker/greeter/greeter.cpp new file mode 100644 index 0000000..a6b29bc --- /dev/null +++ b/ksmserver/screenlocker/greeter/greeter.cpp @@ -0,0 +1,508 @@ +/******************************************************************** + KSld - the KDE Screenlocker Daemon + This file is part of the KDE project. + +Copyright (C) 1999 Martin R. Jones +Copyright (C) 2002 Luboš Luňák +Copyright (C) 2003 Oswald Buddenhagen +Copyright (C) 2011 Martin Gräßlin + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*********************************************************************/ +#include "greeter.h" +#include "kscreensaversettings.h" +// workspace +#include +// KDE +#include +#include +#include +#include +#include +#include + +// Qt +#include +#include +#include +#include +#include +#include +#include + +// kscreenlocker stuff +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +namespace ScreenLocker +{ + +GreeterItem::GreeterItem(QDeclarativeItem *parent) + : QDeclarativeItem(parent) + , m_proxy(new QGraphicsProxyWidget(this)) + , m_unlocker(new Greeter(this)) +{ + init(); +} + +GreeterItem::~GreeterItem() +{ +} + +//#define SHOW_GREETER_BACKGROUND +void GreeterItem::init() +{ + if (!m_unlocker->isValid()) { + exit(1); + return; + } + QWidget *widget = m_unlocker->greeterWidget(); +#ifndef SHOW_GREETER_BACKGROUND + widget->setAttribute(Qt::WA_TranslucentBackground); +#else + QPalette p = widget->palette(); + p.setBrush(QPalette::Background, Qt::red); + widget->setPalette(p); +#endif + m_proxy->setWidget(widget); + m_proxy->setFlag(QGraphicsItem::ItemIsFocusable); + setFlag(QGraphicsItem::ItemIsFocusable); + m_proxy->setFocus(); + QGraphicsItem::setFocus(); + connect(m_unlocker, SIGNAL(greeterFailed()), this, SIGNAL(greeterFailed())); + connect(m_unlocker, SIGNAL(greeterReady()), this, SIGNAL(greeterReady())); + connect(m_unlocker, SIGNAL(greeterMessage(QString)), this, SIGNAL(greeterMessage(QString))); + connect(m_unlocker, SIGNAL(greeterAccepted()), this, SIGNAL(greeterAccepted())); + setWidth(m_proxy->size().width()); + setHeight(m_proxy->size().height()); +} + +void GreeterItem::verify() +{ + m_unlocker->verify(); +} + +void GreeterItem::focusInEvent(QFocusEvent *event) +{ + QGraphicsItem::focusInEvent(event); + if (QLineEdit *lineEdit = m_proxy->widget()->findChild()) { + lineEdit->setFocus(Qt::OtherFocusReason); + } +} + +// KeyboardItem + +KeyboardItem::KeyboardItem(QDeclarativeItem *parent) + : QDeclarativeItem(parent) + , m_widget(new QWidget()) + , m_proxy(new QGraphicsProxyWidget(this)) +{ + m_widget->setAttribute(Qt::WA_TranslucentBackground); + KPluginFactory *kxkbFactory = KPluginLoader(QLatin1String("keyboard_layout_widget")).factory(); + if (kxkbFactory) { + kxkbFactory->create(m_widget); + } else { + kDebug() << "can't load keyboard layout widget library"; + } + m_proxy->setWidget(m_widget); + + setWidth(m_proxy->size().width()); + setHeight(m_proxy->size().height()); +} + +KeyboardItem::~KeyboardItem() +{ +} + +Greeter::Greeter(QObject *parent) + : QObject(parent) + , m_greeterWidget(new QWidget()) + , m_greet(0) + , m_valid(false) + , m_pid(0) + , m_fd(0) + , m_notifier(NULL) + , m_failedLock(false) +{ + m_pluginHandle.library = 0; + initialize(); + m_valid = loadGreetPlugin(); + if (m_valid) { + + m_greet = m_pluginHandle.info->create(this, m_greeterWidget, QString(), + KGreeterPlugin::Authenticate, + KGreeterPlugin::ExUnlock); + } +} + +Greeter::~Greeter() +{ + if (m_pluginHandle.library) { + if (m_pluginHandle.info->done) { + m_pluginHandle.info->done(); + } + m_pluginHandle.library->unload(); + } +} + +void Greeter::initialize() +{ + KScreenSaverSettings::self()->readConfig(); + m_plugins = KScreenSaverSettings::pluginsUnlock(); + if (m_plugins.isEmpty()) { + m_plugins << QLatin1String( "classic" ) << QLatin1String( "generic" ); + } + m_pluginOptions = KScreenSaverSettings::pluginOptions(); + const QStringList dmopt = + QString::fromLatin1( ::getenv( "XDM_MANAGED" )).split(QLatin1Char(','), QString::SkipEmptyParts); + for (QStringList::ConstIterator it = dmopt.constBegin(); it != dmopt.constEnd(); ++it) { + if ((*it).startsWith(QLatin1String( "method=" ))) { + m_method = (*it).mid(7); + } + } +} + +// standard greeter stuff +// private static +QVariant Greeter::getConf(void *ctx, const char *key, const QVariant &dflt) +{ + Greeter *that = (Greeter *)ctx; + QString fkey = QLatin1String( key ) % QLatin1Char( '=' ); + for (QStringList::ConstIterator it = that->m_pluginOptions.constBegin(); + it != that->m_pluginOptions.constEnd(); ++it) + if ((*it).startsWith( fkey )) + return (*it).mid( fkey.length() ); + return dflt; +} + +bool Greeter::loadGreetPlugin() +{ + if (m_pluginHandle.library) { + //we were locked once before, so all the plugin loading's done already + //FIXME should I be unloading the plugin on unlock instead? + return true; + } + for (QStringList::ConstIterator it = m_plugins.constBegin(); it != m_plugins.constEnd(); ++it) { + GreeterPluginHandle plugin; + KLibrary *lib = new KLibrary( (*it)[0] == QLatin1Char( '/' ) ? *it : QLatin1String( "kgreet_" ) + *it ); + if (lib->fileName().isEmpty()) { + kWarning(1212) << "GreeterPlugin " << *it << " does not exist" ; + delete lib; + continue; + } + if (!lib->load()) { + kWarning(1212) << "Cannot load GreeterPlugin " << *it << " (" << lib->fileName() << ")" ; + delete lib; + continue; + } + plugin.library = lib; + plugin.info = (KGreeterPluginInfo *)lib->resolveSymbol( "kgreeterplugin_info" ); + if (!plugin.info ) { + kWarning(1212) << "GreeterPlugin " << *it << " (" << lib->fileName() << ") is no valid greet widget plugin" ; + lib->unload(); + delete lib; + continue; + } + if (plugin.info->method && !m_method.isEmpty() && m_method != QLatin1String( plugin.info->method )) { + kDebug(1212) << "GreeterPlugin " << *it << " (" << lib->fileName() << ") serves " << plugin.info->method << ", not " << m_method; + lib->unload(); + delete lib; + continue; + } + if (!plugin.info->init( m_method, getConf, this )) { + kDebug(1212) << "GreeterPlugin " << *it << " (" << lib->fileName() << ") refuses to serve " << m_method; + lib->unload(); + delete lib; + continue; + } + kDebug(1212) << "GreeterPlugin " << *it << " (" << plugin.info->method << ", " << plugin.info->name << ") loaded"; + m_pluginHandle = plugin; + return true; + } + return false; +} + +void Greeter::verify() +{ + if (m_failedLock) { + // greeter blocked due to failed unlock attempt + return; + } + m_greet->next(); +} + +void Greeter::failedTimer() +{ + emit greeterReady(); + m_greet->revive(); + m_greet->start(); + m_failedLock = false; +} + +////// kckeckpass interface code + +int Greeter::Reader(void *buf, int count) +{ + int ret, rlen; + + for (rlen = 0; rlen < count; ) { + dord: + ret = ::read(m_fd, (void *)((char *)buf + rlen), count - rlen); + if (ret < 0) { + if (errno == EINTR) + goto dord; + if (errno == EAGAIN) + break; + return -1; + } + if (!ret) + break; + rlen += ret; + } + return rlen; +} + +bool Greeter::GRead(void *buf, int count) +{ + return Reader(buf, count) == count; +} + +bool Greeter::GWrite(const void *buf, int count) +{ + return ::write(m_fd, buf, count) == count; +} + +bool Greeter::GSendInt(int val) +{ + return GWrite(&val, sizeof(val)); +} + +bool Greeter::GSendStr(const char *buf) +{ + int len = buf ? ::strlen (buf) + 1 : 0; + return GWrite(&len, sizeof(len)) && GWrite (buf, len); +} + +bool Greeter::GSendArr(int len, const char *buf) +{ + return GWrite(&len, sizeof(len)) && GWrite (buf, len); +} + +bool Greeter::GRecvInt(int *val) +{ + return GRead(val, sizeof(*val)); +} + +bool Greeter::GRecvArr(char **ret) +{ + int len; + char *buf; + + if (!GRecvInt(&len)) + return false; + if (!len) { + *ret = 0; + return true; + } + if (!(buf = (char *)::malloc (len))) + return false; + *ret = buf; + if (GRead (buf, len)) { + return true; + } else { + ::free(buf); + *ret = 0; + return false; + } +} + +void Greeter::reapVerify() +{ + m_notifier->setEnabled( false ); + m_notifier->deleteLater(); + m_notifier = 0; + ::close( m_fd ); + int status; + while (::waitpid( m_pid, &status, 0 ) < 0) + if (errno != EINTR) { // This should not happen ... + cantCheck(); + return; + } + if (WIFEXITED(status)) + switch (WEXITSTATUS(status)) { + case AuthOk: + m_greet->succeeded(); + emit greeterAccepted(); + return; + case AuthBad: + m_greet->failed(); + emit greeterFailed(); + m_failedLock = true; + QTimer::singleShot(1500, this, SLOT(failedTimer())); + //KNotification::event( QLatin1String( "unlockfailed" ) );*/ + return; + case AuthAbort: + return; + } + cantCheck(); +} + +void Greeter::handleVerify() +{ + int ret; + char *arr; + + if (GRecvInt( &ret )) { + switch (ret) { + case ConvGetBinary: + if (!GRecvArr( &arr )) + break; + m_greet->binaryPrompt( arr, false ); + if (arr) + ::free( arr ); + return; + case ConvGetNormal: + if (!GRecvArr( &arr )) + break; + m_greet->textPrompt( arr, true, false ); + if (arr) + ::free( arr ); + return; + case ConvGetHidden: + if (!GRecvArr( &arr )) + break; + m_greet->textPrompt( arr, false, false ); + if (arr) + ::free( arr ); + return; + case ConvPutInfo: + if (!GRecvArr( &arr )) + break; + if (!m_greet->textMessage( arr, false )) + emit greeterMessage(QString::fromLocal8Bit(arr)); + ::free( arr ); + return; + case ConvPutError: + if (!GRecvArr( &arr )) + break; + if (!m_greet->textMessage( arr, true )) + emit greeterMessage(QString::fromLocal8Bit(arr)); + ::free( arr ); + return; + } + } + reapVerify(); +} + +////// greeter plugin callbacks + +void Greeter::gplugReturnText( const char *text, int tag ) +{ + GSendStr( text ); + if (text) + GSendInt( tag ); +} + +void Greeter::gplugReturnBinary( const char *data ) +{ + if (data) { + unsigned const char *up = (unsigned const char *)data; + int len = up[3] | (up[2] << 8) | (up[1] << 16) | (up[0] << 24); + if (!len) + GSendArr( 4, data ); + else + GSendArr( len, data ); + } else + GSendArr( 0, 0 ); +} + +void Greeter::gplugSetUser( const QString & ) +{ + // ignore ... +} + +void Greeter::cantCheck() +{ + m_greet->failed(); + emit greeterMessage(i18n("Cannot unlock the session because the authentication system failed to work!")); + m_greet->revive(); +} + +//--------------------------------------------------------------------------- +// +// Starts the kcheckpass process to check the user's password. +// +void Greeter::gplugStart() +{ + int sfd[2]; + char fdbuf[16]; + + if (m_notifier) + return; + if (::socketpair(AF_LOCAL, SOCK_STREAM, 0, sfd)) { + cantCheck(); + return; + } + if ((m_pid = ::fork()) < 0) { + ::close(sfd[0]); + ::close(sfd[1]); + cantCheck(); + return; + } + if (!m_pid) { + ::close(sfd[0]); + sprintf(fdbuf, "%d", sfd[1]); + execlp(QFile::encodeName(KStandardDirs::findExe(QLatin1String( "kcheckpass" ))).data(), + "kcheckpass", + "-m", m_pluginHandle.info->method, + "-S", fdbuf, + (char *)0); + _exit(20); + } + ::close(sfd[1]); + m_fd = sfd[0]; + m_notifier = new QSocketNotifier(m_fd, QSocketNotifier::Read, this); + connect(m_notifier, SIGNAL(activated(int)), SLOT(handleVerify())); +} + +void Greeter::gplugChanged() +{ +} + +void Greeter::gplugActivity() +{ + // ignore +} + +void Greeter::gplugMsgBox(QMessageBox::Icon type, const QString &text) +{ + Q_UNUSED(type) + emit greeterMessage(text); +} + +bool Greeter::gplugHasNode(const QString &) +{ + return false; +} + +} // end namespace +#include "greeter.moc" diff --git a/ksmserver/screenlocker/greeter/greeter.h b/ksmserver/screenlocker/greeter/greeter.h new file mode 100644 index 0000000..fed2100 --- /dev/null +++ b/ksmserver/screenlocker/greeter/greeter.h @@ -0,0 +1,173 @@ +/******************************************************************** + KSld - the KDE Screenlocker Daemon + This file is part of the KDE project. + +Copyright (C) 1999 Martin R. Jones +Copyright (C) 2002 Luboš Luňák +Copyright (C) 2003 Oswald Buddenhagen +Copyright (C) 2011 Martin Gräßlin + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*********************************************************************/ +#ifndef SCREENLOCKER_GREETER_H +#define SCREENLOCKER_GREETER_H + +#include +#include + +// forward declarations +class KGreetPlugin; +class KLibrary; +class QSocketNotifier; + +struct GreeterPluginHandle { + KLibrary *library; + KGreeterPluginInfo *info; +}; + +namespace ScreenLocker +{ +class Greeter; + +class GreeterItem : public QDeclarativeItem +{ + Q_OBJECT +public: + GreeterItem(QDeclarativeItem *parent = NULL); + virtual ~GreeterItem(); + +public Q_SLOTS: + void verify(); + +Q_SIGNALS: + void greeterFailed(); + void greeterReady(); + void greeterMessage(const QString &text); + void greeterAccepted(); +protected: + virtual void focusInEvent(QFocusEvent *event); +private: + void init(); + QGraphicsProxyWidget *m_proxy; + Greeter *m_unlocker; +}; + +class KeyboardItem : public QDeclarativeItem +{ + Q_OBJECT +public: + KeyboardItem(QDeclarativeItem *parent = NULL); + virtual ~KeyboardItem(); + +private: + QWidget *m_widget; + QGraphicsProxyWidget *m_proxy; +}; + +/** + * @short Class which checks authentication through KGreeterPlugin framework. + * + * This class can be used to perform an authentication through the KGreeterPlugin framework. + * It provides a QWidget containing the widgets provided by the various greeter. + * + * To perform an authentication through the greeter invoke the @link verify slot. The class + * will emit either @link greeterAccepted or @link greeterFailed signals depending on whether + * the authentication succeeded or failed. + * + * @author Martin Gräßlin + **/ +class Greeter : public QObject, public KGreeterPluginHandler +{ + Q_OBJECT +public: + Greeter(QObject *parent); + virtual ~Greeter(); + bool isValid() const { + return m_valid; + } + // from KGreetPluginHandler + virtual void gplugReturnText(const char *text, int tag); + virtual void gplugReturnBinary(const char *data); + virtual void gplugSetUser(const QString &); + virtual void gplugStart(); + virtual void gplugChanged(); + virtual void gplugActivity(); + virtual void gplugMsgBox(QMessageBox::Icon type, const QString &text); + virtual bool gplugHasNode(const QString &id); + + QWidget *greeterWidget() const { + return m_greeterWidget; + } + +Q_SIGNALS: + /** + * Signal emitted in case the authentication through the greeter succeeded. + **/ + void greeterAccepted(); + /** + * Signal emitted in case the authentication through the greeter failed. + */ + void greeterFailed(); + /** + * Signal emitted when the greeter is ready to perform authentication. + * E.g. after the timeout of a failed authentication attempt. + **/ + void greeterReady(); + /** + * Signal broadcasting any messages from the greeter. + **/ + void greeterMessage(const QString &text); + +public Q_SLOTS: + /** + * Invoke to perform an authentication through the greeter plugins. + **/ + void verify(); + +private Q_SLOTS: + void handleVerify(); + void failedTimer(); +private: + void initialize(); + bool loadGreetPlugin(); + static QVariant getConf(void *ctx, const char *key, const QVariant &dflt); + + // kcheckpass interface + int Reader(void *buf, int count); + bool GRead(void *buf, int count); + bool GWrite(const void *buf, int count); + bool GSendInt(int val); + bool GSendStr(const char *buf); + bool GSendArr(int len, const char *buf); + bool GRecvInt(int *val); + bool GRecvArr(char **buf); + void reapVerify(); + void cantCheck(); + + GreeterPluginHandle m_pluginHandle; + QWidget *m_greeterWidget; + KGreeterPlugin *m_greet; + QStringList m_plugins; + QStringList m_pluginOptions; + QString m_method; + bool m_valid; + // for kcheckpass + int m_pid; + int m_fd; + QSocketNotifier *m_notifier; + bool m_failedLock; +}; + +} // end namespace +#endif diff --git a/ksmserver/screenlocker/greeter/greeterapp.cpp b/ksmserver/screenlocker/greeter/greeterapp.cpp new file mode 100644 index 0000000..ad77e36 --- /dev/null +++ b/ksmserver/screenlocker/greeter/greeterapp.cpp @@ -0,0 +1,322 @@ +/******************************************************************** + KSld - the KDE Screenlocker Daemon + This file is part of the KDE project. + +Copyright (C) 2004 Chris Howells +Copyright (C) 2011 Martin Gräßlin + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*********************************************************************/ +#include "greeterapp.h" +#include "kscreensaversettings.h" +#include "greeter.h" +#include "sessions.h" +#include "screensaverwindow.h" + +// workspace +#include +#include +// KDE +#include +#include +#include +#include +#include +#include +#include +//Plasma +#include +#include +// Qt +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// X11 +#include +#include +#include + +namespace ScreenLocker +{ + +static const char *DEFAULT_MAIN_PACKAGE = "org.kde.passworddialog"; + +// App +UnlockApp::UnlockApp() + : KApplication() + , m_resetRequestIgnoreTimer(new QTimer(this)) + , m_testing(false) + , m_capsLocked(false) + , m_ignoreRequests(false) + , m_showScreenSaver(false) +{ + initialize(); + QTimer::singleShot(0, this, SLOT(prepareShow())); +} + +UnlockApp::~UnlockApp() +{ + qDeleteAll(m_views); + qDeleteAll(m_screensaverWindows); +} + +void UnlockApp::initialize() +{ + const char *uri = "org.kde.kscreenlocker"; + qmlRegisterType(uri, 1, 0, "GreeterItem"); + qmlRegisterType(uri, 1, 0, "KeyboardItem"); + qmlRegisterType(uri, 1, 0, "Sessions"); + qmlRegisterType(); + + // set up the request ignore timeout, so that multiple requests to sleep/suspend/shutdown + // are not processed in quick (and confusing) succession) + m_resetRequestIgnoreTimer->setSingleShot(true); + m_resetRequestIgnoreTimer->setInterval(2000); + connect(m_resetRequestIgnoreTimer, SIGNAL(timeout()), this, SLOT(resetRequestIgnore())); + + // disable DrKonqi as the crash dialog blocks the restart of the locker + KCrash::setDrKonqiEnabled(false); + + KScreenSaverSettings::self()->readConfig(); + m_showScreenSaver = KScreenSaverSettings::legacySaverEnabled(); + + const bool canLogout = KAuthorized::authorizeKAction("logout") && KAuthorized::authorize("logout"); + const QSet spdMethods = Solid::PowerManagement::supportedSleepStates(); + + m_structure = Plasma::PackageStructure::load("Plasma/Generic"); + m_package = new Plasma::Package(KStandardDirs::locate("data", "ksmserver/screenlocker/"), KScreenSaverSettings::greeterQML(), m_structure); + m_mainQmlPath = m_package->filePath("mainscript"); + if (m_mainQmlPath.isEmpty()) { + delete m_package; + m_package = new Plasma::Package(KStandardDirs::locate("data", "ksmserver/screenlocker/"), DEFAULT_MAIN_PACKAGE, m_structure); + m_mainQmlPath = m_package->filePath("mainscript"); + } + + for (int i = 0; i < Kephal::Screens::self()->screens().count(); ++i) { + + // create the view + QDeclarativeView *view = new QDeclarativeView(); + connect(view, SIGNAL(statusChanged(QDeclarativeView::Status)), + this, SLOT(viewStatusChanged(QDeclarativeView::Status))); + view->setWindowFlags(Qt::X11BypassWindowManagerHint); + view->setFrameStyle(QFrame::NoFrame); + + // engine stuff + foreach (const QString &importPath, KGlobal::dirs()->findDirs("module", "imports")) { + view->engine()->addImportPath(importPath); + } + + KDeclarative kdeclarative; + kdeclarative.setDeclarativeEngine(view->engine()); + kdeclarative.initialize(); + kdeclarative.setupBindings(); + QDeclarativeContext *context = view->engine()->rootContext(); + context->setContextProperty("kscreenlocker_userName", KUser().property(KUser::FullName).toString()); + + view->setSource(QUrl::fromLocalFile(m_mainQmlPath)); + view->setResizeMode(QDeclarativeView::SizeRootObjectToView); + + connect(view->rootObject(), SIGNAL(unlockRequested()), SLOT(quit())); + + QDeclarativeProperty sleepProperty(view->rootObject(), "suspendToRamSupported"); + sleepProperty.write(spdMethods.contains(Solid::PowerManagement::SuspendState)); + if (spdMethods.contains(Solid::PowerManagement::SuspendState)) { + connect(view->rootObject(), SIGNAL(suspendToRam()), SLOT(suspendToRam())); + } + + QDeclarativeProperty hibernateProperty(view->rootObject(), "suspendToDiskSupported"); + hibernateProperty.write(spdMethods.contains(Solid::PowerManagement::SuspendState)); + if (spdMethods.contains(Solid::PowerManagement::SuspendState)) { + connect(view->rootObject(), SIGNAL(suspendToDisk()), SLOT(suspendToDisk())); + } + + QDeclarativeProperty shutdownProperty(view->rootObject(), "shutdownSupported"); + shutdownProperty.write(canLogout); + if (canLogout) { + connect(view->rootObject(), SIGNAL(shutdown()), SLOT(shutdown())); + } + + m_views << view; + + if (m_showScreenSaver) { + ScreenSaverWindow *screensaverWindow = new ScreenSaverWindow; + screensaverWindow->setWindowFlags(Qt::X11BypassWindowManagerHint); + m_screensaverWindows << screensaverWindow; + } + } + + installEventFilter(this); +} + +void UnlockApp::viewStatusChanged(const QDeclarativeView::Status &status) +{ + // on error, if we did not load the default qml, try to do so now. + if (status == QDeclarativeView::Error && + m_package->metadata().pluginName() != DEFAULT_MAIN_PACKAGE) { + if (QDeclarativeView *view = qobject_cast(sender())) { + m_package = new Plasma::Package(KStandardDirs::locate("data", "ksmserver/screenlocker/"), DEFAULT_MAIN_PACKAGE, m_structure); + m_mainQmlPath = m_package->filePath("mainscript"); + view->setSource(QUrl::fromLocalFile(m_mainQmlPath)); + } + } +} + +void UnlockApp::prepareShow() +{ + // mark as our window + Atom tag = XInternAtom(QX11Info::display(), "_KDE_SCREEN_LOCKER", False); + + for (int i = 0; i < Kephal::Screens::self()->screens().count(); ++i) { + if (i == m_views.size()) { + kError() << "Views and screens not in sync"; + return; + } + QDeclarativeView *view = m_views.at(i); + + XChangeProperty(QX11Info::display(), view->winId(), tag, tag, 32, PropModeReplace, 0, 0); + view->setGeometry(Kephal::Screens::self()->screen(i)->geom()); + view->show(); + view->activateWindow(); + + if (m_showScreenSaver) { + ScreenSaverWindow *screensaverWindow = m_screensaverWindows.at(i); + screensaverWindow->setGeometry(view->geometry()); + XChangeProperty(QX11Info::display(), screensaverWindow->winId(), tag, tag, 32, PropModeReplace, 0, 0); + screensaverWindow->show(); + screensaverWindow->activateWindow(); + } + } + capsLocked(); +} + +void UnlockApp::resetRequestIgnore() +{ + m_ignoreRequests = false; +} + +void UnlockApp::suspendToRam() +{ + if (m_ignoreRequests) { + return; + } + + m_ignoreRequests = true; + m_resetRequestIgnoreTimer->start(); + + QDBusInterface iface("org.kde.Solid.PowerManagement", + "/org/kde/Solid/PowerManagement", + "org.kde.Solid.PowerManagement"); + iface.asyncCall("suspendToRam"); + +} + +void UnlockApp::suspendToDisk() +{ + if (m_ignoreRequests) { + return; + } + + m_ignoreRequests = true; + m_resetRequestIgnoreTimer->start(); + + QDBusInterface iface("org.kde.Solid.PowerManagement", + "/org/kde/Solid/PowerManagement", + "org.kde.Solid.PowerManagement"); + iface.asyncCall("suspendToDisk"); +} + +void UnlockApp::shutdown() +{ + if (m_ignoreRequests) { + return; + } + + m_ignoreRequests = true; + m_resetRequestIgnoreTimer->start(); + + const KWorkSpace::ShutdownConfirm confirm = KWorkSpace::ShutdownConfirmNo; + const KWorkSpace::ShutdownType type = KWorkSpace::ShutdownTypeHalt; + + KWorkSpace::requestShutDown(confirm, type); +} + +void UnlockApp::setTesting(bool enable) +{ + m_testing = enable; + if (m_views.isEmpty()) { + return; + } + if (enable) { + // remove bypass window manager hint + foreach (QDeclarativeView * view, m_views) { + view->setWindowFlags(view->windowFlags() & ~Qt::X11BypassWindowManagerHint); + } + } else { + foreach (QDeclarativeView * view, m_views) { + view->setWindowFlags(view->windowFlags() | Qt::X11BypassWindowManagerHint); + } + } +} + +bool UnlockApp::eventFilter(QObject *obj, QEvent *event) +{ + Q_UNUSED(obj) + if (event->type() == QEvent::KeyPress || event->type() == QEvent::KeyRelease) { + capsLocked(); + QKeyEvent *ke = static_cast(event); + if (ke->key() == Qt::Key_Escape) { + foreach (ScreenSaverWindow *screensaverWindow, m_screensaverWindows) { + screensaverWindow->show(); + } + } + } else if (event->type() == QEvent::GraphicsSceneMousePress) { + QGraphicsSceneMouseEvent *me = static_cast(event); + + foreach (QDeclarativeView *view, m_views) { + if (view->geometry().contains(me->screenPos())) { + view->activateWindow(); + view->grabKeyboard(); + break; + } + } + } + + return false; +} + +void UnlockApp::capsLocked() +{ + unsigned int lmask; + Window dummy1, dummy2; + int dummy3, dummy4, dummy5, dummy6; + XQueryPointer(QX11Info::display(), DefaultRootWindow( QX11Info::display() ), &dummy1, &dummy2, &dummy3, &dummy4, &dummy5, &dummy6, &lmask); + const bool before = m_capsLocked; + m_capsLocked = lmask & LockMask; + if (before != m_capsLocked) { + foreach (QDeclarativeView *view, m_views) { + view->rootObject()->setProperty("capsLockOn", m_capsLocked); + } + } +} + +} // namespace + +#include "greeterapp.moc" diff --git a/ksmserver/screenlocker/greeter/greeterapp.h b/ksmserver/screenlocker/greeter/greeterapp.h new file mode 100644 index 0000000..749398b --- /dev/null +++ b/ksmserver/screenlocker/greeter/greeterapp.h @@ -0,0 +1,75 @@ +/******************************************************************** + KSld - the KDE Screenlocker Daemon + This file is part of the KDE project. + +Copyright (C) 2011 Martin Gräßlin + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*********************************************************************/ +#ifndef SCREENLOCKER_GREETERAPP_H +#define SCREENLOCKER_GREETERAPP_H + +#include + +#include + +#include + +namespace Plasma { + class Package; +}; + +namespace ScreenLocker +{ +class Unlocker; +class ScreenSaverWindow; + +class UnlockApp : public KApplication +{ + Q_OBJECT +public: + UnlockApp(); + virtual ~UnlockApp(); + + void setTesting(bool enable); + +protected: + virtual bool eventFilter(QObject *obj, QEvent *event); + +private Q_SLOTS: + void viewStatusChanged(const QDeclarativeView::Status &status); + void prepareShow(); + void resetRequestIgnore(); + void suspendToRam(); + void suspendToDisk(); + void shutdown(); + +private: + void initialize(); + void capsLocked(); + + QString m_mainQmlPath; + QList m_views; + QList m_screensaverWindows; + QTimer *m_resetRequestIgnoreTimer; + Plasma::PackageStructure::Ptr m_structure; + Plasma::Package *m_package; + bool m_testing; + bool m_capsLocked; + bool m_ignoreRequests; + bool m_showScreenSaver; +}; +} // namespace + +#endif // SCREENLOCKER_GREETERAPP_H diff --git a/ksmserver/screenlocker/greeter/main.cpp b/ksmserver/screenlocker/greeter/main.cpp new file mode 100644 index 0000000..c856957 --- /dev/null +++ b/ksmserver/screenlocker/greeter/main.cpp @@ -0,0 +1,68 @@ +/******************************************************************** + KSld - the KDE Screenlocker Daemon + This file is part of the KDE project. + +Copyright (C) 2011 Martin Gräßlin + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*********************************************************************/ +#include +#include +#include +#include + +#include "greeterapp.h" + +static const char description[] = I18N_NOOP( "Greeter for the KDE Plasma Workspaces Screen locker" ); +static const char version[] = "0.1"; + +int main(int argc, char* argv[]) +{ + KAboutData aboutData( "kscreenlocker_greet", 0, ki18n( "KScreenLocker Greeter" ), + version, ki18n(description), KAboutData::License_GPL, + ki18n("(c) 2011, Martin Gräßlin") ); + aboutData.addAuthor( ki18n("Martin Gräßlin"), + ki18n( "Author and maintainer" ), + "mgraesslin@kde.org" ); + aboutData.addAuthor( ki18n("Chani Armitage"), + ki18n("Author"), + "chanika@gmail.com"); + aboutData.addAuthor( ki18n("Oswald Buddenhagen"), + ki18n("Author"), + "ossi@kde.org"); + aboutData.addAuthor( ki18n("Chris Howells"), + ki18n("Author"), + "howells@kde.org"); + aboutData.addAuthor( ki18n("Luboš Luňák"), + ki18n("Author"), + "l.lunak@kde.org"); + aboutData.addAuthor( ki18n("Martin R. Jones"), + ki18n("Author"), + "mjones@kde.org"); + + KCmdLineArgs::init(argc, argv, &aboutData); + KCmdLineOptions options; + options.add("testing", ki18n("Starts the greeter in testing mode")); + KCmdLineArgs::addCmdLineOptions(options); + + ScreenLocker::UnlockApp app; + KGlobal::locale()->insertCatalog(QLatin1String( "libkworkspace" )); + app.disableSessionManagement(); // manually-started + KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); + if (args->isSet("testing")) { + app.setTesting(true); + } + args->clear(); + return app.exec(); +} diff --git a/ksmserver/screenlocker/greeter/screensaverwindow.cpp b/ksmserver/screenlocker/greeter/screensaverwindow.cpp new file mode 100644 index 0000000..ad36444 --- /dev/null +++ b/ksmserver/screenlocker/greeter/screensaverwindow.cpp @@ -0,0 +1,199 @@ +/* + * Copyright 1999 Martin R. Jones + * Copyright 2003 Oswald Buddenhagen + * Copyright 2008 Chani Armitage + * Copyright 2012 Marco Martin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2, or + * (at your option) any later version. + * + * This program 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 General Public License for more details + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include "screensaverwindow.h" +#include "kscreensaversettings.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace ScreenLocker +{ + +ScreenSaverWindow::ScreenSaverWindow(QWidget *parent) + : QWidget(parent), + m_startMousePos(-1, -1), + m_forbidden(false), + m_openGLVisual(false) +{ + m_reactivateTimer = new QTimer(this); + m_reactivateTimer->setSingleShot(true); + connect(m_reactivateTimer, SIGNAL(timeout()), this, SLOT(show())); + + setMouseTracking(true); + m_saver = KScreenSaverSettings::saver(); + readSaver(); +} + +ScreenSaverWindow::~ScreenSaverWindow() +{ +} + +//--------------------------------------------------------------------------- +// +// Read the command line needed to run the screensaver given a .desktop file. +// +void ScreenSaverWindow::readSaver() +{ + if (!m_saver.isEmpty()) + { + QString entryName = m_saver; + if( entryName.endsWith( QLatin1String( ".desktop" ) )) + entryName = entryName.left( entryName.length() - 8 ); // strip it + const KService::List offers = KServiceTypeTrader::self()->query( QLatin1String( "ScreenSaver" ), + QLatin1String( "DesktopEntryName == '" ) + entryName.toLower() + QLatin1Char( '\'' ) ); + if( offers.isEmpty() ) + { + kDebug(1204) << "Cannot find screesaver: " << m_saver; + return; + } + const QString file = KStandardDirs::locate("services", offers.first()->entryPath()); + + const bool opengl = KAuthorized::authorizeKAction(QLatin1String( "opengl_screensavers" )); + const bool manipulatescreen = KAuthorized::authorizeKAction(QLatin1String( "manipulatescreen_screensavers" )); + KDesktopFile config( file ); + KConfigGroup desktopGroup = config.desktopGroup(); + foreach (const QString &type, desktopGroup.readEntry("X-KDE-Type").split(QLatin1Char(';'))) { + if (type == QLatin1String("ManipulateScreen")) { + if (!manipulatescreen) { + kDebug(1204) << "Screensaver is type ManipulateScreen and ManipulateScreen is forbidden"; + m_forbidden = true; + } + } else if (type == QLatin1String("OpenGL")) { + m_openGLVisual = true; + if (!opengl) { + kDebug(1204) << "Screensaver is type OpenGL and OpenGL is forbidden"; + m_forbidden = true; + } + } + } + + kDebug(1204) << "m_forbidden: " << (m_forbidden ? "true" : "false"); + + if (config.hasActionGroup(QLatin1String( "InWindow" ))) + { + m_saverExec = config.actionGroup(QLatin1String( "InWindow" )).readPathEntry("Exec", QString()); + } + } +} + +void ScreenSaverWindow::mousePressEvent(QMouseEvent *event) +{ + Q_UNUSED(event) + + m_startMousePos = QPoint(-1, -1); + //reappear in one minute + m_reactivateTimer->start(1000 * 60); + hide(); +} + + +void ScreenSaverWindow::keyPressEvent(QKeyEvent *event) +{ + Q_UNUSED(event) + + hide(); +} + +void ScreenSaverWindow::mouseMoveEvent(QMouseEvent *event) +{ + if (m_startMousePos == QPoint(-1, -1)) { + m_startMousePos = event->globalPos(); + } + if ((event->globalPos() - m_startMousePos).manhattanLength() > QApplication::startDragDistance()) { + m_startMousePos = QPoint(-1, -1); + hide(); + //reappear in one minute + m_reactivateTimer->start(1000 * 60); + } +} + +void ScreenSaverWindow::showEvent(QShowEvent *event) +{ + m_reactivateTimer->stop(); + startXScreenSaver(); +} + +void ScreenSaverWindow::paintEvent(QPaintEvent *event) +{ + QPainter p(this); + p.fillRect(event->rect(), Qt::black); + p.end(); +} + +//--------------------------------------------------------------------------- +// + + +bool ScreenSaverWindow::startXScreenSaver() +{ + //QString m_saverExec("kannasaver.kss --window-id=%w"); + kDebug(1204) << "Starting hack:" << m_saverExec; + + if (m_saverExec.isEmpty() || m_forbidden) + { + return false; + } + + QHash keyMap; + keyMap.insert(QLatin1Char( 'w' ), QString::number(winId())); + m_ScreenSaverProcess << KShell::splitArgs(KMacroExpander::expandMacrosShellQuote(m_saverExec, keyMap)); + + m_ScreenSaverProcess.start(); + if (m_ScreenSaverProcess.waitForStarted()) + { +#ifdef HAVE_SETPRIORITY + setpriority(PRIO_PROCESS, m_ScreenSaverProcess.pid(), mPriority); +#endif + return true; + } + + return false; +} + +//--------------------------------------------------------------------------- +// +void ScreenSaverWindow::stopXScreenSaver() +{ + if (m_ScreenSaverProcess.state() != QProcess::NotRunning) + { + m_ScreenSaverProcess.terminate(); + if (!m_ScreenSaverProcess.waitForFinished(10000)) + { + m_ScreenSaverProcess.kill(); + } + } +} + +} // end namespace +#include "screensaverwindow.moc" diff --git a/ksmserver/screenlocker/greeter/screensaverwindow.h b/ksmserver/screenlocker/greeter/screensaverwindow.h new file mode 100644 index 0000000..fc4e8a0 --- /dev/null +++ b/ksmserver/screenlocker/greeter/screensaverwindow.h @@ -0,0 +1,65 @@ +/* + * Copyright 1999 Martin R. Jones + * Copyright 2003 Oswald Buddenhagen + * Copyright 2008 Chani Armitage + * Copyright 2012 Marco Martin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2, or + * (at your option) any later version. + * + * This program 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 General Public License for more details + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef SCREENSAVERWINDOW_H +#define SCREENSAVERWINDOW_H + +#include + +#include + +class QMouseEvent; +class QTimer; + +namespace ScreenLocker +{ + +class ScreenSaverWindow : public QWidget +{ + Q_OBJECT +public: + ScreenSaverWindow(QWidget *parent = 0); + virtual ~ScreenSaverWindow(); + +protected: + void mousePressEvent(QMouseEvent *event); + void keyPressEvent(QKeyEvent *event); + void showEvent(QShowEvent *event); + void paintEvent(QPaintEvent *event); + void mouseMoveEvent(QMouseEvent *event); + +private: + bool startXScreenSaver(); + void stopXScreenSaver(); + void readSaver(); + + KProcess m_ScreenSaverProcess; + QPoint m_startMousePos; + QString m_saver; + QString m_saverExec; + + QTimer *m_reactivateTimer; + + bool m_forbidden : 1; + bool m_openGLVisual : 1; +}; + +} // end namespace +#endif diff --git a/ksmserver/screenlocker/greeter/sessions.cpp b/ksmserver/screenlocker/greeter/sessions.cpp new file mode 100644 index 0000000..1dda9ee --- /dev/null +++ b/ksmserver/screenlocker/greeter/sessions.cpp @@ -0,0 +1,162 @@ +/******************************************************************** + KSld - the KDE Screenlocker Daemon + This file is part of the KDE project. + +Copyright (C) 1999 Martin R. Jones +Copyright (C) 2003 Oswald Buddenhagen +Copyright (C) 2011 Martin Gräßlin + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*********************************************************************/ +#include "sessions.h" +// workspace +#include +// KDE +#include +#include + +namespace ScreenLocker +{ + +UserSessionsModel::UserSessionsModel(QObject *parent) + : QAbstractListModel(parent) +{ + init(); + QHash roles; + roles[Qt::UserRole] = "session"; + roles[Qt::UserRole + 1] = "location"; + roles[Qt::UserRole + 2] = "vt"; + setRoleNames(roles); +} + +UserSessionsModel::~UserSessionsModel() +{ +} + +QVariant UserSessionsModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) { + return QVariant(); + } + if (index.row() < 0 || index.row() >= m_model.size()) { + return QVariant(); + } + switch (role) { + case Qt::DisplayRole: + case Qt::UserRole: + return m_model[index.row()].m_session; + case (Qt::UserRole + 1): + return m_model[index.row()].m_location; + case (Qt::UserRole + 2): + return m_model[index.row()].m_vt; + default: + return QVariant(); + } +} + +QVariant UserSessionsModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + switch (role) { + case Qt::DisplayRole: + case Qt::UserRole: + return i18n("Session"); + case Qt::UserRole + 1: + return i18n("Location"); + default: + return QAbstractItemModel::headerData(section, orientation, role); + } +} + +int UserSessionsModel::rowCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent) + return m_model.count(); +} + +Qt::ItemFlags UserSessionsModel::flags(const QModelIndex &index) const +{ + if (!index.isValid()) { + return QAbstractItemModel::flags(index); + } + if (!m_model[index.row()].m_enabled) { + return QAbstractItemModel::flags(index) & ~Qt::ItemIsEnabled; + } + return QAbstractItemModel::flags(index); +} + +void UserSessionsModel::init() +{ + beginResetModel(); + m_model.clear(); + KDisplayManager dm; + + SessList sess; + if (dm.localSessions(sess)) { + + QString user, loc; + for (SessList::ConstIterator it = sess.constBegin(); it != sess.constEnd(); ++it) { + KDisplayManager::sess2Str2(*it, user, loc); + m_model << UserSessionItem(user, loc, (*it).vt, (*it).vt); + } + } + endResetModel(); +} + +SessionSwitching::SessionSwitching(QObject *parent) + : QObject (parent) + , m_sessionModel(new UserSessionsModel(this)) +{ +} + +SessionSwitching::~SessionSwitching() +{ +} + +bool SessionSwitching::isSwitchUserSupported() const +{ + return KDisplayManager().isSwitchable() && KAuthorized::authorizeKAction(QLatin1String("switch_user")); +} + +bool SessionSwitching::isStartNewSessionSupported() const +{ + KDisplayManager dm; + return dm.isSwitchable() && dm.numReserve() > 0 && KAuthorized::authorizeKAction(QLatin1String("start_new_session")); +} + +void SessionSwitching::startNewSession() +{ + // verify that starting a new session is allowed + if (!isStartNewSessionSupported()) { + return; + } + + KDisplayManager().startReserve(); +} + +void SessionSwitching::activateSession(int index) +{ + // verify that starting a new session is allowed + if (!isSwitchUserSupported()) { + return; + } + QModelIndex modelIndex(m_sessionModel->index(index)); + if (!modelIndex.isValid()) { + return; + } + KDisplayManager().switchVT(m_sessionModel->data(modelIndex, Qt::UserRole + 2).toInt()); +} + +} + +#include "sessions.moc" diff --git a/ksmserver/screenlocker/greeter/sessions.h b/ksmserver/screenlocker/greeter/sessions.h new file mode 100644 index 0000000..67ac813 --- /dev/null +++ b/ksmserver/screenlocker/greeter/sessions.h @@ -0,0 +1,95 @@ +/******************************************************************** + KSld - the KDE Screenlocker Daemon + This file is part of the KDE project. + +Copyright (C) 2011 Martin Gräßlin + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*********************************************************************/ +#ifndef SCREENLOCKER_SESSIONS_H +#define SCREENLOCKER_SESSIONS_H + +#include + +namespace ScreenLocker +{ + +class UserSessionsModel : public QAbstractListModel +{ + Q_OBJECT +public: + UserSessionsModel(QObject *parent = 0); + virtual ~UserSessionsModel(); + + virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + virtual int rowCount(const QModelIndex &parent = QModelIndex()) const; + virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + virtual Qt::ItemFlags flags(const QModelIndex &index) const; + +private: + class UserSessionItem; + void init(); + QList m_model; +}; + +class UserSessionsModel::UserSessionItem +{ +public: + UserSessionItem(const QString &session, const QString &location, int vt, bool enabled) + : m_session(session) + , m_location(location) + , m_vt(vt) + , m_enabled(enabled) + {} + QString m_session; + QString m_location; + int m_vt; + bool m_enabled; +}; + +class SessionSwitching : public QObject +{ + Q_OBJECT + Q_PROPERTY(bool switchUserSupported READ isSwitchUserSupported CONSTANT) + Q_PROPERTY(bool startNewSessionSupported READ isStartNewSessionSupported CONSTANT) + Q_PROPERTY(QAbstractItemModel* model READ sessionModel) +public: + SessionSwitching(QObject *parent = NULL); + virtual ~SessionSwitching(); + + QAbstractItemModel *sessionModel() { + return m_sessionModel; + } + + /** + * @returns @c true if switching between user sessions is possible, @c false otherwise. + **/ + bool isSwitchUserSupported() const; + /** + * @returns @c true if a new session can be started, @c false otherwise. + **/ + bool isStartNewSessionSupported() const; +public Q_SLOTS: + /** + * Invoke to start a new session if allowed. + **/ + void startNewSession(); + void activateSession(int index); +private: + UserSessionsModel *m_sessionModel; +}; + +} // namespace +Q_DECLARE_METATYPE(ScreenLocker::UserSessionsModel*) +#endif // SCREENLOCKER_SESSIONS_H diff --git a/ksmserver/screenlocker/greeter/themes/org.kde.passworddialog/contents/ui/Greeter.qml b/ksmserver/screenlocker/greeter/themes/org.kde.passworddialog/contents/ui/Greeter.qml new file mode 100644 index 0000000..929ca92c --- /dev/null +++ b/ksmserver/screenlocker/greeter/themes/org.kde.passworddialog/contents/ui/Greeter.qml @@ -0,0 +1,157 @@ +/******************************************************************** + KSld - the KDE Screenlocker Daemon + This file is part of the KDE project. + +Copyright (C) 2011 Martin Gräßlin + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*********************************************************************/ +import QtQuick 1.1 +import org.kde.plasma.core 0.1 as PlasmaCore +import org.kde.plasma.components 0.1 as PlasmaComponents +import org.kde.plasma.graphicslayouts 4.7 +import org.kde.kscreenlocker 1.0 + +Item { + signal accepted() + signal switchUserClicked() + signal canceled() + property alias cancelEnabled: cancelButton.visible + property alias notification: message.text + property bool switchUserEnabled + property bool capsLockOn + implicitWidth: layoutItem.width + theme.defaultFont.mSize.width * 4 + 12 + implicitHeight: layoutItem.height + 12 + + anchors { + fill: parent + margins: 6 + } + + Column { + id: layoutItem + anchors.centerIn: parent + spacing: theme.defaultFont.mSize.height/2 + + + PlasmaComponents.Label { + id: message + text: "" + anchors.horizontalCenter: parent.horizontalCenter + font.bold: true + Behavior on opacity { + NumberAnimation { + duration: 250 + } + } + opacity: text == "" ? 0 : 1 + } + + + + PlasmaComponents.Label { + id: capsLockMessage + text: i18n("Warning: Caps Lock on") + anchors.horizontalCenter: parent.horizontalCenter + opacity: capsLockOn ? 1 : 0 + height: capsLockOn ? paintedHeight : 0 + font.bold: true + Behavior on opacity { + NumberAnimation { + duration: 250 + } + } + } + + + PlasmaComponents.Label { + id: lockMessage + text: kscreenlocker_userName.empty ? i18n("The session is locked") : i18n("The session has been locked by %1", kscreenlocker_userName) + anchors.horizontalCenter: parent.horizontalCenter + } + + Item { + width: greeter.width + height: greeter.height + anchors.horizontalCenter: parent.horizontalCenter + GreeterItem { + id: greeter + objectName: "greeter" + + Keys.onEnterPressed: verify() + Keys.onReturnPressed: verify() + } + KeyboardItem { + anchors.left: greeter.right + } + Timer { + interval: 10 + running: true + onTriggered: { + greeter.forceActiveFocus() + greeter.focus = true + } + } + } + + PlasmaComponents.ButtonRow { + id: buttonRow + exclusive: false + spacing: theme.defaultFont.mSize.width / 2 + anchors.horizontalCenter: parent.horizontalCenter + + PlasmaComponents.Button { + id: switchUser + text: i18n("Switch User") + iconSource: "fork" + visible: switchUserEnabled + onClicked: switchUserClicked() + } + + PlasmaComponents.Button { + id: unlock + text: i18n("Unlock") + iconSource: "object-unlocked" + onClicked: greeter.verify() + } + + PlasmaComponents.Button { + id: cancelButton + text: i18n("Cancel") + iconSource: "dialog-cancel" + onClicked: canceled() + visible: false + } + } + } + + + Connections { + target: greeter + onGreeterFailed: { + message.text = i18n("Unlocking failed"); + greeter.enabled = false; + switchUser.enabled = false; + unlock.enabled = false; + } + onGreeterReady: { + message.text = ""; + greeter.enabled = true; + switchUser.enabled = true; + unlock.enabled = true; + } + onGreeterMessage: message.text = text + onGreeterAccepted: accepted() + } +} diff --git a/ksmserver/screenlocker/greeter/themes/org.kde.passworddialog/contents/ui/SessionSwitching.qml b/ksmserver/screenlocker/greeter/themes/org.kde.passworddialog/contents/ui/SessionSwitching.qml new file mode 100644 index 0000000..f9ee3f3 --- /dev/null +++ b/ksmserver/screenlocker/greeter/themes/org.kde.passworddialog/contents/ui/SessionSwitching.qml @@ -0,0 +1,126 @@ +/******************************************************************** + KSld - the KDE Screenlocker Daemon + This file is part of the KDE project. + +Copyright (C) 2011 Martin Gräßlin + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*********************************************************************/ +import QtQuick 1.1 +import org.kde.plasma.components 0.1 as PlasmaComponents +import org.kde.plasma.extras 0.1 as PlasmaExtras +import org.kde.kscreenlocker 1.0 + +Item { + property alias switchUserSupported: sessions.switchUserSupported + implicitWidth: theme.defaultFont.mSize.width * 55 + implicitHeight: Math.min(lockScreen.height, theme.defaultFont.mSize.height * 25) + signal activateSession() + signal startNewSession() + signal cancel() + Sessions { + id: sessions + } + anchors { + fill: parent + margins: 6 + } + PlasmaExtras.ScrollArea { + anchors { + left: parent.left + right: parent.right + bottom: buttonRow.top + bottomMargin: 5 + } + height: parent.height - explainText.implicitHeight - buttonRow.height - 10 + + ListView { + model: sessions.model + id: userSessionsView + anchors.fill: parent + + delegate: PlasmaComponents.ListItem { + content: PlasmaComponents.Label { + text: i18nc("thesession name and the location where the session is running (what vt)", "%1 (%2)", session, location) + } + } + highlight: PlasmaComponents.Highlight { + hover: true + width: parent.width + } + focus: true + MouseArea { + anchors.fill: parent + onClicked: userSessionsView.currentIndex = userSessionsView.indexAt(mouse.x, mouse.y) + onDoubleClicked: { + sessions.activateSession(userSessionsView.indexAt(mouse.x, mouse.y)); + activateSession(); + } + } + } + } + + PlasmaComponents.Label { + id: explainText + text: i18n("The current session will be hidden " + + "and a new login screen or an existing session will be displayed.\n" + + "An F-key is assigned to each session; " + + "F%1 is usually assigned to the first session, " + + "F%2 to the second session and so on. " + + "You can switch between sessions by pressing " + + "Ctrl, Alt and the appropriate F-key at the same time. " + + "Additionally, the KDE Panel and Desktop menus have " + + "actions for switching between sessions.", + 7, 8) + wrapMode: Text.Wrap + anchors { + top: parent.top + left: parent.left + right: parent.right + } + } + PlasmaComponents.ButtonRow { + id: buttonRow + exclusive: false + spacing: theme.defaultFont.mSize.width / 2 + + PlasmaComponents.Button { + id: activateSession + text: i18n("Activate") + iconSource: "fork" + onClicked: { + sessions.activateSession(userSessionsView.currentIndex); + activateSession(); + } + } + PlasmaComponents.Button { + id: newSession + text: i18n("Start New Session") + iconSource: "fork" + visible: sessions.startNewSessionSupported + onClicked: { + sessions.startNewSession(); + startNewSession(); + } + } + PlasmaComponents.Button { + id: cancelSession + text: i18n("Cancel") + iconSource: "dialog-cancel" + onClicked: cancel() + } + anchors.bottom: parent.bottom + anchors.horizontalCenter: userSessionsUI.horizontalCenter + } +} diff --git a/ksmserver/screenlocker/greeter/themes/org.kde.passworddialog/contents/ui/main.qml b/ksmserver/screenlocker/greeter/themes/org.kde.passworddialog/contents/ui/main.qml new file mode 100644 index 0000000..ca85f42 --- /dev/null +++ b/ksmserver/screenlocker/greeter/themes/org.kde.passworddialog/contents/ui/main.qml @@ -0,0 +1,97 @@ +/******************************************************************** + KSld - the KDE Screenlocker Daemon + This file is part of the KDE project. + +Copyright (C) 2011 Martin Gräßlin + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*********************************************************************/ +import QtQuick 1.1 +import org.kde.plasma.core 0.1 as PlasmaCore +import org.kde.qtextracomponents 0.1 +import org.kde.kscreenlocker 1.0 +import org.kde.plasma.components 0.1 as PlasmaComponents + +Item { + id: lockScreen + signal unlockRequested() + property alias capsLockOn: unlockUI.capsLockOn + + PlasmaCore.Theme { + id: theme + } + + Image { + id: background + anchors.fill: parent + source: theme.wallpaperPathForSize(parent.width, parent.height) + } + + PlasmaCore.FrameSvgItem { + id: dialog + anchors.centerIn: parent + imagePath: "widgets/background" + width: mainStack.currentPage.implicitWidth + margins.left + margins.right + height: mainStack.currentPage.implicitHeight + margins.top + margins.bottom + + Behavior on height { + enabled: mainStack.currentPage != null + NumberAnimation { + duration: 250 + } + } + Behavior on width { + enabled: mainStack.currentPage != null + NumberAnimation { + duration: 250 + } + } + PlasmaComponents.PageStack { + id: mainStack + clip: true + anchors { + fill: parent + leftMargin: dialog.margins.left + topMargin: dialog.margins.top + rightMargin: dialog.margins.right + bottomMargin: dialog.margins.bottom + } + initialPage: unlockUI + } + } + + Greeter { + id: unlockUI + + switchUserEnabled: userSessionsUI.switchUserSupported + + Connections { + onAccepted: lockScreen.unlockRequested() + onSwitchUserClicked: mainStack.push(userSessionsUI) + } + } + + + // TODO: loader + SessionSwitching { + id: userSessionsUI + visible: false + + Connections { + onCancel: mainStack.pop() + onActivateSession: mainStack.pop() + onStartNewSession: mainStack.pop() + } + } +} diff --git a/ksmserver/screenlocker/greeter/themes/org.kde.passworddialog/metadata.desktop b/ksmserver/screenlocker/greeter/themes/org.kde.passworddialog/metadata.desktop new file mode 100644 index 0000000..68d9cbe --- /dev/null +++ b/ksmserver/screenlocker/greeter/themes/org.kde.passworddialog/metadata.desktop @@ -0,0 +1,15 @@ +[Desktop Entry] +Name=Password dialog +Comment=Screen locker that provides a password dialog and an interface to switch the current user +Icon=system-lock-screen + +X-Plasma-MainScript=ui/main.qml + +X-KDE-PluginInfo-Author=Martin Gräßlin +X-KDE-PluginInfo-Email=mgraesslin@kde.org +X-KDE-PluginInfo-Name=org.kde.passworddialog +X-KDE-PluginInfo-Version=1.0 + +X-KDE-PluginInfo-Depends= +X-KDE-PluginInfo-License=GPL +Type=Service diff --git a/ksmserver/screenlocker/interface.cpp b/ksmserver/screenlocker/interface.cpp new file mode 100644 index 0000000..3d44d78 --- /dev/null +++ b/ksmserver/screenlocker/interface.cpp @@ -0,0 +1,204 @@ +/******************************************************************** + KSld - the KDE Screenlocker Daemon + This file is part of the KDE project. + +Copyright 1999 Martin R. Jones +Copyright (C) 2011 Martin Gräßlin + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*********************************************************************/ +#include "interface.h" +#include "ksldapp.h" +#include "screensaveradaptor.h" +#include "kscreensaveradaptor.h" +// KDE +#include +#include +#include +#include +// Qt +#include +#include +#include +#include + +namespace ScreenLocker +{ +Interface::Interface(KSldApp *parent) + : QObject(parent) + , m_daemon(parent) + , m_serviceWatcher(new QDBusServiceWatcher(this)) + , m_next_cookie(0) +{ + (void) new ScreenSaverAdaptor( this ); + QDBusConnection::sessionBus().registerService(QLatin1String("org.freedesktop.ScreenSaver")) ; + (void) new KScreenSaverAdaptor( this ); + QDBusConnection::sessionBus().registerService(QLatin1String("org.kde.screensaver")); + QDBusConnection::sessionBus().registerObject(QLatin1String("/ScreenSaver"), this); + connect(m_daemon, SIGNAL(locked()), SLOT(slotLocked())); + connect(m_daemon, SIGNAL(unlocked()), SLOT(slotUnlocked())); + + m_serviceWatcher->setConnection(QDBusConnection::sessionBus()); + m_serviceWatcher->setWatchMode(QDBusServiceWatcher::WatchForUnregistration); + connect(m_serviceWatcher, SIGNAL(serviceUnregistered(QString)), SLOT(serviceUnregistered(QString))); + + // Also receive updates triggered through the DBus (from powerdevil) see Bug #177123 + QStringList modules; + QDBusInterface kdedInterface(QLatin1String( "org.kde.kded" ), QLatin1String( "/kded" ), QLatin1String( "org.kde.kded" )); + QDBusReply reply = kdedInterface.call(QLatin1String( "loadedModules" )); + + if (!reply.isValid()) { + return; + } + + modules = reply.value(); + + if (modules.contains(QLatin1String( "powerdevil" ))) { + if (!QDBusConnection::sessionBus().connect(QLatin1String( "org.kde.kded" ), QLatin1String( "/modules/powerdevil" ), QLatin1String( "org.kde.PowerDevil" ), + QLatin1String( "DPMSconfigUpdated" ), this, SLOT(configure()))) { + kDebug() << "error!"; + } + } + // I make it a really random number to avoid + // some assumptions in clients, but just increase + // while gnome-ss creates a random number every time + m_next_cookie = KRandom::random() % 20000; +} + +Interface::~Interface() +{ +} + +bool Interface::GetActive() +{ + return m_daemon->isLocked(); +} + +uint Interface::GetActiveTime() +{ + return m_daemon->activeTime(); +} + +uint Interface::GetSessionIdleTime() +{ + return KIdleTime::instance()->idleTime(); +} + +void Interface::Lock() +{ + m_daemon->lock(); +} + +bool Interface::SetActive (bool state) +{ + // TODO: what should the return value be? + if (state) { + Lock(); + return true; + } + // set inactive is ignored + return false; +} + +uint Interface::Inhibit(const QString &application_name, const QString &reason_for_inhibit) +{ + Q_UNUSED(application_name) + Q_UNUSED(reason_for_inhibit) + InhibitRequest sr; + sr.cookie = m_next_cookie++; + sr.dbusid = message().service(); + m_requests.append(sr); + m_serviceWatcher->addWatchedService(sr.dbusid); + KSldApp::self()->inhibit(); + return sr.cookie; +} + +void Interface::UnInhibit(uint cookie) +{ + QMutableListIterator it(m_requests); + while (it.hasNext()) { + if (it.next().cookie == cookie) { + it.remove(); + KSldApp::self()->uninhibit(); + break; + } + } +} + +void Interface::serviceUnregistered(const QString &name) +{ + m_serviceWatcher->removeWatchedService(name); + QListIterator it(m_requests); + while (it.hasNext()) { + const InhibitRequest &r = it.next(); + if (r.dbusid == name) { + UnInhibit(r.cookie); + } + } +} + +void Interface::SimulateUserActivity() +{ + // TODO: implement me when we support user activity interaction or the autolock +} + +uint Interface::Throttle(const QString &application_name, const QString &reason_for_inhibit) +{ + Q_UNUSED(application_name) + Q_UNUSED(reason_for_inhibit) + // TODO: implement me + return 0; +} + +void Interface::UnThrottle(uint cookie) +{ + Q_UNUSED(cookie) + // TODO: implement me +} + +void Interface::slotLocked() +{ + emit ActiveChanged(true); +} + +void Interface::slotUnlocked() +{ + emit ActiveChanged(false); +} + +void Interface::configure() +{ + m_daemon->configure(); +} + +void Interface::setupPlasma() +{ + KProcess *plasmaProc = new KProcess; + plasmaProc->setProgram(QLatin1String( "plasma-overlay" )); + *plasmaProc << QLatin1String( "--setup" ); + + //make sure it goes away when it's done (and not before) + connect(plasmaProc, SIGNAL(finished(int,QProcess::ExitStatus)), plasmaProc, SLOT(deleteLater())); + + plasmaProc->start(); +} + +void Interface::saverLockReady() +{ + // unused +} + +} // namespace + +#include "interface.moc" diff --git a/ksmserver/screenlocker/interface.h b/ksmserver/screenlocker/interface.h new file mode 100644 index 0000000..689cd4f --- /dev/null +++ b/ksmserver/screenlocker/interface.h @@ -0,0 +1,124 @@ +/******************************************************************** + KSld - the KDE Screenlocker Daemon + This file is part of the KDE project. + +Copyright 1999 Martin R. Jones +Copyright (C) 2011 Martin Gräßlin + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*********************************************************************/ +#ifndef SCREENLOCKER_INTERFACE_H +#define SCREENLOCKER_INTERFACE_H + +#include +#include + +class QDBusServiceWatcher; + +namespace ScreenLocker +{ + +class InhibitRequest +{ +public: + QString dbusid; + uint cookie; +}; + +class KSldApp; +class Interface : public QObject, protected QDBusContext +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "org.freedesktop.ScreenSaver") +public: + explicit Interface(KSldApp *parent = 0); + virtual ~Interface(); + +public Q_SLOTS: + /** + * Lock the screen. + */ + void Lock(); + + /** + * Simulate user activity + */ + void SimulateUserActivity(); + /** + * Request a change in the state of the screensaver. + * Set to TRUE to request that the screensaver activate. + * Active means that the screensaver has blanked the + * screen and may run a graphical theme. This does + * not necessary mean that the screen is locked. + */ + bool SetActive(bool state); + + /// Returns the value of the current state of activity (See setActive) + bool GetActive(); + + /** + * Returns the number of seconds that the screensaver has + * been active. Returns zero if the screensaver is not active. + */ + uint GetActiveTime(); + + /** + * Returns the number of seconds that the session has + * been idle. Returns zero if the session is not idle. + */ + uint GetSessionIdleTime(); + + /** + * Request that saving the screen due to system idleness + * be blocked until UnInhibit is called or the + * calling process exits. + * The cookie is a random number used to identify the request + */ + uint Inhibit(const QString &application_name, const QString &reason_for_inhibit); + /// Cancel a previous call to Inhibit() identified by the cookie. + void UnInhibit(uint cookie); + + /** + * Request that running themes while the screensaver is active + * be blocked until UnThrottle is called or the + * calling process exits. + * The cookie is a random number used to identify the request + */ + uint Throttle(const QString &application_name, const QString &reason_for_inhibit); + /// Cancel a previous call to Throttle() identified by the cookie. + void UnThrottle(uint cookie); + + // org.kde.screensvar + void setupPlasma(); + void configure(); + void saverLockReady(); + +Q_SIGNALS: + // DBus signals + void ActiveChanged(bool state); + +private Q_SLOTS: + void slotLocked(); + void slotUnlocked(); + void serviceUnregistered(const QString &name); + +private: + KSldApp *m_daemon; + QDBusServiceWatcher *m_serviceWatcher; + QList m_requests; + uint m_next_cookie; +}; +} + +#endif // SCREENLOCKER_INTERFACE_H diff --git a/ksmserver/screenlocker/kcfg/kscreensaversettings.kcfg b/ksmserver/screenlocker/kcfg/kscreensaversettings.kcfg new file mode 100644 index 0000000..e2146a1 --- /dev/null +++ b/ksmserver/screenlocker/kcfg/kscreensaversettings.kcfg @@ -0,0 +1,102 @@ + + + kglobalsettings.h + + + + false + + Enables the screen saver. + + + false + + Uses an X screensaver with the screen locker. + + + 300 + + Sets the seconds after which the screen saver is started. + + + true + + Usually the screen saver is suspended when display power saving kicks in, + as nothing can be seen on the screen anyway, obviously. However, some screen savers + actually perform useful computations, so it is not desirable to suspend them. + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + false + + + + + 5000 + + + + + false + + + + + 600 + + + + + 19 + + + + + + + + + + + + + + + + + + + + false + + + + + kscreenlocker/lockscreen.qml + + + + + diff --git a/ksmserver/screenlocker/kcfg/kscreensaversettings.kcfgc b/ksmserver/screenlocker/kcfg/kscreensaversettings.kcfgc new file mode 100644 index 0000000..af9133d --- /dev/null +++ b/ksmserver/screenlocker/kcfg/kscreensaversettings.kcfgc @@ -0,0 +1,4 @@ +File=kscreensaversettings.kcfg +ClassName=KScreenSaverSettings +Singleton=true +Mutators=true diff --git a/ksmserver/screenlocker/kscreenlocker.notifyrc b/ksmserver/screenlocker/kscreenlocker.notifyrc new file mode 100644 index 0000000..14e37ec --- /dev/null +++ b/ksmserver/screenlocker/kscreenlocker.notifyrc @@ -0,0 +1,741 @@ +[Global] +IconName=system-lock-screen +Comment=Screen Saver +Comment[ar]=حافظة الشاشة +Comment[ast]=Curiapantalles +Comment[bg]=Екранен предпазител +Comment[bs]=Čuvar ekrana +Comment[ca]=Estalvi de pantalla +Comment[ca@valencia]=Estalvi de pantalla +Comment[cs]=Šetřič obrazovky +Comment[da]=Pauseskærm +Comment[de]=Bildschirmschoner +Comment[el]=Προφύλαξη οθόνης +Comment[en_GB]=Screen Saver +Comment[es]=Salvapantallas +Comment[et]=Ekraanisäästja +Comment[eu]=Pantaila babeslea +Comment[fi]=Näytönsäästäjä +Comment[fr]=Écran de veille +Comment[ga]=Spárálaí Scáileáin +Comment[gu]=સ્ક્રીનક્રિન સેવર +Comment[he]=שומר מסך +Comment[hi]=स्क्रीन सेवर +Comment[hr]=Čuvar zaslona +Comment[hu]=Képernyővédő +Comment[ia]=Salvator de schermo +Comment[id]=Penyimpan Layar +Comment[is]=Skjáhvíla +Comment[it]=Salvaschermo +Comment[ja]=スクリーンセーバー +Comment[kk]=Экран сақтағышы +Comment[km]=ធាតុ​រក្សា​អេក្រង់​ +Comment[kn]=ತೆರೆ ರಕ್ಷಕ +Comment[ko]=화면 보호기 +Comment[lt]=Ekrano užsklanda +Comment[lv]=Ekrānsaudzētājs +Comment[nb]=Pauseskjerm +Comment[nds]=Pausschirm +Comment[nl]=Schermbeveiliging +Comment[nn]=Pause­skjerm +Comment[pa]=ਸਕਰੀਨ ਸੇਵਰ +Comment[pl]=Wygaszacz ekranu +Comment[pt]=Protector de Ecrã +Comment[pt_BR]=Protetor de tela +Comment[ro]=Protecție de ecran +Comment[ru]=Хранитель экрана +Comment[si]=තිර සුරැකුම +Comment[sk]=Šetrič obrazovky +Comment[sl]=Ohranjevalnik zaslona +Comment[sr]=Чувар екрана +Comment[sr@ijekavian]=Чувар екрана +Comment[sr@ijekavianlatin]=Čuvar ekrana +Comment[sr@latin]=Čuvar ekrana +Comment[sv]=Skärmsläckare +Comment[tg]=Пардаи экран +Comment[th]=โปรแกรมรักษาจอภาพ +Comment[tr]=Ekran Koruyucu +Comment[ug]=ئېكران قوغدىغۇچ +Comment[uk]=Зберігач екрана +Comment[wa]=Sipårgneu di waitroûle +Comment[x-test]=xxScreen Saverxx +Comment[zh_CN]=屏幕保护程序 +Comment[zh_TW]=螢幕保護程式 + +[Event/savingstarted] +Name=Screen saver started +Name[ar]=بدأت حافظة الشاشة +Name[ast]=Curiapantalles aniciáu +Name[bg]=Зареден е екранен предпазител +Name[bs]=Čuvar ekrana pokrenut +Name[ca]=S'ha iniciat l'estalvi de pantalla +Name[ca@valencia]=S'ha iniciat l'estalvi de pantalla +Name[cs]=Šetřič obrazovky spuštěn +Name[csb]=Zrëszony wëgaszôcz ekranu +Name[da]=Pauseskærm startet +Name[de]=Der Bildschirmschoner wurde gestartet. +Name[el]=Η προφύλαξη οθόνης ξεκίνησε +Name[en_GB]=Screen saver started +Name[eo]=Ekrankurtenon ŝaltis +Name[es]=Salvapantallas iniciado +Name[et]=Ekraanisäästja alustas tööd +Name[eu]=Pantaila babeslea abiarazita +Name[fi]=Näytönsäästäjä käynnistyi +Name[fr]=Écran de veille démarré +Name[fy]=Skermbefeiliging úteinsetten +Name[ga]=Tosaíodh an spárálaí scáileáin +Name[gl]=Iniciouse o protector de pantalla +Name[gu]=સ્ક્રિન સેવર શરૂ થયું +Name[he]=שומר המסך התחיל +Name[hi]=स्क्रीन सेवर चालू +Name[hr]=Zaštita zaslona pokrenuta +Name[hu]=A képernyővédő elindult +Name[ia]=Salvator de schermo startate +Name[id]=Penyimpan layar dijalankan +Name[is]=Skjásvæfa ræst +Name[it]=Salvaschermo avviato +Name[ja]=スクリーンセーバー開始 +Name[kk]=Экран сақтағышы ісін бастады +Name[km]=បាន​ចាប់ផ្ដើម​ធាតុរក្សា​អេក្រង់ +Name[kn]=ಸ್ಕ್ರೀನ್‌ ಸೇವರ್ ಪ್ರಾರಂಭಗೊಂಡಿದೆ +Name[ko]=화면 보호기 시작됨 +Name[lt]=Ekrano užsklanda paleista +Name[lv]=Ekrāna saudzētājs palaists +Name[mk]=Чуварот на екранот е стартуван +Name[ml]=സ്ക്രീന്‍ സേവര്‍ തുടങ്ങി +Name[nb]=Pauseskjerm startet +Name[nds]=Pausschirm opropen +Name[nl]=Schermbeveiliging gestart +Name[nn]=Pauseskjermen er starta +Name[pa]=ਸਕਰੀਨ-ਸੇਵਰ ਸ਼ੁਰੂ ਹੋਏ +Name[pl]=Wygaszacz ekranu uruchomiony +Name[pt]=O protector de ecrã foi iniciado +Name[pt_BR]=O protetor de tela foi iniciado +Name[ro]=Protecție de ecran pornită +Name[ru]=Хранитель экрана запущен +Name[si]=තිර සුරැකුම ආරම්ණ කරන ලදි +Name[sk]=Šetrič obrazovky spustený +Name[sl]=Zagon ohranjevalnika zaslona +Name[sr]=Чувар екрана покренут +Name[sr@ijekavian]=Чувар екрана покренут +Name[sr@ijekavianlatin]=Čuvar ekrana pokrenut +Name[sr@latin]=Čuvar ekrana pokrenut +Name[sv]=Skärmsläckare startad +Name[tg]=Пардаи экран сар шуд +Name[th]=โปรแกรมรักษาจอภาพเริ่มทำงานแล้ว +Name[tr]=Ekran koruyucu başlatıldı +Name[ug]=ئېكران قوغدىغۇچ باشلاندى +Name[uk]=Запущено зберігач екрана +Name[wa]=Sipårgneu di waitroûle enondé +Name[x-test]=xxScreen saver startedxx +Name[zh_CN]=屏幕保护程序已启动 +Name[zh_TW]=螢幕保護程式已啟動 +Comment=The screen saver has been started +Comment[ar]=بدأت حافظة الشاشة +Comment[ast]=Entamóse'l curiapantalles +Comment[bg]=Зареден е екранен предпазител +Comment[bs]=Pokrenut je čuvar ekrana +Comment[ca]=S'ha iniciat l'estalvi de pantalla +Comment[ca@valencia]=S'ha iniciat l'estalvi de pantalla +Comment[cs]=Šetřič obrazovky byl spuštěn +Comment[csb]=Wëgaszôcz ekranu òstôł zrëszony +Comment[da]=Pauseskærmen er blevet startet +Comment[de]=Der Bildschirmschoner wurde gestartet. +Comment[el]=Η προφύλαξη οθόνης έχει ξεκινήσει +Comment[en_GB]=The screen saver has been started +Comment[eo]=la Ekrankurteno lanĉiĝas +Comment[es]=Se ha iniciado el salvapantallas +Comment[et]=Ekraanisäästja alustas tööd +Comment[eu]=Pantaila babeslea abiarazi da +Comment[fi]=Näytönsäästäjä on käynnistynyt +Comment[fr]=L'écran de veille a été démarré +Comment[fy]=De skermbefeiliging is úteinsetten +Comment[ga]=Tosaíodh an spárálaí scáileáin +Comment[gl]=Iniciouse o protector de pantalla +Comment[gu]=સ્ક્રિન સેવર શરૂ કરાયેલ છે +Comment[he]=שומר מסך הופעל +Comment[hr]=Zaštita zaslona je pokrenuta +Comment[hu]=A képernyővédő elindult +Comment[ia]=Le salvator de schermo ha essite startate +Comment[id]=Penyimpan layar telah dijalankan +Comment[is]=Skjáhvílan hefur verið ræst +Comment[it]=Il salvaschermo è stato avviato +Comment[ja]=スクリーンセーバーが開始されました +Comment[kk]=Экран сақтағышы ісін бастады +Comment[km]=ធាតុ​រក្សាអេក្រង់​ត្រូវ​បាន​ចាប់ផ្ដើម +Comment[kn]=ಸ್ಕ್ರೀನ್‌ ಸೇವರನ್ನು ಪ್ರಾರಂಭಿಸಲಾಗಿದೆ +Comment[ko]=화면 보호기 시작됨 +Comment[lt]=Ekrano užsklanda buvo paleista +Comment[lv]=Ekrāna saudzētājs tika palaists +Comment[mk]=Чуварот на екранот беше стартуван +Comment[ml]=സ്ക്രീന്‍ സേവര്‍ തുടങ്ങിയിരിയ്ക്കുന്നു +Comment[nb]=Pauseskjermen er startet +Comment[nds]=De Pausschirm wöör opropen +Comment[nl]=De schermbeveiliging is gestart +Comment[nn]=Pauseskjermen er starta +Comment[pa]=ਸਕਰੀਨਸੇਵਰ ਸ਼ੁਰੂ ਕੀਤਾ ਜਾ ਚੁੱਕਿਆ ਹੈ +Comment[pl]=Wygaszacz ekranu został uruchomiony +Comment[pt]=O protector de ecrã foi iniciado +Comment[pt_BR]=O protetor de tela foi iniciado +Comment[ro]=Protecția de ecran a fost pornită +Comment[ru]=Хранитель экрана запущен +Comment[si]=තිර සුරැකුම ආරම්භ කර ඇත +Comment[sk]=Šetrič obrazovky bol spustený +Comment[sl]=Ohranjevalnik zaslona se je zagnal +Comment[sr]=Покренут је чувар екрана +Comment[sr@ijekavian]=Покренут је чувар екрана +Comment[sr@ijekavianlatin]=Pokrenut je čuvar ekrana +Comment[sr@latin]=Pokrenut je čuvar ekrana +Comment[sv]=Skärmsläckaren har startats +Comment[tg]=Ахлотдон холӣ карда шуд +Comment[th]=โปรแกรมรักษาจอภาพเริ่มการทำงานแล้ว +Comment[tr]=Ekran koruyucu başlatıldı +Comment[ug]=ئېكران قوغدىغۇچ باشلاندى +Comment[uk]=Запущено зберігач екрана +Comment[wa]=Li spårgneu di waitroûle a stî enondé +Comment[x-test]=xxThe screen saver has been startedxx +Comment[zh_CN]=屏幕保护程序已经启动 +Comment[zh_TW]=螢幕保護程式已被啟動 +Action=None + +[Event/locked] +Name=Screen locked +Name[ar]=قُقلت الشاشة +Name[ast]=Pantalla bloquiada +Name[bg]=Екранът е заключен +Name[bs]=Ekran zaključan +Name[ca]=S'ha bloquejat la pantalla +Name[ca@valencia]=S'ha bloquejat la pantalla +Name[cs]=Obrazovka uzamčena +Name[csb]=Zablokòwóny ekranu +Name[da]=Skærmen er låst +Name[de]=Bildschirm gesperrt +Name[el]=Οθόνη κλειδώθηκε +Name[en_GB]=Screen locked +Name[eo]=Ekranŝloso +Name[es]=Pantalla bloqueada +Name[et]=Ekraan on lukustatud +Name[eu]=Pantaila giltzatuta +Name[fi]=Näyttö lukittu +Name[fr]=Écran verrouillé +Name[fy]=Skerm beskoattele +Name[ga]=Tá an scáileán faoi ghlas +Name[gl]=A pantalla está trancada +Name[gu]=સ્ક્રિન તાળું મારેલ છે +Name[he]=מסך נעול +Name[hi]=स्क्रीन तालाबंद +Name[hr]=Zaslon zaključan +Name[hu]=A képernyő zárolt +Name[ia]=Schermo blocate +Name[id]=Layar dikunci +Name[is]=Skjár læstur +Name[it]=Schermo bloccato +Name[ja]=スクリーンロック +Name[kk]=Экран бұғатталды +Name[km]=បាន​ចាក់សោ​អេក្រង់​ +Name[kn]=ತೆರೆ ಲಾಕ್ ಆಗಿದೆ +Name[ko]=화면 잠김 +Name[lt]=Ekranas užrakintas +Name[lv]=Ekrāns slēgts +Name[mk]=Екранот е заклучен +Name[ml]=സ്ക്രീന്‍ പൂട്ടി +Name[nb]=Skjermen låst +Name[nds]=Schirm afslaten +Name[nl]=Scherm vergrendeld +Name[nn]=Skjermen er låst +Name[pa]=ਸਕਰੀਨ ਲਾਕ ਹੈ +Name[pl]=Ekran zablokowany +Name[pt]=Ecrã bloqueado +Name[pt_BR]=Tela bloqueada +Name[ro]=Ecran blocat +Name[ru]=Экран заблокирован +Name[si]=තිරය අගුලු දමන ලදි +Name[sk]=Obrazovka zamknutá +Name[sl]=Zaklep zaslona +Name[sr]=Екран закључан +Name[sr@ijekavian]=Екран закључан +Name[sr@ijekavianlatin]=Ekran zaključan +Name[sr@latin]=Ekran zaključan +Name[sv]=Skärm låst +Name[tg]=Пардаи экран қулф шуд +Name[th]=หน้าจอถูกล็อคอยู่ +Name[tr]=Ekran kilitlendi +Name[ug]=ئېكران قۇلۇپلاندى +Name[uk]=Екран заблоковано +Name[wa]=Waitroûle eclawêye +Name[x-test]=xxScreen lockedxx +Name[zh_CN]=屏幕已锁定 +Name[zh_TW]=螢幕已鎖定 +Comment=The screen has been locked +Comment[ar]=تمّ قفل الشاشة +Comment[ast]=Bloquióse la pantalla +Comment[bg]=Екранът е заключен +Comment[bs]=Ekran je upravo zaključan +Comment[ca]=S'ha bloquejat la pantalla +Comment[ca@valencia]=S'ha bloquejat la pantalla +Comment[cs]=Obrazovka byla uzamčena +Comment[csb]=Ekran òstôł zablokòwóny +Comment[da]=Skærmen er blevet låst +Comment[de]=Der Bildschirm wurde gesperrt. +Comment[el]=Η οθόνη έχει κλειδωθεί +Comment[en_GB]=The screen has been locked +Comment[eo]=La ekrano ŝlosiĝis +Comment[es]=Se ha bloqueado la pantalla +Comment[et]=Ekraan on lukustatud +Comment[eu]=Pantaila giltzatu egin da +Comment[fi]=Näyttö on lukittunut +Comment[fr]=L'écran a été verrouillé +Comment[fy]=It skerm is beskoattele +Comment[ga]=Cuireadh an scáileán faoi ghlas +Comment[gl]=A pantalla trancouse +Comment[gu]=સ્ક્રિનને તાળું મારવામાં આવ્યું છે +Comment[he]=המסך ננעל +Comment[hi]=स्क्रीन तालाबंद कर दिया गया है +Comment[hr]=Zaslon je zaključan +Comment[hu]=A képernyő zárolt +Comment[ia]=Le schermo ha essite blocate +Comment[id]=Layar telah dikunci +Comment[is]=Skjánum hefur verið læst +Comment[it]=Lo schermo è stato bloccato +Comment[ja]=スクリーンがロックされました +Comment[kk]=Экран бұғатталған +Comment[km]=អេក្រង់​ត្រូវ​បាន​ចាក់សោ +Comment[kn]=ಒಂದು ತೆರೆಯನ್ನು ಲಾಕ್‌ ಮಾಡಲಾಗಿದೆ +Comment[ko]=화면 잠김 +Comment[lt]=Ekranas buvo užrakintas +Comment[lv]=Ekrāns tika slēgts +Comment[mk]=Екранот беше заклучен +Comment[ml]=സ്ക്രീന്‍ പൂട്ടിയിരിയ്ക്കുന്നു +Comment[nb]=Skjermen er nå låst +Comment[nds]=De Schirm wöör afslaten +Comment[nl]=Het scherm is vergrendeld +Comment[nn]=Skjermen er låst +Comment[pa]=ਸਕਰੀਨ ਨੂੰ ਲਾਕ ਕੀਤਾ ਗਿਆ ਹੈ +Comment[pl]=Ekran został zablokowany +Comment[pt]=O ecrã foi bloqueado +Comment[pt_BR]=A tela foi bloqueada +Comment[ro]=Ecranul a fost blocat +Comment[ru]=Экран заблокирован +Comment[si]=තිරය අගුළු දමා ඇත +Comment[sk]=Obrazovka bola zamknutá +Comment[sl]=Zaslon je bil zaklenjen +Comment[sr]=Екран је управо закључан +Comment[sr@ijekavian]=Екран је управо закључан +Comment[sr@ijekavianlatin]=Ekran je upravo zaključan +Comment[sr@latin]=Ekran je upravo zaključan +Comment[sv]=Skärmen har låsts +Comment[tg]=Клавиша модификатора зафиксирована +Comment[th]=หน้าจอถูกล็อคอยู่ +Comment[tr]=Ekran kilitlendi +Comment[ug]=ئېكران قۇلۇپلانغان +Comment[uk]=Екран було заблоковано +Comment[wa]=Li waitroûle a stî eclawêye +Comment[x-test]=xxThe screen has been lockedxx +Comment[zh_CN]=屏幕已经被锁定 +Comment[zh_TW]=螢幕已被鎖定 +Action=None + +[Event/savingstopped] +Name=Screen saver exited +Name[ar]=خرجت حافظة الشاشة +Name[ast]=Finó'l curiapantalles +Name[bg]=Екранният предпазител е спрян +Name[bs]=Čuvar ekrana napušten +Name[ca]=S'ha sortit de l'estalvi de pantalla +Name[ca@valencia]=S'ha eixit de l'estalvi de pantalla +Name[cs]=Šetřič obrazovky ukončen +Name[csb]=Wëgaszôcz ekranu òstôł zakùńczony +Name[da]=Pauseskærm afslutter +Name[de]=Der Bildschirmschoner wurde beendet. +Name[el]=Η προφύλαξη οθόνης τερμάτισε +Name[en_GB]=Screen saver exited +Name[eo]=Ekrankurteno finiĝis +Name[es]=El salvapantallas ha terminado +Name[et]=Ekraanisäästja lõpetas töö +Name[eu]=Pantaila babeslea amaituta +Name[fi]=Näytönsäästäjä sulkeutui +Name[fr]=Écran de veille terminé +Name[fy]=Skermbefeiliging is der útgong +Name[ga]=Scoireadh ón spárálaí scáileáin +Name[gl]=O protector de pantalla saíu +Name[he]=שומר המסך הפסיק +Name[hi]=स्क्रीन सेवर बंद +Name[hr]=Zaštita zaslona završila +Name[hu]=A képernyővédő kilépett +Name[ia]=Salvator de schermo exite +Name[id]=Penyimpan layar keluar +Name[is]=Hætt í skjásvæfu +Name[it]=Salvaschermo terminato +Name[ja]=スクリーンセーバー終了 +Name[kk]=Экран сақтаушысы тоқтады +Name[km]=បាន​ចេញ​ពី​ធាតុរក្សាអេក្រង់​ +Name[kn]=ಸ್ಕ್ರೀನ್‌ ಸೇವರ್ ನಿರ್ಗಮಿಸಿದೆ +Name[ko]=화면 보호기 종료됨 +Name[lt]=Ekrano užsklanda išsijungė +Name[lv]=Ekrāna saudzētājs apturēts +Name[mk]=Чуварот на екранот излезе +Name[ml]=സ്ക്രീന്‍ സേവറില്‍ നിന്നും പുറത്തു് കടന്നിരിയ്ക്കുന്നു +Name[nb]=Pauseskjermen avsluttet +Name[nds]=Pausschirm utmaakt +Name[nl]=Schermbeveiliger geëindigd +Name[nn]=Pauseskjermen er avslutta +Name[pa]=ਸਕਰੀਨ ਸੇਵਰ ਬੰਦ +Name[pl]=Wygaszacz ekranu wyszedł +Name[pt]=O protector de ecrã terminou +Name[pt_BR]=O protetor de tela terminou +Name[ro]=Protecția de ecran a s-a terminat +Name[ru]=Хранитель экрана завершил работу +Name[si]=තිර සුරැකුම ඉවත් විය +Name[sk]=Šetrič obrazovky skončil +Name[sl]=Izhod iz ohranjevalnika zaslona +Name[sr]=Чувар екрана напуштен +Name[sr@ijekavian]=Чувар екрана напуштен +Name[sr@ijekavianlatin]=Čuvar ekrana napušten +Name[sr@latin]=Čuvar ekrana napušten +Name[sv]=Skärmsläckare avslutades +Name[tg]=Пардаи экран хомӯш шуд +Name[th]=โปรแกรมรักษาจอภาพจบการทำงานแล้ว +Name[tr]=Ekran koruyucudan çıkıldı +Name[ug]=ئېكران قوغدىغۇچ ئاخىرلاشتى +Name[uk]=Завершено роботу зберігача екрана +Name[wa]=Sipårgneu di waitroûle a cwité +Name[x-test]=xxScreen saver exitedxx +Name[zh_CN]=屏幕保护程序已退出 +Name[zh_TW]=螢幕保護程式已離開 +Comment=The screen saver has finished +Comment[ar]=حافظة الشاشة انتهت +Comment[ast]=Finó'l curiapantalles +Comment[bg]=Екранният предпазител е спрян +Comment[bs]=Čuvar ekrana se upravo okončao +Comment[ca]=L'estalvi de pantalla ha finalitzat +Comment[ca@valencia]=L'estalvi de pantalla ha finalitzat +Comment[cs]=Šetřič obrazovky byl ukončen +Comment[csb]=Wëgaszôcz ekranu òstôł zakùńczony +Comment[da]=Pauseskærmen er afsluttet +Comment[de]=Der Bildschirmschoner wurde beendet. +Comment[el]=Η προφύλαξη οθόνης έχει τελειώσει +Comment[en_GB]=The screen saver has finished +Comment[eo]=La ekrankurteno finiĝis +Comment[es]=El salvapantallas ha terminado +Comment[et]=Ekraanisäästja lõpetas töö +Comment[eu]=Pantaila babeslea amaitu da +Comment[fi]=Näytönsäästäjä on päättynyt +Comment[fr]=L'écran de veille a terminé +Comment[fy]=De skermbefeiliging is foltôge +Comment[ga]=Tá an spárálaí scáileán críochnaithe +Comment[gl]=O protector de pantalla rematou +Comment[gu]=સ્ક્રિન સેવર પૂર્ણ થયું છે +Comment[he]=שומר המסך הפסיק +Comment[hi]=स्क्रीन सेवर समाप्त हुआ +Comment[hr]=Zaštita zaslona je završila +Comment[hu]=A képernyővédő befejeződött +Comment[ia]=Le salvator de schermo ha finite +Comment[id]=Penyimpan layar telah selesai +Comment[is]=Skjáhvílan hefur lokið sér af +Comment[it]=Il salvaschermo si è concluso +Comment[ja]=スクリーンセーバーが終了しました +Comment[kk]=Экран сақтаушысы жұмысын тоқтатты +Comment[km]=បាន​បញ្ចប់​ធាតុ​រក្សា​អេក្រង់ +Comment[kn]=ತೆರೆ ರಕ್ಷಕ (ಸ್ಕ್ರೀನ್ ಸೇವರ್) ಅಂತ್ಯಗೊಂಡಿದೆ +Comment[ko]=화면 보호기 종료됨 +Comment[lt]=Ekrano užsklanda baigė darbą +Comment[lv]=Ekrāna saudzētājs tika apturēts +Comment[mk]=Чуварот на екранот заврши +Comment[ml]=സ്ക്രീന്‍ സേവര്‍ അവസാനിച്ചു +Comment[nb]=Pauseskjermen er ferdig +Comment[nds]=De Pausschirm wöör utmaakt +Comment[nl]=De schermbeveiliging is geëindigd +Comment[nn]=Pauseskjermen er ferdig +Comment[pa]=ਸਕਰੀਨ ਸੇਵਰ ਮੁਕੰਮਲ +Comment[pl]=Wygaszacz ekranu zakończył działanie +Comment[pt]=O protector de ecrã terminou +Comment[pt_BR]=O protetor de tela terminou +Comment[ro]=Protecția de ecran s-a încheiat +Comment[ru]=Хранитель экрана завершил работу +Comment[si]=තිරසුරැකුම අවසන් විය +Comment[sk]=Šetrič obrazovky bol ukončený +Comment[sl]=Ohranjevalnik zaslona se je zaključil +Comment[sr]=Чувар екрана се управо окончао +Comment[sr@ijekavian]=Чувар екрана се управо окончао +Comment[sr@ijekavianlatin]=Čuvar ekrana se upravo okončao +Comment[sr@latin]=Čuvar ekrana se upravo okončao +Comment[sv]=Skärmsläckaren har avslutats +Comment[th]=โปรแกรมรักษาจอภาพทำงานเสร็จสิ้นแล้ว +Comment[tr]=Ekran koruyucu bitti +Comment[ug]=ئېكران قوغدىغۇچ ئاخىرلاشتى +Comment[uk]=Роботу зберігача екрана завершено +Comment[wa]=Li spårgneu di waitroûle a cwité +Comment[x-test]=xxThe screen saver has finishedxx +Comment[zh_CN]=屏幕保护程序已运行完成 +Comment[zh_TW]=螢幕保護程式已完成 +Action=None + +[Event/unlocked] +Name=Screen unlocked +Name[ar]=فُكًَ قفل الشاشة +Name[ast]=Pantalla desbloquiada +Name[bg]=Екранът е отключен +Name[bs]=Ekran otključan +Name[ca]=Pantalla desbloquejada +Name[ca@valencia]=Pantalla desbloquejada +Name[cs]=Obrazovka odemknuta +Name[csb]=Ekran òdblokòwóny +Name[da]=Skærmen er låst op +Name[de]=Bildschirm freigegeben +Name[el]=Οθόνη ξεκλείδωτη +Name[en_GB]=Screen unlocked +Name[eo]=Ekrano malŝlosita +Name[es]=Pantalla desbloqueada +Name[et]=Ekraan on lahtilukustatud +Name[eu]=Pantaila desblokeatuta +Name[fi]=Näytön lukitus aukeni +Name[fr]=Écran déverrouillé +Name[fy]=Skerm ûntskoattele +Name[ga]=Scáileán díghlasáilte +Name[gl]=A pantalla desatrancouse +Name[gu]=સ્ક્રિનનું તાળું ખૂલેલ છે +Name[he]=המסך שוחרר +Name[hi]=स्क्रीन तालाबंद +Name[hr]=Zaslon otključan +Name[hu]=A képernyő feloldva +Name[ia]=Schermo disblocate +Name[id]=Layar tidak dikunci +Name[is]=Skjár aflæstur +Name[it]=Schermo sbloccato +Name[ja]=スクリーンロック解除 +Name[kk]=Экран бұғаты шешілді +Name[km]=បាន​​ដោះសោ​អេក្រង់ +Name[kn]=ತೆರೆಯನ್ನು ಅನ್ ಲಾಕ್ ಮಾಡಲಾಗಿದೆ +Name[ko]=화면 잠금 풀림 +Name[lt]=Ekranas atrakintas +Name[lv]=Ekrāns atslēgts +Name[mk]=Екранот е отклучен +Name[ml]=സ്ക്രീന്‍ തുറന്നു +Name[nb]=Skjermen låst opp +Name[nds]=Schirm opslaten +Name[nl]=Scherm ontgrendeld +Name[nn]=Skjermen er låst opp +Name[pa]=ਸਕਰੀਨ ਅਣ-ਲਾਕ ਹੈ +Name[pl]=Ekran odblokowany +Name[pt]=Ecrã desbloqueado +Name[pt_BR]=Tela desbloqueada +Name[ro]=Ecran deblocat +Name[ru]=Экран разблокирован +Name[si]=තිරය අගුළු හැරිනි +Name[sk]=Obrazovka odomknutá +Name[sl]=Odklep zaslona +Name[sr]=Екран откључан +Name[sr@ijekavian]=Екран откључан +Name[sr@ijekavianlatin]=Ekran otključan +Name[sr@latin]=Ekran otključan +Name[sv]=Skärm upplåst +Name[tg]=Экран кушода шуд +Name[th]=ปลดล็อคหน้าจอแล้ว +Name[tr]=Ekranın kilidi açıldı +Name[ug]=ئېكران قۇلۇپسىزلاندى +Name[uk]=Екран розблоковано +Name[wa]=Waitroûle dizeclawêye +Name[x-test]=xxScreen unlockedxx +Name[zh_CN]=屏幕已解锁 +Name[zh_TW]=螢幕已解除鎖定 +Comment=The screen has been unlocked +Comment[ar]=تم قفل الشاشة +Comment[ast]=Desbloquióse la pantalla +Comment[bg]=Екранът е отключен +Comment[bs]=Ekran je upravo otključan +Comment[ca]=S'ha desbloquejat la pantalla +Comment[ca@valencia]=S'ha desbloquejat la pantalla +Comment[cs]=Obrazovka byla odemknuta +Comment[csb]=Ekran òstôł òdblokòwóny +Comment[da]=Skærmen er blevet låst op +Comment[de]=Der Bildschirm wurde freigegeben. +Comment[el]=Η οθόνη έχει ξεκλειδωθεί +Comment[en_GB]=The screen has been unlocked +Comment[eo]=La ekrano malŝlosiĝis +Comment[es]=Se ha desbloqueado la pantalla +Comment[et]=Ekraan on lahtilukustatud +Comment[eu]=Pantaila desblokeatu da +Comment[fi]=Näytön lukitus on avautunut +Comment[fr]=L'écran a été déverrouillé +Comment[fy]=It skerm is ûntskoattele +Comment[ga]=Tá an scáileán díghlasáilte +Comment[gl]=A pantalla desatrancouse +Comment[he]=המסך שוחרר +Comment[hr]=Zaslon je otključan +Comment[hu]=A képernyő feloldva +Comment[ia]=Le schermo ha essite disblocate +Comment[id]=Layar telah tidak dikunci +Comment[is]=Skjánum hefur verið aflæst +Comment[it]=Lo schermo è stato sbloccato +Comment[ja]=スクリーンのロックが解除されました +Comment[kk]=Экраннан бұғаты шешілді +Comment[km]=ធាតុរក្សាអេក្រង់​ត្រូ​វបានដោះសោ +Comment[kn]=ತೆರೆಯನ್ನು ಅನ್ ಲಾಕ್ ಮಾಡಲಾಗಿದೆ +Comment[ko]=화면 잠금 풀림 +Comment[lt]=Ekranas buvo atrakintas +Comment[lv]=Ekrāns tika atslēgts +Comment[mk]=Екранот беше отклучен +Comment[ml]=സ്ക്രീന്‍ തുറന്നിരിയ്ക്കുന്നു +Comment[nb]=Skjermen er blitt låst opp +Comment[nds]=De Schirm wöör opslaten +Comment[nl]=Het scherm is ontgrendeld +Comment[nn]=Skjermen er låst opp +Comment[pa]=ਸਕਰੀਨ ਨੂੰ ਅਣ-ਲਾਕ ਕੀਤਾ ਗਿਆ +Comment[pl]=Ekran został odblokowany +Comment[pt]=O ecrã foi desbloqueado +Comment[pt_BR]=A tela foi desbloqueada +Comment[ro]=Ecranul a fost deblocat +Comment[ru]=Экран разблокирован +Comment[si]=තිරය අගුළු හැර ඇත +Comment[sk]=Obrazovka bola odomknutá +Comment[sl]=Zaslon je bil odklenjen +Comment[sr]=Екран је управо откључан +Comment[sr@ijekavian]=Екран је управо откључан +Comment[sr@ijekavianlatin]=Ekran je upravo otključan +Comment[sr@latin]=Ekran je upravo otključan +Comment[sv]=Skärmen har låsts upp +Comment[tg]=Клавиша модификатора зафиксирована +Comment[th]=หน้าจอถูกปลดล็อคแล้ว +Comment[tr]=Ekranın kilidi açıldı +Comment[ug]=ئېكران قۇلۇپسىزلانغان +Comment[uk]=Екран було розблоковано +Comment[wa]=Li waitroûle a stî dizeclawêye +Comment[x-test]=xxThe screen has been unlockedxx +Comment[zh_CN]=屏幕已经被解锁 +Comment[zh_TW]=螢幕已解除鎖定 +Action=None + +[Event/unlockfailed] +Name=Screen unlock failed +Name[ar]=فشل فك قفل الشاشة +Name[ast]=Nun pudo desbloquiase la pantalla +Name[bg]=Грешка при отключване на екрана +Name[bs]=Otključavanje ekrana neuspelo +Name[ca]=Ha fallat el desbloqueig de la pantalla +Name[ca@valencia]=Ha fallat el desbloqueig de la pantalla +Name[cs]=Odemknutí obrazovky selhalo +Name[csb]=Felënk òdblokòwaniô ekranu +Name[da]=Det mislykkedes at låse skærmen op +Name[de]=Entsperren des Bildschirms fehlgeschlagen +Name[el]=Το ξεκλειδωμα της οθόνης απέτυχε +Name[en_GB]=Screen unlock failed +Name[eo]=Malŝlositado de ekrano fiaskis +Name[es]=No se pudo desbloquear la pantalla +Name[et]=Ekraani lahtilukustamine nurjus +Name[eu]=Pantaila desblokeatzeak huts egin du +Name[fi]=Näytön lukinnan poisto epäonnistui +Name[fr]=Le déverrouillage de l'écran a échoué +Name[fy]=Skerm ûntskoatteling is mislearre +Name[ga]=Níorbh fhéidir an scáileán a dhíghlasáil +Name[gl]=Fallou o desbloqueo da pantalla +Name[gu]=સ્ક્રિનનું તાળું ખોલવામાં નિષ્ફળ +Name[he]=שיחרור המסך נכשל +Name[hi]=स्क्रीन ताला नहीं खुला +Name[hr]=Neuspjelo otključavanje zaslona +Name[hu]=Nem sikerült feloldani a képernyőt +Name[ia]=Disbloco de schermo falleva +Name[id]=Gagal membuka kunci +Name[is]=Aflæsing skjásins mistókst +Name[it]=Sblocco dello schermo non riuscito +Name[ja]=スクリーンのロック解除失敗 +Name[kk]=Экран бұғатын шешуі болмады +Name[km]=បាន​បរាជ័យ​ក្នុងការ​ដោះសោ​អេក្រង់ +Name[kn]=ತೆರೆಯನ್ನು ಅನ್ ಲಾಕ್ ಮಾಡುವುದು ವಿಫಲವಾಗಿದೆ +Name[ko]=화면 잠금 풀리지 않음 +Name[lt]=Ekrano atrakinimas nepavyko +Name[lv]=Neizdevās atslēgt ekrānu +Name[mk]=Не успеа отклучувањето на екранот +Name[ml]=സ്ക്രീന്‍ തുറക്കുന്നതില്‍ പരാജയപ്പെട്ടു +Name[nb]=Det lyktes ikke å låse opp skjermen +Name[nds]=Opsluten vun den Schirm fehlslaan +Name[nl]=Ontgrendelen van scherm is mislukt +Name[nn]=Klarte ikkje låsa opp skjermen +Name[pa]=ਸਕਰੀਨ ਖੋਲ੍ਹਣ ਲਈ ਫੇਲ੍ਹ +Name[pl]=Nieudane odblokowanie ekranu +Name[pt]=O desbloqueio do ecrã foi mal-sucedido +Name[pt_BR]=O bloqueio de tela falhou +Name[ro]=Deblocare ecranului a eșuat +Name[ru]=Не удалось разблокировать экран +Name[si]=තිරය අගුළු හැරීම අසාර්ථකයි +Name[sk]=Odomknutie obrazovky zlyhalo +Name[sl]=Spodletel odklep zaslona +Name[sr]=Откључавање екрана неуспело +Name[sr@ijekavian]=Откључавање екрана неуспјело +Name[sr@ijekavianlatin]=Otključavanje ekrana neuspjelo +Name[sr@latin]=Otključavanje ekrana neuspelo +Name[sv]=Upplåsning av skärm misslyckades +Name[tg]=Кушодани экран қатъ карда шуд +Name[th]=ล้มเหลวในการปลดล็อคหน้าจอ +Name[tr]=Ekran kilidi açılamadı +Name[ug]=ئېكران قۇلۇپسىزلاش مەغلۇپ بولدى +Name[uk]=Невдала спроба розблокування екрана +Name[wa]=Li dizeclawaedje del waitroûle a fwait berwete +Name[x-test]=xxScreen unlock failedxx +Name[zh_CN]=屏幕解锁失败 +Name[zh_TW]=螢幕解除鎖定失敗 +Comment=Failed attempt to unlock the screen +Comment[ar]=محاولة فاشلة لفك قفل الشاشة +Comment[ast]=Fallu al intentar desbloquiar la pantalla +Comment[bg]=Грешка при опит за отключване на екрана +Comment[bs]=Pokušaj otključavanja ekrana nije uspeo +Comment[ca]=L'intent de desbloquejar la pantalla ha fallat +Comment[ca@valencia]=L'intent de desbloquejar la pantalla ha fallat +Comment[cs]=Pokus o odemknutí obrazovky selhal +Comment[csb]=Felënk przëstãpù do òdblokòwaniô ekranu +Comment[da]=Mislykket forsøg på at låse skærmen op +Comment[de]=Das Entsperren des Bildschirms ist fehlgeschlagen. +Comment[el]=Αποτυχής προσπάθεια ξεκλειδώματος οθόνης +Comment[en_GB]=Failed attempt to unlock the screen +Comment[eo]=Provo de malŝlosi ekranon fiaskis +Comment[es]=Error al intentar desbloquear la pantalla +Comment[et]=Nurjunud katse ekraani lahti lukustada +Comment[eu]=Pantaila desblokeatzeko saiakerak huts egin du +Comment[fi]=Yritys näytön lukituksen poistamiseksi epäonnistui +Comment[fr]=Tentative infructueuse de déverrouiller l'écran +Comment[fy]=It is net slagge om it skerm te ûntskoatteljen +Comment[ga]=Theip ar iarracht an scáileán a dhíghlasáil +Comment[gl]=Fallou a tentativa de desbloquear a pantalla +Comment[he]=ניסיון כושל לשיחרור המסך +Comment[hr]=Propao je pokušaj otključavanja zaslona +Comment[hu]=Nem sikerült feloldani a képernyőt +Comment[ia]=Tentativa fallite de disblocar le schermo +Comment[id]=Gagal mencoba membuka kunci layar +Comment[is]=Tilraun til að aflæsa skjánum mistókst +Comment[it]=Tentanivo di sbloccare lo schermo non riuscito +Comment[ja]=スクリーンのロックを解除できませんでした +Comment[kk]=Экран бұғатын шешу әректі сәтсіз аяқталды +Comment[km]=បាន​បរាជ័យ​ក្នុង​ការ​ដោះសោ​អេក្រង់ +Comment[kn]=ತೆರೆಯನ್ನು ಅನ್ ಲಾಕ್ ಮಾಡುವ ವಿಫಲ ಯತ್ನ +Comment[ko]=화면 잠금 풀리지 않음 +Comment[lt]=Nepavyko bandymas atrakinti ekraną +Comment[lv]=Neizdevās atslēgt ekrānu +Comment[mk]=Не успеа обидот да се отклучи екранот +Comment[ml]=സ്ക്രീന്‍ തുറക്കാനുള്ള ശ്രമം പരാജയപ്പെട്ടിരിയ്ക്കുന്നു +Comment[nb]=Klarte ikke å låse opp skjermen +Comment[nds]=Opsluten vun den Schirm hett nich funkscheneert +Comment[nl]=Een mislukte poging om het scherm te ontgrendelen +Comment[nn]=Forsøket på å låsa opp skjermen var mislukka +Comment[pa]=ਸਕਰੀਨ ਅਣ-ਲਾਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਫੇਲ੍ਹ ਹੋਈ +Comment[pl]=Nieudana próba odblokowania ekranu +Comment[pt]=Falhou a tentativa de desbloquear o ecrã +Comment[pt_BR]=A tentativa de desbloquear a tela falhou +Comment[ro]=Încercare eșuată de a debloca ecranul +Comment[ru]=Не удалось разблокировать экран +Comment[si]=තිරය අගුළු හැරිමේ උත්සාහය අසාර්ථකයි +Comment[sk]=Neúspešný pokus o odomknutie obrazovky +Comment[sl]=Spodletel poskus odklepa zaslona +Comment[sr]=Покушај откључавања екрана није успео +Comment[sr@ijekavian]=Покушај откључавања екрана није успио +Comment[sr@ijekavianlatin]=Pokušaj otključavanja ekrana nije uspio +Comment[sr@latin]=Pokušaj otključavanja ekrana nije uspeo +Comment[sv]=Misslyckat försök att låsa upp skärmen +Comment[th]=ล้มเหลวในการพยายามปลดล็อคหน้าจอ +Comment[tr]=Ekran kilidini açma denemesi başarısız oldu +Comment[ug]=ئېكراننى قۇلۇپسىزلاندۇرالمىدى +Comment[uk]=Спроба розблокування екрана завершилася невдало +Comment[vi]=Mở khoá màn hình thất bại +Comment[wa]=Li saye di dizeclawaedje del waitroûle a fwait berwete +Comment[x-test]=xxFailed attempt to unlock the screenxx +Comment[zh_CN]=尝试解锁屏幕失败 +Comment[zh_TW]=螢幕解除鎖定失敗 +Action=None diff --git a/ksmserver/screenlocker/ksldapp.cpp b/ksmserver/screenlocker/ksldapp.cpp new file mode 100644 index 0000000..c07ac0e --- /dev/null +++ b/ksmserver/screenlocker/ksldapp.cpp @@ -0,0 +1,354 @@ +/******************************************************************** + KSld - the KDE Screenlocker Daemon + This file is part of the KDE project. + + Copyright 1999 Martin R. Jones + Copyright 2003 Oswald Buddenhagen + Copyright 2008 Chani Armitage + Copyright (C) 2011 Martin Gräßlin + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*********************************************************************/ +#include "ksldapp.h" +#include "interface.h" +#include "lockwindow.h" +#include "kscreensaversettings.h" +// workspace +#include +// KDE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// Qt +#include +#include +#include +#include +// X11 +#include +// other +#include + +namespace ScreenLocker +{ + +static KSldApp * s_instance = 0; + +KSldApp* KSldApp::self() +{ + if (!s_instance) { + s_instance = new KSldApp(); + } + + return s_instance; +} + +KSldApp::KSldApp(QObject * parent) + : QObject(parent) + , m_actionCollection(NULL) + , m_locked(false) + , m_lockProcess(NULL) + , m_lockWindow(NULL) + , m_lockedTimer(QElapsedTimer()) + , m_idleId(0) + , m_lockGrace(0) + , m_graceTimer(new QTimer(this)) + , m_inhibitCounter(0) + , m_plasmaEnabled(false) +{ + initialize(); +} + +KSldApp::~KSldApp() +{ +} + +static int s_XTimeout; +static int s_XInterval; +static int s_XBlanking; +static int s_XExposures; + +void KSldApp::cleanUp() +{ + if (m_lockProcess && m_lockProcess->state() != QProcess::NotRunning) { + m_lockProcess->terminate(); + } + delete m_actionCollection; + delete m_lockProcess; + delete m_lockWindow; + + // Restore X screensaver parameters + XSetScreenSaver(QX11Info::display(), s_XTimeout, s_XInterval, s_XBlanking, s_XExposures); +} + +void KSldApp::initialize() +{ + KCrash::setFlags(KCrash::AutoRestart); + // Save X screensaver parameters + XGetScreenSaver(QX11Info::display(), &s_XTimeout, &s_XInterval, &s_XBlanking, &s_XExposures); + // And disable it. The internal X screensaver is not used at all, but we use its + // internal idle timer (and it is also used by DPMS support in X). This timer must not + // be altered by this code, since e.g. resetting the counter after activating our + // screensaver would prevent DPMS from activating. We use the timer merely to detect + // user activity. + XSetScreenSaver(QX11Info::display(), 0, s_XInterval, s_XBlanking, s_XExposures); + + // Global keys + m_actionCollection = new KActionCollection(this); + + if (KAuthorized::authorize(QLatin1String("lock_screen"))) { + kDebug() << "Configuring Lock Action"; + KAction *a = m_actionCollection->addAction(QLatin1String("Lock Session")); + a->setText(i18n("Lock Session")); + a->setGlobalShortcut(KShortcut(Qt::ALT+Qt::CTRL+Qt::Key_L)); + connect(a, SIGNAL(triggered(bool)), this, SLOT(lock())); + } + m_actionCollection->readSettings(); + + // idle support + connect(KIdleTime::instance(), SIGNAL(timeoutReached(int)), SLOT(idleTimeout(int))); + + m_lockProcess = new KProcess(); + connect(m_lockProcess, SIGNAL(finished(int,QProcess::ExitStatus)), SLOT(lockProcessFinished(int,QProcess::ExitStatus))); + m_lockedTimer.invalidate(); + m_graceTimer->setSingleShot(true); + // create our D-Bus interface + new Interface(this); + + configure(); +} + +void KSldApp::configure() +{ + KScreenSaverSettings::self()->readConfig(); + // idle support + if (m_idleId) { + KIdleTime::instance()->removeIdleTimeout(m_idleId); + m_idleId = 0; + } + const int timeout = KScreenSaverSettings::timeout(); + // screen saver enabled means there is an auto lock timer + if (KScreenSaverSettings::screenSaverEnabled() && timeout > 0) { + // timeout stored in seconds + m_idleId = KIdleTime::instance()->addIdleTimeout(timeout*1000); + } + m_lockGrace = KScreenSaverSettings::lockGrace(); + if (m_lockGrace < 0) { + m_lockGrace = 0; + } else if (m_lockGrace > 300000) { + m_lockGrace = 300000; // 5 minutes, keep the value sane + } + m_autoLogoutTimeout = KScreenSaverSettings::autoLogout() ? KScreenSaverSettings::autoLogoutTimeout() * 1000 : 0; + m_plasmaEnabled = KScreenSaverSettings::plasmaEnabled(); +} + +void KSldApp::lock() +{ + if (m_locked) { + // already locked, no need to lock again + return; + } + kDebug() << "lock called"; + if (!establishGrab()) { + kError() << "Could not establish screen lock"; + return; + } + KDisplayManager().setLock(true); + KNotification::event(QLatin1String( "locked" )); + + // blank the screen + showLockWindow(); + + // start unlock screen process + if (!startLockProcess()) { + doUnlock(); + kError() << "Greeter Process not started in time"; + return; + } + m_locked = true; + m_lockedTimer.restart(); + emit locked(); +} + +KActionCollection *KSldApp::actionCollection() +{ + return m_actionCollection; +} + +bool KSldApp::establishGrab() +{ + XSync(QX11Info::display(), False); + + if (!grabKeyboard()) { + sleep(1); + if (!grabKeyboard()) { + return false; + } + } + + if (!grabMouse()) { + sleep(1); + if (!grabMouse()) { + XUngrabKeyboard(QX11Info::display(), CurrentTime); + return false; + } + } + + return true; +} + +bool KSldApp::grabKeyboard() +{ + int rv = XGrabKeyboard( QX11Info::display(), QApplication::desktop()->winId(), + True, GrabModeAsync, GrabModeAsync, CurrentTime ); + + return (rv == GrabSuccess); +} + +bool KSldApp::grabMouse() +{ +#define GRABEVENTS ButtonPressMask | ButtonReleaseMask | PointerMotionMask | \ + EnterWindowMask | LeaveWindowMask + int rv = XGrabPointer( QX11Info::display(), QApplication::desktop()->winId(), + True, GRABEVENTS, GrabModeAsync, GrabModeAsync, None, + QCursor(Qt::ArrowCursor).handle(), CurrentTime ); +#undef GRABEVENTS + + return (rv == GrabSuccess); +} + +void KSldApp::doUnlock() +{ + kDebug() << "Grab Released"; + XUngrabKeyboard(QX11Info::display(), CurrentTime); + XUngrabPointer(QX11Info::display(), CurrentTime); + hideLockWindow(); + // delete the window again, to get rid of event filter + delete m_lockWindow; + m_lockWindow = NULL; + m_locked = false; + m_lockedTimer.invalidate(); + KDisplayManager().setLock(false); + emit unlocked(); + KNotification::event( QLatin1String("unlocked")); +} + +static bool s_graceTimeKill = false; + +void KSldApp::lockProcessFinished(int exitCode, QProcess::ExitStatus exitStatus) +{ + if ((!exitCode && exitStatus == QProcess::NormalExit) || s_graceTimeKill) { + // unlock process finished successfully - we can remove the lock grab + s_graceTimeKill = false; + doUnlock(); + return; + } + // failure, restart lock process + startLockProcess(); +} + +bool KSldApp::startLockProcess() +{ + if (m_plasmaEnabled) { + m_lockProcess->setProgram(KStandardDirs::findExe(QLatin1String("plasma-overlay"))); + *m_lockProcess << QLatin1String("--nofork"); + } else { + m_lockProcess->setProgram(KStandardDirs::findExe(QLatin1String("kscreenlocker_greet"))); + } + m_lockProcess->start(); + // we wait one minute + if (!m_lockProcess->waitForStarted()) { + m_lockProcess->kill(); + return false; + } + return true; +} + +void KSldApp::showLockWindow() +{ + if (!m_lockWindow) { + m_lockWindow = new LockWindow(); + } + m_lockWindow->showLockWindow(); + XSync(QX11Info::display(), False); +} + +void KSldApp::hideLockWindow() +{ + if (!m_lockWindow) { + return; + } + m_lockWindow->hideLockWindow(); +} + +uint KSldApp::activeTime() const +{ + if (m_lockedTimer.isValid()) { + return m_lockedTimer.elapsed(); + } + return 0; +} + +void KSldApp::idleTimeout(int identifier) +{ + if (identifier != m_idleId) { + // not our identifier + return; + } + if (isLocked()) { + return; + } + if (m_inhibitCounter) { + // there is at least one process blocking the auto lock of screen locker + return; + } + if (m_lockGrace) { + m_graceTimer->start(m_lockGrace); + } + lock(); +} + +bool KSldApp::isGraceTime() const +{ + return m_graceTimer->isActive(); +} + +void KSldApp::unlock() +{ + if (!m_graceTimer->isActive()) { + return; + } + s_graceTimeKill = true; + m_lockProcess->kill(); +} + +void KSldApp::inhibit() +{ + ++m_inhibitCounter; +} + +void KSldApp::uninhibit() +{ + --m_inhibitCounter; +} + +} // namespace +#include "ksldapp.moc" diff --git a/ksmserver/screenlocker/ksldapp.h b/ksmserver/screenlocker/ksldapp.h new file mode 100644 index 0000000..51c0906 --- /dev/null +++ b/ksmserver/screenlocker/ksldapp.h @@ -0,0 +1,124 @@ +/******************************************************************** + KSld - the KDE Screenlocker Daemon + This file is part of the KDE project. + + Copyright 1999 Martin R. Jones + Copyright 2003 Oswald Buddenhagen + Copyright 2008 Chani Armitage + Copyright (C) 2011 Martin Gräßlin + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*********************************************************************/ +#ifndef SCREENLOCKER_KSLDAPP_H +#define SCREENLOCKER_KSLDAPP_H + +#include +#include + +// forward declarations +class KActionCollection; +class KProcess; +class QTimer; + +namespace ScreenLocker +{ + +class LockWindow; + +class KSldApp : public QObject +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "org.kde.ksld.App") + +public: + static KSldApp* self(); + + KSldApp(QObject * parent = 0); + virtual ~KSldApp(); + + // The action collection of the active widget + KActionCollection* actionCollection(); + + bool isLocked() const { + return m_locked; + } + + /** + * @returns the number of milliseconds passed since the screen has been locked. + **/ + uint activeTime() const; + + void configure(); + + bool isGraceTime() const; + + /** + * Can be used by the lock window to remove the lock during grace time. + **/ + void unlock(); + void inhibit(); + void uninhibit(); + + uint autoLogoutTimeout() const { + return m_autoLogoutTimeout; + } + +public Q_SLOTS: + Q_SCRIPTABLE void lock(); + void lockProcessFinished(int exitCode, QProcess::ExitStatus exitStatus); + +Q_SIGNALS: + void locked(); + void unlocked(); + +private Q_SLOTS: + void cleanUp(); + void idleTimeout(int identifier); + +private: + void initialize(); + bool establishGrab(); + bool grabKeyboard(); + bool grabMouse(); + bool startLockProcess(); + void showLockWindow(); + void hideLockWindow(); + void doUnlock(); + + KActionCollection *m_actionCollection; + bool m_locked; + KProcess *m_lockProcess; + LockWindow *m_lockWindow; + /** + * Timer to measure how long the screen is locked. + * This information is required by DBus Interface. + **/ + QElapsedTimer m_lockedTimer; + int m_idleId; + /** + * Number of milliseconds after locking in which user activity will result in screen being + * unlocked without requiring a password. + **/ + int m_lockGrace; + /** + * while this timer is active user activity may remove the lock. Only used after idle timeout. + **/ + QTimer *m_graceTimer; + int m_inhibitCounter; + uint m_autoLogoutTimeout; + bool m_plasmaEnabled; +}; +} // namespace + +#endif // SCREENLOCKER_KSLDAPP_H diff --git a/ksmserver/screenlocker/lockwindow.cpp b/ksmserver/screenlocker/lockwindow.cpp new file mode 100644 index 0000000..147853b --- /dev/null +++ b/ksmserver/screenlocker/lockwindow.cpp @@ -0,0 +1,536 @@ +/******************************************************************** + KSld - the KDE Screenlocker Daemon + This file is part of the KDE project. + +Copyright (C) 1999 Martin R. Jones +Copyright (C) 2002 Luboš Luňák +Copyright (C) 2003 Oswald Buddenhagen +Copyright (C) 2008 Chani Armitage +Copyright (C) 2011 Martin Gräßlin + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*********************************************************************/ +#include "lockwindow.h" +#include "autologout.h" +#include "ksldapp.h" +// workspace +#include +// KDE +#include +#include +#include +// Qt +#include +#include +#include +#include +// X11 +#include +#include + +static Window gVRoot = 0; +static Window gVRootData = 0; +static Atom gXA_VROOT; +static Atom gXA_SCREENSAVER_VERSION; + +//#define CHECK_XSELECTINPUT +#ifdef CHECK_XSELECTINPUT +#include +static bool check_xselectinput = false; +extern "C" +int XSelectInput( Display* dpy, Window w, long e ) +{ + typedef int (*ptr)(Display*, Window, long); + static ptr fun = NULL; + if( fun == NULL ) + fun = (ptr)dlsym( RTLD_NEXT, "XSelectInput" ); + if( check_xselectinput && w == DefaultRootWindow( dpy )) + kDebug() << kBacktrace(); + return fun( dpy, w, e ); +} +#endif + +namespace ScreenLocker +{ + +LockWindow::LockWindow() + : QWidget() + , m_autoLogoutTimer(new QTimer(this)) +{ + initialize(); +} + +LockWindow::~LockWindow() +{ +} + +void LockWindow::initialize() +{ + kapp->installX11EventFilter(this); + + // Get root window size + XWindowAttributes rootAttr; + QX11Info info; + XGetWindowAttributes(QX11Info::display(), RootWindow(QX11Info::display(), + info.screen()), &rootAttr); + kapp->desktop(); // make Qt set its event mask on the root window first + XSelectInput( QX11Info::display(), QX11Info::appRootWindow(), + SubstructureNotifyMask | rootAttr.your_event_mask ); +#ifdef CHECK_XSELECTINPUT + check_xselectinput = true; +#endif + + setGeometry(0, 0, rootAttr.width, rootAttr.height); + // virtual root property + gXA_VROOT = XInternAtom (QX11Info::display(), "__SWM_VROOT", False); + gXA_SCREENSAVER_VERSION = XInternAtom (QX11Info::display(), "_SCREENSAVER_VERSION", False); + + // read the initial information about all toplevel windows + Window r, p; + Window* real; + unsigned nreal; + if( XQueryTree( x11Info().display(), x11Info().appRootWindow(), &r, &p, &real, &nreal ) + && real != NULL ) { + KXErrorHandler err; // ignore X errors here + for( unsigned i = 0; i < nreal; ++i ) { + XWindowAttributes winAttr; + if (XGetWindowAttributes(QX11Info::display(), real[ i ], &winAttr)) { + WindowInfo info; + info.window = real[ i ]; + info.viewable = ( winAttr.map_state == IsViewable ); + m_windowInfo.append( info ); // ordered bottom to top + } + } + XFree( real ); + } + m_autoLogoutTimer->setSingleShot(true); + connect(m_autoLogoutTimer, SIGNAL(timeout()), SLOT(autoLogoutTimeout())); +} + +void LockWindow::showLockWindow() +{ + Visual* visual = CopyFromParent; + int depth = CopyFromParent; + XSetWindowAttributes attrs; + int flags = CWOverrideRedirect; + attrs.override_redirect = 1; + hide(); + Window w = XCreateWindow( x11Info().display(), RootWindow( x11Info().display(), x11Info().screen()), + x(), y(), width(), height(), 0, depth, InputOutput, visual, flags, &attrs ); + + create( w, false, true ); + + // Some xscreensaver hacks check for this property + const char *version = "KDE 4.0"; + + XChangeProperty (QX11Info::display(), winId(), + gXA_SCREENSAVER_VERSION, XA_STRING, 8, PropModeReplace, + (unsigned char *) version, strlen(version)); + + + XSetWindowAttributes attr; + attr.event_mask = KeyPressMask | ButtonPressMask | PointerMotionMask | + VisibilityChangeMask | ExposureMask; + XChangeWindowAttributes(QX11Info::display(), winId(), + CWEventMask, &attr); + + QPalette p = palette(); + p.setColor(backgroundRole(), Qt::transparent); + setPalette(p); + setAttribute(Qt::WA_PaintOnScreen, true); + setAttribute(Qt::WA_NoSystemBackground, false); + setAttribute(Qt::WA_PaintOutsidePaintEvent, true); // for bitBlt in resume() + + kDebug() << "Lock window Id: " << winId(); + + move(0, 0); + XSync(QX11Info::display(), False); + + setVRoot( winId(), winId() ); + if (KSldApp::self()->autoLogoutTimeout()) { + m_autoLogoutTimer->start(KSldApp::self()->autoLogoutTimeout()); + } +} + +//--------------------------------------------------------------------------- +// +// Hide the screen locker window +// +void LockWindow::hideLockWindow() +{ + if (m_autoLogoutTimer->isActive()) { + m_autoLogoutTimer->stop(); + } + emit userActivity(); + hide(); + lower(); + removeVRoot(winId()); + XDeleteProperty(QX11Info::display(), winId(), gXA_SCREENSAVER_VERSION); + if ( gVRoot ) { + unsigned long vroot_data[1] = { gVRootData }; + XChangeProperty(QX11Info::display(), gVRoot, gXA_VROOT, XA_WINDOW, 32, + PropModeReplace, (unsigned char *)vroot_data, 1); + gVRoot = 0; + } + XSync(QX11Info::display(), False); +} + +//--------------------------------------------------------------------------- +static int ignoreXError(Display *, XErrorEvent *) +{ + return 0; +} + +//--------------------------------------------------------------------------- +// +// Save the current virtual root window +// +void LockWindow::saveVRoot() +{ + Window rootReturn, parentReturn, *children; + unsigned int numChildren; + QX11Info info; + Window root = RootWindowOfScreen(ScreenOfDisplay(QX11Info::display(), info.screen())); + + gVRoot = 0; + gVRootData = 0; + + int (*oldHandler)(Display *, XErrorEvent *); + oldHandler = XSetErrorHandler(ignoreXError); + + if (XQueryTree(QX11Info::display(), root, &rootReturn, &parentReturn, + &children, &numChildren)) + { + for (unsigned int i = 0; i < numChildren; i++) + { + Atom actual_type; + int actual_format; + unsigned long nitems, bytesafter; + unsigned char *newRoot = 0; + + if ((XGetWindowProperty(QX11Info::display(), children[i], gXA_VROOT, 0, 1, + False, XA_WINDOW, &actual_type, &actual_format, &nitems, &bytesafter, + &newRoot) == Success) && newRoot) + { + gVRoot = children[i]; + Window *dummy = (Window*)newRoot; + gVRootData = *dummy; + XFree ((char*) newRoot); + break; + } + } + if (children) + { + XFree((char *)children); + } + } + + XSetErrorHandler(oldHandler); +} + +//--------------------------------------------------------------------------- +// +// Set the virtual root property +// +void LockWindow::setVRoot(Window win, Window vr) +{ + if (gVRoot) + removeVRoot(gVRoot); + + QX11Info info; + unsigned long rw = RootWindowOfScreen(ScreenOfDisplay(QX11Info::display(), info.screen())); + unsigned long vroot_data[1] = { vr }; + + Window rootReturn, parentReturn, *children; + unsigned int numChildren; + Window top = win; + while (1) { + if (!XQueryTree(QX11Info::display(), top , &rootReturn, &parentReturn, + &children, &numChildren)) + return; + if (children) + XFree((char *)children); + if (parentReturn == rw) { + break; + } else + top = parentReturn; + } + + XChangeProperty(QX11Info::display(), top, gXA_VROOT, XA_WINDOW, 32, + PropModeReplace, (unsigned char *)vroot_data, 1); +} + +//--------------------------------------------------------------------------- +// +// Remove the virtual root property +// +void LockWindow::removeVRoot(Window win) +{ + XDeleteProperty (QX11Info::display(), win, gXA_VROOT); +} +static void fakeFocusIn( WId window ) +{ + // We have keyboard grab, so this application will + // get keyboard events even without having focus. + // Fake FocusIn to make Qt realize it has the active + // window, so that it will correctly show cursor in the dialog. + XEvent ev; + memset(&ev, 0, sizeof(ev)); + ev.xfocus.display = QX11Info::display(); + ev.xfocus.type = FocusIn; + ev.xfocus.window = window; + ev.xfocus.mode = NotifyNormal; + ev.xfocus.detail = NotifyAncestor; + XSendEvent( QX11Info::display(), window, False, NoEventMask, &ev ); +} + +// Event filter +bool LockWindow::x11Event(XEvent* event) +{ + bool ret = false; + switch (event->type) { + case ButtonPress: + case ButtonRelease: + case KeyPress: + case KeyRelease: + case MotionNotify: + if (KSldApp::self()->isGraceTime()) { + KSldApp::self()->unlock(); + return true; + } + if (m_autoLogoutTimer->isActive()) { + m_autoLogoutTimer->start(KSldApp::self()->autoLogoutTimeout()); + } + emit userActivity(); + if (!m_lockWindows.isEmpty()) { + XEvent ev2 = *event; + Window root_return; + int x_return, y_return; + unsigned int width_return, height_return, border_width_return, depth_return; + WId targetWindow = 0; + KXErrorHandler err; // ignore X errors + foreach (WId window, m_lockWindows) { + if (XGetGeometry(QX11Info::display(), window, &root_return, + &x_return, &y_return, + &width_return, &height_return, + &border_width_return, &depth_return) + && + (event->xkey.x>=x_return && event->xkey.x<=x_return+(int)width_return) + && + (event->xkey.y>=y_return && event->xkey.y<=y_return+(int)height_return) ) { + targetWindow = window; + ev2.xkey.window = ev2.xkey.subwindow = targetWindow; + ev2.xkey.x = event->xkey.x - x_return; + ev2.xkey.y = event->xkey.y - y_return; + break; + } + } + XSendEvent(QX11Info::display(), targetWindow, False, NoEventMask, &ev2); + ret = true; + } + break; + case ConfigureNotify: // from SubstructureNotifyMask on the root window + if(event->xconfigure.event == QX11Info::appRootWindow()) { + int index = findWindowInfo( event->xconfigure.window ); + if( index >= 0 ) { + int index2 = event->xconfigure.above ? findWindowInfo( event->xconfigure.above ) : 0; + if( index2 < 0 ) + kDebug(1204) << "Unknown above for ConfigureNotify"; + else { // move just above the other window + if( index2 < index ) + ++index2; + m_windowInfo.move( index, index2 ); + } + } else + kDebug(1204) << "Unknown toplevel for ConfigureNotify"; + //kDebug() << "ConfigureNotify:"; + //the stacking order changed, so let's change the stacking order again to what we want + stayOnTop(); + } + break; + case MapNotify: // from SubstructureNotifyMask on the root window + if( event->xmap.event == QX11Info::appRootWindow()) { + kDebug(1204) << "MapNotify:" << event->xmap.window; + int index = findWindowInfo( event->xmap.window ); + if( index >= 0 ) + m_windowInfo[ index ].viewable = true; + else + kDebug(1204) << "Unknown toplevel for MapNotify"; + KXErrorHandler err; // ignore X errors here + if (isLockWindow(event->xmap.window)) { + if (m_lockWindows.contains(event->xmap.window)) { + kDebug() << "uhoh! duplicate!"; + } else { + if (!isVisible()) { + // not yet shown and we have a lock window, so we show our own window + show(); + setCursor(Qt::ArrowCursor); + } + m_lockWindows.prepend(event->xmap.window); + fakeFocusIn(event->xmap.window); + } + } + stayOnTop(); + } + break; + case UnmapNotify: + if (event->xunmap.event == QX11Info::appRootWindow()) { + kDebug(1204) << "UnmapNotify:" << event->xunmap.window; + int index = findWindowInfo( event->xunmap.window ); + if( index >= 0 ) + m_windowInfo[ index ].viewable = false; + else + kDebug(1204) << "Unknown toplevel for MapNotify"; + m_lockWindows.removeAll(event->xunmap.window); + } + break; + case CreateNotify: + if (event->xcreatewindow.parent == QX11Info::appRootWindow()) { + kDebug() << "CreateNotify:" << event->xcreatewindow.window; + int index = findWindowInfo( event->xcreatewindow.window ); + if( index >= 0 ) + kDebug() << "Already existing toplevel for CreateNotify"; + else { + WindowInfo info; + info.window = event->xcreatewindow.window; + info.viewable = false; + m_windowInfo.append( info ); + } + } + break; + case DestroyNotify: + if (event->xdestroywindow.event == QX11Info::appRootWindow()) { + int index = findWindowInfo( event->xdestroywindow.window ); + if( index >= 0 ) + m_windowInfo.removeAt( index ); + else + kDebug() << "Unknown toplevel for DestroyNotify"; + } + break; + case ReparentNotify: + if (event->xreparent.event == QX11Info::appRootWindow() && event->xreparent.parent != QX11Info::appRootWindow()) { + int index = findWindowInfo( event->xreparent.window ); + if( index >= 0 ) + m_windowInfo.removeAt( index ); + else + kDebug() << "Unknown toplevel for ReparentNotify away"; + } else if (event->xreparent.parent == QX11Info::appRootWindow()) { + int index = findWindowInfo( event->xreparent.window ); + if( index >= 0 ) + kDebug() << "Already existing toplevel for ReparentNotify"; + else { + WindowInfo info; + info.window = event->xreparent.window; + info.viewable = false; + m_windowInfo.append( info ); + } + } + break; + case CirculateNotify: + if (event->xcirculate.event == QX11Info::appRootWindow()) { + int index = findWindowInfo( event->xcirculate.window ); + if( index >= 0 ) { + m_windowInfo.move( index, event->xcirculate.place == PlaceOnTop ? m_windowInfo.size() - 1 : 0 ); + } else + kDebug() << "Unknown toplevel for CirculateNotify"; + } + break; + } + return ret; +} + +int LockWindow::findWindowInfo(Window w) +{ + for( int i = 0; + i < m_windowInfo.size(); + ++i ) + if( m_windowInfo[ i ].window == w ) + return i; + return -1; +} + +void LockWindow::stayOnTop() +{ + + // this restacking is written in a way so that + // if the stacking positions actually don't change, + // all restacking operations will be no-op, + // and no ConfigureNotify will be generated, + // thus avoiding possible infinite loops + QVector< Window > stack( m_lockWindows.count() + 1 ); + int count = 0; + foreach( WId w, m_lockWindows ) + stack[ count++ ] = w; + // finally, the lock window + stack[ count++ ] = winId(); + // do the actual restacking if needed + XRaiseWindow( x11Info().display(), stack[ 0 ] ); + if( count > 1 ) + XRestackWindows( x11Info().display(), stack.data(), count ); +} + +bool LockWindow::isLockWindow(Window id) +{ + Atom tag = XInternAtom(QX11Info::display(), "_KDE_SCREEN_LOCKER", False); + Atom actualType; + int actualFormat; + unsigned long nitems, remaining; + unsigned char *data = 0; + Display *display = QX11Info::display(); + + int result = XGetWindowProperty(display, id, tag, 0, 1, False, tag, &actualType, + &actualFormat, &nitems, &remaining, &data); + + bool lockWindow = false; + if (result == Success && actualType == tag) { + lockWindow = true; + } + if (data) { + XFree(data); + } + return lockWindow; +} + +void LockWindow::autoLogoutTimeout() +{ + QPointer dlg = new AutoLogout(this); + dlg->adjustSize(); + + int screen = Kephal::ScreenUtils::primaryScreenId(); + if (Kephal::ScreenUtils::numScreens() > 1) { + screen = Kephal::ScreenUtils::screenId(QCursor::pos()); + } + + const QRect screenRect = Kephal::ScreenUtils::screenGeometry(screen); + QRect rect = dlg->geometry(); + rect.moveCenter(screenRect.center()); + dlg->move(rect.topLeft()); + Atom tag = XInternAtom(QX11Info::display(), "_KDE_SCREEN_LOCKER", False); + XChangeProperty(QX11Info::display(), dlg->winId(), tag, tag, 32, PropModeReplace, 0, 0); + dlg->exec(); + delete dlg; + // start the timer again - only if the window is still shown + if (isVisible()) { + m_autoLogoutTimer->start(KSldApp::self()->autoLogoutTimeout()); + } +} + +void LockWindow::paintEvent(QPaintEvent* ) +{ + QPainter p(this); + p.setBrush(QBrush(Qt::black)); + p.drawRect(geometry()); +} + +} diff --git a/ksmserver/screenlocker/lockwindow.h b/ksmserver/screenlocker/lockwindow.h new file mode 100644 index 0000000..5cbc769 --- /dev/null +++ b/ksmserver/screenlocker/lockwindow.h @@ -0,0 +1,72 @@ +/******************************************************************** + KSld - the KDE Screenlocker Daemon + This file is part of the KDE project. + +Copyright (C) 1999 Martin R. Jones +Copyright (C) 2002 Luboš Luňák +Copyright (C) 2003 Oswald Buddenhagen +Copyright (C) 2008 Chani Armitage +Copyright (C) 2011 Martin Gräßlin + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*********************************************************************/ +#ifndef SCREENLOCKER_LOCKWINDOW_H +#define SCREENLOCKER_LOCKWINDOW_H +#include +#include +#include + +class QTimer; +namespace ScreenLocker +{ +class LockWindow : public QWidget +{ + Q_OBJECT +public: + LockWindow(); + virtual ~LockWindow(); + + void showLockWindow(); + void hideLockWindow(); + +Q_SIGNALS: + void userActivity(); + +protected: + virtual bool x11Event(XEvent *event); + virtual void paintEvent(QPaintEvent *); + +private Q_SLOTS: + void autoLogoutTimeout(); + +private: + void initialize(); + void saveVRoot(); + void setVRoot(Window win, Window vr); + void removeVRoot(Window win); + int findWindowInfo(Window w); + void stayOnTop(); + bool isLockWindow(Window w); + struct WindowInfo + { + Window window; + bool viewable; + }; + QList m_windowInfo; + QList m_lockWindows; + QTimer *m_autoLogoutTimer; +}; +} + +#endif // SCREENLOCKER_LOCKWINDOW_H diff --git a/ksmserver/server.cpp b/ksmserver/server.cpp index 7073fc9..eb3ac18 100644 --- a/ksmserver/server.cpp +++ b/ksmserver/server.cpp @@ -84,6 +84,11 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "server.moc" +// must go after #include +#ifdef COMPILE_SCREEN_LOCKER +#include "screenlocker/ksldapp.h" +#endif + #include #include #include @@ -598,11 +603,22 @@ static Status KSMNewClientProc ( SmsConn conn, SmPointer manager_data, extern "C" int _IceTransNoListen(const char * protocol); #endif -KSMServer::KSMServer( const QString& windowManager, bool _only_local ) +KSMServer::KSMServer( const QString& windowManager, bool _only_local, bool lockscreen ) : wmProcess( NULL ) , sessionGroup( "" ) , logoutEffectWidget( NULL ) { +#ifdef COMPILE_SCREEN_LOCKER + KGlobal::locale()->insertCatalog(QLatin1String( "libkworkspace" )); + + ScreenLocker::KSldApp::self(); + if (lockscreen) { + ScreenLocker::KSldApp::self()->lock(); + } +#else + Q_UNUSED(lockscreen) +#endif + new KSMServerInterfaceAdaptor( this ); QDBusConnection::sessionBus().registerObject("/KSMServer", this); klauncherSignals = new OrgKdeKLauncherInterface(QLatin1String("org.kde.klauncher"), diff --git a/ksmserver/server.h b/ksmserver/server.h index 8e54221..3b993c5 100644 --- a/ksmserver/server.h +++ b/ksmserver/server.h @@ -77,7 +77,7 @@ class KSMServer : public QObject { Q_OBJECT public: - KSMServer( const QString& windowManager, bool only_local ); + KSMServer( const QString& windowManager, bool only_local, bool lockscreen = false ); ~KSMServer(); static KSMServer* self(); diff --git a/ksmserver/shutdown.cpp b/ksmserver/shutdown.cpp index 6f298ec..d1db3ff 100644 --- a/ksmserver/shutdown.cpp +++ b/ksmserver/shutdown.cpp @@ -542,6 +542,10 @@ void KSMServer::killWM() if( state != Killing ) return; delete logoutEffectWidget; +#ifdef COMPILE_SCREEN_LOCKER + // To prevent kwin from becoming "defunct". + ScreenLocker::KSldApp::self()->cleanUp(); +#endif kDebug( 1218 ) << "Starting killing WM"; state = KillingWM; bool iswm = false; diff --git a/plasma/desktop/applets/kickoff/CMakeLists.txt b/plasma/desktop/applets/kickoff/CMakeLists.txt index 4b0d32a..e9e2888 100644 --- a/plasma/desktop/applets/kickoff/CMakeLists.txt +++ b/plasma/desktop/applets/kickoff/CMakeLists.txt @@ -26,7 +26,7 @@ set(libkickoff_SRCS qt4_add_dbus_adaptor(libkickoff_SRCS core/org.kde.kickoff.xml core/applicationmodel.h Kickoff::ApplicationModel) qt4_add_dbus_adaptor(libkickoff_SRCS core/org.kde.kickoff.recent.xml core/recentlyusedmodel.h Kickoff::RecentlyUsedModel) -set(screensaver_xml ${KDEBASE_WORKSPACE_SOURCE_DIR}/krunner/dbus/org.freedesktop.ScreenSaver.xml) +set(screensaver_xml ${KDEBASE_WORKSPACE_SOURCE_DIR}/ksmserver/screenlocker/dbus/org.freedesktop.ScreenSaver.xml) QT4_ADD_DBUS_INTERFACE(libkickoff_SRCS ${screensaver_xml} screensaver_interface) set(krunner_xml ${KDEBASE_WORKSPACE_SOURCE_DIR}/krunner/dbus/org.kde.krunner.App.xml) QT4_ADD_DBUS_INTERFACE(libkickoff_SRCS ${krunner_xml} krunner_interface) diff --git a/plasma/generic/containmentactions/contextmenu/CMakeLists.txt b/plasma/generic/containmentactions/contextmenu/CMakeLists.txt index 5433294..91d1fad 100644 --- a/plasma/generic/containmentactions/contextmenu/CMakeLists.txt +++ b/plasma/generic/containmentactions/contextmenu/CMakeLists.txt @@ -7,7 +7,7 @@ set(contextmenu_SRCS set(krunner_xml ${KDEBASE_WORKSPACE_SOURCE_DIR}/krunner/dbus/org.kde.krunner.App.xml) QT4_ADD_DBUS_INTERFACE(contextmenu_SRCS ${krunner_xml} krunner_interface) -set(screensaver_xml ${KDEBASE_WORKSPACE_SOURCE_DIR}/krunner/dbus/org.freedesktop.ScreenSaver.xml) +set(screensaver_xml ${KDEBASE_WORKSPACE_SOURCE_DIR}/ksmserver/screenlocker/dbus/org.freedesktop.ScreenSaver.xml) QT4_ADD_DBUS_INTERFACE(contextmenu_SRCS ${screensaver_xml} screensaver_interface) diff --git a/plasma/generic/runners/sessions/CMakeLists.txt b/plasma/generic/runners/sessions/CMakeLists.txt index 1b8292c..816b71d 100644 --- a/plasma/generic/runners/sessions/CMakeLists.txt +++ b/plasma/generic/runners/sessions/CMakeLists.txt @@ -2,7 +2,7 @@ set(krunner_sessions_SRCS sessionrunner.cpp ) -set(screensaver_xml ${KDEBASE_WORKSPACE_SOURCE_DIR}/krunner/dbus/org.freedesktop.ScreenSaver.xml) +set(screensaver_xml ${KDEBASE_WORKSPACE_SOURCE_DIR}/ksmserver/screenlocker/dbus/org.freedesktop.ScreenSaver.xml) QT4_ADD_DBUS_INTERFACE(krunner_sessions_SRCS ${screensaver_xml} screensaver_interface) kde4_add_plugin(krunner_sessions ${krunner_sessions_SRCS}) diff --git a/plasma/screensaver/shell/BackgroundDialog.ui b/plasma/screensaver/shell/BackgroundDialog.ui index d6d2df7..c6b0aa7 100644 --- a/plasma/screensaver/shell/BackgroundDialog.ui +++ b/plasma/screensaver/shell/BackgroundDialog.ui @@ -6,10 +6,16 @@ 0 0 - 519 - 173 + 572 + 600 + + + 0 + 600 + + 200 @@ -19,27 +25,8 @@ - - - - - 0 - 0 - - - - - 75 - true - - - - Widget Translucency - - - - + Qt::Horizontal @@ -54,78 +41,7 @@
- - - - User activity: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - m_activeSlider - - - - - - - 1 - - - 10 - - - 1 - - - Qt::Horizontal - - - - - - - While idle: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - m_idleSlider - - - - - - - 10 - - - 1 - - - Qt::Horizontal - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 17 - 13 - - - - - + @@ -144,23 +60,7 @@ - - - - Qt::Horizontal - - - QSizePolicy::Fixed - - - - 13 - 17 - - - - - + Type: @@ -173,7 +73,7 @@ - + @@ -191,39 +91,6 @@
- - - - - - - 0 - 0 - - - - Monitor - - - Qt::AlignCenter - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - @@ -234,19 +101,6 @@ - - - - Qt::Vertical - - - - 143 - 6 - - - -
diff --git a/plasma/screensaver/shell/CMakeLists.txt b/plasma/screensaver/shell/CMakeLists.txt index 8ea4504..4a80cb6 100644 --- a/plasma/screensaver/shell/CMakeLists.txt +++ b/plasma/screensaver/shell/CMakeLists.txt @@ -1,4 +1,11 @@ -include_directories(${KDEBASE_WORKSPACE_SOURCE_DIR}/libs ${KDEBASE_WORKSPACE_SOURCE_DIR}/libs/plasmagenericshell) +include_directories( + ${KDEBASE_WORKSPACE_SOURCE_DIR}/libs + ${KDEBASE_WORKSPACE_SOURCE_DIR}/libs/plasmagenericshell + ${KDEBASE_WORKSPACE_SOURCE_DIR}/ksmserver/screenlocker/greeter/ + ${CMAKE_BINARY_DIR}/ksmserver/screenlocker/greeter/ + ${KDEBASE_WORKSPACE_SOURCE_DIR}/libs/kworkspace + ${KDEBASE_WORKSPACE_SOURCE_DIR}/kcheckpass +) set(plasma-overlay_SRCS backgrounddialog.cpp @@ -6,10 +13,14 @@ set(plasma-overlay_SRCS plasmaapp.cpp savercorona.cpp saverview.cpp + ${KDEBASE_WORKSPACE_SOURCE_DIR}/ksmserver/screenlocker/greeter/greeter.cpp + ${KDEBASE_WORKSPACE_SOURCE_DIR}/ksmserver/screenlocker/greeter/sessions.cpp ) kde4_add_ui_files(plasma-overlay_SRCS BackgroundDialog.ui) +kde4_add_kcfg_files(plasma-overlay_SRCS ${KDEBASE_WORKSPACE_SOURCE_DIR}/ksmserver/screenlocker/kcfg/kscreensaversettings.kcfgc) + set(plasmaapp_dbusXML org.kde.plasma-overlay.App.xml) #qt4_generate_dbus_interface(plasmaapp.h ${plasmaapp_dbusXML} OPTIONS -S -M) qt4_add_dbus_adaptor(plasma-overlay_SRCS ${plasmaapp_dbusXML} plasmaapp.h PlasmaApp) @@ -17,7 +28,7 @@ qt4_add_dbus_adaptor(plasma-overlay_SRCS ${plasmaapp_dbusXML} plasmaapp.h Plasma kde4_add_executable(plasma-overlay ${plasma-overlay_SRCS}) target_link_libraries(plasma-overlay ${KDE4_PLASMA_LIBS} kworkspace ${KDE4_KIO_LIBS} ${KDE4_KFILE_LIBS} - ${X11_X11_LIB} plasmagenericshell) + ${X11_X11_LIB} plasmagenericshell ${QT_QTDECLARATIVE_LIBRARY} kdeclarative) if(X11_Xrender_FOUND) target_link_libraries(plasma-overlay ${X11_Xrender_LIB}) endif(X11_Xrender_FOUND) diff --git a/plasma/screensaver/shell/backgrounddialog.cpp b/plasma/screensaver/shell/backgrounddialog.cpp index 1357a50..dc6ee8b 100644 --- a/plasma/screensaver/shell/backgrounddialog.cpp +++ b/plasma/screensaver/shell/backgrounddialog.cpp @@ -39,8 +39,7 @@ BackgroundDialog::BackgroundDialog(const QSize& res, Plasma::Containment *c, /*P : KDialog(parent), m_wallpaper(0), //m_view(view), - m_containment(c), - m_preview(0) + m_containment(c) { //setWindowIcon(KIcon("preferences-desktop-wallpaper")); setCaption(i18n("Background Settings")); @@ -54,15 +53,6 @@ BackgroundDialog::BackgroundDialog(const QSize& res, Plasma::Containment *c, /*P qreal previewRatio = (qreal)res.width() / (qreal)res.height(); QSize monitorSize(200, int(200 * previewRatio)); - m_monitor->setFixedSize(200,200); - m_monitor->setText(QString()); - m_monitor->setWhatsThis(i18n( - "This picture of a monitor contains a preview of " - "what the current settings will look like on your desktop.")); - m_preview = new ScreenPreviewWidget(m_monitor); - m_preview->setRatio(previewRatio); - m_preview->resize(200,200); - connect(this, SIGNAL(finished(int)), this, SLOT(cleanup())); connect(this, SIGNAL(okClicked()), this, SLOT(saveConfig())); connect(this, SIGNAL(applyClicked()), this, SLOT(saveConfig())); @@ -70,6 +60,13 @@ BackgroundDialog::BackgroundDialog(const QSize& res, Plasma::Containment *c, /*P setMainWidget(main); reloadConfig(); adjustSize(); + + if (c->view()) { + setParent(c->view()); + setBackgroundRole(QPalette::Window); + setAutoFillBackground(true); + move(c->view()->width()/2 - width()/2, y()); + } } BackgroundDialog::~BackgroundDialog() @@ -86,24 +83,16 @@ void BackgroundDialog::cleanup() void BackgroundDialog::reloadConfig() { - //transparency - m_activeSlider->setValue(PlasmaApp::self()->activeOpacity() * 10); - m_idleSlider->setValue(PlasmaApp::self()->idleOpacity() * 10); - - label->setVisible(PlasmaApp::hasComposite()); - m_activeSlider->setVisible(PlasmaApp::hasComposite()); - // Wallpaper disconnect(m_wallpaperMode, SIGNAL(currentIndexChanged(int)), this, SLOT(changeBackgroundMode(int))); int wallpaperIndex = 0; - bool doWallpaper = m_containment->drawWallpaper() && ! PlasmaApp::hasComposite(); + bool doWallpaper = m_containment->drawWallpaper(); m_wallpaperLabel->setVisible(doWallpaper); m_wallpaperTypeLabel->setVisible(doWallpaper); m_wallpaperMode->setVisible(doWallpaper); m_wallpaperConfig->setVisible(doWallpaper); - m_monitor->setVisible(doWallpaper); - m_preview->setVisible(doWallpaper); + if (doWallpaper) { // Load wallpaper plugins QString currentPlugin; @@ -174,7 +163,6 @@ void BackgroundDialog::changeBackgroundMode(int mode) if (!m_wallpaper) { m_wallpaper = Plasma::Wallpaper::load(wallpaperInfo.first); - m_preview->setPreview(m_wallpaper); } if (m_wallpaper) { @@ -204,10 +192,6 @@ KConfigGroup BackgroundDialog::wallpaperConfig(const QString &plugin) void BackgroundDialog::saveConfig() { - //transparency - PlasmaApp::self()->setActiveOpacity(m_activeSlider->value() / 10.0); - PlasmaApp::self()->setIdleOpacity(m_idleSlider->value() / 10.0); - // Wallpaper QString wallpaperPlugin = m_wallpaperMode->itemData(m_wallpaperMode->currentIndex()).value().first; QString wallpaperMode = m_wallpaperMode->itemData(m_wallpaperMode->currentIndex()).value().second; diff --git a/plasma/screensaver/shell/main.cpp b/plasma/screensaver/shell/main.cpp index a1ae939..be151aa 100644 --- a/plasma/screensaver/shell/main.cpp +++ b/plasma/screensaver/shell/main.cpp @@ -12,10 +12,8 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details * - * You should have received a copy of the GNU Library General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ #include @@ -54,6 +52,8 @@ int main(int argc, char **argv) PlasmaApp *app = PlasmaApp::self(); QApplication::setWindowIcon(KIcon("plasma")); + KGlobal::locale()->insertCatalog(QLatin1String( "libkworkspace" )); + KGlobal::locale()->insertCatalog(QLatin1String( "kscreenlocker_greet" )); app->disableSessionManagement(); // I assume we'd never want a screensaver thing reppearing on login? int rc = app->exec(); delete app; diff --git a/plasma/screensaver/shell/plasmaapp.cpp b/plasma/screensaver/shell/plasmaapp.cpp index ade6c68..0c26efa 100644 --- a/plasma/screensaver/shell/plasmaapp.cpp +++ b/plasma/screensaver/shell/plasmaapp.cpp @@ -13,10 +13,8 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details * - * You should have received a copy of the GNU Library General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ // plasma.loadEngine("hardware") @@ -25,6 +23,9 @@ #include "plasmaapp.h" +#include "greeter.h" +#include "sessions.h" + #include #ifndef _SC_PHYS_PAGES @@ -43,6 +44,7 @@ #include #include #include +#include //#include #include @@ -66,6 +68,7 @@ #include Atom tag; //FIXME should this be a member var or what? +Atom tag2; const unsigned char DIALOG = 1; //FIXME this is really bad code const unsigned char VIEW = 2; @@ -129,6 +132,11 @@ PlasmaApp::PlasmaApp(Display* display, Qt::HANDLE visual, Qt::HANDLE colormap) m_corona(0), m_configDialog(0) { + const char *uri = "org.kde.kscreenlocker"; + qmlRegisterType(uri, 1, 0, "GreeterItem"); + qmlRegisterType(uri, 1, 0, "KeyboardItem"); + qmlRegisterType(uri, 1, 0, "Sessions"); + qmlRegisterType(); //load translations for libplasma KGlobal::locale()->insertCatalog("libplasma"); KGlobal::locale()->insertCatalog("plasmagenericshell"); @@ -206,6 +214,7 @@ PlasmaApp::PlasmaApp(Display* display, Qt::HANDLE visual, Qt::HANDLE colormap) //we have to keep an eye on created windows tag = XInternAtom(QX11Info::display(), "_KDE_SCREENSAVER_OVERRIDE", False); + tag2 = XInternAtom(QX11Info::display(), "_KDE_SCREEN_LOCKER", False); qApp->installEventFilter(this); // this line initializes the corona. @@ -433,7 +442,7 @@ bool PlasmaApp::eventFilter(QObject *obj, QEvent *event) data = DIALOG; } else { Qt::WindowFlags oldFlags = widget->windowFlags(); - Qt::WindowFlags newFlags = oldFlags | Qt::X11BypassWindowManagerHint; + Qt::WindowFlags newFlags = oldFlags |Qt::X11BypassWindowManagerHint; if (oldFlags != newFlags) { //now we're *really* fucking with things //we force-disable window management and frames to cut off access to wm-y stuff @@ -455,8 +464,10 @@ bool PlasmaApp::eventFilter(QObject *obj, QEvent *event) widget->setWindowFlags(newFlags); //we do not know the screen this widget should appear on QRect availableGeometry = desktop->availableGeometry(); - //move to the default screen - widget->move(availableGeometry.x(), availableGeometry.y()); + //if has weird position, move to the default screen + if (!availableGeometry.contains(widget->pos())) { + widget->move(availableGeometry.x(), availableGeometry.y()); + } widget->show(); //setting the flags hid it :( //qApp->setActiveWindow(widget); //gives kbd but not mouse events //kDebug() << "parent" << widget->parentWidget(); @@ -469,6 +480,7 @@ bool PlasmaApp::eventFilter(QObject *obj, QEvent *event) } XChangeProperty(QX11Info::display(), widget->effectiveWinId(), tag, tag, 8, PropModeReplace, &data, 1); + XChangeProperty(QX11Info::display(), widget->effectiveWinId(), tag2, tag2, 32, PropModeReplace, 0, 0); kDebug() << "tagged" << widget << widget->effectiveWinId() << "as" << data; } } diff --git a/plasma/screensaver/shell/plasmaapp.h b/plasma/screensaver/shell/plasmaapp.h index 33137c2..ab7cfbd 100644 --- a/plasma/screensaver/shell/plasmaapp.h +++ b/plasma/screensaver/shell/plasmaapp.h @@ -12,10 +12,8 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details * - * You should have received a copy of the GNU Library General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ #ifndef PLASMA_APP_H diff --git a/plasma/screensaver/shell/savercorona.cpp b/plasma/screensaver/shell/savercorona.cpp index 6f83859..9cd207f 100644 --- a/plasma/screensaver/shell/savercorona.cpp +++ b/plasma/screensaver/shell/savercorona.cpp @@ -1,6 +1,7 @@ /* * Copyright 2008 Aaron Seigo * Copyright 2008 by Chani Armitage + * Copyright 2011 Martin Gräßlin * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as @@ -12,33 +13,44 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details * - * You should have received a copy of the GNU Library General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see .. */ #include "savercorona.h" +#include "kscreensaversettings.h" #include #include #include #include -#include -#include -#include +#include +#include #include #include #include #include +#include #include #include +#include +#include + +#include +#include +#include + +static const char *DEFAULT_MAIN_PACKAGE = "org.kde.passworddialog"; SaverCorona::SaverCorona(QObject *parent) : Plasma::Corona(parent) + , m_engine(NULL) + , m_greeterItem(NULL) + , m_mode(ScreenLock) + , m_capsLocked(false) { init(); } @@ -82,7 +94,19 @@ void SaverCorona::init() //updateShortcuts(); //just in case we ever get a config dialog + // create the QML Component + m_engine = new QDeclarativeEngine(this); + foreach(const QString &importPath, KGlobal::dirs()->findDirs("module", "imports")) { + m_engine->addImportPath(importPath); + } + KDeclarative kdeclarative; + kdeclarative.setDeclarativeEngine(m_engine); + kdeclarative.initialize(); + kdeclarative.setupBindings(); + connect(this, SIGNAL(immutabilityChanged(Plasma::ImmutabilityType)), SLOT(updateActions(Plasma::ImmutabilityType))); + + installEventFilter(this); } void SaverCorona::loadDefaultLayout() @@ -142,64 +166,103 @@ void SaverCorona::updateActions(Plasma::ImmutabilityType immutability) void SaverCorona::toggleLock() { //require a password to unlock - QDBusInterface lockprocess("org.kde.screenlocker", "/LockProcess", "org.kde.screenlocker.LockProcess", QDBusConnection::sessionBus(), this); if (immutability() == Plasma::Mutable) { setImmutability(Plasma::UserImmutable); - lockprocess.call(QDBus::NoBlock, "startLock"); kDebug() << "locking up!"; } else if (immutability() == Plasma::UserImmutable) { - QList args; - args << i18n("Unlock widgets to configure them"); - bool sent = lockprocess.callWithCallback("checkPass", args, this, SLOT(unlock(QDBusMessage)), SLOT(dbusError(QDBusError))); - kDebug() << sent; + // show a greeter + if (!m_greeterItem) { + createGreeter(); + } + m_mode = AppletLock; + // TODO: disable session switching + m_greeterItem->setProperty("notification", i18n("Unlock widgets to configure them")); + m_greeterItem->setVisible(true); } } -void SaverCorona::unlock(QDBusMessage reply) +void SaverCorona::unlockDesktop() { - //assuming everything went as expected - if (reply.arguments().isEmpty()) { - kDebug() << "quit succeeded, I guess"; - return; - } - //else we were trying to unlock just the widgets - bool success = reply.arguments().first().toBool(); - kDebug() << success; - if (success) { - setImmutability(Plasma::Mutable); + if (!m_greeterItem) { + createGreeter(); } + m_mode = ScreenLock; + m_greeterItem->setProperty("notification", ""); + // TODO: enable session switching + m_greeterItem->setVisible(true); } -void SaverCorona::dbusError(QDBusError error) +void SaverCorona::numScreensUpdated(int newCount) { - kDebug() << error.errorString(error.type()); - kDebug() << "bailing out"; - //if it was the quit call and it failed, we shouldn't leave the user stuck in - //plasma-overlay forever. - qApp->quit(); + m_numScreens = newCount; + //do something? } -void SaverCorona::unlockDesktop() +void SaverCorona::createGreeter() +{ + Plasma::PackageStructure::Ptr structure = Plasma::PackageStructure::load("Plasma/Generic"); + Plasma::Package *package = new Plasma::Package(KStandardDirs::locate("data", "ksmserver/screenlocker/"), KScreenSaverSettings::greeterQML(), structure); + + QString mainQmlPath = package->filePath("mainscript"); + if (mainQmlPath.isEmpty()) { + delete package; + package = new Plasma::Package(KStandardDirs::locate("data", "ksmserver/screenlocker/"), DEFAULT_MAIN_PACKAGE, structure); + mainQmlPath = package->filePath("mainscript"); + } + + QDeclarativeComponent component(m_engine, QUrl::fromLocalFile(mainQmlPath)); + + m_greeterItem = qobject_cast(component.create()); + addItem(m_greeterItem); + m_greeterItem->setFocus(); + connect(m_greeterItem, SIGNAL(unlockRequested()), SLOT(greeterAccepted())); + connect(m_greeterItem, SIGNAL(canceled()), SLOT(greeterCanceled())); + const QRect screenRect = screenGeometry(QApplication::desktop()->primaryScreen()); + // TODO: center on screen + m_greeterItem->setPos(screenRect.x() + screenRect.width()/2, + screenRect.y() + screenRect.height()/2); +} + +void SaverCorona::greeterAccepted() { - QDBusInterface lockprocess("org.kde.screenlocker", "/LockProcess", - "org.kde.screenlocker.LockProcess", QDBusConnection::sessionBus(), this); - bool sent = (lockprocess.isValid() && - lockprocess.callWithCallback("quit", QList(), this, SLOT(unlock(QDBusMessage)), SLOT(dbusError(QDBusError)))); - //the unlock slot above is a dummy that should never be called. - //somehow I need a valid reply slot or the error slot is never ever used. - if (!sent) { - //ah crud. - kDebug() << "bailing out!"; + if (m_mode == ScreenLock) { qApp->quit(); + } else if (m_mode == AppletLock) { + setImmutability(Plasma::Mutable); + // greeter has problems with reusing after success + delete m_greeterItem; + m_greeterItem = NULL; } } -void SaverCorona::numScreensUpdated(int newCount) +void SaverCorona::greeterCanceled() { - m_numScreens = newCount; - //do something? + m_greeterItem->setVisible(false); } +bool SaverCorona::eventFilter(QObject* watched, QEvent* event) +{ + Q_UNUSED(watched) + if (event->type() == QEvent::KeyPress || event->type() == QEvent::KeyRelease) { + capsLocked(); + } + return false; +} + +void SaverCorona::capsLocked() +{ + unsigned int lmask; + Window dummy1, dummy2; + int dummy3, dummy4, dummy5, dummy6; + XQueryPointer(QX11Info::display(), DefaultRootWindow( QX11Info::display() ), &dummy1, &dummy2, &dummy3, &dummy4, &dummy5, &dummy6, &lmask); + const bool before = m_capsLocked; + m_capsLocked = lmask & LockMask; + if (before != m_capsLocked) { + if (m_greeterItem) { + m_greeterItem->setProperty("capsLockOn", m_capsLocked); + } + } +} #include "savercorona.moc" diff --git a/plasma/screensaver/shell/savercorona.h b/plasma/screensaver/shell/savercorona.h index 794e50c..4f81476 100644 --- a/plasma/screensaver/shell/savercorona.h +++ b/plasma/screensaver/shell/savercorona.h @@ -12,10 +12,8 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details * - * You should have received a copy of the GNU Library General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ #ifndef SAVERCORONA_H @@ -25,8 +23,7 @@ #include -class QDBusMessage; -class QDBusError; +class QDeclarativeEngine; /** * @short A Corona for the screensaver @@ -46,18 +43,31 @@ public: virtual int numScreens() const; virtual QRect screenGeometry(int id) const; +protected: + virtual bool eventFilter(QObject *watched, QEvent *event); + private Q_SLOTS: void updateActions(Plasma::ImmutabilityType immutability); void toggleLock(); - void unlock(QDBusMessage reply); - void dbusError(QDBusError error); void unlockDesktop(); void numScreensUpdated(int newCount); + void greeterAccepted(); + void greeterCanceled(); private: + enum UnlockMode { + AppletLock, + ScreenLock + }; void init(); + void createGreeter(); + void capsLocked(); int m_numScreens; + QDeclarativeEngine *m_engine; + QGraphicsObject *m_greeterItem; + UnlockMode m_mode; + bool m_capsLocked; }; #endif diff --git a/plasma/screensaver/shell/saverview.cpp b/plasma/screensaver/shell/saverview.cpp index b6a709e..800a1f1 100644 --- a/plasma/screensaver/shell/saverview.cpp +++ b/plasma/screensaver/shell/saverview.cpp @@ -14,10 +14,8 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details * - * You should have received a copy of the GNU Library General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ #include "saverview.h" @@ -73,15 +71,16 @@ SaverView::SaverView(Plasma::Containment *containment, QWidget *parent) m_setupMode(false), m_init(false) { - setAttribute(Qt::WA_TranslucentBackground); - setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::X11BypassWindowManagerHint); - if (!PlasmaApp::hasComposite()) { - setAutoFillBackground(false); - setAttribute(Qt::WA_NoSystemBackground); - } + setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | + Qt::X11BypassWindowManagerHint); + + //app is doing this for us - if needed + //QDesktopWidget *desktop = QApplication::desktop(); + //setGeometry(desktop->screenGeometry(containment->screen())); + + setWallpaperEnabled(true); - setWallpaperEnabled(!PlasmaApp::hasComposite()); - installEventFilter(this); + containment->corona()->installEventFilter(this); } SaverView::~SaverView() @@ -194,6 +193,9 @@ bool SaverView::eventFilter(QObject *watched, QEvent *event) (event->type() == QEvent::GraphicsSceneResize || event->type() == QEvent::GraphicsSceneMove)) { Plasma::WidgetExplorer *widgetExplorer = m_widgetExplorer.data(); widgetExplorer->setPos(0, containment()->geometry().height() - widgetExplorer->geometry().height()); + } else if (watched == containment()->corona() && event->type() == QEvent::GraphicsSceneMousePress) { + activateWindow(); + grabKeyboard(); } return false; @@ -216,6 +218,8 @@ void SaverView::showView() m_suppressShow = true; QTimer::singleShot(SUPPRESS_SHOW_TIMEOUT, this, SLOT(suppressShowTimeout())); + activateWindow(); + grabKeyboard(); } } diff --git a/plasma/screensaver/shell/saverview.h b/plasma/screensaver/shell/saverview.h index 8500e47..00d35a3 100644 --- a/plasma/screensaver/shell/saverview.h +++ b/plasma/screensaver/shell/saverview.h @@ -13,10 +13,8 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details * - * You should have received a copy of the GNU Library General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ #ifndef SAVERVIEW_H diff --git a/powerdevil/daemon/CMakeLists.txt b/powerdevil/daemon/CMakeLists.txt index 35a4fd4..04f3050 100644 --- a/powerdevil/daemon/CMakeLists.txt +++ b/powerdevil/daemon/CMakeLists.txt @@ -31,7 +31,7 @@ set(powerdevilcore_SRCS kde4_add_kcfg_files(powerdevilcore_SRCS ../PowerDevilSettings.kcfgc) -set(screensaver_xml "${KDEBASE_WORKSPACE_SOURCE_DIR}/krunner/dbus/org.freedesktop.ScreenSaver.xml") +set(screensaver_xml "${KDEBASE_WORKSPACE_SOURCE_DIR}/ksmserver/screenlocker/dbus/org.freedesktop.ScreenSaver.xml") qt4_add_dbus_interface(powerdevilcore_SRCS ${screensaver_xml} screensaver_interface ) kde4_add_library(powerdevilcore SHARED ${powerdevilcore_SRCS} ${powerdevil_bundled_actions_SRCS}) diff --git a/startkde.cmake b/startkde.cmake index 36f23f1..3653976 100644 --- a/startkde.cmake +++ b/startkde.cmake @@ -323,15 +323,6 @@ if test $? -ne 0; then exit 1 fi -# If the session should be locked from the start (locked autologin), -# lock now and do the rest of the KDE startup underneath the locker. -if test -n "$dl"; then - if ! kwrapper4 kscreenlocker --forcelock --showunlock --daemon; then - echo 'startkde: Initial session lock failed. Terminating for security reasons.' 1>&2 - exit 1 - fi -fi - # finally, give the session control to the session manager # see kdebase/ksmserver for the description of the rest of the startup sequence # if the KDEWM environment variable has been set, then it will be used as KDE's @@ -343,7 +334,11 @@ fi # started, any problems thereafter, e.g. ksmserver failing to initialize, # will remain undetected. test -n "$KDEWM" && KDEWM="--windowmanager $KDEWM" -kwrapper4 ksmserver $KDEWM +# If the session should be locked from the start (locked autologin), +# lock now and do the rest of the KDE startup underneath the locker. +KSMSERVEROPTIONS="" +test -n "$dl" && KSMSERVEROPTIONS=" --lockscreen" +kwrapper4 ksmserver $KDEWM $KSMSERVEROPTIONS if test $? -eq 255; then # Startup error echo 'startkde: Could not start ksmserver. Check your installation.' 1>&2