Skip to content

Commit

Permalink
Fix Pending property API, adding RRPostPendingProperty.
Browse files Browse the repository at this point in the history
Pending Properties take effect when the driver says they do, so provide an
API to tell DIX when a property effect is made. Also, allow driver
to reject property values in RRChangeOutputProperty.
  • Loading branch information
Keith Packard committed Mar 23, 2007
1 parent 9ca7ba5 commit 8eb288f
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 59 deletions.
2 changes: 1 addition & 1 deletion hw/xfree86/modes/xf86Crtc.c
Expand Up @@ -1923,7 +1923,7 @@ xf86OutputSetEDIDProperty (xf86OutputPtr output, void *data, int data_len)

if (data_len != 0) {
RRChangeOutputProperty(output->randr_output, edid_atom, XA_INTEGER, 8,
PropModeReplace, data_len, data, FALSE);
PropModeReplace, data_len, data, FALSE, TRUE);
} else {
RRDeleteOutputProperty(output->randr_output, edid_atom);
}
Expand Down
5 changes: 4 additions & 1 deletion randr/randrstr.h
Expand Up @@ -759,10 +759,13 @@ RRQueryOutputProperty (RROutputPtr output, Atom property);
void
RRDeleteOutputProperty (RROutputPtr output, Atom property);

Bool
RRPostPendingProperty (RROutputPtr output, Atom property);

int
RRChangeOutputProperty (RROutputPtr output, Atom property, Atom type,
int format, int mode, unsigned long len,
pointer value, Bool sendevent);
pointer value, Bool sendevent, Bool pending);

int
RRConfigureOutputProperty (RROutputPtr output, Atom property,
Expand Down
151 changes: 94 additions & 57 deletions randr/rrproperty.c
Expand Up @@ -121,19 +121,19 @@ RRDeleteOutputProperty (RROutputPtr output, Atom property)
int
RRChangeOutputProperty (RROutputPtr output, Atom property, Atom type,
int format, int mode, unsigned long len,
pointer value, Bool sendevent)
pointer value, Bool sendevent, Bool pending)
{
RRPropertyPtr prop;
xRROutputPropertyNotifyEvent event;
rrScrPrivPtr pScrPriv = rrGetScrPriv(output->pScreen);
int sizeInBytes;
int totalSize;
pointer data;
int size_in_bytes;
int total_size;
unsigned long total_len;
RRPropertyValuePtr prop_value;
RRPropertyValueRec new_value;
Bool add = FALSE;

sizeInBytes = format >> 3;
totalSize = len * sizeInBytes;
size_in_bytes = format >> 3;

/* first see if property already exists */
prop = RRQueryOutputProperty (output, property);
Expand All @@ -145,7 +145,7 @@ RRChangeOutputProperty (RROutputPtr output, Atom property, Atom type,
add = TRUE;
mode = PropModeReplace;
}
if (prop->is_pending)
if (pending && prop->is_pending)
prop_value = &prop->pending;
else
prop_value = &prop->current;
Expand All @@ -159,68 +159,75 @@ RRChangeOutputProperty (RROutputPtr output, Atom property, Atom type,
return(BadMatch);
if ((prop_value->type != type) && (mode != PropModeReplace))
return(BadMatch);
new_value = *prop_value;
if (mode == PropModeReplace)
total_len = len;
else
total_len = prop_value->size + len;

if (mode == PropModeReplace || len > 0)
{
if (totalSize != prop_value->size * (prop_value->format >> 3))
pointer new_data, old_data;

total_size = total_len * size_in_bytes;
new_value.data = (pointer)xalloc (total_size);
if (!new_value.data && total_size)
{
if (prop_value->data)
data = (pointer)xrealloc(prop_value->data, totalSize);
else
data = (pointer)xalloc (totalSize);
if (!data && len)
{
if (add)
RRDestroyOutputProperty (prop);
return(BadAlloc);
}
prop_value->data = data;
if (add)
RRDestroyOutputProperty (prop);
return BadAlloc;
}
if (len)
memmove((char *)prop_value->data, (char *)value, totalSize);
prop_value->size = len;
prop_value->type = type;
prop_value->format = format;
memmove((char *)new_value.data, (char *)value, total_size);
new_value.size = len;
new_value.type = type;
new_value.format = format;

switch (mode) {
case PropModeReplace:
new_data = new_value.data;
old_data = NULL;
break;
case PropModeAppend:
new_data = (pointer) (((char *) new_value.data) +
(prop_value->size * size_in_bytes));
old_data = new_value.data;
break;
case PropModePrepend:
new_data = new_value.data;
old_data = (pointer) (((char *) new_value.data) +
(prop_value->size * size_in_bytes));
break;
}
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))
{
if (new_value.data)
xfree (new_value.data);
return (BadValue);
}
if (prop_value->data)
xfree (prop_value->data);
*prop_value = new_value;
}

else if (len == 0)
{
/* do nothing */
}
else if (mode == PropModeAppend)
{
data = (pointer)xrealloc(prop_value->data,
sizeInBytes * (len + prop_value->size));
if (!data)
return(BadAlloc);
prop_value->data = data;
memmove(&((char *)data)[prop_value->size * sizeInBytes],
(char *)value,
totalSize);
prop_value->size += len;
}
else if (mode == PropModePrepend)
{
data = (pointer)xalloc(sizeInBytes * (len + prop_value->size));
if (!data)
return(BadAlloc);
memmove(&((char *)data)[totalSize], (char *)prop_value->data,
(int)(prop_value->size * sizeInBytes));
memmove((char *)data, (char *)value, totalSize);
xfree(prop_value->data);
prop_value->data = data;
prop_value->size += len;
}

if (add)
{
prop->next = output->properties;
output->properties = prop;
}

if (!prop->is_pending && pScrPriv->rrOutputSetProperty) {
/* What should we do in case of failure? */
pScrPriv->rrOutputSetProperty(output->pScreen, output,
prop->propertyName, prop_value);
}

if (sendevent)
{
event.type = RREventBase + RRNotify;
Expand All @@ -234,6 +241,33 @@ RRChangeOutputProperty (RROutputPtr output, Atom property, Atom type,
return(Success);
}

Bool
RRPostPendingProperty (RROutputPtr output, Atom property)
{
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))
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;
}

RRPropertyPtr
RRQueryOutputProperty (RROutputPtr output, Atom property)
{
Expand Down Expand Up @@ -474,7 +508,7 @@ ProcRRChangeOutputProperty (ClientPtr client)

err = RRChangeOutputProperty(output, stuff->property,
stuff->type, (int)format,
(int)mode, len, (pointer)&stuff[1], TRUE);
(int)mode, len, (pointer)&stuff[1], TRUE, TRUE);
if (err != Success)
return err;
else
Expand Down Expand Up @@ -508,8 +542,8 @@ int
ProcRRGetOutputProperty (ClientPtr client)
{
REQUEST(xRRGetOutputPropertyReq);
RRPropertyPtr prop, *prev;
RRPropertyValuePtr prop_value;
RRPropertyPtr prop, *prev;
RRPropertyValuePtr prop_value;
unsigned long n, len, ind;
RROutputPtr output;
xRRGetOutputPropertyReply reply;
Expand Down Expand Up @@ -600,7 +634,10 @@ ProcRRGetOutputProperty (ClientPtr client)
reply.bytesAfter = n - (ind + len);
reply.format = prop_value->format;
reply.length = (len + 3) >> 2;
reply.nItems = len / (prop_value->format / 8 );
if (prop_value->format)
reply.nItems = len / (prop_value->format / 8);
else
reply.nItems = 0;
reply.propertyType = prop_value->type;

if (stuff->delete && (reply.bytesAfter == 0))
Expand Down

0 comments on commit 8eb288f

Please sign in to comment.