randr: Make deletion of output properties more robust
Previously there was two branches of code with small discrepancies between them (especially prop->valid_values field was not free(3)ed). Extract the common routine and fix double-free prop->valid_values in RRDestroyOutputProperty by the way. Signed-off-by: Mikhail Gusarov <dottedmag@dottedmag.net> Reviewed-by: Jamey Sharp <jamey@minilop.net>
This commit is contained in:
parent
0a4d8cbdcd
commit
67b824a81b
|
@ -53,25 +53,39 @@ static void RRDeliverPropertyEvent(ScreenPtr pScreen, xEvent *event)
|
||||||
WalkTree(pScreen, DeliverPropertyEvent, event);
|
WalkTree(pScreen, DeliverPropertyEvent, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
RRDestroyOutputProperty (RRPropertyPtr prop)
|
||||||
|
{
|
||||||
|
free(prop->valid_values);
|
||||||
|
free(prop->current.data);
|
||||||
|
free(prop->pending.data);
|
||||||
|
free(prop);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
RRDeleteProperty(RROutputRec *output, RRPropertyRec *prop)
|
||||||
|
{
|
||||||
|
xRROutputPropertyNotifyEvent event;
|
||||||
|
event.type = RREventBase + RRNotify;
|
||||||
|
event.subCode = RRNotify_OutputProperty;
|
||||||
|
event.output = output->id;
|
||||||
|
event.state = PropertyDelete;
|
||||||
|
event.atom = prop->propertyName;
|
||||||
|
event.timestamp = currentTime.milliseconds;
|
||||||
|
|
||||||
|
RRDeliverPropertyEvent(output->pScreen, (xEvent *)&event);
|
||||||
|
|
||||||
|
RRDestroyOutputProperty(prop);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
RRDeleteAllOutputProperties (RROutputPtr output)
|
RRDeleteAllOutputProperties(RROutputPtr output)
|
||||||
{
|
{
|
||||||
RRPropertyPtr prop, next;
|
RRPropertyPtr prop, next;
|
||||||
xRROutputPropertyNotifyEvent event;
|
|
||||||
|
|
||||||
for (prop = output->properties; prop; prop = next)
|
for (prop = output->properties; prop; prop = next) {
|
||||||
{
|
|
||||||
next = prop->next;
|
next = prop->next;
|
||||||
event.type = RREventBase + RRNotify;
|
RRDeleteProperty(output, prop);
|
||||||
event.subCode = RRNotify_OutputProperty;
|
|
||||||
event.output = output->id;
|
|
||||||
event.state = PropertyDelete;
|
|
||||||
event.atom = prop->propertyName;
|
|
||||||
event.timestamp = currentTime.milliseconds;
|
|
||||||
RRDeliverPropertyEvent (output->pScreen, (xEvent *)&event);
|
|
||||||
free(prop->current.data);
|
|
||||||
free(prop->pending.data);
|
|
||||||
free(prop);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,37 +118,17 @@ RRCreateOutputProperty (Atom property)
|
||||||
return prop;
|
return prop;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
RRDestroyOutputProperty (RRPropertyPtr prop)
|
|
||||||
{
|
|
||||||
free(prop->valid_values);
|
|
||||||
free(prop->current.data);
|
|
||||||
free(prop->pending.data);
|
|
||||||
free(prop->valid_values);
|
|
||||||
free(prop);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
RRDeleteOutputProperty (RROutputPtr output, Atom property)
|
RRDeleteOutputProperty(RROutputPtr output, Atom property)
|
||||||
{
|
{
|
||||||
RRPropertyPtr prop, *prev;
|
RRPropertyRec *prop, **prev;
|
||||||
xRROutputPropertyNotifyEvent event;
|
|
||||||
|
|
||||||
for (prev = &output->properties; (prop = *prev); prev = &(prop->next))
|
for (prev = &output->properties; (prop = *prev); prev = &(prop->next))
|
||||||
if (prop->propertyName == property)
|
if (prop->propertyName == property) {
|
||||||
break;
|
*prev = prop->next;
|
||||||
if (prop)
|
RRDeleteProperty(output, prop);
|
||||||
{
|
return;
|
||||||
*prev = prop->next;
|
}
|
||||||
event.type = RREventBase + RRNotify;
|
|
||||||
event.subCode = RRNotify_OutputProperty;
|
|
||||||
event.output = output->id;
|
|
||||||
event.state = PropertyDelete;
|
|
||||||
event.atom = prop->propertyName;
|
|
||||||
event.timestamp = currentTime.milliseconds;
|
|
||||||
RRDeliverPropertyEvent (output->pScreen, (xEvent *)&event);
|
|
||||||
RRDestroyOutputProperty (prop);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
Loading…
Reference in New Issue