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;
88 * First time through, create a crtc and output and hook
91 if (pScrPriv
->numOutputs
== 0 && pScrPriv
->numCrtcs
== 0) {
92 crtc
= RRCrtcCreate(pScreen
, NULL
);
95 output
= RROutputCreate(pScreen
, "default", 7, NULL
);
98 RROutputSetCrtcs(output
, &crtc
, 1);
99 RROutputSetConnection(output
, RR_Connected
);
100 RROutputSetSubpixelOrder(output
, PictureGetSubpixelOrder(pScreen
));
103 output
= pScrPriv
->outputs
[0];
106 crtc
= pScrPriv
->crtcs
[0];
110 /* check rotations */
111 if (rotations
!= crtc
->rotations
) {
112 crtc
->rotations
= rotations
;
113 crtc
->changed
= TRUE
;
114 pScrPriv
->changed
= TRUE
;
117 /* regenerate mode list */
118 for (i
= 0; i
< pScrPriv
->nSizes
; i
++) {
119 RRScreenSizePtr size
= &pScrPriv
->pSizes
[i
];
123 for (r
= 0; r
< size
->nRates
; r
++) {
124 mode
= RROldModeAdd(output
, size
, size
->pRates
[r
].rate
);
125 if (i
== pScrPriv
->size
&&
126 size
->pRates
[r
].rate
== pScrPriv
->rate
) {
133 mode
= RROldModeAdd(output
, size
, 0);
134 if (i
== pScrPriv
->size
)
138 if (pScrPriv
->nSizes
)
139 free(pScrPriv
->pSizes
);
140 pScrPriv
->pSizes
= NULL
;
141 pScrPriv
->nSizes
= 0;
143 /* find size bounds */
144 for (i
= 0; i
< output
->numModes
+ output
->numUserModes
; i
++) {
145 mode
= (i
< output
->numModes
?
147 output
->userModes
[i
- output
->numModes
]);
148 width
= mode
->mode
.width
;
149 height
= mode
->mode
.height
;
151 if (width
< minWidth
)
153 if (width
> maxWidth
)
155 if (height
< minHeight
)
157 if (height
> maxHeight
)
161 RRScreenSetSizeRange(pScreen
, minWidth
, minHeight
, maxWidth
, maxHeight
);
163 /* notice current mode */
165 RRCrtcNotify(crtc
, newMode
, 0, 0, pScrPriv
->rotation
, NULL
, 1, &output
);
170 * Poll the driver for changed information
173 RRGetInfo(ScreenPtr pScreen
, Bool force_query
)
179 /* Return immediately if we don't need to re-query and we already have the
183 if (pScrPriv
->numCrtcs
!= 0 || pScrPriv
->numOutputs
!= 0)
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
,
213 CARD16 minHeight
, CARD16 maxWidth
, CARD16 maxHeight
)
219 if (pScrPriv
->minWidth
== minWidth
&& pScrPriv
->minHeight
== minHeight
&&
220 pScrPriv
->maxWidth
== maxWidth
&& pScrPriv
->maxHeight
== maxHeight
) {
224 pScrPriv
->minWidth
= minWidth
;
225 pScrPriv
->minHeight
= minHeight
;
226 pScrPriv
->maxWidth
= maxWidth
;
227 pScrPriv
->maxHeight
= maxHeight
;
228 RRSetChanged(pScreen
);
229 pScrPriv
->configChanged
= TRUE
;
232 #ifdef RANDR_10_INTERFACE
234 RRScreenSizeMatches(RRScreenSizePtr a
, RRScreenSizePtr b
)
236 if (a
->width
!= b
->width
)
238 if (a
->height
!= b
->height
)
240 if (a
->mmWidth
!= b
->mmWidth
)
242 if (a
->mmHeight
!= b
->mmHeight
)
248 RRRegisterSize(ScreenPtr pScreen
,
249 short width
, short height
, short mmWidth
, short mmHeight
)
254 RRScreenSizePtr pNew
;
262 tmp
.mmWidth
= mmWidth
;
263 tmp
.mmHeight
= mmHeight
;
266 for (i
= 0; i
< pScrPriv
->nSizes
; i
++)
267 if (RRScreenSizeMatches(&tmp
, &pScrPriv
->pSizes
[i
]))
268 return &pScrPriv
->pSizes
[i
];
269 pNew
= realloc(pScrPriv
->pSizes
,
270 (pScrPriv
->nSizes
+ 1) * sizeof(RRScreenSize
));
273 pNew
[pScrPriv
->nSizes
++] = tmp
;
274 pScrPriv
->pSizes
= pNew
;
275 return &pNew
[pScrPriv
->nSizes
- 1];
279 RRRegisterRate(ScreenPtr pScreen
, RRScreenSizePtr pSize
, int rate
)
283 RRScreenRatePtr pNew
, pRate
;
288 for (i
= 0; i
< pSize
->nRates
; i
++)
289 if (pSize
->pRates
[i
].rate
== rate
)
292 pNew
= realloc(pSize
->pRates
, (pSize
->nRates
+ 1) * sizeof(RRScreenRate
));
295 pRate
= &pNew
[pSize
->nRates
++];
297 pSize
->pRates
= pNew
;
302 RRGetRotation(ScreenPtr pScreen
)
304 RROutputPtr output
= RRFirstOutput(pScreen
);
309 return output
->crtc
->rotation
;
313 RRSetCurrentConfig(ScreenPtr pScreen
,
314 Rotation rotation
, int rate
, RRScreenSizePtr pSize
)
320 pScrPriv
->size
= pSize
- pScrPriv
->pSizes
;
321 pScrPriv
->rotation
= rotation
;
322 pScrPriv
->rate
= rate
;