2 * Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc.
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that copyright
7 * notice and this permission notice appear in supporting documentation, and
8 * that the name of the copyright holders not be used in advertising or
9 * publicity pertaining to distribution of the software without specific,
10 * written prior permission. The copyright holders make no representations
11 * about the suitability of this software for any purpose. It is provided "as
12 * is" without express or implied warranty.
14 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
23 #ifdef HAVE_XORG_CONFIG_H
24 #include <xorg-config.h>
38 #include "mipointer.h"
39 #include "windowstr.h"
41 #include <X11/extensions/render.h>
44 #include "xf86RandR12.h"
46 typedef struct _xf86RandR12Info
{
53 Rotation rotation
; /* current mode */
54 Rotation supported_rotations
; /* driver supported */
55 } XF86RandRInfoRec
, *XF86RandRInfoPtr
;
57 #ifdef RANDR_12_INTERFACE
58 static Bool
xf86RandR12Init12 (ScreenPtr pScreen
);
59 static Bool
xf86RandR12CreateScreenResources12 (ScreenPtr pScreen
);
62 static int xf86RandR12Index
;
63 static int xf86RandR12Generation
;
65 #define XF86RANDRINFO(p) \
66 ((XF86RandRInfoPtr)(p)->devPrivates[xf86RandR12Index].ptr)
69 xf86RandR12ModeRefresh (DisplayModePtr mode
)
72 return (int) (mode
->VRefresh
+ 0.5);
74 return (int) (mode
->Clock
* 1000.0 / mode
->HTotal
/ mode
->VTotal
+ 0.5);
78 xf86RandR12GetInfo (ScreenPtr pScreen
, Rotation
*rotations
)
80 RRScreenSizePtr pSize
;
81 ScrnInfoPtr scrp
= XF86SCRNINFO(pScreen
);
82 XF86RandRInfoPtr randrp
= XF86RANDRINFO(pScreen
);
85 int maxX
= 0, maxY
= 0;
87 *rotations
= randrp
->supported_rotations
;
89 if (randrp
->virtualX
== -1 || randrp
->virtualY
== -1)
91 randrp
->virtualX
= scrp
->virtualX
;
92 randrp
->virtualY
= scrp
->virtualY
;
95 /* Re-probe the outputs for new monitors or modes */
98 xf86ProbeOutputModes (scrp
, 0, 0);
99 xf86SetScrnInfoModes (scrp
);
100 xf86DiDGAReInit (pScreen
);
103 for (mode
= scrp
->modes
; ; mode
= mode
->next
)
105 int refresh
= xf86RandR12ModeRefresh (mode
);
106 if (randrp
->maxX
== 0 || randrp
->maxY
== 0)
108 if (maxX
< mode
->HDisplay
)
109 maxX
= mode
->HDisplay
;
110 if (maxY
< mode
->VDisplay
)
111 maxY
= mode
->VDisplay
;
113 if (mode
== scrp
->modes
)
115 pSize
= RRRegisterSize (pScreen
,
116 mode
->HDisplay
, mode
->VDisplay
,
117 randrp
->mmWidth
, randrp
->mmHeight
);
120 RRRegisterRate (pScreen
, pSize
, refresh
);
122 if (xf86ModesEqual(mode
, scrp
->currentMode
) &&
123 mode
->HDisplay
== scrp
->virtualX
&&
124 mode
->VDisplay
== scrp
->virtualY
)
126 RRSetCurrentConfig (pScreen
, randrp
->rotation
, refresh
, pSize
);
128 if (mode
->next
== scrp
->modes
)
132 if (randrp
->maxX
== 0 || randrp
->maxY
== 0)
138 if (scrp
->currentMode
->HDisplay
!= randrp
->virtualX
||
139 scrp
->currentMode
->VDisplay
!= randrp
->virtualY
)
141 pSize
= RRRegisterSize (pScreen
,
142 randrp
->virtualX
, randrp
->virtualY
,
147 RRRegisterRate (pScreen
, pSize
, refresh0
);
148 if (scrp
->virtualX
== randrp
->virtualX
&&
149 scrp
->virtualY
== randrp
->virtualY
)
151 RRSetCurrentConfig (pScreen
, randrp
->rotation
, refresh0
, pSize
);
159 xf86RandR12SetMode (ScreenPtr pScreen
,
165 ScrnInfoPtr scrp
= XF86SCRNINFO(pScreen
);
166 XF86RandRInfoPtr randrp
= XF86RANDRINFO(pScreen
);
167 int oldWidth
= pScreen
->width
;
168 int oldHeight
= pScreen
->height
;
169 int oldmmWidth
= pScreen
->mmWidth
;
170 int oldmmHeight
= pScreen
->mmHeight
;
171 WindowPtr pRoot
= WindowTable
[pScreen
->myNum
];
172 DisplayModePtr currentMode
= NULL
;
174 PixmapPtr pspix
= NULL
;
177 (*scrp
->EnableDisableFBAccess
) (pScreen
->myNum
, FALSE
);
180 scrp
->virtualX
= randrp
->virtualX
;
181 scrp
->virtualY
= randrp
->virtualY
;
185 scrp
->virtualX
= mode
->HDisplay
;
186 scrp
->virtualY
= mode
->VDisplay
;
189 if(randrp
->rotation
& (RR_Rotate_90
| RR_Rotate_270
))
191 /* If the screen is rotated 90 or 270 degrees, swap the sizes. */
192 pScreen
->width
= scrp
->virtualY
;
193 pScreen
->height
= scrp
->virtualX
;
194 pScreen
->mmWidth
= mmHeight
;
195 pScreen
->mmHeight
= mmWidth
;
199 pScreen
->width
= scrp
->virtualX
;
200 pScreen
->height
= scrp
->virtualY
;
201 pScreen
->mmWidth
= mmWidth
;
202 pScreen
->mmHeight
= mmHeight
;
204 if (scrp
->currentMode
== mode
) {
205 /* Save current mode */
206 currentMode
= scrp
->currentMode
;
207 /* Reset, just so we ensure the drivers SwitchMode is called */
208 scrp
->currentMode
= NULL
;
211 * We know that if the driver failed to SwitchMode to the rotated
212 * version, then it should revert back to it's prior mode.
214 if (!xf86SwitchMode (pScreen
, mode
))
217 scrp
->virtualX
= pScreen
->width
= oldWidth
;
218 scrp
->virtualY
= pScreen
->height
= oldHeight
;
219 pScreen
->mmWidth
= oldmmWidth
;
220 pScreen
->mmHeight
= oldmmHeight
;
221 scrp
->currentMode
= currentMode
;
224 * Get the new Screen pixmap ptr as SwitchMode might have called
225 * ModifyPixmapHeader and xf86EnableDisableFBAccess will put it back...
228 pspix
= (*pScreen
->GetScreenPixmap
) (pScreen
);
229 if (pspix
->devPrivate
.ptr
)
230 scrp
->pixmapPrivate
= pspix
->devPrivate
;
233 * Make sure the layout is correct
235 xf86ReconfigureLayout();
238 * Make sure the whole screen is visible
240 xf86SetViewport (pScreen
, pScreen
->width
, pScreen
->height
);
241 xf86SetViewport (pScreen
, 0, 0);
243 (*scrp
->EnableDisableFBAccess
) (pScreen
->myNum
, TRUE
);
248 xf86RandR12SetConfig (ScreenPtr pScreen
,
251 RRScreenSizePtr pSize
)
253 ScrnInfoPtr scrp
= XF86SCRNINFO(pScreen
);
254 XF86RandRInfoPtr randrp
= XF86RANDRINFO(pScreen
);
257 Bool useVirtual
= FALSE
;
258 int maxX
= 0, maxY
= 0;
259 Rotation oldRotation
= randrp
->rotation
;
261 randrp
->rotation
= rotation
;
263 if (randrp
->virtualX
== -1 || randrp
->virtualY
== -1)
265 randrp
->virtualX
= scrp
->virtualX
;
266 randrp
->virtualY
= scrp
->virtualY
;
269 miPointerPosition (&px
, &py
);
270 for (mode
= scrp
->modes
; ; mode
= mode
->next
)
272 if (randrp
->maxX
== 0 || randrp
->maxY
== 0)
274 if (maxX
< mode
->HDisplay
)
275 maxX
= mode
->HDisplay
;
276 if (maxY
< mode
->VDisplay
)
277 maxY
= mode
->VDisplay
;
279 if (mode
->HDisplay
== pSize
->width
&&
280 mode
->VDisplay
== pSize
->height
&&
281 (rate
== 0 || xf86RandR12ModeRefresh (mode
) == rate
))
283 if (mode
->next
== scrp
->modes
)
285 if (pSize
->width
== randrp
->virtualX
&&
286 pSize
->height
== randrp
->virtualY
)
292 if (randrp
->maxX
== 0 || randrp
->maxY
== 0)
301 if (randrp
->maxX
== 0 || randrp
->maxY
== 0)
307 if (!xf86RandR12SetMode (pScreen
, mode
, useVirtual
, pSize
->mmWidth
,
309 randrp
->rotation
= oldRotation
;
314 * Move the cursor back where it belongs; SwitchMode repositions it
316 if (pScreen
== miPointerCurrentScreen ())
318 px
= (px
>= pScreen
->width
? (pScreen
->width
- 1) : px
);
319 py
= (py
>= pScreen
->height
? (pScreen
->height
- 1) : py
);
321 xf86SetViewport(pScreen
, px
, py
);
323 (*pScreen
->SetCursorPosition
) (pScreen
, px
, py
, FALSE
);
330 xf86RandR12ScreenSetSize (ScreenPtr pScreen
,
336 XF86RandRInfoPtr randrp
= XF86RANDRINFO(pScreen
);
337 ScrnInfoPtr pScrn
= XF86SCRNINFO(pScreen
);
338 xf86CrtcConfigPtr config
= XF86_CRTC_CONFIG_PTR(pScrn
);
339 WindowPtr pRoot
= WindowTable
[pScreen
->myNum
];
340 PixmapPtr pScrnPix
= (*pScreen
->GetScreenPixmap
)(pScreen
);
343 if (randrp
->virtualX
== -1 || randrp
->virtualY
== -1)
345 randrp
->virtualX
= pScrn
->virtualX
;
346 randrp
->virtualY
= pScrn
->virtualY
;
349 (*pScrn
->EnableDisableFBAccess
) (pScreen
->myNum
, FALSE
);
351 /* Let the driver update virtualX and virtualY */
352 if (!(*config
->funcs
->resize
)(pScrn
, width
, height
))
357 pScreen
->width
= pScrnPix
->drawable
.width
= width
;
358 pScreen
->height
= pScrnPix
->drawable
.height
= height
;
359 pScreen
->mmWidth
= mmWidth
;
360 pScreen
->mmHeight
= mmHeight
;
362 xf86SetViewport (pScreen
, pScreen
->width
-1, pScreen
->height
-1);
363 xf86SetViewport (pScreen
, 0, 0);
367 (*pScrn
->EnableDisableFBAccess
) (pScreen
->myNum
, TRUE
);
368 #if RANDR_12_INTERFACE
369 if (WindowTable
[pScreen
->myNum
] && ret
)
370 RRScreenSizeNotify (pScreen
);
376 xf86RandR12GetRotation(ScreenPtr pScreen
)
378 XF86RandRInfoPtr randrp
= XF86RANDRINFO(pScreen
);
380 return randrp
->rotation
;
384 xf86RandR12CreateScreenResources (ScreenPtr pScreen
)
386 ScrnInfoPtr pScrn
= xf86Screens
[pScreen
->myNum
];
387 xf86CrtcConfigPtr config
= XF86_CRTC_CONFIG_PTR(pScrn
);
388 XF86RandRInfoPtr randrp
= XF86RANDRINFO(pScreen
);
391 int mmWidth
, mmHeight
;
393 /* XXX disable RandR when using Xinerama */
394 if (!noPanoramiXExtension
)
399 * Compute size of screen
401 width
= 0; height
= 0;
402 for (c
= 0; c
< config
->num_crtc
; c
++)
404 xf86CrtcPtr crtc
= config
->crtc
[c
];
405 int crtc_width
= crtc
->x
+ xf86ModeWidth (&crtc
->mode
, crtc
->rotation
);
406 int crtc_height
= crtc
->y
+ xf86ModeHeight (&crtc
->mode
, crtc
->rotation
);
408 if (crtc
->enabled
&& crtc_width
> width
)
410 if (crtc
->enabled
&& crtc_height
> height
)
411 height
= crtc_height
;
417 * Compute physical size of screen
419 if (monitorResolution
)
421 mmWidth
= width
* 25.4 / monitorResolution
;
422 mmHeight
= height
* 25.4 / monitorResolution
;
426 xf86OutputPtr output
= config
->output
[config
->compat_output
];
427 xf86CrtcPtr crtc
= output
->crtc
;
429 if (crtc
&& crtc
->mode
.HDisplay
&&
430 output
->mm_width
&& output
->mm_height
)
433 * If the output has a mode and a declared size, use that
434 * to scale the screen size
436 DisplayModePtr mode
= &crtc
->mode
;
437 mmWidth
= output
->mm_width
* width
/ mode
->HDisplay
;
438 mmHeight
= output
->mm_height
* height
/ mode
->VDisplay
;
443 * Otherwise, just set the screen to 96dpi
445 mmWidth
= width
* 25.4 / 96;
446 mmHeight
= height
* 25.4 / 96;
449 xf86DrvMsg(pScrn
->scrnIndex
, X_INFO
,
450 "Setting screen physical size to %d x %d\n",
452 xf86RandR12ScreenSetSize (pScreen
,
459 if (randrp
->virtualX
== -1 || randrp
->virtualY
== -1)
461 randrp
->virtualX
= pScrn
->virtualX
;
462 randrp
->virtualY
= pScrn
->virtualY
;
464 xf86CrtcSetScreenSubpixelOrder (pScreen
);
465 #if RANDR_12_INTERFACE
466 if (xf86RandR12CreateScreenResources12 (pScreen
))
474 xf86RandR12Init (ScreenPtr pScreen
)
477 XF86RandRInfoPtr randrp
;
480 /* XXX disable RandR when using Xinerama */
481 if (!noPanoramiXExtension
)
484 if (xf86RandR12Generation
!= serverGeneration
)
486 xf86RandR12Index
= AllocateScreenPrivateIndex();
487 xf86RandR12Generation
= serverGeneration
;
490 randrp
= xalloc (sizeof (XF86RandRInfoRec
));
494 if (!RRScreenInit(pScreen
))
499 rp
= rrGetScrPriv(pScreen
);
500 rp
->rrGetInfo
= xf86RandR12GetInfo
;
501 rp
->rrSetConfig
= xf86RandR12SetConfig
;
503 randrp
->virtualX
= -1;
504 randrp
->virtualY
= -1;
505 randrp
->mmWidth
= pScreen
->mmWidth
;
506 randrp
->mmHeight
= pScreen
->mmHeight
;
508 randrp
->rotation
= RR_Rotate_0
; /* initial rotated mode */
510 randrp
->supported_rotations
= RR_Rotate_0
;
512 randrp
->maxX
= randrp
->maxY
= 0;
514 pScreen
->devPrivates
[xf86RandR12Index
].ptr
= randrp
;
516 #if RANDR_12_INTERFACE
517 if (!xf86RandR12Init12 (pScreen
))
524 xf86RandR12SetRotations (ScreenPtr pScreen
, Rotation rotations
)
526 XF86RandRInfoPtr randrp
= XF86RANDRINFO(pScreen
);
527 #if RANDR_12_INTERFACE
528 ScrnInfoPtr pScrn
= xf86Screens
[pScreen
->myNum
];
530 xf86CrtcConfigPtr config
= XF86_CRTC_CONFIG_PTR(pScrn
);
532 for (c
= 0; c
< config
->num_crtc
; c
++) {
533 xf86CrtcPtr crtc
= config
->crtc
[c
];
535 RRCrtcSetRotations (crtc
->randr_crtc
, rotations
);
538 randrp
->supported_rotations
= rotations
;
542 xf86RandR12GetOriginalVirtualSize(ScrnInfoPtr pScrn
, int *x
, int *y
)
544 ScreenPtr pScreen
= screenInfo
.screens
[pScrn
->scrnIndex
];
546 if (xf86RandR12Generation
!= serverGeneration
||
547 XF86RANDRINFO(pScreen
)->virtualX
== -1)
549 *x
= pScrn
->virtualX
;
550 *y
= pScrn
->virtualY
;
552 XF86RandRInfoPtr randrp
= XF86RANDRINFO(pScreen
);
554 *x
= randrp
->virtualX
;
555 *y
= randrp
->virtualY
;
559 #if RANDR_12_INTERFACE
561 #define FLAG_BITS (RR_HSyncPositive | \
572 RR_PixelMultiplex | \
577 xf86RandRModeMatches (RRModePtr randr_mode
,
583 /* check for same name */
584 int len
= strlen (mode
->name
);
585 if (randr_mode
->mode
.nameLength
!= len
) return FALSE
;
586 if (memcmp (randr_mode
->name
, mode
->name
, len
) != 0) return FALSE
;
590 /* check for same timings */
591 if (randr_mode
->mode
.dotClock
/ 1000 != mode
->Clock
) return FALSE
;
592 if (randr_mode
->mode
.width
!= mode
->HDisplay
) return FALSE
;
593 if (randr_mode
->mode
.hSyncStart
!= mode
->HSyncStart
) return FALSE
;
594 if (randr_mode
->mode
.hSyncEnd
!= mode
->HSyncEnd
) return FALSE
;
595 if (randr_mode
->mode
.hTotal
!= mode
->HTotal
) return FALSE
;
596 if (randr_mode
->mode
.hSkew
!= mode
->HSkew
) return FALSE
;
597 if (randr_mode
->mode
.height
!= mode
->VDisplay
) return FALSE
;
598 if (randr_mode
->mode
.vSyncStart
!= mode
->VSyncStart
) return FALSE
;
599 if (randr_mode
->mode
.vSyncEnd
!= mode
->VSyncEnd
) return FALSE
;
600 if (randr_mode
->mode
.vTotal
!= mode
->VTotal
) return FALSE
;
602 /* check for same flags (using only the XF86 valid flag bits) */
603 if ((randr_mode
->mode
.modeFlags
& FLAG_BITS
) != (mode
->Flags
& FLAG_BITS
))
606 /* everything matches */
611 xf86RandR12CrtcNotify (RRCrtcPtr randr_crtc
)
613 ScreenPtr pScreen
= randr_crtc
->pScreen
;
614 ScrnInfoPtr pScrn
= xf86Screens
[pScreen
->myNum
];
615 xf86CrtcConfigPtr config
= XF86_CRTC_CONFIG_PTR(pScrn
);
616 RRModePtr randr_mode
= NULL
;
621 RROutputPtr
*randr_outputs
;
622 RROutputPtr randr_output
;
623 xf86CrtcPtr crtc
= randr_crtc
->devPrivate
;
624 xf86OutputPtr output
;
626 DisplayModePtr mode
= &crtc
->mode
;
629 randr_outputs
= ALLOCATE_LOCAL(config
->num_output
* sizeof (RROutputPtr
));
634 rotation
= crtc
->rotation
;
637 for (i
= 0; i
< config
->num_output
; i
++)
639 output
= config
->output
[i
];
640 if (output
->crtc
== crtc
)
642 randr_output
= output
->randr_output
;
643 randr_outputs
[numOutputs
++] = randr_output
;
645 * We make copies of modes, so pointer equality
648 for (j
= 0; j
< randr_output
->numModes
+ randr_output
->numUserModes
; j
++)
650 RRModePtr m
= (j
< randr_output
->numModes
?
651 randr_output
->modes
[j
] :
652 randr_output
->userModes
[j
-randr_output
->numModes
]);
654 if (xf86RandRModeMatches (m
, mode
))
662 ret
= RRCrtcNotify (randr_crtc
, randr_mode
, x
, y
,
663 rotation
, numOutputs
, randr_outputs
);
664 DEALLOCATE_LOCAL(randr_outputs
);
669 * Convert a RandR mode to a DisplayMode
672 xf86RandRModeConvert (ScrnInfoPtr scrn
,
673 RRModePtr randr_mode
,
679 mode
->status
= MODE_OK
;
682 mode
->Clock
= randr_mode
->mode
.dotClock
/ 1000;
684 mode
->HDisplay
= randr_mode
->mode
.width
;
685 mode
->HSyncStart
= randr_mode
->mode
.hSyncStart
;
686 mode
->HSyncEnd
= randr_mode
->mode
.hSyncEnd
;
687 mode
->HTotal
= randr_mode
->mode
.hTotal
;
688 mode
->HSkew
= randr_mode
->mode
.hSkew
;
690 mode
->VDisplay
= randr_mode
->mode
.height
;
691 mode
->VSyncStart
= randr_mode
->mode
.vSyncStart
;
692 mode
->VSyncEnd
= randr_mode
->mode
.vSyncEnd
;
693 mode
->VTotal
= randr_mode
->mode
.vTotal
;
696 mode
->Flags
= randr_mode
->mode
.modeFlags
& FLAG_BITS
;
698 xf86SetModeCrtc (mode
, scrn
->adjustFlags
);
702 xf86RandR12CrtcSet (ScreenPtr pScreen
,
703 RRCrtcPtr randr_crtc
,
704 RRModePtr randr_mode
,
708 int num_randr_outputs
,
709 RROutputPtr
*randr_outputs
)
711 ScrnInfoPtr pScrn
= xf86Screens
[pScreen
->myNum
];
712 xf86CrtcConfigPtr config
= XF86_CRTC_CONFIG_PTR(pScrn
);
713 xf86CrtcPtr crtc
= randr_crtc
->devPrivate
;
714 Bool changed
= FALSE
;
716 xf86CrtcPtr
*save_crtcs
;
717 Bool save_enabled
= crtc
->enabled
;
719 save_crtcs
= ALLOCATE_LOCAL(config
->num_output
* sizeof (xf86CrtcPtr
));
720 if ((randr_mode
!= NULL
) != crtc
->enabled
)
722 else if (randr_mode
&& !xf86RandRModeMatches (randr_mode
, &crtc
->mode
))
725 if (rotation
!= crtc
->rotation
)
728 if (x
!= crtc
->x
|| y
!= crtc
->y
)
730 for (o
= 0; o
< config
->num_output
; o
++)
732 xf86OutputPtr output
= config
->output
[o
];
733 xf86CrtcPtr new_crtc
;
735 save_crtcs
[o
] = output
->crtc
;
737 if (output
->crtc
== crtc
)
740 new_crtc
= output
->crtc
;
741 for (ro
= 0; ro
< num_randr_outputs
; ro
++)
742 if (output
->randr_output
== randr_outputs
[ro
])
747 if (new_crtc
!= output
->crtc
)
750 output
->crtc
= new_crtc
;
753 for (ro
= 0; ro
< num_randr_outputs
; ro
++)
754 if (randr_outputs
[ro
]->pendingProperties
)
757 /* XXX need device-independent mode setting code through an API */
760 crtc
->enabled
= randr_mode
!= NULL
;
766 xf86RandRModeConvert (pScrn
, randr_mode
, &mode
);
767 if (!xf86CrtcSetMode (crtc
, &mode
, rotation
, x
, y
))
769 crtc
->enabled
= save_enabled
;
770 for (o
= 0; o
< config
->num_output
; o
++)
772 xf86OutputPtr output
= config
->output
[o
];
773 output
->crtc
= save_crtcs
[o
];
775 DEALLOCATE_LOCAL(save_crtcs
);
779 * Save the last successful setting for EnterVT
781 crtc
->desiredMode
= mode
;
782 crtc
->desiredRotation
= rotation
;
786 xf86DisableUnusedFunctions (pScrn
);
788 DEALLOCATE_LOCAL(save_crtcs
);
789 return xf86RandR12CrtcNotify (randr_crtc
);
793 xf86RandR12CrtcSetGamma (ScreenPtr pScreen
,
794 RRCrtcPtr randr_crtc
)
796 xf86CrtcPtr crtc
= randr_crtc
->devPrivate
;
798 if (crtc
->funcs
->gamma_set
== NULL
)
801 if (!crtc
->scrn
->vtSema
)
804 crtc
->funcs
->gamma_set(crtc
, randr_crtc
->gammaRed
, randr_crtc
->gammaGreen
,
805 randr_crtc
->gammaBlue
, randr_crtc
->gammaSize
);
811 xf86RandR12OutputSetProperty (ScreenPtr pScreen
,
812 RROutputPtr randr_output
,
814 RRPropertyValuePtr value
)
816 xf86OutputPtr output
= randr_output
->devPrivate
;
818 /* If we don't have any property handler, then we don't care what the
819 * user is setting properties to.
821 if (output
->funcs
->set_property
== NULL
)
825 * This function gets called even when vtSema is FALSE, as
826 * drivers will need to remember the correct value to apply
827 * when the VT switch occurs
829 return output
->funcs
->set_property(output
, property
, value
);
833 xf86RandR12OutputValidateMode (ScreenPtr pScreen
,
834 RROutputPtr randr_output
,
835 RRModePtr randr_mode
)
837 ScrnInfoPtr pScrn
= xf86Screens
[pScreen
->myNum
];
838 xf86OutputPtr output
= randr_output
->devPrivate
;
841 xf86RandRModeConvert (pScrn
, randr_mode
, &mode
);
843 * This function may be called when vtSema is FALSE, so
844 * the underlying function must either avoid touching the hardware
845 * or return FALSE when vtSema is FALSE
847 if (output
->funcs
->mode_valid (output
, &mode
) != MODE_OK
)
853 xf86RandR12ModeDestroy (ScreenPtr pScreen
, RRModePtr randr_mode
)
858 * Given a list of xf86 modes and a RandR Output object, construct
859 * RandR modes and assign them to the output
862 xf86RROutputSetModes (RROutputPtr randr_output
, DisplayModePtr modes
)
865 RRModePtr
*rrmodes
= NULL
;
871 for (mode
= modes
; mode
; mode
= mode
->next
)
875 rrmodes
= xalloc (nmode
* sizeof (RRModePtr
));
881 for (pref
= 1; pref
>= 0; pref
--) {
882 for (mode
= modes
; mode
; mode
= mode
->next
) {
883 if ((pref
!= 0) == ((mode
->type
& M_T_PREFERRED
) != 0)) {
884 xRRModeInfo modeInfo
;
887 modeInfo
.nameLength
= strlen (mode
->name
);
888 modeInfo
.width
= mode
->HDisplay
;
889 modeInfo
.dotClock
= mode
->Clock
* 1000;
890 modeInfo
.hSyncStart
= mode
->HSyncStart
;
891 modeInfo
.hSyncEnd
= mode
->HSyncEnd
;
892 modeInfo
.hTotal
= mode
->HTotal
;
893 modeInfo
.hSkew
= mode
->HSkew
;
895 modeInfo
.height
= mode
->VDisplay
;
896 modeInfo
.vSyncStart
= mode
->VSyncStart
;
897 modeInfo
.vSyncEnd
= mode
->VSyncEnd
;
898 modeInfo
.vTotal
= mode
->VTotal
;
899 modeInfo
.modeFlags
= mode
->Flags
;
901 rrmode
= RRModeGet (&modeInfo
, mode
->name
);
903 rrmodes
[nmode
++] = rrmode
;
911 ret
= RROutputSetModes (randr_output
, rrmodes
, nmode
, npreferred
);
917 * Mirror the current mode configuration to RandR
920 xf86RandR12SetInfo12 (ScreenPtr pScreen
)
922 ScrnInfoPtr pScrn
= xf86Screens
[pScreen
->myNum
];
923 xf86CrtcConfigPtr config
= XF86_CRTC_CONFIG_PTR(pScrn
);
928 RRCrtcPtr randr_crtc
;
931 clones
= ALLOCATE_LOCAL(config
->num_output
* sizeof (RROutputPtr
));
932 crtcs
= ALLOCATE_LOCAL (config
->num_crtc
* sizeof (RRCrtcPtr
));
933 for (o
= 0; o
< config
->num_output
; o
++)
935 xf86OutputPtr output
= config
->output
[o
];
938 for (c
= 0; c
< config
->num_crtc
; c
++)
939 if (output
->possible_crtcs
& (1 << c
))
940 crtcs
[ncrtc
++] = config
->crtc
[c
]->randr_crtc
;
943 randr_crtc
= output
->crtc
->randr_crtc
;
947 if (!RROutputSetCrtcs (output
->randr_output
, crtcs
, ncrtc
))
949 DEALLOCATE_LOCAL (crtcs
);
950 DEALLOCATE_LOCAL (clones
);
954 RROutputSetPhysicalSize(output
->randr_output
,
957 xf86RROutputSetModes (output
->randr_output
, output
->probed_modes
);
959 switch (output
->status
) {
960 case XF86OutputStatusConnected
:
961 RROutputSetConnection (output
->randr_output
, RR_Connected
);
963 case XF86OutputStatusDisconnected
:
964 RROutputSetConnection (output
->randr_output
, RR_Disconnected
);
966 case XF86OutputStatusUnknown
:
967 RROutputSetConnection (output
->randr_output
, RR_UnknownConnection
);
971 RROutputSetSubpixelOrder (output
->randr_output
, output
->subpixel_order
);
977 for (l
= 0; l
< config
->num_output
; l
++)
979 xf86OutputPtr clone
= config
->output
[l
];
981 if (l
!= o
&& (output
->possible_clones
& (1 << l
)))
982 clones
[nclone
++] = clone
->randr_output
;
984 if (!RROutputSetClones (output
->randr_output
, clones
, nclone
))
986 DEALLOCATE_LOCAL (crtcs
);
987 DEALLOCATE_LOCAL (clones
);
991 DEALLOCATE_LOCAL (crtcs
);
992 DEALLOCATE_LOCAL (clones
);
999 * Query the hardware for the current state, then mirror
1003 xf86RandR12GetInfo12 (ScreenPtr pScreen
, Rotation
*rotations
)
1005 ScrnInfoPtr pScrn
= xf86Screens
[pScreen
->myNum
];
1009 xf86ProbeOutputModes (pScrn
, 0, 0);
1010 xf86SetScrnInfoModes (pScrn
);
1011 xf86DiDGAReInit (pScreen
);
1012 return xf86RandR12SetInfo12 (pScreen
);
1016 xf86RandR12CreateObjects12 (ScreenPtr pScreen
)
1018 ScrnInfoPtr pScrn
= xf86Screens
[pScreen
->myNum
];
1019 xf86CrtcConfigPtr config
= XF86_CRTC_CONFIG_PTR(pScrn
);
1029 for (c
= 0; c
< config
->num_crtc
; c
++)
1031 xf86CrtcPtr crtc
= config
->crtc
[c
];
1033 crtc
->randr_crtc
= RRCrtcCreate (pScreen
, crtc
);
1034 RRCrtcGammaSetSize (crtc
->randr_crtc
, 256);
1039 for (o
= 0; o
< config
->num_output
; o
++)
1041 xf86OutputPtr output
= config
->output
[o
];
1043 output
->randr_output
= RROutputCreate (pScreen
, output
->name
,
1044 strlen (output
->name
),
1047 if (output
->funcs
->create_resources
!= NULL
)
1048 output
->funcs
->create_resources(output
);
1049 RRPostPendingProperties (output
->randr_output
);
1055 xf86RandR12CreateScreenResources12 (ScreenPtr pScreen
)
1058 ScrnInfoPtr pScrn
= xf86Screens
[pScreen
->myNum
];
1059 xf86CrtcConfigPtr config
= XF86_CRTC_CONFIG_PTR(pScrn
);
1061 for (c
= 0; c
< config
->num_crtc
; c
++)
1062 xf86RandR12CrtcNotify (config
->crtc
[c
]->randr_crtc
);
1065 RRScreenSetSizeRange (pScreen
, config
->minWidth
, config
->minHeight
,
1066 config
->maxWidth
, config
->maxHeight
);
1071 * Something happened within the screen configuration due
1072 * to DGA, VidMode or hot key. Tell RandR
1076 xf86RandR12TellChanged (ScreenPtr pScreen
)
1078 ScrnInfoPtr pScrn
= xf86Screens
[pScreen
->myNum
];
1079 xf86CrtcConfigPtr config
= XF86_CRTC_CONFIG_PTR(pScrn
);
1080 XF86RandRInfoPtr randrp
= XF86RANDRINFO(pScreen
);
1085 xf86RandR12SetInfo12 (pScreen
);
1086 for (c
= 0; c
< config
->num_crtc
; c
++)
1087 xf86RandR12CrtcNotify (config
->crtc
[c
]->randr_crtc
);
1089 RRTellChanged (pScreen
);
1093 xf86RandR12PointerMoved (int scrnIndex
, int x
, int y
)
1098 xf86RandR12Init12 (ScreenPtr pScreen
)
1100 ScrnInfoPtr pScrn
= xf86Screens
[pScreen
->myNum
];
1101 rrScrPrivPtr rp
= rrGetScrPriv(pScreen
);
1103 rp
->rrGetInfo
= xf86RandR12GetInfo12
;
1104 rp
->rrScreenSetSize
= xf86RandR12ScreenSetSize
;
1105 rp
->rrCrtcSet
= xf86RandR12CrtcSet
;
1106 rp
->rrCrtcSetGamma
= xf86RandR12CrtcSetGamma
;
1107 rp
->rrOutputSetProperty
= xf86RandR12OutputSetProperty
;
1108 rp
->rrOutputValidateMode
= xf86RandR12OutputValidateMode
;
1109 rp
->rrModeDestroy
= xf86RandR12ModeDestroy
;
1110 rp
->rrSetConfig
= NULL
;
1111 pScrn
->PointerMoved
= xf86RandR12PointerMoved
;
1112 if (!xf86RandR12CreateObjects12 (pScreen
))
1116 * Configure output modes
1118 if (!xf86RandR12SetInfo12 (pScreen
))
1126 xf86RandR12PreInit (ScrnInfoPtr pScrn
)