Add wlr_subcompositor
This commit is contained in:
		
							parent
							
								
									fa84b267e0
								
							
						
					
					
						commit
						bfcd3f3707
					
				|  | @ -6,7 +6,10 @@ | |||
| 
 | ||||
| struct wlr_surface; | ||||
| 
 | ||||
| // TODO: expose subcompositor
 | ||||
| struct wlr_subcompositor { | ||||
| 	struct wl_global *wl_global; | ||||
| 	struct wl_list wl_resources; | ||||
| }; | ||||
| 
 | ||||
| struct wlr_compositor { | ||||
| 	struct wl_global *wl_global; | ||||
|  | @ -14,6 +17,8 @@ struct wlr_compositor { | |||
| 	struct wlr_renderer *renderer; | ||||
| 	struct wl_list surfaces; | ||||
| 
 | ||||
| 	struct wlr_subcompositor subcompositor; | ||||
| 
 | ||||
| 	struct wl_listener display_destroy; | ||||
| 
 | ||||
| 	struct { | ||||
|  |  | |||
|  | @ -10,7 +10,8 @@ | |||
| static const char *subsurface_role = "wl_subsurface"; | ||||
| 
 | ||||
| bool wlr_surface_is_subsurface(struct wlr_surface *surface) { | ||||
| 	return strcmp(surface->role, subsurface_role) == 0; | ||||
| 	return surface->role != NULL && | ||||
| 		strcmp(surface->role, subsurface_role) == 0; | ||||
| } | ||||
| 
 | ||||
| struct wlr_subsurface *wlr_subsurface_from_surface( | ||||
|  | @ -19,9 +20,96 @@ struct wlr_subsurface *wlr_subsurface_from_surface( | |||
| 	return (struct wlr_subsurface *)surface->role_data; | ||||
| } | ||||
| 
 | ||||
| static void subcompositor_handle_destroy(struct wl_client *client, | ||||
| 		struct wl_resource *resource) { | ||||
| 	wl_resource_destroy(resource); | ||||
| } | ||||
| 
 | ||||
| static void subcompositor_handle_get_subsurface(struct wl_client *client, | ||||
| 		struct wl_resource *resource, uint32_t id, | ||||
| 		struct wl_resource *surface_resource, | ||||
| 		struct wl_resource *parent_resource) { | ||||
| 	struct wlr_surface *surface = wlr_surface_from_resource(surface_resource); | ||||
| 	struct wlr_surface *parent = wlr_surface_from_resource(parent_resource); | ||||
| 
 | ||||
| 	static const char msg[] = "get_subsurface: wl_subsurface@"; | ||||
| 
 | ||||
| 	if (surface == parent) { | ||||
| 		wl_resource_post_error(resource, | ||||
| 			WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE, | ||||
| 			"%s%d: wl_surface@%d cannot be its own parent", | ||||
| 			msg, id, wl_resource_get_id(surface_resource)); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	if (wlr_surface_is_subsurface(surface)) { | ||||
| 		wl_resource_post_error(resource, | ||||
| 			WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE, | ||||
| 			"%s%d: wl_surface@%d is already a sub-surface", | ||||
| 			msg, id, wl_resource_get_id(surface_resource)); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	if (wlr_surface_get_root_surface(parent) == surface) { | ||||
| 		wl_resource_post_error(resource, | ||||
| 			WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE, | ||||
| 			"%s%d: wl_surface@%d is an ancestor of parent", | ||||
| 			msg, id, wl_resource_get_id(surface_resource)); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	if (wlr_surface_set_role(surface, subsurface_role, resource, | ||||
| 				WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE) < 0) { | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	wlr_surface_make_subsurface(surface, parent, id); | ||||
| } | ||||
| 
 | ||||
| static const struct wl_subcompositor_interface subcompositor_interface = { | ||||
| 	.destroy = subcompositor_handle_destroy, | ||||
| 	.get_subsurface = subcompositor_handle_get_subsurface, | ||||
| }; | ||||
| 
 | ||||
| static void subcompositor_bind(struct wl_client *client, void *data, | ||||
| 		uint32_t version, uint32_t id) { | ||||
| 	struct wlr_subcompositor *subcompositor = data; | ||||
| 	struct wl_resource *resource = | ||||
| 		wl_resource_create(client, &wl_subcompositor_interface, 1, id); | ||||
| 	if (resource == NULL) { | ||||
| 		wl_client_post_no_memory(client); | ||||
| 		return; | ||||
| 	} | ||||
| 	wl_resource_set_implementation(resource, &subcompositor_interface, | ||||
| 		subcompositor, NULL); | ||||
| 	wl_list_insert(&subcompositor->wl_resources, wl_resource_get_link(resource)); | ||||
| } | ||||
| 
 | ||||
| static void subcompositor_init(struct wlr_subcompositor *subcompositor, | ||||
| 		struct wl_display *display) { | ||||
| 	subcompositor->wl_global = wl_global_create(display, | ||||
| 		&wl_subcompositor_interface, 1, subcompositor, subcompositor_bind); | ||||
| 	if (subcompositor->wl_global == NULL) { | ||||
| 		wlr_log_errno(L_ERROR, "Could not allocate subcompositor global"); | ||||
| 		return; | ||||
| 	} | ||||
| 	wl_list_init(&subcompositor->wl_resources); | ||||
| } | ||||
| 
 | ||||
| static void subcompositor_finish(struct wlr_subcompositor *subcompositor) { | ||||
| 	wl_global_destroy(subcompositor->wl_global); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| static const struct wl_compositor_interface wl_compositor_impl; | ||||
| 
 | ||||
| static struct wlr_compositor *compositor_from_resource(struct wl_resource *resource) { | ||||
| static struct wlr_compositor *compositor_from_resource( | ||||
| 		struct wl_resource *resource) { | ||||
| 	assert(wl_resource_instance_of(resource, &wl_compositor_interface, | ||||
| 		&wl_compositor_impl)); | ||||
| 	return wl_resource_get_user_data(resource); | ||||
|  | @ -86,16 +174,15 @@ static void wl_compositor_bind(struct wl_client *wl_client, void *data, | |||
| 	struct wlr_compositor *compositor = data; | ||||
| 	assert(wl_client && compositor); | ||||
| 
 | ||||
| 	struct wl_resource *wl_resource = | ||||
| 	struct wl_resource *resource = | ||||
| 		wl_resource_create(wl_client, &wl_compositor_interface, version, id); | ||||
| 	if (wl_resource == NULL) { | ||||
| 	if (resource == NULL) { | ||||
| 		wl_client_post_no_memory(wl_client); | ||||
| 		return; | ||||
| 	} | ||||
| 	wl_resource_set_implementation(wl_resource, &wl_compositor_impl, | ||||
| 	wl_resource_set_implementation(resource, &wl_compositor_impl, | ||||
| 		compositor, wl_compositor_destroy); | ||||
| 	wl_list_insert(&compositor->wl_resources, | ||||
| 		wl_resource_get_link(wl_resource)); | ||||
| 	wl_list_insert(&compositor->wl_resources, wl_resource_get_link(resource)); | ||||
| } | ||||
| 
 | ||||
| void wlr_compositor_destroy(struct wlr_compositor *compositor) { | ||||
|  | @ -103,76 +190,12 @@ void wlr_compositor_destroy(struct wlr_compositor *compositor) { | |||
| 		return; | ||||
| 	} | ||||
| 	wlr_signal_emit_safe(&compositor->events.destroy, compositor); | ||||
| 	subcompositor_finish(&compositor->subcompositor); | ||||
| 	wl_list_remove(&compositor->display_destroy.link); | ||||
| 	wl_global_destroy(compositor->wl_global); | ||||
| 	free(compositor); | ||||
| } | ||||
| 
 | ||||
| static void subcompositor_destroy(struct wl_client *client, | ||||
| 		struct wl_resource *resource) { | ||||
| 	wl_resource_destroy(resource); | ||||
| } | ||||
| 
 | ||||
| static void subcompositor_get_subsurface(struct wl_client *client, | ||||
| 		struct wl_resource *resource, uint32_t id, | ||||
| 		struct wl_resource *surface_resource, | ||||
| 		struct wl_resource *parent_resource) { | ||||
| 	struct wlr_surface *surface = wlr_surface_from_resource(surface_resource); | ||||
| 	struct wlr_surface *parent = wlr_surface_from_resource(parent_resource); | ||||
| 
 | ||||
| 	static const char msg[] = "get_subsurface: wl_subsurface@"; | ||||
| 
 | ||||
| 	if (surface == parent) { | ||||
| 		wl_resource_post_error(resource, | ||||
| 			WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE, | ||||
| 			"%s%d: wl_surface@%d cannot be its own parent", | ||||
| 			msg, id, wl_resource_get_id(surface_resource)); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	if (wlr_surface_is_subsurface(surface)) { | ||||
| 		wl_resource_post_error(resource, | ||||
| 			WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE, | ||||
| 			"%s%d: wl_surface@%d is already a sub-surface", | ||||
| 			msg, id, wl_resource_get_id(surface_resource)); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	if (wlr_surface_get_root_surface(parent) == surface) { | ||||
| 		wl_resource_post_error(resource, | ||||
| 			WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE, | ||||
| 			"%s%d: wl_surface@%d is an ancestor of parent", | ||||
| 			msg, id, wl_resource_get_id(surface_resource)); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	if (wlr_surface_set_role(surface, subsurface_role, resource, | ||||
| 				WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE) < 0) { | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	wlr_surface_make_subsurface(surface, parent, id); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| static const struct wl_subcompositor_interface subcompositor_interface = { | ||||
| 	.destroy = subcompositor_destroy, | ||||
| 	.get_subsurface = subcompositor_get_subsurface, | ||||
| }; | ||||
| 
 | ||||
| static void subcompositor_bind(struct wl_client *client, void *data, | ||||
| 		uint32_t version, uint32_t id) { | ||||
| 	struct wlr_compositor *compositor = data; | ||||
| 	struct wl_resource *resource = | ||||
| 		wl_resource_create(client, &wl_subcompositor_interface, 1, id); | ||||
| 	if (resource == NULL) { | ||||
| 		wl_client_post_no_memory(client); | ||||
| 		return; | ||||
| 	} | ||||
| 	wl_resource_set_implementation(resource, &subcompositor_interface, | ||||
| 		compositor, NULL); | ||||
| } | ||||
| 
 | ||||
| static void handle_display_destroy(struct wl_listener *listener, void *data) { | ||||
| 	struct wlr_compositor *compositor = | ||||
| 		wl_container_of(listener, compositor, display_destroy); | ||||
|  | @ -198,14 +221,13 @@ struct wlr_compositor *wlr_compositor_create(struct wl_display *display, | |||
| 	compositor->wl_global = compositor_global; | ||||
| 	compositor->renderer = renderer; | ||||
| 
 | ||||
| 	wl_global_create(display, &wl_subcompositor_interface, 1, compositor, | ||||
| 		subcompositor_bind); | ||||
| 
 | ||||
| 	wl_list_init(&compositor->wl_resources); | ||||
| 	wl_list_init(&compositor->surfaces); | ||||
| 	wl_signal_init(&compositor->events.new_surface); | ||||
| 	wl_signal_init(&compositor->events.destroy); | ||||
| 
 | ||||
| 	subcompositor_init(&compositor->subcompositor, display); | ||||
| 
 | ||||
| 	compositor->display_destroy.notify = handle_display_destroy; | ||||
| 	wl_display_add_destroy_listener(display, &compositor->display_destroy); | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue