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
;
38 memset(&modeInfo
, '\0', sizeof(modeInfo
));
39 snprintf(name
, sizeof(name
), "%dx%d", size
->width
, size
->height
);
41 modeInfo
.width
= size
->width
;
42 modeInfo
.height
= size
->height
;
43 modeInfo
.hTotal
= size
->width
;
44 modeInfo
.vTotal
= size
->height
;
45 modeInfo
.dotClock
= ((CARD32
) size
->width
* (CARD32
) size
->height
*
47 modeInfo
.nameLength
= strlen(name
);
48 mode
= RRModeGet(&modeInfo
, name
);
51 for (i
= 0; i
< output
->numModes
; i
++)
52 if (output
->modes
[i
] == mode
) {
58 modes
= realloc(output
->modes
,
59 (output
->numModes
+ 1) * sizeof(RRModePtr
));
61 modes
= malloc(sizeof(RRModePtr
));
64 FreeResource(mode
->mode
.id
, 0);
67 modes
[output
->numModes
++] = mode
;
68 output
->modes
= modes
;
69 output
->changed
= TRUE
;
70 pScrPriv
->changed
= TRUE
;
71 pScrPriv
->configChanged
= TRUE
;
76 RRScanOldConfig(ScreenPtr pScreen
, Rotation rotations
)
81 RRModePtr mode
, newMode
= NULL
;
83 CARD16 minWidth
= MAXSHORT
, minHeight
= MAXSHORT
;
84 CARD16 maxWidth
= 0, maxHeight
= 0;
87 * First time through, create a crtc and output and hook
90 if (pScrPriv
->numOutputs
== 0 && pScrPriv
->numCrtcs
== 0) {
91 crtc
= RRCrtcCreate(pScreen
, NULL
);
94 output
= RROutputCreate(pScreen
, "default", 7, NULL
);
97 RROutputSetCrtcs(output
, &crtc
, 1);
98 RROutputSetConnection(output
, RR_Connected
);
99 RROutputSetSubpixelOrder(output
, PictureGetSubpixelOrder(pScreen
));
102 output
= pScrPriv
->outputs
[0];
105 crtc
= pScrPriv
->crtcs
[0];
109 /* check rotations */
110 if (rotations
!= crtc
->rotations
) {
111 crtc
->rotations
= rotations
;
112 crtc
->changed
= TRUE
;
113 pScrPriv
->changed
= TRUE
;
116 /* regenerate mode list */
117 for (i
= 0; i
< pScrPriv
->nSizes
; i
++) {
118 RRScreenSizePtr size
= &pScrPriv
->pSizes
[i
];
122 for (r
= 0; r
< size
->nRates
; r
++) {
123 mode
= RROldModeAdd(output
, size
, size
->pRates
[r
].rate
);
124 if (i
== pScrPriv
->size
&&
125 size
->pRates
[r
].rate
== pScrPriv
->rate
) {
132 mode
= RROldModeAdd(output
, size
, 0);
133 if (i
== pScrPriv
->size
)
137 if (pScrPriv
->nSizes
)
138 free(pScrPriv
->pSizes
);
139 pScrPriv
->pSizes
= NULL
;
140 pScrPriv
->nSizes
= 0;
142 /* find size bounds */
143 for (i
= 0; i
< output
->numModes
+ output
->numUserModes
; i
++) {
144 RRModePtr mode
= (i
< output
->numModes
?
146 output
->userModes
[i
- output
->numModes
]);
147 CARD16 width
= mode
->mode
.width
;
148 CARD16 height
= mode
->mode
.height
;
150 if (width
< minWidth
)
152 if (width
> maxWidth
)
154 if (height
< minHeight
)
156 if (height
> maxHeight
)
160 RRScreenSetSizeRange(pScreen
, minWidth
, minHeight
, maxWidth
, maxHeight
);
162 /* notice current mode */
164 RRCrtcNotify(crtc
, newMode
, 0, 0, pScrPriv
->rotation
, NULL
, 1, &output
);
169 * Poll the driver for changed information
172 RRGetInfo(ScreenPtr pScreen
, Bool force_query
)
178 /* Return immediately if we don't need to re-query and we already have the
182 if (pScrPriv
->numCrtcs
!= 0 || pScrPriv
->numOutputs
!= 0)
186 for (i
= 0; i
< pScrPriv
->numOutputs
; i
++)
187 pScrPriv
->outputs
[i
]->changed
= FALSE
;
188 for (i
= 0; i
< pScrPriv
->numCrtcs
; i
++)
189 pScrPriv
->crtcs
[i
]->changed
= FALSE
;
192 pScrPriv
->changed
= FALSE
;
193 pScrPriv
->configChanged
= FALSE
;
195 if (!(*pScrPriv
->rrGetInfo
) (pScreen
, &rotations
))
198 #if RANDR_10_INTERFACE
199 if (pScrPriv
->nSizes
)
200 RRScanOldConfig(pScreen
, rotations
);
202 RRTellChanged(pScreen
);
207 * Register the range of sizes for the screen
210 RRScreenSetSizeRange(ScreenPtr pScreen
,
212 CARD16 minHeight
, CARD16 maxWidth
, CARD16 maxHeight
)
218 if (pScrPriv
->minWidth
== minWidth
&& pScrPriv
->minHeight
== minHeight
&&
219 pScrPriv
->maxWidth
== maxWidth
&& pScrPriv
->maxHeight
== maxHeight
) {
223 pScrPriv
->minWidth
= minWidth
;
224 pScrPriv
->minHeight
= minHeight
;
225 pScrPriv
->maxWidth
= maxWidth
;
226 pScrPriv
->maxHeight
= maxHeight
;
227 pScrPriv
->changed
= TRUE
;
228 pScrPriv
->configChanged
= TRUE
;
231 #ifdef RANDR_10_INTERFACE
233 RRScreenSizeMatches(RRScreenSizePtr a
, RRScreenSizePtr b
)
235 if (a
->width
!= b
->width
)
237 if (a
->height
!= b
->height
)
239 if (a
->mmWidth
!= b
->mmWidth
)
241 if (a
->mmHeight
!= b
->mmHeight
)
247 RRRegisterSize(ScreenPtr pScreen
,
248 short width
, short height
, short mmWidth
, short mmHeight
)
253 RRScreenSizePtr pNew
;
261 tmp
.mmWidth
= mmWidth
;
262 tmp
.mmHeight
= mmHeight
;
265 for (i
= 0; i
< pScrPriv
->nSizes
; i
++)
266 if (RRScreenSizeMatches(&tmp
, &pScrPriv
->pSizes
[i
]))
267 return &pScrPriv
->pSizes
[i
];
268 pNew
= realloc(pScrPriv
->pSizes
,
269 (pScrPriv
->nSizes
+ 1) * sizeof(RRScreenSize
));
272 pNew
[pScrPriv
->nSizes
++] = tmp
;
273 pScrPriv
->pSizes
= pNew
;
274 return &pNew
[pScrPriv
->nSizes
- 1];
278 RRRegisterRate(ScreenPtr pScreen
, RRScreenSizePtr pSize
, int rate
)
282 RRScreenRatePtr pNew
, pRate
;
287 for (i
= 0; i
< pSize
->nRates
; i
++)
288 if (pSize
->pRates
[i
].rate
== rate
)
291 pNew
= realloc(pSize
->pRates
, (pSize
->nRates
+ 1) * sizeof(RRScreenRate
));
294 pRate
= &pNew
[pSize
->nRates
++];
296 pSize
->pRates
= pNew
;
301 RRGetRotation(ScreenPtr pScreen
)
303 RROutputPtr output
= RRFirstOutput(pScreen
);
308 return output
->crtc
->rotation
;
312 RRSetCurrentConfig(ScreenPtr pScreen
,
313 Rotation rotation
, int rate
, RRScreenSizePtr pSize
)
319 pScrPriv
->size
= pSize
- pScrPriv
->pSizes
;
320 pScrPriv
->rotation
= rotation
;
321 pScrPriv
->rate
= rate
;