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