2 * Copyright © 2006 Keith Packard
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
25 #ifdef RANDR_10_INTERFACE
27 RROldModeAdd (RROutputPtr output
, RRScreenSizePtr size
, int refresh
)
29 ScreenPtr pScreen
= output
->pScreen
;
37 memset (&modeInfo
, '\0', sizeof (modeInfo
));
38 sprintf (name
, "%dx%d", size
->width
, size
->height
);
40 modeInfo
.width
= size
->width
;
41 modeInfo
.height
= size
->height
;
42 modeInfo
.hTotal
= size
->width
;
43 modeInfo
.vTotal
= size
->height
;
44 modeInfo
.dotClock
= ((CARD32
) size
->width
* (CARD32
) size
->height
*
46 modeInfo
.nameLength
= strlen (name
);
47 mode
= RRModeGet (&modeInfo
, name
);
50 for (i
= 0; i
< output
->numModes
; i
++)
51 if (output
->modes
[i
] == mode
)
58 modes
= xrealloc (output
->modes
,
59 (output
->numModes
+ 1) * sizeof (RRModePtr
));
61 modes
= xalloc (sizeof (RRModePtr
));
65 FreeResource (mode
->mode
.id
, 0);
68 modes
[output
->numModes
++] = mode
;
69 output
->modes
= modes
;
70 output
->changed
= TRUE
;
71 pScrPriv
->changed
= TRUE
;
72 pScrPriv
->configChanged
= TRUE
;
77 RRScanOldConfig (ScreenPtr pScreen
, Rotation rotations
)
82 RRModePtr mode
, newMode
= NULL
;
84 CARD16 minWidth
= MAXSHORT
, minHeight
= MAXSHORT
;
85 CARD16 maxWidth
= 0, maxHeight
= 0;
88 * First time through, create a crtc and output and hook
91 if (pScrPriv
->numOutputs
== 0 &&
92 pScrPriv
->numCrtcs
== 0)
94 crtc
= RRCrtcCreate (pScreen
, NULL
);
97 output
= RROutputCreate (pScreen
, "default", 7, NULL
);
100 RROutputSetCrtcs (output
, &crtc
, 1);
101 RROutputSetConnection (output
, RR_Connected
);
103 RROutputSetSubpixelOrder (output
, PictureGetSubpixelOrder (pScreen
));
107 output
= pScrPriv
->outputs
[0];
110 crtc
= pScrPriv
->crtcs
[0];
114 /* check rotations */
115 if (rotations
!= crtc
->rotations
)
117 crtc
->rotations
= rotations
;
118 crtc
->changed
= TRUE
;
119 pScrPriv
->changed
= TRUE
;
122 /* regenerate mode list */
123 for (i
= 0; i
< pScrPriv
->nSizes
; i
++)
125 RRScreenSizePtr size
= &pScrPriv
->pSizes
[i
];
130 for (r
= 0; r
< size
->nRates
; r
++)
132 mode
= RROldModeAdd (output
, size
, size
->pRates
[r
].rate
);
133 if (i
== pScrPriv
->size
&&
134 size
->pRates
[r
].rate
== pScrPriv
->rate
)
139 xfree (size
->pRates
);
143 mode
= RROldModeAdd (output
, size
, 0);
144 if (i
== pScrPriv
->size
)
148 if (pScrPriv
->nSizes
)
149 xfree (pScrPriv
->pSizes
);
150 pScrPriv
->pSizes
= NULL
;
151 pScrPriv
->nSizes
= 0;
153 /* find size bounds */
154 for (i
= 0; i
< output
->numModes
+ output
->numUserModes
; i
++)
156 RRModePtr mode
= (i
< output
->numModes
?
158 output
->userModes
[i
-output
->numModes
]);
159 CARD16 width
= mode
->mode
.width
;
160 CARD16 height
= mode
->mode
.height
;
162 if (width
< minWidth
) minWidth
= width
;
163 if (width
> maxWidth
) maxWidth
= width
;
164 if (height
< minHeight
) minHeight
= height
;
165 if (height
> maxHeight
) maxHeight
= height
;
168 RRScreenSetSizeRange (pScreen
, minWidth
, minHeight
, maxWidth
, maxHeight
);
170 /* notice current mode */
172 RRCrtcNotify (crtc
, newMode
, 0, 0, pScrPriv
->rotation
,
178 * Poll the driver for changed information
181 RRGetInfo (ScreenPtr pScreen
)
187 for (i
= 0; i
< pScrPriv
->numOutputs
; i
++)
188 pScrPriv
->outputs
[i
]->changed
= FALSE
;
189 for (i
= 0; i
< pScrPriv
->numCrtcs
; i
++)
190 pScrPriv
->crtcs
[i
]->changed
= FALSE
;
193 pScrPriv
->changed
= FALSE
;
194 pScrPriv
->configChanged
= FALSE
;
196 if (!(*pScrPriv
->rrGetInfo
) (pScreen
, &rotations
))
199 #if RANDR_10_INTERFACE
200 if (pScrPriv
->nSizes
)
201 RRScanOldConfig (pScreen
, rotations
);
203 RRTellChanged (pScreen
);
208 * Register the range of sizes for the screen
211 RRScreenSetSizeRange (ScreenPtr pScreen
,
221 if (pScrPriv
->minWidth
== minWidth
&& pScrPriv
->minHeight
== minHeight
&&
222 pScrPriv
->maxWidth
== maxWidth
&& pScrPriv
->maxHeight
== maxHeight
)
227 pScrPriv
->minWidth
= minWidth
;
228 pScrPriv
->minHeight
= minHeight
;
229 pScrPriv
->maxWidth
= maxWidth
;
230 pScrPriv
->maxHeight
= maxHeight
;
231 pScrPriv
->changed
= TRUE
;
232 pScrPriv
->configChanged
= TRUE
;
235 #ifdef RANDR_10_INTERFACE
237 RRScreenSizeMatches (RRScreenSizePtr a
,
240 if (a
->width
!= b
->width
)
242 if (a
->height
!= b
->height
)
244 if (a
->mmWidth
!= b
->mmWidth
)
246 if (a
->mmHeight
!= b
->mmHeight
)
252 RRRegisterSize (ScreenPtr pScreen
,
261 RRScreenSizePtr pNew
;
269 tmp
.mmWidth
= mmWidth
;
270 tmp
.mmHeight
= mmHeight
;
273 for (i
= 0; i
< pScrPriv
->nSizes
; i
++)
274 if (RRScreenSizeMatches (&tmp
, &pScrPriv
->pSizes
[i
]))
275 return &pScrPriv
->pSizes
[i
];
276 pNew
= xrealloc (pScrPriv
->pSizes
,
277 (pScrPriv
->nSizes
+ 1) * sizeof (RRScreenSize
));
280 pNew
[pScrPriv
->nSizes
++] = tmp
;
281 pScrPriv
->pSizes
= pNew
;
282 return &pNew
[pScrPriv
->nSizes
-1];
285 Bool
RRRegisterRate (ScreenPtr pScreen
,
286 RRScreenSizePtr pSize
,
291 RRScreenRatePtr pNew
, pRate
;
296 for (i
= 0; i
< pSize
->nRates
; i
++)
297 if (pSize
->pRates
[i
].rate
== rate
)
300 pNew
= xrealloc (pSize
->pRates
,
301 (pSize
->nRates
+ 1) * sizeof (RRScreenRate
));
304 pRate
= &pNew
[pSize
->nRates
++];
306 pSize
->pRates
= pNew
;
311 RRGetRotation(ScreenPtr pScreen
)
313 RROutputPtr output
= RRFirstOutput (pScreen
);
318 return output
->crtc
->rotation
;
322 RRSetCurrentConfig (ScreenPtr pScreen
,
325 RRScreenSizePtr pSize
)
331 pScrPriv
->size
= pSize
- pScrPriv
->pSizes
;
332 pScrPriv
->rotation
= rotation
;
333 pScrPriv
->rate
= rate
;