diff options
author | Michel Dänzer <michel.daenzer@amd.com> | 2016-07-29 18:41:06 +0900 |
---|---|---|
committer | Keith Packard <keithp@keithp.com> | 2016-07-30 15:43:54 -0700 |
commit | c833c0866f2f8f829185667efe3d6dfa5979a9e8 (patch) | |
tree | dffd34a40f7813dd79344c3e66f7c307249a2611 /present | |
parent | 0924ac014d7caadab0b15ba69cd0a09cfe8a01da (diff) |
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>
Diffstat (limited to 'present')
-rw-r--r-- | present/present_event.c | 29 | ||||
-rw-r--r-- | present/present_request.c | 2 |
2 files changed, 26 insertions, 5 deletions
diff --git a/present/present_event.c b/present/present_event.c index c586c9a60..c222dd5ff 100644 --- a/present/present_event.c +++ b/present/present_event.c @@ -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) diff --git a/present/present_request.c b/present/present_request.c index 35320b64e..c7663fcc8 100644 --- a/present/present_request.c +++ b/present/present_request.c @@ -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; |