diff options
author | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-04-07 04:18:36 +0000 |
---|---|---|
committer | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-04-07 04:18:36 +0000 |
commit | c97349f53a15c930ce1f5f53ef37c44318a1981a (patch) | |
tree | 6064071088838d50234a4b6fe9d855e7136dea74 | |
parent | 1c9a50141d128a02150d0adca3684f957e3e994f (diff) | |
download | tdebase-c97349f53a15c930ce1f5f53ef37c44318a1981a.tar.gz tdebase-c97349f53a15c930ce1f5f53ef37c44318a1981a.zip |
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
-rw-r--r-- | kdesktop/lock/Makefile.am | 4 | ||||
-rw-r--r-- | kdesktop/lock/infodlg.cc | 117 | ||||
-rw-r--r-- | kdesktop/lock/infodlg.h | 51 | ||||
-rw-r--r-- | kdesktop/lock/lockprocess.cc | 133 | ||||
-rw-r--r-- | kdesktop/lock/lockprocess.h | 13 |
5 files changed, 301 insertions, 17 deletions
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 <[email protected]> + +#include <config.h> + +#include "infodlg.h" + +#include <dmctl.h> + +#include <kapplication.h> +#include <klocale.h> +#include <kpushbutton.h> +#include <kseparator.h> +#include <kstandarddirs.h> +#include <kglobalsettings.h> +#include <kconfig.h> +#include <kiconloader.h> +#include <kdesu/defaults.h> +#include <kpassdlg.h> +#include <kdebug.h> +#include <kuser.h> +#include <dcopref.h> +#include <kmessagebox.h> + +#include <qlayout.h> +#include <qpushbutton.h> +#include <qmessagebox.h> +#include <qsimplerichtext.h> +#include <qlabel.h> +#include <qstringlist.h> +#include <qfontmetrics.h> +#include <qstyle.h> +#include <qapplication.h> +#include <qlistview.h> +#include <qheader.h> +#include <qcheckbox.h> + +#include <ctype.h> +#include <unistd.h> +#include <stdlib.h> +#include <errno.h> +#include <pwd.h> +#include <sys/types.h> +#include <sys/socket.h> + +#include <X11/Xutil.h> +#include <X11/keysym.h> +#include <fixx11h.h> + +#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( "<b> </b>", 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("<b>" + txt + "</b>"); +} + +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 <[email protected]> +// + +#ifndef __INFODLG_H__ +#define __INFODLG_H__ + +#include <qdialog.h> +#include <qstringlist.h> + +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 <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 <linux/stat.h> #include <X11/Xlib.h> #include <X11/Xutil.h> @@ -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 |