1 /* $XConsortium: PEXlibint.h,v 1.8 92/08/26 13:05:15 mor Exp $ */ 2 3 /****************************************************************************** 4 Copyright 1987,1991 by Digital Equipment Corporation, Maynard, Massachusetts 5 Copyright 1992 by the Massachusetts Institute of Technology 6 7 All Rights Reserved 8 9 Permission to use, copy, modify, distribute, and sell this software and its 10 documentation for any purpose is hereby granted without fee, provided that 11 the above copyright notice appear in all copies and that both that copyright 12 notice and this permission notice appear in supporting documentation, and that 13 the name of Digital or M.I.T. not be used in advertising or publicity 14 pertaining to distribution of the software without specific, written prior 15 permission. Digital and M.I.T. make no representations about the suitability 16 of this software for any purpose. It is provided "as is" without express or 17 implied warranty. 18 19 DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 20 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 21 DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 22 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 23 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 24 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 25 SOFTWARE. 26 ******************************************************************************/ 27 28 #ifndef PEXLIBINT_H 29 #define PEXLIBINT_H 30 31 #include <X11/Xlibint.h> 32 #include <X11/Xfuncs.h> 33 #include "PEXproto.h" 34 35 36 /* ------------------------------------------------------------------------- 37 * Typedefs for referencing fields in requests. 38 * ------------------------------------------------------------------------- */ 39 40 /* 41 * Generic request header. 42 */ 43 44 typedef struct pexRequestHeader 45 { 46 unsigned char extOpcode; 47 unsigned char pexOpcode; 48 unsigned short reqLength; 49 } pexRequestHeader; 50 51 52 /* 53 * OC request header. 54 */ 55 56 typedef struct pexOCRequestHeader 57 { 58 unsigned char extOpcode; 59 unsigned char pexOpcode; 60 unsigned short reqLength; 61 unsigned short fpFormat; 62 unsigned short pad; 63 unsigned long target; 64 unsigned long numCommands; 65 } pexOCRequestHeader; 66 67 68 /* 69 * Element header for OC with list. 70 */ 71 72 typedef pexElementInfo pexOCListHeader; 73 74 75 /* 76 * Element header for OC with list & count. 77 */ 78 79 typedef struct pexOCcListHeader 80 { 81 pexElementInfo head; 82 unsigned short length; 83 unsigned short pad; 84 } pexOCcListHeader; 85 86 87 88 /* ------------------------------------------------------------------------- 89 * Display extension data structures and macros. 90 * ------------------------------------------------------------------------- */ 91 92 /* 93 * For each display initialized by PEXInitialize(), a record is allocated 94 * which holds various information about that display. These records are 95 * maintained in a linked list. The record for the most recently referenced 96 * display is always kept at the beginning of the list (for quick access). 97 */ 98 99 typedef struct PEXDisplayInfo 100 { 101 Display *display; /* pointer to X display structure */ 102 XExtCodes *extCodes; /* extension codes */ 103 PEXExtensionInfo *extInfo; /* extension info */ 104 unsigned char extOpcode; /* opcode for pex extension */ 105 unsigned short fpFormat; /* floating point format */ 106 char fpConvert; /* flag for floating point conversion */ 107 PEXEnumTypeDesc *fpSupport; /* float formats supported by server */ 108 int fpCount; /* number of float formats supported */ 109 XID lastResID; /* renderer/structure ID of last OC */ 110 int lastReqType; /* request type (store/rend) of last OC */ 111 int lastReqNum; /* request number of last OC */ 112 struct PEXDisplayInfo *next; /* next in list */ 113 } PEXDisplayInfo; 114 115 116 /* 117 * Pointer to head of list is defined externally. 118 */ 119 120 extern PEXDisplayInfo *PEXDisplayInfoHeader; 121 122 123 /* 124 * Insert a new record in the beginning of the linked list. 125 */ 126 127 #define PEXAddDisplayInfo(_display, _info) \ 128 \ 129 { \ 130 _info->display = _display; \ 131 \ 132 _info->next = PEXDisplayInfoHeader; \ 133 PEXDisplayInfoHeader = _info; \ 134 } 135 136 137 /* 138 * Remove the record assosicated with '_display' from the linked list 139 * and return a pointer to it in '_info'. 140 */ 141 142 #define PEXRemoveDisplayInfo(_display, _info) \ 143 \ 144 { \ 145 PEXDisplayInfo *prev = NULL; \ 146 \ 147 _info = PEXDisplayInfoHeader; \ 148 \ 149 while (_info && _info->display != _display) \ 150 { \ 151 prev = _info; \ 152 _info = _info->next; \ 153 } \ 154 \ 155 if (_info) \ 156 if (!prev) \ 157 PEXDisplayInfoHeader = _info->next; \ 158 else \ 159 prev->next = _info->next; \ 160 } 161 162 163 /* 164 * Return the info assosicated with '_display' in '_info'. 165 * If the info is not the first in the list, move it to the front. 166 */ 167 168 #define PEXGetDisplayInfo(_display, _info) \ 169 \ 170 { \ 171 _info = PEXDisplayInfoHeader; \ 172 \ 173 if (PEXDisplayInfoHeader->display != _display) \ 174 { \ 175 PEXDisplayInfo *prev = PEXDisplayInfoHeader; \ 176 \ 177 _info = _info->next; \ 178 while (_info && _info->display != _display) \ 179 { \ 180 prev = _info; \ 181 _info = _info->next; \ 182 } \ 183 \ 184 if (_info) \ 185 { \ 186 prev->next = _info->next; \ 187 _info->next = PEXDisplayInfoHeader; \ 188 PEXDisplayInfoHeader = _info; \ 189 } \ 190 } \ 191 } 192 193 194 195 /* ------------------------------------------------------------------------- 196 * Memory related macros. 197 * ------------------------------------------------------------------------- */ 198 199 #define PEXAllocBuf(size) Xmalloc(size) 200 #define PEXFreeBuf(ptr) Xfree(ptr) 201 #define PEXReallocBuf(ptr, size) Xrealloc(ptr, size) 202 203 #define COPY_AREA(_from, _to, _size) \ 204 bcopy (_from, _to, _size) 205 206 #define COPY_SMALL_AREA(_from, _to, _size) \ 207 { \ 208 register char *_f = (char *) (_from), *_t = (char *) (_to); \ 209 register int _c = (_size); \ 210 while (--_c >= 0) *_t++ = *_f++; \ 211 } 212 213 #define PAD(_size) (3 - (((_size) + 3) & 0x3)) 214 215 #define PADDED_BYTES(_bytes) (_bytes + PAD (_bytes)) 216 217 #define NUMWORDS(_size) (((unsigned int)((_size) + 3)) >> 2) 218 219 #define NUMBYTES(_len) (((unsigned int)(_len)) << 2) 220 221 #define LENOF(_ctype) (sizeof (_ctype) >> 2) 222 223 224 /* 225 * Count the number of ones in a longword. 226 */ 227 228 #define CountOnes(mask, countReturn) \ 229 countReturn = ((mask) - (((mask)>>1)&0x77777777) \ 230 - (((mask)>>2)&0x33333333) - (((mask)>>3)&0x11111111)); \ 231 countReturn = ((((countReturn)+((countReturn)>>4)) & 0x0F0F0F0F) % 255) 232 233 234 235 /* ------------------------------------------------------------------------- 236 * Macros for dealing with the transport buffer. 237 * ------------------------------------------------------------------------- */ 238 239 /* 240 * The maximum protocol request size. 241 */ 242 243 #define MAX_REQUEST_SIZE ((1<<16) - 1) 244 245 246 /* 247 * Has the X transport buffer been flushed? 248 */ 249 250 #define XBufferFlushed(_display) \ 251 ((_display)->buffer == (_display)->bufptr) 252 253 254 /* 255 * The number of bytes left in the X transport buffer. 256 */ 257 258 #define BytesLeftInXBuffer(_display) \ 259 ((_display)->bufmax - (_display)->bufptr) 260 261 262 /* 263 * The number of words left in the X transport buffer. 264 */ 265 266 #define WordsLeftInXBuffer(_display) \ 267 (((_display)->bufmax - (_display)->bufptr) >> 2) 268 269 270 /* 271 * Setup the OC element info header. 272 */ 273 274 #define STORE_ELEMENT_INFO(_reqPtr,_ocType,_ocLength) \ 275 { \ 276 ((pexElementInfo *)(_reqPtr))->elementType = (_ocType); \ 277 ((pexElementInfo *)(_reqPtr))->length = (_ocLength); \ 278 } 279 280 281 /* 282 * PEXGetReq sets up a request to be sent to the X server. If there isn't 283 * enough room left in the X buffer, it is flushed before the new request 284 * is started. 285 * 286 * PEXGetFPReq is similar to PEXGetReq, except that it sets up a request 287 * that contains floating point values. A return flag indicates whether 288 * or not the client native floating point format has to be converted to 289 * a server supported format. 290 * 291 * SETUP_REQ is a macro containing common code for PEXGetReq and PEXGetFPReq. 292 */ 293 294 #if __STDC__ && !defined(UNIXCPP) 295 296 #define SETUP_REQ(_name, _req) \ 297 PEXDisplayInfo *pexDisplayInfo; \ 298 PEXGetDisplayInfo (display, pexDisplayInfo); \ 299 if ((display->bufptr + sizeof (pex##_name##Req)) > display->bufmax) \ 300 _XFlush (display); \ 301 _req = (pex##_name##Req *) (display->last_req = display->bufptr); \ 302 _req->reqType = pexDisplayInfo->extOpcode; \ 303 _req->opcode = PEXRC##_name; \ 304 _req->length = (sizeof (pex##_name##Req)) >> 2; \ 305 display->bufptr += sizeof (pex##_name##Req); \ 306 display->request++ 307 308 #else /* non-ANSI C uses empty comment instead of "##" for token concat */ 309 310 #define SETUP_REQ(_name, _req) \ 311 PEXDisplayInfo *pexDisplayInfo; \ 312 PEXGetDisplayInfo (display, pexDisplayInfo); \ 313 if ((display->bufptr + sizeof (pex/**/_name/**/Req)) > display->bufmax) \ 314 _XFlush (display); \ 315 _req = (pex/**/_name/**/Req *) (display->last_req = display->bufptr); \ 316 _req->reqType = pexDisplayInfo->extOpcode; \ 317 _req->opcode = PEXRC/**/_name; \ 318 _req->length = (sizeof (pex/**/_name/**/Req)) >> 2; \ 319 display->bufptr += sizeof (pex/**/_name/**/Req); \ 320 display->request++ 321 #endif 322 323 #define PEXGetReq(_name, _req)\ 324 { \ 325 SETUP_REQ (_name, _req); \ 326 } 327 328 #define PEXGetFPReq(_name, _req, _fpConvert)\ 329 { \ 330 SETUP_REQ (_name, _req); \ 331 _req->fpFormat = pexDisplayInfo->fpFormat; \ 332 _fpConvert = pexDisplayInfo->fpConvert; \ 333 } 334 335 336 /* 337 * PEXGetReqExtra and PEXGetFPReqExtra are the same as PEXGetReq and 338 * PEXGetFPReq, except that an additional "n" bytes are allocated after 339 * the request. "n" will be padded to a word boundary. 340 */ 341 342 #if __STDC__ && !defined(UNIXCPP) 343 344 #define SETUP_REQ_EXTRA(_name, _n, _req) \ 345 PEXDisplayInfo *pexDisplayInfo; \ 346 PEXGetDisplayInfo (display, pexDisplayInfo); \ 347 if ((display->bufptr + sizeof (pex##_name##Req) + PADDED_BYTES (_n)) >\ 348 display->bufmax) \ 349 _XFlush (display); \ 350 _req = (pex##_name##Req *) (display->last_req = display->bufptr); \ 351 _req->reqType = pexDisplayInfo->extOpcode; \ 352 _req->opcode = PEXRC##_name; \ 353 _req->length = (sizeof(pex##_name##Req) + PADDED_BYTES (_n)) >> 2; \ 354 display->bufptr += sizeof (pex##_name##Req) + PADDED_BYTES (_n); \ 355 display->request++ 356 357 #else /* non-ANSI C uses empty comment instead of "##" for token concat */ 358 359 #define SETUP_REQ_EXTRA(_name, _n, _req) \ 360 PEXDisplayInfo *pexDisplayInfo; \ 361 PEXGetDisplayInfo (display, pexDisplayInfo); \ 362 if ((display->bufptr + sizeof (pex/**/_name/**/Req) + PADDED_BYTES (_n)) >\ 363 display->bufmax) \ 364 _XFlush (display); \ 365 _req = (pex/**/_name/**/Req *) (display->last_req = display->bufptr); \ 366 _req->reqType = pexDisplayInfo->extOpcode; \ 367 _req->opcode = PEXRC/**/_name; \ 368 _req->length = (sizeof(pex/**/_name/**/Req) + PADDED_BYTES (_n)) >> 2; \ 369 display->bufptr += sizeof (pex/**/_name/**/Req) + PADDED_BYTES (_n); \ 370 display->request++ 371 #endif 372 373 #define PEXGetReqExtra(_name, _n, _req) \ 374 { \ 375 SETUP_REQ_EXTRA (_name, _n, _req); \ 376 } 377 378 #define PEXGetFPReqExtra(_name, _n, _req, _fpConvert) \ 379 { \ 380 SETUP_REQ_EXTRA (_name, _n, _req); \ 381 _req->fpFormat = pexDisplayInfo->fpFormat; \ 382 _fpConvert = pexDisplayInfo->fpConvert; \ 383 } 384 385 386 /* 387 * PEXGetOCReq is similiar to PEXGetReq except that it does not update 388 * display->bufptr. This is used when writing ocs into the transport buffer. 389 */ 390 391 #define PEXGetOCReq(_display, _nBytes) \ 392 { \ 393 if ((_display)->bufptr + (_nBytes) > (_display)->bufmax) \ 394 _XFlush (_display); \ 395 (_display)->last_req = (_display)->bufptr; \ 396 (_display)->request++; \ 397 } 398 399 400 /* 401 * See if XSynchronize has been called. If so, send request right away. 402 */ 403 404 #define PEXSyncHandle(_display)\ 405 if ((_display)->synchandler) (*(_display)->synchandler) (_display) 406 407 408 409 /* ------------------------------------------------------------------------- 410 * Color related macros. 411 * ------------------------------------------------------------------------- */ 412 413 /* 414 * Return the size of the color in bytes by looking at the color type. 415 * Note that the size of an indexed color is pre-padded to a word boundary. 416 */ 417 418 #define GetColorSize(_type) \ 419 ((_type) == PEXColorTypeIndexed ? (sizeof (pexTableIndex) * 2) : \ 420 ((_type) == PEXColorTypeRGB8 ? sizeof (pexRgb8Color) : \ 421 ((_type) == PEXColorTypeRGB16 ? sizeof (pexRgb16Color) : \ 422 sizeof (pexRgbFloatColor)))) 423 424 /* 425 * Return the number of words in a color. Note that all the PEX color 426 * types are padded to end on a word boundary 427 */ 428 429 #define GetColorLength(_type_)\ 430 ((_type_) == PEXColorTypeIndexed ? LENOF( PEXColorIndexed) :\ 431 ((_type_) == PEXColorTypeRGB8 ? LENOF( PEXColorRGB8) :\ 432 ((_type_) == PEXColorTypeRGB16 ? LENOF( PEXColorRGB16) : \ 433 LENOF( PEXColorRGB) ))) 434 435 /* 436 * How big, relative to the largest color specifier, is the color? 437 * The users of this macro must subtract this value from the sizeof value. 438 */ 439 440 #define AdjustSizeFromType(_type) \ 441 (sizeof (pexColor) - GetColorSize (_type)) 442 443 444 /* 445 * Initialize a color specifier. 'dst' is of type PEXColorSpecifier, 446 * and 'src' is of type PEXColor. 447 */ 448 449 #define InitializeColorSpecifier(_dst, _src, _type)\ 450 (_dst).type = _type; \ 451 COPY_SMALL_AREA ((_src), &((_dst).value), GetColorSize (_type)); 452 453 454 /* 455 * PackColorSpecifier is similar to InitalizeColorSpecifier, except that 456 * the destination is a pointer to memory, rather than a static structure. 457 */ 458 459 #define PackColorSpecifier(srcBuf, dstBuf, sizeColor) \ 460 { \ 461 ((PEXColorSpecifier *) (dstBuf))->type = \ 462 ((PEXColorSpecifier *) (srcBuf))->type; \ 463 sizeColor = \ 464 GetColorSize (((PEXColorSpecifier *) (srcBuf))->type); \ 465 COPY_SMALL_AREA (&(((PEXColorSpecifier *) (srcBuf))->value), \ 466 &(((PEXColorSpecifier *) (dstBuf))->value), sizeColor); \ 467 } 468 469 470 471 /* ------------------------------------------------------------------------- 472 * Macros to compute the number of words in a facet/vertex with data. 473 * ------------------------------------------------------------------------- */ 474 475 /* 476 * Compute the number of words in the facet data 477 */ 478 479 #define GetFacetDataLength(_fattribs, _lenofColor) \ 480 (((_fattribs & PEXGAColor) ? _lenofColor : 0) + \ 481 ((_fattribs & PEXGANormal) ? LENOF(pexVector3D) : 0)) 482 483 484 /* 485 * Compute the number of words in a vertex with optional colors and normals 486 */ 487 488 #define GetVertexWithDataLength(_vattribs, _lenofColor) \ 489 (LENOF (pexCoord3D) + \ 490 ((_vattribs & PEXGAColor) ? _lenofColor : 0) + \ 491 ((_vattribs & PEXGANormal) ? LENOF (pexVector3D) : 0)) 492 493 494 495 /* ------------------------------------------------------------------------- 496 * Data structures useful for packing protocol data. 497 * ------------------------------------------------------------------------- */ 498 499 typedef struct 500 { 501 unsigned long attribute; 502 unsigned char value; 503 unsigned char reserved[3]; 504 } PEXASFData; 505 506 507 typedef struct { 508 short fp_format; 509 short reserved; 510 unsigned long renderer; 511 PEXColorSpecifier echo_color; 512 } PEXEchoColorData; 513 514 515 516 /* ------------------------------------------------------------------------- 517 * Miscellaneous. 518 * ------------------------------------------------------------------------- */ 519 520 /* 521 * IEEE-754-32 is the most common floating point type. Vendors who have 522 * a different native floating point format should define NATIVE_FP_FORMAT 523 * at compile time via the -D switch (this is done by modifying the vendors 524 * config file. 525 */ 526 527 #ifndef NATIVE_FP_FORMAT 528 #define NATIVE_FP_FORMAT PEXIEEE_754_32 529 #endif 530 531 532 /* 533 * INPUT and OUTPUT are defined to make looking at function arguments easier. 534 */ 535 536 #define INPUT 537 #define OUTPUT 538 #define INOUT 539 540 541 /* 542 * Pick path cache. 543 */ 544 545 #define MAX_PICK_CACHE_SIZE 2048 546 547 extern PEXPickPath *PEXPickCache; 548 extern unsigned int PEXPickCacheSize; 549 extern int PEXPickCacheInUse; 550 551 552 /* 553 * _XAllocScratch is defined in Xlib. 554 */ 555 556 extern char *_XAllocScratch(); 557 558 559 #endif /* PEXLIBINT_H */ 560