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