present: Handle event mask updates as specified v2
From the Present extension specification: An event context is associated with a specific window; using an existing event context with a different window generates a Match error. If eventContext specifies an existing event context, then if eventMask is empty, PresentSelectInput deletes the specified context, otherwise the specified event context is changed to select a different set of events. If eventContext is an unused XID, then if eventMask is empty no operation is performed. Otherwise, a new event context is created selecting the specified events. Without this change, there's no way for a client to explicitly change or destroy an existing event mask entry. Trying to do so as specified above would just result in a protocol error. v2: (Keith Packard) * Use dixLookupResourceByType instead of walking window_priv->events * Return BadMatch if the existing event context is associated with a different window or client * Call LEGAL_NEW_RESOURCE again when creating a new event context * Drop invalid "leak fix" Signed-off-by: Michel Dänzer <michel.daenzer@amd.com> Signed-off-by: Keith Packard <keithp@keithp.com> Reviewed-by: Keith Packard <keithp@keithp.com> Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
This commit is contained in:
parent
0924ac014d
commit
c833c0866f
|
@ -208,14 +208,37 @@ present_send_idle_notify(WindowPtr window, CARD32 serial, PixmapPtr pixmap, stru
|
||||||
int
|
int
|
||||||
present_select_input(ClientPtr client, XID eid, WindowPtr window, CARD32 mask)
|
present_select_input(ClientPtr client, XID eid, WindowPtr window, CARD32 mask)
|
||||||
{
|
{
|
||||||
present_window_priv_ptr window_priv = present_get_window_priv(window, mask != 0);
|
present_window_priv_ptr window_priv;
|
||||||
present_event_ptr event;
|
present_event_ptr event;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* Check to see if we're modifying an existing event selection */
|
||||||
|
ret = dixLookupResourceByType((void **) &event, eid, present_event_type,
|
||||||
|
client, DixWriteAccess);
|
||||||
|
if (ret == Success) {
|
||||||
|
/* Match error for the wrong window; also don't modify some other
|
||||||
|
* client's event selection
|
||||||
|
*/
|
||||||
|
if (event->window != window || event->client != client)
|
||||||
|
return BadMatch;
|
||||||
|
|
||||||
if (!window_priv) {
|
|
||||||
if (mask)
|
if (mask)
|
||||||
return BadAlloc;
|
event->mask = mask;
|
||||||
|
else
|
||||||
|
FreeResource(eid, RT_NONE);
|
||||||
return Success;
|
return Success;
|
||||||
}
|
}
|
||||||
|
if (ret != BadValue)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if (mask == 0)
|
||||||
|
return Success;
|
||||||
|
|
||||||
|
LEGAL_NEW_RESOURCE(eid, client);
|
||||||
|
|
||||||
|
window_priv = present_get_window_priv(window, TRUE);
|
||||||
|
if (!window_priv)
|
||||||
|
return BadAlloc;
|
||||||
|
|
||||||
event = calloc (1, sizeof (present_event_rec));
|
event = calloc (1, sizeof (present_event_rec));
|
||||||
if (!event)
|
if (!event)
|
||||||
|
|
|
@ -184,8 +184,6 @@ proc_present_select_input (ClientPtr client)
|
||||||
|
|
||||||
REQUEST_SIZE_MATCH(xPresentSelectInputReq);
|
REQUEST_SIZE_MATCH(xPresentSelectInputReq);
|
||||||
|
|
||||||
LEGAL_NEW_RESOURCE(stuff->eid, client);
|
|
||||||
|
|
||||||
rc = dixLookupWindow(&window, stuff->window, client, DixGetAttrAccess);
|
rc = dixLookupWindow(&window, stuff->window, client, DixGetAttrAccess);
|
||||||
if (rc != Success)
|
if (rc != Success)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
Loading…
Reference in New Issue