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