/*
 * Copyright © 2008-2011 Kristian Høgsberg
 * Copyright © 2010-2011 Intel Corporation
 * Copyright © 2013 Vasily Khoruzhick <anarsoul@gmail.com>
 *
 * 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 <assert.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <sys/time.h>
#include <sys/shm.h>
#include <linux/input.h>

#include <xcb/xcb.h>
#include <xcb/shm.h>
#ifdef HAVE_XCB_XKB
#include <xcb/xkb.h>
#endif

#include <X11/Xlib.h>
#include <X11/Xlib-xcb.h>

#include <xkbcommon/xkbcommon.h>

#include "compositor.h"
#include "compositor-x11.h"
#include "shared/config-parser.h"
#include "shared/helpers.h"
#include "shared/image-loader.h"
#include "shared/timespec-util.h"
#include "gl-renderer.h"
#include "weston-egl-ext.h"
#include "pixman-renderer.h"
#include "presentation-time-server-protocol.h"
#include "linux-dmabuf.h"
#include "windowed-output-api.h"

#define DEFAULT_AXIS_STEP_DISTANCE 10

#define WINDOW_MIN_WIDTH 128
#define WINDOW_MIN_HEIGHT 128

#define WINDOW_MAX_WIDTH 8192
#define WINDOW_MAX_HEIGHT 8192

struct x11_backend {
	struct weston_backend	 base;
	struct weston_compositor *compositor;

	Display			*dpy;
	xcb_connection_t	*conn;
	xcb_screen_t		*screen;
	xcb_cursor_t		 null_cursor;
	struct wl_array		 keys;
	struct wl_event_source	*xcb_source;
	struct xkb_keymap	*xkb_keymap;
	unsigned int		 has_xkb;
	uint8_t			 xkb_event_base;
	int			 fullscreen;
	int			 no_input;
	int			 use_pixman;

	int			 has_net_wm_state_fullscreen;

	/* We could map multi-pointer X to multiple wayland seats, but
	 * for now we only support core X input. */
	struct weston_seat		 core_seat;
	double				 prev_x;
	double				 prev_y;

	struct {
		xcb_atom_t		 wm_protocols;
		xcb_atom_t		 wm_normal_hints;
		xcb_atom_t		 wm_size_hints;
		xcb_atom_t		 wm_delete_window;
		xcb_atom_t		 wm_class;
		xcb_atom_t		 net_wm_name;
		xcb_atom_t		 net_supporting_wm_check;
		xcb_atom_t		 net_supported;
		xcb_atom_t		 net_wm_icon;
		xcb_atom_t		 net_wm_state;
		xcb_atom_t		 net_wm_state_fullscreen;
		xcb_atom_t		 string;
		xcb_atom_t		 utf8_string;
		xcb_atom_t		 cardinal;
		xcb_atom_t		 xkb_names;
	} atom;
};

struct x11_output {
	struct weston_output	base;

	xcb_window_t		window;
	struct weston_mode	mode;
	struct weston_mode	native;
	struct wl_event_source *finish_frame_timer;

	xcb_gc_t		gc;
	xcb_shm_seg_t		segment;
	pixman_image_t	       *hw_surface;
	int			shm_id;
	void		       *buf;
	uint8_t			depth;
	int32_t                 scale;
	bool			resize_pending;
	bool			window_resized;
};

struct window_delete_data {
	struct x11_backend	*backend;
	xcb_window_t		window;
};

struct gl_renderer_interface *gl_renderer;

static inline struct x11_output *
to_x11_output(struct weston_output *base)
{
	return container_of(base, struct x11_output, base);
}

static inline struct x11_backend *
to_x11_backend(struct weston_compositor *base)
{
	return container_of(base->backend, struct x11_backend, base);
}

static xcb_screen_t *
x11_compositor_get_default_screen(struct x11_backend *b)
{
	xcb_screen_iterator_t iter;
	int i, screen_nbr = XDefaultScreen(b->dpy);

	iter = xcb_setup_roots_iterator(xcb_get_setup(b->conn));
	for (i = 0; iter.rem; xcb_screen_next(&iter), i++)
		if (i == screen_nbr)
			return iter.data;

	return xcb_setup_roots_iterator(xcb_get_setup(b->conn)).data;
}

static struct xkb_keymap *
x11_backend_get_keymap(struct x11_backend *b)
{
	xcb_get_property_cookie_t cookie;
	xcb_get_property_reply_t *reply;
	struct xkb_rule_names names;
	struct xkb_keymap *ret;
	const char *value_all, *value_part;
	int length_all, length_part;

	memset(&names, 0, sizeof(names));

	cookie = xcb_get_property(b->conn, 0, b->screen->root,
				  b->atom.xkb_names, b->atom.string, 0, 1024);
	reply = xcb_get_property_reply(b->conn, cookie, NULL);
	if (reply == NULL)
		return NULL;

	value_all = xcb_get_property_value(reply);
	length_all = xcb_get_property_value_length(reply);
	value_part = value_all;

#define copy_prop_value(to) \
	length_part = strlen(value_part); \
	if (value_part + length_part < (value_all + length_all) && \
	    length_part > 0) \
		names.to = value_part; \
	value_part += length_part + 1;

	copy_prop_value(rules);
	copy_prop_value(model);
	copy_prop_value(layout);
	copy_prop_value(variant);
	copy_prop_value(options);
#undef copy_prop_value

	ret = xkb_keymap_new_from_names(b->compositor->xkb_context, &names, 0);

	free(reply);
	return ret;
}

static uint32_t
get_xkb_mod_mask(struct x11_backend *b, uint32_t in)
{
	struct weston_keyboard *keyboard =
		weston_seat_get_keyboard(&b->core_seat);
	struct weston_xkb_info *info = keyboard->xkb_info;
	uint32_t ret = 0;

	if ((in & ShiftMask) && info->shift_mod != XKB_MOD_INVALID)
		ret |= (1 << info->shift_mod);
	if ((in & LockMask) && info->caps_mod != XKB_MOD_INVALID)
		ret |= (1 << info->caps_mod);
	if ((in & ControlMask) && info->ctrl_mod != XKB_MOD_INVALID)
		ret |= (1 << info->ctrl_mod);
	if ((in & Mod1Mask) && info->alt_mod != XKB_MOD_INVALID)
		ret |= (1 << info->alt_mod);
	if ((in & Mod2Mask) && info->mod2_mod != XKB_MOD_INVALID)
		ret |= (1 << info->mod2_mod);
	if ((in & Mod3Mask) && info->mod3_mod != XKB_MOD_INVALID)
		ret |= (1 << info->mod3_mod);
	if ((in & Mod4Mask) && info->super_mod != XKB_MOD_INVALID)
		ret |= (1 << info->super_mod);
	if ((in & Mod5Mask) && info->mod5_mod != XKB_MOD_INVALID)
		ret |= (1 << info->mod5_mod);

	return ret;
}

static void
x11_backend_setup_xkb(struct x11_backend *b)
{
#ifndef HAVE_XCB_XKB
	weston_log("XCB-XKB not available during build\n");
	b->has_xkb = 0;
	b->xkb_event_base = 0;
	return;
#else
	struct weston_keyboard *keyboard;
	const xcb_query_extension_reply_t *ext;
	xcb_generic_error_t *error;
	xcb_void_cookie_t select;
	xcb_xkb_use_extension_cookie_t use_ext;
	xcb_xkb_use_extension_reply_t *use_ext_reply;
	xcb_xkb_per_client_flags_cookie_t pcf;
	xcb_xkb_per_client_flags_reply_t *pcf_reply;
	xcb_xkb_get_state_cookie_t state;
	xcb_xkb_get_state_reply_t *state_reply;
	uint32_t values[1] = { XCB_EVENT_MASK_PROPERTY_CHANGE };

	b->has_xkb = 0;
	b->xkb_event_base = 0;

	ext = xcb_get_extension_data(b->conn, &xcb_xkb_id);
	if (!ext) {
		weston_log("XKB extension not available on host X11 server\n");
		return;
	}
	b->xkb_event_base = ext->first_event;

	select = xcb_xkb_select_events_checked(b->conn,
					       XCB_XKB_ID_USE_CORE_KBD,
					       XCB_XKB_EVENT_TYPE_STATE_NOTIFY,
					       0,
					       XCB_XKB_EVENT_TYPE_STATE_NOTIFY,
					       0,
					       0,
					       NULL);
	error = xcb_request_check(b->conn, select);
	if (error) {
		weston_log("error: failed to select for XKB state events\n");
		free(error);
		return;
	}

	use_ext = xcb_xkb_use_extension(b->conn,
					XCB_XKB_MAJOR_VERSION,
					XCB_XKB_MINOR_VERSION);
	use_ext_reply = xcb_xkb_use_extension_reply(b->conn, use_ext, NULL);
	if (!use_ext_reply) {
		weston_log("couldn't start using XKB extension\n");
		return;
	}

	if (!use_ext_reply->supported) {
		weston_log("XKB extension version on the server is too old "
			   "(want %d.%d, has %d.%d)\n",
			   XCB_XKB_MAJOR_VERSION, XCB_XKB_MINOR_VERSION,
			   use_ext_reply->serverMajor, use_ext_reply->serverMinor);
		free(use_ext_reply);
		return;
	}
	free(use_ext_reply);

	pcf = xcb_xkb_per_client_flags(b->conn,
				       XCB_XKB_ID_USE_CORE_KBD,
				       XCB_XKB_PER_CLIENT_FLAG_DETECTABLE_AUTO_REPEAT,
				       XCB_XKB_PER_CLIENT_FLAG_DETECTABLE_AUTO_REPEAT,
				       0,
				       0,
				       0);
	pcf_reply = xcb_xkb_per_client_flags_reply(b->conn, pcf, NULL);
	if (!pcf_reply ||
	    !(pcf_reply->value & XCB_XKB_PER_CLIENT_FLAG_DETECTABLE_AUTO_REPEAT)) {
		weston_log("failed to set XKB per-client flags, not using "
			   "detectable repeat\n");
		free(pcf_reply);
		return;
	}
	free(pcf_reply);

	state = xcb_xkb_get_state(b->conn, XCB_XKB_ID_USE_CORE_KBD);
	state_reply = xcb_xkb_get_state_reply(b->conn, state, NULL);
	if (!state_reply) {
		weston_log("failed to get initial XKB state\n");
		return;
	}

	keyboard = weston_seat_get_keyboard(&b->core_seat);
	xkb_state_update_mask(keyboard->xkb_state.state,
			      get_xkb_mod_mask(b, state_reply->baseMods),
			      get_xkb_mod_mask(b, state_reply->latchedMods),
			      get_xkb_mod_mask(b, state_reply->lockedMods),
			      0,
			      0,
			      state_reply->group);

	free(state_reply);

	xcb_change_window_attributes(b->conn, b->screen->root,
				     XCB_CW_EVENT_MASK, values);

	b->has_xkb = 1;
#endif
}

#ifdef HAVE_XCB_XKB
static void
update_xkb_keymap(struct x11_backend *b)
{
	struct xkb_keymap *keymap;

	keymap = x11_backend_get_keymap(b);
	if (!keymap) {
		weston_log("failed to get XKB keymap\n");
		return;
	}
	weston_seat_update_keymap(&b->core_seat, keymap);
	xkb_keymap_unref(keymap);
}
#endif

static int
x11_input_create(struct x11_backend *b, int no_input)
{
	struct xkb_keymap *keymap;

	weston_seat_init(&b->core_seat, b->compositor, "default");

	if (no_input)
		return 0;

	weston_seat_init_pointer(&b->core_seat);

	keymap = x11_backend_get_keymap(b);
	if (weston_seat_init_keyboard(&b->core_seat, keymap) < 0)
		return -1;
	xkb_keymap_unref(keymap);

	x11_backend_setup_xkb(b);

	return 0;
}

static void
x11_input_destroy(struct x11_backend *b)
{
	weston_seat_release(&b->core_seat);
}

static void
x11_output_start_repaint_loop(struct weston_output *output)
{
	struct timespec ts;

	weston_compositor_read_presentation_clock(output->compositor, &ts);
	weston_output_finish_frame(output, &ts, WP_PRESENTATION_FEEDBACK_INVALID);
}

static int
x11_output_repaint_gl(struct weston_output *output_base,
		      pixman_region32_t *damage,
		      void *repaint_data)
{
	struct x11_output *output = to_x11_output(output_base);
	struct weston_compositor *ec = output->base.compositor;

	ec->renderer->repaint_output(output_base, damage);

	pixman_region32_subtract(&ec->primary_plane.damage,
				 &ec->primary_plane.damage, damage);

	wl_event_source_timer_update(output->finish_frame_timer, 10);
	return 0;
}

static void
set_clip_for_output(struct weston_output *output_base, pixman_region32_t *region)
{
	struct x11_output *output = to_x11_output(output_base);
	struct weston_compositor *ec = output->base.compositor;
	struct x11_backend *b = to_x11_backend(ec);
	pixman_region32_t transformed_region;
	pixman_box32_t *rects;
	xcb_rectangle_t *output_rects;
	xcb_void_cookie_t cookie;
	int nrects, i;
	xcb_generic_error_t *err;

	pixman_region32_init(&transformed_region);
	pixman_region32_copy(&transformed_region, region);
	pixman_region32_translate(&transformed_region,
				  -output_base->x, -output_base->y);
	weston_transformed_region(output_base->width, output_base->height,
				  output_base->transform,
				  output_base->current_scale,
				  &transformed_region, &transformed_region);

	rects = pixman_region32_rectangles(&transformed_region, &nrects);
	output_rects = calloc(nrects, sizeof(xcb_rectangle_t));

	if (output_rects == NULL) {
		pixman_region32_fini(&transformed_region);
		return;
	}

	for (i = 0; i < nrects; i++) {
		output_rects[i].x = rects[i].x1;
		output_rects[i].y = rects[i].y1;
		output_rects[i].width = rects[i].x2 - rects[i].x1;
		output_rects[i].height = rects[i].y2 - rects[i].y1;
	}

	pixman_region32_fini(&transformed_region);

	cookie = xcb_set_clip_rectangles_checked(b->conn, XCB_CLIP_ORDERING_UNSORTED,
					output->gc,
					0, 0, nrects,
					output_rects);
	err = xcb_request_check(b->conn, cookie);
	if (err != NULL) {
		weston_log("Failed to set clip rects, err: %d\n", err->error_code);
		free(err);
	}
	free(output_rects);
}


static int
x11_output_repaint_shm(struct weston_output *output_base,
		       pixman_region32_t *damage,
		       void *repaint_data)
{
	struct x11_output *output = to_x11_output(output_base);
	struct weston_compositor *ec = output->base.compositor;
	struct x11_backend *b = to_x11_backend(ec);
	xcb_void_cookie_t cookie;
	xcb_generic_error_t *err;

	pixman_renderer_output_set_buffer(output_base, output->hw_surface);
	ec->renderer->repaint_output(output_base, damage);

	pixman_region32_subtract(&ec->primary_plane.damage,
				 &ec->primary_plane.damage, damage);
	set_clip_for_output(output_base, damage);
	cookie = xcb_shm_put_image_checked(b->conn, output->window, output->gc,
					pixman_image_get_width(output->hw_surface),
					pixman_image_get_height(output->hw_surface),
					0, 0,
					pixman_image_get_width(output->hw_surface),
					pixman_image_get_height(output->hw_surface),
					0, 0, output->depth, XCB_IMAGE_FORMAT_Z_PIXMAP,
					0, output->segment, 0);
	err = xcb_request_check(b->conn, cookie);
	if (err != NULL) {
		weston_log("Failed to put shm image, err: %d\n", err->error_code);
		free(err);
	}

	wl_event_source_timer_update(output->finish_frame_timer, 10);
	return 0;
}

static int
finish_frame_handler(void *data)
{
	struct x11_output *output = data;
	struct timespec ts;

	weston_compositor_read_presentation_clock(output->base.compositor, &ts);
	weston_output_finish_frame(&output->base, &ts, 0);

	return 1;
}

static void
x11_output_deinit_shm(struct x11_backend *b, struct x11_output *output)
{
	xcb_void_cookie_t cookie;
	xcb_generic_error_t *err;
	xcb_free_gc(b->conn, output->gc);

	pixman_image_unref(output->hw_surface);
	output->hw_surface = NULL;
	cookie = xcb_shm_detach_checked(b->conn, output->segment);
	err = xcb_request_check(b->conn, cookie);
	if (err) {
		weston_log("xcb_shm_detach failed, error %d\n", err->error_code);
		free(err);
	}
	shmdt(output->buf);
}

static void
x11_output_set_wm_protocols(struct x11_backend *b,
			    struct x11_output *output)
{
	xcb_atom_t list[1];

	list[0] = b->atom.wm_delete_window;
	xcb_change_property (b->conn,
			     XCB_PROP_MODE_REPLACE,
			     output->window,
			     b->atom.wm_protocols,
			     XCB_ATOM_ATOM,
			     32,
			     ARRAY_LENGTH(list),
			     list);
}

struct wm_normal_hints {
    	uint32_t flags;
	uint32_t pad[4];
	int32_t min_width, min_height;
	int32_t max_width, max_height;
    	int32_t width_inc, height_inc;
    	int32_t min_aspect_x, min_aspect_y;
    	int32_t max_aspect_x, max_aspect_y;
	int32_t base_width, base_height;
	int32_t win_gravity;
};

#define WM_NORMAL_HINTS_MIN_SIZE	16
#define WM_NORMAL_HINTS_MAX_SIZE	32

static void
x11_output_set_icon(struct x11_backend *b,
		    struct x11_output *output, const char *filename)
{
	uint32_t *icon;
	int32_t width, height;
	pixman_image_t *image;

	image = load_image(filename);
	if (!image)
		return;
	width = pixman_image_get_width(image);
	height = pixman_image_get_height(image);
	icon = malloc(width * height * 4 + 8);
	if (!icon) {
		pixman_image_unref(image);
		return;
	}

	icon[0] = width;
	icon[1] = height;
	memcpy(icon + 2, pixman_image_get_data(image), width * height * 4);
	xcb_change_property(b->conn, XCB_PROP_MODE_REPLACE, output->window,
			    b->atom.net_wm_icon, b->atom.cardinal, 32,
			    width * height + 2, icon);
	free(icon);
	pixman_image_unref(image);
}

static void
x11_output_wait_for_map(struct x11_backend *b, struct x11_output *output)
{
	xcb_map_notify_event_t *map_notify;
	xcb_configure_notify_event_t *configure_notify;
	xcb_generic_event_t *event;
	int mapped = 0, configured = 0;
	uint8_t response_type;

	/* This isn't the nicest way to do this.  Ideally, we could
	 * just go back to the main loop and once we get the configure
	 * notify, we add the output to the compositor.  While we do
	 * support output hotplug, we can't start up with no outputs.
	 * We could add the output and then resize once we get the
	 * configure notify, but we don't want to start up and
	 * immediately resize the output.
	 *
	 * Also, some window managers don't give us our final
	 * fullscreen size before map_notify, so if we don't get a
	 * configure_notify before map_notify, we just wait for the
	 * first one and hope that's our size. */

	xcb_flush(b->conn);

	while (!mapped || !configured) {
		event = xcb_wait_for_event(b->conn);
		response_type = event->response_type & ~0x80;

		switch (response_type) {
		case XCB_MAP_NOTIFY:
			map_notify = (xcb_map_notify_event_t *) event;
			if (map_notify->window == output->window)
				mapped = 1;
			break;

		case XCB_CONFIGURE_NOTIFY:
			configure_notify =
				(xcb_configure_notify_event_t *) event;


			if (configure_notify->width % output->scale != 0 ||
			    configure_notify->height % output->scale != 0)
				weston_log("Resolution is not a multiple of screen size, rounding\n");
			output->mode.width = configure_notify->width;
			output->mode.height = configure_notify->height;
			configured = 1;
			break;
		}
	}
}

static xcb_visualtype_t *
find_visual_by_id(xcb_screen_t *screen,
		   xcb_visualid_t id)
{
	xcb_depth_iterator_t i;
	xcb_visualtype_iterator_t j;
	for (i = xcb_screen_allowed_depths_iterator(screen);
	     i.rem;
	     xcb_depth_next(&i)) {
		for (j = xcb_depth_visuals_iterator(i.data);
		     j.rem;
		     xcb_visualtype_next(&j)) {
			if (j.data->visual_id == id)
				return j.data;
		}
	}
	return 0;
}

static uint8_t
get_depth_of_visual(xcb_screen_t *screen,
		   xcb_visualid_t id)
{
	xcb_depth_iterator_t i;
	xcb_visualtype_iterator_t j;
	for (i = xcb_screen_allowed_depths_iterator(screen);
	     i.rem;
	     xcb_depth_next(&i)) {
		for (j = xcb_depth_visuals_iterator(i.data);
		     j.rem;
		     xcb_visualtype_next(&j)) {
			if (j.data->visual_id == id)
				return i.data->depth;
		}
	}
	return 0;
}

static int
x11_output_init_shm(struct x11_backend *b, struct x11_output *output,
	int width, int height)
{
	xcb_visualtype_t *visual_type;
	xcb_screen_t *screen;
	xcb_format_iterator_t fmt;
	xcb_void_cookie_t cookie;
	xcb_generic_error_t *err;
	const xcb_query_extension_reply_t *ext;
	int bitsperpixel = 0;
	pixman_format_code_t pixman_format;

	/* Check if SHM is available */
	ext = xcb_get_extension_data(b->conn, &xcb_shm_id);
	if (ext == NULL || !ext->present) {
		/* SHM is missing */
		weston_log("SHM extension is not available\n");
		errno = ENOENT;
		return -1;
	}

	screen = x11_compositor_get_default_screen(b);
	visual_type = find_visual_by_id(screen, screen->root_visual);
	if (!visual_type) {
		weston_log("Failed to lookup visual for root window\n");
		errno = ENOENT;
		return -1;
	}
	weston_log("Found visual, bits per value: %d, red_mask: %.8x, green_mask: %.8x, blue_mask: %.8x\n",
		visual_type->bits_per_rgb_value,
		visual_type->red_mask,
		visual_type->green_mask,
		visual_type->blue_mask);
	output->depth = get_depth_of_visual(screen, screen->root_visual);
	weston_log("Visual depth is %d\n", output->depth);

	for (fmt = xcb_setup_pixmap_formats_iterator(xcb_get_setup(b->conn));
	     fmt.rem;
	     xcb_format_next(&fmt)) {
		if (fmt.data->depth == output->depth) {
			bitsperpixel = fmt.data->bits_per_pixel;
			break;
		}
	}
	weston_log("Found format for depth %d, bpp: %d\n",
		output->depth, bitsperpixel);

	if  (bitsperpixel == 32 &&
	     visual_type->red_mask == 0xff0000 &&
	     visual_type->green_mask == 0x00ff00 &&
	     visual_type->blue_mask == 0x0000ff) {
		weston_log("Will use x8r8g8b8 format for SHM surfaces\n");
		pixman_format = PIXMAN_x8r8g8b8;
	} else if (bitsperpixel == 16 &&
	           visual_type->red_mask == 0x00f800 &&
	           visual_type->green_mask == 0x0007e0 &&
	           visual_type->blue_mask == 0x00001f) {
		weston_log("Will use r5g6b5 format for SHM surfaces\n");
		pixman_format = PIXMAN_r5g6b5;
	} else {
		weston_log("Can't find appropriate format for SHM pixmap\n");
		errno = ENOTSUP;
		return -1;
	}


	/* Create SHM segment and attach it */
	output->shm_id = shmget(IPC_PRIVATE, width * height * (bitsperpixel / 8), IPC_CREAT | S_IRWXU);
	if (output->shm_id == -1) {
		weston_log("x11shm: failed to allocate SHM segment\n");
		return -1;
	}
	output->buf = shmat(output->shm_id, NULL, 0 /* read/write */);
	if (-1 == (long)output->buf) {
		weston_log("x11shm: failed to attach SHM segment\n");
		return -1;
	}
	output->segment = xcb_generate_id(b->conn);
	cookie = xcb_shm_attach_checked(b->conn, output->segment, output->shm_id, 1);
	err = xcb_request_check(b->conn, cookie);
	if (err) {
		weston_log("x11shm: xcb_shm_attach error %d, op code %d, resource id %d\n",
			   err->error_code, err->major_code, err->minor_code);
		free(err);
		return -1;
	}

	shmctl(output->shm_id, IPC_RMID, NULL);

	/* Now create pixman image */
	output->hw_surface = pixman_image_create_bits(pixman_format, width, height, output->buf,
		width * (bitsperpixel / 8));

	output->gc = xcb_generate_id(b->conn);
	xcb_create_gc(b->conn, output->gc, output->window, 0, NULL);

	return 0;
}

static int
x11_output_switch_mode(struct weston_output *base, struct weston_mode *mode)
{
	struct x11_backend *b;
	struct x11_output *output;
	static uint32_t values[2];
	int ret;

	if (base == NULL) {
		weston_log("output is NULL.\n");
		return -1;
	}

	if (mode == NULL) {
		weston_log("mode is NULL.\n");
		return -1;
	}

        b = to_x11_backend(base->compositor);
        output = to_x11_output(base);

        if (mode->width == output->mode.width &&
	    mode->height == output->mode.height)
	        return 0;

        if (mode->width < WINDOW_MIN_WIDTH || mode->width > WINDOW_MAX_WIDTH)
		return -1;

	if (mode->height < WINDOW_MIN_HEIGHT || mode->height > WINDOW_MAX_HEIGHT)
		return -1;

	/* xcb_configure_window will create an event, and we could end up
	   being called twice */
	output->resize_pending = true;

	/* window could've been resized by the user, so don't do it twice */
	if (!output->window_resized) {
		values[0] = mode->width;
		values[1] = mode->height;
		xcb_configure_window(b->conn, output->window, XCB_CONFIG_WINDOW_WIDTH |
				     XCB_CONFIG_WINDOW_HEIGHT, values);
	}

	output->mode.width = mode->width;
	output->mode.height = mode->height;

	if (b->use_pixman) {
		pixman_renderer_output_destroy(&output->base);
		x11_output_deinit_shm(b, output);

		if (x11_output_init_shm(b, output,
		                        output->base.current_mode->width,
		                        output->base.current_mode->height) < 0) {
			weston_log("Failed to initialize SHM for the X11 output\n");
			return -1;
		}

		if (pixman_renderer_output_create(&output->base) < 0) {
			weston_log("Failed to create pixman renderer for output\n");
			x11_output_deinit_shm(b, output);
			return -1;
		}
	} else {
		Window xid = (Window) output->window;

		gl_renderer->output_destroy(&output->base);

		ret = gl_renderer->output_window_create(&output->base,
						        (EGLNativeWindowType) output->window,
						        &xid,
						        gl_renderer->opaque_attribs,
						        NULL,
						        0);
		if (ret < 0)
			return -1;
	}

	output->resize_pending = false;
	output->window_resized = false;

	return 0;
}

static int
x11_output_disable(struct weston_output *base)
{
	struct x11_output *output = to_x11_output(base);
	struct x11_backend *backend = to_x11_backend(base->compositor);

	if (!output->base.enabled)
		return 0;

	wl_event_source_remove(output->finish_frame_timer);

	if (backend->use_pixman) {
		pixman_renderer_output_destroy(&output->base);
		x11_output_deinit_shm(backend, output);
	} else {
		gl_renderer->output_destroy(&output->base);
	}

	xcb_destroy_window(backend->conn, output->window);
	xcb_flush(backend->conn);

	return 0;
}

static void
x11_output_destroy(struct weston_output *base)
{
	struct x11_output *output = to_x11_output(base);

	x11_output_disable(&output->base);
	weston_output_release(&output->base);

	free(output);
}

static int
x11_output_enable(struct weston_output *base)
{
	struct x11_output *output = to_x11_output(base);
	struct x11_backend *b = to_x11_backend(base->compositor);

	static const char name[] = "Weston Compositor";
	static const char class[] = "weston-1\0Weston Compositor";
	char *title = NULL;
	xcb_screen_t *screen;
	struct wm_normal_hints normal_hints;
	struct wl_event_loop *loop;

	int ret;
	uint32_t mask = XCB_CW_EVENT_MASK | XCB_CW_CURSOR;
	xcb_atom_t atom_list[1];
	uint32_t values[2] = {
		XCB_EVENT_MASK_EXPOSURE |
		XCB_EVENT_MASK_STRUCTURE_NOTIFY,
		0
	};

	if (!b->no_input)
		values[0] |=
			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_KEYMAP_STATE |
			XCB_EVENT_MASK_FOCUS_CHANGE;

	values[1] = b->null_cursor;
	output->window = xcb_generate_id(b->conn);
	screen = x11_compositor_get_default_screen(b);
	xcb_create_window(b->conn,
			  XCB_COPY_FROM_PARENT,
			  output->window,
			  screen->root,
			  0, 0,
			  output->base.current_mode->width,
			  output->base.current_mode->height,
			  0,
			  XCB_WINDOW_CLASS_INPUT_OUTPUT,
			  screen->root_visual,
			  mask, values);

	if (b->fullscreen) {
		atom_list[0] = b->atom.net_wm_state_fullscreen;
		xcb_change_property(b->conn, XCB_PROP_MODE_REPLACE,
				    output->window,
				    b->atom.net_wm_state,
				    XCB_ATOM_ATOM, 32,
				    ARRAY_LENGTH(atom_list), atom_list);
	} else {
		memset(&normal_hints, 0, sizeof normal_hints);
		normal_hints.flags =
			WM_NORMAL_HINTS_MAX_SIZE | WM_NORMAL_HINTS_MIN_SIZE;
		normal_hints.min_width = WINDOW_MIN_WIDTH;
		normal_hints.min_height = WINDOW_MIN_HEIGHT;
		normal_hints.max_width = WINDOW_MAX_WIDTH;
		normal_hints.max_height = WINDOW_MAX_HEIGHT;
		xcb_change_property(b->conn, XCB_PROP_MODE_REPLACE, output->window,
				    b->atom.wm_normal_hints,
				    b->atom.wm_size_hints, 32,
				    sizeof normal_hints / 4,
				    (uint8_t *) &normal_hints);
	}

	/* Set window name.  Don't bother with non-EWMH WMs. */
	if (output->base.name) {
		if (asprintf(&title, "%s - %s", name, output->base.name) < 0)
			title = NULL;
	} else {
		title = strdup(name);
	}

	if (title) {
		xcb_change_property(b->conn, XCB_PROP_MODE_REPLACE, output->window,
				    b->atom.net_wm_name, b->atom.utf8_string, 8,
				    strlen(title), title);
		free(title);
	} else {
		goto err;
	}

	xcb_change_property(b->conn, XCB_PROP_MODE_REPLACE, output->window,
			    b->atom.wm_class, b->atom.string, 8,
			    sizeof class, class);

	x11_output_set_icon(b, output, DATADIR "/weston/wayland.png");

	x11_output_set_wm_protocols(b, output);

	xcb_map_window(b->conn, output->window);

	if (b->fullscreen)
		x11_output_wait_for_map(b, output);

	if (b->use_pixman) {
		if (x11_output_init_shm(b, output,
					output->base.current_mode->width,
					output->base.current_mode->height) < 0) {
			weston_log("Failed to initialize SHM for the X11 output\n");
			goto err;
		}
		if (pixman_renderer_output_create(&output->base) < 0) {
			weston_log("Failed to create pixman renderer for output\n");
			x11_output_deinit_shm(b, output);
			goto err;
		}

		output->base.repaint = x11_output_repaint_shm;
	} else {
		/* eglCreatePlatformWindowSurfaceEXT takes a Window*
		 * but eglCreateWindowSurface takes a Window. */
		Window xid = (Window) output->window;

		ret = gl_renderer->output_window_create(
					&output->base,
					(EGLNativeWindowType) output->window,
					&xid,
					gl_renderer->opaque_attribs,
					NULL,
					0);
		if (ret < 0)
			goto err;

		output->base.repaint = x11_output_repaint_gl;
	}

	output->base.start_repaint_loop = x11_output_start_repaint_loop;
	output->base.assign_planes = NULL;
	output->base.set_backlight = NULL;
	output->base.set_dpms = NULL;
	output->base.switch_mode = x11_output_switch_mode;

	loop = wl_display_get_event_loop(b->compositor->wl_display);
	output->finish_frame_timer =
		wl_event_loop_add_timer(loop, finish_frame_handler, output);

	weston_log("x11 output %dx%d, window id %d\n",
		   output->base.current_mode->width,
		   output->base.current_mode->height,
		   output->window);

	return 0;

err:
	xcb_destroy_window(b->conn, output->window);
	xcb_flush(b->conn);

	return -1;
}

static int
x11_output_set_size(struct weston_output *base, int width, int height)
{
	struct x11_output *output = to_x11_output(base);
	struct x11_backend *b = to_x11_backend(base->compositor);
	int output_width, output_height;

	/* We can only be called once. */
	assert(!output->base.current_mode);

	/* Make sure we have scale set. */
	assert(output->base.scale);

	if (width < WINDOW_MIN_WIDTH) {
		weston_log("Invalid width \"%d\" for output %s\n",
			   width, output->base.name);
		return -1;
	}

	if (height < WINDOW_MIN_HEIGHT) {
		weston_log("Invalid height \"%d\" for output %s\n",
			   height, output->base.name);
		return -1;
	}

	output_width = width * output->base.scale;
	output_height = height * output->base.scale;

	output->mode.flags =
		WL_OUTPUT_MODE_CURRENT | WL_OUTPUT_MODE_PREFERRED;

	output->mode.width = output_width;
	output->mode.height = output_height;
	output->mode.refresh = 60000;
	output->native = output->mode;
	output->scale = output->base.scale;
	wl_list_insert(&output->base.mode_list, &output->mode.link);

	output->base.current_mode = &output->mode;
	output->base.make = "weston-X11";
	output->base.model = "none";

	output->base.native_mode = &output->native;
	output->base.native_scale = output->base.scale;

	output->base.mm_width = width * b->screen->width_in_millimeters /
		b->screen->width_in_pixels;
	output->base.mm_height = height * b->screen->height_in_millimeters /
		b->screen->height_in_pixels;

	return 0;
}

static int
x11_output_create(struct weston_compositor *compositor,
		  const char *name)
{
	struct x11_output *output;

	/* name can't be NULL. */
	assert(name);

	output = zalloc(sizeof *output);
	if (output == NULL) {
		perror("zalloc");
		return -1;
	}

	weston_output_init(&output->base, compositor, name);

	output->base.destroy = x11_output_destroy;
	output->base.disable = x11_output_disable;
	output->base.enable = x11_output_enable;

	weston_compositor_add_pending_output(&output->base, compositor);

	return 0;
}

static struct x11_output *
x11_backend_find_output(struct x11_backend *b, xcb_window_t window)
{
	struct x11_output *output;

	wl_list_for_each(output, &b->compositor->output_list, base.link) {
		if (output->window == window)
			return output;
	}

	return NULL;
}

static void
x11_backend_delete_window(struct x11_backend *b, xcb_window_t window)
{
	struct x11_output *output;

	output = x11_backend_find_output(b, window);
	if (output)
		x11_output_destroy(&output->base);

	if (wl_list_empty(&b->compositor->output_list))
		weston_compositor_exit(b->compositor);
}

static void delete_cb(void *data)
{
	struct window_delete_data *wd = data;

	x11_backend_delete_window(wd->backend, wd->window);
	free(wd);
}

#ifdef HAVE_XCB_XKB
static void
update_xkb_state(struct x11_backend *b, xcb_xkb_state_notify_event_t *state)
{
	struct weston_keyboard *keyboard =
		weston_seat_get_keyboard(&b->core_seat);

	xkb_state_update_mask(keyboard->xkb_state.state,
			      get_xkb_mod_mask(b, state->baseMods),
			      get_xkb_mod_mask(b, state->latchedMods),
			      get_xkb_mod_mask(b, state->lockedMods),
			      0,
			      0,
			      state->group);

	notify_modifiers(&b->core_seat,
			 wl_display_next_serial(b->compositor->wl_display));
}
#endif

/**
 * This is monumentally unpleasant.  If we don't have XCB-XKB bindings,
 * the best we can do (given that XCB also lacks XI2 support), is to take
 * the state from the core key events.  Unfortunately that only gives us
 * the effective (i.e. union of depressed/latched/locked) state, and we
 * need the granularity.
 *
 * So we still update the state with every key event we see, but also use
 * the state field from X11 events as a mask so we don't get any stuck
 * modifiers.
 */
static void
update_xkb_state_from_core(struct x11_backend *b, uint16_t x11_mask)
{
	uint32_t mask = get_xkb_mod_mask(b, x11_mask);
	struct weston_keyboard *keyboard
		= weston_seat_get_keyboard(&b->core_seat);

	xkb_state_update_mask(keyboard->xkb_state.state,
			      keyboard->modifiers.mods_depressed & mask,
			      keyboard->modifiers.mods_latched & mask,
			      keyboard->modifiers.mods_locked & mask,
			      0,
			      0,
			      (x11_mask >> 13) & 3);
	notify_modifiers(&b->core_seat,
			 wl_display_next_serial(b->compositor->wl_display));
}

static void
x11_backend_deliver_button_event(struct x11_backend *b,
				 xcb_generic_event_t *event)
{
	xcb_button_press_event_t *button_event =
		(xcb_button_press_event_t *) event;
	uint32_t button;
	struct x11_output *output;
	struct weston_pointer_axis_event weston_event;
	bool is_button_pressed = event->response_type == XCB_BUTTON_PRESS;
	struct timespec time = { 0 };

	assert(event->response_type == XCB_BUTTON_PRESS ||
	       event->response_type == XCB_BUTTON_RELEASE);

	output = x11_backend_find_output(b, button_event->event);
	if (!output)
		return;

	if (is_button_pressed)
		xcb_grab_pointer(b->conn, 0, output->window,
				 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_GRAB_MODE_ASYNC,
				 XCB_GRAB_MODE_ASYNC,
				 output->window, XCB_CURSOR_NONE,
				 button_event->time);
	else
		xcb_ungrab_pointer(b->conn, button_event->time);

	if (!b->has_xkb)
		update_xkb_state_from_core(b, button_event->state);

	switch (button_event->detail) {
	case 1:
		button = BTN_LEFT;
		break;
	case 2:
		button = BTN_MIDDLE;
		break;
	case 3:
		button = BTN_RIGHT;
		break;
	case 4:
		/* Axis are measured in pixels, but the xcb events are discrete
		 * steps. Therefore move the axis by some pixels every step. */
		if (is_button_pressed) {
			weston_event.value = -DEFAULT_AXIS_STEP_DISTANCE;
			weston_event.discrete = -1;
			weston_event.has_discrete = true;
			weston_event.axis =
				WL_POINTER_AXIS_VERTICAL_SCROLL;
			weston_compositor_get_time(&time);
			notify_axis(&b->core_seat, &time, &weston_event);
			notify_pointer_frame(&b->core_seat);
		}
		return;
	case 5:
		if (is_button_pressed) {
			weston_event.value = DEFAULT_AXIS_STEP_DISTANCE;
			weston_event.discrete = 1;
			weston_event.has_discrete = true;
			weston_event.axis =
				WL_POINTER_AXIS_VERTICAL_SCROLL;
			weston_compositor_get_time(&time);
			notify_axis(&b->core_seat, &time, &weston_event);
			notify_pointer_frame(&b->core_seat);
		}
		return;
	case 6:
		if (is_button_pressed) {
			weston_event.value = -DEFAULT_AXIS_STEP_DISTANCE;
			weston_event.discrete = -1;
			weston_event.has_discrete = true;
			weston_event.axis =
				WL_POINTER_AXIS_HORIZONTAL_SCROLL;
			weston_compositor_get_time(&time);
			notify_axis(&b->core_seat, &time, &weston_event);
			notify_pointer_frame(&b->core_seat);
		}
		return;
	case 7:
		if (is_button_pressed) {
			weston_event.value = DEFAULT_AXIS_STEP_DISTANCE;
			weston_event.discrete = 1;
			weston_event.has_discrete = true;
			weston_event.axis =
				WL_POINTER_AXIS_HORIZONTAL_SCROLL;
			weston_compositor_get_time(&time);
			notify_axis(&b->core_seat, &time, &weston_event);
			notify_pointer_frame(&b->core_seat);
		}
		return;
	default:
		button = button_event->detail + BTN_SIDE - 8;
		break;
	}

	weston_compositor_get_time(&time);

	notify_button(&b->core_seat, &time, button,
		      is_button_pressed ? WL_POINTER_BUTTON_STATE_PRESSED :
					  WL_POINTER_BUTTON_STATE_RELEASED);
	notify_pointer_frame(&b->core_seat);
}

static void
x11_backend_deliver_motion_event(struct x11_backend *b,
				 xcb_generic_event_t *event)
{
	struct x11_output *output;
	double x, y;
	struct weston_pointer_motion_event motion_event = { 0 };
	xcb_motion_notify_event_t *motion_notify =
			(xcb_motion_notify_event_t *) event;
	struct timespec time;

	if (!b->has_xkb)
		update_xkb_state_from_core(b, motion_notify->state);
	output = x11_backend_find_output(b, motion_notify->event);
	if (!output)
		return;

	weston_output_transform_coordinate(&output->base,
					   motion_notify->event_x,
					   motion_notify->event_y,
					   &x, &y);

	motion_event = (struct weston_pointer_motion_event) {
		.mask = WESTON_POINTER_MOTION_REL,
		.dx = x - b->prev_x,
		.dy = y - b->prev_y
	};

	weston_compositor_get_time(&time);
	notify_motion(&b->core_seat, &time, &motion_event);
	notify_pointer_frame(&b->core_seat);

	b->prev_x = x;
	b->prev_y = y;
}

static void
x11_backend_deliver_enter_event(struct x11_backend *b,
				xcb_generic_event_t *event)
{
	struct x11_output *output;
	double x, y;

	xcb_enter_notify_event_t *enter_notify =
			(xcb_enter_notify_event_t *) event;
	if (enter_notify->state >= Button1Mask)
		return;
	if (!b->has_xkb)
		update_xkb_state_from_core(b, enter_notify->state);
	output = x11_backend_find_output(b, enter_notify->event);
	if (!output)
		return;

	weston_output_transform_coordinate(&output->base,
					   enter_notify->event_x,
					   enter_notify->event_y, &x, &y);

	notify_pointer_focus(&b->core_seat, &output->base, x, y);

	b->prev_x = x;
	b->prev_y = y;
}

static int
x11_backend_next_event(struct x11_backend *b,
		       xcb_generic_event_t **event, uint32_t mask)
{
	if (mask & WL_EVENT_READABLE)
		*event = xcb_poll_for_event(b->conn);
	else
		*event = xcb_poll_for_queued_event(b->conn);

	return *event != NULL;
}

static int
x11_backend_handle_event(int fd, uint32_t mask, void *data)
{
	struct x11_backend *b = data;
	struct x11_output *output;
	xcb_generic_event_t *event, *prev;
	xcb_client_message_event_t *client_message;
	xcb_enter_notify_event_t *enter_notify;
	xcb_key_press_event_t *key_press, *key_release;
	xcb_keymap_notify_event_t *keymap_notify;
	xcb_focus_in_event_t *focus_in;
	xcb_expose_event_t *expose;
	xcb_configure_notify_event_t *configure;
	xcb_atom_t atom;
	xcb_window_t window;
	uint32_t *k;
	uint32_t i, set;
	uint8_t response_type;
	int count;
	struct timespec time;

	prev = NULL;
	count = 0;
	while (x11_backend_next_event(b, &event, mask)) {
		response_type = event->response_type & ~0x80;

		switch (prev ? prev->response_type & ~0x80 : 0x80) {
		case XCB_KEY_RELEASE:
			/* Suppress key repeat events; this is only used if we
			 * don't have XCB XKB support. */
			key_release = (xcb_key_press_event_t *) prev;
			key_press = (xcb_key_press_event_t *) event;
			if (response_type == XCB_KEY_PRESS &&
			    key_release->time == key_press->time &&
			    key_release->detail == key_press->detail) {
				/* Don't deliver the held key release
				 * event or the new key press event. */
				free(event);
				free(prev);
				prev = NULL;
				continue;
			} else {
				/* Deliver the held key release now
				 * and fall through and handle the new
				 * event below. */
				update_xkb_state_from_core(b, key_release->state);
				weston_compositor_get_time(&time);
				notify_key(&b->core_seat,
					   &time,
					   key_release->detail - 8,
					   WL_KEYBOARD_KEY_STATE_RELEASED,
					   STATE_UPDATE_AUTOMATIC);
				free(prev);
				prev = NULL;
				break;
			}

		case XCB_FOCUS_IN:
			assert(response_type == XCB_KEYMAP_NOTIFY);
			keymap_notify = (xcb_keymap_notify_event_t *) event;
			b->keys.size = 0;
			for (i = 0; i < ARRAY_LENGTH(keymap_notify->keys) * 8; i++) {
				set = keymap_notify->keys[i >> 3] &
					(1 << (i & 7));
				if (set) {
					k = wl_array_add(&b->keys, sizeof *k);
					*k = i;
				}
			}

			/* Unfortunately the state only comes with the enter
			 * event, rather than with the focus event.  I'm not
			 * sure of the exact semantics around it and whether
			 * we can ensure that we get both? */
			notify_keyboard_focus_in(&b->core_seat, &b->keys,
						 STATE_UPDATE_AUTOMATIC);

			free(prev);
			prev = NULL;
			break;

		default:
			/* No previous event held */
			break;
		}

		switch (response_type) {
		case XCB_KEY_PRESS:
			key_press = (xcb_key_press_event_t *) event;
			if (!b->has_xkb)
				update_xkb_state_from_core(b, key_press->state);
			weston_compositor_get_time(&time);
			notify_key(&b->core_seat,
				   &time,
				   key_press->detail - 8,
				   WL_KEYBOARD_KEY_STATE_PRESSED,
				   b->has_xkb ? STATE_UPDATE_NONE :
						STATE_UPDATE_AUTOMATIC);
			break;
		case XCB_KEY_RELEASE:
			/* If we don't have XKB, we need to use the lame
			 * autorepeat detection above. */
			if (!b->has_xkb) {
				prev = event;
				break;
			}
			key_release = (xcb_key_press_event_t *) event;
			weston_compositor_get_time(&time);
			notify_key(&b->core_seat,
				   &time,
				   key_release->detail - 8,
				   WL_KEYBOARD_KEY_STATE_RELEASED,
				   STATE_UPDATE_NONE);
			break;
		case XCB_BUTTON_PRESS:
		case XCB_BUTTON_RELEASE:
			x11_backend_deliver_button_event(b, event);
			break;
		case XCB_MOTION_NOTIFY:
			x11_backend_deliver_motion_event(b, event);
			break;

		case XCB_EXPOSE:
			expose = (xcb_expose_event_t *) event;
			output = x11_backend_find_output(b, expose->window);
			if (!output)
				break;

			weston_output_damage(&output->base);
			weston_output_schedule_repaint(&output->base);
			break;

		case XCB_ENTER_NOTIFY:
			x11_backend_deliver_enter_event(b, event);
			break;

		case XCB_LEAVE_NOTIFY:
			enter_notify = (xcb_enter_notify_event_t *) event;
			if (enter_notify->state >= Button1Mask)
				break;
			if (!b->has_xkb)
				update_xkb_state_from_core(b, enter_notify->state);
			notify_pointer_focus(&b->core_seat, NULL, 0, 0);
			break;

		case XCB_CLIENT_MESSAGE:
			client_message = (xcb_client_message_event_t *) event;
			atom = client_message->data.data32[0];
			window = client_message->window;
			if (atom == b->atom.wm_delete_window) {
				struct wl_event_loop *loop;
				struct window_delete_data *data = malloc(sizeof *data);

				/* if malloc failed we should at least try to
				 * delete the window, even if it may result in
				 * a crash.
				 */
				if (!data) {
					x11_backend_delete_window(b, window);
					break;
				}
				data->backend = b;
				data->window = window;
				loop = wl_display_get_event_loop(b->compositor->wl_display);
				wl_event_loop_add_idle(loop, delete_cb, data);
			}
			break;

		case XCB_CONFIGURE_NOTIFY:
			configure = (struct xcb_configure_notify_event_t *) event;
			struct x11_output *output =
				x11_backend_find_output(b, configure->window);

			if (!output || output->resize_pending)
				break;

			struct weston_mode mode = output->mode;

			if (mode.width == configure->width &&
			    mode.height == configure->height)
				break;

			output->window_resized = true;

			mode.width = configure->width;
			mode.height = configure->height;

			if (weston_output_mode_set_native(&output->base,
							  &mode, output->scale) < 0)
				weston_log("Mode switch failed\n");

			break;

		case XCB_FOCUS_IN:
			focus_in = (xcb_focus_in_event_t *) event;
			if (focus_in->mode == XCB_NOTIFY_MODE_WHILE_GRABBED)
				break;

			prev = event;
			break;

		case XCB_FOCUS_OUT:
			focus_in = (xcb_focus_in_event_t *) event;
			if (focus_in->mode == XCB_NOTIFY_MODE_WHILE_GRABBED ||
			    focus_in->mode == XCB_NOTIFY_MODE_UNGRAB)
				break;
			notify_keyboard_focus_out(&b->core_seat);
			break;

		default:
			break;
		}

#ifdef HAVE_XCB_XKB
		if (b->has_xkb) {
			if (response_type == b->xkb_event_base) {
				xcb_xkb_state_notify_event_t *state =
					(xcb_xkb_state_notify_event_t *) event;
				if (state->xkbType == XCB_XKB_STATE_NOTIFY)
					update_xkb_state(b, state);
			} else if (response_type == XCB_PROPERTY_NOTIFY) {
				xcb_property_notify_event_t *prop_notify =
					(xcb_property_notify_event_t *) event;
				if (prop_notify->window == b->screen->root &&
				    prop_notify->atom == b->atom.xkb_names &&
				    prop_notify->state == XCB_PROPERTY_NEW_VALUE)
					update_xkb_keymap(b);
			}
		}
#endif

		count++;
		if (prev != event)
			free (event);
	}

	switch (prev ? prev->response_type & ~0x80 : 0x80) {
	case XCB_KEY_RELEASE:
		key_release = (xcb_key_press_event_t *) prev;
		update_xkb_state_from_core(b, key_release->state);
		weston_compositor_get_time(&time);
		notify_key(&b->core_seat,
			   &time,
			   key_release->detail - 8,
			   WL_KEYBOARD_KEY_STATE_RELEASED,
			   STATE_UPDATE_AUTOMATIC);
		free(prev);
		prev = NULL;
		break;
	default:
		break;
	}

	return count;
}

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

static void
x11_backend_get_resources(struct x11_backend *b)
{
	static const struct { const char *name; int offset; } atoms[] = {
		{ "WM_PROTOCOLS",	F(atom.wm_protocols) },
		{ "WM_NORMAL_HINTS",	F(atom.wm_normal_hints) },
		{ "WM_SIZE_HINTS",	F(atom.wm_size_hints) },
		{ "WM_DELETE_WINDOW",	F(atom.wm_delete_window) },
		{ "WM_CLASS",		F(atom.wm_class) },
		{ "_NET_WM_NAME",	F(atom.net_wm_name) },
		{ "_NET_WM_ICON",	F(atom.net_wm_icon) },
		{ "_NET_WM_STATE",	F(atom.net_wm_state) },
		{ "_NET_WM_STATE_FULLSCREEN", F(atom.net_wm_state_fullscreen) },
		{ "_NET_SUPPORTING_WM_CHECK",
					F(atom.net_supporting_wm_check) },
		{ "_NET_SUPPORTED",     F(atom.net_supported) },
		{ "STRING",		F(atom.string) },
		{ "UTF8_STRING",	F(atom.utf8_string) },
		{ "CARDINAL",		F(atom.cardinal) },
		{ "_XKB_RULES_NAMES",	F(atom.xkb_names) },
	};

	xcb_intern_atom_cookie_t cookies[ARRAY_LENGTH(atoms)];
	xcb_intern_atom_reply_t *reply;
	xcb_pixmap_t pixmap;
	xcb_gc_t gc;
	unsigned int i;
	uint8_t data[] = { 0, 0, 0, 0 };

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

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

	pixmap = xcb_generate_id(b->conn);
	gc = xcb_generate_id(b->conn);
	xcb_create_pixmap(b->conn, 1, pixmap, b->screen->root, 1, 1);
	xcb_create_gc(b->conn, gc, pixmap, 0, NULL);
	xcb_put_image(b->conn, XCB_IMAGE_FORMAT_XY_PIXMAP,
		      pixmap, gc, 1, 1, 0, 0, 0, 32, sizeof data, data);
	b->null_cursor = xcb_generate_id(b->conn);
	xcb_create_cursor (b->conn, b->null_cursor,
			   pixmap, pixmap, 0, 0, 0,  0, 0, 0,  1, 1);
	xcb_free_gc(b->conn, gc);
	xcb_free_pixmap(b->conn, pixmap);
}

static void
x11_backend_get_wm_info(struct x11_backend *c)
{
	xcb_get_property_cookie_t cookie;
	xcb_get_property_reply_t *reply;
	xcb_atom_t *atom;
	unsigned int i;

	cookie = xcb_get_property(c->conn, 0, c->screen->root,
				  c->atom.net_supported,
				  XCB_ATOM_ATOM, 0, 1024);
	reply = xcb_get_property_reply(c->conn, cookie, NULL);
	if (reply == NULL)
		return;

	atom = (xcb_atom_t *) xcb_get_property_value(reply);

	for (i = 0; i < reply->value_len; i++) {
		if (atom[i] == c->atom.net_wm_state_fullscreen)
			c->has_net_wm_state_fullscreen = 1;
	}

	free(reply);
}

static void
x11_restore(struct weston_compositor *ec)
{
}

static void
x11_destroy(struct weston_compositor *ec)
{
	struct x11_backend *backend = to_x11_backend(ec);

	wl_event_source_remove(backend->xcb_source);
	x11_input_destroy(backend);

	weston_compositor_shutdown(ec); /* destroys outputs, too */

	XCloseDisplay(backend->dpy);
	free(backend);
}

static int
init_gl_renderer(struct x11_backend *b)
{
	int ret;

	gl_renderer = weston_load_module("gl-renderer.so",
					 "gl_renderer_interface");
	if (!gl_renderer)
		return -1;

	ret = gl_renderer->display_create(b->compositor, EGL_PLATFORM_X11_KHR,
					  (void *) b->dpy, NULL,
					  gl_renderer->opaque_attribs, NULL, 0);

	return ret;
}

static const struct weston_windowed_output_api api = {
	x11_output_set_size,
	x11_output_create,
};

static struct x11_backend *
x11_backend_create(struct weston_compositor *compositor,
		   struct weston_x11_backend_config *config)
{
	struct x11_backend *b;
	struct wl_event_loop *loop;
	int ret;

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

	b->compositor = compositor;
	b->fullscreen = config->fullscreen;
	b->no_input = config->no_input;

	compositor->backend = &b->base;

	if (weston_compositor_set_presentation_clock_software(compositor) < 0)
		goto err_free;

	b->dpy = XOpenDisplay(NULL);
	if (b->dpy == NULL)
		goto err_free;

	b->conn = XGetXCBConnection(b->dpy);
	XSetEventQueueOwner(b->dpy, XCBOwnsEventQueue);

	if (xcb_connection_has_error(b->conn))
		goto err_xdisplay;

	b->screen = x11_compositor_get_default_screen(b);
	wl_array_init(&b->keys);

	x11_backend_get_resources(b);
	x11_backend_get_wm_info(b);

	if (!b->has_net_wm_state_fullscreen && config->fullscreen) {
		weston_log("Can not fullscreen without window manager support"
			   "(need _NET_WM_STATE_FULLSCREEN)\n");
		config->fullscreen = 0;
	}

	b->use_pixman = config->use_pixman;
	if (b->use_pixman) {
		if (pixman_renderer_init(compositor) < 0) {
			weston_log("Failed to initialize pixman renderer for X11 backend\n");
			goto err_xdisplay;
		}
	}
	else if (init_gl_renderer(b) < 0) {
		goto err_xdisplay;
	}
	weston_log("Using %s renderer\n", config->use_pixman ? "pixman" : "gl");

	b->base.destroy = x11_destroy;
	b->base.restore = x11_restore;

	if (x11_input_create(b, config->no_input) < 0) {
		weston_log("Failed to create X11 input\n");
		goto err_renderer;
	}

	loop = wl_display_get_event_loop(compositor->wl_display);
	b->xcb_source =
		wl_event_loop_add_fd(loop,
				     xcb_get_file_descriptor(b->conn),
				     WL_EVENT_READABLE,
				     x11_backend_handle_event, b);
	wl_event_source_check(b->xcb_source);

	if (compositor->renderer->import_dmabuf) {
		if (linux_dmabuf_setup(compositor) < 0)
			weston_log("Error: initializing dmabuf "
				   "support failed.\n");
	}

	ret = weston_plugin_api_register(compositor, WESTON_WINDOWED_OUTPUT_API_NAME,
					 &api, sizeof(api));

	if (ret < 0) {
		weston_log("Failed to register output API.\n");
		goto err_x11_input;
	}

	return b;

err_x11_input:
	x11_input_destroy(b);
err_renderer:
	compositor->renderer->destroy(compositor);
err_xdisplay:
	XCloseDisplay(b->dpy);
err_free:
	free(b);
	return NULL;
}

static void
config_init_to_defaults(struct weston_x11_backend_config *config)
{
}

WL_EXPORT int
weston_backend_init(struct weston_compositor *compositor,
		    struct weston_backend_config *config_base)
{
	struct x11_backend *b;
	struct weston_x11_backend_config config = {{ 0, }};

	if (config_base == NULL ||
	    config_base->struct_version != WESTON_X11_BACKEND_CONFIG_VERSION ||
	    config_base->struct_size > sizeof(struct weston_x11_backend_config)) {
		weston_log("X11 backend config structure is invalid\n");
		return -1;
	}

	config_init_to_defaults(&config);
	memcpy(&config, config_base, config_base->struct_size);

	b = x11_backend_create(compositor, &config);
	if (b == NULL)
		return -1;

	return 0;
}
