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

#ifndef WAYLAND_PRIVATE_H
#define WAYLAND_PRIVATE_H

#include <stdarg.h>
#include <stdlib.h>
#include <stdint.h>

#define WL_HIDE_DEPRECATED 1

#include "wayland-util.h"

/* Invalid memory address */
#define WL_ARRAY_POISON_PTR (void *) 4

#define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0])

#define container_of(ptr, type, member) ({				\
	const __typeof__( ((type *)0)->member ) *__mptr = (ptr);	\
	(type *)( (char *)__mptr - offsetof(type,member) );})

#define WL_MAP_SERVER_SIDE 0
#define WL_MAP_CLIENT_SIDE 1
#define WL_SERVER_ID_START 0xff000000
#define WL_CLOSURE_MAX_ARGS 20

struct wl_object {
	const struct wl_interface *interface;
	const void *implementation;
	uint32_t id;
};

extern struct wl_object global_zombie_object;
#define WL_ZOMBIE_OBJECT ((void*)&global_zombie_object)

int
wl_interface_equal(const struct wl_interface *iface1,
		   const struct wl_interface *iface2);

/* Flags for wl_map_insert_new and wl_map_insert_at.  Flags can be queried with
 * wl_map_lookup_flags.  The current implementation has room for 1 bit worth of
 * flags.  If more flags are ever added, the implementation of wl_map will have
 * to change to allow for new flags */
enum wl_map_entry_flags {
	WL_MAP_ENTRY_LEGACY = (1 << 0)
};

struct wl_map {
	struct wl_array client_entries;
	struct wl_array server_entries;
	uint32_t side;
	uint32_t free_list;
};

typedef enum wl_iterator_result (*wl_iterator_func_t)(void *element,
						      void *data);

void
wl_map_init(struct wl_map *map, uint32_t side);

void
wl_map_release(struct wl_map *map);

uint32_t
wl_map_insert_new(struct wl_map *map, uint32_t flags, void *data);

int
wl_map_insert_at(struct wl_map *map, uint32_t flags, uint32_t i, void *data);

int
wl_map_reserve_new(struct wl_map *map, uint32_t i);

void
wl_map_remove(struct wl_map *map, uint32_t i);

void *
wl_map_lookup(struct wl_map *map, uint32_t i);

uint32_t
wl_map_lookup_flags(struct wl_map *map, uint32_t i);

void
wl_map_for_each(struct wl_map *map, wl_iterator_func_t func, void *data);

struct wl_connection *
wl_connection_create(int fd);

int
wl_connection_destroy(struct wl_connection *connection);

void
wl_connection_copy(struct wl_connection *connection, void *data, size_t size);

void
wl_connection_consume(struct wl_connection *connection, size_t size);

int
wl_connection_flush(struct wl_connection *connection);

uint32_t
wl_connection_pending_input(struct wl_connection *connection);

int
wl_connection_read(struct wl_connection *connection);

int
wl_connection_write(struct wl_connection *connection,
		    const void *data, size_t count);

int
wl_connection_queue(struct wl_connection *connection,
		    const void *data, size_t count);

int
wl_connection_get_fd(struct wl_connection *connection);

struct wl_closure {
	int count;
	const struct wl_message *message;
	uint32_t opcode;
	uint32_t sender_id;
	union wl_argument args[WL_CLOSURE_MAX_ARGS];
	struct wl_list link;
	struct wl_proxy *proxy;
	struct wl_array extra[0];
};

struct argument_details {
	char type;
	int nullable;
};

const char *
get_next_argument(const char *signature, struct argument_details *details);

int
arg_count_for_signature(const char *signature);

int
wl_message_count_arrays(const struct wl_message *message);

int
wl_message_get_since(const struct wl_message *message);

void
wl_argument_from_va_list(const char *signature, union wl_argument *args,
			 int count, va_list ap);

struct wl_closure *
wl_closure_marshal(struct wl_object *sender,
		    uint32_t opcode, union wl_argument *args,
		    const struct wl_message *message);

struct wl_closure *
wl_closure_vmarshal(struct wl_object *sender,
		    uint32_t opcode, va_list ap,
		    const struct wl_message *message);

struct wl_closure *
wl_connection_demarshal(struct wl_connection *connection,
			uint32_t size,
			struct wl_map *objects,
			const struct wl_message *message);

int
wl_closure_lookup_objects(struct wl_closure *closure, struct wl_map *objects);

enum wl_closure_invoke_flag {
	WL_CLOSURE_INVOKE_CLIENT = (1 << 0),
	WL_CLOSURE_INVOKE_SERVER = (1 << 1)
};

void
wl_closure_invoke(struct wl_closure *closure, uint32_t flags,
		  struct wl_object *target, uint32_t opcode, void *data);

void
wl_closure_dispatch(struct wl_closure *closure, wl_dispatcher_func_t dispatcher,
		    struct wl_object *target, uint32_t opcode);

int
wl_closure_send(struct wl_closure *closure, struct wl_connection *connection);

int
wl_closure_queue(struct wl_closure *closure, struct wl_connection *connection);

void
wl_closure_print(struct wl_closure *closure,
		 struct wl_object *target, int send);

void
wl_closure_destroy(struct wl_closure *closure);

extern wl_log_func_t wl_log_handler;

void wl_log(const char *fmt, ...);
void wl_abort(const char *fmt, ...);

struct wl_display;

struct wl_array *
wl_display_get_additional_shm_formats(struct wl_display *display);

static inline void *
zalloc(size_t s)
{
	return calloc(1, s);
}

#endif
