From 960cc8392da291eaf6c90d2101b721f6c20488f3 Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Thu, 8 Aug 2013 14:36:50 -0500 Subject: Update tdehw-based media manager for new mount API Allow active VT to be queried from tdm Only display media notification messages on active VT Hide logout action buttons if logout process unstalls --- ksmserver/shutdown.cpp | 18 +++--- .../media/mediamanager/tdehardwarebackend.cpp | 28 +------- tdeioslave/media/medianotifier/CMakeLists.txt | 3 +- tdeioslave/media/medianotifier/medianotifier.cpp | 26 ++++++-- tdm/backend/CMakeLists.txt | 2 +- tdm/backend/ctrl.c | 18 ++++++ tdm/backend/getfd.c | 75 ++++++++++++++++++++++ tdm/backend/getfd.h | 1 + tdmlib/dmctl.cpp | 38 ++++++++++- tdmlib/dmctl.h | 2 + 10 files changed, 168 insertions(+), 43 deletions(-) create mode 100644 tdm/backend/getfd.c create mode 100644 tdm/backend/getfd.h diff --git a/ksmserver/shutdown.cpp b/ksmserver/shutdown.cpp index cf849e757..cc6e8ab7c 100644 --- a/ksmserver/shutdown.cpp +++ b/ksmserver/shutdown.cpp @@ -260,6 +260,8 @@ void KSMServer::shutdownInternal( TDEApplication::ShutdownConfirm confirm, if (showLogoutStatusDlg) { shutdownNotifierIPDlg = KSMShutdownIPDlg::showShutdownIP(); if (shutdownNotifierIPDlg) { + connect(shutdownNotifierIPDlg, SIGNAL(abortLogoutClicked()), this, SLOT(cancelShutdown())); + connect(shutdownNotifierIPDlg, SIGNAL(skipNotificationClicked()), this, SLOT(forceSkipSaveYourself())); static_cast(shutdownNotifierIPDlg)->setStatusMessage(i18n("Notifying applications of logout request...")); notificationTimer.start( KSMSERVER_NOTIFICATION_MANUAL_OPTIONS_TIMEOUT, true ); } @@ -440,6 +442,10 @@ void KSMServer::saveYourselfDone( KSMClient* client, bool success ) } notificationTimer.stop(); + if (shutdownNotifierIPDlg) { + static_cast(shutdownNotifierIPDlg)->hideNotificationActionButtons(); + } + updateLogoutStatusDialog(); } @@ -503,8 +509,6 @@ void KSMServer::updateLogoutStatusDialog() static_cast(shutdownNotifierIPDlg)->hide(); notificationTimer.stop(); static_cast(shutdownNotifierIPDlg)->hideNotificationActionButtons(); - disconnect(shutdownNotifierIPDlg, SIGNAL(abortLogoutClicked()), this, SLOT(cancelShutdown())); - disconnect(shutdownNotifierIPDlg, SIGNAL(skipNotificationClicked()), this, SLOT(forceSkipSaveYourself())); #endif if (nextClientToKill == "") { static_cast(shutdownNotifierIPDlg)->setStatusMessage(i18n("An application is requesting attention, logout paused...")); @@ -677,8 +681,6 @@ void KSMServer::handleProtectionTimeout() notificationTimer.stop(); if (shutdownNotifierIPDlg) { static_cast(shutdownNotifierIPDlg)->hideNotificationActionButtons(); - disconnect(shutdownNotifierIPDlg, SIGNAL(abortLogoutClicked()), this, SLOT(cancelShutdown())); - disconnect(shutdownNotifierIPDlg, SIGNAL(skipNotificationClicked()), this, SLOT(forceSkipSaveYourself())); static_cast(shutdownNotifierIPDlg)->setStatusMessage(i18n("Forcing interacting application termination").append("...")); } @@ -695,8 +697,6 @@ void KSMServer::notificationTimeout() { if (shutdownNotifierIPDlg) { // Display the buttons in the logout dialog - connect(shutdownNotifierIPDlg, SIGNAL(abortLogoutClicked()), this, SLOT(cancelShutdown())); - connect(shutdownNotifierIPDlg, SIGNAL(skipNotificationClicked()), this, SLOT(forceSkipSaveYourself())); static_cast(shutdownNotifierIPDlg)->showNotificationActionButtons(); } } @@ -742,6 +742,10 @@ void KSMServer::completeShutdownOrCheckpoint() KSMShutdownIPFeedback::showit(); // hide the UGLY logout process from the user if (!shutdownNotifierIPDlg) { shutdownNotifierIPDlg = KSMShutdownIPDlg::showShutdownIP(); + if (shutdownNotifierIPDlg) { + connect(shutdownNotifierIPDlg, SIGNAL(abortLogoutClicked()), this, SLOT(cancelShutdown())); + connect(shutdownNotifierIPDlg, SIGNAL(skipNotificationClicked()), this, SLOT(forceSkipSaveYourself())); + } } while (!KSMShutdownIPFeedback::ispainted()) { tqApp->processEvents(); @@ -751,8 +755,6 @@ void KSMServer::completeShutdownOrCheckpoint() notificationTimer.stop(); if (shutdownNotifierIPDlg) { static_cast(shutdownNotifierIPDlg)->hideNotificationActionButtons(); - disconnect(shutdownNotifierIPDlg, SIGNAL(abortLogoutClicked()), this, SLOT(cancelShutdown())); - disconnect(shutdownNotifierIPDlg, SIGNAL(skipNotificationClicked()), this, SLOT(forceSkipSaveYourself())); } // synchronize any folders that were requested for shutdown sync diff --git a/tdeioslave/media/mediamanager/tdehardwarebackend.cpp b/tdeioslave/media/mediamanager/tdehardwarebackend.cpp index 3171d8f3c..369f87c3a 100644 --- a/tdeioslave/media/mediamanager/tdehardwarebackend.cpp +++ b/tdeioslave/media/mediamanager/tdehardwarebackend.cpp @@ -969,39 +969,15 @@ TQString TDEBackend::mount(const Medium *medium) return i18n("Internal error"); } - TQString optionString; TQString diskLabel; TQMap valids = MediaManagerUtils::splitOptions(mountoptions(medium->id())); - if (valids["ro"] == "true") { - optionString.append(" -r"); - } - - if (valids["atime"] != "true") { - optionString.append(" -A"); - } - - if (valids["utf8"] == "true") { - optionString.append(" -c utf8"); - } - - if (valids["sync"] == "true") { - optionString.append(" -s"); - } TQString mount_point = valids["mountpoint"]; if (mount_point.startsWith("/media/")) { diskLabel = mount_point.mid(7); } - if (valids.contains("filesystem")) { - optionString.append(TQString(" -t %1").arg(valids["filesystem"])); - } - - if (valids.contains("locale")) { - optionString.append(TQString(" -c %1").arg(valids["locale"])); - } - if (diskLabel == "") { // Try to use a pretty mount point if possible TQStringList pieces = TQStringList::split("/", sdevice->deviceNode(), FALSE); @@ -1015,7 +991,7 @@ TQString TDEBackend::mount(const Medium *medium) if (!medium->isEncrypted()) { // normal volume TQString mountMessages; - TQString mountedPath = sdevice->mountDevice(diskLabel, optionString, &mountMessages); + TQString mountedPath = sdevice->mountDevice(diskLabel, valids, &mountMessages); if (mountedPath.isNull()) { qerror = i18n("Unable to mount this device.

