1706f2543Smrg/*
2706f2543Smrg *
3706f2543Smrg * Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc.
4706f2543Smrg *
5706f2543Smrg * Permission to use, copy, modify, distribute, and sell this software and its
6706f2543Smrg * documentation for any purpose is hereby granted without fee, provided that
7706f2543Smrg * the above copyright notice appear in all copies and that both that
8706f2543Smrg * copyright notice and this permission notice appear in supporting
9706f2543Smrg * documentation, and that the name of Keith Packard not be used in
10706f2543Smrg * advertising or publicity pertaining to distribution of the software without
11706f2543Smrg * specific, written prior permission.  Keith Packard makes no
12706f2543Smrg * representations about the suitability of this software for any purpose.  It
13706f2543Smrg * is provided "as is" without express or implied warranty.
14706f2543Smrg *
15706f2543Smrg * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16706f2543Smrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
17706f2543Smrg * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18706f2543Smrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
19706f2543Smrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
20706f2543Smrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
21706f2543Smrg * PERFORMANCE OF THIS SOFTWARE.
22706f2543Smrg */
23706f2543Smrg
24706f2543Smrg#ifdef HAVE_XORG_CONFIG_H
25706f2543Smrg#include <xorg-config.h>
26706f2543Smrg#endif
27706f2543Smrg
28706f2543Smrg#include <X11/X.h>
29706f2543Smrg#include "os.h"
30706f2543Smrg#include "globals.h"
31706f2543Smrg#include "xf86.h"
32706f2543Smrg#include "xf86str.h"
33706f2543Smrg#include "xf86Priv.h"
34706f2543Smrg#include "xf86DDC.h"
35706f2543Smrg#include "mipointer.h"
36706f2543Smrg#include <randrstr.h>
37706f2543Smrg#include "inputstr.h"
38706f2543Smrg
39706f2543Smrgtypedef struct _xf86RandRInfo {
40706f2543Smrg    CreateScreenResourcesProcPtr    CreateScreenResources;
41706f2543Smrg    CloseScreenProcPtr		    CloseScreen;
42706f2543Smrg    int				    virtualX;
43706f2543Smrg    int				    virtualY;
44706f2543Smrg    int				    mmWidth;
45706f2543Smrg    int				    mmHeight;
46706f2543Smrg    Rotation			    rotation;
47706f2543Smrg} XF86RandRInfoRec, *XF86RandRInfoPtr;
48706f2543Smrg
49706f2543Smrgstatic DevPrivateKeyRec xf86RandRKeyRec;
50706f2543Smrgstatic DevPrivateKey xf86RandRKey;
51706f2543Smrg
52706f2543Smrg#define XF86RANDRINFO(p) ((XF86RandRInfoPtr)dixLookupPrivate(&(p)->devPrivates, xf86RandRKey))
53706f2543Smrg
54706f2543Smrgstatic int
55706f2543Smrgxf86RandRModeRefresh (DisplayModePtr mode)
56706f2543Smrg{
57706f2543Smrg    if (mode->VRefresh)
58706f2543Smrg	return (int) (mode->VRefresh + 0.5);
59706f2543Smrg    else if (mode->Clock == 0)
60706f2543Smrg	return 0;
61706f2543Smrg    else
62706f2543Smrg	return (int) (mode->Clock * 1000.0 / mode->HTotal / mode->VTotal + 0.5);
63706f2543Smrg}
64706f2543Smrg
65706f2543Smrgstatic Bool
66706f2543Smrgxf86RandRGetInfo (ScreenPtr pScreen, Rotation *rotations)
67706f2543Smrg{
68706f2543Smrg    RRScreenSizePtr	    pSize;
69706f2543Smrg    ScrnInfoPtr		    scrp = XF86SCRNINFO(pScreen);
70706f2543Smrg    XF86RandRInfoPtr	    randrp = XF86RANDRINFO(pScreen);
71706f2543Smrg    DisplayModePtr	    mode;
72706f2543Smrg    int			    refresh0 = 60;
73706f2543Smrg    xorgRRModeMM	    RRModeMM;
74706f2543Smrg
75706f2543Smrg    *rotations = RR_Rotate_0;
76706f2543Smrg
77706f2543Smrg    for (mode = scrp->modes; mode != NULL ; mode = mode->next)
78706f2543Smrg    {
79706f2543Smrg	int refresh = xf86RandRModeRefresh (mode);
80706f2543Smrg
81706f2543Smrg	if (mode == scrp->modes)
82706f2543Smrg	    refresh0 = refresh;
83706f2543Smrg
84706f2543Smrg	RRModeMM.mode = mode;
85706f2543Smrg	RRModeMM.virtX = randrp->virtualX;
86706f2543Smrg	RRModeMM.virtY = randrp->virtualY;
87706f2543Smrg	RRModeMM.mmWidth = randrp->mmWidth;
88706f2543Smrg	RRModeMM.mmHeight = randrp->mmHeight;
89706f2543Smrg
90706f2543Smrg	if(scrp->DriverFunc) {
91706f2543Smrg	   (*scrp->DriverFunc)(scrp, RR_GET_MODE_MM, &RRModeMM);
92706f2543Smrg	}
93706f2543Smrg
94706f2543Smrg	pSize = RRRegisterSize (pScreen,
95706f2543Smrg				mode->HDisplay, mode->VDisplay,
96706f2543Smrg				RRModeMM.mmWidth, RRModeMM.mmHeight);
97706f2543Smrg	if (!pSize)
98706f2543Smrg	    return FALSE;
99706f2543Smrg	RRRegisterRate (pScreen, pSize, refresh);
100706f2543Smrg	if (mode == scrp->currentMode &&
101706f2543Smrg	    mode->HDisplay == scrp->virtualX && mode->VDisplay == scrp->virtualY)
102706f2543Smrg	    RRSetCurrentConfig (pScreen, randrp->rotation, refresh, pSize);
103706f2543Smrg	if (mode->next == scrp->modes)
104706f2543Smrg	    break;
105706f2543Smrg    }
106706f2543Smrg    if (scrp->currentMode->HDisplay != randrp->virtualX ||
107706f2543Smrg	scrp->currentMode->VDisplay != randrp->virtualY)
108706f2543Smrg    {
109706f2543Smrg	mode = scrp->modes;
110706f2543Smrg
111706f2543Smrg	RRModeMM.mode = NULL;
112706f2543Smrg	RRModeMM.virtX = randrp->virtualX;
113706f2543Smrg	RRModeMM.virtY = randrp->virtualY;
114706f2543Smrg	RRModeMM.mmWidth = randrp->mmWidth;
115706f2543Smrg	RRModeMM.mmHeight = randrp->mmHeight;
116706f2543Smrg
117706f2543Smrg	if(scrp->DriverFunc) {
118706f2543Smrg	   (*scrp->DriverFunc)(scrp, RR_GET_MODE_MM, &RRModeMM);
119706f2543Smrg	}
120706f2543Smrg
121706f2543Smrg	pSize = RRRegisterSize (pScreen,
122706f2543Smrg				randrp->virtualX, randrp->virtualY,
123706f2543Smrg				RRModeMM.mmWidth, RRModeMM.mmHeight);
124706f2543Smrg	if (!pSize)
125706f2543Smrg	    return FALSE;
126706f2543Smrg	RRRegisterRate (pScreen, pSize, refresh0);
127706f2543Smrg	if (scrp->virtualX == randrp->virtualX &&
128706f2543Smrg	    scrp->virtualY == randrp->virtualY)
129706f2543Smrg	{
130706f2543Smrg	    RRSetCurrentConfig (pScreen, randrp->rotation, refresh0, pSize);
131706f2543Smrg	}
132706f2543Smrg    }
133706f2543Smrg
134706f2543Smrg    /* If there is driver support for randr, let it set our supported rotations */
135706f2543Smrg    if(scrp->DriverFunc) {
136706f2543Smrg	xorgRRRotation RRRotation;
137706f2543Smrg
138706f2543Smrg	RRRotation.RRRotations = *rotations;
139706f2543Smrg	if (!(*scrp->DriverFunc)(scrp, RR_GET_INFO, &RRRotation))
140706f2543Smrg	    return TRUE;
141706f2543Smrg	*rotations = RRRotation.RRRotations;
142706f2543Smrg    }
143706f2543Smrg
144706f2543Smrg    return TRUE;
145706f2543Smrg}
146706f2543Smrg
147706f2543Smrgstatic Bool
148706f2543Smrgxf86RandRSetMode (ScreenPtr	    pScreen,
149706f2543Smrg		  DisplayModePtr    mode,
150706f2543Smrg		  Bool		    useVirtual,
151706f2543Smrg		  int		    mmWidth,
152706f2543Smrg		  int		    mmHeight)
153706f2543Smrg{
154706f2543Smrg    ScrnInfoPtr		scrp = XF86SCRNINFO(pScreen);
155706f2543Smrg    XF86RandRInfoPtr	randrp = XF86RANDRINFO(pScreen);
156706f2543Smrg    int			oldWidth = pScreen->width;
157706f2543Smrg    int			oldHeight = pScreen->height;
158706f2543Smrg    int			oldmmWidth = pScreen->mmWidth;
159706f2543Smrg    int			oldmmHeight = pScreen->mmHeight;
160706f2543Smrg    int			oldVirtualX = scrp->virtualX;
161706f2543Smrg    int			oldVirtualY = scrp->virtualY;
162706f2543Smrg    WindowPtr		pRoot = pScreen->root;
163706f2543Smrg    Bool		ret = TRUE;
164706f2543Smrg
165706f2543Smrg    if (pRoot && scrp->vtSema)
166706f2543Smrg	(*scrp->EnableDisableFBAccess) (pScreen->myNum, FALSE);
167706f2543Smrg    if (useVirtual)
168706f2543Smrg    {
169706f2543Smrg	scrp->virtualX = randrp->virtualX;
170706f2543Smrg	scrp->virtualY = randrp->virtualY;
171706f2543Smrg    }
172706f2543Smrg    else
173706f2543Smrg    {
174706f2543Smrg	scrp->virtualX = mode->HDisplay;
175706f2543Smrg	scrp->virtualY = mode->VDisplay;
176706f2543Smrg    }
177706f2543Smrg
178706f2543Smrg    /*
179706f2543Smrg     * The DIX forgets the physical dimensions we passed into RRRegisterSize, so
180706f2543Smrg     * reconstruct them if possible.
181706f2543Smrg     */
182706f2543Smrg    if(scrp->DriverFunc) {
183706f2543Smrg	xorgRRModeMM RRModeMM;
184706f2543Smrg
185706f2543Smrg	RRModeMM.mode = mode;
186706f2543Smrg	RRModeMM.virtX = scrp->virtualX;
187706f2543Smrg	RRModeMM.virtY = scrp->virtualY;
188706f2543Smrg	RRModeMM.mmWidth = mmWidth;
189706f2543Smrg	RRModeMM.mmHeight = mmHeight;
190706f2543Smrg
191706f2543Smrg	(*scrp->DriverFunc)(scrp, RR_GET_MODE_MM, &RRModeMM);
192706f2543Smrg
193706f2543Smrg	mmWidth = RRModeMM.mmWidth;
194706f2543Smrg	mmHeight = RRModeMM.mmHeight;
195706f2543Smrg    }
196706f2543Smrg    if(randrp->rotation & (RR_Rotate_90 | RR_Rotate_270))
197706f2543Smrg    {
198706f2543Smrg	/* If the screen is rotated 90 or 270 degrees, swap the sizes. */
199706f2543Smrg	pScreen->width = scrp->virtualY;
200706f2543Smrg	pScreen->height = scrp->virtualX;
201706f2543Smrg	pScreen->mmWidth = mmHeight;
202706f2543Smrg	pScreen->mmHeight = mmWidth;
203706f2543Smrg    }
204706f2543Smrg    else
205706f2543Smrg    {
206706f2543Smrg	pScreen->width = scrp->virtualX;
207706f2543Smrg	pScreen->height = scrp->virtualY;
208706f2543Smrg	pScreen->mmWidth = mmWidth;
209706f2543Smrg	pScreen->mmHeight = mmHeight;
210706f2543Smrg    }
211706f2543Smrg    if (!xf86SwitchMode (pScreen, mode))
212706f2543Smrg    {
213706f2543Smrg	pScreen->width = oldWidth;
214706f2543Smrg	pScreen->height = oldHeight;
215706f2543Smrg	pScreen->mmWidth = oldmmWidth;
216706f2543Smrg	pScreen->mmHeight = oldmmHeight;
217706f2543Smrg	scrp->virtualX = oldVirtualX;
218706f2543Smrg	scrp->virtualY = oldVirtualY;
219706f2543Smrg	ret = FALSE;
220706f2543Smrg    }
221706f2543Smrg    /*
222706f2543Smrg     * Make sure the layout is correct
223706f2543Smrg     */
224706f2543Smrg    xf86ReconfigureLayout();
225706f2543Smrg
226706f2543Smrg    /*
227706f2543Smrg     * Make sure the whole screen is visible
228706f2543Smrg     */
229706f2543Smrg    xf86SetViewport (pScreen, pScreen->width, pScreen->height);
230706f2543Smrg    xf86SetViewport (pScreen, 0, 0);
231706f2543Smrg    if (pRoot && scrp->vtSema)
232706f2543Smrg	(*scrp->EnableDisableFBAccess) (pScreen->myNum, TRUE);
233706f2543Smrg    return ret;
234706f2543Smrg}
235706f2543Smrg
236706f2543Smrgstatic Bool
237706f2543Smrgxf86RandRSetConfig (ScreenPtr		pScreen,
238706f2543Smrg		    Rotation		rotation,
239706f2543Smrg		    int			rate,
240706f2543Smrg		    RRScreenSizePtr	pSize)
241706f2543Smrg{
242706f2543Smrg    ScrnInfoPtr		    scrp = XF86SCRNINFO(pScreen);
243706f2543Smrg    XF86RandRInfoPtr	    randrp = XF86RANDRINFO(pScreen);
244706f2543Smrg    DisplayModePtr	    mode;
245706f2543Smrg    int			    px, py;
246706f2543Smrg    Bool		    useVirtual = FALSE;
247706f2543Smrg    Rotation		    oldRotation = randrp->rotation;
248706f2543Smrg
249706f2543Smrg    miPointerGetPosition(inputInfo.pointer, &px, &py);
250706f2543Smrg    for (mode = scrp->modes; ; mode = mode->next)
251706f2543Smrg    {
252706f2543Smrg	if (mode->HDisplay == pSize->width &&
253706f2543Smrg	    mode->VDisplay == pSize->height &&
254706f2543Smrg	    (rate == 0 || xf86RandRModeRefresh (mode) == rate))
255706f2543Smrg	    break;
256706f2543Smrg	if (mode->next == scrp->modes)
257706f2543Smrg	{
258706f2543Smrg	    if (pSize->width == randrp->virtualX &&
259706f2543Smrg		pSize->height == randrp->virtualY)
260706f2543Smrg	    {
261706f2543Smrg		mode = scrp->modes;
262706f2543Smrg		useVirtual = TRUE;
263706f2543Smrg		break;
264706f2543Smrg	    }
265706f2543Smrg	    return FALSE;
266706f2543Smrg	}
267706f2543Smrg    }
268706f2543Smrg
269706f2543Smrg    if (randrp->rotation != rotation) {
270706f2543Smrg
271706f2543Smrg        /* Have the driver do its thing. */
272706f2543Smrg	if (scrp->DriverFunc) {
273706f2543Smrg	    xorgRRRotation RRRotation;
274706f2543Smrg	    RRRotation.RRConfig.rotation = rotation;
275706f2543Smrg	    RRRotation.RRConfig.rate = rate;
276706f2543Smrg	    RRRotation.RRConfig.width = pSize->width;
277706f2543Smrg	    RRRotation.RRConfig.height = pSize->height;
278706f2543Smrg
279706f2543Smrg	    /*
280706f2543Smrg	     * Currently we need to rely on HW support for rotation.
281706f2543Smrg	     */
282706f2543Smrg	    if (!(*scrp->DriverFunc)(scrp, RR_SET_CONFIG, &RRRotation))
283706f2543Smrg		return FALSE;
284706f2543Smrg	} else
285706f2543Smrg	    return FALSE;
286706f2543Smrg
287706f2543Smrg	randrp->rotation = rotation;
288706f2543Smrg    }
289706f2543Smrg
290706f2543Smrg    if (!xf86RandRSetMode (pScreen, mode, useVirtual, pSize->mmWidth, pSize->mmHeight)) {
291706f2543Smrg	if(randrp->rotation != oldRotation) {
292706f2543Smrg	   /* Have the driver undo its thing. */
293706f2543Smrg	   if (scrp->DriverFunc) {
294706f2543Smrg	       xorgRRRotation RRRotation;
295706f2543Smrg	       RRRotation.RRConfig.rotation = oldRotation;
296706f2543Smrg	       RRRotation.RRConfig.rate = xf86RandRModeRefresh (scrp->currentMode);
297706f2543Smrg	       RRRotation.RRConfig.width = scrp->virtualX;
298706f2543Smrg	       RRRotation.RRConfig.height = scrp->virtualY;
299706f2543Smrg	       (*scrp->DriverFunc)(scrp, RR_SET_CONFIG, &RRRotation);
300706f2543Smrg	   }
301706f2543Smrg
302706f2543Smrg	   randrp->rotation = oldRotation;
303706f2543Smrg	}
304706f2543Smrg	return FALSE;
305706f2543Smrg    }
306706f2543Smrg    /*
307706f2543Smrg     * Move the cursor back where it belongs; SwitchMode repositions it
308706f2543Smrg     */
309706f2543Smrg    if (pScreen == miPointerCurrentScreen ())
310706f2543Smrg    {
311706f2543Smrg	px = (px >= pScreen->width ? (pScreen->width - 1) : px);
312706f2543Smrg	py = (py >= pScreen->height ? (pScreen->height - 1) : py);
313706f2543Smrg
314706f2543Smrg        xf86SetViewport(pScreen, px, py);
315706f2543Smrg
316706f2543Smrg        (*pScreen->SetCursorPosition) (inputInfo.pointer, pScreen, px, py, FALSE);
317706f2543Smrg    }
318706f2543Smrg
319706f2543Smrg    return TRUE;
320706f2543Smrg}
321706f2543Smrg
322706f2543Smrg/*
323706f2543Smrg * Wait until the screen is initialized before whacking the
324706f2543Smrg * sizes around; otherwise the screen pixmap will be allocated
325706f2543Smrg * at the current mode size rather than the maximum size
326706f2543Smrg */
327706f2543Smrgstatic Bool
328706f2543Smrgxf86RandRCreateScreenResources (ScreenPtr pScreen)
329706f2543Smrg{
330706f2543Smrg    XF86RandRInfoPtr	    randrp = XF86RANDRINFO(pScreen);
331706f2543Smrg#if 0
332706f2543Smrg    ScrnInfoPtr		    scrp = XF86SCRNINFO(pScreen);
333706f2543Smrg    DisplayModePtr	    mode;
334706f2543Smrg#endif
335706f2543Smrg
336706f2543Smrg    pScreen->CreateScreenResources = randrp->CreateScreenResources;
337706f2543Smrg    if (!(*pScreen->CreateScreenResources) (pScreen))
338706f2543Smrg	return FALSE;
339706f2543Smrg
340706f2543Smrg#if 0
341706f2543Smrg    mode = scrp->currentMode;
342706f2543Smrg    if (mode)
343706f2543Smrg	xf86RandRSetMode (pScreen, mode, TRUE);
344706f2543Smrg#endif
345706f2543Smrg
346706f2543Smrg    return TRUE;
347706f2543Smrg}
348706f2543Smrg
349706f2543Smrg/*
350706f2543Smrg * Reset size back to original
351706f2543Smrg */
352706f2543Smrgstatic Bool
353706f2543Smrgxf86RandRCloseScreen (int index, ScreenPtr pScreen)
354706f2543Smrg{
355706f2543Smrg    ScrnInfoPtr		    scrp = XF86SCRNINFO(pScreen);
356706f2543Smrg    XF86RandRInfoPtr	    randrp = XF86RANDRINFO(pScreen);
357706f2543Smrg
358706f2543Smrg    scrp->virtualX = pScreen->width = randrp->virtualX;
359706f2543Smrg    scrp->virtualY = pScreen->height = randrp->virtualY;
360706f2543Smrg    scrp->currentMode = scrp->modes;
361706f2543Smrg    pScreen->CloseScreen = randrp->CloseScreen;
362706f2543Smrg    free(randrp);
363706f2543Smrg    dixSetPrivate(&pScreen->devPrivates, xf86RandRKey, NULL);
364706f2543Smrg    return (*pScreen->CloseScreen) (index, pScreen);
365706f2543Smrg}
366706f2543Smrg
367706f2543SmrgRotation
368706f2543Smrgxf86GetRotation(ScreenPtr pScreen)
369706f2543Smrg{
370706f2543Smrg    if (xf86RandRKey == NULL)
371706f2543Smrg       return RR_Rotate_0;
372706f2543Smrg
373706f2543Smrg    return XF86RANDRINFO(pScreen)->rotation;
374706f2543Smrg}
375706f2543Smrg
376706f2543Smrg/* Function to change RandR's idea of the virtual screen size */
377706f2543SmrgBool
378706f2543Smrgxf86RandRSetNewVirtualAndDimensions(ScreenPtr pScreen,
379706f2543Smrg	int newvirtX, int newvirtY, int newmmWidth, int newmmHeight,
380706f2543Smrg	Bool resetMode)
381706f2543Smrg{
382706f2543Smrg    XF86RandRInfoPtr randrp;
383706f2543Smrg
384706f2543Smrg    if (xf86RandRKey == NULL)
385706f2543Smrg	return FALSE;
386706f2543Smrg
387706f2543Smrg    randrp = XF86RANDRINFO(pScreen);
388706f2543Smrg    if (randrp == NULL)
389706f2543Smrg	return FALSE;
390706f2543Smrg
391706f2543Smrg    if (newvirtX > 0)
392706f2543Smrg	randrp->virtualX = newvirtX;
393706f2543Smrg
394706f2543Smrg    if (newvirtY > 0)
395706f2543Smrg	randrp->virtualY = newvirtY;
396706f2543Smrg
397706f2543Smrg    if (newmmWidth > 0)
398706f2543Smrg	randrp->mmWidth = newmmWidth;
399706f2543Smrg
400706f2543Smrg    if (newmmHeight > 0)
401706f2543Smrg	randrp->mmHeight = newmmHeight;
402706f2543Smrg
403706f2543Smrg    /* This is only for during server start */
404706f2543Smrg    if (resetMode) {
405706f2543Smrg	return (xf86RandRSetMode(pScreen,
406706f2543Smrg		  XF86SCRNINFO(pScreen)->currentMode,
407706f2543Smrg		  TRUE,
408706f2543Smrg		  pScreen->mmWidth, pScreen->mmHeight));
409706f2543Smrg    }
410706f2543Smrg
411706f2543Smrg    return TRUE;
412706f2543Smrg}
413706f2543Smrg
414706f2543SmrgBool
415706f2543Smrgxf86RandRInit (ScreenPtr    pScreen)
416706f2543Smrg{
417706f2543Smrg    rrScrPrivPtr	rp;
418706f2543Smrg    XF86RandRInfoPtr	randrp;
419706f2543Smrg    ScrnInfoPtr		scrp = XF86SCRNINFO(pScreen);
420706f2543Smrg
421706f2543Smrg#ifdef PANORAMIX
422706f2543Smrg    /* XXX disable RandR when using Xinerama */
423706f2543Smrg    if (!noPanoramiXExtension)
424706f2543Smrg	return TRUE;
425706f2543Smrg#endif
426706f2543Smrg
427706f2543Smrg    xf86RandRKey = &xf86RandRKeyRec;
428706f2543Smrg
429706f2543Smrg    if (!dixRegisterPrivateKey(&xf86RandRKeyRec, PRIVATE_SCREEN, 0))
430706f2543Smrg	return FALSE;
431706f2543Smrg
432706f2543Smrg    randrp = malloc(sizeof (XF86RandRInfoRec));
433706f2543Smrg    if (!randrp)
434706f2543Smrg	return FALSE;
435706f2543Smrg
436706f2543Smrg    if (!RRScreenInit (pScreen))
437706f2543Smrg    {
438706f2543Smrg	free(randrp);
439706f2543Smrg	return FALSE;
440706f2543Smrg    }
441706f2543Smrg    rp = rrGetScrPriv(pScreen);
442706f2543Smrg    rp->rrGetInfo = xf86RandRGetInfo;
443706f2543Smrg    rp->rrSetConfig = xf86RandRSetConfig;
444706f2543Smrg
445706f2543Smrg    randrp->virtualX = scrp->virtualX;
446706f2543Smrg    randrp->virtualY = scrp->virtualY;
447706f2543Smrg    randrp->mmWidth = pScreen->mmWidth;
448706f2543Smrg    randrp->mmHeight = pScreen->mmHeight;
449706f2543Smrg
450706f2543Smrg    randrp->CreateScreenResources = pScreen->CreateScreenResources;
451706f2543Smrg    pScreen->CreateScreenResources = xf86RandRCreateScreenResources;
452706f2543Smrg
453706f2543Smrg    randrp->CloseScreen = pScreen->CloseScreen;
454706f2543Smrg    pScreen->CloseScreen = xf86RandRCloseScreen;
455706f2543Smrg
456706f2543Smrg    randrp->rotation = RR_Rotate_0;
457706f2543Smrg
458706f2543Smrg    dixSetPrivate(&pScreen->devPrivates, xf86RandRKey, randrp);
459706f2543Smrg    return TRUE;
460706f2543Smrg}
461706f2543Smrg
462706f2543Smrg
463