/*
 * Copyright © 2011 Intel Corporation
 *
 * 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 <sys/socket.h>
#include <sys/un.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <signal.h>
#include <limits.h>
#include <assert.h>
#include <X11/Xcursor/Xcursor.h>
#include <linux/input.h>

#include "compositor.h"
#include "xwayland.h"
#include "xwayland-internal-interface.h"

#include "cairo-util.h"
#include "hash.h"
#include "shared/helpers.h"

struct wm_size_hints {
	uint32_t flags;
	int32_t x, y;
	int32_t width, height;	/* should set so old wm's don't mess up */
	int32_t min_width, min_height;
	int32_t max_width, max_height;
	int32_t width_inc, height_inc;
	struct {
		int32_t x;
		int32_t y;
	} min_aspect, max_aspect;
	int32_t base_width, base_height;
	int32_t win_gravity;
};

#define USPosition	(1L << 0)
#define USSize		(1L << 1)
#define PPosition	(1L << 2)
#define PSize		(1L << 3)
#define PMinSize	(1L << 4)
#define PMaxSize	(1L << 5)
#define PResizeInc	(1L << 6)
#define PAspect		(1L << 7)
#define PBaseSize	(1L << 8)
#define PWinGravity	(1L << 9)

struct motif_wm_hints {
	uint32_t flags;
	uint32_t functions;
	uint32_t decorations;
	int32_t input_mode;
	uint32_t status;
};

#define MWM_HINTS_FUNCTIONS     (1L << 0)
#define MWM_HINTS_DECORATIONS   (1L << 1)
#define MWM_HINTS_INPUT_MODE    (1L << 2)
#define MWM_HINTS_STATUS        (1L << 3)

#define MWM_FUNC_ALL            (1L << 0)
#define MWM_FUNC_RESIZE         (1L << 1)
#define MWM_FUNC_MOVE           (1L << 2)
#define MWM_FUNC_MINIMIZE       (1L << 3)
#define MWM_FUNC_MAXIMIZE       (1L << 4)
#define MWM_FUNC_CLOSE          (1L << 5)

#define MWM_DECOR_ALL           (1L << 0)
#define MWM_DECOR_BORDER        (1L << 1)
#define MWM_DECOR_RESIZEH       (1L << 2)
#define MWM_DECOR_TITLE         (1L << 3)
#define MWM_DECOR_MENU          (1L << 4)
#define MWM_DECOR_MINIMIZE      (1L << 5)
#define MWM_DECOR_MAXIMIZE      (1L << 6)

#define MWM_DECOR_EVERYTHING \
	(MWM_DECOR_BORDER | MWM_DECOR_RESIZEH | MWM_DECOR_TITLE | \
	 MWM_DECOR_MENU | MWM_DECOR_MINIMIZE | MWM_DECOR_MAXIMIZE)

#define MWM_INPUT_MODELESS 0
#define MWM_INPUT_PRIMARY_APPLICATION_MODAL 1
#define MWM_INPUT_SYSTEM_MODAL 2
#define MWM_INPUT_FULL_APPLICATION_MODAL 3
#define MWM_INPUT_APPLICATION_MODAL MWM_INPUT_PRIMARY_APPLICATION_MODAL

#define MWM_TEAROFF_WINDOW      (1L<<0)

#define _NET_WM_MOVERESIZE_SIZE_TOPLEFT      0
#define _NET_WM_MOVERESIZE_SIZE_TOP          1
#define _NET_WM_MOVERESIZE_SIZE_TOPRIGHT     2
#define _NET_WM_MOVERESIZE_SIZE_RIGHT        3
#define _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT  4
#define _NET_WM_MOVERESIZE_SIZE_BOTTOM       5
#define _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT   6
#define _NET_WM_MOVERESIZE_SIZE_LEFT         7
#define _NET_WM_MOVERESIZE_MOVE              8   /* movement only */
#define _NET_WM_MOVERESIZE_SIZE_KEYBOARD     9   /* size via keyboard */
#define _NET_WM_MOVERESIZE_MOVE_KEYBOARD    10   /* move via keyboard */
#define _NET_WM_MOVERESIZE_CANCEL           11   /* cancel operation */

struct weston_output_weak_ref {
	struct weston_output *output;
	struct wl_listener destroy_listener;
};

struct weston_wm_window {
	struct weston_wm *wm;
	xcb_window_t id;
	xcb_window_t frame_id;
	struct frame *frame;
	cairo_surface_t *cairo_surface;
	int icon;
	cairo_surface_t *icon_surface;
	uint32_t surface_id;
	struct weston_surface *surface;
	struct weston_desktop_xwayland_surface *shsurf;
	struct wl_listener surface_destroy_listener;
	struct wl_event_source *repaint_source;
	struct wl_event_source *configure_source;
	int properties_dirty;
	int pid;
	char *machine;
	char *class;
	char *name;
	struct weston_wm_window *transient_for;
	uint32_t protocols;
	xcb_atom_t type;
	int width, height;
	int x;
	int y;
	bool pos_dirty;
	int map_request_x;
	int map_request_y;
	struct weston_output_weak_ref legacy_fullscreen_output;
	int saved_width, saved_height;
	int decorate;
	uint32_t last_button_time;
	int did_double;
	int override_redirect;
	int fullscreen;
	int has_alpha;
	int delete_window;
	int maximized_vert;
	int maximized_horz;
	struct wm_size_hints size_hints;
	struct motif_wm_hints motif_hints;
	struct wl_list link;
};

static struct weston_wm_window *
get_wm_window(struct weston_surface *surface);

static void
weston_wm_set_net_active_window(struct weston_wm *wm, xcb_window_t window);

static void
weston_wm_window_schedule_repaint(struct weston_wm_window *window);

static int
legacy_fullscreen(struct weston_wm *wm,
		  struct weston_wm_window *window,
		  struct weston_output **output_ret);

static void
xserver_map_shell_surface(struct weston_wm_window *window,
			  struct weston_surface *surface);

static int __attribute__ ((format (printf, 1, 2)))
wm_log(const char *fmt, ...)
{
#ifdef WM_DEBUG
	int l;
	va_list argp;

	va_start(argp, fmt);
	l = weston_vlog(fmt, argp);
	va_end(argp);

	return l;
#else
	return 0;
#endif
}

static int __attribute__ ((format (printf, 1, 2)))
wm_log_continue(const char *fmt, ...)
{
#ifdef WM_DEBUG
	int l;
	va_list argp;

	va_start(argp, fmt);
	l = weston_vlog_continue(fmt, argp);
	va_end(argp);

	return l;
#else
	return 0;
#endif
}

static void
weston_output_weak_ref_init(struct weston_output_weak_ref *ref)
{
	ref->output = NULL;
}

static void
weston_output_weak_ref_clear(struct weston_output_weak_ref *ref)
{
	if (!ref->output)
		return;

	wl_list_remove(&ref->destroy_listener.link);
	ref->output = NULL;
}

static void
weston_output_weak_ref_handle_destroy(struct wl_listener *listener, void *data)
{
	struct weston_output_weak_ref *ref;

	ref = wl_container_of(listener, ref, destroy_listener);
	assert(ref->output == data);

	weston_output_weak_ref_clear(ref);
}

static void
weston_output_weak_ref_set(struct weston_output_weak_ref *ref,
			   struct weston_output *output)
{
	weston_output_weak_ref_clear(ref);

	if (!output)
		return;

	ref->destroy_listener.notify = weston_output_weak_ref_handle_destroy;
	wl_signal_add(&output->destroy_signal, &ref->destroy_listener);
	ref->output = output;
}

static bool __attribute__ ((warn_unused_result))
wm_lookup_window(struct weston_wm *wm, xcb_window_t hash,
		 struct weston_wm_window **window)
{
	*window = hash_table_lookup(wm->window_hash, hash);
	if (*window)
		return true;
	return false;
}

const char *
get_atom_name(xcb_connection_t *c, xcb_atom_t atom)
{
	xcb_get_atom_name_cookie_t cookie;
	xcb_get_atom_name_reply_t *reply;
	xcb_generic_error_t *e;
	static char buffer[64];

	if (atom == XCB_ATOM_NONE)
		return "None";

	cookie = xcb_get_atom_name (c, atom);
	reply = xcb_get_atom_name_reply (c, cookie, &e);

	if (reply) {
		snprintf(buffer, sizeof buffer, "%.*s",
			 xcb_get_atom_name_name_length (reply),
			 xcb_get_atom_name_name (reply));
	} else {
		snprintf(buffer, sizeof buffer, "(atom %u)", atom);
	}

	free(reply);

	return buffer;
}

static xcb_cursor_t
xcb_cursor_image_load_cursor(struct weston_wm *wm, const XcursorImage *img)
{
	xcb_connection_t *c = wm->conn;
	xcb_screen_iterator_t s = xcb_setup_roots_iterator(xcb_get_setup(c));
	xcb_screen_t *screen = s.data;
	xcb_gcontext_t gc;
	xcb_pixmap_t pix;
	xcb_render_picture_t pic;
	xcb_cursor_t cursor;
	int stride = img->width * 4;

	pix = xcb_generate_id(c);
	xcb_create_pixmap(c, 32, pix, screen->root, img->width, img->height);

	pic = xcb_generate_id(c);
	xcb_render_create_picture(c, pic, pix, wm->format_rgba.id, 0, 0);

	gc = xcb_generate_id(c);
	xcb_create_gc(c, gc, pix, 0, 0);

	xcb_put_image(c, XCB_IMAGE_FORMAT_Z_PIXMAP, pix, gc,
		      img->width, img->height, 0, 0, 0, 32,
		      stride * img->height, (uint8_t *) img->pixels);
	xcb_free_gc(c, gc);

	cursor = xcb_generate_id(c);
	xcb_render_create_cursor(c, cursor, pic, img->xhot, img->yhot);

	xcb_render_free_picture(c, pic);
	xcb_free_pixmap(c, pix);

	return cursor;
}

static xcb_cursor_t
xcb_cursor_images_load_cursor(struct weston_wm *wm, const XcursorImages *images)
{
	/* TODO: treat animated cursors as well */
	if (images->nimage != 1)
		return -1;

	return xcb_cursor_image_load_cursor(wm, images->images[0]);
}

static xcb_cursor_t
xcb_cursor_library_load_cursor(struct weston_wm *wm, const char *file)
{
	xcb_cursor_t cursor;
	XcursorImages *images;
	char *v = NULL;
	int size = 0;

	if (!file)
		return 0;

	v = getenv ("XCURSOR_SIZE");
	if (v)
		size = atoi(v);

	if (!size)
		size = 32;

	images = XcursorLibraryLoadImages (file, NULL, size);
	if (!images)
		return -1;

	cursor = xcb_cursor_images_load_cursor (wm, images);
	XcursorImagesDestroy (images);

	return cursor;
}

void
dump_property(struct weston_wm *wm,
	      xcb_atom_t property, xcb_get_property_reply_t *reply)
{
	int32_t *incr_value;
	const char *text_value, *name;
	xcb_atom_t *atom_value;
	int width, len;
	uint32_t i;

	width = wm_log_continue("%s: ", get_atom_name(wm->conn, property));
	if (reply == NULL) {
		wm_log_continue("(no reply)\n");
		return;
	}

	width += wm_log_continue("%s/%d, length %d (value_len %d): ",
				 get_atom_name(wm->conn, reply->type),
				 reply->format,
				 xcb_get_property_value_length(reply),
				 reply->value_len);

	if (reply->type == wm->atom.incr) {
		incr_value = xcb_get_property_value(reply);
		wm_log_continue("%d\n", *incr_value);
	} else if (reply->type == wm->atom.utf8_string ||
	      reply->type == wm->atom.string) {
		text_value = xcb_get_property_value(reply);
		if (reply->value_len > 40)
			len = 40;
		else
			len = reply->value_len;
		wm_log_continue("\"%.*s\"\n", len, text_value);
	} else if (reply->type == XCB_ATOM_ATOM) {
		atom_value = xcb_get_property_value(reply);
		for (i = 0; i < reply->value_len; i++) {
			name = get_atom_name(wm->conn, atom_value[i]);
			if (width + strlen(name) + 2 > 78) {
				wm_log_continue("\n    ");
				width = 4;
			} else if (i > 0) {
				width +=  wm_log_continue(", ");
			}

			width +=  wm_log_continue("%s", name);
		}
		wm_log_continue("\n");
	} else {
		wm_log_continue("huh?\n");
	}
}

static void
read_and_dump_property(struct weston_wm *wm,
		       xcb_window_t window, xcb_atom_t property)
{
	xcb_get_property_reply_t *reply;
	xcb_get_property_cookie_t cookie;

	cookie = xcb_get_property(wm->conn, 0, window,
				  property, XCB_ATOM_ANY, 0, 2048);
	reply = xcb_get_property_reply(wm->conn, cookie, NULL);

	dump_property(wm, property, reply);

	free(reply);
}

/* We reuse some predefined, but otherwise useles atoms
 * as local type placeholders that never touch the X11 server,
 * to make weston_wm_window_read_properties() less exceptional.
 */
#define TYPE_WM_PROTOCOLS	XCB_ATOM_CUT_BUFFER0
#define TYPE_MOTIF_WM_HINTS	XCB_ATOM_CUT_BUFFER1
#define TYPE_NET_WM_STATE	XCB_ATOM_CUT_BUFFER2
#define TYPE_WM_NORMAL_HINTS	XCB_ATOM_CUT_BUFFER3

static void
weston_wm_window_read_properties(struct weston_wm_window *window)
{
	struct weston_wm *wm = window->wm;

#define F(field) (&window->field)
	const struct {
		xcb_atom_t atom;
		xcb_atom_t type;
		void *ptr;
	} props[] = {
		{ XCB_ATOM_WM_CLASS,           XCB_ATOM_STRING,            F(class) },
		{ XCB_ATOM_WM_NAME,            XCB_ATOM_STRING,            F(name) },
		{ XCB_ATOM_WM_TRANSIENT_FOR,   XCB_ATOM_WINDOW,            F(transient_for) },
		{ wm->atom.wm_protocols,       TYPE_WM_PROTOCOLS,          NULL },
		{ wm->atom.wm_normal_hints,    TYPE_WM_NORMAL_HINTS,       NULL },
		{ wm->atom.net_wm_state,       TYPE_NET_WM_STATE,          NULL },
		{ wm->atom.net_wm_window_type, XCB_ATOM_ATOM,              F(type) },
		{ wm->atom.net_wm_name,        XCB_ATOM_STRING,            F(name) },
		{ wm->atom.net_wm_icon,        XCB_ATOM_CARDINAL,          F(icon) },
		{ wm->atom.net_wm_pid,         XCB_ATOM_CARDINAL,          F(pid) },
		{ wm->atom.motif_wm_hints,     TYPE_MOTIF_WM_HINTS,        NULL },
		{ wm->atom.wm_client_machine,  XCB_ATOM_WM_CLIENT_MACHINE, F(machine) },
	};
#undef F

	xcb_get_property_cookie_t cookie[ARRAY_LENGTH(props)];
	xcb_get_property_reply_t *reply;
	void *p;
	uint32_t *xid;
	xcb_atom_t *atom;
	uint32_t i;
	char name[1024];

	if (!window->properties_dirty)
		return;
	window->properties_dirty = 0;

	for (i = 0; i < ARRAY_LENGTH(props); i++)
		cookie[i] = xcb_get_property(wm->conn,
					     0, /* delete */
					     window->id,
					     props[i].atom,
					     XCB_ATOM_ANY, 0, 2048);

	window->decorate = window->override_redirect ? 0 : MWM_DECOR_EVERYTHING;
	window->size_hints.flags = 0;
	window->motif_hints.flags = 0;
	window->delete_window = 0;

	for (i = 0; i < ARRAY_LENGTH(props); i++)  {
		reply = xcb_get_property_reply(wm->conn, cookie[i], NULL);
		if (!reply)
			/* Bad window, typically */
			continue;
		if (reply->type == XCB_ATOM_NONE) {
			/* No such property */
			free(reply);
			continue;
		}

		p = props[i].ptr;

		switch (props[i].type) {
		case XCB_ATOM_WM_CLIENT_MACHINE:
		case XCB_ATOM_STRING:
			/* FIXME: We're using this for both string and
			   utf8_string */
			if (*(char **) p)
				free(*(char **) p);

			*(char **) p =
				strndup(xcb_get_property_value(reply),
					xcb_get_property_value_length(reply));
			break;
		case XCB_ATOM_WINDOW:
			xid = xcb_get_property_value(reply);
			if (!wm_lookup_window(wm, *xid, p))
				weston_log("XCB_ATOM_WINDOW contains window"
					   " id not found in hash table.\n");
			break;
		case XCB_ATOM_CARDINAL:
		case XCB_ATOM_ATOM:
			atom = xcb_get_property_value(reply);
			*(xcb_atom_t *) p = *atom;
			break;
		case TYPE_WM_PROTOCOLS:
			atom = xcb_get_property_value(reply);
			for (i = 0; i < reply->value_len; i++)
				if (atom[i] == wm->atom.wm_delete_window) {
					window->delete_window = 1;
					break;
				}
			break;
		case TYPE_WM_NORMAL_HINTS:
			memcpy(&window->size_hints,
			       xcb_get_property_value(reply),
			       sizeof window->size_hints);
			break;
		case TYPE_NET_WM_STATE:
			window->fullscreen = 0;
			atom = xcb_get_property_value(reply);
			for (i = 0; i < reply->value_len; i++) {
				if (atom[i] == wm->atom.net_wm_state_fullscreen)
					window->fullscreen = 1;
				if (atom[i] == wm->atom.net_wm_state_maximized_vert)
					window->maximized_vert = 1;
				if (atom[i] == wm->atom.net_wm_state_maximized_horz)
					window->maximized_horz = 1;
			}
			break;
		case TYPE_MOTIF_WM_HINTS:
			memcpy(&window->motif_hints,
			       xcb_get_property_value(reply),
			       sizeof window->motif_hints);
			if (window->motif_hints.flags & MWM_HINTS_DECORATIONS) {
				if (window->motif_hints.decorations & MWM_DECOR_ALL)
					/* MWM_DECOR_ALL means all except the other values listed. */
					window->decorate =
						MWM_DECOR_EVERYTHING & (~window->motif_hints.decorations);
				else
					window->decorate =
						window->motif_hints.decorations;
			}
			break;
		default:
			break;
		}
		free(reply);
	}

	if (window->pid > 0) {
		gethostname(name, sizeof(name));
		for (i = 0; i < sizeof(name); i++) {
			if (name[i] == '\0')
				break;
		}
		if (i == sizeof(name))
			name[0] = '\0'; /* ignore stupid hostnames */

		/* this is only one heuristic to guess the PID of a client is
		* valid, assuming it's compliant with icccm and ewmh.
		* Non-compliants and remote applications of course fail. */
		if (!window->machine || strcmp(window->machine, name))
			window->pid = 0;
	}
}

#undef TYPE_WM_PROTOCOLS
#undef TYPE_MOTIF_WM_HINTS
#undef TYPE_NET_WM_STATE
#undef TYPE_WM_NORMAL_HINTS

static void
weston_wm_window_get_frame_size(struct weston_wm_window *window,
				int *width, int *height)
{
	struct theme *t = window->wm->theme;

	if (window->fullscreen) {
		*width = window->width;
		*height = window->height;
	} else if (window->decorate && window->frame) {
		*width = frame_width(window->frame);
		*height = frame_height(window->frame);
	} else {
		*width = window->width + t->margin * 2;
		*height = window->height + t->margin * 2;
	}
}

static void
weston_wm_window_get_child_position(struct weston_wm_window *window,
				    int *x, int *y)
{
	struct theme *t = window->wm->theme;

	if (window->fullscreen) {
		*x = 0;
		*y = 0;
	} else if (window->decorate && window->frame) {
		frame_interior(window->frame, x, y, NULL, NULL);
	} else {
		*x = t->margin;
		*y = t->margin;
	}
}

static void
weston_wm_window_get_input_rect(struct weston_wm_window *window,
                               int32_t *x, int32_t *y,
                               int32_t *width, int32_t *height)
{
       if (!window->decorate) {
               weston_wm_window_get_child_position(window, x, y);
               *width = window->width;
               *height = window->height;
       } else {
               frame_input_rect(window->frame, x, y, width, height);
       }
}

static void
weston_wm_window_send_configure_notify(struct weston_wm_window *window)
{
	xcb_configure_notify_event_t configure_notify;
	struct weston_wm *wm = window->wm;
	int x, y;

	weston_wm_window_get_child_position(window, &x, &y);
	configure_notify.response_type = XCB_CONFIGURE_NOTIFY;
	configure_notify.pad0 = 0;
	configure_notify.event = window->id;
	configure_notify.window = window->id;
	configure_notify.above_sibling = XCB_WINDOW_NONE;
	configure_notify.x = x;
	configure_notify.y = y;
	configure_notify.width = window->width;
	configure_notify.height = window->height;
	configure_notify.border_width = 0;
	configure_notify.override_redirect = 0;
	configure_notify.pad1 = 0;

	xcb_send_event(wm->conn, 0, window->id,
		       XCB_EVENT_MASK_STRUCTURE_NOTIFY,
		       (char *) &configure_notify);
}

static void
weston_wm_handle_configure_request(struct weston_wm *wm, xcb_generic_event_t *event)
{
	xcb_configure_request_event_t *configure_request =
		(xcb_configure_request_event_t *) event;
	struct weston_wm_window *window;
	uint32_t mask, values[16];
	int x, y, width, height, i = 0;

	wm_log("XCB_CONFIGURE_REQUEST (window %d) %d,%d @ %dx%d\n",
	       configure_request->window,
	       configure_request->x, configure_request->y,
	       configure_request->width, configure_request->height);

	if (!wm_lookup_window(wm, configure_request->window, &window))
		return;

	if (window->fullscreen) {
		weston_wm_window_send_configure_notify(window);
		return;
	}

	if (configure_request->value_mask & XCB_CONFIG_WINDOW_WIDTH)
		window->width = configure_request->width;
	if (configure_request->value_mask & XCB_CONFIG_WINDOW_HEIGHT)
		window->height = configure_request->height;

	if (window->frame)
		frame_resize_inside(window->frame, window->width, window->height);

	weston_wm_window_get_child_position(window, &x, &y);
	values[i++] = x;
	values[i++] = y;
	values[i++] = window->width;
	values[i++] = window->height;
	values[i++] = 0;
	mask = XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y |
		XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT |
		XCB_CONFIG_WINDOW_BORDER_WIDTH;
	if (configure_request->value_mask & XCB_CONFIG_WINDOW_SIBLING) {
		values[i++] = configure_request->sibling;
		mask |= XCB_CONFIG_WINDOW_SIBLING;
	}
	if (configure_request->value_mask & XCB_CONFIG_WINDOW_STACK_MODE) {
		values[i++] = configure_request->stack_mode;
		mask |= XCB_CONFIG_WINDOW_STACK_MODE;
	}

	xcb_configure_window(wm->conn, window->id, mask, values);

	weston_wm_window_get_frame_size(window, &width, &height);
	values[0] = width;
	values[1] = height;
	mask = XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT;
	xcb_configure_window(wm->conn, window->frame_id, mask, values);

	weston_wm_window_schedule_repaint(window);
}

static int
our_resource(struct weston_wm *wm, uint32_t id)
{
	const xcb_setup_t *setup;

	setup = xcb_get_setup(wm->conn);

	return (id & ~setup->resource_id_mask) == setup->resource_id_base;
}

static void
weston_wm_handle_configure_notify(struct weston_wm *wm, xcb_generic_event_t *event)
{
	xcb_configure_notify_event_t *configure_notify =
		(xcb_configure_notify_event_t *) event;
	const struct weston_desktop_xwayland_interface *xwayland_api =
		wm->server->compositor->xwayland_interface;
	struct weston_wm_window *window;

	wm_log("XCB_CONFIGURE_NOTIFY (window %d) %d,%d @ %dx%d%s\n",
	       configure_notify->window,
	       configure_notify->x, configure_notify->y,
	       configure_notify->width, configure_notify->height,
	       configure_notify->override_redirect ? ", override" : "");

	if (!wm_lookup_window(wm, configure_notify->window, &window))
		return;

	window->x = configure_notify->x;
	window->y = configure_notify->y;
	window->pos_dirty = false;

	if (window->override_redirect) {
		window->width = configure_notify->width;
		window->height = configure_notify->height;
		if (window->frame)
			frame_resize_inside(window->frame,
					    window->width, window->height);

		/* We should check if shsurf has been created because sometimes
		 * there are races
		 * (configure_notify is sent before xserver_map_surface) */
		if (window->shsurf)
			xwayland_api->set_xwayland(window->shsurf,
						   window->x, window->y);
	}
}

static void
weston_wm_kill_client(struct wl_listener *listener, void *data)
{
	struct weston_surface *surface = data;
	struct weston_wm_window *window = get_wm_window(surface);
	if (!window)
		return;

	if (window->pid > 0)
		kill(window->pid, SIGKILL);
}

static void
weston_wm_create_surface(struct wl_listener *listener, void *data)
{
	struct weston_surface *surface = data;
	struct weston_wm *wm =
		container_of(listener,
			     struct weston_wm, create_surface_listener);
	struct weston_wm_window *window;

	if (wl_resource_get_client(surface->resource) != wm->server->client)
		return;

	wm_log("XWM: create weston_surface %p\n", surface);

	wl_list_for_each(window, &wm->unpaired_window_list, link)
		if (window->surface_id ==
		    wl_resource_get_id(surface->resource)) {
			xserver_map_shell_surface(window, surface);
			window->surface_id = 0;
			wl_list_remove(&window->link);
			break;
		}
}

static void
weston_wm_send_focus_window(struct weston_wm *wm,
			    struct weston_wm_window *window)
{
	xcb_client_message_event_t client_message;

	if (window) {
		uint32_t values[1];

		if (window->override_redirect)
			return;

		client_message.response_type = XCB_CLIENT_MESSAGE;
		client_message.format = 32;
		client_message.window = window->id;
		client_message.type = wm->atom.wm_protocols;
		client_message.data.data32[0] = wm->atom.wm_take_focus;
		client_message.data.data32[1] = XCB_TIME_CURRENT_TIME;

		xcb_send_event(wm->conn, 0, window->id,
			       XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT,
			       (char *) &client_message);

		xcb_set_input_focus (wm->conn, XCB_INPUT_FOCUS_POINTER_ROOT,
				     window->id, XCB_TIME_CURRENT_TIME);

		values[0] = XCB_STACK_MODE_ABOVE;
		xcb_configure_window (wm->conn, window->frame_id,
				      XCB_CONFIG_WINDOW_STACK_MODE, values);
	} else {
		xcb_set_input_focus (wm->conn,
				     XCB_INPUT_FOCUS_POINTER_ROOT,
				     XCB_NONE,
				     XCB_TIME_CURRENT_TIME);
	}
}

static void
weston_wm_window_activate(struct wl_listener *listener, void *data)
{
	struct weston_surface_activation_data *activation_data = data;
	struct weston_surface *surface = activation_data->surface;
	struct weston_wm_window *window = NULL;
	struct weston_wm *wm =
		container_of(listener, struct weston_wm, activate_listener);

	if (surface) {
		window = get_wm_window(surface);
	}

	if (window) {
		weston_wm_set_net_active_window(wm, window->id);
	} else {
		weston_wm_set_net_active_window(wm, XCB_WINDOW_NONE);
	}

	weston_wm_send_focus_window(wm, window);

	if (wm->focus_window) {
		if (wm->focus_window->frame)
			frame_unset_flag(wm->focus_window->frame, FRAME_FLAG_ACTIVE);
		weston_wm_window_schedule_repaint(wm->focus_window);
	}
	wm->focus_window = window;
	if (wm->focus_window) {
		if (wm->focus_window->frame)
			frame_set_flag(wm->focus_window->frame, FRAME_FLAG_ACTIVE);
		weston_wm_window_schedule_repaint(wm->focus_window);
	}

	xcb_flush(wm->conn);

}

/** Control Xwayland wl_surface.commit behaviour
 *
 * This function sets the "_XWAYLAND_ALLOW_COMMITS" property of the frame window
 * (not the content window!) to \p allow.
 *
 * If the property is set to \c true, Xwayland will commit whenever it likes.
 * If the property is set to \c false, Xwayland will not commit.
 * If the property is not set at all, Xwayland assumes it is \c true.
 *
 * \param window The XWM window to control.
 * \param allow Whether Xwayland is allowed to wl_surface.commit for the window.
 */
static void
weston_wm_window_set_allow_commits(struct weston_wm_window *window, bool allow)
{
	struct weston_wm *wm = window->wm;
	uint32_t property[1];

	assert(window->frame_id != XCB_WINDOW_NONE);

	property[0] = allow ? 1 : 0;

	xcb_change_property(wm->conn,
			    XCB_PROP_MODE_REPLACE,
			    window->frame_id,
			    wm->atom.allow_commits,
			    XCB_ATOM_CARDINAL,
			    32, /* format */
			    1, property);
}

#define ICCCM_WITHDRAWN_STATE	0
#define ICCCM_NORMAL_STATE	1
#define ICCCM_ICONIC_STATE	3

static void
weston_wm_window_set_wm_state(struct weston_wm_window *window, int32_t state)
{
	struct weston_wm *wm = window->wm;
	uint32_t property[2];

	property[0] = state;
	property[1] = XCB_WINDOW_NONE;

	xcb_change_property(wm->conn,
			    XCB_PROP_MODE_REPLACE,
			    window->id,
			    wm->atom.wm_state,
			    wm->atom.wm_state,
			    32, /* format */
			    2, property);
}

static void
weston_wm_window_set_net_wm_state(struct weston_wm_window *window)
{
	struct weston_wm *wm = window->wm;
	uint32_t property[3];
	int i;

	i = 0;
	if (window->fullscreen)
		property[i++] = wm->atom.net_wm_state_fullscreen;
	if (window->maximized_vert)
		property[i++] = wm->atom.net_wm_state_maximized_vert;
	if (window->maximized_horz)
		property[i++] = wm->atom.net_wm_state_maximized_horz;

	xcb_change_property(wm->conn,
			    XCB_PROP_MODE_REPLACE,
			    window->id,
			    wm->atom.net_wm_state,
			    XCB_ATOM_ATOM,
			    32, /* format */
			    i, property);
}

static void
weston_wm_window_create_frame(struct weston_wm_window *window)
{
	struct weston_wm *wm = window->wm;
	uint32_t values[3];
	xcb_rectangle_t rect;
	int x, y, width, height;
	int buttons = FRAME_BUTTON_CLOSE;

	if (window->decorate & MWM_DECOR_MAXIMIZE)
		buttons |= FRAME_BUTTON_MAXIMIZE;

	window->frame = frame_create(window->wm->theme,
	                             window->width, window->height,
	                             buttons, window->name,
	                             window->icon_surface);
	frame_resize_inside(window->frame, window->width, window->height);

	weston_wm_window_get_frame_size(window, &width, &height);
	weston_wm_window_get_child_position(window, &x, &y);

	values[0] = wm->screen->black_pixel;
	values[1] =
		XCB_EVENT_MASK_KEY_PRESS |
		XCB_EVENT_MASK_KEY_RELEASE |
		XCB_EVENT_MASK_BUTTON_PRESS |
		XCB_EVENT_MASK_BUTTON_RELEASE |
		XCB_EVENT_MASK_POINTER_MOTION |
		XCB_EVENT_MASK_ENTER_WINDOW |
		XCB_EVENT_MASK_LEAVE_WINDOW |
		XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY |
		XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT;
	values[2] = wm->colormap;

	window->frame_id = xcb_generate_id(wm->conn);
	xcb_create_window(wm->conn,
			  32,
			  window->frame_id,
			  wm->screen->root,
			  0, 0,
			  width, height,
			  0,
			  XCB_WINDOW_CLASS_INPUT_OUTPUT,
			  wm->visual_id,
			  XCB_CW_BORDER_PIXEL |
			  XCB_CW_EVENT_MASK |
			  XCB_CW_COLORMAP, values);

	xcb_reparent_window(wm->conn, window->id, window->frame_id, x, y);

	values[0] = 0;
	xcb_configure_window(wm->conn, window->id,
			     XCB_CONFIG_WINDOW_BORDER_WIDTH, values);

	window->cairo_surface =
		cairo_xcb_surface_create_with_xrender_format(wm->conn,
							     wm->screen,
							     window->frame_id,
							     &wm->format_rgba,
							     width, height);

	weston_wm_window_get_input_rect(window, &x, &y, &width, &height);
	rect.x = x;
	rect.y = y;
	rect.width = width;
	rect.height = height;

	/* The window frame was created with position and size which include
	 * an offset for margins and shadow. Set the input region to ignore
	 * shadow. */
	xcb_shape_rectangles(wm->conn,
			     XCB_SHAPE_SO_SET,
			     XCB_SHAPE_SK_INPUT,
			     0,
			     window->frame_id,
			     0,
			     0,
			     1,
			     &rect);

	hash_table_insert(wm->window_hash, window->frame_id, window);
}

/*
 * Sets the _NET_WM_DESKTOP property for the window to 'desktop'.
 * Passing a <0 desktop value deletes the property.
 */
static void
weston_wm_window_set_virtual_desktop(struct weston_wm_window *window,
				     int desktop)
{
	if (desktop >= 0) {
		xcb_change_property(window->wm->conn,
		                    XCB_PROP_MODE_REPLACE,
		                    window->id,
		                    window->wm->atom.net_wm_desktop,
		                    XCB_ATOM_CARDINAL,
		                    32, /* format */
		                    1, &desktop);
	} else {
		xcb_delete_property(window->wm->conn,
		                    window->id,
		                    window->wm->atom.net_wm_desktop);
	}
}

static void
weston_wm_handle_map_request(struct weston_wm *wm, xcb_generic_event_t *event)
{
	xcb_map_request_event_t *map_request =
		(xcb_map_request_event_t *) event;
	struct weston_wm_window *window;
	struct weston_output *output;

	if (our_resource(wm, map_request->window)) {
		wm_log("XCB_MAP_REQUEST (window %d, ours)\n",
		       map_request->window);
		return;
	}

	if (!wm_lookup_window(wm, map_request->window, &window))
		return;

	weston_wm_window_read_properties(window);

	/* For a new Window, MapRequest happens before the Window is realized
	 * in Xwayland. We do the real xcb_map_window() here as a response to
	 * MapRequest. The Window will get realized (wl_surface created in
	 * Wayland and WL_SURFACE_ID sent in X11) when it has been mapped for
	 * real.
	 *
	 * MapRequest only happens for (X11) unmapped Windows. On UnmapNotify,
	 * we reset shsurf to NULL, so even if X11 connection races far ahead
	 * of the Wayland connection and the X11 client is repeatedly mapping
	 * and unmapping, we will never have shsurf set on MapRequest.
	 */
	assert(!window->shsurf);

	window->map_request_x = window->x;
	window->map_request_y = window->y;

	if (window->frame_id == XCB_WINDOW_NONE)
		weston_wm_window_create_frame(window); /* sets frame_id */
	assert(window->frame_id != XCB_WINDOW_NONE);

	wm_log("XCB_MAP_REQUEST (window %d, %p, frame %d, %dx%d @ %d,%d)\n",
	       window->id, window, window->frame_id,
	       window->width, window->height,
	       window->map_request_x, window->map_request_y);

	weston_wm_window_set_allow_commits(window, false);
	weston_wm_window_set_wm_state(window, ICCCM_NORMAL_STATE);
	weston_wm_window_set_net_wm_state(window);
	weston_wm_window_set_virtual_desktop(window, 0);

	if (legacy_fullscreen(wm, window, &output)) {
		window->fullscreen = 1;
		weston_output_weak_ref_set(&window->legacy_fullscreen_output,
					   output);
	}

	xcb_map_window(wm->conn, map_request->window);
	xcb_map_window(wm->conn, window->frame_id);

	/* Mapped in the X server, we can draw immediately.
	 * Cannot set pending state though, no weston_surface until
	 * xserver_map_shell_surface() time. */
	weston_wm_window_schedule_repaint(window);
}

static void
weston_wm_handle_map_notify(struct weston_wm *wm, xcb_generic_event_t *event)
{
	xcb_map_notify_event_t *map_notify = (xcb_map_notify_event_t *) event;

	if (our_resource(wm, map_notify->window)) {
		wm_log("XCB_MAP_NOTIFY (window %d, ours)\n",
		       map_notify->window);
			return;
	}

	wm_log("XCB_MAP_NOTIFY (window %d%s)\n", map_notify->window,
	       map_notify->override_redirect ? ", override" : "");
}

static void
weston_wm_handle_unmap_notify(struct weston_wm *wm, xcb_generic_event_t *event)
{
	xcb_unmap_notify_event_t *unmap_notify =
		(xcb_unmap_notify_event_t *) event;
	struct weston_wm_window *window;

	wm_log("XCB_UNMAP_NOTIFY (window %d, event %d%s)\n",
	       unmap_notify->window,
	       unmap_notify->event,
	       our_resource(wm, unmap_notify->window) ? ", ours" : "");

	if (our_resource(wm, unmap_notify->window))
		return;

	if (unmap_notify->response_type & SEND_EVENT_MASK)
		/* We just ignore the ICCCM 4.1.4 synthetic unmap notify
		 * as it may come in after we've destroyed the window. */
		return;

	if (!wm_lookup_window(wm, unmap_notify->window, &window))
		return;

	if (window->surface_id) {
		/* Make sure we're not on the unpaired surface list or we
		 * could be assigned a surface during surface creation that
		 * was mapped before this unmap request.
		 */
		wl_list_remove(&window->link);
		window->surface_id = 0;
	}
	if (wm->focus_window == window)
		wm->focus_window = NULL;
	if (window->surface)
		wl_list_remove(&window->surface_destroy_listener.link);
	window->surface = NULL;
	window->shsurf = NULL;

	weston_wm_window_set_wm_state(window, ICCCM_WITHDRAWN_STATE);
	weston_wm_window_set_virtual_desktop(window, -1);

	xcb_unmap_window(wm->conn, window->frame_id);
}

static void
weston_wm_window_draw_decoration(struct weston_wm_window *window)
{
	cairo_t *cr;
	int width, height;

	wm_log("XWM: draw decoration, win %d\n", window->id);

	weston_wm_window_get_frame_size(window, &width, &height);

	cairo_xcb_surface_set_size(window->cairo_surface, width, height);
	cr = cairo_create(window->cairo_surface);

	if (window->fullscreen) {
		/* nothing */
	} else if (window->decorate) {
		frame_set_title(window->frame, window->name);
		frame_repaint(window->frame, cr);
	} else {
		cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
		cairo_set_source_rgba(cr, 0, 0, 0, 0);
		cairo_paint(cr);

		render_shadow(cr, window->wm->theme->shadow,
			      2, 2, width + 8, height + 8, 64, 64);
	}

	cairo_destroy(cr);
	cairo_surface_flush(window->cairo_surface);
	xcb_flush(window->wm->conn);
}

static void
weston_wm_window_set_pending_state(struct weston_wm_window *window)
{
	int x, y, width, height;
	int32_t input_x, input_y, input_w, input_h;
	const struct weston_desktop_xwayland_interface *xwayland_interface =
		window->wm->server->compositor->xwayland_interface;

	if (!window->surface)
		return;

	weston_wm_window_get_frame_size(window, &width, &height);
	weston_wm_window_get_child_position(window, &x, &y);

	pixman_region32_fini(&window->surface->pending.opaque);
	if (window->has_alpha) {
		pixman_region32_init(&window->surface->pending.opaque);
	} else {
		/* We leave an extra pixel around the X window area to
		 * make sure we don't sample from the undefined alpha
		 * channel when filtering. */
		pixman_region32_init_rect(&window->surface->pending.opaque,
					  x - 1, y - 1,
					  window->width + 2,
					  window->height + 2);
	}

	if (window->decorate && !window->fullscreen) {
		frame_input_rect(window->frame, &input_x, &input_y,
				 &input_w, &input_h);
	} else {
		input_x = x;
		input_y = y;
		input_w = width;
		input_h = height;
	}

	wm_log("XWM: win %d geometry: %d,%d %dx%d\n",
	       window->id, input_x, input_y, input_w, input_h);

	pixman_region32_fini(&window->surface->pending.input);
	pixman_region32_init_rect(&window->surface->pending.input,
				  input_x, input_y, input_w, input_h);

	xwayland_interface->set_window_geometry(window->shsurf,
						input_x, input_y,
						input_w, input_h);
	if (window->name)
		xwayland_interface->set_title(window->shsurf, window->name);
	if (window->pid > 0)
		xwayland_interface->set_pid(window->shsurf, window->pid);
}

static void
weston_wm_window_do_repaint(void *data)
{
	struct weston_wm_window *window = data;

	window->repaint_source = NULL;

	weston_wm_window_read_properties(window);

	weston_wm_window_draw_decoration(window);
	weston_wm_window_set_pending_state(window);
}

static void
weston_wm_window_set_pending_state_OR(struct weston_wm_window *window)
{
	int width, height;

	/* for override-redirect windows */
	assert(window->frame_id == XCB_WINDOW_NONE);

	if (!window->surface)
		return;

	weston_wm_window_get_frame_size(window, &width, &height);
	pixman_region32_fini(&window->surface->pending.opaque);
	if (window->has_alpha) {
		pixman_region32_init(&window->surface->pending.opaque);
	} else {
		pixman_region32_init_rect(&window->surface->pending.opaque, 0, 0,
					  width, height);
	}
}

static void
weston_wm_window_schedule_repaint(struct weston_wm_window *window)
{
	struct weston_wm *wm = window->wm;

	if (window->frame_id == XCB_WINDOW_NONE) {
		/* Override-redirect windows go through here, but we
		 * cannot assert(window->override_redirect); because
		 * we do not deal with changing OR flag yet.
		 * XXX: handle OR flag changes in message handlers
		 */
		weston_wm_window_set_pending_state_OR(window);
		return;
	}

	if (window->repaint_source)
		return;

	wm_log("XWM: schedule repaint, win %d\n", window->id);

	window->repaint_source =
		wl_event_loop_add_idle(wm->server->loop,
				       weston_wm_window_do_repaint, window);
}

static void
weston_wm_handle_icon(struct weston_wm *wm, struct weston_wm_window *window)
{
	xcb_get_property_reply_t *reply;
	xcb_get_property_cookie_t cookie;
	uint32_t length;
	uint32_t *data, width, height;
	cairo_surface_t *new_surface;

	/* TODO: icons don’t have any specified order, we should pick the
	 * closest one to the target dimension instead of the first one. */

	cookie = xcb_get_property(wm->conn, 0, window->id,
	                          wm->atom.net_wm_icon, XCB_ATOM_ANY, 0,
	                          UINT32_MAX);
	reply = xcb_get_property_reply(wm->conn, cookie, NULL);
	length = xcb_get_property_value_length(reply);

	/* This is in 32-bit words, not in bytes. */
	if (length < 2)
		return;

	data = xcb_get_property_value(reply);
	width = *data++;
	height = *data++;

	/* Some checks against malformed input. */
	if (width == 0 || height == 0 || length < 2 + width * height)
		return;

	new_surface =
		cairo_image_surface_create_for_data((unsigned char *)data,
		                                    CAIRO_FORMAT_ARGB32,
		                                    width, height, width * 4);

	/* Bail out in case anything wrong happened during surface creation. */
	if (cairo_surface_status(new_surface) != CAIRO_STATUS_SUCCESS) {
		cairo_surface_destroy(new_surface);
		return;
	}

	if (window->icon_surface)
		cairo_surface_destroy(window->icon_surface);

	window->icon_surface = new_surface;
}

static void
weston_wm_handle_property_notify(struct weston_wm *wm, xcb_generic_event_t *event)
{
	xcb_property_notify_event_t *property_notify =
		(xcb_property_notify_event_t *) event;
	struct weston_wm_window *window;

	if (!wm_lookup_window(wm, property_notify->window, &window))
		return;

	window->properties_dirty = 1;

	wm_log("XCB_PROPERTY_NOTIFY: window %d, ", property_notify->window);
	if (property_notify->state == XCB_PROPERTY_DELETE)
		wm_log_continue("deleted %s\n",
				get_atom_name(wm->conn, property_notify->atom));
	else
		read_and_dump_property(wm, property_notify->window,
				       property_notify->atom);

	if (property_notify->atom == wm->atom.net_wm_icon) {
		if (property_notify->state != XCB_PROPERTY_DELETE) {
			weston_wm_handle_icon(wm, window);
		} else {
			cairo_surface_destroy(window->icon_surface);
			window->icon_surface = NULL;
		}
		weston_wm_window_schedule_repaint(window);
	}

	if (property_notify->atom == wm->atom.net_wm_name ||
	    property_notify->atom == XCB_ATOM_WM_NAME)
		weston_wm_window_schedule_repaint(window);
}

static void
weston_wm_window_create(struct weston_wm *wm,
			xcb_window_t id, int width, int height, int x, int y, int override)
{
	struct weston_wm_window *window;
	uint32_t values[1];
	xcb_get_geometry_cookie_t geometry_cookie;
	xcb_get_geometry_reply_t *geometry_reply;

	window = zalloc(sizeof *window);
	if (window == NULL) {
		wm_log("failed to allocate window\n");
		return;
	}

	geometry_cookie = xcb_get_geometry(wm->conn, id);

	values[0] = XCB_EVENT_MASK_PROPERTY_CHANGE |
                    XCB_EVENT_MASK_FOCUS_CHANGE;
	xcb_change_window_attributes(wm->conn, id, XCB_CW_EVENT_MASK, values);

	window->wm = wm;
	window->id = id;
	window->properties_dirty = 1;
	window->override_redirect = override;
	window->width = width;
	window->height = height;
	window->x = x;
	window->y = y;
	window->pos_dirty = false;
	window->map_request_x = INT_MIN; /* out of range for valid positions */
	window->map_request_y = INT_MIN; /* out of range for valid positions */
	weston_output_weak_ref_init(&window->legacy_fullscreen_output);

	geometry_reply = xcb_get_geometry_reply(wm->conn, geometry_cookie, NULL);
	/* technically we should use XRender and check the visual format's
	alpha_mask, but checking depth is simpler and works in all known cases */
	if (geometry_reply != NULL)
		window->has_alpha = geometry_reply->depth == 32;
	free(geometry_reply);

	hash_table_insert(wm->window_hash, id, window);
}

static void
weston_wm_window_destroy(struct weston_wm_window *window)
{
	struct weston_wm *wm = window->wm;

	weston_output_weak_ref_clear(&window->legacy_fullscreen_output);

	if (window->repaint_source)
		wl_event_source_remove(window->repaint_source);
	if (window->cairo_surface)
		cairo_surface_destroy(window->cairo_surface);

	if (window->frame_id) {
		xcb_reparent_window(wm->conn, window->id, wm->wm_window, 0, 0);
		xcb_destroy_window(wm->conn, window->frame_id);
		weston_wm_window_set_wm_state(window, ICCCM_WITHDRAWN_STATE);
		weston_wm_window_set_virtual_desktop(window, -1);
		hash_table_remove(wm->window_hash, window->frame_id);
		window->frame_id = XCB_WINDOW_NONE;
	}

	if (window->surface_id)
		wl_list_remove(&window->link);

	if (window->surface)
		wl_list_remove(&window->surface_destroy_listener.link);

	hash_table_remove(window->wm->window_hash, window->id);
	free(window);
}

static void
weston_wm_handle_create_notify(struct weston_wm *wm, xcb_generic_event_t *event)
{
	xcb_create_notify_event_t *create_notify =
		(xcb_create_notify_event_t *) event;

	wm_log("XCB_CREATE_NOTIFY (window %d, at (%d, %d), width %d, height %d%s%s)\n",
	       create_notify->window,
	       create_notify->x, create_notify->y,
	       create_notify->width, create_notify->height,
	       create_notify->override_redirect ? ", override" : "",
	       our_resource(wm, create_notify->window) ? ", ours" : "");

	if (our_resource(wm, create_notify->window))
		return;

	weston_wm_window_create(wm, create_notify->window,
				create_notify->width, create_notify->height,
				create_notify->x, create_notify->y,
				create_notify->override_redirect);
}

static void
weston_wm_handle_destroy_notify(struct weston_wm *wm, xcb_generic_event_t *event)
{
	xcb_destroy_notify_event_t *destroy_notify =
		(xcb_destroy_notify_event_t *) event;
	struct weston_wm_window *window;

	wm_log("XCB_DESTROY_NOTIFY, win %d, event %d%s\n",
	       destroy_notify->window,
	       destroy_notify->event,
	       our_resource(wm, destroy_notify->window) ? ", ours" : "");

	if (our_resource(wm, destroy_notify->window))
		return;

	if (!wm_lookup_window(wm, destroy_notify->window, &window))
		return;

	weston_wm_window_destroy(window);
}

static void
weston_wm_handle_reparent_notify(struct weston_wm *wm, xcb_generic_event_t *event)
{
	xcb_reparent_notify_event_t *reparent_notify =
		(xcb_reparent_notify_event_t *) event;
	struct weston_wm_window *window;

	wm_log("XCB_REPARENT_NOTIFY (window %d, parent %d, event %d%s)\n",
	       reparent_notify->window,
	       reparent_notify->parent,
	       reparent_notify->event,
	       reparent_notify->override_redirect ? ", override" : "");

	if (reparent_notify->parent == wm->screen->root) {
		weston_wm_window_create(wm, reparent_notify->window, 10, 10,
					reparent_notify->x, reparent_notify->y,
					reparent_notify->override_redirect);
	} else if (!our_resource(wm, reparent_notify->parent)) {
		if (!wm_lookup_window(wm, reparent_notify->window, &window))
			return;
		weston_wm_window_destroy(window);
	}
}

struct weston_seat *
weston_wm_pick_seat(struct weston_wm *wm)
{
	struct wl_list *seats = wm->server->compositor->seat_list.next;
	if (wl_list_empty(seats))
		return NULL;
	return container_of(seats, struct weston_seat, link);
}

static struct weston_seat *
weston_wm_pick_seat_for_window(struct weston_wm_window *window)
{
	struct weston_wm *wm = window->wm;
	struct weston_seat *seat, *s;

	seat = NULL;
	wl_list_for_each(s, &wm->server->compositor->seat_list, link) {
		struct weston_pointer *pointer = weston_seat_get_pointer(s);
		struct weston_pointer *old_pointer =
			weston_seat_get_pointer(seat);

		if (pointer && pointer->focus &&
		    pointer->focus->surface == window->surface &&
		    pointer->button_count > 0 &&
		    (!seat ||
		     pointer->grab_serial -
		     old_pointer->grab_serial < (1 << 30)))
			seat = s;
	}

	return seat;
}

static void
weston_wm_window_handle_moveresize(struct weston_wm_window *window,
				   xcb_client_message_event_t *client_message)
{
	static const int map[] = {
		THEME_LOCATION_RESIZING_TOP_LEFT,
		THEME_LOCATION_RESIZING_TOP,
		THEME_LOCATION_RESIZING_TOP_RIGHT,
		THEME_LOCATION_RESIZING_RIGHT,
		THEME_LOCATION_RESIZING_BOTTOM_RIGHT,
		THEME_LOCATION_RESIZING_BOTTOM,
		THEME_LOCATION_RESIZING_BOTTOM_LEFT,
		THEME_LOCATION_RESIZING_LEFT
	};

	struct weston_wm *wm = window->wm;
	struct weston_seat *seat = weston_wm_pick_seat_for_window(window);
	struct weston_pointer *pointer = weston_seat_get_pointer(seat);
	int detail;
	const struct weston_desktop_xwayland_interface *xwayland_interface =
		wm->server->compositor->xwayland_interface;

	if (!pointer || pointer->button_count != 1
	    || !pointer->focus
	    || pointer->focus->surface != window->surface)
		return;

	detail = client_message->data.data32[2];
	switch (detail) {
	case _NET_WM_MOVERESIZE_MOVE:
		xwayland_interface->move(window->shsurf, pointer);
		break;
	case _NET_WM_MOVERESIZE_SIZE_TOPLEFT:
	case _NET_WM_MOVERESIZE_SIZE_TOP:
	case _NET_WM_MOVERESIZE_SIZE_TOPRIGHT:
	case _NET_WM_MOVERESIZE_SIZE_RIGHT:
	case _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT:
	case _NET_WM_MOVERESIZE_SIZE_BOTTOM:
	case _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT:
	case _NET_WM_MOVERESIZE_SIZE_LEFT:
		xwayland_interface->resize(window->shsurf, pointer, map[detail]);
		break;
	case _NET_WM_MOVERESIZE_CANCEL:
		break;
	}
}

#define _NET_WM_STATE_REMOVE	0
#define _NET_WM_STATE_ADD	1
#define _NET_WM_STATE_TOGGLE	2

static int
update_state(int action, int *state)
{
	int new_state, changed;

	switch (action) {
	case _NET_WM_STATE_REMOVE:
		new_state = 0;
		break;
	case _NET_WM_STATE_ADD:
		new_state = 1;
		break;
	case _NET_WM_STATE_TOGGLE:
		new_state = !*state;
		break;
	default:
		return 0;
	}

	changed = (*state != new_state);
	*state = new_state;

	return changed;
}

static void
weston_wm_window_configure(void *data);

static void
weston_wm_window_set_toplevel(struct weston_wm_window *window)
{
	const struct weston_desktop_xwayland_interface *xwayland_interface =
		window->wm->server->compositor->xwayland_interface;

	xwayland_interface->set_toplevel(window->shsurf);
	window->width = window->saved_width;
	window->height = window->saved_height;
	if (window->frame)
		frame_resize_inside(window->frame,
					window->width,
					window->height);
	weston_wm_window_configure(window);
}

static inline bool
weston_wm_window_is_maximized(struct weston_wm_window *window)
{
	return window->maximized_horz && window->maximized_vert;
}

static void
weston_wm_window_handle_state(struct weston_wm_window *window,
			      xcb_client_message_event_t *client_message)
{
	struct weston_wm *wm = window->wm;
	const struct weston_desktop_xwayland_interface *xwayland_interface =
		wm->server->compositor->xwayland_interface;
	uint32_t action, property1, property2;
	int maximized = weston_wm_window_is_maximized(window);

	action = client_message->data.data32[0];
	property1 = client_message->data.data32[1];
	property2 = client_message->data.data32[2];

	if ((property1 == wm->atom.net_wm_state_fullscreen ||
	     property2 == wm->atom.net_wm_state_fullscreen) &&
	    update_state(action, &window->fullscreen)) {
		weston_wm_window_set_net_wm_state(window);
		if (window->fullscreen) {
			window->saved_width = window->width;
			window->saved_height = window->height;

			if (window->shsurf)
				xwayland_interface->set_fullscreen(window->shsurf,
								   NULL);
		} else {
			if (window->shsurf)
				weston_wm_window_set_toplevel(window);
		}
	} else {
		if ((property1 == wm->atom.net_wm_state_maximized_vert ||
		     property2 == wm->atom.net_wm_state_maximized_vert) &&
		    update_state(action, &window->maximized_vert))
			weston_wm_window_set_net_wm_state(window);
		if ((property1 == wm->atom.net_wm_state_maximized_horz ||
		     property2 == wm->atom.net_wm_state_maximized_horz) &&
		    update_state(action, &window->maximized_horz))
			weston_wm_window_set_net_wm_state(window);

		if (maximized != weston_wm_window_is_maximized(window)) {
			if (weston_wm_window_is_maximized(window)) {
				window->saved_width = window->width;
				window->saved_height = window->height;

				if (window->shsurf)
					xwayland_interface->set_maximized(window->shsurf);
			} else if (window->shsurf) {
				weston_wm_window_set_toplevel(window);
			}
		}
	}
}

static void
surface_destroy(struct wl_listener *listener, void *data)
{
	struct weston_wm_window *window =
		container_of(listener,
			     struct weston_wm_window, surface_destroy_listener);

	wm_log("surface for xid %d destroyed\n", window->id);

	/* This should have been freed by the shell.
	 * Don't try to use it later. */
	window->shsurf = NULL;
	window->surface = NULL;
}

static void
weston_wm_window_handle_surface_id(struct weston_wm_window *window,
				   xcb_client_message_event_t *client_message)
{
	struct weston_wm *wm = window->wm;
	struct wl_resource *resource;

	if (window->surface_id != 0) {
		wm_log("already have surface id for window %d\n", window->id);
		return;
	}

	/* Xwayland will send the wayland requests to create the
	 * wl_surface before sending this client message.  Even so, we
	 * can end up handling the X event before the wayland requests
	 * and thus when we try to look up the surface ID, the surface
	 * hasn't been created yet.  In that case put the window on
	 * the unpaired window list and continue when the surface gets
	 * created. */
	uint32_t id = client_message->data.data32[0];
	resource = wl_client_get_object(wm->server->client, id);
	if (resource) {
		window->surface_id = 0;
		xserver_map_shell_surface(window,
					  wl_resource_get_user_data(resource));
	}
	else {
		window->surface_id = id;
		wl_list_insert(&wm->unpaired_window_list, &window->link);
	}
}

static void
weston_wm_handle_client_message(struct weston_wm *wm,
				xcb_generic_event_t *event)
{
	xcb_client_message_event_t *client_message =
		(xcb_client_message_event_t *) event;
	struct weston_wm_window *window;

	wm_log("XCB_CLIENT_MESSAGE (%s %d %d %d %d %d win %d)\n",
	       get_atom_name(wm->conn, client_message->type),
	       client_message->data.data32[0],
	       client_message->data.data32[1],
	       client_message->data.data32[2],
	       client_message->data.data32[3],
	       client_message->data.data32[4],
	       client_message->window);

	/* The window may get created and destroyed before we actually
	 * handle the message.  If it doesn't exist, bail.
	 */
	if (!wm_lookup_window(wm, client_message->window, &window))
		return;

	if (client_message->type == wm->atom.net_wm_moveresize)
		weston_wm_window_handle_moveresize(window, client_message);
	else if (client_message->type == wm->atom.net_wm_state)
		weston_wm_window_handle_state(window, client_message);
	else if (client_message->type == wm->atom.wl_surface_id)
		weston_wm_window_handle_surface_id(window, client_message);
}

enum cursor_type {
	XWM_CURSOR_TOP,
	XWM_CURSOR_BOTTOM,
	XWM_CURSOR_LEFT,
	XWM_CURSOR_RIGHT,
	XWM_CURSOR_TOP_LEFT,
	XWM_CURSOR_TOP_RIGHT,
	XWM_CURSOR_BOTTOM_LEFT,
	XWM_CURSOR_BOTTOM_RIGHT,
	XWM_CURSOR_LEFT_PTR,
};

/*
 * The following correspondences between file names and cursors was copied
 * from: https://bugs.kde.org/attachment.cgi?id=67313
 */

static const char *bottom_left_corners[] = {
	"bottom_left_corner",
	"sw-resize",
	"size_bdiag"
};

static const char *bottom_right_corners[] = {
	"bottom_right_corner",
	"se-resize",
	"size_fdiag"
};

static const char *bottom_sides[] = {
	"bottom_side",
	"s-resize",
	"size_ver"
};

static const char *left_ptrs[] = {
	"left_ptr",
	"default",
	"top_left_arrow",
	"left-arrow"
};

static const char *left_sides[] = {
	"left_side",
	"w-resize",
	"size_hor"
};

static const char *right_sides[] = {
	"right_side",
	"e-resize",
	"size_hor"
};

static const char *top_left_corners[] = {
	"top_left_corner",
	"nw-resize",
	"size_fdiag"
};

static const char *top_right_corners[] = {
	"top_right_corner",
	"ne-resize",
	"size_bdiag"
};

static const char *top_sides[] = {
	"top_side",
	"n-resize",
	"size_ver"
};

struct cursor_alternatives {
	const char **names;
	size_t count;
};

static const struct cursor_alternatives cursors[] = {
	{top_sides, ARRAY_LENGTH(top_sides)},
	{bottom_sides, ARRAY_LENGTH(bottom_sides)},
	{left_sides, ARRAY_LENGTH(left_sides)},
	{right_sides, ARRAY_LENGTH(right_sides)},
	{top_left_corners, ARRAY_LENGTH(top_left_corners)},
	{top_right_corners, ARRAY_LENGTH(top_right_corners)},
	{bottom_left_corners, ARRAY_LENGTH(bottom_left_corners)},
	{bottom_right_corners, ARRAY_LENGTH(bottom_right_corners)},
	{left_ptrs, ARRAY_LENGTH(left_ptrs)},
};

static void
weston_wm_create_cursors(struct weston_wm *wm)
{
	const char *name;
	int i, count = ARRAY_LENGTH(cursors);
	size_t j;

	wm->cursors = malloc(count * sizeof(xcb_cursor_t));
	for (i = 0; i < count; i++) {
		for (j = 0; j < cursors[i].count; j++) {
			name = cursors[i].names[j];
			wm->cursors[i] =
				xcb_cursor_library_load_cursor(wm, name);
			if (wm->cursors[i] != (xcb_cursor_t)-1)
				break;
		}
	}

	wm->last_cursor = -1;
}

static void
weston_wm_destroy_cursors(struct weston_wm *wm)
{
	uint8_t i;

	for (i = 0; i < ARRAY_LENGTH(cursors); i++)
		xcb_free_cursor(wm->conn, wm->cursors[i]);

	free(wm->cursors);
}

static int
get_cursor_for_location(enum theme_location location)
{
	switch (location) {
		case THEME_LOCATION_RESIZING_TOP:
			return XWM_CURSOR_TOP;
		case THEME_LOCATION_RESIZING_BOTTOM:
			return XWM_CURSOR_BOTTOM;
		case THEME_LOCATION_RESIZING_LEFT:
			return XWM_CURSOR_LEFT;
		case THEME_LOCATION_RESIZING_RIGHT:
			return XWM_CURSOR_RIGHT;
		case THEME_LOCATION_RESIZING_TOP_LEFT:
			return XWM_CURSOR_TOP_LEFT;
		case THEME_LOCATION_RESIZING_TOP_RIGHT:
			return XWM_CURSOR_TOP_RIGHT;
		case THEME_LOCATION_RESIZING_BOTTOM_LEFT:
			return XWM_CURSOR_BOTTOM_LEFT;
		case THEME_LOCATION_RESIZING_BOTTOM_RIGHT:
			return XWM_CURSOR_BOTTOM_RIGHT;
		case THEME_LOCATION_EXTERIOR:
		case THEME_LOCATION_TITLEBAR:
		default:
			return XWM_CURSOR_LEFT_PTR;
	}
}

static void
weston_wm_window_set_cursor(struct weston_wm *wm, xcb_window_t window_id,
			    int cursor)
{
	uint32_t cursor_value_list;

	if (wm->last_cursor == cursor)
		return;

	wm->last_cursor = cursor;

	cursor_value_list = wm->cursors[cursor];
	xcb_change_window_attributes (wm->conn, window_id,
				      XCB_CW_CURSOR, &cursor_value_list);
	xcb_flush(wm->conn);
}

static void
weston_wm_window_close(struct weston_wm_window *window, xcb_timestamp_t time)
{
	xcb_client_message_event_t client_message;

	if (window->delete_window) {
		client_message.response_type = XCB_CLIENT_MESSAGE;
		client_message.format = 32;
		client_message.window = window->id;
		client_message.type = window->wm->atom.wm_protocols;
		client_message.data.data32[0] =
			window->wm->atom.wm_delete_window;
		client_message.data.data32[1] = time;

		xcb_send_event(window->wm->conn, 0, window->id,
			       XCB_EVENT_MASK_NO_EVENT,
			       (char *) &client_message);
	} else {
		xcb_kill_client(window->wm->conn, window->id);
	}
}

#define DOUBLE_CLICK_PERIOD 250
static void
weston_wm_handle_button(struct weston_wm *wm, xcb_generic_event_t *event)
{
	xcb_button_press_event_t *button = (xcb_button_press_event_t *) event;
	const struct weston_desktop_xwayland_interface *xwayland_interface =
		wm->server->compositor->xwayland_interface;
	struct weston_seat *seat;
	struct weston_pointer *pointer;
	struct weston_wm_window *window;
	enum theme_location location;
	enum wl_pointer_button_state button_state;
	uint32_t button_id;
	uint32_t double_click = 0;

	wm_log("XCB_BUTTON_%s (detail %d)\n",
	       button->response_type == XCB_BUTTON_PRESS ?
	       "PRESS" : "RELEASE", button->detail);

	if (!wm_lookup_window(wm, button->event, &window) ||
	    !window->decorate)
		return;

	if (button->detail != 1 && button->detail != 2)
		return;

	seat = weston_wm_pick_seat_for_window(window);
	pointer = weston_seat_get_pointer(seat);

	button_state = button->response_type == XCB_BUTTON_PRESS ?
		WL_POINTER_BUTTON_STATE_PRESSED :
		WL_POINTER_BUTTON_STATE_RELEASED;
	button_id = button->detail == 1 ? BTN_LEFT : BTN_RIGHT;

	if (button_state == WL_POINTER_BUTTON_STATE_PRESSED) {
		if (button->time - window->last_button_time <= DOUBLE_CLICK_PERIOD) {
			double_click = 1;
			window->did_double = 1;
		} else
			window->did_double = 0;

		window->last_button_time = button->time;
	} else if (window->did_double == 1) {
		double_click = 1;
		window->did_double = 0;
	}

	/* Make sure we're looking at the right location.  The frame
	 * could have received a motion event from a pointer from a
	 * different wl_seat, but under X it looks like our core
	 * pointer moved.  Move the frame pointer to the button press
	 * location before deciding what to do. */
	location = frame_pointer_motion(window->frame, NULL,
					button->event_x, button->event_y);
	if (double_click)
		location = frame_double_click(window->frame, NULL,
					      button_id, button_state);
	else
		location = frame_pointer_button(window->frame, NULL,
						button_id, button_state);

	if (frame_status(window->frame) & FRAME_STATUS_REPAINT)
		weston_wm_window_schedule_repaint(window);

	if (frame_status(window->frame) & FRAME_STATUS_MOVE) {
		if (pointer)
			xwayland_interface->move(window->shsurf, pointer);
		frame_status_clear(window->frame, FRAME_STATUS_MOVE);
	}

	if (frame_status(window->frame) & FRAME_STATUS_RESIZE) {
		if (pointer)
			xwayland_interface->resize(window->shsurf, pointer, location);
		frame_status_clear(window->frame, FRAME_STATUS_RESIZE);
	}

	if (frame_status(window->frame) & FRAME_STATUS_CLOSE) {
		weston_wm_window_close(window, button->time);
		frame_status_clear(window->frame, FRAME_STATUS_CLOSE);
	}

	if (frame_status(window->frame) & FRAME_STATUS_MAXIMIZE) {
		window->maximized_horz = !window->maximized_horz;
		window->maximized_vert = !window->maximized_vert;
		if (weston_wm_window_is_maximized(window)) {
			window->saved_width = window->width;
			window->saved_height = window->height;
			xwayland_interface->set_maximized(window->shsurf);
		} else {
			weston_wm_window_set_toplevel(window);
		}
		frame_status_clear(window->frame, FRAME_STATUS_MAXIMIZE);
	}
}

static void
weston_wm_handle_motion(struct weston_wm *wm, xcb_generic_event_t *event)
{
	xcb_motion_notify_event_t *motion = (xcb_motion_notify_event_t *) event;
	struct weston_wm_window *window;
	enum theme_location location;
	int cursor;

	if (!wm_lookup_window(wm, motion->event, &window) ||
	    !window->decorate)
		return;

	location = frame_pointer_motion(window->frame, NULL,
					motion->event_x, motion->event_y);
	if (frame_status(window->frame) & FRAME_STATUS_REPAINT)
		weston_wm_window_schedule_repaint(window);

	cursor = get_cursor_for_location(location);
	weston_wm_window_set_cursor(wm, window->frame_id, cursor);
}

static void
weston_wm_handle_enter(struct weston_wm *wm, xcb_generic_event_t *event)
{
	xcb_enter_notify_event_t *enter = (xcb_enter_notify_event_t *) event;
	struct weston_wm_window *window;
	enum theme_location location;
	int cursor;

	if (!wm_lookup_window(wm, enter->event, &window) ||
	    !window->decorate)
		return;

	location = frame_pointer_enter(window->frame, NULL,
				       enter->event_x, enter->event_y);
	if (frame_status(window->frame) & FRAME_STATUS_REPAINT)
		weston_wm_window_schedule_repaint(window);

	cursor = get_cursor_for_location(location);
	weston_wm_window_set_cursor(wm, window->frame_id, cursor);
}

static void
weston_wm_handle_leave(struct weston_wm *wm, xcb_generic_event_t *event)
{
	xcb_leave_notify_event_t *leave = (xcb_leave_notify_event_t *) event;
	struct weston_wm_window *window;

	if (!wm_lookup_window(wm, leave->event, &window) ||
	    !window->decorate)
		return;

	frame_pointer_leave(window->frame, NULL);
	if (frame_status(window->frame) & FRAME_STATUS_REPAINT)
		weston_wm_window_schedule_repaint(window);

	weston_wm_window_set_cursor(wm, window->frame_id, XWM_CURSOR_LEFT_PTR);
}

static void
weston_wm_handle_focus_in(struct weston_wm *wm, xcb_generic_event_t *event)
{
	xcb_focus_in_event_t *focus = (xcb_focus_in_event_t *) event;

	/* Do not interfere with grabs */
	if (focus->mode == XCB_NOTIFY_MODE_GRAB ||
	    focus->mode == XCB_NOTIFY_MODE_UNGRAB)
		return;

	/* Do not let X clients change the focus behind the compositor's
	 * back. Reset the focus to the old one if it changed. */
	if (!wm->focus_window || focus->event != wm->focus_window->id)
		weston_wm_send_focus_window(wm, wm->focus_window);
}

static int
weston_wm_handle_event(int fd, uint32_t mask, void *data)
{
	struct weston_wm *wm = data;
	xcb_generic_event_t *event;
	int count = 0;

	while (event = xcb_poll_for_event(wm->conn), event != NULL) {
		if (weston_wm_handle_selection_event(wm, event)) {
			free(event);
			count++;
			continue;
		}

		if (weston_wm_handle_dnd_event(wm, event)) {
			free(event);
			count++;
			continue;
		}

		switch (EVENT_TYPE(event)) {
		case XCB_BUTTON_PRESS:
		case XCB_BUTTON_RELEASE:
			weston_wm_handle_button(wm, event);
			break;
		case XCB_ENTER_NOTIFY:
			weston_wm_handle_enter(wm, event);
			break;
		case XCB_LEAVE_NOTIFY:
			weston_wm_handle_leave(wm, event);
			break;
		case XCB_MOTION_NOTIFY:
			weston_wm_handle_motion(wm, event);
			break;
		case XCB_CREATE_NOTIFY:
			weston_wm_handle_create_notify(wm, event);
			break;
		case XCB_MAP_REQUEST:
			weston_wm_handle_map_request(wm, event);
			break;
		case XCB_MAP_NOTIFY:
			weston_wm_handle_map_notify(wm, event);
			break;
		case XCB_UNMAP_NOTIFY:
			weston_wm_handle_unmap_notify(wm, event);
			break;
		case XCB_REPARENT_NOTIFY:
			weston_wm_handle_reparent_notify(wm, event);
			break;
		case XCB_CONFIGURE_REQUEST:
			weston_wm_handle_configure_request(wm, event);
			break;
		case XCB_CONFIGURE_NOTIFY:
			weston_wm_handle_configure_notify(wm, event);
			break;
		case XCB_DESTROY_NOTIFY:
			weston_wm_handle_destroy_notify(wm, event);
			break;
		case XCB_MAPPING_NOTIFY:
			wm_log("XCB_MAPPING_NOTIFY\n");
			break;
		case XCB_PROPERTY_NOTIFY:
			weston_wm_handle_property_notify(wm, event);
			break;
		case XCB_CLIENT_MESSAGE:
			weston_wm_handle_client_message(wm, event);
			break;
		case XCB_FOCUS_IN:
			weston_wm_handle_focus_in(wm, event);
			break;
		}

		free(event);
		count++;
	}

	if (count != 0)
		xcb_flush(wm->conn);

	return count;
}

static void
weston_wm_set_net_active_window(struct weston_wm *wm, xcb_window_t window) {
	xcb_change_property(wm->conn, XCB_PROP_MODE_REPLACE,
			wm->screen->root, wm->atom.net_active_window,
			wm->atom.window, 32, 1, &window);
}

static void
weston_wm_get_visual_and_colormap(struct weston_wm *wm)
{
	xcb_depth_iterator_t d_iter;
	xcb_visualtype_iterator_t vt_iter;
	xcb_visualtype_t *visualtype;

	d_iter = xcb_screen_allowed_depths_iterator(wm->screen);
	visualtype = NULL;
	while (d_iter.rem > 0) {
		if (d_iter.data->depth == 32) {
			vt_iter = xcb_depth_visuals_iterator(d_iter.data);
			visualtype = vt_iter.data;
			break;
		}

		xcb_depth_next(&d_iter);
	}

	if (visualtype == NULL) {
		weston_log("no 32 bit visualtype\n");
		return;
	}

	wm->visual_id = visualtype->visual_id;
	wm->colormap = xcb_generate_id(wm->conn);
	xcb_create_colormap(wm->conn, XCB_COLORMAP_ALLOC_NONE,
			    wm->colormap, wm->screen->root, wm->visual_id);
}

static void
weston_wm_get_resources(struct weston_wm *wm)
{

#define F(field) offsetof(struct weston_wm, field)

	static const struct { const char *name; int offset; } atoms[] = {
		{ "WM_PROTOCOLS",	F(atom.wm_protocols) },
		{ "WM_NORMAL_HINTS",	F(atom.wm_normal_hints) },
		{ "WM_TAKE_FOCUS",	F(atom.wm_take_focus) },
		{ "WM_DELETE_WINDOW",	F(atom.wm_delete_window) },
		{ "WM_STATE",		F(atom.wm_state) },
		{ "WM_S0",		F(atom.wm_s0) },
		{ "WM_CLIENT_MACHINE",	F(atom.wm_client_machine) },
		{ "_NET_WM_CM_S0",	F(atom.net_wm_cm_s0) },
		{ "_NET_WM_NAME",	F(atom.net_wm_name) },
		{ "_NET_WM_PID",	F(atom.net_wm_pid) },
		{ "_NET_WM_ICON",	F(atom.net_wm_icon) },
		{ "_NET_WM_STATE",	F(atom.net_wm_state) },
		{ "_NET_WM_STATE_MAXIMIZED_VERT", F(atom.net_wm_state_maximized_vert) },
		{ "_NET_WM_STATE_MAXIMIZED_HORZ", F(atom.net_wm_state_maximized_horz) },
		{ "_NET_WM_STATE_FULLSCREEN", F(atom.net_wm_state_fullscreen) },
		{ "_NET_WM_USER_TIME", F(atom.net_wm_user_time) },
		{ "_NET_WM_ICON_NAME", F(atom.net_wm_icon_name) },
		{ "_NET_WM_DESKTOP", F(atom.net_wm_desktop) },
		{ "_NET_WM_WINDOW_TYPE", F(atom.net_wm_window_type) },

		{ "_NET_WM_WINDOW_TYPE_DESKTOP", F(atom.net_wm_window_type_desktop) },
		{ "_NET_WM_WINDOW_TYPE_DOCK", F(atom.net_wm_window_type_dock) },
		{ "_NET_WM_WINDOW_TYPE_TOOLBAR", F(atom.net_wm_window_type_toolbar) },
		{ "_NET_WM_WINDOW_TYPE_MENU", F(atom.net_wm_window_type_menu) },
		{ "_NET_WM_WINDOW_TYPE_UTILITY", F(atom.net_wm_window_type_utility) },
		{ "_NET_WM_WINDOW_TYPE_SPLASH", F(atom.net_wm_window_type_splash) },
		{ "_NET_WM_WINDOW_TYPE_DIALOG", F(atom.net_wm_window_type_dialog) },
		{ "_NET_WM_WINDOW_TYPE_DROPDOWN_MENU", F(atom.net_wm_window_type_dropdown) },
		{ "_NET_WM_WINDOW_TYPE_POPUP_MENU", F(atom.net_wm_window_type_popup) },
		{ "_NET_WM_WINDOW_TYPE_TOOLTIP", F(atom.net_wm_window_type_tooltip) },
		{ "_NET_WM_WINDOW_TYPE_NOTIFICATION", F(atom.net_wm_window_type_notification) },
		{ "_NET_WM_WINDOW_TYPE_COMBO", F(atom.net_wm_window_type_combo) },
		{ "_NET_WM_WINDOW_TYPE_DND", F(atom.net_wm_window_type_dnd) },
		{ "_NET_WM_WINDOW_TYPE_NORMAL",	F(atom.net_wm_window_type_normal) },

		{ "_NET_WM_MOVERESIZE", F(atom.net_wm_moveresize) },
		{ "_NET_SUPPORTING_WM_CHECK",
					F(atom.net_supporting_wm_check) },
		{ "_NET_SUPPORTED",     F(atom.net_supported) },
		{ "_NET_ACTIVE_WINDOW",     F(atom.net_active_window) },
		{ "_MOTIF_WM_HINTS",	F(atom.motif_wm_hints) },
		{ "CLIPBOARD",		F(atom.clipboard) },
		{ "CLIPBOARD_MANAGER",	F(atom.clipboard_manager) },
		{ "TARGETS",		F(atom.targets) },
		{ "UTF8_STRING",	F(atom.utf8_string) },
		{ "_WL_SELECTION",	F(atom.wl_selection) },
		{ "INCR",		F(atom.incr) },
		{ "TIMESTAMP",		F(atom.timestamp) },
		{ "MULTIPLE",		F(atom.multiple) },
		{ "UTF8_STRING"	,	F(atom.utf8_string) },
		{ "COMPOUND_TEXT",	F(atom.compound_text) },
		{ "TEXT",		F(atom.text) },
		{ "STRING",		F(atom.string) },
		{ "WINDOW",		F(atom.window) },
		{ "text/plain;charset=utf-8",	F(atom.text_plain_utf8) },
		{ "text/plain",		F(atom.text_plain) },
		{ "XdndSelection",	F(atom.xdnd_selection) },
		{ "XdndAware",		F(atom.xdnd_aware) },
		{ "XdndEnter",		F(atom.xdnd_enter) },
		{ "XdndLeave",		F(atom.xdnd_leave) },
		{ "XdndDrop",		F(atom.xdnd_drop) },
		{ "XdndStatus",		F(atom.xdnd_status) },
		{ "XdndFinished",	F(atom.xdnd_finished) },
		{ "XdndTypeList",	F(atom.xdnd_type_list) },
		{ "XdndActionCopy",	F(atom.xdnd_action_copy) },
		{ "_XWAYLAND_ALLOW_COMMITS",	F(atom.allow_commits) },
		{ "WL_SURFACE_ID",	F(atom.wl_surface_id) }
	};
#undef F

	xcb_xfixes_query_version_cookie_t xfixes_cookie;
	xcb_xfixes_query_version_reply_t *xfixes_reply;
	xcb_intern_atom_cookie_t cookies[ARRAY_LENGTH(atoms)];
	xcb_intern_atom_reply_t *reply;
	xcb_render_query_pict_formats_reply_t *formats_reply;
	xcb_render_query_pict_formats_cookie_t formats_cookie;
	xcb_render_pictforminfo_t *formats;
	uint32_t i;

	xcb_prefetch_extension_data (wm->conn, &xcb_xfixes_id);
	xcb_prefetch_extension_data (wm->conn, &xcb_composite_id);

	formats_cookie = xcb_render_query_pict_formats(wm->conn);

	for (i = 0; i < ARRAY_LENGTH(atoms); i++)
		cookies[i] = xcb_intern_atom (wm->conn, 0,
					      strlen(atoms[i].name),
					      atoms[i].name);

	for (i = 0; i < ARRAY_LENGTH(atoms); i++) {
		reply = xcb_intern_atom_reply (wm->conn, cookies[i], NULL);
		*(xcb_atom_t *) ((char *) wm + atoms[i].offset) = reply->atom;
		free(reply);
	}

	wm->xfixes = xcb_get_extension_data(wm->conn, &xcb_xfixes_id);
	if (!wm->xfixes || !wm->xfixes->present)
		weston_log("xfixes not available\n");

	xfixes_cookie = xcb_xfixes_query_version(wm->conn,
						 XCB_XFIXES_MAJOR_VERSION,
						 XCB_XFIXES_MINOR_VERSION);
	xfixes_reply = xcb_xfixes_query_version_reply(wm->conn,
						      xfixes_cookie, NULL);

	weston_log("xfixes version: %d.%d\n",
	       xfixes_reply->major_version, xfixes_reply->minor_version);

	free(xfixes_reply);

	formats_reply = xcb_render_query_pict_formats_reply(wm->conn,
							    formats_cookie, 0);
	if (formats_reply == NULL)
		return;

	formats = xcb_render_query_pict_formats_formats(formats_reply);
	for (i = 0; i < formats_reply->num_formats; i++) {
		if (formats[i].direct.red_mask != 0xff &&
		    formats[i].direct.red_shift != 16)
			continue;
		if (formats[i].type == XCB_RENDER_PICT_TYPE_DIRECT &&
		    formats[i].depth == 24)
			wm->format_rgb = formats[i];
		if (formats[i].type == XCB_RENDER_PICT_TYPE_DIRECT &&
		    formats[i].depth == 32 &&
		    formats[i].direct.alpha_mask == 0xff &&
		    formats[i].direct.alpha_shift == 24)
			wm->format_rgba = formats[i];
	}

	free(formats_reply);
}

static void
weston_wm_create_wm_window(struct weston_wm *wm)
{
	static const char name[] = "Weston WM";

	wm->wm_window = xcb_generate_id(wm->conn);
	xcb_create_window(wm->conn,
			  XCB_COPY_FROM_PARENT,
			  wm->wm_window,
			  wm->screen->root,
			  0, 0,
			  10, 10,
			  0,
			  XCB_WINDOW_CLASS_INPUT_OUTPUT,
			  wm->screen->root_visual,
			  0, NULL);

	xcb_change_property(wm->conn,
			    XCB_PROP_MODE_REPLACE,
			    wm->wm_window,
			    wm->atom.net_supporting_wm_check,
			    XCB_ATOM_WINDOW,
			    32, /* format */
			    1, &wm->wm_window);

	xcb_change_property(wm->conn,
			    XCB_PROP_MODE_REPLACE,
			    wm->wm_window,
			    wm->atom.net_wm_name,
			    wm->atom.utf8_string,
			    8, /* format */
			    strlen(name), name);

	xcb_change_property(wm->conn,
			    XCB_PROP_MODE_REPLACE,
			    wm->screen->root,
			    wm->atom.net_supporting_wm_check,
			    XCB_ATOM_WINDOW,
			    32, /* format */
			    1, &wm->wm_window);

	/* Claim the WM_S0 selection even though we don't support
	 * the --replace functionality. */
	xcb_set_selection_owner(wm->conn,
				wm->wm_window,
				wm->atom.wm_s0,
				XCB_TIME_CURRENT_TIME);

	xcb_set_selection_owner(wm->conn,
				wm->wm_window,
				wm->atom.net_wm_cm_s0,
				XCB_TIME_CURRENT_TIME);
}

struct weston_wm *
weston_wm_create(struct weston_xserver *wxs, int fd)
{
	struct weston_wm *wm;
	struct wl_event_loop *loop;
	xcb_screen_iterator_t s;
	uint32_t values[1];
	xcb_atom_t supported[6];

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

	wm->server = wxs;
	wm->window_hash = hash_table_create();
	if (wm->window_hash == NULL) {
		free(wm);
		return NULL;
	}

	/* xcb_connect_to_fd takes ownership of the fd. */
	wm->conn = xcb_connect_to_fd(fd, NULL);
	if (xcb_connection_has_error(wm->conn)) {
		weston_log("xcb_connect_to_fd failed\n");
		close(fd);
		hash_table_destroy(wm->window_hash);
		free(wm);
		return NULL;
	}

	s = xcb_setup_roots_iterator(xcb_get_setup(wm->conn));
	wm->screen = s.data;

	loop = wl_display_get_event_loop(wxs->wl_display);
	wm->source =
		wl_event_loop_add_fd(loop, fd,
				     WL_EVENT_READABLE,
				     weston_wm_handle_event, wm);
	wl_event_source_check(wm->source);

	weston_wm_get_resources(wm);
	weston_wm_get_visual_and_colormap(wm);

	values[0] =
		XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY |
		XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT |
		XCB_EVENT_MASK_PROPERTY_CHANGE;
	xcb_change_window_attributes(wm->conn, wm->screen->root,
				     XCB_CW_EVENT_MASK, values);

	xcb_composite_redirect_subwindows(wm->conn, wm->screen->root,
					  XCB_COMPOSITE_REDIRECT_MANUAL);

	wm->theme = theme_create();

	supported[0] = wm->atom.net_wm_moveresize;
	supported[1] = wm->atom.net_wm_state;
	supported[2] = wm->atom.net_wm_state_fullscreen;
	supported[3] = wm->atom.net_wm_state_maximized_vert;
	supported[4] = wm->atom.net_wm_state_maximized_horz;
	supported[5] = wm->atom.net_active_window;
	xcb_change_property(wm->conn,
			    XCB_PROP_MODE_REPLACE,
			    wm->screen->root,
			    wm->atom.net_supported,
			    XCB_ATOM_ATOM,
			    32, /* format */
			    ARRAY_LENGTH(supported), supported);

	weston_wm_set_net_active_window(wm, XCB_WINDOW_NONE);

	weston_wm_selection_init(wm);

	weston_wm_dnd_init(wm);

	xcb_flush(wm->conn);

	wm->create_surface_listener.notify = weston_wm_create_surface;
	wl_signal_add(&wxs->compositor->create_surface_signal,
		      &wm->create_surface_listener);
	wm->activate_listener.notify = weston_wm_window_activate;
	wl_signal_add(&wxs->compositor->activate_signal,
		      &wm->activate_listener);
	wm->kill_listener.notify = weston_wm_kill_client;
	wl_signal_add(&wxs->compositor->kill_signal,
		      &wm->kill_listener);
	wl_list_init(&wm->unpaired_window_list);

	weston_wm_create_cursors(wm);
	weston_wm_window_set_cursor(wm, wm->screen->root, XWM_CURSOR_LEFT_PTR);

	/* Create wm window and take WM_S0 selection last, which
	 * signals to Xwayland that we're done with setup. */
	weston_wm_create_wm_window(wm);

	weston_log("created wm, root %d\n", wm->screen->root);

	return wm;
}

void
weston_wm_destroy(struct weston_wm *wm)
{
	/* FIXME: Free windows in hash. */
	hash_table_destroy(wm->window_hash);
	weston_wm_destroy_cursors(wm);
	xcb_disconnect(wm->conn);
	wl_event_source_remove(wm->source);
	wl_list_remove(&wm->selection_listener.link);
	wl_list_remove(&wm->activate_listener.link);
	wl_list_remove(&wm->kill_listener.link);
	wl_list_remove(&wm->create_surface_listener.link);

	free(wm);
}

static struct weston_wm_window *
get_wm_window(struct weston_surface *surface)
{
	struct wl_listener *listener;

	listener = wl_signal_get(&surface->destroy_signal, surface_destroy);
	if (listener)
		return container_of(listener, struct weston_wm_window,
				    surface_destroy_listener);

	return NULL;
}

static bool
is_wm_window(struct weston_surface *surface)
{
	return get_wm_window(surface) != NULL;
}

static void
weston_wm_window_configure(void *data)
{
	struct weston_wm_window *window = data;
	struct weston_wm *wm = window->wm;
	uint32_t values[4];
	int x, y, width, height;

	weston_wm_window_get_child_position(window, &x, &y);
	values[0] = x;
	values[1] = y;
	values[2] = window->width;
	values[3] = window->height;
	xcb_configure_window(wm->conn,
			     window->id,
			     XCB_CONFIG_WINDOW_X |
			     XCB_CONFIG_WINDOW_Y |
			     XCB_CONFIG_WINDOW_WIDTH |
			     XCB_CONFIG_WINDOW_HEIGHT,
			     values);

	weston_wm_window_get_frame_size(window, &width, &height);
	values[0] = width;
	values[1] = height;
	xcb_configure_window(wm->conn,
			     window->frame_id,
			     XCB_CONFIG_WINDOW_WIDTH |
			     XCB_CONFIG_WINDOW_HEIGHT,
			     values);

	window->configure_source = NULL;

	weston_wm_window_schedule_repaint(window);
}

static void
send_configure(struct weston_surface *surface, int32_t width, int32_t height)
{
	struct weston_wm_window *window = get_wm_window(surface);
	struct weston_wm *wm = window->wm;
	struct theme *t = window->wm->theme;
	int new_width, new_height;
	int vborder, hborder;

	if (window->decorate && !window->fullscreen) {
		hborder = 2 * t->width;
		vborder = t->titlebar_height + t->width;
	} else {
		hborder = 0;
		vborder = 0;
	}

	if (width > hborder)
		new_width = width - hborder;
	else
		new_width = 1;

	if (height > vborder)
		new_height = height - vborder;
	else
		new_height = 1;

	if (window->width == new_width && window->height == new_height)
		return;

	window->width = new_width;
	window->height = new_height;

	if (window->frame)
		frame_resize_inside(window->frame, window->width, window->height);

	if (window->configure_source)
		return;

	window->configure_source =
		wl_event_loop_add_idle(wm->server->loop,
				       weston_wm_window_configure, window);
}

static void
send_position(struct weston_surface *surface, int32_t x, int32_t y)
{
	struct weston_wm_window *window = get_wm_window(surface);
	struct weston_wm *wm;
	uint32_t mask, values[2];

	if (!window || !window->wm)
		return;

	wm = window->wm;
	/* We use pos_dirty to tell whether a configure message is in flight.
	 * This is needed in case we send two configure events in a very
	 * short time, since window->x/y is set in after a roundtrip, hence
	 * we cannot just check if the current x and y are different. */
	if (window->x != x || window->y != y || window->pos_dirty) {
		window->pos_dirty = true;
		values[0] = x;
		values[1] = y;
		mask = XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y;

		xcb_configure_window(wm->conn, window->frame_id, mask, values);
		xcb_flush(wm->conn);
	}
}

static const struct weston_xwayland_client_interface shell_client = {
	send_configure,
};

static int
legacy_fullscreen(struct weston_wm *wm,
		  struct weston_wm_window *window,
		  struct weston_output **output_ret)
{
	struct weston_compositor *compositor = wm->server->compositor;
	struct weston_output *output;
	uint32_t minmax = PMinSize | PMaxSize;
	int matching_size;

	/* Heuristics for detecting legacy fullscreen windows... */

	wl_list_for_each(output, &compositor->output_list, link) {
		if (output->x == window->x &&
		    output->y == window->y &&
		    output->width == window->width &&
		    output->height == window->height &&
		    window->override_redirect) {
			*output_ret = output;
			return 1;
		}

		matching_size = 0;
		if ((window->size_hints.flags & (USSize |PSize)) &&
		    window->size_hints.width == output->width &&
		    window->size_hints.height == output->height)
			matching_size = 1;
		if ((window->size_hints.flags & minmax) == minmax &&
		    window->size_hints.min_width == output->width &&
		    window->size_hints.min_height == output->height &&
		    window->size_hints.max_width == output->width &&
		    window->size_hints.max_height == output->height)
			matching_size = 1;

		if (matching_size && !window->decorate &&
		    (window->size_hints.flags & (USPosition | PPosition)) &&
		    window->size_hints.x == output->x &&
		    window->size_hints.y == output->y) {
			*output_ret = output;
			return 1;
		}
	}

	return 0;
}

static bool
weston_wm_window_is_positioned(struct weston_wm_window *window)
{
	if (window->map_request_x == INT_MIN ||
	    window->map_request_y == INT_MIN)
		weston_log("XWM warning: win %d did not see map request\n",
			   window->id);

	return window->map_request_x != 0 || window->map_request_y != 0;
}

static bool
weston_wm_window_type_inactive(struct weston_wm_window *window)
{
	struct weston_wm *wm = window->wm;

	return window->type == wm->atom.net_wm_window_type_tooltip ||
	       window->type == wm->atom.net_wm_window_type_dropdown ||
	       window->type == wm->atom.net_wm_window_type_dnd ||
	       window->type == wm->atom.net_wm_window_type_combo ||
	       window->type == wm->atom.net_wm_window_type_popup ||
	       window->type == wm->atom.net_wm_window_type_utility;
}

static void
xserver_map_shell_surface(struct weston_wm_window *window,
			  struct weston_surface *surface)
{
	struct weston_wm *wm = window->wm;
	struct weston_desktop_xwayland *xwayland =
		wm->server->compositor->xwayland;
	const struct weston_desktop_xwayland_interface *xwayland_interface =
		wm->server->compositor->xwayland_interface;
	struct weston_wm_window *parent;

	/* This should be necessary only for override-redirected windows,
	 * because otherwise MapRequest handler would have already updated
	 * the properties. However, if X11 clients set properties after
	 * sending MapWindow, here we can still process them. The decorations
	 * have already been drawn once with the old property values, so if the
	 * app changes something affecting decor after MapWindow, we glitch.
	 * We only hit xserver_map_shell_surface() once per MapWindow and
	 * wl_surface, so better ensure we get the window type right.
	 */
	weston_wm_window_read_properties(window);

	/* A weston_wm_window may have many different surfaces assigned
	 * throughout its life, so we must make sure to remove the listener
	 * from the old surface signal list. */
	if (window->surface)
		wl_list_remove(&window->surface_destroy_listener.link);

	window->surface = surface;
	window->surface_destroy_listener.notify = surface_destroy;
	wl_signal_add(&window->surface->destroy_signal,
		      &window->surface_destroy_listener);

	if (!xwayland_interface)
		return;

	if (window->surface->committed) {
		weston_log("warning, unexpected in %s: "
			   "surface's configure hook is already set.\n",
			   __func__);
		return;
	}

	window->shsurf =
		xwayland_interface->create_surface(xwayland,
						   window->surface,
						   &shell_client);

	wm_log("XWM: map shell surface, win %d, weston_surface %p, xwayland surface %p\n",
	       window->id, window->surface, window->shsurf);

	if (window->name)
		xwayland_interface->set_title(window->shsurf, window->name);
	if (window->pid > 0)
		xwayland_interface->set_pid(window->shsurf, window->pid);

	if (window->fullscreen) {
		window->saved_width = window->width;
		window->saved_height = window->height;
		xwayland_interface->set_fullscreen(window->shsurf,
						   window->legacy_fullscreen_output.output);
		return;
	} else if (window->override_redirect) {
		xwayland_interface->set_xwayland(window->shsurf,
						 window->x, window->y);
	} else if (window->transient_for && window->transient_for->surface) {
		parent = window->transient_for;
		if (weston_wm_window_type_inactive(window)) {
			xwayland_interface->set_transient(window->shsurf,
							  parent->surface,
							  window->x - parent->x,
							  window->y - parent->y);
		} else {
			xwayland_interface->set_toplevel(window->shsurf);
			xwayland_interface->set_parent(window->shsurf,
						       parent->surface);
		}
	} else if (weston_wm_window_is_maximized(window)) {
		xwayland_interface->set_maximized(window->shsurf);
	} else {
		if (weston_wm_window_type_inactive(window)) {
			xwayland_interface->set_xwayland(window->shsurf,
							 window->x,
							 window->y);
		} else if (weston_wm_window_is_positioned(window)) {
			xwayland_interface->set_toplevel_with_position(window->shsurf,
								       window->map_request_x,
								       window->map_request_y);
		} else {
			xwayland_interface->set_toplevel(window->shsurf);
		}
	}

	if (window->frame_id == XCB_WINDOW_NONE) {
		weston_wm_window_set_pending_state_OR(window);
	} else {
		weston_wm_window_set_pending_state(window);
		weston_wm_window_set_allow_commits(window, true);
		xcb_flush(wm->conn);
	}
}

const struct weston_xwayland_surface_api surface_api = {
	is_wm_window,
	send_position,
};
