mirror of
				https://gitlab.freedesktop.org/wayland/wayland.git
				synced 2025-11-03 09:01:42 -05:00 
			
		
		
		
	Use a callback object instead of ad-hoc lists for sync and frame events
So obvious in retrospect. The object system can do all the work for us and keep track of pending calls as regular objects and we don't need to abuse the resource system to get them cleaned up on client exit. We don't need the custom key management or (broken) lookup, we just sue object IDs. And last but not least, anybody can receive the callback, not just display listeners.
This commit is contained in:
		
							parent
							
								
									1648109c84
								
							
						
					
					
						commit
						0af17ed98c
					
				
					 4 changed files with 42 additions and 175 deletions
				
			
		| 
						 | 
				
			
			@ -51,21 +51,6 @@ struct wl_proxy {
 | 
			
		|||
	void *user_data;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct wl_sync_handler {
 | 
			
		||||
	wl_display_sync_func_t func;
 | 
			
		||||
	uint32_t key;
 | 
			
		||||
	void *data;
 | 
			
		||||
	struct wl_list link;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct wl_frame_handler {
 | 
			
		||||
	wl_display_frame_func_t func;
 | 
			
		||||
	uint32_t key;
 | 
			
		||||
	void *data;
 | 
			
		||||
	struct wl_surface *surface;
 | 
			
		||||
	struct wl_list link;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct wl_global {
 | 
			
		||||
	uint32_t id;
 | 
			
		||||
	char *interface;
 | 
			
		||||
| 
						 | 
				
			
			@ -88,9 +73,6 @@ struct wl_display {
 | 
			
		|||
 | 
			
		||||
	wl_display_global_func_t global_handler;
 | 
			
		||||
	void *global_handler_data;
 | 
			
		||||
 | 
			
		||||
	struct wl_list sync_list, frame_list;
 | 
			
		||||
	uint32_t key;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static int wl_debug = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -278,42 +260,11 @@ display_handle_range(void *data,
 | 
			
		|||
	display->next_range = range;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
display_handle_key(void *data,
 | 
			
		||||
		   struct wl_display *display, uint32_t key, uint32_t time)
 | 
			
		||||
{
 | 
			
		||||
	struct wl_sync_handler *sync_handler;
 | 
			
		||||
	struct wl_frame_handler *frame_handler;
 | 
			
		||||
 | 
			
		||||
	sync_handler = container_of(display->sync_list.next,
 | 
			
		||||
				    struct wl_sync_handler, link);
 | 
			
		||||
	if (!wl_list_empty(&display->sync_list) && sync_handler->key == key) {
 | 
			
		||||
		wl_list_remove(&sync_handler->link);
 | 
			
		||||
		sync_handler->func(sync_handler->data);
 | 
			
		||||
		free(sync_handler);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	frame_handler = container_of(display->frame_list. next,
 | 
			
		||||
				     struct wl_frame_handler, link);
 | 
			
		||||
	if (!wl_list_empty(&display->frame_list) &&
 | 
			
		||||
	    frame_handler->key == key) {
 | 
			
		||||
		wl_list_remove(&frame_handler->link);
 | 
			
		||||
		frame_handler->func(frame_handler->surface,
 | 
			
		||||
				    frame_handler->data, time);
 | 
			
		||||
		free(frame_handler);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	fprintf(stderr, "unsolicited sync event, client gone?\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const struct wl_display_listener display_listener = {
 | 
			
		||||
	display_handle_error,
 | 
			
		||||
	display_handle_global,
 | 
			
		||||
	display_handle_global_remove,
 | 
			
		||||
	display_handle_range,
 | 
			
		||||
	display_handle_key
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
| 
						 | 
				
			
			@ -402,9 +353,6 @@ wl_display_connect(const char *name)
 | 
			
		|||
	display->proxy.object.id = 1;
 | 
			
		||||
	display->proxy.display = display;
 | 
			
		||||
 | 
			
		||||
	wl_list_init(&display->sync_list);
 | 
			
		||||
	wl_list_init(&display->frame_list);
 | 
			
		||||
 | 
			
		||||
	display->proxy.object.implementation =
 | 
			
		||||
		(void(**)(void)) &display_listener;
 | 
			
		||||
	display->proxy.user_data = display;
 | 
			
		||||
| 
						 | 
				
			
			@ -455,46 +403,31 @@ wl_display_get_fd(struct wl_display *display,
 | 
			
		|||
	return display->fd;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
WL_EXPORT int
 | 
			
		||||
wl_display_sync_callback(struct wl_display *display,
 | 
			
		||||
			 wl_display_sync_func_t func, void *data)
 | 
			
		||||
static void
 | 
			
		||||
sync_callback(void *data, struct wl_callback *callback, uint32_t time)
 | 
			
		||||
{
 | 
			
		||||
	struct wl_sync_handler *handler;
 | 
			
		||||
   int *done = data;
 | 
			
		||||
 | 
			
		||||
	handler = malloc(sizeof *handler);
 | 
			
		||||
	if (handler == NULL)
 | 
			
		||||
		return -1;
 | 
			
		||||
 | 
			
		||||
	handler->func = func;
 | 
			
		||||
	handler->key = display->key++;
 | 
			
		||||
	handler->data = data;
 | 
			
		||||
 | 
			
		||||
	wl_list_insert(display->sync_list.prev, &handler->link);
 | 
			
		||||
	wl_display_sync(display, handler->key);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
   *done = 1;
 | 
			
		||||
   wl_callback_destroy(callback);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
WL_EXPORT int
 | 
			
		||||
wl_display_frame_callback(struct wl_display *display,
 | 
			
		||||
			  struct wl_surface *surface,
 | 
			
		||||
			  wl_display_frame_func_t func, void *data)
 | 
			
		||||
static const struct wl_callback_listener sync_listener = {
 | 
			
		||||
	sync_callback
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
WL_EXPORT void
 | 
			
		||||
wl_display_roundtrip(struct wl_display *display)
 | 
			
		||||
{
 | 
			
		||||
	struct wl_frame_handler *handler;
 | 
			
		||||
	struct wl_callback *callback;
 | 
			
		||||
	int done;
 | 
			
		||||
 | 
			
		||||
	handler = malloc(sizeof *handler);
 | 
			
		||||
	if (handler == NULL)
 | 
			
		||||
		return -1;
 | 
			
		||||
 | 
			
		||||
	handler->func = func;
 | 
			
		||||
	handler->key = display->key++;
 | 
			
		||||
	handler->data = data;
 | 
			
		||||
	handler->surface = surface;
 | 
			
		||||
 | 
			
		||||
	wl_list_insert(display->frame_list.prev, &handler->link);
 | 
			
		||||
	wl_display_frame(display, handler->surface, handler->key);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
	done = 0;
 | 
			
		||||
	callback = wl_display_sync(display);
 | 
			
		||||
	wl_callback_add_listener(callback, &sync_listener, &done);
 | 
			
		||||
	wl_display_flush(display);
 | 
			
		||||
	while (!done)
 | 
			
		||||
		wl_display_iterate(display, WL_DISPLAY_READABLE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue