/*
 * Copyright © 2008-2012 Kristian Høgsberg
 * Copyright © 2010-2012 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.
 */

#define _GNU_SOURCE

#include <stdlib.h>
#include <stdint.h>
#include <stddef.h>
#include <stdio.h>
#include <stdbool.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <ctype.h>
#include <assert.h>
#include <fcntl.h>
#include <poll.h>
#include <pthread.h>

#include "wayland-util.h"
#include "wayland-os.h"
#include "wayland-client.h"
#include "wayland-private.h"

/** \cond */

enum wl_proxy_flag {
	WL_PROXY_FLAG_ID_DELETED = (1 << 0),
	WL_PROXY_FLAG_DESTROYED = (1 << 1),
	WL_PROXY_FLAG_WRAPPER = (1 << 2),
};

struct wl_proxy {
	struct wl_object object;
	struct wl_display *display;
	struct wl_event_queue *queue;
	uint32_t flags;
	int refcount;
	void *user_data;
	wl_dispatcher_func_t dispatcher;
	uint32_t version;
};

struct wl_global {
	uint32_t id;
	char *interface;
	uint32_t version;
	struct wl_list link;
};

struct wl_event_queue {
	struct wl_list event_list;
	struct wl_display *display;
};

struct wl_display {
	struct wl_proxy proxy;
	struct wl_connection *connection;

	/* errno of the last wl_display error */
	int last_error;

	/* When display gets an error event from some object, it stores
	 * information about it here, so that client can get this
	 * information afterwards */
	struct {
		/* Code of the error. It can be compared to
		 * the interface's errors enumeration. */
		uint32_t code;
		/* interface (protocol) in which the error occurred */
		const struct wl_interface *interface;
		/* id of the proxy that caused the error. There's no warranty
		 * that the proxy is still valid. It's up to client how it will
		 * use it */
		uint32_t id;
	} protocol_error;
	int fd;
	struct wl_map objects;
	struct wl_event_queue display_queue;
	struct wl_event_queue default_queue;
	pthread_mutex_t mutex;

	int reader_count;
	uint32_t read_serial;
	pthread_cond_t reader_cond;
};

/** \endcond */

static int debug_client = 0;

/**
 * This helper function wakes up all threads that are
 * waiting for display->reader_cond (i. e. when reading is done,
 * canceled, or an error occurred)
 *
 * NOTE: must be called with display->mutex locked
 */
static void
display_wakeup_threads(struct wl_display *display)
{
	/* Thread can get sleeping only in read_events(). If we're
	 * waking it up, it means that the read completed or was
	 * canceled, so we must increase the read_serial.
	 * This prevents from indefinite sleeping in read_events().
	 */
	++display->read_serial;

	pthread_cond_broadcast(&display->reader_cond);
}

/**
 * This function is called for local errors (no memory, server hung up)
 *
 * \param display
 * \param error    error value (EINVAL, EFAULT, ...)
 *
 * \note this function is called with display mutex locked
 */
static void
display_fatal_error(struct wl_display *display, int error)
{
	if (display->last_error)
		return;

	if (!error)
		error = EFAULT;

	display->last_error = error;

	display_wakeup_threads(display);
}

/**
 * This function is called for error events
 * and indicates that in some object an error occurred.
 * The difference between this function and display_fatal_error()
 * is that this one handles errors that will come by wire,
 * whereas display_fatal_error() is called for local errors.
 *
 * \param display
 * \param code    error code
 * \param id      id of the object that generated the error
 * \param intf    protocol interface
 */
static void
display_protocol_error(struct wl_display *display, uint32_t code,
		       uint32_t id, const struct wl_interface *intf)
{
	int err;

	if (display->last_error)
		return;

	/* set correct errno */
	if (intf && wl_interface_equal(intf, &wl_display_interface)) {
		switch (code) {
		case WL_DISPLAY_ERROR_INVALID_OBJECT:
		case WL_DISPLAY_ERROR_INVALID_METHOD:
			err = EINVAL;
			break;
		case WL_DISPLAY_ERROR_NO_MEMORY:
			err = ENOMEM;
			break;
		default:
			err = EFAULT;
		}
	} else {
		err = EPROTO;
	}

	pthread_mutex_lock(&display->mutex);

	display->last_error = err;

	display->protocol_error.code = code;
	display->protocol_error.id = id;
	display->protocol_error.interface = intf;

	/*
	 * here it is not necessary to wake up threads like in
	 * display_fatal_error, because this function is called from
	 * an event handler and that means that read_events() is done
	 * and woke up all threads. Since wl_display_prepare_read()
	 * fails when there are events in the queue, no threads
	 * can sleep in read_events() during dispatching
	 * (and therefore during calling this function), so this is safe.
	 */

	pthread_mutex_unlock(&display->mutex);
}

static void
wl_event_queue_init(struct wl_event_queue *queue, struct wl_display *display)
{
	wl_list_init(&queue->event_list);
	queue->display = display;
}

static void
decrease_closure_args_refcount(struct wl_closure *closure)
{
	const char *signature;
	struct argument_details arg;
	int i, count;
	struct wl_proxy *proxy;

	signature = closure->message->signature;
	count = arg_count_for_signature(signature);
	for (i = 0; i < count; i++) {
		signature = get_next_argument(signature, &arg);
		switch (arg.type) {
		case 'n':
		case 'o':
			proxy = (struct wl_proxy *) closure->args[i].o;
			if (proxy) {
				if (proxy->flags & WL_PROXY_FLAG_DESTROYED)
					closure->args[i].o = NULL;

				proxy->refcount--;
				if (!proxy->refcount)
					free(proxy);
			}
			break;
		default:
			break;
		}
	}
}

static void
wl_event_queue_release(struct wl_event_queue *queue)
{
	struct wl_closure *closure;
	struct wl_proxy *proxy;
	bool proxy_destroyed;

	while (!wl_list_empty(&queue->event_list)) {
		closure = container_of(queue->event_list.next,
				       struct wl_closure, link);
		wl_list_remove(&closure->link);

		decrease_closure_args_refcount(closure);

		proxy = closure->proxy;
		proxy_destroyed = !!(proxy->flags & WL_PROXY_FLAG_DESTROYED);

		proxy->refcount--;
		if (proxy_destroyed && !proxy->refcount)
			free(proxy);

		wl_closure_destroy(closure);
	}
}

/** Destroy an event queue
 *
 * \param queue The event queue to be destroyed
 *
 * Destroy the given event queue. Any pending event on that queue is
 * discarded.
 *
 * The \ref wl_display object used to create the queue should not be
 * destroyed until all event queues created with it are destroyed with
 * this function.
 *
 * \memberof wl_event_queue
 */
WL_EXPORT void
wl_event_queue_destroy(struct wl_event_queue *queue)
{
	struct wl_display *display = queue->display;

	pthread_mutex_lock(&display->mutex);
	wl_event_queue_release(queue);
	free(queue);
	pthread_mutex_unlock(&display->mutex);
}

/** Create a new event queue for this display
 *
 * \param display The display context object
 * \return A new event queue associated with this display or NULL on
 * failure.
 *
 * \memberof wl_display
 */
WL_EXPORT struct wl_event_queue *
wl_display_create_queue(struct wl_display *display)
{
	struct wl_event_queue *queue;

	queue = malloc(sizeof *queue);
	if (queue == NULL)
		return NULL;

	wl_event_queue_init(queue, display);

	return queue;
}

static struct wl_proxy *
proxy_create(struct wl_proxy *factory, const struct wl_interface *interface,
	     uint32_t version)
{
	struct wl_proxy *proxy;
	struct wl_display *display = factory->display;

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

	proxy->object.interface = interface;
	proxy->display = display;
	proxy->queue = factory->queue;
	proxy->refcount = 1;
	proxy->version = version;

	proxy->object.id = wl_map_insert_new(&display->objects, 0, proxy);

	return proxy;
}

/** Create a proxy object with a given interface
 *
 * \param factory Factory proxy object
 * \param interface Interface the proxy object should use
 * \return A newly allocated proxy object or NULL on failure
 *
 * This function creates a new proxy object with the supplied interface. The
 * proxy object will have an id assigned from the client id space. The id
 * should be created on the compositor side by sending an appropriate request
 * with \ref wl_proxy_marshal().
 *
 * The proxy will inherit the display and event queue of the factory object.
 *
 * \note This should not normally be used by non-generated code.
 *
 * \sa wl_display, wl_event_queue, wl_proxy_marshal()
 *
 * \memberof wl_proxy
 */
WL_EXPORT struct wl_proxy *
wl_proxy_create(struct wl_proxy *factory, const struct wl_interface *interface)
{
	struct wl_display *display = factory->display;
	struct wl_proxy *proxy;

	pthread_mutex_lock(&display->mutex);
	proxy = proxy_create(factory, interface, factory->version);
	pthread_mutex_unlock(&display->mutex);

	return proxy;
}

/* The caller should hold the display lock */
static struct wl_proxy *
wl_proxy_create_for_id(struct wl_proxy *factory,
		       uint32_t id, const struct wl_interface *interface)
{
	struct wl_proxy *proxy;
	struct wl_display *display = factory->display;

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

	proxy->object.interface = interface;
	proxy->object.id = id;
	proxy->display = display;
	proxy->queue = factory->queue;
	proxy->refcount = 1;
	proxy->version = factory->version;

	wl_map_insert_at(&display->objects, 0, id, proxy);

	return proxy;
}

static void
proxy_destroy(struct wl_proxy *proxy)
{
	if (proxy->flags & WL_PROXY_FLAG_ID_DELETED) {
		wl_map_remove(&proxy->display->objects, proxy->object.id);
	} else if (proxy->object.id < WL_SERVER_ID_START) {
		wl_map_insert_at(&proxy->display->objects,
				 WL_MAP_ENTRY_ZOMBIE,
				 proxy->object.id,
				 WL_ZOMBIE_OBJECT);
	} else {
		wl_map_insert_at(&proxy->display->objects, 0,
				 proxy->object.id, NULL);
	}

	proxy->flags |= WL_PROXY_FLAG_DESTROYED;

	proxy->refcount--;
	if (!proxy->refcount)
		free(proxy);
}

/** Destroy a proxy object
 *
 * \param proxy The proxy to be destroyed
 *
 * \c proxy must not be a proxy wrapper.
 *
 * \memberof wl_proxy
 */
WL_EXPORT void
wl_proxy_destroy(struct wl_proxy *proxy)
{
	struct wl_display *display = proxy->display;

	if (proxy->flags & WL_PROXY_FLAG_WRAPPER)
		wl_abort("Tried to destroy wrapper with wl_proxy_destroy()\n");

	pthread_mutex_lock(&display->mutex);
	proxy_destroy(proxy);
	pthread_mutex_unlock(&display->mutex);
}

/** Set a proxy's listener
 *
 * \param proxy The proxy object
 * \param implementation The listener to be added to proxy
 * \param data User data to be associated with the proxy
 * \return 0 on success or -1 on failure
 *
 * Set proxy's listener to \c implementation and its user data to
 * \c data. If a listener has already been set, this function
 * fails and nothing is changed.
 *
 * \c implementation is a vector of function pointers. For an opcode
 * \c n, \c implementation[n] should point to the handler of \c n for
 * the given object.
 *
 * \c proxy must not be a proxy wrapper.
 *
 * \memberof wl_proxy
 */
WL_EXPORT int
wl_proxy_add_listener(struct wl_proxy *proxy,
		      void (**implementation)(void), void *data)
{
	if (proxy->flags & WL_PROXY_FLAG_WRAPPER)
		wl_abort("Proxy %p is a wrapper\n", proxy);

	if (proxy->object.implementation || proxy->dispatcher) {
		wl_log("proxy %p already has listener\n", proxy);
		return -1;
	}

	proxy->object.implementation = implementation;
	proxy->user_data = data;

	return 0;
}

/** Get a proxy's listener
 *
 * \param proxy The proxy object
 * \return The address of the proxy's listener or NULL if no listener is set
 *
 * Gets the address to the proxy's listener; which is the listener set with
 * \ref wl_proxy_add_listener.
 *
 * This function is useful in clients with multiple listeners on the same
 * interface to allow the identification of which code to execute.
 *
 * \memberof wl_proxy
 */
WL_EXPORT const void *
wl_proxy_get_listener(struct wl_proxy *proxy)
{
	return proxy->object.implementation;
}

/** Set a proxy's listener (with dispatcher)
 *
 * \param proxy The proxy object
 * \param dispatcher The dispatcher to be used for this proxy
 * \param implementation The dispatcher-specific listener implementation
 * \param data User data to be associated with the proxy
 * \return 0 on success or -1 on failure
 *
 * Set proxy's listener to use \c dispatcher_func as its dispatcher and \c
 * dispatcher_data as its dispatcher-specific implementation and its user data
 * to \c data. If a listener has already been set, this function
 * fails and nothing is changed.
 *
 * The exact details of dispatcher_data depend on the dispatcher used.  This
 * function is intended to be used by language bindings, not user code.
 *
 * \c proxy must not be a proxy wrapper.
 *
 * \memberof wl_proxy
 */
WL_EXPORT int
wl_proxy_add_dispatcher(struct wl_proxy *proxy,
			wl_dispatcher_func_t dispatcher,
			const void *implementation, void *data)
{
	if (proxy->flags & WL_PROXY_FLAG_WRAPPER)
		wl_abort("Proxy %p is a wrapper\n", proxy);

	if (proxy->object.implementation || proxy->dispatcher) {
		wl_log("proxy %p already has listener\n", proxy);
		return -1;
	}

	proxy->object.implementation = implementation;
	proxy->dispatcher = dispatcher;
	proxy->user_data = data;

	return 0;
}

static struct wl_proxy *
create_outgoing_proxy(struct wl_proxy *proxy, const struct wl_message *message,
		      union wl_argument *args,
		      const struct wl_interface *interface, uint32_t version)
{
	int i, count;
	const char *signature;
	struct argument_details arg;
	struct wl_proxy *new_proxy = NULL;

	signature = message->signature;
	count = arg_count_for_signature(signature);
	for (i = 0; i < count; i++) {
		signature = get_next_argument(signature, &arg);

		switch (arg.type) {
		case 'n':
			new_proxy = proxy_create(proxy, interface, version);
			if (new_proxy == NULL)
				return NULL;

			args[i].o = &new_proxy->object;
			break;
		}
	}

	return new_proxy;
}

