XSync.c revision 05a4e9a7
1/* 2 3Copyright 1991, 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 12in all copies or substantial portions of the Software. 13 14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR 18OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20OTHER DEALINGS IN THE SOFTWARE. 21 22Except as contained in this notice, the name of The Open Group shall 23not be used in advertising or otherwise to promote the sale, use or 24other dealings in this Software without prior written authorization 25from The Open Group. 26 27*/ 28 29/*********************************************************** 30Copyright 1991,1993 by Digital Equipment Corporation, Maynard, Massachusetts, 31and Olivetti Research Limited, Cambridge, England. 32 33 All Rights Reserved 34 35Permission to use, copy, modify, and distribute this software and its 36documentation for any purpose and without fee is hereby granted, 37provided that the above copyright notice appear in all copies and that 38both that copyright notice and this permission notice appear in 39supporting documentation, and that the names of Digital or Olivetti 40not be used in advertising or publicity pertaining to distribution of the 41software without specific, written prior permission. 42 43DIGITAL AND OLIVETTI DISCLAIM ALL WARRANTIES WITH REGARD TO THIS 44SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND 45FITNESS, IN NO EVENT SHALL THEY BE LIABLE FOR ANY SPECIAL, INDIRECT OR 46CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF 47USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 48OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 49PERFORMANCE OF THIS SOFTWARE. 50 51******************************************************************/ 52 53#ifdef HAVE_CONFIG_H 54#include <config.h> 55#endif 56#include <stdio.h> 57#include <X11/Xlibint.h> 58#include <X11/extensions/Xext.h> 59#include <X11/extensions/extutil.h> 60#include <X11/extensions/sync.h> 61#include <X11/extensions/syncproto.h> 62 63static XExtensionInfo _sync_info_data; 64static XExtensionInfo *sync_info = &_sync_info_data; 65static char *sync_extension_name = SYNC_NAME; 66 67#define SyncCheckExtension(dpy,i,val) \ 68 XextCheckExtension(dpy, i, sync_extension_name, val) 69#define SyncSimpleCheckExtension(dpy,i) \ 70 XextSimpleCheckExtension(dpy, i, sync_extension_name) 71 72static int close_display(Display *dpy, XExtCodes *codes); 73static Bool wire_to_event(Display *dpy, XEvent *event, xEvent *wire); 74static Status event_to_wire(Display *dpy, XEvent *event, xEvent *wire); 75static char *error_string(Display *dpy, int code, XExtCodes *codes, 76 char *buf, int n); 77 78static XExtensionHooks sync_extension_hooks = { 79 NULL, /* create_gc */ 80 NULL, /* copy_gc */ 81 NULL, /* flush_gc */ 82 NULL, /* free_gc */ 83 NULL, /* create_font */ 84 NULL, /* free_font */ 85 close_display, /* close_display */ 86 wire_to_event, /* wire_to_event */ 87 event_to_wire, /* event_to_wire */ 88 NULL, /* error */ 89 error_string, /* error_string */ 90}; 91 92static char *sync_error_list[] = { 93 "BadCounter", 94 "BadAlarm", 95 "BadFence", 96}; 97 98typedef struct _SyncVersionInfoRec { 99 short major; 100 short minor; 101 int num_errors; 102} SyncVersionInfo; 103 104static /* const */ SyncVersionInfo supported_versions[] = { 105 { 3 /* major */, 0 /* minor */, 2 /* num_errors */ }, 106 { 3 /* major */, 1 /* minor */, 3 /* num_errors */ }, 107}; 108 109#define NUM_VERSIONS (sizeof(supported_versions)/sizeof(supported_versions[0])) 110#define GET_VERSION(info) ((const SyncVersionInfo*)(info)->data) 111#define IS_VERSION_SUPPORTED(info) (!!(info)) 112 113static 114const SyncVersionInfo* GetVersionInfo(Display *dpy) 115{ 116 xSyncInitializeReply rep; 117 xSyncInitializeReq *req; 118 XExtCodes codes; 119 int i; 120 121 if (!XQueryExtension(dpy, sync_extension_name, 122 &codes.major_opcode, 123 &codes.first_event, 124 &codes.first_error)) 125 return NULL; 126 127 LockDisplay(dpy); 128 GetReq(SyncInitialize, req); 129 req->reqType = codes.major_opcode; 130 req->syncReqType = X_SyncInitialize; 131 req->majorVersion = SYNC_MAJOR_VERSION; 132 req->minorVersion = SYNC_MINOR_VERSION; 133 if (!_XReply(dpy, (xReply *) & rep, 0, xTrue)) 134 { 135 UnlockDisplay(dpy); 136 SyncHandle(); 137 return NULL; 138 } 139 UnlockDisplay(dpy); 140 SyncHandle(); 141 142 for (i = 0; i < NUM_VERSIONS; i++) { 143 if (supported_versions[i].major == rep.majorVersion && 144 supported_versions[i].minor == rep.minorVersion) { 145 return &supported_versions[i]; 146 } 147 } 148 149 return NULL; 150} 151 152static 153XExtDisplayInfo *find_display_create_optional(Display *dpy, Bool create) 154{ 155 XExtDisplayInfo *dpyinfo; 156 157 if (!sync_info) { 158 if (!(sync_info = XextCreateExtension())) return NULL; 159 } 160 161 if (!(dpyinfo = XextFindDisplay (sync_info, dpy)) && create) { 162 dpyinfo = XextAddDisplay(sync_info, dpy, 163 sync_extension_name, 164 &sync_extension_hooks, 165 XSyncNumberEvents, 166 (XPointer)GetVersionInfo(dpy)); 167 } 168 169 return dpyinfo; 170} 171 172static 173XExtDisplayInfo *find_display (Display *dpy) 174{ 175 return find_display_create_optional(dpy, True); 176} 177 178static 179XEXT_GENERATE_CLOSE_DISPLAY(close_display, sync_info) 180 181static 182char *error_string(Display *dpy, int code, XExtCodes *codes, char *buf, int n) 183{ 184 XExtDisplayInfo *info = find_display_create_optional(dpy, False); 185 int nerr = IS_VERSION_SUPPORTED(info) ? GET_VERSION(info)->num_errors : 0; 186 187 code -= codes->first_error; 188 if (code >= 0 && code < nerr) { 189 char tmp[256]; 190 sprintf (tmp, "%s.%d", sync_extension_name, code); 191 XGetErrorDatabaseText (dpy, "XProtoError", tmp, sync_error_list[code], buf, n); 192 return buf; 193 } 194 return (char *)0; 195} 196 197static Bool 198wire_to_event(Display *dpy, XEvent *event, xEvent *wire) 199{ 200 XExtDisplayInfo *info = find_display(dpy); 201 XSyncCounterNotifyEvent *aevent; 202 xSyncCounterNotifyEvent *awire; 203 XSyncAlarmNotifyEvent *anl; 204 xSyncAlarmNotifyEvent *ane; 205 206 SyncCheckExtension(dpy, info, False); 207 208 switch ((wire->u.u.type & 0x7F) - info->codes->first_event) 209 { 210 case XSyncCounterNotify: 211 awire = (xSyncCounterNotifyEvent *) wire; 212 aevent = (XSyncCounterNotifyEvent *) event; 213 aevent->type = awire->type & 0x7F; 214 aevent->serial = _XSetLastRequestRead(dpy, 215 (xGenericReply *) wire); 216 aevent->send_event = (awire->type & 0x80) != 0; 217 aevent->display = dpy; 218 aevent->counter = awire->counter; 219 XSyncIntsToValue(&aevent->wait_value, awire->wait_value_lo, 220 awire->wait_value_hi); 221 XSyncIntsToValue(&aevent->counter_value, 222 awire->counter_value_lo, 223 awire->counter_value_hi); 224 aevent->time = awire->time; 225 aevent->count = awire->count; 226 aevent->destroyed = awire->destroyed; 227 return True; 228 229 case XSyncAlarmNotify: 230 ane = (xSyncAlarmNotifyEvent *) wire; /* ENCODING EVENT PTR */ 231 anl = (XSyncAlarmNotifyEvent *) event; /* LIBRARY EVENT PTR */ 232 anl->type = ane->type & 0x7F; 233 anl->serial = _XSetLastRequestRead(dpy, 234 (xGenericReply *) wire); 235 anl->send_event = (ane->type & 0x80) != 0; 236 anl->display = dpy; 237 anl->alarm = ane->alarm; 238 XSyncIntsToValue(&anl->counter_value, 239 ane->counter_value_lo, 240 ane->counter_value_hi); 241 XSyncIntsToValue(&anl->alarm_value, 242 ane->alarm_value_lo, 243 ane->alarm_value_hi); 244 anl->state = (XSyncAlarmState)ane->state; 245 anl->time = ane->time; 246 return True; 247 } 248 249 return False; 250} 251 252static Status 253event_to_wire(Display *dpy, XEvent *event, xEvent *wire) 254{ 255 XExtDisplayInfo *info = find_display(dpy); 256 XSyncCounterNotifyEvent *aevent; 257 xSyncCounterNotifyEvent *awire; 258 XSyncAlarmNotifyEvent *anl; 259 xSyncAlarmNotifyEvent *ane; 260 261 SyncCheckExtension(dpy, info, False); 262 263 switch ((event->type & 0x7F) - info->codes->first_event) 264 { 265 case XSyncCounterNotify: 266 awire = (xSyncCounterNotifyEvent *) wire; 267 aevent = (XSyncCounterNotifyEvent *) event; 268 awire->type = aevent->type | (aevent->send_event ? 0x80 : 0); 269 awire->sequenceNumber = aevent->serial & 0xFFFF; 270 awire->counter = aevent->counter; 271 awire->wait_value_lo = XSyncValueLow32(aevent->wait_value); 272 awire->wait_value_hi = XSyncValueHigh32(aevent->wait_value); 273 awire->counter_value_lo = XSyncValueLow32(aevent->counter_value); 274 awire->counter_value_hi = XSyncValueHigh32(aevent->counter_value); 275 awire->time = aevent->time; 276 awire->count = aevent->count; 277 awire->destroyed = aevent->destroyed; 278 return True; 279 280 case XSyncAlarmNotify: 281 ane = (xSyncAlarmNotifyEvent *) wire; /* ENCODING EVENT PTR */ 282 anl = (XSyncAlarmNotifyEvent *) event; /* LIBRARY EVENT PTR */ 283 ane->type = anl->type | (anl->send_event ? 0x80 : 0); 284 ane->sequenceNumber = anl->serial & 0xFFFF; 285 ane->alarm = anl->alarm; 286 ane->counter_value_lo = XSyncValueLow32(anl->counter_value); 287 ane->counter_value_hi = XSyncValueHigh32(anl->counter_value); 288 ane->alarm_value_lo = XSyncValueLow32(anl->alarm_value); 289 ane->alarm_value_hi = XSyncValueHigh32(anl->alarm_value); 290 ane->state = anl->state; 291 ane->time = anl->time; 292 return True; 293 } 294 return False; 295} 296 297Status 298XSyncQueryExtension( 299 Display *dpy, 300 int *event_base_return, int *error_base_return) 301{ 302 XExtDisplayInfo *info = find_display(dpy); 303 304 if (XextHasExtension(info)) 305 { 306 *event_base_return = info->codes->first_event; 307 *error_base_return = info->codes->first_error; 308 return True; 309 } 310 else 311 return False; 312} 313 314Status 315XSyncInitialize( 316 Display *dpy, 317 int *major_version_return, int *minor_version_return) 318{ 319 XExtDisplayInfo *info = find_display(dpy); 320 321 SyncCheckExtension(dpy, info, False); 322 323 if (IS_VERSION_SUPPORTED(info)) { 324 *major_version_return = GET_VERSION(info)->major; 325 *minor_version_return = GET_VERSION(info)->minor; 326 327 return True; 328 } else { 329 return False; 330 } 331} 332 333XSyncSystemCounter * 334XSyncListSystemCounters(Display *dpy, int *n_counters_return) 335{ 336 XExtDisplayInfo *info = find_display(dpy); 337 xSyncListSystemCountersReply rep; 338 xSyncListSystemCountersReq *req; 339 XSyncSystemCounter *list = NULL; 340 341 SyncCheckExtension(dpy, info, NULL); 342 343 LockDisplay(dpy); 344 GetReq(SyncListSystemCounters, req); 345 req->reqType = info->codes->major_opcode; 346 req->syncReqType = X_SyncListSystemCounters; 347 if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) 348 goto bail; 349 350 *n_counters_return = rep.nCounters; 351 if (rep.nCounters > 0) 352 { 353 xSyncSystemCounter *pWireSysCounter, *pNextWireSysCounter; 354 XSyncCounter counter; 355 int replylen; 356 int i; 357 358 list = Xmalloc(rep.nCounters * sizeof(XSyncSystemCounter)); 359 replylen = rep.length << 2; 360 pWireSysCounter = Xmalloc ((unsigned) replylen + sizeof(XSyncCounter)); 361 /* +1 to leave room for last counter read-ahead */ 362 363 if ((!list) || (!pWireSysCounter)) 364 { 365 if (list) Xfree((char *) list); 366 if (pWireSysCounter) Xfree((char *) pWireSysCounter); 367 _XEatData(dpy, (unsigned long) replylen); 368 list = NULL; 369 goto bail; 370 } 371 372 _XReadPad(dpy, (char *)pWireSysCounter, replylen); 373 374 counter = pWireSysCounter->counter; 375 for (i = 0; i < rep.nCounters; i++) 376 { 377 list[i].counter = counter; 378 XSyncIntsToValue(&list[i].resolution, 379 pWireSysCounter->resolution_lo, 380 pWireSysCounter->resolution_hi); 381 382 /* we may be about to clobber the counter field of the 383 * next syscounter because we have to add a null terminator 384 * to the counter name string. So we save the next counter 385 * here. 386 */ 387 pNextWireSysCounter = (xSyncSystemCounter *) 388 (((char *)pWireSysCounter) + ((SIZEOF(xSyncSystemCounter) + 389 pWireSysCounter->name_length + 3) & ~3)); 390 counter = pNextWireSysCounter->counter; 391 392 list[i].name = ((char *)pWireSysCounter) + 393 SIZEOF(xSyncSystemCounter); 394 /* null-terminate the string */ 395 *(list[i].name + pWireSysCounter->name_length) = '\0'; 396 pWireSysCounter = pNextWireSysCounter; 397 } 398 } 399 400bail: 401 UnlockDisplay(dpy); 402 SyncHandle(); 403 return list; 404} 405 406void 407XSyncFreeSystemCounterList(XSyncSystemCounter *list) 408{ 409 if (list) 410 { 411 Xfree( ((char *)list[0].name) - SIZEOF(xSyncSystemCounter)); 412 Xfree(list); 413 } 414} 415 416 417XSyncCounter 418XSyncCreateCounter(Display *dpy, XSyncValue initial_value) 419{ 420 XExtDisplayInfo *info = find_display(dpy); 421 xSyncCreateCounterReq *req; 422 423 SyncCheckExtension(dpy, info, None); 424 425 LockDisplay(dpy); 426 GetReq(SyncCreateCounter, req); 427 req->reqType = info->codes->major_opcode; 428 req->syncReqType = X_SyncCreateCounter; 429 430 req->cid = XAllocID(dpy); 431 req->initial_value_lo = XSyncValueLow32(initial_value); 432 req->initial_value_hi = XSyncValueHigh32(initial_value); 433 434 UnlockDisplay(dpy); 435 SyncHandle(); 436 return req->cid; 437} 438 439Status 440XSyncSetCounter(Display *dpy, XSyncCounter counter, XSyncValue value) 441{ 442 XExtDisplayInfo *info = find_display(dpy); 443 xSyncSetCounterReq *req; 444 445 SyncCheckExtension(dpy, info, False); 446 447 LockDisplay(dpy); 448 GetReq(SyncSetCounter, req); 449 req->reqType = info->codes->major_opcode; 450 req->syncReqType = X_SyncSetCounter; 451 req->cid = counter; 452 req->value_lo = XSyncValueLow32(value); 453 req->value_hi = XSyncValueHigh32(value); 454 UnlockDisplay(dpy); 455 SyncHandle(); 456 return True; 457} 458 459Status 460XSyncChangeCounter(Display *dpy, XSyncCounter counter, XSyncValue value) 461{ 462 XExtDisplayInfo *info = find_display(dpy); 463 xSyncChangeCounterReq *req; 464 465 SyncCheckExtension(dpy, info, False); 466 467 LockDisplay(dpy); 468 GetReq(SyncChangeCounter, req); 469 req->reqType = info->codes->major_opcode; 470 req->syncReqType = X_SyncChangeCounter; 471 req->cid = counter; 472 req->value_lo = XSyncValueLow32(value); 473 req->value_hi = XSyncValueHigh32(value); 474 UnlockDisplay(dpy); 475 SyncHandle(); 476 return True; 477} 478 479Status 480XSyncDestroyCounter(Display *dpy, XSyncCounter counter) 481{ 482 XExtDisplayInfo *info = find_display(dpy); 483 xSyncDestroyCounterReq *req; 484 485 SyncCheckExtension(dpy, info, False); 486 487 LockDisplay(dpy); 488 GetReq(SyncDestroyCounter, req); 489 req->reqType = info->codes->major_opcode; 490 req->syncReqType = X_SyncDestroyCounter; 491 req->counter = counter; 492 UnlockDisplay(dpy); 493 SyncHandle(); 494 495 return True; 496} 497 498Status 499XSyncQueryCounter(Display *dpy, XSyncCounter counter, XSyncValue *value_return) 500{ 501 XExtDisplayInfo *info = find_display(dpy); 502 xSyncQueryCounterReply rep; 503 xSyncQueryCounterReq *req; 504 505 SyncCheckExtension(dpy, info, False); 506 507 LockDisplay(dpy); 508 GetReq(SyncQueryCounter, req); 509 req->reqType = info->codes->major_opcode; 510 req->syncReqType = X_SyncQueryCounter; 511 req->counter = counter; 512 if (!_XReply(dpy, (xReply *) & rep, 0, xTrue)) 513 { 514 UnlockDisplay(dpy); 515 SyncHandle(); 516 return False; 517 } 518 XSyncIntsToValue(value_return, rep.value_lo, rep.value_hi); 519 UnlockDisplay(dpy); 520 SyncHandle(); 521 522 return True; 523} 524 525 526Status 527XSyncAwait(Display *dpy, XSyncWaitCondition *wait_list, int n_conditions) 528{ 529 XExtDisplayInfo *info = find_display(dpy); 530 XSyncWaitCondition *wait_item = wait_list; 531 xSyncAwaitReq *req; 532 unsigned int len; 533 534 SyncCheckExtension(dpy, info, False); 535 536 LockDisplay(dpy); 537 GetReq(SyncAwait, req); 538 req->reqType = info->codes->major_opcode; 539 req->syncReqType = X_SyncAwait; 540 len = (n_conditions * SIZEOF(xSyncWaitCondition)) >> 2; 541 SetReqLen(req, len, len /* XXX */ ); 542 543 while (n_conditions--) 544 { 545 xSyncWaitCondition wc; 546 wc.counter = wait_item->trigger.counter; 547 wc.value_type = wait_item->trigger.value_type; 548 wc.wait_value_lo = XSyncValueLow32(wait_item->trigger.wait_value); 549 wc.wait_value_hi = XSyncValueHigh32(wait_item->trigger.wait_value); 550 wc.test_type = wait_item->trigger.test_type; 551 wc.event_threshold_lo = XSyncValueLow32(wait_item->event_threshold); 552 wc.event_threshold_hi = XSyncValueHigh32(wait_item->event_threshold); 553 Data(dpy, (char *)&wc, SIZEOF(xSyncWaitCondition)); 554 wait_item++; /* get next trigger */ 555 } 556 557 UnlockDisplay(dpy); 558 SyncHandle(); 559 return True; 560} 561 562static void 563_XProcessAlarmAttributes(Display *dpy, xSyncChangeAlarmReq *req, 564 unsigned long valuemask, 565 XSyncAlarmAttributes *attributes) 566{ 567 568 unsigned long values[32]; 569 unsigned long *value = values; 570 unsigned int nvalues; 571 572 if (valuemask & XSyncCACounter) 573 *value++ = attributes->trigger.counter; 574 575 if (valuemask & XSyncCAValueType) 576 *value++ = attributes->trigger.value_type; 577 578 if (valuemask & XSyncCAValue) 579 { 580 *value++ = XSyncValueHigh32(attributes->trigger.wait_value); 581 *value++ = XSyncValueLow32(attributes->trigger.wait_value); 582 } 583 584 if (valuemask & XSyncCATestType) 585 *value++ = attributes->trigger.test_type; 586 587 if (valuemask & XSyncCADelta) 588 { 589 *value++ = XSyncValueHigh32(attributes->delta); 590 *value++ = XSyncValueLow32(attributes->delta); 591 } 592 593 if (valuemask & XSyncCAEvents) 594 *value++ = attributes->events; 595 596 /* N.B. the 'state' field cannot be set or changed */ 597 req->length += (nvalues = value - values); 598 nvalues <<= 2; /* watch out for macros... */ 599 600 Data32(dpy, (long *) values, (long) nvalues); 601} 602 603XSyncAlarm 604XSyncCreateAlarm( 605 Display *dpy, 606 unsigned long values_mask, 607 XSyncAlarmAttributes *values) 608{ 609 XExtDisplayInfo *info = find_display(dpy); 610 xSyncCreateAlarmReq *req; 611 XSyncAlarm aid; 612 613 SyncCheckExtension(dpy, info, False); 614 615 LockDisplay(dpy); 616 GetReq(SyncCreateAlarm, req); 617 req->reqType = info->codes->major_opcode; 618 req->syncReqType = X_SyncCreateAlarm; 619 req->id = aid = XAllocID(dpy); 620 values_mask &= XSyncCACounter | XSyncCAValueType | XSyncCAValue 621 | XSyncCATestType | XSyncCADelta | XSyncCAEvents; 622 if ((req->valueMask = values_mask)) 623 _XProcessAlarmAttributes(dpy, (xSyncChangeAlarmReq *) req, 624 values_mask, values); 625 UnlockDisplay(dpy); 626 SyncHandle(); 627 return aid; 628} 629 630Status 631XSyncDestroyAlarm(Display *dpy, XSyncAlarm alarm) 632{ 633 XExtDisplayInfo *info = find_display(dpy); 634 xSyncDestroyAlarmReq *req; 635 636 SyncCheckExtension(dpy, info, False); 637 638 LockDisplay(dpy); 639 GetReq(SyncDestroyAlarm, req); 640 req->reqType = info->codes->major_opcode; 641 req->syncReqType = X_SyncDestroyAlarm; 642 req->alarm = alarm; 643 UnlockDisplay(dpy); 644 SyncHandle(); 645 return True; 646} 647 648Status 649XSyncQueryAlarm( 650 Display *dpy, 651 XSyncAlarm alarm, 652 XSyncAlarmAttributes *values_return) 653{ 654 XExtDisplayInfo *info = find_display(dpy); 655 xSyncQueryAlarmReq *req; 656 xSyncQueryAlarmReply rep; 657 658 SyncCheckExtension(dpy, info, False); 659 660 LockDisplay(dpy); 661 GetReq(SyncQueryAlarm, req); 662 req->reqType = info->codes->major_opcode; 663 req->syncReqType = X_SyncQueryAlarm; 664 req->alarm = alarm; 665 666 if (!(_XReply(dpy, (xReply *) & rep, 667 ((SIZEOF(xSyncQueryAlarmReply) - SIZEOF(xGenericReply)) >> 2), xFalse))) 668 { 669 UnlockDisplay(dpy); 670 SyncHandle(); 671 return False; 672 } 673 674 values_return->trigger.counter = rep.counter; 675 values_return->trigger.value_type = (XSyncValueType)rep.value_type; 676 XSyncIntsToValue(&values_return->trigger.wait_value, 677 rep.wait_value_lo, rep.wait_value_hi); 678 values_return->trigger.test_type = (XSyncTestType)rep.test_type; 679 XSyncIntsToValue(&values_return->delta, rep.delta_lo, 680 rep.delta_hi); 681 values_return->events = rep.events; 682 values_return->state = (XSyncAlarmState)rep.state; 683 UnlockDisplay(dpy); 684 SyncHandle(); 685 return True; 686} 687 688Status 689XSyncChangeAlarm( 690 Display *dpy, 691 XSyncAlarm alarm, 692 unsigned long values_mask, 693 XSyncAlarmAttributes *values) 694{ 695 XExtDisplayInfo *info = find_display(dpy); 696 xSyncChangeAlarmReq *req; 697 698 SyncCheckExtension(dpy, info, False); 699 700 LockDisplay(dpy); 701 GetReq(SyncChangeAlarm, req); 702 req->reqType = info->codes->major_opcode; 703 req->syncReqType = X_SyncChangeAlarm; 704 req->alarm = alarm; 705 values_mask &= XSyncCACounter | XSyncCAValueType | XSyncCAValue 706 | XSyncCATestType | XSyncCADelta | XSyncCAEvents; 707 if ((req->valueMask = values_mask)) 708 _XProcessAlarmAttributes(dpy, req, values_mask, values); 709 UnlockDisplay(dpy); 710 SyncHandle(); 711 return True; 712} 713 714Status 715XSyncSetPriority( 716 Display *dpy, 717 XID client_resource_id, 718 int priority) 719{ 720 XExtDisplayInfo *info = find_display(dpy); 721 xSyncSetPriorityReq *req; 722 723 SyncCheckExtension(dpy, info, False); 724 725 LockDisplay(dpy); 726 GetReq(SyncSetPriority, req); 727 req->reqType = info->codes->major_opcode; 728 req->syncReqType = X_SyncSetPriority; 729 req->id = client_resource_id; 730 req->priority = priority; 731 UnlockDisplay(dpy); 732 SyncHandle(); 733 return True; 734} 735 736Status 737XSyncGetPriority(Display *dpy, XID client_resource_id, int *return_priority) 738{ 739 XExtDisplayInfo *info = find_display(dpy); 740 xSyncGetPriorityReply rep; 741 xSyncGetPriorityReq *req; 742 743 SyncCheckExtension(dpy, info, False); 744 745 LockDisplay(dpy); 746 GetReq(SyncGetPriority, req); 747 req->reqType = info->codes->major_opcode; 748 req->syncReqType = X_SyncGetPriority; 749 req->id = client_resource_id; 750 751 if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) 752 { 753 UnlockDisplay(dpy); 754 SyncHandle(); 755 return False; 756 } 757 if (return_priority) 758 *return_priority = rep.priority; 759 760 UnlockDisplay(dpy); 761 SyncHandle(); 762 return True; 763} 764 765XSyncFence 766XSyncCreateFence(Display *dpy, Drawable d, Bool initially_triggered) 767{ 768 XExtDisplayInfo *info = find_display(dpy); 769 xSyncCreateFenceReq *req; 770 XSyncFence id; 771 772 SyncCheckExtension(dpy, info, None); 773 774 LockDisplay(dpy); 775 GetReq(SyncCreateFence, req); 776 req->reqType = info->codes->major_opcode; 777 req->syncReqType = X_SyncCreateFence; 778 779 req->d = d; 780 id = req->fid = XAllocID(dpy); 781 req->initially_triggered = initially_triggered; 782 783 UnlockDisplay(dpy); 784 SyncHandle(); 785 return id; 786} 787 788Bool 789XSyncTriggerFence(Display *dpy, XSyncFence fence) 790{ 791 XExtDisplayInfo *info = find_display(dpy); 792 xSyncTriggerFenceReq *req; 793 794 SyncCheckExtension(dpy, info, None); 795 796 LockDisplay(dpy); 797 GetReq(SyncTriggerFence, req); 798 req->reqType = info->codes->major_opcode; 799 req->syncReqType = X_SyncTriggerFence; 800 801 req->fid = fence; 802 803 UnlockDisplay(dpy); 804 SyncHandle(); 805 return True; 806} 807 808Bool 809XSyncResetFence(Display *dpy, XSyncFence fence) 810{ 811 XExtDisplayInfo *info = find_display(dpy); 812 xSyncResetFenceReq *req; 813 814 SyncCheckExtension(dpy, info, None); 815 816 LockDisplay(dpy); 817 GetReq(SyncResetFence, req); 818 req->reqType = info->codes->major_opcode; 819 req->syncReqType = X_SyncResetFence; 820 821 req->fid = fence; 822 823 UnlockDisplay(dpy); 824 SyncHandle(); 825 return True; 826} 827 828Bool 829XSyncDestroyFence(Display *dpy, XSyncFence fence) 830{ 831 XExtDisplayInfo *info = find_display(dpy); 832 xSyncDestroyFenceReq *req; 833 834 SyncCheckExtension(dpy, info, None); 835 836 LockDisplay(dpy); 837 GetReq(SyncDestroyFence, req); 838 req->reqType = info->codes->major_opcode; 839 req->syncReqType = X_SyncDestroyFence; 840 841 req->fid = fence; 842 843 UnlockDisplay(dpy); 844 SyncHandle(); 845 return True; 846} 847 848Bool 849XSyncQueryFence(Display *dpy, XSyncFence fence, Bool *triggered) 850{ 851 XExtDisplayInfo *info = find_display(dpy); 852 xSyncQueryFenceReply rep; 853 xSyncQueryFenceReq *req; 854 855 SyncCheckExtension(dpy, info, None); 856 857 LockDisplay(dpy); 858 GetReq(SyncQueryFence, req); 859 req->reqType = info->codes->major_opcode; 860 req->syncReqType = X_SyncQueryFence; 861 req->fid = fence; 862 863 if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) 864 { 865 UnlockDisplay(dpy); 866 SyncHandle(); 867 return False; 868 } 869 if (triggered) 870 *triggered = rep.triggered; 871 872 UnlockDisplay(dpy); 873 SyncHandle(); 874 return True; 875} 876 877Bool 878XSyncAwaitFence(Display *dpy, const XSyncFence *fence_list, int n_fences) 879{ 880 XExtDisplayInfo *info = find_display(dpy); 881 xSyncAwaitFenceReq *req; 882 883 SyncCheckExtension(dpy, info, False); 884 885 LockDisplay(dpy); 886 GetReq(SyncAwaitFence, req); 887 req->reqType = info->codes->major_opcode; 888 req->syncReqType = X_SyncAwaitFence; 889 SetReqLen(req, n_fences, n_fences); 890 891 Data32(dpy, (char *)fence_list, sizeof(CARD32) * n_fences); 892 893 UnlockDisplay(dpy); 894 SyncHandle(); 895 return True; 896} 897 898/* 899 * Functions corresponding to the macros for manipulating 64-bit values 900 */ 901 902void 903XSyncIntToValue(XSyncValue *pv, int i) 904{ 905 _XSyncIntToValue(pv,i); 906} 907 908void 909XSyncIntsToValue(XSyncValue *pv, unsigned int l, int h) 910{ 911 _XSyncIntsToValue(pv, l, h); 912} 913 914Bool 915XSyncValueGreaterThan(XSyncValue a, XSyncValue b) 916{ 917 return _XSyncValueGreaterThan(a, b); 918} 919 920Bool 921XSyncValueLessThan(XSyncValue a, XSyncValue b) 922{ 923 return _XSyncValueLessThan(a, b); 924} 925 926Bool 927XSyncValueGreaterOrEqual(XSyncValue a, XSyncValue b) 928{ 929 return _XSyncValueGreaterOrEqual(a, b); 930} 931 932Bool 933XSyncValueLessOrEqual(XSyncValue a, XSyncValue b) 934{ 935 return _XSyncValueLessOrEqual(a, b); 936} 937 938Bool 939XSyncValueEqual(XSyncValue a, XSyncValue b) 940{ 941 return _XSyncValueEqual(a, b); 942} 943 944Bool 945XSyncValueIsNegative(XSyncValue v) 946{ 947 return _XSyncValueIsNegative(v); 948} 949 950Bool 951XSyncValueIsZero(XSyncValue a) 952{ 953 return _XSyncValueIsZero(a); 954} 955 956Bool 957XSyncValueIsPositive(XSyncValue v) 958{ 959 return _XSyncValueIsPositive(v); 960} 961 962unsigned int 963XSyncValueLow32(XSyncValue v) 964{ 965 return _XSyncValueLow32(v); 966} 967 968int 969XSyncValueHigh32(XSyncValue v) 970{ 971 return _XSyncValueHigh32(v); 972} 973 974void 975XSyncValueAdd(XSyncValue *presult, XSyncValue a, XSyncValue b, Bool *poverflow) 976{ 977 _XSyncValueAdd(presult, a, b, poverflow); 978} 979 980void 981XSyncValueSubtract( 982 XSyncValue *presult, 983 XSyncValue a, XSyncValue b, 984 Bool *poverflow) 985{ 986 _XSyncValueSubtract(presult, a, b, poverflow); 987} 988 989void 990XSyncMaxValue(XSyncValue *pv) 991{ 992 _XSyncMaxValue(pv); 993} 994 995void 996XSyncMinValue(XSyncValue *pv) 997{ 998 _XSyncMinValue(pv); 999} 1000