1 /*
2 
3 Copyright 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 /* THIS IS NOT AN X CONSORTIUM STANDARD OR AN X PROJECT TEAM SPECIFICATION */
31 
32 #ifdef HAVE_DIX_CONFIG_H
33 #include <dix-config.h>
34 #endif
35 
36 #ifdef XF86VIDMODE
37 
38 #include <X11/X.h>
39 #include <X11/Xproto.h>
40 #include <X11/extensions/xf86vmproto.h>
41 #include "misc.h"
42 #include "dixstruct.h"
43 #include "extnsionst.h"
44 #include "scrnintstr.h"
45 #include "servermd.h"
46 #include "swaprep.h"
47 #include "vidmodestr.h"
48 #include "globals.h"
49 #include "protocol-versions.h"
50 
51 static int VidModeErrorBase;
52 static int VidModeAllowNonLocal;
53 
54 static DevPrivateKeyRec VidModeClientPrivateKeyRec;
55 #define VidModeClientPrivateKey (&VidModeClientPrivateKeyRec)
56 
57 static DevPrivateKeyRec VidModePrivateKeyRec;
58 #define VidModePrivateKey (&VidModePrivateKeyRec)
59 
60 /* This holds the client's version information */
61 typedef struct {
62     int major;
63     int minor;
64 } VidModePrivRec, *VidModePrivPtr;
65 
66 #define VM_GETPRIV(c) ((VidModePrivPtr) \
67     dixLookupPrivate(&(c)->devPrivates, VidModeClientPrivateKey))
68 #define VM_SETPRIV(c,p) \
69     dixSetPrivate(&(c)->devPrivates, VidModeClientPrivateKey, p)
70 
71 #ifdef DEBUG
72 #define DEBUG_P(x) DebugF(x"\n")
73 #else
74 #define DEBUG_P(x) /**/
75 #endif
76 
77 static DisplayModePtr
VidModeCreateMode(void)78 VidModeCreateMode(void)
79 {
80     DisplayModePtr mode;
81 
82     mode = malloc(sizeof(DisplayModeRec));
83     if (mode != NULL) {
84         mode->name = "";
85         mode->VScan = 1;        /* divides refresh rate. default = 1 */
86         mode->Private = NULL;
87         mode->next = mode;
88         mode->prev = mode;
89     }
90     return mode;
91 }
92 
93 static void
VidModeCopyMode(DisplayModePtr modefrom,DisplayModePtr modeto)94 VidModeCopyMode(DisplayModePtr modefrom, DisplayModePtr modeto)
95 {
96     memcpy(modeto, modefrom, sizeof(DisplayModeRec));
97 }
98 
99 static int
VidModeGetModeValue(DisplayModePtr mode,int valtyp)100 VidModeGetModeValue(DisplayModePtr mode, int valtyp)
101 {
102     int ret = 0;
103 
104     switch (valtyp) {
105     case VIDMODE_H_DISPLAY:
106         ret = mode->HDisplay;
107         break;
108     case VIDMODE_H_SYNCSTART:
109         ret = mode->HSyncStart;
110         break;
111     case VIDMODE_H_SYNCEND:
112         ret = mode->HSyncEnd;
113         break;
114     case VIDMODE_H_TOTAL:
115         ret = mode->HTotal;
116         break;
117     case VIDMODE_H_SKEW:
118         ret = mode->HSkew;
119         break;
120     case VIDMODE_V_DISPLAY:
121         ret = mode->VDisplay;
122         break;
123     case VIDMODE_V_SYNCSTART:
124         ret = mode->VSyncStart;
125         break;
126     case VIDMODE_V_SYNCEND:
127         ret = mode->VSyncEnd;
128         break;
129     case VIDMODE_V_TOTAL:
130         ret = mode->VTotal;
131         break;
132     case VIDMODE_FLAGS:
133         ret = mode->Flags;
134         break;
135     case VIDMODE_CLOCK:
136         ret = mode->Clock;
137         break;
138     }
139     return ret;
140 }
141 
142 static void
VidModeSetModeValue(DisplayModePtr mode,int valtyp,int val)143 VidModeSetModeValue(DisplayModePtr mode, int valtyp, int val)
144 {
145     switch (valtyp) {
146     case VIDMODE_H_DISPLAY:
147         mode->HDisplay = val;
148         break;
149     case VIDMODE_H_SYNCSTART:
150         mode->HSyncStart = val;
151         break;
152     case VIDMODE_H_SYNCEND:
153         mode->HSyncEnd = val;
154         break;
155     case VIDMODE_H_TOTAL:
156         mode->HTotal = val;
157         break;
158     case VIDMODE_H_SKEW:
159         mode->HSkew = val;
160         break;
161     case VIDMODE_V_DISPLAY:
162         mode->VDisplay = val;
163         break;
164     case VIDMODE_V_SYNCSTART:
165         mode->VSyncStart = val;
166         break;
167     case VIDMODE_V_SYNCEND:
168         mode->VSyncEnd = val;
169         break;
170     case VIDMODE_V_TOTAL:
171         mode->VTotal = val;
172         break;
173     case VIDMODE_FLAGS:
174         mode->Flags = val;
175         break;
176     case VIDMODE_CLOCK:
177         mode->Clock = val;
178         break;
179     }
180     return;
181 }
182 
183 static int
ClientMajorVersion(ClientPtr client)184 ClientMajorVersion(ClientPtr client)
185 {
186     VidModePrivPtr pPriv;
187 
188     pPriv = VM_GETPRIV(client);
189     if (!pPriv)
190         return 0;
191     else
192         return pPriv->major;
193 }
194 
195 static int
ProcVidModeQueryVersion(ClientPtr client)196 ProcVidModeQueryVersion(ClientPtr client)
197 {
198     xXF86VidModeQueryVersionReply rep = {
199         .type = X_Reply,
200         .sequenceNumber = client->sequence,
201         .length = 0,
202         .majorVersion = SERVER_XF86VIDMODE_MAJOR_VERSION,
203         .minorVersion = SERVER_XF86VIDMODE_MINOR_VERSION
204     };
205 
206     DEBUG_P("XF86VidModeQueryVersion");
207 
208     REQUEST_SIZE_MATCH(xXF86VidModeQueryVersionReq);
209 
210     if (client->swapped) {
211         swaps(&rep.sequenceNumber);
212         swapl(&rep.length);
213         swaps(&rep.majorVersion);
214         swaps(&rep.minorVersion);
215     }
216     WriteToClient(client, sizeof(xXF86VidModeQueryVersionReply), &rep);
217     return Success;
218 }
219 
220 static int
ProcVidModeGetModeLine(ClientPtr client)221 ProcVidModeGetModeLine(ClientPtr client)
222 {
223     REQUEST(xXF86VidModeGetModeLineReq);
224     xXF86VidModeGetModeLineReply rep = {
225         .type = X_Reply,
226         .sequenceNumber = client->sequence
227     };
228     ScreenPtr pScreen;
229     VidModePtr pVidMode;
230     DisplayModePtr mode;
231     int dotClock;
232     int ver;
233 
234     DEBUG_P("XF86VidModeGetModeline");
235 
236     ver = ClientMajorVersion(client);
237     REQUEST_SIZE_MATCH(xXF86VidModeGetModeLineReq);
238 
239     if (ver < 2) {
240         rep.length = bytes_to_int32(SIZEOF(xXF86OldVidModeGetModeLineReply) -
241                                     SIZEOF(xGenericReply));
242     }
243     else {
244         rep.length = bytes_to_int32(SIZEOF(xXF86VidModeGetModeLineReply) -
245                                     SIZEOF(xGenericReply));
246     }
247 
248     if (stuff->screen >= screenInfo.numScreens)
249         return BadValue;
250     pScreen = screenInfo.screens[stuff->screen];
251     pVidMode = VidModeGetPtr(pScreen);
252     if (pVidMode == NULL)
253         return BadImplementation;
254 
255     if (!pVidMode->GetCurrentModeline(pScreen, &mode, &dotClock))
256         return BadValue;
257 
258     rep.dotclock = dotClock;
259     rep.hdisplay = VidModeGetModeValue(mode, VIDMODE_H_DISPLAY);
260     rep.hsyncstart = VidModeGetModeValue(mode, VIDMODE_H_SYNCSTART);
261     rep.hsyncend = VidModeGetModeValue(mode, VIDMODE_H_SYNCEND);
262     rep.htotal = VidModeGetModeValue(mode, VIDMODE_H_TOTAL);
263     rep.hskew = VidModeGetModeValue(mode, VIDMODE_H_SKEW);
264     rep.vdisplay = VidModeGetModeValue(mode, VIDMODE_V_DISPLAY);
265     rep.vsyncstart = VidModeGetModeValue(mode, VIDMODE_V_SYNCSTART);
266     rep.vsyncend = VidModeGetModeValue(mode, VIDMODE_V_SYNCEND);
267     rep.vtotal = VidModeGetModeValue(mode, VIDMODE_V_TOTAL);
268     rep.flags = VidModeGetModeValue(mode, VIDMODE_FLAGS);
269 
270     DebugF("GetModeLine - scrn: %d clock: %ld\n",
271            stuff->screen, (unsigned long) rep.dotclock);
272     DebugF("GetModeLine - hdsp: %d hbeg: %d hend: %d httl: %d\n",
273            rep.hdisplay, rep.hsyncstart, rep.hsyncend, rep.htotal);
274     DebugF("              vdsp: %d vbeg: %d vend: %d vttl: %d flags: %ld\n",
275            rep.vdisplay, rep.vsyncstart, rep.vsyncend,
276            rep.vtotal, (unsigned long) rep.flags);
277 
278     /*
279      * Older servers sometimes had server privates that the VidMode
280      * extention made available. So to be compatiable pretend that
281      * there are no server privates to pass to the client
282      */
283     rep.privsize = 0;
284 
285     if (client->swapped) {
286         swaps(&rep.sequenceNumber);
287         swapl(&rep.length);
288         swapl(&rep.dotclock);
289         swaps(&rep.hdisplay);
290         swaps(&rep.hsyncstart);
291         swaps(&rep.hsyncend);
292         swaps(&rep.htotal);
293         swaps(&rep.hskew);
294         swaps(&rep.vdisplay);
295         swaps(&rep.vsyncstart);
296         swaps(&rep.vsyncend);
297         swaps(&rep.vtotal);
298         swapl(&rep.flags);
299         swapl(&rep.privsize);
300     }
301     if (ver < 2) {
302         xXF86OldVidModeGetModeLineReply oldrep = {
303             .type = rep.type,
304             .sequenceNumber = rep.sequenceNumber,
305             .length = rep.length,
306             .dotclock = rep.dotclock,
307             .hdisplay = rep.hdisplay,
308             .hsyncstart = rep.hsyncstart,
309             .hsyncend = rep.hsyncend,
310             .htotal = rep.htotal,
311             .vdisplay = rep.vdisplay,
312             .vsyncstart = rep.vsyncstart,
313             .vsyncend = rep.vsyncend,
314             .vtotal = rep.vtotal,
315             .flags = rep.flags,
316             .privsize = rep.privsize
317         };
318         WriteToClient(client, sizeof(xXF86OldVidModeGetModeLineReply), &oldrep);
319     }
320     else {
321         WriteToClient(client, sizeof(xXF86VidModeGetModeLineReply), &rep);
322     }
323     return Success;
324 }
325 
326 static int
ProcVidModeGetAllModeLines(ClientPtr client)327 ProcVidModeGetAllModeLines(ClientPtr client)
328 {
329     REQUEST(xXF86VidModeGetAllModeLinesReq);
330     xXF86VidModeGetAllModeLinesReply rep;
331     ScreenPtr pScreen;
332     VidModePtr pVidMode;
333     DisplayModePtr mode;
334     int modecount, dotClock;
335     int ver;
336 
337     DEBUG_P("XF86VidModeGetAllModelines");
338 
339     REQUEST_SIZE_MATCH(xXF86VidModeGetAllModeLinesReq);
340 
341     if (stuff->screen >= screenInfo.numScreens)
342         return BadValue;
343     pScreen = screenInfo.screens[stuff->screen];
344     ver = ClientMajorVersion(client);
345     pVidMode = VidModeGetPtr(pScreen);
346     if (pVidMode == NULL)
347         return BadImplementation;
348 
349     modecount = pVidMode->GetNumOfModes(pScreen);
350     if (modecount < 1)
351         return VidModeErrorBase + XF86VidModeExtensionDisabled;
352 
353     if (!pVidMode->GetFirstModeline(pScreen, &mode, &dotClock))
354         return BadValue;
355 
356     rep = (xXF86VidModeGetAllModeLinesReply) {
357         .type = X_Reply,
358         .length = SIZEOF(xXF86VidModeGetAllModeLinesReply) -
359             SIZEOF(xGenericReply),
360         .sequenceNumber = client->sequence,
361         .modecount = modecount
362     };
363     if (ver < 2)
364         rep.length += modecount * sizeof(xXF86OldVidModeModeInfo);
365     else
366         rep.length += modecount * sizeof(xXF86VidModeModeInfo);
367     rep.length >>= 2;
368     if (client->swapped) {
369         swaps(&rep.sequenceNumber);
370         swapl(&rep.length);
371         swapl(&rep.modecount);
372     }
373     WriteToClient(client, sizeof(xXF86VidModeGetAllModeLinesReply), &rep);
374 
375     do {
376         xXF86VidModeModeInfo mdinf = {
377             .dotclock = dotClock,
378             .hdisplay = VidModeGetModeValue(mode, VIDMODE_H_DISPLAY),
379             .hsyncstart = VidModeGetModeValue(mode, VIDMODE_H_SYNCSTART),
380             .hsyncend = VidModeGetModeValue(mode, VIDMODE_H_SYNCEND),
381             .htotal = VidModeGetModeValue(mode, VIDMODE_H_TOTAL),
382             .hskew = VidModeGetModeValue(mode, VIDMODE_H_SKEW),
383             .vdisplay = VidModeGetModeValue(mode, VIDMODE_V_DISPLAY),
384             .vsyncstart = VidModeGetModeValue(mode, VIDMODE_V_SYNCSTART),
385             .vsyncend = VidModeGetModeValue(mode, VIDMODE_V_SYNCEND),
386             .vtotal = VidModeGetModeValue(mode, VIDMODE_V_TOTAL),
387             .flags = VidModeGetModeValue(mode, VIDMODE_FLAGS),
388             .privsize = 0
389         };
390         if (client->swapped) {
391             swapl(&mdinf.dotclock);
392             swaps(&mdinf.hdisplay);
393             swaps(&mdinf.hsyncstart);
394             swaps(&mdinf.hsyncend);
395             swaps(&mdinf.htotal);
396             swapl(&mdinf.hskew);
397             swaps(&mdinf.vdisplay);
398             swaps(&mdinf.vsyncstart);
399             swaps(&mdinf.vsyncend);
400             swaps(&mdinf.vtotal);
401             swapl(&mdinf.flags);
402             swapl(&mdinf.privsize);
403         }
404         if (ver < 2) {
405             xXF86OldVidModeModeInfo oldmdinf = {
406                 .dotclock = mdinf.dotclock,
407                 .hdisplay = mdinf.hdisplay,
408                 .hsyncstart = mdinf.hsyncstart,
409                 .hsyncend = mdinf.hsyncend,
410                 .htotal = mdinf.htotal,
411                 .vdisplay = mdinf.vdisplay,
412                 .vsyncstart = mdinf.vsyncstart,
413                 .vsyncend = mdinf.vsyncend,
414                 .vtotal = mdinf.vtotal,
415                 .flags = mdinf.flags,
416                 .privsize = mdinf.privsize
417             };
418             WriteToClient(client, sizeof(xXF86OldVidModeModeInfo), &oldmdinf);
419         }
420         else {
421             WriteToClient(client, sizeof(xXF86VidModeModeInfo), &mdinf);
422         }
423 
424     } while (pVidMode->GetNextModeline(pScreen, &mode, &dotClock));
425 
426     return Success;
427 }
428 
429 #define MODEMATCH(mode,stuff)	  \
430      (VidModeGetModeValue(mode, VIDMODE_H_DISPLAY)  == stuff->hdisplay \
431      && VidModeGetModeValue(mode, VIDMODE_H_SYNCSTART)  == stuff->hsyncstart \
432      && VidModeGetModeValue(mode, VIDMODE_H_SYNCEND)  == stuff->hsyncend \
433      && VidModeGetModeValue(mode, VIDMODE_H_TOTAL)  == stuff->htotal \
434      && VidModeGetModeValue(mode, VIDMODE_V_DISPLAY)  == stuff->vdisplay \
435      && VidModeGetModeValue(mode, VIDMODE_V_SYNCSTART)  == stuff->vsyncstart \
436      && VidModeGetModeValue(mode, VIDMODE_V_SYNCEND)  == stuff->vsyncend \
437      && VidModeGetModeValue(mode, VIDMODE_V_TOTAL)  == stuff->vtotal \
438      && VidModeGetModeValue(mode, VIDMODE_FLAGS)  == stuff->flags )
439 
440 static int
ProcVidModeAddModeLine(ClientPtr client)441 ProcVidModeAddModeLine(ClientPtr client)
442 {
443     REQUEST(xXF86VidModeAddModeLineReq);
444     xXF86OldVidModeAddModeLineReq *oldstuff =
445         (xXF86OldVidModeAddModeLineReq *) client->requestBuffer;
446     xXF86VidModeAddModeLineReq newstuff;
447     ScreenPtr pScreen;
448     VidModePtr pVidMode;
449     DisplayModePtr mode;
450     int len;
451     int dotClock;
452     int ver;
453 
454     DEBUG_P("XF86VidModeAddModeline");
455 
456     ver = ClientMajorVersion(client);
457 
458     if (ver < 2) {
459         REQUEST_AT_LEAST_SIZE(xXF86OldVidModeAddModeLineReq);
460         len =
461             client->req_len -
462             bytes_to_int32(sizeof(xXF86OldVidModeAddModeLineReq));
463     }
464     else {
465         REQUEST_AT_LEAST_SIZE(xXF86VidModeAddModeLineReq);
466         len =
467             client->req_len -
468             bytes_to_int32(sizeof(xXF86VidModeAddModeLineReq));
469     }
470 
471     if (ver < 2) {
472         /* convert from old format */
473         stuff = &newstuff;
474         stuff->length = oldstuff->length;
475         stuff->screen = oldstuff->screen;
476         stuff->dotclock = oldstuff->dotclock;
477         stuff->hdisplay = oldstuff->hdisplay;
478         stuff->hsyncstart = oldstuff->hsyncstart;
479         stuff->hsyncend = oldstuff->hsyncend;
480         stuff->htotal = oldstuff->htotal;
481         stuff->hskew = 0;
482         stuff->vdisplay = oldstuff->vdisplay;
483         stuff->vsyncstart = oldstuff->vsyncstart;
484         stuff->vsyncend = oldstuff->vsyncend;
485         stuff->vtotal = oldstuff->vtotal;
486         stuff->flags = oldstuff->flags;
487         stuff->privsize = oldstuff->privsize;
488         stuff->after_dotclock = oldstuff->after_dotclock;
489         stuff->after_hdisplay = oldstuff->after_hdisplay;
490         stuff->after_hsyncstart = oldstuff->after_hsyncstart;
491         stuff->after_hsyncend = oldstuff->after_hsyncend;
492         stuff->after_htotal = oldstuff->after_htotal;
493         stuff->after_hskew = 0;
494         stuff->after_vdisplay = oldstuff->after_vdisplay;
495         stuff->after_vsyncstart = oldstuff->after_vsyncstart;
496         stuff->after_vsyncend = oldstuff->after_vsyncend;
497         stuff->after_vtotal = oldstuff->after_vtotal;
498         stuff->after_flags = oldstuff->after_flags;
499     }
500     DebugF("AddModeLine - scrn: %d clock: %ld\n",
501            (int) stuff->screen, (unsigned long) stuff->dotclock);
502     DebugF("AddModeLine - hdsp: %d hbeg: %d hend: %d httl: %d\n",
503            stuff->hdisplay, stuff->hsyncstart,
504            stuff->hsyncend, stuff->htotal);
505     DebugF("              vdsp: %d vbeg: %d vend: %d vttl: %d flags: %ld\n",
506            stuff->vdisplay, stuff->vsyncstart, stuff->vsyncend,
507            stuff->vtotal, (unsigned long) stuff->flags);
508     DebugF("      after - scrn: %d clock: %ld\n",
509            (int) stuff->screen, (unsigned long) stuff->after_dotclock);
510     DebugF("              hdsp: %d hbeg: %d hend: %d httl: %d\n",
511            stuff->after_hdisplay, stuff->after_hsyncstart,
512            stuff->after_hsyncend, stuff->after_htotal);
513     DebugF("              vdsp: %d vbeg: %d vend: %d vttl: %d flags: %ld\n",
514            stuff->after_vdisplay, stuff->after_vsyncstart,
515            stuff->after_vsyncend, stuff->after_vtotal,
516            (unsigned long) stuff->after_flags);
517 
518     if (len != stuff->privsize)
519         return BadLength;
520 
521     if (stuff->screen >= screenInfo.numScreens)
522         return BadValue;
523     pScreen = screenInfo.screens[stuff->screen];
524 
525     if (stuff->hsyncstart < stuff->hdisplay ||
526         stuff->hsyncend < stuff->hsyncstart ||
527         stuff->htotal < stuff->hsyncend ||
528         stuff->vsyncstart < stuff->vdisplay ||
529         stuff->vsyncend < stuff->vsyncstart || stuff->vtotal < stuff->vsyncend)
530         return BadValue;
531 
532     if (stuff->after_hsyncstart < stuff->after_hdisplay ||
533         stuff->after_hsyncend < stuff->after_hsyncstart ||
534         stuff->after_htotal < stuff->after_hsyncend ||
535         stuff->after_vsyncstart < stuff->after_vdisplay ||
536         stuff->after_vsyncend < stuff->after_vsyncstart ||
537         stuff->after_vtotal < stuff->after_vsyncend)
538         return BadValue;
539 
540     pVidMode = VidModeGetPtr(pScreen);
541     if (pVidMode == NULL)
542         return BadImplementation;
543 
544     if (stuff->after_htotal != 0 || stuff->after_vtotal != 0) {
545         Bool found = FALSE;
546 
547         if (pVidMode->GetFirstModeline(pScreen, &mode, &dotClock)) {
548             do {
549                 if ((pVidMode->GetDotClock(pScreen, stuff->dotclock)
550                      == dotClock) && MODEMATCH(mode, stuff)) {
551                     found = TRUE;
552                     break;
553                 }
554             } while (pVidMode->GetNextModeline(pScreen, &mode, &dotClock));
555         }
556         if (!found)
557             return BadValue;
558     }
559 
560     mode = VidModeCreateMode();
561     if (mode == NULL)
562         return BadValue;
563 
564     VidModeSetModeValue(mode, VIDMODE_CLOCK, stuff->dotclock);
565     VidModeSetModeValue(mode, VIDMODE_H_DISPLAY, stuff->hdisplay);
566     VidModeSetModeValue(mode, VIDMODE_H_SYNCSTART, stuff->hsyncstart);
567     VidModeSetModeValue(mode, VIDMODE_H_SYNCEND, stuff->hsyncend);
568     VidModeSetModeValue(mode, VIDMODE_H_TOTAL, stuff->htotal);
569     VidModeSetModeValue(mode, VIDMODE_H_SKEW, stuff->hskew);
570     VidModeSetModeValue(mode, VIDMODE_V_DISPLAY, stuff->vdisplay);
571     VidModeSetModeValue(mode, VIDMODE_V_SYNCSTART, stuff->vsyncstart);
572     VidModeSetModeValue(mode, VIDMODE_V_SYNCEND, stuff->vsyncend);
573     VidModeSetModeValue(mode, VIDMODE_V_TOTAL, stuff->vtotal);
574     VidModeSetModeValue(mode, VIDMODE_FLAGS, stuff->flags);
575 
576     if (stuff->privsize)
577         DebugF("AddModeLine - Privates in request have been ignored\n");
578 
579     /* Check that the mode is consistent with the monitor specs */
580     switch (pVidMode->CheckModeForMonitor(pScreen, mode)) {
581     case MODE_OK:
582         break;
583     case MODE_HSYNC:
584     case MODE_H_ILLEGAL:
585         free(mode);
586         return VidModeErrorBase + XF86VidModeBadHTimings;
587     case MODE_VSYNC:
588     case MODE_V_ILLEGAL:
589         free(mode);
590         return VidModeErrorBase + XF86VidModeBadVTimings;
591     default:
592         free(mode);
593         return VidModeErrorBase + XF86VidModeModeUnsuitable;
594     }
595 
596     /* Check that the driver is happy with the mode */
597     if (pVidMode->CheckModeForDriver(pScreen, mode) != MODE_OK) {
598         free(mode);
599         return VidModeErrorBase + XF86VidModeModeUnsuitable;
600     }
601 
602     pVidMode->SetCrtcForMode(pScreen, mode);
603 
604     pVidMode->AddModeline(pScreen, mode);
605 
606     DebugF("AddModeLine - Succeeded\n");
607 
608     return Success;
609 }
610 
611 static int
ProcVidModeDeleteModeLine(ClientPtr client)612 ProcVidModeDeleteModeLine(ClientPtr client)
613 {
614     REQUEST(xXF86VidModeDeleteModeLineReq);
615     xXF86OldVidModeDeleteModeLineReq *oldstuff =
616         (xXF86OldVidModeDeleteModeLineReq *) client->requestBuffer;
617     xXF86VidModeDeleteModeLineReq newstuff;
618     ScreenPtr pScreen;
619     VidModePtr pVidMode;
620     DisplayModePtr mode;
621     int len, dotClock;
622     int ver;
623 
624     DEBUG_P("XF86VidModeDeleteModeline");
625 
626     ver = ClientMajorVersion(client);
627 
628     if (ver < 2) {
629         REQUEST_AT_LEAST_SIZE(xXF86OldVidModeDeleteModeLineReq);
630         len =
631             client->req_len -
632             bytes_to_int32(sizeof(xXF86OldVidModeDeleteModeLineReq));
633     }
634     else {
635         REQUEST_AT_LEAST_SIZE(xXF86VidModeDeleteModeLineReq);
636         len =
637             client->req_len -
638             bytes_to_int32(sizeof(xXF86VidModeDeleteModeLineReq));
639     }
640 
641     if (ver < 2) {
642         /* convert from old format */
643         stuff = &newstuff;
644         stuff->length = oldstuff->length;
645         stuff->screen = oldstuff->screen;
646         stuff->dotclock = oldstuff->dotclock;
647         stuff->hdisplay = oldstuff->hdisplay;
648         stuff->hsyncstart = oldstuff->hsyncstart;
649         stuff->hsyncend = oldstuff->hsyncend;
650         stuff->htotal = oldstuff->htotal;
651         stuff->hskew = 0;
652         stuff->vdisplay = oldstuff->vdisplay;
653         stuff->vsyncstart = oldstuff->vsyncstart;
654         stuff->vsyncend = oldstuff->vsyncend;
655         stuff->vtotal = oldstuff->vtotal;
656         stuff->flags = oldstuff->flags;
657         stuff->privsize = oldstuff->privsize;
658     }
659     DebugF("DeleteModeLine - scrn: %d clock: %ld\n",
660            (int) stuff->screen, (unsigned long) stuff->dotclock);
661     DebugF("                 hdsp: %d hbeg: %d hend: %d httl: %d\n",
662            stuff->hdisplay, stuff->hsyncstart,
663            stuff->hsyncend, stuff->htotal);
664     DebugF("                 vdsp: %d vbeg: %d vend: %d vttl: %d flags: %ld\n",
665            stuff->vdisplay, stuff->vsyncstart, stuff->vsyncend, stuff->vtotal,
666            (unsigned long) stuff->flags);
667 
668     if (len != stuff->privsize) {
669         DebugF("req_len = %ld, sizeof(Req) = %d, privsize = %ld, "
670                "len = %d, length = %d\n",
671                (unsigned long) client->req_len,
672                (int) sizeof(xXF86VidModeDeleteModeLineReq) >> 2,
673                (unsigned long) stuff->privsize, len, stuff->length);
674         return BadLength;
675     }
676 
677     if (stuff->screen >= screenInfo.numScreens)
678         return BadValue;
679     pScreen = screenInfo.screens[stuff->screen];
680 
681     pVidMode = VidModeGetPtr(pScreen);
682     if (pVidMode == NULL)
683         return BadImplementation;
684 
685     if (!pVidMode->GetCurrentModeline(pScreen, &mode, &dotClock))
686         return BadValue;
687 
688     DebugF("Checking against clock: %d (%d)\n",
689            VidModeGetModeValue(mode, VIDMODE_CLOCK), dotClock);
690     DebugF("                 hdsp: %d hbeg: %d hend: %d httl: %d\n",
691            VidModeGetModeValue(mode, VIDMODE_H_DISPLAY),
692            VidModeGetModeValue(mode, VIDMODE_H_SYNCSTART),
693            VidModeGetModeValue(mode, VIDMODE_H_SYNCEND),
694            VidModeGetModeValue(mode, VIDMODE_H_TOTAL));
695     DebugF("                 vdsp: %d vbeg: %d vend: %d vttl: %d flags: %d\n",
696            VidModeGetModeValue(mode, VIDMODE_V_DISPLAY),
697            VidModeGetModeValue(mode, VIDMODE_V_SYNCSTART),
698            VidModeGetModeValue(mode, VIDMODE_V_SYNCEND),
699            VidModeGetModeValue(mode, VIDMODE_V_TOTAL),
700            VidModeGetModeValue(mode, VIDMODE_FLAGS));
701 
702     if ((pVidMode->GetDotClock(pScreen, stuff->dotclock) == dotClock) &&
703         MODEMATCH(mode, stuff))
704         return BadValue;
705 
706     if (!pVidMode->GetFirstModeline(pScreen, &mode, &dotClock))
707         return BadValue;
708 
709     do {
710         DebugF("Checking against clock: %d (%d)\n",
711                VidModeGetModeValue(mode, VIDMODE_CLOCK), dotClock);
712         DebugF("                 hdsp: %d hbeg: %d hend: %d httl: %d\n",
713                VidModeGetModeValue(mode, VIDMODE_H_DISPLAY),
714                VidModeGetModeValue(mode, VIDMODE_H_SYNCSTART),
715                VidModeGetModeValue(mode, VIDMODE_H_SYNCEND),
716                VidModeGetModeValue(mode, VIDMODE_H_TOTAL));
717         DebugF("                 vdsp: %d vbeg: %d vend: %d vttl: %d flags: %d\n",
718                VidModeGetModeValue(mode, VIDMODE_V_DISPLAY),
719                VidModeGetModeValue(mode, VIDMODE_V_SYNCSTART),
720                VidModeGetModeValue(mode, VIDMODE_V_SYNCEND),
721                VidModeGetModeValue(mode, VIDMODE_V_TOTAL),
722                VidModeGetModeValue(mode, VIDMODE_FLAGS));
723 
724         if ((pVidMode->GetDotClock(pScreen, stuff->dotclock) == dotClock) &&
725             MODEMATCH(mode, stuff)) {
726             pVidMode->DeleteModeline(pScreen, mode);
727             DebugF("DeleteModeLine - Succeeded\n");
728             return Success;
729         }
730     } while (pVidMode->GetNextModeline(pScreen, &mode, &dotClock));
731 
732     return BadValue;
733 }
734 
735 static int
ProcVidModeModModeLine(ClientPtr client)736 ProcVidModeModModeLine(ClientPtr client)
737 {
738     REQUEST(xXF86VidModeModModeLineReq);
739     xXF86OldVidModeModModeLineReq *oldstuff =
740         (xXF86OldVidModeModModeLineReq *) client->requestBuffer;
741     xXF86VidModeModModeLineReq newstuff;
742     ScreenPtr pScreen;
743     VidModePtr pVidMode;
744     DisplayModePtr mode, modetmp;
745     int len, dotClock;
746     int ver;
747 
748     DEBUG_P("XF86VidModeModModeline");
749 
750     ver = ClientMajorVersion(client);
751 
752     if (ver < 2) {
753         REQUEST_AT_LEAST_SIZE(xXF86OldVidModeModModeLineReq);
754         len =
755             client->req_len -
756             bytes_to_int32(sizeof(xXF86OldVidModeModModeLineReq));
757     }
758     else {
759         REQUEST_AT_LEAST_SIZE(xXF86VidModeModModeLineReq);
760         len =
761             client->req_len -
762             bytes_to_int32(sizeof(xXF86VidModeModModeLineReq));
763     }
764 
765     if (ver < 2) {
766         /* convert from old format */
767         stuff = &newstuff;
768         stuff->length = oldstuff->length;
769         stuff->screen = oldstuff->screen;
770         stuff->hdisplay = oldstuff->hdisplay;
771         stuff->hsyncstart = oldstuff->hsyncstart;
772         stuff->hsyncend = oldstuff->hsyncend;
773         stuff->htotal = oldstuff->htotal;
774         stuff->hskew = 0;
775         stuff->vdisplay = oldstuff->vdisplay;
776         stuff->vsyncstart = oldstuff->vsyncstart;
777         stuff->vsyncend = oldstuff->vsyncend;
778         stuff->vtotal = oldstuff->vtotal;
779         stuff->flags = oldstuff->flags;
780         stuff->privsize = oldstuff->privsize;
781     }
782     DebugF("ModModeLine - scrn: %d hdsp: %d hbeg: %d hend: %d httl: %d\n",
783            (int) stuff->screen, stuff->hdisplay, stuff->hsyncstart,
784            stuff->hsyncend, stuff->htotal);
785     DebugF("              vdsp: %d vbeg: %d vend: %d vttl: %d flags: %ld\n",
786            stuff->vdisplay, stuff->vsyncstart, stuff->vsyncend,
787            stuff->vtotal, (unsigned long) stuff->flags);
788 
789     if (len != stuff->privsize)
790         return BadLength;
791 
792     if (stuff->hsyncstart < stuff->hdisplay ||
793         stuff->hsyncend < stuff->hsyncstart ||
794         stuff->htotal < stuff->hsyncend ||
795         stuff->vsyncstart < stuff->vdisplay ||
796         stuff->vsyncend < stuff->vsyncstart || stuff->vtotal < stuff->vsyncend)
797         return BadValue;
798 
799     if (stuff->screen >= screenInfo.numScreens)
800         return BadValue;
801     pScreen = screenInfo.screens[stuff->screen];
802 
803     pVidMode = VidModeGetPtr(pScreen);
804     if (pVidMode == NULL)
805         return BadImplementation;
806 
807     if (!pVidMode->GetCurrentModeline(pScreen, &mode, &dotClock))
808         return BadValue;
809 
810     modetmp = VidModeCreateMode();
811     VidModeCopyMode(mode, modetmp);
812 
813     VidModeSetModeValue(modetmp, VIDMODE_H_DISPLAY, stuff->hdisplay);
814     VidModeSetModeValue(modetmp, VIDMODE_H_SYNCSTART, stuff->hsyncstart);
815     VidModeSetModeValue(modetmp, VIDMODE_H_SYNCEND, stuff->hsyncend);
816     VidModeSetModeValue(modetmp, VIDMODE_H_TOTAL, stuff->htotal);
817     VidModeSetModeValue(modetmp, VIDMODE_H_SKEW, stuff->hskew);
818     VidModeSetModeValue(modetmp, VIDMODE_V_DISPLAY, stuff->vdisplay);
819     VidModeSetModeValue(modetmp, VIDMODE_V_SYNCSTART, stuff->vsyncstart);
820     VidModeSetModeValue(modetmp, VIDMODE_V_SYNCEND, stuff->vsyncend);
821     VidModeSetModeValue(modetmp, VIDMODE_V_TOTAL, stuff->vtotal);
822     VidModeSetModeValue(modetmp, VIDMODE_FLAGS, stuff->flags);
823 
824     if (stuff->privsize)
825         DebugF("ModModeLine - Privates in request have been ignored\n");
826 
827     /* Check that the mode is consistent with the monitor specs */
828     switch (pVidMode->CheckModeForMonitor(pScreen, modetmp)) {
829     case MODE_OK:
830         break;
831     case MODE_HSYNC:
832     case MODE_H_ILLEGAL:
833         free(modetmp);
834         return VidModeErrorBase + XF86VidModeBadHTimings;
835     case MODE_VSYNC:
836     case MODE_V_ILLEGAL:
837         free(modetmp);
838         return VidModeErrorBase + XF86VidModeBadVTimings;
839     default:
840         free(modetmp);
841         return VidModeErrorBase + XF86VidModeModeUnsuitable;
842     }
843 
844     /* Check that the driver is happy with the mode */
845     if (pVidMode->CheckModeForDriver(pScreen, modetmp) != MODE_OK) {
846         free(modetmp);
847         return VidModeErrorBase + XF86VidModeModeUnsuitable;
848     }
849     free(modetmp);
850 
851     VidModeSetModeValue(mode, VIDMODE_H_DISPLAY, stuff->hdisplay);
852     VidModeSetModeValue(mode, VIDMODE_H_SYNCSTART, stuff->hsyncstart);
853     VidModeSetModeValue(mode, VIDMODE_H_SYNCEND, stuff->hsyncend);
854     VidModeSetModeValue(mode, VIDMODE_H_TOTAL, stuff->htotal);
855     VidModeSetModeValue(mode, VIDMODE_H_SKEW, stuff->hskew);
856     VidModeSetModeValue(mode, VIDMODE_V_DISPLAY, stuff->vdisplay);
857     VidModeSetModeValue(mode, VIDMODE_V_SYNCSTART, stuff->vsyncstart);
858     VidModeSetModeValue(mode, VIDMODE_V_SYNCEND, stuff->vsyncend);
859     VidModeSetModeValue(mode, VIDMODE_V_TOTAL, stuff->vtotal);
860     VidModeSetModeValue(mode, VIDMODE_FLAGS, stuff->flags);
861 
862     pVidMode->SetCrtcForMode(pScreen, mode);
863     pVidMode->SwitchMode(pScreen, mode);
864 
865     DebugF("ModModeLine - Succeeded\n");
866     return Success;
867 }
868 
869 static int
ProcVidModeValidateModeLine(ClientPtr client)870 ProcVidModeValidateModeLine(ClientPtr client)
871 {
872     REQUEST(xXF86VidModeValidateModeLineReq);
873     xXF86OldVidModeValidateModeLineReq *oldstuff =
874         (xXF86OldVidModeValidateModeLineReq *) client->requestBuffer;
875     xXF86VidModeValidateModeLineReq newstuff;
876     xXF86VidModeValidateModeLineReply rep;
877     ScreenPtr pScreen;
878     VidModePtr pVidMode;
879     DisplayModePtr mode, modetmp = NULL;
880     int len, status, dotClock;
881     int ver;
882 
883     DEBUG_P("XF86VidModeValidateModeline");
884 
885     ver = ClientMajorVersion(client);
886 
887     if (ver < 2) {
888         REQUEST_AT_LEAST_SIZE(xXF86OldVidModeValidateModeLineReq);
889         len = client->req_len -
890             bytes_to_int32(sizeof(xXF86OldVidModeValidateModeLineReq));
891     }
892     else {
893         REQUEST_AT_LEAST_SIZE(xXF86VidModeValidateModeLineReq);
894         len =
895             client->req_len -
896             bytes_to_int32(sizeof(xXF86VidModeValidateModeLineReq));
897     }
898 
899     if (ver < 2) {
900         /* convert from old format */
901         stuff = &newstuff;
902         stuff->length = oldstuff->length;
903         stuff->screen = oldstuff->screen;
904         stuff->dotclock = oldstuff->dotclock;
905         stuff->hdisplay = oldstuff->hdisplay;
906         stuff->hsyncstart = oldstuff->hsyncstart;
907         stuff->hsyncend = oldstuff->hsyncend;
908         stuff->htotal = oldstuff->htotal;
909         stuff->hskew = 0;
910         stuff->vdisplay = oldstuff->vdisplay;
911         stuff->vsyncstart = oldstuff->vsyncstart;
912         stuff->vsyncend = oldstuff->vsyncend;
913         stuff->vtotal = oldstuff->vtotal;
914         stuff->flags = oldstuff->flags;
915         stuff->privsize = oldstuff->privsize;
916     }
917 
918     DebugF("ValidateModeLine - scrn: %d clock: %ld\n",
919            (int) stuff->screen, (unsigned long) stuff->dotclock);
920     DebugF("                   hdsp: %d hbeg: %d hend: %d httl: %d\n",
921            stuff->hdisplay, stuff->hsyncstart,
922            stuff->hsyncend, stuff->htotal);
923     DebugF("                   vdsp: %d vbeg: %d vend: %d vttl: %d flags: %ld\n",
924            stuff->vdisplay, stuff->vsyncstart, stuff->vsyncend, stuff->vtotal,
925            (unsigned long) stuff->flags);
926 
927     if (len != stuff->privsize)
928         return BadLength;
929 
930     if (stuff->screen >= screenInfo.numScreens)
931         return BadValue;
932     pScreen = screenInfo.screens[stuff->screen];
933 
934     status = MODE_OK;
935 
936     if (stuff->hsyncstart < stuff->hdisplay ||
937         stuff->hsyncend < stuff->hsyncstart ||
938         stuff->htotal < stuff->hsyncend ||
939         stuff->vsyncstart < stuff->vdisplay ||
940         stuff->vsyncend < stuff->vsyncstart ||
941         stuff->vtotal < stuff->vsyncend) {
942         status = MODE_BAD;
943         goto status_reply;
944     }
945 
946     pVidMode = VidModeGetPtr(pScreen);
947     if (pVidMode == NULL)
948         return BadImplementation;
949 
950     if (!pVidMode->GetCurrentModeline(pScreen, &mode, &dotClock))
951         return BadValue;
952 
953     modetmp = VidModeCreateMode();
954     VidModeCopyMode(mode, modetmp);
955 
956     VidModeSetModeValue(modetmp, VIDMODE_H_DISPLAY, stuff->hdisplay);
957     VidModeSetModeValue(modetmp, VIDMODE_H_SYNCSTART, stuff->hsyncstart);
958     VidModeSetModeValue(modetmp, VIDMODE_H_SYNCEND, stuff->hsyncend);
959     VidModeSetModeValue(modetmp, VIDMODE_H_TOTAL, stuff->htotal);
960     VidModeSetModeValue(modetmp, VIDMODE_H_SKEW, stuff->hskew);
961     VidModeSetModeValue(modetmp, VIDMODE_V_DISPLAY, stuff->vdisplay);
962     VidModeSetModeValue(modetmp, VIDMODE_V_SYNCSTART, stuff->vsyncstart);
963     VidModeSetModeValue(modetmp, VIDMODE_V_SYNCEND, stuff->vsyncend);
964     VidModeSetModeValue(modetmp, VIDMODE_V_TOTAL, stuff->vtotal);
965     VidModeSetModeValue(modetmp, VIDMODE_FLAGS, stuff->flags);
966     if (stuff->privsize)
967         DebugF("ValidateModeLine - Privates in request have been ignored\n");
968 
969     /* Check that the mode is consistent with the monitor specs */
970     if ((status =
971          pVidMode->CheckModeForMonitor(pScreen, modetmp)) != MODE_OK)
972         goto status_reply;
973 
974     /* Check that the driver is happy with the mode */
975     status = pVidMode->CheckModeForDriver(pScreen, modetmp);
976 
977  status_reply:
978     free(modetmp);
979 
980     rep = (xXF86VidModeValidateModeLineReply) {
981         .type = X_Reply,
982         .sequenceNumber = client->sequence,
983         .length = bytes_to_int32(SIZEOF(xXF86VidModeValidateModeLineReply)
984                                  - SIZEOF(xGenericReply)),
985         .status = status
986     };
987     if (client->swapped) {
988         swaps(&rep.sequenceNumber);
989         swapl(&rep.length);
990         swapl(&rep.status);
991     }
992     WriteToClient(client, sizeof(xXF86VidModeValidateModeLineReply), &rep);
993     DebugF("ValidateModeLine - Succeeded (status = %d)\n", status);
994 
995     return Success;
996 }
997 
998 static int
ProcVidModeSwitchMode(ClientPtr client)999 ProcVidModeSwitchMode(ClientPtr client)
1000 {
1001     REQUEST(xXF86VidModeSwitchModeReq);
1002     ScreenPtr pScreen;
1003     VidModePtr pVidMode;
1004 
1005     DEBUG_P("XF86VidModeSwitchMode");
1006 
1007     REQUEST_SIZE_MATCH(xXF86VidModeSwitchModeReq);
1008 
1009     if (stuff->screen >= screenInfo.numScreens)
1010         return BadValue;
1011     pScreen = screenInfo.screens[stuff->screen];
1012 
1013     pVidMode = VidModeGetPtr(pScreen);
1014     if (pVidMode == NULL)
1015         return BadImplementation;
1016 
1017     pVidMode->ZoomViewport(pScreen, (short) stuff->zoom);
1018 
1019     return Success;
1020 }
1021 
1022 static int
ProcVidModeSwitchToMode(ClientPtr client)1023 ProcVidModeSwitchToMode(ClientPtr client)
1024 {
1025     REQUEST(xXF86VidModeSwitchToModeReq);
1026     xXF86OldVidModeSwitchToModeReq *oldstuff =
1027         (xXF86OldVidModeSwitchToModeReq *) client->requestBuffer;
1028     xXF86VidModeSwitchToModeReq newstuff;
1029     ScreenPtr pScreen;
1030     VidModePtr pVidMode;
1031     DisplayModePtr mode;
1032     int len, dotClock;
1033     int ver;
1034 
1035     DEBUG_P("XF86VidModeSwitchToMode");
1036 
1037     ver = ClientMajorVersion(client);
1038 
1039     if (ver < 2) {
1040         REQUEST_AT_LEAST_SIZE(xXF86OldVidModeSwitchToModeReq);
1041         len =
1042             client->req_len -
1043             bytes_to_int32(sizeof(xXF86OldVidModeSwitchToModeReq));
1044     }
1045     else {
1046         REQUEST_AT_LEAST_SIZE(xXF86VidModeSwitchToModeReq);
1047         len =
1048             client->req_len -
1049             bytes_to_int32(sizeof(xXF86VidModeSwitchToModeReq));
1050     }
1051 
1052     if (ver < 2) {
1053         /* convert from old format */
1054         stuff = &newstuff;
1055         stuff->length = oldstuff->length;
1056         stuff->screen = oldstuff->screen;
1057         stuff->dotclock = oldstuff->dotclock;
1058         stuff->hdisplay = oldstuff->hdisplay;
1059         stuff->hsyncstart = oldstuff->hsyncstart;
1060         stuff->hsyncend = oldstuff->hsyncend;
1061         stuff->htotal = oldstuff->htotal;
1062         stuff->hskew = 0;
1063         stuff->vdisplay = oldstuff->vdisplay;
1064         stuff->vsyncstart = oldstuff->vsyncstart;
1065         stuff->vsyncend = oldstuff->vsyncend;
1066         stuff->vtotal = oldstuff->vtotal;
1067         stuff->flags = oldstuff->flags;
1068         stuff->privsize = oldstuff->privsize;
1069     }
1070 
1071     DebugF("SwitchToMode - scrn: %d clock: %ld\n",
1072            (int) stuff->screen, (unsigned long) stuff->dotclock);
1073     DebugF("               hdsp: %d hbeg: %d hend: %d httl: %d\n",
1074            stuff->hdisplay, stuff->hsyncstart,
1075            stuff->hsyncend, stuff->htotal);
1076     DebugF("               vdsp: %d vbeg: %d vend: %d vttl: %d flags: %ld\n",
1077            stuff->vdisplay, stuff->vsyncstart, stuff->vsyncend, stuff->vtotal,
1078            (unsigned long) stuff->flags);
1079 
1080     if (len != stuff->privsize)
1081         return BadLength;
1082 
1083     if (stuff->screen >= screenInfo.numScreens)
1084         return BadValue;
1085     pScreen = screenInfo.screens[stuff->screen];
1086 
1087     pVidMode = VidModeGetPtr(pScreen);
1088     if (pVidMode == NULL)
1089         return BadImplementation;
1090 
1091     if (!pVidMode->GetCurrentModeline(pScreen, &mode, &dotClock))
1092         return BadValue;
1093 
1094     if ((pVidMode->GetDotClock(pScreen, stuff->dotclock) == dotClock)
1095         && MODEMATCH(mode, stuff))
1096         return Success;
1097 
1098     if (!pVidMode->GetFirstModeline(pScreen, &mode, &dotClock))
1099         return BadValue;
1100 
1101     do {
1102         DebugF("Checking against clock: %d (%d)\n",
1103                VidModeGetModeValue(mode, VIDMODE_CLOCK), dotClock);
1104         DebugF("                 hdsp: %d hbeg: %d hend: %d httl: %d\n",
1105                VidModeGetModeValue(mode, VIDMODE_H_DISPLAY),
1106                VidModeGetModeValue(mode, VIDMODE_H_SYNCSTART),
1107                VidModeGetModeValue(mode, VIDMODE_H_SYNCEND),
1108                VidModeGetModeValue(mode, VIDMODE_H_TOTAL));
1109         DebugF("                 vdsp: %d vbeg: %d vend: %d vttl: %d flags: %d\n",
1110                VidModeGetModeValue(mode, VIDMODE_V_DISPLAY),
1111                VidModeGetModeValue(mode, VIDMODE_V_SYNCSTART),
1112                VidModeGetModeValue(mode, VIDMODE_V_SYNCEND),
1113                VidModeGetModeValue(mode, VIDMODE_V_TOTAL),
1114                VidModeGetModeValue(mode, VIDMODE_FLAGS));
1115 
1116         if ((pVidMode->GetDotClock(pScreen, stuff->dotclock) == dotClock) &&
1117             MODEMATCH(mode, stuff)) {
1118 
1119             if (!pVidMode->SwitchMode(pScreen, mode))
1120                 return BadValue;
1121 
1122             DebugF("SwitchToMode - Succeeded\n");
1123             return Success;
1124         }
1125     } while (pVidMode->GetNextModeline(pScreen, &mode, &dotClock));
1126 
1127     return BadValue;
1128 }
1129 
1130 static int
ProcVidModeLockModeSwitch(ClientPtr client)1131 ProcVidModeLockModeSwitch(ClientPtr client)
1132 {
1133     REQUEST(xXF86VidModeLockModeSwitchReq);
1134     ScreenPtr pScreen;
1135     VidModePtr pVidMode;
1136 
1137     REQUEST_SIZE_MATCH(xXF86VidModeLockModeSwitchReq);
1138 
1139     DEBUG_P("XF86VidModeLockModeSwitch");
1140 
1141     if (stuff->screen >= screenInfo.numScreens)
1142         return BadValue;
1143     pScreen = screenInfo.screens[stuff->screen];
1144 
1145     pVidMode = VidModeGetPtr(pScreen);
1146     if (pVidMode == NULL)
1147         return BadImplementation;
1148 
1149     if (!pVidMode->LockZoom(pScreen, (short) stuff->lock))
1150         return VidModeErrorBase + XF86VidModeZoomLocked;
1151 
1152     return Success;
1153 }
1154 
1155 static int
ProcVidModeGetMonitor(ClientPtr client)1156 ProcVidModeGetMonitor(ClientPtr client)
1157 {
1158     REQUEST(xXF86VidModeGetMonitorReq);
1159     xXF86VidModeGetMonitorReply rep = {
1160         .type = X_Reply,
1161         .sequenceNumber = client->sequence
1162     };
1163     CARD32 *hsyncdata, *vsyncdata;
1164     ScreenPtr pScreen;
1165     VidModePtr pVidMode;
1166     int i, nHsync, nVrefresh;
1167 
1168     DEBUG_P("XF86VidModeGetMonitor");
1169 
1170     REQUEST_SIZE_MATCH(xXF86VidModeGetMonitorReq);
1171 
1172     if (stuff->screen >= screenInfo.numScreens)
1173         return BadValue;
1174     pScreen = screenInfo.screens[stuff->screen];
1175 
1176     pVidMode = VidModeGetPtr(pScreen);
1177     if (pVidMode == NULL)
1178         return BadImplementation;
1179 
1180     nHsync = pVidMode->GetMonitorValue(pScreen, VIDMODE_MON_NHSYNC, 0).i;
1181     nVrefresh = pVidMode->GetMonitorValue(pScreen, VIDMODE_MON_NVREFRESH, 0).i;
1182 
1183     if ((char *) (pVidMode->GetMonitorValue(pScreen, VIDMODE_MON_VENDOR, 0)).ptr)
1184         rep.vendorLength = strlen((char *) (pVidMode->GetMonitorValue(pScreen,
1185                                                                       VIDMODE_MON_VENDOR,
1186                                                                       0)).ptr);
1187     else
1188         rep.vendorLength = 0;
1189     if ((char *) (pVidMode->GetMonitorValue(pScreen, VIDMODE_MON_MODEL, 0)).ptr)
1190         rep.modelLength = strlen((char *) (pVidMode->GetMonitorValue(pScreen,
1191                                                                      VIDMODE_MON_MODEL,
1192                                                                      0)).ptr);
1193     else
1194         rep.modelLength = 0;
1195     rep.length =
1196         bytes_to_int32(SIZEOF(xXF86VidModeGetMonitorReply) -
1197                        SIZEOF(xGenericReply) + (nHsync +
1198                                                 nVrefresh) * sizeof(CARD32) +
1199                        pad_to_int32(rep.vendorLength) +
1200                        pad_to_int32(rep.modelLength));
1201     rep.nhsync = nHsync;
1202     rep.nvsync = nVrefresh;
1203     hsyncdata = xallocarray(nHsync, sizeof(CARD32));
1204     if (!hsyncdata) {
1205         return BadAlloc;
1206     }
1207     vsyncdata = xallocarray(nVrefresh, sizeof(CARD32));
1208 
1209     if (!vsyncdata) {
1210         free(hsyncdata);
1211         return BadAlloc;
1212     }
1213 
1214     for (i = 0; i < nHsync; i++) {
1215         hsyncdata[i] = (unsigned short) (pVidMode->GetMonitorValue(pScreen,
1216                                                                    VIDMODE_MON_HSYNC_LO,
1217                                                                    i)).f |
1218             (unsigned
1219              short) (pVidMode->GetMonitorValue(pScreen, VIDMODE_MON_HSYNC_HI,
1220                                                i)).f << 16;
1221     }
1222     for (i = 0; i < nVrefresh; i++) {
1223         vsyncdata[i] = (unsigned short) (pVidMode->GetMonitorValue(pScreen,
1224                                                                    VIDMODE_MON_VREFRESH_LO,
1225                                                                    i)).f |
1226             (unsigned
1227              short) (pVidMode->GetMonitorValue(pScreen, VIDMODE_MON_VREFRESH_HI,
1228                                                i)).f << 16;
1229     }
1230 
1231     if (client->swapped) {
1232         swaps(&rep.sequenceNumber);
1233         swapl(&rep.length);
1234     }
1235     WriteToClient(client, SIZEOF(xXF86VidModeGetMonitorReply), &rep);
1236     client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
1237     WriteSwappedDataToClient(client, nHsync * sizeof(CARD32), hsyncdata);
1238     WriteSwappedDataToClient(client, nVrefresh * sizeof(CARD32), vsyncdata);
1239     if (rep.vendorLength)
1240         WriteToClient(client, rep.vendorLength,
1241                  (pVidMode->GetMonitorValue(pScreen, VIDMODE_MON_VENDOR, 0)).ptr);
1242     if (rep.modelLength)
1243         WriteToClient(client, rep.modelLength,
1244                  (pVidMode->GetMonitorValue(pScreen, VIDMODE_MON_MODEL, 0)).ptr);
1245 
1246     free(hsyncdata);
1247     free(vsyncdata);
1248 
1249     return Success;
1250 }
1251 
1252 static int
ProcVidModeGetViewPort(ClientPtr client)1253 ProcVidModeGetViewPort(ClientPtr client)
1254 {
1255     REQUEST(xXF86VidModeGetViewPortReq);
1256     xXF86VidModeGetViewPortReply rep;
1257     ScreenPtr pScreen;
1258     VidModePtr pVidMode;
1259     int x, y;
1260 
1261     DEBUG_P("XF86VidModeGetViewPort");
1262 
1263     REQUEST_SIZE_MATCH(xXF86VidModeGetViewPortReq);
1264 
1265     if (stuff->screen >= screenInfo.numScreens)
1266         return BadValue;
1267     pScreen = screenInfo.screens[stuff->screen];
1268 
1269     pVidMode = VidModeGetPtr(pScreen);
1270     if (pVidMode == NULL)
1271         return BadImplementation;
1272 
1273     pVidMode->GetViewPort(pScreen, &x, &y);
1274 
1275     rep = (xXF86VidModeGetViewPortReply) {
1276         .type = X_Reply,
1277         .sequenceNumber = client->sequence,
1278         .length = 0,
1279         .x = x,
1280         .y = y
1281     };
1282 
1283     if (client->swapped) {
1284         swaps(&rep.sequenceNumber);
1285         swapl(&rep.length);
1286         swapl(&rep.x);
1287         swapl(&rep.y);
1288     }
1289     WriteToClient(client, SIZEOF(xXF86VidModeGetViewPortReply), &rep);
1290     return Success;
1291 }
1292 
1293 static int
ProcVidModeSetViewPort(ClientPtr client)1294 ProcVidModeSetViewPort(ClientPtr client)
1295 {
1296     REQUEST(xXF86VidModeSetViewPortReq);
1297     ScreenPtr pScreen;
1298     VidModePtr pVidMode;
1299 
1300     DEBUG_P("XF86VidModeSetViewPort");
1301 
1302     REQUEST_SIZE_MATCH(xXF86VidModeSetViewPortReq);
1303 
1304     if (stuff->screen >= screenInfo.numScreens)
1305         return BadValue;
1306     pScreen = screenInfo.screens[stuff->screen];
1307 
1308     pVidMode = VidModeGetPtr(pScreen);
1309     if (pVidMode == NULL)
1310         return BadImplementation;
1311 
1312     if (!pVidMode->SetViewPort(pScreen, stuff->x, stuff->y))
1313         return BadValue;
1314 
1315     return Success;
1316 }
1317 
1318 static int
ProcVidModeGetDotClocks(ClientPtr client)1319 ProcVidModeGetDotClocks(ClientPtr client)
1320 {
1321     REQUEST(xXF86VidModeGetDotClocksReq);
1322     xXF86VidModeGetDotClocksReply rep;
1323     ScreenPtr pScreen;
1324     VidModePtr pVidMode;
1325     int n;
1326     int numClocks;
1327     CARD32 dotclock;
1328     int *Clocks = NULL;
1329     Bool ClockProg;
1330 
1331     DEBUG_P("XF86VidModeGetDotClocks");
1332 
1333     REQUEST_SIZE_MATCH(xXF86VidModeGetDotClocksReq);
1334 
1335     if (stuff->screen >= screenInfo.numScreens)
1336         return BadValue;
1337     pScreen = screenInfo.screens[stuff->screen];
1338 
1339     pVidMode = VidModeGetPtr(pScreen);
1340     if (pVidMode == NULL)
1341         return BadImplementation;
1342 
1343     numClocks = pVidMode->GetNumOfClocks(pScreen, &ClockProg);
1344 
1345     rep = (xXF86VidModeGetDotClocksReply) {
1346         .type = X_Reply,
1347         .sequenceNumber = client->sequence,
1348         .length = bytes_to_int32(SIZEOF(xXF86VidModeGetDotClocksReply)
1349                                  - SIZEOF(xGenericReply) + numClocks),
1350         .clocks = numClocks,
1351         .maxclocks = MAXCLOCKS,
1352         .flags = 0
1353     };
1354 
1355     if (!ClockProg) {
1356         Clocks = calloc(numClocks, sizeof(int));
1357         if (!Clocks)
1358             return BadValue;
1359         if (!pVidMode->GetClocks(pScreen, Clocks)) {
1360             free(Clocks);
1361             return BadValue;
1362         }
1363     }
1364     if (ClockProg) {
1365         rep.flags |= CLKFLAG_PROGRAMABLE;
1366     }
1367     if (client->swapped) {
1368         swaps(&rep.sequenceNumber);
1369         swapl(&rep.length);
1370         swapl(&rep.clocks);
1371         swapl(&rep.maxclocks);
1372         swapl(&rep.flags);
1373     }
1374     WriteToClient(client, sizeof(xXF86VidModeGetDotClocksReply), &rep);
1375     if (!ClockProg) {
1376         for (n = 0; n < numClocks; n++) {
1377             dotclock = Clocks[n];
1378             if (client->swapped) {
1379                 WriteSwappedDataToClient(client, 4, (char *) &dotclock);
1380             }
1381             else {
1382                 WriteToClient(client, 4, &dotclock);
1383             }
1384         }
1385     }
1386 
1387     free(Clocks);
1388     return Success;
1389 }
1390 
1391 static int
ProcVidModeSetGamma(ClientPtr client)1392 ProcVidModeSetGamma(ClientPtr client)
1393 {
1394     REQUEST(xXF86VidModeSetGammaReq);
1395     ScreenPtr pScreen;
1396     VidModePtr pVidMode;
1397 
1398     DEBUG_P("XF86VidModeSetGamma");
1399 
1400     REQUEST_SIZE_MATCH(xXF86VidModeSetGammaReq);
1401 
1402     if (stuff->screen >= screenInfo.numScreens)
1403         return BadValue;
1404     pScreen = screenInfo.screens[stuff->screen];
1405 
1406     pVidMode = VidModeGetPtr(pScreen);
1407     if (pVidMode == NULL)
1408         return BadImplementation;
1409 
1410     if (!pVidMode->SetGamma(pScreen, ((float) stuff->red) / 10000.,
1411                          ((float) stuff->green) / 10000.,
1412                          ((float) stuff->blue) / 10000.))
1413         return BadValue;
1414 
1415     return Success;
1416 }
1417 
1418 static int
ProcVidModeGetGamma(ClientPtr client)1419 ProcVidModeGetGamma(ClientPtr client)
1420 {
1421     REQUEST(xXF86VidModeGetGammaReq);
1422     xXF86VidModeGetGammaReply rep;
1423     ScreenPtr pScreen;
1424     VidModePtr pVidMode;
1425     float red, green, blue;
1426 
1427     DEBUG_P("XF86VidModeGetGamma");
1428 
1429     REQUEST_SIZE_MATCH(xXF86VidModeGetGammaReq);
1430 
1431     if (stuff->screen >= screenInfo.numScreens)
1432         return BadValue;
1433     pScreen = screenInfo.screens[stuff->screen];
1434 
1435     pVidMode = VidModeGetPtr(pScreen);
1436     if (pVidMode == NULL)
1437         return BadImplementation;
1438 
1439     if (!pVidMode->GetGamma(pScreen, &red, &green, &blue))
1440         return BadValue;
1441     rep = (xXF86VidModeGetGammaReply) {
1442         .type = X_Reply,
1443         .sequenceNumber = client->sequence,
1444         .length = 0,
1445         .red = (CARD32) (red * 10000.),
1446         .green = (CARD32) (green * 10000.),
1447         .blue = (CARD32) (blue * 10000.)
1448     };
1449     if (client->swapped) {
1450         swaps(&rep.sequenceNumber);
1451         swapl(&rep.length);
1452         swapl(&rep.red);
1453         swapl(&rep.green);
1454         swapl(&rep.blue);
1455     }
1456     WriteToClient(client, sizeof(xXF86VidModeGetGammaReply), &rep);
1457 
1458     return Success;
1459 }
1460 
1461 static int
ProcVidModeSetGammaRamp(ClientPtr client)1462 ProcVidModeSetGammaRamp(ClientPtr client)
1463 {
1464     CARD16 *r, *g, *b;
1465     int length;
1466     ScreenPtr pScreen;
1467     VidModePtr pVidMode;
1468 
1469     REQUEST(xXF86VidModeSetGammaRampReq);
1470     REQUEST_AT_LEAST_SIZE(xXF86VidModeSetGammaRampReq);
1471 
1472     if (stuff->screen >= screenInfo.numScreens)
1473         return BadValue;
1474     pScreen = screenInfo.screens[stuff->screen];
1475 
1476     pVidMode = VidModeGetPtr(pScreen);
1477     if (pVidMode == NULL)
1478         return BadImplementation;
1479 
1480     if (stuff->size != pVidMode->GetGammaRampSize(pScreen))
1481         return BadValue;
1482 
1483     length = (stuff->size + 1) & ~1;
1484 
1485     REQUEST_FIXED_SIZE(xXF86VidModeSetGammaRampReq, length * 6);
1486 
1487     r = (CARD16 *) &stuff[1];
1488     g = r + length;
1489     b = g + length;
1490 
1491     if (!pVidMode->SetGammaRamp(pScreen, stuff->size, r, g, b))
1492         return BadValue;
1493 
1494     return Success;
1495 }
1496 
1497 static int
ProcVidModeGetGammaRamp(ClientPtr client)1498 ProcVidModeGetGammaRamp(ClientPtr client)
1499 {
1500     CARD16 *ramp = NULL;
1501     int length;
1502     size_t ramplen = 0;
1503     xXF86VidModeGetGammaRampReply rep;
1504     ScreenPtr pScreen;
1505     VidModePtr pVidMode;
1506 
1507     REQUEST(xXF86VidModeGetGammaRampReq);
1508 
1509     REQUEST_SIZE_MATCH(xXF86VidModeGetGammaRampReq);
1510 
1511     if (stuff->screen >= screenInfo.numScreens)
1512         return BadValue;
1513     pScreen = screenInfo.screens[stuff->screen];
1514 
1515     pVidMode = VidModeGetPtr(pScreen);
1516     if (pVidMode == NULL)
1517         return BadImplementation;
1518 
1519     if (stuff->size != pVidMode->GetGammaRampSize(pScreen))
1520         return BadValue;
1521 
1522     length = (stuff->size + 1) & ~1;
1523 
1524     if (stuff->size) {
1525         if (!(ramp = xallocarray(length, 3 * sizeof(CARD16))))
1526             return BadAlloc;
1527         ramplen = length * 3 * sizeof(CARD16);
1528 
1529         if (!pVidMode->GetGammaRamp(pScreen, stuff->size,
1530                                  ramp, ramp + length, ramp + (length * 2))) {
1531             free(ramp);
1532             return BadValue;
1533         }
1534     }
1535     rep = (xXF86VidModeGetGammaRampReply) {
1536         .type = X_Reply,
1537         .sequenceNumber = client->sequence,
1538         .length = (length >> 1) * 3,
1539         .size = stuff->size
1540     };
1541     if (client->swapped) {
1542         swaps(&rep.sequenceNumber);
1543         swapl(&rep.length);
1544         swaps(&rep.size);
1545         SwapShorts((short *) ramp, length * 3);
1546     }
1547     WriteToClient(client, sizeof(xXF86VidModeGetGammaRampReply), &rep);
1548 
1549     if (stuff->size) {
1550         WriteToClient(client, ramplen, ramp);
1551         free(ramp);
1552     }
1553 
1554     return Success;
1555 }
1556 
1557 
1558 static int
ProcVidModeGetGammaRampSize(ClientPtr client)1559 ProcVidModeGetGammaRampSize(ClientPtr client)
1560 {
1561     xXF86VidModeGetGammaRampSizeReply rep;
1562     ScreenPtr pScreen;
1563     VidModePtr pVidMode;
1564 
1565     REQUEST(xXF86VidModeGetGammaRampSizeReq);
1566 
1567     REQUEST_SIZE_MATCH(xXF86VidModeGetGammaRampSizeReq);
1568 
1569     if (stuff->screen >= screenInfo.numScreens)
1570         return BadValue;
1571     pScreen = screenInfo.screens[stuff->screen];
1572 
1573     pVidMode = VidModeGetPtr(pScreen);
1574     if (pVidMode == NULL)
1575         return BadImplementation;
1576 
1577     rep = (xXF86VidModeGetGammaRampSizeReply) {
1578         .type = X_Reply,
1579         .sequenceNumber = client->sequence,
1580         .length = 0,
1581         .size = pVidMode->GetGammaRampSize(pScreen)
1582     };
1583     if (client->swapped) {
1584         swaps(&rep.sequenceNumber);
1585         swapl(&rep.length);
1586         swaps(&rep.size);
1587     }
1588     WriteToClient(client, sizeof(xXF86VidModeGetGammaRampSizeReply), &rep);
1589 
1590     return Success;
1591 }
1592 
1593 static int
ProcVidModeGetPermissions(ClientPtr client)1594 ProcVidModeGetPermissions(ClientPtr client)
1595 {
1596     xXF86VidModeGetPermissionsReply rep =  {
1597         .type = X_Reply,
1598         .sequenceNumber = client->sequence,
1599         .length = 0,
1600         .permissions = XF86VM_READ_PERMISSION
1601     };
1602 
1603     REQUEST(xXF86VidModeGetPermissionsReq);
1604 
1605     REQUEST_SIZE_MATCH(xXF86VidModeGetPermissionsReq);
1606 
1607     if (stuff->screen >= screenInfo.numScreens)
1608         return BadValue;
1609 
1610     if (VidModeAllowNonLocal || client->local) {
1611         rep.permissions |= XF86VM_WRITE_PERMISSION;
1612     }
1613     if (client->swapped) {
1614         swaps(&rep.sequenceNumber);
1615         swapl(&rep.length);
1616         swapl(&rep.permissions);
1617     }
1618     WriteToClient(client, sizeof(xXF86VidModeGetPermissionsReply), &rep);
1619 
1620     return Success;
1621 }
1622 
1623 static int
ProcVidModeSetClientVersion(ClientPtr client)1624 ProcVidModeSetClientVersion(ClientPtr client)
1625 {
1626     REQUEST(xXF86VidModeSetClientVersionReq);
1627 
1628     VidModePrivPtr pPriv;
1629 
1630     DEBUG_P("XF86VidModeSetClientVersion");
1631 
1632     REQUEST_SIZE_MATCH(xXF86VidModeSetClientVersionReq);
1633 
1634     if ((pPriv = VM_GETPRIV(client)) == NULL) {
1635         pPriv = malloc(sizeof(VidModePrivRec));
1636         if (!pPriv)
1637             return BadAlloc;
1638         VM_SETPRIV(client, pPriv);
1639     }
1640     pPriv->major = stuff->major;
1641 
1642     pPriv->minor = stuff->minor;
1643 
1644     return Success;
1645 }
1646 
1647 static int
ProcVidModeDispatch(ClientPtr client)1648 ProcVidModeDispatch(ClientPtr client)
1649 {
1650     REQUEST(xReq);
1651     switch (stuff->data) {
1652     case X_XF86VidModeQueryVersion:
1653         return ProcVidModeQueryVersion(client);
1654     case X_XF86VidModeGetModeLine:
1655         return ProcVidModeGetModeLine(client);
1656     case X_XF86VidModeGetMonitor:
1657         return ProcVidModeGetMonitor(client);
1658     case X_XF86VidModeGetAllModeLines:
1659         return ProcVidModeGetAllModeLines(client);
1660     case X_XF86VidModeValidateModeLine:
1661         return ProcVidModeValidateModeLine(client);
1662     case X_XF86VidModeGetViewPort:
1663         return ProcVidModeGetViewPort(client);
1664     case X_XF86VidModeGetDotClocks:
1665         return ProcVidModeGetDotClocks(client);
1666     case X_XF86VidModeSetClientVersion:
1667         return ProcVidModeSetClientVersion(client);
1668     case X_XF86VidModeGetGamma:
1669         return ProcVidModeGetGamma(client);
1670     case X_XF86VidModeGetGammaRamp:
1671         return ProcVidModeGetGammaRamp(client);
1672     case X_XF86VidModeGetGammaRampSize:
1673         return ProcVidModeGetGammaRampSize(client);
1674     case X_XF86VidModeGetPermissions:
1675         return ProcVidModeGetPermissions(client);
1676     default:
1677         if (VidModeAllowNonLocal || client->local) {
1678             switch (stuff->data) {
1679             case X_XF86VidModeAddModeLine:
1680                 return ProcVidModeAddModeLine(client);
1681             case X_XF86VidModeDeleteModeLine:
1682                 return ProcVidModeDeleteModeLine(client);
1683             case X_XF86VidModeModModeLine:
1684                 return ProcVidModeModModeLine(client);
1685             case X_XF86VidModeSwitchMode:
1686                 return ProcVidModeSwitchMode(client);
1687             case X_XF86VidModeSwitchToMode:
1688                 return ProcVidModeSwitchToMode(client);
1689             case X_XF86VidModeLockModeSwitch:
1690                 return ProcVidModeLockModeSwitch(client);
1691             case X_XF86VidModeSetViewPort:
1692                 return ProcVidModeSetViewPort(client);
1693             case X_XF86VidModeSetGamma:
1694                 return ProcVidModeSetGamma(client);
1695             case X_XF86VidModeSetGammaRamp:
1696                 return ProcVidModeSetGammaRamp(client);
1697             default:
1698                 return BadRequest;
1699             }
1700         }
1701         else
1702             return VidModeErrorBase + XF86VidModeClientNotLocal;
1703     }
1704 }
1705 
1706 static int _X_COLD
SProcVidModeQueryVersion(ClientPtr client)1707 SProcVidModeQueryVersion(ClientPtr client)
1708 {
1709     REQUEST(xXF86VidModeQueryVersionReq);
1710     swaps(&stuff->length);
1711     return ProcVidModeQueryVersion(client);
1712 }
1713 
1714 static int _X_COLD
SProcVidModeGetModeLine(ClientPtr client)1715 SProcVidModeGetModeLine(ClientPtr client)
1716 {
1717     REQUEST(xXF86VidModeGetModeLineReq);
1718     swaps(&stuff->length);
1719     REQUEST_SIZE_MATCH(xXF86VidModeGetModeLineReq);
1720     swaps(&stuff->screen);
1721     return ProcVidModeGetModeLine(client);
1722 }
1723 
1724 static int _X_COLD
SProcVidModeGetAllModeLines(ClientPtr client)1725 SProcVidModeGetAllModeLines(ClientPtr client)
1726 {
1727     REQUEST(xXF86VidModeGetAllModeLinesReq);
1728     swaps(&stuff->length);
1729     REQUEST_SIZE_MATCH(xXF86VidModeGetAllModeLinesReq);
1730     swaps(&stuff->screen);
1731     return ProcVidModeGetAllModeLines(client);
1732 }
1733 
1734 static int _X_COLD
SProcVidModeAddModeLine(ClientPtr client)1735 SProcVidModeAddModeLine(ClientPtr client)
1736 {
1737     xXF86OldVidModeAddModeLineReq *oldstuff =
1738         (xXF86OldVidModeAddModeLineReq *) client->requestBuffer;
1739     int ver;
1740 
1741     REQUEST(xXF86VidModeAddModeLineReq);
1742     ver = ClientMajorVersion(client);
1743     if (ver < 2) {
1744         swaps(&oldstuff->length);
1745         REQUEST_AT_LEAST_SIZE(xXF86OldVidModeAddModeLineReq);
1746         swapl(&oldstuff->screen);
1747         swaps(&oldstuff->hdisplay);
1748         swaps(&oldstuff->hsyncstart);
1749         swaps(&oldstuff->hsyncend);
1750         swaps(&oldstuff->htotal);
1751         swaps(&oldstuff->vdisplay);
1752         swaps(&oldstuff->vsyncstart);
1753         swaps(&oldstuff->vsyncend);
1754         swaps(&oldstuff->vtotal);
1755         swapl(&oldstuff->flags);
1756         swapl(&oldstuff->privsize);
1757         SwapRestL(oldstuff);
1758     }
1759     else {
1760         swaps(&stuff->length);
1761         REQUEST_AT_LEAST_SIZE(xXF86VidModeAddModeLineReq);
1762         swapl(&stuff->screen);
1763         swaps(&stuff->hdisplay);
1764         swaps(&stuff->hsyncstart);
1765         swaps(&stuff->hsyncend);
1766         swaps(&stuff->htotal);
1767         swaps(&stuff->hskew);
1768         swaps(&stuff->vdisplay);
1769         swaps(&stuff->vsyncstart);
1770         swaps(&stuff->vsyncend);
1771         swaps(&stuff->vtotal);
1772         swapl(&stuff->flags);
1773         swapl(&stuff->privsize);
1774         SwapRestL(stuff);
1775     }
1776     return ProcVidModeAddModeLine(client);
1777 }
1778 
1779 static int _X_COLD
SProcVidModeDeleteModeLine(ClientPtr client)1780 SProcVidModeDeleteModeLine(ClientPtr client)
1781 {
1782     xXF86OldVidModeDeleteModeLineReq *oldstuff =
1783         (xXF86OldVidModeDeleteModeLineReq *) client->requestBuffer;
1784     int ver;
1785 
1786     REQUEST(xXF86VidModeDeleteModeLineReq);
1787     ver = ClientMajorVersion(client);
1788     if (ver < 2) {
1789         swaps(&oldstuff->length);
1790         REQUEST_AT_LEAST_SIZE(xXF86OldVidModeDeleteModeLineReq);
1791         swapl(&oldstuff->screen);
1792         swaps(&oldstuff->hdisplay);
1793         swaps(&oldstuff->hsyncstart);
1794         swaps(&oldstuff->hsyncend);
1795         swaps(&oldstuff->htotal);
1796         swaps(&oldstuff->vdisplay);
1797         swaps(&oldstuff->vsyncstart);
1798         swaps(&oldstuff->vsyncend);
1799         swaps(&oldstuff->vtotal);
1800         swapl(&oldstuff->flags);
1801         swapl(&oldstuff->privsize);
1802         SwapRestL(oldstuff);
1803     }
1804     else {
1805         swaps(&stuff->length);
1806         REQUEST_AT_LEAST_SIZE(xXF86VidModeDeleteModeLineReq);
1807         swapl(&stuff->screen);
1808         swaps(&stuff->hdisplay);
1809         swaps(&stuff->hsyncstart);
1810         swaps(&stuff->hsyncend);
1811         swaps(&stuff->htotal);
1812         swaps(&stuff->hskew);
1813         swaps(&stuff->vdisplay);
1814         swaps(&stuff->vsyncstart);
1815         swaps(&stuff->vsyncend);
1816         swaps(&stuff->vtotal);
1817         swapl(&stuff->flags);
1818         swapl(&stuff->privsize);
1819         SwapRestL(stuff);
1820     }
1821     return ProcVidModeDeleteModeLine(client);
1822 }
1823 
1824 static int _X_COLD
SProcVidModeModModeLine(ClientPtr client)1825 SProcVidModeModModeLine(ClientPtr client)
1826 {
1827     xXF86OldVidModeModModeLineReq *oldstuff =
1828         (xXF86OldVidModeModModeLineReq *) client->requestBuffer;
1829     int ver;
1830 
1831     REQUEST(xXF86VidModeModModeLineReq);
1832     ver = ClientMajorVersion(client);
1833     if (ver < 2) {
1834         swaps(&oldstuff->length);
1835         REQUEST_AT_LEAST_SIZE(xXF86OldVidModeModModeLineReq);
1836         swapl(&oldstuff->screen);
1837         swaps(&oldstuff->hdisplay);
1838         swaps(&oldstuff->hsyncstart);
1839         swaps(&oldstuff->hsyncend);
1840         swaps(&oldstuff->htotal);
1841         swaps(&oldstuff->vdisplay);
1842         swaps(&oldstuff->vsyncstart);
1843         swaps(&oldstuff->vsyncend);
1844         swaps(&oldstuff->vtotal);
1845         swapl(&oldstuff->flags);
1846         swapl(&oldstuff->privsize);
1847         SwapRestL(oldstuff);
1848     }
1849     else {
1850         swaps(&stuff->length);
1851         REQUEST_AT_LEAST_SIZE(xXF86VidModeModModeLineReq);
1852         swapl(&stuff->screen);
1853         swaps(&stuff->hdisplay);
1854         swaps(&stuff->hsyncstart);
1855         swaps(&stuff->hsyncend);
1856         swaps(&stuff->htotal);
1857         swaps(&stuff->hskew);
1858         swaps(&stuff->vdisplay);
1859         swaps(&stuff->vsyncstart);
1860         swaps(&stuff->vsyncend);
1861         swaps(&stuff->vtotal);
1862         swapl(&stuff->flags);
1863         swapl(&stuff->privsize);
1864         SwapRestL(stuff);
1865     }
1866     return ProcVidModeModModeLine(client);
1867 }
1868 
1869 static int _X_COLD
SProcVidModeValidateModeLine(ClientPtr client)1870 SProcVidModeValidateModeLine(ClientPtr client)
1871 {
1872     xXF86OldVidModeValidateModeLineReq *oldstuff =
1873         (xXF86OldVidModeValidateModeLineReq *) client->requestBuffer;
1874     int ver;
1875 
1876     REQUEST(xXF86VidModeValidateModeLineReq);
1877     ver = ClientMajorVersion(client);
1878     if (ver < 2) {
1879         swaps(&oldstuff->length);
1880         REQUEST_AT_LEAST_SIZE(xXF86OldVidModeValidateModeLineReq);
1881         swapl(&oldstuff->screen);
1882         swaps(&oldstuff->hdisplay);
1883         swaps(&oldstuff->hsyncstart);
1884         swaps(&oldstuff->hsyncend);
1885         swaps(&oldstuff->htotal);
1886         swaps(&oldstuff->vdisplay);
1887         swaps(&oldstuff->vsyncstart);
1888         swaps(&oldstuff->vsyncend);
1889         swaps(&oldstuff->vtotal);
1890         swapl(&oldstuff->flags);
1891         swapl(&oldstuff->privsize);
1892         SwapRestL(oldstuff);
1893     }
1894     else {
1895         swaps(&stuff->length);
1896         REQUEST_AT_LEAST_SIZE(xXF86VidModeValidateModeLineReq);
1897         swapl(&stuff->screen);
1898         swaps(&stuff->hdisplay);
1899         swaps(&stuff->hsyncstart);
1900         swaps(&stuff->hsyncend);
1901         swaps(&stuff->htotal);
1902         swaps(&stuff->hskew);
1903         swaps(&stuff->vdisplay);
1904         swaps(&stuff->vsyncstart);
1905         swaps(&stuff->vsyncend);
1906         swaps(&stuff->vtotal);
1907         swapl(&stuff->flags);
1908         swapl(&stuff->privsize);
1909         SwapRestL(stuff);
1910     }
1911     return ProcVidModeValidateModeLine(client);
1912 }
1913 
1914 static int _X_COLD
SProcVidModeSwitchMode(ClientPtr client)1915 SProcVidModeSwitchMode(ClientPtr client)
1916 {
1917     REQUEST(xXF86VidModeSwitchModeReq);
1918     swaps(&stuff->length);
1919     REQUEST_SIZE_MATCH(xXF86VidModeSwitchModeReq);
1920     swaps(&stuff->screen);
1921     swaps(&stuff->zoom);
1922     return ProcVidModeSwitchMode(client);
1923 }
1924 
1925 static int _X_COLD
SProcVidModeSwitchToMode(ClientPtr client)1926 SProcVidModeSwitchToMode(ClientPtr client)
1927 {
1928     REQUEST(xXF86VidModeSwitchToModeReq);
1929     swaps(&stuff->length);
1930     REQUEST_SIZE_MATCH(xXF86VidModeSwitchToModeReq);
1931     swapl(&stuff->screen);
1932     return ProcVidModeSwitchToMode(client);
1933 }
1934 
1935 static int _X_COLD
SProcVidModeLockModeSwitch(ClientPtr client)1936 SProcVidModeLockModeSwitch(ClientPtr client)
1937 {
1938     REQUEST(xXF86VidModeLockModeSwitchReq);
1939     swaps(&stuff->length);
1940     REQUEST_SIZE_MATCH(xXF86VidModeLockModeSwitchReq);
1941     swaps(&stuff->screen);
1942     swaps(&stuff->lock);
1943     return ProcVidModeLockModeSwitch(client);
1944 }
1945 
1946 static int _X_COLD
SProcVidModeGetMonitor(ClientPtr client)1947 SProcVidModeGetMonitor(ClientPtr client)
1948 {
1949     REQUEST(xXF86VidModeGetMonitorReq);
1950     swaps(&stuff->length);
1951     REQUEST_SIZE_MATCH(xXF86VidModeGetMonitorReq);
1952     swaps(&stuff->screen);
1953     return ProcVidModeGetMonitor(client);
1954 }
1955 
1956 static int _X_COLD
SProcVidModeGetViewPort(ClientPtr client)1957 SProcVidModeGetViewPort(ClientPtr client)
1958 {
1959     REQUEST(xXF86VidModeGetViewPortReq);
1960     swaps(&stuff->length);
1961     REQUEST_SIZE_MATCH(xXF86VidModeGetViewPortReq);
1962     swaps(&stuff->screen);
1963     return ProcVidModeGetViewPort(client);
1964 }
1965 
1966 static int _X_COLD
SProcVidModeSetViewPort(ClientPtr client)1967 SProcVidModeSetViewPort(ClientPtr client)
1968 {
1969     REQUEST(xXF86VidModeSetViewPortReq);
1970     swaps(&stuff->length);
1971     REQUEST_SIZE_MATCH(xXF86VidModeSetViewPortReq);
1972     swaps(&stuff->screen);
1973     swapl(&stuff->x);
1974     swapl(&stuff->y);
1975     return ProcVidModeSetViewPort(client);
1976 }
1977 
1978 static int _X_COLD
SProcVidModeGetDotClocks(ClientPtr client)1979 SProcVidModeGetDotClocks(ClientPtr client)
1980 {
1981     REQUEST(xXF86VidModeGetDotClocksReq);
1982     swaps(&stuff->length);
1983     REQUEST_SIZE_MATCH(xXF86VidModeGetDotClocksReq);
1984     swaps(&stuff->screen);
1985     return ProcVidModeGetDotClocks(client);
1986 }
1987 
1988 static int _X_COLD
SProcVidModeSetClientVersion(ClientPtr client)1989 SProcVidModeSetClientVersion(ClientPtr client)
1990 {
1991     REQUEST(xXF86VidModeSetClientVersionReq);
1992     swaps(&stuff->length);
1993     REQUEST_SIZE_MATCH(xXF86VidModeSetClientVersionReq);
1994     swaps(&stuff->major);
1995     swaps(&stuff->minor);
1996     return ProcVidModeSetClientVersion(client);
1997 }
1998 
1999 static int _X_COLD
SProcVidModeSetGamma(ClientPtr client)2000 SProcVidModeSetGamma(ClientPtr client)
2001 {
2002     REQUEST(xXF86VidModeSetGammaReq);
2003     swaps(&stuff->length);
2004     REQUEST_SIZE_MATCH(xXF86VidModeSetGammaReq);
2005     swaps(&stuff->screen);
2006     swapl(&stuff->red);
2007     swapl(&stuff->green);
2008     swapl(&stuff->blue);
2009     return ProcVidModeSetGamma(client);
2010 }
2011 
2012 static int _X_COLD
SProcVidModeGetGamma(ClientPtr client)2013 SProcVidModeGetGamma(ClientPtr client)
2014 {
2015     REQUEST(xXF86VidModeGetGammaReq);
2016     swaps(&stuff->length);
2017     REQUEST_SIZE_MATCH(xXF86VidModeGetGammaReq);
2018     swaps(&stuff->screen);
2019     return ProcVidModeGetGamma(client);
2020 }
2021 
2022 static int _X_COLD
SProcVidModeSetGammaRamp(ClientPtr client)2023 SProcVidModeSetGammaRamp(ClientPtr client)
2024 {
2025     int length;
2026 
2027     REQUEST(xXF86VidModeSetGammaRampReq);
2028     swaps(&stuff->length);
2029     REQUEST_AT_LEAST_SIZE(xXF86VidModeSetGammaRampReq);
2030     swaps(&stuff->size);
2031     swaps(&stuff->screen);
2032     length = ((stuff->size + 1) & ~1) * 6;
2033     REQUEST_FIXED_SIZE(xXF86VidModeSetGammaRampReq, length);
2034     SwapRestS(stuff);
2035     return ProcVidModeSetGammaRamp(client);
2036 }
2037 
2038 static int _X_COLD
SProcVidModeGetGammaRamp(ClientPtr client)2039 SProcVidModeGetGammaRamp(ClientPtr client)
2040 {
2041     REQUEST(xXF86VidModeGetGammaRampReq);
2042     swaps(&stuff->length);
2043     REQUEST_SIZE_MATCH(xXF86VidModeGetGammaRampReq);
2044     swaps(&stuff->size);
2045     swaps(&stuff->screen);
2046     return ProcVidModeGetGammaRamp(client);
2047 }
2048 
2049 static int _X_COLD
SProcVidModeGetGammaRampSize(ClientPtr client)2050 SProcVidModeGetGammaRampSize(ClientPtr client)
2051 {
2052     REQUEST(xXF86VidModeGetGammaRampSizeReq);
2053     swaps(&stuff->length);
2054     REQUEST_SIZE_MATCH(xXF86VidModeGetGammaRampSizeReq);
2055     swaps(&stuff->screen);
2056     return ProcVidModeGetGammaRampSize(client);
2057 }
2058 
2059 static int _X_COLD
SProcVidModeGetPermissions(ClientPtr client)2060 SProcVidModeGetPermissions(ClientPtr client)
2061 {
2062     REQUEST(xXF86VidModeGetPermissionsReq);
2063     swaps(&stuff->length);
2064     REQUEST_SIZE_MATCH(xXF86VidModeGetPermissionsReq);
2065     swaps(&stuff->screen);
2066     return ProcVidModeGetPermissions(client);
2067 }
2068 
2069 static int _X_COLD
SProcVidModeDispatch(ClientPtr client)2070 SProcVidModeDispatch(ClientPtr client)
2071 {
2072     REQUEST(xReq);
2073     switch (stuff->data) {
2074     case X_XF86VidModeQueryVersion:
2075         return SProcVidModeQueryVersion(client);
2076     case X_XF86VidModeGetModeLine:
2077         return SProcVidModeGetModeLine(client);
2078     case X_XF86VidModeGetMonitor:
2079         return SProcVidModeGetMonitor(client);
2080     case X_XF86VidModeGetAllModeLines:
2081         return SProcVidModeGetAllModeLines(client);
2082     case X_XF86VidModeGetViewPort:
2083         return SProcVidModeGetViewPort(client);
2084     case X_XF86VidModeValidateModeLine:
2085         return SProcVidModeValidateModeLine(client);
2086     case X_XF86VidModeGetDotClocks:
2087         return SProcVidModeGetDotClocks(client);
2088     case X_XF86VidModeSetClientVersion:
2089         return SProcVidModeSetClientVersion(client);
2090     case X_XF86VidModeGetGamma:
2091         return SProcVidModeGetGamma(client);
2092     case X_XF86VidModeGetGammaRamp:
2093         return SProcVidModeGetGammaRamp(client);
2094     case X_XF86VidModeGetGammaRampSize:
2095         return SProcVidModeGetGammaRampSize(client);
2096     case X_XF86VidModeGetPermissions:
2097         return SProcVidModeGetPermissions(client);
2098     default:
2099         if (VidModeAllowNonLocal || client->local) {
2100             switch (stuff->data) {
2101             case X_XF86VidModeAddModeLine:
2102                 return SProcVidModeAddModeLine(client);
2103             case X_XF86VidModeDeleteModeLine:
2104                 return SProcVidModeDeleteModeLine(client);
2105             case X_XF86VidModeModModeLine:
2106                 return SProcVidModeModModeLine(client);
2107             case X_XF86VidModeSwitchMode:
2108                 return SProcVidModeSwitchMode(client);
2109             case X_XF86VidModeSwitchToMode:
2110                 return SProcVidModeSwitchToMode(client);
2111             case X_XF86VidModeLockModeSwitch:
2112                 return SProcVidModeLockModeSwitch(client);
2113             case X_XF86VidModeSetViewPort:
2114                 return SProcVidModeSetViewPort(client);
2115             case X_XF86VidModeSetGamma:
2116                 return SProcVidModeSetGamma(client);
2117             case X_XF86VidModeSetGammaRamp:
2118                 return SProcVidModeSetGammaRamp(client);
2119             default:
2120                 return BadRequest;
2121             }
2122         }
2123         else
2124             return VidModeErrorBase + XF86VidModeClientNotLocal;
2125     }
2126 }
2127 
2128 void
VidModeAddExtension(Bool allow_non_local)2129 VidModeAddExtension(Bool allow_non_local)
2130 {
2131     ExtensionEntry *extEntry;
2132 
2133     DEBUG_P("VidModeAddExtension");
2134 
2135     if (!dixRegisterPrivateKey(VidModeClientPrivateKey, PRIVATE_CLIENT, 0))
2136         return;
2137 
2138     if ((extEntry = AddExtension(XF86VIDMODENAME,
2139                                  XF86VidModeNumberEvents,
2140                                  XF86VidModeNumberErrors,
2141                                  ProcVidModeDispatch,
2142                                  SProcVidModeDispatch,
2143                                  NULL, StandardMinorOpcode))) {
2144         VidModeErrorBase = extEntry->errorBase;
2145         VidModeAllowNonLocal = allow_non_local;
2146     }
2147 }
2148 
VidModeGetPtr(ScreenPtr pScreen)2149 VidModePtr VidModeGetPtr(ScreenPtr pScreen)
2150 {
2151     return (VidModePtr) (dixLookupPrivate(&pScreen->devPrivates, VidModePrivateKey));
2152 }
2153 
VidModeInit(ScreenPtr pScreen)2154 VidModePtr VidModeInit(ScreenPtr pScreen)
2155 {
2156     if (!dixRegisterPrivateKey(VidModePrivateKey, PRIVATE_SCREEN, sizeof(VidModeRec)))
2157         return NULL;
2158 
2159     return VidModeGetPtr(pScreen);
2160 }
2161 
2162 #endif /* XF86VIDMODE */
2163