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
|
||||
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;
|
||||
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)
|
||||
return BadAlloc;
|
||||
event->mask = mask;
|
||||
else
|
||||
FreeResource(eid, RT_NONE);
|
||||
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));
|
||||
if (!event)
|
||||
|
|
|
@ -184,8 +184,6 @@ proc_present_select_input (ClientPtr client)
|
|||
|
||||
REQUEST_SIZE_MATCH(xPresentSelectInputReq);
|
||||
|
||||
LEGAL_NEW_RESOURCE(stuff->eid, client);
|
||||
|
||||
rc = dixLookupWindow(&window, stuff->window, client, DixGetAttrAccess);
|
||||
if (rc != Success)
|
||||
return rc;
|
||||
|
|
Loading…
Reference in New Issue