1/*****************************************************************
2ksmserver - the KDE session management server
3
4Copyright 2000 Matthias Ettrich <ettrich@kde.org>
5
6Permission is hereby granted, free of charge, to any person obtaining a copy
7of this software and associated documentation files (the "Software"), to deal
8in the Software without restriction, including without limitation the rights
9to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10copies of the Software, and to permit persons to whom the Software is
11furnished to do so, subject to the following conditions:
12
13The above copyright notice and this permission notice shall be included in
14all copies or substantial portions of the Software.
15
16THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
20AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
23******************************************************************/
24
25#ifndef SERVER_H
26#define SERVER_H
27
28// needed to avoid clash with INT8 defined in X11/Xmd.h on solaris
29#define QT_CLEAN_NAMESPACE 1
30#include <QStringList>
31#include <QObject>
32
33#include <kapplication.h>
34#include <kworkspace/kworkspace.h>
35#include <kmessagebox.h>
36#include <QTimer>
37#include <QTime>
38#include <QMap>
39
40#define INT32 QINT32
41#include <X11/Xlib.h>
42#include <X11/Xmd.h>
43#include <X11/ICE/ICElib.h>
44extern "C" {
45#include <X11/ICE/ICEutil.h>
46#include <X11/ICE/ICEmsg.h>
47#include <X11/ICE/ICEproto.h>
48#include <X11/SM/SM.h>
49#include <X11/SM/SMlib.h>
50}
51
52#include <fixx11h.h>
53
54#define SESSION_PREVIOUS_LOGOUT "saved at previous logout"
55#define SESSION_BY_USER "saved by user"
56
57class KProcess;
58
59class KSMListener;
60class KSMConnection;
61class KSMClient;
62
63class OrgKdeKLauncherInterface;
64class QDBusInterface;
65
66enum SMType { SM_ERROR, SM_WMCOMMAND, SM_WMSAVEYOURSELF };
67struct SMData
68 {
69 SMType type;
70 QStringList wmCommand;
71 QString wmClientMachine;
72 QString wmclass1, wmclass2;
73 };
74typedef QMap<WId,SMData> WindowMap;
75
76class KSMServer : public QObject
77{
78Q_OBJECT
79public:
80 KSMServer( const QString& windowManager, bool only_local, bool lockscreen = false );
81 ~KSMServer();
82
83 static KSMServer* self();
84
85 void* watchConnection( IceConn iceConn );
86 void removeConnection( KSMConnection* conn );
87
88 KSMClient* newClient( SmsConn );
89 void deleteClient( KSMClient* client );
90
91 // callbacks
92 void saveYourselfDone( KSMClient* client, bool success );
93 void interactRequest( KSMClient* client, int dialogType );
94 void interactDone( KSMClient* client, bool cancelShutdown );
95 void phase2Request( KSMClient* client );
96
97 // error handling
98 void ioError( IceConn iceConn );
99
100 // notification
101 void clientSetProgram( KSMClient* client );
102 void clientRegistered( const char* previousId );
103
104 // public API
105 void restoreSession( const QString &sessionName );
106 void startDefaultSession();
107 void shutdown( KWorkSpace::ShutdownConfirm confirm,
108 KWorkSpace::ShutdownType sdtype,
109 KWorkSpace::ShutdownMode sdmode );
110
111 virtual void suspendStartup( const QString &app );
112 virtual void resumeStartup( const QString &app );
113
114 void launchWM( const QList< QStringList >& wmStartCommands );
115
116public Q_SLOTS:
117 void cleanUp();
118
119private Q_SLOTS:
120 void newConnection( int socket );
121 void processData( int socket );
122
123 void protectionTimeout();
124 void timeoutQuit();
125 void timeoutWMQuit();
126 void kcmPhase1Timeout();
127 void kcmPhase2Timeout();
128 void pendingShutdownTimeout();
129 void logoutSoundTimeout();
130
131 void autoStart0();
132 void autoStart1();
133 void autoStart2();
134 void tryRestoreNext();
135 void startupSuspendTimeout();
136 void wmProcessChange();
137 void logoutSoundFinished();
138 void autoStart0Done();
139 void autoStart1Done();
140 void autoStart2Done();
141 void kcmPhase1Done();
142 void kcmPhase2Done();
143
144 void defaultLogout();
145 void logoutWithoutConfirmation();
146 void haltWithoutConfirmation();
147 void rebootWithoutConfirmation();
148
149private:
150 void handlePendingInteractions();
151 void completeShutdownOrCheckpoint();
152 void startKilling();
153 void startKillingSubSession();
154 void performStandardKilling();
155 void completeKilling();
156 void completeKillingSubSession();
157 void killWM();
158 void signalSubSessionClosed();
159 void completeKillingWM();
160 void cancelShutdown( KSMClient* c );
161 void killingCompleted();
162 void createLogoutEffectWidget();
163
164 void runUserAutostart();
165
166 void discardSession();
167 void storeSession();
168
169 void startProtection();
170 void endProtection();
171
172 KProcess* startApplication( const QStringList& command,
173 const QString& clientMachine = QString(),
174 const QString& userId = QString(),
175 bool wm = false );
176 void executeCommand( const QStringList& command );
177
178 bool isWM( const KSMClient* client ) const;
179 bool isWM( const QString& command ) const;
180 void selectWm( const QString& kdewm );
181 bool defaultSession() const; // empty session
182 void setupXIOErrorHandler();
183
184 void performLegacySessionSave();
185 void storeLegacySession( KConfig* config );
186 void restoreLegacySession( KConfig* config );
187 void restoreLegacySessionInternal( KConfigGroup* config, char sep = ',' );
188 QStringList windowWmCommand(WId w);
189 QString windowWmClientMachine(WId w);
190 WId windowWmClientLeader(WId w);
191 QByteArray windowSessionId(WId w, WId leader);
192
193 bool checkStartupSuspend();
194 void finishStartup();
195 void resumeStartupInternal();
196 void setupShortcuts();
197
198 // public dcop interface
199
200 public Q_SLOTS: //public dcop interface
201 void logout( int, int, int );
202 bool canShutdown();
203 QString currentSession();
204 void saveCurrentSession();
205 void saveCurrentSessionAs( const QString & );
206 QStringList sessionList();
207 void wmChanged();
208 void saveSubSession( const QString &name, QStringList saveAndClose,
209 QStringList saveOnly = QStringList() );
210 void restoreSubSession( const QString &name );
211
212 Q_SIGNALS:
213 void subSessionClosed();
214 void subSessionCloseCanceled();
215 void subSessionOpened();
216
217 private:
218 QList<KSMListener*> listener;
219 QList<KSMClient*> clients;
220
221 enum State
222 {
223 Idle,
224 LaunchingWM, AutoStart0, KcmInitPhase1, AutoStart1, Restoring, FinishingStartup, // startup
225 Shutdown, Checkpoint, Killing, KillingWM, WaitingForKNotify, // shutdown
226 ClosingSubSession, KillingSubSession, RestoringSubSession
227 };
228 State state;
229 bool dialogActive;
230 bool saveSession;
231 int wmPhase1WaitingCount;
232 int saveType;
233 QMap< QString, int > startupSuspendCount;
234
235 KWorkSpace::ShutdownType shutdownType;
236 KWorkSpace::ShutdownMode shutdownMode;
237 QString bootOption;
238
239 bool clean;
240 KSMClient* clientInteracting;
241 QString wm;
242 QStringList wmCommands;
243 KProcess* wmProcess;
244 QString sessionGroup;
245 QString sessionName;
246 QTimer protectionTimer;
247 QTimer restoreTimer;
248 QString xonCommand;
249 QTimer startupSuspendTimeoutTimer;
250 bool waitAutoStart2;
251 bool waitKcmInit2;
252 QTimer pendingShutdown;
253 QWidget* logoutEffectWidget;
254 KWorkSpace::ShutdownConfirm pendingShutdown_confirm;
255 KWorkSpace::ShutdownType pendingShutdown_sdtype;
256 KWorkSpace::ShutdownMode pendingShutdown_sdmode;
257
258 // ksplash interface
259 void upAndRunning( const QString& msg );
260
261 // sequential startup
262 int appsToStart;
263 int lastAppStarted;
264 QString lastIdStarted;
265
266 QStringList excludeApps;
267
268 WindowMap legacyWindows;
269
270 OrgKdeKLauncherInterface* klauncherSignals;
271 QDBusInterface* kcminitSignals;
272
273 int inhibitCookie;
274
275 //subSession stuff
276 QList<KSMClient*> clientsToKill;
277 QList<KSMClient*> clientsToSave;
278};
279
280#endif
281