Git init
[framework/uifw/xorg/lib/libsm.git] / src / SMlibint.h
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 #ifndef _SMLIBINT_H_
32 #define _SMLIBINT_H_
33
34 #include <X11/Xos.h>
35 #include <X11/Xfuncs.h>
36 #include <X11/Xmd.h>
37 #include <X11/ICE/ICEmsg.h>
38 #include <X11/ICE/ICEproto.h>
39 #include <X11/SM/SMproto.h>
40
41 #include <stdlib.h>
42
43 #ifndef NULL
44 #include <stddef.h>
45 #endif
46
47
48 /*
49  * Vendor & Release
50  */
51
52 #define SmVendorString  "MIT"
53 #define SmReleaseString "1.0"
54
55
56 /*
57  * Pad to a 64 bit boundary
58  */
59
60 #define PAD64(_bytes) ((8 - ((unsigned int) (_bytes) % 8)) % 8)
61
62 #define PADDED_BYTES64(_bytes) (_bytes + PAD64 (_bytes))
63
64
65 /*
66  * Pad to 32 bit boundary
67  */
68
69 #define PAD32(_bytes) ((4 - ((unsigned int) (_bytes) % 4)) % 4)
70
71 #define PADDED_BYTES32(_bytes) (_bytes + PAD32 (_bytes))
72
73
74 /*
75  * Number of 8 byte units in _bytes.
76  */
77
78 #define WORD64COUNT(_bytes) (((unsigned int) ((_bytes) + 7)) >> 3)
79
80
81 /*
82  * Compute the number of bytes for an ARRAY8 representation
83  */
84
85 #define ARRAY8_BYTES(_len) (4 + _len + PAD64 (4 + _len))
86
87
88
89 /*
90  * Byte swapping
91  */
92
93 /* byte swap a long literal */
94 #define lswapl(_val) ((((_val) & 0xff) << 24) |\
95                    (((_val) & 0xff00) << 8) |\
96                    (((_val) & 0xff0000) >> 8) |\
97                    (((_val) >> 24) & 0xff))
98
99 /* byte swap a short literal */
100 #define lswaps(_val) ((((_val) & 0xff) << 8) | (((_val) >> 8) & 0xff))
101
102
103 /*
104  * STORE macros
105  */
106
107 #ifndef WORD64
108
109 #define STORE_CARD32(_pBuf, _val) \
110 { \
111     *((CARD32 *) _pBuf) = _val; \
112     _pBuf += 4; \
113 }
114
115 #else /* WORD64 */
116
117 #define STORE_CARD32(_pBuf, _val) \
118 { \
119     struct { \
120         int value   :32; \
121     } _d; \
122     _d.value = _val; \
123     memcpy (_pBuf, &_d, 4); \
124     _pBuf += 4; \
125 }
126
127 #endif /* WORD64 */
128
129
130 /*
131  * EXTRACT macros
132  */
133
134 #ifndef WORD64
135
136 #define EXTRACT_CARD16(_pBuf, _swap, _val) \
137 { \
138     _val = *((CARD16 *) _pBuf); \
139     _pBuf += 2; \
140     if (_swap) \
141         _val = lswaps (_val); \
142 }
143
144 #define EXTRACT_CARD32(_pBuf, _swap, _val) \
145 { \
146     _val = *((CARD32 *) _pBuf); \
147     _pBuf += 4; \
148     if (_swap) \
149         _val = lswapl (_val); \
150 }
151
152 #else /* WORD64 */
153
154 #define EXTRACT_CARD16(_pBuf, _swap, _val) \
155 { \
156     _val = *(_pBuf + 0) & 0xff;         /* 0xff incase _pBuf is signed */ \
157     _val <<= 8; \
158     _val |= *(_pBuf + 1) & 0xff;\
159     _pBuf += 2; \
160     if (_swap) \
161         _val = lswaps (_val); \
162 }
163
164 #define EXTRACT_CARD32(_pBuf, _swap, _val) \
165 { \
166     _val = *(_pBuf + 0) & 0xff;         /* 0xff incase _pBuf is signed */ \
167     _val <<= 8; \
168     _val |= *(_pBuf + 1) & 0xff;\
169     _val <<= 8; \
170     _val |= *(_pBuf + 2) & 0xff;\
171     _val <<= 8; \
172     _val |= *(_pBuf + 3) & 0xff;\
173     _pBuf += 4; \
174     if (_swap) \
175         _val = lswapl (_val); \
176 }
177
178 #endif /* WORD64 */
179
180
181 /*
182  * Compute the number of bytes for a LISTofPROPERTY representation
183  */
184
185 #define LISTOF_PROP_BYTES(_numProps, _props, _bytes) \
186 { \
187     int _i, _j; \
188     _bytes = 8; \
189     for (_i = 0; _i < _numProps; _i++) \
190     { \
191         _bytes += (8 + ARRAY8_BYTES (strlen (_props[_i]->name)) + \
192             ARRAY8_BYTES (strlen (_props[_i]->type))); \
193 \
194         for (_j = 0; _j < _props[_i]->num_vals; _j++) \
195             _bytes += ARRAY8_BYTES (_props[_i]->vals[_j].length); \
196     } \
197 }
198
199
200 /*
201  * STORE FOO
202  */
203
204 #define STORE_ARRAY8(_pBuf, _len, _array8) \
205 { \
206     STORE_CARD32 (_pBuf, _len); \
207     if (_len) \
208         memcpy (_pBuf, _array8, _len); \
209     _pBuf += _len + PAD64 (4 + _len); \
210 }
211
212 #define STORE_LISTOF_PROPERTY(_pBuf, _count, _props) \
213 { \
214     int _i, _j; \
215     STORE_CARD32 (_pBuf, _count); \
216     _pBuf += 4; \
217     for (_i = 0; _i < _count; _i++) \
218     { \
219         STORE_ARRAY8 (_pBuf, strlen (_props[_i]->name), _props[_i]->name); \
220         STORE_ARRAY8 (_pBuf, strlen (_props[_i]->type), _props[_i]->type); \
221         STORE_CARD32 (_pBuf, _props[_i]->num_vals); \
222         _pBuf += 4; \
223         for (_j = 0; _j < _props[_i]->num_vals; _j++) \
224         { \
225             STORE_ARRAY8 (_pBuf, _props[_i]->vals[_j].length, \
226                 (char *) _props[_i]->vals[_j].value); \
227         } \
228     } \
229 }
230
231
232 /*
233  * EXTRACT FOO
234  */
235
236 #define EXTRACT_ARRAY8(_pBuf, _swap, _len, _array8) \
237 { \
238     EXTRACT_CARD32 (_pBuf, _swap, _len); \
239     _array8 = (char *) malloc (_len + 1); \
240     memcpy (_array8, _pBuf, _len); \
241     _array8[_len] = '\0'; \
242     _pBuf += _len + PAD64 (4 + _len); \
243 }
244
245 #define EXTRACT_ARRAY8_AS_STRING(_pBuf, _swap, _string) \
246 { \
247     CARD32 _len; \
248     EXTRACT_CARD32 (_pBuf, _swap, _len); \
249     _string = (char *) malloc (_len + 1); \
250     memcpy (_string, _pBuf, _len); \
251     _string[_len] = '\0'; \
252     _pBuf += _len + PAD64 (4 + _len); \
253 }
254
255 #define EXTRACT_LISTOF_PROPERTY(_pBuf, _swap, _count, _props) \
256 { \
257     int _i, _j; \
258     EXTRACT_CARD32 (_pBuf, _swap, _count); \
259     _pBuf += 4; \
260     _props = (SmProp **) malloc (_count * sizeof (SmProp *)); \
261     for (_i = 0; _i < _count; _i++) \
262     { \
263         _props[_i] = (SmProp *) malloc (sizeof (SmProp)); \
264         EXTRACT_ARRAY8_AS_STRING (_pBuf, _swap, _props[_i]->name); \
265         EXTRACT_ARRAY8_AS_STRING (_pBuf, _swap, _props[_i]->type); \
266         EXTRACT_CARD32 (_pBuf, _swap, _props[_i]->num_vals); \
267         _pBuf += 4; \
268         _props[_i]->vals = (SmPropValue *) malloc ( \
269             _props[_i]->num_vals * sizeof (SmPropValue)); \
270         for (_j = 0; _j < _props[_i]->num_vals; _j++) \
271         { \
272             char *_temp; \
273             EXTRACT_ARRAY8 (_pBuf, _swap, _props[_i]->vals[_j].length, _temp);\
274             _props[_i]->vals[_j].value = (SmPointer) _temp; \
275         } \
276     } \
277 }
278
279
280 #define SKIP_ARRAY8(_pBuf, _swap) \
281 { \
282     CARD32 _len; \
283     EXTRACT_CARD32 (_pBuf, _swap, _len); \
284     _pBuf += _len + PAD64 (4 + _len); \
285 }
286
287 #define SKIP_LISTOF_PROPERTY(_pBuf, _swap) \
288 { \
289     int _i, _j; \
290     CARD32 _count; \
291     EXTRACT_CARD32 (_pBuf, _swap, _count); \
292     _pBuf += 4; \
293     for (_i = 0; _i < _count; _i++) \
294     { \
295         CARD32 _numvals; \
296         SKIP_ARRAY8 (_pBuf, _swap); \
297         SKIP_ARRAY8 (_pBuf, _swap); \
298         EXTRACT_CARD32 (_pBuf, _swap, _numvals); \
299         _pBuf += 4; \
300         for (_j = 0; _j < _numvals; _j++) \
301             SKIP_ARRAY8 (_pBuf, _swap);\
302     } \
303 }
304
305
306 /*
307  * Client replies not processed by callbacks (we block for them).
308  */
309
310 typedef struct {
311     Status      status;         /* if 1, client successfully registered */
312     char        *client_id;
313 } _SmcRegisterClientReply;
314
315
316 /*
317  * Waiting for Interact
318  */
319
320 typedef struct _SmcInteractWait {
321     SmcInteractProc             interact_proc;
322     SmPointer                   client_data;
323     struct _SmcInteractWait     *next;
324 } _SmcInteractWait;
325
326
327 /*
328  * Waiting for SaveYourselfPhase2
329  */
330
331 typedef struct _SmcPhase2Wait {
332     SmcSaveYourselfPhase2Proc   phase2_proc;
333     SmPointer                   client_data;
334 } _SmcPhase2Wait;
335
336
337 /*
338  * Waiting for Properties Reply
339  */
340
341 typedef struct _SmcPropReplyWait {
342     SmcPropReplyProc            prop_reply_proc;
343     SmPointer                   client_data;
344     struct _SmcPropReplyWait    *next;
345 } _SmcPropReplyWait;
346
347
348
349 /*
350  * Client connection object
351  */
352
353 struct _SmcConn {
354
355     /*
356      * Some state.
357      */
358
359     unsigned int save_yourself_in_progress : 1;
360     unsigned int shutdown_in_progress : 1;
361     unsigned int unused1 : 6;                /* future use */
362     unsigned int unused2 : 8;                /* future use */
363
364
365     /*
366      * We use ICE to esablish a connection with the SM.
367      */
368
369     IceConn             iceConn;
370
371
372     /*
373      * Major and minor versions of the XSMP.
374      */
375
376     int                 proto_major_version;
377     int                 proto_minor_version;
378
379
380     /*
381      * The session manager vendor and release number.
382      */
383
384     char                *vendor;
385     char                *release;
386
387
388     /*
389      * The Client Id uniquely identifies this client to the session manager.
390      */
391
392     char                *client_id;
393
394
395     /*
396      * Callbacks to be invoked when messages arrive from the session manager.
397      * These callbacks are specified at SmcOpenConnection time.
398      */
399
400     SmcCallbacks        callbacks;
401
402
403     /*
404      * We keep track of all Interact Requests sent by the client.  When the
405      * Interact message arrives, we remove it from the list (a FIFO list
406      * is maintained).
407      */
408
409     _SmcInteractWait    *interact_waits;
410
411
412     /*
413      * If we send a SaveYourselfPhase2Request, we wait for SaveYourselfPhase2.
414      */
415
416     _SmcPhase2Wait      *phase2_wait;
417
418
419     /*
420      * We keep track of all Get Properties sent by the client.  When the
421      * Properties Reply arrives, we remove it from the list (a FIFO list
422      * is maintained).
423      */
424
425     _SmcPropReplyWait   *prop_reply_waits;
426 };
427
428
429
430 /*
431  * Session manager connection object
432  */
433
434 struct _SmsConn {
435
436     /*
437      * Some state.
438      */
439
440     unsigned int save_yourself_in_progress : 1;
441     unsigned int can_cancel_shutdown : 1;
442     unsigned int interact_in_progress : 1;
443     unsigned int unused1 : 5;                /* future use */
444     unsigned int unused2 : 8;                /* future use */
445
446
447     /*
448      * We use ICE to esablish a connection with the client.
449      */
450
451     IceConn             iceConn;
452
453
454     /*
455      * Major and minor versions of the XSMP.
456      */
457
458     int                 proto_major_version;
459     int                 proto_minor_version;
460
461
462     /*
463      * The Client Id uniquely identifies this client to the session manager.
464      */
465
466     char                *client_id;
467
468
469     /*
470      * Callbacks to be invoked when messages arrive from the client.
471      */
472
473     SmsCallbacks        callbacks;
474
475
476     /*
477      * What type of interaction is allowed - SmInteractStyle{None,Errors,Any}
478      */
479
480     char                interaction_allowed;
481 };
482
483
484
485 /*
486  * Extern declarations
487  */
488 extern void
489 _SmcProcessMessage(IceConn iceConn, IcePointer clientData, int opcode,
490                    unsigned long length, Bool swap,
491                    IceReplyWaitInfo *replyWait, Bool *replyReadyRet);
492
493 extern void
494 _SmsProcessMessage(IceConn iceConn, IcePointer clientData, int opcode,
495                    unsigned long length, Bool swap);
496
497 extern void
498 _SmcDefaultErrorHandler(SmcConn smcConn, Bool swap, int offendingMinorOpcode,
499                         unsigned long offendingSequence, int errorClass,
500                         int severity, SmPointer values);
501
502 extern void
503 _SmsDefaultErrorHandler(SmsConn smsConn, Bool swap, int offendingMinorOpcode,
504                         unsigned long offendingSequence, int errorClass,
505                         int severity, SmPointer values);
506
507 extern int     _SmcOpcode;
508 extern int     _SmsOpcode;
509
510 extern SmsNewClientProc _SmsNewClientProc;
511 extern SmPointer        _SmsNewClientData;
512
513 extern SmcErrorHandler _SmcErrorHandler;
514 extern SmsErrorHandler _SmsErrorHandler;
515
516 #endif /* _SMLIBINT_H_ */