From c97349f53a15c930ce1f5f53ef37c44318a1981a Mon Sep 17 00:00:00 2001 From: tpearson Date: Wed, 7 Apr 2010 04:18:36 +0000 Subject: Added initial support for pipe-based root-only control of all running kdesktop_lock processes Right now this allows a background authentication process to display pop-up status messages on all screens git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdebase@1111946 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- kdesktop/lock/Makefile.am | 4 +- kdesktop/lock/infodlg.cc | 117 +++++++++++++++++++++++++++++++++++++ kdesktop/lock/infodlg.h | 51 +++++++++++++++++ kdesktop/lock/lockprocess.cc | 133 ++++++++++++++++++++++++++++++++++++++----- kdesktop/lock/lockprocess.h | 13 ++++- 5 files changed, 301 insertions(+), 17 deletions(-) create mode 100644 kdesktop/lock/infodlg.cc create mode 100644 kdesktop/lock/infodlg.h diff --git a/kdesktop/lock/Makefile.am b/kdesktop/lock/Makefile.am index 4af8d4fae..e9963ffab 100644 --- a/kdesktop/lock/Makefile.am +++ b/kdesktop/lock/Makefile.am @@ -8,9 +8,9 @@ kdesktop_lock_LDADD = ../libkdesktopsettings.la ../../kdmlib/libdmctl.la $(LI bin_PROGRAMS = kdesktop_lock -kdesktop_lock_SOURCES = lockprocess.cc lockdlg.cc autologout.cc main.cc +kdesktop_lock_SOURCES = lockprocess.cc lockdlg.cc infodlg.cc autologout.cc main.cc -noinst_HEADERS = lockprocess.h lockdlg.h autologout.h main.h +noinst_HEADERS = lockprocess.h lockdlg.h infodlg.h autologout.h main.h METASOURCES = AUTO diff --git a/kdesktop/lock/infodlg.cc b/kdesktop/lock/infodlg.cc new file mode 100644 index 000000000..86351dd7b --- /dev/null +++ b/kdesktop/lock/infodlg.cc @@ -0,0 +1,117 @@ +//=========================================================================== +// +// This file is part of the KDE project +// +// Copyright (c) 2010 Timothy Pearson + +#include + +#include "infodlg.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 + +#ifndef AF_LOCAL +# define AF_LOCAL AF_UNIX +#endif + +//=========================================================================== +// +// Simple dialog for displaying an unlock status or recurring error message +// +InfoDlg::InfoDlg(LockProcess *parent) + : QDialog(parent, "information dialog", true, WX11BypassWM), + mUnlockingFailed(false) +{ + frame = new QFrame( this ); + frame->setFrameStyle( QFrame::Panel | QFrame::Raised ); + frame->setLineWidth( 2 ); + + mpixLabel = new QLabel( frame, "pixlabel" ); + mpixLabel->setPixmap(DesktopIcon("unlock")); + + KUser user; + + mStatusLabel = new QLabel( " ", frame ); + mStatusLabel->setAlignment( QLabel::AlignCenter ); + + QVBoxLayout *unlockDialogLayout = new QVBoxLayout( this ); + unlockDialogLayout->addWidget( frame ); + + QHBoxLayout *layStatus = new QHBoxLayout( 0, 0, KDialog::spacingHint()); + layStatus->addWidget( mStatusLabel ); + + frameLayout = new QGridLayout( frame, 1, 1, KDialog::marginHint(), KDialog::spacingHint() ); + frameLayout->addMultiCellWidget( mpixLabel, 0, 2, 0, 0, AlignTop ); + frameLayout->addLayout( layStatus, 1, 1 ); + + installEventFilter(this); +} + +InfoDlg::~InfoDlg() +{ + hide(); +} + +void InfoDlg::updateLabel(QString &txt) +{ + mStatusLabel->setPaletteForegroundColor(Qt::black); + mStatusLabel->setText("" + txt + ""); +} + +void InfoDlg::setUnlockIcon() +{ + mpixLabel->setPixmap(DesktopIcon("unlock")); +} + +void InfoDlg::setWarningIcon() +{ + mpixLabel->setPixmap(DesktopIcon("messagebox_warning")); +} + +void InfoDlg::show() +{ + QDialog::show(); + QApplication::flushX(); +} + +#include "infodlg.moc" diff --git a/kdesktop/lock/infodlg.h b/kdesktop/lock/infodlg.h new file mode 100644 index 000000000..2eedf6269 --- /dev/null +++ b/kdesktop/lock/infodlg.h @@ -0,0 +1,51 @@ +//=========================================================================== +// +// This file is part of the KDE project +// +// Copyright (c) 2010 Timothy Pearson +// + +#ifndef __INFODLG_H__ +#define __INFODLG_H__ + +#include +#include + +class QFrame; +class QGridLayout; +class QLabel; +class KPushButton; +class QListView; + +//=========================================================================== +// +// Simple dialog for displaying an info message. +// It does not handle password validation. +// +class InfoDlg : public QDialog +{ + Q_OBJECT + +public: + InfoDlg(LockProcess *parent); + ~InfoDlg(); + virtual void show(); + + void updateLabel( QString &txt ); + void setUnlockIcon(); + void setWarningIcon(); + +private: + QFrame *frame; + QGridLayout *frameLayout; + QLabel *mStatusLabel; + QLabel *mpixLabel; + int mCapsLocked; + bool mUnlockingFailed; + QStringList layoutsList; + QStringList::iterator currLayout; + int sPid, sFd; +}; + +#endif + diff --git a/kdesktop/lock/lockprocess.cc b/kdesktop/lock/lockprocess.cc index a813b6899..75465bb34 100644 --- a/kdesktop/lock/lockprocess.cc +++ b/kdesktop/lock/lockprocess.cc @@ -19,6 +19,7 @@ #include "lockprocess.h" #include "lockdlg.h" +#include "infodlg.h" #include "autologout.h" #include "kdesktopsettings.h" @@ -56,6 +57,16 @@ #include #include #endif +#include +#include +#include +#include +#include +#include +#include + + +#include #include #include @@ -108,9 +119,13 @@ LockProcess::LockProcess(bool child, bool useBlankOnly) mVisibility(false), mRestoreXF86Lock(false), mForbidden(false), - mAutoLogout(false) + mAutoLogout(false), + mPipeOpen(false), + mInfoMessageDisplayed(false), + mForceReject(false) { setupSignals(); + setupPipe(); kapp->installX11EventFilter(this); @@ -191,6 +206,9 @@ LockProcess::~LockProcess() greetPlugin.info->done(); greetPlugin.library->unload(); } + + mPipeOpen = false; + //close(mPipe_fd); } static int signal_pipe[2]; @@ -217,6 +235,82 @@ void LockProcess::timerEvent(QTimerEvent *ev) } } +void LockProcess::setupPipe() +{ + /* Create the FIFO if it does not exist */ + umask(0); + mkdir(FIFO_DIR,0600); + mknod(FIFO_FILE, S_IFIFO|0600, 0); + + mPipe_fd = open(FIFO_FILE, O_RDONLY | O_NONBLOCK); + if (mPipe_fd > -1) { + mPipeOpen = true; + QTimer::singleShot( 100, this, SLOT(checkPipe()) ); + } +} + +void LockProcess::checkPipe() +{ + char readbuf[128]; + int numread; + QString to_display; + + if (mPipeOpen == true) { + readbuf[0]=' '; + numread = read(mPipe_fd, readbuf, 128); + readbuf[numread] = 0; + if (numread > 0) { + if (readbuf[0] == 'C') { + printf("Clearing info box!\n\r"); + mInfoMessageDisplayed=false; + if (currentDialog != NULL) { + mForceReject = true; + currentDialog->close(); + } + } + if (readbuf[0] == 'T') { + to_display = readbuf; + to_display = to_display.remove(0,1); + printf("Will display info message: %s\n", to_display.ascii()); + // Lock out password dialogs and close any active dialog + mInfoMessageDisplayed=true; + if (currentDialog != NULL) { + mForceReject = true; + currentDialog->close(); + } + // Display info message dialog + QTimer::singleShot( 100, this, SLOT(checkPipe()) ); + InfoDlg inDlg( this ); + inDlg.updateLabel(to_display); + inDlg.setUnlockIcon(); + int ret = execDialog( &inDlg ); + mForceReject = false; + return; + } + if (readbuf[0] == 'E') { + to_display = readbuf; + to_display = to_display.remove(0,1); + printf("Will display error message: %s\n", to_display.ascii()); + // Lock out password dialogs and close any active dialog + mInfoMessageDisplayed=true; + if (currentDialog != NULL) { + mForceReject = true; + currentDialog->close(); + } + // Display info message dialog + QTimer::singleShot( 100, this, SLOT(checkPipe()) ); + InfoDlg inDlg( this ); + inDlg.updateLabel(to_display); + inDlg.setWarningIcon(); + int ret = execDialog( &inDlg ); + mForceReject = false; + return; + } + } + QTimer::singleShot( 100, this, SLOT(checkPipe()) ); + } +} + void LockProcess::setupSignals() { struct sigaction act; @@ -907,24 +1001,33 @@ void LockProcess::resume( bool force ) // bool LockProcess::checkPass() { - if (mAutoLogout) - killTimer(mAutoLogoutTimerId); + if (mInfoMessageDisplayed == false) { + if (mAutoLogout) + killTimer(mAutoLogoutTimerId); - PasswordDlg passDlg( this, &greetPlugin); + PasswordDlg passDlg( this, &greetPlugin); - int ret = execDialog( &passDlg ); + int ret = execDialog( &passDlg ); + if (mForceReject == true) { + ret = QDialog::Rejected; + } + mForceReject = false; - XWindowAttributes rootAttr; - XGetWindowAttributes(qt_xdisplay(), RootWindow(qt_xdisplay(), + XWindowAttributes rootAttr; + XGetWindowAttributes(qt_xdisplay(), RootWindow(qt_xdisplay(), qt_xscreen()), &rootAttr); - if(( rootAttr.your_event_mask & SubstructureNotifyMask ) == 0 ) - { - kdWarning() << "ERROR: Something removed SubstructureNotifyMask from the root window!!!" << endl; - XSelectInput( qt_xdisplay(), qt_xrootwin(), - SubstructureNotifyMask | rootAttr.your_event_mask ); - } + if(( rootAttr.your_event_mask & SubstructureNotifyMask ) == 0 ) + { + kdWarning() << "ERROR: Something removed SubstructureNotifyMask from the root window!!!" << endl; + XSelectInput( qt_xdisplay(), qt_xrootwin(), + SubstructureNotifyMask | rootAttr.your_event_mask ); + } - return ret == QDialog::Accepted; + return ret == QDialog::Accepted; + } + else { + return 0; + } } static void fakeFocusIn( WId window ) @@ -945,6 +1048,7 @@ static void fakeFocusIn( WId window ) int LockProcess::execDialog( QDialog *dlg ) { + currentDialog=dlg; dlg->adjustSize(); QRect rect = dlg->geometry(); @@ -967,6 +1071,7 @@ int LockProcess::execDialog( QDialog *dlg ) resume( false ); } else fakeFocusIn( mDialogs.first()->winId()); + currentDialog = NULL; return rt; } diff --git a/kdesktop/lock/lockprocess.h b/kdesktop/lock/lockprocess.h index d7043e64d..18a624d57 100644 --- a/kdesktop/lock/lockprocess.h +++ b/kdesktop/lock/lockprocess.h @@ -29,6 +29,9 @@ struct GreeterPluginHandle { kgreeterplugin_info *info; }; +#define FIFO_DIR "/tmp/ksocket-global" +#define FIFO_FILE "/tmp/ksocket-global/kdesktoplockcontrol" + //=========================================================================== // // Screen saver handling process. Handles screensaver window, @@ -53,11 +56,12 @@ public: void msgBox( QMessageBox::Icon type, const QString &txt ); int execDialog( QDialog* dlg ); - + public slots: void quitSaver(); void preparePopup(); void cleanupPopup(); + void checkPipe(); protected: virtual bool x11Event(XEvent *); @@ -89,6 +93,7 @@ private: bool startHack(); void stopHack(); void setupSignals(); + void setupPipe(); bool checkPass(); void stayOnTop(); void lockXF86(); @@ -125,6 +130,12 @@ private: int mAutoLogoutTimerId; int mAutoLogoutTimeout; bool mAutoLogout; + bool mInfoMessageDisplayed; + QDialog *currentDialog; + bool mForceReject; + + bool mPipeOpen; + int mPipe_fd; }; #endif -- cgit v1.2.1