libkworkspace
kworkspace.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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>
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
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
00068 KRequestShutdownHelper::KRequestShutdownHelper()
00069 {
00070 SmcCallbacks calls;
00071 calls.save_yourself.callback = save_yourself_callback;
00072 calls.die.callback = dummy_callback;
00073 calls.save_complete.callback = dummy_callback;
00074 calls.shutdown_cancelled.callback = dummy_callback;
00075 char* id = NULL;
00076 char err[ 11 ];
00077 conn = SmcOpenConnection( NULL, NULL, 1, 0,
00078 SmcSaveYourselfProcMask | SmcDieProcMask | SmcSaveCompleteProcMask
00079 | SmcShutdownCancelledProcMask, &calls, NULL, &id, 10, err );
00080 if( id != NULL )
00081 free( id );
00082 if( conn == NULL )
00083 return;
00084
00085 SmPropValue propvalue[ 5 ];
00086 SmProp props[ 5 ];
00087 propvalue[ 0 ].length = sizeof( int );
00088 int value0 = SmRestartNever;
00089 propvalue[ 0 ].value = &value0;
00090 props[ 0 ].name = const_cast< char* >( SmRestartStyleHint );
00091 props[ 0 ].type = const_cast< char* >( SmCARD8 );
00092 props[ 0 ].num_vals = 1;
00093 props[ 0 ].vals = &propvalue[ 0 ];
00094 struct passwd* entry = getpwuid( geteuid() );
00095 propvalue[ 1 ].length = entry != NULL ? strlen( entry->pw_name ) : 0;
00096 propvalue[ 1 ].value = (SmPointer)( entry != NULL ? entry->pw_name : "" );
00097 props[ 1 ].name = const_cast< char* >( SmUserID );
00098 props[ 1 ].type = const_cast< char* >( SmARRAY8 );
00099 props[ 1 ].num_vals = 1;
00100 props[ 1 ].vals = &propvalue[ 1 ];
00101 propvalue[ 2 ].length = 0;
00102 propvalue[ 2 ].value = (SmPointer)( "" );
00103 props[ 2 ].name = const_cast< char* >( SmRestartCommand );
00104 props[ 2 ].type = const_cast< char* >( SmLISTofARRAY8 );
00105 props[ 2 ].num_vals = 1;
00106 props[ 2 ].vals = &propvalue[ 2 ];
00107 propvalue[ 3 ].length = strlen( "requestshutdownhelper" );
00108 propvalue[ 3 ].value = (SmPointer)"requestshutdownhelper";
00109 props[ 3 ].name = const_cast< char* >( SmProgram );
00110 props[ 3 ].type = const_cast< char* >( SmARRAY8 );
00111 props[ 3 ].num_vals = 1;
00112 props[ 3 ].vals = &propvalue[ 3 ];
00113 propvalue[ 4 ].length = 0;
00114 propvalue[ 4 ].value = (SmPointer)( "" );
00115 props[ 4 ].name = const_cast< char* >( SmCloneCommand );
00116 props[ 4 ].type = const_cast< char* >( SmLISTofARRAY8 );
00117 props[ 4 ].num_vals = 1;
00118 props[ 4 ].vals = &propvalue[ 4 ];
00119 SmProp* p[ 5 ] = { &props[ 0 ], &props[ 1 ], &props[ 2 ], &props[ 3 ], &props[ 4 ] };
00120 SmcSetProperties( conn, 5, p );
00121 notifier = new QSocketNotifier( IceConnectionNumber( SmcGetIceConnection( conn )),
00122 QSocketNotifier::Read, this );
00123 connect( notifier, SIGNAL( activated( int )), SLOT( processData()));
00124 }
00125
00126 KRequestShutdownHelper::~KRequestShutdownHelper()
00127 {
00128 if( conn != NULL )
00129 {
00130 delete notifier;
00131 SmcCloseConnection( conn, 0, NULL );
00132 }
00133 }
00134
00135 void KRequestShutdownHelper::processData()
00136 {
00137 if( conn != NULL )
00138 IceProcessMessages( SmcGetIceConnection( conn ), 0, 0 );
00139 }
00140
00141 bool KRequestShutdownHelper::requestShutdown( ShutdownConfirm confirm )
00142 {
00143 if( conn == NULL )
00144 return false;
00145 SmcRequestSaveYourself( conn, SmSaveBoth, True, SmInteractStyleAny,
00146 confirm == ShutdownConfirmNo, True );
00147
00148 IceFlush(SmcGetIceConnection(conn));
00149 return true;
00150 }
00151
00152 static KRequestShutdownHelper* helper = NULL;
00153
00154 static void cleanup_sm()
00155 {
00156 delete helper;
00157 }
00158
00159 bool requestShutDown(
00160 ShutdownConfirm confirm, ShutdownType sdtype, ShutdownMode sdmode )
00161 {
00162 QApplication::syncX();
00163 kapp->updateRemoteUserTimestamp( "org.kde.ksmserver" );
00164
00165 if ( confirm == ShutdownConfirmYes ||
00166 sdtype != ShutdownTypeDefault ||
00167 sdmode != ShutdownModeDefault )
00168 {
00169 org::kde::KSMServerInterface ksmserver("org.kde.ksmserver", "/KSMServer", QDBusConnection::sessionBus());
00170 QDBusReply<void> reply = ksmserver.logout((int)confirm, (int)sdtype, (int)sdmode);
00171 return (reply.isValid());
00172 }
00173 if( helper == NULL )
00174 {
00175 helper = new KRequestShutdownHelper();
00176 qAddPostRoutine(cleanup_sm);
00177 }
00178 return helper->requestShutdown( confirm );
00179 }
00180
00181 static QTime smModificationTime;
00182 void propagateSessionManager()
00183 {
00184 QByteArray fName = QFile::encodeName(KStandardDirs::locateLocal("socket", "KSMserver"));
00185 QString display = QString::fromLocal8Bit( ::getenv(DISPLAY) );
00186
00187 display.remove(QRegExp("\\.[0-9]+$"));
00188 int i;
00189 while( (i = display.indexOf(':')) >= 0)
00190 display[i] = '_';
00191
00192 fName += '_';
00193 fName += display.toLocal8Bit();
00194 QByteArray smEnv = ::getenv("SESSION_MANAGER");
00195 bool check = smEnv.isEmpty();
00196 if ( !check && smModificationTime.isValid() ) {
00197 QFileInfo info( fName );
00198 QTime current = info.lastModified().time();
00199 check = current > smModificationTime;
00200 }
00201 if ( check ) {
00202 QFile f( fName );
00203 if ( !f.open( QIODevice::ReadOnly ) )
00204 return;
00205 QFileInfo info ( f );
00206 smModificationTime = QTime( info.lastModified().time() );
00207 QTextStream t(&f);
00208 t.setCodec( "ISO 8859-1" );
00209 QString s = t.readLine();
00210 f.close();
00211 ::setenv( "SESSION_MANAGER", s.toLatin1(), true );
00212 }
00213 }
00214
00215 }
00216
00217 #include "kworkspace_p.moc"