]> git.sesse.net Git - rdpsrv/blob - Xserver/programs/Xserver/Xext/xf86vmode.c
Support RDP5 logon packets.
[rdpsrv] / Xserver / programs / Xserver / Xext / xf86vmode.c
1 /* $XFree86: xc/programs/Xserver/Xext/xf86vmode.c,v 3.30.2.3 1997/06/11 12:08:44 dawes Exp $ */
2
3 /*
4
5 Copyright (c) 1995  Kaleb S. KEITHLEY
6
7 Permission is hereby granted, free of charge, to any person obtaining
8 a copy of this software and associated documentation files (the
9 "Software"), to deal in the Software without restriction, including
10 without limitation the rights to use, copy, modify, merge, publish,
11 distribute, sublicense, and/or sell copies of the Software, and to
12 permit persons to whom the Software is furnished to do so, subject to
13 the following conditions:
14
15 The above copyright notice and this permission notice shall be
16 included in all copies or substantial portions of the Software.
17
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21 IN NO EVENT SHALL Kaleb S. KEITHLEY BE LIABLE FOR ANY CLAIM, DAMAGES 
22 OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24 OTHER DEALINGS IN THE SOFTWARE.
25
26 Except as contained in this notice, the name of Kaleb S. KEITHLEY 
27 shall not be used in advertising or otherwise to promote the sale, use 
28 or other dealings in this Software without prior written authorization
29 from Kaleb S. KEITHLEY
30
31 */
32 /* $XConsortium: xf86vmode.c /main/24 1996/10/26 21:56:29 kaleb $ */
33 /* THIS IS NOT AN X CONSORTIUM STANDARD */
34
35 #define NEED_REPLIES
36 #define NEED_EVENTS
37 #include "X.h"
38 #include "Xproto.h"
39 #include "misc.h"
40 #include "dixstruct.h"
41 #include "extnsionst.h"
42 #include "scrnintstr.h"
43 #include "servermd.h"
44 #define _XF86VIDMODE_SERVER_
45 #include "xf86vmstr.h"
46 #include "Xfuncproto.h"
47 #include "../hw/xfree86/common/xf86.h"
48 #include "../hw/xfree86/common/xf86Priv.h"
49
50 #include <X11/Xtrans.h>
51 #include "../os/osdep.h"
52 #include <X11/Xauth.h>
53 #ifndef ESIX
54 #ifndef Lynx
55 #include <sys/socket.h>
56 #else
57 #include <socket.h>
58 #endif
59 #else
60 #include <lan/socket.h>
61 #endif
62
63 #include "swaprep.h"
64
65 extern int xf86ScreenIndex;
66 extern Bool xf86VidModeEnabled;
67 extern Bool xf86VidModeAllowNonLocal;
68
69 static int vidmodeErrorBase;
70
71 static void XF86VidModeResetProc(
72 #if NeedFunctionPrototypes
73     ExtensionEntry* /* extEntry */
74 #endif
75 );
76
77 static DISPATCH_PROC(ProcXF86VidModeDispatch);
78 static DISPATCH_PROC(ProcXF86VidModeGetAllModeLines);
79 static DISPATCH_PROC(ProcXF86VidModeGetModeLine);
80 static DISPATCH_PROC(ProcXF86VidModeGetMonitor);
81 static DISPATCH_PROC(ProcXF86VidModeLockModeSwitch);
82 static DISPATCH_PROC(ProcXF86VidModeAddModeLine);
83 static DISPATCH_PROC(ProcXF86VidModeDeleteModeLine);
84 static DISPATCH_PROC(ProcXF86VidModeModModeLine);
85 static DISPATCH_PROC(ProcXF86VidModeValidateModeLine);
86 static DISPATCH_PROC(ProcXF86VidModeQueryVersion);
87 static DISPATCH_PROC(ProcXF86VidModeSwitchMode);
88 static DISPATCH_PROC(ProcXF86VidModeSwitchToMode);
89 static DISPATCH_PROC(ProcXF86VidModeGetViewPort);
90 static DISPATCH_PROC(ProcXF86VidModeSetViewPort);
91 static DISPATCH_PROC(SProcXF86VidModeDispatch);
92 static DISPATCH_PROC(SProcXF86VidModeGetAllModeLines);
93 static DISPATCH_PROC(SProcXF86VidModeGetModeLine);
94 static DISPATCH_PROC(SProcXF86VidModeGetMonitor);
95 static DISPATCH_PROC(SProcXF86VidModeLockModeSwitch);
96 static DISPATCH_PROC(SProcXF86VidModeAddModeLine);
97 static DISPATCH_PROC(SProcXF86VidModeDeleteModeLine);
98 static DISPATCH_PROC(SProcXF86VidModeModModeLine);
99 static DISPATCH_PROC(SProcXF86VidModeValidateModeLine);
100 static DISPATCH_PROC(SProcXF86VidModeQueryVersion);
101 static DISPATCH_PROC(SProcXF86VidModeSwitchMode);
102 static DISPATCH_PROC(SProcXF86VidModeSwitchToMode);
103 static DISPATCH_PROC(SProcXF86VidModeGetViewPort);
104 static DISPATCH_PROC(SProcXF86VidModeSetViewPort);
105
106 static unsigned char XF86VidModeReqCode = 0;
107
108 /* The XF86VIDMODE_EVENTS code is far from complete */
109
110 #ifdef XF86VIDMODE_EVENTS
111 static int XF86VidModeEventBase = 0;
112
113 static void SXF86VidModeNotifyEvent();
114 #if NeedFunctionPrototypes
115     xXF86VidModeNotifyEvent * /* from */,
116     xXF86VidModeNotifyEvent * /* to */
117 #endif
118 );
119
120 extern WindowPtr *WindowTable;
121
122 static RESTYPE EventType;       /* resource type for event masks */
123
124 typedef struct _XF86VidModeEvent *XF86VidModeEventPtr;
125
126 typedef struct _XF86VidModeEvent {
127     XF86VidModeEventPtr next;
128     ClientPtr           client;
129     ScreenPtr           screen;
130     XID                 resource;
131     CARD32              mask;
132 } XF86VidModeEventRec;
133
134 static int XF86VidModeFreeEvents();
135
136 typedef struct _XF86VidModeScreenPrivate {
137     XF86VidModeEventPtr events;
138     Bool                hasWindow;
139 } XF86VidModeScreenPrivateRec, *XF86VidModeScreenPrivatePtr;
140    
141 static int ScreenPrivateIndex;
142
143 #define GetScreenPrivate(s) ((ScreenSaverScreenPrivatePtr)(s)->devPrivates[ScreenPrivateIndex].ptr)
144 #define SetScreenPrivate(s,v) ((s)->devPrivates[ScreenPrivateIndex].ptr = (pointer) v);
145 #define SetupScreen(s)  ScreenSaverScreenPrivatePtr pPriv = GetScreenPrivate(s)
146
147 #define New(t)  ((t *) xalloc (sizeof (t)))
148 #endif
149
150 void
151 XFree86VidModeExtensionInit()
152 {
153     ExtensionEntry* extEntry;
154 #ifdef XF86VIDMODE_EVENTS
155     int             i;
156     ScreenPtr       pScreen;
157
158     EventType = CreateNewResourceType(XF86VidModeFreeEvents);
159     ScreenPrivateIndex = AllocateScreenPrivateIndex ();
160     for (i = 0; i < screenInfo.numScreens; i++)
161     {
162         pScreen = screenInfo.screens[i];
163         SetScreenPrivate (pScreen, NULL);
164     }
165 #endif
166
167     if (
168 #ifdef XF86VIDMODE_EVENTS
169         EventType && ScreenPrivateIndex != -1 &&
170 #endif
171         (extEntry = AddExtension(XF86VIDMODENAME,
172                                 XF86VidModeNumberEvents,
173                                 XF86VidModeNumberErrors,
174                                 ProcXF86VidModeDispatch,
175                                 SProcXF86VidModeDispatch,
176                                 XF86VidModeResetProc,
177                                 StandardMinorOpcode))) {
178         XF86VidModeReqCode = (unsigned char)extEntry->base;
179         vidmodeErrorBase = extEntry->errorBase;
180 #ifdef XF86VIDMODE_EVENTS
181         XF86VidModeEventBase = extEntry->eventBase;
182         EventSwapVector[XF86VidModeEventBase] = SXF86VidModeNotifyEvent;
183 #endif
184     }
185 }
186
187 /*ARGSUSED*/
188 static void
189 XF86VidModeResetProc (extEntry)
190     ExtensionEntry* extEntry;
191 {
192 }
193
194 #ifdef XF86VIDMODE_EVENTS
195 static void
196 CheckScreenPrivate (pScreen)
197     ScreenPtr   pScreen;
198 {
199     SetupScreen (pScreen);
200
201     if (!pPriv)
202         return;
203     if (!pPriv->events && !pPriv->hasWindow) {
204         xfree (pPriv);
205         SetScreenPrivate (pScreen, NULL);
206     }
207 }
208     
209 static XF86VidModeScreenPrivatePtr
210 MakeScreenPrivate (pScreen)
211     ScreenPtr   pScreen;
212 {
213     SetupScreen (pScreen);
214
215     if (pPriv)
216         return pPriv;
217     pPriv = New (XF86VidModeScreenPrivateRec);
218     if (!pPriv)
219         return 0;
220     pPriv->events = 0;
221     pPriv->hasWindow = FALSE;
222     SetScreenPrivate (pScreen, pPriv);
223     return pPriv;
224 }
225
226 static unsigned long
227 getEventMask (pScreen, client)
228     ScreenPtr   pScreen;
229     ClientPtr   client;
230 {
231     SetupScreen(pScreen);
232     XF86VidModeEventPtr pEv;
233
234     if (!pPriv)
235         return 0;
236     for (pEv = pPriv->events; pEv; pEv = pEv->next)
237         if (pEv->client == client)
238             return pEv->mask;
239     return 0;
240 }
241
242 static Bool
243 setEventMask (pScreen, client, mask)
244     ScreenPtr   pScreen;
245     ClientPtr   client;
246     unsigned long mask;
247 {
248     SetupScreen(pScreen);
249     XF86VidModeEventPtr pEv, *pPrev;
250
251     if (getEventMask (pScreen, client) == mask)
252         return TRUE;
253     if (!pPriv) {
254         pPriv = MakeScreenPrivate (pScreen);
255         if (!pPriv)
256             return FALSE;
257     }
258     for (pPrev = &pPriv->events; pEv = *pPrev; pPrev = &pEv->next)
259         if (pEv->client == client)
260             break;
261     if (mask == 0) {
262         *pPrev = pEv->next;
263         xfree (pEv);
264         CheckScreenPrivate (pScreen);
265     } else {
266         if (!pEv) {
267             pEv = New (ScreenSaverEventRec);
268             if (!pEv) {
269                 CheckScreenPrivate (pScreen);
270                 return FALSE;
271             }
272             *pPrev = pEv;
273             pEv->next = NULL;
274             pEv->client = client;
275             pEv->screen = pScreen;
276             pEv->resource = FakeClientID (client->index);
277         }
278         pEv->mask = mask;
279     }
280     return TRUE;
281 }
282
283 static int
284 XF86VidModeFreeEvents (value, id)
285     pointer value;
286     XID id;
287 {
288     XF86VidModeEventPtr pOld = (XF86VidModeEventPtr)value;
289     ScreenPtr pScreen = pOld->screen;
290     SetupScreen (pScreen);
291     XF86VidModeEventPtr pEv, *pPrev;
292
293     if (!pPriv)
294         return TRUE;
295     for (pPrev = &pPriv->events; pEv = *pPrev; pPrev = &pEv->next)
296         if (pEv == pOld)
297             break;
298     if (!pEv)
299         return TRUE;
300     *pPrev = pEv->next;
301     xfree (pEv);
302     CheckScreenPrivate (pScreen);
303     return TRUE;
304 }
305
306 static void
307 SendXF86VidModeNotify (pScreen, state, forced)
308     ScreenPtr   pScreen;
309     int     state;
310     Bool    forced;
311 {
312     XF86VidModeScreenPrivatePtr pPriv;
313     XF86VidModeEventPtr         pEv;
314     unsigned long               mask;
315     xXF86VidModeNotifyEvent     ev;
316     ClientPtr                   client;
317     int                         kind;
318
319     UpdateCurrentTimeIf ();
320     mask = XF86VidModeNotifyMask;
321     pScreen = screenInfo.screens[pScreen->myNum];
322     pPriv = GetScreenPrivate(pScreen);
323     if (!pPriv)
324         return;
325     kind = XF86VidModeModeChange;
326     for (pEv = pPriv->events; pEv; pEv = pEv->next)
327     {
328         client = pEv->client;
329         if (client->clientGone)
330             continue;
331         if (!(pEv->mask & mask))
332             continue;
333         ev.type = XF86VidModeNotify + XF86VidModeEventBase;
334         ev.state = state;
335         ev.sequenceNumber = client->sequence;
336         ev.timestamp = currentTime.milliseconds;
337         ev.root = WindowTable[pScreen->myNum]->drawable.id;
338         ev.kind = kind;
339         ev.forced = forced;
340         WriteEventsToClient (client, 1, (xEvent *) &ev);
341     }
342 }
343
344 static void
345 SXF86VidModeNotifyEvent (from, to)
346     xXF86VidModeNotifyEvent *from, *to;
347 {
348     to->type = from->type;
349     to->state = from->state;
350     cpswaps (from->sequenceNumber, to->sequenceNumber);
351     cpswapl (from->timestamp, to->timestamp);    
352     cpswapl (from->root, to->root);    
353     to->kind = from->kind;
354     to->forced = from->forced;
355 }
356 #endif
357         
358 static int
359 ProcXF86VidModeQueryVersion(client)
360     register ClientPtr client;
361 {
362     xXF86VidModeQueryVersionReply rep;
363     register int n;
364
365     REQUEST_SIZE_MATCH(xXF86VidModeQueryVersionReq);
366     rep.type = X_Reply;
367     rep.length = 0;
368     rep.sequenceNumber = client->sequence;
369     rep.majorVersion = XF86VIDMODE_MAJOR_VERSION;
370     rep.minorVersion = XF86VIDMODE_MINOR_VERSION;
371     if (client->swapped) {
372         swaps(&rep.sequenceNumber, n);
373         swapl(&rep.length, n);
374         swaps(&rep.majorVersion, n);
375         swaps(&rep.minorVersion, n);
376     }
377     WriteToClient(client, sizeof(xXF86VidModeQueryVersionReply), (char *)&rep);
378     return (client->noClientException);
379 }
380
381 static int
382 ProcXF86VidModeGetModeLine(client)
383     register ClientPtr client;
384 {
385     REQUEST(xXF86VidModeGetModeLineReq);
386     xXF86VidModeGetModeLineReply rep;
387     register int n;
388     ScrnInfoPtr vptr;
389     DisplayModePtr mptr;
390     int privsize;
391
392     if (stuff->screen > screenInfo.numScreens)
393         return BadValue;
394
395     vptr = (ScrnInfoPtr) screenInfo.screens[stuff->screen]->devPrivates[xf86ScreenIndex].ptr;
396     mptr = vptr->modes;
397
398     if (!mptr->Private)
399         privsize = 0;
400     else
401         privsize = mptr->PrivSize;
402
403     REQUEST_SIZE_MATCH(xXF86VidModeGetModeLineReq);
404     rep.type = X_Reply;
405     rep.length = (SIZEOF(xXF86VidModeGetModeLineReply) - SIZEOF(xGenericReply) +
406                   privsize * sizeof(INT32)) >> 2;
407     rep.sequenceNumber = client->sequence;
408     rep.dotclock = vptr->clock[mptr->Clock];
409     rep.hdisplay = mptr->HDisplay;
410     rep.hsyncstart = mptr->HSyncStart;
411     rep.hsyncend = mptr->HSyncEnd;
412     rep.htotal = mptr->HTotal;
413     rep.vdisplay = mptr->VDisplay;
414     rep.vsyncstart = mptr->VSyncStart;
415     rep.vsyncend = mptr->VSyncEnd;
416     rep.vtotal = mptr->VTotal;
417     rep.flags = mptr->Flags;
418     rep.privsize = privsize;
419     if (client->swapped) {
420         swaps(&rep.sequenceNumber, n);
421         swapl(&rep.length, n);
422         swapl(&rep.dotclock, n);
423         swaps(&rep.hdisplay, n);
424         swaps(&rep.hsyncstart, n);
425         swaps(&rep.hsyncend, n);
426         swaps(&rep.htotal, n);
427         swaps(&rep.vdisplay, n);
428         swaps(&rep.vsyncstart, n);
429         swaps(&rep.vsyncend, n);
430         swaps(&rep.vtotal, n);
431         swapl(&rep.flags, n);
432         swapl(&rep.privsize, n);
433     }
434     WriteToClient(client, sizeof(xXF86VidModeGetModeLineReply), (char *)&rep);
435     if (privsize) {
436         client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
437         WriteSwappedDataToClient(client, privsize * sizeof(INT32),
438                                  mptr->Private);
439     }
440     return (client->noClientException);
441 }
442
443 static int
444 ProcXF86VidModeGetAllModeLines(client)
445     register ClientPtr client;
446 {
447     REQUEST(xXF86VidModeGetAllModeLinesReq);
448     xXF86VidModeGetAllModeLinesReply rep;
449     xXF86VidModeModeInfo mdinf;
450     register int n;
451     ScrnInfoPtr vptr;
452     DisplayModePtr mptr, curmptr;
453     int privsize, modecount=1;
454     int totalPrivSize = 0;
455
456     if (stuff->screen > screenInfo.numScreens)
457         return BadValue;
458
459     vptr = (ScrnInfoPtr) screenInfo.screens[stuff->screen]->devPrivates[xf86ScreenIndex].ptr;
460     curmptr = mptr = vptr->modes;
461
462     totalPrivSize = mptr->Private ? mptr->PrivSize : 0;
463
464     while (mptr->next != curmptr) {
465         ++modecount;
466         mptr = mptr->next;
467         if (mptr->Private)
468             totalPrivSize += mptr->PrivSize;
469     }
470
471     REQUEST_SIZE_MATCH(xXF86VidModeGetAllModeLinesReq);
472     rep.type = X_Reply;
473     rep.length = (SIZEOF(xXF86VidModeGetAllModeLinesReply) - SIZEOF(xGenericReply) +
474                   modecount * sizeof(xXF86VidModeModeInfo) +
475                   totalPrivSize * sizeof(INT32)) >> 2;
476     rep.sequenceNumber = client->sequence;
477     rep.modecount = modecount;
478     if (client->swapped) {
479         swaps(&rep.sequenceNumber, n);
480         swapl(&rep.length, n);
481         swapl(&rep.modecount, n);
482     }
483     WriteToClient(client, sizeof(xXF86VidModeGetAllModeLinesReply), (char *)&rep);
484     mptr = curmptr;
485     do {
486         if (!mptr->Private)
487             privsize = 0;
488         else
489             privsize = mptr->PrivSize;
490
491         mdinf.dotclock = vptr->clock[mptr->Clock];
492         mdinf.hdisplay = mptr->HDisplay;
493         mdinf.hsyncstart = mptr->HSyncStart;
494         mdinf.hsyncend = mptr->HSyncEnd;
495         mdinf.htotal = mptr->HTotal;
496         mdinf.vdisplay = mptr->VDisplay;
497         mdinf.vsyncstart = mptr->VSyncStart;
498         mdinf.vsyncend = mptr->VSyncEnd;
499         mdinf.vtotal = mptr->VTotal;
500         mdinf.flags = mptr->Flags;
501         mdinf.privsize = privsize;
502         if (client->swapped) {
503             swapl(&mdinf.dotclock, n);
504             swaps(&mdinf.hdisplay, n);
505             swaps(&mdinf.hsyncstart, n);
506             swaps(&mdinf.hsyncend, n);
507             swaps(&mdinf.htotal, n);
508             swaps(&mdinf.vdisplay, n);
509             swaps(&mdinf.vsyncstart, n);
510             swaps(&mdinf.vsyncend, n);
511             swaps(&mdinf.vtotal, n);
512             swapl(&mdinf.flags, n);
513             swapl(&mdinf.privsize, n);
514         }
515         WriteToClient(client, sizeof(xXF86VidModeModeInfo), (char *)&mdinf);
516         if (privsize) {
517             client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
518             WriteSwappedDataToClient(client, privsize * sizeof(INT32),
519                                      mptr->Private);
520         }
521         mptr = mptr->next;
522     } while (mptr != curmptr);
523     return (client->noClientException);
524 }
525
526 #define CLOCKSPD(clk,scrp)      ((clk>MAXCLOCKS)? clk: scrp->clock[clk])
527 #define MODEMATCH(mptr,stuff,scrp)      \
528         (CLOCKSPD(mptr->Clock,scrp) == CLOCKSPD(stuff->dotclock,scrp) \
529                                 && mptr->HDisplay  == stuff->hdisplay \
530                                 && mptr->HSyncStart== stuff->hsyncstart \
531                                 && mptr->HSyncEnd  == stuff->hsyncend \
532                                 && mptr->HTotal    == stuff->htotal \
533                                 && mptr->VDisplay  == stuff->vdisplay \
534                                 && mptr->VSyncStart== stuff->vsyncstart \
535                                 && mptr->VSyncEnd  == stuff->vsyncend \
536                                 && mptr->VTotal    == stuff->vtotal \
537                                 && mptr->Flags     == stuff->flags )
538
539 #include "xf86_Config.h"
540
541 static int
542 ProcXF86VidModeAddModeLine(client)
543     register ClientPtr client;
544 {
545     REQUEST(xXF86VidModeAddModeLineReq);
546     ScrnInfoPtr vptr;
547     DisplayModePtr curmptr, mptr, newmptr;
548     Bool clock_added = FALSE;
549     int i, len;
550
551     if (xf86Verbose > 1) {
552         ErrorF("AddModeLine - scrn: %d clock: %d\n",
553                 stuff->screen, stuff->dotclock);
554         ErrorF("AddModeLine - hdsp: %d hbeg: %d hend: %d httl: %d\n",
555                 stuff->hdisplay, stuff->hsyncstart,
556                 stuff->hsyncend, stuff->htotal);
557         ErrorF("              vdsp: %d vbeg: %d vend: %d vttl: %d flags: %d\n",
558                 stuff->vdisplay, stuff->vsyncstart, stuff->vsyncend,
559                 stuff->vtotal, stuff->flags);
560         ErrorF("      after - scrn: %d clock: %d\n",
561                 stuff->screen, stuff->after_dotclock);
562         ErrorF("              hdsp: %d hbeg: %d hend: %d httl: %d\n",
563                 stuff->after_hdisplay, stuff->after_hsyncstart,
564                 stuff->after_hsyncend, stuff->after_htotal);
565         ErrorF("              vdsp: %d vbeg: %d vend: %d vttl: %d flags: %d\n",
566                 stuff->after_vdisplay, stuff->after_vsyncstart,
567                 stuff->after_vsyncend, stuff->after_vtotal, stuff->after_flags);
568     }
569     if (stuff->screen > screenInfo.numScreens)
570         return BadValue;
571
572     vptr = (ScrnInfoPtr) screenInfo.screens[stuff->screen]->devPrivates[xf86ScreenIndex].ptr;
573     curmptr = mptr = vptr->modes;
574
575     REQUEST_AT_LEAST_SIZE(xXF86VidModeAddModeLineReq);
576     len = client->req_len - (sizeof(xXF86VidModeAddModeLineReq) >> 2);
577     if (len != stuff->privsize)
578         return BadLength;
579
580     if (stuff->hsyncstart < stuff->hdisplay   ||
581         stuff->hsyncend   < stuff->hsyncstart ||
582         stuff->htotal     < stuff->hsyncend   ||
583         stuff->vsyncstart < stuff->vdisplay   ||
584         stuff->vsyncend   < stuff->vsyncstart ||
585         stuff->vtotal     < stuff->vsyncend)
586         return BadValue;
587
588     if (stuff->after_hsyncstart < stuff->after_hdisplay   ||
589         stuff->after_hsyncend   < stuff->after_hsyncstart ||
590         stuff->after_htotal     < stuff->after_hsyncend   ||
591         stuff->after_vsyncstart < stuff->after_vdisplay   ||
592         stuff->after_vsyncend   < stuff->after_vsyncstart ||
593         stuff->after_vtotal     < stuff->after_vsyncend)
594         return BadValue;
595
596     if (stuff->after_htotal != 0 || stuff->after_vtotal != 0) {
597         Bool found = FALSE;
598         do {
599             if (MODEMATCH(mptr, stuff, vptr)) {
600                 found = TRUE;
601                 break;
602             }
603         } while ((mptr = mptr->next) != curmptr);
604         if (!found)
605             return BadValue;
606     }
607
608     newmptr = (DisplayModePtr) xalloc(sizeof(DisplayModeRec));
609
610     /* Clock checking code, mostly copied from the xf86LookupMode function */
611     if (stuff->dotclock < vptr->clocks) {
612         newmptr->Clock = stuff->dotclock;
613     } else {
614         if ((OFLG_ISSET(CLOCK_OPTION_PROGRAMABLE, &(vptr->clockOptions))) &&
615             !OFLG_ISSET(OPTION_NO_PROGRAM_CLOCKS, &(vptr->options)))
616         {
617             for (i = 0; i < vptr->clocks; i++)
618                 if (stuff->dotclock == vptr->clock[i])
619                     break;
620
621             if (i >= MAXCLOCKS || vptr->clock[i]/1000 > vptr->maxClock/1000) {
622                 xfree(newmptr);
623                 return vidmodeErrorBase + XF86VidModeBadClock;
624             }
625         
626             if (i == vptr->clocks) {
627                 vptr->clock[i] = stuff->dotclock;
628                 vptr->clocks++;
629                 clock_added = TRUE;
630             }
631         } else {
632             int         flags=0, j, k, Gap, Minimum_Gap = CLOCK_TOLERANCE + 1;
633             double      refresh, bestRefresh = 0.0;
634
635             if (OFLG_ISSET(OPTION_CLKDIV2, &(vptr->options)))
636                 k=2;
637             else
638                 k=1;
639             
640             if (xf86BestRefresh)
641                 flags |= LOOKUP_BEST_REFRESH;
642
643             for (j=1 ; j<=k ; j++) {
644                 i = xf86GetNearestClock(vptr, stuff->dotclock * j);
645                 if (flags & LOOKUP_BEST_REFRESH) {
646                     if ( ((vptr->clock[i]/j) / 1000) > (vptr->maxClock / 1000) ) {
647                         xfree(newmptr);
648                         return vidmodeErrorBase + XF86VidModeBadClock;
649                     } else {
650                         refresh = stuff->dotclock * 1000.0 / stuff->htotal / stuff->vtotal;
651                         if (stuff->flags & V_INTERLACE) {
652                             refresh *= 2;
653                             refresh /= INTERLACE_REFRESH_WEIGHT;
654                         } else if (stuff->flags & V_DBLSCAN)
655                             refresh /= 2;
656
657                         if (refresh > bestRefresh) {
658                             newmptr->Clock = i;
659                             if (j==2) stuff->flags |= V_CLKDIV2;
660                             bestRefresh = refresh;
661                         }
662                     }
663                 } else {
664                     Gap = abs( stuff->dotclock - (vptr->clock[i]/j) );
665                     if (Gap < Minimum_Gap) {
666                         if ( ((vptr->clock[i]/j) / 1000) > (vptr->maxClock / 1000) ) {
667                             xfree(newmptr);
668                             return vidmodeErrorBase + XF86VidModeBadClock;
669                         } else {
670                             newmptr->Clock = i;
671                             if (j==2) stuff->flags |= V_CLKDIV2;
672                             Minimum_Gap = Gap;
673                         }
674                     }
675                 }
676             }
677         }
678     }
679
680     newmptr->CrtcHDisplay  = newmptr->HDisplay      = stuff->hdisplay;
681     newmptr->CrtcHSyncStart= newmptr->HSyncStart    = stuff->hsyncstart;
682     newmptr->CrtcHSyncEnd  = newmptr->HSyncEnd      = stuff->hsyncend;
683     newmptr->CrtcHTotal    = newmptr->HTotal        = stuff->htotal;
684     newmptr->CrtcVDisplay  = newmptr->VDisplay      = stuff->vdisplay;
685     newmptr->CrtcVSyncStart= newmptr->VSyncStart    = stuff->vsyncstart;
686     newmptr->CrtcVSyncEnd  = newmptr->VSyncEnd      = stuff->vsyncend;
687     newmptr->CrtcVTotal    = newmptr->VTotal        = stuff->vtotal;
688     newmptr->Flags         = stuff->flags;
689 #if 0
690     newmptr->CrtcHSkew     = newmptr->HSkew         = stuff->hskew;
691 #endif
692     newmptr->CrtcHAdjusted = FALSE;
693     newmptr->CrtcVAdjusted = FALSE;
694     newmptr->name          = "";
695     newmptr->Private       = NULL;
696     if (stuff->privsize) {
697         if (xf86Verbose > 1)
698             ErrorF("AddModeLine - Request includes privates\n");
699         newmptr->Private =
700             (INT32 *) ALLOCATE_LOCAL(stuff->privsize * sizeof(INT32));
701         memcpy(newmptr->Private, &stuff[1], stuff->privsize*sizeof(INT32));
702     }
703
704     /* Check that the mode is consistent with the monitor specs */
705     switch (xf86CheckMode(vptr, newmptr, vptr->monitor, FALSE)) {
706         case MODE_OK:
707             break;
708         case MODE_HSYNC:
709             xfree(newmptr->Private);
710             xfree(newmptr);
711             if (clock_added)
712                 vptr->clocks--;
713             return vidmodeErrorBase + XF86VidModeBadHTimings;
714         case MODE_VSYNC:
715             xfree(newmptr->Private);
716             xfree(newmptr);
717             if (clock_added)
718                 vptr->clocks--;
719             return vidmodeErrorBase + XF86VidModeBadVTimings;
720         default:
721             if (clock_added)
722                 vptr->clocks--;
723             return vidmodeErrorBase + XF86VidModeModeUnsuitable;
724     }
725
726     /* Check that the driver is happy with the mode */
727     if (vptr->ValidMode(newmptr, xf86Verbose, MODE_VID) != MODE_OK) {
728         xfree(newmptr->Private);
729         xfree(newmptr);
730         if (clock_added)
731             vptr->clocks--;
732         return vidmodeErrorBase + XF86VidModeModeUnsuitable;
733     }
734
735     if (newmptr->Flags & V_DBLSCAN)
736     {
737         newmptr->CrtcVDisplay *= 2;
738         newmptr->CrtcVSyncStart *= 2;
739         newmptr->CrtcVSyncEnd *= 2;
740         newmptr->CrtcVTotal *= 2;
741         newmptr->CrtcVAdjusted = TRUE;
742     }
743
744     newmptr->next       = mptr->next;
745     newmptr->prev       = mptr;
746     mptr->next          = newmptr;
747     newmptr->next->prev = newmptr;
748
749 #if 0  /* Do we want this? */
750     (vptr->SwitchMode)(newmptr);
751 #endif
752
753     if (xf86Verbose > 1)
754         ErrorF("AddModeLine - Succeeded\n");
755     return(client->noClientException);
756 }
757
758 static int
759 ProcXF86VidModeDeleteModeLine(client)
760     register ClientPtr client;
761 {
762     REQUEST(xXF86VidModeDeleteModeLineReq);
763     ScrnInfoPtr vptr;
764     DisplayModePtr curmptr, mptr;
765     int len;
766
767     if (xf86Verbose > 1) {
768         ErrorF("DeleteModeLine - scrn: %d clock: %d\n",
769                 stuff->screen, stuff->dotclock, stuff->dotclock);
770         ErrorF("                 hdsp: %d hbeg: %d hend: %d httl: %d\n",
771                 stuff->hdisplay, stuff->hsyncstart,
772                 stuff->hsyncend, stuff->htotal);
773         ErrorF("                 vdsp: %d vbeg: %d vend: %d vttl: %d flags: %d\n",
774                 stuff->vdisplay, stuff->vsyncstart, stuff->vsyncend,
775                 stuff->vtotal, stuff->flags);
776     }
777     if (stuff->screen > screenInfo.numScreens)
778         return BadValue;
779
780     vptr = (ScrnInfoPtr) screenInfo.screens[stuff->screen]->devPrivates[xf86ScreenIndex].ptr;
781     curmptr = mptr = vptr->modes;
782
783     REQUEST_AT_LEAST_SIZE(xXF86VidModeDeleteModeLineReq);
784     len = client->req_len - (sizeof(xXF86VidModeDeleteModeLineReq) >> 2);
785     if (len != stuff->privsize) {
786         if (xf86Verbose > 1) {
787             ErrorF("req_len = %d, sizeof(Req) = %d, privsize = %d, len = %d, length = %d\n",
788                     client->req_len, sizeof(xXF86VidModeDeleteModeLineReq)>>2, stuff->privsize, len, stuff->length);
789         }
790         return BadLength;
791     }
792     if (xf86Verbose > 1) {
793         ErrorF("Checking against clock: %d (%d)\n",
794                 mptr->Clock, CLOCKSPD(mptr->Clock, vptr));
795         ErrorF("                 hdsp: %d hbeg: %d hend: %d httl: %d\n",
796                 mptr->HDisplay, mptr->HSyncStart,
797                 mptr->HSyncEnd, mptr->HTotal);
798         ErrorF("                 vdsp: %d vbeg: %d vend: %d vttl: %d flags: %d\n",
799                 mptr->VDisplay, mptr->VSyncStart, mptr->VSyncEnd,
800                 mptr->VTotal, mptr->Flags);
801     }
802     if (MODEMATCH(mptr, stuff, vptr))
803         return BadValue;
804
805     while ((mptr = mptr->next) != curmptr) {
806         if (xf86Verbose > 1) {
807             ErrorF("Checking against clock: %d (%d)\n",
808                     mptr->Clock, CLOCKSPD(mptr->Clock, vptr));
809             ErrorF("                 hdsp: %d hbeg: %d hend: %d httl: %d\n",
810                     mptr->HDisplay, mptr->HSyncStart,
811                     mptr->HSyncEnd, mptr->HTotal);
812             ErrorF("                 vdsp: %d vbeg: %d vend: %d vttl: %d flags: %d\n",
813                     mptr->VDisplay, mptr->VSyncStart, mptr->VSyncEnd,
814                     mptr->VTotal, mptr->Flags);
815         }
816         if (MODEMATCH(mptr, stuff, vptr)) {
817             mptr->prev->next = mptr->next;
818             mptr->next->prev = mptr->prev;
819             xfree(mptr->name);
820             xfree(mptr->Private);
821             xfree(mptr);
822             if (xf86Verbose)
823                 ErrorF("DeleteModeLine - Succeeded\n");
824             return(client->noClientException);
825         }
826     }
827     return BadValue;
828 }
829
830 static int
831 ProcXF86VidModeModModeLine(client)
832     register ClientPtr client;
833 {
834     REQUEST(xXF86VidModeModModeLineReq);
835     ScrnInfoPtr vptr;
836     DisplayModePtr mptr;
837     DisplayModeRec modetmp;
838     int len;
839
840     if (xf86Verbose > 1) {
841         ErrorF("ModModeLine - scrn: %d hdsp: %d hbeg: %d hend: %d httl: %d\n",
842                 stuff->screen, stuff->hdisplay, stuff->hsyncstart,
843                 stuff->hsyncend, stuff->htotal);
844         ErrorF("              vdsp: %d vbeg: %d vend: %d vttl: %d flags: %d\n",
845                 stuff->vdisplay, stuff->vsyncstart, stuff->vsyncend,
846                 stuff->vtotal, stuff->flags);
847     }
848     if (stuff->screen > screenInfo.numScreens)
849         return BadValue;
850
851     vptr = (ScrnInfoPtr) screenInfo.screens[stuff->screen]->devPrivates[xf86ScreenIndex].ptr;
852     mptr = vptr->modes;
853
854     REQUEST_AT_LEAST_SIZE(xXF86VidModeModModeLineReq);
855     len = client->req_len - (sizeof(xXF86VidModeModModeLineReq) >> 2);
856     if (len != stuff->privsize)
857         return BadLength;
858
859     if (stuff->hsyncstart < stuff->hdisplay   ||
860         stuff->hsyncend   < stuff->hsyncstart ||
861         stuff->htotal     < stuff->hsyncend   ||
862         stuff->vsyncstart < stuff->vdisplay   ||
863         stuff->vsyncend   < stuff->vsyncstart ||
864         stuff->vtotal     < stuff->vsyncend)
865         return BadValue;
866
867     memcpy(&modetmp, mptr, sizeof(DisplayModeRec));
868
869     modetmp.HDisplay   = stuff->hdisplay;
870     modetmp.HSyncStart = stuff->hsyncstart;
871     modetmp.HSyncEnd   = stuff->hsyncend;
872     modetmp.HTotal     = stuff->htotal;
873     modetmp.VDisplay   = stuff->vdisplay;
874     modetmp.VSyncStart = stuff->vsyncstart;
875     modetmp.VSyncEnd   = stuff->vsyncend;
876     modetmp.VTotal     = stuff->vtotal;
877     modetmp.Flags      = stuff->flags;
878     if (mptr->PrivSize && stuff->privsize) {
879         if (mptr->PrivSize != stuff->privsize)
880             return BadValue;
881     }
882     if (mptr->PrivSize && mptr->Private) {
883         modetmp.Private =
884                 (INT32 *)ALLOCATE_LOCAL(mptr->PrivSize * sizeof(INT32));
885         if (stuff->privsize) {
886             if (xf86Verbose > 1)
887                 ErrorF("ModModeLine - Request includes privates\n");
888             memcpy(modetmp.Private, &stuff[1], mptr->PrivSize * sizeof(INT32));
889         } else
890             memcpy(modetmp.Private, mptr->Private,
891                    mptr->PrivSize * sizeof(INT32));
892     }
893
894     /* Check that the mode is consistent with the monitor specs */
895     switch (xf86CheckMode(vptr, &modetmp, vptr->monitor, FALSE)) {
896         case MODE_HSYNC:
897             DEALLOCATE_LOCAL(modetmp.Private);
898             return vidmodeErrorBase + XF86VidModeBadHTimings;
899         case MODE_VSYNC:
900             DEALLOCATE_LOCAL(modetmp.Private);
901             return vidmodeErrorBase + XF86VidModeBadVTimings;
902     }
903
904     /* Check that the driver is happy with the mode */
905     if (vptr->ValidMode(&modetmp, xf86Verbose, MODE_VID) != MODE_OK) {
906         DEALLOCATE_LOCAL(modetmp.Private);
907         return vidmodeErrorBase + XF86VidModeModeUnsuitable;
908     }
909
910     DEALLOCATE_LOCAL(modetmp.Private);
911
912     mptr->HDisplay   = stuff->hdisplay;
913     mptr->HSyncStart = stuff->hsyncstart;
914     mptr->HSyncEnd   = stuff->hsyncend;
915     mptr->HTotal     = stuff->htotal;
916     mptr->VDisplay   = stuff->vdisplay;
917     mptr->VSyncStart = stuff->vsyncstart;
918     mptr->VSyncEnd   = stuff->vsyncend;
919     mptr->VTotal     = stuff->vtotal;
920     mptr->Flags      = stuff->flags;
921     mptr->CrtcHDisplay   = stuff->hdisplay;
922     mptr->CrtcHSyncStart = stuff->hsyncstart;
923     mptr->CrtcHSyncEnd   = stuff->hsyncend;
924     mptr->CrtcHTotal     = stuff->htotal;
925     mptr->CrtcVDisplay   = stuff->vdisplay;
926     mptr->CrtcVSyncStart = stuff->vsyncstart;
927     mptr->CrtcVSyncEnd   = stuff->vsyncend;
928     mptr->CrtcVTotal     = stuff->vtotal;
929     mptr->CrtcVAdjusted = FALSE;
930     mptr->CrtcHAdjusted = FALSE;
931     if (mptr->Flags & V_DBLSCAN)
932     {
933         mptr->CrtcVDisplay *= 2;
934         mptr->CrtcVSyncStart *= 2;
935         mptr->CrtcVSyncEnd *= 2;
936         mptr->CrtcVTotal *= 2;
937         mptr->CrtcVAdjusted = TRUE;
938     }
939     if (mptr->PrivSize && stuff->privsize) {
940         memcpy(mptr->Private, &stuff[1], mptr->PrivSize * sizeof(INT32));
941     }
942
943     (vptr->SwitchMode)(mptr);
944     (vptr->AdjustFrame)(vptr->frameX0, vptr->frameY0);
945
946     if (xf86Verbose > 1)
947         ErrorF("ModModeLine - Succeeded\n");
948     return(client->noClientException);
949 }
950
951 static int
952 ProcXF86VidModeValidateModeLine(client)
953     register ClientPtr client;
954 {
955     REQUEST(xXF86VidModeValidateModeLineReq);
956     xXF86VidModeValidateModeLineReply rep;
957     ScrnInfoPtr vptr;
958     DisplayModePtr mptr;
959     DisplayModeRec modetmp;
960     int len, status;
961
962     if (xf86Verbose > 1) {
963         ErrorF("ValidateModeLine - scrn: %d clock: %d\n",
964                 stuff->screen, stuff->dotclock);
965         ErrorF("                   hdsp: %d hbeg: %d hend: %d httl: %d\n",
966                 stuff->hdisplay, stuff->hsyncstart,
967                 stuff->hsyncend, stuff->htotal);
968         ErrorF("                   vdsp: %d vbeg: %d vend: %d vttl: %d flags: %d\n",
969                 stuff->vdisplay, stuff->vsyncstart, stuff->vsyncend,
970                 stuff->vtotal, stuff->flags);
971     }
972     if (stuff->screen > screenInfo.numScreens)
973         return BadValue;
974
975     vptr = (ScrnInfoPtr) screenInfo.screens[stuff->screen]->devPrivates[xf86ScreenIndex].ptr;
976     mptr = vptr->modes;
977
978     REQUEST_AT_LEAST_SIZE(xXF86VidModeValidateModeLineReq);
979     len = client->req_len - (sizeof(xXF86VidModeValidateModeLineReq) >> 2);
980     if (len != stuff->privsize)
981         return BadLength;
982
983     status = MODE_OK;
984     modetmp.Private = NULL;
985
986     if (stuff->hsyncstart < stuff->hdisplay   ||
987         stuff->hsyncend   < stuff->hsyncstart ||
988         stuff->htotal     < stuff->hsyncend   ||
989         stuff->vsyncstart < stuff->vdisplay   ||
990         stuff->vsyncend   < stuff->vsyncstart ||
991         stuff->vtotal     < stuff->vsyncend)
992     {
993         status = MODE_BAD;
994         goto status_reply;
995     }
996
997     memcpy(&modetmp, mptr, sizeof(DisplayModeRec));
998
999     modetmp.HDisplay   = stuff->hdisplay;
1000     modetmp.HSyncStart = stuff->hsyncstart;
1001     modetmp.HSyncEnd   = stuff->hsyncend;
1002     modetmp.HTotal     = stuff->htotal;
1003     modetmp.VDisplay   = stuff->vdisplay;
1004     modetmp.VSyncStart = stuff->vsyncstart;
1005     modetmp.VSyncEnd   = stuff->vsyncend;
1006     modetmp.VTotal     = stuff->vtotal;
1007     modetmp.Flags      = stuff->flags;
1008     modetmp.Private    = NULL;
1009     if (mptr->PrivSize && stuff->privsize) {
1010         if (mptr->PrivSize != stuff->privsize) {
1011             status = MODE_BAD;
1012             goto status_reply;
1013         }
1014     }
1015     if (mptr->PrivSize && mptr->Private) {
1016         modetmp.Private =
1017                 (INT32 *)ALLOCATE_LOCAL(mptr->PrivSize * sizeof(INT32));
1018         if (stuff->privsize) {
1019             if (xf86Verbose)
1020                 ErrorF("ValidateModeLine - Request includes privates\n");
1021             memcpy(modetmp.Private, &stuff[1], mptr->PrivSize * sizeof(INT32));
1022         } else
1023             memcpy(modetmp.Private, mptr->Private,
1024                    mptr->PrivSize * sizeof(INT32));
1025     }
1026
1027     /* Check that the mode is consistent with the monitor specs */
1028     if ((status = xf86CheckMode(vptr, &modetmp, vptr->monitor, FALSE)) != MODE_OK)
1029         goto status_reply;
1030
1031     /* Check that the driver is happy with the mode */
1032     status = vptr->ValidMode(&modetmp, xf86Verbose, MODE_VID);
1033
1034 status_reply:
1035     if (modetmp.Private)
1036         DEALLOCATE_LOCAL(modetmp.Private);
1037     rep.type = X_Reply;
1038     rep.length = (SIZEOF(xXF86VidModeValidateModeLineReply)
1039                          - SIZEOF(xGenericReply)) >> 2;
1040     rep.sequenceNumber = client->sequence;
1041     rep.status = status;
1042     if (client->swapped) {
1043         register int n;
1044         swaps(&rep.sequenceNumber, n);
1045         swapl(&rep.length, n);
1046         swapl(&rep.status, n);
1047     }
1048     WriteToClient(client, sizeof(xXF86VidModeValidateModeLineReply), (char *)&rep);
1049     if (xf86Verbose > 1)
1050         ErrorF("ValidateModeLine - Succeeded\n");
1051     return(client->noClientException);
1052 }
1053
1054 static int
1055 ProcXF86VidModeSwitchMode(client)
1056     register ClientPtr client;
1057 {
1058     REQUEST(xXF86VidModeSwitchModeReq);
1059     ScreenPtr vptr;
1060
1061     if (stuff->screen > screenInfo.numScreens)
1062         return BadValue;
1063
1064     vptr = screenInfo.screens[stuff->screen];
1065     if (xf86Info.dontZoom)
1066         return vidmodeErrorBase + XF86VidModeZoomLocked;
1067
1068     REQUEST_SIZE_MATCH(xXF86VidModeSwitchModeReq);
1069
1070     xf86ZoomViewport(vptr, (short)stuff->zoom);
1071     return (client->noClientException);
1072 }
1073
1074 static int
1075 ProcXF86VidModeSwitchToMode(client)
1076     register ClientPtr client;
1077 {
1078     REQUEST(xXF86VidModeSwitchToModeReq);
1079     ScrnInfoPtr vptr;
1080     DisplayModePtr curmptr, mptr;
1081     int len;
1082
1083     if (xf86Verbose > 1) {
1084         ErrorF("SwitchToMode - scrn: %d clock: %d\n",
1085                 stuff->screen, stuff->dotclock);
1086         ErrorF("               hdsp: %d hbeg: %d hend: %d httl: %d\n",
1087                 stuff->hdisplay, stuff->hsyncstart,
1088                 stuff->hsyncend, stuff->htotal);
1089         ErrorF("               vdsp: %d vbeg: %d vend: %d vttl: %d flags: %d\n",
1090                 stuff->vdisplay, stuff->vsyncstart, stuff->vsyncend,
1091                 stuff->vtotal, stuff->flags);
1092     }
1093     if (stuff->screen > screenInfo.numScreens)
1094         return BadValue;
1095
1096     if (xf86Info.dontZoom)
1097         return vidmodeErrorBase + XF86VidModeZoomLocked;
1098
1099     vptr = (ScrnInfoPtr) screenInfo.screens[stuff->screen]->devPrivates[xf86ScreenIndex].ptr;
1100     curmptr = mptr = vptr->modes;
1101
1102     REQUEST_AT_LEAST_SIZE(xXF86VidModeSwitchToModeReq);
1103     len = client->req_len - (sizeof(xXF86VidModeSwitchToModeReq) >> 2);
1104     if (len != stuff->privsize)
1105         return BadLength;
1106
1107
1108     if (MODEMATCH(mptr, stuff, vptr))
1109         return (client->noClientException);
1110
1111     while ((mptr = mptr->next) != curmptr) {
1112         if (xf86Verbose > 1) {
1113             ErrorF("Checking against clock: %d (%d)\n",
1114                     mptr->Clock, CLOCKSPD(mptr->Clock, vptr));
1115             ErrorF("                 hdsp: %d hbeg: %d hend: %d httl: %d\n",
1116                     mptr->HDisplay, mptr->HSyncStart,
1117                     mptr->HSyncEnd, mptr->HTotal);
1118             ErrorF("                 vdsp: %d vbeg: %d vend: %d vttl: %d flags: %d\n",
1119                     mptr->VDisplay, mptr->VSyncStart, mptr->VSyncEnd,
1120                     mptr->VTotal, mptr->Flags);
1121         }
1122         if (MODEMATCH(mptr, stuff, vptr)) {
1123             if ((vptr->SwitchMode)(mptr)) {
1124                 vptr->modes = mptr;
1125                 vptr->frameX0 = (vptr->frameX1 +vptr->frameX0 -mptr->HDisplay)/2;
1126                 vptr->frameX1 = vptr->frameX0 + mptr->HDisplay -1;
1127                 if (vptr->frameX0 < 0) {
1128                     vptr->frameX0 = 0;
1129                     vptr->frameX1 = mptr->HDisplay -1;
1130                 } else if (vptr->frameX1 >= vptr->virtualX) {
1131                     vptr->frameX0 = vptr->virtualX - mptr->HDisplay;
1132                     vptr->frameX1 = vptr->frameX0 + mptr->HDisplay -1;
1133                 }
1134                 vptr->frameY0 = (vptr->frameY1 +vptr->frameY0 -mptr->VDisplay)/2;
1135                 vptr->frameY1 = vptr->frameY0 + mptr->VDisplay -1;
1136                 if (vptr->frameY0 < 0) {
1137                     vptr->frameY0 = 0;
1138                     vptr->frameY1 = mptr->VDisplay -1;
1139                 } else if (vptr->frameY1 >= vptr->virtualY) {
1140                     vptr->frameY0 = vptr->virtualY - mptr->VDisplay;
1141                     vptr->frameY1 = vptr->frameY0 + mptr->VDisplay -1;
1142                 }
1143             }
1144             (vptr->AdjustFrame)(vptr->frameX0, vptr->frameY0);
1145             if (xf86Verbose > 1)
1146                 ErrorF("SwitchToMode - Succeeded\n");
1147             return(client->noClientException);
1148         }
1149     }
1150     return BadValue;
1151 }
1152
1153 static int
1154 ProcXF86VidModeLockModeSwitch(client)
1155     register ClientPtr client;
1156 {
1157     REQUEST(xXF86VidModeLockModeSwitchReq);
1158     ScreenPtr vptr;
1159
1160     if (stuff->screen > screenInfo.numScreens)
1161         return BadValue;
1162
1163     vptr = screenInfo.screens[stuff->screen];
1164     if (xf86Info.dontZoom)
1165         return vidmodeErrorBase + XF86VidModeZoomLocked;
1166
1167     REQUEST_SIZE_MATCH(xXF86VidModeLockModeSwitchReq);
1168
1169     xf86LockZoom(vptr, (short)stuff->lock);
1170     return (client->noClientException);
1171 }
1172
1173 static int
1174 ProcXF86VidModeGetMonitor(client)
1175     register ClientPtr client;
1176 {
1177     REQUEST(xXF86VidModeGetMonitorReq);
1178     xXF86VidModeGetMonitorReply rep;
1179     register int n;
1180     ScrnInfoPtr vptr;
1181     MonPtr mptr;
1182     CARD32 *hsyncdata, *vsyncdata;
1183     int i;
1184
1185     if (stuff->screen > screenInfo.numScreens)
1186         return BadValue;
1187
1188     vptr = (ScrnInfoPtr) screenInfo.screens[stuff->screen]->devPrivates[xf86ScreenIndex].ptr;
1189     mptr = vptr->monitor;
1190
1191     REQUEST_SIZE_MATCH(xXF86VidModeGetMonitorReq);
1192     rep.type = X_Reply;
1193     if (mptr->vendor)
1194         rep.vendorLength = strlen(mptr->vendor);
1195     else
1196         rep.vendorLength = 0;
1197     if (mptr->model)
1198         rep.modelLength = strlen(mptr->model);
1199     else
1200         rep.modelLength = 0;
1201     rep.length = (SIZEOF(xXF86VidModeGetMonitorReply) - SIZEOF(xGenericReply) +
1202                   (mptr->n_hsync + mptr->n_vrefresh) * sizeof(CARD32) +
1203                   ((rep.vendorLength + 3) & ~3) +
1204                   ((rep.modelLength + 3) & ~3)) >> 2;
1205     rep.sequenceNumber = client->sequence;
1206     rep.nhsync = mptr->n_hsync;
1207     rep.nvsync = mptr->n_vrefresh;
1208 #if 0
1209     rep.bandwidth = (unsigned long)(mptr->bandwidth * 1e6);
1210 #endif
1211     hsyncdata = ALLOCATE_LOCAL(mptr->n_hsync * sizeof(CARD32));
1212     if (!hsyncdata) {
1213         return BadAlloc;
1214     }
1215     vsyncdata = ALLOCATE_LOCAL(mptr->n_vrefresh * sizeof(CARD32));
1216     if (!vsyncdata) {
1217         DEALLOCATE_LOCAL(hsyncdata);
1218         return BadAlloc;
1219     }
1220     for (i = 0; i < mptr->n_hsync; i++) {
1221         hsyncdata[i] = (unsigned short)(mptr->hsync[i].lo * 100.0) |
1222                        (unsigned short)(mptr->hsync[i].hi * 100.0) << 16;
1223     }
1224     for (i = 0; i < mptr->n_vrefresh; i++) {
1225         vsyncdata[i] = (unsigned short)(mptr->vrefresh[i].lo * 100.0) |
1226                        (unsigned short)(mptr->vrefresh[i].hi * 100.0) << 16;
1227     }
1228     
1229     if (client->swapped) {
1230         swaps(&rep.sequenceNumber, n);
1231         swapl(&rep.length, n);
1232 #if 0
1233         swapl(&rep.bandwidth, n);
1234 #endif
1235     }
1236     WriteToClient(client, SIZEOF(xXF86VidModeGetMonitorReply), (char *)&rep);
1237     client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
1238     WriteSwappedDataToClient(client, mptr->n_hsync * sizeof(CARD32),
1239                              hsyncdata);
1240     WriteSwappedDataToClient(client, mptr->n_vrefresh * sizeof(CARD32),
1241                              vsyncdata);
1242     if (rep.vendorLength)
1243         WriteToClient(client, rep.vendorLength, mptr->vendor);
1244     if (rep.modelLength)
1245         WriteToClient(client, rep.modelLength, mptr->model);
1246     DEALLOCATE_LOCAL(hsyncdata);
1247     DEALLOCATE_LOCAL(vsyncdata);
1248     return (client->noClientException);
1249 }
1250
1251 static int
1252 ProcXF86VidModeGetViewPort(client)
1253     register ClientPtr client;
1254 {
1255     REQUEST(xXF86VidModeGetViewPortReq);
1256     xXF86VidModeGetViewPortReply rep;
1257     ScrnInfoPtr vptr;
1258     int n;
1259
1260     if (stuff->screen > screenInfo.numScreens)
1261         return BadValue;
1262
1263     vptr = (ScrnInfoPtr) screenInfo.screens[stuff->screen]->devPrivates[xf86ScreenIndex].ptr;
1264
1265     REQUEST_SIZE_MATCH(xXF86VidModeGetViewPortReq);
1266     rep.type = X_Reply;
1267     rep.length = 0;
1268     rep.sequenceNumber = client->sequence;
1269     rep.x = vptr->frameX0;
1270     rep.y = vptr->frameY0;
1271
1272     if (client->swapped) {
1273         swaps(&rep.sequenceNumber, n);
1274         swapl(&rep.length, n);
1275         swapl(&rep.x, n);
1276         swapl(&rep.y, n);
1277     }
1278     WriteToClient(client, SIZEOF(xXF86VidModeGetViewPortReply), (char *)&rep);
1279     return (client->noClientException);
1280 }
1281
1282 static int
1283 ProcXF86VidModeSetViewPort(client)
1284     register ClientPtr client;
1285 {
1286     REQUEST(xXF86VidModeSetViewPortReq);
1287     ScrnInfoPtr vptr;
1288     int x, y;
1289
1290     if (stuff->screen > screenInfo.numScreens)
1291         return BadValue;
1292
1293     vptr = (ScrnInfoPtr) screenInfo.screens[stuff->screen]->devPrivates[xf86ScreenIndex].ptr;
1294
1295     REQUEST_SIZE_MATCH(xXF86VidModeSetViewPortReq);
1296
1297     if (stuff->x < 0)
1298         x = 0;
1299     else if (stuff->x + vptr->modes->HDisplay + 1 > vptr->virtualX)
1300         x = vptr->virtualX - vptr->modes->HDisplay - 1;
1301     else
1302         x = stuff->x;
1303
1304     if (stuff->y < 0)
1305         y = 0;
1306     else if (stuff->y + vptr->modes->VDisplay + 1 > vptr->virtualY)
1307         y = vptr->virtualY - vptr->modes->VDisplay - 1;
1308     else
1309         y = stuff->y;
1310
1311     if (vptr->AdjustFrame && xf86VTSema) {
1312         vptr->AdjustFrame(x, y);
1313         vptr->frameX0 = x;
1314         vptr->frameX1 = x + vptr->modes->HDisplay - 1;
1315         vptr->frameY0 = y;
1316         vptr->frameY1 = y + vptr->modes->VDisplay - 1;
1317     }
1318     
1319     return (client->noClientException);
1320 }
1321
1322
1323 static int
1324 ProcXF86VidModeDispatch (client)
1325     register ClientPtr  client;
1326 {
1327     REQUEST(xReq);
1328     switch (stuff->data)
1329     {
1330     case X_XF86VidModeQueryVersion:
1331         return ProcXF86VidModeQueryVersion(client);
1332     case X_XF86VidModeGetModeLine:
1333         return ProcXF86VidModeGetModeLine(client);
1334     case X_XF86VidModeGetAllModeLines:
1335         return ProcXF86VidModeGetAllModeLines(client);
1336     case X_XF86VidModeGetMonitor:
1337         return ProcXF86VidModeGetMonitor(client);
1338     case X_XF86VidModeValidateModeLine:
1339         return ProcXF86VidModeValidateModeLine(client);
1340     case X_XF86VidModeGetViewPort:
1341         return ProcXF86VidModeGetViewPort(client);
1342     default:
1343         if (!xf86VidModeEnabled)
1344             return vidmodeErrorBase + XF86VidModeExtensionDisabled;
1345         if (xf86VidModeAllowNonLocal || LocalClient (client)) {
1346             switch (stuff->data) {
1347             case X_XF86VidModeAddModeLine:
1348                 return ProcXF86VidModeAddModeLine(client);
1349             case X_XF86VidModeDeleteModeLine:
1350                 return ProcXF86VidModeDeleteModeLine(client);
1351             case X_XF86VidModeModModeLine:
1352                 return ProcXF86VidModeModModeLine(client);
1353             case X_XF86VidModeSwitchMode:
1354                 return ProcXF86VidModeSwitchMode(client);
1355             case X_XF86VidModeSwitchToMode:
1356                 return ProcXF86VidModeSwitchToMode(client);
1357             case X_XF86VidModeLockModeSwitch:
1358                 return ProcXF86VidModeLockModeSwitch(client);
1359             case X_XF86VidModeSetViewPort:
1360                 return ProcXF86VidModeSetViewPort(client);
1361             default:
1362                 return BadRequest;
1363             }
1364         } else
1365             return vidmodeErrorBase + XF86VidModeClientNotLocal;
1366     }
1367 }
1368
1369 static int
1370 SProcXF86VidModeQueryVersion(client)
1371     register ClientPtr  client;
1372 {
1373     register int n;
1374     REQUEST(xXF86VidModeQueryVersionReq);
1375     swaps(&stuff->length, n);
1376     return ProcXF86VidModeQueryVersion(client);
1377 }
1378
1379 static int
1380 SProcXF86VidModeGetModeLine(client)
1381     ClientPtr client;
1382 {
1383     register int n;
1384     REQUEST(xXF86VidModeGetModeLineReq);
1385     swaps(&stuff->length, n);
1386     REQUEST_SIZE_MATCH(xXF86VidModeGetModeLineReq);
1387     swaps(&stuff->screen, n);
1388     return ProcXF86VidModeGetModeLine(client);
1389 }
1390
1391 static int
1392 SProcXF86VidModeGetAllModeLines(client)
1393     ClientPtr client;
1394 {
1395     register int n;
1396     REQUEST(xXF86VidModeGetAllModeLinesReq);
1397     swaps(&stuff->length, n);
1398     REQUEST_SIZE_MATCH(xXF86VidModeGetAllModeLinesReq);
1399     swaps(&stuff->screen, n);
1400     return ProcXF86VidModeGetAllModeLines(client);
1401 }
1402
1403 static int
1404 SProcXF86VidModeAddModeLine(client)
1405     ClientPtr client;
1406 {
1407     register int n;
1408     REQUEST(xXF86VidModeAddModeLineReq);
1409     swaps(&stuff->length, n);
1410     REQUEST_AT_LEAST_SIZE(xXF86VidModeAddModeLineReq);
1411     swapl(&stuff->screen, n);
1412     swaps(&stuff->hdisplay, n);
1413     swaps(&stuff->hsyncstart, n);
1414     swaps(&stuff->hsyncend, n);
1415     swaps(&stuff->htotal, n);
1416     swaps(&stuff->vdisplay, n);
1417     swaps(&stuff->vsyncstart, n);
1418     swaps(&stuff->vsyncend, n);
1419     swaps(&stuff->vtotal, n);
1420     swapl(&stuff->flags, n);
1421     swapl(&stuff->privsize, n);
1422     SwapRestL(stuff);
1423     return ProcXF86VidModeAddModeLine(client);
1424 }
1425
1426 static int
1427 SProcXF86VidModeDeleteModeLine(client)
1428     ClientPtr client;
1429 {
1430     register int n;
1431     REQUEST(xXF86VidModeDeleteModeLineReq);
1432     swaps(&stuff->length, n);
1433     REQUEST_AT_LEAST_SIZE(xXF86VidModeDeleteModeLineReq);
1434     swapl(&stuff->screen, n);
1435     swaps(&stuff->hdisplay, n);
1436     swaps(&stuff->hsyncstart, n);
1437     swaps(&stuff->hsyncend, n);
1438     swaps(&stuff->htotal, n);
1439     swaps(&stuff->vdisplay, n);
1440     swaps(&stuff->vsyncstart, n);
1441     swaps(&stuff->vsyncend, n);
1442     swaps(&stuff->vtotal, n);
1443     swapl(&stuff->flags, n);
1444     swapl(&stuff->privsize, n);
1445     SwapRestL(stuff);
1446     return ProcXF86VidModeDeleteModeLine(client);
1447 }
1448
1449 static int
1450 SProcXF86VidModeModModeLine(client)
1451     ClientPtr client;
1452 {
1453     register int n;
1454     REQUEST(xXF86VidModeModModeLineReq);
1455     swaps(&stuff->length, n);
1456     REQUEST_AT_LEAST_SIZE(xXF86VidModeModModeLineReq);
1457     swapl(&stuff->screen, n);
1458     swaps(&stuff->hdisplay, n);
1459     swaps(&stuff->hsyncstart, n);
1460     swaps(&stuff->hsyncend, n);
1461     swaps(&stuff->htotal, n);
1462     swaps(&stuff->vdisplay, n);
1463     swaps(&stuff->vsyncstart, n);
1464     swaps(&stuff->vsyncend, n);
1465     swaps(&stuff->vtotal, n);
1466     swapl(&stuff->flags, n);
1467     swapl(&stuff->privsize, n);
1468     SwapRestL(stuff);
1469     return ProcXF86VidModeModModeLine(client);
1470 }
1471
1472 static int
1473 SProcXF86VidModeValidateModeLine(client)
1474     ClientPtr client;
1475 {
1476     register int n;
1477     REQUEST(xXF86VidModeValidateModeLineReq);
1478     swaps(&stuff->length, n);
1479     REQUEST_AT_LEAST_SIZE(xXF86VidModeValidateModeLineReq);
1480     swapl(&stuff->screen, n);
1481     swaps(&stuff->hdisplay, n);
1482     swaps(&stuff->hsyncstart, n);
1483     swaps(&stuff->hsyncend, n);
1484     swaps(&stuff->htotal, n);
1485     swaps(&stuff->vdisplay, n);
1486     swaps(&stuff->vsyncstart, n);
1487     swaps(&stuff->vsyncend, n);
1488     swaps(&stuff->vtotal, n);
1489     swapl(&stuff->flags, n);
1490     swapl(&stuff->privsize, n);
1491     SwapRestL(stuff);
1492     return ProcXF86VidModeValidateModeLine(client);
1493 }
1494
1495 static int
1496 SProcXF86VidModeSwitchMode(client)
1497     ClientPtr client;
1498 {
1499     register int n;
1500     REQUEST(xXF86VidModeSwitchModeReq);
1501     swaps(&stuff->length, n);
1502     REQUEST_SIZE_MATCH(xXF86VidModeSwitchModeReq);
1503     swaps(&stuff->screen, n);
1504     swaps(&stuff->zoom, n);
1505     return ProcXF86VidModeSwitchMode(client);
1506 }
1507
1508 static int
1509 SProcXF86VidModeSwitchToMode(client)
1510     ClientPtr client;
1511 {
1512     register int n;
1513     REQUEST(xXF86VidModeSwitchToModeReq);
1514     swaps(&stuff->length, n);
1515     REQUEST_SIZE_MATCH(xXF86VidModeSwitchToModeReq);
1516     swaps(&stuff->screen, n);
1517     return ProcXF86VidModeSwitchToMode(client);
1518 }
1519
1520 static int
1521 SProcXF86VidModeLockModeSwitch(client)
1522     ClientPtr client;
1523 {
1524     register int n;
1525     REQUEST(xXF86VidModeLockModeSwitchReq);
1526     swaps(&stuff->length, n);
1527     REQUEST_SIZE_MATCH(xXF86VidModeLockModeSwitchReq);
1528     swaps(&stuff->screen, n);
1529     swaps(&stuff->lock, n);
1530     return ProcXF86VidModeLockModeSwitch(client);
1531 }
1532
1533 static int
1534 SProcXF86VidModeGetMonitor(client)
1535     ClientPtr client;
1536 {
1537     register int n;
1538     REQUEST(xXF86VidModeGetMonitorReq);
1539     swaps(&stuff->length, n);
1540     REQUEST_SIZE_MATCH(xXF86VidModeGetMonitorReq);
1541     swaps(&stuff->screen, n);
1542     return ProcXF86VidModeGetMonitor(client);
1543 }
1544
1545 static int
1546 SProcXF86VidModeGetViewPort(client)
1547     ClientPtr client;
1548 {
1549     register int n;
1550     REQUEST(xXF86VidModeGetViewPortReq);
1551     swaps(&stuff->length, n);
1552     REQUEST_SIZE_MATCH(xXF86VidModeGetViewPortReq);
1553     swaps(&stuff->screen, n);
1554     return ProcXF86VidModeGetViewPort(client);
1555 }
1556
1557 static int
1558 SProcXF86VidModeSetViewPort(client)
1559     ClientPtr client;
1560 {
1561     register int n;
1562     REQUEST(xXF86VidModeSetViewPortReq);
1563     swaps(&stuff->length, n);
1564     REQUEST_SIZE_MATCH(xXF86VidModeSetViewPortReq);
1565     swaps(&stuff->screen, n);
1566     swapl(&stuff->x, n);
1567     swapl(&stuff->y, n);
1568     return ProcXF86VidModeSetViewPort(client);
1569 }
1570
1571 static int
1572 SProcXF86VidModeDispatch (client)
1573     register ClientPtr  client;
1574 {
1575     REQUEST(xReq);
1576     switch (stuff->data)
1577     {
1578     case X_XF86VidModeQueryVersion:
1579         return SProcXF86VidModeQueryVersion(client);
1580     case X_XF86VidModeGetModeLine:
1581         return SProcXF86VidModeGetModeLine(client);
1582     case X_XF86VidModeGetAllModeLines:
1583         return SProcXF86VidModeGetAllModeLines(client);
1584     case X_XF86VidModeGetMonitor:
1585         return SProcXF86VidModeGetMonitor(client);
1586     case X_XF86VidModeGetViewPort:
1587         return SProcXF86VidModeGetViewPort(client);
1588     case X_XF86VidModeValidateModeLine:
1589         return SProcXF86VidModeValidateModeLine(client);
1590     default:
1591         if (!xf86VidModeEnabled)
1592             return vidmodeErrorBase + XF86VidModeExtensionDisabled;
1593         if (xf86VidModeAllowNonLocal || LocalClient(client)) {
1594             switch (stuff->data) {
1595             case X_XF86VidModeAddModeLine:
1596                 return SProcXF86VidModeAddModeLine(client);
1597             case X_XF86VidModeDeleteModeLine:
1598                 return SProcXF86VidModeDeleteModeLine(client);
1599             case X_XF86VidModeModModeLine:
1600                 return SProcXF86VidModeModModeLine(client);
1601             case X_XF86VidModeSwitchMode:
1602                 return SProcXF86VidModeSwitchMode(client);
1603             case X_XF86VidModeSwitchToMode:
1604                 return SProcXF86VidModeSwitchToMode(client);
1605             case X_XF86VidModeLockModeSwitch:
1606                 return SProcXF86VidModeLockModeSwitch(client);
1607             case X_XF86VidModeSetViewPort:
1608                 return SProcXF86VidModeSetViewPort(client);
1609             default:
1610                 return BadRequest;
1611             }
1612         } else
1613             return vidmodeErrorBase + XF86VidModeClientNotLocal;
1614     }
1615 }