1266e564dSmrg/******************************************************************************
2266e564dSmrg
3266e564dSmrg
4266e564dSmrgCopyright 1993, 1998  The Open Group
5266e564dSmrg
6266e564dSmrgPermission to use, copy, modify, distribute, and sell this software and its
7266e564dSmrgdocumentation for any purpose is hereby granted without fee, provided that
8266e564dSmrgthe above copyright notice appear in all copies and that both that
9266e564dSmrgcopyright notice and this permission notice appear in supporting
10266e564dSmrgdocumentation.
11266e564dSmrg
12266e564dSmrgThe above copyright notice and this permission notice shall be included in
13266e564dSmrgall copies or substantial portions of the Software.
14266e564dSmrg
15266e564dSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16266e564dSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17266e564dSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
18266e564dSmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
19266e564dSmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20266e564dSmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21266e564dSmrg
22266e564dSmrgExcept as contained in this notice, the name of The Open Group shall not be
23266e564dSmrgused in advertising or otherwise to promote the sale, use or other dealings
24266e564dSmrgin this Software without prior written authorization from The Open Group.
25266e564dSmrg
26266e564dSmrgAuthor: Ralph Mor, X Consortium
27266e564dSmrg******************************************************************************/
28266e564dSmrg
29266e564dSmrg#ifndef _ICEMSG_H_
30266e564dSmrg#define _ICEMSG_H_
31266e564dSmrg
32266e564dSmrg#include <X11/Xfuncproto.h>
33266e564dSmrg
34266e564dSmrg#include <X11/ICE/ICEconn.h>
35266e564dSmrg
361009a292Smrg#include <assert.h>
371009a292Smrg#if !defined(__cplusplus) && !defined(static_assert)
381009a292Smrg#define static_assert(cond, msg) /* skip for non-C11 compilers */
391009a292Smrg#endif
401009a292Smrg
41266e564dSmrg_XFUNCPROTOBEGIN
42266e564dSmrg
43266e564dSmrg/*
44266e564dSmrg * Function prototypes for internal ICElib functions
45266e564dSmrg */
46266e564dSmrg
47266e564dSmrgextern Status _IceRead (
48266e564dSmrg    IceConn		/* iceConn */,
49266e564dSmrg    unsigned long	/* nbytes */,
50266e564dSmrg    char *		/* ptr */
51266e564dSmrg);
52266e564dSmrg
53266e564dSmrgextern void _IceReadSkip (
54266e564dSmrg    IceConn		/* iceConn */,
55266e564dSmrg    unsigned long	/* nbytes */
56266e564dSmrg);
57266e564dSmrg
58266e564dSmrgextern void _IceWrite (
59266e564dSmrg    IceConn		/* iceConn */,
60266e564dSmrg    unsigned long	/* nbytes */,
61266e564dSmrg    char *		/* ptr */
62266e564dSmrg);
63266e564dSmrg
64266e564dSmrg
65266e564dSmrgextern void _IceErrorBadMinor (
66266e564dSmrg    IceConn		/* iceConn */,
67266e564dSmrg    int			/* majorOpcode */,
68266e564dSmrg    int			/* offendingMinor */,
69266e564dSmrg    int			/* severity */
70266e564dSmrg);
71266e564dSmrg
72266e564dSmrgextern void _IceErrorBadState (
73266e564dSmrg    IceConn		/* iceConn */,
74266e564dSmrg    int			/* majorOpcode */,
75266e564dSmrg    int			/* offendingMinor */,
76266e564dSmrg    int			/* severity */
77266e564dSmrg);
78266e564dSmrg
79266e564dSmrgextern void _IceErrorBadLength (
80266e564dSmrg    IceConn		/* iceConn */,
81266e564dSmrg    int			/* majorOpcode */,
82266e564dSmrg    int			/* offendingMinor */,
83266e564dSmrg    int			/* severity */
84266e564dSmrg);
85266e564dSmrg
86266e564dSmrgextern void _IceErrorBadValue (
87266e564dSmrg    IceConn		/* iceConn */,
88266e564dSmrg    int			/* majorOpcode */,
89266e564dSmrg    int			/* offendingMinor */,
90266e564dSmrg    int			/* offset */,
91266e564dSmrg    int			/* length */,
92266e564dSmrg    IcePointer		/* value */
93266e564dSmrg);
94266e564dSmrg
95c5629e66Smrgextern IcePoAuthStatus _IcePoMagicCookie1Proc (
96c5629e66Smrg    IceConn		/* iceConn */,
97c5629e66Smrg    IcePointer *	/* authStatePtr */,
98c5629e66Smrg    Bool 		/* cleanUp */,
99c5629e66Smrg    Bool		/* swap */,
100c5629e66Smrg    int     		/* authDataLen */,
101c5629e66Smrg    IcePointer		/* authData */,
102c5629e66Smrg    int *		/* replyDataLenRet */,
103c5629e66Smrg    IcePointer *	/* replyDataRet */,
104c5629e66Smrg    char **		/* errorStringRet */
105c5629e66Smrg);
106c5629e66Smrg
107c5629e66Smrgextern IcePaAuthStatus _IcePaMagicCookie1Proc (
108c5629e66Smrg    IceConn		/* iceConn */,
109c5629e66Smrg    IcePointer *	/* authStatePtr */,
110c5629e66Smrg    Bool		/* swap */,
111c5629e66Smrg    int     		/* authDataLen */,
112c5629e66Smrg    IcePointer		/* authData */,
113c5629e66Smrg    int *		/* replyDataLenRet */,
114c5629e66Smrg    IcePointer *	/* replyDataRet */,
115c5629e66Smrg    char **		/* errorStringRet */
116c5629e66Smrg);
117c5629e66Smrg
118266e564dSmrg
119266e564dSmrg/*
120266e564dSmrg * Macro to check if IO operations are valid on an ICE connection.
121266e564dSmrg */
122266e564dSmrg
123266e564dSmrg#define IceValidIO(_iceConn) _iceConn->io_ok
124266e564dSmrg
125266e564dSmrg
126266e564dSmrg/*
127266e564dSmrg * Macros for writing messages.
128266e564dSmrg */
129266e564dSmrg
130266e564dSmrg#define IceGetHeader(_iceConn, _major, _minor, _headerSize, _msgType, _pMsg) \
1311009a292Smrgdo { \
1321009a292Smrg    static_assert(_headerSize <= 1024, \
1331009a292Smrg                  "Header size larger than ICE_OUTBUFSIZE"); \
134266e564dSmrg    if ((_iceConn->outbufptr + _headerSize) > _iceConn->outbufmax) \
135266e564dSmrg        IceFlush (_iceConn); \
136266e564dSmrg    _pMsg = (_msgType *) _iceConn->outbufptr; \
137266e564dSmrg    _pMsg->majorOpcode = _major; \
138266e564dSmrg    _pMsg->minorOpcode = _minor; \
139266e564dSmrg    _pMsg->length = (_headerSize - SIZEOF (iceMsg)) >> 3; \
140266e564dSmrg    _iceConn->outbufptr += _headerSize; \
1411009a292Smrg    _iceConn->send_sequence++; \
1421009a292Smrg} while (0)
143266e564dSmrg
144266e564dSmrg#define IceGetHeaderExtra(_iceConn, _major, _minor, _headerSize, _extra, _msgType, _pMsg, _pData) \
1451009a292Smrgdo { \
1461009a292Smrg    static_assert(_headerSize <= 1024, \
1471009a292Smrg                  "Header size larger than ICE_OUTBUFSIZE"); \
148266e564dSmrg    if ((_iceConn->outbufptr + \
149266e564dSmrg	_headerSize + ((_extra) << 3)) > _iceConn->outbufmax) \
150266e564dSmrg        IceFlush (_iceConn); \
151266e564dSmrg    _pMsg = (_msgType *) _iceConn->outbufptr; \
1521009a292Smrg    _iceConn->outbufptr += _headerSize; \
1531009a292Smrg    if ((_iceConn->outbufptr + ((_extra) << 3)) <= _iceConn->outbufmax) { \
1541009a292Smrg        _pData = _iceConn->outbufptr; \
1551009a292Smrg        _iceConn->outbufptr += ((_extra) << 3); \
1561009a292Smrg    } \
157266e564dSmrg    else \
158266e564dSmrg        _pData = NULL; \
159266e564dSmrg    _pMsg->majorOpcode = _major; \
160266e564dSmrg    _pMsg->minorOpcode = _minor; \
161266e564dSmrg    _pMsg->length = ((_headerSize - SIZEOF (iceMsg)) >> 3) + (_extra); \
1621009a292Smrg    _iceConn->send_sequence++; \
1631009a292Smrg} while (0)
164266e564dSmrg
165266e564dSmrg#define IceSimpleMessage(_iceConn, _major, _minor) \
166266e564dSmrg{ \
167266e564dSmrg    iceMsg *_pMsg; \
168266e564dSmrg    IceGetHeader (_iceConn, _major, _minor, SIZEOF (iceMsg), iceMsg, _pMsg); \
169266e564dSmrg}
170266e564dSmrg
171266e564dSmrg#define IceErrorHeader(_iceConn, _offendingMajorOpcode, _offendingMinorOpcode, _offendingSequenceNum, _severity, _errorClass, _dataLength) \
172266e564dSmrg{ \
173266e564dSmrg    iceErrorMsg	*_pMsg; \
174266e564dSmrg\
175266e564dSmrg    IceGetHeader (_iceConn, _offendingMajorOpcode, ICE_Error, \
176266e564dSmrg	SIZEOF (iceErrorMsg), iceErrorMsg, _pMsg); \
177266e564dSmrg    _pMsg->length += (_dataLength); \
178fb5e8d76Smrg    _pMsg->offendingMinorOpcode = (CARD8) _offendingMinorOpcode; \
179fb5e8d76Smrg    _pMsg->severity = (CARD8) _severity; \
180fb5e8d76Smrg    _pMsg->offendingSequenceNum = (CARD32) _offendingSequenceNum; \
181fb5e8d76Smrg    _pMsg->errorClass = (CARD16) _errorClass; \
182266e564dSmrg}
183266e564dSmrg
184266e564dSmrg
185266e564dSmrg/*
186266e564dSmrg * Write data into the ICE output buffer.
187266e564dSmrg */
188266e564dSmrg
189266e564dSmrg#define IceWriteData(_iceConn, _bytes, _data) \
190266e564dSmrg{ \
191266e564dSmrg    if ((_iceConn->outbufptr + (_bytes)) > _iceConn->outbufmax) \
192266e564dSmrg    { \
193266e564dSmrg	IceFlush (_iceConn); \
194266e564dSmrg        _IceWrite (_iceConn, (unsigned long) (_bytes), _data); \
195266e564dSmrg    } \
196266e564dSmrg    else \
197266e564dSmrg    { \
198266e564dSmrg        memcpy (_iceConn->outbufptr, _data, _bytes); \
199266e564dSmrg        _iceConn->outbufptr += (_bytes); \
200266e564dSmrg    } \
201266e564dSmrg}
202266e564dSmrg
203266e564dSmrg#define IceWriteData16(_iceConn, _bytes, _data) \
204266e564dSmrg    IceWriteData (_iceConn, _bytes, (char *) _data)
205266e564dSmrg
206266e564dSmrg#define IceWriteData32(_iceConn, _bytes, _data) \
207266e564dSmrg    IceWriteData (_iceConn, _bytes, (char *) _data)
208266e564dSmrg
209266e564dSmrg
210266e564dSmrg/*
211266e564dSmrg * The IceSendData macro bypasses copying the data to the
212266e564dSmrg * ICE connection buffer and sends the data directly.  If necessary,
213266e564dSmrg * the ICE connection buffer is first flushed.
214266e564dSmrg */
215266e564dSmrg
216266e564dSmrg#define IceSendData(_iceConn, _bytes, _data) \
217266e564dSmrg{ \
218266e564dSmrg    if (_iceConn->outbufptr > _iceConn->outbuf) \
219266e564dSmrg	IceFlush (_iceConn); \
220266e564dSmrg    _IceWrite (_iceConn, (unsigned long) (_bytes), _data); \
221266e564dSmrg}
222266e564dSmrg
223266e564dSmrg
224266e564dSmrg/*
225266e564dSmrg * Write pad bytes.  Used to force 32 or 64 bit alignment.
2269ef0b394Smrg * A maximum of 7 pad bytes can be specified.
227266e564dSmrg */
228266e564dSmrg
229266e564dSmrg#define IceWritePad(_iceConn, _bytes) \
230266e564dSmrg{ \
231a3129944Smrg    char _dummy[7] = { 0 }; \
232a3129944Smrg    IceWriteData (_iceConn, (_bytes), _dummy); \
233266e564dSmrg}
234266e564dSmrg
235266e564dSmrg
236266e564dSmrg/*
237266e564dSmrg * Macros for reading messages.
238266e564dSmrg */
239266e564dSmrg
240266e564dSmrg#define IceReadCompleteMessage(_iceConn, _headerSize, _msgType, _pMsg, _pData)\
241266e564dSmrg{ \
242266e564dSmrg    unsigned long _bytes; \
243266e564dSmrg    IceReadMessageHeader (_iceConn, _headerSize, _msgType, _pMsg); \
244266e564dSmrg    _bytes = (_pMsg->length << 3) - (_headerSize - SIZEOF (iceMsg)); \
245266e564dSmrg    if ((_iceConn->inbufmax - _iceConn->inbufptr) >= _bytes) \
246266e564dSmrg    { \
247266e564dSmrg	_IceRead (_iceConn, _bytes, _iceConn->inbufptr); \
248266e564dSmrg	_pData = _iceConn->inbufptr; \
249266e564dSmrg	_iceConn->inbufptr += _bytes; \
250266e564dSmrg    } \
251266e564dSmrg    else \
252266e564dSmrg    { \
253fb5e8d76Smrg	_pData = malloc (_bytes); \
254266e564dSmrg        if (_pData) \
255266e564dSmrg	    _IceRead (_iceConn, _bytes, _pData); \
256266e564dSmrg        else \
257266e564dSmrg	    _IceReadSkip (_iceConn, _bytes); \
258266e564dSmrg    } \
259266e564dSmrg}
260266e564dSmrg
261266e564dSmrg#define IceDisposeCompleteMessage(_iceConn, _pData) \
262266e564dSmrg    if ((char *) _pData < _iceConn->inbuf || \
263266e564dSmrg	(char *) _pData >= _iceConn->inbufmax) \
264fb5e8d76Smrg        free (_pData);
265266e564dSmrg
266266e564dSmrg
267266e564dSmrg#define IceReadSimpleMessage(_iceConn, _msgType, _pMsg) \
268266e564dSmrg    _pMsg = (_msgType *) (_iceConn->inbuf);
269266e564dSmrg
270266e564dSmrg#define IceReadMessageHeader(_iceConn, _headerSize, _msgType, _pMsg) \
271266e564dSmrg{ \
272266e564dSmrg    _IceRead (_iceConn, \
273266e564dSmrg	(unsigned long) (_headerSize - SIZEOF (iceMsg)), \
274266e564dSmrg	_iceConn->inbufptr); \
275266e564dSmrg    _pMsg = (_msgType *) (_iceConn->inbuf); \
276266e564dSmrg    _iceConn->inbufptr += (_headerSize - SIZEOF (iceMsg)); \
277266e564dSmrg}
278266e564dSmrg
279266e564dSmrg#define IceReadData(_iceConn, _bytes, _pData) \
280266e564dSmrg    _IceRead (_iceConn, (unsigned long) (_bytes), (char *) _pData); \
281266e564dSmrg
282266e564dSmrg#define IceReadData16(_iceConn, _swap, _bytes, _pData) \
283266e564dSmrg{ \
284266e564dSmrg    _IceRead (_iceConn, (unsigned long) (_bytes), (char *) _pData); \
285266e564dSmrg}
286266e564dSmrg
287266e564dSmrg#define IceReadData32(_iceConn, _swap, _bytes, _pData) \
288266e564dSmrg{ \
289266e564dSmrg    _IceRead (_iceConn, (unsigned long) (_bytes), (char *) _pData); \
290266e564dSmrg}
291266e564dSmrg
292266e564dSmrg
293266e564dSmrg/*
294266e564dSmrg * Read pad bytes (for 32 or 64 bit alignment).
2951009a292Smrg * A maximum of 7 pad bytes can be specified.
296266e564dSmrg */
297266e564dSmrg
298266e564dSmrg#define IceReadPad(_iceConn, _bytes) \
299266e564dSmrg{ \
300266e564dSmrg    char _dummy[7]; \
301266e564dSmrg    _IceRead (_iceConn, (unsigned long) (_bytes), _dummy); \
302266e564dSmrg}
303266e564dSmrg
304266e564dSmrg_XFUNCPROTOEND
305266e564dSmrg
306266e564dSmrg#endif /* _ICEMSG_H_ */
307