/*
 * Copyright © 2008-2011 Kristian Høgsberg
 * Copyright © 2014 Jason Ekstrand
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice (including the
 * next paragraph) shall be included in all copies or substantial
 * portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#include "config.h"

#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/mman.h>
#include <signal.h>
#include <linux/input.h>
#include <errno.h>
#include <ctype.h>

#include <wayland-client.h>

#include "compositor.h"
#include "weston.h"
#include "shared/helpers.h"
#include "shared/os-compatibility.h"
#include "shared/timespec-util.h"
#include "fullscreen-shell-unstable-v1-client-protocol.h"

struct shared_output {
	struct weston_output *output;
	struct wl_listener output_destroyed;
	struct wl_list seat_list;

	struct {
		struct wl_display *display;
		struct wl_registry *registry;
		struct wl_compositor *compositor;
		struct wl_shm *shm;
		uint32_t shm_formats;
		struct zwp_fullscreen_shell_v1 *fshell;
		struct wl_output *output;
		struct wl_surface *surface;
		struct wl_callback *frame_cb;
		struct zwp_fullscreen_shell_mode_feedback_v1 *mode_feedback;
	} parent;

	struct wl_event_source *event_source;
	struct wl_listener frame_listener;

	struct {
		int32_t width, height;

		struct wl_list buffers;
		struct wl_list free_buffers;
	} shm;

	int cache_dirty;
	pixman_image_t *cache_image;
	uint32_t *tmp_data;
	size_t tmp_data_size;
};

struct ss_seat {
	struct weston_seat base;
	struct shared_output *output;
	struct wl_list link;

	struct {
		struct wl_seat *seat;
		struct wl_pointer *pointer;
		struct wl_keyboard *keyboard;
	} parent;

	enum weston_key_state_update keyboard_state_update;
	uint32_t key_serial;
};

struct ss_shm_buffer {
	struct shared_output *output;
	struct wl_list link;
	struct wl_list free_link;

	struct wl_buffer *buffer;
	void *data;
	size_t size;
	pixman_region32_t damage;

	pixman_image_t *pm_image;
};

struct screen_share {
	struct weston_compositor *compositor;
	char *command;
};

static void
ss_seat_handle_pointer_enter(void *data, struct wl_pointer *pointer,
			     uint32_t serial, struct wl_surface *surface,
			     wl_fixed_t x, wl_fixed_t y)
{
	struct ss_seat *seat = data;

	/* No transformation of input position is required here because we are
	 * always receiving the input in the same coordinates as the output. */

	notify_pointer_focus(&seat->base, NULL, 0, 0);
}

static void
ss_seat_handle_pointer_leave(void *data, struct wl_pointer *pointer,
			     uint32_t serial, struct wl_surface *surface)
{
	struct ss_seat *seat = data;

	notify_pointer_focus(&seat->base, NULL, 0, 0);
}

static void
ss_seat_handle_motion(void *data, struct wl_pointer *pointer,
		      uint32_t time, wl_fixed_t x, wl_fixed_t y)
{
	struct ss_seat *seat = data;
	struct timespec ts;

	timespec_from_msec(&ts, time);

	/* No transformation of input position is required here because we are
	 * always receiving the input in the same coordinates as the output. */

	notify_motion_absolute(&seat->base, &ts,
			       wl_fixed_to_double(x), wl_fixed_to_double(y));
	notify_pointer_frame(&seat->base);
}

static void
ss_seat_handle_button(void *data, struct wl_pointer *pointer,
		      uint32_t serial, uint32_t time, uint32_t button,
		      uint32_t state)
{
	struct ss_seat *seat = data;
	struct timespec ts;

	timespec_from_msec(&ts, time);

	notify_button(&seat->base, &ts, button, state);
	notify_pointer_frame(&seat->base);
}

static void
ss_seat_handle_axis(void *data, struct wl_pointer *pointer,
		    uint32_t time, uint32_t axis, wl_fixed_t value)
{
	struct ss_seat *seat = data;
	struct weston_pointer_axis_event weston_event;
	struct timespec ts;

	weston_event.axis = axis;
	weston_event.value = wl_fixed_to_double(value);
	weston_event.has_discrete = false;

	timespec_from_msec(&ts, time);

	notify_axis(&seat->base, &ts, &weston_event);
	notify_pointer_frame(&seat->base);
}