/** Prepare a request to be sent to the compositor
 *
 * \param proxy The proxy object
 * \param opcode Opcode of the request to be sent
 * \param args Extra arguments for the given request
 * \param interface The interface to use for the new proxy
 *
 * This function translates a request given an opcode, an interface and a
 * wl_argument array to the wire format and writes it to the connection
 * buffer.
 *
 * For new-id arguments, this function will allocate a new wl_proxy
 * and send the ID to the server.  The new wl_proxy will be returned
 * on success or NULL on error with errno set accordingly.  The newly
 * created proxy will inherit their version from their parent.
 *
 * \note This is intended to be used by language bindings and not in
 * non-generated code.
 *
 * \sa wl_proxy_marshal()
 *
 * \memberof wl_proxy
 */
WL_EXPORT struct wl_proxy *
wl_proxy_marshal_array_constructor(struct wl_proxy *proxy,
				   uint32_t opcode, union wl_argument *args,
				   const struct wl_interface *interface)
{
	return wl_proxy_marshal_array_constructor_versioned(proxy, opcode,
							    args, interface,
							    proxy->version);
}


/** Prepare a request to be sent to the compositor
 *
 * \param proxy The proxy object
 * \param opcode Opcode of the request to be sent
 * \param args Extra arguments for the given request
 * \param interface The interface to use for the new proxy
 * \param version The protocol object version for the new proxy
 *
 * Translates the request given by opcode and the extra arguments into the
 * wire format and write it to the connection buffer.  This version takes an
 * array of the union type wl_argument.
 *
 * For new-id arguments, this function will allocate a new wl_proxy
 * and send the ID to the server.  The new wl_proxy will be returned
 * on success or NULL on error with errno set accordingly.  The newly
 * created proxy will have the version specified.
 *
 * \note This is intended to be used by language bindings and not in
 * non-generated code.
 *
 * \sa wl_proxy_marshal()
 *
 * \memberof wl_proxy
 */
WL_EXPORT struct wl_proxy *
wl_proxy_marshal_array_constructor_versioned(struct wl_proxy *proxy,
					     uint32_t opcode,
					     union wl_argument *args,
					     const struct wl_interface *interface,
					     uint32_t version)
{
	struct wl_closure *closure;
	struct wl_proxy *new_proxy = NULL;
	const struct wl_message *message;

	pthread_mutex_lock(&proxy->display->mutex);

	message = &proxy->object.interface->methods[opcode];
	if (interface) {
		new_proxy = create_outgoing_proxy(proxy, message,
						  args, interface,
						  version);
		if (new_proxy == NULL)
			goto err_unlock;
	}

	closure = wl_closure_marshal(&proxy->object, opcode, args, message);
	if (closure == NULL)
		wl_abort("Error marshalling request: %s\n", strerror(errno));

	if (debug_client)
		wl_closure_print(closure, &proxy->object, true);

	if (wl_closure_send(closure, proxy->display->connection))
		wl_abort("Error sending request: %s\n", strerror(errno));

	wl_closure_destroy(closure);

 err_unlock:
	pthread_mutex_unlock(&proxy->display->mutex);

	return new_proxy;
}


/** Prepare a request to be sent to the compositor
 *
 * \param proxy The proxy object
 * \param opcode Opcode of the request to be sent
 * \param ... Extra arguments for the given request
 *
 * This function is similar to wl_proxy_marshal_constructor(), except
 * it doesn't create proxies for new-id arguments.
 *
 * \note This should not normally be used by non-generated code.
 *
 * \sa wl_proxy_create()
 *
 * \memberof wl_proxy
 */
WL_EXPORT void
wl_proxy_marshal(struct wl_proxy *proxy, uint32_t opcode, ...)
{
	union wl_argument args[WL_CLOSURE_MAX_ARGS];
	va_list ap;

	va_start(ap, opcode);
	wl_argument_from_va_list(proxy->object.interface->methods[opcode].signature,
				 args, WL_CLOSURE_MAX_ARGS, ap);
	va_end(ap);

	wl_proxy_marshal_array_constructor(proxy, opcode, args, NULL);
}

/** Prepare a request to be sent to the compositor
 *
 * \param proxy The proxy object
 * \param opcode Opcode of the request to be sent
 * \param interface The interface to use for the new proxy
 * \param ... Extra arguments for the given request
 * \return A new wl_proxy for the new_id argument or NULL on error
 *
 * This function translates a request given an opcode, an interface and extra
 * arguments to the wire format and writes it to the connection buffer. The
 * types of the extra arguments must correspond to the argument types of the
 * method associated with the opcode in the interface.
 *
 * For new-id arguments, this function will allocate a new wl_proxy
 * and send the ID to the server.  The new wl_proxy will be returned
 * on success or NULL on error with errno set accordingly.  The newly
 * created proxy will inherit their version from their parent.
 *
 * \note This should not normally be used by non-generated code.
 *
 * \memberof wl_proxy
 */
WL_EXPORT struct wl_proxy *
wl_proxy_marshal_constructor(struct wl_proxy *proxy, uint32_t opcode,
			     const struct wl_interface *interface, ...)
{
	union wl_argument args[WL_CLOSURE_MAX_ARGS];
	va_list ap;

	va_start(ap, interface);
	wl_argument_from_va_list(proxy->object.interface->methods[opcode].signature,
				 args, WL_CLOSURE_MAX_ARGS, ap);
	va_end(ap);

	return wl_proxy_marshal_array_constructor(proxy, opcode,
						  args, interface);
}


/** Prepare a request to be sent to the compositor
 *
 * \param proxy The proxy object
 * \param opcode Opcode of the request to be sent
 * \param interface The interface to use for the new proxy
 * \param version The protocol object version of the new proxy
 * \param ... Extra arguments for the given request
 * \return A new wl_proxy for the new_id argument or NULL on error
 *
 * Translates the request given by opcode and the extra arguments into the
 * wire format and write it to the connection buffer.
 *
 * For new-id arguments, this function will allocate a new wl_proxy
 * and send the ID to the server.  The new wl_proxy will be returned
 * on success or NULL on error with errno set accordingly.  The newly
 * created proxy will have the version specified.
 *
 * \note This should not normally be used by non-generated code.
 *
 * \memberof wl_proxy
 */
WL_EXPORT struct wl_proxy *
wl_proxy_marshal_constructor_versioned(struct wl_proxy *proxy, uint32_t opcode,
				       const struct wl_interface *interface,
				       uint32_t version, ...)
{
	union wl_argument args[WL_CLOSURE_MAX_ARGS];
	va_list ap;

	va_start(ap, version);
	wl_argument_from_va_list(proxy->object.interface->methods[opcode].signature,
				 args, WL_CLOSURE_MAX_ARGS, ap);
	va_end(ap);

	return wl_proxy_marshal_array_constructor_versioned(proxy, opcode,
							    args, interface,
							    version);
}

/** Prepare a request to be sent to the compositor
 *
 * \param proxy The proxy object
 * \param opcode Opcode of the request to be sent
 * \param args Extra arguments for the given request
 *
 * This function is similar to wl_proxy_marshal_array_constructor(), except
 * it doesn't create proxies for new-id arguments.
 *
 * \note This is intended to be used by language bindings and not in
 * non-generated code.
 *
 * \sa wl_proxy_marshal()
 *
 * \memberof wl_proxy
 */
WL_EXPORT void
wl_proxy_marshal_array(struct wl_proxy *proxy, uint32_t opcode,
		       union wl_argument *args)
{
	wl_proxy_marshal_array_constructor(proxy, opcode, args, NULL);
}

static void
display_handle_error(void *data,
		     struct wl_display *display, void *object,
		     uint32_t code, const char *message)
{
	struct wl_proxy *proxy = object;
	uint32_t object_id;
	const struct wl_interface *interface;

	if (proxy) {
		wl_log("%s@%u: error %d: %s\n",
		       proxy->object.interface->name,
		       proxy->object.id,
		       code, message);

		object_id = proxy->object.id;
		interface = proxy->object.interface;
	} else {
		wl_log("[destroyed object]: error %d: %s\n",
		       code, message);

		object_id = 0;
		interface = NULL;
	}

	display_protocol_error(display, code, object_id, interface);
}

static void
display_handle_delete_id(void *data, struct wl_display *display, uint32_t id)
{
	struct wl_proxy *proxy;

	pthread_mutex_lock(&display->mutex);

	proxy = wl_map_lookup(&display->objects, id);

	if (wl_object_is_zombie(&display->objects, id))
		wl_map_remove(&display->objects, id);
	else if (proxy)
		proxy->flags |= WL_PROXY_FLAG_ID_DELETED;
	else
		wl_log("error: received delete_id for unknown id (%u)\n", id);

	pthread_mutex_unlock(&display->mutex);
}

static const struct wl_display_listener display_listener = {
	display_handle_error,
	display_handle_delete_id
};

static int
connect_to_socket(const char *name)
{
	struct sockaddr_un addr;
	socklen_t size;
	const char *runtime_dir;
	int name_size, fd;
	bool path_is_absolute;

	if (name == NULL)
		name = getenv("WAYLAND_DISPLAY");
	if (name == NULL)
		name = "wayland-0";

	path_is_absolute = name[0] == '/';

	runtime_dir = getenv("XDG_RUNTIME_DIR");
	if (!runtime_dir && !path_is_absolute) {
		wl_log("error: XDG_RUNTIME_DIR not set in the environment.\n");
		/* to prevent programs reporting
		 * "failed to create display: Success" */
		errno = ENOENT;
		return -1;
	}

	fd = wl_os_socket_cloexec(PF_LOCAL, SOCK_STREAM, 0);
	if (fd < 0)
		return -1;

	memset(&addr, 0, sizeof addr);
	addr.sun_family = AF_LOCAL;
	if (!path_is_absolute) {
		name_size =
			snprintf(addr.sun_path, sizeof addr.sun_path,
			         "%s/%s", runtime_dir, name) + 1;
	} else {
		/* absolute path */
		name_size =
			snprintf(addr.sun_path, sizeof addr.sun_path,
			         "%s", name) + 1;
	}

	assert(name_size > 0);
	if (name_size > (int)sizeof addr.sun_path) {
		if (!path_is_absolute) {
			wl_log("error: socket path \"%s/%s\" plus null terminator"
			       " exceeds %i bytes\n", runtime_dir, name, (int) sizeof(addr.sun_path));
		} else {
			wl_log("error: socket path \"%s\" plus null terminator"
			       " exceeds %i bytes\n", name, (int) sizeof(addr.sun_path));
		}
		close(fd);
		/* to prevent programs reporting
		 * "failed to add socket: Success" */
		errno = ENAMETOOLONG;
		return -1;
	};

	size = offsetof (struct sockaddr_un, sun_path) + name_size;

	if (connect(fd, (struct sockaddr *) &addr, size) < 0) {
		close(fd);
		return -1;
	}

	return fd;
}

/** Connect to Wayland display on an already open fd
 *
 * \param fd The fd to use for the connection
 * \return A \ref wl_display object or \c NULL on failure
 *
 * The wl_display takes ownership of the fd and will close it when the
 * display is destroyed.  The fd will also be closed in case of
 * failure.
 *
 * \memberof wl_display
 */
WL_EXPORT struct wl_display *
wl_display_connect_to_fd(int fd)
{
	struct wl_display *display;
	const char *debug;

	debug = getenv("WAYLAND_DEBUG");
	if (debug && (strstr(debug, "client") || strstr(debug, "1")))
		debug_client = 1;

	display = zalloc(sizeof *display);
	if (display == NULL) {
		close(fd);
		return NULL;
	}

	display->fd = fd;
	wl_map_init(&display->objects, WL_MAP_CLIENT_SIDE);
	wl_event_queue_init(&display->default_queue, display);
	wl_event_queue_init(&display->display_queue, display);
	pthread_mutex_init(&display->mutex, NULL);
	pthread_cond_init(&display->reader_cond, NULL);
	display->reader_count = 0;

	wl_map_insert_new(&display->objects, 0, NULL);

	display->proxy.object.interface = &wl_display_interface;
	display->proxy.object.id =
		wl_map_insert_new(&display->objects, 0, display);
	display->proxy.display = display;
	display->proxy.object.implementation = (void(**)(void)) &display_listener;
	display->proxy.user_data = display;
	display->proxy.queue = &display->default_queue;
	display->proxy.flags = 0;
	display->proxy.refcount = 1;

	/* We set this version to 0 for backwards compatibility.
	 *
	 * If a client is using old versions of protocol headers,
	 * it will use unversioned API to create proxies.  Those
	 * proxies will inherit this 0.
	 *
	 * A client could be passing these proxies into library
	 * code newer than the headers that checks proxy
	 * versions.  When the proxy version is reported as 0
	 * the library will know that it can't reliably determine
	 * the proxy version, and should do whatever fallback is
	 * required.
	 *
	 * This trick forces wl_display to always report 0, but
	 * since it's a special object that we can't bind
	 * specific versions of anyway, this should be fine.
	 */
	display->proxy.version = 0;

	display->connection = wl_connection_create(display->fd);
	if (display->connection == NULL)
		goto err_connection;

	return display;

 err_connection:
	pthread_mutex_destroy(&display->mutex);
	pthread_cond_destroy(&display->reader_cond);
	wl_map_release(&display->objects);
	close(display->fd);
	free(display);

	return NULL;
}

/** Connect to a Wayland display
 *
 * \param name Name of the Wayland display to connect to
 * \return A \ref wl_display object or \c NULL on failure
 *
 * Connect to the Wayland display named \c name. If \c name is \c NULL,
 * its value will be replaced with the WAYLAND_DISPLAY environment
 * variable if it is set, otherwise display "wayland-0" will be used.
 *
 * If \c name is an absolute path, then that path is used as-is for
 * the location of the socket at which the Wayland server is listening;
 * no qualification inside XDG_RUNTIME_DIR is attempted.
 *
 * If \c name is \c NULL and the WAYLAND_DISPLAY environment variable
 * is set to an absolute pathname, then that pathname is used as-is
 * for the socket in the same manner as if \c name held an absolute
 * path. Support for absolute paths in \c name and WAYLAND_DISPLAY
 * is present since Wayland version 1.15.
 *
 * \memberof wl_display
 */
WL_EXPORT struct wl_display *
wl_display_connect(const char *name)
{
	char *connection, *end;
	int flags, fd;

	connection = getenv("WAYLAND_SOCKET");
	if (connection) {
		int prev_errno = errno;
		errno = 0;
		fd = strtol(connection, &end, 10);
		if (errno != 0 || connection == end || *end != '\0')
			return NULL;
		errno = prev_errno;

		flags = fcntl(fd, F_GETFD);
		if (flags != -1)
			fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
		unsetenv("WAYLAND_SOCKET");
	} else {
		fd = connect_to_socket(name);
		if (fd < 0)
			return NULL;
	}

	return wl_display_connect_to_fd(fd);
}

/** Close a connection to a Wayland display
 *
 * \param display The display context object
 *
 * Close the connection to \c display and free all resources associated
 * with it.
 *
 * \memberof wl_display
 */
WL_EXPORT void
wl_display_disconnect(struct wl_display *display)
{
	wl_connection_destroy(display->connection);
	wl_map_release(&display->objects);
	wl_event_queue_release(&display->default_queue);
	wl_event_queue_release(&display->display_queue);
	pthread_mutex_destroy(&display->mutex);
	pthread_cond_destroy(&display->reader_cond);
	close(display->fd);

	free(display);
}

/** Get a display context's file descriptor
 *
 * \param display The display context object
 * \return Display object file descriptor
 *
 * Return the file descriptor associated with a display so it can be
 * integrated into the client's main loop.
 *
 * \memberof wl_display
 */
WL_EXPORT int
wl_display_get_fd(struct wl_display *display)
{
	return display->fd;
}

static void
sync_callback(void *data, struct wl_callback *callback, uint32_t serial)
{
	int *done = data;

	*done = 1;
	wl_callback_destroy(callback);
}

static const struct wl_callback_listener sync_listener = {
	sync_callback
};

/** Block until all pending request are processed by the server
 *
 * \param display The display context object
 * \param queue The queue on which to run the roundtrip
 * \return The number of dispatched events on success or -1 on failure
 *
 * This function blocks until the server has processed all currently issued
 * requests by sending a request to the display server and waiting for a
 * reply before returning.
 *
 * This function uses wl_display_dispatch_queue() internally. It is not allowed
 * to call this function while the thread is being prepared for reading events,
 * and doing so will cause a dead lock.
 *
 * \note This function may dispatch other events being received on the given
 * queue.
 *
 * \sa wl_display_roundtrip()
 * \memberof wl_display
 */
WL_EXPORT int
wl_display_roundtrip_queue(struct wl_display *display, struct wl_event_queue *queue)
{
	struct wl_display *display_wrapper;
	struct wl_callback *callback;
	int done, ret = 0;

	done = 0;

	display_wrapper = wl_proxy_create_wrapper(display);
	if (!display_wrapper)
		return -1;

	wl_proxy_set_queue((struct wl_proxy *) display_wrapper, queue);
	callback = wl_display_sync(display_wrapper);
	wl_proxy_wrapper_destroy(display_wrapper);

	if (callback == NULL)
		return -1;

	wl_callback_add_listener(callback, &sync_listener, &done);
	while (!done && ret >= 0)
		ret = wl_display_dispatch_queue(display, queue);

	if (ret == -1 && !done)
		wl_callback_destroy(callback);

	return ret;
}

/** Block until all pending request are processed by the server
 *
 * \param display The display context object
 * \return The number of dispatched events on success or -1 on failure
 *
 * This function blocks until the server has processed all currently issued
 * requests by sending a request to the display server and waiting for a reply
 * before returning.
 *
 * This function uses wl_display_dispatch_queue() internally. It is not allowed
 * to call this function while the thread is being prepared for reading events,
 * and doing so will cause a dead lock.
 *
 * \note This function may dispatch other events being received on the default
 * queue.
 *
 * \memberof wl_display
 */
WL_EXPORT int
wl_display_roundtrip(struct wl_display *display)
{
	return wl_display_roundtrip_queue(display, &display->default_queue);
}

static int
create_proxies(struct wl_proxy *sender, struct wl_closure *closure)
{
	struct wl_proxy *proxy;
	const char *signature;
	struct argument_details arg;
	uint32_t id;
	int i;
	int count;

	signature = closure->message->signature;
	count = arg_count_for_signature(signature);
	for (i = 0; i < count; i++) {
		signature = get_next_argument(signature, &arg);
		switch (arg.type) {
		case 'n':
			id = closure->args[i].n;
			if (id == 0) {
				closure->args[i].o = NULL;
				break;
			}
			proxy = wl_proxy_create_for_id(sender, id,
						       closure->message->types[i]);
			if (proxy == NULL)
				return -1;
			closure->args[i].o = (struct wl_object *)proxy;
			break;
		default:
			break;
		}
	}

	return 0;
}

static void
increase_closure_args_refcount(struct wl_closure *closure)
{
	const char *signature;
	struct argument_details arg;
	int i, count;
	struct wl_proxy *proxy;

	signature = closure->message->signature;
	count = arg_count_for_signature(signature);
	for (i = 0; i < count; i++) {
		signature = get_next_argument(signature, &arg);
		switch (arg.type) {
		case 'n':
		case 'o':
			proxy = (struct wl_proxy *) closure->args[i].o;
			if (proxy)
				proxy->refcount++;
			break;
		default:
			break;
		}
	}
}

static int
queue_event(struct wl_display *display, int len)
{
	uint32_t p[2], id;
	int opcode, size;
	struct wl_proxy *proxy;
	struct wl_closure *closure;
	const struct wl_message *message;
	struct wl_event_queue *queue;

	wl_connection_copy(display->connection, p, sizeof p);
	id = p[0];
	opcode = p[1] & 0xffff;
	size = p[1] >> 16;
	if (len < size)
		return 0;

	proxy = wl_map_lookup(&display->objects, id);
	if (!proxy || wl_object_is_zombie(&display->objects, id)) {
		wl_connection_consume(display->connection, size);
		return size;
	}

	message = &proxy->object.interface->events[opcode];
	closure = wl_connection_demarshal(display->connection, size,
					  &display->objects, message);
	if (!closure)
		return -1;

	if (create_proxies(proxy, closure) < 0) {
		wl_closure_destroy(closure);
		return -1;
	}

	if (wl_closure_lookup_objects(closure, &display->objects) != 0) {
		wl_closure_destroy(closure);
		return -1;
	}

	increase_closure_args_refcount(closure);
	proxy->refcount++;
	closure->proxy = proxy;

	if (proxy == &display->proxy)
		queue = &display->display_queue;
	else
		queue = proxy->queue;

	wl_list_insert(queue->event_list.prev, &closure->link);

	return size;
}

static void
dispatch_event(struct wl_display *display, struct wl_event_queue *queue)
{
	struct wl_closure *closure;
	struct wl_proxy *proxy;
	int opcode;
	bool proxy_destroyed;

	closure = container_of(queue->event_list.next,
			       struct wl_closure, link);
	wl_list_remove(&closure->link);
	opcode = closure->opcode;

	/* Verify that the receiving object is still valid by checking if has
	 * been destroyed by the application. */

	decrease_closure_args_refcount(closure);
	proxy = closure->proxy;
	proxy_destroyed = !!(proxy->flags & WL_PROXY_FLAG_DESTROYED);

	proxy->refcount--;
	if (proxy_destroyed) {
		if (!proxy->refcount)
			free(proxy);

		wl_closure_destroy(closure);
		return;
	}

	pthread_mutex_unlock(&display->mutex);

	if (proxy->dispatcher) {
		if (debug_client)
			wl_closure_print(closure, &proxy->object, false);

		wl_closure_dispatch(closure, proxy->dispatcher,
				    &proxy->object, opcode);
	} else if (proxy->object.implementation) {
		if (debug_client)
			wl_closure_print(closure, &proxy->object, false);

		wl_closure_invoke(closure, WL_CLOSURE_INVOKE_CLIENT,
				  &proxy->object, opcode, proxy->user_data);
	}

	wl_closure_destroy(closure);

	pthread_mutex_lock(&display->mutex);
}

