[PATCH xserver] present: Handle event mask updates as specified

Michel Dänzer michel at daenzer.net
Thu Jul 28 08:58:57 UTC 2016


From: Michel Dänzer <michel.daenzer at amd.com>

>From the Present extension specification:

 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 actually result in a new entry being created with
the mask value passed in.

While we're at it, fix a memory leak if AddResource fails.

Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
---
 present/present_event.c   | 22 ++++++++++++++++++++--
 present/present_request.c |  2 --
 2 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/present/present_event.c b/present/present_event.c
index c586c9a..05862ca 100644
--- a/present/present_event.c
+++ b/present/present_event.c
@@ -209,7 +209,7 @@ 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_event_ptr event;
+    present_event_ptr event, next;
 
     if (!window_priv) {
         if (mask)
@@ -217,6 +217,22 @@ present_select_input(ClientPtr client, XID eid, WindowPtr window, CARD32 mask)
         return Success;
     }
 
+    for (event = window_priv->events; event; event = next) {
+        next = event->next;
+
+        if (event->client == client && event->id == eid) {
+            if (mask)
+                event->mask = mask;
+            else
+                FreeResource(eid, RT_NONE);
+
+            return Success;
+        }
+    }
+
+    if (!mask)
+        return Success;
+
     event = calloc (1, sizeof (present_event_rec));
     if (!event)
         return BadAlloc;
@@ -229,8 +245,10 @@ present_select_input(ClientPtr client, XID eid, WindowPtr window, CARD32 mask)
     event->next = window_priv->events;
     window_priv->events = event;
 
-    if (!AddResource(event->id, present_event_type, (void *) event))
+    if (!AddResource(event->id, present_event_type, (void *) event)) {
+        free(event);
         return BadAlloc;
+    }
 
     return Success;
 }
diff --git a/present/present_request.c b/present/present_request.c
index 35320b6..c7663fc 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;
-- 
2.8.1



More information about the xorg-devel mailing list