static const struct wl_pointer_listener ss_seat_pointer_listener = {
	ss_seat_handle_pointer_enter,
	ss_seat_handle_pointer_leave,
	ss_seat_handle_motion,
	ss_seat_handle_button,
	ss_seat_handle_axis,
};

static void
ss_seat_handle_keymap(void *data, struct wl_keyboard *wl_keyboard,
		      uint32_t format, int fd, uint32_t size)
{
	struct ss_seat *seat = data;
	struct xkb_keymap *keymap;
	char *map_str;

	if (!data)
		goto error_no_seat;

	if (format == WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) {
		map_str = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
		if (map_str == MAP_FAILED) {
			weston_log("mmap failed: %m\n");
			goto error;
		}

		keymap = xkb_keymap_new_from_string(seat->base.compositor->xkb_context,
						    map_str,
						    XKB_KEYMAP_FORMAT_TEXT_V1,
						    0);
		munmap(map_str, size);

		if (!keymap) {
			weston_log("failed to compile keymap\n");
			goto error;
		}

		seat->keyboard_state_update = STATE_UPDATE_NONE;
	} else if (format == WL_KEYBOARD_KEYMAP_FORMAT_NO_KEYMAP) {
		weston_log("No keymap provided; falling back to default\n");
		keymap = NULL;
		seat->keyboard_state_update = STATE_UPDATE_AUTOMATIC;
	} else {
		weston_log("Invalid keymap\n");
		goto error;
	}

	close(fd);

	if (seat->base.keyboard_device_count)
		weston_seat_update_keymap(&seat->base, keymap);
	else
		weston_seat_init_keyboard(&seat->base, keymap);

	xkb_keymap_unref(keymap);

	return;

error:
	wl_keyboard_release(seat->parent.keyboard);
error_no_seat:
	close(fd);
}

static void
ss_seat_handle_keyboard_enter(void *data, struct wl_keyboard *keyboard,
			      uint32_t serial, struct wl_surface *surface,
			      struct wl_array *keys)
{
	struct ss_seat *seat = data;

	/* XXX: If we get a modifier event immediately before the focus,
	 *      we should try to keep the same serial. */
	notify_keyboard_focus_in(&seat->base, keys,
				 STATE_UPDATE_AUTOMATIC);
}

static void
ss_seat_handle_keyboard_leave(void *data, struct wl_keyboard *keyboard,
			      uint32_t serial, struct wl_surface *surface)
{
	struct ss_seat *seat = data;

	notify_keyboard_focus_out(&seat->base);
}

static void
ss_seat_handle_key(void *data, struct wl_keyboard *keyboard,
		   uint32_t serial, uint32_t time,
		   uint32_t key, uint32_t state)
{
	struct ss_seat *seat = data;
	struct timespec ts;

	timespec_from_msec(&ts, time);
	seat->key_serial = serial;
	notify_key(&seat->base, &ts, key,
		   state ? WL_KEYBOARD_KEY_STATE_PRESSED :
			   WL_KEYBOARD_KEY_STATE_RELEASED,
		   seat->keyboard_state_update);
}

static void
ss_seat_handle_modifiers(void *data, struct wl_keyboard *wl_keyboard,
			 uint32_t serial_in, uint32_t mods_depressed,
			 uint32_t mods_latched, uint32_t mods_locked,
			 uint32_t group)
{
	struct ss_seat *seat = data;
	struct weston_compositor *c = seat->base.compositor;
	struct weston_keyboard *keyboard;
	uint32_t serial_out;

	/* If we get a key event followed by a modifier event with the
	 * same serial number, then we try to preserve those semantics by
	 * reusing the same serial number on the way out too. */
	if (serial_in == seat->key_serial)
		serial_out = wl_display_get_serial(c->wl_display);
	else
		serial_out = wl_display_next_serial(c->wl_display);

	keyboard = weston_seat_get_keyboard(&seat->base);
	xkb_state_update_mask(keyboard->xkb_state.state,
			      mods_depressed, mods_latched,
			      mods_locked, 0, 0, group);
	notify_modifiers(&seat->base, serial_out);
}

static const struct wl_keyboard_listener ss_seat_keyboard_listener = {
	ss_seat_handle_keymap,
	ss_seat_handle_keyboard_enter,
	ss_seat_handle_keyboard_leave,
	ss_seat_handle_key,
	ss_seat_handle_modifiers,
};

static void
ss_seat_handle_capabilities(void *data, struct wl_seat *seat,
			    enum wl_seat_capability caps)
{
	struct ss_seat *ss_seat = data;

	if ((caps & WL_SEAT_CAPABILITY_POINTER) && !ss_seat->parent.pointer) {
		ss_seat->parent.pointer = wl_seat_get_pointer(seat);
		wl_pointer_set_user_data(ss_seat->parent.pointer, ss_seat);
		wl_pointer_add_listener(ss_seat->parent.pointer,
					&ss_seat_pointer_listener, ss_seat);
		weston_seat_init_pointer(&ss_seat->base);
	} else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && ss_seat->parent.pointer) {
		wl_pointer_destroy(ss_seat->parent.pointer);
		ss_seat->parent.pointer = NULL;
	}

	if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !ss_seat->parent.keyboard) {
		ss_seat->parent.keyboard = wl_seat_get_keyboard(seat);
		wl_keyboard_set_user_data(ss_seat->parent.keyboard, ss_seat);
		wl_keyboard_add_listener(ss_seat->parent.keyboard,
					 &ss_seat_keyboard_listener, ss_seat);
	} else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && ss_seat->parent.keyboard) {
		wl_keyboard_destroy(ss_seat->parent.keyboard);
		ss_seat->parent.keyboard = NULL;
	}
}

static const struct wl_seat_listener ss_seat_listener = {
	ss_seat_handle_capabilities,
};

static struct ss_seat *
ss_seat_create(struct shared_output *so, uint32_t id)
{
	struct ss_seat *seat;

	seat = zalloc(sizeof *seat);
	if (seat == NULL)
		return NULL;

	weston_seat_init(&seat->base, so->output->compositor, "default");
	seat->output = so;
	seat->parent.seat = wl_registry_bind(so->parent.registry, id,
					     &wl_seat_interface, 1);
	wl_list_insert(so->seat_list.prev, &seat->link);

	wl_seat_add_listener(seat->parent.seat, &ss_seat_listener, seat);
	wl_seat_set_user_data(seat->parent.seat, seat);

	return seat;
}

static void
ss_seat_destroy(struct ss_seat *seat)
{
	if (seat->parent.pointer)
		wl_pointer_release(seat->parent.pointer);
	if (seat->parent.keyboard)
		wl_keyboard_release(seat->parent.keyboard);
	wl_seat_destroy(seat->parent.seat);

	wl_list_remove(&seat->link);

	weston_seat_release(&seat->base);

	free(seat);
}

static void
ss_shm_buffer_destroy(struct ss_shm_buffer *buffer)
{
	pixman_image_unref(buffer->pm_image);

	wl_buffer_destroy(buffer->buffer);
	munmap(buffer->data, buffer->size);

	pixman_region32_fini(&buffer->damage);

	wl_list_remove(&buffer->link);
	wl_list_remove(&buffer->free_link);
	free(buffer);
}

static void
buffer_release(void *data, struct wl_buffer *buffer)
{
	struct ss_shm_buffer *sb = data;

	if (sb->output) {
		wl_list_insert(&sb->output->shm.free_buffers, &sb->free_link);
	} else {
		ss_shm_buffer_destroy(sb);
	}
}

static const struct wl_buffer_listener buffer_listener = {
	buffer_release
};

static struct ss_shm_buffer *
shared_output_get_shm_buffer(struct shared_output *so)
{
	struct ss_shm_buffer *sb, *bnext;
	struct wl_shm_pool *pool;
	int width, height, stride;
	int fd;
	unsigned char *data;

	width = so->output->width;
	height = so->output->height;
	stride = width * 4;

	/* If the size of the output changed, we free the old buffers and
	 * make new ones. */
	if (so->shm.width != width ||
	    so->shm.height != height) {

		/* Destroy free buffers */
		wl_list_for_each_safe(sb, bnext, &so->shm.free_buffers, free_link)
			ss_shm_buffer_destroy(sb);

		/* Orphan in-use buffers so they get destroyed */
		wl_list_for_each(sb, &so->shm.buffers, link)
			sb->output = NULL;

		so->shm.width = width;
		so->shm.height = height;
	}

	if (!wl_list_empty(&so->shm.free_buffers)) {
		sb = container_of(so->shm.free_buffers.next,
				  struct ss_shm_buffer, free_link);
		wl_list_remove(&sb->free_link);
		wl_list_init(&sb->free_link);

		return sb;
	}

	fd = os_create_anonymous_file(height * stride);
	if (fd < 0) {
		weston_log("os_create_anonymous_file: %m\n");
		return NULL;
	}

	data = mmap(NULL, height * stride, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
	if (data == MAP_FAILED) {
		weston_log("mmap: %m\n");
		goto out_close;
	}

	sb = zalloc(sizeof *sb);
	if (!sb)
		goto out_unmap;

	sb->output = so;
	wl_list_init(&sb->free_link);
	wl_list_insert(&so->shm.buffers, &sb->link);

	pixman_region32_init_rect(&sb->damage, 0, 0, width, height);

	sb->data = data;
	sb->size = height * stride;

	pool = wl_shm_create_pool(so->parent.shm, fd, sb->size);

	sb->buffer = wl_shm_pool_create_buffer(pool, 0,
					       width, height, stride,
					       WL_SHM_FORMAT_ARGB8888);
	wl_buffer_add_listener(sb->buffer, &buffer_listener, sb);
	wl_shm_pool_destroy(pool);
	close(fd);
	fd = -1;

	memset(data, 0, sb->size);

	sb->pm_image =
		pixman_image_create_bits(PIXMAN_a8r8g8b8, width, height,
					 (uint32_t *)data, stride);
	if (!sb->pm_image)
		goto out_pixman_error;

	return sb;

out_pixman_error:
	pixman_region32_fini(&sb->damage);
out_unmap:
	munmap(data, height * stride);
out_close:
	if (fd != -1)
		close(fd);
	return NULL;
}

static void
output_compute_transform(struct weston_output *output,
			 pixman_transform_t *transform)
{
	pixman_fixed_t fw, fh;

	pixman_transform_init_identity(transform);

	fw = pixman_int_to_fixed(output->width);
	fh = pixman_int_to_fixed(output->height);

	switch (output->transform) {
	case WL_OUTPUT_TRANSFORM_FLIPPED:
	case WL_OUTPUT_TRANSFORM_FLIPPED_90:
	case WL_OUTPUT_TRANSFORM_FLIPPED_180:
	case WL_OUTPUT_TRANSFORM_FLIPPED_270:
		pixman_transform_scale(transform, NULL,
				       pixman_int_to_fixed (-1),
				       pixman_int_to_fixed (1));
		pixman_transform_translate(transform, NULL, fw, 0);
	}

	switch (output->transform) {
	default:
	case WL_OUTPUT_TRANSFORM_NORMAL:
	case WL_OUTPUT_TRANSFORM_FLIPPED:
		break;
	case WL_OUTPUT_TRANSFORM_90:
	case WL_OUTPUT_TRANSFORM_FLIPPED_90:
		pixman_transform_rotate(transform, NULL, 0, pixman_fixed_1);
		pixman_transform_translate(transform, NULL, fh, 0);
		break;
	case WL_OUTPUT_TRANSFORM_180:
	case WL_OUTPUT_TRANSFORM_FLIPPED_180:
		pixman_transform_rotate(transform, NULL, -pixman_fixed_1, 0);
		pixman_transform_translate(transform, NULL, fw, fh);
		break;
	case WL_OUTPUT_TRANSFORM_270:
	case WL_OUTPUT_TRANSFORM_FLIPPED_270:
		pixman_transform_rotate(transform, NULL, 0, -pixman_fixed_1);
		pixman_transform_translate(transform, NULL, 0, fw);
		break;
	}

	pixman_transform_scale(transform, NULL,
			       pixman_fixed_1 * output->current_scale,
			       pixman_fixed_1 * output->current_scale);
}

static void
shared_output_destroy(struct shared_output *so);

static int
shared_output_ensure_tmp_data(struct shared_output *so,
			      pixman_region32_t *region)
{
	pixman_box32_t *ext;
	size_t size;

	if (!pixman_region32_not_empty(region))
		return 0;

	ext = pixman_region32_extents(region);

	/* Damage is in output coordinates.
	 *
	 * We are multiplying by 4 because the temporary data needs to be able
	 * to store an 32 bit-per-pixel buffer.
	 */
	size = 4 * (ext->x2 - ext->x1) * (ext->y2 - ext->y1)
		 * so->output->current_scale * so->output->current_scale;

	if (so->tmp_data != NULL && size <= so->tmp_data_size)
		return 0;

	free(so->tmp_data);
	so->tmp_data = malloc(size);
	if (so->tmp_data == NULL) {
		so->tmp_data_size = 0;
		errno = ENOMEM;
		return -1;
	}

	so->tmp_data_size = size;

	return 0;
}

static void
shared_output_update(struct shared_output *so);

static void
shared_output_frame_callback(void *data, struct wl_callback *cb, uint32_t time)
{
	struct shared_output *so = data;

	if (cb != so->parent.frame_cb)
		return;

	wl_callback_destroy(cb);
	so->parent.frame_cb = NULL;

	shared_output_update(so);
}

static const struct wl_callback_listener shared_output_frame_listener = {
	shared_output_frame_callback
};

static void
shared_output_update(struct shared_output *so)
{
	struct ss_shm_buffer *sb;
	pixman_box32_t *r;
	int i, nrects;
	pixman_transform_t transform;

	/* Only update if we need to */
	if (!so->cache_dirty || so->parent.frame_cb)
		return;

	sb = shared_output_get_shm_buffer(so);
	if (sb == NULL) {
		shared_output_destroy(so);
		return;
	}

	output_compute_transform(so->output, &transform);
	pixman_image_set_transform(so->cache_image, &transform);

	pixman_image_set_clip_region32(sb->pm_image, &sb->damage);

	if (so->output->current_scale == 1) {
		pixman_image_set_filter(so->cache_image,
					PIXMAN_FILTER_NEAREST, NULL, 0);
	} else {
		pixman_image_set_filter(so->cache_image,
					PIXMAN_FILTER_BILINEAR, NULL, 0);
	}

	pixman_image_composite32(PIXMAN_OP_SRC,
				 so->cache_image, /* src */
				 NULL, /* mask */
				 sb->pm_image, /* dest */
				 0, 0, /* src_x, src_y */
				 0, 0, /* mask_x, mask_y */
				 0, 0, /* dest_x, dest_y */
				 so->output->width, /* width */
				 so->output->height /* height */);

	pixman_image_set_transform(sb->pm_image, NULL);
	pixman_image_set_clip_region32(sb->pm_image, NULL);

	r = pixman_region32_rectangles(&sb->damage, &nrects);
	for (i = 0; i < nrects; ++i)
		wl_surface_damage(so->parent.surface, r[i].x1, r[i].y1,
				  r[i].x2 - r[i].x1, r[i].y2 - r[i].y1);

	wl_surface_attach(so->parent.surface, sb->buffer, 0, 0);

	so->parent.frame_cb = wl_surface_frame(so->parent.surface);
	wl_callback_add_listener(so->parent.frame_cb,
				 &shared_output_frame_listener, so);

	wl_surface_commit(so->parent.surface);
	wl_callback_destroy(wl_display_sync(so->parent.display));
	wl_display_flush(so->parent.display);

	/* Clear the buffer damage */
	pixman_region32_fini(&sb->damage);
	pixman_region32_init(&sb->damage);
}

static void
shm_handle_format(void *data, struct wl_shm *wl_shm, uint32_t format)
{
	struct shared_output *so = data;

	so->parent.shm_formats |= (1 << format);
}

struct wl_shm_listener shm_listener = {
	shm_handle_format
};

static void
registry_handle_global(void *data, struct wl_registry *registry,
		       uint32_t id, const char *interface, uint32_t version)
{
	struct shared_output *so = data;

	if (strcmp(interface, "wl_compositor") == 0) {
		so->parent.compositor =
			wl_registry_bind(registry,
					 id, &wl_compositor_interface, 1);
	} else if (strcmp(interface, "wl_output") == 0 && !so->parent.output) {
		so->parent.output =
			wl_registry_bind(registry,
					 id, &wl_output_interface, 1);
	} else if (strcmp(interface, "wl_seat") == 0) {
		ss_seat_create(so, id);
	} else if (strcmp(interface, "wl_shm") == 0) {
		so->parent.shm =
			wl_registry_bind(registry,
					 id, &wl_shm_interface, 1);
		wl_shm_add_listener(so->parent.shm, &shm_listener, so);
	} else if (strcmp(interface, "zwp_fullscreen_shell_v1") == 0) {
		so->parent.fshell =
			wl_registry_bind(registry,
					 id,
					 &zwp_fullscreen_shell_v1_interface,
					 1);
	}
}

static void
registry_handle_global_remove(void *data, struct wl_registry *registry,
			      uint32_t name)
{
}

static const struct wl_registry_listener registry_listener = {
	registry_handle_global,
	registry_handle_global_remove
};

static int
shared_output_handle_event(int fd, uint32_t mask, void *data)
{
	struct shared_output *so = data;
	int count = 0;

	if ((mask & WL_EVENT_HANGUP) || (mask & WL_EVENT_ERROR)) {
		shared_output_destroy(so);
		return 0;
	}

	if (mask & WL_EVENT_READABLE)
		count = wl_display_dispatch(so->parent.display);
	if (mask & WL_EVENT_WRITABLE)
		wl_display_flush(so->parent.display);

	if (mask == 0) {
		count = wl_display_dispatch_pending(so->parent.display);
		wl_display_flush(so->parent.display);
	}

	return count;
}

static void
output_destroyed(struct wl_listener *l, void *data)
{
	struct shared_output *so;

	so = container_of(l, struct shared_output, output_destroyed);

	shared_output_destroy(so);
}

static void
mode_feedback_ok(void *data, struct zwp_fullscreen_shell_mode_feedback_v1 *fb)
{
	struct shared_output *so = data;

	zwp_fullscreen_shell_mode_feedback_v1_destroy(so->parent.mode_feedback);
}

static void
mode_feedback_failed(void *data, struct zwp_fullscreen_shell_mode_feedback_v1 *fb)
{
	struct shared_output *so = data;

	zwp_fullscreen_shell_mode_feedback_v1_destroy(so->parent.mode_feedback);

	weston_log("Screen share failed: present_surface_for_mode failed\n");
	shared_output_destroy(so);
}

struct zwp_fullscreen_shell_mode_feedback_v1_listener mode_feedback_listener = {
	mode_feedback_ok,
	mode_feedback_failed,
	mode_feedback_ok,
};

static void
shared_output_repainted(struct wl_listener *listener, void *data)
{
	struct shared_output *so =
		container_of(listener, struct shared_output, frame_listener);
	pixman_region32_t damage;
	struct ss_shm_buffer *sb;
	int32_t x, y, width, height, stride;
	int i, nrects, do_yflip;
	pixman_box32_t *r;
	uint32_t *cache_data;

	/* Damage in output coordinates */
	pixman_region32_init(&damage);
	pixman_region32_intersect(&damage, &so->output->region,
				  &so->output->previous_damage);
	pixman_region32_translate(&damage, -so->output->x, -so->output->y);

	/* Apply damage to all buffers */
	wl_list_for_each(sb, &so->shm.buffers, link)
		pixman_region32_union(&sb->damage, &sb->damage, &damage);

	/* Transform to buffer coordinates */
	weston_transformed_region(so->output->width, so->output->height,
				  so->output->transform,
				  so->output->current_scale,
				  &damage, &damage);

	width = so->output->current_mode->width;
	height = so->output->current_mode->height;
	stride = width;

	if (!so->cache_image ||
	    pixman_image_get_width(so->cache_image) != width ||
	    pixman_image_get_height(so->cache_image) != height) {
		if (so->cache_image)
			pixman_image_unref(so->cache_image);

		so->cache_image =
			pixman_image_create_bits(PIXMAN_a8r8g8b8,
						 width, height, NULL,
						 stride);
		if (!so->cache_image) {
			shared_output_destroy(so);
			return;
		}

		pixman_region32_fini(&damage);
		pixman_region32_init_rect(&damage, 0, 0, width, height);
	}

	if (shared_output_ensure_tmp_data(so, &damage) < 0) {
		shared_output_destroy(so);
		return;
	}

	do_yflip = !!(so->output->compositor->capabilities & WESTON_CAP_CAPTURE_YFLIP);

	cache_data = pixman_image_get_data(so->cache_image);
	r = pixman_region32_rectangles(&damage, &nrects);
	for (i = 0; i < nrects; ++i) {
		x = r[i].x1;
		y = r[i].y1;
		width = r[i].x2 - r[i].x1;
		height = r[i].y2 - r[i].y1;

		if (do_yflip) {
			so->output->compositor->renderer->read_pixels(
				so->output, PIXMAN_a8r8g8b8, so->tmp_data,
				x, so->output->current_mode->height - r[i].y2,
				width, height);

			pixman_blt(so->tmp_data, cache_data, -width, stride,
				   32, 32, 0, 1 - height, x, y, width, height);
		} else {
			so->output->compositor->renderer->read_pixels(
				so->output, PIXMAN_a8r8g8b8, so->tmp_data,
				x, y, width, height);

			pixman_blt(so->tmp_data, cache_data, width, stride,
				   32, 32, 0, 0, x, y, width, height);
		}
	}

	pixman_region32_fini(&damage);

	so->cache_dirty = 1;

	shared_output_update(so);
}

static struct shared_output *
shared_output_create(struct weston_output *output, int parent_fd)
{
	struct shared_output *so;
	struct wl_event_loop *loop;
	struct ss_seat *seat, *tmp;
	int epoll_fd;

	so = zalloc(sizeof *so);
	if (so == NULL)
		goto err_close;

	wl_list_init(&so->seat_list);

	so->parent.display = wl_display_connect_to_fd(parent_fd);
	if (!so->parent.display)
		goto err_alloc;

	so->parent.registry = wl_display_get_registry(so->parent.display);
	if (!so->parent.registry)
		goto err_display;
	wl_registry_add_listener(so->parent.registry,
				 &registry_listener, so);
	wl_display_roundtrip(so->parent.display);
	if (so->parent.shm == NULL) {
		weston_log("Screen share failed: No wl_shm found\n");
		goto err_display;
	}
	if (so->parent.fshell == NULL) {
		weston_log("Screen share failed: "
			   "Parent does not support wl_fullscreen_shell\n");
		goto err_display;
	}
	if (so->parent.compositor == NULL) {
		weston_log("Screen share failed: No wl_compositor found\n");
		goto err_display;
	}

	/* Get SHM formats */
	wl_display_roundtrip(so->parent.display);
	if (!(so->parent.shm_formats & (1 << WL_SHM_FORMAT_XRGB8888))) {
		weston_log("Screen share failed: "
			   "WL_SHM_FORMAT_XRGB8888 not available\n");
		goto err_display;
	}

	so->parent.surface =
		wl_compositor_create_surface(so->parent.compositor);
	if (!so->parent.surface) {
		weston_log("Screen share failed: %m\n");
		goto err_display;
	}

	so->parent.mode_feedback =
		zwp_fullscreen_shell_v1_present_surface_for_mode(so->parent.fshell,
								 so->parent.surface,
								 so->parent.output,
								 output->current_mode->refresh);
	if (!so->parent.mode_feedback) {
		weston_log("Screen share failed: %m\n");
		goto err_display;
	}
	zwp_fullscreen_shell_mode_feedback_v1_add_listener(so->parent.mode_feedback,
							   &mode_feedback_listener,
							   so);

	loop = wl_display_get_event_loop(output->compositor->wl_display);

	epoll_fd = wl_display_get_fd(so->parent.display);
	so->event_source =
		wl_event_loop_add_fd(loop, epoll_fd, WL_EVENT_READABLE,
				     shared_output_handle_event, so);
	if (!so->event_source) {
		weston_log("Screen share failed: %m\n");
		goto err_display;
	}

	/* Ok, everything's created.  We should be good to go */
	wl_list_init(&so->shm.buffers);
	wl_list_init(&so->shm.free_buffers);

	so->output = output;
	so->output_destroyed.notify = output_destroyed;
	wl_signal_add(&so->output->destroy_signal, &so->output_destroyed);

	so->frame_listener.notify = shared_output_repainted;
	wl_signal_add(&output->frame_signal, &so->frame_listener);
	output->disable_planes++;
	weston_output_damage(output);

	return so;

err_display:
	wl_list_for_each_safe(seat, tmp, &so->seat_list, link)
		ss_seat_destroy(seat);
	wl_display_disconnect(so->parent.display);
err_alloc:
	free(so);
err_close:
	close(parent_fd);
	return NULL;
}

static void
shared_output_destroy(struct shared_output *so)
{
	struct ss_shm_buffer *buffer, *bnext;

	so->output->disable_planes--;

	wl_list_for_each_safe(buffer, bnext, &so->shm.buffers, link)
		ss_shm_buffer_destroy(buffer);
	wl_list_for_each_safe(buffer, bnext, &so->shm.free_buffers, free_link)
		ss_shm_buffer_destroy(buffer);

	wl_display_disconnect(so->parent.display);
	wl_event_source_remove(so->event_source);

	wl_list_remove(&so->output_destroyed.link);
	wl_list_remove(&so->frame_listener.link);

	pixman_image_unref(so->cache_image);
	free(so->tmp_data);

	free(so);
}

static struct shared_output *
weston_output_share(struct weston_output *output, const char* command)
{
	int sv[2];
	char str[32];
	pid_t pid;
	sigset_t allsigs;
	char *const argv[] = {
	  "/bin/sh",
	  "-c",
	  (char*)command,
	  NULL
	};

	if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, sv) < 0) {
		weston_log("weston_output_share: socketpair failed: %m\n");
		return NULL;
	}

	pid = fork();

	if (pid == -1) {
		close(sv[0]);
		close(sv[1]);
		weston_log("weston_output_share: fork failed: %m\n");
		return NULL;
	}

	if (pid == 0) {
		/* do not give our signal mask to the new process */
		sigfillset(&allsigs);
		sigprocmask(SIG_UNBLOCK, &allsigs, NULL);

		/* Launch clients as the user. Do not launch clients with
		 * wrong euid. */
		if (seteuid(getuid()) == -1) {
			weston_log("weston_output_share: setuid failed: %m\n");
			abort();
		}

		sv[1] = dup(sv[1]);
		if (sv[1] == -1) {
			weston_log("weston_output_share: dup failed: %m\n");
			abort();
		}

		snprintf(str, sizeof str, "%d", sv[1]);
		setenv("WAYLAND_SERVER_SOCKET", str, 1);

		execv(argv[0], argv);
		weston_log("weston_output_share: exec failed: %m\n");
		abort();
	} else {
		close(sv[1]);
		return shared_output_create(output, sv[0]);
	}

	return NULL;
}

