Documentation for <wlr/types/wlr_compositor.h>

Back to index

Table of contents

struct wlr_compositor

struct wlr_compositor {
	struct wl_global *global;
	struct wlr_renderer *renderer; // may be NULL
	
	struct wl_listener display_destroy;
	struct wl_listener renderer_destroy;
	
	struct {
		struct wl_signal new_surface;
		struct wl_signal destroy;
	} events;
};

wlr_compositor_create()

struct wlr_compositor *wlr_compositor_create(​struct wl_display *display, uint32_t version, struct wlr_renderer *renderer);

Create the wl_compositor global, which can be used by clients to create surfaces and regions.

If a renderer is supplied, the compositor will create struct wlr_texture objects from client buffers on surface commit.

wlr_compositor_set_renderer()

void wlr_compositor_set_renderer(​struct wlr_compositor *compositor, struct wlr_renderer *renderer);

Set the renderer used for creating struct wlr_texture objects from client buffers on surface commit.

The renderer may be NULL, in which case no textures are created.

Calling this function does not update existing textures, it only affects future surface commits.

struct wlr_surface

struct wlr_surface {
	struct wl_resource *resource;
	struct wlr_compositor *compositor;
	/**
	 * The surface's buffer, if any. A surface has an attached buffer when it
	 * commits with a non-null buffer in its pending state. A surface will not
	 * have a buffer if it has never committed one, has committed a null buffer,
	 * or something went wrong with uploading the buffer.
	 */
	struct wlr_client_buffer *buffer;
	/**
	 * The last commit's buffer damage, in buffer-local coordinates. This
	 * contains both the damage accumulated by the client via
	 * `wlr_surface_state.surface_damage` and `wlr_surface_state.buffer_damage`.
	 * If the buffer has been resized, the whole buffer is damaged.
	 *
	 * This region needs to be scaled and transformed into output coordinates,
	 * just like the buffer's texture. In addition, if the buffer has shrunk the
	 * old size needs to be damaged and if the buffer has moved the old and new
	 * positions need to be damaged.
	 */
	pixman_region32_t buffer_damage;
	/**
	 * The current opaque region, in surface-local coordinates. It is clipped to
	 * the surface bounds. If the surface's buffer is using a fully opaque
	 * format, this is set to the whole surface.
	 */
	pixman_region32_t opaque_region;
	/**
	 * The current input region, in surface-local coordinates. It is clipped to
	 * the surface bounds.
	 *
	 * If the protocol states that the input region is ignored, this is empty.
	 */
	pixman_region32_t input_region;
	/**
	 * `current` contains the current, committed surface state. `pending`
	 * accumulates state changes from the client between commits and shouldn't
	 * be accessed by the compositor directly.
	 */
	struct wlr_surface_state current, pending;
	
	struct wl_list cached; // wlr_surface_state.cached_link
	
	/**
	 * Whether the surface is ready to be displayed.
	 */
	bool mapped;
	
	/**
	 * The lifetime-bound role of the surface. NULL if the role was never set.
	 */
	const struct wlr_surface_role *role;
	
	/**
	 * The role object representing the role. NULL if the role isn't
	 * represented by any object or the object was destroyed.
	 */
	struct wl_resource *role_resource;
	
	struct {
		struct wl_signal client_commit;
		struct wl_signal commit;
		
		/**
		 * The `map` event signals that the surface has a non-null buffer
		 * committed and is ready to be displayed.
		 */
		struct wl_signal map;
		/**
		 * The `unmap` event signals that the surface shouldn't be displayed
		 * anymore. This can happen when a null buffer is committed,
		 * the associated role object is destroyed, or when the role-specific
		 * conditions for the surface to be mapped no longer apply.
		 */
		struct wl_signal unmap;
		
		/**
		 * Note: unlike other new_* signals, new_subsurface is emitted when
		 * the subsurface is added to the parent surface's current state,
		 * not when the object is created.
		 */
		struct wl_signal new_subsurface; // struct wlr_subsurface
		struct wl_signal destroy;
	} events;
	
	struct wl_list current_outputs; // wlr_surface_output.link
	
	struct wlr_addon_set addons;
	void *data;
	
	// private state
	
	struct wl_listener role_resource_destroy;
	
	struct {
		int32_t scale;
		enum wl_output_transform transform;
		int width, height;
		int buffer_width, buffer_height;
	} previous;
	
	bool unmap_commit;
	
	bool opaque;
	
	bool handling_commit;
	bool pending_rejected;
	
	int32_t preferred_buffer_scale;
	bool preferred_buffer_transform_sent;
	enum wl_output_transform preferred_buffer_transform;
	
	struct wl_list synced; // wlr_surface_synced.link
	size_t synced_len;
	
	struct wl_resource *pending_buffer_resource;
	struct wl_listener pending_buffer_resource_destroy;
};

wlr_surface_for_each_surface()

void wlr_surface_for_each_surface(​struct wlr_surface *surface, wlr_surface_iterator_func_t iterator, void *user_data);

Call `iterator` on each mapped surface in the surface tree (whether or not this surface is mapped), with the surface's position relative to the root surface. The function is called from root to leaves (in rendering order).

wlr_surface_from_resource()

struct wlr_surface *wlr_surface_from_resource(​struct wl_resource *resource);

Get the struct wlr_surface corresponding to a wl_surface resource.

This asserts that the resource is a valid wl_surface resource created by wlroots and will never return NULL.

wlr_surface_get_buffer_source_box()

void wlr_surface_get_buffer_source_box(​struct wlr_surface *surface, struct wlr_fbox *box);

Get the source rectangle describing the region of the buffer that needs to be sampled to render this surface's current state. The box is in buffer-local coordinates.

If the viewport's source rectangle is unset, the position is zero and the size is the buffer's.

wlr_surface_get_effective_damage()

void wlr_surface_get_effective_damage(​struct wlr_surface *surface, pixman_region32_t *damage);

Get the effective surface damage in surface-local coordinate space.

wlr_surface_get_extents()

void wlr_surface_get_extents(​struct wlr_surface *surface, struct wlr_box *box);

Get the bounding box that contains the surface and all subsurfaces in surface coordinates. X and y may be negative, if there are subsurfaces with negative position.

wlr_surface_get_root_surface()

struct wlr_surface *wlr_surface_get_root_surface(​struct wlr_surface *surface);

Get the root of the subsurface tree for this surface. May return the same surface passed if that surface is the root. Never returns NULL.

wlr_surface_get_texture()

struct wlr_texture *wlr_surface_get_texture(​struct wlr_surface *surface);

Get the texture of the buffer currently attached to this surface. Returns NULL if no buffer is currently attached or if something went wrong with uploading the buffer.

wlr_surface_has_buffer()

bool wlr_surface_has_buffer(​struct wlr_surface *surface);

typedef wlr_surface_iterator_func_t

typedef void (*wlr_surface_iterator_func_t)(​struct wlr_surface *surface, int sx, int sy, void *data);

wlr_surface_lock_pending()

uint32_t wlr_surface_lock_pending(​struct wlr_surface *surface);

Acquire a lock for the pending surface state.

The state won't be committed before the caller releases the lock. Instead, the state becomes cached. The caller needs to use wlr_surface_unlock_cached() to release the lock.

Returns a surface commit sequence number for the cached state.

wlr_surface_map()

void wlr_surface_map(​struct wlr_surface *surface);

Map the surface. If the surface is already mapped, this is no-op.

This function must only be used by surface role implementations.

struct wlr_surface_output

struct wlr_surface_output {
	struct wlr_surface *surface;
	struct wlr_output *output;
	
	struct wl_list link; // wlr_surface.current_outputs
	struct wl_listener bind;
	struct wl_listener destroy;
};

wlr_surface_point_accepts_input()

bool wlr_surface_point_accepts_input(​struct wlr_surface *surface, double sx, double sy);

wlr_surface_reject_pending()

