mirror of
				https://gitlab.freedesktop.org/wlroots/wlroots.git
				synced 2025-11-03 09:01:40 -05:00 
			
		
		
		
	screencopy: Implement damage reporting
This commit is contained in:
		
							parent
							
								
									2a63f4fc61
								
							
						
					
					
						commit
						61a6f2b928
					
				
					 2 changed files with 208 additions and 28 deletions
				
			
		| 
						 | 
					@ -27,9 +27,15 @@ struct wlr_screencopy_manager_v1 {
 | 
				
			||||||
	void *data;
 | 
						void *data;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct wlr_screencopy_v1_client {
 | 
				
			||||||
 | 
						int ref;
 | 
				
			||||||
 | 
						struct wlr_screencopy_manager_v1 *manager;
 | 
				
			||||||
 | 
						struct wl_list damages;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct wlr_screencopy_frame_v1 {
 | 
					struct wlr_screencopy_frame_v1 {
 | 
				
			||||||
	struct wl_resource *resource;
 | 
						struct wl_resource *resource;
 | 
				
			||||||
	struct wlr_screencopy_manager_v1 *manager;
 | 
						struct wlr_screencopy_v1_client *client;
 | 
				
			||||||
	struct wl_list link;
 | 
						struct wl_list link;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	enum wl_shm_format format;
 | 
						enum wl_shm_format format;
 | 
				
			||||||
| 
						 | 
					@ -38,6 +44,8 @@ struct wlr_screencopy_frame_v1 {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool overlay_cursor, cursor_locked;
 | 
						bool overlay_cursor, cursor_locked;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bool with_damage;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct wl_shm_buffer *buffer;
 | 
						struct wl_shm_buffer *buffer;
 | 
				
			||||||
	struct wl_listener buffer_destroy;
 | 
						struct wl_listener buffer_destroy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,10 +8,119 @@
 | 
				
			||||||
#include "wlr-screencopy-unstable-v1-protocol.h"
 | 
					#include "wlr-screencopy-unstable-v1-protocol.h"
 | 
				
			||||||
#include "util/signal.h"
 | 
					#include "util/signal.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define SCREENCOPY_MANAGER_VERSION 1
 | 
					#define SCREENCOPY_MANAGER_VERSION 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct screencopy_damage {
 | 
				
			||||||
 | 
						struct wl_list link;
 | 
				
			||||||
 | 
						struct wlr_output *output;
 | 
				
			||||||
 | 
						struct pixman_region32 damage;
 | 
				
			||||||
 | 
						struct wl_listener output_precommit;
 | 
				
			||||||
 | 
						struct wl_listener output_destroy;
 | 
				
			||||||
 | 
						uint32_t last_commit_seq;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct zwlr_screencopy_frame_v1_interface frame_impl;
 | 
					static const struct zwlr_screencopy_frame_v1_interface frame_impl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct screencopy_damage *screencopy_damage_find(
 | 
				
			||||||
 | 
							struct wlr_screencopy_v1_client *client,
 | 
				
			||||||
 | 
							struct wlr_output *output) {
 | 
				
			||||||
 | 
						struct screencopy_damage *damage;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wl_list_for_each(damage, &client->damages, link) {
 | 
				
			||||||
 | 
							if (damage->output == output) {
 | 
				
			||||||
 | 
								return damage;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void screencopy_damage_accumulate(struct screencopy_damage *damage) {
 | 
				
			||||||
 | 
						struct pixman_region32 *region = &damage->damage;
 | 
				
			||||||
 | 
						struct wlr_output *output = damage->output;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* This check is done so damage that has been added and cleared in the
 | 
				
			||||||
 | 
						 * frame precommit handler is not added again after it has been handled.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						if (damage->last_commit_seq == output->commit_seq) {
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pixman_region32_union(region, region, &output->pending.damage);
 | 
				
			||||||
 | 
						pixman_region32_intersect_rect(region, region, 0, 0, output->width,
 | 
				
			||||||
 | 
							output->height);
 | 
				
			||||||
 | 
						damage->last_commit_seq = output->commit_seq;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void screencopy_damage_handle_output_precommit(
 | 
				
			||||||
 | 
							struct wl_listener *listener, void *data) {
 | 
				
			||||||
 | 
						struct screencopy_damage *damage =
 | 
				
			||||||
 | 
							wl_container_of(listener, damage, output_precommit);
 | 
				
			||||||
 | 
						screencopy_damage_accumulate(damage);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void screencopy_damage_destroy(struct screencopy_damage *damage) {
 | 
				
			||||||
 | 
						wl_list_remove(&damage->output_destroy.link);
 | 
				
			||||||
 | 
						wl_list_remove(&damage->output_precommit.link);
 | 
				
			||||||
 | 
						wl_list_remove(&damage->link);
 | 
				
			||||||
 | 
						pixman_region32_fini(&damage->damage);
 | 
				
			||||||
 | 
						free(damage);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void screencopy_damage_handle_output_destroy(
 | 
				
			||||||
 | 
							struct wl_listener *listener, void *data) {
 | 
				
			||||||
 | 
						struct screencopy_damage *damage =
 | 
				
			||||||
 | 
							wl_container_of(listener, damage, output_destroy);
 | 
				
			||||||
 | 
						screencopy_damage_destroy(damage);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct screencopy_damage *screencopy_damage_create(
 | 
				
			||||||
 | 
							struct wlr_screencopy_v1_client *client,
 | 
				
			||||||
 | 
							struct wlr_output *output) {
 | 
				
			||||||
 | 
						struct screencopy_damage *damage =
 | 
				
			||||||
 | 
							calloc(1, sizeof(struct screencopy_damage));
 | 
				
			||||||
 | 
						if (!damage) {
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						damage->output = output;
 | 
				
			||||||
 | 
						damage->last_commit_seq = output->commit_seq - 1;
 | 
				
			||||||
 | 
						pixman_region32_init_rect(&damage->damage, 0, 0, output->width,
 | 
				
			||||||
 | 
							output->height);
 | 
				
			||||||
 | 
						wl_list_insert(&client->damages, &damage->link);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wl_signal_add(&output->events.precommit, &damage->output_precommit);
 | 
				
			||||||
 | 
						damage->output_precommit.notify =
 | 
				
			||||||
 | 
							screencopy_damage_handle_output_precommit;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wl_signal_add(&output->events.destroy, &damage->output_destroy);
 | 
				
			||||||
 | 
						damage->output_destroy.notify = screencopy_damage_handle_output_destroy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return damage;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct screencopy_damage *screencopy_damage_get_or_create(
 | 
				
			||||||
 | 
							struct wlr_screencopy_v1_client *client,
 | 
				
			||||||
 | 
							struct wlr_output *output) {
 | 
				
			||||||
 | 
						struct screencopy_damage *damage = screencopy_damage_find(client, output);
 | 
				
			||||||
 | 
						return damage ? damage : screencopy_damage_create(client, output);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void client_unref(struct wlr_screencopy_v1_client *client) {
 | 
				
			||||||
 | 
						assert(client->ref > 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (--client->ref != 0) {
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct screencopy_damage *damage, *tmp_damage;
 | 
				
			||||||
 | 
						wl_list_for_each_safe(damage, tmp_damage, &client->damages, link) {
 | 
				
			||||||
 | 
							screencopy_damage_destroy(damage);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						free(client);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct wlr_screencopy_frame_v1 *frame_from_resource(
 | 
					static struct wlr_screencopy_frame_v1 *frame_from_resource(
 | 
				
			||||||
		struct wl_resource *resource) {
 | 
							struct wl_resource *resource) {
 | 
				
			||||||
	assert(wl_resource_instance_of(resource,
 | 
						assert(wl_resource_instance_of(resource,
 | 
				
			||||||
| 
						 | 
					@ -36,6 +145,7 @@ static void frame_destroy(struct wlr_screencopy_frame_v1 *frame) {
 | 
				
			||||||
	wl_list_remove(&frame->buffer_destroy.link);
 | 
						wl_list_remove(&frame->buffer_destroy.link);
 | 
				
			||||||
	// Make the frame resource inert
 | 
						// Make the frame resource inert
 | 
				
			||||||
	wl_resource_set_user_data(frame->resource, NULL);
 | 
						wl_resource_set_user_data(frame->resource, NULL);
 | 
				
			||||||
 | 
						client_unref(frame->client);
 | 
				
			||||||
	free(frame);
 | 
						free(frame);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -52,6 +162,17 @@ static void frame_handle_output_precommit(struct wl_listener *listener,
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct screencopy_damage *damage = NULL;
 | 
				
			||||||
 | 
						if (frame->with_damage) {
 | 
				
			||||||
 | 
							damage = screencopy_damage_get_or_create(frame->client, output);
 | 
				
			||||||
 | 
							if (damage) {
 | 
				
			||||||
 | 
								screencopy_damage_accumulate(damage);
 | 
				
			||||||
 | 
								if (!pixman_region32_not_empty(&damage->damage)) {
 | 
				
			||||||
 | 
									return;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wl_list_remove(&frame->output_precommit.link);
 | 
						wl_list_remove(&frame->output_precommit.link);
 | 
				
			||||||
	wl_list_init(&frame->output_precommit.link);
 | 
						wl_list_init(&frame->output_precommit.link);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -81,6 +202,22 @@ static void frame_handle_output_precommit(struct wl_listener *listener,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	zwlr_screencopy_frame_v1_send_flags(frame->resource, flags);
 | 
						zwlr_screencopy_frame_v1_send_flags(frame->resource, flags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// TODO: send fine-grained damage events
 | 
				
			||||||
 | 
						if (damage) {
 | 
				
			||||||
 | 
							struct pixman_box32 *damage_box =
 | 
				
			||||||
 | 
								pixman_region32_extents(&damage->damage);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							int damage_x = damage_box->x1;
 | 
				
			||||||
 | 
							int damage_y = damage_box->y1;
 | 
				
			||||||
 | 
							int damage_width = damage_box->x2 - damage_box->x1;
 | 
				
			||||||
 | 
							int damage_height = damage_box->y2 - damage_box->y1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							zwlr_screencopy_frame_v1_send_damage(frame->resource,
 | 
				
			||||||
 | 
								damage_x, damage_y, damage_width, damage_height);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							pixman_region32_clear(&damage->damage);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	time_t tv_sec = event->when->tv_sec;
 | 
						time_t tv_sec = event->when->tv_sec;
 | 
				
			||||||
	uint32_t tv_sec_hi = (sizeof(tv_sec) > 4) ? tv_sec >> 32 : 0;
 | 
						uint32_t tv_sec_hi = (sizeof(tv_sec) > 4) ? tv_sec >> 32 : 0;
 | 
				
			||||||
	uint32_t tv_sec_lo = tv_sec & 0xFFFFFFFF;
 | 
						uint32_t tv_sec_lo = tv_sec & 0xFFFFFFFF;
 | 
				
			||||||
| 
						 | 
					@ -116,7 +253,7 @@ static void frame_handle_buffer_destroy(struct wl_listener *listener,
 | 
				
			||||||
	frame_destroy(frame);
 | 
						frame_destroy(frame);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void frame_handle_copy(struct wl_client *client,
 | 
					static void frame_handle_copy(struct wl_client *wl_client,
 | 
				
			||||||
		struct wl_resource *frame_resource,
 | 
							struct wl_resource *frame_resource,
 | 
				
			||||||
		struct wl_resource *buffer_resource) {
 | 
							struct wl_resource *buffer_resource) {
 | 
				
			||||||
	struct wlr_screencopy_frame_v1 *frame = frame_from_resource(frame_resource);
 | 
						struct wlr_screencopy_frame_v1 *frame = frame_from_resource(frame_resource);
 | 
				
			||||||
| 
						 | 
					@ -185,7 +322,18 @@ static void frame_handle_copy(struct wl_client *client,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void frame_handle_destroy(struct wl_client *client,
 | 
					static void frame_handle_copy_with_damage(struct wl_client *wl_client,
 | 
				
			||||||
 | 
							struct wl_resource *frame_resource,
 | 
				
			||||||
 | 
							struct wl_resource *buffer_resource) {
 | 
				
			||||||
 | 
						struct wlr_screencopy_frame_v1 *frame = frame_from_resource(frame_resource);
 | 
				
			||||||
 | 
						if (frame == NULL) {
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						frame->with_damage = true;
 | 
				
			||||||
 | 
						frame_handle_copy(wl_client, frame_resource, buffer_resource);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void frame_handle_destroy(struct wl_client *wl_client,
 | 
				
			||||||
		struct wl_resource *frame_resource) {
 | 
							struct wl_resource *frame_resource) {
 | 
				
			||||||
	wl_resource_destroy(frame_resource);
 | 
						wl_resource_destroy(frame_resource);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -193,6 +341,7 @@ static void frame_handle_destroy(struct wl_client *client,
 | 
				
			||||||
static const struct zwlr_screencopy_frame_v1_interface frame_impl = {
 | 
					static const struct zwlr_screencopy_frame_v1_interface frame_impl = {
 | 
				
			||||||
	.copy = frame_handle_copy,
 | 
						.copy = frame_handle_copy,
 | 
				
			||||||
	.destroy = frame_handle_destroy,
 | 
						.destroy = frame_handle_destroy,
 | 
				
			||||||
 | 
						.copy_with_damage = frame_handle_copy_with_damage,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void frame_handle_resource_destroy(struct wl_resource *frame_resource) {
 | 
					static void frame_handle_resource_destroy(struct wl_resource *frame_resource) {
 | 
				
			||||||
| 
						 | 
					@ -203,38 +352,41 @@ static void frame_handle_resource_destroy(struct wl_resource *frame_resource) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct zwlr_screencopy_manager_v1_interface manager_impl;
 | 
					static const struct zwlr_screencopy_manager_v1_interface manager_impl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct wlr_screencopy_manager_v1 *manager_from_resource(
 | 
					static struct wlr_screencopy_v1_client *client_from_resource(
 | 
				
			||||||
		struct wl_resource *resource) {
 | 
							struct wl_resource *resource) {
 | 
				
			||||||
	assert(wl_resource_instance_of(resource,
 | 
						assert(wl_resource_instance_of(resource,
 | 
				
			||||||
		&zwlr_screencopy_manager_v1_interface, &manager_impl));
 | 
							&zwlr_screencopy_manager_v1_interface, &manager_impl));
 | 
				
			||||||
	return wl_resource_get_user_data(resource);
 | 
						return wl_resource_get_user_data(resource);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void capture_output(struct wl_client *client,
 | 
					static void capture_output(struct wl_client *wl_client,
 | 
				
			||||||
		struct wlr_screencopy_manager_v1 *manager, uint32_t version, uint32_t id,
 | 
							struct wlr_screencopy_v1_client *client, uint32_t version,
 | 
				
			||||||
		int32_t overlay_cursor, struct wlr_output *output,
 | 
							uint32_t id, int32_t overlay_cursor, struct wlr_output *output,
 | 
				
			||||||
		const struct wlr_box *box) {
 | 
							const struct wlr_box *box) {
 | 
				
			||||||
	struct wlr_screencopy_frame_v1 *frame =
 | 
						struct wlr_screencopy_frame_v1 *frame =
 | 
				
			||||||
		calloc(1, sizeof(struct wlr_screencopy_frame_v1));
 | 
							calloc(1, sizeof(struct wlr_screencopy_frame_v1));
 | 
				
			||||||
	if (frame == NULL) {
 | 
						if (frame == NULL) {
 | 
				
			||||||
		wl_client_post_no_memory(client);
 | 
							wl_client_post_no_memory(wl_client);
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	frame->manager = manager;
 | 
					 | 
				
			||||||
	frame->output = output;
 | 
						frame->output = output;
 | 
				
			||||||
	frame->overlay_cursor = !!overlay_cursor;
 | 
						frame->overlay_cursor = !!overlay_cursor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	frame->resource = wl_resource_create(client,
 | 
						frame->resource = wl_resource_create(wl_client,
 | 
				
			||||||
		&zwlr_screencopy_frame_v1_interface, version, id);
 | 
							&zwlr_screencopy_frame_v1_interface, version, id);
 | 
				
			||||||
	if (frame->resource == NULL) {
 | 
						if (frame->resource == NULL) {
 | 
				
			||||||
		free(frame);
 | 
							free(frame);
 | 
				
			||||||
		wl_client_post_no_memory(client);
 | 
							wl_client_post_no_memory(wl_client);
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						frame->client = client;
 | 
				
			||||||
 | 
						client->ref++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wl_resource_set_implementation(frame->resource, &frame_impl, frame,
 | 
						wl_resource_set_implementation(frame->resource, &frame_impl, frame,
 | 
				
			||||||
		frame_handle_resource_destroy);
 | 
							frame_handle_resource_destroy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wl_list_insert(&manager->frames, &frame->link);
 | 
						wl_list_insert(&client->manager->frames, &frame->link);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wl_list_init(&frame->output_precommit.link);
 | 
						wl_list_init(&frame->output_precommit.link);
 | 
				
			||||||
	wl_list_init(&frame->output_enable.link);
 | 
						wl_list_init(&frame->output_enable.link);
 | 
				
			||||||
| 
						 | 
					@ -283,23 +435,24 @@ error:
 | 
				
			||||||
	frame_destroy(frame);
 | 
						frame_destroy(frame);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void manager_handle_capture_output(struct wl_client *client,
 | 
					static void manager_handle_capture_output(struct wl_client *wl_client,
 | 
				
			||||||
		struct wl_resource *manager_resource, uint32_t id,
 | 
							struct wl_resource *manager_resource, uint32_t id,
 | 
				
			||||||
		int32_t overlay_cursor, struct wl_resource *output_resource) {
 | 
							int32_t overlay_cursor, struct wl_resource *output_resource) {
 | 
				
			||||||
	struct wlr_screencopy_manager_v1 *manager =
 | 
						struct wlr_screencopy_v1_client *client =
 | 
				
			||||||
		manager_from_resource(manager_resource);
 | 
							client_from_resource(manager_resource);
 | 
				
			||||||
	uint32_t version = wl_resource_get_version(manager_resource);
 | 
						uint32_t version = wl_resource_get_version(manager_resource);
 | 
				
			||||||
	struct wlr_output *output = wlr_output_from_resource(output_resource);
 | 
						struct wlr_output *output = wlr_output_from_resource(output_resource);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	capture_output(client, manager, version, id, overlay_cursor, output, NULL);
 | 
						capture_output(wl_client, client, version, id, overlay_cursor, output,
 | 
				
			||||||
 | 
							NULL);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void manager_handle_capture_output_region(struct wl_client *client,
 | 
					static void manager_handle_capture_output_region(struct wl_client *wl_client,
 | 
				
			||||||
		struct wl_resource *manager_resource, uint32_t id,
 | 
							struct wl_resource *manager_resource, uint32_t id,
 | 
				
			||||||
		int32_t overlay_cursor, struct wl_resource *output_resource,
 | 
							int32_t overlay_cursor, struct wl_resource *output_resource,
 | 
				
			||||||
		int32_t x, int32_t y, int32_t width, int32_t height) {
 | 
							int32_t x, int32_t y, int32_t width, int32_t height) {
 | 
				
			||||||
	struct wlr_screencopy_manager_v1 *manager =
 | 
						struct wlr_screencopy_v1_client *client =
 | 
				
			||||||
		manager_from_resource(manager_resource);
 | 
							client_from_resource(manager_resource);
 | 
				
			||||||
	uint32_t version = wl_resource_get_version(manager_resource);
 | 
						uint32_t version = wl_resource_get_version(manager_resource);
 | 
				
			||||||
	struct wlr_output *output = wlr_output_from_resource(output_resource);
 | 
						struct wlr_output *output = wlr_output_from_resource(output_resource);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -309,10 +462,11 @@ static void manager_handle_capture_output_region(struct wl_client *client,
 | 
				
			||||||
		.width = width,
 | 
							.width = width,
 | 
				
			||||||
		.height = height,
 | 
							.height = height,
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
	capture_output(client, manager, version, id, overlay_cursor, output, &box);
 | 
						capture_output(wl_client, client, version, id, overlay_cursor, output,
 | 
				
			||||||
 | 
							&box);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void manager_handle_destroy(struct wl_client *client,
 | 
					static void manager_handle_destroy(struct wl_client *wl_client,
 | 
				
			||||||
		struct wl_resource *manager_resource) {
 | 
							struct wl_resource *manager_resource) {
 | 
				
			||||||
	wl_resource_destroy(manager_resource);
 | 
						wl_resource_destroy(manager_resource);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -324,23 +478,41 @@ static const struct zwlr_screencopy_manager_v1_interface manager_impl = {
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void manager_handle_resource_destroy(struct wl_resource *resource) {
 | 
					void manager_handle_resource_destroy(struct wl_resource *resource) {
 | 
				
			||||||
 | 
						struct wlr_screencopy_v1_client *client =
 | 
				
			||||||
 | 
							client_from_resource(resource);
 | 
				
			||||||
 | 
						client_unref(client);
 | 
				
			||||||
	wl_list_remove(wl_resource_get_link(resource));
 | 
						wl_list_remove(wl_resource_get_link(resource));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void manager_bind(struct wl_client *client, void *data, uint32_t version,
 | 
					static void manager_bind(struct wl_client *wl_client, void *data,
 | 
				
			||||||
		uint32_t id) {
 | 
							uint32_t version, uint32_t id) {
 | 
				
			||||||
	struct wlr_screencopy_manager_v1 *manager = data;
 | 
						struct wlr_screencopy_manager_v1 *manager = data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct wl_resource *resource = wl_resource_create(client,
 | 
						struct wlr_screencopy_v1_client *client =
 | 
				
			||||||
 | 
							calloc(1, sizeof(struct wlr_screencopy_v1_client));
 | 
				
			||||||
 | 
						if (client == NULL) {
 | 
				
			||||||
 | 
							goto failure;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct wl_resource *resource = wl_resource_create(wl_client,
 | 
				
			||||||
		&zwlr_screencopy_manager_v1_interface, version, id);
 | 
							&zwlr_screencopy_manager_v1_interface, version, id);
 | 
				
			||||||
	if (resource == NULL) {
 | 
						if (resource == NULL) {
 | 
				
			||||||
		wl_client_post_no_memory(client);
 | 
							goto failure;
 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	wl_resource_set_implementation(resource, &manager_impl, manager,
 | 
					
 | 
				
			||||||
 | 
						client->ref = 1;
 | 
				
			||||||
 | 
						client->manager = manager;
 | 
				
			||||||
 | 
						wl_list_init(&client->damages);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wl_resource_set_implementation(resource, &manager_impl, client,
 | 
				
			||||||
		manager_handle_resource_destroy);
 | 
							manager_handle_resource_destroy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wl_list_insert(&manager->resources, wl_resource_get_link(resource));
 | 
						wl_list_insert(&manager->resources, wl_resource_get_link(resource));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return;
 | 
				
			||||||
 | 
					failure:
 | 
				
			||||||
 | 
						free(client);
 | 
				
			||||||
 | 
						wl_client_post_no_memory(wl_client);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void handle_display_destroy(struct wl_listener *listener, void *data) {
 | 
					static void handle_display_destroy(struct wl_listener *listener, void *data) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue