XF86VMode.c revision 191cded7
1/* $XConsortium: XF86VMode.c /main/2 1995/11/14 18:17:58 kaleb $ */
2/* $XFree86: xc/lib/Xxf86vm/XF86VMode.c,v 3.33 2002/10/16 00:37:34 dawes Exp $ */
3/*
4
5Copyright (c) 1995  Kaleb S. KEITHLEY
6
7Permission is hereby granted, free of charge, to any person obtaining
8a copy of this software and associated documentation files (the
9"Software"), to deal in the Software without restriction, including
10without limitation the rights to use, copy, modify, merge, publish,
11distribute, sublicense, and/or sell copies of the Software, and to
12permit persons to whom the Software is furnished to do so, subject to
13the following conditions:
14
15The above copyright notice and this permission notice shall be
16included in all copies or substantial portions of the Software.
17
18THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21IN NO EVENT SHALL Kaleb S. KEITHLEY BE LIABLE FOR ANY CLAIM, DAMAGES
22OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24OTHER DEALINGS IN THE SOFTWARE.
25
26Except as contained in this notice, the name of Kaleb S. KEITHLEY
27shall not be used in advertising or otherwise to promote the sale, use
28or other dealings in this Software without prior written authorization
29from Kaleb S. KEITHLEY.
30
31*/
32/* $XConsortium: XF86VMode.c /main/4 1996/01/16 07:52:25 kaleb CHECKEDOUT $ */
33
34/* THIS IS NOT AN X CONSORTIUM STANDARD */
35
36#define NEED_EVENTS
37#define NEED_REPLIES
38#include <X11/Xlibint.h>
39#include <X11/extensions/xf86vmstr.h>
40#include <X11/extensions/Xext.h>
41#include <X11/extensions/extutil.h>
42
43#ifdef DEBUG
44#include <stdio.h>
45#endif
46
47#ifndef MODE_BAD
48#define MODE_BAD 255
49#endif
50
51static XExtensionInfo _xf86vidmode_info_data;
52static XExtensionInfo *xf86vidmode_info = &_xf86vidmode_info_data;
53static char *xf86vidmode_extension_name = XF86VIDMODENAME;
54
55#define XF86VidModeCheckExtension(dpy,i,val) \
56  XextCheckExtension (dpy, i, xf86vidmode_extension_name, val)
57
58/*****************************************************************************
59 *                                                                           *
60 *			   private utility routines                          *
61 *                                                                           *
62 *****************************************************************************/
63
64static XEXT_CLOSE_DISPLAY_PROTO(close_display);
65static /* const */ XExtensionHooks xf86vidmode_extension_hooks = {
66    NULL,				/* create_gc */
67    NULL,				/* copy_gc */
68    NULL,				/* flush_gc */
69    NULL,				/* free_gc */
70    NULL,				/* create_font */
71    NULL,				/* free_font */
72    close_display,			/* close_display */
73    NULL,				/* wire_to_event */
74    NULL,				/* event_to_wire */
75    NULL,				/* error */
76    NULL,				/* error_string */
77};
78
79static XEXT_GENERATE_FIND_DISPLAY (find_display, xf86vidmode_info,
80				   xf86vidmode_extension_name,
81				   &xf86vidmode_extension_hooks,
82				   0, NULL)
83
84static XEXT_GENERATE_CLOSE_DISPLAY (close_display, xf86vidmode_info)
85
86
87/*****************************************************************************
88 *                                                                           *
89 *		    public XFree86-VidMode Extension routines                *
90 *                                                                           *
91 *****************************************************************************/
92
93Bool
94XF86VidModeQueryExtension (dpy, event_basep, error_basep)
95    Display *dpy;
96    int *event_basep, *error_basep;
97{
98    XExtDisplayInfo *info = find_display (dpy);
99
100    if (XextHasExtension(info)) {
101	*event_basep = info->codes->first_event;
102	*error_basep = info->codes->first_error;
103	return True;
104    } else {
105	return False;
106    }
107}
108
109Bool
110XF86VidModeQueryVersion(dpy, majorVersion, minorVersion)
111    Display* dpy;
112    int* majorVersion;
113    int* minorVersion;
114{
115    XExtDisplayInfo *info = find_display (dpy);
116    xXF86VidModeQueryVersionReply rep;
117    xXF86VidModeQueryVersionReq *req;
118
119    XF86VidModeCheckExtension (dpy, info, False);
120
121    LockDisplay(dpy);
122    GetReq(XF86VidModeQueryVersion, req);
123    req->reqType = info->codes->major_opcode;
124    req->xf86vidmodeReqType = X_XF86VidModeQueryVersion;
125    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
126	UnlockDisplay(dpy);
127	SyncHandle();
128	return False;
129    }
130    *majorVersion = rep.majorVersion;
131    *minorVersion = rep.minorVersion;
132    UnlockDisplay(dpy);
133    SyncHandle();
134    if (*majorVersion >= 2)
135	XF86VidModeSetClientVersion(dpy);
136    return True;
137}
138
139Bool
140XF86VidModeSetClientVersion(Display *dpy)
141{
142    XExtDisplayInfo *info = find_display(dpy);
143    xXF86VidModeSetClientVersionReq *req;
144
145    XF86VidModeCheckExtension(dpy, info, False);
146
147    LockDisplay(dpy);
148    GetReq(XF86VidModeSetClientVersion, req);
149    req->reqType = info->codes->major_opcode;
150    req->xf86vidmodeReqType = X_XF86VidModeSetClientVersion;
151    req->major = XF86VIDMODE_MAJOR_VERSION;
152    req->minor = XF86VIDMODE_MINOR_VERSION;
153    UnlockDisplay(dpy);
154    SyncHandle();
155    return True;
156}
157
158Bool
159XF86VidModeSetGamma(Display *dpy, int screen, XF86VidModeGamma *Gamma)
160{
161    XExtDisplayInfo *info = find_display(dpy);
162    xXF86VidModeSetGammaReq *req;
163
164    XF86VidModeCheckExtension(dpy, info, False);
165
166    LockDisplay(dpy);
167    GetReq(XF86VidModeSetGamma, req);
168    req->reqType = info->codes->major_opcode;
169    req->xf86vidmodeReqType = X_XF86VidModeSetGamma;
170    req->screen = screen;
171    req->red = (CARD32)(Gamma->red * 10000.);
172    req->green = (CARD32)(Gamma->green * 10000.);
173    req->blue = (CARD32)(Gamma->blue * 10000.);
174    UnlockDisplay(dpy);
175    SyncHandle();
176    return True;
177}
178
179Bool
180XF86VidModeGetGamma(Display *dpy, int screen, XF86VidModeGamma *Gamma)
181{
182    XExtDisplayInfo *info = find_display (dpy);
183    xXF86VidModeGetGammaReply rep;
184    xXF86VidModeGetGammaReq *req;
185
186    XF86VidModeCheckExtension (dpy, info, False);
187
188    LockDisplay(dpy);
189    GetReq(XF86VidModeGetGamma, req);
190    req->reqType = info->codes->major_opcode;
191    req->xf86vidmodeReqType = X_XF86VidModeGetGamma;
192    req->screen = screen;
193    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
194	UnlockDisplay(dpy);
195	SyncHandle();
196	return False;
197    }
198    Gamma->red = ((float)rep.red) / 10000.;
199    Gamma->green = ((float)rep.green) / 10000.;
200    Gamma->blue = ((float)rep.blue) / 10000.;
201    UnlockDisplay(dpy);
202    SyncHandle();
203    return True;
204}
205
206Bool
207XF86VidModeGetModeLine(dpy, screen, dotclock, modeline)
208    Display* dpy;
209    int screen;
210    int* dotclock;
211    XF86VidModeModeLine* modeline;
212{
213    XExtDisplayInfo *info = find_display (dpy);
214    xXF86VidModeGetModeLineReply rep;
215    xXF86OldVidModeGetModeLineReply oldrep;
216    xXF86VidModeGetModeLineReq *req;
217    int majorVersion, minorVersion;
218
219    XF86VidModeCheckExtension (dpy, info, False);
220    XF86VidModeQueryVersion(dpy, &majorVersion, &minorVersion);
221
222    LockDisplay(dpy);
223    GetReq(XF86VidModeGetModeLine, req);
224    req->reqType = info->codes->major_opcode;
225    req->xf86vidmodeReqType = X_XF86VidModeGetModeLine;
226    req->screen = screen;
227
228    if (majorVersion < 2) {
229	if (!_XReply(dpy, (xReply *)&oldrep,
230            (SIZEOF(xXF86OldVidModeGetModeLineReply) - SIZEOF(xReply)) >> 2, xFalse)) {
231	    UnlockDisplay(dpy);
232	    SyncHandle();
233	    return False;
234	}
235	*dotclock = oldrep.dotclock;
236	modeline->hdisplay   = oldrep.hdisplay;
237	modeline->hsyncstart = oldrep.hsyncstart;
238	modeline->hsyncend   = oldrep.hsyncend;
239	modeline->htotal     = oldrep.htotal;
240	modeline->hskew      = 0;
241	modeline->vdisplay   = oldrep.vdisplay;
242	modeline->vsyncstart = oldrep.vsyncstart;
243	modeline->vsyncend   = oldrep.vsyncend;
244	modeline->vtotal     = oldrep.vtotal;
245	modeline->flags      = oldrep.flags;
246	modeline->privsize   = oldrep.privsize;
247    } else {
248	if (!_XReply(dpy, (xReply *)&rep,
249            (SIZEOF(xXF86VidModeGetModeLineReply) - SIZEOF(xReply)) >> 2, xFalse)) {
250	    UnlockDisplay(dpy);
251	    SyncHandle();
252	    return False;
253	}
254	*dotclock = rep.dotclock;
255	modeline->hdisplay   = rep.hdisplay;
256	modeline->hsyncstart = rep.hsyncstart;
257	modeline->hsyncend   = rep.hsyncend;
258	modeline->htotal     = rep.htotal;
259	modeline->hskew      = rep.hskew;
260	modeline->vdisplay   = rep.vdisplay;
261	modeline->vsyncstart = rep.vsyncstart;
262	modeline->vsyncend   = rep.vsyncend;
263	modeline->vtotal     = rep.vtotal;
264	modeline->flags      = rep.flags;
265	modeline->privsize   = rep.privsize;
266    }
267
268    if (modeline->privsize > 0) {
269	if (!(modeline->private = Xcalloc(modeline->privsize, sizeof(INT32)))) {
270	    _XEatData(dpy, (modeline->privsize) * sizeof(INT32));
271	    Xfree(modeline->private);
272	    return False;
273	}
274	_XRead(dpy, (char*)modeline->private, modeline->privsize * sizeof(INT32));
275    } else {
276	modeline->private = NULL;
277    }
278    UnlockDisplay(dpy);
279    SyncHandle();
280    return True;
281}
282
283Bool
284XF86VidModeGetAllModeLines(dpy, screen, modecount, modelinesPtr)
285    Display* dpy;
286    int screen;
287    int* modecount;
288    XF86VidModeModeInfo ***modelinesPtr;
289{
290    XExtDisplayInfo *info = find_display (dpy);
291    xXF86VidModeGetAllModeLinesReply rep;
292    xXF86VidModeGetAllModeLinesReq *req;
293    XF86VidModeModeInfo *mdinfptr, **modelines;
294    xXF86VidModeModeInfo xmdline;
295    xXF86OldVidModeModeInfo oldxmdline;
296    int i;
297    int majorVersion, minorVersion;
298    Bool protocolBug = False;
299
300    XF86VidModeCheckExtension (dpy, info, False);
301
302    /*
303     * Note: There was a bug in the protocol implementation in versions
304     * 0.x with x < 8 (the .private field wasn't being passed over the wire).
305     * Check the server's version, and accept the old format if appropriate.
306     */
307
308    XF86VidModeQueryVersion(dpy, &majorVersion, &minorVersion);
309    if (majorVersion == 0 && minorVersion < 8) {
310	protocolBug = True;
311#ifdef DEBUG
312	fprintf(stderr, "XF86VidModeGetAllModeLines: Warning: Xserver is"
313		"running an old version (%d.%d)\n", majorVersion,
314		minorVersion);
315#endif
316    }
317
318    LockDisplay(dpy);
319    GetReq(XF86VidModeGetAllModeLines, req);
320    req->reqType = info->codes->major_opcode;
321    req->xf86vidmodeReqType = X_XF86VidModeGetAllModeLines;
322    req->screen = screen;
323    if (!_XReply(dpy, (xReply *)&rep,
324        (SIZEOF(xXF86VidModeGetAllModeLinesReply) - SIZEOF(xReply)) >> 2, xFalse)) {
325        UnlockDisplay(dpy);
326	SyncHandle();
327	return False;
328    }
329
330    *modecount = rep.modecount;
331
332    if (!(modelines = (XF86VidModeModeInfo **) Xcalloc(rep.modecount,
333                                          sizeof(XF86VidModeModeInfo *)
334                                          +sizeof(XF86VidModeModeInfo)))) {
335	if (majorVersion < 2)
336            _XEatData(dpy, (rep.modecount) * sizeof(xXF86OldVidModeModeInfo));
337	else
338            _XEatData(dpy, (rep.modecount) * sizeof(xXF86VidModeModeInfo));
339        Xfree(modelines);
340        return False;
341    }
342    mdinfptr = (XF86VidModeModeInfo *) (
343			    (char *) modelines
344			    + rep.modecount*sizeof(XF86VidModeModeInfo *)
345		    );
346
347    for (i = 0; i < rep.modecount; i++) {
348        modelines[i] = mdinfptr++;
349	if (majorVersion < 2) {
350            _XRead(dpy, (char*)&oldxmdline, sizeof(xXF86OldVidModeModeInfo));
351	    modelines[i]->dotclock   = oldxmdline.dotclock;
352	    modelines[i]->hdisplay   = oldxmdline.hdisplay;
353	    modelines[i]->hsyncstart = oldxmdline.hsyncstart;
354	    modelines[i]->hsyncend   = oldxmdline.hsyncend;
355	    modelines[i]->htotal     = oldxmdline.htotal;
356	    modelines[i]->hskew      = 0;
357	    modelines[i]->vdisplay   = oldxmdline.vdisplay;
358	    modelines[i]->vsyncstart = oldxmdline.vsyncstart;
359	    modelines[i]->vsyncend   = oldxmdline.vsyncend;
360	    modelines[i]->vtotal     = oldxmdline.vtotal;
361	    modelines[i]->flags      = oldxmdline.flags;
362	    if (protocolBug) {
363		modelines[i]->privsize = 0;
364		modelines[i]->private = NULL;
365	    } else {
366		modelines[i]->privsize   = oldxmdline.privsize;
367		if (oldxmdline.privsize > 0) {
368	            if (!(modelines[i]->private =
369			    Xcalloc(oldxmdline.privsize, sizeof(INT32)))) {
370			_XEatData(dpy, (oldxmdline.privsize) * sizeof(INT32));
371			Xfree(modelines[i]->private);
372		    } else {
373			_XRead(dpy, (char*)modelines[i]->private,
374			     oldxmdline.privsize * sizeof(INT32));
375		    }
376		} else {
377		  modelines[i]->private = NULL;
378		}
379	    }
380	} else {
381            _XRead(dpy, (char*)&xmdline, sizeof(xXF86VidModeModeInfo));
382	    modelines[i]->dotclock   = xmdline.dotclock;
383	    modelines[i]->hdisplay   = xmdline.hdisplay;
384	    modelines[i]->hsyncstart = xmdline.hsyncstart;
385	    modelines[i]->hsyncend   = xmdline.hsyncend;
386	    modelines[i]->htotal     = xmdline.htotal;
387	    modelines[i]->hskew      = xmdline.hskew;
388	    modelines[i]->vdisplay   = xmdline.vdisplay;
389	    modelines[i]->vsyncstart = xmdline.vsyncstart;
390	    modelines[i]->vsyncend   = xmdline.vsyncend;
391	    modelines[i]->vtotal     = xmdline.vtotal;
392	    modelines[i]->flags      = xmdline.flags;
393	    if (protocolBug) {
394		modelines[i]->privsize = 0;
395		modelines[i]->private = NULL;
396	    } else {
397		modelines[i]->privsize   = xmdline.privsize;
398		if (xmdline.privsize > 0) {
399		    if (!(modelines[i]->private =
400			    Xcalloc(xmdline.privsize, sizeof(INT32)))) {
401			_XEatData(dpy, (xmdline.privsize) * sizeof(INT32));
402			Xfree(modelines[i]->private);
403		    } else {
404			_XRead(dpy, (char*)modelines[i]->private,
405			     xmdline.privsize * sizeof(INT32));
406		    }
407		} else {
408		    modelines[i]->private = NULL;
409		}
410	    }
411	}
412    }
413    *modelinesPtr = modelines;
414    UnlockDisplay(dpy);
415    SyncHandle();
416    return True;
417}
418
419/*
420 * GetReq replacement for use with VidMode protocols earlier than 2.0
421 */
422#if !defined(UNIXCPP) || defined(ANSICPP)
423#define GetOldReq(name, oldname, req) \
424        WORD64ALIGN\
425	if ((dpy->bufptr + SIZEOF(x##oldname##Req)) > dpy->bufmax)\
426		_XFlush(dpy);\
427	req = (x##oldname##Req *)(dpy->last_req = dpy->bufptr);\
428	req->reqType = X_##name;\
429	req->length = (SIZEOF(x##oldname##Req))>>2;\
430	dpy->bufptr += SIZEOF(x##oldname##Req);\
431	dpy->request++
432
433#else  /* non-ANSI C uses empty comment instead of "##" for token concatenation */
434#define GetOldReq(name, oldname, req) \
435        WORD64ALIGN\
436	if ((dpy->bufptr + SIZEOF(x/**/oldname/**/Req)) > dpy->bufmax)\
437		_XFlush(dpy);\
438	req = (x/**/oldname/**/Req *)(dpy->last_req = dpy->bufptr);\
439	req->reqType = X_/**/name;\
440	req->length = (SIZEOF(x/**/oldname/**/Req))>>2;\
441	dpy->bufptr += SIZEOF(x/**/oldname/**/Req);\
442	dpy->request++
443#endif
444
445Bool
446XF86VidModeAddModeLine (dpy, screen, newmodeline, aftermodeline)
447    Display *dpy;
448    int screen;
449    XF86VidModeModeInfo* newmodeline;
450    XF86VidModeModeInfo* aftermodeline;
451{
452    XExtDisplayInfo *info = find_display (dpy);
453    xXF86VidModeAddModeLineReq *req;
454    xXF86OldVidModeAddModeLineReq *oldreq;
455    int majorVersion, minorVersion;
456
457    XF86VidModeCheckExtension (dpy, info, False);
458    XF86VidModeQueryVersion(dpy, &majorVersion, &minorVersion);
459
460    LockDisplay(dpy);
461    if (majorVersion < 2) {
462	GetOldReq(XF86VidModeAddModeLine, XF86OldVidModeAddModeLine, oldreq);
463	oldreq->reqType = info->codes->major_opcode;
464	oldreq->xf86vidmodeReqType = X_XF86VidModeAddModeLine;
465	oldreq->screen = screen;
466	oldreq->dotclock =	newmodeline->dotclock;
467	oldreq->hdisplay =	newmodeline->hdisplay;
468	oldreq->hsyncstart =	newmodeline->hsyncstart;
469	oldreq->hsyncend =	newmodeline->hsyncend;
470	oldreq->htotal =	newmodeline->htotal;
471	oldreq->vdisplay =	newmodeline->vdisplay;
472	oldreq->vsyncstart =	newmodeline->vsyncstart;
473	oldreq->vsyncend =	newmodeline->vsyncend;
474	oldreq->vtotal =	newmodeline->vtotal;
475	oldreq->flags =		newmodeline->flags;
476	oldreq->privsize =	newmodeline->privsize;
477	if (aftermodeline != NULL) {
478	    oldreq->after_dotclock =	aftermodeline->dotclock;
479	    oldreq->after_hdisplay =	aftermodeline->hdisplay;
480	    oldreq->after_hsyncstart =	aftermodeline->hsyncstart;
481	    oldreq->after_hsyncend =	aftermodeline->hsyncend;
482	    oldreq->after_htotal =	aftermodeline->htotal;
483	    oldreq->after_vdisplay =	aftermodeline->vdisplay;
484	    oldreq->after_vsyncstart =	aftermodeline->vsyncstart;
485	    oldreq->after_vsyncend =	aftermodeline->vsyncend;
486	    oldreq->after_vtotal =	aftermodeline->vtotal;
487	    oldreq->after_flags =	aftermodeline->flags;
488	} else {
489	    oldreq->after_dotclock =	0;
490	    oldreq->after_hdisplay =	0;
491	    oldreq->after_hsyncstart =	0;
492	    oldreq->after_hsyncend =	0;
493	    oldreq->after_htotal =	0;
494	    oldreq->after_vdisplay =	0;
495	    oldreq->after_vsyncstart =	0;
496	    oldreq->after_vsyncend =	0;
497	    oldreq->after_vtotal =	0;
498	    oldreq->after_flags =	0;
499	}
500	if (newmodeline->privsize) {
501	    oldreq->length += newmodeline->privsize;
502	    Data32(dpy, (long *) newmodeline->private,
503	       newmodeline->privsize * sizeof(INT32));
504	}
505    } else {
506	GetReq(XF86VidModeAddModeLine, req);
507	req->reqType = info->codes->major_opcode;
508	req->xf86vidmodeReqType = X_XF86VidModeAddModeLine;
509	req->screen = screen;
510	req->dotclock =		newmodeline->dotclock;
511	req->hdisplay =		newmodeline->hdisplay;
512	req->hsyncstart =	newmodeline->hsyncstart;
513	req->hsyncend =		newmodeline->hsyncend;
514	req->htotal =		newmodeline->htotal;
515	req->hskew =		newmodeline->hskew;
516	req->vdisplay =		newmodeline->vdisplay;
517	req->vsyncstart =	newmodeline->vsyncstart;
518	req->vsyncend =		newmodeline->vsyncend;
519	req->vtotal =		newmodeline->vtotal;
520	req->flags =		newmodeline->flags;
521	req->privsize =		newmodeline->privsize;
522	if (aftermodeline != NULL) {
523	    req->after_dotclock =	aftermodeline->dotclock;
524	    req->after_hdisplay =	aftermodeline->hdisplay;
525	    req->after_hsyncstart =	aftermodeline->hsyncstart;
526	    req->after_hsyncend =	aftermodeline->hsyncend;
527	    req->after_htotal =		aftermodeline->htotal;
528	    req->after_hskew =		aftermodeline->hskew;
529	    req->after_vdisplay =	aftermodeline->vdisplay;
530	    req->after_vsyncstart =	aftermodeline->vsyncstart;
531	    req->after_vsyncend =	aftermodeline->vsyncend;
532	    req->after_vtotal =		aftermodeline->vtotal;
533	    req->after_flags =		aftermodeline->flags;
534	} else {
535	    req->after_dotclock =	0;
536	    req->after_hdisplay =	0;
537	    req->after_hsyncstart =	0;
538	    req->after_hsyncend =	0;
539	    req->after_htotal =		0;
540	    req->after_hskew =		0;
541	    req->after_vdisplay =	0;
542	    req->after_vsyncstart =	0;
543	    req->after_vsyncend =	0;
544	    req->after_vtotal =		0;
545	    req->after_flags =		0;
546	}
547	if (newmodeline->privsize) {
548	    req->length += newmodeline->privsize;
549	    Data32(dpy, (long *) newmodeline->private,
550	       newmodeline->privsize * sizeof(INT32));
551	}
552    }
553    UnlockDisplay(dpy);
554    SyncHandle();
555    return True;
556}
557
558Bool
559XF86VidModeDeleteModeLine (dpy, screen, modeline)
560    Display *dpy;
561    int screen;
562    XF86VidModeModeInfo* modeline;
563{
564    XExtDisplayInfo *info = find_display (dpy);
565    xXF86VidModeDeleteModeLineReq *req;
566    xXF86OldVidModeDeleteModeLineReq *oldreq;
567    int majorVersion, minorVersion;
568
569    XF86VidModeCheckExtension (dpy, info, 0);
570    XF86VidModeQueryVersion(dpy, &majorVersion, &minorVersion);
571
572    LockDisplay(dpy);
573    if (majorVersion < 2) {
574	GetOldReq(XF86VidModeDeleteModeLine, XF86OldVidModeDeleteModeLine, oldreq);
575	oldreq->reqType = info->codes->major_opcode;
576	oldreq->xf86vidmodeReqType = X_XF86VidModeDeleteModeLine;
577	oldreq->screen = screen;
578	oldreq->dotclock =	modeline->dotclock;
579	oldreq->hdisplay =	modeline->hdisplay;
580	oldreq->hsyncstart =	modeline->hsyncstart;
581	oldreq->hsyncend =	modeline->hsyncend;
582	oldreq->htotal =	modeline->htotal;
583	oldreq->vdisplay =	modeline->vdisplay;
584	oldreq->vsyncstart =	modeline->vsyncstart;
585	oldreq->vsyncend =	modeline->vsyncend;
586	oldreq->vtotal =	modeline->vtotal;
587	oldreq->flags =		modeline->flags;
588	oldreq->privsize =	modeline->privsize;
589	if (modeline->privsize) {
590	    oldreq->length += modeline->privsize;
591	    Data32(dpy, (long *) modeline->private,
592	       modeline->privsize * sizeof(INT32));
593	}
594    } else {
595	GetReq(XF86VidModeDeleteModeLine, req);
596	req->reqType = info->codes->major_opcode;
597	req->xf86vidmodeReqType = X_XF86VidModeDeleteModeLine;
598	req->screen = screen;
599	req->dotclock =		modeline->dotclock;
600	req->hdisplay =		modeline->hdisplay;
601	req->hsyncstart =	modeline->hsyncstart;
602	req->hsyncend =		modeline->hsyncend;
603	req->htotal =		modeline->htotal;
604	req->hskew =		modeline->hskew;
605	req->vdisplay =		modeline->vdisplay;
606	req->vsyncstart =	modeline->vsyncstart;
607	req->vsyncend =		modeline->vsyncend;
608	req->vtotal =		modeline->vtotal;
609	req->flags =		modeline->flags;
610	req->privsize =		modeline->privsize;
611	if (modeline->privsize) {
612	    req->length += modeline->privsize;
613	    Data32(dpy, (long *) modeline->private,
614	       modeline->privsize * sizeof(INT32));
615	}
616    }
617    UnlockDisplay(dpy);
618    SyncHandle();
619    return True;
620}
621
622Bool
623XF86VidModeModModeLine (dpy, screen, modeline)
624    Display *dpy;
625    int screen;
626    XF86VidModeModeLine* modeline;
627{
628    XExtDisplayInfo *info = find_display (dpy);
629    xXF86VidModeModModeLineReq *req;
630    xXF86OldVidModeModModeLineReq *oldreq;
631    int majorVersion, minorVersion;
632
633    XF86VidModeCheckExtension (dpy, info, 0);
634    XF86VidModeQueryVersion(dpy, &majorVersion, &minorVersion);
635
636    LockDisplay(dpy);
637    if (majorVersion < 2) {
638	GetOldReq(XF86VidModeModModeLine, XF86OldVidModeModModeLine, oldreq);
639	oldreq->reqType = info->codes->major_opcode;
640	oldreq->xf86vidmodeReqType = X_XF86VidModeModModeLine;
641	oldreq->screen = screen;
642	oldreq->hdisplay =	modeline->hdisplay;
643	oldreq->hsyncstart =	modeline->hsyncstart;
644	oldreq->hsyncend =	modeline->hsyncend;
645	oldreq->htotal =	modeline->htotal;
646	oldreq->vdisplay =	modeline->vdisplay;
647	oldreq->vsyncstart =	modeline->vsyncstart;
648	oldreq->vsyncend =	modeline->vsyncend;
649	oldreq->vtotal =	modeline->vtotal;
650	oldreq->flags =		modeline->flags;
651	oldreq->privsize =	modeline->privsize;
652	if (modeline->privsize) {
653	    oldreq->length += modeline->privsize;
654	    Data32(dpy, (long *) modeline->private,
655	       modeline->privsize * sizeof(INT32));
656	}
657    } else {
658	GetReq(XF86VidModeModModeLine, req);
659	req->reqType = info->codes->major_opcode;
660	req->xf86vidmodeReqType = X_XF86VidModeModModeLine;
661	req->screen = screen;
662	req->hdisplay =		modeline->hdisplay;
663	req->hsyncstart =	modeline->hsyncstart;
664	req->hsyncend =		modeline->hsyncend;
665	req->htotal =		modeline->htotal;
666	req->hskew =		modeline->hskew;
667	req->vdisplay =		modeline->vdisplay;
668	req->vsyncstart =	modeline->vsyncstart;
669	req->vsyncend =		modeline->vsyncend;
670	req->vtotal =		modeline->vtotal;
671	req->flags =		modeline->flags;
672	req->privsize =		modeline->privsize;
673	if (modeline->privsize) {
674	    req->length += modeline->privsize;
675	    Data32(dpy, (long *) modeline->private,
676	       modeline->privsize * sizeof(INT32));
677	}
678    }
679    UnlockDisplay(dpy);
680    SyncHandle();
681    return True;
682}
683
684Status
685XF86VidModeValidateModeLine (dpy, screen, modeline)
686    Display *dpy;
687    int screen;
688    XF86VidModeModeInfo* modeline;
689{
690    XExtDisplayInfo *info = find_display (dpy);
691    xXF86VidModeValidateModeLineReq *req;
692    xXF86OldVidModeValidateModeLineReq *oldreq;
693    xXF86VidModeValidateModeLineReply rep;
694    int majorVersion, minorVersion;
695
696    XF86VidModeCheckExtension (dpy, info, 0);
697    XF86VidModeQueryVersion(dpy, &majorVersion, &minorVersion);
698
699    LockDisplay(dpy);
700
701    if (majorVersion < 2) {
702	GetOldReq(XF86VidModeValidateModeLine, XF86OldVidModeValidateModeLine, oldreq);
703	oldreq->reqType = info->codes->major_opcode;
704	oldreq->xf86vidmodeReqType = X_XF86VidModeValidateModeLine;
705	oldreq->screen = screen;
706	oldreq->dotclock =	modeline->dotclock;
707	oldreq->hdisplay =	modeline->hdisplay;
708	oldreq->hsyncstart =	modeline->hsyncstart;
709	oldreq->hsyncend =	modeline->hsyncend;
710	oldreq->htotal =	modeline->htotal;
711	oldreq->vdisplay =	modeline->vdisplay;
712	oldreq->vsyncstart =	modeline->vsyncstart;
713	oldreq->vsyncend =	modeline->vsyncend;
714	oldreq->vtotal =	modeline->vtotal;
715	oldreq->flags =		modeline->flags;
716	oldreq->privsize =	modeline->privsize;
717	if (modeline->privsize) {
718	    oldreq->length += modeline->privsize;
719	    Data32(dpy, (long *) modeline->private,
720	       modeline->privsize * sizeof(INT32));
721	}
722    } else {
723	GetReq(XF86VidModeValidateModeLine, req);
724	req->reqType = info->codes->major_opcode;
725	req->xf86vidmodeReqType = X_XF86VidModeValidateModeLine;
726	req->screen = screen;
727	req->dotclock =		modeline->dotclock;
728	req->hdisplay =		modeline->hdisplay;
729	req->hsyncstart =	modeline->hsyncstart;
730	req->hsyncend =		modeline->hsyncend;
731	req->htotal =		modeline->htotal;
732	req->hskew =		modeline->hskew;
733	req->vdisplay =		modeline->vdisplay;
734	req->vsyncstart =	modeline->vsyncstart;
735	req->vsyncend =		modeline->vsyncend;
736	req->vtotal =		modeline->vtotal;
737	req->flags =		modeline->flags;
738	req->privsize =		modeline->privsize;
739	if (modeline->privsize) {
740	    req->length += modeline->privsize;
741	    Data32(dpy, (long *) modeline->private,
742	       modeline->privsize * sizeof(INT32));
743	}
744    }
745    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
746	UnlockDisplay(dpy);
747	SyncHandle();
748	return MODE_BAD;
749    }
750    UnlockDisplay(dpy);
751    SyncHandle();
752    return rep.status;
753}
754
755Bool
756XF86VidModeSwitchMode(dpy, screen, zoom)
757    Display* dpy;
758    int screen;
759    int zoom;
760{
761    XExtDisplayInfo *info = find_display (dpy);
762    xXF86VidModeSwitchModeReq *req;
763
764    XF86VidModeCheckExtension (dpy, info, False);
765
766    LockDisplay(dpy);
767    GetReq(XF86VidModeSwitchMode, req);
768    req->reqType = info->codes->major_opcode;
769    req->xf86vidmodeReqType = X_XF86VidModeSwitchMode;
770    req->screen = screen;
771    req->zoom = zoom;
772    UnlockDisplay(dpy);
773    SyncHandle();
774    return True;
775}
776
777Bool
778XF86VidModeSwitchToMode(dpy, screen, modeline)
779    Display* dpy;
780    int screen;
781    XF86VidModeModeInfo* modeline;
782{
783    XExtDisplayInfo *info = find_display (dpy);
784    xXF86VidModeSwitchToModeReq *req;
785    xXF86OldVidModeSwitchToModeReq *oldreq;
786    int majorVersion, minorVersion;
787    Bool protocolBug = False;
788
789    XF86VidModeCheckExtension (dpy, info, False);
790
791    /*
792     * Note: There was a bug in the protocol implementation in versions
793     * 0.x with x < 8 (the .private field wasn't expected to be sent over
794     * the wire).  Check the server's version, and accept the old format
795     * if appropriate.
796     */
797
798    XF86VidModeQueryVersion(dpy, &majorVersion, &minorVersion);
799    if (majorVersion == 0 && minorVersion < 8) {
800	protocolBug = True;
801#ifdef DEBUG
802	fprintf(stderr, "XF86VidModeSwitchToMode: Warning: Xserver is"
803		"running an old version (%d.%d)\n", majorVersion,
804		minorVersion);
805#endif
806    }
807
808    LockDisplay(dpy);
809    if (majorVersion < 2) {
810	GetOldReq(XF86VidModeSwitchToMode, XF86OldVidModeSwitchToMode, oldreq);
811	oldreq->reqType = info->codes->major_opcode;
812	oldreq->xf86vidmodeReqType = X_XF86VidModeSwitchToMode;
813	oldreq->screen = screen;
814	oldreq->dotclock =	modeline->dotclock;
815	oldreq->hdisplay =	modeline->hdisplay;
816	oldreq->hsyncstart =	modeline->hsyncstart;
817	oldreq->hsyncend =	modeline->hsyncend;
818	oldreq->htotal =	modeline->htotal;
819	oldreq->vdisplay =	modeline->vdisplay;
820	oldreq->vsyncstart =	modeline->vsyncstart;
821	oldreq->vsyncend =	modeline->vsyncend;
822	oldreq->vtotal =	modeline->vtotal;
823	oldreq->flags =	modeline->flags;
824	if (protocolBug) {
825	    oldreq->privsize = 0;
826	} else {
827	    oldreq->privsize =	modeline->privsize;
828	    if (modeline->privsize) {
829		oldreq->length += modeline->privsize;
830		Data32(dpy, (long *) modeline->private,
831	           modeline->privsize * sizeof(INT32));
832	    }
833	}
834    } else {
835	GetReq(XF86VidModeSwitchToMode, req);
836	req->reqType = info->codes->major_opcode;
837	req->xf86vidmodeReqType = X_XF86VidModeSwitchToMode;
838	req->screen = screen;
839	req->dotclock =	modeline->dotclock;
840	req->hdisplay =	modeline->hdisplay;
841	req->hsyncstart =	modeline->hsyncstart;
842	req->hsyncend =	modeline->hsyncend;
843	req->htotal =	modeline->htotal;
844	req->hskew =	modeline->hskew;
845	req->vdisplay =	modeline->vdisplay;
846	req->vsyncstart =	modeline->vsyncstart;
847	req->vsyncend =	modeline->vsyncend;
848	req->vtotal =	modeline->vtotal;
849	req->flags =	modeline->flags;
850	if (protocolBug) {
851	    req->privsize = 0;
852	} else {
853	    req->privsize =	modeline->privsize;
854	    if (modeline->privsize) {
855		req->length += modeline->privsize;
856		Data32(dpy, (long *) modeline->private,
857	           modeline->privsize * sizeof(INT32));
858	    }
859	}
860    }
861    UnlockDisplay(dpy);
862    SyncHandle();
863    return True;
864}
865
866Bool
867XF86VidModeLockModeSwitch(dpy, screen, lock)
868    Display* dpy;
869    int screen;
870    int lock;
871{
872    XExtDisplayInfo *info = find_display (dpy);
873    xXF86VidModeLockModeSwitchReq *req;
874
875    XF86VidModeCheckExtension (dpy, info, False);
876
877    LockDisplay(dpy);
878    GetReq(XF86VidModeLockModeSwitch, req);
879    req->reqType = info->codes->major_opcode;
880    req->xf86vidmodeReqType = X_XF86VidModeLockModeSwitch;
881    req->screen = screen;
882    req->lock = lock;
883    UnlockDisplay(dpy);
884    SyncHandle();
885    return True;
886}
887
888Bool
889XF86VidModeGetMonitor(dpy, screen, monitor)
890    Display* dpy;
891    int screen;
892    XF86VidModeMonitor* monitor;
893{
894    XExtDisplayInfo *info = find_display (dpy);
895    xXF86VidModeGetMonitorReply rep;
896    xXF86VidModeGetMonitorReq *req;
897    CARD32 syncrange;
898    int i;
899
900    XF86VidModeCheckExtension (dpy, info, False);
901
902    LockDisplay(dpy);
903    GetReq(XF86VidModeGetMonitor, req);
904    req->reqType = info->codes->major_opcode;
905    req->xf86vidmodeReqType = X_XF86VidModeGetMonitor;
906    req->screen = screen;
907    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
908	UnlockDisplay(dpy);
909	SyncHandle();
910	return False;
911    }
912    monitor->nhsync = rep.nhsync;
913    monitor->nvsync = rep.nvsync;
914#if 0
915    monitor->bandwidth = (float)rep.bandwidth / 1e6;
916#endif
917    if (rep.vendorLength) {
918	if (!(monitor->vendor = (char *)Xcalloc(rep.vendorLength + 1, 1))) {
919	    _XEatData(dpy, (rep.nhsync + rep.nvsync) * 4 +
920		      ((rep.vendorLength+3) & ~3) + ((rep.modelLength+3) & ~3));
921	    return False;
922	}
923    } else {
924	monitor->vendor = NULL;
925    }
926    if (rep.modelLength) {
927	if (!(monitor->model = Xcalloc(rep.modelLength + 1, 1))) {
928	    _XEatData(dpy, (rep.nhsync + rep.nvsync) * 4 +
929		      ((rep.vendorLength+3) & ~3) + ((rep.modelLength+3) & ~3));
930	    if (monitor->vendor)
931		Xfree(monitor->vendor);
932	    return False;
933	}
934    } else {
935	monitor->model = NULL;
936    }
937    if (!(monitor->hsync = Xcalloc(rep.nhsync, sizeof(XF86VidModeSyncRange)))) {
938	_XEatData(dpy, (rep.nhsync + rep.nvsync) * 4 +
939		  ((rep.vendorLength+3) & ~3) + ((rep.modelLength+3) & ~3));
940
941	if (monitor->vendor)
942	    Xfree(monitor->vendor);
943	if (monitor->model)
944	    Xfree(monitor->model);
945	return False;
946    }
947    if (!(monitor->vsync = Xcalloc(rep.nvsync, sizeof(XF86VidModeSyncRange)))) {
948	_XEatData(dpy, (rep.nhsync + rep.nvsync) * 4 +
949		  ((rep.vendorLength+3) & ~3) + ((rep.modelLength+3) & ~3));
950	if (monitor->vendor)
951	    Xfree(monitor->vendor);
952	if (monitor->model)
953	    Xfree(monitor->model);
954	Xfree(monitor->hsync);
955	return False;
956    }
957    for (i = 0; i < rep.nhsync; i++) {
958	_XRead(dpy, (char *)&syncrange, 4);
959	monitor->hsync[i].lo = (float)(syncrange & 0xFFFF) / 100.0;
960	monitor->hsync[i].hi = (float)(syncrange >> 16) / 100.0;
961    }
962    for (i = 0; i < rep.nvsync; i++) {
963	_XRead(dpy, (char *)&syncrange, 4);
964	monitor->vsync[i].lo = (float)(syncrange & 0xFFFF) / 100.0;
965	monitor->vsync[i].hi = (float)(syncrange >> 16) / 100.0;
966    }
967    if (rep.vendorLength)
968	_XReadPad(dpy, monitor->vendor, rep.vendorLength);
969    else
970	monitor->vendor = "";
971    if (rep.modelLength)
972	_XReadPad(dpy, monitor->model, rep.modelLength);
973    else
974	monitor->model = "";
975
976    UnlockDisplay(dpy);
977    SyncHandle();
978    return True;
979}
980
981Bool
982XF86VidModeGetViewPort(dpy, screen, x, y)
983    Display* dpy;
984    int screen;
985    int *x, *y;
986{
987    XExtDisplayInfo *info = find_display (dpy);
988    xXF86VidModeGetViewPortReply rep;
989    xXF86VidModeGetViewPortReq *req;
990    int majorVersion, minorVersion;
991    Bool protocolBug = False;
992
993    XF86VidModeCheckExtension (dpy, info, False);
994
995    /*
996     * Note: There was a bug in the protocol implementation in versions
997     * 0.x with x < 8 (no reply was sent, so the client would hang)
998     * Check the server's version, and don't wait for a reply with older
999     * versions.
1000     */
1001
1002    XF86VidModeQueryVersion(dpy, &majorVersion, &minorVersion);
1003    if (majorVersion == 0 && minorVersion < 8) {
1004	protocolBug = True;
1005#ifdef DEBUG
1006	fprintf(stderr, "XF86VidModeGetViewPort: Warning: Xserver is"
1007		"running an old version (%d.%d)\n", majorVersion,
1008		minorVersion);
1009#endif
1010    }
1011    LockDisplay(dpy);
1012    GetReq(XF86VidModeGetViewPort, req);
1013    req->reqType = info->codes->major_opcode;
1014    req->xf86vidmodeReqType = X_XF86VidModeGetViewPort;
1015    req->screen = screen;
1016    if (protocolBug) {
1017	*x = 0;
1018	*y = 0;
1019    } else {
1020	if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
1021	    UnlockDisplay(dpy);
1022	    SyncHandle();
1023	    return False;
1024	}
1025	*x = rep.x;
1026	*y = rep.y;
1027    }
1028
1029    UnlockDisplay(dpy);
1030    SyncHandle();
1031    return True;
1032}
1033
1034Bool
1035XF86VidModeSetViewPort(dpy, screen, x, y)
1036    Display* dpy;
1037    int screen;
1038    int x, y;
1039{
1040    XExtDisplayInfo *info = find_display (dpy);
1041    xXF86VidModeSetViewPortReq *req;
1042
1043    XF86VidModeCheckExtension (dpy, info, False);
1044
1045    LockDisplay(dpy);
1046    GetReq(XF86VidModeSetViewPort, req);
1047    req->reqType = info->codes->major_opcode;
1048    req->xf86vidmodeReqType = X_XF86VidModeSetViewPort;
1049    req->screen = screen;
1050    req->x = x;
1051    req->y = y;
1052
1053    UnlockDisplay(dpy);
1054    SyncHandle();
1055    return True;
1056}
1057
1058Bool
1059XF86VidModeGetDotClocks(dpy, screen,
1060	    flagsPtr, numclocksPtr, maxclocksPtr, clocksPtr)
1061    Display* dpy;
1062    int screen;
1063    int *flagsPtr, *numclocksPtr, *maxclocksPtr, *clocksPtr[];
1064{
1065    XExtDisplayInfo *info = find_display (dpy);
1066    xXF86VidModeGetDotClocksReply rep;
1067    xXF86VidModeGetDotClocksReq *req;
1068    int i, *dotclocks;
1069    CARD32 dotclk;
1070
1071    XF86VidModeCheckExtension (dpy, info, False);
1072
1073    LockDisplay(dpy);
1074    GetReq(XF86VidModeGetDotClocks, req);
1075    req->reqType = info->codes->major_opcode;
1076    req->xf86vidmodeReqType = X_XF86VidModeGetDotClocks;
1077    req->screen = screen;
1078    if (!_XReply(dpy, (xReply *)&rep,
1079        (SIZEOF(xXF86VidModeGetDotClocksReply) - SIZEOF(xReply)) >> 2, xFalse))
1080    {
1081        UnlockDisplay(dpy);
1082        SyncHandle();
1083        return False;
1084    }
1085    *numclocksPtr = rep.clocks;
1086    *maxclocksPtr = rep.maxclocks;
1087    *flagsPtr     = rep.flags;
1088
1089    if (!(dotclocks = (int*) Xcalloc(rep.clocks, sizeof(int)))) {
1090        _XEatData(dpy, (rep.clocks) * 4);
1091        Xfree(dotclocks);
1092        return False;
1093    }
1094
1095    for (i = 0; i < rep.clocks; i++) {
1096        _XRead(dpy, (char*)&dotclk, 4);
1097	dotclocks[i] = dotclk;
1098    }
1099    *clocksPtr = dotclocks;
1100    UnlockDisplay(dpy);
1101    SyncHandle();
1102    return True;
1103}
1104
1105Bool
1106XF86VidModeSetGammaRamp (
1107    Display *dpy,
1108    int screen,
1109    int size,
1110    unsigned short *red,
1111    unsigned short *green,
1112    unsigned short *blue
1113)
1114{
1115    int length = (size + 1) & ~1;
1116    XExtDisplayInfo *info = find_display (dpy);
1117    xXF86VidModeSetGammaRampReq *req;
1118
1119    XF86VidModeCheckExtension (dpy, info, False);
1120    LockDisplay(dpy);
1121    GetReq(XF86VidModeSetGammaRamp, req);
1122    req->reqType = info->codes->major_opcode;
1123    req->xf86vidmodeReqType = X_XF86VidModeSetGammaRamp;
1124    req->screen = screen;
1125    req->length += (length >> 1) * 3;
1126    req->size = size;
1127    _XSend(dpy, (char*)red, size * 2);
1128    _XSend(dpy, (char*)green, size * 2);
1129    _XSend(dpy, (char*)blue, size * 2);
1130    UnlockDisplay(dpy);
1131    SyncHandle();
1132    return True;
1133}
1134
1135
1136Bool
1137XF86VidModeGetGammaRamp (
1138    Display *dpy,
1139    int screen,
1140    int size,
1141    unsigned short *red,
1142    unsigned short *green,
1143    unsigned short *blue
1144)
1145{
1146    XExtDisplayInfo *info = find_display (dpy);
1147    xXF86VidModeGetGammaRampReq *req;
1148    xXF86VidModeGetGammaRampReply rep;
1149
1150    XF86VidModeCheckExtension (dpy, info, False);
1151
1152    LockDisplay(dpy);
1153    GetReq(XF86VidModeGetGammaRamp, req);
1154    req->reqType = info->codes->major_opcode;
1155    req->xf86vidmodeReqType = X_XF86VidModeGetGammaRamp;
1156    req->screen = screen;
1157    req->size = size;
1158    if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) {
1159        UnlockDisplay (dpy);
1160        SyncHandle ();
1161        return False;
1162    }
1163    if(rep.size) {
1164	_XRead(dpy, (char*)red, rep.size << 1);
1165	_XRead(dpy, (char*)green, rep.size << 1);
1166	_XRead(dpy, (char*)blue, rep.size << 1);
1167    }
1168
1169    UnlockDisplay(dpy);
1170    SyncHandle();
1171    return True;
1172}
1173
1174Bool XF86VidModeGetGammaRampSize(
1175    Display *dpy,
1176    int screen,
1177    int *size
1178)
1179{
1180    XExtDisplayInfo *info = find_display (dpy);
1181    xXF86VidModeGetGammaRampSizeReq *req;
1182    xXF86VidModeGetGammaRampSizeReply rep;
1183
1184    *size = 0;
1185
1186    XF86VidModeCheckExtension (dpy, info, False);
1187
1188    LockDisplay(dpy);
1189    GetReq(XF86VidModeGetGammaRampSize, req);
1190    req->reqType = info->codes->major_opcode;
1191    req->xf86vidmodeReqType = X_XF86VidModeGetGammaRampSize;
1192    req->screen = screen;
1193    if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) {
1194        UnlockDisplay (dpy);
1195        SyncHandle ();
1196        return False;
1197    }
1198    *size = rep.size;
1199    UnlockDisplay(dpy);
1200    SyncHandle();
1201    return True;
1202}
1203
1204Bool XF86VidModeGetPermissions(
1205    Display *dpy,
1206    int screen,
1207    int *permissions
1208)
1209{
1210    XExtDisplayInfo *info = find_display (dpy);
1211    xXF86VidModeGetPermissionsReq *req;
1212    xXF86VidModeGetPermissionsReply rep;
1213
1214    *permissions = 0;
1215
1216    XF86VidModeCheckExtension (dpy, info, False);
1217
1218    LockDisplay(dpy);
1219    GetReq(XF86VidModeGetPermissions, req);
1220    req->reqType = info->codes->major_opcode;
1221    req->xf86vidmodeReqType = X_XF86VidModeGetPermissions;
1222    req->screen = screen;
1223    if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) {
1224        UnlockDisplay (dpy);
1225        SyncHandle ();
1226        return False;
1227    }
1228    *permissions = rep.permissions;
1229    UnlockDisplay(dpy);
1230    SyncHandle();
1231    return True;
1232}
1233
1234