• Skip to content
  • Skip to link menu
KDE 4.4 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

libkworkspace

kworkspace.cpp

Go to the documentation of this file.
00001 /* This file is part of the KDE libraries
00002     Copyright (C) 1997 Matthias Kalle Dalheimer (kalle@kde.org)
00003 
00004     This library is free software; you can redistribute it and/or
00005     modify it under the terms of the GNU Library General Public
00006     License as published by the Free Software Foundation; either
00007     version 2 of the License, or (at your option) any later version.
00008 
00009     This library is distributed in the hope that it will be useful,
00010     but WITHOUT ANY WARRANTY; without even the implied warranty of
00011     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012     Library General Public License for more details.
00013 
00014     You should have received a copy of the GNU Library General Public License
00015     along with this library; see the file COPYING.LIB.  If not, write to
00016     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017     Boston, MA 02110-1301, USA.
00018 */
00019 
00020 #include "kworkspace.h"
00021 #include <QApplication>
00022 #include <QDataStream>
00023 #include <kapplication.h>
00024 #include <QFile>
00025 #include <QFileInfo>
00026 #include <QTextStream>
00027 #include <klocale.h>
00028 #include <QDateTime>
00029 #include <kstandarddirs.h>
00030 #include <QtDBus/QtDBus>
00031 #include <stdlib.h> // getenv()
00032 #include <ksmserver_interface.h>
00033 #include <kdefakes.h>
00034 #include <QSocketNotifier>
00035 
00036 #ifdef Q_WS_X11
00037 #include <X11/Xlib.h>
00038 #include <X11/Xutil.h>
00039 #include <X11/Xatom.h>
00040 #include <X11/SM/SMlib.h>
00041 #include <fixx11h.h>
00042 #endif
00043 
00044 #ifdef Q_WS_X11
00045 #define DISPLAY "DISPLAY"
00046 #elif defined(Q_WS_QWS)
00047 #define DISPLAY "QWS_DISPLAY"
00048 #endif
00049 
00050 #include <unistd.h>
00051 #include <pwd.h>
00052 #include <sys/types.h>
00053 
00054 #include "kworkspace_p.h"
00055 
00056 namespace KWorkSpace
00057 {
00058 #ifdef Q_WS_X11
00059 static void save_yourself_callback( SmcConn conn_P, SmPointer, int, Bool , int, Bool )
00060     {
00061     SmcSaveYourselfDone( conn_P, True );
00062     }
00063 
00064 static void dummy_callback( SmcConn, SmPointer )
00065     {
00066     }
00067 #endif
00068 KRequestShutdownHelper::KRequestShutdownHelper()
00069     {
00070 #ifdef Q_WS_X11     
00071     SmcCallbacks calls;
00072     calls.save_yourself.callback = save_yourself_callback;
00073     calls.die.callback = dummy_callback;
00074     calls.save_complete.callback = dummy_callback;
00075     calls.shutdown_cancelled.callback = dummy_callback;
00076     char* id = NULL;
00077     char err[ 11 ];
00078     conn = SmcOpenConnection( NULL, NULL, 1, 0,
00079         SmcSaveYourselfProcMask | SmcDieProcMask | SmcSaveCompleteProcMask
00080         | SmcShutdownCancelledProcMask, &calls, NULL, &id, 10, err );
00081     if( id != NULL )
00082         free( id );
00083     if( conn == NULL )
00084         return; // no SM
00085     // set the required properties, mostly dummy values
00086     SmPropValue propvalue[ 5 ];
00087     SmProp props[ 5 ];
00088     propvalue[ 0 ].length = sizeof( unsigned char );
00089     unsigned char value0 = SmRestartNever; // so that this extra SM connection doesn't interfere
00090     propvalue[ 0 ].value = &value0;
00091     props[ 0 ].name = const_cast< char* >( SmRestartStyleHint );
00092     props[ 0 ].type = const_cast< char* >( SmCARD8 );
00093     props[ 0 ].num_vals = 1;
00094     props[ 0 ].vals = &propvalue[ 0 ];
00095     struct passwd* entry = getpwuid( geteuid() );
00096     propvalue[ 1 ].length = entry != NULL ? strlen( entry->pw_name ) : 0;
00097     propvalue[ 1 ].value = (SmPointer)( entry != NULL ? entry->pw_name : "" );
00098     props[ 1 ].name = const_cast< char* >( SmUserID );
00099     props[ 1 ].type = const_cast< char* >( SmARRAY8 );
00100     props[ 1 ].num_vals = 1;
00101     props[ 1 ].vals = &propvalue[ 1 ];
00102     propvalue[ 2 ].length = 0;
00103     propvalue[ 2 ].value = (SmPointer)( "" );
00104     props[ 2 ].name = const_cast< char* >( SmRestartCommand );
00105     props[ 2 ].type = const_cast< char* >( SmLISTofARRAY8 );
00106     props[ 2 ].num_vals = 1;
00107     props[ 2 ].vals = &propvalue[ 2 ];
00108     propvalue[ 3 ].length = strlen( "requestshutdownhelper" );
00109     propvalue[ 3 ].value = (SmPointer)"requestshutdownhelper";
00110     props[ 3 ].name = const_cast< char* >( SmProgram );
00111     props[ 3 ].type = const_cast< char* >( SmARRAY8 );
00112     props[ 3 ].num_vals = 1;
00113     props[ 3 ].vals = &propvalue[ 3 ];
00114     propvalue[ 4 ].length = 0;
00115     propvalue[ 4 ].value = (SmPointer)( "" );
00116     props[ 4 ].name = const_cast< char* >( SmCloneCommand );
00117     props[ 4 ].type = const_cast< char* >( SmLISTofARRAY8 );
00118     props[ 4 ].num_vals = 1;
00119     props[ 4 ].vals = &propvalue[ 4 ];
00120     SmProp* p[ 5 ] = { &props[ 0 ], &props[ 1 ], &props[ 2 ], &props[ 3 ], &props[ 4 ] };
00121     SmcSetProperties( conn, 5, p );
00122     notifier = new QSocketNotifier( IceConnectionNumber( SmcGetIceConnection( conn )),
00123         QSocketNotifier::Read, this );
00124     connect( notifier, SIGNAL( activated( int )), SLOT( processData()));
00125 #endif
00126     }
00127 
00128 KRequestShutdownHelper::~KRequestShutdownHelper()
00129     {
00130 #ifdef Q_WS_X11     
00131     if( conn != NULL )
00132         {
00133         delete notifier;
00134         SmcCloseConnection( conn, 0, NULL );
00135         }
00136 #endif
00137     }
00138 
00139 void KRequestShutdownHelper::processData()
00140     {
00141 #ifdef Q_WS_X11     
00142     if( conn != NULL )
00143         IceProcessMessages( SmcGetIceConnection( conn ), 0, 0 );
00144 #endif    
00145     }
00146 
00147 bool KRequestShutdownHelper::requestShutdown( ShutdownConfirm confirm )
00148     {
00149 #ifdef Q_WS_X11     
00150     if( conn == NULL )
00151         return false;
00152     SmcRequestSaveYourself( conn, SmSaveBoth, True, SmInteractStyleAny,
00153         confirm == ShutdownConfirmNo, True );
00154     // flush the request
00155     IceFlush(SmcGetIceConnection(conn));
00156 #endif    
00157     return true;
00158     }
00159 #ifdef Q_WS_X11
00160 static KRequestShutdownHelper* helper = NULL;
00161 
00162 static void cleanup_sm()
00163 {
00164     delete helper;
00165 }
00166 #endif
00167 
00168 bool requestShutDown(
00169     ShutdownConfirm confirm, ShutdownType sdtype, ShutdownMode sdmode )
00170 {
00171 #ifdef Q_WS_X11
00172     QApplication::syncX();
00173     kapp->updateRemoteUserTimestamp( "org.kde.ksmserver" );
00174     /*  use ksmserver's dcop interface if necessary  */
00175     if ( confirm == ShutdownConfirmYes ||
00176          sdtype != ShutdownTypeDefault ||
00177          sdmode != ShutdownModeDefault )
00178     {
00179         org::kde::KSMServerInterface ksmserver("org.kde.ksmserver", "/KSMServer", QDBusConnection::sessionBus());
00180         QDBusReply<void> reply = ksmserver.logout((int)confirm,  (int)sdtype,  (int)sdmode);
00181         return (reply.isValid());
00182     }
00183     if( helper == NULL )
00184     {
00185         helper = new KRequestShutdownHelper();
00186         qAddPostRoutine(cleanup_sm);
00187     }
00188     return helper->requestShutdown( confirm );
00189 #else
00190     return false;
00191 #endif
00192 }
00193 
00194 bool canShutDown( ShutdownConfirm confirm,
00195                   ShutdownType sdtype,
00196                   ShutdownMode sdmode )
00197 {
00198 #ifdef Q_WS_X11
00199     if ( confirm == ShutdownConfirmYes ||
00200          sdtype != ShutdownTypeDefault ||
00201          sdmode != ShutdownModeDefault )
00202     {
00203         org::kde::KSMServerInterface ksmserver("org.kde.ksmserver", "/KSMServer", QDBusConnection::sessionBus());
00204         QDBusReply<bool> reply = ksmserver.canShutdown();
00205         if (!reply.isValid()) {
00206             return false;
00207         }
00208         return reply;
00209     }
00210 
00211     return true;
00212 #else
00213     return false;
00214 #endif
00215 }
00216 
00217 static QTime smModificationTime;
00218 void propagateSessionManager()
00219 {
00220 #ifdef Q_WS_X11
00221     QByteArray fName = QFile::encodeName(KStandardDirs::locateLocal("socket", "KSMserver"));
00222     QString display = QString::fromLocal8Bit( ::getenv(DISPLAY) );
00223     // strip the screen number from the display
00224     display.remove(QRegExp("\\.[0-9]+$"));
00225     int i;
00226     while( (i = display.indexOf(':')) >= 0)
00227        display[i] = '_';
00228 
00229     fName += '_';
00230     fName += display.toLocal8Bit();
00231     QByteArray smEnv = ::getenv("SESSION_MANAGER");
00232     bool check = smEnv.isEmpty();
00233     if ( !check && smModificationTime.isValid() ) {
00234          QFileInfo info( fName );
00235          QTime current = info.lastModified().time();
00236          check = current > smModificationTime;
00237     }
00238     if ( check ) {
00239         QFile f( fName );
00240         if ( !f.open( QIODevice::ReadOnly ) )
00241             return;
00242         QFileInfo info ( f );
00243         smModificationTime = QTime( info.lastModified().time() );
00244         QTextStream t(&f);
00245         t.setCodec( "ISO 8859-1" );
00246         QString s = t.readLine();
00247         f.close();
00248         ::setenv( "SESSION_MANAGER", s.toLatin1(), true  );
00249     }
00250 #endif
00251 }
00252 
00253 } // end namespace
00254 
00255 #include "kworkspace_p.moc"

libkworkspace

Skip menu "libkworkspace"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

API Reference

Skip menu "API Reference"
  • KWin
  •   KWin Libraries
  • Libraries
  •   libkworkspace
  •   libsolidcontrol
  •   libtaskmanager
  • Plasma
  •     Animators
  •     Applets
  •     Engines
  • Solid Modules
  • System Settings
  •   SystemSettingsView
Generated for API Reference by doxygen 1.5.9-20090814
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal