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 #define STORE_CARD32(_pBuf, _val) \
108 { \
109     *((CARD32 *) _pBuf) = _val; \
110     _pBuf += 4; \
111 }
112 
113 
114 /*
115  * EXTRACT macros
116  */
117 
118 #define EXTRACT_CARD16(_pBuf, _swap, _val) \
119 { \
120     _val = *((CARD16 *) _pBuf); \
121     _pBuf += 2; \
122     if (_swap) \
123         _val = lswaps (_val); \
124 }
125 
126 #define EXTRACT_CARD32(_pBuf, _swap, _val) \
127 { \
128     _val = *((CARD32 *) _pBuf); \
129     _pBuf += 4; \
130     if (_swap) \
131         _val = lswapl (_val); \
132 }
133 
134 
135 /*
136  * Compute the number of bytes for a LISTofPROPERTY representation
137  */
138 
139 #define LISTOF_PROP_BYTES(_numProps, _props, _bytes) \
140 { \
141     int _i, _j; \
142     _bytes = 8; \
143     for (_i = 0; _i < _numProps; _i++) \
144     { \
145 	_bytes += (8 + ARRAY8_BYTES (strlen (_props[_i]->name)) + \
146 	    ARRAY8_BYTES (strlen (_props[_i]->type))); \
147 \
148 	for (_j = 0; _j < _props[_i]->num_vals; _j++) \
149 	    _bytes += ARRAY8_BYTES (_props[_i]->vals[_j].length); \
150     } \
151 }
152 
153 
154 /*
155  * STORE FOO
156  */
157 
158 #define STORE_ARRAY8(_pBuf, _len, _array8) \
159 { \
160     STORE_CARD32 (_pBuf, (CARD32) _len); \
161     if (_len) \
162         memcpy (_pBuf, _array8, _len); \
163     _pBuf += _len + PAD64 (4 + _len); \
164 }
165 
166 #define STORE_LISTOF_PROPERTY(_pBuf, _count, _props) \
167 { \
168     int _i, _j; \
169     STORE_CARD32 (_pBuf, _count); \
170     _pBuf += 4; \
171     for (_i = 0; _i < _count; _i++) \
172     { \
173         STORE_ARRAY8 (_pBuf, strlen (_props[_i]->name), _props[_i]->name); \
174         STORE_ARRAY8 (_pBuf, strlen (_props[_i]->type), _props[_i]->type); \
175         STORE_CARD32 (_pBuf, _props[_i]->num_vals); \
176         _pBuf += 4; \
177         for (_j = 0; _j < _props[_i]->num_vals; _j++) \
178 	{ \
179             STORE_ARRAY8 (_pBuf, _props[_i]->vals[_j].length, \
180 		(char *) _props[_i]->vals[_j].value); \
181 	} \
182     } \
183 }
184 
185 
186 /*
187  * Client replies not processed by callbacks (we block for them).
188  */
189 
190 typedef struct {
191     Status  	status;		/* if 1, client successfully registered */
192     char	*client_id;
193 } _SmcRegisterClientReply;
194 
195 
196 /*
197  * Waiting for Interact
198  */
199 
200 typedef struct _SmcInteractWait {
201     SmcInteractProc		interact_proc;
202     SmPointer			client_data;
203     struct _SmcInteractWait 	*next;
204 } _SmcInteractWait;
205 
206 
207 /*
208  * Waiting for SaveYourselfPhase2
209  */
210 
211 typedef struct _SmcPhase2Wait {
212     SmcSaveYourselfPhase2Proc	phase2_proc;
213     SmPointer			client_data;
214 } _SmcPhase2Wait;
215 
216 
217 /*
218  * Waiting for Properties Reply
219  */
220 
221 typedef struct _SmcPropReplyWait {
222     SmcPropReplyProc		prop_reply_proc;
223     SmPointer			client_data;
224     struct _SmcPropReplyWait 	*next;
225 } _SmcPropReplyWait;
226 
227 
228 
229 /*
230  * Client connection object
231  */
232 
233 struct _SmcConn {
234 
235     /*
236      * Some state.
237      */
238 
239     unsigned int save_yourself_in_progress : 1;
240     unsigned int shutdown_in_progress : 1;
241     unsigned int unused1 : 6;		     /* future use */
242     unsigned int unused2 : 8;		     /* future use */
243 
244 
245     /*
246      * We use ICE to esablish a connection with the SM.
247      */
248 
249     IceConn		iceConn;
250 
251 
252     /*
253      * Major and minor versions of the XSMP.
254      */
255 
256     int			proto_major_version;
257     int			proto_minor_version;
258 
259 
260     /*
261      * The session manager vendor and release number.
262      */
263 
264     char		*vendor;
265     char		*release;
266 
267 
268     /*
269      * The Client Id uniquely identifies this client to the session manager.
270      */
271 
272     char		*client_id;
273 
274 
275     /*
276      * Callbacks to be invoked when messages arrive from the session manager.
277      * These callbacks are specified at SmcOpenConnection time.
278      */
279 
280     SmcCallbacks	callbacks;
281 
282 
283     /*
284      * We keep track of all Interact Requests sent by the client.  When the
285      * Interact message arrives, we remove it from the list (a FIFO list
286      * is maintained).
287      */
288 
289     _SmcInteractWait	*interact_waits;
290 
291 
292     /*
293      * If we send a SaveYourselfPhase2Request, we wait for SaveYourselfPhase2.
294      */
295 
296     _SmcPhase2Wait	*phase2_wait;
297 
298 
299     /*
300      * We keep track of all Get Properties sent by the client.  When the
301      * Properties Reply arrives, we remove it from the list (a FIFO list
302      * is maintained).
303      */
304 
305     _SmcPropReplyWait	*prop_reply_waits;
306 };
307 
308 
309 
310 /*
311  * Session manager connection object
312  */
313 
314 struct _SmsConn {
315 
316     /*
317      * Some state.
318      */
319 
320     unsigned int save_yourself_in_progress : 1;
321     unsigned int can_cancel_shutdown : 1;
322     unsigned int interact_in_progress : 1;
323     unsigned int unused1 : 5;		     /* future use */
324     unsigned int unused2 : 8;		     /* future use */
325 
326 
327     /*
328      * We use ICE to esablish a connection with the client.
329      */
330 
331     IceConn		iceConn;
332 
333 
334     /*
335      * Major and minor versions of the XSMP.
336      */
337 
338     int			proto_major_version;
339     int			proto_minor_version;
340 
341 
342     /*
343      * The Client Id uniquely identifies this client to the session manager.
344      */
345 
346     char		*client_id;
347 
348 
349     /*
350      * Callbacks to be invoked when messages arrive from the client.
351      */
352 
353     SmsCallbacks	callbacks;
354 
355 
356     /*
357      * What type of interaction is allowed - SmInteractStyle{None,Errors,Any}
358      */
359 
360     char		interaction_allowed;
361 };
362 
363 
364 
365 /*
366  * Extern declarations
367  */
368 extern void
369 _SmcProcessMessage(IceConn iceConn, IcePointer clientData, int opcode,
370 		   unsigned long length, Bool swap,
371 		   IceReplyWaitInfo *replyWait, Bool *replyReadyRet);
372 
373 extern void
374 _SmsProcessMessage(IceConn iceConn, IcePointer clientData, int opcode,
375 		   unsigned long length, Bool swap);
376 
377 extern void
378 _SmcDefaultErrorHandler(SmcConn smcConn, Bool swap, int offendingMinorOpcode,
379 			unsigned long offendingSequence, int errorClass,
380 			int severity, SmPointer values);
381 
382 extern void
383 _SmsDefaultErrorHandler(SmsConn smsConn, Bool swap, int offendingMinorOpcode,
384 			unsigned long offendingSequence, int errorClass,
385 			int severity, SmPointer values);
386 
387 extern int     _SmcOpcode;
388 extern int     _SmsOpcode;
389 
390 extern SmsNewClientProc	_SmsNewClientProc;
391 extern SmPointer	_SmsNewClientData;
392 
393 extern SmcErrorHandler _SmcErrorHandler;
394 extern SmsErrorHandler _SmsErrorHandler;
395 
396 #endif /* _SMLIBINT_H_ */
397