Potential reasons include:
Improper device and/or user privilege level
Corrupt data on storage device"); if (!mountMessages.isNull()) { @@ -1068,7 +1044,7 @@ TQString TDEBackend::mount(const Medium *medium) // mount encrypted volume with password int mountRetcode; TQString mountMessages; - TQString mountedPath = sdevice->mountEncryptedDevice(m_decryptionPassword, diskLabel, optionString, &mountMessages, &mountRetcode); + TQString mountedPath = sdevice->mountEncryptedDevice(m_decryptionPassword, diskLabel, valids, &mountMessages, &mountRetcode); if (mountedPath.isNull()) { if (mountRetcode == 0) { // Mounting was successful diff --git a/tdeioslave/media/medianotifier/CMakeLists.txt b/tdeioslave/media/medianotifier/CMakeLists.txt index 9618f79ab..35d639d1b 100644 --- a/tdeioslave/media/medianotifier/CMakeLists.txt +++ b/tdeioslave/media/medianotifier/CMakeLists.txt @@ -13,6 +13,7 @@ include_directories( ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_BINARY_DIR}/tdeioslave/media/libmediacommon ${CMAKE_SOURCE_DIR}/tdeioslave/media/libmediacommon + ${CMAKE_SOURCE_DIR}/tdmlib ${TDE_INCLUDE_DIR} ${TQT_INCLUDE_DIRS} ) @@ -38,6 +39,6 @@ set( ${target}_SRCS tde_add_kpart( ${target} AUTOMOC SOURCES ${${target}_SRCS} - LINK mediacommon-static tdeinit_kded-shared + LINK mediacommon-static tdeinit_kded-shared dmctl-static DESTINATION ${PLUGIN_INSTALL_DIR} ) diff --git a/tdeioslave/media/medianotifier/medianotifier.cpp b/tdeioslave/media/medianotifier/medianotifier.cpp index e500731a2..9b4c0e17e 100644 --- a/tdeioslave/media/medianotifier/medianotifier.cpp +++ b/tdeioslave/media/medianotifier/medianotifier.cpp @@ -41,6 +41,8 @@ #include "notifieraction.h" #include "mediamanagersettings.h" +#include "dmctl.h" + MediaNotifier::MediaNotifier(const TQCString &name) : KDEDModule(name) { connectDCOPSignal( "kded", "mediamanager", "mediumAdded(TQString, bool)", @@ -69,13 +71,14 @@ void MediaNotifier::onMediumChange( const TQString &name, bool allowNotification kdDebug() << "MediaNotifier::onMediumChange( " << name << ", " << allowNotification << ")" << endl; - if ( !allowNotification ) + if ( !allowNotification ) { return; + } -// Update user activity timestamp, otherwise the notification dialog will be shown -// in the background due to focus stealing prevention. Entering a new media can -// be seen as a kind of user activity after all. It'd be better to update the timestamp -// as soon as the media is entered, but it apparently takes some time to get here. + // Update user activity timestamp, otherwise the notification dialog will be shown + // in the background due to focus stealing prevention. Entering a new media can + // be seen as a kind of user activity after all. It'd be better to update the timestamp + // as soon as the media is entered, but it apparently takes some time to get here. kapp->updateUserTimestamp(); KURL url( "system:/media/"+name ); @@ -285,6 +288,19 @@ void MediaNotifier::notify( KFileItem &medium ) { kdDebug() << "Notification triggered." << endl; + DM dm; + int currentActiveVT = dm.activeVT(); + int currentX11VT = TDEApplication::currentX11VT(); + + if (currentX11VT < 0) { + // Do not notify if user is not local + return; + } + if ((currentActiveVT >= 0) && (currentX11VT != currentActiveVT)) { + // Do not notify if VT is not active! + return; + } + NotifierSettings *settings = new NotifierSettings(); if ( settings->autoActionForMimetype( medium.mimetype() )==0L ) diff --git a/tdm/backend/CMakeLists.txt b/tdm/backend/CMakeLists.txt index cd98b3a9c..625c8e85b 100644 --- a/tdm/backend/CMakeLists.txt +++ b/tdm/backend/CMakeLists.txt @@ -38,7 +38,7 @@ endif() tde_add_executable( tdm SOURCES access.c auth.c bootman.c choose.c client.c consolekit.c - ctrl.c daemon.c dm.c dpylist.c error.c genauth.c + ctrl.c daemon.c dm.c dpylist.c error.c genauth.c getfd.c inifile.c krb5auth.c mitauth.c netaddr.c policy.c process.c protodpy.c reset.c resource.c rpcauth.c server.c session.c sessreg.c socket.c streams.c diff --git a/tdm/backend/ctrl.c b/tdm/backend/ctrl.c index 622c9370d..4e10309e6 100644 --- a/tdm/backend/ctrl.c +++ b/tdm/backend/ctrl.c @@ -42,6 +42,9 @@ from the copyright holder. #include #include +#include +#include "getfd.h" + static void acceptSock( CtrlRec *cr ) { @@ -582,6 +585,21 @@ processCtrl( const char *string, int len, int fd, struct display *d ) ListSessions( flags, d, (void *)fd, emitXSessC, emitTTYSessC ); Reply( "\n" ); goto bust; + } else if (fd >= 0 && !strcmp( ar[0], "activevt" )) { +#ifdef HAVE_VTS + Reply( "ok" ); + int vt_fd = getfd(NULL); + if (vt_fd > 0) { + struct vt_stat vtstat; + if (!ioctl(vt_fd, VT_GETSTATE, &vtstat)) { + Writer( fd, cbuf, sprintf( cbuf, "\t%d", vtstat.v_active ) ); + } + } + Reply( "\n" ); +#else + Reply( "notsup\tvirtual terminal support not available\n" ); +#endif + goto bust; } else if (!strcmp( ar[0], "reserve" )) { int lt = 60; /* XXX make default timeout configurable? */ if (ar[1]) { diff --git a/tdm/backend/getfd.c b/tdm/backend/getfd.c new file mode 100644 index 000000000..3632161d3 --- /dev/null +++ b/tdm/backend/getfd.c @@ -0,0 +1,75 @@ +#include +#include +#include +#include +#include +#include +#include +#include "getfd.h" + +/* + * getfd.c + * + * Get an fd for use with kbd/console ioctls. + * We try several things because opening /dev/console will fail + * if someone else used X (which does a chown on /dev/console). + */ + +static int +is_a_console(int fd) { + char arg; + + arg = 0; + return (ioctl(fd, KDGKBTYPE, &arg) == 0 + && ((arg == KB_101) || (arg == KB_84))); +} + +static int +open_a_console(const char *fnam) { + int fd; + + /* + * For ioctl purposes we only need some fd and permissions + * do not matter. But setfont:activatemap() does a write. + */ + fd = open(fnam, O_RDWR); + if (fd < 0 && errno == EACCES) + fd = open(fnam, O_WRONLY); + if (fd < 0 && errno == EACCES) + fd = open(fnam, O_RDONLY); + if (fd < 0) + return -1; + if (!is_a_console(fd)) { + close(fd); + return -1; + } + return fd; +} + +int getfd() { + int fd; + + fd = open_a_console("/dev/tty"); + if (fd >= 0) + return fd; + + fd = open_a_console("/dev/tty0"); + if (fd >= 0) + return fd; + + fd = open_a_console("/dev/vc/0"); + if (fd >= 0) + return fd; + + fd = open_a_console("/dev/console"); + if (fd >= 0) + return fd; + + for (fd = 0; fd < 3; fd++) + if (is_a_console(fd)) + return fd; + + // "Couldnt get a file descriptor referring to the console + return -1; +} + diff --git a/tdm/backend/getfd.h b/tdm/backend/getfd.h new file mode 100644 index 000000000..b0b33a892 --- /dev/null +++ b/tdm/backend/getfd.h @@ -0,0 +1 @@ +extern int getfd(); diff --git a/tdmlib/dmctl.cpp b/tdmlib/dmctl.cpp index 9cf7e9d34..c4fc0a5dd 100644 --- a/tdmlib/dmctl.cpp +++ b/tdmlib/dmctl.cpp @@ -392,8 +392,42 @@ DM::switchVT( int vt ) void DM::lockSwitchVT( int vt ) { - if (switchVT( vt )) - kapp->dcopClient()->send( "kdesktop", "KScreensaverIface", "lock()", TQString("") ); + if (switchVT( vt )) { + TQByteArray data; + TQCString replyType; + TQByteArray replyData; + // Block here until lock is complete + // If this is not done the desktop of the locked session will be shown after VT switch until the lock fully engages! + kapp->dcopClient()->call("kdesktop", "KScreensaverIface", "lock()", data, replyType, replyData); + } +} + +int +DM::activeVT() +{ + if (DMType == OldTDM) { + return -1; + } + + TQCString re; + + if (DMType == GDM) { + return -1; + } + else { + if (!exec( "activevt\n", re )) { + return -1; + } + TQString retrunc = TQString( re.data() + 3 ); + bool ok = false; + int activevt = retrunc.toInt(&ok, 10); + if (ok) { + return activevt; + } + else { + return -1; + } + } } void diff --git a/tdmlib/dmctl.h b/tdmlib/dmctl.h index 376a9ddd7..f50f72f6c 100644 --- a/tdmlib/dmctl.h +++ b/tdmlib/dmctl.h @@ -54,6 +54,7 @@ public: bool localSessions( SessList &list ); bool switchVT( int vt ); void lockSwitchVT( int vt ); + int activeVT(); bool bootOptions( TQStringList &opts, int &dflt, int &curr ); @@ -87,6 +88,7 @@ public: void startReserve() {} bool localSessions( SessList &list ) { return false; } void switchVT( int vt ) {} + int activeVT() { return -1; } bool bootOptions( TQStringList &opts, int &dflt, int &curr ); -- cgit v1.2.3