summaryrefslogtreecommitdiff
path: root/present
diff options
context:
space:
mode:
authorMichel Dänzer <michel.daenzer@amd.com>2016-07-29 18:41:06 +0900
committerKeith Packard <keithp@keithp.com>2016-07-30 15:43:54 -0700
commitc833c0866f2f8f829185667efe3d6dfa5979a9e8 (patch)
treedffd34a40f7813dd79344c3e66f7c307249a2611 /present
parent0924ac014d7caadab0b15ba69cd0a09cfe8a01da (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.c29
-rw-r--r--present/present_request.c2
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;