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