static int
read_events(struct wl_display *display)
{
	int total, rem, size;
	uint32_t serial;

	display->reader_count--;
	if (display->reader_count == 0) {
		total = wl_connection_read(display->connection);
		if (total == -1) {
			if (errno == EAGAIN) {
				/* we must wake up threads whenever
				 * the reader_count dropped to 0 */
				display_wakeup_threads(display);

				return 0;
			}

			display_fatal_error(display, errno);
			return -1;
		} else if (total == 0) {
			/* The compositor has closed the socket. This
			 * should be considered an error so we'll fake
			 * an errno */
			errno = EPIPE;
			display_fatal_error(display, errno);
			return -1;
		}

		for (rem = total; rem >= 8; rem -= size) {
			size = queue_event(display, rem);
			if (size == -1) {
				display_fatal_error(display, errno);
				return -1;
			} else if (size == 0) {
				break;
			}
		}

		display_wakeup_threads(display);
	} else {
		serial = display->read_serial;
		while (display->read_serial == serial)
			pthread_cond_wait(&display->reader_cond,
					  &display->mutex);

		if (display->last_error) {
			errno = display->last_error;
			return -1;
		}
	}

	return 0;
}

static void
cancel_read(struct wl_display *display)
{
	display->reader_count--;
	if (display->reader_count == 0)
		display_wakeup_threads(display);
}

/** Read events from display file descriptor
 *
 * \param display The display context object
 * \return 0 on success or -1 on error.  In case of error errno will
 * be set accordingly
 *
 * Calling this function will result in data available on the display file
 * descriptor being read and read events will be queued on their corresponding
 * event queues.
 *
 * Before calling this function, depending on what thread it is to be called
 * from, wl_display_prepare_read_queue() or wl_display_prepare_read() needs to
 * be called. See wl_display_prepare_read_queue() for more details.
 *
 * When being called at a point where other threads have been prepared to read
 * (using wl_display_prepare_read_queue() or wl_display_prepare_read()) this
 * function will sleep until all other prepared threads have either been
 * cancelled (using wl_display_cancel_read()) or them self entered this
 * function. The last thread that calls this function will then read and queue
 * events on their corresponding event queues, and finally wake up all other
 * wl_display_read_events() calls causing them to return.
 *
 * If a thread cancels a read preparation when all other threads that have
 * prepared to read has either called wl_display_cancel_read() or
 * wl_display_read_events(), all reader threads will return without having read
 * any data.
 *
 * To dispatch events that may have been queued, call
 * wl_display_dispatch_pending() or wl_display_dispatch_queue_pending().
 *
 * \sa wl_display_prepare_read(), wl_display_cancel_read(),
 * wl_display_dispatch_pending(), wl_display_dispatch()
 *
 * \memberof wl_display
 */
WL_EXPORT int
wl_display_read_events(struct wl_display *display)
{
	int ret;

	pthread_mutex_lock(&display->mutex);

	if (display->last_error) {
		cancel_read(display);
		pthread_mutex_unlock(&display->mutex);

		errno = display->last_error;
		return -1;
	}

	ret = read_events(display);

	pthread_mutex_unlock(&display->mutex);

	return ret;
}

static int
dispatch_queue(struct wl_display *display, struct wl_event_queue *queue)
{
	int count;

	if (display->last_error)
		goto err;

	count = 0;
	while (!wl_list_empty(&display->display_queue.event_list)) {
		dispatch_event(display, &display->display_queue);
		if (display->last_error)
			goto err;
		count++;
	}

	while (!wl_list_empty(&queue->event_list)) {
		dispatch_event(display, queue);
		if (display->last_error)
			goto err;
		count++;
	}

	return count;

err:
	errno = display->last_error;

	return -1;
}

/** Prepare to read events from the display's file descriptor to a queue
 *
 * \param display The display context object
 * \param queue The event queue to use
 * \return 0 on success or -1 if event queue was not empty
 *
 * This function (or wl_display_prepare_read()) must be called before reading
 * from the file descriptor using wl_display_read_events(). Calling
 * wl_display_prepare_read_queue() announces the calling thread's intention to
 * read and ensures that until the thread is ready to read and calls
 * wl_display_read_events(), no other thread will read from the file descriptor.
 * This only succeeds if the event queue is empty, and if not -1 is returned and
 * errno set to EAGAIN.
 *
 * If a thread successfully calls wl_display_prepare_read_queue(), it must
 * either call wl_display_read_events() when it's ready or cancel the read
 * intention by calling wl_display_cancel_read().
 *
 * Use this function before polling on the display fd or integrate the fd into a
 * toolkit event loop in a race-free way. A correct usage would be (with most
 * error checking left out):
 *
 * \code
 * while (wl_display_prepare_read_queue(display, queue) != 0)
 *         wl_display_dispatch_queue_pending(display, queue);
 * wl_display_flush(display);
 *
 * ret = poll(fds, nfds, -1);
 * if (has_error(ret))
 *         wl_display_cancel_read(display);
 * else
 *         wl_display_read_events(display);
 *
 * wl_display_dispatch_queue_pending(display, queue);
 * \endcode
 *
 * Here we call wl_display_prepare_read_queue(), which ensures that between
 * returning from that call and eventually calling wl_display_read_events(), no
 * other thread will read from the fd and queue events in our queue. If the call
 * to wl_display_prepare_read_queue() fails, we dispatch the pending events and
 * try again until we're successful.
 *
 * The wl_display_prepare_read_queue() function doesn't acquire exclusive access
 * to the display's fd. It only registers that the thread calling this function
 * has intention to read from fd. When all registered readers call
 * wl_display_read_events(), only one (at random) eventually reads and queues
 * the events and the others are sleeping meanwhile. This way we avoid races and
 * still can read from more threads.
 *
 * \sa wl_display_cancel_read(), wl_display_read_events(),
 * wl_display_prepare_read()
 *
 * \memberof wl_display
 */
WL_EXPORT int
wl_display_prepare_read_queue(struct wl_display *display,
			      struct wl_event_queue *queue)
{
	int ret;

	pthread_mutex_lock(&display->mutex);

	if (!wl_list_empty(&queue->event_list)) {
		errno = EAGAIN;
		ret = -1;
	} else {
		display->reader_count++;
		ret = 0;
	}

	pthread_mutex_unlock(&display->mutex);

	return ret;
}

/** Prepare to read events from the display's file descriptor
 *
 * \param display The display context object
 * \return 0 on success or -1 if event queue was not empty
 *
 * This function does the same thing as wl_display_prepare_read_queue()
 * with the default queue passed as the queue.
 *
 * \sa wl_display_prepare_read_queue
 * \memberof wl_display
 */
WL_EXPORT int
wl_display_prepare_read(struct wl_display *display)
{
	return wl_display_prepare_read_queue(display, &display->default_queue);
}

/** Cancel read intention on display's fd
 *
 * \param display The display context object
 *
 * After a thread successfully called wl_display_prepare_read() it must
 * either call wl_display_read_events() or wl_display_cancel_read().
 * If the threads do not follow this rule it will lead to deadlock.
 *
 * \sa wl_display_prepare_read(), wl_display_read_events()
 *
 * \memberof wl_display
 */
WL_EXPORT void
wl_display_cancel_read(struct wl_display *display)
{
	pthread_mutex_lock(&display->mutex);

	cancel_read(display);

	pthread_mutex_unlock(&display->mutex);
}

