XSync.c revision e8a5466a
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};
96
97static
98XEXT_GENERATE_FIND_DISPLAY(find_display, sync_info,
99			   sync_extension_name,
100			   &sync_extension_hooks,
101			   XSyncNumberEvents, (XPointer) NULL)
102
103static
104XEXT_GENERATE_CLOSE_DISPLAY(close_display, sync_info)
105
106static
107XEXT_GENERATE_ERROR_STRING(error_string, sync_extension_name,
108			   XSyncNumberErrors, sync_error_list)
109
110
111static Bool
112wire_to_event(Display *dpy, XEvent *event, xEvent *wire)
113{
114    XExtDisplayInfo *info = find_display(dpy);
115    XSyncCounterNotifyEvent *aevent;
116    xSyncCounterNotifyEvent *awire;
117    XSyncAlarmNotifyEvent *anl;
118    xSyncAlarmNotifyEvent *ane;
119
120    SyncCheckExtension(dpy, info, False);
121
122    switch ((wire->u.u.type & 0x7F) - info->codes->first_event)
123    {
124      case XSyncCounterNotify:
125	awire = (xSyncCounterNotifyEvent *) wire;
126	aevent = (XSyncCounterNotifyEvent *) event;
127	aevent->type = awire->type & 0x7F;
128	aevent->serial = _XSetLastRequestRead(dpy,
129					      (xGenericReply *) wire);
130	aevent->send_event = (awire->type & 0x80) != 0;
131	aevent->display = dpy;
132	aevent->counter = awire->counter;
133	XSyncIntsToValue(&aevent->wait_value, awire->wait_value_lo,
134				    awire->wait_value_hi);
135	XSyncIntsToValue(&aevent->counter_value,
136				    awire->counter_value_lo,
137				    awire->counter_value_hi);
138	aevent->time = awire->time;
139	aevent->count = awire->count;
140	aevent->destroyed = awire->destroyed;
141	return True;
142
143      case XSyncAlarmNotify:
144	ane = (xSyncAlarmNotifyEvent *) wire;	/* ENCODING EVENT PTR */
145	anl = (XSyncAlarmNotifyEvent *) event;	/* LIBRARY EVENT PTR */
146	anl->type = ane->type & 0x7F;
147	anl->serial = _XSetLastRequestRead(dpy,
148					   (xGenericReply *) wire);
149	anl->send_event = (ane->type & 0x80) != 0;
150	anl->display = dpy;
151	anl->alarm = ane->alarm;
152	XSyncIntsToValue(&anl->counter_value,
153				    ane->counter_value_lo,
154				    ane->counter_value_hi);
155	XSyncIntsToValue(&anl->alarm_value,
156				    ane->alarm_value_lo,
157				    ane->alarm_value_hi);
158	anl->state = (XSyncAlarmState)ane->state;
159	anl->time = ane->time;
160	return True;
161    }
162
163    return False;
164}
165
166static Status
167event_to_wire(Display *dpy, XEvent *event, xEvent *wire)
168{
169    XExtDisplayInfo *info = find_display(dpy);
170    XSyncCounterNotifyEvent *aevent;
171    xSyncCounterNotifyEvent *awire;
172    XSyncAlarmNotifyEvent *anl;
173    xSyncAlarmNotifyEvent *ane;
174
175    SyncCheckExtension(dpy, info, False);
176
177    switch ((event->type & 0x7F) - info->codes->first_event)
178    {
179      case XSyncCounterNotify:
180	awire = (xSyncCounterNotifyEvent *) wire;
181	aevent = (XSyncCounterNotifyEvent *) event;
182	awire->type = aevent->type | (aevent->send_event ? 0x80 : 0);
183	awire->sequenceNumber = aevent->serial & 0xFFFF;
184	awire->counter = aevent->counter;
185	awire->wait_value_lo = XSyncValueLow32(aevent->wait_value);
186	awire->wait_value_hi = XSyncValueHigh32(aevent->wait_value);
187	awire->counter_value_lo = XSyncValueLow32(aevent->counter_value);
188	awire->counter_value_hi = XSyncValueHigh32(aevent->counter_value);
189	awire->time = aevent->time;
190	awire->count = aevent->count;
191	awire->destroyed = aevent->destroyed;
192	return True;
193
194      case XSyncAlarmNotify:
195	ane = (xSyncAlarmNotifyEvent *) wire;	/* ENCODING EVENT PTR */
196	anl = (XSyncAlarmNotifyEvent *) event;	/* LIBRARY EVENT PTR */
197	ane->type = anl->type | (anl->send_event ? 0x80 : 0);
198	ane->sequenceNumber = anl->serial & 0xFFFF;
199	ane->alarm = anl->alarm;
200	ane->counter_value_lo = XSyncValueLow32(anl->counter_value);
201	ane->counter_value_hi = XSyncValueHigh32(anl->counter_value);
202	ane->alarm_value_lo = XSyncValueLow32(anl->alarm_value);
203	ane->alarm_value_hi = XSyncValueHigh32(anl->alarm_value);
204	ane->state = anl->state;
205	ane->time = anl->time;
206	return True;
207    }
208    return False;
209}
210
211Status
212XSyncQueryExtension(
213    Display *dpy,
214    int *event_base_return, int *error_base_return)
215{
216    XExtDisplayInfo *info = find_display(dpy);
217
218    if (XextHasExtension(info))
219    {
220	*event_base_return = info->codes->first_event;
221	*error_base_return = info->codes->first_error;
222	return True;
223    }
224    else
225	return False;
226}
227
228Status
229XSyncInitialize(
230    Display *dpy,
231    int *major_version_return, int *minor_version_return)
232{
233    XExtDisplayInfo *info = find_display(dpy);
234    xSyncInitializeReply rep;
235    xSyncInitializeReq *req;
236
237    SyncCheckExtension(dpy, info, False);
238
239    LockDisplay(dpy);
240    GetReq(SyncInitialize, req);
241    req->reqType = info->codes->major_opcode;
242    req->syncReqType = X_SyncInitialize;
243    req->majorVersion = SYNC_MAJOR_VERSION;
244    req->minorVersion = SYNC_MINOR_VERSION;
245    if (!_XReply(dpy, (xReply *) & rep, 0, xTrue))
246    {
247	UnlockDisplay(dpy);
248	SyncHandle();
249	return False;
250    }
251    UnlockDisplay(dpy);
252    SyncHandle();
253    *major_version_return = rep.majorVersion;
254    *minor_version_return = rep.minorVersion;
255    return ((rep.majorVersion == SYNC_MAJOR_VERSION)
256#if SYNC_MINOR_VERSION > 0	/* avoid compiler warning */
257	    && (rep.minorVersion >= SYNC_MINOR_VERSION)
258#endif
259	    );
260}
261
262XSyncSystemCounter *
263XSyncListSystemCounters(Display *dpy, int *n_counters_return)
264{
265    XExtDisplayInfo *info = find_display(dpy);
266    xSyncListSystemCountersReply rep;
267    xSyncListSystemCountersReq *req;
268    XSyncSystemCounter *list = NULL;
269
270    SyncCheckExtension(dpy, info, NULL);
271
272    LockDisplay(dpy);
273    GetReq(SyncListSystemCounters, req);
274    req->reqType = info->codes->major_opcode;
275    req->syncReqType = X_SyncListSystemCounters;
276    if (!_XReply(dpy, (xReply *) & rep, 0, xFalse))
277	goto bail;
278
279    *n_counters_return = rep.nCounters;
280    if (rep.nCounters > 0)
281    {
282	xSyncSystemCounter *pWireSysCounter, *pNextWireSysCounter;
283	XSyncCounter counter;
284	int replylen;
285	int i;
286
287	list = Xmalloc(rep.nCounters * sizeof(XSyncSystemCounter));
288	replylen = rep.length << 2;
289	pWireSysCounter = Xmalloc ((unsigned) replylen + sizeof(XSyncCounter));
290        /* +1 to leave room for last counter read-ahead */
291
292	if ((!list) || (!pWireSysCounter))
293	{
294	    if (list) Xfree((char *) list);
295	    if (pWireSysCounter)   Xfree((char *) pWireSysCounter);
296	    _XEatData(dpy, (unsigned long) replylen);
297	    list = NULL;
298	    goto bail;
299	}
300
301	_XReadPad(dpy, (char *)pWireSysCounter, replylen);
302
303	counter = pWireSysCounter->counter;
304	for (i = 0; i < rep.nCounters; i++)
305	{
306	    list[i].counter = counter;
307	    XSyncIntsToValue(&list[i].resolution,
308					pWireSysCounter->resolution_lo,
309					pWireSysCounter->resolution_hi);
310
311	    /* we may be about to clobber the counter field of the
312	     * next syscounter because we have to add a null terminator
313	     * to the counter name string.  So we save the next counter
314	     * here.
315	     */
316	    pNextWireSysCounter = (xSyncSystemCounter *)
317		(((char *)pWireSysCounter) + ((SIZEOF(xSyncSystemCounter) +
318				     pWireSysCounter->name_length + 3) & ~3));
319	    counter = pNextWireSysCounter->counter;
320
321	    list[i].name = ((char *)pWireSysCounter) +
322						SIZEOF(xSyncSystemCounter);
323	    /* null-terminate the string */
324	    *(list[i].name + pWireSysCounter->name_length) = '\0';
325	    pWireSysCounter = pNextWireSysCounter;
326	}
327    }
328
329bail:
330    UnlockDisplay(dpy);
331    SyncHandle();
332    return list;
333}
334
335void
336XSyncFreeSystemCounterList(XSyncSystemCounter *list)
337{
338    if (list)
339    {
340	Xfree( ((char *)list[0].name) - SIZEOF(xSyncSystemCounter));
341	Xfree(list);
342    }
343}
344
345
346XSyncCounter
347XSyncCreateCounter(Display *dpy, XSyncValue initial_value)
348{
349    XExtDisplayInfo *info = find_display(dpy);
350    xSyncCreateCounterReq *req;
351
352    SyncCheckExtension(dpy, info, None);
353
354    LockDisplay(dpy);
355    GetReq(SyncCreateCounter, req);
356    req->reqType = info->codes->major_opcode;
357    req->syncReqType = X_SyncCreateCounter;
358
359    req->cid = XAllocID(dpy);
360    req->initial_value_lo = XSyncValueLow32(initial_value);
361    req->initial_value_hi = XSyncValueHigh32(initial_value);
362
363    UnlockDisplay(dpy);
364    SyncHandle();
365    return req->cid;
366}
367
368Status
369XSyncSetCounter(Display *dpy, XSyncCounter counter, XSyncValue value)
370{
371    XExtDisplayInfo *info = find_display(dpy);
372    xSyncSetCounterReq *req;
373
374    SyncCheckExtension(dpy, info, False);
375
376    LockDisplay(dpy);
377    GetReq(SyncSetCounter, req);
378    req->reqType = info->codes->major_opcode;
379    req->syncReqType = X_SyncSetCounter;
380    req->cid = counter;
381    req->value_lo = XSyncValueLow32(value);
382    req->value_hi = XSyncValueHigh32(value);
383    UnlockDisplay(dpy);
384    SyncHandle();
385    return True;
386}
387
388Status
389XSyncChangeCounter(Display *dpy, XSyncCounter counter, XSyncValue value)
390{
391    XExtDisplayInfo *info = find_display(dpy);
392    xSyncChangeCounterReq *req;
393
394    SyncCheckExtension(dpy, info, False);
395
396    LockDisplay(dpy);
397    GetReq(SyncChangeCounter, req);
398    req->reqType = info->codes->major_opcode;
399    req->syncReqType = X_SyncChangeCounter;
400    req->cid = counter;
401    req->value_lo = XSyncValueLow32(value);
402    req->value_hi = XSyncValueHigh32(value);
403    UnlockDisplay(dpy);
404    SyncHandle();
405    return True;
406}
407
408Status
409XSyncDestroyCounter(Display *dpy, XSyncCounter counter)
410{
411    XExtDisplayInfo *info = find_display(dpy);
412    xSyncDestroyCounterReq *req;
413
414    SyncCheckExtension(dpy, info, False);
415
416    LockDisplay(dpy);
417    GetReq(SyncDestroyCounter, req);
418    req->reqType = info->codes->major_opcode;
419    req->syncReqType = X_SyncDestroyCounter;
420    req->counter = counter;
421    UnlockDisplay(dpy);
422    SyncHandle();
423
424    return True;
425}
426
427Status
428XSyncQueryCounter(Display *dpy, XSyncCounter counter, XSyncValue *value_return)
429{
430    XExtDisplayInfo *info = find_display(dpy);
431    xSyncQueryCounterReply rep;
432    xSyncQueryCounterReq *req;
433
434    SyncCheckExtension(dpy, info, False);
435
436    LockDisplay(dpy);
437    GetReq(SyncQueryCounter, req);
438    req->reqType = info->codes->major_opcode;
439    req->syncReqType = X_SyncQueryCounter;
440    req->counter = counter;
441    if (!_XReply(dpy, (xReply *) & rep, 0, xTrue))
442    {
443	UnlockDisplay(dpy);
444	SyncHandle();
445	return False;
446    }
447    XSyncIntsToValue(value_return, rep.value_lo, rep.value_hi);
448    UnlockDisplay(dpy);
449    SyncHandle();
450
451    return True;
452}
453
454
455Status
456XSyncAwait(Display *dpy, XSyncWaitCondition *wait_list, int n_conditions)
457{
458    XExtDisplayInfo *info = find_display(dpy);
459    XSyncWaitCondition *wait_item = wait_list;
460    xSyncAwaitReq  *req;
461    unsigned int    len;
462
463    SyncCheckExtension(dpy, info, False);
464
465    LockDisplay(dpy);
466    GetReq(SyncAwait, req);
467    req->reqType = info->codes->major_opcode;
468    req->syncReqType = X_SyncAwait;
469    len = (n_conditions * SIZEOF(xSyncWaitCondition)) >> 2;
470    SetReqLen(req, len, len /* XXX */ );
471
472    while (n_conditions--)
473    {
474	xSyncWaitCondition  wc;
475	wc.counter = wait_item->trigger.counter;
476	wc.value_type = wait_item->trigger.value_type;
477	wc.wait_value_lo = XSyncValueLow32(wait_item->trigger.wait_value);
478	wc.wait_value_hi = XSyncValueHigh32(wait_item->trigger.wait_value);
479	wc.test_type = wait_item->trigger.test_type;
480	wc.event_threshold_lo = XSyncValueLow32(wait_item->event_threshold);
481	wc.event_threshold_hi = XSyncValueHigh32(wait_item->event_threshold);
482	Data(dpy, (char *)&wc, SIZEOF(xSyncWaitCondition));
483	wait_item++;		/* get next trigger */
484    }
485
486    UnlockDisplay(dpy);
487    SyncHandle();
488    return True;
489}
490
491static void
492_XProcessAlarmAttributes(Display *dpy, xSyncChangeAlarmReq *req,
493			 unsigned long valuemask,
494			 XSyncAlarmAttributes *attributes)
495{
496
497    unsigned long  values[32];
498    unsigned long *value = values;
499    unsigned int    nvalues;
500
501    if (valuemask & XSyncCACounter)
502	*value++ = attributes->trigger.counter;
503
504    if (valuemask & XSyncCAValueType)
505	*value++ = attributes->trigger.value_type;
506
507    if (valuemask & XSyncCAValue)
508    {
509	*value++ = XSyncValueHigh32(attributes->trigger.wait_value);
510	*value++ = XSyncValueLow32(attributes->trigger.wait_value);
511    }
512
513    if (valuemask & XSyncCATestType)
514	*value++ = attributes->trigger.test_type;
515
516    if (valuemask & XSyncCADelta)
517    {
518	*value++ = XSyncValueHigh32(attributes->delta);
519	*value++ = XSyncValueLow32(attributes->delta);
520    }
521
522    if (valuemask & XSyncCAEvents)
523	*value++ = attributes->events;
524
525    /* N.B. the 'state' field cannot be set or changed */
526    req->length += (nvalues = value - values);
527    nvalues <<= 2;		/* watch out for macros... */
528
529    Data32(dpy, (long *) values, (long) nvalues);
530}
531
532XSyncAlarm
533XSyncCreateAlarm(
534    Display *dpy,
535    unsigned long values_mask,
536    XSyncAlarmAttributes *values)
537{
538    XExtDisplayInfo *info = find_display(dpy);
539    xSyncCreateAlarmReq *req;
540    XSyncAlarm      aid;
541
542    SyncCheckExtension(dpy, info, False);
543
544    LockDisplay(dpy);
545    GetReq(SyncCreateAlarm, req);
546    req->reqType = info->codes->major_opcode;
547    req->syncReqType = X_SyncCreateAlarm;
548    req->id = aid = XAllocID(dpy);
549    values_mask &= XSyncCACounter | XSyncCAValueType | XSyncCAValue
550			| XSyncCATestType | XSyncCADelta | XSyncCAEvents;
551    if ((req->valueMask = values_mask))
552	_XProcessAlarmAttributes(dpy, (xSyncChangeAlarmReq *) req,
553				 values_mask, values);
554    UnlockDisplay(dpy);
555    SyncHandle();
556    return aid;
557}
558
559Status
560XSyncDestroyAlarm(Display *dpy, XSyncAlarm alarm)
561{
562    XExtDisplayInfo *info = find_display(dpy);
563    xSyncDestroyAlarmReq *req;
564
565    SyncCheckExtension(dpy, info, False);
566
567    LockDisplay(dpy);
568    GetReq(SyncDestroyAlarm, req);
569    req->reqType = info->codes->major_opcode;
570    req->syncReqType = X_SyncDestroyAlarm;
571    req->alarm = alarm;
572    UnlockDisplay(dpy);
573    SyncHandle();
574    return True;
575}
576
577Status
578XSyncQueryAlarm(
579    Display *dpy,
580    XSyncAlarm alarm,
581    XSyncAlarmAttributes *values_return)
582{
583    XExtDisplayInfo *info = find_display(dpy);
584    xSyncQueryAlarmReq *req;
585    xSyncQueryAlarmReply rep;
586
587    SyncCheckExtension(dpy, info, False);
588
589    LockDisplay(dpy);
590    GetReq(SyncQueryAlarm, req);
591    req->reqType = info->codes->major_opcode;
592    req->syncReqType = X_SyncQueryAlarm;
593    req->alarm = alarm;
594
595    if (!(_XReply(dpy, (xReply *) & rep,
596    ((SIZEOF(xSyncQueryAlarmReply) - SIZEOF(xGenericReply)) >> 2), xFalse)))
597    {
598	UnlockDisplay(dpy);
599	SyncHandle();
600	return False;
601    }
602
603    values_return->trigger.counter = rep.counter;
604    values_return->trigger.value_type = (XSyncValueType)rep.value_type;
605    XSyncIntsToValue(&values_return->trigger.wait_value,
606				rep.wait_value_lo, rep.wait_value_hi);
607    values_return->trigger.test_type = (XSyncTestType)rep.test_type;
608    XSyncIntsToValue(&values_return->delta, rep.delta_lo,
609				rep.delta_hi);
610    values_return->events = rep.events;
611    values_return->state = (XSyncAlarmState)rep.state;
612    UnlockDisplay(dpy);
613    SyncHandle();
614    return True;
615}
616
617Status
618XSyncChangeAlarm(
619    Display *dpy,
620    XSyncAlarm alarm,
621    unsigned long values_mask,
622    XSyncAlarmAttributes *values)
623{
624    XExtDisplayInfo *info = find_display(dpy);
625    xSyncChangeAlarmReq *req;
626
627    SyncCheckExtension(dpy, info, False);
628
629    LockDisplay(dpy);
630    GetReq(SyncChangeAlarm, req);
631    req->reqType = info->codes->major_opcode;
632    req->syncReqType = X_SyncChangeAlarm;
633    req->alarm = alarm;
634    values_mask &= XSyncCACounter | XSyncCAValueType | XSyncCAValue
635		 | XSyncCATestType | XSyncCADelta | XSyncCAEvents;
636    if ((req->valueMask = values_mask))
637	_XProcessAlarmAttributes(dpy, req, values_mask, values);
638    UnlockDisplay(dpy);
639    SyncHandle();
640    return True;
641}
642
643Status
644XSyncSetPriority(
645    Display *dpy,
646    XID client_resource_id,
647    int priority)
648{
649    XExtDisplayInfo *info = find_display(dpy);
650    xSyncSetPriorityReq *req;
651
652    SyncCheckExtension(dpy, info, False);
653
654    LockDisplay(dpy);
655    GetReq(SyncSetPriority, req);
656    req->reqType = info->codes->major_opcode;
657    req->syncReqType = X_SyncSetPriority;
658    req->id = client_resource_id;
659    req->priority = priority;
660    UnlockDisplay(dpy);
661    SyncHandle();
662    return True;
663}
664
665Status
666XSyncGetPriority(Display *dpy, XID client_resource_id, int *return_priority)
667{
668    XExtDisplayInfo *info = find_display(dpy);
669    xSyncGetPriorityReply rep;
670    xSyncGetPriorityReq *req;
671
672    SyncCheckExtension(dpy, info, False);
673
674    LockDisplay(dpy);
675    GetReq(SyncGetPriority, req);
676    req->reqType = info->codes->major_opcode;
677    req->syncReqType = X_SyncGetPriority;
678    req->id = client_resource_id;
679
680    if (!_XReply(dpy, (xReply *) & rep, 0, xFalse))
681    {
682	UnlockDisplay(dpy);
683	SyncHandle();
684	return False;
685    }
686    if (return_priority)
687	*return_priority = rep.priority;
688
689    UnlockDisplay(dpy);
690    SyncHandle();
691    return True;
692}
693
694/*
695 *  Functions corresponding to the macros for manipulating 64-bit values
696 */
697
698void
699XSyncIntToValue(XSyncValue *pv, int i)
700{
701    _XSyncIntToValue(pv,i);
702}
703
704void
705XSyncIntsToValue(XSyncValue *pv, unsigned int l, int h)
706{
707    _XSyncIntsToValue(pv, l, h);
708}
709
710Bool
711XSyncValueGreaterThan(XSyncValue a, XSyncValue b)
712{
713    return _XSyncValueGreaterThan(a, b);
714}
715
716Bool
717XSyncValueLessThan(XSyncValue a, XSyncValue b)
718{
719    return _XSyncValueLessThan(a, b);
720}
721
722Bool
723XSyncValueGreaterOrEqual(XSyncValue a, XSyncValue b)
724{
725    return _XSyncValueGreaterOrEqual(a, b);
726}
727
728Bool
729XSyncValueLessOrEqual(XSyncValue a, XSyncValue b)
730{
731    return _XSyncValueLessOrEqual(a, b);
732}
733
734Bool
735XSyncValueEqual(XSyncValue a, XSyncValue b)
736{
737    return _XSyncValueEqual(a, b);
738}
739
740Bool
741XSyncValueIsNegative(XSyncValue v)
742{
743    return _XSyncValueIsNegative(v);
744}
745
746Bool
747XSyncValueIsZero(XSyncValue a)
748{
749    return _XSyncValueIsZero(a);
750}
751
752Bool
753XSyncValueIsPositive(XSyncValue v)
754{
755    return _XSyncValueIsPositive(v);
756}
757
758unsigned int
759XSyncValueLow32(XSyncValue v)
760{
761    return _XSyncValueLow32(v);
762}
763
764int
765XSyncValueHigh32(XSyncValue v)
766{
767    return _XSyncValueHigh32(v);
768}
769
770void
771XSyncValueAdd(XSyncValue *presult, XSyncValue a, XSyncValue b, Bool *poverflow)
772{
773    _XSyncValueAdd(presult, a, b, poverflow);
774}
775
776void
777XSyncValueSubtract(
778    XSyncValue *presult,
779    XSyncValue a, XSyncValue b,
780    Bool *poverflow)
781{
782    _XSyncValueSubtract(presult, a, b, poverflow);
783}
784
785void
786XSyncMaxValue(XSyncValue *pv)
787{
788    _XSyncMaxValue(pv);
789}
790
791void
792XSyncMinValue(XSyncValue *pv)
793{
794    _XSyncMinValue(pv);
795}
796