summaryrefslogtreecommitdiffstats
path: root/kdesktop/lock/lockprocess.cc
diff options
context:
space:
mode:
Diffstat (limited to 'kdesktop/lock/lockprocess.cc')
-rw-r--r--kdesktop/lock/lockprocess.cc3045
1 files changed, 0 insertions, 3045 deletions
diff --git a/kdesktop/lock/lockprocess.cc b/kdesktop/lock/lockprocess.cc
deleted file mode 100644
index fdde3fc9e..000000000
--- a/kdesktop/lock/lockprocess.cc
+++ /dev/null
@@ -1,3045 +0,0 @@
-//===========================================================================
-//
-// This file is part of the TDE project
-//
-// Copyright (c) 1999 Martin R. Jones <[email protected]>
-// Copyright (c) 2003 Oswald Buddenhagen <[email protected]>
-// Copyright (c) 2010 - 2015 Timothy Pearson <[email protected]>
-//
-
-//kdesktop keeps running and checks user inactivity
-//when it should show screensaver (and maybe lock the session),
-//it starts kdesktop_lock, who does all the locking and who
-//actually starts the screensaver
-
-//It's done this way to prevent screen unlocking when kdesktop
-//crashes (e.g. because it's set to multiple wallpapers and
-//some image will be corrupted).
-
-#include <config.h>
-
-#include "lockprocess.h"
-#include "lockdlg.h"
-#include "infodlg.h"
-#include "querydlg.h"
-#include "sakdlg.h"
-#include "securedlg.h"
-#include "autologout.h"
-#include "kdesktopsettings.h"
-
-#include <dmctl.h>
-#include <dcopref.h>
-
-#include <kstandarddirs.h>
-#include <tdeapplication.h>
-#include <kservicegroup.h>
-#include <kdebug.h>
-#include <kuser.h>
-#include <tdemessagebox.h>
-#include <tdeglobalsettings.h>
-#include <tdelocale.h>
-#include <klibloader.h>
-#include <kpushbutton.h>
-#include <kstdguiitem.h>
-#include <kpixmapeffect.h>
-#include <kpixmap.h>
-#include <twin.h>
-#include <twinmodule.h>
-#include <kdialog.h>
-
-#include <tqframe.h>
-#include <tqlabel.h>
-#include <tqlayout.h>
-#include <tqcursor.h>
-#include <tqtimer.h>
-#include <tqfile.h>
-#include <tqsocketnotifier.h>
-#include <tqvaluevector.h>
-#include <tqtooltip.h>
-#include <tqimage.h>
-#include <tqregexp.h>
-#include <tqpainter.h>
-#include <tqeventloop.h>
-
-#include <tqdatetime.h>
-
-#include <stdlib.h>
-#include <assert.h>
-#include <signal.h>
-#ifdef HAVE_SETPRIORITY
-#include <sys/time.h>
-#include <sys/resource.h>
-#endif
-#include <stdio.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <errno.h>
-#include <ctype.h>
-#include <sys/types.h>
-#include <fcntl.h>
-
-#include <kcrash.h>
-
-#include <pthread.h>
-
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include <X11/keysym.h>
-#include <X11/Xatom.h>
-#include <X11/Intrinsic.h>
-
-#ifdef HAVE_DPMS
-extern "C" {
-#include <X11/Xmd.h>
-#ifndef Bool
-#define Bool BOOL
-#endif
-#include <X11/extensions/dpms.h>
-
-#ifndef HAVE_DPMSINFO_PROTO
-Status DPMSInfo ( Display *, CARD16 *, BOOL * );
-#endif
-}
-#endif
-
-#ifdef HAVE_XF86MISC
-#include <X11/extensions/xf86misc.h>
-#endif
-
-#ifdef HAVE_GLXCHOOSEVISUAL
-#include <GL/glx.h>
-#endif
-
-#define KDESKTOP_DEBUG_ID 1204
-
-#define LOCK_GRACE_DEFAULT 5000
-#define AUTOLOGOUT_DEFAULT 600
-
-#define DESKTOP_WALLPAPER_OBTAIN_TIMEOUT_MS 3000
-
-// Setting this define is INSECURE
-// Use it for debugging purposes ONLY
-// #define KEEP_MOUSE_UNGRABBED 1
-
-// These lines are taken on 10/2009 from X.org (X11/XF86keysym.h), defining some special multimedia keys
-#define XF86XK_AudioMute 0x1008FF12
-#define XF86XK_AudioRaiseVolume 0x1008FF13
-#define XF86XK_AudioLowerVolume 0x1008FF11
-#define XF86XK_Display 0x1008FF59
-
-// These lines are taken on 08/2013 from X.org (X11/XF86keysym.h), defining some special ACPI power keys
-#define XF86XK_PowerOff 0x1008FF2A
-#define XF86XK_Sleep 0x1008FF2F
-#define XF86XK_Suspend 0x1008FFA7
-#define XF86XK_Hibernate 0x1008FFA8
-
-#define DPMS_MONITOR_BLANKED(x) ((x == DPMSModeStandby) || (x == DPMSModeSuspend) || (x == DPMSModeOff))
-
-static Window gVRoot = 0;
-static Window gVRootData = 0;
-static Atom gXA_VROOT;
-static Atom gXA_SCREENSAVER_VERSION;
-
-Atom kde_wm_system_modal_notification = 0;
-Atom kde_wm_transparent_to_desktop = 0;
-Atom kde_wm_transparent_to_black = 0;
-
-static void segv_handler(int)
-{
- kdError(KDESKTOP_DEBUG_ID) << "A fatal exception was encountered."
- << " Trapping and ignoring it so as not to compromise desktop security..."
- << kdBacktrace() << endl;
- sleep(1);
-}
-
-extern Atom tqt_wm_state;
-extern bool trinity_desktop_lock_use_system_modal_dialogs;
-extern bool trinity_desktop_lock_delay_screensaver_start;
-extern bool trinity_desktop_lock_use_sak;
-extern bool trinity_desktop_lock_hide_active_windows;
-extern bool trinity_desktop_lock_hide_cancel_button;
-extern bool trinity_desktop_lock_forced;
-
-extern LockProcess* trinity_desktop_lock_process;
-
-extern bool argb_visual;
-extern pid_t kdesktop_pid;
-
-extern TQXLibWindowList trinity_desktop_lock_hidden_window_list;
-
-bool trinity_desktop_lock_autohide_lockdlg = TRUE;
-
-#define ENABLE_CONTINUOUS_LOCKDLG_DISPLAY \
-if (!mForceContinualLockDisplayTimer->isActive()) mForceContinualLockDisplayTimer->start(100, FALSE); \
-trinity_desktop_lock_autohide_lockdlg = FALSE; \
-mHackDelayStartupTimer->stop();
-
-#define DISABLE_CONTINUOUS_LOCKDLG_DISPLAY \
-mForceContinualLockDisplayTimer->stop(); \
-trinity_desktop_lock_autohide_lockdlg = TRUE; \
-mHackDelayStartupTimer->stop();
-
-//===========================================================================
-//
-// Screen saver handling process. Handles screensaver window,
-// starting screensaver hacks, and password entry.
-//
-LockProcess::LockProcess()
- : TQWidget(0L, "saver window", ((WFlags)(WStyle_StaysOnTop|WStyle_Customize|WStyle_NoBorder))),
- mOpenGLVisual(0),
- mParent(0),
- mShowLockDateTime(false),
- mSuspended(false),
- mVisibility(false),
- mRestoreXF86Lock(false),
- mForbidden(false),
- mAutoLogout(false),
- resizeTimer(NULL),
- hackResumeTimer(NULL),
- mVkbdProcess(NULL),
- mKWinModule(NULL),
- mPipeOpen(false),
- mPipeOpen_out(false),
- mInfoMessageDisplayed(false),
- mDialogControlLock(false),
- mForceReject(false),
- currentDialog(NULL),
- mEnsureScreenHiddenTimer(NULL),
- mForceContinualLockDisplayTimer(NULL),
- mEnsureVRootWindowSecurityTimer(NULL),
- mHackDelayStartupTimer(NULL),
- mHackDelayStartupTimeout(0),
- mHackStartupEnabled(true),
- mOverrideHackStartupEnabled(false),
- mResizingDesktopLock(false),
- mFullyOnlineSent(false),
- mClosingWindows(false),
- mInSecureDialog(false),
- mHackActive(false),
- m_rootPixmap(NULL),
- mBackingStartupDelayTimer(0),
- m_startupStatusDialog(NULL),
- m_mouseDown(0),
- m_mousePrevX(0),
- m_mousePrevY(0),
- m_dialogPrevX(0),
- m_dialogPrevY(0),
- m_notifyReadyRequested(false),
- m_loginCardDevice(NULL),
- m_maskWidget(NULL),
- m_saverRootWindow(0)
-{
-#ifdef KEEP_MOUSE_UNGRABBED
- setNFlags(WX11DisableMove|WX11DisableClose|WX11DisableShade|WX11DisableMinimize|WX11DisableMaximize);
-#endif
-
- setupSignals();
-
- // Set up atoms
- kde_wm_system_modal_notification = XInternAtom(tqt_xdisplay(), "_TDE_WM_MODAL_SYS_NOTIFICATION", False);
- kde_wm_transparent_to_desktop = XInternAtom(tqt_xdisplay(), "_TDE_TRANSPARENT_TO_DESKTOP", False);
- kde_wm_transparent_to_black = XInternAtom(tqt_xdisplay(), "_TDE_TRANSPARENT_TO_BLACK", False);
-
- kapp->installX11EventFilter(this);
-
- mForceContinualLockDisplayTimer = new TQTimer( this );
- mHackDelayStartupTimer = new TQTimer( this );
- mEnsureVRootWindowSecurityTimer = new TQTimer( this );
-
- if (!argb_visual) {
- // Try to get the root pixmap
- if (!m_rootPixmap) m_rootPixmap = new KRootPixmap(this);
- connect(m_rootPixmap, TQT_SIGNAL(backgroundUpdated(const TQPixmap &)), this, TQT_SLOT(slotPaintBackground(const TQPixmap &)));
- m_rootPixmap->setCustomPainting(true);
- m_rootPixmap->start();
- }
-
- // Get root window attributes
- XWindowAttributes rootAttr;
- XGetWindowAttributes(tqt_xdisplay(), RootWindow(tqt_xdisplay(), tqt_xscreen()), &rootAttr);
- { // trigger creation of QToolTipManager, it does XSelectInput() on the root window
- TQWidget w;
- TQToolTip::add( &w, "foo" );
- }
- XSelectInput( tqt_xdisplay(), tqt_xrootwin(), SubstructureNotifyMask | rootAttr.your_event_mask );
-
- // Add non-TDE path
- TDEGlobal::dirs()->addResourceType("scrsav",
- TDEGlobal::dirs()->kde_default("apps") +
- "System/ScreenSavers/");
-
- // Add KDE specific screensaver path
- TQString relPath="System/ScreenSavers/";
- KServiceGroup::Ptr servGroup = KServiceGroup::baseGroup( "screensavers");
- if (servGroup) {
- relPath=servGroup->relPath();
- kdDebug(KDESKTOP_DEBUG_ID) << "relPath=" << relPath << endl;
- }
- TDEGlobal::dirs()->addResourceType("scrsav",
- TDEGlobal::dirs()->kde_default("apps") +
- relPath);
-
- // virtual root property
- gXA_VROOT = XInternAtom (tqt_xdisplay(), "__SWM_VROOT", False);
- gXA_SCREENSAVER_VERSION = XInternAtom (tqt_xdisplay(), "_SCREENSAVER_VERSION", False);
-
- TQStringList dmopt = TQStringList::split(TQChar(','),
- TQString::fromLatin1( ::getenv( "XDM_MANAGED" )));
- for (TQStringList::ConstIterator it = dmopt.begin(); it != dmopt.end(); ++it) {
- if ((*it).startsWith("method=")) {
- mMethod = (*it).mid(7);
- }
- }
-
- // Initialize SmartCard readers
- TDEGenericDevice *hwdevice;
- TDEHardwareDevices *hwdevices = TDEGlobal::hardwareDevices();
- TDEGenericHardwareList cardReaderList = hwdevices->listByDeviceClass(TDEGenericDeviceType::CryptographicCard);
- for (hwdevice = cardReaderList.first(); hwdevice; hwdevice = cardReaderList.next()) {
- TDECryptographicCardDevice* cdevice = static_cast<TDECryptographicCardDevice*>(hwdevice);
- // connect(cdevice, SIGNAL(pinRequested(TQString,TDECryptographicCardDevice*)), this, SLOT(cryptographicCardPinRequested(TQString,TDECryptographicCardDevice*)));
- connect(cdevice, TQT_SIGNAL(certificateListAvailable(TDECryptographicCardDevice*)), this, TQT_SLOT(cryptographicCardInserted(TDECryptographicCardDevice*)));
- connect(cdevice, TQT_SIGNAL(cardRemoved(TDECryptographicCardDevice*)), this, TQT_SLOT(cryptographicCardRemoved(TDECryptographicCardDevice*)));
- cdevice->enableCardMonitoring(true);
- // cdevice->enablePINEntryCallbacks(true);
- }
-
-#ifdef KEEP_MOUSE_UNGRABBED
- setEnabled(false);
-#endif
-
- greetPlugin.library = 0;
-
- TDECrash::setCrashHandler(segv_handler);
-}
-
-//---------------------------------------------------------------------------
-//
-// Destructor - usual cleanups.
-//
-LockProcess::~LockProcess()
-{
- mControlPipeHandler->terminateThread();
- mControlPipeHandlerThread->wait();
- delete mControlPipeHandler;
-// delete mControlPipeHandlerThread;
-
- if (resizeTimer != NULL) {
- resizeTimer->stop();
- delete resizeTimer;
- }
- if (hackResumeTimer != NULL) {
- hackResumeTimer->stop();
- delete hackResumeTimer;
- }
- if (mEnsureScreenHiddenTimer != NULL) {
- mEnsureScreenHiddenTimer->stop();
- delete mEnsureScreenHiddenTimer;
- }
- if (mForceContinualLockDisplayTimer != NULL) {
- mForceContinualLockDisplayTimer->stop();
- delete mForceContinualLockDisplayTimer;
- }
- if (mHackDelayStartupTimer != NULL) {
- mHackDelayStartupTimer->stop();
- delete mHackDelayStartupTimer;
- }
- if (mEnsureVRootWindowSecurityTimer != NULL) {
- mEnsureVRootWindowSecurityTimer->stop();
- delete mEnsureVRootWindowSecurityTimer;
- }
-
- if (greetPlugin.library) {
- if (greetPlugin.info->done)
- greetPlugin.info->done();
- greetPlugin.library->unload();
- }
-
- if (m_rootPixmap) {
- m_rootPixmap->stop();
- delete m_rootPixmap;
- }
-
- mPipeOpen = false;
- mPipeOpen_out = false;
-}
-
-//---------------------------------------------------------------------------
-//
-// Initialization for startup
-// This is where instance settings should be set--all objects should have already been created in the constructor above
-//
-void LockProcess::init(bool child, bool useBlankOnly)
-{
- // Get root window size
- XWindowAttributes rootAttr;
- XGetWindowAttributes(tqt_xdisplay(), RootWindow(tqt_xdisplay(), tqt_xscreen()), &rootAttr);
- mRootWidth = rootAttr.width;
- mRootHeight = rootAttr.height;
- generateBackingImages();
-
- // Connect all signals
- connect( mForceContinualLockDisplayTimer, TQT_SIGNAL(timeout()), this, TQT_SLOT(displayLockDialogIfNeeded()) );
- connect( mHackDelayStartupTimer, TQT_SIGNAL(timeout()), this, TQT_SLOT(closeDialogAndStartHack()) );
- connect( mEnsureVRootWindowSecurityTimer, TQT_SIGNAL(timeout()), this, TQT_SLOT(repaintRootWindowIfNeeded()) );
- connect(tqApp, TQT_SIGNAL(mouseInteraction(XEvent *)), TQT_SLOT(slotMouseActivity(XEvent *)));
- connect(&mHackProc, TQT_SIGNAL(processExited(TDEProcess *)), TQT_SLOT(hackExited(TDEProcess *)));
- connect(&mSuspendTimer, TQT_SIGNAL(timeout()), TQT_SLOT(suspend()));
-
-#ifdef HAVE_DPMS
- //if the user decided that the screensaver should run independent from
- //dpms, we shouldn't check for it, aleXXX
- if (KDesktopSettings::dpmsDependent()) {
- BOOL on;
- CARD16 state;
- if (DPMSInfo(tqt_xdisplay(), &state, &on)) {
- if (on) {
- connect(&mCheckDPMS, TQT_SIGNAL(timeout()), TQT_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
-
-#if (TQT_VERSION-0 >= 0x030200) // XRANDR support
- connect( kapp->desktop(), TQT_SIGNAL( resized( int )), TQT_SLOT( desktopResized()));
-#endif
-
- if (!trinity_desktop_lock_use_system_modal_dialogs) {
- setWFlags((WFlags)WX11BypassWM);
- }
-
- child_saver = child;
- mUseBlankOnly = useBlankOnly;
-
- mShowLockDateTime = KDesktopSettings::showLockDateTime();
- mlockDateTime = TQDateTime::currentDateTime();
-
- mHackDelayStartupTimeout = trinity_desktop_lock_delay_screensaver_start?KDesktopSettings::timeout()*1000:10*1000;
- mHackStartupEnabled = trinity_desktop_lock_use_system_modal_dialogs?KDesktopSettings::screenSaverEnabled():true;
-
- configure();
-
- mControlPipeHandlerThread = new TQEventLoopThread();
- mControlPipeHandler = new ControlPipeHandlerObject();
- mControlPipeHandler->mParent = this;
- mControlPipeHandler->moveToThread(mControlPipeHandlerThread);
- TQObject::connect(mControlPipeHandler, SIGNAL(processCommand(TQString)), this, SLOT(processInputPipeCommand(TQString)));
- TQTimer::singleShot(0, mControlPipeHandler, SLOT(run()));
- mControlPipeHandlerThread->start();
-}
-
-static int signal_pipe[2];
-
-static void sigterm_handler(int)
-{
- if ((!trinity_desktop_lock_process) || (!trinity_desktop_lock_process->inSecureDialog())) {
- // Exit uncleanly
- char tmp = 'U';
- if (::write( signal_pipe[1], &tmp, 1) == -1) {
- // Error handler to shut up gcc warnings
- }
- }
-}
-
-static void sighup_handler(int)
-{
- char tmp = 'H';
- if (::write( signal_pipe[1], &tmp, 1) == -1) {
- // Error handler to shut up gcc warnings
- }
-}
-
-bool LockProcess::closeCurrentWindow()
-{
- mClosingWindows = TRUE;
- if (currentDialog != NULL) {
- mForceReject = true;
- if (dynamic_cast<SAKDlg*>(currentDialog)) {
- dynamic_cast<SAKDlg*>(currentDialog)->closeDialogForced();
- }
- else if (dynamic_cast<SecureDlg*>(currentDialog)) {
- dynamic_cast<SecureDlg*>(currentDialog)->closeDialogForced();
- }
- else {
- currentDialog->close();
- }
- }
-
- if( mDialogs.isEmpty() ) {
- mClosingWindows = FALSE;
- mForceReject = false;
- return false;
- }
- else {
- mClosingWindows = TRUE;
- return true;
- }
-}
-
-void LockProcess::timerEvent(TQTimerEvent *ev)
-{
- if (mAutoLogout && ev->timerId() == mAutoLogoutTimerId) {
- killTimer(mAutoLogoutTimerId);
- AutoLogout autologout(this);
- execDialog(&autologout);
- }
-}
-
-void LockProcess::resizeEvent(TQResizeEvent *)
-{
- //
-}
-
-void LockProcess::setupSignals()
-{
- struct sigaction act;
- // ignore SIGINT
- act.sa_handler=SIG_IGN;
- sigemptyset(&(act.sa_mask));
- sigaddset(&(act.sa_mask), SIGINT);
- act.sa_flags = 0;
- sigaction(SIGINT, &act, 0L);
- // ignore SIGQUIT
- act.sa_handler=SIG_IGN;
- sigemptyset(&(act.sa_mask));
- sigaddset(&(act.sa_mask), SIGQUIT);
- act.sa_flags = 0;
- sigaction(SIGQUIT, &act, 0L);
- // exit uncleanly on SIGTERM
- act.sa_handler= sigterm_handler;
- sigemptyset(&(act.sa_mask));
- sigaddset(&(act.sa_mask), SIGTERM);
- act.sa_flags = 0;
- sigaction(SIGTERM, &act, 0L);
- // SIGHUP forces lock
- act.sa_handler= sighup_handler;
- sigemptyset(&(act.sa_mask));
- sigaddset(&(act.sa_mask), SIGHUP);
- act.sa_flags = 0;
- sigaction(SIGHUP, &act, 0L);
-
- if (pipe(signal_pipe) == -1) {
- // Error handler to shut up gcc warnings
- }
- TQSocketNotifier* notif = new TQSocketNotifier(signal_pipe[0], TQSocketNotifier::Read, TQT_TQOBJECT(this) );
- connect( notif, TQT_SIGNAL(activated(int)), TQT_SLOT(signalPipeSignal()));
-}
-
-
-void LockProcess::signalPipeSignal()
-{
- char tmp;
- if (::read( signal_pipe[0], &tmp, 1) == -1) {
- // Error handler to shut up gcc warnings
- }
- if( tmp == 'T' ) {
- quitSaver();
- }
- else if( tmp == 'H' ) {
- if( !mLocked )
- startLock();
- }
- else if( tmp == 'U' ) {
- // Exit uncleanly
- quitSaver();
- exit(1);
- }
-}
-
-//---------------------------------------------------------------------------
-bool LockProcess::lock()
-{
-#ifdef USE_SECURING_DESKTOP_NOTIFICATION
- m_startupStatusDialog = new KSMModalDialog(this);
- m_startupStatusDialog->setStatusMessage(i18n("Securing desktop session").append("..."));
- m_startupStatusDialog->show();
- m_startupStatusDialog->setActiveWindow();
- tqApp->processEvents();
-#endif
-
- if (startSaver(true)) {
- // 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;
- if (startLock()) {
- TQTimer::singleShot(1000, this, TQT_SLOT(slotDeadTimePassed()));
- return true;
- }
- stopSaver();
- mBusy = false;
- }
- return false;
-}
-//---------------------------------------------------------------------------
-void LockProcess::slotDeadTimePassed()
-{
- mBusy = false;
-}
-
-//---------------------------------------------------------------------------
-bool LockProcess::defaultSave()
-{
- mLocked = false;
- mOverrideHackStartupEnabled = true;
- if (startSaver()) {
- if (mLockGrace >= 0) {
- TQTimer::singleShot(mLockGrace, this, TQT_SLOT(startLock()));
- }
- return true;
- }
- mOverrideHackStartupEnabled = false;
- return false;
-}
-
-//---------------------------------------------------------------------------
-bool LockProcess::dontLock()
-{
- mLocked = false;
- return startSaver();
-}
-
-//---------------------------------------------------------------------------
-void LockProcess::quitSaver()
-{
- DISABLE_CONTINUOUS_LOCKDLG_DISPLAY
- if (closeCurrentWindow()) {
- TQTimer::singleShot( 0, this, SLOT(quitSaver()) );
- return;
- }
- stopSaver();
- kapp->quit();
-}
-
-//---------------------------------------------------------------------------
-void LockProcess::startSecureDialog()
-{
- if ((backingPixmap.isNull()) && (mBackingStartupDelayTimer < 100)) {
- TQTimer::singleShot(10, this, TQT_SLOT(startSecureDialog()));
- mBackingStartupDelayTimer++;
- return;
- }
-
- setGeometry(0, 0, mRootWidth, mRootHeight);
- saverReadyIfNeeded();
-
- int ret;
- SecureDlg inDlg( this );
- inDlg.setRetInt(&ret);
- mBusy = true;
- execDialog( &inDlg );
- mBusy = false;
- bool forcecontdisp = mForceContinualLockDisplayTimer->isActive();
- if (forcecontdisp) {
- DISABLE_CONTINUOUS_LOCKDLG_DISPLAY
- }
- mInSecureDialog = false;
- if (ret == 0) {
- mClosingWindows = 1;
- kapp->quit();
- }
- if (ret == 1) {
- // 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;
- trinity_desktop_lock_forced = true;
- // Make sure the cursor is not showing busy status
- setCursor( tqarrowCursor );
- if (startLock())
- {
- if (trinity_desktop_lock_delay_screensaver_start) {
- mBusy = false;
- }
- else {
- TQTimer::singleShot(1000, this, TQT_SLOT(slotDeadTimePassed()));
- }
- if (trinity_desktop_lock_delay_screensaver_start && trinity_desktop_lock_forced && trinity_desktop_lock_use_system_modal_dialogs) {
- ENABLE_CONTINUOUS_LOCKDLG_DISPLAY
- if (mHackStartupEnabled) mHackDelayStartupTimer->start(mHackDelayStartupTimeout, TRUE);
- }
- else {
- if (mHackStartupEnabled == true) {
- startHack();
- }
- else {
- if (trinity_desktop_lock_use_system_modal_dialogs == true) {
- ENABLE_CONTINUOUS_LOCKDLG_DISPLAY
- if (mHackStartupEnabled) mHackDelayStartupTimer->start(mHackDelayStartupTimeout, TRUE);
- }
- else {
- startHack();
- }
- }
- }
- return;
- }
- stopSaver();
- mBusy = false;
- return;
- }
- if (ret == 2) {
- mClosingWindows = 1;
- if (system("ksysguard &") == -1) {
- // Error handler to shut up gcc warnings
- }
- kapp->quit();
- }
- if (ret == 3) {
- mClosingWindows = 1;
- DCOPRef("ksmserver","ksmserver").send("logout", (int)TDEApplication::ShutdownConfirmYes, (int)TDEApplication::ShutdownTypeNone, (int)TDEApplication::ShutdownModeInteractive);
- kapp->quit();
- }
- // FIXME
- // Handle remaining case (switch user)
- if (forcecontdisp) {
- ENABLE_CONTINUOUS_LOCKDLG_DISPLAY
- if (mHackStartupEnabled) mHackDelayStartupTimer->start(mHackDelayStartupTimeout, TRUE);
- }
- stopSaver();
-}
-
-bool LockProcess::runSecureDialog()
-{
-#ifdef USE_SECURING_DESKTOP_NOTIFICATION
- m_startupStatusDialog = new KSMModalDialog(this);
- m_startupStatusDialog->setStatusMessage(i18n("Securing desktop session").append("..."));
- m_startupStatusDialog->show();
- m_startupStatusDialog->setActiveWindow();
- tqApp->processEvents();
-#endif
-
- mInSecureDialog = true;
- if (startSaver()) {
- mBackingStartupDelayTimer = 0;
- TQTimer::singleShot(0, this, TQT_SLOT(startSecureDialog()));
- return true;
- }
- else {
- mInSecureDialog = false;
- return false;
- }
-}
-
-bool LockProcess::inSecureDialog()
-{
- return mInSecureDialog;
-}
-
-//---------------------------------------------------------------------------
-//
-// Read and apply configuration.
-//
-void LockProcess::configure()
-{
- // the configuration is stored in kdesktop's config file
- if( KDesktopSettings::lock() ) {
- mLockGrace = KDesktopSettings::lockGrace();
- if (mLockGrace < 0)
- mLockGrace = 0;
- else if (mLockGrace > 300000)
- mLockGrace = 300000; // 5 minutes, keep the value sane
- }
- else
- mLockGrace = -1;
-
- if ( KDesktopSettings::autoLogout() ) {
- mAutoLogout = true;
- mAutoLogoutTimeout = KDesktopSettings::autoLogoutTimeout();
- mAutoLogoutTimerId = startTimer(mAutoLogoutTimeout * 1000); // in milliseconds
- }
-
- mPriority = KDesktopSettings::priority();
- if (mPriority < 0) mPriority = 0;
- if (mPriority > 19) mPriority = 19;
-
- mSaver = KDesktopSettings::saver();
- if (mSaver.isEmpty() || mUseBlankOnly) {
- mSaver = "KBlankscreen.desktop";
- }
- if (!trinity_desktop_lock_use_system_modal_dialogs) {
- if (KDesktopSettings::screenSaverEnabled() == false) {
- mSaver = "";
- mSaverExec = "";
- }
- }
-
- readSaver();
-
- mPlugins = KDesktopSettings::pluginsUnlock();
- if (mPlugins.isEmpty()) {
- mPlugins = TQStringList("classic");
- }
- mPluginOptions = KDesktopSettings::pluginOptions();
-}
-
-//---------------------------------------------------------------------------
-//
-// Read the command line needed to run the screensaver given a .desktop file.
-//
-void LockProcess::readSaver()
-{
- if (!mSaver.isEmpty()) {
- TQString file = locate("scrsav", mSaver);
-
- bool opengl = kapp->authorize("opengl_screensavers");
- bool manipulatescreen = kapp->authorize("manipulatescreen_screensavers");
- KDesktopFile config(file, true);
- if (config.readEntry("X-TDE-Type").utf8() != 0) {
- TQString saverType = config.readEntry("X-TDE-Type").utf8();
- TQStringList saverTypes = TQStringList::split(";", saverType);
- for (uint i = 0; i < saverTypes.count(); i++) {
- if ((saverTypes[i] == "ManipulateScreen") && !manipulatescreen) {
- kdDebug(KDESKTOP_DEBUG_ID) << "Screensaver is type ManipulateScreen and ManipulateScreen is forbidden" << endl;
- mForbidden = true;
- }
- if ((saverTypes[i] == "OpenGL") && !opengl) {
- kdDebug(KDESKTOP_DEBUG_ID) << "Screensaver is type OpenGL and OpenGL is forbidden" << endl;
- mForbidden = true;
- }
- if (saverTypes[i] == "OpenGL") {
- mOpenGLVisual = true;
- }
- }
- }
-
- kdDebug(KDESKTOP_DEBUG_ID) << "mForbidden: " << (mForbidden ? "true" : "false") << endl;
-
- if (trinity_desktop_lock_use_system_modal_dialogs) {
- if (config.hasActionGroup("InWindow")) {
- config.setActionGroup("InWindow");
- mSaverExec = config.readPathEntry("Exec");
- }
- }
- else {
- if (config.hasActionGroup("Root")) {
- config.setActionGroup("Root");
- mSaverExec = config.readPathEntry("Exec");
- }
- }
- }
-}
-
-//---------------------------------------------------------------------------
-//
-// Create a window to draw our screen saver on.
-//
-void LockProcess::createSaverWindow()
-{
- Visual* visual = CopyFromParent;
- XSetWindowAttributes attrs;
- XVisualInfo* info = NULL;
- int flags = trinity_desktop_lock_use_system_modal_dialogs?0:CWOverrideRedirect;
-#ifdef HAVE_GLXCHOOSEVISUAL
- if( mOpenGLVisual ) {
- static 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 ) {
- int n_glxfb_configs;
- GLXFBConfig *fbc = glXChooseFBConfig( x11Display(), x11Screen(), attribs[ i ], &n_glxfb_configs);
- if (!fbc) {
- n_glxfb_configs = 0;
- }
- for( int j = 0; j < n_glxfb_configs; j++ ) {
- info = glXGetVisualFromFBConfig(x11Display(), fbc[j]);
- if( info ) {
- if (argb_visual) {
- // Xorg can only use GPU compositing for ARGB32 8:8:8:8 visuals
- // Ensure the selected visual is 8 bits per RGB
- // Selecting a non-8-bit visual will result in stuttering and high
- // CPU load, while Xorg tries to composite each frame on the CPU!
- if ((info->depth < 32) || (info->bits_per_rgb != 8)) {
- XFree( info );
- info = NULL;
- continue;
- }
- }
- visual = info->visual;
- static Colormap colormap = 0;
- if( colormap != 0 ) {
- XFreeColormap( x11Display(), colormap );
- }
- colormap = XCreateColormap( x11Display(), RootWindow( x11Display(), x11Screen()), visual, AllocNone );
- attrs.colormap = colormap;
- flags |= CWColormap;
- break;
- }
- }
- if (flags & CWColormap) {
- break;
- }
- }
- if ( !info ) {
- printf("[WARNING] Unable to locate matching X11 GLX Visual; this OpenGL application may not function correctly!\n");
- }
- }
-#endif
-
- attrs.override_redirect = 1;
- hide();
-
- if (argb_visual) {
- // The GL visual selection can return a visual with invalid depth
- // Check for this and use a fallback visual if needed
- if (info && (info->depth < 32)) {
- printf("[WARNING] Unable to locate matching X11 GLX Visual; this OpenGL application may not function correctly!\n");
- XFree( info );
- info = NULL;
- flags &= ~CWColormap;
- }
-
- attrs.background_pixel = 0;
- attrs.border_pixel = 0;
- flags |= CWBackPixel;
- flags |= CWBorderPixel;
- if (!(flags & CWColormap)) {
- if (!info) {
- info = new XVisualInfo;
- if (!XMatchVisualInfo( x11Display(), x11Screen(), 32, TrueColor, info )) {
- printf("[ERROR] Unable to locate matching X11 Visual; this application will not function correctly!\n");
- free(info);
- info = NULL;
- }
- }
- if (info) {
- visual = info->visual;
- attrs.colormap = XCreateColormap( x11Display(), RootWindow( x11Display(), x11Screen()), visual, AllocNone );
- flags |= CWColormap;
- }
- }
- }
- if (info) {
- XFree( info );
- }
-
- m_saverRootWindow = XCreateWindow( x11Display(), RootWindow( x11Display(), x11Screen()), x(), y(), width(), height(), 0, x11Depth(), InputOutput, visual, flags, &attrs );
- create( m_saverRootWindow );
-
- // Some xscreensaver hacks check for this property
- const char *version = "KDE 2.0";
- XChangeProperty (tqt_xdisplay(), winId(),
- gXA_SCREENSAVER_VERSION, XA_STRING, 8, PropModeReplace,
- (unsigned char *) version, strlen(version));
-
- XSetWindowAttributes attr;
- attr.event_mask = KeyPressMask | ButtonPressMask | PointerMotionMask | VisibilityChangeMask | ExposureMask;
- XChangeWindowAttributes(tqt_xdisplay(), winId(), CWEventMask, &attr);
-
- // Signal that we want to be transparent to the desktop, not to windows behind us...
- XChangeProperty(tqt_xdisplay(), m_saverRootWindow, kde_wm_transparent_to_desktop, XA_INTEGER, 32, PropModeReplace, (unsigned char *) "TRUE", 1L);
-
- // erase();
-
- // set NoBackground so that the saver can capture the current
- // screen state if necessary
- // this is a security risk and has been deactivated--welcome to the 21st century folks!
- // setBackgroundMode(TQWidget::NoBackground);
-
- setGeometry(0, 0, mRootWidth, mRootHeight);
- saverReadyIfNeeded();
-
- // HACK
- // Hide all tooltips and notification windows
- {
- Window rootWindow = RootWindow(x11Display(), x11Screen());
- Window parent;
- Window* children = NULL;
- unsigned int noOfChildren = 0;
- XWindowAttributes childAttr;
- Window childTransient;
-
- if (XQueryTree(x11Display(), rootWindow, &rootWindow, &parent, &children, &noOfChildren) && noOfChildren>0 ) {
- for (unsigned int i=0; i<noOfChildren; i++) {
- if (XGetWindowAttributes(x11Display(), children[i], &childAttr) && XGetTransientForHint(x11Display(), children[i], &childTransient)) {
- if ((childAttr.map_state == IsViewable) && (childAttr.override_redirect) && (childTransient)) {
- if (!trinity_desktop_lock_hidden_window_list.contains(children[i])) {
- trinity_desktop_lock_hidden_window_list.append(children[i]);
- }
- XLowerWindow(x11Display(), children[i]);
- XFlush(x11Display());
- }
- }
- }
- }
- }
-
- kdDebug(KDESKTOP_DEBUG_ID) << "Saver window Id: " << winId() << endl;
-}
-
-void LockProcess::desktopResized()
-{
- // Get root window size
- XWindowAttributes rootAttr;
- XGetWindowAttributes(tqt_xdisplay(), RootWindow(tqt_xdisplay(), tqt_xscreen()), &rootAttr);
- if ((rootAttr.width == mRootWidth) && (rootAttr.height == mRootHeight)) {
- return;
- }
- mRootWidth = rootAttr.width;
- mRootHeight = rootAttr.height;
- generateBackingImages();
-
- mBusy = true;
- mHackDelayStartupTimer->stop();
- stopHack();
- DISABLE_CONTINUOUS_LOCKDLG_DISPLAY
- mResizingDesktopLock = true;
-
- backingPixmap = TQPixmap();
-
- if (trinity_desktop_lock_use_system_modal_dialogs) {
- // Temporarily hide the entire screen with a new override redirect window
- if (m_maskWidget) {
- m_maskWidget->setGeometry(0, 0, mRootWidth, mRootHeight);
- }
- else {
- m_maskWidget = new TQWidget(0, 0, TQt::WStyle_StaysOnTop | TQt::WX11BypassWM);
- m_maskWidget->setGeometry(0, 0, mRootWidth, mRootHeight);
- m_maskWidget->setBackgroundColor(TQt::black);
- m_maskWidget->erase();
- m_maskWidget->show();
- }
- XSync(tqt_xdisplay(), False);
- saverReadyIfNeeded();
-
- if (mEnsureScreenHiddenTimer) {
- mEnsureScreenHiddenTimer->stop();
- }
- else {
- mEnsureScreenHiddenTimer = new TQTimer( this );
- connect( mEnsureScreenHiddenTimer, TQT_SIGNAL(timeout()), this, TQT_SLOT(slotForcePaintBackground()) );
- }
- mEnsureScreenHiddenTimer->start(DESKTOP_WALLPAPER_OBTAIN_TIMEOUT_MS, true);
- }
-
- // Resize the background widget
- setGeometry(0, 0, mRootWidth, mRootHeight);
- XSync(tqt_xdisplay(), False);
- saverReadyIfNeeded();
-
- // Black out the background widget to hide ugly resize tiling artifacts
- if (argb_visual) {
- setTransparentBackgroundARGB();
- }
- else {
- setBackgroundColor(black);
- }
- erase();
-
- // This slot needs to be able to execute very rapidly so as to prevent the user's desktop from ever
- // being displayed, so we finish the hack restarting/display prettying operations in a separate timed slot
- if (resizeTimer == NULL) {
- resizeTimer = new TQTimer( this );
- connect( resizeTimer, TQT_SIGNAL(timeout()), this, TQT_SLOT(doDesktopResizeFinish()) );
- }
- resizeTimer->start( 100, TRUE ); // 100 millisecond single shot timer; should allow display switching operations to finish before hack is started
-}
-
-void LockProcess::doDesktopResizeFinish()
-{
- while (mDialogControlLock == true) {
- usleep(100000);
- }
- mDialogControlLock = true;
- if (closeCurrentWindow()) {
- TQTimer::singleShot( 0, this, SLOT(doDesktopResizeFinish()) );
- mDialogControlLock = false;
- return;
- }
- mDialogControlLock = false;
-
- // Restart the hack as the window size is now different
- if (trinity_desktop_lock_delay_screensaver_start && trinity_desktop_lock_use_system_modal_dialogs) {
- ENABLE_CONTINUOUS_LOCKDLG_DISPLAY
- if (mHackStartupEnabled) mHackDelayStartupTimer->start(mHackDelayStartupTimeout, TRUE);
- }
- else {
- if (mHackStartupEnabled == true) {
- startHack();
- }
- else {
- if (trinity_desktop_lock_use_system_modal_dialogs == true) {
- ENABLE_CONTINUOUS_LOCKDLG_DISPLAY
- if (mHackStartupEnabled) mHackDelayStartupTimer->start(mHackDelayStartupTimeout, TRUE);
- }
- else {
- startHack();
- }
- }
- }
-
- mResizingDesktopLock = false;
- mBusy = false;
-}
-
-//---------------------------------------------------------------------------
-//
-// Hide the screensaver window
-//
-void LockProcess::hideSaverWindow()
-{
- hide();
- lower();
- removeVRoot(winId());
- XDeleteProperty(tqt_xdisplay(), winId(), gXA_SCREENSAVER_VERSION);
- if ( gVRoot ) {
- unsigned long vroot_data[1] = { gVRootData };
- XChangeProperty(tqt_xdisplay(), gVRoot, gXA_VROOT, XA_WINDOW, 32,
- PropModeReplace, (unsigned char *)vroot_data, 1);
- gVRoot = 0;
- }
- XSync(tqt_xdisplay(), False);
-}
-
-//---------------------------------------------------------------------------
-static int ignoreXError(Display *, XErrorEvent *)
-{
- return 0;
-}
-
-//---------------------------------------------------------------------------
-//
-// Save the current virtual root window
-//
-void LockProcess::saveVRoot()
-{
- Window rootReturn, parentReturn, *children;
- unsigned int numChildren;
- Window root = RootWindowOfScreen(ScreenOfDisplay(tqt_xdisplay(), tqt_xscreen()));
-
- gVRoot = 0;
- gVRootData = 0;
-
- int (*oldHandler)(Display *, XErrorEvent *);
- oldHandler = XSetErrorHandler(ignoreXError);
-
- if (XQueryTree(tqt_xdisplay(), 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(tqt_xdisplay(), 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);
- }
-
- unsigned long rw = RootWindowOfScreen(ScreenOfDisplay(tqt_xdisplay(), tqt_xscreen()));
- unsigned long vroot_data[1] = { vr };
-
- Window rootReturn;
- Window parentReturn;
- Window *children = NULL;
- unsigned int numChildren;
- Window top = win;
- while (1) {
- if (XQueryTree(tqt_xdisplay(), top, &rootReturn, &parentReturn, &children, &numChildren) == 0) {
- printf("[WARNING] XQueryTree() failed!\n"); fflush(stdout);
- break;
- }
- if (children) {
- XFree((char *)children);
- }
- if (parentReturn == rw) {
- break;
- }
- else {
- top = parentReturn;
- }
- }
-
- XChangeProperty(tqt_xdisplay(), top, gXA_VROOT, XA_WINDOW, 32, PropModeReplace, (unsigned char *)vroot_data, 1);
-}
-
-//---------------------------------------------------------------------------
-//
-// Remove the virtual root property
-//
-void LockProcess::removeVRoot(Window win)
-{
- XDeleteProperty (tqt_xdisplay(), win, gXA_VROOT);
-}
-
-//---------------------------------------------------------------------------
-//
-// Grab the keyboard. Returns true on success
-//
-bool LockProcess::grabKeyboard()
-{
- int rv = XGrabKeyboard( tqt_xdisplay(), TQApplication::desktop()->winId(),
- True, GrabModeAsync, GrabModeAsync, CurrentTime );
-
- if (rv != GrabSuccess) {
- kdWarning(1204) << "LockProcess::grabKeyboard() failed: " << rv << endl;
- }
- return (rv == GrabSuccess);
-}
-
-#define GRABEVENTS ButtonPressMask | ButtonReleaseMask | PointerMotionMask | \
- EnterWindowMask | LeaveWindowMask
-
-//---------------------------------------------------------------------------
-//
-// Grab the mouse. Returns true on success
-//
-bool LockProcess::grabMouse()
-{
- HANDLE cursorHandle;
- if (mHackActive) {
- cursorHandle = TQCursor(tqblankCursor).handle();
- }
- else {
- cursorHandle = TQCursor(tqbusyCursor).handle();
- }
- int rv = XGrabPointer( tqt_xdisplay(), TQApplication::desktop()->winId(),
- True, GRABEVENTS, GrabModeAsync, GrabModeAsync, None,
- cursorHandle, CurrentTime );
-
- if (rv != GrabSuccess) {
- kdWarning(1204) << "LockProcess::grabMouse() failed: " << rv << endl;
- }
- return (rv == GrabSuccess);
-}
-
-//---------------------------------------------------------------------------
-//
-// Grab keyboard and mouse. Returns true on success.
-//
-bool LockProcess::grabInput()
-{
- XSync(tqt_xdisplay(), False);
-
- if (!grabKeyboard()) {
- usleep(100000);
- if (!grabKeyboard()) {
- return false;
- }
- }
-
-#ifndef KEEP_MOUSE_UNGRABBED
- if (!grabMouse()) {
- usleep(100000);
- if (!grabMouse()) {
- XUngrabKeyboard(tqt_xdisplay(), CurrentTime);
- return false;
- }
- }
-#endif
-
- lockXF86();
-
- return true;
-}
-
-//---------------------------------------------------------------------------
-//
-// Release mouse an keyboard grab.
-//
-void LockProcess::ungrabInput()
-{
- XUngrabKeyboard(tqt_xdisplay(), CurrentTime);
- XUngrabPointer(tqt_xdisplay(), CurrentTime);
- unlockXF86();
-}
-
-//---------------------------------------------------------------------------
-//
-// Generate requisite backing images for ARGB mode
-//
-void LockProcess::generateBackingImages()
-{
- if (argb_visual) {
- mArgbTransparentBackgroundPixmap.resize(mRootWidth, mRootHeight);
- TQPainter p;
- p.begin( &mArgbTransparentBackgroundPixmap );
- p.fillRect( 0, 0, mArgbTransparentBackgroundPixmap.width(), mArgbTransparentBackgroundPixmap.height(), TQBrush(tqRgba(0, 0, 0, 0)) );
- p.end();
- }
-}
-
-//---------------------------------------------------------------------------
-//
-// Set a fully transparent ARGB background image.
-//
-void LockProcess::setTransparentBackgroundARGB()
-{
- // eliminate nasty flicker on first show
- setBackgroundPixmap( mArgbTransparentBackgroundPixmap );
-}
-
-void LockProcess::saverReadyIfNeeded()
-{
- if (m_notifyReadyRequested) {
- // Make sure the desktop is hidden before notifying the desktop that the saver is running
- m_notifyReadyRequested = false;
- saverReady();
- fullyOnline();
- }
-}
-
-//---------------------------------------------------------------------------
-//
-// Start the screen saver.
-//
-bool LockProcess::startSaver(bool notify_ready)
-{
- if (!child_saver && !grabInput())
- {
- kdWarning(KDESKTOP_DEBUG_ID) << "LockProcess::startSaver() grabInput() failed!!!!" << endl;
- return false;
- }
- mBusy = false;
-
- // eliminate nasty flicker on first show
- setTransparentBackgroundARGB();
-
- saveVRoot();
-
- if (mParent) {
- TQSocketNotifier *notifier = new TQSocketNotifier(mParent, TQSocketNotifier::Read, TQT_TQOBJECT(this), "notifier");
- connect(notifier, TQT_SIGNAL( activated (int)), TQT_SLOT( quitSaver()));
- }
- createSaverWindow();
- move(0, 0);
- show();
-
- raise();
- XSync(tqt_xdisplay(), False);
- setVRoot( winId(), winId() );
-
- if (!trinity_desktop_lock_hide_active_windows) {
- if (m_rootPixmap) m_rootPixmap->stop();
- TQPixmap rootWinSnapShot = TQPixmap::grabWindow(TQApplication::desktop()->winId());
- slotPaintBackground(rootWinSnapShot);
- }
-
- if (((!(trinity_desktop_lock_delay_screensaver_start && trinity_desktop_lock_forced)) && (!mInSecureDialog)) && (mHackStartupEnabled || mOverrideHackStartupEnabled)) {
- if (argb_visual) {
- setTransparentBackgroundARGB();
- }
- else {
- if (backingPixmap.isNull()) {
- setBackgroundColor(black);
- }
- else {
- setBackgroundPixmap(backingPixmap);
- }
- }
- setGeometry(0, 0, mRootWidth, mRootHeight);
- erase();
-
- if (notify_ready) {
- m_notifyReadyRequested = false;
- saverReady();
- fullyOnline();
- }
- }
- else {
- if (notify_ready) {
- m_notifyReadyRequested = true;
- }
- }
-
- if (mInSecureDialog == FALSE) {
- if (trinity_desktop_lock_delay_screensaver_start && trinity_desktop_lock_forced && trinity_desktop_lock_use_system_modal_dialogs) {
- ENABLE_CONTINUOUS_LOCKDLG_DISPLAY
- if (mHackStartupEnabled) mHackDelayStartupTimer->start(mHackDelayStartupTimeout, TRUE);
- }
- else {
- if (mHackStartupEnabled || mOverrideHackStartupEnabled) {
- mOverrideHackStartupEnabled = false;
- startHack();
- }
- else {
- if (trinity_desktop_lock_use_system_modal_dialogs == true) {
- ENABLE_CONTINUOUS_LOCKDLG_DISPLAY
- if (mHackStartupEnabled) mHackDelayStartupTimer->start(mHackDelayStartupTimeout, TRUE);
- }
- else {
- startHack();
- }
- }
- }
- }
-
- return true;
-}
-
-//---------------------------------------------------------------------------
-//
-// Stop the screen saver.
-//
-void LockProcess::stopSaver()
-{
- kdDebug(KDESKTOP_DEBUG_ID) << "LockProcess: stopping saver" << endl;
- mHackProc.kill(SIGCONT);
- stopHack();
- mSuspended = false;
- hideSaverWindow();
- mVisibility = false;
- if (!child_saver) {
- if (mLocked) {
- DM().setLock( false );
- }
- ungrabInput();
- const char *out = "GOAWAY!";
- for (TQValueList<int>::ConstIterator it = child_sockets.begin(); it != child_sockets.end(); ++it) {
- if (write(*it, out, sizeof(out)) == -1) {
- // Error handler to shut up gcc warnings
- }
- }
- }
-}
-
-// private static
-TQVariant LockProcess::getConf(void *ctx, const char *key, const TQVariant &dflt)
-{
- LockProcess *that = (LockProcess *)ctx;
- TQString fkey = TQString::fromLatin1( key ) + '=';
- for (TQStringList::ConstIterator it = that->mPluginOptions.begin(); it != that->mPluginOptions.end(); ++it) {
- if ((*it).startsWith( fkey )) {
- return (*it).mid( fkey.length() );
- }
- }
- return dflt;
-}
-
-void LockProcess::cantLock( const TQString &txt)
-{
- msgBox( TQMessageBox::Critical, i18n("Will not lock the session, as unlocking would be impossible:\n") + txt );
-}
-
-#if 0 // placeholders for later
-i18n("Cannot start <i>kcheckpass</i>.");
-i18n("<i>kcheckpass</i> is unable to operate. Possibly it is not SetUID root.");
-#endif
-
-//---------------------------------------------------------------------------
-//
-// Make the screen saver password protected.
-//
-bool LockProcess::startLock()
-{
- for (TQStringList::ConstIterator it = mPlugins.begin(); it != mPlugins.end(); ++it) {
- GreeterPluginHandle plugin;
- TQString path = KLibLoader::self()->findLibrary( ((*it)[0] == '/' ? *it : "kgreet_" + *it ).latin1() );
- if (path.isEmpty()) {
- kdWarning(KDESKTOP_DEBUG_ID) << "GreeterPlugin " << *it << " does not exist" << endl;
- continue;
- }
- if (!(plugin.library = KLibLoader::self()->library( path.latin1() ))) {
- kdWarning(KDESKTOP_DEBUG_ID) << "Cannot load GreeterPlugin " << *it << " (" << path << ")" << endl;
- continue;
- }
- if (!plugin.library->hasSymbol( "kgreeterplugin_info" )) {
- kdWarning(KDESKTOP_DEBUG_ID) << "GreeterPlugin " << *it << " (" << path << ") is no valid greet widget plugin" << endl;
- plugin.library->unload();
- continue;
- }
- plugin.info = (kgreeterplugin_info*)plugin.library->symbol( "kgreeterplugin_info" );
- if (plugin.info->method && !mMethod.isEmpty() && mMethod != plugin.info->method) {
- kdDebug(KDESKTOP_DEBUG_ID) << "GreeterPlugin " << *it << " (" << path << ") serves " << plugin.info->method << ", not " << mMethod << endl;
- plugin.library->unload();
- continue;
- }
- if (!plugin.info->init( mMethod, getConf, this )) {
- kdDebug(KDESKTOP_DEBUG_ID) << "GreeterPlugin " << *it << " (" << path << ") refuses to serve " << mMethod << endl;
- plugin.library->unload();
- continue;
- }
- kdDebug(KDESKTOP_DEBUG_ID) << "GreeterPlugin " << *it << " (" << plugin.info->method << ", " << plugin.info->name << ") loaded" << endl;
- greetPlugin = plugin;
- mLocked = true;
- DM().setLock( true );
- return true;
- }
- cantLock( i18n("No appropriate greeter plugin configured.") );
- return false;
-}
-
-//---------------------------------------------------------------------------
-//
-
-void LockProcess::closeDialogAndStartHack()
-{
-#ifdef HAVE_DPMS
- if (KDesktopSettings::dpmsDependent()) {
- BOOL on;
- CARD16 state;
- if (DPMSInfo(tqt_xdisplay(), &state, &on)) {
- //kdDebug() << "checkDPMSActive " << on << " " << state << endl;
- if (DPMS_MONITOR_BLANKED(state)) {
- // Make sure saver will attempt to start again after DPMS wakeup
- // This is related to Bug 1475
- ENABLE_CONTINUOUS_LOCKDLG_DISPLAY
- if (mHackStartupEnabled) mHackDelayStartupTimer->start(mHackDelayStartupTimeout, TRUE);
- // Should not start saver here, because the DPMS check method below would turn it right back off!
- // This is related to Bug 1475
- return;
- }
- }
- }
-#endif
-
- // Close any active dialogs
- DISABLE_CONTINUOUS_LOCKDLG_DISPLAY
- mSuspended = true;
- if (closeCurrentWindow()) {
- TQTimer::singleShot( 0, this, SLOT(closeDialogAndStartHack()) );
- }
- else {
- resume(true);
- }
-}
-
-void LockProcess::repaintRootWindowIfNeeded()
-{
- if (trinity_desktop_lock_use_system_modal_dialogs) {
- if (!mHackProc.isRunning()) {
- if (argb_visual) {
- setTransparentBackgroundARGB();
- erase();
- }
- else {
- if (backingPixmap.isNull()) {
- setBackgroundColor(black);
- setGeometry(0, 0, mRootWidth, mRootHeight);
- erase();
- }
- else {
- bitBlt(this, 0, 0, &backingPixmap);
- }
- }
- }
- if (currentDialog == NULL) {
- raise();
- }
- saverReadyIfNeeded();
- }
-}
-
-bool LockProcess::startHack()
-{
- mHackActive = TRUE;
-
- if ((mEnsureVRootWindowSecurityTimer) && (!mEnsureVRootWindowSecurityTimer->isActive())) {
- mEnsureVRootWindowSecurityTimer->start(250, FALSE);
- }
-
- if (currentDialog || (!mDialogs.isEmpty())) {
- // no resuming with dialog visible or when not visible
- if (argb_visual) {
- setTransparentBackgroundARGB();
- }
- else {
- if (backingPixmap.isNull()) {
- setBackgroundColor(black);
- }
- else {
- setBackgroundPixmap(backingPixmap);
- }
- }
- setGeometry(0, 0, mRootWidth, mRootHeight);
- erase();
- saverReadyIfNeeded();
- return false;
- }
-
- setCursor( tqblankCursor );
- XChangeActivePointerGrab( tqt_xdisplay(), GRABEVENTS, TQCursor(tqblankCursor).handle(), CurrentTime);
-
- if (mSaverExec.isEmpty()) {
- return false;
- }
-
- if (mHackProc.isRunning()) {
- stopHack();
- }
-
- mHackProc.clearArguments();
-
- TQTextStream ts(&mSaverExec, IO_ReadOnly);
- TQString word;
- ts >> word;
- TQString path = TDEStandardDirs::findExe(word);
-
- if (!path.isEmpty()) {
- mHackProc << path;
-
- kdDebug(KDESKTOP_DEBUG_ID) << "Starting hack: " << path << endl;
-
- while (!ts.atEnd()) {
- ts >> word;
- if (word == "%w")
- {
- word = word.setNum(winId());
- }
- mHackProc << word;
- }
-
- if (!mForbidden) {
- if (trinity_desktop_lock_use_system_modal_dialogs) {
- // Make sure we have a nice clean display to start with!
- if (argb_visual) {
- // Signal that we want to be transparent to a black background...
- if (m_saverRootWindow) {
- XChangeProperty(tqt_xdisplay(), m_saverRootWindow, kde_wm_transparent_to_black, XA_INTEGER, 32, PropModeReplace, (unsigned char *) "TRUE", 1L);
- XClearArea(tqt_xdisplay(), m_saverRootWindow, 0, 0, 0, 0, True);
- }
- setTransparentBackgroundARGB();
- }
- else {
- if (backingPixmap.isNull()) {
- setBackgroundColor(black);
- }
- else {
- setBackgroundPixmap(backingPixmap);
- }
- }
- setGeometry(0, 0, mRootWidth, mRootHeight);
- erase();
- saverReadyIfNeeded();
- mSuspended = false;
- }
-
- XChangeActivePointerGrab( tqt_xdisplay(), GRABEVENTS, TQCursor(tqblankCursor).handle(), CurrentTime);
- if (mHackProc.start() == true) {
-#ifdef HAVE_SETPRIORITY
- setpriority(PRIO_PROCESS, mHackProc.pid(), mPriority);
-#endif
- //bitBlt(this, 0, 0, &mOriginal);
- DISABLE_CONTINUOUS_LOCKDLG_DISPLAY
- if (trinity_desktop_lock_delay_screensaver_start && trinity_desktop_lock_forced) {
- // Close any active dialogs
- if (closeCurrentWindow()) {
- TQTimer::singleShot( 0, this, SLOT(closeCurrentWindow()) );
- }
- }
- if (m_startupStatusDialog) { m_startupStatusDialog->closeSMDialog(); m_startupStatusDialog=NULL; }
- return true;
- }
- }
- else {
- // we aren't allowed to start the specified screensaver either because it didn't run for some reason
- // according to the kiosk restrictions forbid it
- usleep(100);
- TQApplication::syncX();
- if (!trinity_desktop_lock_use_system_modal_dialogs) {
- if (argb_visual) {
- setTransparentBackgroundARGB();
- }
- else {
- if (backingPixmap.isNull()) {
- setBackgroundColor(black);
- }
- else {
- setBackgroundPixmap(backingPixmap);
- }
- }
- }
- if (argb_visual) {
- setTransparentBackgroundARGB();
- erase();
- }
- else {
- if (backingPixmap.isNull()) {
- setGeometry(0, 0, mRootWidth, mRootHeight);
- erase();
- }
- else {
- bitBlt(this, 0, 0, &backingPixmap);
- }
- }
- if (trinity_desktop_lock_use_system_modal_dialogs) {
- ENABLE_CONTINUOUS_LOCKDLG_DISPLAY
- if (mHackStartupEnabled) mHackDelayStartupTimer->start(mHackDelayStartupTimeout, TRUE);
- }
- saverReadyIfNeeded();
- }
- }
-
- if (m_startupStatusDialog) {
- m_startupStatusDialog->closeSMDialog();
- m_startupStatusDialog=NULL;
- }
-
- return false;
-}
-
-//---------------------------------------------------------------------------
-//
-void LockProcess::stopHack()
-{
- if (mHackProc.isRunning()) {
- mHackProc.kill();
- if (!mHackProc.wait(10)) {
- mHackProc.kill(SIGKILL);
- }
- }
- setCursor( tqarrowCursor );
-
- mHackActive = FALSE;
-}
-
-//---------------------------------------------------------------------------
-//
-void LockProcess::hackExited(TDEProcess *)
-{
- // Hack exited while we're supposed to be saving the screen.
- // Make sure the saver window is black.
- mHackActive = FALSE;
- usleep(100);
- TQApplication::syncX();
- if (!trinity_desktop_lock_use_system_modal_dialogs) {
- if (argb_visual) {
- setTransparentBackgroundARGB();
- }
- else {
- if (backingPixmap.isNull()) {
- setBackgroundColor(black);
- }
- else {
- setBackgroundPixmap(backingPixmap);
- }
- }
- }
- if (argb_visual) {
- if (m_saverRootWindow) {
- XDeleteProperty(tqt_xdisplay(), m_saverRootWindow, kde_wm_transparent_to_black);
- XClearArea(tqt_xdisplay(), m_saverRootWindow, 0, 0, 0, 0, True);
- }
- setTransparentBackgroundARGB();
- }
- else {
- if (backingPixmap.isNull()) {
- setGeometry(0, 0, mRootWidth, mRootHeight);
- erase();
- }
- else {
- bitBlt(this, 0, 0, &backingPixmap);
- }
- }
- if (!mSuspended) {
- if (trinity_desktop_lock_use_system_modal_dialogs) {
- ENABLE_CONTINUOUS_LOCKDLG_DISPLAY
- if (mHackStartupEnabled) mHackDelayStartupTimer->start(mHackDelayStartupTimeout, TRUE);
- }
- }
- saverReadyIfNeeded();
-}
-
-void LockProcess::displayLockDialogIfNeeded()
-{
- if (m_startupStatusDialog) {
- m_startupStatusDialog->closeSMDialog();
- m_startupStatusDialog = NULL;
- }
- if (!mInSecureDialog) {
- if (trinity_desktop_lock_use_system_modal_dialogs) {
- if (!mBusy) {
- mBusy = true;
- if (mLocked) {
- if (checkPass()) {
- mClosingWindows = true;
- stopSaver();
- kapp->quit();
- }
- }
- mBusy = false;
- }
- }
- }
-}
-
-void LockProcess::suspend()
-{
- if (!mSuspended) {
- if (trinity_desktop_lock_use_system_modal_dialogs) {
- mSuspended = true;
- stopHack();
- ENABLE_CONTINUOUS_LOCKDLG_DISPLAY
- if (mHackStartupEnabled) {
- mHackDelayStartupTimer->start(mHackDelayStartupTimeout, TRUE);
- }
- }
- else {
- TQString hackStatus;
- mHackProc.kill(SIGSTOP);
- mSuspended = true;
-#if 0
- // wait for the stop signal to take effect
- while (hackStatus != "T") {
- char hackstat[8192];
- FILE *fp = fopen(TQString("/proc/%1/stat").arg(mHackProc.pid()).ascii(),"r");
- if (fp != NULL) {
- fgets (hackstat, 8192, fp);
- fclose (fp);
- }
- hackstat[8191] = 0;
- hackStatus = hackstat;
- hackStatus = hackStatus.remove(TQRegExp("(*) ", TRUE, TRUE));
- TQStringList hackStatusList = TQStringList::split(" ", hackStatus);
- hackStatus = (*(hackStatusList.at(1)));
- }
-#endif
- TQApplication::syncX();
- usleep(100000); // Allow certain bad graphics drivers (*cough* fglrx *cough*) time to actually sync up the display
- }
- TQApplication::syncX();
- mSavedScreen = TQPixmap::grabWindow( winId());
- }
-}
-
-void LockProcess::resume( bool force )
-{
- if (trinity_desktop_lock_use_sak && (mHackDelayStartupTimer->isActive() || !mHackStartupEnabled)) {
- return;
- }
- if( !force && (!mDialogs.isEmpty() || !mVisibility )) {
- // no resuming with dialog visible or when not visible
- if (trinity_desktop_lock_use_system_modal_dialogs) {
- if (argb_visual) {
- setTransparentBackgroundARGB();
- }
- else {
- if (backingPixmap.isNull()) {
- setBackgroundColor(black);
- }
- else {
- setBackgroundPixmap(backingPixmap);
- }
- }
- setGeometry(0, 0, mRootWidth, mRootHeight);
- erase();
- }
- else {
- setGeometry(0, 0, mRootWidth, mRootHeight);
- }
- saverReadyIfNeeded();
- return;
- }
- if ((mSuspended) && (mHackProc.isRunning())) {
- XForceScreenSaver(tqt_xdisplay(), ScreenSaverReset );
- bitBlt( this, 0, 0, &mSavedScreen );
- TQApplication::syncX();
- mHackProc.kill(SIGCONT);
- mSuspended = false;
- }
- else if (mSuspended && trinity_desktop_lock_use_system_modal_dialogs) {
- startHack();
- }
-}
-
-//---------------------------------------------------------------------------
-//
-// Show the password dialog
-// This is called only in the master process
-//
-bool LockProcess::checkPass()
-{
- if (!mDialogs.isEmpty()) {
- // Another dialog is already shown
- // Abort!
- return 0;
- }
- if (mInfoMessageDisplayed == false) {
- if (mAutoLogout) {
- killTimer(mAutoLogoutTimerId);
- }
-
- // Make sure we never launch the SAK or login dialog if windows are being closed down
- // Otherwise we can get stuck in an irrecoverable state where any attempt to show the login screen is instantly aborted
- if (mClosingWindows) {
- return 0;
- }
-
- if (trinity_desktop_lock_use_sak) {
- // Verify SAK operational status
- TDEProcess* checkSAKProcess = new TDEProcess;
- *checkSAKProcess << "tdmtsak" << "check";
- checkSAKProcess->start(TDEProcess::Block, TDEProcess::NoCommunication);
- int retcode = checkSAKProcess->exitStatus();
- delete checkSAKProcess;
- if (retcode != 0) {
- trinity_desktop_lock_use_sak = false;
- }
- }
-
- if (trinity_desktop_lock_use_sak) {
- // Wait for SAK press before continuing...
- SAKDlg inDlg( this );
- execDialog( &inDlg );
- if (mClosingWindows) {
- return 0;
- }
- }
-
- showVkbd();
- PasswordDlg passDlg( this, &greetPlugin, (mShowLockDateTime)?mlockDateTime:TQDateTime());
- int ret = execDialog( &passDlg );
- hideVkbd();
-
- if (mForceReject == true) {
- ret = TQDialog::Rejected;
- }
- mForceReject = false;
-
- XWindowAttributes rootAttr;
- XGetWindowAttributes(tqt_xdisplay(), RootWindow(tqt_xdisplay(),
- tqt_xscreen()), &rootAttr);
- if(( rootAttr.your_event_mask & SubstructureNotifyMask ) == 0 ) {
- kdWarning() << "ERROR: Something removed SubstructureNotifyMask from the root window!!!" << endl;
- XSelectInput( tqt_xdisplay(), tqt_xrootwin(),
- SubstructureNotifyMask | rootAttr.your_event_mask );
- }
-
- return ret == TQDialog::Accepted;
- }
- else {
- return 0;
- }
-}
-
-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 = tqt_xdisplay();
- ev.xfocus.type = FocusIn;
- ev.xfocus.window = window;
- ev.xfocus.mode = NotifyNormal;
- ev.xfocus.detail = NotifyAncestor;
- XSendEvent( tqt_xdisplay(), window, False, NoEventMask, &ev );
-}
-
-void LockProcess::resumeUnforced()
-{
- resume( false );
-}
-
-int LockProcess::execDialog( TQDialog *dlg )
-{
- currentDialog=dlg;
- dlg->adjustSize();
-
- TQRect rect = dlg->geometry();
- rect.moveCenter(TDEGlobalSettings::desktopGeometry(TQCursor::pos()).center());
- dlg->move( rect.topLeft() );
-
- if (mDialogs.isEmpty()) {
- suspend();
- XChangeActivePointerGrab( tqt_xdisplay(), GRABEVENTS, TQCursor(tqarrowCursor).handle(), CurrentTime);
- }
- mDialogs.prepend( dlg );
- fakeFocusIn( dlg->winId());
- if (trinity_desktop_lock_use_system_modal_dialogs) {
- if (backingPixmap.isNull()) {
- setGeometry(0, 0, mRootWidth, mRootHeight);
- erase();
- }
- else {
- bitBlt(this, 0, 0, &backingPixmap);
- }
- saverReadyIfNeeded();
- }
- // dlg->exec may generate BadMatch errors, so make sure they are silently ignored
- int (*oldHandler)(Display *, XErrorEvent *);
- oldHandler = XSetErrorHandler(ignoreXError);
- int rt = dlg->exec();
- XSetErrorHandler(oldHandler);
- while (mDialogControlLock == true) {
- usleep(100000);
- }
- currentDialog = NULL;
- mDialogs.remove( dlg );
- if( mDialogs.isEmpty() ) {
- HANDLE cursorHandle;
- if (mHackActive) {
- cursorHandle = TQCursor(tqblankCursor).handle();
- }
- else {
- cursorHandle = TQCursor(tqbusyCursor).handle();
- }
- XChangeActivePointerGrab( tqt_xdisplay(), GRABEVENTS, cursorHandle, CurrentTime);
- if (trinity_desktop_lock_use_system_modal_dialogs) {
- // Slight delay before screensaver resume to allow the dialog window to fully disappear
- if (hackResumeTimer == NULL) {
- hackResumeTimer = new TQTimer( this );
- connect( hackResumeTimer, TQT_SIGNAL(timeout()), this, TQT_SLOT(resumeUnforced()) );
- }
- if (mResizingDesktopLock == false) {
- hackResumeTimer->start( 10, TRUE );
- }
- }
- else {
- resume( false );
- }
- }
- else {
- fakeFocusIn( mDialogs.first()->winId());
- currentDialog = dynamic_cast<TQDialog*>(mDialogs.first());
- }
- return rt;
-}
-
-void LockProcess::slotForcePaintBackground()
-{
- TQPixmap blankPixmap(mRootWidth, mRootHeight);
- blankPixmap.fill(Qt::black);
- slotPaintBackground(blankPixmap);
- printf("[WARNING] Unable to obtain desktop wallpaper in a timely manner. High system load or possibly a TDE bug!\n"); fflush(stdout);
-}
-
-void LockProcess::slotPaintBackground(const TQPixmap &rpm)
-{
- if (argb_visual) {
- if (mEnsureScreenHiddenTimer) {
- mEnsureScreenHiddenTimer->stop();
- }
- return;
- }
-
- if (mEnsureScreenHiddenTimer) {
- mEnsureScreenHiddenTimer->stop();
- }
- else {
- mEnsureScreenHiddenTimer = new TQTimer( this );
- connect( mEnsureScreenHiddenTimer, TQT_SIGNAL(timeout()), this, TQT_SLOT(slotForcePaintBackground()) );
- }
-
- // Only remove the mask widget once the resize is 100% complete!
- if (m_maskWidget) {
- delete m_maskWidget;
- m_maskWidget = NULL;
- XSync(tqt_xdisplay(), False);
- }
-
- TQPixmap pm = rpm;
-
- if (TQPaintDevice::x11AppDepth() == 32) {
- // Remove the alpha components from the image
- TQImage correctedImage = pm.convertToImage();
- correctedImage = correctedImage.convertDepth(32);
- correctedImage.setAlphaBuffer(true);
- int w = correctedImage.width();
- int h = correctedImage.height();
- for (int y = 0; y < h; ++y) {
- TQRgb *ls = (TQRgb *)correctedImage.scanLine( y );
- for (int x = 0; x < w; ++x) {
- TQRgb l = ls[x];
- int r = int( tqRed( l ) );
- int g = int( tqGreen( l ) );
- int b = int( tqBlue( l ) );
- int a = int( 255 );
- ls[x] = tqRgba( r, g, b, a );
- }
- }
- pm.convertFromImage(correctedImage);
- }
-
- backingPixmap = pm;
- if ((trinity_desktop_lock_delay_screensaver_start && trinity_desktop_lock_forced) || (!mHackStartupEnabled)) {
- setBackgroundPixmap(backingPixmap);
- setGeometry(0, 0, mRootWidth, mRootHeight);
- erase();
- }
-}
-
-void LockProcess::preparePopup()
-{
- TQWidget *dlg = (TQWidget *)sender();
- mDialogs.prepend( dlg );
- fakeFocusIn( dlg->winId() );
-}
-
-void LockProcess::cleanupPopup()
-{
- TQWidget *dlg = (TQWidget *)sender();
- mDialogs.remove( dlg );
- if ( mDialogs.isEmpty() ) {
- fakeFocusIn( mDialogs.first()->winId() );
- }
-}
-
-void LockProcess::doFunctionKeyBroadcast() {
- // Provide a clean, pretty display switch by hiding the password dialog here
- // This does NOT work with the SAK or system modal dialogs!
- if ((!trinity_desktop_lock_use_system_modal_dialogs) && (!trinity_desktop_lock_use_sak)) {
- mBusy=true;
- TQTimer::singleShot(1000, this, TQT_SLOT(slotDeadTimePassed()));
- if (mkeyCode == XKeysymToKeycode(tqt_xdisplay(), XF86XK_Display)) {
- while (mDialogControlLock == true) {
- usleep(100000);
- }
- mDialogControlLock = true;
- currentDialog->close(); // DO NOT use closeCurrentWindow() here!
- mDialogControlLock = false;
- }
- }
-
- DCOPRef ref( "*", "MainApplication-Interface");
- ref.send("sendFakeKey", DCOPArg(mkeyCode , "unsigned int"));
-}
-
-//---------------------------------------------------------------------------
-//
-// X11 Event.
-//
-bool LockProcess::x11Event(XEvent *event)
-{
- // Allow certain very specific keypresses through
- // Key: Reason:
- // XF86Display You need to be able to see the screen when unlocking your computer
- // XF86AudioMute Would be nice to be able to shut your computer up in an emergency while it is locked
- // XF86AudioRaiseVolume Ditto
- // XF86AudioLowerVolume Ditto
- // XF86XK_PowerOff If someone has access to the power button, they can hard power off the machine anyway
- // XF86XK_Sleep Ditto
- // XF86XK_Suspend Ditto
- // XF86XK_Hibernate Ditto
-
- //if ((event->type == KeyPress) || (event->type == KeyRelease)) {
- if (event->type == KeyPress) {
- // Multimedia keys
- if ((event->xkey.keycode == XKeysymToKeycode(event->xkey.display, XF86XK_Display)) || \
- (event->xkey.keycode == XKeysymToKeycode(event->xkey.display, XF86XK_AudioMute)) || \
- (event->xkey.keycode == XKeysymToKeycode(event->xkey.display, XF86XK_AudioRaiseVolume)) || \
- (event->xkey.keycode == XKeysymToKeycode(event->xkey.display, XF86XK_AudioLowerVolume))) {
- mkeyCode = event->xkey.keycode;
- TQTimer::singleShot( 100, this, TQT_SLOT(doFunctionKeyBroadcast()) );
- return true;
- }
- // ACPI power keys
- if ((event->xkey.keycode == XKeysymToKeycode(event->xkey.display, XF86XK_PowerOff)) || \
- (event->xkey.keycode == XKeysymToKeycode(event->xkey.display, XF86XK_Sleep)) || \
- (event->xkey.keycode == XKeysymToKeycode(event->xkey.display, XF86XK_Suspend)) || \
- (event->xkey.keycode == XKeysymToKeycode(event->xkey.display, XF86XK_Hibernate))) {
- mkeyCode = event->xkey.keycode;
- TQTimer::singleShot( 100, this, TQT_SLOT(doFunctionKeyBroadcast()) );
- return true;
- }
- }
-
- switch (event->type)
- {
- case ButtonPress:
- case MotionNotify:
- case ButtonRelease:
- if( forwardVkbdEvent( event )) {
- return true; // filter out
- }
- // fall through
- case KeyPress:
- if ((mHackDelayStartupTimer) && (mHackDelayStartupTimer->isActive())) {
- if (mHackStartupEnabled) mHackDelayStartupTimer->start(mHackDelayStartupTimeout, TRUE);
- }
- if (mBusy || !mDialogs.isEmpty()) {
- break;
- }
- mBusy = true;
- if (trinity_desktop_lock_delay_screensaver_start) {
- if (mLocked) {
- ENABLE_CONTINUOUS_LOCKDLG_DISPLAY
- if (mHackStartupEnabled) {
- mHackDelayStartupTimer->start(mHackDelayStartupTimeout, TRUE);
- }
- }
- if ((!mLocked) && (!mInSecureDialog)) {
- stopSaver();
- kapp->quit();
- }
- if (mAutoLogout) {
- // we need to restart the auto logout countdown
- killTimer(mAutoLogoutTimerId);
- mAutoLogoutTimerId = startTimer(mAutoLogoutTimeout);
- }
- }
- else {
- if (!mLocked || checkPass()) {
- mClosingWindows = true;
- stopSaver();
- kapp->quit();
- }
- else if (mAutoLogout) {
- // we need to restart the auto logout countdown
- killTimer(mAutoLogoutTimerId);
- mAutoLogoutTimerId = startTimer(mAutoLogoutTimeout);
- }
- }
- mBusy = false;
- return true;
-
- case VisibilityNotify:
- if( event->xvisibility.window == winId()) {
- // mVisibility == false means the screensaver is not visible at all
- // e.g. when switched to text console
- mVisibility = !(event->xvisibility.state == VisibilityFullyObscured);
- if(!mVisibility) {
- mSuspendTimer.start(2000, true);
- }
- else {
- mSuspendTimer.stop();
- if (mResizingDesktopLock == false) {
- if (trinity_desktop_lock_delay_screensaver_start && trinity_desktop_lock_forced && trinity_desktop_lock_use_system_modal_dialogs) {
- // Do nothing
- }
- else {
- if (mHackStartupEnabled == true) {
- resume( false );
- }
- else {
- if (trinity_desktop_lock_use_system_modal_dialogs == true) {
- ENABLE_CONTINUOUS_LOCKDLG_DISPLAY
- if (mHackStartupEnabled) mHackDelayStartupTimer->start(mHackDelayStartupTimeout, TRUE);
- }
- else {
- resume( false );
- }
- }
- }
- }
- }
- if (event->xvisibility.state != VisibilityUnobscured) {
- stayOnTop();
- }
- }
- break;
-
- case ConfigureNotify: // from SubstructureNotifyMask on the root window
- if(event->xconfigure.event == tqt_xrootwin()) {
- stayOnTop();
- }
- for( TQValueList< VkbdWindow >::Iterator it = mVkbdWindows.begin();
- it != mVkbdWindows.end();
- ++it ) {
- if( (*it).id == event->xconfigure.window ) {
- (*it).rect = TQRect( event->xconfigure.x, event->xconfigure.y,
- event->xconfigure.width, event->xconfigure.height );
- break;
- }
- }
- break;
- case MapNotify: // from SubstructureNotifyMask on the root window
- windowAdded( event->xmap.window, false );
- if( event->xmap.event == tqt_xrootwin()) {
- stayOnTop();
- }
- break;
- case DestroyNotify:
- for( TQValueList< VkbdWindow >::Iterator it = mVkbdWindows.begin(); it != mVkbdWindows.end(); ++it ) {
- if( (*it).id == event->xdestroywindow.window ) {
- mVkbdWindows.remove( it );
- break;
- }
- }
- 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() && ( event->type == KeyPress || event->type == KeyRelease)
- && event->xkey.window != mDialogs.first()->winId()) {
- XEvent ev2 = *event;
- ev2.xkey.window = ev2.xkey.subwindow = mDialogs.first()->winId();
- tqApp->x11ProcessEvent( &ev2 );
- return true;
- }
-
- return false;
-}
-
-void LockProcess::stayOnTop()
-{
- if(!mDialogs.isEmpty() || !mVkbdWindows.isEmpty()) {
- // 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
- if( !mVkbdWindows.isEmpty()) {
- XRaiseWindow( tqt_xdisplay(), mVkbdWindows.first().id );
- }
- else {
- XRaiseWindow( tqt_xdisplay(), mDialogs.first()->winId()); // raise topmost
- }
- // and stack others below it
- Window* stack = new Window[ mDialogs.count() + mVkbdWindows.count() + 1 ];
- int count = 0;
- for( TQValueList< VkbdWindow >::ConstIterator it = mVkbdWindows.begin(); it != mVkbdWindows.end(); ++it ) {
- stack[ count++ ] = (*it).id;
- }
- for( TQValueList< TQWidget* >::ConstIterator it = mDialogs.begin(); it != mDialogs.end(); ++it ) {
- stack[ count++ ] = (*it)->winId();
- }
- stack[ count++ ] = winId();
- XRestackWindows( x11Display(), stack, count );
- delete[] stack;
- }
- else {
- XRaiseWindow(tqt_xdisplay(), winId());
- }
-}
-
-void LockProcess::checkDPMSActive()
-{
-#ifdef HAVE_DPMS
- if (KDesktopSettings::dpmsDependent()) {
- BOOL on;
- CARD16 state;
- if (DPMSInfo(tqt_xdisplay(), &state, &on)) {
- //kdDebug() << "checkDPMSActive " << on << " " << state << endl;
- if (DPMS_MONITOR_BLANKED(state)) {
- suspend();
- }
- else if (mSuspended) {
- if (mResizingDesktopLock == false) {
- resume( true );
- }
- }
- }
- }
-#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 kdesktop_lock 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;
- if( XF86MiscQueryVersion( tqt_xdisplay(), &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( tqt_xdisplay(), False ) != MiscExtGrabStateSuccess ) {
- return;
- }
- // success
- mRestoreXF86Lock = true;
-}
-
-void LockProcess::unlockXF86()
-{
- if( can_do_xf86_lock != Yes ) {
- return;
- }
- if( !mRestoreXF86Lock ) {
- return;
- }
- XF86MiscSetGrabKeysState( tqt_xdisplay(), True );
- mRestoreXF86Lock = false;
-}
-#else
-void LockProcess::lockXF86()
-{
- //
-}
-
-void LockProcess::unlockXF86()
-{
- //
-}
-#endif
-
-void LockProcess::msgBox( TQMessageBox::Icon type, const TQString &txt )
-{
- TQDialog box( 0, "messagebox", true, (trinity_desktop_lock_use_system_modal_dialogs?((WFlags)WStyle_StaysOnTop):((WFlags)WX11BypassWM)) );
- if (trinity_desktop_lock_use_system_modal_dialogs) {
- // Signal that we do not want any window controls to be shown at all
- XChangeProperty(tqt_xdisplay(), box.winId(), kde_wm_system_modal_notification, XA_INTEGER, 32, PropModeReplace, (unsigned char *) "TRUE", 1L);
- }
- box.setCaption(i18n("Authentication Subsystem Notice"));
- TQFrame *winFrame = new TQFrame( &box );
- if (trinity_desktop_lock_use_system_modal_dialogs) {
- winFrame->setFrameStyle( TQFrame::NoFrame );
- }
- else {
- winFrame->setFrameStyle( TQFrame::WinPanel | TQFrame::Raised );
- }
- winFrame->setLineWidth( 2 );
- TQLabel *label1 = new TQLabel( winFrame );
- label1->setPixmap( TQMessageBox::standardIcon( type ) );
- TQLabel *label2 = new TQLabel( txt, winFrame );
- KPushButton *button = new KPushButton( KStdGuiItem::ok(), winFrame );
- button->setDefault( true );
- button->setSizePolicy( TQSizePolicy( TQSizePolicy::Preferred, TQSizePolicy::Preferred ) );
- connect( button, TQT_SIGNAL( clicked() ), &box, TQT_SLOT( accept() ) );
-
- TQVBoxLayout *vbox = new TQVBoxLayout( &box );
- vbox->addWidget( winFrame );
- TQGridLayout *grid = new TQGridLayout( winFrame, 2, 2, 10 );
- grid->addWidget( label1, 0, 0, Qt::AlignCenter );
- grid->addWidget( label2, 0, 1, Qt::AlignCenter );
- grid->addMultiCellWidget( button, 1,1, 0,1, Qt::AlignCenter );
-
- execDialog( &box );
-}
-
-static int run_vkbd = -1;
-void LockProcess::showVkbd()
-{
- if( run_vkbd == - 1 ) {
-#ifdef WITH_HAL
- int status = system( "hal-find-by-property --key system.formfactor.subtype --string tabletpc" );
-// status = 0; // enable for testing
- run_vkbd = ( WIFEXITED( status ) && WEXITSTATUS( status ) == 0 && !TDEStandardDirs::findExe( "xvkbd" ).isEmpty()) ? 1 : 0;
-#else // WITH_HAL
- run_vkbd = (!TDEStandardDirs::findExe( "xvkbd" ).isEmpty());
-#endif // WITH_HAL
- }
- if( run_vkbd ) {
- mVkbdWindows.clear();
- mVkbdLastEventWindow = None;
- mKWinModule = new KWinModule( NULL, KWinModule::INFO_WINDOWS );
- connect( mKWinModule, TQT_SIGNAL( windowAdded( WId )), TQT_SLOT( windowAdded( WId )));
- mVkbdProcess = new TDEProcess;
- *mVkbdProcess << "xvkbd" << "-compact" << "-geometry" << "-0-0" << "-xdm";
- mVkbdProcess->start();
- }
-}
-
-void LockProcess::hideVkbd()
-{
- if( mVkbdProcess != NULL ) {
- mVkbdProcess->kill();
- delete mVkbdProcess;
- mVkbdProcess = NULL;
- delete mKWinModule;
- mKWinModule = NULL;
- mVkbdWindows.clear();
- }
-}
-
-void LockProcess::windowAdded( WId w )
-{
- windowAdded( w, true );
-}
-
-void LockProcess::windowAdded( WId w, bool managed )
-{
- // KWin::windowInfo may generate BadWindow errors, so make sure they are silently ignored
- int (*oldHandler)(Display *, XErrorEvent *);
- oldHandler = XSetErrorHandler(ignoreXError);
- KWin::WindowInfo info = KWin::windowInfo( w, 0, NET::WM2WindowClass );
- XSetErrorHandler(oldHandler);
-
- if( info.windowClassClass().lower() != "xvkbd" ) {
- return;
- }
- // Unmanaged windows (i.e. popups) don't currently work anyway, since they
- // don't have WM_CLASS set anyway. I could perhaps try tricks with X id
- // ranges if really needed.
- if( managed ) {
- // withdraw the window, wait for it to be withdrawn, reparent it directly
- // to root at the right position
- XWithdrawWindow( tqt_xdisplay(), w, tqt_xscreen());
- for(;;) {
- Atom type;
- int format;
- unsigned long length, after;
- unsigned char *data;
- int r = XGetWindowProperty( tqt_xdisplay(), w, tqt_wm_state, 0, 2,
- false, AnyPropertyType, &type, &format,
- &length, &after, &data );
- bool withdrawn = true;
- if ( r == Success && data && format == 32 ) {
- TQ_UINT32 *wstate = (TQ_UINT32*)data;
- withdrawn = (*wstate == WithdrawnState );
- XFree( (char *)data );
- }
- if( withdrawn ) {
- break;
- }
- }
- }
- XSelectInput( tqt_xdisplay(), w, StructureNotifyMask );
- XWindowAttributes attr_geom;
- if( !XGetWindowAttributes( tqt_xdisplay(), w, &attr_geom )) {
- return;
- }
- int x = XDisplayWidth( tqt_xdisplay(), tqt_xscreen()) - attr_geom.width;
- int y = XDisplayHeight( tqt_xdisplay(), tqt_xscreen()) - attr_geom.height;
- if( managed ) {
- XSetWindowAttributes attr;
- if (!trinity_desktop_lock_use_system_modal_dialogs) {
- attr.override_redirect = True;
- XChangeWindowAttributes( tqt_xdisplay(), w, CWOverrideRedirect, &attr );
- }
- XReparentWindow( tqt_xdisplay(), w, tqt_xrootwin(), x, y );
- XMapWindow( tqt_xdisplay(), w );
- }
- VkbdWindow data;
- data.id = w;
- data.rect = TQRect( x, y, attr_geom.width, attr_geom.height );
- mVkbdWindows.prepend( data );
-}
-
-bool LockProcess::forwardVkbdEvent( XEvent* event )
-{
- if( mVkbdProcess == NULL ) {
- return false;
- }
- TQPoint pos;
- Time time;
- switch( event->type )
- {
- case ButtonPress:
- case ButtonRelease:
- pos = TQPoint( event->xbutton.x, event->xbutton.y );
- time = event->xbutton.time;
- break;
- case MotionNotify:
- pos = TQPoint( event->xmotion.x, event->xmotion.y );
- time = event->xmotion.time;
- break;
- default:
- return false;
- }
- // vkbd windows are kept topmost, so just find the first one in the position
- for( TQValueList< VkbdWindow >::ConstIterator it = mVkbdWindows.begin(); it != mVkbdWindows.end(); ++it ) {
- if( TQT_TQRECT_OBJECT((*it).rect).contains( pos )) {
- // Find the subwindow where the event should actually go.
- // Not exactly cheap in the number of X roundtrips but oh well.
- Window window = (*it).id;
- Window root, child;
- int root_x, root_y, x, y;
- unsigned int mask;
- for(;;) {
- if( !XQueryPointer( tqt_xdisplay(), window, &root, &child, &root_x, &root_y, &x, &y, &mask )) {
- return false;
- }
- if( child == None ) {
- break;
- }
- window = child;
- }
- switch( event->type )
- {
- case ButtonPress:
- case ButtonRelease:
- event->xbutton.x = x;
- event->xbutton.y = y;
- event->xbutton.subwindow = None;
- break;
- case MotionNotify:
- event->xmotion.x = x;
- event->xmotion.y = y;
- event->xmotion.subwindow = None;
- break;
- }
- event->xany.window = window;
- sendVkbdFocusInOut( window, time );
- XSendEvent( tqt_xdisplay(), window, False, 0, event );
- return true;
- }
- }
- sendVkbdFocusInOut( None, time );
- return false;
-}
-
-// Fake EnterNotify/LeaveNotify events as the mouse moves. They're not sent by X
-// because of the grab and having them makes xvkbd highlight the buttons (but
-// not needed otherwise it seems).
-void LockProcess::sendVkbdFocusInOut( WId window, Time t )
-{
- if( mVkbdLastEventWindow == window ) {
- return;
- }
- if( mVkbdLastEventWindow != None ) {
- XEvent e;
- e.xcrossing.type = LeaveNotify;
- e.xcrossing.display = tqt_xdisplay();
- e.xcrossing.window = mVkbdLastEventWindow;
- e.xcrossing.root = tqt_xrootwin();
- e.xcrossing.subwindow = None;
- e.xcrossing.time = t;
- e.xcrossing.x = 0;
- e.xcrossing.y = 0;
- e.xcrossing.x_root = -1;
- e.xcrossing.y_root = -1;
- e.xcrossing.mode = NotifyNormal;
- e.xcrossing.detail = NotifyAncestor;
- e.xcrossing.same_screen = True;
- e.xcrossing.focus = False;
- e.xcrossing.state = 0;
- XSendEvent( tqt_xdisplay(), mVkbdLastEventWindow, False, 0, &e );
- }
- mVkbdLastEventWindow = window;
- if( mVkbdLastEventWindow != None ) {
- XEvent e;
- e.xcrossing.type = EnterNotify;
- e.xcrossing.display = tqt_xdisplay();
- e.xcrossing.window = mVkbdLastEventWindow;
- e.xcrossing.root = tqt_xrootwin();
- e.xcrossing.subwindow = None;
- e.xcrossing.time = t;
- e.xcrossing.x = 0;
- e.xcrossing.y = 0;
- e.xcrossing.x_root = 0;
- e.xcrossing.y_root = 0;
- e.xcrossing.mode = NotifyNormal;
- e.xcrossing.detail = NotifyAncestor;
- e.xcrossing.same_screen = True;
- e.xcrossing.focus = False;
- e.xcrossing.state = 0;
- XSendEvent( tqt_xdisplay(), mVkbdLastEventWindow, False, 0, &e );
- }
-}
-
-void LockProcess::slotMouseActivity(XEvent *event)
-{
- bool inFrame = 0;
- bool inDialog = 0;
- XButtonEvent *be = (XButtonEvent *) event;
- XMotionEvent *me = (XMotionEvent *) event;
- if ((event->type == ButtonPress) && (!mDialogs.isEmpty())) {
- // Get geometry including window frame/titlebar
- TQRect fgeom = mDialogs.first()->frameGeometry();
- TQRect wgeom = mDialogs.first()->geometry();
-
- if (((be->x_root > fgeom.x()) && (be->y_root > fgeom.y())) && ((be->x_root < (fgeom.x()+fgeom.width())) && (be->y_root < (fgeom.y()+fgeom.height())))) {
- inFrame = 1;
- }
- if (((be->x_root > wgeom.x()) && (be->y_root > wgeom.y())) && ((be->x_root < (wgeom.x()+wgeom.width())) && (be->y_root < (wgeom.y()+wgeom.height())))) {
- inDialog = 1;
- }
-
- // Clicked inside dialog; set focus
- if (inFrame == TRUE) {
- WId window = mDialogs.first()->winId();
- XSetInputFocus(tqt_xdisplay(), window, RevertToParent, CurrentTime);
- fakeFocusIn(window);
- // Why this needs to be repeated I have no idea...
- XSetInputFocus(tqt_xdisplay(), window, RevertToParent, CurrentTime);
- fakeFocusIn(window);
- }
-
- // Clicked inside window handle (or border); drag window
- if ((inFrame == TRUE) && (inDialog == FALSE)) {
- TQPoint oldPoint = mDialogs.first()->pos();
- m_mouseDown = 1;
- m_dialogPrevX = oldPoint.x();
- m_dialogPrevY = oldPoint.y();
- m_mousePrevX = be->x_root;
- m_mousePrevY = be->y_root;
- XChangeActivePointerGrab( tqt_xdisplay(), GRABEVENTS, TQCursor(tqsizeAllCursor).handle(), CurrentTime);
- }
- }
-
- // Drag the window...
- if (event->type == MotionNotify) {
- if (m_mouseDown == TRUE) {
- int deltaX = me->x_root - m_mousePrevX;
- int deltaY = me->y_root - m_mousePrevY;
- m_dialogPrevX = m_dialogPrevX + deltaX;
- m_dialogPrevY = m_dialogPrevY + deltaY;
- if (!mDialogs.isEmpty()) mDialogs.first()->move(m_dialogPrevX, m_dialogPrevY);
-
- m_mousePrevX = me->x_root;
- m_mousePrevY = me->y_root;
- }
- }
-
- if (event->type == ButtonRelease) {
- m_mouseDown = 0;
- XChangeActivePointerGrab( tqt_xdisplay(), GRABEVENTS, TQCursor(tqarrowCursor).handle(), CurrentTime);
- }
-}
-
-void LockProcess::processInputPipeCommand(TQString inputcommand) {
- TQCString command(inputcommand.ascii());
- TQString to_display;
- TQString pin_entry;
-
- if (command[0] == 'C') {
- while (mDialogControlLock == true) usleep(100000);
- mDialogControlLock = true;
- if (mInfoMessageDisplayed || !trinity_desktop_lock_use_system_modal_dialogs) {
- if (currentDialog != NULL) {
- mForceReject = true;
- closeCurrentWindow();
- }
- }
- mClosingWindows = false;
- mInfoMessageDisplayed = false;
- mDialogControlLock = false;
- }
- if (command[0] == 'T') {
- to_display = command.data();
- to_display = to_display.remove(0,1);
- // Lock out password dialogs and close any active dialog
- while (mDialogControlLock == true) usleep(100000);
- mDialogControlLock = true;
- if (mInfoMessageDisplayed || !trinity_desktop_lock_use_system_modal_dialogs) {
- if (currentDialog != NULL) {
- mForceReject = true;
- closeCurrentWindow();
- }
- }
- mInfoMessageDisplayed = true;
- mDialogControlLock = false;
- // Display info message dialog
- InfoDlg inDlg( this );
- inDlg.updateLabel(to_display);
- inDlg.setUnlockIcon();
- execDialog( &inDlg );
- mForceReject = false;
- mClosingWindows = false;
- return;
- }
- if ((command[0] == 'E') || (command[0] == 'W') || (command[0] == 'I') || (command[0] == 'K')) {
- to_display = command.data();
- to_display = to_display.remove(0,1);
- // Lock out password dialogs and close any active dialog
- while (mDialogControlLock == true) usleep(100000);
- mDialogControlLock = true;
- if (mInfoMessageDisplayed || !trinity_desktop_lock_use_system_modal_dialogs) {
- if (currentDialog != NULL) {
- mForceReject = true;
- closeCurrentWindow();
- }
- }
- mInfoMessageDisplayed = true;
- mDialogControlLock = false;
- // Display info message dialog
- InfoDlg inDlg( this );
- inDlg.updateLabel(to_display);
- if (command[0] == 'K') inDlg.setKDEIcon();
- if (command[0] == 'I') inDlg.setInfoIcon();
- if (command[0] == 'W') inDlg.setWarningIcon();
- if (command[0] == 'E') inDlg.setErrorIcon();
- execDialog( &inDlg );
- mForceReject = false;
- mClosingWindows = false;
- return;
- }
- if (command[0] == 'Q') {
- to_display = command.data();
- to_display = to_display.remove(0,1);
- // Lock out password dialogs and close any active dialog
- while (mDialogControlLock == true) usleep(100000);
- mDialogControlLock = true;
- if (mInfoMessageDisplayed || !trinity_desktop_lock_use_system_modal_dialogs) {
- if (currentDialog != NULL) {
- mForceReject = true;
- closeCurrentWindow();
- }
- }
- mInfoMessageDisplayed = true;
- mDialogControlLock = false;
- // Display query dialog
- QueryDlg qryDlg( this );
- qryDlg.updateLabel(to_display);
- qryDlg.setUnlockIcon();
- mForceReject = false;
- execDialog( &qryDlg );
- if (mForceReject == false) {
- pin_entry = qryDlg.getEntry();
- mInfoMessageDisplayed=false;
- if (mPipeOpen_out == true) {
- TQCString pin_entry_local8 = pin_entry.local8Bit(); // local 8 bit length may differ from TQString length
- if (write(mPipe_fd_out, pin_entry_local8.data(), pin_entry_local8.length()+1) == -1) {
- // Error handler to shut up gcc warnings
- }
- if (write(mPipe_fd_out, "\n\r", 3) == -1) {
- // Error handler to shut up gcc warnings
- }
- }
- }
- mForceReject = false;
- mClosingWindows = false;
- return;
- }
-}
-
-void LockProcess::cryptographicCardInserted(TDECryptographicCardDevice* cdevice) {
- TQString login_name = TQString::null;
- X509CertificatePtrList certList = cdevice->cardX509Certificates();
- if (certList.count() > 0) {
- KSSLCertificate* card_cert = NULL;
- card_cert = KSSLCertificate::fromX509(certList[0]);
- TQStringList cert_subject_parts = TQStringList::split("/", card_cert->getSubject(), false);
- for (TQStringList::Iterator it = cert_subject_parts.begin(); it != cert_subject_parts.end(); ++it ) {
- TQString lcpart = (*it).lower();
- if (lcpart.startsWith("cn=")) {
- login_name = lcpart.right(lcpart.length() - strlen("cn="));
- }
- }
- delete card_cert;
- }
-
- if (login_name != "") {
- KUser user;
- if (login_name == user.loginName()) {
- // Pass login to the PAM stack...
- m_loginCardDevice = cdevice;
- if (dynamic_cast<SAKDlg*>(currentDialog)) {
- dynamic_cast<SAKDlg*>(currentDialog)->closeDialogForced();
- TQTimer::singleShot(0, this, SLOT(signalPassDlgToAttemptCardLogin()));
- }
- else if (dynamic_cast<SecureDlg*>(currentDialog)) {
- dynamic_cast<SecureDlg*>(currentDialog)->closeDialogForced();
- TQTimer::singleShot(0, this, SLOT(signalPassDlgToAttemptCardLogin()));
- }
- else if (dynamic_cast<PasswordDlg*>(currentDialog)) {
- signalPassDlgToAttemptCardLogin();
- }
- }
- }
-}
-
-void LockProcess::cryptographicCardRemoved(TDECryptographicCardDevice* cdevice) {
- PasswordDlg* passDlg = dynamic_cast<PasswordDlg*>(currentDialog);
- if (passDlg) {
- passDlg->resetCardLogin();
- }
- else {
- m_loginCardDevice = NULL;
- TQTimer::singleShot(0, this, SLOT(signalPassDlgToAttemptCardAbort()));
- }
-}
-
-void LockProcess::signalPassDlgToAttemptCardLogin() {
- PasswordDlg* passDlg = dynamic_cast<PasswordDlg*>(currentDialog);
- if (passDlg && m_loginCardDevice) {
- passDlg->attemptCardLogin();
- }
- else {
- if (currentDialog && m_loginCardDevice) {
- // Try again later
- TQTimer::singleShot(0, this, SLOT(signalPassDlgToAttemptCardLogin()));
- }
- }
-}
-
-void LockProcess::signalPassDlgToAttemptCardAbort() {
- PasswordDlg* passDlg = dynamic_cast<PasswordDlg*>(currentDialog);
- if (passDlg) {
- passDlg->resetCardLogin();
- }
- else {
- if (currentDialog) {
- // Try again later
- TQTimer::singleShot(0, this, SLOT(signalPassDlgToAttemptCardAbort()));
- }
- }
-}
-
-void LockProcess::cryptographicCardPinRequested(TQString prompt, TDECryptographicCardDevice* cdevice) {
- TQCString password;
- TQString pin_entry;
-
- QueryDlg qryDlg(this);
- qryDlg.updateLabel(prompt);
- qryDlg.setUnlockIcon();
- mForceReject = false;
- execDialog(&qryDlg);
- if (mForceReject == false) {
- pin_entry = qryDlg.getEntry();
- cdevice->setProvidedPin(pin_entry);
- }
- else {
- cdevice->setProvidedPin(TQString::null);
- }
-}
-
-TDECryptographicCardDevice* LockProcess::cryptographicCardDevice() {
- return m_loginCardDevice;
-}
-
-void LockProcess::fullyOnline() {
- if (!mFullyOnlineSent) {
- if (kdesktop_pid > 0) {
- if (kill(kdesktop_pid, SIGUSR2) < 0) {
- // The controlling kdesktop process probably died. Commit suicide...
- // Exit uncleanly
- exit(1);
- }
- else {
- mFullyOnlineSent = true;
- }
- }
- }
-}
-
-void LockProcess::saverReady() {
- DCOPRef ref( "kdesktop", "KScreensaverIface");
- ref.send( "saverLockReady" );
-}
-
-//===========================================================================
-//
-// Control pipe handler
-//
-ControlPipeHandlerObject::ControlPipeHandlerObject() : TQObject() {
- mParent = NULL;
- mRunning = false;
- mTerminate = false;
- mThreadID = 0L;
-}
-
-ControlPipeHandlerObject::~ControlPipeHandlerObject() {
- //
-}
-
-void ControlPipeHandlerObject::run(void) {
- mThreadID = pthread_self();
- mRunning = true;
-
- sigset_t new_mask;
- sigemptyset(&new_mask);
- sigaddset(&new_mask, SIGUSR1);
-
- // Unblock SIGUSR1
- pthread_sigmask(SIG_UNBLOCK, &new_mask, NULL);
-
- int display_number = atoi(TQString(XDisplayString(tqt_xdisplay())).replace(":","").ascii());
-
- if (display_number < 0) {
- printf("[kdesktop_lock] Warning: unable to create control socket. Interactive logon modules may not function properly.\n");
- mRunning = false;
- TQApplication::eventLoop()->exit(-1);
- return;
- }
-
- char fifo_file[PATH_MAX];
- char fifo_file_out[PATH_MAX];
- snprintf(fifo_file, PATH_MAX, FIFO_FILE, display_number);
- snprintf(fifo_file_out, PATH_MAX, FIFO_FILE_OUT, display_number);
-
- /* Create the FIFOs if they do not exist */
- umask(0);
- mkdir(FIFO_DIR,0644);
- mknod(fifo_file, S_IFIFO|0644, 0);
- chmod(fifo_file, 0644);
-
- mParent->mPipe_fd = open(fifo_file, O_RDONLY | O_NONBLOCK);
- if (mParent->mPipe_fd > -1) {
- mParent->mPipeOpen = true;
- }
-
- mknod(fifo_file_out, S_IFIFO|0600, 0);
- chmod(fifo_file_out, 0600);
-
- mParent->mPipe_fd_out = open(fifo_file_out, O_RDWR | O_NONBLOCK);
- if (mParent->mPipe_fd_out > -1) {
- mParent->mPipeOpen_out = true;
- }
-
- if (!mParent->mPipeOpen) {
- printf("[kdesktop_lock] Warning: unable to create control socket '%s'. Interactive logon modules may not function properly.\n", fifo_file);
- mRunning = false;
- TQApplication::eventLoop()->exit(-1);
- return;
- }
-
- int numread;
- int retval;
- fd_set rfds;
- FD_ZERO(&rfds);
- FD_SET(mParent->mPipe_fd, &rfds);
- TQByteArray readbuf(128);
-
- while (mParent->mPipeOpen && !mTerminate) {
- TQString inputcommand = "";
-
- // Wait for mParent->mPipe_fd to receive input
- retval = select(mParent->mPipe_fd + 1, &rfds, NULL, NULL, NULL);
- if (retval < 0) {
- // ERROR
- }
- else if (retval) {
- // New data is available
- readbuf[0]=' ';
- numread = read(mParent->mPipe_fd, readbuf.data(), 128);
- readbuf[numread] = 0;
- if (numread > 0) {
- inputcommand += readbuf;
- emit processCommand(inputcommand);
- }
- }
- }
-
- mRunning = false;
- TQApplication::eventLoop()->exit(0);
- return;
-}
-
-void ControlPipeHandlerObject::terminateThread() {
- if (mRunning) {
- mTerminate = true;
- pthread_kill(mThreadID, SIGUSR1);
- }
-}
-
-#include "lockprocess.moc"