summaryrefslogtreecommitdiffstats
path: root/src/3rdparty
diff options
context:
space:
mode:
authorJørgen Lind <jorgen.lind@nokia.com>2011-03-02 13:26:40 +0100
committerJørgen Lind <jorgen.lind@nokia.com>2011-03-02 13:46:19 +0100
commit1691e9ed575bf21121da522acb388f99c4771fc8 (patch)
tree830fedad558bb531c80ec47cd2e63ec1b9f3a840 /src/3rdparty
Initial commit for the Qt-Compositor.
The project goal is to be a toolbox which all Qt based Wayland compositors use. Initial work is done by: Samuel Rødal <samuel.rodal@nokia.com> Paul Olav Tvete <paul.tvete@nokia.com> and myself
Diffstat (limited to 'src/3rdparty')
-rw-r--r--src/3rdparty/ffi-arm/LICENSE21
-rw-r--r--src/3rdparty/ffi-arm/ffi.c309
-rw-r--r--src/3rdparty/ffi-arm/ffi.h399
-rw-r--r--src/3rdparty/ffi-arm/ffi.pro13
-rw-r--r--src/3rdparty/ffi-arm/ffi_common.h122
-rw-r--r--src/3rdparty/ffi-arm/fficonfig.h182
-rw-r--r--src/3rdparty/ffi-arm/ffitarget.h49
-rw-r--r--src/3rdparty/ffi-arm/prep_cif.c174
-rw-r--r--src/3rdparty/ffi-arm/sysv.S306
-rw-r--r--src/3rdparty/ffi-arm/types.c77
-rw-r--r--src/3rdparty/wayland/client/client.pro19
-rw-r--r--src/3rdparty/wayland/connection.c729
-rw-r--r--src/3rdparty/wayland/connection.h68
-rw-r--r--src/3rdparty/wayland/event-loop.c444
-rw-r--r--src/3rdparty/wayland/server/server.pro20
-rw-r--r--src/3rdparty/wayland/wayland-client-protocol.h919
-rw-r--r--src/3rdparty/wayland/wayland-client.c565
-rw-r--r--src/3rdparty/wayland/wayland-client.h75
-rw-r--r--src/3rdparty/wayland/wayland-egl.h82
-rw-r--r--src/3rdparty/wayland/wayland-hash.c296
-rw-r--r--src/3rdparty/wayland/wayland-protocol.c228
-rw-r--r--src/3rdparty/wayland/wayland-server-protocol.h265
-rw-r--r--src/3rdparty/wayland/wayland-server.c726
-rw-r--r--src/3rdparty/wayland/wayland-server.h265
-rw-r--r--src/3rdparty/wayland/wayland-util.c123
-rw-r--r--src/3rdparty/wayland/wayland-util.h157
-rw-r--r--src/3rdparty/wayland/wayland.pro3
27 files changed, 6636 insertions, 0 deletions
diff --git a/src/3rdparty/ffi-arm/LICENSE b/src/3rdparty/ffi-arm/LICENSE
new file mode 100644
index 000000000..ec2fd6948
--- /dev/null
+++ b/src/3rdparty/ffi-arm/LICENSE
@@ -0,0 +1,21 @@
+libffi - Copyright (c) 1996-2009 Anthony Green, Red Hat, Inc and others.
+See source files for details.
+
+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 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.
diff --git a/src/3rdparty/ffi-arm/ffi.c b/src/3rdparty/ffi-arm/ffi.c
new file mode 100644
index 000000000..f6a64758f
--- /dev/null
+++ b/src/3rdparty/ffi-arm/ffi.c
@@ -0,0 +1,309 @@
+/* -----------------------------------------------------------------------
+ ffi.c - Copyright (c) 1998, 2008 Red Hat, Inc.
+
+ ARM Foreign Function Interface
+
+ 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 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 <ffi.h>
+#include <ffi_common.h>
+
+#include <stdlib.h>
+
+/* ffi_prep_args is called by the assembly routine once stack space
+ has been allocated for the function's arguments */
+
+void ffi_prep_args(char *stack, extended_cif *ecif)
+{
+ register unsigned int i;
+ register void **p_argv;
+ register char *argp;
+ register ffi_type **p_arg;
+
+ argp = stack;
+
+ if ( ecif->cif->flags == FFI_TYPE_STRUCT ) {
+ *(void **) argp = ecif->rvalue;
+ argp += 4;
+ }
+
+ p_argv = ecif->avalue;
+
+ for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
+ (i != 0);
+ i--, p_arg++)
+ {
+ size_t z;
+
+ /* Align if necessary */
+ if (((*p_arg)->alignment - 1) & (unsigned) argp) {
+ argp = (char *) ALIGN(argp, (*p_arg)->alignment);
+ }
+
+ if ((*p_arg)->type == FFI_TYPE_STRUCT)
+ argp = (char *) ALIGN(argp, 4);
+
+ z = (*p_arg)->size;
+ if (z < sizeof(int))
+ {
+ z = sizeof(int);
+ switch ((*p_arg)->type)
+ {
+ case FFI_TYPE_SINT8:
+ *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_UINT8:
+ *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_SINT16:
+ *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_UINT16:
+ *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_STRUCT:
+ memcpy(argp, *p_argv, (*p_arg)->size);
+ break;
+
+ default:
+ FFI_ASSERT(0);
+ }
+ }
+ else if (z == sizeof(int))
+ {
+ *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
+ }
+ else
+ {
+ memcpy(argp, *p_argv, z);
+ }
+ p_argv++;
+ argp += z;
+ }
+
+ return;
+}
+
+/* Perform machine dependent cif processing */
+ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
+{
+ /* Round the stack up to a multiple of 8 bytes. This isn't needed
+ everywhere, but it is on some platforms, and it doesn't harm anything
+ when it isn't needed. */
+ cif->bytes = (cif->bytes + 7) & ~7;
+
+ /* Set the return type flag */
+ switch (cif->rtype->type)
+ {
+ case FFI_TYPE_VOID:
+ case FFI_TYPE_FLOAT:
+ case FFI_TYPE_DOUBLE:
+ cif->flags = (unsigned) cif->rtype->type;
+ break;
+
+ case FFI_TYPE_SINT64:
+ case FFI_TYPE_UINT64:
+ cif->flags = (unsigned) FFI_TYPE_SINT64;
+ break;
+
+ case FFI_TYPE_STRUCT:
+ if (cif->rtype->size <= 4)
+ /* A Composite Type not larger than 4 bytes is returned in r0. */
+ cif->flags = (unsigned)FFI_TYPE_INT;
+ else
+ /* A Composite Type larger than 4 bytes, or whose size cannot
+ be determined statically ... is stored in memory at an
+ address passed [in r0]. */
+ cif->flags = (unsigned)FFI_TYPE_STRUCT;
+ break;
+
+ default:
+ cif->flags = FFI_TYPE_INT;
+ break;
+ }
+
+ return FFI_OK;
+}
+
+extern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *,
+ unsigned, unsigned, unsigned *, void (*fn)(void));
+
+void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
+{
+ extended_cif ecif;
+
+ int small_struct = (cif->flags == FFI_TYPE_INT
+ && cif->rtype->type == FFI_TYPE_STRUCT);
+
+ ecif.cif = cif;
+ ecif.avalue = avalue;
+
+ unsigned int temp;
+
+ /* If the return value is a struct and we don't have a return */
+ /* value address then we need to make one */
+
+ if ((rvalue == NULL) &&
+ (cif->flags == FFI_TYPE_STRUCT))
+ {
+ ecif.rvalue = alloca(cif->rtype->size);
+ }
+ else if (small_struct)
+ ecif.rvalue = &temp;
+ else
+ ecif.rvalue = rvalue;
+
+ switch (cif->abi)
+ {
+ case FFI_SYSV:
+ ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue,
+ fn);
+
+ break;
+ default:
+ FFI_ASSERT(0);
+ break;
+ }
+ if (small_struct)
+ memcpy (rvalue, &temp, cif->rtype->size);
+}
+
+/** private members **/
+
+static void ffi_prep_incoming_args_SYSV (char *stack, void **ret,
+ void** args, ffi_cif* cif);
+
+void ffi_closure_SYSV (ffi_closure *);
+
+/* This function is jumped to by the trampoline */
+
+unsigned int
+ffi_closure_SYSV_inner (closure, respp, args)
+ ffi_closure *closure;
+ void **respp;
+ void *args;
+{
+ // our various things...
+ ffi_cif *cif;
+ void **arg_area;
+
+ cif = closure->cif;
+ arg_area = (void**) alloca (cif->nargs * sizeof (void*));
+
+ /* this call will initialize ARG_AREA, such that each
+ * element in that array points to the corresponding
+ * value on the stack; and if the function returns
+ * a structure, it will re-set RESP to point to the
+ * structure return address. */
+
+ ffi_prep_incoming_args_SYSV(args, respp, arg_area, cif);
+
+ (closure->fun) (cif, *respp, arg_area, closure->user_data);
+
+ return cif->flags;
+}
+
+/*@-exportheader@*/
+static void
+ffi_prep_incoming_args_SYSV(char *stack, void **rvalue,
+ void **avalue, ffi_cif *cif)
+/*@=exportheader@*/
+{
+ register unsigned int i;
+ register void **p_argv;
+ register char *argp;
+ register ffi_type **p_arg;
+
+ argp = stack;
+
+ if ( cif->flags == FFI_TYPE_STRUCT ) {
+ *rvalue = *(void **) argp;
+ argp += 4;
+ }
+
+ p_argv = avalue;
+
+ for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++)
+ {
+ size_t z;
+
+ size_t alignment = (*p_arg)->alignment;
+ if (alignment < 4)
+ alignment = 4;
+ /* Align if necessary */
+ if ((alignment - 1) & (unsigned) argp) {
+ argp = (char *) ALIGN(argp, alignment);
+ }
+
+ z = (*p_arg)->size;
+
+ /* because we're little endian, this is what it turns into. */
+
+ *p_argv = (void*) argp;
+
+ p_argv++;
+ argp += z;
+ }
+
+ return;
+}
+
+/* How to make a trampoline. */
+
+#define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX) \
+({ unsigned char *__tramp = (unsigned char*)(TRAMP); \
+ unsigned int __fun = (unsigned int)(FUN); \
+ unsigned int __ctx = (unsigned int)(CTX); \
+ *(unsigned int*) &__tramp[0] = 0xe92d000f; /* stmfd sp!, {r0-r3} */ \
+ *(unsigned int*) &__tramp[4] = 0xe59f0000; /* ldr r0, [pc] */ \
+ *(unsigned int*) &__tramp[8] = 0xe59ff000; /* ldr pc, [pc] */ \
+ *(unsigned int*) &__tramp[12] = __ctx; \
+ *(unsigned int*) &__tramp[16] = __fun; \
+ __clear_cache((&__tramp[0]), (&__tramp[19])); \
+ })
+
+
+/* the cif must already be prep'ed */
+
+ffi_status
+ffi_prep_closure_loc (ffi_closure* closure,
+ ffi_cif* cif,
+ void (*fun)(ffi_cif*,void*,void**,void*),
+ void *user_data,
+ void *codeloc)
+{
+ FFI_ASSERT (cif->abi == FFI_SYSV);
+
+ FFI_INIT_TRAMPOLINE (&closure->tramp[0], \
+ &ffi_closure_SYSV, \
+ codeloc);
+
+ closure->cif = cif;
+ closure->user_data = user_data;
+ closure->fun = fun;
+
+ return FFI_OK;
+}
diff --git a/src/3rdparty/ffi-arm/ffi.h b/src/3rdparty/ffi-arm/ffi.h
new file mode 100644
index 000000000..1f578d9a6
--- /dev/null
+++ b/src/3rdparty/ffi-arm/ffi.h
@@ -0,0 +1,399 @@
+/* -----------------------------------------------------------------*-C-*-
+ libffi 3.0.9 - Copyright (c) 1996-2003, 2007, 2008 Red Hat, Inc.
+
+ 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 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.
+
+ ----------------------------------------------------------------------- */
+
+/* -------------------------------------------------------------------
+ The basic API is described in the README file.
+
+ The raw API is designed to bypass some of the argument packing
+ and unpacking on architectures for which it can be avoided.
+
+ The closure API allows interpreted functions to be packaged up
+ inside a C function pointer, so that they can be called as C functions,
+ with no understanding on the client side that they are interpreted.
+ It can also be used in other cases in which it is necessary to package
+ up a user specified parameter and a function pointer as a single
+ function pointer.
+
+ The closure API must be implemented in order to get its functionality,
+ e.g. for use by gij. Routines are provided to emulate the raw API
+ if the underlying platform doesn't allow faster implementation.
+
+ More details on the raw and cloure API can be found in:
+
+ http://gcc.gnu.org/ml/java/1999-q3/msg00138.html
+
+ and
+
+ http://gcc.gnu.org/ml/java/1999-q3/msg00174.html
+ -------------------------------------------------------------------- */
+
+#ifndef LIBFFI_H
+#define LIBFFI_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Specify which architecture libffi is configured for. */
+#define ARM
+
+/* ---- System configuration information --------------------------------- */
+
+#include <ffitarget.h>
+
+#ifndef LIBFFI_ASM
+
+#ifdef _MSC_VER
+#define __attribute__(X)
+#endif
+
+#include <stddef.h>
+#include <limits.h>
+
+/* LONG_LONG_MAX is not always defined (not if STRICT_ANSI, for example).
+ But we can find it either under the correct ANSI name, or under GNU
+ C's internal name. */
+#ifdef LONG_LONG_MAX
+# define FFI_LONG_LONG_MAX LONG_LONG_MAX
+#else
+# ifdef LLONG_MAX
+# define FFI_LONG_LONG_MAX LLONG_MAX
+# else
+# ifdef __GNUC__
+# define FFI_LONG_LONG_MAX __LONG_LONG_MAX__
+# endif
+# endif
+#endif
+
+/* The closure code assumes that this works on pointers, i.e. a size_t */
+/* can hold a pointer. */
+
+typedef struct _ffi_type
+{
+ size_t size;
+ unsigned short alignment;
+ unsigned short type;
+ struct _ffi_type **elements;
+} ffi_type;
+
+#ifndef LIBFFI_HIDE_BASIC_TYPES
+#if SCHAR_MAX == 127
+# define ffi_type_uchar ffi_type_uint8
+# define ffi_type_schar ffi_type_sint8
+#else
+ #error "char size not supported"
+#endif
+
+#if SHRT_MAX == 32767
+# define ffi_type_ushort ffi_type_uint16
+# define ffi_type_sshort ffi_type_sint16
+#elif SHRT_MAX == 2147483647
+# define ffi_type_ushort ffi_type_uint32
+# define ffi_type_sshort ffi_type_sint32
+#else
+ #error "short size not supported"
+#endif
+
+#if INT_MAX == 32767
+# define ffi_type_uint ffi_type_uint16
+# define ffi_type_sint ffi_type_sint16
+#elif INT_MAX == 2147483647
+# define ffi_type_uint ffi_type_uint32
+# define ffi_type_sint ffi_type_sint32
+#elif INT_MAX == 9223372036854775807
+# define ffi_type_uint ffi_type_uint64
+# define ffi_type_sint ffi_type_sint64
+#else
+ #error "int size not supported"
+#endif
+
+#if LONG_MAX == 2147483647
+# if FFI_LONG_LONG_MAX != 9223372036854775807
+ #error "no 64-bit data type supported"
+# endif
+#elif LONG_MAX != 9223372036854775807
+ #error "long size not supported"
+#endif
+
+#if LONG_MAX == 2147483647
+# define ffi_type_ulong ffi_type_uint32
+# define ffi_type_slong ffi_type_sint32
+#elif LONG_MAX == 9223372036854775807
+# define ffi_type_ulong ffi_type_uint64
+# define ffi_type_slong ffi_type_sint64
+#else
+ #error "long size not supported"
+#endif
+
+/* These are defined in types.c */
+extern ffi_type ffi_type_void;
+extern ffi_type ffi_type_uint8;
+extern ffi_type ffi_type_sint8;
+extern ffi_type ffi_type_uint16;
+extern ffi_type ffi_type_sint16;
+extern ffi_type ffi_type_uint32;
+extern ffi_type ffi_type_sint32;
+extern ffi_type ffi_type_uint64;
+extern ffi_type ffi_type_sint64;
+extern ffi_type ffi_type_float;
+extern ffi_type ffi_type_double;
+extern ffi_type ffi_type_pointer;
+
+#if 1
+extern ffi_type ffi_type_longdouble;
+#else
+#define ffi_type_longdouble ffi_type_double
+#endif
+#endif /* LIBFFI_HIDE_BASIC_TYPES */
+
+typedef enum {
+ FFI_OK = 0,
+ FFI_BAD_TYPEDEF,
+ FFI_BAD_ABI
+} ffi_status;
+
+typedef unsigned FFI_TYPE;
+
+typedef struct {
+ ffi_abi abi;
+ unsigned nargs;
+ ffi_type **arg_types;
+ ffi_type *rtype;
+ unsigned bytes;
+ unsigned flags;
+#ifdef FFI_EXTRA_CIF_FIELDS
+ FFI_EXTRA_CIF_FIELDS;
+#endif
+} ffi_cif;
+
+/* ---- Definitions for the raw API -------------------------------------- */
+
+#ifndef FFI_SIZEOF_ARG
+# if LONG_MAX == 2147483647
+# define FFI_SIZEOF_ARG 4
+# elif LONG_MAX == 9223372036854775807
+# define FFI_SIZEOF_ARG 8
+# endif
+#endif
+
+#ifndef FFI_SIZEOF_JAVA_RAW
+# define FFI_SIZEOF_JAVA_RAW FFI_SIZEOF_ARG
+#endif
+
+typedef union {
+ ffi_sarg sint;
+ ffi_arg uint;
+ float flt;
+ char data[FFI_SIZEOF_ARG];
+ void* ptr;
+} ffi_raw;
+
+#if FFI_SIZEOF_JAVA_RAW == 4 && FFI_SIZEOF_ARG == 8
+/* This is a special case for mips64/n32 ABI (and perhaps others) where
+ sizeof(void *) is 4 and FFI_SIZEOF_ARG is 8. */
+typedef union {
+ signed int sint;
+ unsigned int uint;
+ float flt;
+ char data[FFI_SIZEOF_JAVA_RAW];
+ void* ptr;
+} ffi_java_raw;
+#else
+typedef ffi_raw ffi_java_raw;
+#endif
+
+
+void ffi_raw_call (ffi_cif *cif,
+ void (*fn)(void),
+ void *rvalue,
+ ffi_raw *avalue);
+
+void ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw);
+void ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args);
+size_t ffi_raw_size (ffi_cif *cif);
+
+/* This is analogous to the raw API, except it uses Java parameter */
+/* packing, even on 64-bit machines. I.e. on 64-bit machines */
+/* longs and doubles are followed by an empty 64-bit word. */
+
+void ffi_java_raw_call (ffi_cif *cif,
+ void (*fn)(void),
+ void *rvalue,
+ ffi_java_raw *avalue);
+
+void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_java_raw *raw);
+void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_java_raw *raw, void **args);
+size_t ffi_java_raw_size (ffi_cif *cif);
+
+/* ---- Definitions for closures ----------------------------------------- */
+
+#if FFI_CLOSURES
+
+typedef struct {
+ char tramp[FFI_TRAMPOLINE_SIZE];
+ ffi_cif *cif;
+ void (*fun)(ffi_cif*,void*,void**,void*);
+ void *user_data;
+#ifdef __GNUC__
+} ffi_closure __attribute__((aligned (8)));
+#else
+} ffi_closure;
+#endif
+
+void *ffi_closure_alloc (size_t size, void **code);
+void ffi_closure_free (void *);
+
+ffi_status
+ffi_prep_closure (ffi_closure*,
+ ffi_cif *,
+ void (*fun)(ffi_cif*,void*,void**,void*),
+ void *user_data);
+
+ffi_status
+ffi_prep_closure_loc (ffi_closure*,
+ ffi_cif *,
+ void (*fun)(ffi_cif*,void*,void**,void*),
+ void *user_data,
+ void*codeloc);
+
+typedef struct {
+ char tramp[FFI_TRAMPOLINE_SIZE];
+
+ ffi_cif *cif;
+
+#if !FFI_NATIVE_RAW_API
+
+ /* if this is enabled, then a raw closure has the same layout
+ as a regular closure. We use this to install an intermediate
+ handler to do the transaltion, void** -> ffi_raw*. */
+
+ void (*translate_args)(ffi_cif*,void*,void**,void*);
+ void *this_closure;
+
+#endif
+
+ void (*fun)(ffi_cif*,void*,ffi_raw*,void*);
+ void *user_data;
+
+} ffi_raw_closure;
+
+typedef struct {
+ char tramp[FFI_TRAMPOLINE_SIZE];
+
+ ffi_cif *cif;
+
+#if !FFI_NATIVE_RAW_API
+
+ /* if this is enabled, then a raw closure has the same layout
+ as a regular closure. We use this to install an intermediate
+ handler to do the transaltion, void** -> ffi_raw*. */
+
+ void (*translate_args)(ffi_cif*,void*,void**,void*);
+ void *this_closure;
+
+#endif
+
+ void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*);
+ void *user_data;
+
+} ffi_java_raw_closure;
+
+ffi_status
+ffi_prep_raw_closure (ffi_raw_closure*,
+ ffi_cif *cif,
+ void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
+ void *user_data);
+
+ffi_status
+ffi_prep_raw_closure_loc (ffi_raw_closure*,
+ ffi_cif *cif,
+ void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
+ void *user_data,
+ void *codeloc);
+
+ffi_status
+ffi_prep_java_raw_closure (ffi_java_raw_closure*,
+ ffi_cif *cif,
+ void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),
+ void *user_data);
+
+ffi_status
+ffi_prep_java_raw_closure_loc (ffi_java_raw_closure*,
+ ffi_cif *cif,
+ void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),
+ void *user_data,
+ void *codeloc);
+
+#endif /* FFI_CLOSURES */
+
+/* ---- Public interface definition -------------------------------------- */
+
+ffi_status ffi_prep_cif(ffi_cif *cif,
+ ffi_abi abi,
+ unsigned int nargs,
+ ffi_type *rtype,
+ ffi_type **atypes);
+
+void ffi_call(ffi_cif *cif,
+ void (*fn)(void),
+ void *rvalue,
+ void **avalue);
+
+/* Useful for eliminating compiler warnings */
+#define FFI_FN(f) ((void (*)(void))f)
+
+/* ---- Definitions shared with assembly code ---------------------------- */
+
+#endif
+
+/* If these change, update src/mips/ffitarget.h. */
+#define FFI_TYPE_VOID 0
+#define FFI_TYPE_INT 1
+#define FFI_TYPE_FLOAT 2
+#define FFI_TYPE_DOUBLE 3
+#if 1
+#define FFI_TYPE_LONGDOUBLE 4
+#else
+#define FFI_TYPE_LONGDOUBLE FFI_TYPE_DOUBLE
+#endif
+#define FFI_TYPE_UINT8 5
+#define FFI_TYPE_SINT8 6
+#define FFI_TYPE_UINT16 7
+#define FFI_TYPE_SINT16 8
+#define FFI_TYPE_UINT32 9
+#define FFI_TYPE_SINT32 10
+#define FFI_TYPE_UINT64 11
+#define FFI_TYPE_SINT64 12
+#define FFI_TYPE_STRUCT 13
+#define FFI_TYPE_POINTER 14
+
+/* This should always refer to the last type code (for sanity checks) */
+#define FFI_TYPE_LAST FFI_TYPE_POINTER
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/3rdparty/ffi-arm/ffi.pro b/src/3rdparty/ffi-arm/ffi.pro
new file mode 100644
index 000000000..1e9106292
--- /dev/null
+++ b/src/3rdparty/ffi-arm/ffi.pro
@@ -0,0 +1,13 @@
+TEMPLATE = lib
+TARGET = ffi
+DESTDIR=$$PWD/../../../lib/
+
+CONFIG -= qt
+CONFIG += shared
+
+SOURCES = ffi.c \
+ prep_cif.c \
+ types.c \
+ sysv.S
+
+OBJECTS_DIR = .obj
diff --git a/src/3rdparty/ffi-arm/ffi_common.h b/src/3rdparty/ffi-arm/ffi_common.h
new file mode 100644
index 000000000..42cace915
--- /dev/null
+++ b/src/3rdparty/ffi-arm/ffi_common.h
@@ -0,0 +1,122 @@
+/* -----------------------------------------------------------------------
+ ffi_common.h - Copyright (c) 1996 Red Hat, Inc.
+ Copyright (C) 2007 Free Software Foundation, Inc
+
+ Common internal definitions and macros. Only necessary for building
+ libffi.
+ ----------------------------------------------------------------------- */
+
+#ifndef FFI_COMMON_H
+#define FFI_COMMON_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <fficonfig.h>
+
+/* Do not move this. Some versions of AIX are very picky about where
+ this is positioned. */
+#ifdef __GNUC__
+/* mingw64 defines this already in malloc.h. */
+#ifndef alloca
+# define alloca __builtin_alloca
+#endif
+# define MAYBE_UNUSED __attribute__((__unused__))
+#else
+# define MAYBE_UNUSED
+# if HAVE_ALLOCA_H
+# include <alloca.h>
+# else
+# ifdef _AIX
+ #pragma alloca
+# else
+# ifndef alloca /* predefined by HP cc +Olibcalls */
+# ifdef _MSC_VER
+# define alloca _alloca
+# else
+char *alloca ();
+# endif
+# endif
+# endif
+# endif
+#endif
+
+/* Check for the existence of memcpy. */
+#if STDC_HEADERS
+# include <string.h>
+#else
+# ifndef HAVE_MEMCPY
+# define memcpy(d, s, n) bcopy ((s), (d), (n))
+# endif
+#endif
+
+#if defined(FFI_DEBUG)
+#include <stdio.h>
+#endif
+
+#ifdef FFI_DEBUG
+void ffi_assert(char *expr, char *file, int line);
+void ffi_stop_here(void);
+void ffi_type_test(ffi_type *a, char *file, int line);
+
+#define FFI_ASSERT(x) ((x) ? (void)0 : ffi_assert(#x, __FILE__,__LINE__))
+#define FFI_ASSERT_AT(x, f, l) ((x) ? 0 : ffi_assert(#x, (f), (l)))
+#define FFI_ASSERT_VALID_TYPE(x) ffi_type_test (x, __FILE__, __LINE__)
+#else
+#define FFI_ASSERT(x)
+#define FFI_ASSERT_AT(x, f, l)
+#define FFI_ASSERT_VALID_TYPE(x)
+#endif
+
+#define ALIGN(v, a) (((((size_t) (v))-1) | ((a)-1))+1)
+#define ALIGN_DOWN(v, a) (((size_t) (v)) & -a)
+
+/* Perform machine dependent cif processing */
+ffi_status ffi_prep_cif_machdep(ffi_cif *cif);
+
+/* Extended cif, used in callback from assembly routine */
+typedef struct
+{
+ ffi_cif *cif;
+ void *rvalue;
+ void **avalue;
+} extended_cif;
+
+/* Terse sized type definitions. */
+#if defined(_MSC_VER) || defined(__sgi)
+typedef unsigned char UINT8;
+typedef signed char SINT8;
+typedef unsigned short UINT16;
+typedef signed short SINT16;
+typedef unsigned int UINT32;
+typedef signed int SINT32;
+# ifdef _MSC_VER
+typedef unsigned __int64 UINT64;
+typedef signed __int64 SINT64;
+# else
+# include <inttypes.h>
+typedef uint64_t UINT64;
+typedef int64_t SINT64;
+# endif
+#else
+typedef unsigned int UINT8 __attribute__((__mode__(__QI__)));
+typedef signed int SINT8 __attribute__((__mode__(__QI__)));
+typedef unsigned int UINT16 __attribute__((__mode__(__HI__)));
+typedef signed int SINT16 __attribute__((__mode__(__HI__)));
+typedef unsigned int UINT32 __attribute__((__mode__(__SI__)));
+typedef signed int SINT32 __attribute__((__mode__(__SI__)));
+typedef unsigned int UINT64 __attribute__((__mode__(__DI__)));
+typedef signed int SINT64 __attribute__((__mode__(__DI__)));
+#endif
+
+typedef float FLOAT32;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
diff --git a/src/3rdparty/ffi-arm/fficonfig.h b/src/3rdparty/ffi-arm/fficonfig.h
new file mode 100644
index 000000000..61b3a1db6
--- /dev/null
+++ b/src/3rdparty/ffi-arm/fficonfig.h
@@ -0,0 +1,182 @@
+/* fficonfig.h. Generated from fficonfig.h.in by configure. */
+/* fficonfig.h.in. Generated from configure.ac by autoheader. */
+
+/* Define if building universal (internal helper macro) */
+/* #undef AC_APPLE_UNIVERSAL_BUILD */
+
+/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
+ systems. This function is required for `alloca.c' support on those systems.
+ */
+/* #undef CRAY_STACKSEG_END */
+
+/* Define to 1 if using `alloca.c'. */
+/* #undef C_ALLOCA */
+
+/* Define to the flags needed for the .section .eh_frame directive. */
+#define EH_FRAME_FLAGS "a"
+
+/* Define this if you want extra debugging. */
+/* #undef FFI_DEBUG */
+
+/* Cannot use malloc on this target, so, we revert to alternative means */
+/* #undef FFI_MMAP_EXEC_WRIT */
+
+/* Define this is you do not want support for the raw API. */
+/* #undef FFI_NO_RAW_API */
+
+/* Define this is you do not want support for aggregate types. */
+/* #undef FFI_NO_STRUCTS */
+
+/* Define to 1 if you have `alloca', as a function or macro. */
+#define HAVE_ALLOCA 1
+
+/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
+ */
+#define HAVE_ALLOCA_H 1
+
+/* Define if your assembler supports .cfi_* directives. */
+#define HAVE_AS_CFI_PSEUDO_OP 1
+
+/* Define if your assembler supports .register. */
+/* #undef HAVE_AS_REGISTER_PSEUDO_OP */
+
+/* Define if your assembler and linker support unaligned PC relative relocs.
+ */
+/* #undef HAVE_AS_SPARC_UA_PCREL */
+
+/* Define if your assembler supports PC relative relocs. */
+/* #undef HAVE_AS_X86_PCREL */
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#define HAVE_DLFCN_H 1
+
+/* Define if __attribute__((visibility("hidden"))) is supported. */
+#define HAVE_HIDDEN_VISIBILITY_ATTRIBUTE 1
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define if you have the long double type and it is bigger than a double */
+#define HAVE_LONG_DOUBLE 1
+
+/* Define to 1 if you have the `memcpy' function. */
+#define HAVE_MEMCPY 1
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the `mmap' function. */
+#define HAVE_MMAP 1
+
+/* Define if mmap with MAP_ANON(YMOUS) works. */
+#define HAVE_MMAP_ANON 1
+
+/* Define if mmap of /dev/zero works. */
+#define HAVE_MMAP_DEV_ZERO 1
+
+/* Define if read-only mmap of a plain file works. */
+#define HAVE_MMAP_FILE 1
+
+/* Define if .eh_frame sections should be read-only. */
+#define HAVE_RO_EH_FRAME 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the <sys/mman.h> header file. */
+#define HAVE_SYS_MMAN_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+ */
+#define LT_OBJDIR ".libs/"
+
+/* Define to 1 if your C compiler doesn't accept -c and -o together. */
+/* #undef NO_MINUS_C_MINUS_O */
+
+/* Name of package */
+#define PACKAGE "libffi"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "http://gcc.gnu.org/bugs.html"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "libffi"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "libffi 3.0.9"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "libffi"
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "3.0.9"
+
+/* The size of `double', as computed by sizeof. */
+#define SIZEOF_DOUBLE 8
+
+/* The size of `long double', as computed by sizeof. */
+#define SIZEOF_LONG_DOUBLE 12
+
+/* If using the C implementation of alloca, define if you know the
+ direction of stack growth for your system; otherwise it will be
+ automatically deduced at runtime.
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown */
+/* #undef STACK_DIRECTION */
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Define this if you are using Purify and want to suppress spurious messages.
+ */
+/* #undef USING_PURIFY */
+
+/* Version number of package */
+#define VERSION "3.0.9"
+
+/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
+ significant byte first (like Motorola and SPARC, unlike Intel). */
+#if defined AC_APPLE_UNIVERSAL_BUILD
+# if defined __BIG_ENDIAN__
+# define WORDS_BIGENDIAN 1
+# endif
+#else
+# ifndef WORDS_BIGENDIAN
+/* # undef WORDS_BIGENDIAN */
+# endif
+#endif
+
+
+#ifdef HAVE_HIDDEN_VISIBILITY_ATTRIBUTE
+#ifdef LIBFFI_ASM
+#define FFI_HIDDEN(name) .hidden name
+#else
+#define FFI_HIDDEN __attribute__ ((visibility ("hidden")))
+#endif
+#else
+#ifdef LIBFFI_ASM
+#define FFI_HIDDEN(name)
+#else
+#define FFI_HIDDEN
+#endif
+#endif
+
diff --git a/src/3rdparty/ffi-arm/ffitarget.h b/src/3rdparty/ffi-arm/ffitarget.h
new file mode 100644
index 000000000..a95742669
--- /dev/null
+++ b/src/3rdparty/ffi-arm/ffitarget.h
@@ -0,0 +1,49 @@
+/* -----------------------------------------------------------------*-C-*-
+ ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc.
+ Target configuration macros for ARM.
+
+ 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 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 LIBFFI_TARGET_H
+#define LIBFFI_TARGET_H
+
+#ifndef LIBFFI_ASM
+typedef unsigned long ffi_arg;
+typedef signed long ffi_sarg;
+
+typedef enum ffi_abi {
+ FFI_FIRST_ABI = 0,
+ FFI_SYSV,
+ FFI_DEFAULT_ABI = FFI_SYSV,
+ FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
+} ffi_abi;
+#endif
+
+/* ---- Definitions for closures ----------------------------------------- */
+
+#define FFI_CLOSURES 1
+#define FFI_TRAMPOLINE_SIZE 20
+#define FFI_NATIVE_RAW_API 0
+
+#endif
+
diff --git a/src/3rdparty/ffi-arm/prep_cif.c b/src/3rdparty/ffi-arm/prep_cif.c
new file mode 100644
index 000000000..eb78f9a2e
--- /dev/null
+++ b/src/3rdparty/ffi-arm/prep_cif.c
@@ -0,0 +1,174 @@
+/* -----------------------------------------------------------------------
+ prep_cif.c - Copyright (c) 1996, 1998, 2007 Red Hat, Inc.
+
+ 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 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 <ffi.h>
+#include <ffi_common.h>
+#include <stdlib.h>
+
+/* Round up to FFI_SIZEOF_ARG. */
+
+#define STACK_ARG_SIZE(x) ALIGN(x, FFI_SIZEOF_ARG)
+
+/* Perform machine independent initialization of aggregate type
+ specifications. */
+
+static ffi_status initialize_aggregate(ffi_type *arg)
+{
+ ffi_type **ptr;
+
+ FFI_ASSERT(arg != NULL);
+
+ FFI_ASSERT(arg->elements != NULL);
+ FFI_ASSERT(arg->size == 0);
+ FFI_ASSERT(arg->alignment == 0);
+
+ ptr = &(arg->elements[0]);
+
+ while ((*ptr) != NULL)
+ {
+ if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK))
+ return FFI_BAD_TYPEDEF;
+
+ /* Perform a sanity check on the argument type */
+ FFI_ASSERT_VALID_TYPE(*ptr);
+
+ arg->size = ALIGN(arg->size, (*ptr)->alignment);
+ arg->size += (*ptr)->size;
+
+ arg->alignment = (arg->alignment > (*ptr)->alignment) ?
+ arg->alignment : (*ptr)->alignment;
+
+ ptr++;
+ }
+
+ /* Structure size includes tail padding. This is important for
+ structures that fit in one register on ABIs like the PowerPC64
+ Linux ABI that right justify small structs in a register.
+ It's also needed for nested structure layout, for example
+ struct A { long a; char b; }; struct B { struct A x; char y; };
+ should find y at an offset of 2*sizeof(long) and result in a
+ total size of 3*sizeof(long). */
+ arg->size = ALIGN (arg->size, arg->alignment);
+
+ if (arg->size == 0)
+ return FFI_BAD_TYPEDEF;
+ else
+ return FFI_OK;
+}
+
+#ifndef __CRIS__
+/* The CRIS ABI specifies structure elements to have byte
+ alignment only, so it completely overrides this functions,
+ which assumes "natural" alignment and padding. */
+
+/* Perform machine independent ffi_cif preparation, then call
+ machine dependent routine. */
+
+ffi_status ffi_prep_cif(ffi_cif *cif, ffi_abi abi, unsigned int nargs,
+ ffi_type *rtype, ffi_type **atypes)
+{
+ unsigned bytes = 0;
+ unsigned int i;
+ ffi_type **ptr;
+
+ FFI_ASSERT(cif != NULL);
+ FFI_ASSERT((abi > FFI_FIRST_ABI) && (abi <= FFI_DEFAULT_ABI));
+
+ cif->abi = abi;
+ cif->arg_types = atypes;
+ cif->nargs = nargs;
+ cif->rtype = rtype;
+
+ cif->flags = 0;
+
+ /* Initialize the return type if necessary */
+ if ((cif->rtype->size == 0) && (initialize_aggregate(cif->rtype) != FFI_OK))
+ return FFI_BAD_TYPEDEF;
+
+ /* Perform a sanity check on the return type */
+ FFI_ASSERT_VALID_TYPE(cif->rtype);
+
+ /* x86-64 and s390 stack space allocation is handled in prep_machdep. */
+#if !defined M68K && !defined __x86_64__ && !defined S390 && !defined PA
+ /* Make space for the return structure pointer */
+ if (cif->rtype->type == FFI_TYPE_STRUCT
+#ifdef SPARC
+ && (cif->abi != FFI_V9 || cif->rtype->size > 32)
+#endif
+#ifdef X86_DARWIN
+ && (cif->rtype->size > 8)
+#endif
+ )
+ bytes = STACK_ARG_SIZE(sizeof(void*));
+#endif
+
+ for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
+ {
+
+ /* Initialize any uninitialized aggregate type definitions */
+ if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK))
+ return FFI_BAD_TYPEDEF;
+
+ /* Perform a sanity check on the argument type, do this
+ check after the initialization. */
+ FFI_ASSERT_VALID_TYPE(*ptr);
+
+#if !defined __x86_64__ && !defined S390 && !defined PA
+#ifdef SPARC
+ if (((*ptr)->type == FFI_TYPE_STRUCT
+ && ((*ptr)->size > 16 || cif->abi != FFI_V9))
+ || ((*ptr)->type == FFI_TYPE_LONGDOUBLE
+ && cif->abi != FFI_V9))
+ bytes += sizeof(void*);
+ else
+#endif
+ {
+ /* Add any padding if necessary */
+ if (((*ptr)->alignment - 1) & bytes)
+ bytes = ALIGN(bytes, (*ptr)->alignment);
+
+ bytes += STACK_ARG_SIZE((*ptr)->size);
+ }
+#endif
+ }
+
+ cif->bytes = bytes;
+
+ /* Perform machine dependent cif processing */
+ return ffi_prep_cif_machdep(cif);
+}
+#endif /* not __CRIS__ */
+
+#if FFI_CLOSURES
+
+ffi_status
+ffi_prep_closure (ffi_closure* closure,
+ ffi_cif* cif,
+ void (*fun)(ffi_cif*,void*,void**,void*),
+ void *user_data)
+{
+ return ffi_prep_closure_loc (closure, cif, fun, user_data, closure);
+}
+
+#endif
diff --git a/src/3rdparty/ffi-arm/sysv.S b/src/3rdparty/ffi-arm/sysv.S
new file mode 100644
index 000000000..4c289c697
--- /dev/null
+++ b/src/3rdparty/ffi-arm/sysv.S
@@ -0,0 +1,306 @@
+/* -----------------------------------------------------------------------
+ sysv.S - Copyright (c) 1998, 2008 Red Hat, Inc.
+
+ ARM Foreign Function Interface
+
+ 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 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 LIBFFI_ASM
+#include <fficonfig.h>
+#include <ffi.h>
+#ifdef HAVE_MACHINE_ASM_H
+#include <machine/asm.h>
+#else
+#ifdef __USER_LABEL_PREFIX__
+#define CONCAT1(a, b) CONCAT2(a, b)
+#define CONCAT2(a, b) a ## b
+
+/* Use the right prefix for global labels. */
+#define CNAME(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
+#else
+#define CNAME(x) x
+#endif
+#define ENTRY(x) .globl CNAME(x); .type CNAME(x),%function; CNAME(x):
+#endif
+
+#ifdef __ELF__
+#define LSYM(x) .x
+#else
+#define LSYM(x) x
+#endif
+
+/* We need a better way of testing for this, but for now, this is all
+ we can do. */
+@ This selects the minimum architecture level required.
+#define __ARM_ARCH__ 3
+
+#if defined(__ARM_ARCH_4__) || defined(__ARM_ARCH_4T__)
+# undef __ARM_ARCH__
+# define __ARM_ARCH__ 4
+#endif
+
+#if defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) \
+ || defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) \
+ || defined(__ARM_ARCH_5TEJ__)
+# undef __ARM_ARCH__
+# define __ARM_ARCH__ 5
+#endif
+
+#if defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \
+ || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) \
+ || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) \
+ || defined(__ARM_ARCH_6M__)
+# undef __ARM_ARCH__
+# define __ARM_ARCH__ 6
+#endif
+
+#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \
+ || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__)
+# undef __ARM_ARCH__
+# define __ARM_ARCH__ 7
+#endif
+
+#if __ARM_ARCH__ >= 5
+# define call_reg(x) blx x
+#elif defined (__ARM_ARCH_4T__)
+# define call_reg(x) mov lr, pc ; bx x
+# if defined(__thumb__) || defined(__THUMB_INTERWORK__)
+# define __INTERWORKING__
+# endif
+#else
+# define call_reg(x) mov lr, pc ; mov pc, x
+#endif
+
+/* Conditionally compile unwinder directives. */
+#ifdef __ARM_EABI__
+#define UNWIND
+#else
+#define UNWIND @
+#endif
+
+
+#if defined(__thumb__) && !defined(__THUMB_INTERWORK__)
+.macro ARM_FUNC_START name
+ .text
+ .align 0
+ .thumb
+ .thumb_func
+ ENTRY(\name)
+ bx pc
+ nop
+ .arm
+ UNWIND .fnstart
+/* A hook to tell gdb that we've switched to ARM mode. Also used to call
+ directly from other local arm routines. */
+_L__\name:
+.endm
+#else
+.macro ARM_FUNC_START name
+ .text
+ .align 0
+ .arm
+ ENTRY(\name)
+ UNWIND .fnstart
+.endm
+#endif
+
+.macro RETLDM regs=, cond=, dirn=ia
+#if defined (__INTERWORKING__)
+ .ifc "\regs",""
+ ldr\cond lr, [sp], #4
+ .else
+ ldm\cond\dirn sp!, {\regs, lr}
+ .endif
+ bx\cond lr
+#else
+ .ifc "\regs",""
+ ldr\cond pc, [sp], #4
+ .else
+ ldm\cond\dirn sp!, {\regs, pc}
+ .endif
+#endif
+.endm
+
+
+ @ r0: ffi_prep_args
+ @ r1: &ecif
+ @ r2: cif->bytes
+ @ r3: fig->flags
+ @ sp+0: ecif.rvalue
+ @ sp+4: fn
+
+ @ This assumes we are using gas.
+ARM_FUNC_START ffi_call_SYSV
+ @ Save registers
+ stmfd sp!, {r0-r3, fp, lr}
+ UNWIND .save {r0-r3, fp, lr}
+ mov fp, sp
+
+ UNWIND .setfp fp, sp
+
+ @ Make room for all of the new args.
+ sub sp, fp, r2
+
+ @ Place all of the ffi_prep_args in position
+ mov ip, r0
+ mov r0, sp
+ @ r1 already set
+
+ @ Call ffi_prep_args(stack, &ecif)
+ call_reg(ip)
+
+ @ move first 4 parameters in registers
+ ldmia sp, {r0-r3}
+
+ @ and adjust stack
+ ldr ip, [fp, #8]
+ cmp ip, #16
+ movhs ip, #16
+ add sp, sp, ip
+
+ @ call (fn) (...)
+ ldr ip, [fp, #28]
+ call_reg(ip)
+
+ @ Remove the space we pushed for the args
+ mov sp, fp
+
+ @ Load r2 with the pointer to storage for the return value
+ ldr r2, [sp, #24]
+
+ @ Load r3 with the return type code
+ ldr r3, [sp, #12]
+
+ @ If the return value pointer is NULL, assume no return value.
+ cmp r2, #0
+ beq LSYM(Lepilogue)
+
+@ return INT
+ cmp r3, #FFI_TYPE_INT
+#if defined(__SOFTFP__) || defined(__ARM_EABI__)
+ cmpne r3, #FFI_TYPE_FLOAT
+#endif
+ streq r0, [r2]
+ beq LSYM(Lepilogue)
+
+ @ return INT64
+ cmp r3, #FFI_TYPE_SINT64
+#if defined(__SOFTFP__) || defined(__ARM_EABI__)
+ cmpne r3, #FFI_TYPE_DOUBLE
+#endif
+ stmeqia r2, {r0, r1}
+
+#if !defined(__SOFTFP__) && !defined(__ARM_EABI__)
+ beq LSYM(Lepilogue)
+
+@ return FLOAT
+ cmp r3, #FFI_TYPE_FLOAT
+ stfeqs f0, [r2]
+ beq LSYM(Lepilogue)
+
+@ return DOUBLE or LONGDOUBLE
+ cmp r3, #FFI_TYPE_DOUBLE
+ stfeqd f0, [r2]
+#endif
+
+LSYM(Lepilogue):
+ RETLDM "r0-r3,fp"
+
+.ffi_call_SYSV_end:
+ UNWIND .fnend
+ .size CNAME(ffi_call_SYSV),.ffi_call_SYSV_end-CNAME(ffi_call_SYSV)
+
+/*
+ unsigned int FFI_HIDDEN
+ ffi_closure_SYSV_inner (closure, respp, args)
+ ffi_closure *closure;
+ void **respp;
+ void *args;
+*/
+
+ARM_FUNC_START ffi_closure_SYSV
+ UNWIND .pad #16
+ add ip, sp, #16
+ stmfd sp!, {ip, lr}
+ UNWIND .save {r0, lr}
+ add r2, sp, #8
+ .pad #16
+ sub sp, sp, #16
+ str sp, [sp, #8]
+ add r1, sp, #8
+ bl ffi_closure_SYSV_inner
+ cmp r0, #FFI_TYPE_INT
+ beq .Lretint
+
+ cmp r0, #FFI_TYPE_FLOAT
+#if defined(__SOFTFP__) || defined(__ARM_EABI__)
+ beq .Lretint
+#else
+ beq .Lretfloat
+#endif
+
+ cmp r0, #FFI_TYPE_DOUBLE
+#if defined(__SOFTFP__) || defined(__ARM_EABI__)
+ beq .Lretlonglong
+#else
+ beq .Lretdouble
+#endif
+
+ cmp r0, #FFI_TYPE_LONGDOUBLE
+#if defined(__SOFTFP__) || defined(__ARM_EABI__)
+ beq .Lretlonglong
+#else
+ beq .Lretlongdouble
+#endif
+
+ cmp r0, #FFI_TYPE_SINT64
+ beq .Lretlonglong
+.Lclosure_epilogue:
+ add sp, sp, #16
+ ldmfd sp, {sp, pc}
+.Lretint:
+ ldr r0, [sp]
+ b .Lclosure_epilogue
+.Lretlonglong:
+ ldr r0, [sp]
+ ldr r1, [sp, #4]
+ b .Lclosure_epilogue
+
+#if !defined(__SOFTFP__) && !defined(__ARM_EABI__)
+.Lretfloat:
+ ldfs f0, [sp]
+ b .Lclosure_epilogue
+.Lretdouble:
+ ldfd f0, [sp]
+ b .Lclosure_epilogue
+.Lretlongdouble:
+ ldfd f0, [sp]
+ b .Lclosure_epilogue
+#endif
+
+.ffi_closure_SYSV_end:
+ UNWIND .fnend
+ .size CNAME(ffi_closure_SYSV),.ffi_closure_SYSV_end-CNAME(ffi_closure_SYSV)
+
+#if defined __ELF__ && defined __linux__
+ .section .note.GNU-stack,"",%progbits
+#endif
diff --git a/src/3rdparty/ffi-arm/types.c b/src/3rdparty/ffi-arm/types.c
new file mode 100644
index 000000000..0a11eb0fb
--- /dev/null
+++ b/src/3rdparty/ffi-arm/types.c
@@ -0,0 +1,77 @@
+/* -----------------------------------------------------------------------
+ types.c - Copyright (c) 1996, 1998 Red Hat, Inc.
+
+ Predefined ffi_types needed by libffi.
+
+ 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 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.
+ ----------------------------------------------------------------------- */
+
+/* Hide the basic type definitions from the header file, so that we
+ can redefine them here as "const". */
+#define LIBFFI_HIDE_BASIC_TYPES
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+/* Type definitions */
+
+#define FFI_TYPEDEF(name, type, id) \
+struct struct_align_##name { \
+ char c; \
+ type x; \
+}; \
+const ffi_type ffi_type_##name = { \
+ sizeof(type), \
+ offsetof(struct struct_align_##name, x), \
+ id, NULL \
+}
+
+/* Size and alignment are fake here. They must not be 0. */
+const ffi_type ffi_type_void = {
+ 1, 1, FFI_TYPE_VOID, NULL
+};
+
+FFI_TYPEDEF(uint8, UINT8, FFI_TYPE_UINT8);
+FFI_TYPEDEF(sint8, SINT8, FFI_TYPE_SINT8);
+FFI_TYPEDEF(uint16, UINT16, FFI_TYPE_UINT16);
+FFI_TYPEDEF(sint16, SINT16, FFI_TYPE_SINT16);
+FFI_TYPEDEF(uint32, UINT32, FFI_TYPE_UINT32);
+FFI_TYPEDEF(sint32, SINT32, FFI_TYPE_SINT32);
+FFI_TYPEDEF(uint64, UINT64, FFI_TYPE_UINT64);
+FFI_TYPEDEF(sint64, SINT64, FFI_TYPE_SINT64);
+
+FFI_TYPEDEF(pointer, void*, FFI_TYPE_POINTER);
+
+FFI_TYPEDEF(float, float, FFI_TYPE_FLOAT);
+FFI_TYPEDEF(double, double, FFI_TYPE_DOUBLE);
+
+#ifdef __alpha__
+/* Even if we're not configured to default to 128-bit long double,
+ maintain binary compatibility, as -mlong-double-128 can be used
+ at any time. */
+/* Validate the hard-coded number below. */
+# if defined(__LONG_DOUBLE_128__) && FFI_TYPE_LONGDOUBLE != 4
+# error FFI_TYPE_LONGDOUBLE out of date
+# endif
+const ffi_type ffi_type_longdouble = { 16, 16, 4, NULL };
+#elif FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+FFI_TYPEDEF(longdouble, long double, FFI_TYPE_LONGDOUBLE);
+#endif
diff --git a/src/3rdparty/wayland/client/client.pro b/src/3rdparty/wayland/client/client.pro
new file mode 100644
index 000000000..ebf24b4ee
--- /dev/null
+++ b/src/3rdparty/wayland/client/client.pro
@@ -0,0 +1,19 @@
+TEMPLATE = lib
+TARGET = wayland-client
+DESTDIR=$$PWD/../../../../lib/
+
+CONFIG -= qt
+CONFIG += shared
+
+INCLUDEPATH += $$PWD/.. \
+ $$PWD/../../ffi
+
+LIBS += -L $$PWD/../../../../lib/ -lffi
+
+SOURCES = ../wayland-client.c \
+ ../wayland-protocol.c \
+ ../connection.c \
+ ../wayland-util.c \
+ ../wayland-hash.c
+
+OBJECTS_DIR = .obj
diff --git a/src/3rdparty/wayland/connection.c b/src/3rdparty/wayland/connection.c
new file mode 100644
index 000000000..4a004705b
--- /dev/null
+++ b/src/3rdparty/wayland/connection.c
@@ -0,0 +1,729 @@
+/*
+ * Copyright © 2008 Kristian Høgsberg
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+#include <sys/uio.h>
+#include <ffi.h>
+#include <assert.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include "wayland-util.h"
+#include "connection.h"
+
+#define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0])
+
+struct wl_buffer {
+ char data[4096];
+ int head, tail;
+};
+
+#define MASK(i) ((i) & 4095)
+
+struct wl_closure {
+ int count;
+ const struct wl_message *message;
+ ffi_type *types[20];
+ ffi_cif cif;
+ void *args[20];
+ uint32_t buffer[64];
+ uint32_t *start;
+};
+
+struct wl_connection {
+ struct wl_buffer in, out;
+ struct wl_buffer fds_in, fds_out;
+ int fd;
+ void *data;
+ wl_connection_update_func_t update;
+ struct wl_closure receive_closure, send_closure;
+};
+
+union wl_value {
+ uint32_t uint32;
+ char *string;
+ struct wl_object *object;
+ uint32_t new_id;
+ struct wl_array *array;
+};
+
+static void
+wl_buffer_put(struct wl_buffer *b, const void *data, size_t count)
+{
+ int head, size;
+
+ head = MASK(b->head);
+ if (head + count <= sizeof b->data) {
+ memcpy(b->data + head, data, count);
+ } else {
+ size = sizeof b->data - head;
+ memcpy(b->data + head, data, size);
+ memcpy(b->data, (const char *) data + size, count - size);
+ }
+
+ b->head += count;
+}
+
+static void
+wl_buffer_put_iov(struct wl_buffer *b, struct iovec *iov, int *count)
+{
+ int head, tail;
+
+ head = MASK(b->head);
+ tail = MASK(b->tail);
+ if (head < tail) {
+ iov[0].iov_base = b->data + head;
+ iov[0].iov_len = tail - head;
+ *count = 1;
+ } else if (tail == 0) {
+ iov[0].iov_base = b->data + head;
+ iov[0].iov_len = sizeof b->data - head;
+ *count = 1;
+ } else {
+ iov[0].iov_base = b->data + head;
+ iov[0].iov_len = sizeof b->data - head;
+ iov[1].iov_base = b->data;
+ iov[1].iov_len = tail;
+ *count = 2;
+ }
+}
+
+static void
+wl_buffer_get_iov(struct wl_buffer *b, struct iovec *iov, int *count)
+{
+ int head, tail;
+
+ head = MASK(b->head);
+ tail = MASK(b->tail);
+ if (tail < head) {
+ iov[0].iov_base = b->data + tail;
+ iov[0].iov_len = head - tail;
+ *count = 1;
+ } else if (head == 0) {
+ iov[0].iov_base = b->data + tail;
+ iov[0].iov_len = sizeof b->data - tail;
+ *count = 1;
+ } else {
+ iov[0].iov_base = b->data + tail;
+ iov[0].iov_len = sizeof b->data - tail;
+ iov[1].iov_base = b->data;
+ iov[1].iov_len = head;
+ *count = 2;
+ }
+}
+
+static void
+wl_buffer_copy(struct wl_buffer *b, void *data, size_t count)
+{
+ int tail, size;
+
+ tail = MASK(b->tail);
+ if (tail + count <= sizeof b->data) {
+ memcpy(data, b->data + tail, count);
+ } else {
+ size = sizeof b->data - tail;
+ memcpy(data, b->data + tail, size);
+ memcpy((char *) data + size, b->data, count - size);
+ }
+}
+
+struct wl_connection *
+wl_connection_create(int fd,
+ wl_connection_update_func_t update,
+ void *data)
+{
+ struct wl_connection *connection;
+
+ connection = malloc(sizeof *connection);
+ memset(connection, 0, sizeof *connection);
+ connection->fd = fd;
+ connection->update = update;
+ connection->data = data;
+
+ connection->update(connection,
+ WL_CONNECTION_READABLE,
+ connection->data);
+
+ return connection;
+}
+
+void
+wl_connection_destroy(struct wl_connection *connection)
+{
+ close(connection->fd);
+ free(connection);
+}
+
+void
+wl_connection_copy(struct wl_connection *connection, void *data, size_t size)
+{
+ wl_buffer_copy(&connection->in, data, size);
+}
+
+void
+wl_connection_consume(struct wl_connection *connection, size_t size)
+{
+ connection->in.tail += size;
+}
+
+static void
+build_cmsg(struct wl_buffer *buffer, char *data, int *clen)
+{
+ struct cmsghdr *cmsg;
+ size_t size;
+
+ size = buffer->head - buffer->tail;
+ if (size > 0) {
+ cmsg = (struct cmsghdr *) data;
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SCM_RIGHTS;
+ cmsg->cmsg_len = CMSG_LEN(size);
+ wl_buffer_copy(buffer, CMSG_DATA(cmsg), size);
+ *clen = cmsg->cmsg_len;
+ } else {
+ *clen = 0;
+ }
+}
+
+static void
+close_fds(struct wl_buffer *buffer)
+{
+ int fds[32], i, count;
+ size_t size;
+
+ size = buffer->head - buffer->tail;
+ if (size == 0)
+ return;
+
+ wl_buffer_copy(buffer, fds, size);
+ count = size / sizeof fds[0];
+ for (i = 0; i < count; i++)
+ close(fds[i]);
+ buffer->tail += size;
+}
+
+static void
+decode_cmsg(struct wl_buffer *buffer, struct msghdr *msg)
+{
+ struct cmsghdr *cmsg;
+ size_t size;
+
+ for (cmsg = CMSG_FIRSTHDR(msg); cmsg != NULL;
+ cmsg = CMSG_NXTHDR(msg, cmsg)) {
+ if (cmsg->cmsg_level == SOL_SOCKET &&
+ cmsg->cmsg_type == SCM_RIGHTS) {
+ size = cmsg->cmsg_len - CMSG_LEN(0);
+ wl_buffer_put(buffer, CMSG_DATA(cmsg), size);
+ }
+ }
+}
+
+int
+wl_connection_data(struct wl_connection *connection, uint32_t mask)
+{
+ struct iovec iov[2];
+ struct msghdr msg;
+ char cmsg[128];
+ int len, count, clen;
+
+ if (mask & WL_CONNECTION_WRITABLE) {
+ wl_buffer_get_iov(&connection->out, iov, &count);
+
+ build_cmsg(&connection->fds_out, cmsg, &clen);
+
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_iov = iov;
+ msg.msg_iovlen = count;
+ msg.msg_control = cmsg;
+ msg.msg_controllen = clen;
+ msg.msg_flags = 0;
+
+ do {
+ len = sendmsg(connection->fd, &msg, MSG_NOSIGNAL);
+ } while (len < 0 && errno == EINTR);
+
+ if (len == -1 && errno == EPIPE) {
+ return -1;
+ } else if (len < 0) {
+ fprintf(stderr,
+ "write error for connection %p, fd %d: %m\n",
+ connection, connection->fd);
+ return -1;
+ }
+
+ close_fds(&connection->fds_out);
+
+ connection->out.tail += len;
+ if (connection->out.tail == connection->out.head)
+ connection->update(connection,
+ WL_CONNECTION_READABLE,
+ connection->data);
+ }
+
+ if (mask & WL_CONNECTION_READABLE) {
+ wl_buffer_put_iov(&connection->in, iov, &count);
+
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_iov = iov;
+ msg.msg_iovlen = count;
+ msg.msg_control = cmsg;
+ msg.msg_controllen = sizeof cmsg;
+ msg.msg_flags = 0;
+
+ do {
+ len = recvmsg(connection->fd, &msg, 0);
+ } while (len < 0 && errno == EINTR);
+
+ if (len < 0) {
+ fprintf(stderr,
+ "read error from connection %p: %m (%d)\n",
+ connection, errno);
+ return -1;
+ } else if (len == 0) {
+ /* FIXME: Handle this better? */
+ return -1;
+ }
+
+ decode_cmsg(&connection->fds_in, &msg);
+
+ connection->in.head += len;
+ }
+
+ return connection->in.head - connection->in.tail;
+}
+
+void
+wl_connection_write(struct wl_connection *connection,
+ const void *data, size_t count)
+{
+ wl_buffer_put(&connection->out, data, count);
+
+ if (connection->out.head - connection->out.tail == count)
+ connection->update(connection,
+ WL_CONNECTION_READABLE |
+ WL_CONNECTION_WRITABLE,
+ connection->data);
+}
+
+static int
+wl_message_size_extra(const struct wl_message *message)
+{
+ int i, extra;
+
+ for (i = 0, extra = 0; message->signature[i]; i++) {
+
+ switch (message->signature[i]) {
+ case 's':
+ case 'o':
+ extra += sizeof (void *);
+ break;
+ case 'a':
+ extra += sizeof (void *) + sizeof (struct wl_array);
+ break;
+ case 'h':
+ extra += sizeof (uint32_t);
+ break;
+ default:
+ break;
+ }
+ }
+
+ return extra;
+}
+
+struct wl_closure *
+wl_connection_vmarshal(struct wl_connection *connection,
+ struct wl_object *sender,
+ uint32_t opcode, va_list ap,
+ const struct wl_message *message)
+{
+ struct wl_closure *closure = &connection->send_closure;
+ struct wl_object **objectp, *object;
+ uint32_t length, *p, *start, size;
+ int dup_fd;
+ struct wl_array **arrayp, *array;
+ const char **sp, *s;
+ char *extra;
+ int i, count, fd, extra_size, *fd_ptr;
+
+ extra_size = wl_message_size_extra(message);
+ count = strlen(message->signature) + 2;
+ extra = (char *) closure->buffer;
+ start = &closure->buffer[DIV_ROUNDUP(extra_size, sizeof *p)];
+ p = &start[2];
+ for (i = 2; i < count; i++) {
+ switch (message->signature[i - 2]) {
+ case 'u':
+ closure->types[i] = &ffi_type_uint32;
+ closure->args[i] = p;
+ *p++ = va_arg(ap, uint32_t);
+ break;
+ case 'i':
+ closure->types[i] = &ffi_type_sint32;
+ closure->args[i] = p;
+ *p++ = va_arg(ap, int32_t);
+ break;
+ case 's':
+ closure->types[i] = &ffi_type_pointer;
+ closure->args[i] = extra;
+ sp = (const char **) extra;
+ extra += sizeof *sp;
+
+ s = va_arg(ap, const char *);
+ length = s ? strlen(s) + 1: 0;
+ *p++ = length;
+
+ if (length > 0)
+ *sp = (const char *) p;
+ else
+ *sp = NULL;
+
+ memcpy(p, s, length);
+ p += DIV_ROUNDUP(length, sizeof *p);
+ break;
+ case 'o':
+ closure->types[i] = &ffi_type_pointer;
+ closure->args[i] = extra;
+ objectp = (struct wl_object **) extra;
+ extra += sizeof *objectp;
+
+ object = va_arg(ap, struct wl_object *);
+ *objectp = object;
+ *p++ = object ? object->id : 0;
+ break;
+
+ case 'n':
+ closure->types[i] = &ffi_type_uint32;
+ closure->args[i] = p;
+ object = va_arg(ap, struct wl_object *);
+ *p++ = object->id;
+ break;
+
+ case 'a':
+ closure->types[i] = &ffi_type_pointer;
+ closure->args[i] = extra;
+ arrayp = (struct wl_array **) extra;
+ extra += sizeof *arrayp;
+
+ *arrayp = (struct wl_array *) extra;
+ extra += sizeof **arrayp;
+
+ array = va_arg(ap, struct wl_array *);
+ if (array == NULL || array->size == 0) {
+ *p++ = 0;
+ break;
+ }
+ *p++ = array->size;
+ memcpy(p, array->data, array->size);
+
+ (*arrayp)->size = array->size;
+ (*arrayp)->alloc = array->alloc;
+ (*arrayp)->data = p;
+
+ p += DIV_ROUNDUP(array->size, sizeof *p);
+ break;
+
+ case 'h':
+ closure->types[i] = &ffi_type_sint;
+ closure->args[i] = extra;
+ fd_ptr = (int *) extra;
+ extra += sizeof *fd_ptr;
+
+ fd = va_arg(ap, int);
+ dup_fd = dup(fd);
+ if (dup_fd < 0) {
+ fprintf(stderr, "dup failed: %m");
+ abort();
+ }
+ *fd_ptr = dup_fd;
+ wl_buffer_put(&connection->fds_out,
+ &dup_fd, sizeof dup_fd);
+ break;
+ default:
+ assert(0);
+ break;
+ }
+ }
+
+ size = (p - start) * sizeof *p;
+ start[0] = sender->id;
+ start[1] = opcode | (size << 16);
+
+ closure->start = start;
+ closure->message = message;
+ closure->count = count;
+
+ return closure;
+}
+
+struct wl_closure *
+wl_connection_demarshal(struct wl_connection *connection,
+ uint32_t size,
+ struct wl_hash_table *objects,
+ const struct wl_message *message)
+{
+ uint32_t *p, *next, *end, length;
+ int *fd;
+ char *extra, **s;
+ int i, count, extra_space;
+ struct wl_object **object;
+ struct wl_array **array;
+ struct wl_closure *closure = &connection->receive_closure;
+
+ count = strlen(message->signature) + 2;
+ if (count > ARRAY_LENGTH(closure->types)) {
+ printf("too many args (%d)\n", count);
+ assert(0);
+ }
+
+ extra_space = wl_message_size_extra(message);
+ if (sizeof closure->buffer < size + extra_space) {
+ printf("request too big, should malloc tmp buffer here\n");
+ assert(0);
+ }
+
+ closure->message = message;
+ closure->types[0] = &ffi_type_pointer;
+ closure->types[1] = &ffi_type_pointer;
+
+ wl_connection_copy(connection, closure->buffer, size);
+ p = &closure->buffer[2];
+ end = (uint32_t *) ((char *) (p + size));
+ extra = (char *) end;
+ for (i = 2; i < count; i++) {
+ if (p + 1 > end) {
+ printf("message too short, "
+ "object (%d), message %s(%s)\n",
+ *p, message->name, message->signature);
+ errno = EINVAL;
+ goto err;
+ }
+
+ switch (message->signature[i - 2]) {
+ case 'u':
+ closure->types[i] = &ffi_type_uint32;
+ closure->args[i] = p++;
+ break;
+ case 'i':
+ closure->types[i] = &ffi_type_sint32;
+ closure->args[i] = p++;
+ break;
+ case 's':
+ closure->types[i] = &ffi_type_pointer;
+ length = *p++;
+
+ next = p + DIV_ROUNDUP(length, sizeof *p);
+ if (next > end) {
+ printf("message too short, "
+ "object (%d), message %s(%s)\n",
+ *p, message->name, message->signature);
+ errno = EINVAL;
+ goto err;
+ }
+
+ s = (char **) extra;
+ extra += sizeof *s;
+ closure->args[i] = s;
+
+ if (length == 0) {
+ *s = NULL;
+ } else {
+ *s = (char *) p;
+ }
+
+ if (length > 0 && (*s)[length - 1] != '\0') {
+ printf("string not nul-terminated, "
+ "message %s(%s)\n",
+ message->name, message->signature);
+ errno = EINVAL;
+ goto err;
+ }
+ p = next;
+ break;
+ case 'o':
+ closure->types[i] = &ffi_type_pointer;
+ object = (struct wl_object **) extra;
+ extra += sizeof *object;
+ closure->args[i] = object;
+
+ *object = wl_hash_table_lookup(objects, *p);
+ if (*object == NULL && *p != 0) {
+ printf("unknown object (%d), message %s(%s)\n",
+ *p, message->name, message->signature);
+ errno = EINVAL;
+ goto err;
+ }
+
+ p++;
+ break;
+ case 'n':
+ closure->types[i] = &ffi_type_uint32;
+ closure->args[i] = p;
+ object = wl_hash_table_lookup(objects, *p);
+ if (object != NULL) {
+ printf("not a new object (%d), "
+ "message %s(%s)\n",
+ *p, message->name, message->signature);
+ errno = EINVAL;
+ goto err;
+ }
+ p++;
+ break;
+ case 'a':
+ closure->types[i] = &ffi_type_pointer;
+ length = *p++;
+
+ next = p + DIV_ROUNDUP(length, sizeof *p);
+ if (next > end) {
+ printf("message too short, "
+ "object (%d), message %s(%s)\n",
+ *p, message->name, message->signature);
+ errno = EINVAL;
+ goto err;
+ }
+
+ array = (struct wl_array **) extra;
+ extra += sizeof *array;
+ closure->args[i] = array;
+
+ *array = (struct wl_array *) extra;
+ extra += sizeof **array;
+
+ (*array)->size = length;
+ (*array)->alloc = 0;
+ (*array)->data = p;
+ p = next;
+ break;
+ case 'h':
+ closure->types[i] = &ffi_type_sint;
+
+ fd = (int *) extra;
+ extra += sizeof *fd;
+ closure->args[i] = fd;
+
+ wl_buffer_copy(&connection->fds_in, fd, sizeof *fd);
+ connection->fds_in.tail += sizeof *fd;
+ break;
+ default:
+ printf("unknown type\n");
+ assert(0);
+ break;
+ }
+ }
+
+ closure->count = i;
+ ffi_prep_cif(&closure->cif, FFI_DEFAULT_ABI,
+ closure->count, &ffi_type_uint32, closure->types);
+
+ wl_connection_consume(connection, size);
+
+ return closure;
+
+ err:
+ closure->count = i;
+ wl_closure_destroy(closure);
+ wl_connection_consume(connection, size);
+
+ return NULL;
+}
+
+void
+wl_closure_invoke(struct wl_closure *closure,
+ struct wl_object *target, void (*func)(void), void *data)
+{
+ int result;
+
+ closure->args[0] = &data;
+ closure->args[1] = &target;
+
+ ffi_call(&closure->cif, func, &result, closure->args);
+}
+
+void
+wl_closure_send(struct wl_closure *closure, struct wl_connection *connection)
+{
+ uint32_t size;
+
+ size = closure->start[1] >> 16;
+ wl_connection_write(connection, closure->start, size);
+}
+
+void
+wl_closure_print(struct wl_closure *closure, struct wl_object *target)
+{
+ union wl_value *value;
+ int i;
+
+ fprintf(stderr, "%s@%d.%s(",
+ target->interface->name, target->id,
+ closure->message->name);
+
+ for (i = 2; i < closure->count; i++) {
+ if (i > 2)
+ fprintf(stderr, ", ");
+
+ value = closure->args[i];
+ switch (closure->message->signature[i - 2]) {
+ case 'u':
+ fprintf(stderr, "%u", value->uint32);
+ break;
+ case 'i':
+ fprintf(stderr, "%d", value->uint32);
+ break;
+ case 's':
+ fprintf(stderr, "\"%s\"", value->string);
+ break;
+ case 'o':
+ if (value->object)
+ fprintf(stderr, "%s@%u",
+ value->object->interface->name,
+ value->object->id);
+ else
+ fprintf(stderr, "nil");
+ break;
+ case 'n':
+ fprintf(stderr, "new id %u", value->uint32);
+ break;
+ case 'a':
+ fprintf(stderr, "array");
+ break;
+ case 'h':
+ fprintf(stderr, "fd %d", value->uint32);
+ break;
+ }
+ }
+
+ fprintf(stderr, ")\n");
+}
+
+void
+wl_closure_destroy(struct wl_closure *closure)
+{
+}
diff --git a/src/3rdparty/wayland/connection.h b/src/3rdparty/wayland/connection.h
new file mode 100644
index 000000000..413977dff
--- /dev/null
+++ b/src/3rdparty/wayland/connection.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright © 2008 Kristian Høgsberg
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#ifndef _CONNECTION_H_
+#define _CONNECTION_H_
+
+#include <stdarg.h>
+#include "wayland-util.h"
+
+struct wl_connection;
+struct wl_closure;
+
+#define WL_CONNECTION_READABLE 0x01
+#define WL_CONNECTION_WRITABLE 0x02
+
+typedef int (*wl_connection_update_func_t)(struct wl_connection *connection,
+ uint32_t mask, void *data);
+
+struct wl_connection *wl_connection_create(int fd,
+ wl_connection_update_func_t update,
+ void *data);
+void 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_data(struct wl_connection *connection, uint32_t mask);
+void wl_connection_write(struct wl_connection *connection, const void *data, size_t count);
+
+struct wl_closure *
+wl_connection_vmarshal(struct wl_connection *connection,
+ 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_hash_table *objects,
+ const struct wl_message *message);
+void
+wl_closure_invoke(struct wl_closure *closure,
+ struct wl_object *target, void (*func)(void), void *data);
+void
+wl_closure_send(struct wl_closure *closure, struct wl_connection *connection);
+void
+wl_closure_print(struct wl_closure *closure, struct wl_object *target);
+void
+wl_closure_destroy(struct wl_closure *closure);
+
+#endif
diff --git a/src/3rdparty/wayland/event-loop.c b/src/3rdparty/wayland/event-loop.c
new file mode 100644
index 000000000..bf2a9aafb
--- /dev/null
+++ b/src/3rdparty/wayland/event-loop.c
@@ -0,0 +1,444 @@
+/*
+ * Copyright © 2008 Kristian Høgsberg
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#include <stddef.h>
+#include <stdio.h>
+#include <errno.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/epoll.h>
+#include <sys/signalfd.h>
+#include <sys/timerfd.h>
+#include <unistd.h>
+#include <assert.h>
+#include "wayland-server.h"
+
+struct wl_event_loop {
+ int epoll_fd;
+ struct wl_list idle_list;
+};
+
+struct wl_event_source_interface {
+ void (*dispatch)(struct wl_event_source *source,
+ struct epoll_event *ep);
+ int (*remove)(struct wl_event_source *source);
+};
+
+struct wl_event_source {
+ struct wl_event_source_interface *interface;
+ struct wl_event_loop *loop;
+};
+
+struct wl_event_source_fd {
+ struct wl_event_source base;
+ int fd;
+ wl_event_loop_fd_func_t func;
+ void *data;
+};
+
+static void
+wl_event_source_fd_dispatch(struct wl_event_source *source,
+ struct epoll_event *ep)
+{
+ struct wl_event_source_fd *fd_source = (struct wl_event_source_fd *) source;
+ uint32_t mask;
+
+ mask = 0;
+ if (ep->events & EPOLLIN)
+ mask |= WL_EVENT_READABLE;
+ if (ep->events & EPOLLOUT)
+ mask |= WL_EVENT_WRITEABLE;
+
+ fd_source->func(fd_source->fd, mask, fd_source->data);
+}
+
+static int
+wl_event_source_fd_remove(struct wl_event_source *source)
+{
+ struct wl_event_source_fd *fd_source =
+ (struct wl_event_source_fd *) source;
+ struct wl_event_loop *loop = source->loop;
+ int fd;
+
+ fd = fd_source->fd;
+ free(source);
+
+ return epoll_ctl(loop->epoll_fd, EPOLL_CTL_DEL, fd, NULL);
+}
+
+struct wl_event_source_interface fd_source_interface = {
+ wl_event_source_fd_dispatch,
+ wl_event_source_fd_remove
+};
+
+WL_EXPORT struct wl_event_source *
+wl_event_loop_add_fd(struct wl_event_loop *loop,
+ int fd, uint32_t mask,
+ wl_event_loop_fd_func_t func,
+ void *data)
+{
+ struct wl_event_source_fd *source;
+ struct epoll_event ep;
+
+ source = malloc(sizeof *source);
+ if (source == NULL)
+ return NULL;
+
+ source->base.interface = &fd_source_interface;
+ source->base.loop = loop;
+ source->fd = fd;
+ source->func = func;
+ source->data = data;
+
+ memset(&ep, 0, sizeof ep);
+ if (mask & WL_EVENT_READABLE)
+ ep.events |= EPOLLIN;
+ if (mask & WL_EVENT_WRITEABLE)
+ ep.events |= EPOLLOUT;
+ ep.data.ptr = source;
+
+ if (epoll_ctl(loop->epoll_fd, EPOLL_CTL_ADD, fd, &ep) < 0) {
+ free(source);
+ return NULL;
+ }
+
+ return &source->base;
+}
+
+WL_EXPORT int
+wl_event_source_fd_update(struct wl_event_source *source, uint32_t mask)
+{
+ struct wl_event_source_fd *fd_source =
+ (struct wl_event_source_fd *) source;
+ struct wl_event_loop *loop = source->loop;
+ struct epoll_event ep;
+
+ memset(&ep, 0, sizeof ep);
+ if (mask & WL_EVENT_READABLE)
+ ep.events |= EPOLLIN;
+ if (mask & WL_EVENT_WRITEABLE)
+ ep.events |= EPOLLOUT;
+ ep.data.ptr = source;
+
+ return epoll_ctl(loop->epoll_fd,
+ EPOLL_CTL_MOD, fd_source->fd, &ep);
+}
+
+struct wl_event_source_timer {
+ struct wl_event_source base;
+ int fd;
+ wl_event_loop_timer_func_t func;
+ void *data;
+};
+
+static void
+wl_event_source_timer_dispatch(struct wl_event_source *source,
+ struct epoll_event *ep)
+{
+ struct wl_event_source_timer *timer_source =
+ (struct wl_event_source_timer *) source;
+ uint64_t expires;
+
+ read(timer_source->fd, &expires, sizeof expires);
+
+ timer_source->func(timer_source->data);
+}
+
+static int
+wl_event_source_timer_remove(struct wl_event_source *source)
+{
+ struct wl_event_source_timer *timer_source =
+ (struct wl_event_source_timer *) source;
+ struct wl_event_loop *loop = source->loop;
+ int fd;
+
+ fd = timer_source->fd;
+ free(source);
+
+ return epoll_ctl(loop->epoll_fd, EPOLL_CTL_DEL, fd, NULL);
+}
+
+struct wl_event_source_interface timer_source_interface = {
+ wl_event_source_timer_dispatch,
+ wl_event_source_timer_remove
+};
+
+WL_EXPORT struct wl_event_source *
+wl_event_loop_add_timer(struct wl_event_loop *loop,
+ wl_event_loop_timer_func_t func,
+ void *data)
+{
+ struct wl_event_source_timer *source;
+ struct epoll_event ep;
+
+ source = malloc(sizeof *source);
+ if (source == NULL)
+ return NULL;
+
+ source->base.interface = &timer_source_interface;
+ source->base.loop = loop;
+
+ source->fd = timerfd_create(CLOCK_MONOTONIC, 0);
+ if (source->fd < 0) {
+ fprintf(stderr, "could not create timerfd\n: %m");
+ free(source);
+ return NULL;
+ }
+
+ source->func = func;
+ source->data = data;
+
+ memset(&ep, 0, sizeof ep);
+ ep.events = EPOLLIN;
+ ep.data.ptr = source;
+
+ if (epoll_ctl(loop->epoll_fd, EPOLL_CTL_ADD, source->fd, &ep) < 0) {
+ free(source);
+ return NULL;
+ }
+
+ return &source->base;
+}
+
+WL_EXPORT int
+wl_event_source_timer_update(struct wl_event_source *source, int ms_delay)
+{
+ struct wl_event_source_timer *timer_source =
+ (struct wl_event_source_timer *) source;
+ struct itimerspec its;
+
+ its.it_interval.tv_sec = 0;
+ its.it_interval.tv_nsec = 0;
+ its.it_value.tv_sec = 0;
+ its.it_value.tv_nsec = ms_delay * 1000 * 1000;
+ if (timerfd_settime(timer_source->fd, 0, &its, NULL) < 0) {
+ fprintf(stderr, "could not set timerfd\n: %m");
+ return -1;
+ }
+
+ return 0;
+}
+
+struct wl_event_source_signal {
+ struct wl_event_source base;
+ int fd;
+ int signal_number;
+ wl_event_loop_signal_func_t func;
+ void *data;
+};
+
+static void
+wl_event_source_signal_dispatch(struct wl_event_source *source,
+ struct epoll_event *ep)
+{
+ struct wl_event_source_signal *signal_source =
+ (struct wl_event_source_signal *) source;
+ struct signalfd_siginfo signal_info;
+
+ read(signal_source->fd, &signal_info, sizeof signal_info);
+
+ signal_source->func(signal_source->signal_number, signal_source->data);
+}
+
+static int
+wl_event_source_signal_remove(struct wl_event_source *source)
+{
+ struct wl_event_source_signal *signal_source =
+ (struct wl_event_source_signal *) source;
+ struct wl_event_loop *loop = source->loop;
+ int fd;
+
+ fd = signal_source->fd;
+ free(source);
+
+ return epoll_ctl(loop->epoll_fd, EPOLL_CTL_DEL, fd, NULL);
+}
+
+struct wl_event_source_interface signal_source_interface = {
+ wl_event_source_signal_dispatch,
+ wl_event_source_signal_remove
+};
+
+WL_EXPORT struct wl_event_source *
+wl_event_loop_add_signal(struct wl_event_loop *loop,
+ int signal_number,
+ wl_event_loop_signal_func_t func,
+ void *data)
+{
+ struct wl_event_source_signal *source;
+ struct epoll_event ep;
+ sigset_t mask;
+
+ source = malloc(sizeof *source);
+ if (source == NULL)
+ return NULL;
+
+ source->base.interface = &signal_source_interface;
+ source->base.loop = loop;
+
+ sigemptyset(&mask);
+ sigaddset(&mask, signal_number);
+ source->fd = signalfd(-1, &mask, 0);
+ if (source->fd < 0) {
+ fprintf(stderr, "could not create fd to watch signal\n: %m");
+ free(source);
+ return NULL;
+ }
+ sigprocmask(SIG_BLOCK, &mask, NULL);
+
+ source->func = func;
+ source->data = data;
+
+ memset(&ep, 0, sizeof ep);
+ ep.events = EPOLLIN;
+ ep.data.ptr = source;
+
+ if (epoll_ctl(loop->epoll_fd, EPOLL_CTL_ADD, source->fd, &ep) < 0) {
+ free(source);
+ return NULL;
+ }
+
+ return &source->base;
+}
+
+struct wl_event_source_idle {
+ struct wl_event_source base;
+ struct wl_list link;
+ wl_event_loop_idle_func_t func;
+ void *data;
+};
+
+static void
+wl_event_source_idle_dispatch(struct wl_event_source *source,
+ struct epoll_event *ep)
+{
+ assert(0);
+}
+
+static int
+wl_event_source_idle_remove(struct wl_event_source *source)
+{
+ struct wl_event_source_idle *idle_source =
+ (struct wl_event_source_idle *) source;
+
+ wl_list_remove(&idle_source->link);
+ free(source);
+
+ return 0;
+}
+
+struct wl_event_source_interface idle_source_interface = {
+ wl_event_source_idle_dispatch,
+ wl_event_source_idle_remove
+};
+
+WL_EXPORT struct wl_event_source *
+wl_event_loop_add_idle(struct wl_event_loop *loop,
+ wl_event_loop_idle_func_t func,
+ void *data)
+{
+ struct wl_event_source_idle *source;
+
+ source = malloc(sizeof *source);
+ if (source == NULL)
+ return NULL;
+
+ source->base.interface = &idle_source_interface;
+ source->base.loop = loop;
+
+ source->func = func;
+ source->data = data;
+ wl_list_insert(loop->idle_list.prev, &source->link);
+
+ return &source->base;
+}
+
+WL_EXPORT int
+wl_event_source_remove(struct wl_event_source *source)
+{
+ source->interface->remove(source);
+
+ return 0;
+}
+
+WL_EXPORT struct wl_event_loop *
+wl_event_loop_create(void)
+{
+ struct wl_event_loop *loop;
+
+ loop = malloc(sizeof *loop);
+ if (loop == NULL)
+ return NULL;
+
+ loop->epoll_fd = epoll_create(16);
+ if (loop->epoll_fd < 0) {
+ free(loop);
+ return NULL;
+ }
+ wl_list_init(&loop->idle_list);
+
+ return loop;
+}
+
+WL_EXPORT void
+wl_event_loop_destroy(struct wl_event_loop *loop)
+{
+ close(loop->epoll_fd);
+ free(loop);
+}
+
+WL_EXPORT int
+wl_event_loop_dispatch(struct wl_event_loop *loop, int timeout)
+{
+ struct epoll_event ep[32];
+ struct wl_event_source *source;
+ struct wl_event_source_idle *idle;
+ int i, count;
+
+ count = epoll_wait(loop->epoll_fd, ep, ARRAY_LENGTH(ep), timeout);
+ if (count < 0)
+ return -1;
+
+ for (i = 0; i < count; i++) {
+ source = ep[i].data.ptr;
+ source->interface->dispatch(source, &ep[i]);
+ }
+
+ while (!wl_list_empty(&loop->idle_list)) {
+ idle = container_of(loop->idle_list.next,
+ struct wl_event_source_idle, link);
+ wl_list_remove(&idle->link);
+ idle->func(idle->data);
+ free(idle);
+ }
+
+ return 0;
+}
+
+WL_EXPORT int
+wl_event_loop_get_fd(struct wl_event_loop *loop)
+{
+ return loop->epoll_fd;
+}
diff --git a/src/3rdparty/wayland/server/server.pro b/src/3rdparty/wayland/server/server.pro
new file mode 100644
index 000000000..2c1788ce2
--- /dev/null
+++ b/src/3rdparty/wayland/server/server.pro
@@ -0,0 +1,20 @@
+TEMPLATE = lib
+TARGET = wayland-server
+DESTDIR=$$PWD/../../../../lib/
+
+CONFIG -= qt
+CONFIG += shared
+
+INCLUDEPATH += $$PWD/.. \
+ $$PWD/../../ffi
+
+LIBS += -L $$PWD/../../../../lib/ -lffi
+
+SOURCES = ../event-loop.c \
+ ../wayland-server.c \
+ ../wayland-protocol.c \
+ ../connection.c \
+ ../wayland-util.c \
+ ../wayland-hash.c
+
+OBJECTS_DIR = .obj
diff --git a/src/3rdparty/wayland/wayland-client-protocol.h b/src/3rdparty/wayland/wayland-client-protocol.h
new file mode 100644
index 000000000..0af6645bb
--- /dev/null
+++ b/src/3rdparty/wayland/wayland-client-protocol.h
@@ -0,0 +1,919 @@
+/*
+ * Copyright © 2010 Kristian Høgsberg
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+
+#ifndef WAYLAND_CLIENT_PROTOCOL_H
+#define WAYLAND_CLIENT_PROTOCOL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <stddef.h>
+#include "wayland-util.h"
+
+struct wl_client;
+
+struct wl_display;
+struct wl_compositor;
+struct wl_drm;
+struct wl_shm;
+struct wl_buffer;
+struct wl_shell;
+struct wl_selection;
+struct wl_selection_offer;
+struct wl_drag;
+struct wl_drag_offer;
+struct wl_surface;
+struct wl_input_device;
+struct wl_output;
+struct wl_visual;
+
+struct wl_proxy;
+
+extern void
+wl_proxy_marshal(struct wl_proxy *p, uint32_t opcode, ...);
+extern struct wl_proxy *
+wl_proxy_create(struct wl_proxy *factory,
+ const struct wl_interface *interface);
+extern struct wl_proxy *
+wl_proxy_create_for_id(struct wl_display *display,
+ const struct wl_interface *interface, uint32_t id);
+extern void
+wl_proxy_destroy(struct wl_proxy *proxy);
+
+extern int
+wl_proxy_add_listener(struct wl_proxy *proxy,
+ void (**implementation)(void), void *data);
+
+extern void
+wl_proxy_set_user_data(struct wl_proxy *proxy, void *user_data);
+
+extern void *
+wl_proxy_get_user_data(struct wl_proxy *proxy);
+
+extern const struct wl_interface wl_display_interface;
+extern const struct wl_interface wl_compositor_interface;
+extern const struct wl_interface wl_drm_interface;
+extern const struct wl_interface wl_shm_interface;
+extern const struct wl_interface wl_buffer_interface;
+extern const struct wl_interface wl_shell_interface;
+extern const struct wl_interface wl_selection_interface;
+extern const struct wl_interface wl_selection_offer_interface;
+extern const struct wl_interface wl_drag_interface;
+extern const struct wl_interface wl_drag_offer_interface;
+extern const struct wl_interface wl_surface_interface;
+extern const struct wl_interface wl_input_device_interface;
+extern const struct wl_interface wl_output_interface;
+extern const struct wl_interface wl_visual_interface;
+
+struct wl_display_listener {
+ void (*invalid_object)(void *data,
+ struct wl_display *display,
+ uint32_t object_id);
+ void (*invalid_method)(void *data,
+ struct wl_display *display,
+ uint32_t object_id,
+ uint32_t opcode);
+ void (*no_memory)(void *data,
+ struct wl_display *display);
+ void (*global)(void *data,
+ struct wl_display *display,
+ uint32_t id,
+ const char *name,
+ uint32_t version);
+ void (*range)(void *data,
+ struct wl_display *display,
+ uint32_t base);
+ void (*key)(void *data,
+ struct wl_display *display,
+ uint32_t key,
+ uint32_t time);
+};
+
+static inline int
+wl_display_add_listener(struct wl_display *display,
+ const struct wl_display_listener *listener, void *data)
+{
+ return wl_proxy_add_listener((struct wl_proxy *) display,
+ (void (**)(void)) listener, data);
+}
+
+#define WL_DISPLAY_SYNC 0
+#define WL_DISPLAY_FRAME 1
+
+static inline void
+wl_display_set_user_data(struct wl_display *display, void *user_data)
+{
+ wl_proxy_set_user_data((struct wl_proxy *) display, user_data);
+}
+
+static inline void *
+wl_display_get_user_data(struct wl_display *display)
+{
+ return wl_proxy_get_user_data((struct wl_proxy *) display);
+}
+
+static inline void
+wl_display_sync(struct wl_display *display, uint32_t key)
+{
+ wl_proxy_marshal((struct wl_proxy *) display,
+ WL_DISPLAY_SYNC, key);
+}
+
+static inline void
+wl_display_frame(struct wl_display *display, uint32_t key)
+{
+ wl_proxy_marshal((struct wl_proxy *) display,
+ WL_DISPLAY_FRAME, key);
+}
+
+#define WL_COMPOSITOR_CREATE_SURFACE 0
+
+static inline struct wl_compositor *
+wl_compositor_create(struct wl_display *display, uint32_t id)
+{
+ return (struct wl_compositor *)
+ wl_proxy_create_for_id(display, &wl_compositor_interface, id);
+}
+
+static inline void
+wl_compositor_set_user_data(struct wl_compositor *compositor, void *user_data)
+{
+ wl_proxy_set_user_data((struct wl_proxy *) compositor, user_data);
+}
+
+static inline void *
+wl_compositor_get_user_data(struct wl_compositor *compositor)
+{
+ return wl_proxy_get_user_data((struct wl_proxy *) compositor);
+}
+
+static inline void
+wl_compositor_destroy(struct wl_compositor *compositor)
+{
+ wl_proxy_destroy((struct wl_proxy *) compositor);
+}
+
+static inline struct wl_surface *
+wl_compositor_create_surface(struct wl_compositor *compositor)
+{
+ struct wl_proxy *id;
+
+ id = wl_proxy_create((struct wl_proxy *) compositor,
+ &wl_surface_interface);
+ if (!id)
+ return NULL;
+
+ wl_proxy_marshal((struct wl_proxy *) compositor,
+ WL_COMPOSITOR_CREATE_SURFACE, id);
+
+ return (struct wl_surface *) id;
+}
+
+struct wl_drm_listener {
+ void (*device)(void *data,
+ struct wl_drm *drm,
+ const char *name);
+ void (*authenticated)(void *data,
+ struct wl_drm *drm);
+};
+
+static inline int
+wl_drm_add_listener(struct wl_drm *drm,
+ const struct wl_drm_listener *listener, void *data)
+{
+ return wl_proxy_add_listener((struct wl_proxy *) drm,
+ (void (**)(void)) listener, data);
+}
+
+#define WL_DRM_AUTHENTICATE 0
+#define WL_DRM_CREATE_BUFFER 1
+
+static inline struct wl_drm *
+wl_drm_create(struct wl_display *display, uint32_t id)
+{
+ return (struct wl_drm *)
+ wl_proxy_create_for_id(display, &wl_drm_interface, id);
+}
+
+static inline void
+wl_drm_set_user_data(struct wl_drm *drm, void *user_data)
+{
+ wl_proxy_set_user_data((struct wl_proxy *) drm, user_data);
+}
+
+static inline void *
+wl_drm_get_user_data(struct wl_drm *drm)
+{
+ return wl_proxy_get_user_data((struct wl_proxy *) drm);
+}
+
+static inline void
+wl_drm_destroy(struct wl_drm *drm)
+{
+ wl_proxy_destroy((struct wl_proxy *) drm);
+}
+
+static inline void
+wl_drm_authenticate(struct wl_drm *drm, uint32_t id)
+{
+ wl_proxy_marshal((struct wl_proxy *) drm,
+ WL_DRM_AUTHENTICATE, id);
+}
+
+static inline struct wl_buffer *
+wl_drm_create_buffer(struct wl_drm *drm, uint32_t name, int width, int height, uint32_t stride, struct wl_visual *visual)
+{
+ struct wl_proxy *id;
+
+ id = wl_proxy_create((struct wl_proxy *) drm,
+ &wl_buffer_interface);
+ if (!id)
+ return NULL;
+
+ wl_proxy_marshal((struct wl_proxy *) drm,
+ WL_DRM_CREATE_BUFFER, id, name, width, height, stride, visual);
+
+ return (struct wl_buffer *) id;
+}
+
+#define WL_SHM_CREATE_BUFFER 0
+
+static inline struct wl_shm *
+wl_shm_create(struct wl_display *display, uint32_t id)
+{
+ return (struct wl_shm *)
+ wl_proxy_create_for_id(display, &wl_shm_interface, id);
+}
+
+static inline void
+wl_shm_set_user_data(struct wl_shm *shm, void *user_data)
+{
+ wl_proxy_set_user_data((struct wl_proxy *) shm, user_data);
+}
+
+static inline void *
+wl_shm_get_user_data(struct wl_shm *shm)
+{
+ return wl_proxy_get_user_data((struct wl_proxy *) shm);
+}
+
+static inline void
+wl_shm_destroy(struct wl_shm *shm)
+{
+ wl_proxy_destroy((struct wl_proxy *) shm);
+}
+
+static inline struct wl_buffer *
+wl_shm_create_buffer(struct wl_shm *shm, int fd, int width, int height, uint32_t stride, struct wl_visual *visual)
+{
+ struct wl_proxy *id;
+
+ id = wl_proxy_create((struct wl_proxy *) shm,
+ &wl_buffer_interface);
+ if (!id)
+ return NULL;
+
+ wl_proxy_marshal((struct wl_proxy *) shm,
+ WL_SHM_CREATE_BUFFER, id, fd, width, height, stride, visual);
+
+ return (struct wl_buffer *) id;
+}
+
+#define WL_BUFFER_DESTROY 0
+
+static inline struct wl_buffer *
+wl_buffer_create(struct wl_display *display, uint32_t id)
+{
+ return (struct wl_buffer *)
+ wl_proxy_create_for_id(display, &wl_buffer_interface, id);
+}
+
+static inline void
+wl_buffer_set_user_data(struct wl_buffer *buffer, void *user_data)
+{
+ wl_proxy_set_user_data((struct wl_proxy *) buffer, user_data);
+}
+
+static inline void *
+wl_buffer_get_user_data(struct wl_buffer *buffer)
+{
+ return wl_proxy_get_user_data((struct wl_proxy *) buffer);
+}
+
+static inline void
+wl_buffer_destroy(struct wl_buffer *buffer)
+{
+ wl_proxy_marshal((struct wl_proxy *) buffer,
+ WL_BUFFER_DESTROY);
+
+ wl_proxy_destroy((struct wl_proxy *) buffer);
+}
+
+#ifndef WL_SHELL_RESIZE_ENUM
+#define WL_SHELL_RESIZE_ENUM
+enum wl_shell_resize {
+ WL_SHELL_RESIZE_NONE = 0,
+ WL_SHELL_RESIZE_TOP = 1,
+ WL_SHELL_RESIZE_BOTTOM = 2,
+ WL_SHELL_RESIZE_LEFT = 4,
+ WL_SHELL_RESIZE_TOP_LEFT = 5,
+ WL_SHELL_RESIZE_BOTTOM_LEFT = 6,
+ WL_SHELL_RESIZE_RIGHT = 8,
+ WL_SHELL_RESIZE_TOP_RIGHT = 9,
+ WL_SHELL_RESIZE_BOTTOM_RIGHT = 10,
+};
+#endif /* WL_SHELL_RESIZE_ENUM */
+
+struct wl_shell_listener {
+ void (*configure)(void *data,
+ struct wl_shell *shell,
+ uint32_t time,
+ uint32_t edges,
+ struct wl_surface *surface,
+ int width,
+ int height);
+};
+
+static inline int
+wl_shell_add_listener(struct wl_shell *shell,
+ const struct wl_shell_listener *listener, void *data)
+{
+ return wl_proxy_add_listener((struct wl_proxy *) shell,
+ (void (**)(void)) listener, data);
+}
+
+#define WL_SHELL_MOVE 0
+#define WL_SHELL_RESIZE 1
+#define WL_SHELL_CREATE_DRAG 2
+#define WL_SHELL_CREATE_SELECTION 3
+
+static inline struct wl_shell *
+wl_shell_create(struct wl_display *display, uint32_t id)
+{
+ return (struct wl_shell *)
+ wl_proxy_create_for_id(display, &wl_shell_interface, id);
+}
+
+static inline void
+wl_shell_set_user_data(struct wl_shell *shell, void *user_data)
+{
+ wl_proxy_set_user_data((struct wl_proxy *) shell, user_data);
+}
+
+static inline void *
+wl_shell_get_user_data(struct wl_shell *shell)
+{
+ return wl_proxy_get_user_data((struct wl_proxy *) shell);
+}
+
+static inline void
+wl_shell_destroy(struct wl_shell *shell)
+{
+ wl_proxy_destroy((struct wl_proxy *) shell);
+}
+
+static inline void
+wl_shell_move(struct wl_shell *shell, struct wl_surface *surface, struct wl_input_device *input_device, uint32_t time)
+{
+ wl_proxy_marshal((struct wl_proxy *) shell,
+ WL_SHELL_MOVE, surface, input_device, time);
+}
+
+static inline void
+wl_shell_resize(struct wl_shell *shell, struct wl_surface *surface, struct wl_input_device *input_device, uint32_t time, uint32_t edges)
+{
+ wl_proxy_marshal((struct wl_proxy *) shell,
+ WL_SHELL_RESIZE, surface, input_device, time, edges);
+}
+
+static inline struct wl_drag *
+wl_shell_create_drag(struct wl_shell *shell)
+{
+ struct wl_proxy *id;
+
+ id = wl_proxy_create((struct wl_proxy *) shell,
+ &wl_drag_interface);
+ if (!id)
+ return NULL;
+
+ wl_proxy_marshal((struct wl_proxy *) shell,
+ WL_SHELL_CREATE_DRAG, id);
+
+ return (struct wl_drag *) id;
+}
+
+static inline struct wl_selection *
+wl_shell_create_selection(struct wl_shell *shell)
+{
+ struct wl_proxy *id;
+
+ id = wl_proxy_create((struct wl_proxy *) shell,
+ &wl_selection_interface);
+ if (!id)
+ return NULL;
+
+ wl_proxy_marshal((struct wl_proxy *) shell,
+ WL_SHELL_CREATE_SELECTION, id);
+
+ return (struct wl_selection *) id;
+}
+
+struct wl_selection_listener {
+ void (*send)(void *data,
+ struct wl_selection *selection,
+ const char *mime_type,
+ int fd);
+ void (*cancelled)(void *data,
+ struct wl_selection *selection);
+};
+
+static inline int
+wl_selection_add_listener(struct wl_selection *selection,
+ const struct wl_selection_listener *listener, void *data)
+{
+ return wl_proxy_add_listener((struct wl_proxy *) selection,
+ (void (**)(void)) listener, data);
+}
+
+#define WL_SELECTION_OFFER 0
+#define WL_SELECTION_ACTIVATE 1
+#define WL_SELECTION_DESTROY 2
+
+static inline struct wl_selection *
+wl_selection_create(struct wl_display *display, uint32_t id)
+{
+ return (struct wl_selection *)
+ wl_proxy_create_for_id(display, &wl_selection_interface, id);
+}
+
+static inline void
+wl_selection_set_user_data(struct wl_selection *selection, void *user_data)
+{
+ wl_proxy_set_user_data((struct wl_proxy *) selection, user_data);
+}
+
+static inline void *
+wl_selection_get_user_data(struct wl_selection *selection)
+{
+ return wl_proxy_get_user_data((struct wl_proxy *) selection);
+}
+
+static inline void
+wl_selection_offer(struct wl_selection *selection, const char *type)
+{
+ wl_proxy_marshal((struct wl_proxy *) selection,
+ WL_SELECTION_OFFER, type);
+}
+
+static inline void
+wl_selection_activate(struct wl_selection *selection, struct wl_input_device *input_device, uint32_t time)
+{
+ wl_proxy_marshal((struct wl_proxy *) selection,
+ WL_SELECTION_ACTIVATE, input_device, time);
+}
+
+static inline void
+wl_selection_destroy(struct wl_selection *selection)
+{
+ wl_proxy_marshal((struct wl_proxy *) selection,
+ WL_SELECTION_DESTROY);
+
+ wl_proxy_destroy((struct wl_proxy *) selection);
+}
+
+struct wl_selection_offer_listener {
+ void (*offer)(void *data,
+ struct wl_selection_offer *selection_offer,
+ const char *type);
+ void (*keyboard_focus)(void *data,
+ struct wl_selection_offer *selection_offer,
+ struct wl_input_device *input_device);
+};
+
+static inline int
+wl_selection_offer_add_listener(struct wl_selection_offer *selection_offer,
+ const struct wl_selection_offer_listener *listener, void *data)
+{
+ return wl_proxy_add_listener((struct wl_proxy *) selection_offer,
+ (void (**)(void)) listener, data);
+}
+
+#define WL_SELECTION_OFFER_RECEIVE 0
+
+static inline struct wl_selection_offer *
+wl_selection_offer_create(struct wl_display *display, uint32_t id)
+{
+ return (struct wl_selection_offer *)
+ wl_proxy_create_for_id(display, &wl_selection_offer_interface, id);
+}
+
+static inline void
+wl_selection_offer_set_user_data(struct wl_selection_offer *selection_offer, void *user_data)
+{
+ wl_proxy_set_user_data((struct wl_proxy *) selection_offer, user_data);
+}
+
+static inline void *
+wl_selection_offer_get_user_data(struct wl_selection_offer *selection_offer)
+{
+ return wl_proxy_get_user_data((struct wl_proxy *) selection_offer);
+}
+
+static inline void
+wl_selection_offer_destroy(struct wl_selection_offer *selection_offer)
+{
+ wl_proxy_destroy((struct wl_proxy *) selection_offer);
+}
+
+static inline void
+wl_selection_offer_receive(struct wl_selection_offer *selection_offer, const char *mime_type, int fd)
+{
+ wl_proxy_marshal((struct wl_proxy *) selection_offer,
+ WL_SELECTION_OFFER_RECEIVE, mime_type, fd);
+}
+
+struct wl_drag_listener {
+ void (*target)(void *data,
+ struct wl_drag *drag,
+ const char *mime_type);
+ void (*finish)(void *data,
+ struct wl_drag *drag,
+ int fd);
+ void (*reject)(void *data,
+ struct wl_drag *drag);
+};
+
+static inline int
+wl_drag_add_listener(struct wl_drag *drag,
+ const struct wl_drag_listener *listener, void *data)
+{
+ return wl_proxy_add_listener((struct wl_proxy *) drag,
+ (void (**)(void)) listener, data);
+}
+
+#define WL_DRAG_OFFER 0
+#define WL_DRAG_ACTIVATE 1
+#define WL_DRAG_DESTROY 2
+
+static inline struct wl_drag *
+wl_drag_create(struct wl_display *display, uint32_t id)
+{
+ return (struct wl_drag *)
+ wl_proxy_create_for_id(display, &wl_drag_interface, id);
+}
+
+static inline void
+wl_drag_set_user_data(struct wl_drag *drag, void *user_data)
+{
+ wl_proxy_set_user_data((struct wl_proxy *) drag, user_data);
+}
+
+static inline void *
+wl_drag_get_user_data(struct wl_drag *drag)
+{
+ return wl_proxy_get_user_data((struct wl_proxy *) drag);
+}
+
+static inline void
+wl_drag_offer(struct wl_drag *drag, const char *type)
+{
+ wl_proxy_marshal((struct wl_proxy *) drag,
+ WL_DRAG_OFFER, type);
+}
+
+static inline void
+wl_drag_activate(struct wl_drag *drag, struct wl_surface *surface, struct wl_input_device *input_device, uint32_t time)
+{
+ wl_proxy_marshal((struct wl_proxy *) drag,
+ WL_DRAG_ACTIVATE, surface, input_device, time);
+}
+
+static inline void
+wl_drag_destroy(struct wl_drag *drag)
+{
+ wl_proxy_marshal((struct wl_proxy *) drag,
+ WL_DRAG_DESTROY);
+
+ wl_proxy_destroy((struct wl_proxy *) drag);
+}
+
+struct wl_drag_offer_listener {
+ void (*offer)(void *data,
+ struct wl_drag_offer *drag_offer,
+ const char *type);
+ void (*pointer_focus)(void *data,
+ struct wl_drag_offer *drag_offer,
+ uint32_t time,
+ struct wl_surface *surface,
+ int x,
+ int y,
+ int surface_x,
+ int surface_y);
+ void (*motion)(void *data,
+ struct wl_drag_offer *drag_offer,
+ uint32_t time,
+ int x,
+ int y,
+ int surface_x,
+ int surface_y);
+ void (*drop)(void *data,
+ struct wl_drag_offer *drag_offer);
+};
+
+static inline int
+wl_drag_offer_add_listener(struct wl_drag_offer *drag_offer,
+ const struct wl_drag_offer_listener *listener, void *data)
+{
+ return wl_proxy_add_listener((struct wl_proxy *) drag_offer,
+ (void (**)(void)) listener, data);
+}
+
+#define WL_DRAG_OFFER_ACCEPT 0
+#define WL_DRAG_OFFER_RECEIVE 1
+#define WL_DRAG_OFFER_REJECT 2
+
+static inline struct wl_drag_offer *
+wl_drag_offer_create(struct wl_display *display, uint32_t id)
+{
+ return (struct wl_drag_offer *)
+ wl_proxy_create_for_id(display, &wl_drag_offer_interface, id);
+}
+
+static inline void
+wl_drag_offer_set_user_data(struct wl_drag_offer *drag_offer, void *user_data)
+{
+ wl_proxy_set_user_data((struct wl_proxy *) drag_offer, user_data);
+}
+
+static inline void *
+wl_drag_offer_get_user_data(struct wl_drag_offer *drag_offer)
+{
+ return wl_proxy_get_user_data((struct wl_proxy *) drag_offer);
+}
+
+static inline void
+wl_drag_offer_destroy(struct wl_drag_offer *drag_offer)
+{
+ wl_proxy_destroy((struct wl_proxy *) drag_offer);
+}
+
+static inline void
+wl_drag_offer_accept(struct wl_drag_offer *drag_offer, uint32_t time, const char *type)
+{
+ wl_proxy_marshal((struct wl_proxy *) drag_offer,
+ WL_DRAG_OFFER_ACCEPT, time, type);
+}
+
+static inline void
+wl_drag_offer_receive(struct wl_drag_offer *drag_offer, int fd)
+{
+ wl_proxy_marshal((struct wl_proxy *) drag_offer,
+ WL_DRAG_OFFER_RECEIVE, fd);
+}
+
+static inline void
+wl_drag_offer_reject(struct wl_drag_offer *drag_offer)
+{
+ wl_proxy_marshal((struct wl_proxy *) drag_offer,
+ WL_DRAG_OFFER_REJECT);
+}
+
+#define WL_SURFACE_DESTROY 0
+#define WL_SURFACE_ATTACH 1
+#define WL_SURFACE_MAP_TOPLEVEL 2
+#define WL_SURFACE_MAP_TRANSIENT 3
+#define WL_SURFACE_MAP_FULLSCREEN 4
+#define WL_SURFACE_DAMAGE 5
+
+static inline struct wl_surface *
+wl_surface_create(struct wl_display *display, uint32_t id)
+{
+ return (struct wl_surface *)
+ wl_proxy_create_for_id(display, &wl_surface_interface, id);
+}
+
+static inline void
+wl_surface_set_user_data(struct wl_surface *surface, void *user_data)
+{
+ wl_proxy_set_user_data((struct wl_proxy *) surface, user_data);
+}
+
+static inline void *
+wl_surface_get_user_data(struct wl_surface *surface)
+{
+ return wl_proxy_get_user_data((struct wl_proxy *) surface);
+}
+
+static inline void
+wl_surface_destroy(struct wl_surface *surface)
+{
+ wl_proxy_marshal((struct wl_proxy *) surface,
+ WL_SURFACE_DESTROY);
+
+ wl_proxy_destroy((struct wl_proxy *) surface);
+}
+
+static inline void
+wl_surface_attach(struct wl_surface *surface, struct wl_buffer *buffer, int x, int y)
+{
+ wl_proxy_marshal((struct wl_proxy *) surface,
+ WL_SURFACE_ATTACH, buffer, x, y);
+}
+
+static inline void
+wl_surface_map_toplevel(struct wl_surface *surface)
+{
+ wl_proxy_marshal((struct wl_proxy *) surface,
+ WL_SURFACE_MAP_TOPLEVEL);
+}
+
+static inline void
+wl_surface_map_transient(struct wl_surface *surface, struct wl_surface *parent, int x, int y, uint32_t flags)
+{
+ wl_proxy_marshal((struct wl_proxy *) surface,
+ WL_SURFACE_MAP_TRANSIENT, parent, x, y, flags);
+}
+
+static inline void
+wl_surface_map_fullscreen(struct wl_surface *surface)
+{
+ wl_proxy_marshal((struct wl_proxy *) surface,
+ WL_SURFACE_MAP_FULLSCREEN);
+}
+
+static inline void
+wl_surface_damage(struct wl_surface *surface, int x, int y, int width, int height)
+{
+ wl_proxy_marshal((struct wl_proxy *) surface,
+ WL_SURFACE_DAMAGE, x, y, width, height);
+}
+
+struct wl_input_device_listener {
+ void (*motion)(void *data,
+ struct wl_input_device *input_device,
+ uint32_t time,
+ int x,
+ int y,
+ int surface_x,
+ int surface_y);
+ void (*button)(void *data,
+ struct wl_input_device *input_device,
+ uint32_t time,
+ uint32_t button,
+ uint32_t state);
+ void (*key)(void *data,
+ struct wl_input_device *input_device,
+ uint32_t time,
+ uint32_t key,
+ uint32_t state);
+ void (*pointer_focus)(void *data,
+ struct wl_input_device *input_device,
+ uint32_t time,
+ struct wl_surface *surface,
+ int x,
+ int y,
+ int surface_x,
+ int surface_y);
+ void (*keyboard_focus)(void *data,
+ struct wl_input_device *input_device,
+ uint32_t time,
+ struct wl_surface *surface,
+ struct wl_array *keys);
+};
+
+static inline int
+wl_input_device_add_listener(struct wl_input_device *input_device,
+ const struct wl_input_device_listener *listener, void *data)
+{
+ return wl_proxy_add_listener((struct wl_proxy *) input_device,
+ (void (**)(void)) listener, data);
+}
+
+#define WL_INPUT_DEVICE_ATTACH 0
+
+static inline struct wl_input_device *
+wl_input_device_create(struct wl_display *display, uint32_t id)
+{
+ return (struct wl_input_device *)
+ wl_proxy_create_for_id(display, &wl_input_device_interface, id);
+}
+
+static inline void
+wl_input_device_set_user_data(struct wl_input_device *input_device, void *user_data)
+{
+ wl_proxy_set_user_data((struct wl_proxy *) input_device, user_data);
+}
+
+static inline void *
+wl_input_device_get_user_data(struct wl_input_device *input_device)
+{
+ return wl_proxy_get_user_data((struct wl_proxy *) input_device);
+}
+
+static inline void
+wl_input_device_destroy(struct wl_input_device *input_device)
+{
+ wl_proxy_destroy((struct wl_proxy *) input_device);
+}
+
+static inline void
+wl_input_device_attach(struct wl_input_device *input_device, uint32_t time, struct wl_buffer *buffer, int hotspot_x, int hotspot_y)
+{
+ wl_proxy_marshal((struct wl_proxy *) input_device,
+ WL_INPUT_DEVICE_ATTACH, time, buffer, hotspot_x, hotspot_y);
+}
+
+struct wl_output_listener {
+ void (*geometry)(void *data,
+ struct wl_output *output,
+ int x,
+ int y,
+ int width,
+ int height);
+};
+
+static inline int
+wl_output_add_listener(struct wl_output *output,
+ const struct wl_output_listener *listener, void *data)
+{
+ return wl_proxy_add_listener((struct wl_proxy *) output,
+ (void (**)(void)) listener, data);
+}
+
+static inline struct wl_output *
+wl_output_create(struct wl_display *display, uint32_t id)
+{
+ return (struct wl_output *)
+ wl_proxy_create_for_id(display, &wl_output_interface, id);
+}
+
+static inline void
+wl_output_set_user_data(struct wl_output *output, void *user_data)
+{
+ wl_proxy_set_user_data((struct wl_proxy *) output, user_data);
+}
+
+static inline void *
+wl_output_get_user_data(struct wl_output *output)
+{
+ return wl_proxy_get_user_data((struct wl_proxy *) output);
+}
+
+static inline void
+wl_output_destroy(struct wl_output *output)
+{
+ wl_proxy_destroy((struct wl_proxy *) output);
+}
+
+static inline struct wl_visual *
+wl_visual_create(struct wl_display *display, uint32_t id)
+{
+ return (struct wl_visual *)
+ wl_proxy_create_for_id(display, &wl_visual_interface, id);
+}
+
+static inline void
+wl_visual_set_user_data(struct wl_visual *visual, void *user_data)
+{
+ wl_proxy_set_user_data((struct wl_proxy *) visual, user_data);
+}
+
+static inline void *
+wl_visual_get_user_data(struct wl_visual *visual)
+{
+ return wl_proxy_get_user_data((struct wl_proxy *) visual);
+}
+
+static inline void
+wl_visual_destroy(struct wl_visual *visual)
+{
+ wl_proxy_destroy((struct wl_proxy *) visual);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/3rdparty/wayland/wayland-client.c b/src/3rdparty/wayland/wayland-client.c
new file mode 100644
index 000000000..e3198c729
--- /dev/null
+++ b/src/3rdparty/wayland/wayland-client.c
@@ -0,0 +1,565 @@
+/*
+ * Copyright © 2008 Kristian Høgsberg
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <stddef.h>
+#include <stdio.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 <sys/poll.h>
+
+#include "wayland-client-protocol.h"
+#include "connection.h"
+#include "wayland-util.h"
+#include "wayland-client.h"
+
+struct wl_global_listener {
+ wl_display_global_func_t handler;
+ void *data;
+ struct wl_list link;
+};
+
+struct wl_listener {
+ void (**implementation)(void);
+ void *data;
+ struct wl_list link;
+};
+
+struct wl_proxy {
+ struct wl_object object;
+ struct wl_display *display;
+ struct wl_list listener_list;
+ void *user_data;
+};
+
+struct wl_sync_handler {
+ wl_display_sync_func_t func;
+ uint32_t key;
+ void *data;
+ struct wl_list link;
+};
+
+struct wl_frame_handler {
+ wl_display_frame_func_t func;
+ uint32_t key;
+ void *data;
+ struct wl_list link;
+};
+
+struct wl_display {
+ struct wl_proxy proxy;
+ struct wl_connection *connection;
+ int fd;
+ uint32_t id, id_count, next_range;
+ uint32_t mask;
+ struct wl_hash_table *objects;
+ struct wl_listener listener;
+ struct wl_list global_listener_list;
+
+ struct wl_visual *argb_visual;
+ struct wl_visual *premultiplied_argb_visual;
+ struct wl_visual *rgb_visual;
+
+ wl_display_update_func_t update;
+ void *update_data;
+
+ wl_display_global_func_t global_handler;
+ void *global_handler_data;
+
+ struct wl_list sync_list, frame_list;
+ uint32_t key;
+};
+
+static int wl_debug = 0;
+
+static int
+connection_update(struct wl_connection *connection,
+ uint32_t mask, void *data)
+{
+ struct wl_display *display = data;
+
+ display->mask = mask;
+ if (display->update)
+ return display->update(display->mask,
+ display->update_data);
+
+ return 0;
+}
+
+WL_EXPORT struct wl_global_listener *
+wl_display_add_global_listener(struct wl_display *display,
+ wl_display_global_func_t handler, void *data)
+{
+ struct wl_global_listener *listener;
+
+ listener = malloc(sizeof *listener);
+ if (listener == NULL)
+ return NULL;
+
+ listener->handler = handler;
+ listener->data = data;
+ wl_list_insert(display->global_listener_list.prev, &listener->link);
+
+ return listener;
+}
+
+WL_EXPORT void
+wl_display_remove_global_listener(struct wl_display *display,
+ struct wl_global_listener *listener)
+{
+ wl_list_remove(&listener->link);
+ free(listener);
+}
+
+WL_EXPORT struct wl_proxy *
+wl_proxy_create_for_id(struct wl_display *display,
+ const struct wl_interface *interface, uint32_t id)
+{
+ struct wl_proxy *proxy;
+
+ proxy = malloc(sizeof *proxy);
+ if (proxy == NULL)
+ return NULL;
+
+ proxy->object.interface = interface;
+ proxy->object.id = id;
+ proxy->display = display;
+ wl_list_init(&proxy->listener_list);
+ wl_hash_table_insert(display->objects, proxy->object.id, proxy);
+
+ return proxy;
+}
+
+WL_EXPORT struct wl_proxy *
+wl_proxy_create(struct wl_proxy *factory,
+ const struct wl_interface *interface)
+{
+ return wl_proxy_create_for_id(factory->display, interface,
+ wl_display_allocate_id(factory->display));
+}
+
+WL_EXPORT void
+wl_proxy_destroy(struct wl_proxy *proxy)
+{
+ struct wl_listener *listener, *next;
+
+ wl_list_for_each_safe(listener, next, &proxy->listener_list, link)
+ free(listener);
+
+ wl_hash_table_remove(proxy->display->objects, proxy->object.id);
+ free(proxy);
+}
+
+WL_EXPORT int
+wl_proxy_add_listener(struct wl_proxy *proxy,
+ void (**implementation)(void), void *data)
+{
+ struct wl_listener *listener;
+
+ listener = malloc(sizeof *listener);
+ if (listener == NULL)
+ return -1;
+
+ listener->implementation = (void (**)(void)) implementation;
+ listener->data = data;
+ wl_list_insert(proxy->listener_list.prev, &listener->link);
+
+ return 0;
+}
+
+WL_EXPORT void
+wl_proxy_marshal(struct wl_proxy *proxy, uint32_t opcode, ...)
+{
+ struct wl_closure *closure;
+ va_list ap;
+
+ va_start(ap, opcode);
+ closure = wl_connection_vmarshal(proxy->display->connection,
+ &proxy->object, opcode, ap,
+ &proxy->object.interface->methods[opcode]);
+ va_end(ap);
+
+ wl_closure_send(closure, proxy->display->connection);
+
+ if (wl_debug) {
+ fprintf(stderr, " -> ");
+ wl_closure_print(closure, &proxy->object);
+ }
+
+ wl_closure_destroy(closure);
+}
+
+static void
+add_visual(struct wl_display *display, uint32_t id)
+{
+ struct wl_visual *visual;
+
+ visual = (struct wl_visual *)
+ wl_proxy_create_for_id(display, &wl_visual_interface, id);
+ if (display->argb_visual == NULL)
+ display->argb_visual = visual;
+ else if (display->premultiplied_argb_visual == NULL)
+ display->premultiplied_argb_visual = visual;
+ else
+ display->rgb_visual = visual;
+}
+
+WL_EXPORT struct wl_visual *
+wl_display_get_argb_visual(struct wl_display *display)
+{
+ return display->argb_visual;
+}
+
+WL_EXPORT struct wl_visual *
+wl_display_get_premultiplied_argb_visual(struct wl_display *display)
+{
+ return display->premultiplied_argb_visual;
+}
+
+WL_EXPORT struct wl_visual *
+wl_display_get_rgb_visual(struct wl_display *display)
+{
+ return display->rgb_visual;
+}
+
+static void
+display_handle_invalid_object(void *data,
+ struct wl_display *display, uint32_t id)
+{
+ fprintf(stderr, "sent request to invalid object\n");
+ abort();
+}
+
+static void
+display_handle_invalid_method(void *data,
+ struct wl_display *display,
+ uint32_t id, uint32_t opcode)
+{
+ fprintf(stderr, "sent invalid request opcode\n");
+ abort();
+}
+
+static void
+display_handle_no_memory(void *data,
+ struct wl_display *display)
+{
+ fprintf(stderr, "server out of memory\n");
+ abort();
+}
+
+static void
+display_handle_global(void *data,
+ struct wl_display *display,
+ uint32_t id, const char *interface, uint32_t version)
+{
+ struct wl_global_listener *listener;
+
+ if (strcmp(interface, "display") == 0)
+ wl_hash_table_insert(display->objects,
+ id, &display->proxy.object);
+ else if (strcmp(interface, "visual") == 0)
+ add_visual(display, id);
+
+ wl_list_for_each(listener, &display->global_listener_list, link)
+ (*listener->handler)(display,
+ id, interface, version, listener->data);
+}
+
+static void
+display_handle_range(void *data,
+ struct wl_display *display, uint32_t range)
+{
+ display->next_range = range;
+}
+
+static void
+display_handle_key(void *data,
+ struct wl_display *display, uint32_t key, uint32_t time)
+{
+ struct wl_sync_handler *sync_handler;
+ struct wl_frame_handler *frame_handler;
+
+ sync_handler = container_of(display->sync_list.next,
+ struct wl_sync_handler, link);
+ if (!wl_list_empty(&display->sync_list) && sync_handler->key == key) {
+ wl_list_remove(&sync_handler->link);
+ sync_handler->func(sync_handler->data);
+ free(sync_handler);
+ return;
+ }
+
+ frame_handler = container_of(display->frame_list. next,
+ struct wl_frame_handler, link);
+ if (!wl_list_empty(&display->frame_list) &&
+ frame_handler->key == key) {
+ wl_list_remove(&frame_handler->link);
+ frame_handler->func(frame_handler->data, time);
+ free(frame_handler);
+ return;
+ }
+
+ fprintf(stderr, "unsolicited sync event, client gone?\n");
+}
+
+static const struct wl_display_listener display_listener = {
+ display_handle_invalid_object,
+ display_handle_invalid_method,
+ display_handle_no_memory,
+ display_handle_global,
+ display_handle_range,
+ display_handle_key
+};
+
+WL_EXPORT struct wl_display *
+wl_display_connect(const char *name)
+{
+ struct wl_display *display;
+ struct sockaddr_un addr;
+ socklen_t size;
+ const char *runtime_dir;
+ const char *debug;
+ size_t name_size;
+
+ debug = getenv("WAYLAND_DEBUG");
+ if (debug)
+ wl_debug = 1;
+
+ display = malloc(sizeof *display);
+ if (display == NULL)
+ return NULL;
+
+ memset(display, 0, sizeof *display);
+ display->fd = socket(PF_LOCAL, SOCK_STREAM, 0);
+ if (display->fd < 0) {
+ free(display);
+ return NULL;
+ }
+
+ runtime_dir = getenv("XDG_RUNTIME_DIR");
+ if (runtime_dir == NULL) {
+ runtime_dir = ".";
+ fprintf(stderr,
+ "XDG_RUNTIME_DIR not set, falling back to %s\n",
+ runtime_dir);
+ }
+
+ if (name == NULL)
+ name = getenv("WAYLAND_DISPLAY");
+ if (name == NULL)
+ name = "wayland-0";
+
+ memset(&addr, 0, sizeof addr);
+ addr.sun_family = AF_LOCAL;
+ name_size =
+ snprintf(addr.sun_path, sizeof addr.sun_path,
+ "%s/%s", runtime_dir, name) + 1;
+
+ size = offsetof (struct sockaddr_un, sun_path) + name_size;
+
+ if (connect(display->fd, (struct sockaddr *) &addr, size) < 0) {
+ close(display->fd);
+ free(display);
+ return NULL;
+ }
+
+ display->objects = wl_hash_table_create();
+ wl_list_init(&display->global_listener_list);
+
+ display->proxy.object.interface = &wl_display_interface;
+ display->proxy.object.id = 1;
+ display->proxy.display = display;
+ wl_list_init(&display->proxy.listener_list);
+
+ wl_list_init(&display->sync_list);
+ wl_list_init(&display->frame_list);
+
+ display->listener.implementation = (void(**)(void)) &display_listener;
+ wl_list_insert(display->proxy.listener_list.prev, &display->listener.link);
+
+ display->connection = wl_connection_create(display->fd,
+ connection_update,
+ display);
+
+ return display;
+}
+
+WL_EXPORT void
+wl_display_destroy(struct wl_display *display)
+{
+ wl_connection_destroy(display->connection);
+ close(display->fd);
+ free(display);
+}
+
+WL_EXPORT int
+wl_display_get_fd(struct wl_display *display,
+ wl_display_update_func_t update, void *data)
+{
+ display->update = update;
+ display->update_data = data;
+
+ display->update(display->mask, display->update_data);
+
+ return display->fd;
+}
+
+WL_EXPORT int
+wl_display_sync_callback(struct wl_display *display,
+ wl_display_sync_func_t func, void *data)
+{
+ struct wl_sync_handler *handler;
+
+ handler = malloc(sizeof *handler);
+ if (handler == NULL)
+ return -1;
+
+ handler->func = func;
+ handler->key = display->key++;
+ handler->data = data;
+
+ wl_list_insert(display->sync_list.prev, &handler->link);
+ wl_display_sync(display, handler->key);
+
+ return 0;
+}
+
+WL_EXPORT int
+wl_display_frame_callback(struct wl_display *display,
+ wl_display_frame_func_t func, void *data)
+{
+ struct wl_frame_handler *handler;
+
+ handler = malloc(sizeof *handler);
+ if (handler == NULL)
+ return -1;
+
+ handler->func = func;
+ handler->key = display->key++;
+ handler->data = data;
+
+ wl_list_insert(display->frame_list.prev, &handler->link);
+ wl_display_frame(display, handler->key);
+
+ return 0;
+}
+
+static void
+handle_event(struct wl_display *display,
+ uint32_t id, uint32_t opcode, uint32_t size)
+{
+ uint32_t p[32];
+ struct wl_listener *listener;
+ struct wl_proxy *proxy;
+ struct wl_closure *closure;
+ const struct wl_message *message;
+
+ wl_connection_copy(display->connection, p, size);
+ if (id == 1)
+ proxy = &display->proxy;
+ else
+ proxy = wl_hash_table_lookup(display->objects, id);
+
+ if (proxy == NULL) {
+ wl_connection_consume(display->connection, size);
+ return;
+ }
+
+ message = &proxy->object.interface->events[opcode];
+ closure = wl_connection_demarshal(display->connection,
+ size, display->objects, message);
+
+ if (wl_debug)
+ wl_closure_print(closure, &proxy->object);
+
+ wl_list_for_each(listener, &proxy->listener_list, link)
+ wl_closure_invoke(closure, &proxy->object,
+ listener->implementation[opcode],
+ listener->data);
+
+ wl_closure_destroy(closure);
+}
+
+WL_EXPORT void
+wl_display_iterate(struct wl_display *display, uint32_t mask)
+{
+ uint32_t p[2], object, opcode, size;
+ int len;
+
+ mask &= display->mask;
+ if (mask == 0) {
+ fprintf(stderr,
+ "wl_display_iterate called with unsolicited flags");
+ return;
+ }
+
+ len = wl_connection_data(display->connection, mask);
+ while (len > 0) {
+ if (len < sizeof p)
+ break;
+
+ wl_connection_copy(display->connection, p, sizeof p);
+ object = p[0];
+ opcode = p[1] & 0xffff;
+ size = p[1] >> 16;
+ if (len < size)
+ break;
+
+ handle_event(display, object, opcode, size);
+ len -= size;
+ }
+
+ if (len < 0) {
+ fprintf(stderr, "read error: %m\n");
+ exit(EXIT_FAILURE);
+ }
+}
+
+WL_EXPORT uint32_t
+wl_display_allocate_id(struct wl_display *display)
+{
+ if (display->id_count == 0) {
+ display->id_count = 256;
+ display->id = display->next_range;
+ }
+
+ display->id_count--;
+
+ return display->id++;
+}
+
+WL_EXPORT void
+wl_proxy_set_user_data(struct wl_proxy *proxy, void *user_data)
+{
+ proxy->user_data = user_data;
+}
+
+WL_EXPORT void *
+wl_proxy_get_user_data(struct wl_proxy *proxy)
+{
+ return proxy->user_data;
+}
diff --git a/src/3rdparty/wayland/wayland-client.h b/src/3rdparty/wayland/wayland-client.h
new file mode 100644
index 000000000..d207b0763
--- /dev/null
+++ b/src/3rdparty/wayland/wayland-client.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright © 2008 Kristian Høgsberg
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#ifndef _WAYLAND_CLIENT_H
+#define _WAYLAND_CLIENT_H
+
+#include "wayland-util.h"
+#include "wayland-client-protocol.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define WL_DISPLAY_READABLE 0x01
+#define WL_DISPLAY_WRITABLE 0x02
+
+typedef int (*wl_display_update_func_t)(uint32_t mask, void *data);
+typedef void (*wl_display_sync_func_t)(void *data);
+typedef void (*wl_display_frame_func_t)(void *data, uint32_t time);
+
+struct wl_display *wl_display_connect(const char *name);
+void wl_display_destroy(struct wl_display *display);
+int wl_display_get_fd(struct wl_display *display,
+ wl_display_update_func_t update, void *data);
+uint32_t wl_display_allocate_id(struct wl_display *display);
+void wl_display_iterate(struct wl_display *display, uint32_t mask);
+int wl_display_sync_callback(struct wl_display *display,
+ wl_display_sync_func_t func, void *data);
+int wl_display_frame_callback(struct wl_display *display,
+ wl_display_frame_func_t func, void *data);
+
+struct wl_global_listener;
+typedef void (*wl_display_global_func_t)(struct wl_display *display,
+ uint32_t id,
+ const char *interface,
+ uint32_t version,
+ void *data);
+void
+wl_display_remove_global_listener(struct wl_display *display,
+ struct wl_global_listener *listener);
+
+struct wl_global_listener *
+wl_display_add_global_listener(struct wl_display *display,
+ wl_display_global_func_t handler, void *data);
+struct wl_visual *
+wl_display_get_argb_visual(struct wl_display *display);
+struct wl_visual *
+wl_display_get_premultiplied_argb_visual(struct wl_display *display);
+struct wl_visual *
+wl_display_get_rgb_visual(struct wl_display *display);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/3rdparty/wayland/wayland-egl.h b/src/3rdparty/wayland/wayland-egl.h
new file mode 100644
index 000000000..d3de87c79
--- /dev/null
+++ b/src/3rdparty/wayland/wayland-egl.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright © 2011 Kristian Høgsberg
+ * Copyright © 2011 Benjamin Franzke
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#ifndef _WAYLAND_EGL_H
+#define _WAYLAND_EGL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <wayland-client.h>
+
+#define WL_EGL_PLATFORM 1
+
+struct wl_egl_display;
+struct wl_egl_window;
+struct wl_egl_pixmap;
+
+struct wl_egl_display *
+wl_egl_display_create(struct wl_display *egl_display);
+
+void
+wl_egl_display_destroy(struct wl_egl_display *egl_display);
+
+struct wl_egl_window *
+wl_egl_window_create(struct wl_egl_display *egl_display,
+ struct wl_surface *surface,
+ int width, int height,
+ struct wl_visual *visual);
+
+void
+wl_egl_window_destroy(struct wl_egl_window *egl_window);
+
+void
+wl_egl_window_resize(struct wl_egl_window *egl_window,
+ int width, int height,
+ int dx, int dy);
+
+void
+wl_egl_window_get_attached_size(struct wl_egl_window *egl_window,
+ int *width, int *height);
+
+struct wl_egl_pixmap *
+wl_egl_pixmap_create(struct wl_egl_display *egl_display,
+ int width, int height,
+ struct wl_visual *visual, uint32_t flags);
+void
+wl_egl_pixmap_destroy(struct wl_egl_pixmap *egl_pixmap);
+
+struct wl_buffer *
+wl_egl_pixmap_create_buffer(struct wl_egl_display *egl_display,
+ struct wl_egl_pixmap *egl_pixmap);
+
+void
+wl_egl_pixmap_flush(struct wl_egl_display *egl_display,
+ struct wl_egl_pixmap *egl_pixmap);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/3rdparty/wayland/wayland-hash.c b/src/3rdparty/wayland/wayland-hash.c
new file mode 100644
index 000000000..b299a33da
--- /dev/null
+++ b/src/3rdparty/wayland/wayland-hash.c
@@ -0,0 +1,296 @@
+/*
+ * Copyright © 2009 Intel Corporation
+ * Copyright © 1988-2004 Keith Packard and Bart Massey.
+ *
+ * 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.
+ *
+ * Except as contained in this notice, the names of the authors
+ * or their institutions shall not be used in advertising or
+ * otherwise to promote the sale, use or other dealings in this
+ * Software without prior written authorization from the
+ * authors.
+ *
+ * Authors:
+ * Eric Anholt <eric@anholt.net>
+ * Keith Packard <keithp@keithp.com>
+ */
+
+#include <stdlib.h>
+
+#include "wayland-util.h"
+
+struct hash_entry {
+ uint32_t hash;
+ void *data;
+};
+
+struct wl_hash_table {
+ struct hash_entry *table;
+ uint32_t size;
+ uint32_t rehash;
+ uint32_t max_entries;
+ uint32_t size_index;
+ uint32_t entries;
+ uint32_t deleted_entries;
+};
+
+#define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0]))
+
+/*
+ * From Knuth -- a good choice for hash/rehash values is p, p-2 where
+ * p and p-2 are both prime. These tables are sized to have an extra 10%
+ * free to avoid exponential performance degradation as the hash table fills
+ */
+
+static const uint32_t deleted_data;
+
+static const struct {
+ uint32_t max_entries, size, rehash;
+} hash_sizes[] = {
+ { 2, 5, 3 },
+ { 4, 7, 5 },
+ { 8, 13, 11 },
+ { 16, 19, 17 },
+ { 32, 43, 41 },
+ { 64, 73, 71 },
+ { 128, 151, 149 },
+ { 256, 283, 281 },
+ { 512, 571, 569 },
+ { 1024, 1153, 1151 },
+ { 2048, 2269, 2267 },
+ { 4096, 4519, 4517 },
+ { 8192, 9013, 9011 },
+ { 16384, 18043, 18041 },
+ { 32768, 36109, 36107 },
+ { 65536, 72091, 72089 },
+ { 131072, 144409, 144407 },
+ { 262144, 288361, 288359 },
+ { 524288, 576883, 576881 },
+ { 1048576, 1153459, 1153457 },
+ { 2097152, 2307163, 2307161 },
+ { 4194304, 4613893, 4613891 },
+ { 8388608, 9227641, 9227639 },
+ { 16777216, 18455029, 18455027 },
+ { 33554432, 36911011, 36911009 },
+ { 67108864, 73819861, 73819859 },
+ { 134217728, 147639589, 147639587 },
+ { 268435456, 295279081, 295279079 },
+ { 536870912, 590559793, 590559791 },
+ { 1073741824, 1181116273, 1181116271},
+ { 2147483648ul, 2362232233ul, 2362232231ul}
+};
+
+static int
+entry_is_free(struct hash_entry *entry)
+{
+ return entry->data == NULL;
+}
+
+static int
+entry_is_deleted(struct hash_entry *entry)
+{
+ return entry->data == &deleted_data;
+}
+
+static int
+entry_is_present(struct hash_entry *entry)
+{
+ return entry->data != NULL && entry->data != &deleted_data;
+}
+
+WL_EXPORT struct wl_hash_table *
+wl_hash_table_create(void)
+{
+ struct wl_hash_table *ht;
+
+ ht = malloc(sizeof(*ht));
+ if (ht == NULL)
+ return NULL;
+
+ ht->size_index = 0;
+ ht->size = hash_sizes[ht->size_index].size;
+ ht->rehash = hash_sizes[ht->size_index].rehash;
+ ht->max_entries = hash_sizes[ht->size_index].max_entries;
+ ht->table = calloc(ht->size, sizeof(*ht->table));
+ ht->entries = 0;
+ ht->deleted_entries = 0;
+
+ if (ht->table == NULL) {
+ free(ht);
+ return NULL;
+ }
+
+ return ht;
+}
+
+/**
+ * Frees the given hash table.
+ */
+WL_EXPORT void
+wl_hash_table_destroy(struct wl_hash_table *ht)
+{
+ if (!ht)
+ return;
+
+ free(ht->table);
+ free(ht);
+}
+
+/**
+ * Finds a hash table entry with the given key and hash of that key.
+ *
+ * Returns NULL if no entry is found. Note that the data pointer may be
+ * modified by the user.
+ */
+static void *
+hash_table_search(struct wl_hash_table *ht, uint32_t hash)
+{
+ uint32_t hash_address;
+
+ hash_address = hash % ht->size;
+ do {
+ uint32_t double_hash;
+
+ struct hash_entry *entry = ht->table + hash_address;
+
+ if (entry_is_free(entry)) {
+ return NULL;
+ } else if (entry_is_present(entry) && entry->hash == hash) {
+ return entry;
+ }
+
+ double_hash = hash % ht->rehash;
+ if (double_hash == 0)
+ double_hash = 1;
+
+ hash_address = (hash_address + double_hash) % ht->size;
+ } while (hash_address != hash % ht->size);
+
+ return NULL;
+}
+
+WL_EXPORT void *
+wl_hash_table_lookup(struct wl_hash_table *ht, uint32_t hash)
+{
+ struct hash_entry *entry;
+
+ entry = hash_table_search(ht, hash);
+ if (entry != NULL)
+ return entry->data;
+
+ return NULL;
+}
+
+static void
+hash_table_rehash(struct wl_hash_table *ht, int new_size_index)
+{
+ struct wl_hash_table old_ht;
+ struct hash_entry *table, *entry;
+
+ if (new_size_index >= ARRAY_SIZE(hash_sizes))
+ return;
+
+ table = calloc(hash_sizes[new_size_index].size, sizeof(*ht->table));
+ if (table == NULL)
+ return;
+
+ old_ht = *ht;
+
+ ht->table = table;
+ ht->size_index = new_size_index;
+ ht->size = hash_sizes[ht->size_index].size;
+ ht->rehash = hash_sizes[ht->size_index].rehash;
+ ht->max_entries = hash_sizes[ht->size_index].max_entries;
+ ht->entries = 0;
+ ht->deleted_entries = 0;
+
+ for (entry = old_ht.table;
+ entry != old_ht.table + old_ht.size;
+ entry++) {
+ if (entry_is_present(entry)) {
+ wl_hash_table_insert(ht, entry->hash, entry->data);
+ }
+ }
+
+ free(old_ht.table);
+}
+
+/**
+ * Inserts the data with the given hash into the table.
+ *
+ * Note that insertion may rearrange the table on a resize or rehash,
+ * so previously found hash_entries are no longer valid after this function.
+ */
+WL_EXPORT int
+wl_hash_table_insert(struct wl_hash_table *ht, uint32_t hash, void *data)
+{
+ uint32_t hash_address;
+
+ if (ht->entries >= ht->max_entries) {
+ hash_table_rehash(ht, ht->size_index + 1);
+ } else if (ht->deleted_entries + ht->entries >= ht->max_entries) {
+ hash_table_rehash(ht, ht->size_index);
+ }
+
+ hash_address = hash % ht->size;
+ do {
+ struct hash_entry *entry = ht->table + hash_address;
+ uint32_t double_hash;
+
+ if (!entry_is_present(entry)) {
+ if (entry_is_deleted(entry))
+ ht->deleted_entries--;
+ entry->hash = hash;
+ entry->data = data;
+ ht->entries++;
+ return 0;
+ }
+
+ double_hash = hash % ht->rehash;
+ if (double_hash == 0)
+ double_hash = 1;
+
+ hash_address = (hash_address + double_hash) % ht->size;
+ } while (hash_address != hash % ht->size);
+
+ /* We could hit here if a required resize failed. An unchecked-malloc
+ * application could ignore this result.
+ */
+ return -1;
+}
+
+/**
+ * This function deletes the given hash table entry.
+ *
+ * Note that deletion doesn't otherwise modify the table, so an iteration over
+ * the table deleting entries is safe.
+ */
+WL_EXPORT void
+wl_hash_table_remove(struct wl_hash_table *ht, uint32_t hash)
+{
+ struct hash_entry *entry;
+
+ entry = hash_table_search(ht, hash);
+ if (entry != NULL) {
+ entry->data = (void *) &deleted_data;
+ ht->entries--;
+ ht->deleted_entries++;
+ }
+}
diff --git a/src/3rdparty/wayland/wayland-protocol.c b/src/3rdparty/wayland/wayland-protocol.c
new file mode 100644
index 000000000..1b00ac44c
--- /dev/null
+++ b/src/3rdparty/wayland/wayland-protocol.c
@@ -0,0 +1,228 @@
+/*
+ * Copyright © 2010 Kristian Høgsberg
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+
+#include <stdlib.h>
+#include <stdint.h>
+#include "wayland-util.h"
+
+static const struct wl_message display_requests[] = {
+ { "sync", "u" },
+ { "frame", "u" },
+};
+
+static const struct wl_message display_events[] = {
+ { "invalid_object", "u" },
+ { "invalid_method", "uu" },
+ { "no_memory", "" },
+ { "global", "nsu" },
+ { "range", "u" },
+ { "key", "uu" },
+};
+
+WL_EXPORT const struct wl_interface wl_display_interface = {
+ "display", 1,
+ ARRAY_LENGTH(display_requests), display_requests,
+ ARRAY_LENGTH(display_events), display_events,
+};
+
+static const struct wl_message compositor_requests[] = {
+ { "create_surface", "n" },
+};
+
+WL_EXPORT const struct wl_interface wl_compositor_interface = {
+ "compositor", 1,
+ ARRAY_LENGTH(compositor_requests), compositor_requests,
+ 0, NULL,
+};
+
+static const struct wl_message drm_requests[] = {
+ { "authenticate", "u" },
+ { "create_buffer", "nuiiuo" },
+};
+
+static const struct wl_message drm_events[] = {
+ { "device", "s" },
+ { "authenticated", "" },
+};
+
+WL_EXPORT const struct wl_interface wl_drm_interface = {
+ "drm", 1,
+ ARRAY_LENGTH(drm_requests), drm_requests,
+ ARRAY_LENGTH(drm_events), drm_events,
+};
+
+static const struct wl_message shm_requests[] = {
+ { "create_buffer", "nhiiuo" },
+};
+
+WL_EXPORT const struct wl_interface wl_shm_interface = {
+ "shm", 1,
+ ARRAY_LENGTH(shm_requests), shm_requests,
+ 0, NULL,
+};
+
+static const struct wl_message buffer_requests[] = {
+ { "destroy", "" },
+};
+
+WL_EXPORT const struct wl_interface wl_buffer_interface = {
+ "buffer", 1,
+ ARRAY_LENGTH(buffer_requests), buffer_requests,
+ 0, NULL,
+};
+
+static const struct wl_message shell_requests[] = {
+ { "move", "oou" },
+ { "resize", "oouu" },
+ { "create_drag", "n" },
+ { "create_selection", "n" },
+};
+
+static const struct wl_message shell_events[] = {
+ { "configure", "uuoii" },
+};
+
+WL_EXPORT const struct wl_interface wl_shell_interface = {
+ "shell", 1,
+ ARRAY_LENGTH(shell_requests), shell_requests,
+ ARRAY_LENGTH(shell_events), shell_events,
+};
+
+static const struct wl_message selection_requests[] = {
+ { "offer", "s" },
+ { "activate", "ou" },
+ { "destroy", "" },
+};
+
+static const struct wl_message selection_events[] = {
+ { "send", "sh" },
+ { "cancelled", "" },
+};
+
+WL_EXPORT const struct wl_interface wl_selection_interface = {
+ "selection", 1,
+ ARRAY_LENGTH(selection_requests), selection_requests,
+ ARRAY_LENGTH(selection_events), selection_events,
+};
+
+static const struct wl_message selection_offer_requests[] = {
+ { "receive", "sh" },
+};
+
+static const struct wl_message selection_offer_events[] = {
+ { "offer", "s" },
+ { "keyboard_focus", "o" },
+};
+
+WL_EXPORT const struct wl_interface wl_selection_offer_interface = {
+ "selection_offer", 1,
+ ARRAY_LENGTH(selection_offer_requests), selection_offer_requests,
+ ARRAY_LENGTH(selection_offer_events), selection_offer_events,
+};
+
+static const struct wl_message drag_requests[] = {
+ { "offer", "s" },
+ { "activate", "oou" },
+ { "destroy", "" },
+};
+
+static const struct wl_message drag_events[] = {
+ { "target", "s" },
+ { "finish", "h" },
+ { "reject", "" },
+};
+
+WL_EXPORT const struct wl_interface wl_drag_interface = {
+ "drag", 1,
+ ARRAY_LENGTH(drag_requests), drag_requests,
+ ARRAY_LENGTH(drag_events), drag_events,
+};
+
+static const struct wl_message drag_offer_requests[] = {
+ { "accept", "us" },
+ { "receive", "h" },
+ { "reject", "" },
+};
+
+static const struct wl_message drag_offer_events[] = {
+ { "offer", "s" },
+ { "pointer_focus", "uoiiii" },
+ { "motion", "uiiii" },
+ { "drop", "" },
+};
+
+WL_EXPORT const struct wl_interface wl_drag_offer_interface = {
+ "drag_offer", 1,
+ ARRAY_LENGTH(drag_offer_requests), drag_offer_requests,
+ ARRAY_LENGTH(drag_offer_events), drag_offer_events,
+};
+
+static const struct wl_message surface_requests[] = {
+ { "destroy", "" },
+ { "attach", "oii" },
+ { "map_toplevel", "" },
+ { "map_transient", "oiiu" },
+ { "map_fullscreen", "" },
+ { "damage", "iiii" },
+};
+
+WL_EXPORT const struct wl_interface wl_surface_interface = {
+ "surface", 1,
+ ARRAY_LENGTH(surface_requests), surface_requests,
+ 0, NULL,
+};
+
+static const struct wl_message input_device_requests[] = {
+ { "attach", "uoii" },
+};
+
+static const struct wl_message input_device_events[] = {
+ { "motion", "uiiii" },
+ { "button", "uuu" },
+ { "key", "uuu" },
+ { "pointer_focus", "uoiiii" },
+ { "keyboard_focus", "uoa" },
+};
+
+WL_EXPORT const struct wl_interface wl_input_device_interface = {
+ "input_device", 1,
+ ARRAY_LENGTH(input_device_requests), input_device_requests,
+ ARRAY_LENGTH(input_device_events), input_device_events,
+};
+
+static const struct wl_message output_events[] = {
+ { "geometry", "iiii" },
+};
+
+WL_EXPORT const struct wl_interface wl_output_interface = {
+ "output", 1,
+ 0, NULL,
+ ARRAY_LENGTH(output_events), output_events,
+};
+
+WL_EXPORT const struct wl_interface wl_visual_interface = {
+ "visual", 1,
+ 0, NULL,
+ 0, NULL,
+};
+
diff --git a/src/3rdparty/wayland/wayland-server-protocol.h b/src/3rdparty/wayland/wayland-server-protocol.h
new file mode 100644
index 000000000..8da6b7aa7
--- /dev/null
+++ b/src/3rdparty/wayland/wayland-server-protocol.h
@@ -0,0 +1,265 @@
+/*
+ * Copyright © 2010 Kristian Høgsberg
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+
+#ifndef WAYLAND_SERVER_PROTOCOL_H
+#define WAYLAND_SERVER_PROTOCOL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <stddef.h>
+#include "wayland-util.h"
+
+struct wl_client;
+
+struct wl_display;
+struct wl_compositor;
+struct wl_drm;
+struct wl_shm;
+struct wl_buffer;
+struct wl_shell;
+struct wl_selection;
+struct wl_selection_offer;
+struct wl_drag;
+struct wl_drag_offer;
+struct wl_surface;
+struct wl_input_device;
+struct wl_output;
+struct wl_visual;
+
+extern const struct wl_interface wl_display_interface;
+extern const struct wl_interface wl_compositor_interface;
+extern const struct wl_interface wl_drm_interface;
+extern const struct wl_interface wl_shm_interface;
+extern const struct wl_interface wl_buffer_interface;
+extern const struct wl_interface wl_shell_interface;
+extern const struct wl_interface wl_selection_interface;
+extern const struct wl_interface wl_selection_offer_interface;
+extern const struct wl_interface wl_drag_interface;
+extern const struct wl_interface wl_drag_offer_interface;
+extern const struct wl_interface wl_surface_interface;
+extern const struct wl_interface wl_input_device_interface;
+extern const struct wl_interface wl_output_interface;
+extern const struct wl_interface wl_visual_interface;
+
+struct wl_display_interface {
+ void (*sync)(struct wl_client *client,
+ struct wl_display *display,
+ uint32_t key);
+ void (*frame)(struct wl_client *client,
+ struct wl_display *display,
+ uint32_t key);
+};
+
+#define WL_DISPLAY_INVALID_OBJECT 0
+#define WL_DISPLAY_INVALID_METHOD 1
+#define WL_DISPLAY_NO_MEMORY 2
+#define WL_DISPLAY_GLOBAL 3
+#define WL_DISPLAY_RANGE 4
+#define WL_DISPLAY_KEY 5
+
+struct wl_compositor_interface {
+ void (*create_surface)(struct wl_client *client,
+ struct wl_compositor *compositor,
+ uint32_t id);
+};
+
+struct wl_drm_interface {
+ void (*authenticate)(struct wl_client *client,
+ struct wl_drm *drm,
+ uint32_t id);
+ void (*create_buffer)(struct wl_client *client,
+ struct wl_drm *drm,
+ uint32_t id,
+ uint32_t name,
+ int width,
+ int height,
+ uint32_t stride,
+ struct wl_visual *visual);
+};
+
+#define WL_DRM_DEVICE 0
+#define WL_DRM_AUTHENTICATED 1
+
+struct wl_shm_interface {
+ void (*create_buffer)(struct wl_client *client,
+ struct wl_shm *shm,
+ uint32_t id,
+ int fd,
+ int width,
+ int height,
+ uint32_t stride,
+ struct wl_visual *visual);
+};
+
+struct wl_buffer_interface {
+ void (*destroy)(struct wl_client *client,
+ struct wl_buffer *buffer);
+};
+
+#ifndef WL_SHELL_RESIZE_ENUM
+#define WL_SHELL_RESIZE_ENUM
+enum wl_shell_resize {
+ WL_SHELL_RESIZE_NONE = 0,
+ WL_SHELL_RESIZE_TOP = 1,
+ WL_SHELL_RESIZE_BOTTOM = 2,
+ WL_SHELL_RESIZE_LEFT = 4,
+ WL_SHELL_RESIZE_TOP_LEFT = 5,
+ WL_SHELL_RESIZE_BOTTOM_LEFT = 6,
+ WL_SHELL_RESIZE_RIGHT = 8,
+ WL_SHELL_RESIZE_TOP_RIGHT = 9,
+ WL_SHELL_RESIZE_BOTTOM_RIGHT = 10,
+};
+#endif /* WL_SHELL_RESIZE_ENUM */
+
+struct wl_shell_interface {
+ void (*move)(struct wl_client *client,
+ struct wl_shell *shell,
+ struct wl_surface *surface,
+ struct wl_input_device *input_device,
+ uint32_t time);
+ void (*resize)(struct wl_client *client,
+ struct wl_shell *shell,
+ struct wl_surface *surface,
+ struct wl_input_device *input_device,
+ uint32_t time,
+ uint32_t edges);
+ void (*create_drag)(struct wl_client *client,
+ struct wl_shell *shell,
+ uint32_t id);
+ void (*create_selection)(struct wl_client *client,
+ struct wl_shell *shell,
+ uint32_t id);
+};
+
+#define WL_SHELL_CONFIGURE 0
+
+struct wl_selection_interface {
+ void (*offer)(struct wl_client *client,
+ struct wl_selection *selection,
+ const char *type);
+ void (*activate)(struct wl_client *client,
+ struct wl_selection *selection,
+ struct wl_input_device *input_device,
+ uint32_t time);
+ void (*destroy)(struct wl_client *client,
+ struct wl_selection *selection);
+};
+
+#define WL_SELECTION_SEND 0
+#define WL_SELECTION_CANCELLED 1
+
+struct wl_selection_offer_interface {
+ void (*receive)(struct wl_client *client,
+ struct wl_selection_offer *selection_offer,
+ const char *mime_type,
+ int fd);
+};
+
+#define WL_SELECTION_OFFER_OFFER 0
+#define WL_SELECTION_OFFER_KEYBOARD_FOCUS 1
+
+struct wl_drag_interface {
+ void (*offer)(struct wl_client *client,
+ struct wl_drag *drag,
+ const char *type);
+ void (*activate)(struct wl_client *client,
+ struct wl_drag *drag,
+ struct wl_surface *surface,
+ struct wl_input_device *input_device,
+ uint32_t time);
+ void (*destroy)(struct wl_client *client,
+ struct wl_drag *drag);
+};
+
+#define WL_DRAG_TARGET 0
+#define WL_DRAG_FINISH 1
+#define WL_DRAG_REJECT 2
+
+struct wl_drag_offer_interface {
+ void (*accept)(struct wl_client *client,
+ struct wl_drag_offer *drag_offer,
+ uint32_t time,
+ const char *type);
+ void (*receive)(struct wl_client *client,
+ struct wl_drag_offer *drag_offer,
+ int fd);
+ void (*reject)(struct wl_client *client,
+ struct wl_drag_offer *drag_offer);
+};
+
+#define WL_DRAG_OFFER_OFFER 0
+#define WL_DRAG_OFFER_POINTER_FOCUS 1
+#define WL_DRAG_OFFER_MOTION 2
+#define WL_DRAG_OFFER_DROP 3
+
+struct wl_surface_interface {
+ void (*destroy)(struct wl_client *client,
+ struct wl_surface *surface);
+ void (*attach)(struct wl_client *client,
+ struct wl_surface *surface,
+ struct wl_buffer *buffer,
+ int x,
+ int y);
+ void (*map_toplevel)(struct wl_client *client,
+ struct wl_surface *surface);
+ void (*map_transient)(struct wl_client *client,
+ struct wl_surface *surface,
+ struct wl_surface *parent,
+ int x,
+ int y,
+ uint32_t flags);
+ void (*map_fullscreen)(struct wl_client *client,
+ struct wl_surface *surface);
+ void (*damage)(struct wl_client *client,
+ struct wl_surface *surface,
+ int x,
+ int y,
+ int width,
+ int height);
+};
+
+struct wl_input_device_interface {
+ void (*attach)(struct wl_client *client,
+ struct wl_input_device *input_device,
+ uint32_t time,
+ struct wl_buffer *buffer,
+ int hotspot_x,
+ int hotspot_y);
+};
+
+#define WL_INPUT_DEVICE_MOTION 0
+#define WL_INPUT_DEVICE_BUTTON 1
+#define WL_INPUT_DEVICE_KEY 2
+#define WL_INPUT_DEVICE_POINTER_FOCUS 3
+#define WL_INPUT_DEVICE_KEYBOARD_FOCUS 4
+
+#define WL_OUTPUT_GEOMETRY 0
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/3rdparty/wayland/wayland-server.c b/src/3rdparty/wayland/wayland-server.c
new file mode 100644
index 000000000..dece0d1b2
--- /dev/null
+++ b/src/3rdparty/wayland/wayland-server.c
@@ -0,0 +1,726 @@
+/*
+ * Copyright © 2008 Kristian Høgsberg
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <dlfcn.h>
+#include <assert.h>
+#include <sys/time.h>
+#include <ffi.h>
+
+#include "wayland-server.h"
+#include "wayland-server-protocol.h"
+#include "connection.h"
+
+struct wl_socket {
+ int fd;
+ struct sockaddr_un addr;
+ struct wl_list link;
+};
+
+struct wl_client {
+ struct wl_connection *connection;
+ struct wl_event_source *source;
+ struct wl_display *display;
+ struct wl_list resource_list;
+ uint32_t id_count;
+};
+
+struct wl_display {
+ struct wl_object object;
+ struct wl_event_loop *loop;
+ struct wl_hash_table *objects;
+ int run;
+
+ struct wl_list frame_list;
+ uint32_t client_id_range;
+ uint32_t id;
+
+ struct wl_list global_list;
+ struct wl_list socket_list;
+};
+
+struct wl_frame_listener {
+ struct wl_resource resource;
+ struct wl_client *client;
+ uint32_t key;
+ struct wl_list link;
+};
+
+struct wl_global {
+ struct wl_object *object;
+ wl_client_connect_func_t func;
+ struct wl_list link;
+};
+
+static int wl_debug = 0;
+
+WL_EXPORT void
+wl_client_post_event(struct wl_client *client, struct wl_object *sender,
+ uint32_t opcode, ...)
+{
+ struct wl_closure *closure;
+ va_list ap;
+
+ va_start(ap, opcode);
+ closure = wl_connection_vmarshal(client->connection,
+ sender, opcode, ap,
+ &sender->interface->events[opcode]);
+ va_end(ap);
+
+ wl_closure_send(closure, client->connection);
+
+ if (wl_debug) {
+ fprintf(stderr, " -> ");
+ wl_closure_print(closure, sender);
+ }
+
+ wl_closure_destroy(closure);
+}
+
+static void
+wl_client_connection_data(int fd, uint32_t mask, void *data)
+{
+ struct wl_client *client = data;
+ struct wl_connection *connection = client->connection;
+ struct wl_object *object;
+ struct wl_closure *closure;
+ const struct wl_message *message;
+ uint32_t p[2], opcode, size;
+ uint32_t cmask = 0;
+ int len;
+
+ if (mask & WL_EVENT_READABLE)
+ cmask |= WL_CONNECTION_READABLE;
+ if (mask & WL_EVENT_WRITEABLE)
+ cmask |= WL_CONNECTION_WRITABLE;
+
+ len = wl_connection_data(connection, cmask);
+ if (len < 0) {
+ wl_client_destroy(client);
+ return;
+ }
+
+ while (len >= sizeof p) {
+ wl_connection_copy(connection, p, sizeof p);
+ opcode = p[1] & 0xffff;
+ size = p[1] >> 16;
+ if (len < size)
+ break;
+
+ object = wl_hash_table_lookup(client->display->objects, p[0]);
+ if (object == NULL) {
+ wl_client_post_event(client, &client->display->object,
+ WL_DISPLAY_INVALID_OBJECT, p[0]);
+ wl_connection_consume(connection, size);
+ len -= size;
+ continue;
+ }
+
+ if (opcode >= object->interface->method_count) {
+ wl_client_post_event(client, &client->display->object,
+ WL_DISPLAY_INVALID_METHOD, p[0], opcode);
+ wl_connection_consume(connection, size);
+ len -= size;
+ continue;
+ }
+
+ message = &object->interface->methods[opcode];
+ closure = wl_connection_demarshal(client->connection, size,
+ client->display->objects,
+ message);
+ len -= size;
+
+ if (closure == NULL && errno == EINVAL) {
+ wl_client_post_event(client, &client->display->object,
+ WL_DISPLAY_INVALID_METHOD,
+ p[0], opcode);
+ continue;
+ } else if (closure == NULL && errno == ENOMEM) {
+ wl_client_post_no_memory(client);
+ continue;
+ }
+
+
+ if (wl_debug)
+ wl_closure_print(closure, object);
+
+ wl_closure_invoke(closure, object,
+ object->implementation[opcode], client);
+
+ wl_closure_destroy(closure);
+ }
+}
+
+static int
+wl_client_connection_update(struct wl_connection *connection,
+ uint32_t mask, void *data)
+{
+ struct wl_client *client = data;
+ uint32_t emask = 0;
+
+ if (mask & WL_CONNECTION_READABLE)
+ emask |= WL_EVENT_READABLE;
+ if (mask & WL_CONNECTION_WRITABLE)
+ emask |= WL_EVENT_WRITEABLE;
+
+ return wl_event_source_fd_update(client->source, emask);
+}
+
+WL_EXPORT struct wl_display *
+wl_client_get_display(struct wl_client *client)
+{
+ return client->display;
+}
+
+static void
+wl_display_post_range(struct wl_display *display, struct wl_client *client)
+{
+ wl_client_post_event(client, &client->display->object,
+ WL_DISPLAY_RANGE, display->client_id_range);
+ display->client_id_range += 256;
+ client->id_count += 256;
+}
+
+static struct wl_client *
+wl_client_create(struct wl_display *display, int fd)
+{
+ struct wl_client *client;
+ struct wl_global *global;
+
+ client = malloc(sizeof *client);
+ if (client == NULL)
+ return NULL;
+
+ memset(client, 0, sizeof *client);
+ client->display = display;
+ client->source = wl_event_loop_add_fd(display->loop, fd,
+ WL_EVENT_READABLE,
+ wl_client_connection_data, client);
+ client->connection =
+ wl_connection_create(fd, wl_client_connection_update, client);
+
+ wl_list_init(&client->resource_list);
+
+ wl_display_post_range(display, client);
+
+ wl_list_for_each(global, &display->global_list, link)
+ wl_client_post_event(client, &client->display->object,
+ WL_DISPLAY_GLOBAL,
+ global->object,
+ global->object->interface->name,
+ global->object->interface->version);
+
+ wl_list_for_each(global, &display->global_list, link)
+ if (global->func)
+ global->func(client, global->object);
+
+ return client;
+}
+
+WL_EXPORT void
+wl_client_add_resource(struct wl_client *client,
+ struct wl_resource *resource)
+{
+ struct wl_display *display = client->display;
+
+ if (client->id_count-- < 64)
+ wl_display_post_range(display, client);
+
+ wl_hash_table_insert(client->display->objects,
+ resource->object.id, resource);
+ wl_list_insert(client->resource_list.prev, &resource->link);
+}
+
+WL_EXPORT void
+wl_client_post_no_memory(struct wl_client *client)
+{
+ wl_client_post_event(client,
+ &client->display->object,
+ WL_DISPLAY_NO_MEMORY);
+}
+
+WL_EXPORT void
+wl_client_post_global(struct wl_client *client, struct wl_object *object)
+{
+ wl_client_post_event(client,
+ &client->display->object,
+ WL_DISPLAY_GLOBAL,
+ object,
+ object->interface->name,
+ object->interface->version);
+}
+
+WL_EXPORT void
+wl_resource_destroy(struct wl_resource *resource, struct wl_client *client)
+{
+ struct wl_display *display = client->display;
+
+ wl_list_remove(&resource->link);
+ if (resource->object.id > 0)
+ wl_hash_table_remove(display->objects, resource->object.id);
+ resource->destroy(resource, client);
+}
+
+WL_EXPORT void
+wl_client_destroy(struct wl_client *client)
+{
+ struct wl_resource *resource, *tmp;
+
+ printf("disconnect from client %p\n", client);
+
+ wl_list_for_each_safe(resource, tmp, &client->resource_list, link)
+ wl_resource_destroy(resource, client);
+
+ wl_event_source_remove(client->source);
+ wl_connection_destroy(client->connection);
+ free(client);
+}
+
+static void
+lose_pointer_focus(struct wl_listener *listener,
+ struct wl_surface *surface, uint32_t time)
+{
+ struct wl_input_device *device =
+ container_of(listener, struct wl_input_device,
+ pointer_focus_listener);
+
+ wl_input_device_set_pointer_focus(device, NULL, time, 0, 0, 0, 0);
+}
+
+static void
+lose_keyboard_focus(struct wl_listener *listener,
+ struct wl_surface *surface, uint32_t time)
+{
+ struct wl_input_device *device =
+ container_of(listener, struct wl_input_device,
+ keyboard_focus_listener);
+
+ wl_input_device_set_keyboard_focus(device, NULL, time);
+}
+
+WL_EXPORT void
+wl_input_device_init(struct wl_input_device *device,
+ struct wl_compositor *compositor)
+{
+ wl_list_init(&device->pointer_focus_listener.link);
+ device->pointer_focus_listener.func = lose_pointer_focus;
+ wl_list_init(&device->keyboard_focus_listener.link);
+ device->keyboard_focus_listener.func = lose_keyboard_focus;
+
+ device->x = 100;
+ device->y = 100;
+ device->compositor = compositor;
+}
+
+WL_EXPORT void
+wl_input_device_set_pointer_focus(struct wl_input_device *device,
+ struct wl_surface *surface,
+ uint32_t time,
+ int32_t x, int32_t y,
+ int32_t sx, int32_t sy)
+{
+ if (device->pointer_focus == surface)
+ return;
+
+ if (device->pointer_focus &&
+ (!surface || device->pointer_focus->client != surface->client))
+ wl_client_post_event(device->pointer_focus->client,
+ &device->object,
+ WL_INPUT_DEVICE_POINTER_FOCUS,
+ time, NULL, 0, 0, 0, 0);
+ if (surface)
+ wl_client_post_event(surface->client,
+ &device->object,
+ WL_INPUT_DEVICE_POINTER_FOCUS,
+ time, surface, x, y, sx, sy);
+
+ device->pointer_focus = surface;
+ device->pointer_focus_time = time;
+
+ wl_list_remove(&device->pointer_focus_listener.link);
+ if (surface)
+ wl_list_insert(surface->destroy_listener_list.prev,
+ &device->pointer_focus_listener.link);
+}
+
+WL_EXPORT void
+wl_input_device_set_keyboard_focus(struct wl_input_device *device,
+ struct wl_surface *surface,
+ uint32_t time)
+{
+ if (device->keyboard_focus == surface)
+ return;
+
+ if (device->keyboard_focus &&
+ (!surface || device->keyboard_focus->client != surface->client))
+ wl_client_post_event(device->keyboard_focus->client,
+ &device->object,
+ WL_INPUT_DEVICE_KEYBOARD_FOCUS,
+ time, NULL, &device->keys);
+
+ if (surface)
+ wl_client_post_event(surface->client,
+ &device->object,
+ WL_INPUT_DEVICE_KEYBOARD_FOCUS,
+ time, surface, &device->keys);
+
+ device->keyboard_focus = surface;
+ device->keyboard_focus_time = time;
+
+ wl_list_remove(&device->keyboard_focus_listener.link);
+ if (surface)
+ wl_list_insert(surface->destroy_listener_list.prev,
+ &device->keyboard_focus_listener.link);
+}
+
+WL_EXPORT void
+wl_input_device_end_grab(struct wl_input_device *device, uint32_t time)
+{
+ const struct wl_grab_interface *interface;
+
+ interface = device->grab->interface;
+ interface->end(device->grab, time);
+ device->grab->input_device = NULL;
+ device->grab = NULL;
+
+ wl_list_remove(&device->grab_listener.link);
+}
+
+static void
+lose_grab_surface(struct wl_listener *listener,
+ struct wl_surface *surface, uint32_t time)
+{
+ struct wl_input_device *device =
+ container_of(listener,
+ struct wl_input_device, grab_listener);
+
+ wl_input_device_end_grab(device, time);
+}
+
+WL_EXPORT void
+wl_input_device_start_grab(struct wl_input_device *device,
+ struct wl_grab *grab,
+ uint32_t button, uint32_t time)
+{
+ struct wl_surface *focus = device->pointer_focus;
+
+ device->grab = grab;
+ device->grab_button = button;
+ device->grab_time = time;
+ device->grab_x = device->x;
+ device->grab_y = device->y;
+
+ device->grab_listener.func = lose_grab_surface;
+ wl_list_insert(focus->destroy_listener_list.prev,
+ &device->grab_listener.link);
+
+ grab->input_device = device;
+}
+
+WL_EXPORT int
+wl_input_device_update_grab(struct wl_input_device *device,
+ struct wl_grab *grab,
+ struct wl_surface *surface, uint32_t time)
+{
+ if (device->grab != &device->motion_grab ||
+ device->grab_time != time ||
+ device->pointer_focus != surface)
+ return -1;
+
+ device->grab = grab;
+ grab->input_device = device;
+
+ return 0;
+}
+
+static void
+display_sync(struct wl_client *client,
+ struct wl_display *display, uint32_t key)
+{
+ wl_client_post_event(client, &display->object, WL_DISPLAY_KEY, key, 0);
+}
+
+static void
+destroy_frame_listener(struct wl_resource *resource, struct wl_client *client)
+{
+ struct wl_frame_listener *listener =
+ container_of(resource, struct wl_frame_listener, resource);
+
+ wl_list_remove(&listener->link);
+ free(listener);
+}
+
+static void
+display_frame(struct wl_client *client,
+ struct wl_display *display, uint32_t key)
+{
+ struct wl_frame_listener *listener;
+
+ listener = malloc(sizeof *listener);
+ if (listener == NULL) {
+ wl_client_post_no_memory(client);
+ return;
+ }
+
+ /* The listener is a resource so we destroy it when the client
+ * goes away. */
+ listener->resource.destroy = destroy_frame_listener;
+ listener->resource.object.id = 0;
+ listener->client = client;
+ listener->key = key;
+ wl_list_insert(client->resource_list.prev, &listener->resource.link);
+ wl_list_insert(display->frame_list.prev, &listener->link);
+}
+
+struct wl_display_interface display_interface = {
+ display_sync,
+ display_frame
+};
+
+
+WL_EXPORT struct wl_display *
+wl_display_create(void)
+{
+ struct wl_display *display;
+ const char *debug;
+
+ debug = getenv("WAYLAND_DEBUG");
+ if (debug)
+ wl_debug = 1;
+
+ display = malloc(sizeof *display);
+ if (display == NULL)
+ return NULL;
+
+ display->loop = wl_event_loop_create();
+ if (display->loop == NULL) {
+ free(display);
+ return NULL;
+ }
+
+ display->objects = wl_hash_table_create();
+ if (display->objects == NULL) {
+ free(display);
+ return NULL;
+ }
+
+ wl_list_init(&display->frame_list);
+ wl_list_init(&display->global_list);
+ wl_list_init(&display->socket_list);
+
+ display->client_id_range = 256; /* Gah, arbitrary... */
+
+ display->id = 1;
+ display->object.interface = &wl_display_interface;
+ display->object.implementation = (void (**)(void)) &display_interface;
+ wl_display_add_object(display, &display->object);
+ if (wl_display_add_global(display, &display->object, NULL)) {
+ wl_event_loop_destroy(display->loop);
+ free(display);
+ return NULL;
+ }
+
+ return display;
+}
+
+WL_EXPORT void
+wl_display_destroy(struct wl_display *display)
+{
+ struct wl_socket *s, *next;
+
+ wl_event_loop_destroy(display->loop);
+ wl_hash_table_destroy(display->objects);
+
+ wl_list_for_each_safe(s, next, &display->socket_list, link) {
+ close(s->fd);
+ unlink(s->addr.sun_path);
+ free(s);
+ }
+
+ free(display);
+}
+
+WL_EXPORT void
+wl_display_add_object(struct wl_display *display, struct wl_object *object)
+{
+ object->id = display->id++;
+ wl_hash_table_insert(display->objects, object->id, object);
+}
+
+WL_EXPORT int
+wl_display_add_global(struct wl_display *display,
+ struct wl_object *object, wl_client_connect_func_t func)
+{
+ struct wl_global *global;
+
+ global = malloc(sizeof *global);
+ if (global == NULL)
+ return -1;
+
+ global->object = object;
+ global->func = func;
+ wl_list_insert(display->global_list.prev, &global->link);
+
+ return 0;
+}
+
+WL_EXPORT void
+wl_display_post_frame(struct wl_display *display, uint32_t time)
+{
+ struct wl_frame_listener *listener, *next;
+
+ wl_list_for_each_safe(listener, next, &display->frame_list, link) {
+ wl_client_post_event(listener->client, &display->object,
+ WL_DISPLAY_KEY, listener->key, time);
+ wl_resource_destroy(&listener->resource, listener->client);
+ }
+}
+
+WL_EXPORT struct wl_event_loop *
+wl_display_get_event_loop(struct wl_display *display)
+{
+ return display->loop;
+}
+
+WL_EXPORT void
+wl_display_terminate(struct wl_display *display)
+{
+ display->run = 0;
+}
+
+WL_EXPORT void
+wl_display_run(struct wl_display *display)
+{
+ display->run = 1;
+
+ while (display->run)
+ wl_event_loop_dispatch(display->loop, -1);
+}
+
+static void
+socket_data(int fd, uint32_t mask, void *data)
+{
+ struct wl_display *display = data;
+ struct sockaddr_un name;
+ socklen_t length;
+ int client_fd;
+
+ length = sizeof name;
+ client_fd = accept (fd, (struct sockaddr *) &name, &length);
+ if (client_fd < 0)
+ fprintf(stderr, "failed to accept\n");
+
+ wl_client_create(display, client_fd);
+}
+
+WL_EXPORT int
+wl_display_add_socket(struct wl_display *display, const char *name)
+{
+ struct wl_socket *s;
+ socklen_t size, name_size;
+ const char *runtime_dir;
+
+ s = malloc(sizeof *s);
+ if (s == NULL)
+ return -1;
+
+ s->fd = socket(PF_LOCAL, SOCK_STREAM, 0);
+ if (s->fd < 0)
+ return -1;
+
+ runtime_dir = getenv("XDG_RUNTIME_DIR");
+ if (runtime_dir == NULL) {
+ runtime_dir = ".";
+ fprintf(stderr,
+ "XDG_RUNTIME_DIR not set, falling back to %s\n",
+ runtime_dir);
+ }
+
+ if (name == NULL)
+ name = getenv("WAYLAND_DISPLAY");
+ if (name == NULL)
+ name = "wayland-0";
+
+ memset(&s->addr, 0, sizeof s->addr);
+ s->addr.sun_family = AF_LOCAL;
+ name_size = snprintf(s->addr.sun_path, sizeof s->addr.sun_path,
+ "%s/%s", runtime_dir, name) + 1;
+ fprintf(stderr, "using socket %s\n", s->addr.sun_path);
+
+ size = offsetof (struct sockaddr_un, sun_path) + name_size;
+ if (bind(s->fd, (struct sockaddr *) &s->addr, size) < 0)
+ return -1;
+
+ if (listen(s->fd, 1) < 0)
+ return -1;
+
+ wl_event_loop_add_fd(display->loop, s->fd,
+ WL_EVENT_READABLE,
+ socket_data, display);
+ wl_list_insert(display->socket_list.prev, &s->link);
+
+ return 0;
+}
+
+WL_EXPORT int
+wl_compositor_init(struct wl_compositor *compositor,
+ const struct wl_compositor_interface *interface,
+ struct wl_display *display)
+{
+ compositor->object.interface = &wl_compositor_interface;
+ compositor->object.implementation = (void (**)(void)) interface;
+ wl_display_add_object(display, &compositor->object);
+ if (wl_display_add_global(display, &compositor->object, NULL))
+ return -1;
+
+ compositor->argb_visual.object.interface = &wl_visual_interface;
+ compositor->argb_visual.object.implementation = NULL;
+ wl_display_add_object(display, &compositor->argb_visual.object);
+ wl_display_add_global(display, &compositor->argb_visual.object, NULL);
+
+ compositor->premultiplied_argb_visual.object.interface =
+ &wl_visual_interface;
+ compositor->premultiplied_argb_visual.object.implementation = NULL;
+ wl_display_add_object(display,
+ &compositor->premultiplied_argb_visual.object);
+ wl_display_add_global(display,
+ &compositor->premultiplied_argb_visual.object,
+ NULL);
+
+ compositor->rgb_visual.object.interface = &wl_visual_interface;
+ compositor->rgb_visual.object.implementation = NULL;
+ wl_display_add_object(display,
+ &compositor->rgb_visual.object);
+ wl_display_add_global(display,
+ &compositor->rgb_visual.object, NULL);
+
+ return 0;
+}
diff --git a/src/3rdparty/wayland/wayland-server.h b/src/3rdparty/wayland/wayland-server.h
new file mode 100644
index 000000000..f74cbae04
--- /dev/null
+++ b/src/3rdparty/wayland/wayland-server.h
@@ -0,0 +1,265 @@
+/*
+ * Copyright © 2008 Kristian Høgsberg
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#ifndef WAYLAND_H
+#define WAYLAND_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include "wayland-util.h"
+#include "wayland-server-protocol.h"
+
+enum {
+ WL_EVENT_READABLE = 0x01,
+ WL_EVENT_WRITEABLE = 0x02
+};
+
+struct wl_event_loop;
+struct wl_event_source;
+typedef void (*wl_event_loop_fd_func_t)(int fd, uint32_t mask, void *data);
+typedef void (*wl_event_loop_timer_func_t)(void *data);
+typedef void (*wl_event_loop_signal_func_t)(int signal_number, void *data);
+typedef void (*wl_event_loop_idle_func_t)(void *data);
+
+struct wl_event_loop *wl_event_loop_create(void);
+void wl_event_loop_destroy(struct wl_event_loop *loop);
+struct wl_event_source *wl_event_loop_add_fd(struct wl_event_loop *loop,
+ int fd, uint32_t mask,
+ wl_event_loop_fd_func_t func,
+ void *data);
+int wl_event_source_fd_update(struct wl_event_source *source, uint32_t mask);
+struct wl_event_source *wl_event_loop_add_timer(struct wl_event_loop *loop,
+ wl_event_loop_timer_func_t func,
+ void *data);
+struct wl_event_source *
+wl_event_loop_add_signal(struct wl_event_loop *loop,
+ int signal_number,
+ wl_event_loop_signal_func_t func,
+ void *data);
+
+int wl_event_source_timer_update(struct wl_event_source *source,
+ int ms_delay);
+int wl_event_source_remove(struct wl_event_source *source);
+
+
+int wl_event_loop_dispatch(struct wl_event_loop *loop, int timeout);
+struct wl_event_source *wl_event_loop_add_idle(struct wl_event_loop *loop,
+ wl_event_loop_idle_func_t func,
+ void *data);
+int wl_event_loop_get_fd(struct wl_event_loop *loop);
+
+struct wl_client;
+struct wl_display;
+struct wl_input_device;
+
+struct wl_display *wl_display_create(void);
+void wl_display_destroy(struct wl_display *display);
+struct wl_event_loop *wl_display_get_event_loop(struct wl_display *display);
+int wl_display_add_socket(struct wl_display *display, const char *name);
+void wl_display_terminate(struct wl_display *display);
+void wl_display_run(struct wl_display *display);
+
+void wl_display_add_object(struct wl_display *display, struct wl_object *object);
+
+typedef void (*wl_client_connect_func_t)(struct wl_client *client, struct wl_object *global);
+
+int wl_display_add_global(struct wl_display *display, struct wl_object *object, wl_client_connect_func_t func);
+
+void wl_client_destroy(struct wl_client *client);
+void wl_client_post_no_memory(struct wl_client *client);
+void wl_client_post_global(struct wl_client *client, struct wl_object *object);
+
+struct wl_visual {
+ struct wl_object object;
+};
+
+struct wl_compositor {
+ struct wl_object object;
+ struct wl_visual argb_visual;
+ struct wl_visual premultiplied_argb_visual;
+ struct wl_visual rgb_visual;
+};
+
+struct wl_resource {
+ struct wl_object object;
+ void (*destroy)(struct wl_resource *resource,
+ struct wl_client *client);
+ struct wl_list link;
+};
+
+struct wl_buffer {
+ struct wl_resource resource;
+ struct wl_compositor *compositor;
+ struct wl_visual *visual;
+ int32_t width, height;
+ void (*attach)(struct wl_buffer *buffer, struct wl_surface *surface);
+ void (*damage)(struct wl_buffer *buffer,
+ struct wl_surface *surface,
+ int32_t x, int32_t y, int32_t width, int32_t height);
+};
+
+struct wl_listener {
+ struct wl_list link;
+ void (*func)(struct wl_listener *listener,
+ struct wl_surface *surface, uint32_t time);
+};
+
+struct wl_surface {
+ struct wl_resource resource;
+ struct wl_client *client;
+ struct wl_list destroy_listener_list;
+};
+
+struct wl_shell {
+ struct wl_object object;
+};
+
+struct wl_grab;
+struct wl_grab_interface {
+ void (*motion)(struct wl_grab *grab,
+ uint32_t time, int32_t x, int32_t y);
+ void (*button)(struct wl_grab *grab,
+ uint32_t time, int32_t button, int32_t state);
+ void (*end)(struct wl_grab *grab, uint32_t time);
+};
+
+struct wl_grab {
+ const struct wl_grab_interface *interface;
+ struct wl_input_device *input_device;
+};
+
+struct wl_input_device {
+ struct wl_object object;
+ struct wl_compositor *compositor;
+ struct wl_surface *pointer_focus;
+ struct wl_surface *keyboard_focus;
+ struct wl_array keys;
+ uint32_t pointer_focus_time;
+ uint32_t keyboard_focus_time;
+ struct wl_listener pointer_focus_listener;
+ struct wl_listener keyboard_focus_listener;
+
+ int32_t x, y;
+ struct wl_grab *grab;
+ struct wl_grab motion_grab;
+ uint32_t grab_time;
+ int32_t grab_x, grab_y;
+ uint32_t grab_button;
+ struct wl_listener grab_listener;
+};
+
+struct wl_drag_offer {
+ struct wl_object object;
+};
+
+struct wl_drag {
+ struct wl_resource resource;
+ struct wl_grab grab;
+ struct wl_drag_offer drag_offer;
+ struct wl_surface *source;
+ struct wl_surface *drag_focus;
+ struct wl_client *target;
+ int32_t x, y, sx, sy;
+ struct wl_array types;
+ const char *type;
+ uint32_t pointer_focus_time;
+ struct wl_listener drag_focus_listener;
+};
+
+struct wl_selection_offer {
+ struct wl_object object;
+};
+
+struct wl_selection {
+ struct wl_resource resource;
+ struct wl_client *client;
+ struct wl_input_device *input_device;
+ struct wl_selection_offer selection_offer;
+ struct wl_surface *selection_focus;
+ struct wl_client *target;
+ struct wl_array types;
+ struct wl_listener selection_focus_listener;
+};
+
+void
+wl_client_post_event(struct wl_client *client,
+ struct wl_object *sender,
+ uint32_t event, ...);
+
+int
+wl_display_set_compositor(struct wl_display *display,
+ struct wl_compositor *compositor,
+ const struct wl_compositor_interface *implementation);
+
+void
+wl_display_post_frame(struct wl_display *display, uint32_t msecs);
+
+void
+wl_client_add_resource(struct wl_client *client,
+ struct wl_resource *resource);
+
+struct wl_display *
+wl_client_get_display(struct wl_client *client);
+
+void
+wl_resource_destroy(struct wl_resource *resource, struct wl_client *client);
+
+void
+wl_input_device_init(struct wl_input_device *device,
+ struct wl_compositor *compositor);
+
+void
+wl_input_device_set_pointer_focus(struct wl_input_device *device,
+ struct wl_surface *surface,
+ uint32_t time,
+ int32_t x, int32_t y,
+ int32_t sx, int32_t sy);
+
+void
+wl_input_device_set_keyboard_focus(struct wl_input_device *device,
+ struct wl_surface *surface,
+ uint32_t time);
+
+void
+wl_input_device_end_grab(struct wl_input_device *device, uint32_t time);
+void
+wl_input_device_start_grab(struct wl_input_device *device,
+ struct wl_grab *grab,
+ uint32_t button, uint32_t time);
+int
+wl_input_device_update_grab(struct wl_input_device *device,
+ struct wl_grab *grab,
+ struct wl_surface *surface, uint32_t time);
+
+int
+wl_compositor_init(struct wl_compositor *compositor,
+ const struct wl_compositor_interface *interface,
+ struct wl_display *display);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/3rdparty/wayland/wayland-util.c b/src/3rdparty/wayland/wayland-util.c
new file mode 100644
index 000000000..364327433
--- /dev/null
+++ b/src/3rdparty/wayland/wayland-util.c
@@ -0,0 +1,123 @@
+/*
+ * Copyright © 2008 Kristian Høgsberg
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include "wayland-util.h"
+
+WL_EXPORT void
+wl_list_init(struct wl_list *list)
+{
+ list->prev = list;
+ list->next = list;
+}
+
+WL_EXPORT void
+wl_list_insert(struct wl_list *list, struct wl_list *elm)
+{
+ elm->prev = list;
+ elm->next = list->next;
+ list->next = elm;
+ elm->next->prev = elm;
+}
+
+WL_EXPORT void
+wl_list_remove(struct wl_list *elm)
+{
+ elm->prev->next = elm->next;
+ elm->next->prev = elm->prev;
+}
+
+WL_EXPORT int
+wl_list_length(struct wl_list *list)
+{
+ struct wl_list *e;
+ int count;
+
+ count = 0;
+ e = list->next;
+ while (e != list) {
+ e = e->next;
+ count++;
+ }
+
+ return count;
+}
+
+WL_EXPORT int
+wl_list_empty(struct wl_list *list)
+{
+ return list->next == list;
+}
+
+WL_EXPORT void
+wl_array_init(struct wl_array *array)
+{
+ memset(array, 0, sizeof *array);
+}
+
+WL_EXPORT void
+wl_array_release(struct wl_array *array)
+{
+ free(array->data);
+}
+
+WL_EXPORT void *
+wl_array_add(struct wl_array *array, int size)
+{
+ int alloc;
+ void *data, *p;
+
+ if (array->alloc > 0)
+ alloc = array->alloc;
+ else
+ alloc = 16;
+
+ while (alloc < array->size + size)
+ alloc *= 2;
+
+ if (array->alloc < alloc) {
+ if (array->alloc > 0)
+ data = realloc(array->data, alloc);
+ else
+ data = malloc(alloc);
+
+ if (data == NULL)
+ return 0;
+ array->data = data;
+ array->alloc = alloc;
+ }
+
+ p = array->data + array->size;
+ array->size += size;
+
+ return p;
+}
+
+WL_EXPORT void
+wl_array_copy(struct wl_array *array, struct wl_array *source)
+{
+ array->size = 0;
+ wl_array_add(array, source->size);
+ memcpy(array->data, source->data, source->size);
+}
diff --git a/src/3rdparty/wayland/wayland-util.h b/src/3rdparty/wayland/wayland-util.h
new file mode 100644
index 000000000..6c1231a99
--- /dev/null
+++ b/src/3rdparty/wayland/wayland-util.h
@@ -0,0 +1,157 @@
+/*
+ * Copyright © 2008 Kristian Høgsberg
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#ifndef WAYLAND_UTIL_H
+#define WAYLAND_UTIL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <inttypes.h>
+
+/* GCC visibility */
+#if defined(__GNUC__) && __GNUC__ >= 4
+#define WL_EXPORT __attribute__ ((visibility("default")))
+#else
+#define WL_EXPORT
+#endif
+
+#define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0])
+#define ALIGN(n, a) ( ((n) + ((a) - 1)) & ~((a) - 1) )
+#define DIV_ROUNDUP(n, a) ( ((n) + ((a) - 1)) / (a) )
+
+#define container_of(ptr, type, member) ({ \
+ const typeof( ((type *)0)->member ) *__mptr = (ptr); \
+ (type *)( (char *)__mptr - offsetof(type,member) );})
+
+struct wl_argument {
+ uint32_t type;
+ void *data;
+};
+
+struct wl_message {
+ const char *name;
+ const char *signature;
+ const void **types;
+};
+
+struct wl_interface {
+ const char *name;
+ int version;
+ int method_count;
+ const struct wl_message *methods;
+ int event_count;
+ const struct wl_message *events;
+};
+
+struct wl_object {
+ const struct wl_interface *interface;
+ void (**implementation)(void);
+ uint32_t id;
+};
+
+struct wl_hash_table;
+struct wl_hash_table *wl_hash_table_create(void);
+void wl_hash_table_destroy(struct wl_hash_table *ht);
+void *wl_hash_table_lookup(struct wl_hash_table *ht, uint32_t hash);
+int wl_hash_table_insert(struct wl_hash_table *ht, uint32_t hash, void *data);
+void wl_hash_table_remove(struct wl_hash_table *ht, uint32_t hash);
+
+/**
+ * wl_list - linked list
+ *
+ * The list head is of "struct wl_list" type, and must be initialized
+ * using wl_list_init(). All entries in the list must be of the same
+ * type. The item type must have a "struct wl_list" member. This
+ * member will be initialized by wl_list_insert(). There is no need to
+ * call wl_list_init() on the individual item. To query if the list is
+ * empty in O(1), use wl_list_empty().
+ *
+ * Let's call the list reference "struct wl_list foo_list", the item type as
+ * "item_t", and the item member as "struct wl_list link". The following code
+ *
+ * The following code will initialize a list:
+ *
+ * wl_list_init(foo_list);
+ * wl_list_insert(foo_list, item1); Pushes item1 at the head
+ * wl_list_insert(foo_list, item2); Pushes item2 at the head
+ * wl_list_insert(item2, item3); Pushes item3 after item2
+ *
+ * The list now looks like [item2, item3, item1]
+ *
+ * Will iterate the list in ascending order:
+ *
+ * item_t *item;
+ * wl_list_for_each(item, foo_list, link) {
+ * Do_something_with_item(item);
+ * }
+ */
+struct wl_list {
+ struct wl_list *prev;
+ struct wl_list *next;
+};
+
+void wl_list_init(struct wl_list *list);
+void wl_list_insert(struct wl_list *list, struct wl_list *elm);
+void wl_list_remove(struct wl_list *elm);
+int wl_list_length(struct wl_list *list);
+int wl_list_empty(struct wl_list *list);
+
+#define __container_of(ptr, sample, member) \
+ (void *)((char *)(ptr) - \
+ ((char *)&(sample)->member - (char *)(sample)))
+
+#define wl_list_for_each(pos, head, member) \
+ for (pos = 0, pos = __container_of((head)->next, pos, member); \
+ &pos->member != (head); \
+ pos = __container_of(pos->member.next, pos, member))
+
+#define wl_list_for_each_safe(pos, tmp, head, member) \
+ for (pos = 0, tmp = 0, \
+ pos = __container_of((head)->next, pos, member), \
+ tmp = __container_of((pos)->member.next, tmp, member); \
+ &pos->member != (head); \
+ pos = tmp, \
+ tmp = __container_of(pos->member.next, tmp, member))
+
+#define wl_list_for_each_reverse(pos, head, member) \
+ for (pos = 0, pos = __container_of((head)->prev, pos, member); \
+ &pos->member != (head); \
+ pos = __container_of(pos->member.prev, pos, member))
+
+struct wl_array {
+ uint32_t size;
+ uint32_t alloc;
+ void *data;
+};
+
+void wl_array_init(struct wl_array *array);
+void wl_array_release(struct wl_array *array);
+void *wl_array_add(struct wl_array *array, int size);
+void wl_array_copy(struct wl_array *array, struct wl_array *source);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/3rdparty/wayland/wayland.pro b/src/3rdparty/wayland/wayland.pro
new file mode 100644
index 000000000..214ed9955
--- /dev/null
+++ b/src/3rdparty/wayland/wayland.pro
@@ -0,0 +1,3 @@
+TEMPLATE = subdirs
+
+SUBDIRS = client server