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