mirror of
				https://gitlab.freedesktop.org/wlroots/wlroots.git
				synced 2025-11-03 09:01:40 -05:00 
			
		
		
		
	Add first wlr_surface example implementation
This commit is contained in:
		
							parent
							
								
									6345d6deed
								
							
						
					
					
						commit
						8473c3955c
					
				
					 5 changed files with 155 additions and 90 deletions
				
			
		| 
						 | 
					@ -14,6 +14,7 @@
 | 
				
			||||||
#include <wlr/util/log.h>
 | 
					#include <wlr/util/log.h>
 | 
				
			||||||
#include "shared.h"
 | 
					#include "shared.h"
 | 
				
			||||||
#include "compositor.h"
 | 
					#include "compositor.h"
 | 
				
			||||||
 | 
					#include "wlr_surface.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct sample_state {
 | 
					struct sample_state {
 | 
				
			||||||
	struct wlr_renderer *renderer;
 | 
						struct wlr_renderer *renderer;
 | 
				
			||||||
| 
						 | 
					@ -32,11 +33,11 @@ void handle_output_frame(struct output_state *output, struct timespec *ts) {
 | 
				
			||||||
	struct wl_resource *_res;
 | 
						struct wl_resource *_res;
 | 
				
			||||||
	float matrix[16];
 | 
						float matrix[16];
 | 
				
			||||||
	wl_list_for_each(_res, &sample->compositor.surfaces, link) {
 | 
						wl_list_for_each(_res, &sample->compositor.surfaces, link) {
 | 
				
			||||||
		struct wlr_texture *texture = wl_resource_get_user_data(_res);
 | 
							struct wlr_surface *surface = wl_resource_get_user_data(_res);
 | 
				
			||||||
		if (texture->valid) {
 | 
							if (surface->texture->valid) {
 | 
				
			||||||
			wlr_texture_get_matrix(texture, &matrix,
 | 
								wlr_texture_get_matrix(surface->texture, &matrix,
 | 
				
			||||||
					&wlr_output->transform_matrix, 200, 200);
 | 
										&wlr_output->transform_matrix, 200, 200);
 | 
				
			||||||
			wlr_render_with_matrix(sample->renderer, texture, &matrix);
 | 
								wlr_render_with_matrix(sample->renderer, surface->texture, &matrix);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,90 +1,13 @@
 | 
				
			||||||
#include <assert.h>
 | 
					#include <assert.h>
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
#include <wayland-server.h>
 | 
					#include <wayland-server.h>
 | 
				
			||||||
#include <wlr/util/log.h>
 | 
					#include <wlr/util/log.h>
 | 
				
			||||||
#include "compositor.h"
 | 
					#include "compositor.h"
 | 
				
			||||||
 | 
					#include "compositor/wlr_surface.h"
 | 
				
			||||||
static void surface_destroy(struct wl_client *client, struct wl_resource *resource) {
 | 
					 | 
				
			||||||
	wl_resource_destroy(resource);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void surface_attach(struct wl_client *client,
 | 
					 | 
				
			||||||
		struct wl_resource *resource,
 | 
					 | 
				
			||||||
		struct wl_resource *buffer_resource, int32_t sx, int32_t sy) {
 | 
					 | 
				
			||||||
	struct wlr_texture *texture = wl_resource_get_user_data(resource);
 | 
					 | 
				
			||||||
	struct wl_shm_buffer *buffer = wl_shm_buffer_get(buffer_resource);
 | 
					 | 
				
			||||||
	uint32_t format = wl_shm_buffer_get_format(buffer);
 | 
					 | 
				
			||||||
	wlr_texture_upload_shm(texture, format, buffer);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void surface_damage(struct wl_client *client,
 | 
					 | 
				
			||||||
		struct wl_resource *resource,
 | 
					 | 
				
			||||||
		int32_t x, int32_t y, int32_t width, int32_t height) {
 | 
					 | 
				
			||||||
	wlr_log(L_DEBUG, "TODO: surface damage");
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void surface_frame(struct wl_client *client,
 | 
					 | 
				
			||||||
		struct wl_resource *resource, uint32_t callback) {
 | 
					 | 
				
			||||||
	wlr_log(L_DEBUG, "TODO: surface frame");
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void surface_set_opaque_region(struct wl_client *client,
 | 
					 | 
				
			||||||
		struct wl_resource *resource,
 | 
					 | 
				
			||||||
		struct wl_resource *region_resource) {
 | 
					 | 
				
			||||||
	wlr_log(L_DEBUG, "TODO: surface opaque region");
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void surface_set_input_region(struct wl_client *client,
 | 
					 | 
				
			||||||
		struct wl_resource *resource,
 | 
					 | 
				
			||||||
		struct wl_resource *region_resource) {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	wlr_log(L_DEBUG, "TODO: surface input region");
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void surface_commit(struct wl_client *client,
 | 
					 | 
				
			||||||
		struct wl_resource *resource) {
 | 
					 | 
				
			||||||
	wlr_log(L_DEBUG, "TODO: surface surface commit");
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void surface_set_buffer_transform(struct wl_client *client,
 | 
					 | 
				
			||||||
		struct wl_resource *resource, int transform) {
 | 
					 | 
				
			||||||
	wlr_log(L_DEBUG, "TODO: surface surface buffer transform");
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void surface_set_buffer_scale(struct wl_client *client,
 | 
					 | 
				
			||||||
		struct wl_resource *resource,
 | 
					 | 
				
			||||||
		int32_t scale) {
 | 
					 | 
				
			||||||
	wlr_log(L_DEBUG, "TODO: surface set buffer scale");
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void surface_damage_buffer(struct wl_client *client,
 | 
					 | 
				
			||||||
		struct wl_resource *resource,
 | 
					 | 
				
			||||||
		int32_t x, int32_t y, int32_t width,
 | 
					 | 
				
			||||||
		int32_t height) {
 | 
					 | 
				
			||||||
	wlr_log(L_DEBUG, "TODO: surface damage buffer");
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct wl_surface_interface surface_interface = {
 | 
					 | 
				
			||||||
	surface_destroy,
 | 
					 | 
				
			||||||
	surface_attach,
 | 
					 | 
				
			||||||
	surface_damage,
 | 
					 | 
				
			||||||
	surface_frame,
 | 
					 | 
				
			||||||
	surface_set_opaque_region,
 | 
					 | 
				
			||||||
	surface_set_input_region,
 | 
					 | 
				
			||||||
	surface_commit,
 | 
					 | 
				
			||||||
	surface_set_buffer_transform,
 | 
					 | 
				
			||||||
	surface_set_buffer_scale,
 | 
					 | 
				
			||||||
	surface_damage_buffer
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void destroy_surface(struct wl_resource *resource) {
 | 
					 | 
				
			||||||
	struct wlr_texture *surface = wl_resource_get_user_data(resource);
 | 
					 | 
				
			||||||
	wlr_texture_destroy(surface);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void destroy_surface_listener(struct wl_listener *listener, void *data) {
 | 
					static void destroy_surface_listener(struct wl_listener *listener, void *data) {
 | 
				
			||||||
	struct wl_compositor_state *state;
 | 
						struct wl_compositor_state *state;
 | 
				
			||||||
	struct wlr_texture *surface = data;
 | 
						struct wlr_surface *surface = data;
 | 
				
			||||||
	state = wl_container_of(listener, state, destroy_surface_listener);
 | 
						state = wl_container_of(listener, state, destroy_surface_listener);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct wl_resource *res = NULL;
 | 
						struct wl_resource *res = NULL;
 | 
				
			||||||
| 
						 | 
					@ -101,13 +24,9 @@ static void wl_compositor_create_surface(struct wl_client *client,
 | 
				
			||||||
	struct wl_compositor_state *state = wl_resource_get_user_data(resource);
 | 
						struct wl_compositor_state *state = wl_resource_get_user_data(resource);
 | 
				
			||||||
	struct wl_resource *surface_resource = wl_resource_create(client,
 | 
						struct wl_resource *surface_resource = wl_resource_create(client,
 | 
				
			||||||
			&wl_surface_interface, wl_resource_get_version(resource), id);
 | 
								&wl_surface_interface, wl_resource_get_version(resource), id);
 | 
				
			||||||
	struct wlr_texture *texture = wlr_render_texture_init(state->renderer);
 | 
						struct wlr_surface *surface = wlr_surface_create(surface_resource, state->renderer);
 | 
				
			||||||
	texture->resource = surface_resource;
 | 
					 | 
				
			||||||
	wl_resource_set_implementation(surface_resource, &surface_interface,
 | 
					 | 
				
			||||||
			texture, destroy_surface);
 | 
					 | 
				
			||||||
	wl_resource_set_user_data(surface_resource, texture);
 | 
					 | 
				
			||||||
	wl_list_insert(&state->surfaces, wl_resource_get_link(surface_resource));
 | 
						wl_list_insert(&state->surfaces, wl_resource_get_link(surface_resource));
 | 
				
			||||||
	wl_signal_add(&texture->destroy_signal, &state->destroy_surface_listener);
 | 
						wl_signal_add(&surface->signals.destroy, &state->destroy_surface_listener);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void wl_compositor_create_region(struct wl_client *client,
 | 
					static void wl_compositor_create_region(struct wl_client *client,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										120
									
								
								examples/compositor/wlr_surface.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										120
									
								
								examples/compositor/wlr_surface.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,120 @@
 | 
				
			||||||
 | 
					#include <assert.h>
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <wayland-server.h>
 | 
				
			||||||
 | 
					#include <wlr/util/log.h>
 | 
				
			||||||
 | 
					#include <wlr/render/interface.h>
 | 
				
			||||||
 | 
					#include "wlr_surface.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void surface_destroy(struct wl_client *client, struct wl_resource *resource) {
 | 
				
			||||||
 | 
						struct wlr_surface *surface = wl_resource_get_user_data(resource);
 | 
				
			||||||
 | 
						wl_signal_emit(&surface->signals.destroy, surface);
 | 
				
			||||||
 | 
						wl_resource_destroy(resource);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void surface_attach(struct wl_client *client,
 | 
				
			||||||
 | 
							struct wl_resource *resource,
 | 
				
			||||||
 | 
							struct wl_resource *buffer, int32_t sx, int32_t sy) {
 | 
				
			||||||
 | 
						struct wlr_surface *surface = wl_resource_get_user_data(resource);
 | 
				
			||||||
 | 
						surface->pending_buffer = buffer;
 | 
				
			||||||
 | 
						surface->pending_attached = true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void surface_damage(struct wl_client *client,
 | 
				
			||||||
 | 
							struct wl_resource *resource,
 | 
				
			||||||
 | 
							int32_t x, int32_t y, int32_t width, int32_t height) {
 | 
				
			||||||
 | 
						wlr_log(L_DEBUG, "TODO: surface damage");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void surface_frame(struct wl_client *client,
 | 
				
			||||||
 | 
							struct wl_resource *resource, uint32_t callback) {
 | 
				
			||||||
 | 
						wlr_log(L_DEBUG, "TODO: surface frame");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void surface_set_opaque_region(struct wl_client *client,
 | 
				
			||||||
 | 
							struct wl_resource *resource,
 | 
				
			||||||
 | 
							struct wl_resource *region_resource) {
 | 
				
			||||||
 | 
						wlr_log(L_DEBUG, "TODO: surface opaque region");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void surface_set_input_region(struct wl_client *client,
 | 
				
			||||||
 | 
							struct wl_resource *resource,
 | 
				
			||||||
 | 
							struct wl_resource *region_resource) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wlr_log(L_DEBUG, "TODO: surface input region");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void surface_commit(struct wl_client *client,
 | 
				
			||||||
 | 
							struct wl_resource *resource) {
 | 
				
			||||||
 | 
						struct wlr_surface *surface = wl_resource_get_user_data(resource);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// apply pending state
 | 
				
			||||||
 | 
						if (surface->pending_attached) {
 | 
				
			||||||
 | 
							surface->attached = surface->pending_buffer;
 | 
				
			||||||
 | 
							if (surface->pending_buffer) {
 | 
				
			||||||
 | 
								struct wl_shm_buffer *buffer = wl_shm_buffer_get(surface->pending_buffer);
 | 
				
			||||||
 | 
								if (!buffer) {
 | 
				
			||||||
 | 
									wlr_log(L_INFO, "Unknown buffer handle attached");
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									uint32_t format = wl_shm_buffer_get_format(buffer);
 | 
				
			||||||
 | 
									wlr_texture_upload_shm(surface->texture, format, buffer);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// reset pending state
 | 
				
			||||||
 | 
						surface->pending_buffer = NULL;
 | 
				
			||||||
 | 
						surface->pending_attached = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wl_signal_emit(&surface->signals.commit, surface);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void surface_set_buffer_transform(struct wl_client *client,
 | 
				
			||||||
 | 
							struct wl_resource *resource, int transform) {
 | 
				
			||||||
 | 
						wlr_log(L_DEBUG, "TODO: surface surface buffer transform");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void surface_set_buffer_scale(struct wl_client *client,
 | 
				
			||||||
 | 
							struct wl_resource *resource,
 | 
				
			||||||
 | 
							int32_t scale) {
 | 
				
			||||||
 | 
						wlr_log(L_DEBUG, "TODO: surface set buffer scale");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void surface_damage_buffer(struct wl_client *client,
 | 
				
			||||||
 | 
							struct wl_resource *resource,
 | 
				
			||||||
 | 
							int32_t x, int32_t y, int32_t width,
 | 
				
			||||||
 | 
							int32_t height) {
 | 
				
			||||||
 | 
						wlr_log(L_DEBUG, "TODO: surface damage buffer");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct wl_surface_interface surface_interface = {
 | 
				
			||||||
 | 
						surface_destroy,
 | 
				
			||||||
 | 
						surface_attach,
 | 
				
			||||||
 | 
						surface_damage,
 | 
				
			||||||
 | 
						surface_frame,
 | 
				
			||||||
 | 
						surface_set_opaque_region,
 | 
				
			||||||
 | 
						surface_set_input_region,
 | 
				
			||||||
 | 
						surface_commit,
 | 
				
			||||||
 | 
						surface_set_buffer_transform,
 | 
				
			||||||
 | 
						surface_set_buffer_scale,
 | 
				
			||||||
 | 
						surface_damage_buffer
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void destroy_surface(struct wl_resource *resource) {
 | 
				
			||||||
 | 
						struct wlr_surface *surface = wl_resource_get_user_data(resource);
 | 
				
			||||||
 | 
						wl_signal_emit(&surface->signals.destroy, surface);
 | 
				
			||||||
 | 
						wlr_texture_destroy(surface->texture);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct wlr_surface *wlr_surface_create(struct wl_resource *res,
 | 
				
			||||||
 | 
							struct wlr_renderer *renderer) {
 | 
				
			||||||
 | 
						struct wlr_surface *surface = calloc(1, sizeof(struct wlr_surface));
 | 
				
			||||||
 | 
						surface->texture = wlr_render_texture_init(renderer);
 | 
				
			||||||
 | 
						surface->resource = res;
 | 
				
			||||||
 | 
						wl_signal_init(&surface->signals.commit);
 | 
				
			||||||
 | 
						wl_signal_init(&surface->signals.destroy);
 | 
				
			||||||
 | 
						wl_resource_set_implementation(res, &surface_interface,
 | 
				
			||||||
 | 
								surface, destroy_surface);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return surface;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										24
									
								
								examples/compositor/wlr_surface.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								examples/compositor/wlr_surface.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,24 @@
 | 
				
			||||||
 | 
					#ifndef _EXAMPLES_COMPOSITOR_SURFACE_H
 | 
				
			||||||
 | 
					#define _EXAMPLES_COMPOSITOR_SURFACE_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <wayland-server.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct wlr_surface {
 | 
				
			||||||
 | 
						struct wl_resource *pending_buffer;
 | 
				
			||||||
 | 
						bool pending_attached;
 | 
				
			||||||
 | 
						bool attached; // whether the surface currently has a buffer attached
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct wlr_texture *texture;
 | 
				
			||||||
 | 
						const char *role; // the lifetime-bound role or null
 | 
				
			||||||
 | 
						struct wl_resource *resource;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct {
 | 
				
			||||||
 | 
							struct wl_signal destroy;
 | 
				
			||||||
 | 
							struct wl_signal commit;
 | 
				
			||||||
 | 
						} signals;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct wlr_surface *wlr_surface_create(struct wl_resource *res,
 | 
				
			||||||
 | 
							struct wlr_renderer *renderer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					@ -12,6 +12,7 @@ compositor_src = [
 | 
				
			||||||
    'compositor/main.c',
 | 
					    'compositor/main.c',
 | 
				
			||||||
    'compositor/wl_compositor.c',
 | 
					    'compositor/wl_compositor.c',
 | 
				
			||||||
    'compositor/wl_shell.c',
 | 
					    'compositor/wl_shell.c',
 | 
				
			||||||
 | 
					    'compositor/wlr_surface.c',
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
executable('compositor', compositor_src, dependencies: dep_wlr, link_with: lib_shared)
 | 
					executable('compositor', compositor_src, dependencies: dep_wlr, link_with: lib_shared)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue