Initial commit
[xorg_rtime.git] / xorg-server-1.4 / randr / rrinfo.c
blob7e77d393de5bdd296fa346744d2714caa6c9de03
1 /*
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
20 * OF THIS SOFTWARE.
23 #include "randrstr.h"
25 #ifdef RANDR_10_INTERFACE
26 static RRModePtr
27 RROldModeAdd (RROutputPtr output, RRScreenSizePtr size, int refresh)
29 ScreenPtr pScreen = output->pScreen;
30 rrScrPriv(pScreen);
31 xRRModeInfo modeInfo;
32 char name[100];
33 RRModePtr mode;
34 int i;
35 RRModePtr *modes;
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 *
45 (CARD32) refresh);
46 modeInfo.nameLength = strlen (name);
47 mode = RRModeGet (&modeInfo, name);
48 if (!mode)
49 return NULL;
50 for (i = 0; i < output->numModes; i++)
51 if (output->modes[i] == mode)
53 RRModeDestroy (mode);
54 return mode;
57 if (output->numModes)
58 modes = xrealloc (output->modes,
59 (output->numModes + 1) * sizeof (RRModePtr));
60 else
61 modes = xalloc (sizeof (RRModePtr));
62 if (!modes)
64 RRModeDestroy (mode);
65 FreeResource (mode->mode.id, 0);
66 return NULL;
68 modes[output->numModes++] = mode;
69 output->modes = modes;
70 output->changed = TRUE;
71 pScrPriv->changed = TRUE;
72 pScrPriv->configChanged = TRUE;
73 return mode;
76 static void
77 RRScanOldConfig (ScreenPtr pScreen, Rotation rotations)
79 rrScrPriv(pScreen);
80 RROutputPtr output;
81 RRCrtcPtr crtc;
82 RRModePtr mode, newMode = NULL;
83 int i;
84 CARD16 minWidth = MAXSHORT, minHeight = MAXSHORT;
85 CARD16 maxWidth = 0, maxHeight = 0;
88 * First time through, create a crtc and output and hook
89 * them together
91 if (pScrPriv->numOutputs == 0 &&
92 pScrPriv->numCrtcs == 0)
94 crtc = RRCrtcCreate (pScreen, NULL);
95 if (!crtc)
96 return;
97 output = RROutputCreate (pScreen, "default", 7, NULL);
98 if (!output)
99 return;
100 RROutputSetCrtcs (output, &crtc, 1);
101 RROutputSetConnection (output, RR_Connected);
102 #ifdef RENDER
103 RROutputSetSubpixelOrder (output, PictureGetSubpixelOrder (pScreen));
104 #endif
107 output = pScrPriv->outputs[0];
108 if (!output)
109 return;
110 crtc = pScrPriv->crtcs[0];
111 if (!crtc)
112 return;
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];
126 int r;
128 if (size->nRates)
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)
136 newMode = mode;
139 xfree (size->pRates);
141 else
143 mode = RROldModeAdd (output, size, 0);
144 if (i == pScrPriv->size)
145 newMode = mode;
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 ?
157 output->modes[i] :
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 */
171 if (newMode)
172 RRCrtcNotify (crtc, newMode, 0, 0, pScrPriv->rotation,
173 1, &output);
175 #endif
178 * Poll the driver for changed information
180 Bool
181 RRGetInfo (ScreenPtr pScreen)
183 rrScrPriv (pScreen);
184 Rotation rotations;
185 int i;
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;
192 rotations = 0;
193 pScrPriv->changed = FALSE;
194 pScrPriv->configChanged = FALSE;
196 if (!(*pScrPriv->rrGetInfo) (pScreen, &rotations))
197 return FALSE;
199 #if RANDR_10_INTERFACE
200 if (pScrPriv->nSizes)
201 RRScanOldConfig (pScreen, rotations);
202 #endif
203 RRTellChanged (pScreen);
204 return TRUE;
208 * Register the range of sizes for the screen
210 void
211 RRScreenSetSizeRange (ScreenPtr pScreen,
212 CARD16 minWidth,
213 CARD16 minHeight,
214 CARD16 maxWidth,
215 CARD16 maxHeight)
217 rrScrPriv (pScreen);
219 if (!pScrPriv)
220 return;
221 if (pScrPriv->minWidth == minWidth && pScrPriv->minHeight == minHeight &&
222 pScrPriv->maxWidth == maxWidth && pScrPriv->maxHeight == maxHeight)
224 return;
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
236 static Bool
237 RRScreenSizeMatches (RRScreenSizePtr a,
238 RRScreenSizePtr b)
240 if (a->width != b->width)
241 return FALSE;
242 if (a->height != b->height)
243 return FALSE;
244 if (a->mmWidth != b->mmWidth)
245 return FALSE;
246 if (a->mmHeight != b->mmHeight)
247 return FALSE;
248 return TRUE;
251 RRScreenSizePtr
252 RRRegisterSize (ScreenPtr pScreen,
253 short width,
254 short height,
255 short mmWidth,
256 short mmHeight)
258 rrScrPriv (pScreen);
259 int i;
260 RRScreenSize tmp;
261 RRScreenSizePtr pNew;
263 if (!pScrPriv)
264 return 0;
266 tmp.id = 0;
267 tmp.width = width;
268 tmp.height= height;
269 tmp.mmWidth = mmWidth;
270 tmp.mmHeight = mmHeight;
271 tmp.pRates = 0;
272 tmp.nRates = 0;
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));
278 if (!pNew)
279 return 0;
280 pNew[pScrPriv->nSizes++] = tmp;
281 pScrPriv->pSizes = pNew;
282 return &pNew[pScrPriv->nSizes-1];
285 Bool RRRegisterRate (ScreenPtr pScreen,
286 RRScreenSizePtr pSize,
287 int rate)
289 rrScrPriv(pScreen);
290 int i;
291 RRScreenRatePtr pNew, pRate;
293 if (!pScrPriv)
294 return FALSE;
296 for (i = 0; i < pSize->nRates; i++)
297 if (pSize->pRates[i].rate == rate)
298 return TRUE;
300 pNew = xrealloc (pSize->pRates,
301 (pSize->nRates + 1) * sizeof (RRScreenRate));
302 if (!pNew)
303 return FALSE;
304 pRate = &pNew[pSize->nRates++];
305 pRate->rate = rate;
306 pSize->pRates = pNew;
307 return TRUE;
310 Rotation
311 RRGetRotation(ScreenPtr pScreen)
313 RROutputPtr output = RRFirstOutput (pScreen);
315 if (!output)
316 return RR_Rotate_0;
318 return output->crtc->rotation;
321 void
322 RRSetCurrentConfig (ScreenPtr pScreen,
323 Rotation rotation,
324 int rate,
325 RRScreenSizePtr pSize)
327 rrScrPriv (pScreen);
329 if (!pScrPriv)
330 return;
331 pScrPriv->size = pSize - pScrPriv->pSizes;
332 pScrPriv->rotation = rotation;
333 pScrPriv->rate = rate;
335 #endif