vidmode.c revision 35c4bbdf
1/*
2
3Copyright 1995  Kaleb S. KEITHLEY
4
5Permission is hereby granted, free of charge, to any person obtaining
6a copy of this software and associated documentation files (the
7"Software"), to deal in the Software without restriction, including
8without limitation the rights to use, copy, modify, merge, publish,
9distribute, sublicense, and/or sell copies of the Software, and to
10permit persons to whom the Software is furnished to do so, subject to
11the following conditions:
12
13The above copyright notice and this permission notice shall be
14included in all copies or substantial portions of the Software.
15
16THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19IN NO EVENT SHALL Kaleb S. KEITHLEY BE LIABLE FOR ANY CLAIM, DAMAGES
20OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22OTHER DEALINGS IN THE SOFTWARE.
23
24Except as contained in this notice, the name of Kaleb S. KEITHLEY
25shall not be used in advertising or otherwise to promote the sale, use
26or other dealings in this Software without prior written authorization
27from Kaleb S. KEITHLEY
28
29*/
30/* 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
51static int VidModeErrorBase;
52static int VidModeAllowNonLocal;
53
54static DevPrivateKeyRec VidModeClientPrivateKeyRec;
55#define VidModeClientPrivateKey (&VidModeClientPrivateKeyRec)
56
57static DevPrivateKeyRec VidModePrivateKeyRec;
58#define VidModePrivateKey (&VidModePrivateKeyRec)
59
60/* This holds the client's version information */
61typedef 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
77static DisplayModePtr
78VidModeCreateMode(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
93static void
94VidModeCopyMode(DisplayModePtr modefrom, DisplayModePtr modeto)
95{
96    memcpy(modeto, modefrom, sizeof(DisplayModeRec));
97}
98
99static int
100VidModeGetModeValue(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
142static void
143VidModeSetModeValue(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
183static int
184ClientMajorVersion(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
195static int
196ProcVidModeQueryVersion(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
220static int
221ProcVidModeGetModeLine(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
326static int
327ProcVidModeGetAllModeLines(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
440static int
441ProcVidModeAddModeLine(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    if (ver < 2) {
458        /* convert from old format */
459        stuff = &newstuff;
460        stuff->length = oldstuff->length;
461        stuff->screen = oldstuff->screen;
462        stuff->dotclock = oldstuff->dotclock;
463        stuff->hdisplay = oldstuff->hdisplay;
464        stuff->hsyncstart = oldstuff->hsyncstart;
465        stuff->hsyncend = oldstuff->hsyncend;
466        stuff->htotal = oldstuff->htotal;
467        stuff->hskew = 0;
468        stuff->vdisplay = oldstuff->vdisplay;
469        stuff->vsyncstart = oldstuff->vsyncstart;
470        stuff->vsyncend = oldstuff->vsyncend;
471        stuff->vtotal = oldstuff->vtotal;
472        stuff->flags = oldstuff->flags;
473        stuff->privsize = oldstuff->privsize;
474        stuff->after_dotclock = oldstuff->after_dotclock;
475        stuff->after_hdisplay = oldstuff->after_hdisplay;
476        stuff->after_hsyncstart = oldstuff->after_hsyncstart;
477        stuff->after_hsyncend = oldstuff->after_hsyncend;
478        stuff->after_htotal = oldstuff->after_htotal;
479        stuff->after_hskew = 0;
480        stuff->after_vdisplay = oldstuff->after_vdisplay;
481        stuff->after_vsyncstart = oldstuff->after_vsyncstart;
482        stuff->after_vsyncend = oldstuff->after_vsyncend;
483        stuff->after_vtotal = oldstuff->after_vtotal;
484        stuff->after_flags = oldstuff->after_flags;
485    }
486    DebugF("AddModeLine - scrn: %d clock: %ld\n",
487           (int) stuff->screen, (unsigned long) stuff->dotclock);
488    DebugF("AddModeLine - hdsp: %d hbeg: %d hend: %d httl: %d\n",
489           stuff->hdisplay, stuff->hsyncstart,
490           stuff->hsyncend, stuff->htotal);
491    DebugF("              vdsp: %d vbeg: %d vend: %d vttl: %d flags: %ld\n",
492           stuff->vdisplay, stuff->vsyncstart, stuff->vsyncend,
493           stuff->vtotal, (unsigned long) stuff->flags);
494    DebugF("      after - scrn: %d clock: %ld\n",
495           (int) stuff->screen, (unsigned long) stuff->after_dotclock);
496    DebugF("              hdsp: %d hbeg: %d hend: %d httl: %d\n",
497           stuff->after_hdisplay, stuff->after_hsyncstart,
498           stuff->after_hsyncend, stuff->after_htotal);
499    DebugF("              vdsp: %d vbeg: %d vend: %d vttl: %d flags: %ld\n",
500           stuff->after_vdisplay, stuff->after_vsyncstart,
501           stuff->after_vsyncend, stuff->after_vtotal,
502           (unsigned long) stuff->after_flags);
503
504    if (ver < 2) {
505        REQUEST_AT_LEAST_SIZE(xXF86OldVidModeAddModeLineReq);
506        len =
507            client->req_len -
508            bytes_to_int32(sizeof(xXF86OldVidModeAddModeLineReq));
509    }
510    else {
511        REQUEST_AT_LEAST_SIZE(xXF86VidModeAddModeLineReq);
512        len =
513            client->req_len -
514            bytes_to_int32(sizeof(xXF86VidModeAddModeLineReq));
515    }
516    if (len != stuff->privsize)
517        return BadLength;
518
519    if (stuff->screen >= screenInfo.numScreens)
520        return BadValue;
521    pScreen = screenInfo.screens[stuff->screen];
522
523    if (stuff->hsyncstart < stuff->hdisplay ||
524        stuff->hsyncend < stuff->hsyncstart ||
525        stuff->htotal < stuff->hsyncend ||
526        stuff->vsyncstart < stuff->vdisplay ||
527        stuff->vsyncend < stuff->vsyncstart || stuff->vtotal < stuff->vsyncend)
528        return BadValue;
529
530    if (stuff->after_hsyncstart < stuff->after_hdisplay ||
531        stuff->after_hsyncend < stuff->after_hsyncstart ||
532        stuff->after_htotal < stuff->after_hsyncend ||
533        stuff->after_vsyncstart < stuff->after_vdisplay ||
534        stuff->after_vsyncend < stuff->after_vsyncstart ||
535        stuff->after_vtotal < stuff->after_vsyncend)
536        return BadValue;
537
538    pVidMode = VidModeGetPtr(pScreen);
539    if (pVidMode == NULL)
540        return BadImplementation;
541
542    if (stuff->after_htotal != 0 || stuff->after_vtotal != 0) {
543        Bool found = FALSE;
544
545        if (pVidMode->GetFirstModeline(pScreen, &mode, &dotClock)) {
546            do {
547                if ((pVidMode->GetDotClock(pScreen, stuff->dotclock)
548                     == dotClock) && MODEMATCH(mode, stuff)) {
549                    found = TRUE;
550                    break;
551                }
552            } while (pVidMode->GetNextModeline(pScreen, &mode, &dotClock));
553        }
554        if (!found)
555            return BadValue;
556    }
557
558    mode = VidModeCreateMode();
559    if (mode == NULL)
560        return BadValue;
561
562    VidModeSetModeValue(mode, VIDMODE_CLOCK, stuff->dotclock);
563    VidModeSetModeValue(mode, VIDMODE_H_DISPLAY, stuff->hdisplay);
564    VidModeSetModeValue(mode, VIDMODE_H_SYNCSTART, stuff->hsyncstart);
565    VidModeSetModeValue(mode, VIDMODE_H_SYNCEND, stuff->hsyncend);
566    VidModeSetModeValue(mode, VIDMODE_H_TOTAL, stuff->htotal);
567    VidModeSetModeValue(mode, VIDMODE_H_SKEW, stuff->hskew);
568    VidModeSetModeValue(mode, VIDMODE_V_DISPLAY, stuff->vdisplay);
569    VidModeSetModeValue(mode, VIDMODE_V_SYNCSTART, stuff->vsyncstart);
570    VidModeSetModeValue(mode, VIDMODE_V_SYNCEND, stuff->vsyncend);
571    VidModeSetModeValue(mode, VIDMODE_V_TOTAL, stuff->vtotal);
572    VidModeSetModeValue(mode, VIDMODE_FLAGS, stuff->flags);
573
574    if (stuff->privsize)
575        DebugF("AddModeLine - Privates in request have been ignored\n");
576
577    /* Check that the mode is consistent with the monitor specs */
578    switch (pVidMode->CheckModeForMonitor(pScreen, mode)) {
579    case MODE_OK:
580        break;
581    case MODE_HSYNC:
582    case MODE_H_ILLEGAL:
583        free(mode);
584        return VidModeErrorBase + XF86VidModeBadHTimings;
585    case MODE_VSYNC:
586    case MODE_V_ILLEGAL:
587        free(mode);
588        return VidModeErrorBase + XF86VidModeBadVTimings;
589    default:
590        free(mode);
591        return VidModeErrorBase + XF86VidModeModeUnsuitable;
592    }
593
594    /* Check that the driver is happy with the mode */
595    if (pVidMode->CheckModeForDriver(pScreen, mode) != MODE_OK) {
596        free(mode);
597        return VidModeErrorBase + XF86VidModeModeUnsuitable;
598    }
599
600    pVidMode->SetCrtcForMode(pScreen, mode);
601
602    pVidMode->AddModeline(pScreen, mode);
603
604    DebugF("AddModeLine - Succeeded\n");
605
606    return Success;
607}
608
609static int
610ProcVidModeDeleteModeLine(ClientPtr client)
611{
612    REQUEST(xXF86VidModeDeleteModeLineReq);
613    xXF86OldVidModeDeleteModeLineReq *oldstuff =
614        (xXF86OldVidModeDeleteModeLineReq *) client->requestBuffer;
615    xXF86VidModeDeleteModeLineReq newstuff;
616    ScreenPtr pScreen;
617    VidModePtr pVidMode;
618    DisplayModePtr mode;
619    int len, dotClock;
620    int ver;
621
622    DEBUG_P("XF86VidModeDeleteModeline");
623
624    ver = ClientMajorVersion(client);
625    if (ver < 2) {
626        /* convert from old format */
627        stuff = &newstuff;
628        stuff->length = oldstuff->length;
629        stuff->screen = oldstuff->screen;
630        stuff->dotclock = oldstuff->dotclock;
631        stuff->hdisplay = oldstuff->hdisplay;
632        stuff->hsyncstart = oldstuff->hsyncstart;
633        stuff->hsyncend = oldstuff->hsyncend;
634        stuff->htotal = oldstuff->htotal;
635        stuff->hskew = 0;
636        stuff->vdisplay = oldstuff->vdisplay;
637        stuff->vsyncstart = oldstuff->vsyncstart;
638        stuff->vsyncend = oldstuff->vsyncend;
639        stuff->vtotal = oldstuff->vtotal;
640        stuff->flags = oldstuff->flags;
641        stuff->privsize = oldstuff->privsize;
642    }
643    DebugF("DeleteModeLine - scrn: %d clock: %ld\n",
644           (int) stuff->screen, (unsigned long) stuff->dotclock);
645    DebugF("                 hdsp: %d hbeg: %d hend: %d httl: %d\n",
646           stuff->hdisplay, stuff->hsyncstart,
647           stuff->hsyncend, stuff->htotal);
648    DebugF("                 vdsp: %d vbeg: %d vend: %d vttl: %d flags: %ld\n",
649           stuff->vdisplay, stuff->vsyncstart, stuff->vsyncend, stuff->vtotal,
650           (unsigned long) stuff->flags);
651
652    if (ver < 2) {
653        REQUEST_AT_LEAST_SIZE(xXF86OldVidModeDeleteModeLineReq);
654        len =
655            client->req_len -
656            bytes_to_int32(sizeof(xXF86OldVidModeDeleteModeLineReq));
657    }
658    else {
659        REQUEST_AT_LEAST_SIZE(xXF86VidModeDeleteModeLineReq);
660        len =
661            client->req_len -
662            bytes_to_int32(sizeof(xXF86VidModeDeleteModeLineReq));
663    }
664    if (len != stuff->privsize) {
665        DebugF("req_len = %ld, sizeof(Req) = %d, privsize = %ld, "
666               "len = %d, length = %d\n",
667               (unsigned long) client->req_len,
668               (int) sizeof(xXF86VidModeDeleteModeLineReq) >> 2,
669               (unsigned long) stuff->privsize, len, stuff->length);
670        return BadLength;
671    }
672
673    if (stuff->screen >= screenInfo.numScreens)
674        return BadValue;
675    pScreen = screenInfo.screens[stuff->screen];
676
677    pVidMode = VidModeGetPtr(pScreen);
678    if (pVidMode == NULL)
679        return BadImplementation;
680
681    if (!pVidMode->GetCurrentModeline(pScreen, &mode, &dotClock))
682        return BadValue;
683
684    DebugF("Checking against clock: %d (%d)\n",
685           VidModeGetModeValue(mode, VIDMODE_CLOCK), dotClock);
686    DebugF("                 hdsp: %d hbeg: %d hend: %d httl: %d\n",
687           VidModeGetModeValue(mode, VIDMODE_H_DISPLAY),
688           VidModeGetModeValue(mode, VIDMODE_H_SYNCSTART),
689           VidModeGetModeValue(mode, VIDMODE_H_SYNCEND),
690           VidModeGetModeValue(mode, VIDMODE_H_TOTAL));
691    DebugF("                 vdsp: %d vbeg: %d vend: %d vttl: %d flags: %d\n",
692           VidModeGetModeValue(mode, VIDMODE_V_DISPLAY),
693           VidModeGetModeValue(mode, VIDMODE_V_SYNCSTART),
694           VidModeGetModeValue(mode, VIDMODE_V_SYNCEND),
695           VidModeGetModeValue(mode, VIDMODE_V_TOTAL),
696           VidModeGetModeValue(mode, VIDMODE_FLAGS));
697
698    if ((pVidMode->GetDotClock(pScreen, stuff->dotclock) == dotClock) &&
699        MODEMATCH(mode, stuff))
700        return BadValue;
701
702    if (!pVidMode->GetFirstModeline(pScreen, &mode, &dotClock))
703        return BadValue;
704
705    do {
706        DebugF("Checking against clock: %d (%d)\n",
707               VidModeGetModeValue(mode, VIDMODE_CLOCK), dotClock);
708        DebugF("                 hdsp: %d hbeg: %d hend: %d httl: %d\n",
709               VidModeGetModeValue(mode, VIDMODE_H_DISPLAY),
710               VidModeGetModeValue(mode, VIDMODE_H_SYNCSTART),
711               VidModeGetModeValue(mode, VIDMODE_H_SYNCEND),
712               VidModeGetModeValue(mode, VIDMODE_H_TOTAL));
713        DebugF("                 vdsp: %d vbeg: %d vend: %d vttl: %d flags: %d\n",
714               VidModeGetModeValue(mode, VIDMODE_V_DISPLAY),
715               VidModeGetModeValue(mode, VIDMODE_V_SYNCSTART),
716               VidModeGetModeValue(mode, VIDMODE_V_SYNCEND),
717               VidModeGetModeValue(mode, VIDMODE_V_TOTAL),
718               VidModeGetModeValue(mode, VIDMODE_FLAGS));
719
720        if ((pVidMode->GetDotClock(pScreen, stuff->dotclock) == dotClock) &&
721            MODEMATCH(mode, stuff)) {
722            pVidMode->DeleteModeline(pScreen, mode);
723            DebugF("DeleteModeLine - Succeeded\n");
724            return Success;
725        }
726    } while (pVidMode->GetNextModeline(pScreen, &mode, &dotClock));
727
728    return BadValue;
729}
730
731static int
732ProcVidModeModModeLine(ClientPtr client)
733{
734    REQUEST(xXF86VidModeModModeLineReq);
735    xXF86OldVidModeModModeLineReq *oldstuff =
736        (xXF86OldVidModeModModeLineReq *) client->requestBuffer;
737    xXF86VidModeModModeLineReq newstuff;
738    ScreenPtr pScreen;
739    VidModePtr pVidMode;
740    DisplayModePtr mode, modetmp;
741    int len, dotClock;
742    int ver;
743
744    DEBUG_P("XF86VidModeModModeline");
745
746    ver = ClientMajorVersion(client);
747    if (ver < 2) {
748        /* convert from old format */
749        stuff = &newstuff;
750        stuff->length = oldstuff->length;
751        stuff->screen = oldstuff->screen;
752        stuff->hdisplay = oldstuff->hdisplay;
753        stuff->hsyncstart = oldstuff->hsyncstart;
754        stuff->hsyncend = oldstuff->hsyncend;
755        stuff->htotal = oldstuff->htotal;
756        stuff->hskew = 0;
757        stuff->vdisplay = oldstuff->vdisplay;
758        stuff->vsyncstart = oldstuff->vsyncstart;
759        stuff->vsyncend = oldstuff->vsyncend;
760        stuff->vtotal = oldstuff->vtotal;
761        stuff->flags = oldstuff->flags;
762        stuff->privsize = oldstuff->privsize;
763    }
764    DebugF("ModModeLine - scrn: %d hdsp: %d hbeg: %d hend: %d httl: %d\n",
765           (int) stuff->screen, stuff->hdisplay, stuff->hsyncstart,
766           stuff->hsyncend, stuff->htotal);
767    DebugF("              vdsp: %d vbeg: %d vend: %d vttl: %d flags: %ld\n",
768           stuff->vdisplay, stuff->vsyncstart, stuff->vsyncend,
769           stuff->vtotal, (unsigned long) stuff->flags);
770
771    if (ver < 2) {
772        REQUEST_AT_LEAST_SIZE(xXF86OldVidModeModModeLineReq);
773        len =
774            client->req_len -
775            bytes_to_int32(sizeof(xXF86OldVidModeModModeLineReq));
776    }
777    else {
778        REQUEST_AT_LEAST_SIZE(xXF86VidModeModModeLineReq);
779        len =
780            client->req_len -
781            bytes_to_int32(sizeof(xXF86VidModeModModeLineReq));
782    }
783    if (len != stuff->privsize)
784        return BadLength;
785
786    if (stuff->hsyncstart < stuff->hdisplay ||
787        stuff->hsyncend < stuff->hsyncstart ||
788        stuff->htotal < stuff->hsyncend ||
789        stuff->vsyncstart < stuff->vdisplay ||
790        stuff->vsyncend < stuff->vsyncstart || stuff->vtotal < stuff->vsyncend)
791        return BadValue;
792
793    if (stuff->screen >= screenInfo.numScreens)
794        return BadValue;
795    pScreen = screenInfo.screens[stuff->screen];
796
797    pVidMode = VidModeGetPtr(pScreen);
798    if (pVidMode == NULL)
799        return BadImplementation;
800
801    if (!pVidMode->GetCurrentModeline(pScreen, &mode, &dotClock))
802        return BadValue;
803
804    modetmp = VidModeCreateMode();
805    VidModeCopyMode(mode, modetmp);
806
807    VidModeSetModeValue(modetmp, VIDMODE_H_DISPLAY, stuff->hdisplay);
808    VidModeSetModeValue(modetmp, VIDMODE_H_SYNCSTART, stuff->hsyncstart);
809    VidModeSetModeValue(modetmp, VIDMODE_H_SYNCEND, stuff->hsyncend);
810    VidModeSetModeValue(modetmp, VIDMODE_H_TOTAL, stuff->htotal);
811    VidModeSetModeValue(modetmp, VIDMODE_H_SKEW, stuff->hskew);
812    VidModeSetModeValue(modetmp, VIDMODE_V_DISPLAY, stuff->vdisplay);
813    VidModeSetModeValue(modetmp, VIDMODE_V_SYNCSTART, stuff->vsyncstart);
814    VidModeSetModeValue(modetmp, VIDMODE_V_SYNCEND, stuff->vsyncend);
815    VidModeSetModeValue(modetmp, VIDMODE_V_TOTAL, stuff->vtotal);
816    VidModeSetModeValue(modetmp, VIDMODE_FLAGS, stuff->flags);
817
818    if (stuff->privsize)
819        DebugF("ModModeLine - Privates in request have been ignored\n");
820
821    /* Check that the mode is consistent with the monitor specs */
822    switch (pVidMode->CheckModeForMonitor(pScreen, modetmp)) {
823    case MODE_OK:
824        break;
825    case MODE_HSYNC:
826    case MODE_H_ILLEGAL:
827        free(modetmp);
828        return VidModeErrorBase + XF86VidModeBadHTimings;
829    case MODE_VSYNC:
830    case MODE_V_ILLEGAL:
831        free(modetmp);
832        return VidModeErrorBase + XF86VidModeBadVTimings;
833    default:
834        free(modetmp);
835        return VidModeErrorBase + XF86VidModeModeUnsuitable;
836    }
837
838    /* Check that the driver is happy with the mode */
839    if (pVidMode->CheckModeForDriver(pScreen, modetmp) != MODE_OK) {
840        free(modetmp);
841        return VidModeErrorBase + XF86VidModeModeUnsuitable;
842    }
843    free(modetmp);
844
845    VidModeSetModeValue(mode, VIDMODE_H_DISPLAY, stuff->hdisplay);
846    VidModeSetModeValue(mode, VIDMODE_H_SYNCSTART, stuff->hsyncstart);
847    VidModeSetModeValue(mode, VIDMODE_H_SYNCEND, stuff->hsyncend);
848    VidModeSetModeValue(mode, VIDMODE_H_TOTAL, stuff->htotal);
849    VidModeSetModeValue(mode, VIDMODE_H_SKEW, stuff->hskew);
850    VidModeSetModeValue(mode, VIDMODE_V_DISPLAY, stuff->vdisplay);
851    VidModeSetModeValue(mode, VIDMODE_V_SYNCSTART, stuff->vsyncstart);
852    VidModeSetModeValue(mode, VIDMODE_V_SYNCEND, stuff->vsyncend);
853    VidModeSetModeValue(mode, VIDMODE_V_TOTAL, stuff->vtotal);
854    VidModeSetModeValue(mode, VIDMODE_FLAGS, stuff->flags);
855
856    pVidMode->SetCrtcForMode(pScreen, mode);
857    pVidMode->SwitchMode(pScreen, mode);
858
859    DebugF("ModModeLine - Succeeded\n");
860    return Success;
861}
862
863static int
864ProcVidModeValidateModeLine(ClientPtr client)
865{
866    REQUEST(xXF86VidModeValidateModeLineReq);
867    xXF86OldVidModeValidateModeLineReq *oldstuff =
868        (xXF86OldVidModeValidateModeLineReq *) client->requestBuffer;
869    xXF86VidModeValidateModeLineReq newstuff;
870    xXF86VidModeValidateModeLineReply rep;
871    ScreenPtr pScreen;
872    VidModePtr pVidMode;
873    DisplayModePtr mode, modetmp = NULL;
874    int len, status, dotClock;
875    int ver;
876
877    DEBUG_P("XF86VidModeValidateModeline");
878
879    ver = ClientMajorVersion(client);
880    if (ver < 2) {
881        /* convert from old format */
882        stuff = &newstuff;
883        stuff->length = oldstuff->length;
884        stuff->screen = oldstuff->screen;
885        stuff->dotclock = oldstuff->dotclock;
886        stuff->hdisplay = oldstuff->hdisplay;
887        stuff->hsyncstart = oldstuff->hsyncstart;
888        stuff->hsyncend = oldstuff->hsyncend;
889        stuff->htotal = oldstuff->htotal;
890        stuff->hskew = 0;
891        stuff->vdisplay = oldstuff->vdisplay;
892        stuff->vsyncstart = oldstuff->vsyncstart;
893        stuff->vsyncend = oldstuff->vsyncend;
894        stuff->vtotal = oldstuff->vtotal;
895        stuff->flags = oldstuff->flags;
896        stuff->privsize = oldstuff->privsize;
897    }
898
899    DebugF("ValidateModeLine - scrn: %d clock: %ld\n",
900           (int) stuff->screen, (unsigned long) stuff->dotclock);
901    DebugF("                   hdsp: %d hbeg: %d hend: %d httl: %d\n",
902           stuff->hdisplay, stuff->hsyncstart,
903           stuff->hsyncend, stuff->htotal);
904    DebugF("                   vdsp: %d vbeg: %d vend: %d vttl: %d flags: %ld\n",
905           stuff->vdisplay, stuff->vsyncstart, stuff->vsyncend, stuff->vtotal,
906           (unsigned long) stuff->flags);
907
908    if (ver < 2) {
909        REQUEST_AT_LEAST_SIZE(xXF86OldVidModeValidateModeLineReq);
910        len = client->req_len -
911            bytes_to_int32(sizeof(xXF86OldVidModeValidateModeLineReq));
912    }
913    else {
914        REQUEST_AT_LEAST_SIZE(xXF86VidModeValidateModeLineReq);
915        len =
916            client->req_len -
917            bytes_to_int32(sizeof(xXF86VidModeValidateModeLineReq));
918    }
919    if (len != stuff->privsize)
920        return BadLength;
921
922    if (stuff->screen >= screenInfo.numScreens)
923        return BadValue;
924    pScreen = screenInfo.screens[stuff->screen];
925
926    status = MODE_OK;
927
928    if (stuff->hsyncstart < stuff->hdisplay ||
929        stuff->hsyncend < stuff->hsyncstart ||
930        stuff->htotal < stuff->hsyncend ||
931        stuff->vsyncstart < stuff->vdisplay ||
932        stuff->vsyncend < stuff->vsyncstart ||
933        stuff->vtotal < stuff->vsyncend) {
934        status = MODE_BAD;
935        goto status_reply;
936    }
937
938    pVidMode = VidModeGetPtr(pScreen);
939    if (pVidMode == NULL)
940        return BadImplementation;
941
942    if (!pVidMode->GetCurrentModeline(pScreen, &mode, &dotClock))
943        return BadValue;
944
945    modetmp = VidModeCreateMode();
946    VidModeCopyMode(mode, modetmp);
947
948    VidModeSetModeValue(modetmp, VIDMODE_H_DISPLAY, stuff->hdisplay);
949    VidModeSetModeValue(modetmp, VIDMODE_H_SYNCSTART, stuff->hsyncstart);
950    VidModeSetModeValue(modetmp, VIDMODE_H_SYNCEND, stuff->hsyncend);
951    VidModeSetModeValue(modetmp, VIDMODE_H_TOTAL, stuff->htotal);
952    VidModeSetModeValue(modetmp, VIDMODE_H_SKEW, stuff->hskew);
953    VidModeSetModeValue(modetmp, VIDMODE_V_DISPLAY, stuff->vdisplay);
954    VidModeSetModeValue(modetmp, VIDMODE_V_SYNCSTART, stuff->vsyncstart);
955    VidModeSetModeValue(modetmp, VIDMODE_V_SYNCEND, stuff->vsyncend);
956    VidModeSetModeValue(modetmp, VIDMODE_V_TOTAL, stuff->vtotal);
957    VidModeSetModeValue(modetmp, VIDMODE_FLAGS, stuff->flags);
958    if (stuff->privsize)
959        DebugF("ValidateModeLine - Privates in request have been ignored\n");
960
961    /* Check that the mode is consistent with the monitor specs */
962    if ((status =
963         pVidMode->CheckModeForMonitor(pScreen, modetmp)) != MODE_OK)
964        goto status_reply;
965
966    /* Check that the driver is happy with the mode */
967    status = pVidMode->CheckModeForDriver(pScreen, modetmp);
968
969 status_reply:
970    free(modetmp);
971
972    rep = (xXF86VidModeValidateModeLineReply) {
973        .type = X_Reply,
974        .sequenceNumber = client->sequence,
975        .length = bytes_to_int32(SIZEOF(xXF86VidModeValidateModeLineReply)
976                                 - SIZEOF(xGenericReply)),
977        .status = status
978    };
979    if (client->swapped) {
980        swaps(&rep.sequenceNumber);
981        swapl(&rep.length);
982        swapl(&rep.status);
983    }
984    WriteToClient(client, sizeof(xXF86VidModeValidateModeLineReply), &rep);
985    DebugF("ValidateModeLine - Succeeded (status = %d)\n", status);
986
987    return Success;
988}
989
990static int
991ProcVidModeSwitchMode(ClientPtr client)
992{
993    REQUEST(xXF86VidModeSwitchModeReq);
994    ScreenPtr pScreen;
995    VidModePtr pVidMode;
996
997    DEBUG_P("XF86VidModeSwitchMode");
998
999    REQUEST_SIZE_MATCH(xXF86VidModeSwitchModeReq);
1000
1001    if (stuff->screen >= screenInfo.numScreens)
1002        return BadValue;
1003    pScreen = screenInfo.screens[stuff->screen];
1004
1005    pVidMode = VidModeGetPtr(pScreen);
1006    if (pVidMode == NULL)
1007        return BadImplementation;
1008
1009    pVidMode->ZoomViewport(pScreen, (short) stuff->zoom);
1010
1011    return Success;
1012}
1013
1014static int
1015ProcVidModeSwitchToMode(ClientPtr client)
1016{
1017    REQUEST(xXF86VidModeSwitchToModeReq);
1018    xXF86OldVidModeSwitchToModeReq *oldstuff =
1019        (xXF86OldVidModeSwitchToModeReq *) client->requestBuffer;
1020    xXF86VidModeSwitchToModeReq newstuff;
1021    ScreenPtr pScreen;
1022    VidModePtr pVidMode;
1023    DisplayModePtr mode;
1024    int len, dotClock;
1025    int ver;
1026
1027    DEBUG_P("XF86VidModeSwitchToMode");
1028
1029    ver = ClientMajorVersion(client);
1030    if (ver < 2) {
1031        /* convert from old format */
1032        stuff = &newstuff;
1033        stuff->length = oldstuff->length;
1034        stuff->screen = oldstuff->screen;
1035        stuff->dotclock = oldstuff->dotclock;
1036        stuff->hdisplay = oldstuff->hdisplay;
1037        stuff->hsyncstart = oldstuff->hsyncstart;
1038        stuff->hsyncend = oldstuff->hsyncend;
1039        stuff->htotal = oldstuff->htotal;
1040        stuff->hskew = 0;
1041        stuff->vdisplay = oldstuff->vdisplay;
1042        stuff->vsyncstart = oldstuff->vsyncstart;
1043        stuff->vsyncend = oldstuff->vsyncend;
1044        stuff->vtotal = oldstuff->vtotal;
1045        stuff->flags = oldstuff->flags;
1046        stuff->privsize = oldstuff->privsize;
1047    }
1048
1049    DebugF("SwitchToMode - scrn: %d clock: %ld\n",
1050           (int) stuff->screen, (unsigned long) stuff->dotclock);
1051    DebugF("               hdsp: %d hbeg: %d hend: %d httl: %d\n",
1052           stuff->hdisplay, stuff->hsyncstart,
1053           stuff->hsyncend, stuff->htotal);
1054    DebugF("               vdsp: %d vbeg: %d vend: %d vttl: %d flags: %ld\n",
1055           stuff->vdisplay, stuff->vsyncstart, stuff->vsyncend, stuff->vtotal,
1056           (unsigned long) stuff->flags);
1057
1058    if (ver < 2) {
1059        REQUEST_AT_LEAST_SIZE(xXF86OldVidModeSwitchToModeReq);
1060        len =
1061            client->req_len -
1062            bytes_to_int32(sizeof(xXF86OldVidModeSwitchToModeReq));
1063    }
1064    else {
1065        REQUEST_AT_LEAST_SIZE(xXF86VidModeSwitchToModeReq);
1066        len =
1067            client->req_len -
1068            bytes_to_int32(sizeof(xXF86VidModeSwitchToModeReq));
1069    }
1070    if (len != stuff->privsize)
1071        return BadLength;
1072
1073    if (stuff->screen >= screenInfo.numScreens)
1074        return BadValue;
1075    pScreen = screenInfo.screens[stuff->screen];
1076
1077    pVidMode = VidModeGetPtr(pScreen);
1078    if (pVidMode == NULL)
1079        return BadImplementation;
1080
1081    if (!pVidMode->GetCurrentModeline(pScreen, &mode, &dotClock))
1082        return BadValue;
1083
1084    if ((pVidMode->GetDotClock(pScreen, stuff->dotclock) == dotClock)
1085        && MODEMATCH(mode, stuff))
1086        return Success;
1087
1088    if (!pVidMode->GetFirstModeline(pScreen, &mode, &dotClock))
1089        return BadValue;
1090
1091    do {
1092        DebugF("Checking against clock: %d (%d)\n",
1093               VidModeGetModeValue(mode, VIDMODE_CLOCK), dotClock);
1094        DebugF("                 hdsp: %d hbeg: %d hend: %d httl: %d\n",
1095               VidModeGetModeValue(mode, VIDMODE_H_DISPLAY),
1096               VidModeGetModeValue(mode, VIDMODE_H_SYNCSTART),
1097               VidModeGetModeValue(mode, VIDMODE_H_SYNCEND),
1098               VidModeGetModeValue(mode, VIDMODE_H_TOTAL));
1099        DebugF("                 vdsp: %d vbeg: %d vend: %d vttl: %d flags: %d\n",
1100               VidModeGetModeValue(mode, VIDMODE_V_DISPLAY),
1101               VidModeGetModeValue(mode, VIDMODE_V_SYNCSTART),
1102               VidModeGetModeValue(mode, VIDMODE_V_SYNCEND),
1103               VidModeGetModeValue(mode, VIDMODE_V_TOTAL),
1104               VidModeGetModeValue(mode, VIDMODE_FLAGS));
1105
1106        if ((pVidMode->GetDotClock(pScreen, stuff->dotclock) == dotClock) &&
1107            MODEMATCH(mode, stuff)) {
1108
1109            if (!pVidMode->SwitchMode(pScreen, mode))
1110                return BadValue;
1111
1112            DebugF("SwitchToMode - Succeeded\n");
1113            return Success;
1114        }
1115    } while (pVidMode->GetNextModeline(pScreen, &mode, &dotClock));
1116
1117    return BadValue;
1118}
1119
1120static int
1121ProcVidModeLockModeSwitch(ClientPtr client)
1122{
1123    REQUEST(xXF86VidModeLockModeSwitchReq);
1124    ScreenPtr pScreen;
1125    VidModePtr pVidMode;
1126
1127    REQUEST_SIZE_MATCH(xXF86VidModeLockModeSwitchReq);
1128
1129    DEBUG_P("XF86VidModeLockModeSwitch");
1130
1131    if (stuff->screen >= screenInfo.numScreens)
1132        return BadValue;
1133    pScreen = screenInfo.screens[stuff->screen];
1134
1135    pVidMode = VidModeGetPtr(pScreen);
1136    if (pVidMode == NULL)
1137        return BadImplementation;
1138
1139    if (!pVidMode->LockZoom(pScreen, (short) stuff->lock))
1140        return VidModeErrorBase + XF86VidModeZoomLocked;
1141
1142    return Success;
1143}
1144
1145static int
1146ProcVidModeGetMonitor(ClientPtr client)
1147{
1148    REQUEST(xXF86VidModeGetMonitorReq);
1149    xXF86VidModeGetMonitorReply rep = {
1150        .type = X_Reply,
1151        .sequenceNumber = client->sequence
1152    };
1153    CARD32 *hsyncdata, *vsyncdata;
1154    ScreenPtr pScreen;
1155    VidModePtr pVidMode;
1156    int i, nHsync, nVrefresh;
1157
1158    DEBUG_P("XF86VidModeGetMonitor");
1159
1160    REQUEST_SIZE_MATCH(xXF86VidModeGetMonitorReq);
1161
1162    if (stuff->screen >= screenInfo.numScreens)
1163        return BadValue;
1164    pScreen = screenInfo.screens[stuff->screen];
1165
1166    pVidMode = VidModeGetPtr(pScreen);
1167    if (pVidMode == NULL)
1168        return BadImplementation;
1169
1170    nHsync = pVidMode->GetMonitorValue(pScreen, VIDMODE_MON_NHSYNC, 0).i;
1171    nVrefresh = pVidMode->GetMonitorValue(pScreen, VIDMODE_MON_NVREFRESH, 0).i;
1172
1173    if ((char *) (pVidMode->GetMonitorValue(pScreen, VIDMODE_MON_VENDOR, 0)).ptr)
1174        rep.vendorLength = strlen((char *) (pVidMode->GetMonitorValue(pScreen,
1175                                                                      VIDMODE_MON_VENDOR,
1176                                                                      0)).ptr);
1177    else
1178        rep.vendorLength = 0;
1179    if ((char *) (pVidMode->GetMonitorValue(pScreen, VIDMODE_MON_MODEL, 0)).ptr)
1180        rep.modelLength = strlen((char *) (pVidMode->GetMonitorValue(pScreen,
1181                                                                     VIDMODE_MON_MODEL,
1182                                                                     0)).ptr);
1183    else
1184        rep.modelLength = 0;
1185    rep.length =
1186        bytes_to_int32(SIZEOF(xXF86VidModeGetMonitorReply) -
1187                       SIZEOF(xGenericReply) + (nHsync +
1188                                                nVrefresh) * sizeof(CARD32) +
1189                       pad_to_int32(rep.vendorLength) +
1190                       pad_to_int32(rep.modelLength));
1191    rep.nhsync = nHsync;
1192    rep.nvsync = nVrefresh;
1193    hsyncdata = xallocarray(nHsync, sizeof(CARD32));
1194    if (!hsyncdata) {
1195        return BadAlloc;
1196    }
1197    vsyncdata = xallocarray(nVrefresh, sizeof(CARD32));
1198
1199    if (!vsyncdata) {
1200        free(hsyncdata);
1201        return BadAlloc;
1202    }
1203
1204    for (i = 0; i < nHsync; i++) {
1205        hsyncdata[i] = (unsigned short) (pVidMode->GetMonitorValue(pScreen,
1206                                                                   VIDMODE_MON_HSYNC_LO,
1207                                                                   i)).f |
1208            (unsigned
1209             short) (pVidMode->GetMonitorValue(pScreen, VIDMODE_MON_HSYNC_HI,
1210                                               i)).f << 16;
1211    }
1212    for (i = 0; i < nVrefresh; i++) {
1213        vsyncdata[i] = (unsigned short) (pVidMode->GetMonitorValue(pScreen,
1214                                                                   VIDMODE_MON_VREFRESH_LO,
1215                                                                   i)).f |
1216            (unsigned
1217             short) (pVidMode->GetMonitorValue(pScreen, VIDMODE_MON_VREFRESH_HI,
1218                                               i)).f << 16;
1219    }
1220
1221    if (client->swapped) {
1222        swaps(&rep.sequenceNumber);
1223        swapl(&rep.length);
1224    }
1225    WriteToClient(client, SIZEOF(xXF86VidModeGetMonitorReply), &rep);
1226    client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
1227    WriteSwappedDataToClient(client, nHsync * sizeof(CARD32), hsyncdata);
1228    WriteSwappedDataToClient(client, nVrefresh * sizeof(CARD32), vsyncdata);
1229    if (rep.vendorLength)
1230        WriteToClient(client, rep.vendorLength,
1231                 (pVidMode->GetMonitorValue(pScreen, VIDMODE_MON_VENDOR, 0)).ptr);
1232    if (rep.modelLength)
1233        WriteToClient(client, rep.modelLength,
1234                 (pVidMode->GetMonitorValue(pScreen, VIDMODE_MON_MODEL, 0)).ptr);
1235
1236    free(hsyncdata);
1237    free(vsyncdata);
1238
1239    return Success;
1240}
1241
1242static int
1243ProcVidModeGetViewPort(ClientPtr client)
1244{
1245    REQUEST(xXF86VidModeGetViewPortReq);
1246    xXF86VidModeGetViewPortReply rep;
1247    ScreenPtr pScreen;
1248    VidModePtr pVidMode;
1249    int x, y;
1250
1251    DEBUG_P("XF86VidModeGetViewPort");
1252
1253    REQUEST_SIZE_MATCH(xXF86VidModeGetViewPortReq);
1254
1255    if (stuff->screen >= screenInfo.numScreens)
1256        return BadValue;
1257    pScreen = screenInfo.screens[stuff->screen];
1258
1259    pVidMode = VidModeGetPtr(pScreen);
1260    if (pVidMode == NULL)
1261        return BadImplementation;
1262
1263    pVidMode->GetViewPort(pScreen, &x, &y);
1264
1265    rep = (xXF86VidModeGetViewPortReply) {
1266        .type = X_Reply,
1267        .sequenceNumber = client->sequence,
1268        .length = 0,
1269        .x = x,
1270        .y = y
1271    };
1272
1273    if (client->swapped) {
1274        swaps(&rep.sequenceNumber);
1275        swapl(&rep.length);
1276        swapl(&rep.x);
1277        swapl(&rep.y);
1278    }
1279    WriteToClient(client, SIZEOF(xXF86VidModeGetViewPortReply), &rep);
1280    return Success;
1281}
1282
1283static int
1284ProcVidModeSetViewPort(ClientPtr client)
1285{
1286    REQUEST(xXF86VidModeSetViewPortReq);
1287    ScreenPtr pScreen;
1288    VidModePtr pVidMode;
1289
1290    DEBUG_P("XF86VidModeSetViewPort");
1291
1292    REQUEST_SIZE_MATCH(xXF86VidModeSetViewPortReq);
1293
1294    if (stuff->screen >= screenInfo.numScreens)
1295        return BadValue;
1296    pScreen = screenInfo.screens[stuff->screen];
1297
1298    pVidMode = VidModeGetPtr(pScreen);
1299    if (pVidMode == NULL)
1300        return BadImplementation;
1301
1302    if (!pVidMode->SetViewPort(pScreen, stuff->x, stuff->y))
1303        return BadValue;
1304
1305    return Success;
1306}
1307
1308static int
1309ProcVidModeGetDotClocks(ClientPtr client)
1310{
1311    REQUEST(xXF86VidModeGetDotClocksReq);
1312    xXF86VidModeGetDotClocksReply rep;
1313    ScreenPtr pScreen;
1314    VidModePtr pVidMode;
1315    int n;
1316    int numClocks;
1317    CARD32 dotclock;
1318    int *Clocks = NULL;
1319    Bool ClockProg;
1320
1321    DEBUG_P("XF86VidModeGetDotClocks");
1322
1323    REQUEST_SIZE_MATCH(xXF86VidModeGetDotClocksReq);
1324
1325    if (stuff->screen >= screenInfo.numScreens)
1326        return BadValue;
1327    pScreen = screenInfo.screens[stuff->screen];
1328
1329    pVidMode = VidModeGetPtr(pScreen);
1330    if (pVidMode == NULL)
1331        return BadImplementation;
1332
1333    numClocks = pVidMode->GetNumOfClocks(pScreen, &ClockProg);
1334
1335    rep = (xXF86VidModeGetDotClocksReply) {
1336        .type = X_Reply,
1337        .sequenceNumber = client->sequence,
1338        .length = bytes_to_int32(SIZEOF(xXF86VidModeGetDotClocksReply)
1339                                 - SIZEOF(xGenericReply) + numClocks),
1340        .clocks = numClocks,
1341        .maxclocks = MAXCLOCKS,
1342        .flags = 0
1343    };
1344
1345    if (!ClockProg) {
1346        Clocks = calloc(numClocks, sizeof(int));
1347        if (!Clocks)
1348            return BadValue;
1349        if (!pVidMode->GetClocks(pScreen, Clocks)) {
1350            free(Clocks);
1351            return BadValue;
1352        }
1353    }
1354    if (ClockProg) {
1355        rep.flags |= CLKFLAG_PROGRAMABLE;
1356    }
1357    if (client->swapped) {
1358        swaps(&rep.sequenceNumber);
1359        swapl(&rep.length);
1360        swapl(&rep.clocks);
1361        swapl(&rep.maxclocks);
1362        swapl(&rep.flags);
1363    }
1364    WriteToClient(client, sizeof(xXF86VidModeGetDotClocksReply), &rep);
1365    if (!ClockProg) {
1366        for (n = 0; n < numClocks; n++) {
1367            dotclock = *Clocks++;
1368            if (client->swapped) {
1369                WriteSwappedDataToClient(client, 4, (char *) &dotclock);
1370            }
1371            else {
1372                WriteToClient(client, 4, &dotclock);
1373            }
1374        }
1375    }
1376
1377    free(Clocks);
1378    return Success;
1379}
1380
1381static int
1382ProcVidModeSetGamma(ClientPtr client)
1383{
1384    REQUEST(xXF86VidModeSetGammaReq);
1385    ScreenPtr pScreen;
1386    VidModePtr pVidMode;
1387
1388    DEBUG_P("XF86VidModeSetGamma");
1389
1390    REQUEST_SIZE_MATCH(xXF86VidModeSetGammaReq);
1391
1392    if (stuff->screen >= screenInfo.numScreens)
1393        return BadValue;
1394    pScreen = screenInfo.screens[stuff->screen];
1395
1396    pVidMode = VidModeGetPtr(pScreen);
1397    if (pVidMode == NULL)
1398        return BadImplementation;
1399
1400    if (!pVidMode->SetGamma(pScreen, ((float) stuff->red) / 10000.,
1401                         ((float) stuff->green) / 10000.,
1402                         ((float) stuff->blue) / 10000.))
1403        return BadValue;
1404
1405    return Success;
1406}
1407
1408static int
1409ProcVidModeGetGamma(ClientPtr client)
1410{
1411    REQUEST(xXF86VidModeGetGammaReq);
1412    xXF86VidModeGetGammaReply rep;
1413    ScreenPtr pScreen;
1414    VidModePtr pVidMode;
1415    float red, green, blue;
1416
1417    DEBUG_P("XF86VidModeGetGamma");
1418
1419    REQUEST_SIZE_MATCH(xXF86VidModeGetGammaReq);
1420
1421    if (stuff->screen >= screenInfo.numScreens)
1422        return BadValue;
1423    pScreen = screenInfo.screens[stuff->screen];
1424
1425    pVidMode = VidModeGetPtr(pScreen);
1426    if (pVidMode == NULL)
1427        return BadImplementation;
1428
1429    if (!pVidMode->GetGamma(pScreen, &red, &green, &blue))
1430        return BadValue;
1431    rep = (xXF86VidModeGetGammaReply) {
1432        .type = X_Reply,
1433        .sequenceNumber = client->sequence,
1434        .length = 0,
1435        .red = (CARD32) (red * 10000.),
1436        .green = (CARD32) (green * 10000.),
1437        .blue = (CARD32) (blue * 10000.)
1438    };
1439    if (client->swapped) {
1440        swaps(&rep.sequenceNumber);
1441        swapl(&rep.length);
1442        swapl(&rep.red);
1443        swapl(&rep.green);
1444        swapl(&rep.blue);
1445    }
1446    WriteToClient(client, sizeof(xXF86VidModeGetGammaReply), &rep);
1447
1448    return Success;
1449}
1450
1451static int
1452ProcVidModeSetGammaRamp(ClientPtr client)
1453{
1454    CARD16 *r, *g, *b;
1455    int length;
1456    ScreenPtr pScreen;
1457    VidModePtr pVidMode;
1458
1459    REQUEST(xXF86VidModeSetGammaRampReq);
1460
1461    if (stuff->screen >= screenInfo.numScreens)
1462        return BadValue;
1463    pScreen = screenInfo.screens[stuff->screen];
1464
1465    pVidMode = VidModeGetPtr(pScreen);
1466    if (pVidMode == NULL)
1467        return BadImplementation;
1468
1469    if (stuff->size != pVidMode->GetGammaRampSize(pScreen))
1470        return BadValue;
1471
1472    length = (stuff->size + 1) & ~1;
1473
1474    REQUEST_FIXED_SIZE(xXF86VidModeSetGammaRampReq, length * 6);
1475
1476    r = (CARD16 *) &stuff[1];
1477    g = r + length;
1478    b = g + length;
1479
1480    if (!pVidMode->SetGammaRamp(pScreen, stuff->size, r, g, b))
1481        return BadValue;
1482
1483    return Success;
1484}
1485
1486static int
1487ProcVidModeGetGammaRamp(ClientPtr client)
1488{
1489    CARD16 *ramp = NULL;
1490    int length;
1491    size_t ramplen = 0;
1492    xXF86VidModeGetGammaRampReply rep;
1493    ScreenPtr pScreen;
1494    VidModePtr pVidMode;
1495
1496    REQUEST(xXF86VidModeGetGammaRampReq);
1497
1498    REQUEST_SIZE_MATCH(xXF86VidModeGetGammaRampReq);
1499
1500    if (stuff->screen >= screenInfo.numScreens)
1501        return BadValue;
1502    pScreen = screenInfo.screens[stuff->screen];
1503
1504    pVidMode = VidModeGetPtr(pScreen);
1505    if (pVidMode == NULL)
1506        return BadImplementation;
1507
1508    if (stuff->size != pVidMode->GetGammaRampSize(pScreen))
1509        return BadValue;
1510
1511    length = (stuff->size + 1) & ~1;
1512
1513    if (stuff->size) {
1514        if (!(ramp = xallocarray(length, 3 * sizeof(CARD16))))
1515            return BadAlloc;
1516        ramplen = length * 3 * sizeof(CARD16);
1517
1518        if (!pVidMode->GetGammaRamp(pScreen, stuff->size,
1519                                 ramp, ramp + length, ramp + (length * 2))) {
1520            free(ramp);
1521            return BadValue;
1522        }
1523    }
1524    rep = (xXF86VidModeGetGammaRampReply) {
1525        .type = X_Reply,
1526        .sequenceNumber = client->sequence,
1527        .length = (length >> 1) * 3,
1528        .size = stuff->size
1529    };
1530    if (client->swapped) {
1531        swaps(&rep.sequenceNumber);
1532        swapl(&rep.length);
1533        swaps(&rep.size);
1534        SwapShorts((short *) ramp, length * 3);
1535    }
1536    WriteToClient(client, sizeof(xXF86VidModeGetGammaRampReply), &rep);
1537
1538    if (stuff->size) {
1539        WriteToClient(client, ramplen, ramp);
1540        free(ramp);
1541    }
1542
1543    return Success;
1544}
1545
1546
1547static int
1548ProcVidModeGetGammaRampSize(ClientPtr client)
1549{
1550    xXF86VidModeGetGammaRampSizeReply rep;
1551    ScreenPtr pScreen;
1552    VidModePtr pVidMode;
1553
1554    REQUEST(xXF86VidModeGetGammaRampSizeReq);
1555
1556    REQUEST_SIZE_MATCH(xXF86VidModeGetGammaRampSizeReq);
1557
1558    if (stuff->screen >= screenInfo.numScreens)
1559        return BadValue;
1560    pScreen = screenInfo.screens[stuff->screen];
1561
1562    pVidMode = VidModeGetPtr(pScreen);
1563    if (pVidMode == NULL)
1564        return BadImplementation;
1565
1566    rep = (xXF86VidModeGetGammaRampSizeReply) {
1567        .type = X_Reply,
1568        .sequenceNumber = client->sequence,
1569        .length = 0,
1570        .size = pVidMode->GetGammaRampSize(pScreen)
1571    };
1572    if (client->swapped) {
1573        swaps(&rep.sequenceNumber);
1574        swapl(&rep.length);
1575        swaps(&rep.size);
1576    }
1577    WriteToClient(client, sizeof(xXF86VidModeGetGammaRampSizeReply), &rep);
1578
1579    return Success;
1580}
1581
1582static int
1583ProcVidModeGetPermissions(ClientPtr client)
1584{
1585    xXF86VidModeGetPermissionsReply rep =  {
1586        .type = X_Reply,
1587        .sequenceNumber = client->sequence,
1588        .length = 0,
1589        .permissions = XF86VM_READ_PERMISSION
1590    };
1591
1592    REQUEST(xXF86VidModeGetPermissionsReq);
1593
1594    REQUEST_SIZE_MATCH(xXF86VidModeGetPermissionsReq);
1595
1596    if (stuff->screen >= screenInfo.numScreens)
1597        return BadValue;
1598
1599    if (VidModeAllowNonLocal || client->local) {
1600        rep.permissions |= XF86VM_WRITE_PERMISSION;
1601    }
1602    if (client->swapped) {
1603        swaps(&rep.sequenceNumber);
1604        swapl(&rep.length);
1605        swapl(&rep.permissions);
1606    }
1607    WriteToClient(client, sizeof(xXF86VidModeGetPermissionsReply), &rep);
1608
1609    return Success;
1610}
1611
1612static int
1613ProcVidModeSetClientVersion(ClientPtr client)
1614{
1615    REQUEST(xXF86VidModeSetClientVersionReq);
1616
1617    VidModePrivPtr pPriv;
1618
1619    DEBUG_P("XF86VidModeSetClientVersion");
1620
1621    REQUEST_SIZE_MATCH(xXF86VidModeSetClientVersionReq);
1622
1623    if ((pPriv = VM_GETPRIV(client)) == NULL) {
1624        pPriv = malloc(sizeof(VidModePrivRec));
1625        if (!pPriv)
1626            return BadAlloc;
1627        VM_SETPRIV(client, pPriv);
1628    }
1629    pPriv->major = stuff->major;
1630
1631    pPriv->minor = stuff->minor;
1632
1633    return Success;
1634}
1635
1636static int
1637ProcVidModeDispatch(ClientPtr client)
1638{
1639    REQUEST(xReq);
1640    switch (stuff->data) {
1641    case X_XF86VidModeQueryVersion:
1642        return ProcVidModeQueryVersion(client);
1643    case X_XF86VidModeGetModeLine:
1644        return ProcVidModeGetModeLine(client);
1645    case X_XF86VidModeGetMonitor:
1646        return ProcVidModeGetMonitor(client);
1647    case X_XF86VidModeGetAllModeLines:
1648        return ProcVidModeGetAllModeLines(client);
1649    case X_XF86VidModeValidateModeLine:
1650        return ProcVidModeValidateModeLine(client);
1651    case X_XF86VidModeGetViewPort:
1652        return ProcVidModeGetViewPort(client);
1653    case X_XF86VidModeGetDotClocks:
1654        return ProcVidModeGetDotClocks(client);
1655    case X_XF86VidModeSetClientVersion:
1656        return ProcVidModeSetClientVersion(client);
1657    case X_XF86VidModeGetGamma:
1658        return ProcVidModeGetGamma(client);
1659    case X_XF86VidModeGetGammaRamp:
1660        return ProcVidModeGetGammaRamp(client);
1661    case X_XF86VidModeGetGammaRampSize:
1662        return ProcVidModeGetGammaRampSize(client);
1663    case X_XF86VidModeGetPermissions:
1664        return ProcVidModeGetPermissions(client);
1665    default:
1666        if (VidModeAllowNonLocal || client->local) {
1667            switch (stuff->data) {
1668            case X_XF86VidModeAddModeLine:
1669                return ProcVidModeAddModeLine(client);
1670            case X_XF86VidModeDeleteModeLine:
1671                return ProcVidModeDeleteModeLine(client);
1672            case X_XF86VidModeModModeLine:
1673                return ProcVidModeModModeLine(client);
1674            case X_XF86VidModeSwitchMode:
1675                return ProcVidModeSwitchMode(client);
1676            case X_XF86VidModeSwitchToMode:
1677                return ProcVidModeSwitchToMode(client);
1678            case X_XF86VidModeLockModeSwitch:
1679                return ProcVidModeLockModeSwitch(client);
1680            case X_XF86VidModeSetViewPort:
1681                return ProcVidModeSetViewPort(client);
1682            case X_XF86VidModeSetGamma:
1683                return ProcVidModeSetGamma(client);
1684            case X_XF86VidModeSetGammaRamp:
1685                return ProcVidModeSetGammaRamp(client);
1686            default:
1687                return BadRequest;
1688            }
1689        }
1690        else
1691            return VidModeErrorBase + XF86VidModeClientNotLocal;
1692    }
1693}
1694
1695static int
1696SProcVidModeQueryVersion(ClientPtr client)
1697{
1698    REQUEST(xXF86VidModeQueryVersionReq);
1699    swaps(&stuff->length);
1700    return ProcVidModeQueryVersion(client);
1701}
1702
1703static int
1704SProcVidModeGetModeLine(ClientPtr client)
1705{
1706    REQUEST(xXF86VidModeGetModeLineReq);
1707    swaps(&stuff->length);
1708    REQUEST_SIZE_MATCH(xXF86VidModeGetModeLineReq);
1709    swaps(&stuff->screen);
1710    return ProcVidModeGetModeLine(client);
1711}
1712
1713static int
1714SProcVidModeGetAllModeLines(ClientPtr client)
1715{
1716    REQUEST(xXF86VidModeGetAllModeLinesReq);
1717    swaps(&stuff->length);
1718    REQUEST_SIZE_MATCH(xXF86VidModeGetAllModeLinesReq);
1719    swaps(&stuff->screen);
1720    return ProcVidModeGetAllModeLines(client);
1721}
1722
1723static int
1724SProcVidModeAddModeLine(ClientPtr client)
1725{
1726    xXF86OldVidModeAddModeLineReq *oldstuff =
1727        (xXF86OldVidModeAddModeLineReq *) client->requestBuffer;
1728    int ver;
1729
1730    REQUEST(xXF86VidModeAddModeLineReq);
1731    ver = ClientMajorVersion(client);
1732    if (ver < 2) {
1733        swaps(&oldstuff->length);
1734        REQUEST_AT_LEAST_SIZE(xXF86OldVidModeAddModeLineReq);
1735        swapl(&oldstuff->screen);
1736        swaps(&oldstuff->hdisplay);
1737        swaps(&oldstuff->hsyncstart);
1738        swaps(&oldstuff->hsyncend);
1739        swaps(&oldstuff->htotal);
1740        swaps(&oldstuff->vdisplay);
1741        swaps(&oldstuff->vsyncstart);
1742        swaps(&oldstuff->vsyncend);
1743        swaps(&oldstuff->vtotal);
1744        swapl(&oldstuff->flags);
1745        swapl(&oldstuff->privsize);
1746        SwapRestL(oldstuff);
1747    }
1748    else {
1749        swaps(&stuff->length);
1750        REQUEST_AT_LEAST_SIZE(xXF86VidModeAddModeLineReq);
1751        swapl(&stuff->screen);
1752        swaps(&stuff->hdisplay);
1753        swaps(&stuff->hsyncstart);
1754        swaps(&stuff->hsyncend);
1755        swaps(&stuff->htotal);
1756        swaps(&stuff->hskew);
1757        swaps(&stuff->vdisplay);
1758        swaps(&stuff->vsyncstart);
1759        swaps(&stuff->vsyncend);
1760        swaps(&stuff->vtotal);
1761        swapl(&stuff->flags);
1762        swapl(&stuff->privsize);
1763        SwapRestL(stuff);
1764    }
1765    return ProcVidModeAddModeLine(client);
1766}
1767
1768static int
1769SProcVidModeDeleteModeLine(ClientPtr client)
1770{
1771    xXF86OldVidModeDeleteModeLineReq *oldstuff =
1772        (xXF86OldVidModeDeleteModeLineReq *) client->requestBuffer;
1773    int ver;
1774
1775    REQUEST(xXF86VidModeDeleteModeLineReq);
1776    ver = ClientMajorVersion(client);
1777    if (ver < 2) {
1778        swaps(&oldstuff->length);
1779        REQUEST_AT_LEAST_SIZE(xXF86OldVidModeDeleteModeLineReq);
1780        swapl(&oldstuff->screen);
1781        swaps(&oldstuff->hdisplay);
1782        swaps(&oldstuff->hsyncstart);
1783        swaps(&oldstuff->hsyncend);
1784        swaps(&oldstuff->htotal);
1785        swaps(&oldstuff->vdisplay);
1786        swaps(&oldstuff->vsyncstart);
1787        swaps(&oldstuff->vsyncend);
1788        swaps(&oldstuff->vtotal);
1789        swapl(&oldstuff->flags);
1790        swapl(&oldstuff->privsize);
1791        SwapRestL(oldstuff);
1792    }
1793    else {
1794        swaps(&stuff->length);
1795        REQUEST_AT_LEAST_SIZE(xXF86VidModeDeleteModeLineReq);
1796        swapl(&stuff->screen);
1797        swaps(&stuff->hdisplay);
1798        swaps(&stuff->hsyncstart);
1799        swaps(&stuff->hsyncend);
1800        swaps(&stuff->htotal);
1801        swaps(&stuff->hskew);
1802        swaps(&stuff->vdisplay);
1803        swaps(&stuff->vsyncstart);
1804        swaps(&stuff->vsyncend);
1805        swaps(&stuff->vtotal);
1806        swapl(&stuff->flags);
1807        swapl(&stuff->privsize);
1808        SwapRestL(stuff);
1809    }
1810    return ProcVidModeDeleteModeLine(client);
1811}
1812
1813static int
1814SProcVidModeModModeLine(ClientPtr client)
1815{
1816    xXF86OldVidModeModModeLineReq *oldstuff =
1817        (xXF86OldVidModeModModeLineReq *) client->requestBuffer;
1818    int ver;
1819
1820    REQUEST(xXF86VidModeModModeLineReq);
1821    ver = ClientMajorVersion(client);
1822    if (ver < 2) {
1823        swaps(&oldstuff->length);
1824        REQUEST_AT_LEAST_SIZE(xXF86OldVidModeModModeLineReq);
1825        swapl(&oldstuff->screen);
1826        swaps(&oldstuff->hdisplay);
1827        swaps(&oldstuff->hsyncstart);
1828        swaps(&oldstuff->hsyncend);
1829        swaps(&oldstuff->htotal);
1830        swaps(&oldstuff->vdisplay);
1831        swaps(&oldstuff->vsyncstart);
1832        swaps(&oldstuff->vsyncend);
1833        swaps(&oldstuff->vtotal);
1834        swapl(&oldstuff->flags);
1835        swapl(&oldstuff->privsize);
1836        SwapRestL(oldstuff);
1837    }
1838    else {
1839        swaps(&stuff->length);
1840        REQUEST_AT_LEAST_SIZE(xXF86VidModeModModeLineReq);
1841        swapl(&stuff->screen);
1842        swaps(&stuff->hdisplay);
1843        swaps(&stuff->hsyncstart);
1844        swaps(&stuff->hsyncend);
1845        swaps(&stuff->htotal);
1846        swaps(&stuff->hskew);
1847        swaps(&stuff->vdisplay);
1848        swaps(&stuff->vsyncstart);
1849        swaps(&stuff->vsyncend);
1850        swaps(&stuff->vtotal);
1851        swapl(&stuff->flags);
1852        swapl(&stuff->privsize);
1853        SwapRestL(stuff);
1854    }
1855    return ProcVidModeModModeLine(client);
1856}
1857
1858static int
1859SProcVidModeValidateModeLine(ClientPtr client)
1860{
1861    xXF86OldVidModeValidateModeLineReq *oldstuff =
1862        (xXF86OldVidModeValidateModeLineReq *) client->requestBuffer;
1863    int ver;
1864
1865    REQUEST(xXF86VidModeValidateModeLineReq);
1866    ver = ClientMajorVersion(client);
1867    if (ver < 2) {
1868        swaps(&oldstuff->length);
1869        REQUEST_AT_LEAST_SIZE(xXF86OldVidModeValidateModeLineReq);
1870        swapl(&oldstuff->screen);
1871        swaps(&oldstuff->hdisplay);
1872        swaps(&oldstuff->hsyncstart);
1873        swaps(&oldstuff->hsyncend);
1874        swaps(&oldstuff->htotal);
1875        swaps(&oldstuff->vdisplay);
1876        swaps(&oldstuff->vsyncstart);
1877        swaps(&oldstuff->vsyncend);
1878        swaps(&oldstuff->vtotal);
1879        swapl(&oldstuff->flags);
1880        swapl(&oldstuff->privsize);
1881        SwapRestL(oldstuff);
1882    }
1883    else {
1884        swaps(&stuff->length);
1885        REQUEST_AT_LEAST_SIZE(xXF86VidModeValidateModeLineReq);
1886        swapl(&stuff->screen);
1887        swaps(&stuff->hdisplay);
1888        swaps(&stuff->hsyncstart);
1889        swaps(&stuff->hsyncend);
1890        swaps(&stuff->htotal);
1891        swaps(&stuff->hskew);
1892        swaps(&stuff->vdisplay);
1893        swaps(&stuff->vsyncstart);
1894        swaps(&stuff->vsyncend);
1895        swaps(&stuff->vtotal);
1896        swapl(&stuff->flags);
1897        swapl(&stuff->privsize);
1898        SwapRestL(stuff);
1899    }
1900    return ProcVidModeValidateModeLine(client);
1901}
1902
1903static int
1904SProcVidModeSwitchMode(ClientPtr client)
1905{
1906    REQUEST(xXF86VidModeSwitchModeReq);
1907    swaps(&stuff->length);
1908    REQUEST_SIZE_MATCH(xXF86VidModeSwitchModeReq);
1909    swaps(&stuff->screen);
1910    swaps(&stuff->zoom);
1911    return ProcVidModeSwitchMode(client);
1912}
1913
1914static int
1915SProcVidModeSwitchToMode(ClientPtr client)
1916{
1917    REQUEST(xXF86VidModeSwitchToModeReq);
1918    swaps(&stuff->length);
1919    REQUEST_SIZE_MATCH(xXF86VidModeSwitchToModeReq);
1920    swapl(&stuff->screen);
1921    return ProcVidModeSwitchToMode(client);
1922}
1923
1924static int
1925SProcVidModeLockModeSwitch(ClientPtr client)
1926{
1927    REQUEST(xXF86VidModeLockModeSwitchReq);
1928    swaps(&stuff->length);
1929    REQUEST_SIZE_MATCH(xXF86VidModeLockModeSwitchReq);
1930    swaps(&stuff->screen);
1931    swaps(&stuff->lock);
1932    return ProcVidModeLockModeSwitch(client);
1933}
1934
1935static int
1936SProcVidModeGetMonitor(ClientPtr client)
1937{
1938    REQUEST(xXF86VidModeGetMonitorReq);
1939    swaps(&stuff->length);
1940    REQUEST_SIZE_MATCH(xXF86VidModeGetMonitorReq);
1941    swaps(&stuff->screen);
1942    return ProcVidModeGetMonitor(client);
1943}
1944
1945static int
1946SProcVidModeGetViewPort(ClientPtr client)
1947{
1948    REQUEST(xXF86VidModeGetViewPortReq);
1949    swaps(&stuff->length);
1950    REQUEST_SIZE_MATCH(xXF86VidModeGetViewPortReq);
1951    swaps(&stuff->screen);
1952    return ProcVidModeGetViewPort(client);
1953}
1954
1955static int
1956SProcVidModeSetViewPort(ClientPtr client)
1957{
1958    REQUEST(xXF86VidModeSetViewPortReq);
1959    swaps(&stuff->length);
1960    REQUEST_SIZE_MATCH(xXF86VidModeSetViewPortReq);
1961    swaps(&stuff->screen);
1962    swapl(&stuff->x);
1963    swapl(&stuff->y);
1964    return ProcVidModeSetViewPort(client);
1965}
1966
1967static int
1968SProcVidModeGetDotClocks(ClientPtr client)
1969{
1970    REQUEST(xXF86VidModeGetDotClocksReq);
1971    swaps(&stuff->length);
1972    REQUEST_SIZE_MATCH(xXF86VidModeGetDotClocksReq);
1973    swaps(&stuff->screen);
1974    return ProcVidModeGetDotClocks(client);
1975}
1976
1977static int
1978SProcVidModeSetClientVersion(ClientPtr client)
1979{
1980    REQUEST(xXF86VidModeSetClientVersionReq);
1981    swaps(&stuff->length);
1982    REQUEST_SIZE_MATCH(xXF86VidModeSetClientVersionReq);
1983    swaps(&stuff->major);
1984    swaps(&stuff->minor);
1985    return ProcVidModeSetClientVersion(client);
1986}
1987
1988static int
1989SProcVidModeSetGamma(ClientPtr client)
1990{
1991    REQUEST(xXF86VidModeSetGammaReq);
1992    swaps(&stuff->length);
1993    REQUEST_SIZE_MATCH(xXF86VidModeSetGammaReq);
1994    swaps(&stuff->screen);
1995    swapl(&stuff->red);
1996    swapl(&stuff->green);
1997    swapl(&stuff->blue);
1998    return ProcVidModeSetGamma(client);
1999}
2000
2001static int
2002SProcVidModeGetGamma(ClientPtr client)
2003{
2004    REQUEST(xXF86VidModeGetGammaReq);
2005    swaps(&stuff->length);
2006    REQUEST_SIZE_MATCH(xXF86VidModeGetGammaReq);
2007    swaps(&stuff->screen);
2008    return ProcVidModeGetGamma(client);
2009}
2010
2011static int
2012SProcVidModeSetGammaRamp(ClientPtr client)
2013{
2014    int length;
2015
2016    REQUEST(xXF86VidModeSetGammaRampReq);
2017    swaps(&stuff->length);
2018    REQUEST_AT_LEAST_SIZE(xXF86VidModeSetGammaRampReq);
2019    swaps(&stuff->size);
2020    swaps(&stuff->screen);
2021    length = ((stuff->size + 1) & ~1) * 6;
2022    REQUEST_FIXED_SIZE(xXF86VidModeSetGammaRampReq, length);
2023    SwapRestS(stuff);
2024    return ProcVidModeSetGammaRamp(client);
2025}
2026
2027static int
2028SProcVidModeGetGammaRamp(ClientPtr client)
2029{
2030    REQUEST(xXF86VidModeGetGammaRampReq);
2031    swaps(&stuff->length);
2032    REQUEST_SIZE_MATCH(xXF86VidModeGetGammaRampReq);
2033    swaps(&stuff->size);
2034    swaps(&stuff->screen);
2035    return ProcVidModeGetGammaRamp(client);
2036}
2037
2038static int
2039SProcVidModeGetGammaRampSize(ClientPtr client)
2040{
2041    REQUEST(xXF86VidModeGetGammaRampSizeReq);
2042    swaps(&stuff->length);
2043    REQUEST_SIZE_MATCH(xXF86VidModeGetGammaRampSizeReq);
2044    swaps(&stuff->screen);
2045    return ProcVidModeGetGammaRampSize(client);
2046}
2047
2048static int
2049SProcVidModeGetPermissions(ClientPtr client)
2050{
2051    REQUEST(xXF86VidModeGetPermissionsReq);
2052    swaps(&stuff->length);
2053    REQUEST_SIZE_MATCH(xXF86VidModeGetPermissionsReq);
2054    swaps(&stuff->screen);
2055    return ProcVidModeGetPermissions(client);
2056}
2057
2058static int
2059SProcVidModeDispatch(ClientPtr client)
2060{
2061    REQUEST(xReq);
2062    switch (stuff->data) {
2063    case X_XF86VidModeQueryVersion:
2064        return SProcVidModeQueryVersion(client);
2065    case X_XF86VidModeGetModeLine:
2066        return SProcVidModeGetModeLine(client);
2067    case X_XF86VidModeGetMonitor:
2068        return SProcVidModeGetMonitor(client);
2069    case X_XF86VidModeGetAllModeLines:
2070        return SProcVidModeGetAllModeLines(client);
2071    case X_XF86VidModeGetViewPort:
2072        return SProcVidModeGetViewPort(client);
2073    case X_XF86VidModeValidateModeLine:
2074        return SProcVidModeValidateModeLine(client);
2075    case X_XF86VidModeGetDotClocks:
2076        return SProcVidModeGetDotClocks(client);
2077    case X_XF86VidModeSetClientVersion:
2078        return SProcVidModeSetClientVersion(client);
2079    case X_XF86VidModeGetGamma:
2080        return SProcVidModeGetGamma(client);
2081    case X_XF86VidModeGetGammaRamp:
2082        return SProcVidModeGetGammaRamp(client);
2083    case X_XF86VidModeGetGammaRampSize:
2084        return SProcVidModeGetGammaRampSize(client);
2085    case X_XF86VidModeGetPermissions:
2086        return SProcVidModeGetPermissions(client);
2087    default:
2088        if (VidModeAllowNonLocal || client->local) {
2089            switch (stuff->data) {
2090            case X_XF86VidModeAddModeLine:
2091                return SProcVidModeAddModeLine(client);
2092            case X_XF86VidModeDeleteModeLine:
2093                return SProcVidModeDeleteModeLine(client);
2094            case X_XF86VidModeModModeLine:
2095                return SProcVidModeModModeLine(client);
2096            case X_XF86VidModeSwitchMode:
2097                return SProcVidModeSwitchMode(client);
2098            case X_XF86VidModeSwitchToMode:
2099                return SProcVidModeSwitchToMode(client);
2100            case X_XF86VidModeLockModeSwitch:
2101                return SProcVidModeLockModeSwitch(client);
2102            case X_XF86VidModeSetViewPort:
2103                return SProcVidModeSetViewPort(client);
2104            case X_XF86VidModeSetGamma:
2105                return SProcVidModeSetGamma(client);
2106            case X_XF86VidModeSetGammaRamp:
2107                return SProcVidModeSetGammaRamp(client);
2108            default:
2109                return BadRequest;
2110            }
2111        }
2112        else
2113            return VidModeErrorBase + XF86VidModeClientNotLocal;
2114    }
2115}
2116
2117void
2118VidModeAddExtension(Bool allow_non_local)
2119{
2120    ExtensionEntry *extEntry;
2121
2122    DEBUG_P("VidModeAddExtension");
2123
2124    if (!dixRegisterPrivateKey(VidModeClientPrivateKey, PRIVATE_CLIENT, 0))
2125        return;
2126
2127    if ((extEntry = AddExtension(XF86VIDMODENAME,
2128                                 XF86VidModeNumberEvents,
2129                                 XF86VidModeNumberErrors,
2130                                 ProcVidModeDispatch,
2131                                 SProcVidModeDispatch,
2132                                 NULL, StandardMinorOpcode))) {
2133        VidModeErrorBase = extEntry->errorBase;
2134        VidModeAllowNonLocal = allow_non_local;
2135    }
2136}
2137
2138VidModePtr VidModeGetPtr(ScreenPtr pScreen)
2139{
2140    return (VidModePtr) (dixLookupPrivate(&pScreen->devPrivates, VidModePrivateKey));
2141}
2142
2143VidModePtr VidModeInit(ScreenPtr pScreen)
2144{
2145    if (!dixRegisterPrivateKey(VidModePrivateKey, PRIVATE_SCREEN, sizeof(VidModeRec)))
2146        return NULL;
2147
2148    return VidModeGetPtr(pScreen);
2149}
2150
2151#endif /* XF86VIDMODE */
2152