XSync.c revision caade7cc
1caade7ccSmrg/* $Xorg: XSync.c,v 1.5 2001/02/09 02:03:49 xorgcvs Exp $ */
2caade7ccSmrg/*
3caade7ccSmrg
4caade7ccSmrgCopyright 1991, 1993, 1998  The Open Group
5caade7ccSmrg
6caade7ccSmrgPermission to use, copy, modify, distribute, and sell this software and its
7caade7ccSmrgdocumentation for any purpose is hereby granted without fee, provided that
8caade7ccSmrgthe above copyright notice appear in all copies and that both that
9caade7ccSmrgcopyright notice and this permission notice appear in supporting
10caade7ccSmrgdocumentation.
11caade7ccSmrg
12caade7ccSmrgThe above copyright notice and this permission notice shall be included
13caade7ccSmrgin all copies or substantial portions of the Software.
14caade7ccSmrg
15caade7ccSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16caade7ccSmrgOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17caade7ccSmrgMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18caade7ccSmrgIN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
19caade7ccSmrgOTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20caade7ccSmrgARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21caade7ccSmrgOTHER DEALINGS IN THE SOFTWARE.
22caade7ccSmrg
23caade7ccSmrgExcept as contained in this notice, the name of The Open Group shall
24caade7ccSmrgnot be used in advertising or otherwise to promote the sale, use or
25caade7ccSmrgother dealings in this Software without prior written authorization
26caade7ccSmrgfrom The Open Group.
27caade7ccSmrg
28caade7ccSmrg*/
29caade7ccSmrg
30caade7ccSmrg/***********************************************************
31caade7ccSmrgCopyright 1991,1993 by Digital Equipment Corporation, Maynard, Massachusetts,
32caade7ccSmrgand Olivetti Research Limited, Cambridge, England.
33caade7ccSmrg
34caade7ccSmrg                        All Rights Reserved
35caade7ccSmrg
36caade7ccSmrgPermission to use, copy, modify, and distribute this software and its
37caade7ccSmrgdocumentation for any purpose and without fee is hereby granted,
38caade7ccSmrgprovided that the above copyright notice appear in all copies and that
39caade7ccSmrgboth that copyright notice and this permission notice appear in
40caade7ccSmrgsupporting documentation, and that the names of Digital or Olivetti
41caade7ccSmrgnot be used in advertising or publicity pertaining to distribution of the
42caade7ccSmrgsoftware without specific, written prior permission.
43caade7ccSmrg
44caade7ccSmrgDIGITAL AND OLIVETTI DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
45caade7ccSmrgSOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
46caade7ccSmrgFITNESS, IN NO EVENT SHALL THEY BE LIABLE FOR ANY SPECIAL, INDIRECT OR
47caade7ccSmrgCONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
48caade7ccSmrgUSE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
49caade7ccSmrgOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
50caade7ccSmrgPERFORMANCE OF THIS SOFTWARE.
51caade7ccSmrg
52caade7ccSmrg******************************************************************/
53caade7ccSmrg/* $XFree86: xc/lib/Xext/XSync.c,v 1.7tsi Exp $ */
54caade7ccSmrg
55caade7ccSmrg#ifdef HAVE_CONFIG_H
56caade7ccSmrg#include <config.h>
57caade7ccSmrg#endif
58caade7ccSmrg#include <stdio.h>
59caade7ccSmrg#define NEED_EVENTS
60caade7ccSmrg#define NEED_REPLIES
61caade7ccSmrg#include <X11/Xlibint.h>
62caade7ccSmrg#include <X11/extensions/Xext.h>
63caade7ccSmrg#include <X11/extensions/extutil.h>
64caade7ccSmrg#include <X11/extensions/syncstr.h>
65caade7ccSmrg
66caade7ccSmrgstatic XExtensionInfo _sync_info_data;
67caade7ccSmrgstatic XExtensionInfo *sync_info = &_sync_info_data;
68caade7ccSmrgstatic char    *sync_extension_name = SYNC_NAME;
69caade7ccSmrg
70caade7ccSmrg#define SyncCheckExtension(dpy,i,val) \
71caade7ccSmrg		XextCheckExtension(dpy, i, sync_extension_name, val)
72caade7ccSmrg#define SyncSimpleCheckExtension(dpy,i) \
73caade7ccSmrg		XextSimpleCheckExtension(dpy, i, sync_extension_name)
74caade7ccSmrg
75caade7ccSmrgstatic int      close_display(Display *dpy, XExtCodes *codes);
76caade7ccSmrgstatic Bool wire_to_event(Display *dpy, XEvent *event, xEvent *wire);
77caade7ccSmrgstatic Status event_to_wire(Display *dpy, XEvent *event, xEvent *wire);
78caade7ccSmrgstatic char    *error_string(Display *dpy, int code, XExtCodes *codes,
79caade7ccSmrg			     char *buf, int n);
80caade7ccSmrg
81caade7ccSmrgstatic XExtensionHooks sync_extension_hooks = {
82caade7ccSmrg    NULL,			/* create_gc */
83caade7ccSmrg    NULL,			/* copy_gc */
84caade7ccSmrg    NULL,			/* flush_gc */
85caade7ccSmrg    NULL,			/* free_gc */
86caade7ccSmrg    NULL,			/* create_font */
87caade7ccSmrg    NULL,			/* free_font */
88caade7ccSmrg    close_display,		/* close_display */
89caade7ccSmrg    wire_to_event,		/* wire_to_event */
90caade7ccSmrg    event_to_wire,		/* event_to_wire */
91caade7ccSmrg    NULL,			/* error */
92caade7ccSmrg    error_string,		/* error_string */
93caade7ccSmrg};
94caade7ccSmrg
95caade7ccSmrgstatic char    *sync_error_list[] = {
96caade7ccSmrg    "BadCounter",
97caade7ccSmrg    "BadAlarm",
98caade7ccSmrg};
99caade7ccSmrg
100caade7ccSmrgstatic
101caade7ccSmrgXEXT_GENERATE_FIND_DISPLAY(find_display, sync_info,
102caade7ccSmrg			   sync_extension_name,
103caade7ccSmrg			   &sync_extension_hooks,
104caade7ccSmrg			   XSyncNumberEvents, (XPointer) NULL)
105caade7ccSmrg
106caade7ccSmrgstatic
107caade7ccSmrgXEXT_GENERATE_CLOSE_DISPLAY(close_display, sync_info)
108caade7ccSmrg
109caade7ccSmrgstatic
110caade7ccSmrgXEXT_GENERATE_ERROR_STRING(error_string, sync_extension_name,
111caade7ccSmrg			   XSyncNumberErrors, sync_error_list)
112caade7ccSmrg
113caade7ccSmrg
114caade7ccSmrgstatic Bool
115caade7ccSmrgwire_to_event(Display *dpy, XEvent *event, xEvent *wire)
116caade7ccSmrg{
117caade7ccSmrg    XExtDisplayInfo *info = find_display(dpy);
118caade7ccSmrg    XSyncCounterNotifyEvent *aevent;
119caade7ccSmrg    xSyncCounterNotifyEvent *awire;
120caade7ccSmrg    XSyncAlarmNotifyEvent *anl;
121caade7ccSmrg    xSyncAlarmNotifyEvent *ane;
122caade7ccSmrg
123caade7ccSmrg    SyncCheckExtension(dpy, info, False);
124caade7ccSmrg
125caade7ccSmrg    switch ((wire->u.u.type & 0x7F) - info->codes->first_event)
126caade7ccSmrg    {
127caade7ccSmrg      case XSyncCounterNotify:
128caade7ccSmrg	awire = (xSyncCounterNotifyEvent *) wire;
129caade7ccSmrg	aevent = (XSyncCounterNotifyEvent *) event;
130caade7ccSmrg	aevent->type = awire->type & 0x7F;
131caade7ccSmrg	aevent->serial = _XSetLastRequestRead(dpy,
132caade7ccSmrg					      (xGenericReply *) wire);
133caade7ccSmrg	aevent->send_event = (awire->type & 0x80) != 0;
134caade7ccSmrg	aevent->display = dpy;
135caade7ccSmrg	aevent->counter = awire->counter;
136caade7ccSmrg	XSyncIntsToValue(&aevent->wait_value, awire->wait_value_lo,
137caade7ccSmrg				    awire->wait_value_hi);
138caade7ccSmrg	XSyncIntsToValue(&aevent->counter_value,
139caade7ccSmrg				    awire->counter_value_lo,
140caade7ccSmrg				    awire->counter_value_hi);
141caade7ccSmrg	aevent->time = awire->time;
142caade7ccSmrg	aevent->count = awire->count;
143caade7ccSmrg	aevent->destroyed = awire->destroyed;
144caade7ccSmrg	return True;
145caade7ccSmrg
146caade7ccSmrg      case XSyncAlarmNotify:
147caade7ccSmrg	ane = (xSyncAlarmNotifyEvent *) wire;	/* ENCODING EVENT PTR */
148caade7ccSmrg	anl = (XSyncAlarmNotifyEvent *) event;	/* LIBRARY EVENT PTR */
149caade7ccSmrg	anl->type = ane->type & 0x7F;
150caade7ccSmrg	anl->serial = _XSetLastRequestRead(dpy,
151caade7ccSmrg					   (xGenericReply *) wire);
152caade7ccSmrg	anl->send_event = (ane->type & 0x80) != 0;
153caade7ccSmrg	anl->display = dpy;
154caade7ccSmrg	anl->alarm = ane->alarm;
155caade7ccSmrg	XSyncIntsToValue(&anl->counter_value,
156caade7ccSmrg				    ane->counter_value_lo,
157caade7ccSmrg				    ane->counter_value_hi);
158caade7ccSmrg	XSyncIntsToValue(&anl->alarm_value,
159caade7ccSmrg				    ane->alarm_value_lo,
160caade7ccSmrg				    ane->alarm_value_hi);
161caade7ccSmrg	anl->state = (XSyncAlarmState)ane->state;
162caade7ccSmrg	anl->time = ane->time;
163caade7ccSmrg	return True;
164caade7ccSmrg    }
165caade7ccSmrg
166caade7ccSmrg    return False;
167caade7ccSmrg}
168caade7ccSmrg
169caade7ccSmrgstatic Status
170caade7ccSmrgevent_to_wire(Display *dpy, XEvent *event, xEvent *wire)
171caade7ccSmrg{
172caade7ccSmrg    XExtDisplayInfo *info = find_display(dpy);
173caade7ccSmrg    XSyncCounterNotifyEvent *aevent;
174caade7ccSmrg    xSyncCounterNotifyEvent *awire;
175caade7ccSmrg    XSyncAlarmNotifyEvent *anl;
176caade7ccSmrg    xSyncAlarmNotifyEvent *ane;
177caade7ccSmrg
178caade7ccSmrg    SyncCheckExtension(dpy, info, False);
179caade7ccSmrg
180caade7ccSmrg    switch ((event->type & 0x7F) - info->codes->first_event)
181caade7ccSmrg    {
182caade7ccSmrg      case XSyncCounterNotify:
183caade7ccSmrg	awire = (xSyncCounterNotifyEvent *) wire;
184caade7ccSmrg	aevent = (XSyncCounterNotifyEvent *) event;
185caade7ccSmrg	awire->type = aevent->type | (aevent->send_event ? 0x80 : 0);
186caade7ccSmrg	awire->sequenceNumber = aevent->serial & 0xFFFF;
187caade7ccSmrg	awire->counter = aevent->counter;
188caade7ccSmrg	awire->wait_value_lo = XSyncValueLow32(aevent->wait_value);
189caade7ccSmrg	awire->wait_value_hi = XSyncValueHigh32(aevent->wait_value);
190caade7ccSmrg	awire->counter_value_lo = XSyncValueLow32(aevent->counter_value);
191caade7ccSmrg	awire->counter_value_hi = XSyncValueHigh32(aevent->counter_value);
192caade7ccSmrg	awire->time = aevent->time;
193caade7ccSmrg	awire->count = aevent->count;
194caade7ccSmrg	awire->destroyed = aevent->destroyed;
195caade7ccSmrg	return True;
196caade7ccSmrg
197caade7ccSmrg      case XSyncAlarmNotify:
198caade7ccSmrg	ane = (xSyncAlarmNotifyEvent *) wire;	/* ENCODING EVENT PTR */
199caade7ccSmrg	anl = (XSyncAlarmNotifyEvent *) event;	/* LIBRARY EVENT PTR */
200caade7ccSmrg	ane->type = anl->type | (anl->send_event ? 0x80 : 0);
201caade7ccSmrg	ane->sequenceNumber = anl->serial & 0xFFFF;
202caade7ccSmrg	ane->alarm = anl->alarm;
203caade7ccSmrg	ane->counter_value_lo = XSyncValueLow32(anl->counter_value);
204caade7ccSmrg	ane->counter_value_hi = XSyncValueHigh32(anl->counter_value);
205caade7ccSmrg	ane->alarm_value_lo = XSyncValueLow32(anl->alarm_value);
206caade7ccSmrg	ane->alarm_value_hi = XSyncValueHigh32(anl->alarm_value);
207caade7ccSmrg	ane->state = anl->state;
208caade7ccSmrg	ane->time = anl->time;
209caade7ccSmrg	return True;
210caade7ccSmrg    }
211caade7ccSmrg    return False;
212caade7ccSmrg}
213caade7ccSmrg
214caade7ccSmrgStatus
215caade7ccSmrgXSyncQueryExtension(
216caade7ccSmrg    Display *dpy,
217caade7ccSmrg    int *event_base_return, int *error_base_return)
218caade7ccSmrg{
219caade7ccSmrg    XExtDisplayInfo *info = find_display(dpy);
220caade7ccSmrg
221caade7ccSmrg    if (XextHasExtension(info))
222caade7ccSmrg    {
223caade7ccSmrg	*event_base_return = info->codes->first_event;
224caade7ccSmrg	*error_base_return = info->codes->first_error;
225caade7ccSmrg	return True;
226caade7ccSmrg    }
227caade7ccSmrg    else
228caade7ccSmrg	return False;
229caade7ccSmrg}
230caade7ccSmrg
231caade7ccSmrgStatus
232caade7ccSmrgXSyncInitialize(
233caade7ccSmrg    Display *dpy,
234caade7ccSmrg    int *major_version_return, int *minor_version_return)
235caade7ccSmrg{
236caade7ccSmrg    XExtDisplayInfo *info = find_display(dpy);
237caade7ccSmrg    xSyncInitializeReply rep;
238caade7ccSmrg    xSyncInitializeReq *req;
239caade7ccSmrg
240caade7ccSmrg    SyncCheckExtension(dpy, info, False);
241caade7ccSmrg
242caade7ccSmrg    LockDisplay(dpy);
243caade7ccSmrg    GetReq(SyncInitialize, req);
244caade7ccSmrg    req->reqType = info->codes->major_opcode;
245caade7ccSmrg    req->syncReqType = X_SyncInitialize;
246caade7ccSmrg    req->majorVersion = SYNC_MAJOR_VERSION;
247caade7ccSmrg    req->minorVersion = SYNC_MINOR_VERSION;
248caade7ccSmrg    if (!_XReply(dpy, (xReply *) & rep, 0, xTrue))
249caade7ccSmrg    {
250caade7ccSmrg	UnlockDisplay(dpy);
251caade7ccSmrg	SyncHandle();
252caade7ccSmrg	return False;
253caade7ccSmrg    }
254caade7ccSmrg    UnlockDisplay(dpy);
255caade7ccSmrg    SyncHandle();
256caade7ccSmrg    *major_version_return = rep.majorVersion;
257caade7ccSmrg    *minor_version_return = rep.minorVersion;
258caade7ccSmrg    return ((rep.majorVersion == SYNC_MAJOR_VERSION)
259caade7ccSmrg#if SYNC_MINOR_VERSION > 0	/* avoid compiler warning */
260caade7ccSmrg	    && (rep.minorVersion >= SYNC_MINOR_VERSION)
261caade7ccSmrg#endif
262caade7ccSmrg	    );
263caade7ccSmrg}
264caade7ccSmrg
265caade7ccSmrgXSyncSystemCounter *
266caade7ccSmrgXSyncListSystemCounters(Display *dpy, int *n_counters_return)
267caade7ccSmrg{
268caade7ccSmrg    XExtDisplayInfo *info = find_display(dpy);
269caade7ccSmrg    xSyncListSystemCountersReply rep;
270caade7ccSmrg    xSyncListSystemCountersReq *req;
271caade7ccSmrg    XSyncSystemCounter *list = NULL;
272caade7ccSmrg
273caade7ccSmrg    SyncCheckExtension(dpy, info, NULL);
274caade7ccSmrg
275caade7ccSmrg    LockDisplay(dpy);
276caade7ccSmrg    GetReq(SyncListSystemCounters, req);
277caade7ccSmrg    req->reqType = info->codes->major_opcode;
278caade7ccSmrg    req->syncReqType = X_SyncListSystemCounters;
279caade7ccSmrg    if (!_XReply(dpy, (xReply *) & rep, 0, xFalse))
280caade7ccSmrg	goto bail;
281caade7ccSmrg
282caade7ccSmrg    *n_counters_return = rep.nCounters;
283caade7ccSmrg    if (rep.nCounters > 0)
284caade7ccSmrg    {
285caade7ccSmrg	xSyncSystemCounter *pWireSysCounter, *pNextWireSysCounter;
286caade7ccSmrg	XSyncCounter counter;
287caade7ccSmrg	int replylen;
288caade7ccSmrg	int i;
289caade7ccSmrg
290caade7ccSmrg	list = (XSyncSystemCounter *)Xmalloc(
291caade7ccSmrg			rep.nCounters * sizeof(XSyncSystemCounter));
292caade7ccSmrg	replylen = rep.length << 2;
293caade7ccSmrg	pWireSysCounter = (xSyncSystemCounter *) Xmalloc ((unsigned) replylen + 1);
294caade7ccSmrg                /* +1 to leave room for last null-terminator */
295caade7ccSmrg
296caade7ccSmrg	if ((!list) || (!pWireSysCounter))
297caade7ccSmrg	{
298caade7ccSmrg	    if (list) Xfree((char *) list);
299caade7ccSmrg	    if (pWireSysCounter)   Xfree((char *) pWireSysCounter);
300caade7ccSmrg	    _XEatData(dpy, (unsigned long) replylen);
301caade7ccSmrg	    list = NULL;
302caade7ccSmrg	    goto bail;
303caade7ccSmrg	}
304caade7ccSmrg
305caade7ccSmrg	_XReadPad(dpy, (char *)pWireSysCounter, replylen);
306caade7ccSmrg
307caade7ccSmrg	counter = pWireSysCounter->counter;
308caade7ccSmrg	for (i = 0; i < rep.nCounters; i++)
309caade7ccSmrg	{
310caade7ccSmrg	    list[i].counter = counter;
311caade7ccSmrg	    XSyncIntsToValue(&list[i].resolution,
312caade7ccSmrg					pWireSysCounter->resolution_lo,
313caade7ccSmrg					pWireSysCounter->resolution_hi);
314caade7ccSmrg
315caade7ccSmrg	    /* we may be about to clobber the counter field of the
316caade7ccSmrg	     * next syscounter because we have to add a null terminator
317caade7ccSmrg	     * to the counter name string.  So we save the next counter
318caade7ccSmrg	     * here.
319caade7ccSmrg	     */
320caade7ccSmrg	    pNextWireSysCounter = (xSyncSystemCounter *)
321caade7ccSmrg		(((char *)pWireSysCounter) + ((SIZEOF(xSyncSystemCounter) +
322caade7ccSmrg				     pWireSysCounter->name_length + 3) & ~3));
323caade7ccSmrg	    counter = pNextWireSysCounter->counter;
324caade7ccSmrg
325caade7ccSmrg	    list[i].name = ((char *)pWireSysCounter) +
326caade7ccSmrg						SIZEOF(xSyncSystemCounter);
327caade7ccSmrg	    /* null-terminate the string */
328caade7ccSmrg	    *(list[i].name + pWireSysCounter->name_length) = '\0';
329caade7ccSmrg	    pWireSysCounter = pNextWireSysCounter;
330caade7ccSmrg	}
331caade7ccSmrg    }
332caade7ccSmrg
333caade7ccSmrgbail:
334caade7ccSmrg    UnlockDisplay(dpy);
335caade7ccSmrg    SyncHandle();
336caade7ccSmrg    return list;
337caade7ccSmrg}
338caade7ccSmrg
339caade7ccSmrgvoid
340caade7ccSmrgXSyncFreeSystemCounterList(XSyncSystemCounter *list)
341caade7ccSmrg{
342caade7ccSmrg    if (list)
343caade7ccSmrg    {
344caade7ccSmrg	Xfree( ((char *)list[0].name) - SIZEOF(xSyncSystemCounter));
345caade7ccSmrg	Xfree(list);
346caade7ccSmrg    }
347caade7ccSmrg}
348caade7ccSmrg
349caade7ccSmrg
350caade7ccSmrgXSyncCounter
351caade7ccSmrgXSyncCreateCounter(Display *dpy, XSyncValue initial_value)
352caade7ccSmrg{
353caade7ccSmrg    XExtDisplayInfo *info = find_display(dpy);
354caade7ccSmrg    xSyncCreateCounterReq *req;
355caade7ccSmrg
356caade7ccSmrg    SyncCheckExtension(dpy, info, None);
357caade7ccSmrg
358caade7ccSmrg    LockDisplay(dpy);
359caade7ccSmrg    GetReq(SyncCreateCounter, req);
360caade7ccSmrg    req->reqType = info->codes->major_opcode;
361caade7ccSmrg    req->syncReqType = X_SyncCreateCounter;
362caade7ccSmrg
363caade7ccSmrg    req->cid = XAllocID(dpy);
364caade7ccSmrg    req->initial_value_lo = XSyncValueLow32(initial_value);
365caade7ccSmrg    req->initial_value_hi = XSyncValueHigh32(initial_value);
366caade7ccSmrg
367caade7ccSmrg    UnlockDisplay(dpy);
368caade7ccSmrg    SyncHandle();
369caade7ccSmrg    return req->cid;
370caade7ccSmrg}
371caade7ccSmrg
372caade7ccSmrgStatus
373caade7ccSmrgXSyncSetCounter(Display *dpy, XSyncCounter counter, XSyncValue value)
374caade7ccSmrg{
375caade7ccSmrg    XExtDisplayInfo *info = find_display(dpy);
376caade7ccSmrg    xSyncSetCounterReq *req;
377caade7ccSmrg
378caade7ccSmrg    SyncCheckExtension(dpy, info, False);
379caade7ccSmrg
380caade7ccSmrg    LockDisplay(dpy);
381caade7ccSmrg    GetReq(SyncSetCounter, req);
382caade7ccSmrg    req->reqType = info->codes->major_opcode;
383caade7ccSmrg    req->syncReqType = X_SyncSetCounter;
384caade7ccSmrg    req->cid = counter;
385caade7ccSmrg    req->value_lo = XSyncValueLow32(value);
386caade7ccSmrg    req->value_hi = XSyncValueHigh32(value);
387caade7ccSmrg    UnlockDisplay(dpy);
388caade7ccSmrg    SyncHandle();
389caade7ccSmrg    return True;
390caade7ccSmrg}
391caade7ccSmrg
392caade7ccSmrgStatus
393caade7ccSmrgXSyncChangeCounter(Display *dpy, XSyncCounter counter, XSyncValue value)
394caade7ccSmrg{
395caade7ccSmrg    XExtDisplayInfo *info = find_display(dpy);
396caade7ccSmrg    xSyncChangeCounterReq *req;
397caade7ccSmrg
398caade7ccSmrg    SyncCheckExtension(dpy, info, False);
399caade7ccSmrg
400caade7ccSmrg    LockDisplay(dpy);
401caade7ccSmrg    GetReq(SyncChangeCounter, req);
402caade7ccSmrg    req->reqType = info->codes->major_opcode;
403caade7ccSmrg    req->syncReqType = X_SyncChangeCounter;
404caade7ccSmrg    req->cid = counter;
405caade7ccSmrg    req->value_lo = XSyncValueLow32(value);
406caade7ccSmrg    req->value_hi = XSyncValueHigh32(value);
407caade7ccSmrg    UnlockDisplay(dpy);
408caade7ccSmrg    SyncHandle();
409caade7ccSmrg    return True;
410caade7ccSmrg}
411caade7ccSmrg
412caade7ccSmrgStatus
413caade7ccSmrgXSyncDestroyCounter(Display *dpy, XSyncCounter counter)
414caade7ccSmrg{
415caade7ccSmrg    XExtDisplayInfo *info = find_display(dpy);
416caade7ccSmrg    xSyncDestroyCounterReq *req;
417caade7ccSmrg
418caade7ccSmrg    SyncCheckExtension(dpy, info, False);
419caade7ccSmrg
420caade7ccSmrg    LockDisplay(dpy);
421caade7ccSmrg    GetReq(SyncDestroyCounter, req);
422caade7ccSmrg    req->reqType = info->codes->major_opcode;
423caade7ccSmrg    req->syncReqType = X_SyncDestroyCounter;
424caade7ccSmrg    req->counter = counter;
425caade7ccSmrg    UnlockDisplay(dpy);
426caade7ccSmrg    SyncHandle();
427caade7ccSmrg
428caade7ccSmrg    return True;
429caade7ccSmrg}
430caade7ccSmrg
431caade7ccSmrgStatus
432caade7ccSmrgXSyncQueryCounter(Display *dpy, XSyncCounter counter, XSyncValue *value_return)
433caade7ccSmrg{
434caade7ccSmrg    XExtDisplayInfo *info = find_display(dpy);
435caade7ccSmrg    xSyncQueryCounterReply rep;
436caade7ccSmrg    xSyncQueryCounterReq *req;
437caade7ccSmrg
438caade7ccSmrg    SyncCheckExtension(dpy, info, False);
439caade7ccSmrg
440caade7ccSmrg    LockDisplay(dpy);
441caade7ccSmrg    GetReq(SyncQueryCounter, req);
442caade7ccSmrg    req->reqType = info->codes->major_opcode;
443caade7ccSmrg    req->syncReqType = X_SyncQueryCounter;
444caade7ccSmrg    req->counter = counter;
445caade7ccSmrg    if (!_XReply(dpy, (xReply *) & rep, 0, xTrue))
446caade7ccSmrg    {
447caade7ccSmrg	UnlockDisplay(dpy);
448caade7ccSmrg	SyncHandle();
449caade7ccSmrg	return False;
450caade7ccSmrg    }
451caade7ccSmrg    XSyncIntsToValue(value_return, rep.value_lo, rep.value_hi);
452caade7ccSmrg    UnlockDisplay(dpy);
453caade7ccSmrg    SyncHandle();
454caade7ccSmrg
455caade7ccSmrg    return True;
456caade7ccSmrg}
457caade7ccSmrg
458caade7ccSmrg
459caade7ccSmrgStatus
460caade7ccSmrgXSyncAwait(Display *dpy, XSyncWaitCondition *wait_list, int n_conditions)
461caade7ccSmrg{
462caade7ccSmrg    XExtDisplayInfo *info = find_display(dpy);
463caade7ccSmrg    XSyncWaitCondition *wait_item = wait_list;
464caade7ccSmrg    xSyncAwaitReq  *req;
465caade7ccSmrg    unsigned int    len;
466caade7ccSmrg
467caade7ccSmrg    SyncCheckExtension(dpy, info, False);
468caade7ccSmrg
469caade7ccSmrg    LockDisplay(dpy);
470caade7ccSmrg    GetReq(SyncAwait, req);
471caade7ccSmrg    req->reqType = info->codes->major_opcode;
472caade7ccSmrg    req->syncReqType = X_SyncAwait;
473caade7ccSmrg    len = (n_conditions * SIZEOF(xSyncWaitCondition)) >> 2;
474caade7ccSmrg    SetReqLen(req, len, len /* XXX */ );
475caade7ccSmrg
476caade7ccSmrg    while (n_conditions--)
477caade7ccSmrg    {
478caade7ccSmrg	xSyncWaitCondition  wc;
479caade7ccSmrg	wc.counter = wait_item->trigger.counter;
480caade7ccSmrg	wc.value_type = wait_item->trigger.value_type;
481caade7ccSmrg	wc.wait_value_lo = XSyncValueLow32(wait_item->trigger.wait_value);
482caade7ccSmrg	wc.wait_value_hi = XSyncValueHigh32(wait_item->trigger.wait_value);
483caade7ccSmrg	wc.test_type = wait_item->trigger.test_type;
484caade7ccSmrg	wc.event_threshold_lo = XSyncValueLow32(wait_item->event_threshold);
485caade7ccSmrg	wc.event_threshold_hi = XSyncValueHigh32(wait_item->event_threshold);
486caade7ccSmrg	Data(dpy, (char *)&wc, SIZEOF(xSyncWaitCondition));
487caade7ccSmrg	wait_item++;		/* get next trigger */
488caade7ccSmrg    }
489caade7ccSmrg
490caade7ccSmrg    UnlockDisplay(dpy);
491caade7ccSmrg    SyncHandle();
492caade7ccSmrg    return True;
493caade7ccSmrg}
494caade7ccSmrg
495caade7ccSmrgstatic void
496caade7ccSmrg_XProcessAlarmAttributes(Display *dpy, xSyncChangeAlarmReq *req,
497caade7ccSmrg			 unsigned long valuemask,
498caade7ccSmrg			 XSyncAlarmAttributes *attributes)
499caade7ccSmrg{
500caade7ccSmrg
501caade7ccSmrg    unsigned long  values[32];
502caade7ccSmrg    unsigned long *value = values;
503caade7ccSmrg    unsigned int    nvalues;
504caade7ccSmrg
505caade7ccSmrg    if (valuemask & XSyncCACounter)
506caade7ccSmrg	*value++ = attributes->trigger.counter;
507caade7ccSmrg
508caade7ccSmrg    if (valuemask & XSyncCAValueType)
509caade7ccSmrg	*value++ = attributes->trigger.value_type;
510caade7ccSmrg
511caade7ccSmrg    if (valuemask & XSyncCAValue)
512caade7ccSmrg    {
513caade7ccSmrg	*value++ = XSyncValueHigh32(attributes->trigger.wait_value);
514caade7ccSmrg	*value++ = XSyncValueLow32(attributes->trigger.wait_value);
515caade7ccSmrg    }
516caade7ccSmrg
517caade7ccSmrg    if (valuemask & XSyncCATestType)
518caade7ccSmrg	*value++ = attributes->trigger.test_type;
519caade7ccSmrg
520caade7ccSmrg    if (valuemask & XSyncCADelta)
521caade7ccSmrg    {
522caade7ccSmrg	*value++ = XSyncValueHigh32(attributes->delta);
523caade7ccSmrg	*value++ = XSyncValueLow32(attributes->delta);
524caade7ccSmrg    }
525caade7ccSmrg
526caade7ccSmrg    if (valuemask & XSyncCAEvents)
527caade7ccSmrg	*value++ = attributes->events;
528caade7ccSmrg
529caade7ccSmrg    /* N.B. the 'state' field cannot be set or changed */
530caade7ccSmrg    req->length += (nvalues = value - values);
531caade7ccSmrg    nvalues <<= 2;		/* watch out for macros... */
532caade7ccSmrg
533caade7ccSmrg    Data32(dpy, (long *) values, (long) nvalues);
534caade7ccSmrg}
535caade7ccSmrg
536caade7ccSmrgXSyncAlarm
537caade7ccSmrgXSyncCreateAlarm(
538caade7ccSmrg    Display *dpy,
539caade7ccSmrg    unsigned long values_mask,
540caade7ccSmrg    XSyncAlarmAttributes *values)
541caade7ccSmrg{
542caade7ccSmrg    XExtDisplayInfo *info = find_display(dpy);
543caade7ccSmrg    xSyncCreateAlarmReq *req;
544caade7ccSmrg    XSyncAlarm      aid;
545caade7ccSmrg
546caade7ccSmrg    SyncCheckExtension(dpy, info, False);
547caade7ccSmrg
548caade7ccSmrg    LockDisplay(dpy);
549caade7ccSmrg    GetReq(SyncCreateAlarm, req);
550caade7ccSmrg    req->reqType = info->codes->major_opcode;
551caade7ccSmrg    req->syncReqType = X_SyncCreateAlarm;
552caade7ccSmrg    req->id = aid = XAllocID(dpy);
553caade7ccSmrg    values_mask &= XSyncCACounter | XSyncCAValueType | XSyncCAValue
554caade7ccSmrg			| XSyncCATestType | XSyncCADelta | XSyncCAEvents;
555caade7ccSmrg    if ((req->valueMask = values_mask))
556caade7ccSmrg	_XProcessAlarmAttributes(dpy, (xSyncChangeAlarmReq *) req,
557caade7ccSmrg				 values_mask, values);
558caade7ccSmrg    UnlockDisplay(dpy);
559caade7ccSmrg    SyncHandle();
560caade7ccSmrg    return aid;
561caade7ccSmrg}
562caade7ccSmrg
563caade7ccSmrgStatus
564caade7ccSmrgXSyncDestroyAlarm(Display *dpy, XSyncAlarm alarm)
565caade7ccSmrg{
566caade7ccSmrg    XExtDisplayInfo *info = find_display(dpy);
567caade7ccSmrg    xSyncDestroyAlarmReq *req;
568caade7ccSmrg
569caade7ccSmrg    SyncCheckExtension(dpy, info, False);
570caade7ccSmrg
571caade7ccSmrg    LockDisplay(dpy);
572caade7ccSmrg    GetReq(SyncDestroyAlarm, req);
573caade7ccSmrg    req->reqType = info->codes->major_opcode;
574caade7ccSmrg    req->syncReqType = X_SyncDestroyAlarm;
575caade7ccSmrg    req->alarm = alarm;
576caade7ccSmrg    UnlockDisplay(dpy);
577caade7ccSmrg    SyncHandle();
578caade7ccSmrg    return True;
579caade7ccSmrg}
580caade7ccSmrg
581caade7ccSmrgStatus
582caade7ccSmrgXSyncQueryAlarm(
583caade7ccSmrg    Display *dpy,
584caade7ccSmrg    XSyncAlarm alarm,
585caade7ccSmrg    XSyncAlarmAttributes *values_return)
586caade7ccSmrg{
587caade7ccSmrg    XExtDisplayInfo *info = find_display(dpy);
588caade7ccSmrg    xSyncQueryAlarmReq *req;
589caade7ccSmrg    xSyncQueryAlarmReply rep;
590caade7ccSmrg
591caade7ccSmrg    SyncCheckExtension(dpy, info, False);
592caade7ccSmrg
593caade7ccSmrg    LockDisplay(dpy);
594caade7ccSmrg    GetReq(SyncQueryAlarm, req);
595caade7ccSmrg    req->reqType = info->codes->major_opcode;
596caade7ccSmrg    req->syncReqType = X_SyncQueryAlarm;
597caade7ccSmrg    req->alarm = alarm;
598caade7ccSmrg
599caade7ccSmrg    if (!(_XReply(dpy, (xReply *) & rep,
600caade7ccSmrg    ((SIZEOF(xSyncQueryAlarmReply) - SIZEOF(xGenericReply)) >> 2), xFalse)))
601caade7ccSmrg    {
602caade7ccSmrg	UnlockDisplay(dpy);
603caade7ccSmrg	SyncHandle();
604caade7ccSmrg	return False;
605caade7ccSmrg    }
606caade7ccSmrg
607caade7ccSmrg    values_return->trigger.counter = rep.counter;
608caade7ccSmrg    values_return->trigger.value_type = (XSyncValueType)rep.value_type;
609caade7ccSmrg    XSyncIntsToValue(&values_return->trigger.wait_value,
610caade7ccSmrg				rep.wait_value_lo, rep.wait_value_hi);
611caade7ccSmrg    values_return->trigger.test_type = (XSyncTestType)rep.test_type;
612caade7ccSmrg    XSyncIntsToValue(&values_return->delta, rep.delta_lo,
613caade7ccSmrg				rep.delta_hi);
614caade7ccSmrg    values_return->events = rep.events;
615caade7ccSmrg    values_return->state = (XSyncAlarmState)rep.state;
616caade7ccSmrg    UnlockDisplay(dpy);
617caade7ccSmrg    SyncHandle();
618caade7ccSmrg    return True;
619caade7ccSmrg}
620caade7ccSmrg
621caade7ccSmrgStatus
622caade7ccSmrgXSyncChangeAlarm(
623caade7ccSmrg    Display *dpy,
624caade7ccSmrg    XSyncAlarm alarm,
625caade7ccSmrg    unsigned long values_mask,
626caade7ccSmrg    XSyncAlarmAttributes *values)
627caade7ccSmrg{
628caade7ccSmrg    XExtDisplayInfo *info = find_display(dpy);
629caade7ccSmrg    xSyncChangeAlarmReq *req;
630caade7ccSmrg
631caade7ccSmrg    SyncCheckExtension(dpy, info, False);
632caade7ccSmrg
633caade7ccSmrg    LockDisplay(dpy);
634caade7ccSmrg    GetReq(SyncChangeAlarm, req);
635caade7ccSmrg    req->reqType = info->codes->major_opcode;
636caade7ccSmrg    req->syncReqType = X_SyncChangeAlarm;
637caade7ccSmrg    req->alarm = alarm;
638caade7ccSmrg    values_mask &= XSyncCACounter | XSyncCAValueType | XSyncCAValue
639caade7ccSmrg		 | XSyncCATestType | XSyncCADelta | XSyncCAEvents;
640caade7ccSmrg    if ((req->valueMask = values_mask))
641caade7ccSmrg	_XProcessAlarmAttributes(dpy, req, values_mask, values);
642caade7ccSmrg    UnlockDisplay(dpy);
643caade7ccSmrg    SyncHandle();
644caade7ccSmrg    return True;
645caade7ccSmrg}
646caade7ccSmrg
647caade7ccSmrgStatus
648caade7ccSmrgXSyncSetPriority(
649caade7ccSmrg    Display *dpy,
650caade7ccSmrg    XID client_resource_id,
651caade7ccSmrg    int priority)
652caade7ccSmrg{
653caade7ccSmrg    XExtDisplayInfo *info = find_display(dpy);
654caade7ccSmrg    xSyncSetPriorityReq *req;
655caade7ccSmrg
656caade7ccSmrg    SyncCheckExtension(dpy, info, False);
657caade7ccSmrg
658caade7ccSmrg    LockDisplay(dpy);
659caade7ccSmrg    GetReq(SyncSetPriority, req);
660caade7ccSmrg    req->reqType = info->codes->major_opcode;
661caade7ccSmrg    req->syncReqType = X_SyncSetPriority;
662caade7ccSmrg    req->id = client_resource_id;
663caade7ccSmrg    req->priority = priority;
664caade7ccSmrg    UnlockDisplay(dpy);
665caade7ccSmrg    SyncHandle();
666caade7ccSmrg    return True;
667caade7ccSmrg}
668caade7ccSmrg
669caade7ccSmrgStatus
670caade7ccSmrgXSyncGetPriority(Display *dpy, XID client_resource_id, int *return_priority)
671caade7ccSmrg{
672caade7ccSmrg    XExtDisplayInfo *info = find_display(dpy);
673caade7ccSmrg    xSyncGetPriorityReply rep;
674caade7ccSmrg    xSyncGetPriorityReq *req;
675caade7ccSmrg
676caade7ccSmrg    SyncCheckExtension(dpy, info, False);
677caade7ccSmrg
678caade7ccSmrg    LockDisplay(dpy);
679caade7ccSmrg    GetReq(SyncGetPriority, req);
680caade7ccSmrg    req->reqType = info->codes->major_opcode;
681caade7ccSmrg    req->syncReqType = X_SyncGetPriority;
682caade7ccSmrg    req->id = client_resource_id;
683caade7ccSmrg
684caade7ccSmrg    if (!_XReply(dpy, (xReply *) & rep, 0, xFalse))
685caade7ccSmrg    {
686caade7ccSmrg	UnlockDisplay(dpy);
687caade7ccSmrg	SyncHandle();
688caade7ccSmrg	return False;
689caade7ccSmrg    }
690caade7ccSmrg    if (return_priority)
691caade7ccSmrg	*return_priority = rep.priority;
692caade7ccSmrg
693caade7ccSmrg    UnlockDisplay(dpy);
694caade7ccSmrg    SyncHandle();
695caade7ccSmrg    return True;
696caade7ccSmrg}
697caade7ccSmrg
698caade7ccSmrg/*
699caade7ccSmrg *  Functions corresponding to the macros for manipulating 64-bit values
700caade7ccSmrg */
701caade7ccSmrg
702caade7ccSmrg/* get rid of macros so we can define corresponding functions */
703caade7ccSmrg#undef XSyncIntToValue
704caade7ccSmrg#undef XSyncIntsToValue
705caade7ccSmrg#undef XSyncValueGreaterThan
706caade7ccSmrg#undef XSyncValueLessThan
707caade7ccSmrg#undef XSyncValueGreaterOrEqual
708caade7ccSmrg#undef XSyncValueLessOrEqual
709caade7ccSmrg#undef XSyncValueEqual
710caade7ccSmrg#undef XSyncValueIsNegative
711caade7ccSmrg#undef XSyncValueIsZero
712caade7ccSmrg#undef XSyncValueIsPositive
713caade7ccSmrg#undef XSyncValueLow32
714caade7ccSmrg#undef XSyncValueHigh32
715caade7ccSmrg#undef XSyncValueAdd
716caade7ccSmrg#undef XSyncValueSubtract
717caade7ccSmrg#undef XSyncMaxValue
718caade7ccSmrg#undef XSyncMinValue
719caade7ccSmrg
720caade7ccSmrgvoid
721caade7ccSmrgXSyncIntToValue(XSyncValue *pv, int i)
722caade7ccSmrg{
723caade7ccSmrg    _XSyncIntToValue(pv,i);
724caade7ccSmrg}
725caade7ccSmrg
726caade7ccSmrgvoid
727caade7ccSmrgXSyncIntsToValue(XSyncValue *pv, unsigned int l, int h)
728caade7ccSmrg{
729caade7ccSmrg    _XSyncIntsToValue(pv, l, h);
730caade7ccSmrg}
731caade7ccSmrg
732caade7ccSmrgBool
733caade7ccSmrgXSyncValueGreaterThan(XSyncValue a, XSyncValue b)
734caade7ccSmrg{
735caade7ccSmrg    return _XSyncValueGreaterThan(a, b);
736caade7ccSmrg}
737caade7ccSmrg
738caade7ccSmrgBool
739caade7ccSmrgXSyncValueLessThan(XSyncValue a, XSyncValue b)
740caade7ccSmrg{
741caade7ccSmrg    return _XSyncValueLessThan(a, b);
742caade7ccSmrg}
743caade7ccSmrg
744caade7ccSmrgBool
745caade7ccSmrgXSyncValueGreaterOrEqual(XSyncValue a, XSyncValue b)
746caade7ccSmrg{
747caade7ccSmrg    return _XSyncValueGreaterOrEqual(a, b);
748caade7ccSmrg}
749caade7ccSmrg
750caade7ccSmrgBool
751caade7ccSmrgXSyncValueLessOrEqual(XSyncValue a, XSyncValue b)
752caade7ccSmrg{
753caade7ccSmrg    return _XSyncValueLessOrEqual(a, b);
754caade7ccSmrg}
755caade7ccSmrg
756caade7ccSmrgBool
757caade7ccSmrgXSyncValueEqual(XSyncValue a, XSyncValue b)
758caade7ccSmrg{
759caade7ccSmrg    return _XSyncValueEqual(a, b);
760caade7ccSmrg}
761caade7ccSmrg
762caade7ccSmrgBool
763caade7ccSmrgXSyncValueIsNegative(XSyncValue v)
764caade7ccSmrg{
765caade7ccSmrg    return _XSyncValueIsNegative(v);
766caade7ccSmrg}
767caade7ccSmrg
768caade7ccSmrgBool
769caade7ccSmrgXSyncValueIsZero(XSyncValue a)
770caade7ccSmrg{
771caade7ccSmrg    return _XSyncValueIsZero(a);
772caade7ccSmrg}
773caade7ccSmrg
774caade7ccSmrgBool
775caade7ccSmrgXSyncValueIsPositive(XSyncValue v)
776caade7ccSmrg{
777caade7ccSmrg    return _XSyncValueIsPositive(v);
778caade7ccSmrg}
779caade7ccSmrg
780caade7ccSmrgunsigned int
781caade7ccSmrgXSyncValueLow32(XSyncValue v)
782caade7ccSmrg{
783caade7ccSmrg    return _XSyncValueLow32(v);
784caade7ccSmrg}
785caade7ccSmrg
786caade7ccSmrgint
787caade7ccSmrgXSyncValueHigh32(XSyncValue v)
788caade7ccSmrg{
789caade7ccSmrg    return _XSyncValueHigh32(v);
790caade7ccSmrg}
791caade7ccSmrg
792caade7ccSmrgvoid
793caade7ccSmrgXSyncValueAdd(XSyncValue *presult, XSyncValue a, XSyncValue b, Bool *poverflow)
794caade7ccSmrg{
795caade7ccSmrg    _XSyncValueAdd(presult, a, b, poverflow);
796caade7ccSmrg}
797caade7ccSmrg
798caade7ccSmrgvoid
799caade7ccSmrgXSyncValueSubtract(
800caade7ccSmrg    XSyncValue *presult,
801caade7ccSmrg    XSyncValue a, XSyncValue b,
802caade7ccSmrg    Bool *poverflow)
803caade7ccSmrg{
804caade7ccSmrg    _XSyncValueSubtract(presult, a, b, poverflow);
805caade7ccSmrg}
806caade7ccSmrg
807caade7ccSmrgvoid
808caade7ccSmrgXSyncMaxValue(XSyncValue *pv)
809caade7ccSmrg{
810caade7ccSmrg    _XSyncMaxValue(pv);
811caade7ccSmrg}
812caade7ccSmrg
813caade7ccSmrgvoid
814caade7ccSmrgXSyncMinValue(XSyncValue *pv)
815caade7ccSmrg{
816caade7ccSmrg    _XSyncMinValue(pv);
817caade7ccSmrg}
818