• Skip to content
  • Skip to link menu
KDE 4.2 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 
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; // no SM
00084     // set the required properties, mostly dummy values
00085     SmPropValue propvalue[ 5 ];
00086     SmProp props[ 5 ];
00087     propvalue[ 0 ].length = sizeof( int );
00088     int value0 = SmRestartNever; // so that this extra SM connection doesn't interfere
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     // flush the request
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     /*  use ksmserver's dcop interface if necessary  */
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 bool canShutDown( ShutdownConfirm confirm,
00182                   ShutdownType sdtype,
00183                   ShutdownMode sdmode )
00184 {
00185     if ( confirm == ShutdownConfirmYes ||
00186          sdtype != ShutdownTypeDefault ||
00187          sdmode != ShutdownModeDefault )
00188     {
00189         org::kde::KSMServerInterface ksmserver("org.kde.ksmserver", "/KSMServer", QDBusConnection::sessionBus());
00190         QDBusReply<bool> reply = ksmserver.canShutdown();
00191         if (!reply.isValid()) {
00192             return false;
00193         }
00194         return reply;
00195     }
00196 
00197     return true;
00198 }
00199 
00200 static QTime smModificationTime;
00201 void propagateSessionManager()
00202 {
00203     QByteArray fName = QFile::encodeName(KStandardDirs::locateLocal("socket", "KSMserver"));
00204     QString display = QString::fromLocal8Bit( ::getenv(DISPLAY) );
00205     // strip the screen number from the display
00206     display.remove(QRegExp("\\.[0-9]+$"));
00207     int i;
00208     while( (i = display.indexOf(':')) >= 0)
00209        display[i] = '_';
00210 
00211     fName += '_';
00212     fName += display.toLocal8Bit();
00213     QByteArray smEnv = ::getenv("SESSION_MANAGER");
00214     bool check = smEnv.isEmpty();
00215     if ( !check && smModificationTime.isValid() ) {
00216          QFileInfo info( fName );
00217          QTime current = info.lastModified().time();
00218          check = current > smModificationTime;
00219     }
00220     if ( check ) {
00221         QFile f( fName );
00222         if ( !f.open( QIODevice::ReadOnly ) )
00223             return;
00224         QFileInfo info ( f );
00225         smModificationTime = QTime( info.lastModified().time() );
00226         QTextStream t(&f);
00227         t.setCodec( "ISO 8859-1" );
00228         QString s = t.readLine();
00229         f.close();
00230         ::setenv( "SESSION_MANAGER", s.toLatin1(), true  );
00231     }
00232 }
00233 
00234 } // end namespace
00235 
00236 #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
Generated for API Reference by doxygen 1.5.7
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