upload tizen2.0 source
[framework/uifw/xorg/lib/libsm.git] / src / sm_manager.c
1 /*
2
3 Copyright 1993, 1998  The Open Group
4
5 Permission to use, copy, modify, distribute, and sell this software and its
6 documentation for any purpose is hereby granted without fee, provided that
7 the above copyright notice appear in all copies and that both that
8 copyright notice and this permission notice appear in supporting
9 documentation.
10
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
13
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
17 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
21 Except as contained in this notice, the name of The Open Group shall not be
22 used in advertising or otherwise to promote the sale, use or other dealings
23 in this Software without prior written authorization from The Open Group.
24
25 */
26
27 /*
28  * Author: Ralph Mor, X Consortium
29  */
30
31 #ifdef HAVE_CONFIG_H
32 #include <config.h>
33 #endif
34 #include <X11/SM/SMlib.h>
35 #include "SMlibint.h"
36 #include <X11/Xtrans/Xtrans.h>
37
38 #ifdef __UNIXWARE__
39 #undef shutdown
40 #endif
41
42 \f
43
44 static Status
45 _SmsProtocolSetupProc (IceConn    iceConn,
46                        int majorVersion,
47                        int minorVersion,
48                        char *vendor,
49                        char *release,
50                        IcePointer *clientDataRet,
51                        char **failureReasonRet)
52 {
53     SmsConn             smsConn;
54     unsigned long       mask;
55     Status              status;
56
57     /*
58      * vendor/release are undefined for ProtocolSetup in XSMP.
59      */
60
61     if (vendor)
62         free (vendor);
63     if (release)
64         free (release);
65
66
67     /*
68      * Allocate new SmsConn.
69      */
70
71     if ((smsConn = malloc (sizeof (struct _SmsConn))) == NULL)
72     {
73         const char *str = "Memory allocation failed";
74
75         *failureReasonRet = strdup (str);
76
77         return (0);
78     }
79
80     smsConn->iceConn = iceConn;
81     smsConn->proto_major_version = majorVersion;
82     smsConn->proto_minor_version = minorVersion;
83     smsConn->client_id = NULL;
84
85     smsConn->save_yourself_in_progress = False;
86     smsConn->interaction_allowed = SmInteractStyleNone;
87     smsConn->can_cancel_shutdown = False;
88     smsConn->interact_in_progress = False;
89
90     *clientDataRet = (IcePointer) smsConn;
91
92
93     /*
94      * Now give the session manager the new smsConn and get back the
95      * callbacks to invoke when messages arrive from the client.
96      *
97      * In the future, we can use the mask return value to check
98      * if the SM is expecting an older rev of SMlib.
99      */
100
101     bzero ((char *) &smsConn->callbacks, sizeof (SmsCallbacks));
102
103     status = (*_SmsNewClientProc) (smsConn, _SmsNewClientData,
104         &mask, &smsConn->callbacks, failureReasonRet);
105
106     return (status);
107 }
108
109
110 \f
111
112 Status
113 SmsInitialize(const char *vendor, const char *release,
114               SmsNewClientProc newClientProc,
115               SmPointer managerData, IceHostBasedAuthProc hostBasedAuthProc,
116               int errorLength, char *errorStringRet)
117 {
118     const char *auth_names[] = {"MIT-MAGIC-COOKIE-1"};
119     IcePaAuthProc auth_procs[] = {_IcePaMagicCookie1Proc};
120     int auth_count = 1;
121
122     IcePaVersionRec versions[] = {
123         {SmProtoMajor, SmProtoMinor, _SmsProcessMessage}
124     };
125     int version_count = 1;
126
127     if (errorStringRet && errorLength > 0)
128         *errorStringRet = '\0';
129
130     if (!newClientProc)
131     {
132         if (errorStringRet && errorLength > 0) {
133             strncpy (errorStringRet,
134                      "The SmsNewClientProc callback can't be NULL",
135                      errorLength);
136             errorStringRet[errorLength - 1] = '\0';
137         }
138
139         return (0);
140     }
141
142     if (!_SmsOpcode)
143     {
144
145         if ((_SmsOpcode = IceRegisterForProtocolReply ("XSMP",
146             vendor, release, version_count, versions,
147             auth_count, auth_names, auth_procs, hostBasedAuthProc,
148             _SmsProtocolSetupProc,
149             NULL,       /* IceProtocolActivateProc - we don't care about
150                            when the Protocol Reply is sent, because the
151                            session manager can not immediately send a
152                            message - it must wait for RegisterClient. */
153             NULL        /* IceIOErrorProc */
154             )) < 0)
155         {
156             if (errorStringRet && errorLength > 0) {
157                 strncpy (errorStringRet,
158                          "Could not register XSMP protocol with ICE",
159                          errorLength);
160                 errorStringRet[errorLength - 1] = '\0';
161             }
162             return (0);
163         }
164     }
165
166     _SmsNewClientProc = newClientProc;
167     _SmsNewClientData = managerData;
168
169     return (1);
170 }
171
172
173 \f
174 char *
175 SmsClientHostName(SmsConn smsConn)
176 {
177     return (IceGetPeerName (smsConn->iceConn));
178 }
179
180
181 \f
182 Status
183 SmsRegisterClientReply(SmsConn smsConn, char *clientId)
184 {
185     IceConn                     iceConn = smsConn->iceConn;
186     int                         extra;
187     smRegisterClientReplyMsg    *pMsg;
188     char                        *pData;
189
190     if ((smsConn->client_id = strdup (clientId)) == NULL)
191     {
192         return (0);
193     }
194
195     extra = ARRAY8_BYTES (strlen (clientId));
196
197     IceGetHeaderExtra (iceConn, _SmsOpcode, SM_RegisterClientReply,
198         SIZEOF (smRegisterClientReplyMsg), WORD64COUNT (extra),
199         smRegisterClientReplyMsg, pMsg, pData);
200
201     STORE_ARRAY8 (pData, strlen (clientId), clientId);
202
203     IceFlush (iceConn);
204
205     return (1);
206 }
207
208
209 \f
210 void
211 SmsSaveYourself(SmsConn smsConn, int saveType, Bool shutdown,
212                 int interactStyle, Bool fast)
213 {
214     IceConn             iceConn = smsConn->iceConn;
215     smSaveYourselfMsg   *pMsg;
216
217     IceGetHeader (iceConn, _SmsOpcode, SM_SaveYourself,
218         SIZEOF (smSaveYourselfMsg), smSaveYourselfMsg, pMsg);
219
220     pMsg->saveType = saveType;
221     pMsg->shutdown = shutdown;
222     pMsg->interactStyle = interactStyle;
223     pMsg->fast = fast;
224
225     IceFlush (iceConn);
226
227     smsConn->save_yourself_in_progress = True;
228
229     if (interactStyle == SmInteractStyleNone ||
230         interactStyle == SmInteractStyleErrors ||
231         interactStyle == SmInteractStyleAny)
232     {
233         smsConn->interaction_allowed = interactStyle;
234     }
235     else
236     {
237         smsConn->interaction_allowed = SmInteractStyleNone;
238     }
239
240     smsConn->can_cancel_shutdown = shutdown &&
241         (interactStyle == SmInteractStyleAny ||
242         interactStyle == SmInteractStyleErrors);
243 }
244
245
246 \f
247 void
248 SmsSaveYourselfPhase2(SmsConn smsConn)
249 {
250     IceConn     iceConn = smsConn->iceConn;
251
252     IceSimpleMessage (iceConn, _SmsOpcode, SM_SaveYourselfPhase2);
253     IceFlush (iceConn);
254 }
255
256
257 \f
258 void
259 SmsInteract(SmsConn smsConn)
260 {
261     IceConn     iceConn = smsConn->iceConn;
262
263     IceSimpleMessage (iceConn, _SmsOpcode, SM_Interact);
264     IceFlush (iceConn);
265
266     smsConn->interact_in_progress = True;
267 }
268
269
270 \f
271 void
272 SmsDie(SmsConn smsConn)
273 {
274     IceConn     iceConn = smsConn->iceConn;
275
276     IceSimpleMessage (iceConn, _SmsOpcode, SM_Die);
277     IceFlush (iceConn);
278 }
279
280
281 \f
282 void
283 SmsSaveComplete(SmsConn smsConn)
284 {
285     IceConn     iceConn = smsConn->iceConn;
286
287     IceSimpleMessage (iceConn, _SmsOpcode, SM_SaveComplete);
288     IceFlush (iceConn);
289 }
290
291
292 \f
293 void
294 SmsShutdownCancelled(SmsConn smsConn)
295 {
296     IceConn     iceConn = smsConn->iceConn;
297
298     IceSimpleMessage (iceConn, _SmsOpcode, SM_ShutdownCancelled);
299     IceFlush (iceConn);
300
301     smsConn->can_cancel_shutdown = False;
302 }
303
304
305 \f
306 void
307 SmsReturnProperties(SmsConn smsConn, int numProps, SmProp **props)
308 {
309     IceConn                     iceConn = smsConn->iceConn;
310     int                         bytes;
311     smPropertiesReplyMsg        *pMsg;
312     char                        *pBuf;
313     char                        *pStart;
314
315     IceGetHeader (iceConn, _SmsOpcode, SM_PropertiesReply,
316         SIZEOF (smPropertiesReplyMsg), smPropertiesReplyMsg, pMsg);
317
318     LISTOF_PROP_BYTES (numProps, props, bytes);
319     pMsg->length += WORD64COUNT (bytes);
320
321     pBuf = pStart = IceAllocScratch (iceConn, bytes);
322
323     STORE_LISTOF_PROPERTY (pBuf, numProps, props);
324
325     IceWriteData (iceConn, bytes, pStart);
326     IceFlush (iceConn);
327 }
328
329
330 \f
331 void
332 SmsCleanUp(SmsConn smsConn)
333 {
334     IceProtocolShutdown (smsConn->iceConn, _SmsOpcode);
335
336     if (smsConn->client_id)
337         free (smsConn->client_id);
338
339     free (smsConn);
340 }