static struct weston_output *
weston_output_find(struct weston_compositor *c, int32_t x, int32_t y)
{
	struct weston_output *output;

	wl_list_for_each(output, &c->output_list, link) {
		if (x >= output->x && y >= output->y &&
		    x < output->x + output->width &&
		    y < output->y + output->height)
			return output;
	}

	return NULL;
}

static void
share_output_binding(struct weston_keyboard *keyboard,
		     const struct timespec *time, uint32_t key, void *data)
{
	struct weston_output *output;
	struct weston_pointer *pointer;
	struct screen_share *ss = data;

	pointer = weston_seat_get_pointer(keyboard->seat);
	if (!pointer) {
		weston_log("Cannot pick output: Seat does not have pointer\n");
		return;
	}

	output = weston_output_find(pointer->seat->compositor,
				    wl_fixed_to_int(pointer->x),
				    wl_fixed_to_int(pointer->y));
	if (!output) {
		weston_log("Cannot pick output: Pointer not on any output\n");
		return;
	}

	weston_output_share(output, ss->command);
}

WL_EXPORT int
wet_module_init(struct weston_compositor *compositor,
		int *argc, char *argv[])
{
	struct screen_share *ss;
	struct weston_config *config = wet_get_config(compositor);
	struct weston_config_section *section;

	ss = zalloc(sizeof *ss);
	if (ss == NULL)
		return -1;
	ss->compositor = compositor;

	section = weston_config_get_section(config, "screen-share", NULL, NULL);

	weston_config_section_get_string(section, "command", &ss->command, "");

	weston_compositor_add_key_binding(compositor, KEY_S,
				          MODIFIER_CTRL | MODIFIER_ALT,
					  share_output_binding, ss);
	return 0;
}