void wlr_surface_reject_pending(​struct wlr_surface *surface, struct wl_resource *resource, uint32_t code, const char *msg, ...);

Mark the pending state of a surface as rejected due to a protocol violation, preventing it from being cached or committed.

This function must only be used while processing a commit request.

struct wlr_surface_role

struct wlr_surface_role {
	const char *name;
	/**
	 * If true, the role isn't represented by any object.
	 * For example, this applies to cursor surfaces.
	 */
	bool no_object;
	/**
	 * Called when the client sends the wl_surface.commit request. May be NULL.
	 * Typically used to check that the pending state is valid, and send
	 * protocol errors if not.
	 *
	 * If the role is represented by an object, this is only called if
	 * such object exists.
	 */
	void (*client_commit)(​struct wlr_surface *surface);
	/**
	 * Called when a new surface state is committed. May be NULL.
	 *
	 * If the role is represented by an object, this is only called if
	 * such object exists.
	 */
	void (*commit)(​struct wlr_surface *surface);
	/**
	 * Called when the surface is unmapped. May be NULL.
	 *
	 * If the role is represented by an object, this is only called if
	 * such object exists.
	 */
	void (*unmap)(​struct wlr_surface *surface);
	/**
	 * Called when the object representing the role is destroyed. May be NULL.
	 */
	void (*destroy)(​struct wlr_surface *surface);
};

wlr_surface_send_enter()

void wlr_surface_send_enter(​struct wlr_surface *surface, struct wlr_output *output);

Notify the client that the surface has entered an output.

This is a no-op if the surface has already entered the output.

wlr_surface_send_frame_done()

void wlr_surface_send_frame_done(​struct wlr_surface *surface, const struct timespec *when);

Complete the queued frame callbacks for this surface.

This will send an event to the client indicating that now is a good time to draw its next frame.

wlr_surface_send_leave()

void wlr_surface_send_leave(​struct wlr_surface *surface, struct wlr_output *output);

Notify the client that the surface has left an output.

This is a no-op if the surface has already left the output.

wlr_surface_set_preferred_buffer_scale()

void wlr_surface_set_preferred_buffer_scale(​struct wlr_surface *surface, int32_t scale);

Set the preferred buffer scale for the surface.

This sends an event to the client indicating the preferred scale to use for buffers attached to this surface.

wlr_surface_set_preferred_buffer_transform()

void wlr_surface_set_preferred_buffer_transform(​struct wlr_surface *surface, enum wl_output_transform transform);

Set the preferred buffer transform for the surface.

This sends an event to the client indicating the preferred transform to use for buffers attached to this surface.

wlr_surface_set_role()

bool wlr_surface_set_role(​struct wlr_surface *surface, const struct wlr_surface_role *role, struct wl_resource *error_resource, uint32_t error_code);

wlr_surface_set_role_object()

void wlr_surface_set_role_object(​struct wlr_surface *surface, struct wl_resource *role_resource);

Set the role object for this surface. The surface must have a role and no already set role object.

When the resource is destroyed, the surface is unmapped, wlr_surface_role.destroy is called and the role object is unset.

struct wlr_surface_state

struct wlr_surface_state {
	uint32_t committed; // enum wlr_surface_state_field
	// Sequence number of the surface state. Incremented on each commit, may
	// overflow.
	uint32_t seq;
	
	struct wlr_buffer *buffer;
	int32_t dx, dy; // relative to previous position
	pixman_region32_t surface_damage, buffer_damage; // clipped to bounds
	pixman_region32_t opaque, input;
	enum wl_output_transform transform;
	int32_t scale;
	struct wl_list frame_callback_list; // wl_resource
	
	int width, height; // in surface-local coordinates
	int buffer_width, buffer_height;
	
	struct wl_list subsurfaces_below;
	struct wl_list subsurfaces_above;
	
	/**
	 * The viewport is applied after the surface transform and scale.
	 *
	 * If has_src is true, the surface content is cropped to the provided
	 * rectangle. If has_dst is true, the surface content is scaled to the
	 * provided rectangle.
	 */
	struct {
		bool has_src, has_dst;
		// In coordinates after scale/transform are applied, but before the
		// destination rectangle is applied
		struct wlr_fbox src;
		int dst_width, dst_height; // in surface-local coordinates
	} viewport;
	
	// Number of locks that prevent this surface state from being committed.
	size_t cached_state_locks;
	struct wl_list cached_state_link; // wlr_surface.cached
	
	// Sync'ed object states, one per struct wlr_surface_synced
	struct wl_array synced; // void *
};

enum wlr_surface_state_field

enum wlr_surface_state_field {
	WLR_SURFACE_STATE_BUFFER,
	WLR_SURFACE_STATE_SURFACE_DAMAGE,
	WLR_SURFACE_STATE_BUFFER_DAMAGE,
	WLR_SURFACE_STATE_OPAQUE_REGION,
	WLR_SURFACE_STATE_INPUT_REGION,
	WLR_SURFACE_STATE_TRANSFORM,
	WLR_SURFACE_STATE_SCALE,
	WLR_SURFACE_STATE_FRAME_CALLBACK_LIST,
	WLR_SURFACE_STATE_VIEWPORT,
	WLR_SURFACE_STATE_OFFSET,
};

wlr_surface_state_has_buffer()

bool wlr_surface_state_has_buffer(​const struct wlr_surface_state *state);

wlr_surface_surface_at()

struct wlr_surface *wlr_surface_surface_at(​struct wlr_surface *surface, double sx, double sy, double *sub_x, double *sub_y);

Find a surface in this surface's tree that accepts input events and has all parents mapped (except this surface, which can be unmapped) at the given surface-local coordinates. Returns the surface and coordinates in the leaf surface coordinate system or NULL if no surface is found at that location.

struct wlr_surface_synced

struct wlr_surface_synced {
	struct wlr_surface *surface;
	const struct wlr_surface_synced_impl *impl;
	struct wl_list link; // wlr_surface.synced
	size_t index;
};

An object synchronized with a surface.

This is typically used by surface add-ons which integrate with the surface commit mechanism.

A sync'ed object maintains state whose lifecycle is managed by struct wlr_surface_synced_impl. Clients make requests to mutate the pending state, then clients commit the pending state via wl_surface.commit. The pending state may become cached, then becomes current when it's applied.

wlr_surface_synced_finish()

void wlr_surface_synced_finish(​struct wlr_surface_synced *synced);

Finish a sync'ed object.

This must be called before the struct wlr_surface is destroyed.

wlr_surface_synced_get_state()

void *wlr_surface_synced_get_state(​struct wlr_surface_synced *synced, const struct wlr_surface_state *state);

Obtain a sync'ed object state.

struct wlr_surface_synced_impl

struct wlr_surface_synced_impl {
	// Size in bytes of the state struct.
	size_t state_size;
	// Initialize a state. If NULL, this is a no-op.
	void (*init_state)(​void *state);
	// Finish a state. If NULL, this is a no-op.
	void (*finish_state)(​void *state);
	// Move a state. If NULL, memcpy() is used.
	void (*move_state)(​void *dst, void *src);
};

Implementation for struct wlr_surface_synced.

struct wlr_surface takes care of allocating the sync'ed object state.

The only mandatory field is state_size.

wlr_surface_synced_init()

bool wlr_surface_synced_init(​struct wlr_surface_synced *synced, struct wlr_surface *surface, const struct wlr_surface_synced_impl *impl, void *pending, void *current);

wlr_surface_unlock_cached()

void wlr_surface_unlock_cached(​struct wlr_surface *surface, uint32_t seq);

Release a lock for a cached state.

Callers should not assume that the cached state will immediately be committed. Another caller may still have an active lock.

wlr_surface_unmap()

void wlr_surface_unmap(​struct wlr_surface *surface);

Unmap the surface. If the surface is already unmapped, this is no-op.

This function must only be used by surface role implementations.