summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hw/xfree86/modes/xf86Crtc.c6
-rw-r--r--hw/xfree86/modes/xf86RandR12.c7
-rw-r--r--randr/mirandr.c11
-rw-r--r--randr/randrstr.h33
-rw-r--r--randr/rrcrtc.c92
-rw-r--r--randr/rrinfo.c11
-rw-r--r--randr/rroutput.c49
-rw-r--r--randr/rrproperty.c89
8 files changed, 147 insertions, 151 deletions
diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index b9895d9da..7d86b6606 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -312,7 +312,13 @@ xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation,
{
xf86OutputPtr output = xf86_config->output[i];
if (output->crtc == crtc)
+ {
output->funcs->commit(output);
+#ifdef RANDR_12_INTERFACE
+ if (output->randr_output)
+ RRPostPendingProperties (output->randr_output);
+#endif
+ }
}
/* XXX free adjustedmode */
diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c
index 4213fea52..6f52ee2d9 100644
--- a/hw/xfree86/modes/xf86RandR12.c
+++ b/hw/xfree86/modes/xf86RandR12.c
@@ -1011,8 +1011,7 @@ xf86RandR12CreateObjects12 (ScreenPtr pScreen)
{
xf86CrtcPtr crtc = config->crtc[c];
- crtc->randr_crtc = RRCrtcCreate (crtc);
- RRCrtcAttachScreen (crtc->randr_crtc, pScreen);
+ crtc->randr_crtc = RRCrtcCreate (pScreen, crtc);
RRCrtcGammaSetSize (crtc->randr_crtc, 256);
}
/*
@@ -1022,13 +1021,13 @@ xf86RandR12CreateObjects12 (ScreenPtr pScreen)
{
xf86OutputPtr output = config->output[o];
- output->randr_output = RROutputCreate (output->name,
+ output->randr_output = RROutputCreate (pScreen, output->name,
strlen (output->name),
output);
- RROutputAttachScreen (output->randr_output, pScreen);
if (output->funcs->create_resources != NULL)
output->funcs->create_resources(output);
+ RRPostPendingProperties (output->randr_output);
}
return TRUE;
}
diff --git a/randr/mirandr.c b/randr/mirandr.c
index 47136fb96..3c4991e5a 100644
--- a/randr/mirandr.c
+++ b/randr/mirandr.c
@@ -133,20 +133,13 @@ miRandRInit (ScreenPtr pScreen)
if (!mode)
return FALSE;
- crtc = RRCrtcCreate (NULL);
+ crtc = RRCrtcCreate (pScreen, NULL);
if (!crtc)
return FALSE;
- if (!RRCrtcAttachScreen (crtc, pScreen))
- {
- RRCrtcDestroy (crtc);
- return FALSE;
- }
- output = RROutputCreate ("screen", 6, NULL);
+ output = RROutputCreate (pScreen, "screen", 6, NULL);
if (!output)
return FALSE;
- if (!RROutputAttachScreen (output, pScreen))
- return FALSE;
if (!RROutputSetClones (output, NULL, 0))
return FALSE;
if (!RROutputSetModes (output, &mode, 1, 0))
diff --git a/randr/randrstr.h b/randr/randrstr.h
index 9f039f747..4cc3a469e 100644
--- a/randr/randrstr.h
+++ b/randr/randrstr.h
@@ -138,6 +138,7 @@ struct _rrOutput {
RRModePtr *userModes;
Bool changed;
RRPropertyPtr properties;
+ Bool pendingProperties;
void *devPrivate;
};
@@ -496,16 +497,14 @@ RRCrtcChanged (RRCrtcPtr crtc, Bool layoutChanged);
* Create a CRTC
*/
RRCrtcPtr
-RRCrtcCreate (void *devPrivate);
+RRCrtcCreate (ScreenPtr pScreen, void *devPrivate);
/*
- * Attach a CRTC to a screen. Once done, this cannot be
- * undone without destroying the CRTC; it is separate from Create
- * only to allow an xf86-based driver to create objects in preinit
+ * Set the allowed rotations on a CRTC
*/
-Bool
-RRCrtcAttachScreen (RRCrtcPtr crtc, ScreenPtr pScreen);
-
+void
+RRCrtcSetRotations (RRCrtcPtr crtc, Rotation rotations);
+
/*
* Notify the extension that the Crtc has been reconfigured,
* the driver calls this whenever it has updated the mode
@@ -562,13 +561,6 @@ RRCrtcGammaSetSize (RRCrtcPtr crtc,
int size);
/*
- * Set the allowable rotations of the CRTC.
- */
-Bool
-RRCrtcSetRotations (RRCrtcPtr crtc,
- Rotation rotations);
-
-/*
* Return the area of the frame buffer scanned out by the crtc,
* taking into account the current mode and rotation
*/
@@ -670,19 +662,12 @@ RROutputChanged (RROutputPtr output, Bool configChanged);
*/
RROutputPtr
-RROutputCreate (const char *name,
+RROutputCreate (ScreenPtr pScreen,
+ const char *name,
int nameLength,
void *devPrivate);
/*
- * Attach an output to a screen, again split from creation so
- * xf86 DDXen can create randr resources before the ScreenRec
- * exists
- */
-Bool
-RROutputAttachScreen (RROutputPtr output, ScreenPtr pScreen);
-
-/*
* Notify extension that output parameters have been changed
*/
Bool
@@ -762,7 +747,7 @@ void
RRDeleteOutputProperty (RROutputPtr output, Atom property);
Bool
-RRPostPendingProperty (RROutputPtr output, Atom property);
+RRPostPendingProperties (RROutputPtr output);
int
RRChangeOutputProperty (RROutputPtr output, Atom property, Atom type,
diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c
index 7131dfb3a..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
*/
@@ -271,7 +285,8 @@ 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))
{
ret = TRUE;
}
@@ -328,7 +343,13 @@ RRCrtcSet (RRCrtcPtr crtc,
#endif
}
if (ret)
+ {
+ int o;
RRTellChanged (pScreen);
+
+ for (o = 0; o < numOutputs; o++)
+ RRPostPendingProperties (outputs[o]);
+ }
}
return ret;
}
@@ -469,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
diff --git a/randr/rrinfo.c b/randr/rrinfo.c
index 549d501dc..5ef1a6b83 100644
--- a/randr/rrinfo.c
+++ b/randr/rrinfo.c
@@ -91,19 +91,12 @@ RRScanOldConfig (ScreenPtr pScreen, Rotation rotations)
if (pScrPriv->numOutputs == 0 &&
pScrPriv->numCrtcs == 0)
{
- crtc = RRCrtcCreate (NULL);
+ crtc = RRCrtcCreate (pScreen, NULL);
if (!crtc)
return;
- if (!RRCrtcAttachScreen (crtc, pScreen))
- {
- RRCrtcDestroy (crtc);
- return;
- }
- output = RROutputCreate ("default", 7, NULL);
+ output = RROutputCreate (pScreen, "default", 7, NULL);
if (!output)
return;
- if (!RROutputAttachScreen (output, pScreen))
- return;
RROutputSetCrtcs (output, &crtc, 1);
RROutputSetCrtc (output, crtc);
RROutputSetConnection (output, RR_Connected);
diff --git a/randr/rroutput.c b/randr/rroutput.c
index 160071bcf..e00116283 100644
--- a/randr/rroutput.c
+++ b/randr/rroutput.c
@@ -47,19 +47,35 @@ RROutputChanged (RROutputPtr output, Bool configChanged)
*/
RROutputPtr
-RROutputCreate (const char *name,
+RROutputCreate (ScreenPtr pScreen,
+ const char *name,
int nameLength,
void *devPrivate)
{
- RROutputPtr output;
+ RROutputPtr output;
+ RROutputPtr *outputs;
+ rrScrPrivPtr pScrPriv;
if (!RRInit())
return NULL;
+
+ pScrPriv = rrGetScrPriv(pScreen);
+
+ if (pScrPriv->numOutputs)
+ outputs = xrealloc (pScrPriv->outputs,
+ (pScrPriv->numOutputs + 1) * sizeof (RROutputPtr));
+ else
+ outputs = xalloc (sizeof (RROutputPtr));
+ if (!outputs)
+ return FALSE;
+
+ pScrPriv->outputs = outputs;
+
output = xalloc (sizeof (RROutputRec) + nameLength + 1);
if (!output)
return NULL;
output->id = FakeClientID (0);
- output->pScreen = NULL;
+ output->pScreen = pScreen;
output->name = (char *) (output + 1);
output->nameLength = nameLength;
memcpy (output->name, name, nameLength);
@@ -85,36 +101,11 @@ RROutputCreate (const char *name,
if (!AddResource (output->id, RROutputType, (pointer) output))
return NULL;
+ pScrPriv->outputs[pScrPriv->numOutputs++] = output;
return output;
}
/*
- * Attach an Output to a screen. This is done as a separate step
- * so that an xf86-based driver can create Outputs in PreInit
- * before the Screen has been created
- */
-
-Bool
-RROutputAttachScreen (RROutputPtr output, ScreenPtr pScreen)
-{
- rrScrPriv (pScreen);
- RROutputPtr *outputs;
-
- if (pScrPriv->numOutputs)
- outputs = xrealloc (pScrPriv->outputs,
- (pScrPriv->numOutputs + 1) * sizeof (RROutputPtr));
- else
- outputs = xalloc (sizeof (RROutputPtr));
- if (!outputs)
- return FALSE;
- output->pScreen = pScreen;
- pScrPriv->outputs = outputs;
- pScrPriv->outputs[pScrPriv->numOutputs++] = output;
- RROutputChanged (output, FALSE);
- return TRUE;
-}
-
-/*
* Notify extension that output parameters have been changed
*/
Bool
diff --git a/randr/rrproperty.c b/randr/rrproperty.c
index 148e4a27d..5ac073f81 100644
--- a/randr/rrproperty.c
+++ b/randr/rrproperty.c
@@ -27,7 +27,7 @@
static void
RRDeliverEvent (ScreenPtr pScreen, xEvent *event, CARD32 mask)
{
-
+
}
void
@@ -50,7 +50,7 @@ RRDeleteAllOutputProperties (RROutputPtr output)
xfree(prop->current.data);
if (prop->pending.data)
xfree(prop->pending.data);
- xfree(prop);
+ xfree(prop);
}
}
@@ -67,7 +67,7 @@ static RRPropertyPtr
RRCreateOutputProperty (Atom property)
{
RRPropertyPtr prop;
-
+
prop = (RRPropertyPtr)xalloc(sizeof(RRPropertyRec));
if (!prop)
return NULL;
@@ -139,7 +139,7 @@ RRChangeOutputProperty (RROutputPtr output, Atom property, Atom type,
prop = RRQueryOutputProperty (output, property);
if (!prop) /* just add to list */
{
- prop = RRCreateOutputProperty (property);
+ prop = RRCreateOutputProperty (property);
if (!prop)
return(BadAlloc);
add = TRUE;
@@ -149,11 +149,11 @@ RRChangeOutputProperty (RROutputPtr output, Atom property, Atom type,
prop_value = &prop->pending;
else
prop_value = &prop->current;
-
+
/* To append or prepend to a property the request format and type
- must match those of the already defined property. The
- existing format and type are irrelevant when using the mode
- "PropModeReplace" since they will be written over. */
+ must match those of the already defined property. The
+ existing format and type are irrelevant when using the mode
+ "PropModeReplace" since they will be written over. */
if ((format != prop_value->format) && (mode != PropModeReplace))
return(BadMatch);
@@ -167,8 +167,8 @@ RRChangeOutputProperty (RROutputPtr output, Atom property, Atom type,
if (mode == PropModeReplace || len > 0)
{
- pointer new_data, old_data;
-
+ pointer new_data = NULL, old_data = NULL;
+
total_size = total_len * size_in_bytes;
new_value.data = (pointer)xalloc (total_size);
if (!new_value.data && total_size)
@@ -197,11 +197,12 @@ RRChangeOutputProperty (RROutputPtr output, Atom property, Atom type,
(prop_value->size * size_in_bytes));
break;
}
- memcpy ((char *) new_data, (char *) value, len * size_in_bytes);
+ if (new_data)
+ memcpy ((char *) new_data, (char *) value, len * size_in_bytes);
if (old_data)
memcpy ((char *) old_data, (char *) prop_value->data,
prop_value->size * size_in_bytes);
-
+
if (pending && pScrPriv->rrOutputSetProperty &&
!pScrPriv->rrOutputSetProperty(output->pScreen, output,
prop->propertyName, &new_value))
@@ -214,18 +215,21 @@ RRChangeOutputProperty (RROutputPtr output, Atom property, Atom type,
xfree (prop_value->data);
*prop_value = new_value;
}
-
+
else if (len == 0)
{
/* do nothing */
}
-
+
if (add)
{
prop->next = output->properties;
output->properties = prop;
}
+ if (pending && prop->is_pending)
+ output->pendingProperties = TRUE;
+
if (sendevent)
{
event.type = RREventBase + RRNotify;
@@ -240,30 +244,45 @@ RRChangeOutputProperty (RROutputPtr output, Atom property, Atom type,
}
Bool
-RRPostPendingProperty (RROutputPtr output, Atom property)
+RRPostPendingProperties (RROutputPtr output)
{
- RRPropertyPtr prop = RRQueryOutputProperty (output, property);
- RRPropertyValuePtr pending_value;
- RRPropertyValuePtr current_value;
-
- if (!prop)
- return FALSE;
- if (!prop->is_pending)
- return FALSE;
- pending_value = &prop->pending;
- current_value = &prop->current;
-
- if (pending_value->type == current_value->type &&
- pending_value->format == current_value->format &&
- pending_value->size == current_value->size &&
- !memcmp (pending_value->data, current_value->data, pending_value->size))
+ RRPropertyValuePtr pending_value;
+ RRPropertyValuePtr current_value;
+ RRPropertyPtr property;
+ Bool ret = TRUE;
+
+ if (!output->pendingProperties)
return TRUE;
- if (RRChangeOutputProperty (output, property,
- pending_value->type, pending_value->format, PropModeReplace,
- pending_value->size, pending_value->data, TRUE, FALSE) != Success)
- return FALSE;
- return TRUE;
+ output->pendingProperties = FALSE;
+ for (property = output->properties; property; property = property->next)
+ {
+ /* Skip non-pending properties */
+ if (!property->is_pending)
+ continue;
+
+ pending_value = &property->pending;
+ current_value = &property->current;
+
+ /*
+ * If the pending and current values are equal, don't mark it
+ * as changed (which would deliver an event)
+ */
+ if (pending_value->type == current_value->type &&
+ pending_value->format == current_value->format &&
+ pending_value->size == current_value->size &&
+ !memcmp (pending_value->data, current_value->data,
+ pending_value->size))
+ continue;
+
+ if (RRChangeOutputProperty (output, property->propertyName,
+ pending_value->type, pending_value->format,
+ PropModeReplace, pending_value->size,
+ pending_value->data, TRUE,
+ FALSE) != Success)
+ ret = FALSE;
+ }
+ return ret;
}
RRPropertyPtr