Make pending properties force mode set. And, remove AttachScreen calls.

Yes, two changes in one commit. Sorry 'bout that.

The first change ensures that when pending property values have been
changed, a mode set to the current mode will actually do something, rather
than being identified as a no-op. In addition, the driver no longer needs to
manage the migration of pending to current values, that is handled both
within the xf86 mode setting code (to deal with non-RandR changes) as well
as within the RandR extension itself.

The second change eliminates the two-call Create/AttachScreen stuff that was
done in a failed attempt to create RandR resources before the screen
structures were allocated. Merging these back into the Create function is
cleaner.
(cherry picked from commit 57e87e0d00)

Conflicts:

	randr/randrstr.h
	randr/rrcrtc.c

I think master and server-1.3-branch are more in sync now.
This commit is contained in:
Keith Packard 2007-03-23 23:41:36 -07:00
parent 1f77120775
commit 804080a709
8 changed files with 146 additions and 150 deletions

View File

@ -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 */

View File

@ -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;
}

View File

@ -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))

View File

@ -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
@ -561,13 +560,6 @@ Bool
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,18 +662,11 @@ 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
*/
@ -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,

View File

@ -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;
}
@ -468,17 +489,6 @@ RRCrtcGammaSetSize (RRCrtcPtr crtc,
return TRUE;
}
/*
* Set the allowable rotations of the CRTC.
*/
Bool
RRCrtcSetRotations (RRCrtcPtr crtc,
Rotation rotations)
{
crtc->rotations = rotations;
return TRUE;
}
/*
* Initialize crtc type
*/

View File

@ -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);

View File

@ -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,35 +101,10 @@ 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
*/

View File

@ -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;
RRPropertyValuePtr pending_value;
RRPropertyValuePtr current_value;
RRPropertyPtr property;
Bool ret = TRUE;
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))
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