xref: /OK3568_Linux_fs/external/xserver/hw/xfree86/common/xf86RandR.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  *
3*4882a593Smuzhiyun  * Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc.
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Permission to use, copy, modify, distribute, and sell this software and its
6*4882a593Smuzhiyun  * documentation for any purpose is hereby granted without fee, provided that
7*4882a593Smuzhiyun  * the above copyright notice appear in all copies and that both that
8*4882a593Smuzhiyun  * copyright notice and this permission notice appear in supporting
9*4882a593Smuzhiyun  * documentation, and that the name of Keith Packard not be used in
10*4882a593Smuzhiyun  * advertising or publicity pertaining to distribution of the software without
11*4882a593Smuzhiyun  * specific, written prior permission.  Keith Packard makes no
12*4882a593Smuzhiyun  * representations about the suitability of this software for any purpose.  It
13*4882a593Smuzhiyun  * is provided "as is" without express or implied warranty.
14*4882a593Smuzhiyun  *
15*4882a593Smuzhiyun  * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16*4882a593Smuzhiyun  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
17*4882a593Smuzhiyun  * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18*4882a593Smuzhiyun  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
19*4882a593Smuzhiyun  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
20*4882a593Smuzhiyun  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
21*4882a593Smuzhiyun  * PERFORMANCE OF THIS SOFTWARE.
22*4882a593Smuzhiyun  */
23*4882a593Smuzhiyun 
24*4882a593Smuzhiyun #ifdef HAVE_XORG_CONFIG_H
25*4882a593Smuzhiyun #include <xorg-config.h>
26*4882a593Smuzhiyun #endif
27*4882a593Smuzhiyun 
28*4882a593Smuzhiyun #include <X11/X.h>
29*4882a593Smuzhiyun #include "os.h"
30*4882a593Smuzhiyun #include "globals.h"
31*4882a593Smuzhiyun #include "xf86.h"
32*4882a593Smuzhiyun #include "xf86str.h"
33*4882a593Smuzhiyun #include "xf86Priv.h"
34*4882a593Smuzhiyun #include "xf86DDC.h"
35*4882a593Smuzhiyun #include "mipointer.h"
36*4882a593Smuzhiyun #include <randrstr.h>
37*4882a593Smuzhiyun #include "inputstr.h"
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun typedef struct _xf86RandRInfo {
40*4882a593Smuzhiyun     CloseScreenProcPtr CloseScreen;
41*4882a593Smuzhiyun     int virtualX;
42*4882a593Smuzhiyun     int virtualY;
43*4882a593Smuzhiyun     int mmWidth;
44*4882a593Smuzhiyun     int mmHeight;
45*4882a593Smuzhiyun     Rotation rotation;
46*4882a593Smuzhiyun } XF86RandRInfoRec, *XF86RandRInfoPtr;
47*4882a593Smuzhiyun 
48*4882a593Smuzhiyun static DevPrivateKeyRec xf86RandRKeyRec;
49*4882a593Smuzhiyun static DevPrivateKey xf86RandRKey;
50*4882a593Smuzhiyun 
51*4882a593Smuzhiyun #define XF86RANDRINFO(p) ((XF86RandRInfoPtr)dixLookupPrivate(&(p)->devPrivates, xf86RandRKey))
52*4882a593Smuzhiyun 
53*4882a593Smuzhiyun static int
xf86RandRModeRefresh(DisplayModePtr mode)54*4882a593Smuzhiyun xf86RandRModeRefresh(DisplayModePtr mode)
55*4882a593Smuzhiyun {
56*4882a593Smuzhiyun     if (mode->VRefresh)
57*4882a593Smuzhiyun         return (int) (mode->VRefresh + 0.5);
58*4882a593Smuzhiyun     else if (mode->Clock == 0)
59*4882a593Smuzhiyun         return 0;
60*4882a593Smuzhiyun     else
61*4882a593Smuzhiyun         return (int) (mode->Clock * 1000.0 / mode->HTotal / mode->VTotal + 0.5);
62*4882a593Smuzhiyun }
63*4882a593Smuzhiyun 
64*4882a593Smuzhiyun static Bool
xf86RandRGetInfo(ScreenPtr pScreen,Rotation * rotations)65*4882a593Smuzhiyun xf86RandRGetInfo(ScreenPtr pScreen, Rotation * rotations)
66*4882a593Smuzhiyun {
67*4882a593Smuzhiyun     RRScreenSizePtr pSize;
68*4882a593Smuzhiyun     ScrnInfoPtr scrp = xf86ScreenToScrn(pScreen);
69*4882a593Smuzhiyun     XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
70*4882a593Smuzhiyun     DisplayModePtr mode;
71*4882a593Smuzhiyun     int refresh0 = 60;
72*4882a593Smuzhiyun     xorgRRModeMM RRModeMM;
73*4882a593Smuzhiyun 
74*4882a593Smuzhiyun     *rotations = RR_Rotate_0;
75*4882a593Smuzhiyun 
76*4882a593Smuzhiyun     for (mode = scrp->modes; mode != NULL; mode = mode->next) {
77*4882a593Smuzhiyun         int refresh = xf86RandRModeRefresh(mode);
78*4882a593Smuzhiyun 
79*4882a593Smuzhiyun         if (mode == scrp->modes)
80*4882a593Smuzhiyun             refresh0 = refresh;
81*4882a593Smuzhiyun 
82*4882a593Smuzhiyun         RRModeMM.mode = mode;
83*4882a593Smuzhiyun         RRModeMM.virtX = randrp->virtualX;
84*4882a593Smuzhiyun         RRModeMM.virtY = randrp->virtualY;
85*4882a593Smuzhiyun         RRModeMM.mmWidth = randrp->mmWidth;
86*4882a593Smuzhiyun         RRModeMM.mmHeight = randrp->mmHeight;
87*4882a593Smuzhiyun 
88*4882a593Smuzhiyun         if (scrp->DriverFunc) {
89*4882a593Smuzhiyun             (*scrp->DriverFunc) (scrp, RR_GET_MODE_MM, &RRModeMM);
90*4882a593Smuzhiyun         }
91*4882a593Smuzhiyun 
92*4882a593Smuzhiyun         pSize = RRRegisterSize(pScreen,
93*4882a593Smuzhiyun                                mode->HDisplay, mode->VDisplay,
94*4882a593Smuzhiyun                                RRModeMM.mmWidth, RRModeMM.mmHeight);
95*4882a593Smuzhiyun         if (!pSize)
96*4882a593Smuzhiyun             return FALSE;
97*4882a593Smuzhiyun         RRRegisterRate(pScreen, pSize, refresh);
98*4882a593Smuzhiyun         if (mode == scrp->currentMode &&
99*4882a593Smuzhiyun             mode->HDisplay == scrp->virtualX &&
100*4882a593Smuzhiyun             mode->VDisplay == scrp->virtualY)
101*4882a593Smuzhiyun             RRSetCurrentConfig(pScreen, randrp->rotation, refresh, pSize);
102*4882a593Smuzhiyun         if (mode->next == scrp->modes)
103*4882a593Smuzhiyun             break;
104*4882a593Smuzhiyun     }
105*4882a593Smuzhiyun     if (scrp->currentMode->HDisplay != randrp->virtualX ||
106*4882a593Smuzhiyun         scrp->currentMode->VDisplay != randrp->virtualY) {
107*4882a593Smuzhiyun         mode = scrp->modes;
108*4882a593Smuzhiyun 
109*4882a593Smuzhiyun         RRModeMM.mode = NULL;
110*4882a593Smuzhiyun         RRModeMM.virtX = randrp->virtualX;
111*4882a593Smuzhiyun         RRModeMM.virtY = randrp->virtualY;
112*4882a593Smuzhiyun         RRModeMM.mmWidth = randrp->mmWidth;
113*4882a593Smuzhiyun         RRModeMM.mmHeight = randrp->mmHeight;
114*4882a593Smuzhiyun 
115*4882a593Smuzhiyun         if (scrp->DriverFunc) {
116*4882a593Smuzhiyun             (*scrp->DriverFunc) (scrp, RR_GET_MODE_MM, &RRModeMM);
117*4882a593Smuzhiyun         }
118*4882a593Smuzhiyun 
119*4882a593Smuzhiyun         pSize = RRRegisterSize(pScreen,
120*4882a593Smuzhiyun                                randrp->virtualX, randrp->virtualY,
121*4882a593Smuzhiyun                                RRModeMM.mmWidth, RRModeMM.mmHeight);
122*4882a593Smuzhiyun         if (!pSize)
123*4882a593Smuzhiyun             return FALSE;
124*4882a593Smuzhiyun         RRRegisterRate(pScreen, pSize, refresh0);
125*4882a593Smuzhiyun         if (scrp->virtualX == randrp->virtualX &&
126*4882a593Smuzhiyun             scrp->virtualY == randrp->virtualY) {
127*4882a593Smuzhiyun             RRSetCurrentConfig(pScreen, randrp->rotation, refresh0, pSize);
128*4882a593Smuzhiyun         }
129*4882a593Smuzhiyun     }
130*4882a593Smuzhiyun 
131*4882a593Smuzhiyun     /* If there is driver support for randr, let it set our supported rotations */
132*4882a593Smuzhiyun     if (scrp->DriverFunc) {
133*4882a593Smuzhiyun         xorgRRRotation RRRotation;
134*4882a593Smuzhiyun 
135*4882a593Smuzhiyun         RRRotation.RRRotations = *rotations;
136*4882a593Smuzhiyun         if (!(*scrp->DriverFunc) (scrp, RR_GET_INFO, &RRRotation))
137*4882a593Smuzhiyun             return TRUE;
138*4882a593Smuzhiyun         *rotations = RRRotation.RRRotations;
139*4882a593Smuzhiyun     }
140*4882a593Smuzhiyun 
141*4882a593Smuzhiyun     return TRUE;
142*4882a593Smuzhiyun }
143*4882a593Smuzhiyun 
144*4882a593Smuzhiyun static Bool
xf86RandRSetMode(ScreenPtr pScreen,DisplayModePtr mode,Bool useVirtual,int mmWidth,int mmHeight)145*4882a593Smuzhiyun xf86RandRSetMode(ScreenPtr pScreen,
146*4882a593Smuzhiyun                  DisplayModePtr mode,
147*4882a593Smuzhiyun                  Bool useVirtual, int mmWidth, int mmHeight)
148*4882a593Smuzhiyun {
149*4882a593Smuzhiyun     ScrnInfoPtr scrp = xf86ScreenToScrn(pScreen);
150*4882a593Smuzhiyun     XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
151*4882a593Smuzhiyun     int oldWidth = pScreen->width;
152*4882a593Smuzhiyun     int oldHeight = pScreen->height;
153*4882a593Smuzhiyun     int oldmmWidth = pScreen->mmWidth;
154*4882a593Smuzhiyun     int oldmmHeight = pScreen->mmHeight;
155*4882a593Smuzhiyun     int oldVirtualX = scrp->virtualX;
156*4882a593Smuzhiyun     int oldVirtualY = scrp->virtualY;
157*4882a593Smuzhiyun     WindowPtr pRoot = pScreen->root;
158*4882a593Smuzhiyun     Bool ret = TRUE;
159*4882a593Smuzhiyun 
160*4882a593Smuzhiyun     if (pRoot && scrp->vtSema)
161*4882a593Smuzhiyun         (*scrp->EnableDisableFBAccess) (scrp, FALSE);
162*4882a593Smuzhiyun     if (useVirtual) {
163*4882a593Smuzhiyun         scrp->virtualX = randrp->virtualX;
164*4882a593Smuzhiyun         scrp->virtualY = randrp->virtualY;
165*4882a593Smuzhiyun     }
166*4882a593Smuzhiyun     else {
167*4882a593Smuzhiyun         scrp->virtualX = mode->HDisplay;
168*4882a593Smuzhiyun         scrp->virtualY = mode->VDisplay;
169*4882a593Smuzhiyun     }
170*4882a593Smuzhiyun 
171*4882a593Smuzhiyun     /*
172*4882a593Smuzhiyun      * The DIX forgets the physical dimensions we passed into RRRegisterSize, so
173*4882a593Smuzhiyun      * reconstruct them if possible.
174*4882a593Smuzhiyun      */
175*4882a593Smuzhiyun     if (scrp->DriverFunc) {
176*4882a593Smuzhiyun         xorgRRModeMM RRModeMM;
177*4882a593Smuzhiyun 
178*4882a593Smuzhiyun         RRModeMM.mode = mode;
179*4882a593Smuzhiyun         RRModeMM.virtX = scrp->virtualX;
180*4882a593Smuzhiyun         RRModeMM.virtY = scrp->virtualY;
181*4882a593Smuzhiyun         RRModeMM.mmWidth = mmWidth;
182*4882a593Smuzhiyun         RRModeMM.mmHeight = mmHeight;
183*4882a593Smuzhiyun 
184*4882a593Smuzhiyun         (*scrp->DriverFunc) (scrp, RR_GET_MODE_MM, &RRModeMM);
185*4882a593Smuzhiyun 
186*4882a593Smuzhiyun         mmWidth = RRModeMM.mmWidth;
187*4882a593Smuzhiyun         mmHeight = RRModeMM.mmHeight;
188*4882a593Smuzhiyun     }
189*4882a593Smuzhiyun     if (randrp->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
190*4882a593Smuzhiyun         /* If the screen is rotated 90 or 270 degrees, swap the sizes. */
191*4882a593Smuzhiyun         pScreen->width = scrp->virtualY;
192*4882a593Smuzhiyun         pScreen->height = scrp->virtualX;
193*4882a593Smuzhiyun         pScreen->mmWidth = mmHeight;
194*4882a593Smuzhiyun         pScreen->mmHeight = mmWidth;
195*4882a593Smuzhiyun     }
196*4882a593Smuzhiyun     else {
197*4882a593Smuzhiyun         pScreen->width = scrp->virtualX;
198*4882a593Smuzhiyun         pScreen->height = scrp->virtualY;
199*4882a593Smuzhiyun         pScreen->mmWidth = mmWidth;
200*4882a593Smuzhiyun         pScreen->mmHeight = mmHeight;
201*4882a593Smuzhiyun     }
202*4882a593Smuzhiyun     if (!xf86SwitchMode(pScreen, mode)) {
203*4882a593Smuzhiyun         pScreen->width = oldWidth;
204*4882a593Smuzhiyun         pScreen->height = oldHeight;
205*4882a593Smuzhiyun         pScreen->mmWidth = oldmmWidth;
206*4882a593Smuzhiyun         pScreen->mmHeight = oldmmHeight;
207*4882a593Smuzhiyun         scrp->virtualX = oldVirtualX;
208*4882a593Smuzhiyun         scrp->virtualY = oldVirtualY;
209*4882a593Smuzhiyun         ret = FALSE;
210*4882a593Smuzhiyun     }
211*4882a593Smuzhiyun     /*
212*4882a593Smuzhiyun      * Make sure the layout is correct
213*4882a593Smuzhiyun      */
214*4882a593Smuzhiyun     xf86ReconfigureLayout();
215*4882a593Smuzhiyun 
216*4882a593Smuzhiyun     if (scrp->vtSema) {
217*4882a593Smuzhiyun         /*
218*4882a593Smuzhiyun          * Make sure the whole screen is visible
219*4882a593Smuzhiyun          */
220*4882a593Smuzhiyun         xf86SetViewport (pScreen, pScreen->width, pScreen->height);
221*4882a593Smuzhiyun         xf86SetViewport (pScreen, 0, 0);
222*4882a593Smuzhiyun         if (pRoot)
223*4882a593Smuzhiyun             (*scrp->EnableDisableFBAccess) (scrp, TRUE);
224*4882a593Smuzhiyun     }
225*4882a593Smuzhiyun     return ret;
226*4882a593Smuzhiyun }
227*4882a593Smuzhiyun 
228*4882a593Smuzhiyun static Bool
xf86RandRSetConfig(ScreenPtr pScreen,Rotation rotation,int rate,RRScreenSizePtr pSize)229*4882a593Smuzhiyun xf86RandRSetConfig(ScreenPtr pScreen,
230*4882a593Smuzhiyun                    Rotation rotation, int rate, RRScreenSizePtr pSize)
231*4882a593Smuzhiyun {
232*4882a593Smuzhiyun     ScrnInfoPtr scrp = xf86ScreenToScrn(pScreen);
233*4882a593Smuzhiyun     XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
234*4882a593Smuzhiyun     DisplayModePtr mode;
235*4882a593Smuzhiyun     int pos[MAXDEVICES][2];
236*4882a593Smuzhiyun     Bool useVirtual = FALSE;
237*4882a593Smuzhiyun     Rotation oldRotation = randrp->rotation;
238*4882a593Smuzhiyun     DeviceIntPtr dev;
239*4882a593Smuzhiyun     Bool view_adjusted = FALSE;
240*4882a593Smuzhiyun 
241*4882a593Smuzhiyun     for (dev = inputInfo.devices; dev; dev = dev->next) {
242*4882a593Smuzhiyun         if (!IsMaster(dev) && !IsFloating(dev))
243*4882a593Smuzhiyun             continue;
244*4882a593Smuzhiyun 
245*4882a593Smuzhiyun         miPointerGetPosition(dev, &pos[dev->id][0], &pos[dev->id][1]);
246*4882a593Smuzhiyun     }
247*4882a593Smuzhiyun 
248*4882a593Smuzhiyun     for (mode = scrp->modes;; mode = mode->next) {
249*4882a593Smuzhiyun         if (mode->HDisplay == pSize->width &&
250*4882a593Smuzhiyun             mode->VDisplay == pSize->height &&
251*4882a593Smuzhiyun             (rate == 0 || xf86RandRModeRefresh(mode) == rate))
252*4882a593Smuzhiyun             break;
253*4882a593Smuzhiyun         if (mode->next == scrp->modes) {
254*4882a593Smuzhiyun             if (pSize->width == randrp->virtualX &&
255*4882a593Smuzhiyun                 pSize->height == randrp->virtualY) {
256*4882a593Smuzhiyun                 mode = scrp->modes;
257*4882a593Smuzhiyun                 useVirtual = TRUE;
258*4882a593Smuzhiyun                 break;
259*4882a593Smuzhiyun             }
260*4882a593Smuzhiyun             return FALSE;
261*4882a593Smuzhiyun         }
262*4882a593Smuzhiyun     }
263*4882a593Smuzhiyun 
264*4882a593Smuzhiyun     if (randrp->rotation != rotation) {
265*4882a593Smuzhiyun 
266*4882a593Smuzhiyun         /* Have the driver do its thing. */
267*4882a593Smuzhiyun         if (scrp->DriverFunc) {
268*4882a593Smuzhiyun             xorgRRRotation RRRotation;
269*4882a593Smuzhiyun 
270*4882a593Smuzhiyun             RRRotation.RRConfig.rotation = rotation;
271*4882a593Smuzhiyun             RRRotation.RRConfig.rate = rate;
272*4882a593Smuzhiyun             RRRotation.RRConfig.width = pSize->width;
273*4882a593Smuzhiyun             RRRotation.RRConfig.height = pSize->height;
274*4882a593Smuzhiyun 
275*4882a593Smuzhiyun             /*
276*4882a593Smuzhiyun              * Currently we need to rely on HW support for rotation.
277*4882a593Smuzhiyun              */
278*4882a593Smuzhiyun             if (!(*scrp->DriverFunc) (scrp, RR_SET_CONFIG, &RRRotation))
279*4882a593Smuzhiyun                 return FALSE;
280*4882a593Smuzhiyun         }
281*4882a593Smuzhiyun         else
282*4882a593Smuzhiyun             return FALSE;
283*4882a593Smuzhiyun 
284*4882a593Smuzhiyun         randrp->rotation = rotation;
285*4882a593Smuzhiyun     }
286*4882a593Smuzhiyun 
287*4882a593Smuzhiyun     if (!xf86RandRSetMode
288*4882a593Smuzhiyun         (pScreen, mode, useVirtual, pSize->mmWidth, pSize->mmHeight)) {
289*4882a593Smuzhiyun         if (randrp->rotation != oldRotation) {
290*4882a593Smuzhiyun             /* Have the driver undo its thing. */
291*4882a593Smuzhiyun             if (scrp->DriverFunc) {
292*4882a593Smuzhiyun                 xorgRRRotation RRRotation;
293*4882a593Smuzhiyun 
294*4882a593Smuzhiyun                 RRRotation.RRConfig.rotation = oldRotation;
295*4882a593Smuzhiyun                 RRRotation.RRConfig.rate =
296*4882a593Smuzhiyun                     xf86RandRModeRefresh(scrp->currentMode);
297*4882a593Smuzhiyun                 RRRotation.RRConfig.width = scrp->virtualX;
298*4882a593Smuzhiyun                 RRRotation.RRConfig.height = scrp->virtualY;
299*4882a593Smuzhiyun                 (*scrp->DriverFunc) (scrp, RR_SET_CONFIG, &RRRotation);
300*4882a593Smuzhiyun             }
301*4882a593Smuzhiyun 
302*4882a593Smuzhiyun             randrp->rotation = oldRotation;
303*4882a593Smuzhiyun         }
304*4882a593Smuzhiyun         return FALSE;
305*4882a593Smuzhiyun     }
306*4882a593Smuzhiyun 
307*4882a593Smuzhiyun     update_desktop_dimensions();
308*4882a593Smuzhiyun 
309*4882a593Smuzhiyun     /*
310*4882a593Smuzhiyun      * Move the cursor back where it belongs; SwitchMode repositions it
311*4882a593Smuzhiyun      * FIXME: duplicated code, see modes/xf86RandR12.c
312*4882a593Smuzhiyun      */
313*4882a593Smuzhiyun     for (dev = inputInfo.devices; dev; dev = dev->next) {
314*4882a593Smuzhiyun         if (!IsMaster(dev) && !IsFloating(dev))
315*4882a593Smuzhiyun             continue;
316*4882a593Smuzhiyun 
317*4882a593Smuzhiyun         if (pScreen == miPointerGetScreen(dev)) {
318*4882a593Smuzhiyun             int px = pos[dev->id][0];
319*4882a593Smuzhiyun             int py = pos[dev->id][1];
320*4882a593Smuzhiyun 
321*4882a593Smuzhiyun             px = (px >= pScreen->width ? (pScreen->width - 1) : px);
322*4882a593Smuzhiyun             py = (py >= pScreen->height ? (pScreen->height - 1) : py);
323*4882a593Smuzhiyun 
324*4882a593Smuzhiyun             /* Setting the viewpoint makes only sense on one device */
325*4882a593Smuzhiyun             if (!view_adjusted && IsMaster(dev)) {
326*4882a593Smuzhiyun                 xf86SetViewport(pScreen, px, py);
327*4882a593Smuzhiyun                 view_adjusted = TRUE;
328*4882a593Smuzhiyun             }
329*4882a593Smuzhiyun 
330*4882a593Smuzhiyun             (*pScreen->SetCursorPosition) (dev, pScreen, px, py, FALSE);
331*4882a593Smuzhiyun         }
332*4882a593Smuzhiyun     }
333*4882a593Smuzhiyun 
334*4882a593Smuzhiyun     return TRUE;
335*4882a593Smuzhiyun }
336*4882a593Smuzhiyun 
337*4882a593Smuzhiyun /*
338*4882a593Smuzhiyun  * Reset size back to original
339*4882a593Smuzhiyun  */
340*4882a593Smuzhiyun static Bool
xf86RandRCloseScreen(ScreenPtr pScreen)341*4882a593Smuzhiyun xf86RandRCloseScreen(ScreenPtr pScreen)
342*4882a593Smuzhiyun {
343*4882a593Smuzhiyun     ScrnInfoPtr scrp = xf86ScreenToScrn(pScreen);
344*4882a593Smuzhiyun     XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
345*4882a593Smuzhiyun 
346*4882a593Smuzhiyun     scrp->virtualX = pScreen->width = randrp->virtualX;
347*4882a593Smuzhiyun     scrp->virtualY = pScreen->height = randrp->virtualY;
348*4882a593Smuzhiyun     scrp->currentMode = scrp->modes;
349*4882a593Smuzhiyun     pScreen->CloseScreen = randrp->CloseScreen;
350*4882a593Smuzhiyun     free(randrp);
351*4882a593Smuzhiyun     dixSetPrivate(&pScreen->devPrivates, xf86RandRKey, NULL);
352*4882a593Smuzhiyun     return (*pScreen->CloseScreen) (pScreen);
353*4882a593Smuzhiyun }
354*4882a593Smuzhiyun 
355*4882a593Smuzhiyun Rotation
xf86GetRotation(ScreenPtr pScreen)356*4882a593Smuzhiyun xf86GetRotation(ScreenPtr pScreen)
357*4882a593Smuzhiyun {
358*4882a593Smuzhiyun     if (xf86RandRKey == NULL)
359*4882a593Smuzhiyun         return RR_Rotate_0;
360*4882a593Smuzhiyun 
361*4882a593Smuzhiyun     return XF86RANDRINFO(pScreen)->rotation;
362*4882a593Smuzhiyun }
363*4882a593Smuzhiyun 
364*4882a593Smuzhiyun /* Function to change RandR's idea of the virtual screen size */
365*4882a593Smuzhiyun Bool
xf86RandRSetNewVirtualAndDimensions(ScreenPtr pScreen,int newvirtX,int newvirtY,int newmmWidth,int newmmHeight,Bool resetMode)366*4882a593Smuzhiyun xf86RandRSetNewVirtualAndDimensions(ScreenPtr pScreen,
367*4882a593Smuzhiyun                                     int newvirtX, int newvirtY, int newmmWidth,
368*4882a593Smuzhiyun                                     int newmmHeight, Bool resetMode)
369*4882a593Smuzhiyun {
370*4882a593Smuzhiyun     XF86RandRInfoPtr randrp;
371*4882a593Smuzhiyun 
372*4882a593Smuzhiyun     if (xf86RandRKey == NULL)
373*4882a593Smuzhiyun         return FALSE;
374*4882a593Smuzhiyun 
375*4882a593Smuzhiyun     randrp = XF86RANDRINFO(pScreen);
376*4882a593Smuzhiyun     if (randrp == NULL)
377*4882a593Smuzhiyun         return FALSE;
378*4882a593Smuzhiyun 
379*4882a593Smuzhiyun     if (newvirtX > 0)
380*4882a593Smuzhiyun         randrp->virtualX = newvirtX;
381*4882a593Smuzhiyun 
382*4882a593Smuzhiyun     if (newvirtY > 0)
383*4882a593Smuzhiyun         randrp->virtualY = newvirtY;
384*4882a593Smuzhiyun 
385*4882a593Smuzhiyun     if (newmmWidth > 0)
386*4882a593Smuzhiyun         randrp->mmWidth = newmmWidth;
387*4882a593Smuzhiyun 
388*4882a593Smuzhiyun     if (newmmHeight > 0)
389*4882a593Smuzhiyun         randrp->mmHeight = newmmHeight;
390*4882a593Smuzhiyun 
391*4882a593Smuzhiyun     /* This is only for during server start */
392*4882a593Smuzhiyun     if (resetMode) {
393*4882a593Smuzhiyun 	ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
394*4882a593Smuzhiyun         return (xf86RandRSetMode(pScreen,
395*4882a593Smuzhiyun                                  pScrn->currentMode,
396*4882a593Smuzhiyun                                  TRUE, pScreen->mmWidth, pScreen->mmHeight));
397*4882a593Smuzhiyun     }
398*4882a593Smuzhiyun 
399*4882a593Smuzhiyun     return TRUE;
400*4882a593Smuzhiyun }
401*4882a593Smuzhiyun 
402*4882a593Smuzhiyun Bool
xf86RandRInit(ScreenPtr pScreen)403*4882a593Smuzhiyun xf86RandRInit(ScreenPtr pScreen)
404*4882a593Smuzhiyun {
405*4882a593Smuzhiyun     rrScrPrivPtr rp;
406*4882a593Smuzhiyun     XF86RandRInfoPtr randrp;
407*4882a593Smuzhiyun     ScrnInfoPtr scrp = xf86ScreenToScrn(pScreen);
408*4882a593Smuzhiyun 
409*4882a593Smuzhiyun #ifdef PANORAMIX
410*4882a593Smuzhiyun     /* XXX disable RandR when using Xinerama */
411*4882a593Smuzhiyun     if (!noPanoramiXExtension)
412*4882a593Smuzhiyun         return TRUE;
413*4882a593Smuzhiyun #endif
414*4882a593Smuzhiyun 
415*4882a593Smuzhiyun     xf86RandRKey = &xf86RandRKeyRec;
416*4882a593Smuzhiyun 
417*4882a593Smuzhiyun     if (!dixRegisterPrivateKey(&xf86RandRKeyRec, PRIVATE_SCREEN, 0))
418*4882a593Smuzhiyun         return FALSE;
419*4882a593Smuzhiyun 
420*4882a593Smuzhiyun     randrp = malloc(sizeof(XF86RandRInfoRec));
421*4882a593Smuzhiyun     if (!randrp)
422*4882a593Smuzhiyun         return FALSE;
423*4882a593Smuzhiyun 
424*4882a593Smuzhiyun     if (!RRScreenInit(pScreen)) {
425*4882a593Smuzhiyun         free(randrp);
426*4882a593Smuzhiyun         return FALSE;
427*4882a593Smuzhiyun     }
428*4882a593Smuzhiyun     rp = rrGetScrPriv(pScreen);
429*4882a593Smuzhiyun     rp->rrGetInfo = xf86RandRGetInfo;
430*4882a593Smuzhiyun     rp->rrSetConfig = xf86RandRSetConfig;
431*4882a593Smuzhiyun 
432*4882a593Smuzhiyun     randrp->virtualX = scrp->virtualX;
433*4882a593Smuzhiyun     randrp->virtualY = scrp->virtualY;
434*4882a593Smuzhiyun     randrp->mmWidth = pScreen->mmWidth;
435*4882a593Smuzhiyun     randrp->mmHeight = pScreen->mmHeight;
436*4882a593Smuzhiyun 
437*4882a593Smuzhiyun     randrp->CloseScreen = pScreen->CloseScreen;
438*4882a593Smuzhiyun     pScreen->CloseScreen = xf86RandRCloseScreen;
439*4882a593Smuzhiyun 
440*4882a593Smuzhiyun     randrp->rotation = RR_Rotate_0;
441*4882a593Smuzhiyun 
442*4882a593Smuzhiyun     dixSetPrivate(&pScreen->devPrivates, xf86RandRKey, randrp);
443*4882a593Smuzhiyun     return TRUE;
444*4882a593Smuzhiyun }
445