summaryrefslogtreecommitdiff
path: root/randr/rrcrtc.c
diff options
context:
space:
mode:
Diffstat (limited to 'randr/rrcrtc.c')
-rw-r--r--randr/rrcrtc.c196
1 files changed, 110 insertions, 86 deletions
diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c
index db506f4b0..1dfc3bbb0 100644
--- a/randr/rrcrtc.c
+++ b/randr/rrcrtc.c
@@ -51,17 +51,32 @@ RRCrtcChanged (RRCrtcPtr crtc, Bool layoutChanged)
* Create a CRTC
*/
RRCrtcPtr
-RRCrtcCreate (void *devPrivate)
+RRCrtcCreate (ScreenPtr pScreen, void *devPrivate)
{
- RRCrtcPtr crtc;
-
+ RRCrtcPtr crtc;
+ RRCrtcPtr *crtcs;
+ rrScrPrivPtr pScrPriv;
+
if (!RRInit())
return NULL;
+
+ pScrPriv = rrGetScrPriv(pScreen);
+
+ /* make space for the crtc pointer */
+ if (pScrPriv->numCrtcs)
+ crtcs = xrealloc (pScrPriv->crtcs,
+ (pScrPriv->numCrtcs + 1) * sizeof (RRCrtcPtr));
+ else
+ crtcs = xalloc (sizeof (RRCrtcPtr));
+ if (!crtcs)
+ return FALSE;
+ pScrPriv->crtcs = crtcs;
+
crtc = xalloc (sizeof (RRCrtcRec));
if (!crtc)
return NULL;
crtc->id = FakeClientID (0);
- crtc->pScreen = NULL;
+ crtc->pScreen = pScreen;
crtc->mode = NULL;
crtc->x = 0;
crtc->y = 0;
@@ -77,37 +92,20 @@ RRCrtcCreate (void *devPrivate)
if (!AddResource (crtc->id, RRCrtcType, (pointer) crtc))
return NULL;
+ /* attach the screen and crtc together */
+ crtc->pScreen = pScreen;
+ pScrPriv->crtcs[pScrPriv->numCrtcs++] = crtc;
+
return crtc;
}
/*
- * Attach a Crtc to a screen. This is done as a separate step
- * so that an xf86-based driver can create CRTCs in PreInit
- * before the Screen has been created
+ * Set the allowed rotations on a CRTC
*/
-
-Bool
-RRCrtcAttachScreen (RRCrtcPtr crtc, ScreenPtr pScreen)
+void
+RRCrtcSetRotations (RRCrtcPtr crtc, Rotation rotations)
{
- rrScrPriv (pScreen);
- RRCrtcPtr *crtcs;
-
- /* make space for the crtc pointer */
- if (pScrPriv->numCrtcs)
- crtcs = xrealloc (pScrPriv->crtcs,
- (pScrPriv->numCrtcs + 1) * sizeof (RRCrtcPtr));
- else
- crtcs = xalloc (sizeof (RRCrtcPtr));
- if (!crtcs)
- return FALSE;
-
- /* attach the screen and crtc together */
- crtc->pScreen = pScreen;
- pScrPriv->crtcs = crtcs;
- pScrPriv->crtcs[pScrPriv->numCrtcs++] = crtc;
-
- RRCrtcChanged (crtc, TRUE);
- return TRUE;
+ crtc->rotations = rotations;
}
/*
@@ -249,6 +247,22 @@ RRDeliverCrtcEvent (ClientPtr client, WindowPtr pWin, RRCrtcPtr crtc)
WriteEventsToClient (client, 1, (xEvent *) &ce);
}
+static Bool
+RRCrtcPendingProperties (RRCrtcPtr crtc)
+{
+ ScreenPtr pScreen = crtc->pScreen;
+ rrScrPriv(pScreen);
+ int o;
+
+ for (o = 0; o < pScrPriv->numOutputs; o++)
+ {
+ RROutputPtr output = pScrPriv->outputs[o];
+ if (output->crtc == crtc && output->pendingProperties)
+ return TRUE;
+ }
+ return FALSE;
+}
+
/*
* Request that the Crtc be reconfigured
*/
@@ -262,6 +276,8 @@ RRCrtcSet (RRCrtcPtr crtc,
RROutputPtr *outputs)
{
ScreenPtr pScreen = crtc->pScreen;
+ Bool ret = FALSE;
+ rrScrPriv(pScreen);
/* See if nothing changed */
if (crtc->mode == mode &&
@@ -269,63 +285,73 @@ RRCrtcSet (RRCrtcPtr crtc,
crtc->y == y &&
crtc->rotation == rotation &&
crtc->numOutputs == numOutputs &&
- !memcmp (crtc->outputs, outputs, numOutputs * sizeof (RROutputPtr)))
+ !memcmp (crtc->outputs, outputs, numOutputs * sizeof (RROutputPtr)) &&
+ !RRCrtcPendingProperties (crtc))
{
- return TRUE;
+ ret = TRUE;
}
- if (pScreen)
+ else
{
#if RANDR_12_INTERFACE
- rrScrPriv(pScreen);
if (pScrPriv->rrCrtcSet)
{
- return (*pScrPriv->rrCrtcSet) (pScreen, crtc, mode, x, y,
- rotation, numOutputs, outputs);
+ ret = (*pScrPriv->rrCrtcSet) (pScreen, crtc, mode, x, y,
+ rotation, numOutputs, outputs);
}
+ else
#endif
-#if RANDR_10_INTERFACE
- if (pScrPriv->rrSetConfig)
{
- RRScreenSize size;
- RRScreenRate rate;
- Bool ret;
-
- if (!mode)
+#if RANDR_10_INTERFACE
+ if (pScrPriv->rrSetConfig)
{
- RRCrtcNotify (crtc, NULL, x, y, rotation, 0, NULL);
- return TRUE;
+ RRScreenSize size;
+ RRScreenRate rate;
+
+ if (!mode)
+ {
+ RRCrtcNotify (crtc, NULL, x, y, rotation, 0, NULL);
+ ret = TRUE;
+ }
+ else
+ {
+ size.width = mode->mode.width;
+ size.height = mode->mode.height;
+ if (outputs[0]->mmWidth && outputs[0]->mmHeight)
+ {
+ size.mmWidth = outputs[0]->mmWidth;
+ size.mmHeight = outputs[0]->mmHeight;
+ }
+ else
+ {
+ size.mmWidth = pScreen->mmWidth;
+ size.mmHeight = pScreen->mmHeight;
+ }
+ size.nRates = 1;
+ rate.rate = RRVerticalRefresh (&mode->mode);
+ size.pRates = &rate;
+ ret = (*pScrPriv->rrSetConfig) (pScreen, rotation, rate.rate, &size);
+ /*
+ * Old 1.0 interface tied screen size to mode size
+ */
+ if (ret)
+ {
+ RRCrtcNotify (crtc, mode, x, y, rotation, 1, outputs);
+ RRScreenSizeNotify (pScreen);
+ }
+ }
}
+#endif
+ }
+ if (ret)
+ {
+ int o;
+ RRTellChanged (pScreen);
- size.width = mode->mode.width;
- size.height = mode->mode.height;
- if (outputs[0]->mmWidth && outputs[0]->mmHeight)
- {
- size.mmWidth = outputs[0]->mmWidth;
- size.mmHeight = outputs[0]->mmHeight;
- }
- else
- {
- size.mmWidth = pScreen->mmWidth;
- size.mmHeight = pScreen->mmHeight;
- }
- size.nRates = 1;
- rate.rate = RRVerticalRefresh (&mode->mode);
- size.pRates = &rate;
- ret = (*pScrPriv->rrSetConfig) (pScreen, rotation, rate.rate, &size);
- /*
- * Old 1.0 interface tied screen size to mode size
- */
- if (ret)
- {
- RRCrtcNotify (crtc, mode, x, y, rotation, 1, outputs);
- RRScreenSizeNotify (pScreen);
- }
- return ret;
+ for (o = 0; o < numOutputs; o++)
+ RRPostPendingProperties (outputs[o]);
}
-#endif
- RRTellChanged (pScreen);
}
- return FALSE;
+ return ret;
}
/*
@@ -361,6 +387,8 @@ RRCrtcDestroyResource (pointer value, XID pid)
}
if (crtc->gammaRed)
xfree (crtc->gammaRed);
+ if (crtc->mode)
+ RRModeDestroy (crtc->mode);
xfree (crtc);
return 1;
}
@@ -462,17 +490,6 @@ RRCrtcGammaSetSize (RRCrtcPtr crtc,
}
/*
- * Set the allowable rotations of the CRTC.
- */
-Bool
-RRCrtcSetRotations (RRCrtcPtr crtc,
- Rotation rotations)
-{
- crtc->rotations = rotations;
- return TRUE;
-}
-
-/*
* Initialize crtc type
*/
Bool
@@ -666,10 +683,15 @@ ProcRRSetCrtcConfig (ClientPtr client)
return BadMatch;
}
/* validate mode for this output */
- for (j = 0; j < outputs[i]->numModes; j++)
- if (outputs[i]->modes[j] == mode)
+ for (j = 0; j < outputs[i]->numModes + outputs[i]->numUserModes; j++)
+ {
+ RRModePtr m = (j < outputs[i]->numModes ?
+ outputs[i]->modes[j] :
+ outputs[i]->userModes[j - outputs[i]->numModes]);
+ if (m == mode)
break;
- if (j == outputs[i]->numModes)
+ }
+ if (j == outputs[i]->numModes + outputs[i]->numUserModes)
{
if (outputs)
xfree (outputs);
@@ -711,6 +733,7 @@ ProcRRSetCrtcConfig (ClientPtr client)
goto sendReply;
}
+#if 0
/*
* if the client's config timestamp is not the same as the last config
* timestamp, then the config information isn't up-to-date and
@@ -721,6 +744,7 @@ ProcRRSetCrtcConfig (ClientPtr client)
rep.status = RRSetConfigInvalidConfigTime;
goto sendReply;
}
+#endif
/*
* Validate requested rotation