@ -9,31 +9,19 @@
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					# define PRESENTATION_VERSION 1 # define PRESENTATION_VERSION 1  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					static  struct  wlr_presentation_feedback  * presentation_feedback_from_resource (  
			
		
	
		
		
			
				
					
							struct  wl_resource  * resource )  { 
 
			
		
	
		
		
			
				
					
						assert ( wl_resource_instance_of ( resource , 
 
			
		
	
		
		
			
				
					
							& wp_presentation_feedback_interface ,  NULL ) ) ; 
 
			
		
	
		
		
			
				
					
						return  wl_resource_get_user_data ( resource ) ; 
 
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					static  void  feedback_handle_resource_destroy ( struct  wl_resource  * resource )  { static  void  feedback_handle_resource_destroy ( struct  wl_resource  * resource )  {  
			
		
	
		
		
			
				
					
						struct  wlr_presentation_feedback  * feedback  = 
	wl_list_remove ( wl_resource_get_link ( resource ) ) ; 
 
			
				
				
			
		
	
		
		
			
				
					
							presentation_feedback_from_resource ( resource ) ; 
 
			
		
	
		
		
			
				
					
						wl_list_remove ( & feedback - > surface_commit . link ) ; 
 
			
		
	
		
		
			
				
					
						wl_list_remove ( & feedback - > surface_destroy . link ) ; 
 
			
		
	
		
		
			
				
					
						wl_list_remove ( & feedback - > link ) ; 
 
			
		
	
		
		
			
				
					
						free ( feedback ) ; 
 
			
		
	
		
		
	
		
		
			
				
					
					} }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					// Destroys the feedback
 static  void  feedback_resource_send_presented (  
			
				
				
			
		
	
		
		
			
				
					
					static  void  feedback_send_presented ( struct  wlr_presentation_feedback  * feedback , 		struct  wl_resource  * feedback_resource , 
 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
							struct  wlr_presentation_event  * event )  { 
		struct  wlr_presentation_event  * event )  { 
 
			
		
	
		
		
			
				
					
						struct  wl_client  * client  =  wl_resource_get_client ( feedback - > ) ; 
	struct  wl_client  * client  =  wl_resource_get_client ( feedback _ resource) ; 
 
			
				
				
			
		
	
		
		
			
				
					
						struct  wl_resource  * ; 
	struct  wl_resource  * output_ resource; 
 
			
				
				
			
		
	
		
		
			
				
					
						wl_resource_for_each ( ,  & event - > output - > resources )  { 
	wl_resource_for_each ( output_ resource,  & event - > output - > resources )  { 
 
			
				
				
			
		
	
		
		
			
				
					
							if  ( wl_resource_get_client ( )  = =  client )  { 
		if  ( wl_resource_get_client ( output_ resource)  = =  client )  { 
 
			
				
				
			
		
	
		
		
			
				
					
								wp_presentation_feedback_send_sync_output ( feedback - > , 
			wp_presentation_feedback_send_sync_output ( feedback _ resource, 
 
			
				
				
			
		
	
		
		
			
				
					
									) ; 
				output_ resource) ; 
 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
							} 
		} 
 
			
		
	
		
		
			
				
					
						} 
	} 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -41,18 +29,17 @@ static void feedback_send_presented(struct wlr_presentation_feedback *feedback,
 
			
		
	
		
		
			
				
					
						uint32_t  tv_sec_lo  =  event - > tv_sec  &  0xFFFFFFFF ; 
	uint32_t  tv_sec_lo  =  event - > tv_sec  &  0xFFFFFFFF ; 
 
			
		
	
		
		
			
				
					
						uint32_t  seq_hi  =  event - > seq  > >  32 ; 
	uint32_t  seq_hi  =  event - > seq  > >  32 ; 
 
			
		
	
		
		
			
				
					
						uint32_t  seq_lo  =  event - > seq  &  0xFFFFFFFF ; 
	uint32_t  seq_lo  =  event - > seq  &  0xFFFFFFFF ; 
 
			
		
	
		
		
			
				
					
						wp_presentation_feedback_send_presented ( feedback - > , 
	wp_presentation_feedback_send_presented ( feedback _ resource, 
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
							tv_sec_hi ,  tv_sec_lo ,  event - > tv_nsec ,  event - > refresh , 
		tv_sec_hi ,  tv_sec_lo ,  event - > tv_nsec ,  event - > refresh , 
 
			
		
	
		
		
			
				
					
							seq_hi ,  seq_lo ,  event - > flags ) ; 
		seq_hi ,  seq_lo ,  event - > flags ) ; 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
						wl_resource_destroy ( feedback - > ) ; 
	wl_resource_destroy ( feedback _ resource) ; 
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					} }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					// Destroys the feedback
 static  void  feedback_resource_send_discarded (  
			
				
				
			
		
	
		
		
			
				
					
					static  void  feedback_send_discarded ( 		struct  wl_resource  * feedback_resource )  { 
 
			
				
				
			
		
	
		
		
			
				
					
							struct  wlr_presentation_feedback  * feedback )  { 
	wp_presentation_feedback_send_discarded ( feedback_resource ) ; 
 
			
				
				
			
		
	
		
		
			
				
					
						wp_presentation_feedback_send_discarded ( feedback - > resource ) ; 
	wl_resource_destroy ( feedback_resource ) ; 
 
			
				
				
			
		
	
		
		
			
				
					
						wl_resource_destroy ( feedback - > resource ) ; 
 
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					} }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					static  void  feedback_handle_surface_commit ( struct  wl_listener  * listener , static  void  feedback_handle_surface_commit ( struct  wl_listener  * listener ,  
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -63,18 +50,33 @@ static void feedback_handle_surface_commit(struct wl_listener *listener,
 
			
		
	
		
		
			
				
					
						if  ( feedback - > committed )  { 
	if  ( feedback - > committed )  { 
 
			
		
	
		
		
			
				
					
							if  ( ! feedback - > sampled )  { 
		if  ( ! feedback - > sampled )  { 
 
			
		
	
		
		
			
				
					
								// The content update has been superseded
 
			// The content update has been superseded
 
 
			
		
	
		
		
			
				
					
								feedback_send_discarded ( feedback ) ; 
			wlr_presentation_feedback_destroy ( feedback ) ; 
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
							} 
		} 
 
			
		
	
		
		
			
				
					
						}  else  { 
	}  else  { 
 
			
		
	
		
		
			
				
					
							feedback - > committed  =  true ; 
		feedback - > committed  =  true ; 
 
			
		
	
		
		
			
				
					
						} 
	} 
 
			
		
	
		
		
			
				
					
					} }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					static  void  feedback_unset_surface ( struct  wlr_presentation_feedback  * feedback )  {  
			
		
	
		
		
			
				
					
						if  ( feedback - > surface  = =  NULL )  { 
 
			
		
	
		
		
			
				
					
							return ; 
 
			
		
	
		
		
			
				
					
						} 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
						feedback - > surface  =  NULL ; 
 
			
		
	
		
		
			
				
					
						wl_list_remove ( & feedback - > surface_commit . link ) ; 
 
			
		
	
		
		
			
				
					
						wl_list_remove ( & feedback - > surface_destroy . link ) ; 
 
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					static  void  feedback_handle_surface_destroy ( struct  wl_listener  * listener , static  void  feedback_handle_surface_destroy ( struct  wl_listener  * listener ,  
			
		
	
		
		
			
				
					
							void  * data )  { 
		void  * data )  { 
 
			
		
	
		
		
			
				
					
						struct  wlr_presentation_feedback  * feedback  = 
	struct  wlr_presentation_feedback  * feedback  = 
 
			
		
	
		
		
			
				
					
							wl_container_of ( listener ,  feedback ,  surface_destroy ) ; 
		wl_container_of ( listener ,  feedback ,  surface_destroy ) ; 
 
			
		
	
		
		
			
				
					
						feedback_send_discarded ( feedback ) ; 
	if  ( feedback - > sampled )  { 
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
							// The compositor might have a handle on this feedback
 
 
			
		
	
		
		
			
				
					
							feedback_unset_surface ( feedback ) ; 
 
			
		
	
		
		
			
				
					
						}  else  { 
 
			
		
	
		
		
			
				
					
							wlr_presentation_feedback_destroy ( feedback ) ; 
 
			
		
	
		
		
			
				
					
						} 
 
			
		
	
		
		
			
				
					
					} }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					static  const  struct  wp_presentation_interface  presentation_impl ; static  const  struct  wp_presentation_interface  presentation_impl ;  
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -87,31 +89,29 @@ static struct wlr_presentation *presentation_from_resource(
 
			
		
	
		
		
			
				
					
					} }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					static  void  presentation_handle_feedback ( struct  wl_client  * client , static  void  presentation_handle_feedback ( struct  wl_client  * client ,  
			
		
	
		
		
			
				
					
							struct  wl_resource  * resource,  struct  wl_resource  * surface  _resource, 
		struct  wl_resource  * presentation _resource, 
 
			
				
				
			
		
	
		
		
			
				
					
							uint32_t  id )  { 
		struct  wl_resource  * surface_resource ,  uint32_t  id )  { 
 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
						struct  wlr_presentation  * presentation  = 
	struct  wlr_presentation  * presentation  = 
 
			
		
	
		
		
			
				
					
							presentation_from_resource ( ) ; 
		presentation_from_resource ( presentation_ resource) ; 
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
						struct  wlr_surface  * surface  =  wlr_surface_from_resource ( surface_resource ) ; 
	struct  wlr_surface  * surface  =  wlr_surface_from_resource ( surface_resource ) ; 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
						struct  wlr_presentation_feedback  * feedback  = 
	bool  found  =  false ; 
 
			
				
				
			
		
	
		
		
			
				
					
							calloc ( 1 ,  sizeof ( struct  wlr_presentation_feedback ) ) ; 
	struct  wlr_presentation_feedback  * feedback ; 
 
			
				
				
			
		
	
		
		
			
				
					
						if  ( feedback  = =  NULL )  { 
	wl_list_for_each ( feedback ,  & presentation - > feedbacks ,  link )  { 
 
			
				
				
			
		
	
		
		
			
				
					
							wl_client_post_no_memory ( client ) ; 
		if  ( feedback - > surface  = =  surface  & &  ! feedback - > committed )  { 
 
			
				
				
			
		
	
		
		
			
				
					
							return ; 
			found  =  true ; 
 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
								break ; 
 
			
		
	
		
		
			
				
					
							} 
		} 
 
			
		
	
		
		
			
				
					
					
	} 
 
			
				
				
			
		
	
		
		
			
				
					
						uint32_t  version  =  wl_resource_get_version ( resource ) ; 
	if  ( ! found )  { 
 
			
				
				
			
		
	
		
		
			
				
					
						feedback - > resource  =  wl_resource_create ( client , 
		feedback  =  calloc ( 1 ,  sizeof ( struct  wlr_presentation_feedback ) ) ; 
 
			
				
				
			
		
	
		
		
			
				
					
							& wp_presentation_feedback_interface ,  version ,  id ) ; 
		if  ( feedback  = =  NULL )  { 
 
			
				
				
			
		
	
		
		
			
				
					
						if  ( feedback - > resource  = =  NULL )  { 
 
			
		
	
		
		
			
				
					
							free ( feedback ) ; 
 
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
								wl_client_post_no_memory ( client ) ; 
			wl_client_post_no_memory ( client ) ; 
 
			
		
	
		
		
			
				
					
								return ; 
			return ; 
 
			
		
	
		
		
			
				
					
							} 
		} 
 
			
		
	
		
		
			
				
					
						wl_resource_set_implementation ( feedback - > resource ,  NULL ,  feedback , 
 
			
		
	
		
		
			
				
					
							feedback_handle_resource_destroy ) ; 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
							feedback - > surface  =  surface ; 
		feedback - > surface  =  surface ; 
 
			
		
	
		
		
			
				
					
							wl_list_init ( & feedback - > resources ) ; 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
							feedback - > surface_commit . notify  =  feedback_handle_surface_commit ; 
		feedback - > surface_commit . notify  =  feedback_handle_surface_commit ; 
 
			
		
	
		
		
			
				
					
							wl_signal_add ( & surface - > events . commit ,  & feedback - > surface_commit ) ; 
		wl_signal_add ( & surface - > events . commit ,  & feedback - > surface_commit ) ; 
 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -120,6 +120,19 @@ static void presentation_handle_feedback(struct wl_client *client,
 
			
		
	
		
		
			
				
					
							wl_signal_add ( & surface - > events . destroy ,  & feedback - > surface_destroy ) ; 
		wl_signal_add ( & surface - > events . destroy ,  & feedback - > surface_destroy ) ; 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
							wl_list_insert ( & presentation - > feedbacks ,  & feedback - > link ) ; 
		wl_list_insert ( & presentation - > feedbacks ,  & feedback - > link ) ; 
 
			
		
	
		
		
			
				
					
						} 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
						uint32_t  version  =  wl_resource_get_version ( presentation_resource ) ; 
 
			
		
	
		
		
			
				
					
						struct  wl_resource  * resource  =  wl_resource_create ( client , 
 
			
		
	
		
		
			
				
					
							& wp_presentation_feedback_interface ,  version ,  id ) ; 
 
			
		
	
		
		
			
				
					
						if  ( resource  = =  NULL )  { 
 
			
		
	
		
		
			
				
					
							wl_client_post_no_memory ( client ) ; 
 
			
		
	
		
		
			
				
					
							return ; 
 
			
		
	
		
		
			
				
					
						} 
 
			
		
	
		
		
			
				
					
						wl_resource_set_implementation ( resource ,  NULL ,  feedback , 
 
			
		
	
		
		
			
				
					
							feedback_handle_resource_destroy ) ; 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
						wl_list_insert ( & feedback - > resources ,  wl_resource_get_link ( resource ) ) ; 
 
			
		
	
		
		
			
				
					
					} }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					static  void  presentation_handle_destroy ( struct  wl_client  * client , static  void  presentation_handle_destroy ( struct  wl_client  * client ,  
			
		
	
	
		
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
					@ -198,7 +211,7 @@ void wlr_presentation_destroy(struct wlr_presentation *presentation) {
 
			
		
	
		
		
			
				
					
						struct  wlr_presentation_feedback  * feedback ,  * feedback_tmp ; 
	struct  wlr_presentation_feedback  * feedback ,  * feedback_tmp ; 
 
			
		
	
		
		
			
				
					
						wl_list_for_each_safe ( feedback ,  feedback_tmp ,  & presentation - > feedbacks , 
	wl_list_for_each_safe ( feedback ,  feedback_tmp ,  & presentation - > feedbacks , 
 
			
		
	
		
		
			
				
					
								link )  { 
			link )  { 
 
			
		
	
		
		
			
				
					
							wl _resource_destroy( feedback - > resource  ) ; 
		wl r_presentation_feedback_destroy( feedback  ) ; 
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
						} 
	} 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
						struct  wl_resource  * resource ,  * resource_tmp ; 
	struct  wl_resource  * resource ,  * resource_tmp ; 
 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -211,27 +224,47 @@ void wlr_presentation_destroy(struct wlr_presentation *presentation) {
 
			
		
	
		
		
			
				
					
						free ( presentation ) ; 
	free ( presentation ) ; 
 
			
		
	
		
		
			
				
					
					} }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					void  wlr_presentation_ send_surface _presented( void  wlr_presentation_ feedback_send _presented(  
			
				
				
			
		
	
		
		
			
				
					
							struct  wlr_presentation  * presentation ,  struct  wlr_surface  * surface  , 
		struct  wlr_presentation _feedback * feedback  , 
 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
							struct  wlr_presentation_event  * event )  { 
		struct  wlr_presentation_event  * event )  { 
 
			
		
	
		
		
			
				
					
						// TODO: maybe use a hashtable to optimize this function
 
	struct  wl_resource  * resource ,  * tmp ; 
 
			
				
				
			
		
	
		
		
			
				
					
						struct  wlr_presentation_feedback  * feedback ,  * feedback_tmp ; 
	wl_resource_for_each_safe ( resource ,  tmp ,  & feedback - > resources )  { 
 
			
				
				
			
		
	
		
		
			
				
					
						wl_list_for_each_safe ( feedback ,  feedback_tmp , 
		feedback_resource_send_presented ( resource ,  event ) ; 
 
			
				
				
			
		
	
		
		
			
				
					
								& presentation - > feedbacks ,  link )  { 
 
			
		
	
		
		
			
				
					
							if  ( feedback - > surface  = =  surface  & &  feedback - > sampled )  { 
 
			
		
	
		
		
			
				
					
								feedback_send_presented ( feedback ,  event ) ; 
 
			
		
	
		
		
			
				
					
							} 
 
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
						} 
	} 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
						feedback - > presented  =  true ; 
 
			
		
	
		
		
			
				
					
					} }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					void  wlr_presentation_surface_sampled ( struct  wlr_presentation_feedback  * wlr_presentation_surface_sampled (  
			
				
				
			
		
	
		
		
	
		
		
			
				
					
							struct  wlr_presentation  * presentation ,  struct  wlr_surface  * surface )  { 
		struct  wlr_presentation  * presentation ,  struct  wlr_surface  * surface )  { 
 
			
		
	
		
		
			
				
					
						// TODO: maybe use a hashtable to optimize this function
 
	// TODO: maybe use a hashtable to optimize this function
 
 
			
		
	
		
		
			
				
					
						struct  wlr_presentation_feedback  * feedback ,  * feedback_tmp ; 
	struct  wlr_presentation_feedback  * feedback ,  * feedback_tmp ; 
 
			
		
	
		
		
			
				
					
						wl_list_for_each_safe ( feedback ,  feedback_tmp , 
	wl_list_for_each_safe ( feedback ,  feedback_tmp , 
 
			
		
	
		
		
			
				
					
								& presentation - > feedbacks ,  link )  { 
			& presentation - > feedbacks ,  link )  { 
 
			
		
	
		
		
			
				
					
							if  ( feedback - > surface  = =  surface  & &  feedback - > committed )  { 
		if  ( feedback - > surface  = =  surface  & &  feedback - > committed  & & 
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
									! feedback - > sampled )  { 
 
			
		
	
		
		
			
				
					
								feedback - > sampled  =  true ; 
			feedback - > sampled  =  true ; 
 
			
		
	
		
		
			
				
					
								return  feedback ; 
 
			
		
	
		
		
			
				
					
							} 
 
			
		
	
		
		
			
				
					
						} 
 
			
		
	
		
		
			
				
					
						return  NULL ; 
 
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					void  wlr_presentation_feedback_destroy (  
			
		
	
		
		
			
				
					
							struct  wlr_presentation_feedback  * feedback )  { 
 
			
		
	
		
		
			
				
					
						if  ( feedback  = =  NULL )  { 
 
			
		
	
		
		
			
				
					
							return ; 
 
			
		
	
		
		
			
				
					
						} 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
						if  ( ! feedback - > presented )  { 
 
			
		
	
		
		
			
				
					
							struct  wl_resource  * resource ,  * tmp ; 
 
			
		
	
		
		
			
				
					
							wl_resource_for_each_safe ( resource ,  tmp ,  & feedback - > resources )  { 
 
			
		
	
		
		
			
				
					
								feedback_resource_send_discarded ( resource ) ; 
 
			
		
	
		
		
			
				
					
							} 
		} 
 
			
		
	
		
		
			
				
					
						} 
	} 
 
			
		
	
		
		
			
				
					
						assert ( wl_list_empty ( & feedback - > resources ) ) ; 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
						feedback_unset_surface ( feedback ) ; 
 
			
		
	
		
		
			
				
					
						wl_list_remove ( & feedback - > link ) ; 
 
			
		
	
		
		
			
				
					
						free ( feedback ) ; 
 
			
		
	
		
		
			
				
					
					} }