static int
wl_display_poll(struct wl_display *display, short int events)
{
	int ret;
	struct pollfd pfd[1];

	pfd[0].fd = display->fd;
	pfd[0].events = events;
	do {
		ret = poll(pfd, 1, -1);
	} while (ret == -1 && errno == EINTR);

	return ret;
}

/** Dispatch events in an event queue
 *
 * \param display The display context object
 * \param queue The event queue to dispatch
 * \return The number of dispatched events on success or -1 on failure
 *
 * Dispatch events on the given event queue.
 *
 * If the given event queue is empty, this function blocks until there are
 * events to be read from the display fd. Events are read and queued on
 * the appropriate event queues. Finally, events on given event queue are
 * dispatched. On failure -1 is returned and errno set appropriately.
 *
 * In a multi threaded environment, do not manually wait using poll() (or
 * equivalent) before calling this function, as doing so might cause a dead
 * lock. If external reliance on poll() (or equivalent) is required, see
 * wl_display_prepare_read_queue() of how to do so.
 *
 * This function is thread safe as long as it dispatches the right queue on the
 * right thread. It is also compatible with the multi thread event reading
 * preparation API (see wl_display_prepare_read_queue()), and uses the
 * equivalent functionality internally. It is not allowed to call this function
 * while the thread is being prepared for reading events, and doing so will
 * cause a dead lock.
 *
 * It can be used as a helper function to ease the procedure of reading and
 * dispatching events.
 *
 * \note Since Wayland 1.5 the display has an extra queue
 * for its own events (i. e. delete_id). This queue is dispatched always,
 * no matter what queue we passed as an argument to this function.
 * That means that this function can return non-0 value even when it
 * haven't dispatched any event for the given queue.
 *
 * \sa wl_display_dispatch(), wl_display_dispatch_pending(),
 * wl_display_dispatch_queue_pending(), wl_display_prepare_read_queue()
 *
 * \memberof wl_display
 */
WL_EXPORT int
wl_display_dispatch_queue(struct wl_display *display,
			  struct wl_event_queue *queue)
{
	int ret;

	if (wl_display_prepare_read_queue(display, queue) == -1)
		return wl_display_dispatch_queue_pending(display, queue);

	while (true) {
		ret = wl_display_flush(display);

		if (ret != -1 || errno != EAGAIN)
			break;

		if (wl_display_poll(display, POLLOUT) == -1) {
			wl_display_cancel_read(display);
			return -1;
		}
	}

	/* Don't stop if flushing hits an EPIPE; continue so we can read any
	 * protocol error that may have triggered it. */
	if (ret < 0 && errno != EPIPE) {
		wl_display_cancel_read(display);
		return -1;
	}

	if (wl_display_poll(display, POLLIN) == -1) {
		wl_display_cancel_read(display);
		return -1;
	}

	if (wl_display_read_events(display) == -1)
		return -1;

	return wl_display_dispatch_queue_pending(display, queue);
}

/** Dispatch pending events in an event queue
 *
 * \param display The display context object
 * \param queue The event queue to dispatch
 * \return The number of dispatched events on success or -1 on failure
 *
 * Dispatch all incoming events for objects assigned to the given
 * event queue. On failure -1 is returned and errno set appropriately.
 * If there are no events queued, this function returns immediately.
 *
 * \memberof wl_display
 * \since 1.0.2
 */
WL_EXPORT int
wl_display_dispatch_queue_pending(struct wl_display *display,
				  struct wl_event_queue *queue)
{
	int ret;

	pthread_mutex_lock(&display->mutex);

	ret = dispatch_queue(display, queue);

	pthread_mutex_unlock(&display->mutex);

	return ret;
}

/** Process incoming events
 *
 * \param display The display context object
 * \return The number of dispatched events on success or -1 on failure
 *
 * Dispatch events on the default event queue.
 *
 * If the default event queue is empty, this function blocks until there are
 * events to be read from the display fd. Events are read and queued on
 * the appropriate event queues. Finally, events on the default event queue
 * are dispatched. On failure -1 is returned and errno set appropriately.
 *
 * In a multi threaded environment, do not manually wait using poll() (or
 * equivalent) before calling this function, as doing so might cause a dead
 * lock. If external reliance on poll() (or equivalent) is required, see
 * wl_display_prepare_read_queue() of how to do so.
 *
 * This function is thread safe as long as it dispatches the right queue on the
 * right thread. It is also compatible with the multi thread event reading
 * preparation API (see wl_display_prepare_read_queue()), and uses the
 * equivalent functionality internally. It is not allowed to call this function
 * while the thread is being prepared for reading events, and doing so will
 * cause a dead lock.
 *
 * \note It is not possible to check if there are events on the queue
 * or not. For dispatching default queue events without blocking, see \ref
 * wl_display_dispatch_pending().
 *
 * \sa wl_display_dispatch_pending(), wl_display_dispatch_queue(),
 * wl_display_read_events()
 *
 * \memberof wl_display
 */
WL_EXPORT int
wl_display_dispatch(struct wl_display *display)
{
	return wl_display_dispatch_queue(display, &display->default_queue);
}

/** Dispatch default queue events without reading from the display fd
 *
 * \param display The display context object
 * \return The number of dispatched events or -1 on failure
 *
 * This function dispatches events on the main event queue. It does not
 * attempt to read the display fd and simply returns zero if the main
 * queue is empty, i.e., it doesn't block.
 *
 * \sa wl_display_dispatch(), wl_display_dispatch_queue(),
 * wl_display_flush()
 *
 * \memberof wl_display
 */
WL_EXPORT int
wl_display_dispatch_pending(struct wl_display *display)
{
	return wl_display_dispatch_queue_pending(display,
						 &display->default_queue);
}

/** Retrieve the last error that occurred on a display
 *
 * \param display The display context object
 * \return The last error that occurred on \c display or 0 if no error occurred
 *
 * Return the last error that occurred on the display. This may be an error sent
 * by the server or caused by the local client.
 *
 * \note Errors are \b fatal. If this function returns non-zero the display
 * can no longer be used.
 *
 * \memberof wl_display
 */
WL_EXPORT int
wl_display_get_error(struct wl_display *display)
{
	int ret;

	pthread_mutex_lock(&display->mutex);

	ret = display->last_error;

	pthread_mutex_unlock(&display->mutex);

	return ret;
}

/** Retrieves the information about a protocol error:
 *
 * \param display    The Wayland display
 * \param interface  if not NULL, stores the interface where the error occurred,
 *                   or NULL, if unknown.
 * \param id         if not NULL, stores the object id that generated
 *                   the error, or 0, if the object id is unknown. There's no
 *                   guarantee the object is still valid; the client must know
 *                   if it deleted the object.
 * \return           The error code as defined in the interface specification.
 *
 * \code
 * int err = wl_display_get_error(display);
 *
 * if (err == EPROTO) {
 *        code = wl_display_get_protocol_error(display, &interface, &id);
 *        handle_error(code, interface, id);
 * }
 *
 * ...
 * \endcode
 * \memberof wl_display
 */
WL_EXPORT uint32_t
wl_display_get_protocol_error(struct wl_display *display,
			      const struct wl_interface **interface,
			      uint32_t *id)
{
	uint32_t ret;

	pthread_mutex_lock(&display->mutex);

	ret = display->protocol_error.code;

	if (interface)
		*interface = display->protocol_error.interface;
	if (id)
		*id = display->protocol_error.id;

	pthread_mutex_unlock(&display->mutex);

	return ret;
}


/** Send all buffered requests on the display to the server
 *
 * \param display The display context object
 * \return The number of bytes sent on success or -1 on failure
 *
 * Send all buffered data on the client side to the server. Clients should
 * always call this function before blocking on input from the display fd.
 * On success, the number of bytes sent to the server is returned. On
 * failure, this function returns -1 and errno is set appropriately.
 *
 * wl_display_flush() never blocks.  It will write as much data as
 * possible, but if all data could not be written, errno will be set
 * to EAGAIN and -1 returned.  In that case, use poll on the display
 * file descriptor to wait for it to become writable again.
 *
 * \memberof wl_display
 */
WL_EXPORT int
wl_display_flush(struct wl_display *display)
{
	int ret;

	pthread_mutex_lock(&display->mutex);

	if (display->last_error) {
		errno = display->last_error;
		ret = -1;
	} else {
		/* We don't make EPIPE a fatal error here, so that we may try to
		 * read events after the failed flush. When the compositor sends
		 * an error it will close the socket, and if we make EPIPE fatal
		 * here we don't get a chance to process the error. */
		ret = wl_connection_flush(display->connection);
		if (ret < 0 && errno != EAGAIN && errno != EPIPE)
			display_fatal_error(display, errno);
	}

	pthread_mutex_unlock(&display->mutex);

	return ret;
}

/** Set the user data associated with a proxy
 *
 * \param proxy The proxy object
 * \param user_data The data to be associated with proxy
 *
 * Set the user data associated with \c proxy. When events for this
 * proxy are received, \c user_data will be supplied to its listener.
 *
 * \memberof wl_proxy
 */
WL_EXPORT void
wl_proxy_set_user_data(struct wl_proxy *proxy, void *user_data)
{
	proxy->user_data = user_data;
}

/** Get the user data associated with a proxy
 *
 * \param proxy The proxy object
 * \return The user data associated with proxy
 *
 * \memberof wl_proxy
 */
WL_EXPORT void *
wl_proxy_get_user_data(struct wl_proxy *proxy)
{
	return proxy->user_data;
}

/** Get the protocol object version of a proxy object
 *
 * \param proxy The proxy object
 * \return The protocol object version of the proxy or 0
 *
 * Gets the protocol object version of a proxy object, or 0
 * if the proxy was created with unversioned API.
 *
 * A returned value of 0 means that no version information is
 * available, so the caller must make safe assumptions about
 * the object's real version.
 *
 * wl_display's version will always return 0.
 *
 * \memberof wl_proxy
 */
WL_EXPORT uint32_t
wl_proxy_get_version(struct wl_proxy *proxy)
{
	return proxy->version;
}

/** Get the id of a proxy object
 *
 * \param proxy The proxy object
 * \return The id the object associated with the proxy
 *
 * \memberof wl_proxy
 */
WL_EXPORT uint32_t
wl_proxy_get_id(struct wl_proxy *proxy)
{
	return proxy->object.id;
}

/** Get the interface name (class) of a proxy object
 *
 * \param proxy The proxy object
 * \return The interface name of the object associated with the proxy
 *
 * \memberof wl_proxy
 */
WL_EXPORT const char *
wl_proxy_get_class(struct wl_proxy *proxy)
{
	return proxy->object.interface->name;
}

/** Assign a proxy to an event queue
 *
 * \param proxy The proxy object
 * \param queue The event queue that will handle this proxy or NULL
 *
 * Assign proxy to event queue. Events coming from \c proxy will be
 * queued in \c queue from now. If queue is NULL, then the display's
 * default queue is set to the proxy.
 *
 * \note By default, the queue set in proxy is the one inherited from parent.
 *
 * \sa wl_display_dispatch_queue()
 *
 * \memberof wl_proxy
 */
WL_EXPORT void
wl_proxy_set_queue(struct wl_proxy *proxy, struct wl_event_queue *queue)
{
	if (queue)
		proxy->queue = queue;
	else
		proxy->queue = &proxy->display->default_queue;
}

/** Create a proxy wrapper for making queue assignments thread-safe
 *
 * \param proxy The proxy object to be wrapped
 * \return A proxy wrapper for the given proxy or NULL on failure
 *
 * A proxy wrapper is type of 'struct wl_proxy' instance that can be used when
 * sending requests instead of using the original proxy. A proxy wrapper does
 * not have an implementation or dispatcher, and events received on the
 * object is still emitted on the original proxy. Trying to set an
 * implementation or dispatcher will have no effect but result in a warning
 * being logged.
 *
 * Setting the proxy queue of the proxy wrapper will make new objects created
 * using the proxy wrapper use the set proxy queue.
 * Even though there is no implementation nor dispatcher, the proxy queue can
 * be changed. This will affect the default queue of new objects created by
 * requests sent via the proxy wrapper.
 *
 * A proxy wrapper can only be destroyed using wl_proxy_wrapper_destroy().
 *
 * A proxy wrapper must be destroyed before the proxy it was created from.
 *
 * If a user reads and dispatches events on more than one thread, it is
 * necessary to use a proxy wrapper when sending requests on objects when the
 * intention is that a newly created proxy is to use a proxy queue different
 * from the proxy the request was sent on, as creating the new proxy and then
 * setting the queue is not thread safe.
 *
 * For example, a module that runs using its own proxy queue that needs to
 * do display roundtrip must wrap the wl_display proxy object before sending
 * the wl_display.sync request. For example:
 *
 * \code
 *
 *   struct wl_event_queue *queue = ...;
 *   struct wl_display *wrapped_display;
 *   struct wl_callback *callback;
 *
 *   wrapped_display = wl_proxy_create_wrapper(display);
 *   wl_proxy_set_queue((struct wl_proxy *) wrapped_display, queue);
 *   callback = wl_display_sync(wrapped_display);
 *   wl_proxy_wrapper_destroy(wrapped_display);
 *   wl_callback_add_listener(callback, ...);
 *
 * \endcode
 *
 * \memberof wl_proxy
 */
WL_EXPORT void *
wl_proxy_create_wrapper(void *proxy)
{
	struct wl_proxy *wrapped_proxy = proxy;
	struct wl_proxy *wrapper;

	wrapper = zalloc(sizeof *wrapper);
	if (!wrapper)
		return NULL;

	pthread_mutex_lock(&wrapped_proxy->display->mutex);

	wrapper->object.interface = wrapped_proxy->object.interface;
	wrapper->object.id = wrapped_proxy->object.id;
	wrapper->version = wrapped_proxy->version;
	wrapper->display = wrapped_proxy->display;
	wrapper->queue = wrapped_proxy->queue;
	wrapper->flags = WL_PROXY_FLAG_WRAPPER;
	wrapper->refcount = 1;

	pthread_mutex_unlock(&wrapped_proxy->display->mutex);

	return wrapper;
}

/** Destroy a proxy wrapper
 * \param proxy_wrapper The proxy wrapper to be destroyed
 *
 * \memberof wl_proxy
 */
WL_EXPORT void
wl_proxy_wrapper_destroy(void *proxy_wrapper)
{
	struct wl_proxy *wrapper = proxy_wrapper;

	if (!(wrapper->flags & WL_PROXY_FLAG_WRAPPER))
		wl_abort("Tried to destroy non-wrapper proxy with "
			 "wl_proxy_wrapper_destroy\n");

	assert(wrapper->refcount == 1);

	free(wrapper);
}

WL_EXPORT void
wl_log_set_handler_client(wl_log_func_t handler)
{
	wl_log_handler = handler;
}
