1/*
2
3Copyright 1993, 1998  The Open Group
4
5Permission to use, copy, modify, distribute, and sell this software and its
6documentation for any purpose is hereby granted without fee, provided that
7the above copyright notice appear in all copies and that both that
8copyright notice and this permission notice appear in supporting
9documentation.
10
11The above copyright notice and this permission notice shall be included in
12all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
17OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
21Except as contained in this notice, the name of The Open Group shall not be
22used in advertising or otherwise to promote the sale, use or other dealings
23in 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 * Send an ARRAY8 that doesn't fit in the iceConn send buffer.
187 */
188#define SEND_ARRAY8(_iceConn, _len, _array8) \
189{ \
190    char _padding[7] = { 0 }; \
191    CARD32 _array_len = (CARD32) _len;  \
192    IceWriteData32 (_iceConn, 4, &_array_len); \
193    if (_len) \
194        IceSendData (_iceConn, _len, (char *) _array8); \
195    IceSendData (_iceConn, PAD64 (4 + _len), _padding); \
196}
197
198
199/*
200 * Client replies not processed by callbacks (we block for them).
201 */
202
203typedef struct {
204    Status  	status;		/* if 1, client successfully registered */
205    char	*client_id;
206} _SmcRegisterClientReply;
207
208
209/*
210 * Waiting for Interact
211 */
212
213typedef struct _SmcInteractWait {
214    SmcInteractProc		interact_proc;
215    SmPointer			client_data;
216    struct _SmcInteractWait 	*next;
217} _SmcInteractWait;
218
219
220/*
221 * Waiting for SaveYourselfPhase2
222 */
223
224typedef struct _SmcPhase2Wait {
225    SmcSaveYourselfPhase2Proc	phase2_proc;
226    SmPointer			client_data;
227} _SmcPhase2Wait;
228
229
230/*
231 * Waiting for Properties Reply
232 */
233
234typedef struct _SmcPropReplyWait {
235    SmcPropReplyProc		prop_reply_proc;
236    SmPointer			client_data;
237    struct _SmcPropReplyWait 	*next;
238} _SmcPropReplyWait;
239
240
241
242/*
243 * Client connection object
244 */
245
246struct _SmcConn {
247
248    /*
249     * Some state.
250     */
251
252    unsigned int save_yourself_in_progress : 1;
253    unsigned int shutdown_in_progress : 1;
254    unsigned int unused1 : 6;		     /* future use */
255    unsigned int unused2 : 8;		     /* future use */
256
257
258    /*
259     * We use ICE to esablish a connection with the SM.
260     */
261
262    IceConn		iceConn;
263
264
265    /*
266     * Major and minor versions of the XSMP.
267     */
268
269    int			proto_major_version;
270    int			proto_minor_version;
271
272
273    /*
274     * The session manager vendor and release number.
275     */
276
277    char		*vendor;
278    char		*release;
279
280
281    /*
282     * The Client Id uniquely identifies this client to the session manager.
283     */
284
285    char		*client_id;
286
287
288    /*
289     * Callbacks to be invoked when messages arrive from the session manager.
290     * These callbacks are specified at SmcOpenConnection time.
291     */
292
293    SmcCallbacks	callbacks;
294
295
296    /*
297     * We keep track of all Interact Requests sent by the client.  When the
298     * Interact message arrives, we remove it from the list (a FIFO list
299     * is maintained).
300     */
301
302    _SmcInteractWait	*interact_waits;
303
304
305    /*
306     * If we send a SaveYourselfPhase2Request, we wait for SaveYourselfPhase2.
307     */
308
309    _SmcPhase2Wait	*phase2_wait;
310
311
312    /*
313     * We keep track of all Get Properties sent by the client.  When the
314     * Properties Reply arrives, we remove it from the list (a FIFO list
315     * is maintained).
316     */
317
318    _SmcPropReplyWait	*prop_reply_waits;
319};
320
321
322
323/*
324 * Session manager connection object
325 */
326
327struct _SmsConn {
328
329    /*
330     * Some state.
331     */
332
333    unsigned int save_yourself_in_progress : 1;
334    unsigned int can_cancel_shutdown : 1;
335    unsigned int interact_in_progress : 1;
336    unsigned int unused1 : 5;		     /* future use */
337    unsigned int unused2 : 8;		     /* future use */
338
339
340    /*
341     * We use ICE to esablish a connection with the client.
342     */
343
344    IceConn		iceConn;
345
346
347    /*
348     * Major and minor versions of the XSMP.
349     */
350
351    int			proto_major_version;
352    int			proto_minor_version;
353
354
355    /*
356     * The Client Id uniquely identifies this client to the session manager.
357     */
358
359    char		*client_id;
360
361
362    /*
363     * Callbacks to be invoked when messages arrive from the client.
364     */
365
366    SmsCallbacks	callbacks;
367
368
369    /*
370     * What type of interaction is allowed - SmInteractStyle{None,Errors,Any}
371     */
372
373    char		interaction_allowed;
374};
375
376
377
378/*
379 * Extern declarations
380 */
381extern void
382_SmcProcessMessage(IceConn iceConn, IcePointer clientData, int opcode,
383		   unsigned long length, Bool swap,
384		   IceReplyWaitInfo *replyWait, Bool *replyReadyRet);
385
386extern void
387_SmsProcessMessage(IceConn iceConn, IcePointer clientData, int opcode,
388		   unsigned long length, Bool swap);
389
390extern void
391_SmcDefaultErrorHandler(SmcConn smcConn, Bool swap, int offendingMinorOpcode,
392			unsigned long offendingSequence, int errorClass,
393			int severity, SmPointer values);
394
395extern void
396_SmsDefaultErrorHandler(SmsConn smsConn, Bool swap, int offendingMinorOpcode,
397			unsigned long offendingSequence, int errorClass,
398			int severity, SmPointer values);
399
400extern int     _SmcOpcode;
401extern int     _SmsOpcode;
402
403extern SmsNewClientProc	_SmsNewClientProc;
404extern SmPointer	_SmsNewClientData;
405
406extern SmcErrorHandler _SmcErrorHandler;
407extern SmsErrorHandler _SmsErrorHandler;
408
409#endif /* _SMLIBINT_H_ */
410