1 /****************************************************************************** 2 3 4 Copyright 1993, 1998 The Open Group 5 6 Permission to use, copy, modify, distribute, and sell this software and its 7 documentation for any purpose is hereby granted without fee, provided that 8 the above copyright notice appear in all copies and that both that 9 copyright notice and this permission notice appear in supporting 10 documentation. 11 12 The above copyright notice and this permission notice shall be included in 13 all copies or substantial portions of the Software. 14 15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 19 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 22 Except as contained in this notice, the name of The Open Group shall not be 23 used in advertising or otherwise to promote the sale, use or other dealings 24 in this Software without prior written authorization from The Open Group. 25 26 Author: Ralph Mor, X Consortium 27 ******************************************************************************/ 28 29 #ifndef _ICEMSG_H_ 30 #define _ICEMSG_H_ 31 32 #include <X11/Xfuncproto.h> 33 34 #include <X11/ICE/ICEconn.h> 35 36 #include <assert.h> 37 #if !defined(__cplusplus) && !defined(static_assert) 38 #define static_assert(cond, msg) /* skip for non-C11 compilers */ 39 #endif 40 41 _XFUNCPROTOBEGIN 42 43 /* 44 * Function prototypes for internal ICElib functions 45 */ 46 47 extern Status _IceRead ( 48 IceConn /* iceConn */, 49 unsigned long /* nbytes */, 50 char * /* ptr */ 51 ); 52 53 extern void _IceReadSkip ( 54 IceConn /* iceConn */, 55 unsigned long /* nbytes */ 56 ); 57 58 extern void _IceWrite ( 59 IceConn /* iceConn */, 60 unsigned long /* nbytes */, 61 char * /* ptr */ 62 ); 63 64 65 extern void _IceErrorBadMinor ( 66 IceConn /* iceConn */, 67 int /* majorOpcode */, 68 int /* offendingMinor */, 69 int /* severity */ 70 ); 71 72 extern void _IceErrorBadState ( 73 IceConn /* iceConn */, 74 int /* majorOpcode */, 75 int /* offendingMinor */, 76 int /* severity */ 77 ); 78 79 extern void _IceErrorBadLength ( 80 IceConn /* iceConn */, 81 int /* majorOpcode */, 82 int /* offendingMinor */, 83 int /* severity */ 84 ); 85 86 extern void _IceErrorBadValue ( 87 IceConn /* iceConn */, 88 int /* majorOpcode */, 89 int /* offendingMinor */, 90 int /* offset */, 91 int /* length */, 92 IcePointer /* value */ 93 ); 94 95 extern IcePoAuthStatus _IcePoMagicCookie1Proc ( 96 IceConn /* iceConn */, 97 IcePointer * /* authStatePtr */, 98 Bool /* cleanUp */, 99 Bool /* swap */, 100 int /* authDataLen */, 101 IcePointer /* authData */, 102 int * /* replyDataLenRet */, 103 IcePointer * /* replyDataRet */, 104 char ** /* errorStringRet */ 105 ); 106 107 extern IcePaAuthStatus _IcePaMagicCookie1Proc ( 108 IceConn /* iceConn */, 109 IcePointer * /* authStatePtr */, 110 Bool /* swap */, 111 int /* authDataLen */, 112 IcePointer /* authData */, 113 int * /* replyDataLenRet */, 114 IcePointer * /* replyDataRet */, 115 char ** /* errorStringRet */ 116 ); 117 118 119 /* 120 * Macro to check if IO operations are valid on an ICE connection. 121 */ 122 123 #define IceValidIO(_iceConn) _iceConn->io_ok 124 125 126 /* 127 * Macros for writing messages. 128 */ 129 130 #define IceGetHeader(_iceConn, _major, _minor, _headerSize, _msgType, _pMsg) \ 131 do { \ 132 static_assert(_headerSize <= 1024, \ 133 "Header size larger than ICE_OUTBUFSIZE"); \ 134 if ((_iceConn->outbufptr + _headerSize) > _iceConn->outbufmax) \ 135 IceFlush (_iceConn); \ 136 _pMsg = (_msgType *) _iceConn->outbufptr; \ 137 _pMsg->majorOpcode = _major; \ 138 _pMsg->minorOpcode = _minor; \ 139 _pMsg->length = (_headerSize - SIZEOF (iceMsg)) >> 3; \ 140 _iceConn->outbufptr += _headerSize; \ 141 _iceConn->send_sequence++; \ 142 } while (0) 143 144 #define IceGetHeaderExtra(_iceConn, _major, _minor, _headerSize, _extra, _msgType, _pMsg, _pData) \ 145 do { \ 146 static_assert(_headerSize <= 1024, \ 147 "Header size larger than ICE_OUTBUFSIZE"); \ 148 if ((_iceConn->outbufptr + \ 149 _headerSize + ((_extra) << 3)) > _iceConn->outbufmax) \ 150 IceFlush (_iceConn); \ 151 _pMsg = (_msgType *) _iceConn->outbufptr; \ 152 _iceConn->outbufptr += _headerSize; \ 153 if ((_iceConn->outbufptr + ((_extra) << 3)) <= _iceConn->outbufmax) { \ 154 _pData = _iceConn->outbufptr; \ 155 _iceConn->outbufptr += ((_extra) << 3); \ 156 } \ 157 else \ 158 _pData = NULL; \ 159 _pMsg->majorOpcode = _major; \ 160 _pMsg->minorOpcode = _minor; \ 161 _pMsg->length = ((_headerSize - SIZEOF (iceMsg)) >> 3) + (_extra); \ 162 _iceConn->send_sequence++; \ 163 } while (0) 164 165 #define IceSimpleMessage(_iceConn, _major, _minor) \ 166 { \ 167 iceMsg *_pMsg; \ 168 IceGetHeader (_iceConn, _major, _minor, SIZEOF (iceMsg), iceMsg, _pMsg); \ 169 } 170 171 #define IceErrorHeader(_iceConn, _offendingMajorOpcode, _offendingMinorOpcode, _offendingSequenceNum, _severity, _errorClass, _dataLength) \ 172 { \ 173 iceErrorMsg *_pMsg; \ 174 \ 175 IceGetHeader (_iceConn, _offendingMajorOpcode, ICE_Error, \ 176 SIZEOF (iceErrorMsg), iceErrorMsg, _pMsg); \ 177 _pMsg->length += (_dataLength); \ 178 _pMsg->offendingMinorOpcode = (CARD8) _offendingMinorOpcode; \ 179 _pMsg->severity = (CARD8) _severity; \ 180 _pMsg->offendingSequenceNum = (CARD32) _offendingSequenceNum; \ 181 _pMsg->errorClass = (CARD16) _errorClass; \ 182 } 183 184 185 /* 186 * Write data into the ICE output buffer. 187 */ 188 189 #define IceWriteData(_iceConn, _bytes, _data) \ 190 { \ 191 if ((_iceConn->outbufptr + (_bytes)) > _iceConn->outbufmax) \ 192 { \ 193 IceFlush (_iceConn); \ 194 _IceWrite (_iceConn, (unsigned long) (_bytes), _data); \ 195 } \ 196 else \ 197 { \ 198 memcpy (_iceConn->outbufptr, _data, _bytes); \ 199 _iceConn->outbufptr += (_bytes); \ 200 } \ 201 } 202 203 #define IceWriteData16(_iceConn, _bytes, _data) \ 204 IceWriteData (_iceConn, _bytes, (char *) _data) 205 206 #define IceWriteData32(_iceConn, _bytes, _data) \ 207 IceWriteData (_iceConn, _bytes, (char *) _data) 208 209 210 /* 211 * The IceSendData macro bypasses copying the data to the 212 * ICE connection buffer and sends the data directly. If necessary, 213 * the ICE connection buffer is first flushed. 214 */ 215 216 #define IceSendData(_iceConn, _bytes, _data) \ 217 { \ 218 if (_iceConn->outbufptr > _iceConn->outbuf) \ 219 IceFlush (_iceConn); \ 220 _IceWrite (_iceConn, (unsigned long) (_bytes), _data); \ 221 } 222 223 224 /* 225 * Write pad bytes. Used to force 32 or 64 bit alignment. 226 * A maximum of 7 pad bytes can be specified. 227 */ 228 229 #define IceWritePad(_iceConn, _bytes) \ 230 { \ 231 char _dummy[7] = { 0 }; \ 232 IceWriteData (_iceConn, (_bytes), _dummy); \ 233 } 234 235 236 /* 237 * Macros for reading messages. 238 */ 239 240 #define IceReadCompleteMessage(_iceConn, _headerSize, _msgType, _pMsg, _pData)\ 241 { \ 242 unsigned long _bytes; \ 243 IceReadMessageHeader (_iceConn, _headerSize, _msgType, _pMsg); \ 244 _bytes = (_pMsg->length << 3) - (_headerSize - SIZEOF (iceMsg)); \ 245 if ((_iceConn->inbufmax - _iceConn->inbufptr) >= _bytes) \ 246 { \ 247 _IceRead (_iceConn, _bytes, _iceConn->inbufptr); \ 248 _pData = _iceConn->inbufptr; \ 249 _iceConn->inbufptr += _bytes; \ 250 } \ 251 else \ 252 { \ 253 _pData = malloc (_bytes); \ 254 if (_pData) \ 255 _IceRead (_iceConn, _bytes, _pData); \ 256 else \ 257 _IceReadSkip (_iceConn, _bytes); \ 258 } \ 259 } 260 261 #define IceDisposeCompleteMessage(_iceConn, _pData) \ 262 if ((char *) _pData < _iceConn->inbuf || \ 263 (char *) _pData >= _iceConn->inbufmax) \ 264 free (_pData); 265 266 267 #define IceReadSimpleMessage(_iceConn, _msgType, _pMsg) \ 268 _pMsg = (_msgType *) (_iceConn->inbuf); 269 270 #define IceReadMessageHeader(_iceConn, _headerSize, _msgType, _pMsg) \ 271 { \ 272 _IceRead (_iceConn, \ 273 (unsigned long) (_headerSize - SIZEOF (iceMsg)), \ 274 _iceConn->inbufptr); \ 275 _pMsg = (_msgType *) (_iceConn->inbuf); \ 276 _iceConn->inbufptr += (_headerSize - SIZEOF (iceMsg)); \ 277 } 278 279 #define IceReadData(_iceConn, _bytes, _pData) \ 280 _IceRead (_iceConn, (unsigned long) (_bytes), (char *) _pData); \ 281 282 #define IceReadData16(_iceConn, _swap, _bytes, _pData) \ 283 { \ 284 _IceRead (_iceConn, (unsigned long) (_bytes), (char *) _pData); \ 285 } 286 287 #define IceReadData32(_iceConn, _swap, _bytes, _pData) \ 288 { \ 289 _IceRead (_iceConn, (unsigned long) (_bytes), (char *) _pData); \ 290 } 291 292 293 /* 294 * Read pad bytes (for 32 or 64 bit alignment). 295 * A maximum of 7 pad bytes can be specified. 296 */ 297 298 #define IceReadPad(_iceConn, _bytes) \ 299 { \ 300 char _dummy[7]; \ 301 _IceRead (_iceConn, (unsigned long) (_bytes), _dummy); \ 302 } 303 304 _XFUNCPROTOEND 305 306 #endif /* _ICEMSG_H_ */ 307