upload tizen2.0 source
[framework/uifw/xorg/lib/libxext.git] / src / XSync.c
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
63 static XExtensionInfo _sync_info_data;
64 static XExtensionInfo *sync_info = &_sync_info_data;
65 static const 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
72 static int      close_display(Display *dpy, XExtCodes *codes);
73 static Bool wire_to_event(Display *dpy, XEvent *event, xEvent *wire);
74 static Status event_to_wire(Display *dpy, XEvent *event, xEvent *wire);
75 static char    *error_string(Display *dpy, int code, XExtCodes *codes,
76                              char *buf, int n);
77
78 static 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
92 static const char *sync_error_list[] = {
93     "BadCounter",
94     "BadAlarm",
95     "BadFence",
96 };
97
98 typedef struct _SyncVersionInfoRec {
99     short major;
100     short minor;
101     int num_errors;
102 } SyncVersionInfo;
103
104 static /* 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) ((info) ? (const SyncVersionInfo*)(info)->data : NULL)
111 #define IS_VERSION_SUPPORTED(info) (!!GET_VERSION(info))
112
113 static
114 const 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
152 static
153 XExtDisplayInfo *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
172 static
173 XExtDisplayInfo *find_display (Display *dpy)
174 {
175     return find_display_create_optional(dpy, True);
176 }
177
178 static
179 XEXT_GENERATE_CLOSE_DISPLAY(close_display, sync_info)
180
181 static
182 char *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
197 static Bool
198 wire_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
252 static Status
253 event_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
297 Status
298 XSyncQueryExtension(
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
314 Status
315 XSyncInitialize(
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
333 XSyncSystemCounter *
334 XSyncListSystemCounters(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
400 bail:
401     UnlockDisplay(dpy);
402     SyncHandle();
403     return list;
404 }
405
406 void
407 XSyncFreeSystemCounterList(XSyncSystemCounter *list)
408 {
409     if (list)
410     {
411         Xfree( ((char *)list[0].name) - SIZEOF(xSyncSystemCounter));
412         Xfree(list);
413     }
414 }
415
416
417 XSyncCounter
418 XSyncCreateCounter(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
439 Status
440 XSyncSetCounter(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
459 Status
460 XSyncChangeCounter(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
479 Status
480 XSyncDestroyCounter(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
498 Status
499 XSyncQueryCounter(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
526 Status
527 XSyncAwait(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
562 static 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
603 XSyncAlarm
604 XSyncCreateAlarm(
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
630 Status
631 XSyncDestroyAlarm(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
648 Status
649 XSyncQueryAlarm(
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
688 Status
689 XSyncChangeAlarm(
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
714 Status
715 XSyncSetPriority(
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
736 Status
737 XSyncGetPriority(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
765 XSyncFence
766 XSyncCreateFence(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
788 Bool
789 XSyncTriggerFence(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
808 Bool
809 XSyncResetFence(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
828 Bool
829 XSyncDestroyFence(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
848 Bool
849 XSyncQueryFence(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
877 Bool
878 XSyncAwaitFence(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
902 void
903 XSyncIntToValue(XSyncValue *pv, int i)
904 {
905     _XSyncIntToValue(pv,i);
906 }
907
908 void
909 XSyncIntsToValue(XSyncValue *pv, unsigned int l, int h)
910 {
911     _XSyncIntsToValue(pv, l, h);
912 }
913
914 Bool
915 XSyncValueGreaterThan(XSyncValue a, XSyncValue b)
916 {
917     return _XSyncValueGreaterThan(a, b);
918 }
919
920 Bool
921 XSyncValueLessThan(XSyncValue a, XSyncValue b)
922 {
923     return _XSyncValueLessThan(a, b);
924 }
925
926 Bool
927 XSyncValueGreaterOrEqual(XSyncValue a, XSyncValue b)
928 {
929     return _XSyncValueGreaterOrEqual(a, b);
930 }
931
932 Bool
933 XSyncValueLessOrEqual(XSyncValue a, XSyncValue b)
934 {
935     return _XSyncValueLessOrEqual(a, b);
936 }
937
938 Bool
939 XSyncValueEqual(XSyncValue a, XSyncValue b)
940 {
941     return _XSyncValueEqual(a, b);
942 }
943
944 Bool
945 XSyncValueIsNegative(XSyncValue v)
946 {
947     return _XSyncValueIsNegative(v);
948 }
949
950 Bool
951 XSyncValueIsZero(XSyncValue a)
952 {
953     return _XSyncValueIsZero(a);
954 }
955
956 Bool
957 XSyncValueIsPositive(XSyncValue v)
958 {
959     return _XSyncValueIsPositive(v);
960 }
961
962 unsigned int
963 XSyncValueLow32(XSyncValue v)
964 {
965     return _XSyncValueLow32(v);
966 }
967
968 int
969 XSyncValueHigh32(XSyncValue v)
970 {
971     return _XSyncValueHigh32(v);
972 }
973
974 void
975 XSyncValueAdd(XSyncValue *presult, XSyncValue a, XSyncValue b, Bool *poverflow)
976 {
977     _XSyncValueAdd(presult, a, b, poverflow);
978 }
979
980 void
981 XSyncValueSubtract(
982     XSyncValue *presult,
983     XSyncValue a, XSyncValue b,
984     Bool *poverflow)
985 {
986     _XSyncValueSubtract(presult, a, b, poverflow);
987 }
988
989 void
990 XSyncMaxValue(XSyncValue *pv)
991 {
992     _XSyncMaxValue(pv);
993 }
994
995 void
996 XSyncMinValue(XSyncValue *pv)
997 {
998     _XSyncMinValue(pv);
999 }