Merge branch 'devel/upgrade' into tizen
[platform/upstream/libXxf86vm.git] / src / XF86VMode.c
1 /*
2
3 Copyright (c) 1995  Kaleb S. KEITHLEY
4
5 Permission is hereby granted, free of charge, to any person obtaining
6 a copy of this software and associated documentation files (the
7 "Software"), to deal in the Software without restriction, including
8 without limitation the rights to use, copy, modify, merge, publish,
9 distribute, sublicense, and/or sell copies of the Software, and to
10 permit persons to whom the Software is furnished to do so, subject to
11 the following conditions:
12
13 The above copyright notice and this permission notice shall be
14 included in all copies or substantial portions of the Software.
15
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19 IN NO EVENT SHALL Kaleb S. KEITHLEY BE LIABLE FOR ANY CLAIM, DAMAGES
20 OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 OTHER DEALINGS IN THE SOFTWARE.
23
24 Except as contained in this notice, the name of Kaleb S. KEITHLEY
25 shall not be used in advertising or otherwise to promote the sale, use
26 or other dealings in this Software without prior written authorization
27 from 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
45 static 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
63 static XExtensionInfo _xf86vidmode_info_data;
64 static XExtensionInfo *xf86vidmode_info = &_xf86vidmode_info_data;
65 static 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
76 static XEXT_CLOSE_DISPLAY_PROTO(close_display);
77 static /* 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
91 static XEXT_GENERATE_FIND_DISPLAY (find_display, xf86vidmode_info,
92                                    xf86vidmode_extension_name,
93                                    &xf86vidmode_extension_hooks,
94                                    0, NULL)
95
96 static XEXT_GENERATE_CLOSE_DISPLAY (close_display, xf86vidmode_info)
97
98
99 /*****************************************************************************
100  *                                                                           *
101  *                  public XFree86-VidMode Extension routines                *
102  *                                                                           *
103  *****************************************************************************/
104
105 Bool
106 XF86VidModeQueryExtension(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
119 Bool
120 XF86VidModeQueryVersion(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
146 Bool
147 XF86VidModeSetClientVersion(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
165 Bool
166 XF86VidModeSetGamma(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
186 Bool
187 XF86VidModeGetGamma(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
213 Bool
214 XF86VidModeGetModeLine(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
292 Bool
293 XF86VidModeGetAllModeLines(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
448 Bool
449 XF86VidModeAddModeLine(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
559 Bool
560 XF86VidModeDeleteModeLine(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
621 Bool
622 XF86VidModeModModeLine(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
680 Status
681 XF86VidModeValidateModeLine(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
749 Bool
750 XF86VidModeSwitchMode(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
768 Bool
769 XF86VidModeSwitchToMode(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
854 Bool
855 XF86VidModeLockModeSwitch(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
873 Bool
874 XF86VidModeGetMonitor(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
954 Bool
955 XF86VidModeGetViewPort(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
1004 Bool
1005 XF86VidModeSetViewPort(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
1025 Bool
1026 XF86VidModeGetDotClocks(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
1072 Bool
1073 XF86VidModeSetGammaRamp (
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
1103 Bool
1104 XF86VidModeGetGammaRamp (
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
1146 Bool 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
1176 Bool 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