Squashed 'import-layers/meta-raspberrypi/' content from commit 2745399

Change-Id: I8a89d81813dea98209d089ef500a403ea4da5d9d
git-subtree-dir: import-layers/meta-raspberrypi
git-subtree-split: 2745399f75d7564fcc586d0365ff73be47849d0e
Signed-off-by: Patrick Williams <patrick@stwcx.xyz>
diff --git a/import-layers/meta-raspberrypi/recipes-graphics/eglinfo/eglinfo-fb_%.bbappend b/import-layers/meta-raspberrypi/recipes-graphics/eglinfo/eglinfo-fb_%.bbappend
new file mode 100644
index 0000000..7f8b600
--- /dev/null
+++ b/import-layers/meta-raspberrypi/recipes-graphics/eglinfo/eglinfo-fb_%.bbappend
@@ -0,0 +1 @@
+EGLINFO_DEVICE_rpi  = "raspberrypi"
diff --git a/import-layers/meta-raspberrypi/recipes-graphics/eglinfo/eglinfo-x11_%.bbappend b/import-layers/meta-raspberrypi/recipes-graphics/eglinfo/eglinfo-x11_%.bbappend
new file mode 100644
index 0000000..fd32abc
--- /dev/null
+++ b/import-layers/meta-raspberrypi/recipes-graphics/eglinfo/eglinfo-x11_%.bbappend
@@ -0,0 +1,2 @@
+EGLINFO_DEVICE_rpi  = "raspberrypi"
+ASNEEDED = ""
diff --git a/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0001-Allow-applications-to-set-next-resource-handle.patch b/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0001-Allow-applications-to-set-next-resource-handle.patch
new file mode 100644
index 0000000..4d026bd
--- /dev/null
+++ b/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0001-Allow-applications-to-set-next-resource-handle.patch
@@ -0,0 +1,208 @@
+From 83c5ac5892d0cd29caa8922ff8b639b9a373c3cb Mon Sep 17 00:00:00 2001
+From: Dom Cobley <dc4@broadcom.com>
+Date: Tue, 9 Jul 2013 09:26:26 -0400
+Subject: [PATCH 01/13] Allow applications to set next resource handle
+
+This patch adds provisions in userland to
+let apps callers set the next rendereing dispmanx resource.
+It's useful for implementing, say, a buffer carousel.
+---
+ interface/khronos/common/khrn_client_rpc.h |  2 ++
+ interface/khronos/common/khrn_int_ids.h    |  2 ++
+ interface/khronos/egl/egl_client.c         | 30 +++++++++++++++++++++++++++---
+ interface/khronos/egl/egl_client_surface.c | 24 +++++++++++++++++++++++-
+ interface/khronos/egl/egl_client_surface.h |  3 ++-
+ interface/khronos/egl/egl_int_impl.h       |  5 +++--
+ 6 files changed, 59 insertions(+), 7 deletions(-)
+
+diff --git a/interface/khronos/common/khrn_client_rpc.h b/interface/khronos/common/khrn_client_rpc.h
+index 418aa67..a7557a8 100644
+--- a/interface/khronos/common/khrn_client_rpc.h
++++ b/interface/khronos/common/khrn_client_rpc.h
+@@ -683,6 +683,7 @@ static INLINE void rpc_call12_out_ctrl(CLIENT_THREAD_STATE_T *thread,uint32_t id
+ static INLINE void rpc_call13_out_ctrl(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4, uint32_t p5, uint32_t p6, uint32_t p7, uint32_t p8, uint32_t p9, uint32_t p10, uint32_t p11, void *out)               { rpc_begin(thread); RPC_CALL(thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11);      rpc_recv(thread, out, NULL, (RPC_RECV_FLAG_T)(RPC_RECV_FLAG_CTRL | RPC_RECV_FLAG_LEN)); rpc_end(thread); }
+ static INLINE void rpc_call14_out_ctrl(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4, uint32_t p5, uint32_t p6, uint32_t p7, uint32_t p8, uint32_t p9, uint32_t p10, uint32_t p11, uint32_t p12, void *out) { rpc_begin(thread); RPC_CALL(thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); rpc_recv(thread, out, NULL, (RPC_RECV_FLAG_T)(RPC_RECV_FLAG_CTRL | RPC_RECV_FLAG_LEN)); rpc_end(thread); }
+ static INLINE void rpc_call15_out_ctrl(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4, uint32_t p5, uint32_t p6, uint32_t p7, uint32_t p8, uint32_t p9, uint32_t p10, uint32_t p11, uint32_t p12, uint32_t p13, void *out) { rpc_begin(thread); RPC_CALL(thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13); rpc_recv(thread, out, NULL, (RPC_RECV_FLAG_T)(RPC_RECV_FLAG_CTRL | RPC_RECV_FLAG_LEN)); rpc_end(thread); }
++static INLINE void rpc_call16_out_ctrl(CLIENT_THREAD_STATE_T *thread,uint32_t id, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4, uint32_t p5, uint32_t p6, uint32_t p7, uint32_t p8, uint32_t p9, uint32_t p10, uint32_t p11, uint32_t p12, uint32_t p13, uint32_t p14, void *out) { rpc_begin(thread); RPC_CALL(thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14); rpc_recv(thread, out, NULL, (RPC_RECV_FLAG_T)(RPC_RECV_FLAG_CTRL | RPC_RECV_FLAG_LEN)); rpc_end(thread); }
+ #endif
+ 
+ #define RPC_CALL1_OUT_CTRL(fn, thread, id, out)                                               rpc_call1_out_ctrl(thread, id, out)
+@@ -700,6 +701,7 @@ static INLINE void rpc_call15_out_ctrl(CLIENT_THREAD_STATE_T *thread,uint32_t id
+ #define RPC_CALL13_OUT_CTRL(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, out)      rpc_call13_out_ctrl(thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, out)
+ #define RPC_CALL14_OUT_CTRL(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, out) rpc_call14_out_ctrl(thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, out)
+ #define RPC_CALL15_OUT_CTRL(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, out) rpc_call15_out_ctrl(thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, out)
++#define RPC_CALL16_OUT_CTRL(fn, thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, out) rpc_call16_out_ctrl(thread, id, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, out)
+ 
+ # if !defined(__SYMBIAN32__)  //use functions defined in khrpc.cpp
+ static INLINE uint32_t rpc_call1_out_ctrl_res(CLIENT_THREAD_STATE_T *thread,uint32_t id, void *out)                                                                                                                       { uint32_t res; rpc_begin(thread); RPC_CALL(thread, id);                                     res = rpc_recv(thread, out, NULL, (RPC_RECV_FLAG_T)(RPC_RECV_FLAG_RES | RPC_RECV_FLAG_CTRL | RPC_RECV_FLAG_LEN)); rpc_end(thread); return res; }
+diff --git a/interface/khronos/common/khrn_int_ids.h b/interface/khronos/common/khrn_int_ids.h
+index 8378f4a..ec961e0 100644
+--- a/interface/khronos/common/khrn_int_ids.h
++++ b/interface/khronos/common/khrn_int_ids.h
+@@ -367,6 +367,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+ 
+ #define EGLINTCREATESURFACE_ID            0x4000
++#define EGLINTCREATESURFACE_ID_V2         0x4100
+ #define EGLINTCREATEGLES11_ID             0x4001
+ #define EGLINTCREATEGLES20_ID             0x4002
+ #define EGLINTCREATEVG_ID                 0x4003
+@@ -377,6 +378,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ #define EGLINTMAKECURRENT_ID              0x4008
+ #define EGLINTFLUSHANDWAIT_ID             0x4009
+ #define EGLINTSWAPBUFFERS_ID              0x400a
++#define EGLINTSWAPBUFFERS_ID_V2           0x410a
+ #define EGLINTSELECTMIPMAP_ID             0x400b
+ #define EGLINTFLUSH_ID                    0x400c
+ #define EGLINTGETCOLORDATA_ID             0x400d
+diff --git a/interface/khronos/egl/egl_client.c b/interface/khronos/egl/egl_client.c
+index 472ef0c..234da65 100644
+--- a/interface/khronos/egl/egl_client.c
++++ b/interface/khronos/egl/egl_client.c
+@@ -162,6 +162,17 @@ static void egl_current_release(CLIENT_PROCESS_STATE_T *process, EGL_CURRENT_T *
+ void egl_gl_flush_callback(bool wait);
+ void egl_vg_flush_callback(bool wait);
+ 
++#include "interface/vmcs_host/vc_dispmanx_types.h"
++/**HACKHACK - give us the ability to inject a DispmanX 
++ * resource handle into the CreateWindowSurface and 
++ * SwapBuffers calls */ 
++static DISPMANX_RESOURCE_HANDLE_T next_resource_handle;
++
++EGLAPI EGLBoolean EGLAPIENTRY eglSetNextResourceHandle(DISPMANX_RESOURCE_HANDLE_T handle)
++{
++   next_resource_handle = handle;
++}
++
+ /*
+ TODO: do an RPC call to make sure the Khronos vll is loaded (and that it stays loaded until eglTerminate)
+ Also affects global image (and possibly others?)
+@@ -644,7 +655,8 @@ EGLAPI EGLSurface EGLAPIENTRY eglCreateWindowSurface(EGLDisplay dpy, EGLConfig c
+                                 false,
+                                 EGL_NO_TEXTURE,
+                                 EGL_NO_TEXTURE,
+-                                0, 0);
++                                0, 0,
++                                next_resource_handle);
+ 
+                if (surface) {
+                   if (khrn_pointer_map_insert(&process->surfaces, process->next_surface, surface)) {
+@@ -889,7 +901,7 @@ EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig
+                              mipmap_texture,
+                              texture_format,
+                              texture_target,
+-                             0, 0);
++                             0, 0, 0);
+ 
+             if (surface) {
+                if (khrn_pointer_map_insert(&process->surfaces, process->next_surface, surface)) {
+@@ -1031,7 +1043,7 @@ EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig c
+                                    false,
+                                    EGL_NO_TEXTURE,
+                                    EGL_NO_TEXTURE,
+-                                   pixmap, ((server_handle[0] == 0) && (server_handle[1] == (uint32_t)(-1))) ? NULL : server_handle);
++                                   pixmap, ((server_handle[0] == 0) && (server_handle[1] == (uint32_t)(-1))) ? NULL : server_handle, 0);
+ 
+                      if (surface) {
+                         if (khrn_pointer_map_insert(&process->surfaces, process->next_surface, surface)) {
+@@ -2303,6 +2315,18 @@ EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers(EGLDisplay dpy, EGLSurface surf)
+ 
+                vcos_log_trace("eglSwapBuffers server call");
+ 
++               if (next_resource_handle)
++               RPC_CALL7(eglIntSwapBuffers_impl,
++                     thread,
++                     EGLINTSWAPBUFFERS_ID_V2,
++                     RPC_UINT(surface->serverbuffer),
++                     RPC_UINT(surface->width),
++                     RPC_UINT(surface->height),
++                     RPC_UINT(surface->internal_handle),
++                     RPC_UINT(surface->swap_behavior == EGL_BUFFER_PRESERVED ? 1 : 0),
++                     RPC_UINT(khrn_platform_get_window_position(surface->win)),
++                     RPC_INT(next_resource_handle));
++               else
+                RPC_CALL6(eglIntSwapBuffers_impl,
+                      thread,
+                      EGLINTSWAPBUFFERS_ID,
+diff --git a/interface/khronos/egl/egl_client_surface.c b/interface/khronos/egl/egl_client_surface.c
+index 0fa1fd1..0dc10e2 100644
+--- a/interface/khronos/egl/egl_client_surface.c
++++ b/interface/khronos/egl/egl_client_surface.c
+@@ -314,7 +314,8 @@ EGL_SURFACE_T *egl_surface_create(
+    EGLenum texture_format,
+    EGLenum texture_target,
+    EGLNativePixmapType pixmap,
+-   const uint32_t *pixmap_server_handle)
++   const uint32_t *pixmap_server_handle,
++   DISPMANX_RESOURCE_HANDLE_T next_resource_handle)
+ {
+    KHRN_IMAGE_FORMAT_T color;
+    KHRN_IMAGE_FORMAT_T depth;
+@@ -473,6 +474,27 @@ EGL_SURFACE_T *egl_surface_create(
+ #endif
+          uint32_t results[3];
+ 
++         if (next_resource_handle)
++         RPC_CALL16_OUT_CTRL(eglIntCreateSurface_impl,
++                             thread,
++                             EGLINTCREATESURFACE_ID_V2,
++                             RPC_UINT(serverwin),
++                             RPC_UINT(buffers),
++                             RPC_UINT(width),
++                             RPC_UINT(height),
++                             RPC_UINT(color),
++                             RPC_UINT(depth),
++                             RPC_UINT(mask),
++                             RPC_UINT(multi),
++                             RPC_UINT(largest_pbuffer),
++                             RPC_UINT(mipmap_texture),
++                             RPC_UINT(config_depth_bits),
++                             RPC_UINT(config_stencil_bits),
++                             RPC_UINT(sem_name),
++                             RPC_UINT(type),
++                             RPC_INT(next_resource_handle),
++                             results);
++         else
+          RPC_CALL15_OUT_CTRL(eglIntCreateSurface_impl,
+                              thread,
+                              EGLINTCREATESURFACE_ID,
+diff --git a/interface/khronos/egl/egl_client_surface.h b/interface/khronos/egl/egl_client_surface.h
+index c99d44c..b5bf70a 100644
+--- a/interface/khronos/egl/egl_client_surface.h
++++ b/interface/khronos/egl/egl_client_surface.h
+@@ -322,7 +322,8 @@ extern EGL_SURFACE_T *egl_surface_create(
+    EGLenum texture_format,
+    EGLenum texture_target,
+    EGLNativePixmapType pixmap,
+-   const uint32_t *pixmap_server_handle);
++   const uint32_t *pixmap_server_handle,
++   DISPMANX_RESOURCE_HANDLE_T next_resource_handle);
+ extern EGL_SURFACE_T *egl_surface_from_vg_image(
+    VGImage vg_handle,
+    EGLSurface name,
+diff --git a/interface/khronos/egl/egl_int_impl.h b/interface/khronos/egl/egl_int_impl.h
+index 8a5734c..51b3580 100644
+--- a/interface/khronos/egl/egl_int_impl.h
++++ b/interface/khronos/egl/egl_int_impl.h
+@@ -56,7 +56,8 @@ FN(int, eglIntCreateSurface_impl, (
+    uint32_t config_stencil_bits,
+    uint32_t sem,
+    uint32_t type,
+-   uint32_t *results))
++   uint32_t *results,
++   DISPMANX_RESOURCE_HANDLE_T next_resource_handle))
+ 
+ FN(int, eglIntCreatePbufferFromVGImage_impl, (
+    VGImage vg_handle,
+@@ -110,7 +111,7 @@ FN(void, eglIntMakeCurrent_impl, (uint32_t pid_0, uint32_t pid_1, uint32_t glver
+ FN(int, eglIntFlushAndWait_impl, (uint32_t flushgl, uint32_t flushvg))
+ FN(void, eglIntFlush_impl, (uint32_t flushgl, uint32_t flushvg))
+ 
+-FN(void, eglIntSwapBuffers_impl, (EGL_SURFACE_ID_T s, uint32_t width, uint32_t height, uint32_t handle, uint32_t preserve, uint32_t position))
++FN(void, eglIntSwapBuffers_impl, (EGL_SURFACE_ID_T s, uint32_t width, uint32_t height, uint32_t handle, uint32_t preserve, uint32_t position, DISPMANX_RESOURCE_HANDLE_T new_back_buffer))
+ FN(void, eglIntSelectMipmap_impl, (EGL_SURFACE_ID_T s, int level))
+ 
+ FN(void, eglIntGetColorData_impl, (EGL_SURFACE_ID_T s, KHRN_IMAGE_FORMAT_T format, uint32_t width, uint32_t height, int32_t stride, uint32_t y_offset, void *data))
+-- 
+2.9.0
+
diff --git a/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0002-wayland-Add-support-for-the-Wayland-winsys.patch b/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0002-wayland-Add-support-for-the-Wayland-winsys.patch
new file mode 100644
index 0000000..aa09dda
--- /dev/null
+++ b/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0002-wayland-Add-support-for-the-Wayland-winsys.patch
@@ -0,0 +1,1880 @@
+From 79ce2b4125359593f37c5b9744a37203e24249de Mon Sep 17 00:00:00 2001
+From: Tomeu Vizoso <tomeu.vizoso@collabora.com>
+Date: Tue, 1 Oct 2013 13:19:20 +0200
+Subject: [PATCH 02/13] wayland: Add support for the Wayland winsys
+
+* Adds EGL_WL_bind_wayland_display extension
+* Adds wayland-egl library
+* Adds wl_dispmanx_buffer protocol extension
+
+TODO: Check that platform_get_dimensions() returning swapchain_count == 1 is correct
+
+TODO: Remove the requirement of passing a valid DispmanX element handle to
+the SwapBuffers and CreateSurface RPC calls. This will remove the need to open
+a DispmanX display from the clients.
+
+TODO: wl_dispmanx_server_buffer should probably be defined in a
+private header that can be included from EGL and vc_* instead of in
+vc_vchi_dispmanx.h
+---
+ .gitignore                                         |   2 +
+ CMakeLists.txt                                     |  11 +
+ README.md                                          |   4 +
+ buildme                                            |  14 +-
+ interface/khronos/CMakeLists.txt                   |  52 ++++-
+ interface/khronos/common/khrn_client.c             |  15 ++
+ interface/khronos/common/khrn_client.h             |  10 +
+ interface/khronos/common/khrn_client_mangle.h      |   3 +
+ interface/khronos/common/khrn_client_platform.h    |   8 +
+ interface/khronos/common/khrn_client_unmangle.h    |   3 +
+ .../common/linux/khrn_client_platform_linux.c      | 115 ++++++++--
+ interface/khronos/common/linux/khrn_wayland.c      | 215 ++++++++++++++++++
+ .../common/linux/khrn_wayland.h}                   |  46 +---
+ interface/khronos/egl/egl_client.c                 |  92 +++++---
+ interface/khronos/egl/egl_client_get_proc.c        |  11 +
+ interface/khronos/egl/egl_client_surface.c         |  42 +++-
+ interface/khronos/egl/egl_client_surface.h         |  38 +++-
+ interface/khronos/egl/egl_int_impl.h               |   2 +-
+ interface/khronos/ext/egl_wayland.c                | 246 +++++++++++++++++++++
+ interface/khronos/include/EGL/eglext.h             |  23 ++
+ interface/khronos/wayland-egl/wayland-egl-priv.h   |  53 +++++
+ interface/khronos/wayland-egl/wayland-egl.c        |  59 +++++
+ interface/khronos/wayland-egl/wayland-egl.pc.in    |  10 +
+ interface/vmcs_host/CMakeLists.txt                 |  21 +-
+ interface/vmcs_host/vc_dispmanx.h                  |  10 +
+ interface/vmcs_host/vc_vchi_dispmanx.c             |  42 ++++
+ interface/vmcs_host/vc_vchi_dispmanx.h             |  15 ++
+ interface/wayland/dispmanx.xml                     | 123 +++++++++++
+ makefiles/cmake/Wayland.cmake                      |  72 ++++++
+ 29 files changed, 1260 insertions(+), 97 deletions(-)
+ create mode 100644 interface/khronos/common/linux/khrn_wayland.c
+ copy interface/{vmcs_host/vc_vchi_dispmanx.h => khronos/common/linux/khrn_wayland.h} (56%)
+ create mode 100644 interface/khronos/ext/egl_wayland.c
+ create mode 100644 interface/khronos/wayland-egl/wayland-egl-priv.h
+ create mode 100644 interface/khronos/wayland-egl/wayland-egl.c
+ create mode 100644 interface/khronos/wayland-egl/wayland-egl.pc.in
+ create mode 100644 interface/wayland/dispmanx.xml
+ create mode 100644 makefiles/cmake/Wayland.cmake
+
+diff --git a/.gitignore b/.gitignore
+index 8df9393..d0d1387 100644
+--- a/.gitignore
++++ b/.gitignore
+@@ -10,3 +10,5 @@
+ *.lai
+ *.la
+ *.a
++
++*~
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index 3113618..56b7fb8 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -19,6 +19,17 @@ include(makefiles/cmake/global_settings.cmake)
+ include(makefiles/cmake/arm-linux.cmake)
+ include(makefiles/cmake/vmcs.cmake)
+ 
++if (BUILD_WAYLAND)
++   include(makefiles/cmake/Wayland.cmake)
++
++   # Find Wayland libraries
++   find_package(PkgConfig)
++   pkg_check_modules(WAYLAND_CLIENT wayland-client REQUIRED)
++   pkg_check_modules(WAYLAND_SERVER wayland-server REQUIRED)
++
++   set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DBUILD_WAYLAND")
++endif()
++
+ enable_language(ASM)
+ 
+ # Global include paths
+diff --git a/README.md b/README.md
+index 358d2b4..4da4448 100644
+--- a/README.md
++++ b/README.md
+@@ -4,3 +4,7 @@ EGL, mmal, GLESv2, vcos, openmaxil, vchiq_arm, bcm_host, WFC, OpenVG.
+ 
+ Use buildme to build. It requires cmake to be installed and an arm cross compiler. It is set up to use this one:
+ https://github.com/raspberrypi/tools/tree/master/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian
++
++To build support for the Wayland winsys in EGL, execute the buildme script like this:
++
++$ BUILD_WAYLAND=1 ./buildme.
+diff --git a/buildme b/buildme
+index d5d3de9..c46f214 100755
+--- a/buildme
++++ b/buildme
+@@ -1,10 +1,14 @@
+ #!/bin/bash
+ 
++if [ -n "$BUILD_WAYLAND" ]; then
++       WAYLAND_VARS="-DBUILD_WAYLAND=TRUE"
++fi
++
+ if [ "armv6l" = `arch` ] || [ "armv7l" = `arch` ]; then
+ 	# Native compile on the Raspberry Pi
+ 	mkdir -p build/raspberry/release
+ 	pushd build/raspberry/release
+-	cmake -DCMAKE_BUILD_TYPE=Release ../../..
++	cmake -DCMAKE_BUILD_TYPE=Release $WAYLAND_VARS ../../..
+ 	if [ "armv6l" = `arch` ]; then
+ 		make
+ 	else
+@@ -17,9 +21,15 @@ if [ "armv6l" = `arch` ] || [ "armv7l" = `arch` ]; then
+ 	fi
+ else
+ 	# Cross compile on a more capable machine
++
++	if [ -n "$BUILD_WAYLAND" ]; then
++		# Use wayland-scanner from the build platform
++		WAYLAND_VARS+=" -DWAYLAND_SCANNER_EXECUTABLE:FILEPATH=/usr/bin/wayland-scanner"
++	fi
++
+ 	mkdir -p build/arm-linux/release/
+ 	pushd build/arm-linux/release/
+-	cmake -DCMAKE_TOOLCHAIN_FILE=../../../makefiles/cmake/toolchains/arm-linux-gnueabihf.cmake -DCMAKE_BUILD_TYPE=Release ../../..
++	cmake -DCMAKE_TOOLCHAIN_FILE=../../../makefiles/cmake/toolchains/arm-linux-gnueabihf.cmake -DCMAKE_BUILD_TYPE=Release $WAYLAND_VARS ../../..
+ 	make -j 6
+ 
+ 	if [ "$1" != "" ]; then
+diff --git a/interface/khronos/CMakeLists.txt b/interface/khronos/CMakeLists.txt
+index c437291..6778e10 100644
+--- a/interface/khronos/CMakeLists.txt
++++ b/interface/khronos/CMakeLists.txt
+@@ -6,6 +6,12 @@
+ # have quite a few circular dependencies, and so the only way
+ # to make it work seems to be to have everything static.
+ 
++if (BUILD_WAYLAND)
++include_directories(
++   ${WAYLAND_SERVER_INCLUDE_DIRS}
++)
++endif ()
++
+ set(EGL_SOURCE
+    egl/egl_client_config.c
+    egl/egl_client_context.c
+@@ -55,19 +61,63 @@ set(CLIENT_SOURCE
+    common/khrn_int_hash_asm.s
+    common/khrn_client_cache.c)
+ 
++set(EGL_LIBS
++   khrn_client
++   vchiq_arm
++   vcos
++   bcm_host
++   -lm)
++
++if (BUILD_WAYLAND)
++   set(EGL_SOURCE
++      ${EGL_SOURCE}
++      ext/egl_wayland.c
++      common/linux/khrn_wayland.c)
++
++   set(EGL_LIBS
++      ${EGL_LIBS}
++      wayland-client
++      wayland-server)
++
++   set(WAYLAND_EGL_SOURCE
++      wayland-egl/wayland-egl.c)
++
++   wayland_add_protocol_server(
++       EGL_SOURCE
++       ../../interface/wayland/dispmanx.xml
++       dispmanx
++   )
++
++   wayland_add_protocol_client(
++       EGL_SOURCE
++       ../../interface/wayland/dispmanx.xml
++       dispmanx
++   )
++
++   add_library(wayland-egl ${SHARED} ${WAYLAND_EGL_SOURCE})
++   install(TARGETS wayland-egl DESTINATION lib)
++
++   configure_file ("wayland-egl/wayland-egl.pc.in" "wayland-egl/wayland-egl.pc" @ONLY)
++   install (FILES "${CMAKE_CURRENT_BINARY_DIR}/wayland-egl/wayland-egl.pc"
++            DESTINATION lib/pkgconfig)
++endif ()
++
+ add_library(EGL ${SHARED} ${EGL_SOURCE})
+ add_library(GLESv2 ${SHARED} ${GLES_SOURCE})
+ add_library(OpenVG ${SHARED} ${VG_SOURCE})
+ add_library(WFC ${SHARED} ${WFC_SOURCE})
+ add_library(khrn_client ${CLIENT_SOURCE})
+ 
++set_target_properties(EGL PROPERTIES SOVERSION 1 VERSION 1.0.0)
++set_target_properties(GLESv2 PROPERTIES SOVERSION 2 VERSION 2.0.0)
++
+ # TODO do we need EGL_static and GLESv2_static now that khrn_static exists?
+ add_library(EGL_static STATIC ${EGL_SOURCE})
+ add_library(GLESv2_static STATIC ${GLES_SOURCE})
+ add_library(khrn_static STATIC
+    ${EGL_SOURCE} ${GLES_SOURCE} ${VG_SOURCE} ${WFC_SOURCE} ${CLIENT_SOURCE})
+ 
+-target_link_libraries(EGL khrn_client vchiq_arm vcos bcm_host -lm)
++target_link_libraries(EGL ${EGL_LIBS})
+ target_link_libraries(GLESv2 EGL khrn_client vcos)
+ target_link_libraries(WFC EGL)
+ target_link_libraries(OpenVG EGL)
+diff --git a/interface/khronos/common/khrn_client.c b/interface/khronos/common/khrn_client.c
+index e38a85f..783a68e 100644
+--- a/interface/khronos/common/khrn_client.c
++++ b/interface/khronos/common/khrn_client.c
+@@ -54,6 +54,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ #include "applications/vmcs/khronos/khronos_server.h"
+ #endif
+ 
++#ifdef BUILD_WAYLAND
++#include "interface/khronos/common/linux/khrn_wayland.h"
++#endif
++
+ VCOS_LOG_CAT_T khrn_client_log = VCOS_LOG_INIT("khrn_client", VCOS_LOG_WARN);
+ 
+ /*
+@@ -142,6 +146,10 @@ void client_try_unload_server(CLIENT_PROCESS_STATE_T *process)
+ bool client_process_state_init(CLIENT_PROCESS_STATE_T *process)
+ {
+    if (!process->inited) {
++#ifdef BUILD_WAYLAND
++      process->wl_global = NULL;
++#endif
++
+       if (!khrn_pointer_map_init(&process->contexts, 64))
+          return false;
+ 
+@@ -194,6 +202,13 @@ bool client_process_state_init(CLIENT_PROCESS_STATE_T *process)
+       }
+ #endif
+ 
++#ifdef BUILD_WAYLAND
++      struct wl_display *wl_display = khrn_platform_get_wl_display();
++      if (wl_display)
++         if (!init_process_wayland(process))
++            return false;
++#endif
++
+       process->inited = true;
+    }
+ 
+diff --git a/interface/khronos/common/khrn_client.h b/interface/khronos/common/khrn_client.h
+index 804039b..615f7b4 100644
+--- a/interface/khronos/common/khrn_client.h
++++ b/interface/khronos/common/khrn_client.h
+@@ -310,6 +310,16 @@ struct CLIENT_PROCESS_STATE {
+ #ifdef RPC_LIBRARY
+    KHRONOS_SERVER_CONNECTION_T khrn_connection;
+ #endif
++
++#ifdef BUILD_WAYLAND
++   /* Client-side Wayland state */
++   struct wl_registry *wl_registry;
++   struct wl_dispmanx *wl_dispmanx;
++   struct wl_event_queue *wl_queue;
++
++   /* Compositor-side Wayland state */
++   struct wl_global *wl_global;
++#endif
+ };
+ 
+ extern bool client_process_state_init(CLIENT_PROCESS_STATE_T *process);
+diff --git a/interface/khronos/common/khrn_client_mangle.h b/interface/khronos/common/khrn_client_mangle.h
+index b3c04f4..b7b21c5 100644
+--- a/interface/khronos/common/khrn_client_mangle.h
++++ b/interface/khronos/common/khrn_client_mangle.h
+@@ -83,6 +83,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ #define eglReleaseGlobalImageBRCM mangled_eglReleaseGlobalImageBRCM
+ #define eglInitGlobalImageBRCM mangled_eglInitGlobalImageBRCM
+ #define eglTermGlobalImageBRCM mangled_eglTermGlobalImageBRCM
++#define eglBindWaylandDisplayWL mangled_eglBindWaylandDisplayWL
++#define eglUnbindWaylandDisplayWL mangled_eglUnbindWaylandDisplayWL
++#define eglQueryWaylandBufferWL mangled_eglQueryWaylandBufferWL
+ 
+ /* OpenGL ES 1.1 and 2.0 functions */
+ 
+diff --git a/interface/khronos/common/khrn_client_platform.h b/interface/khronos/common/khrn_client_platform.h
+index 1c9da3a..715c67e 100644
+--- a/interface/khronos/common/khrn_client_platform.h
++++ b/interface/khronos/common/khrn_client_platform.h
+@@ -48,6 +48,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ #include "interface/khronos/common/vcos/khrn_client_platform_filler_vcos.h"
+ #endif
+ 
++#ifdef BUILD_WAYLAND
++#include <wayland-client.h>
++#endif
++
+ #ifdef __cplusplus
+ extern "C" {
+ #endif
+@@ -328,4 +332,8 @@ typedef struct
+ 
+ void *platform_wfc_bounce_thread(void *param);
+ 
++#ifdef BUILD_WAYLAND
++struct wl_display *khrn_platform_get_wl_display();
++#endif
++
+ #endif // KHRN_CLIENT_PLATFORM_H
+diff --git a/interface/khronos/common/khrn_client_unmangle.h b/interface/khronos/common/khrn_client_unmangle.h
+index 4f3ce49..84f6ec0 100644
+--- a/interface/khronos/common/khrn_client_unmangle.h
++++ b/interface/khronos/common/khrn_client_unmangle.h
+@@ -83,6 +83,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ #undef eglReleaseGlobalImageBRCM
+ #undef eglInitGlobalImageBRCM
+ #undef eglTermGlobalImageBRCM
++#undef eglBindWaylandDisplayWL
++#undef eglUnbindWaylandDisplayWL
++#undef eglQueryWaylandBufferWL
+ 
+ /* OpenGL ES 1.1 and 2.0 functions */
+ 
+diff --git a/interface/khronos/common/linux/khrn_client_platform_linux.c b/interface/khronos/common/linux/khrn_client_platform_linux.c
+index 9d43d15..00821d3 100644
+--- a/interface/khronos/common/linux/khrn_client_platform_linux.c
++++ b/interface/khronos/common/linux/khrn_client_platform_linux.c
+@@ -37,6 +37,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ #include "X11/Xlib.h"
+ #endif
+ 
++#ifdef BUILD_WAYLAND
++#include <wayland-client.h>
++#include "interface/khronos/wayland-egl/wayland-egl-priv.h"
++#endif
++
+ extern VCOS_LOG_CAT_T khrn_client_log;
+ 
+ extern void vc_vchi_khronos_init();
+@@ -460,13 +465,36 @@ EGLDisplay khrn_platform_set_display_id(EGLNativeDisplayType display_id)
+ 	   return EGL_NO_DISPLAY;
+ }
+ #else
++
++#ifdef BUILD_WAYLAND
++static struct wl_display *hacky_display = NULL;
++#endif
++
+ EGLDisplay khrn_platform_set_display_id(EGLNativeDisplayType display_id)
+ {
+    if (display_id == EGL_DEFAULT_DISPLAY)
+       return (EGLDisplay)1;
+-   else
+-      return EGL_NO_DISPLAY;
++   else {
++#ifdef BUILD_WAYLAND
++      void *first_pointer = *(void **) display_id;
++
++      /* wl_display is a wl_proxy, which is a wl_object.
++       * wl_object's first element points to the interfacetype. */
++      if (first_pointer == &wl_display_interface) {
++         hacky_display = (struct wl_display*)display_id;
++         return (EGLDisplay)1;
++      } else
++#endif
++         return EGL_NO_DISPLAY;
++   }
+ }
++
++#ifdef BUILD_WAYLAND
++struct wl_display *khrn_platform_get_wl_display()
++{
++   return hacky_display;
++}
++#endif
+ #endif
+ 
+ #ifdef WANT_X
+@@ -801,22 +829,81 @@ static EGL_DISPMANX_WINDOW_T *check_default(EGLNativeWindowType win)
+ void platform_get_dimensions(EGLDisplay dpy, EGLNativeWindowType win,
+       uint32_t *width, uint32_t *height, uint32_t *swapchain_count)
+ {
+-   EGL_DISPMANX_WINDOW_T *dwin = check_default(win);
+-   vcos_assert(dwin);
+-   vcos_assert(dwin->width < 1<<16); // sanity check
+-   vcos_assert(dwin->height < 1<<16); // sanity check
+-   *width = dwin->width;
+-   *height = dwin->height;
+-   *swapchain_count = 0;
++#ifdef BUILD_WAYLAND
++   if(khrn_platform_get_wl_display()) {
++      struct wl_egl_window *wl_egl_window = (struct wl_egl_window*)win;
++      *width = wl_egl_window->width;
++      *height = wl_egl_window->height;
++      /* This seems to be used for sync'ing with the VC on buffer creation, but
++         we are managing them on the CPU side */
++      *swapchain_count = 1;
++   } else {
++#endif
++      EGL_DISPMANX_WINDOW_T *dwin = check_default(win);
++      vcos_assert(dwin);
++      vcos_assert(dwin->width < 1<<16); // sanity check
++      vcos_assert(dwin->height < 1<<16); // sanity check
++      *width = dwin->width;
++      *height = dwin->height;
++      *swapchain_count = 0;
++#ifdef BUILD_WAYLAND
++   }
++#endif
+ }
+ 
++#ifdef BUILD_WAYLAND
++static DISPMANX_ELEMENT_HANDLE_T create_dummy_element()
++{
++   DISPMANX_DISPLAY_HANDLE_T display = vc_dispmanx_display_open(0);
++   DISPMANX_UPDATE_HANDLE_T update = vc_dispmanx_update_start(0);
++   DISPMANX_ELEMENT_HANDLE_T element;
++   VC_DISPMANX_ALPHA_T alpha = {DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS, 255, 0};
++   VC_RECT_T src_rect;
++   VC_RECT_T dst_rect;
++
++   src_rect.x = 0;
++   src_rect.y = 0;
++   src_rect.width = 1 << 16;
++   src_rect.height = 1 << 16;
++
++   dst_rect.x = 0;
++   dst_rect.y = 0;
++   dst_rect.width = 1;
++   dst_rect.height = 1;
++
++   element = vc_dispmanx_element_add(update, display, 0/*layer*/, &dst_rect,
++                                     0/*src*/, &src_rect,
++                                     DISPMANX_PROTECTION_NONE, &alpha,
++                                     0/*clamp*/, 0/*transform*/);
++
++   vc_dispmanx_update_submit_sync(update);
++
++   vc_dispmanx_display_close(display);
++
++   return element;
++}
++#endif
++
+ uint32_t platform_get_handle(EGLDisplay dpy, EGLNativeWindowType win)
+ {
+-   EGL_DISPMANX_WINDOW_T *dwin = check_default(win);
+-   vcos_assert(dwin);
+-   vcos_assert(dwin->width < 1<<16); // sanity check
+-   vcos_assert(dwin->height < 1<<16); // sanity check
+-   return dwin->element;
++#ifdef BUILD_WAYLAND
++   if(khrn_platform_get_wl_display()) {
++      struct wl_egl_window *wl_egl_window = (struct wl_egl_window*)win;
++
++      if (wl_egl_window->dummy_element == PLATFORM_WIN_NONE)
++         wl_egl_window->dummy_element = create_dummy_element();
++
++      return wl_egl_window->dummy_element;
++   } else {
++#endif
++      EGL_DISPMANX_WINDOW_T *dwin = check_default(win);
++      vcos_assert(dwin);
++      vcos_assert(dwin->width < 1<<16); // sanity check
++      vcos_assert(dwin->height < 1<<16); // sanity check
++      return dwin->element;
++#ifdef BUILD_WAYLAND
++   }
++#endif
+ }
+ 
+ #endif
+diff --git a/interface/khronos/common/linux/khrn_wayland.c b/interface/khronos/common/linux/khrn_wayland.c
+new file mode 100644
+index 0000000..0e1b9e7
+--- /dev/null
++++ b/interface/khronos/common/linux/khrn_wayland.c
+@@ -0,0 +1,215 @@
++/*
++Copyright (c) 2013, Raspberry Pi Foundation
++All rights reserved.
++
++Redistribution and use in source and binary forms, with or without
++modification, are permitted provided that the following conditions are met:
++    * Redistributions of source code must retain the above copyright
++      notice, this list of conditions and the following disclaimer.
++    * Redistributions in binary form must reproduce the above copyright
++      notice, this list of conditions and the following disclaimer in the
++      documentation and/or other materials provided with the distribution.
++    * Neither the name of the copyright holder nor the
++      names of its contributors may be used to endorse or promote products
++      derived from this software without specific prior written permission.
++
++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
++ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
++WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
++DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
++DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
++(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
++LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
++ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
++SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++*/
++
++#define VCOS_LOG_CATEGORY (&khrn_client_log)
++
++#include "interface/khronos/common/linux/khrn_wayland.h"
++#include "interface/khronos/wayland-dispmanx-client-protocol.h"
++#include "interface/khronos/wayland-egl/wayland-egl-priv.h"
++
++extern VCOS_LOG_CAT_T khrn_client_log;
++
++static void handle_dispmanx_format(void *data, struct wl_dispmanx *dispmanx,
++                                   uint32_t format)
++{
++}
++
++static void handle_dispmanx_allocated(void *data, struct wl_dispmanx *dispmanx,
++                                      struct wl_buffer *wl_buffer,
++                                      uint32_t resource_handle)
++{
++    struct wl_dispmanx_client_buffer *buffer = wl_buffer_get_user_data(wl_buffer);
++
++    buffer->pending_allocation = 0;
++    buffer->resource = resource_handle;
++}
++
++static const struct wl_dispmanx_listener dispmanx_listener = {
++    handle_dispmanx_format,
++    handle_dispmanx_allocated,
++};
++
++static void
++sync_callback(void *data, struct wl_callback *callback, uint32_t serial)
++{
++   int *done = data;
++
++   *done = 1;
++
++   wl_callback_destroy(callback);
++}
++
++static const struct wl_callback_listener sync_listener = {
++   sync_callback
++};
++
++static int
++roundtrip(CLIENT_PROCESS_STATE_T *process)
++{
++   struct wl_display *wl_display = khrn_platform_get_wl_display();
++   struct wl_callback *callback;
++   int done = 0, ret = 0;
++
++   callback = wl_display_sync(wl_display);
++   wl_callback_add_listener(callback, &sync_listener, &done);
++   wl_proxy_set_queue((struct wl_proxy *) callback, process->wl_queue);
++   while (ret != -1 && !done)
++      ret = wl_display_dispatch_queue(wl_display, process->wl_queue);
++
++   if (!done)
++      wl_callback_destroy(callback);
++
++   return ret;
++}
++
++int do_wl_roundtrip()
++{
++   CLIENT_PROCESS_STATE_T *process = CLIENT_GET_PROCESS_STATE();
++   return roundtrip(process);
++}
++
++static void
++registry_handle_global(void *data, struct wl_registry *registry,
++                       uint32_t name, const char *interface, uint32_t version)
++{
++   struct wl_display *wl_display = khrn_platform_get_wl_display();
++   CLIENT_PROCESS_STATE_T *process = (CLIENT_PROCESS_STATE_T *)data;
++
++   if (strcmp(interface, "wl_dispmanx") == 0) {
++      process->wl_dispmanx = wl_registry_bind(registry, name,
++	       &wl_dispmanx_interface, 1);
++
++      wl_proxy_set_queue((struct wl_proxy *) process->wl_dispmanx,
++                         process->wl_queue);
++      wl_dispmanx_add_listener(process->wl_dispmanx, &dispmanx_listener, wl_display);
++      roundtrip(process);
++   }
++}
++
++static void
++registry_handle_global_remove(void *data, struct wl_registry *registry,
++                              uint32_t name)
++{
++}
++
++static const struct wl_registry_listener registry_listener = {
++	registry_handle_global,
++	registry_handle_global_remove
++};
++
++int
++init_process_wayland(CLIENT_PROCESS_STATE_T *process)
++{
++    struct wl_display *wl_display = khrn_platform_get_wl_display();
++
++    process->wl_queue = wl_display_create_queue(wl_display);
++    if (!process->wl_queue) {
++        vcos_log_error("wl_display_create_queue failed\n");
++        return false;
++    }
++    wl_display_dispatch_pending(wl_display);
++
++    process->wl_registry = wl_display_get_registry(wl_display);
++    if (!process->wl_registry) {
++        vcos_log_error("wl_display_get_registry failed\n");
++        return false;
++    }
++
++    wl_proxy_set_queue((struct wl_proxy *) process->wl_registry,
++    process->wl_queue);
++
++    wl_registry_add_listener(process->wl_registry, &registry_listener, process);
++
++    if (roundtrip(process) < 0 || process->wl_dispmanx == NULL) {
++        vcos_log_error("failed to get wl_dispmanx\n");
++        return false;
++    }
++
++    return true;
++}
++
++#ifndef ALIGN_UP
++#define ALIGN_UP(x,y)  ((x + (y)-1) & ~((y)-1))
++#endif
++
++static void handle_buffer_release(void *data, struct wl_buffer *buffer_wl)
++{
++   struct wl_dispmanx_client_buffer *wl_dispmanx_client_buffer = data;
++   wl_dispmanx_client_buffer->in_use = 0;
++}
++
++static const struct wl_buffer_listener buffer_listener = {
++   handle_buffer_release
++};
++
++struct wl_dispmanx_client_buffer *
++allocate_wl_buffer(struct wl_egl_window *window, KHRN_IMAGE_FORMAT_T color)
++{
++   CLIENT_PROCESS_STATE_T *process = CLIENT_GET_PROCESS_STATE();
++   struct wl_dispmanx_client_buffer *wl_dispmanx_client_buffer;
++   struct wl_buffer *wl_buffer;
++   uint32_t stride = ALIGN_UP(window->width * 4, 16);
++   uint32_t buffer_height = ALIGN_UP(window->height, 16);
++   enum wl_dispmanx_format color_format;
++   int ret = 0;
++
++   switch (color) {
++   case ABGR_8888:
++      color_format = WL_DISPMANX_FORMAT_ABGR8888;
++      break;
++   case XBGR_8888:
++      color_format = WL_DISPMANX_FORMAT_XBGR8888;
++      break;
++   case RGB_565:
++      color_format = WL_DISPMANX_FORMAT_RGB565;
++      break;
++   default:
++      vcos_log_error("unknown KHRN_IMAGE_FORMAT_T 0x%x\n", color);
++      return NULL;
++   }
++
++   wl_buffer = wl_dispmanx_create_buffer(process->wl_dispmanx, window->width,
++                                         window->height, stride, buffer_height,
++                                         color_format);
++   if (wl_buffer == NULL)
++      return NULL;
++
++   wl_dispmanx_client_buffer = calloc(1, sizeof(struct wl_dispmanx_client_buffer));
++   wl_dispmanx_client_buffer->wl_buffer = wl_buffer;
++   wl_dispmanx_client_buffer->in_use = 0;
++   wl_dispmanx_client_buffer->pending_allocation = 1;
++   wl_dispmanx_client_buffer->width = window->width;
++   wl_dispmanx_client_buffer->height = window->height;
++
++   wl_proxy_set_queue((struct wl_proxy *) wl_buffer, process->wl_queue);
++   wl_buffer_add_listener(wl_buffer, &buffer_listener, wl_dispmanx_client_buffer);
++
++   while (ret != -1 && wl_dispmanx_client_buffer->pending_allocation)
++      ret = do_wl_roundtrip();
++
++   return wl_dispmanx_client_buffer;
++}
+diff --git a/interface/vmcs_host/vc_vchi_dispmanx.h b/interface/khronos/common/linux/khrn_wayland.h
+similarity index 56%
+copy from interface/vmcs_host/vc_vchi_dispmanx.h
+copy to interface/khronos/common/linux/khrn_wayland.h
+index b723b76..b9bf08c 100644
+--- a/interface/vmcs_host/vc_vchi_dispmanx.h
++++ b/interface/khronos/common/linux/khrn_wayland.h
+@@ -1,5 +1,5 @@
+ /*
+-Copyright (c) 2012, Broadcom Europe Ltd
++Copyright (c) 2013, Raspberry Pi Foundation
+ All rights reserved.
+ 
+ Redistribution and use in source and binary forms, with or without
+@@ -25,45 +25,9 @@ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+ 
+-#ifndef VC_VCHI_DISPMANX_H
+-#define VC_VCHI_DISPMANX_H
++#include "interface/khronos/common/khrn_client.h"
+ 
+-#include "interface/peer/vc_vchi_dispmanx_common.h"
++int init_process_wayland(CLIENT_PROCESS_STATE_T *process);
++int do_wl_roundtrip();
+ 
+-#define VC_NUM_HOST_RESOURCES 64
+-#define DISPMANX_MSGFIFO_SIZE 1024
+-#define DISPMANX_CLIENT_NAME MAKE_FOURCC("DISP")
+-#define DISPMANX_NOTIFY_NAME MAKE_FOURCC("UPDH")
+-
+-//Or with command to indicate we don't need a response
+-#define DISPMANX_NO_REPLY_MASK (1<<31)
+-
+-typedef struct {
+-   char     description[32];
+-   uint32_t width;
+-   uint32_t height;
+-   uint32_t aspect_pixwidth;
+-   uint32_t aspect_pixheight;
+-   uint32_t fieldrate_num;
+-   uint32_t fieldrate_denom;
+-   uint32_t fields_per_frame;
+-   uint32_t transform;        
+-} GET_MODES_DATA_T;
+-
+-typedef struct {
+-   int32_t  response;
+-   uint32_t width;
+-   uint32_t height;
+-   uint32_t transform;
+-   uint32_t input_format;
+-} GET_INFO_DATA_T;
+-
+-//Attributes changes flag mask
+-#define ELEMENT_CHANGE_LAYER          (1<<0)
+-#define ELEMENT_CHANGE_OPACITY        (1<<1)
+-#define ELEMENT_CHANGE_DEST_RECT      (1<<2)
+-#define ELEMENT_CHANGE_SRC_RECT       (1<<3)
+-#define ELEMENT_CHANGE_MASK_RESOURCE  (1<<4)
+-#define ELEMENT_CHANGE_TRANSFORM      (1<<5)
+-
+-#endif
++struct wl_dispmanx_client_buffer *allocate_wl_buffer(struct wl_egl_window *window, KHRN_IMAGE_FORMAT_T color);
+diff --git a/interface/khronos/egl/egl_client.c b/interface/khronos/egl/egl_client.c
+index 234da65..024f3ed 100644
+--- a/interface/khronos/egl/egl_client.c
++++ b/interface/khronos/egl/egl_client.c
+@@ -153,6 +153,10 @@ by an attribute value"
+ #include <stdlib.h>
+ #include <string.h>
+ 
++#ifdef BUILD_WAYLAND
++#include "interface/khronos/wayland-egl/wayland-egl-priv.h"
++#include "interface/khronos/common/linux/khrn_wayland.h"
++#endif
+ 
+ #include "interface/khronos/egl/egl_client_cr.c"
+ 
+@@ -162,17 +166,6 @@ static void egl_current_release(CLIENT_PROCESS_STATE_T *process, EGL_CURRENT_T *
+ void egl_gl_flush_callback(bool wait);
+ void egl_vg_flush_callback(bool wait);
+ 
+-#include "interface/vmcs_host/vc_dispmanx_types.h"
+-/**HACKHACK - give us the ability to inject a DispmanX 
+- * resource handle into the CreateWindowSurface and 
+- * SwapBuffers calls */ 
+-static DISPMANX_RESOURCE_HANDLE_T next_resource_handle;
+-
+-EGLAPI EGLBoolean EGLAPIENTRY eglSetNextResourceHandle(DISPMANX_RESOURCE_HANDLE_T handle)
+-{
+-   next_resource_handle = handle;
+-}
+-
+ /*
+ TODO: do an RPC call to make sure the Khronos vll is loaded (and that it stays loaded until eglTerminate)
+ Also affects global image (and possibly others?)
+@@ -451,6 +444,9 @@ EGLAPI const char EGLAPIENTRY * eglQueryString(EGLDisplay dpy, EGLint name)
+             "EGL_KHR_fence_sync "
+ #endif
+ #endif
++#if EGL_WL_bind_wayland_display
++            "EGL_WL_bind_wayland_display "
++#endif
+             ;
+          break;
+       case EGL_VENDOR:
+@@ -655,8 +651,7 @@ EGLAPI EGLSurface EGLAPIENTRY eglCreateWindowSurface(EGLDisplay dpy, EGLConfig c
+                                 false,
+                                 EGL_NO_TEXTURE,
+                                 EGL_NO_TEXTURE,
+-                                0, 0,
+-                                next_resource_handle);
++                                0, 0);
+ 
+                if (surface) {
+                   if (khrn_pointer_map_insert(&process->surfaces, process->next_surface, surface)) {
+@@ -901,7 +896,7 @@ EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig
+                              mipmap_texture,
+                              texture_format,
+                              texture_target,
+-                             0, 0, 0);
++                             0, 0);
+ 
+             if (surface) {
+                if (khrn_pointer_map_insert(&process->surfaces, process->next_surface, surface)) {
+@@ -1043,7 +1038,7 @@ EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig c
+                                    false,
+                                    EGL_NO_TEXTURE,
+                                    EGL_NO_TEXTURE,
+-                                   pixmap, ((server_handle[0] == 0) && (server_handle[1] == (uint32_t)(-1))) ? NULL : server_handle, 0);
++                                   pixmap, ((server_handle[0] == 0) && (server_handle[1] == (uint32_t)(-1))) ? NULL : server_handle);
+ 
+                      if (surface) {
+                         if (khrn_pointer_map_insert(&process->surfaces, process->next_surface, surface)) {
+@@ -2245,6 +2240,9 @@ EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers(EGLDisplay dpy, EGLSurface surf)
+    CLIENT_THREAD_STATE_T *thread;
+    CLIENT_PROCESS_STATE_T *process;
+    EGLBoolean result;
++#ifdef BUILD_WAYLAND
++   struct wl_display *wl_display = khrn_platform_get_wl_display();
++#endif
+ 
+    vcos_log_trace("eglSwapBuffers start. dpy=%d. surf=%d.", (int)dpy, (int)surf);
+ 
+@@ -2315,18 +2313,58 @@ EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers(EGLDisplay dpy, EGLSurface surf)
+ 
+                vcos_log_trace("eglSwapBuffers server call");
+ 
+-               if (next_resource_handle)
+-               RPC_CALL7(eglIntSwapBuffers_impl,
+-                     thread,
+-                     EGLINTSWAPBUFFERS_ID_V2,
+-                     RPC_UINT(surface->serverbuffer),
+-                     RPC_UINT(surface->width),
+-                     RPC_UINT(surface->height),
+-                     RPC_UINT(surface->internal_handle),
+-                     RPC_UINT(surface->swap_behavior == EGL_BUFFER_PRESERVED ? 1 : 0),
+-                     RPC_UINT(khrn_platform_get_window_position(surface->win)),
+-                     RPC_INT(next_resource_handle));
+-               else
++#ifdef BUILD_WAYLAND
++               if (wl_display) {
++                  struct wl_egl_window *wl_egl_window = surface->wl_egl_window;
++                  struct wl_dispmanx_client_buffer *buffer_temp;
++                  uint32_t configid;
++                  KHRN_IMAGE_FORMAT_T color;
++                  int ret = 0;
++
++                  buffer_temp = surface->front_wl_buffer;
++                  surface->front_wl_buffer = surface->back_wl_buffer;
++                  surface->back_wl_buffer = buffer_temp;
++
++                  configid = egl_config_to_id(surface->config);
++                  color = egl_config_get_color_format(configid);
++
++                  if (surface->back_wl_buffer == NULL)
++                     surface->back_wl_buffer = allocate_wl_buffer(wl_egl_window, color);
++                  else if (surface->back_wl_buffer->width != width ||
++                           surface->back_wl_buffer->height != height) {
++
++                     struct wl_dispmanx_client_buffer *buffer;
++
++                     wl_buffer_destroy(surface->back_wl_buffer->wl_buffer);
++                     free(surface->back_wl_buffer);
++
++                     buffer = allocate_wl_buffer(wl_egl_window, color);
++                     surface->back_wl_buffer = buffer;
++                  }
++
++                  RPC_CALL7(eglIntSwapBuffers_impl,
++                        thread,
++                        EGLINTSWAPBUFFERS_ID_V2,
++                        RPC_UINT(surface->serverbuffer),
++                        RPC_UINT(surface->width),
++                        RPC_UINT(surface->height),
++                        RPC_UINT(surface->internal_handle),
++                        RPC_UINT(surface->swap_behavior == EGL_BUFFER_PRESERVED ? 1 : 0),
++                        RPC_UINT(khrn_platform_get_window_position(surface->win)),
++                        RPC_INT(surface->back_wl_buffer->resource));
++
++                  surface->front_wl_buffer->in_use = 1;
++                  wl_surface_attach(wl_egl_window->wl_surface,
++                                    surface->front_wl_buffer->wl_buffer,
++                                    0, 0);
++                  wl_surface_damage(wl_egl_window->wl_surface, 0, 0,
++                                    surface->width, surface->height);
++                  wl_surface_commit(wl_egl_window->wl_surface);
++
++                  while(ret != -1 && surface->back_wl_buffer->in_use)
++                     ret = wl_display_dispatch_queue(wl_display, process->wl_queue);
++               } else
++#endif
+                RPC_CALL6(eglIntSwapBuffers_impl,
+                      thread,
+                      EGLINTSWAPBUFFERS_ID,
+diff --git a/interface/khronos/egl/egl_client_get_proc.c b/interface/khronos/egl/egl_client_get_proc.c
+index 4cfa9ff..6a715af 100644
+--- a/interface/khronos/egl/egl_client_get_proc.c
++++ b/interface/khronos/egl/egl_client_get_proc.c
+@@ -254,6 +254,17 @@ EGLAPI void EGLAPIENTRY (* eglGetProcAddress(const char *procname))(void)
+       return (void(*)(void))eglQueryGlobalImageBRCM;
+ #endif
+ 
++#ifdef BUILD_WAYLAND
++#if EGL_WL_bind_wayland_display
++   if (!strcmp(procname, "eglBindWaylandDisplayWL"))
++      return (void(*)(void))eglBindWaylandDisplayWL;
++   if (!strcmp(procname, "eglUnbindWaylandDisplayWL"))
++      return (void(*)(void))eglUnbindWaylandDisplayWL;
++   if (!strcmp(procname, "eglQueryWaylandBufferWL"))
++      return (void(*)(void))eglQueryWaylandBufferWL;
++#endif
++#endif
++
+    return (void(*)(void)) NULL;
+ }
+ 
+diff --git a/interface/khronos/egl/egl_client_surface.c b/interface/khronos/egl/egl_client_surface.c
+index 0dc10e2..49cf7e5 100644
+--- a/interface/khronos/egl/egl_client_surface.c
++++ b/interface/khronos/egl/egl_client_surface.c
+@@ -46,6 +46,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ #include "interface/khronos/egl/egl_int_impl.h"
+ #endif
+ 
++#ifdef BUILD_WAYLAND
++#include "interface/khronos/wayland-egl/wayland-egl-priv.h"
++#include "interface/khronos/common/linux/khrn_wayland.h"
++#endif
++
+ #include <stdlib.h>
+ 
+ 
+@@ -314,8 +319,7 @@ EGL_SURFACE_T *egl_surface_create(
+    EGLenum texture_format,
+    EGLenum texture_target,
+    EGLNativePixmapType pixmap,
+-   const uint32_t *pixmap_server_handle,
+-   DISPMANX_RESOURCE_HANDLE_T next_resource_handle)
++   const uint32_t *pixmap_server_handle)
+ {
+    KHRN_IMAGE_FORMAT_T color;
+    KHRN_IMAGE_FORMAT_T depth;
+@@ -326,6 +330,10 @@ EGL_SURFACE_T *egl_surface_create(
+    EGLint   config_depth_bits;
+    EGLint   config_stencil_bits;
+    CLIENT_THREAD_STATE_T *thread = CLIENT_GET_THREAD_STATE();
++#ifdef BUILD_WAYLAND
++   struct wl_display *wl_display = khrn_platform_get_wl_display();
++   DISPMANX_RESOURCE_HANDLE_T resource;
++#endif
+ 
+    EGL_SURFACE_T *surface = egl_surface_pool_alloc();
+ 
+@@ -390,6 +398,18 @@ EGL_SURFACE_T *egl_surface_create(
+ 
+    vcos_assert(color != IMAGE_FORMAT_INVALID);
+ 
++#ifdef BUILD_WAYLAND
++   if (type == WINDOW && wl_display) {
++      surface->wl_egl_window = (struct wl_egl_window*)win;
++      surface->back_wl_buffer = allocate_wl_buffer(
++            surface->wl_egl_window, color);
++      resource = surface->back_wl_buffer->resource;
++   } else {
++      surface->wl_egl_window = NULL;
++      resource = DISPMANX_NO_HANDLE;
++   }
++#endif
++
+ #ifdef KHRONOS_EGL_PLATFORM_OPENWFC
+    // Create stream for this window
+    if(type != PBUFFER)
+@@ -474,7 +494,8 @@ EGL_SURFACE_T *egl_surface_create(
+ #endif
+          uint32_t results[3];
+ 
+-         if (next_resource_handle)
++#ifdef BUILD_WAYLAND
++         if (resource != DISPMANX_NO_HANDLE)
+          RPC_CALL16_OUT_CTRL(eglIntCreateSurface_impl,
+                              thread,
+                              EGLINTCREATESURFACE_ID_V2,
+@@ -492,9 +513,10 @@ EGL_SURFACE_T *egl_surface_create(
+                              RPC_UINT(config_stencil_bits),
+                              RPC_UINT(sem_name),
+                              RPC_UINT(type),
+-                             RPC_INT(next_resource_handle),
++                             RPC_INT(resource),
+                              results);
+          else
++#endif
+          RPC_CALL15_OUT_CTRL(eglIntCreateSurface_impl,
+                              thread,
+                              EGLINTCREATESURFACE_ID,
+@@ -663,6 +685,18 @@ void egl_surface_free(EGL_SURFACE_T *surface)
+    if( surface->type == WINDOW ) {
+       vcos_log_trace("egl_surface_free: calling platform_destroy_winhandle...");
+       platform_destroy_winhandle( surface->win, surface->internal_handle );
++
++#ifdef BUILD_WAYLAND
++      if (surface->back_wl_buffer) {
++         wl_buffer_destroy(surface->back_wl_buffer->wl_buffer);
++         free(surface->back_wl_buffer);
++      }
++
++      if (surface->front_wl_buffer) {
++         wl_buffer_destroy(surface->front_wl_buffer->wl_buffer);
++         free(surface->front_wl_buffer);
++      }
++#endif
+    }
+    /* return value ignored -- read performed to ensure blocking. we want this to
+     * block so clients can safely destroy the surface's window as soon as the
+diff --git a/interface/khronos/egl/egl_client_surface.h b/interface/khronos/egl/egl_client_surface.h
+index b5bf70a..e328b77 100644
+--- a/interface/khronos/egl/egl_client_surface.h
++++ b/interface/khronos/egl/egl_client_surface.h
+@@ -288,6 +288,41 @@ typedef struct {
+       type == PIXMAP
+    */
+    bool server_owned;
++
++#ifdef BUILD_WAYLAND
++   /*
++      wl_egl_window
++
++      Validity:
++      type == WINDOW
++
++      Invariant:
++      wayland EGL window
++   */
++   struct wl_egl_window *wl_egl_window;
++
++   /*
++      front_wl_buffer
++
++      Validity:
++      type == WINDOW
++
++      Invariant:
++      client-side information about the wl_buffer in the front
++   */
++   struct wl_dispmanx_client_buffer *front_wl_buffer;
++
++   /*
++      back_wl_buffer
++
++      Validity:
++      type == WINDOW
++
++      Invariant:
++      client-side information about the wl_buffer in the back
++   */
++   struct wl_dispmanx_client_buffer *back_wl_buffer;
++#endif
+ } EGL_SURFACE_T;
+ 
+ extern bool egl_surface_check_attribs(
+@@ -322,8 +357,7 @@ extern EGL_SURFACE_T *egl_surface_create(
+    EGLenum texture_format,
+    EGLenum texture_target,
+    EGLNativePixmapType pixmap,
+-   const uint32_t *pixmap_server_handle,
+-   DISPMANX_RESOURCE_HANDLE_T next_resource_handle);
++   const uint32_t *pixmap_server_handle);
+ extern EGL_SURFACE_T *egl_surface_from_vg_image(
+    VGImage vg_handle,
+    EGLSurface name,
+diff --git a/interface/khronos/egl/egl_int_impl.h b/interface/khronos/egl/egl_int_impl.h
+index 51b3580..6863a3b 100644
+--- a/interface/khronos/egl/egl_int_impl.h
++++ b/interface/khronos/egl/egl_int_impl.h
+@@ -57,7 +57,7 @@ FN(int, eglIntCreateSurface_impl, (
+    uint32_t sem,
+    uint32_t type,
+    uint32_t *results,
+-   DISPMANX_RESOURCE_HANDLE_T next_resource_handle))
++   DISPMANX_RESOURCE_HANDLE_T resource_handle))
+ 
+ FN(int, eglIntCreatePbufferFromVGImage_impl, (
+    VGImage vg_handle,
+diff --git a/interface/khronos/ext/egl_wayland.c b/interface/khronos/ext/egl_wayland.c
+new file mode 100644
+index 0000000..5730743
+--- /dev/null
++++ b/interface/khronos/ext/egl_wayland.c
+@@ -0,0 +1,246 @@
++/*
++Copyright (c) 2013, Raspberry Pi Foundation
++All rights reserved.
++
++Redistribution and use in source and binary forms, with or without
++modification, are permitted provided that the following conditions are met:
++    * Redistributions of source code must retain the above copyright
++      notice, this list of conditions and the following disclaimer.
++    * Redistributions in binary form must reproduce the above copyright
++      notice, this list of conditions and the following disclaimer in the
++      documentation and/or other materials provided with the distribution.
++    * Neither the name of the copyright holder nor the
++      names of its contributors may be used to endorse or promote products
++      derived from this software without specific prior written permission.
++
++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
++ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
++WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
++DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
++DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
++(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
++LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
++ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
++SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++*/
++
++#include "interface/khronos/common/khrn_client_mangle.h"
++#include "interface/khronos/common/khrn_client_rpc.h"
++
++#include "interface/khronos/ext/egl_khr_sync_client.h"
++#include "interface/khronos/include/EGL/egl.h"
++#include "interface/khronos/include/EGL/eglext.h"
++
++#include "interface/vmcs_host/vc_vchi_dispmanx.h"
++
++#include <wayland-server.h>
++#include "interface/khronos/wayland-dispmanx-server-protocol.h"
++
++static void
++destroy_buffer(struct wl_resource *resource)
++{
++   struct wl_dispmanx_server_buffer *buffer = wl_resource_get_user_data(resource);
++
++   if(!buffer->in_use)
++      vc_dispmanx_resource_delete(buffer->handle);
++
++   free(buffer);
++}
++
++static void
++buffer_destroy(struct wl_client *client, struct wl_resource *resource)
++{
++   wl_resource_destroy(resource);
++}
++
++static const struct wl_buffer_interface dispmanx_buffer_interface = {
++   buffer_destroy
++};
++
++static VC_IMAGE_TYPE_T
++get_vc_format(enum wl_dispmanx_format format)
++{
++	/* XXX: The app is likely to have been premultiplying in its shaders,
++	 * but the VC scanout hardware on the RPi cannot mix premultiplied alpha
++	 * channel with the element's alpha.
++	 */
++	switch (format) {
++	case WL_DISPMANX_FORMAT_ABGR8888:
++		return VC_IMAGE_RGBA32;
++	case WL_DISPMANX_FORMAT_XBGR8888:
++		return VC_IMAGE_BGRX8888;
++	case WL_DISPMANX_FORMAT_RGB565:
++		return VC_IMAGE_RGB565;
++	default:
++		/* invalid format */
++		return VC_IMAGE_MIN;
++	}
++}
++
++static void
++dispmanx_create_buffer(struct wl_client *client, struct wl_resource *resource,
++                       uint32_t id, int32_t width, int32_t height,
++                       uint32_t stride, uint32_t buffer_height, uint32_t format)
++{
++   struct wl_dispmanx_server_buffer *buffer;
++   VC_IMAGE_TYPE_T vc_format = get_vc_format(format);
++   uint32_t dummy;
++
++   if(vc_format == VC_IMAGE_MIN) {
++      wl_resource_post_error(resource,
++                             WL_DISPMANX_ERROR_INVALID_FORMAT,
++                             "invalid format");
++      return;
++   }
++
++   buffer = calloc(1, sizeof *buffer);
++   if (buffer == NULL) {
++      wl_resource_post_no_memory(resource);
++      return;
++   }
++
++   buffer->handle = vc_dispmanx_resource_create(vc_format,
++                                                width | (stride << 16),
++                                                height | (buffer_height << 16),
++                                                &dummy);
++   if(buffer->handle == DISPMANX_NO_HANDLE) {
++      wl_resource_post_error(resource,
++                             WL_DISPMANX_ERROR_ALLOC_FAILED,
++                             "allocation failed");
++      free(buffer);
++      return;
++   }
++
++   buffer->width = width;
++   buffer->height = height;
++   buffer->format = format;
++
++   buffer->resource = wl_resource_create(resource->client, &wl_buffer_interface,
++                                         1, id);
++   if (!buffer->resource) {
++      wl_resource_post_no_memory(resource);
++      vc_dispmanx_resource_delete(buffer->handle);
++      free(buffer);
++      return;
++   }
++
++   wl_resource_set_implementation(buffer->resource,
++				       (void (**)(void)) &dispmanx_buffer_interface,
++				       buffer, destroy_buffer);
++
++   wl_dispmanx_send_buffer_allocated(resource, buffer->resource,
++                                     buffer->handle);
++}
++
++static const struct wl_dispmanx_interface dispmanx_interface = {
++   dispmanx_create_buffer,
++};
++
++static void
++bind_dispmanx(struct wl_client *client, void *data, uint32_t version, uint32_t id)
++{
++   struct wl_resource *resource;
++
++   resource = wl_resource_create(client, &wl_dispmanx_interface, 1, id);
++   wl_resource_set_implementation(resource, &dispmanx_interface, NULL, NULL);
++
++   wl_resource_post_event(resource, WL_DISPMANX_FORMAT,
++                          WL_DISPMANX_FORMAT_ARGB8888);
++
++   wl_resource_post_event(resource, WL_DISPMANX_FORMAT,
++                          WL_DISPMANX_FORMAT_XRGB8888);
++
++   wl_resource_post_event(resource, WL_DISPMANX_FORMAT,
++                          WL_DISPMANX_FORMAT_ABGR8888);
++
++   wl_resource_post_event(resource, WL_DISPMANX_FORMAT,
++                          WL_DISPMANX_FORMAT_XBGR8888);
++
++   wl_resource_post_event(resource, WL_DISPMANX_FORMAT,
++                          WL_DISPMANX_FORMAT_RGB565);
++}
++
++EGLBoolean EGLAPIENTRY
++eglBindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
++{
++   CLIENT_THREAD_STATE_T *thread;
++   CLIENT_PROCESS_STATE_T *process;
++
++   if (!CLIENT_LOCK_AND_GET_STATES(dpy, &thread, &process))
++      return EGL_FALSE;
++
++   if (process->wl_global != NULL)
++      goto error;
++
++   process->wl_global = wl_global_create(display, &wl_dispmanx_interface, 1,
++                                         NULL, bind_dispmanx);
++   if (process->wl_global == NULL)
++      goto error;
++
++   return EGL_TRUE;
++
++error:
++   CLIENT_UNLOCK();
++   return EGL_FALSE;
++}
++
++EGLBoolean EGLAPIENTRY
++eglUnbindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
++{
++   CLIENT_THREAD_STATE_T *thread;
++   CLIENT_PROCESS_STATE_T *process;
++
++   if (!CLIENT_LOCK_AND_GET_STATES(dpy, &thread, &process))
++      return EGL_FALSE;
++
++   wl_global_destroy(process->wl_global);
++   process->wl_global = NULL;
++
++   CLIENT_UNLOCK();
++
++   return EGL_TRUE;
++}
++
++static int
++get_egl_format(enum wl_dispmanx_format format)
++{
++	switch (format) {
++	case WL_DISPMANX_FORMAT_ABGR8888:
++		return EGL_TEXTURE_RGBA;
++	case WL_DISPMANX_FORMAT_XBGR8888:
++		return EGL_TEXTURE_RGB;
++	case WL_DISPMANX_FORMAT_RGB565:
++		return EGL_TEXTURE_RGB;
++	default:
++		/* invalid format */
++		return EGL_NO_TEXTURE;
++	}
++}
++
++EGLBoolean EGLAPIENTRY
++eglQueryWaylandBufferWL(EGLDisplay dpy, struct wl_resource *_buffer,
++         EGLint attribute, EGLint *value)
++{
++   struct wl_dispmanx_server_buffer *buffer = wl_resource_get_user_data(_buffer);
++
++   if (wl_resource_instance_of(_buffer, &wl_dispmanx_interface,
++                               &dispmanx_buffer_interface))
++      return EGL_FALSE;
++
++   switch (attribute) {
++   case EGL_TEXTURE_FORMAT:
++      *value = get_egl_format(buffer->format);
++      if (*value == EGL_NO_TEXTURE)
++         return EGL_FALSE;
++      return EGL_TRUE;
++   case EGL_WIDTH:
++      *value = buffer->width;
++      return EGL_TRUE;
++   case EGL_HEIGHT:
++      *value = buffer->height;
++      return EGL_TRUE;
++   }
++
++   return EGL_FALSE;
++}
+diff --git a/interface/khronos/include/EGL/eglext.h b/interface/khronos/include/EGL/eglext.h
+index 89a3369..d7e5ba7 100755
+--- a/interface/khronos/include/EGL/eglext.h
++++ b/interface/khronos/include/EGL/eglext.h
+@@ -191,6 +191,29 @@ typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSYNCATTRIBKHRPROC) (EGLDisplay dpy, EG
+ #endif
+ 
+ 
++#ifndef EGL_WL_bind_wayland_display
++#define EGL_WL_bind_wayland_display 1
++
++#define EGL_WAYLAND_BUFFER_WL		0x31D5 /* eglCreateImageKHR target */
++#define EGL_WAYLAND_PLANE_WL		0x31D6 /* eglCreateImageKHR target */
++#define EGL_TEXTURE_Y_U_V_WL            0x31D7
++#define EGL_TEXTURE_Y_UV_WL             0x31D8
++#define EGL_TEXTURE_Y_XUXV_WL           0x31D9
++
++struct wl_display;
++struct wl_resource;
++#ifdef EGL_EGLEXT_PROTOTYPES
++EGLAPI EGLBoolean EGLAPIENTRY eglBindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display);
++EGLAPI EGLBoolean EGLAPIENTRY eglUnbindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display);
++EGLAPI EGLBoolean EGLAPIENTRY eglQueryWaylandBufferWL(EGLDisplay dpy, struct wl_resource *buffer, EGLint attribute, EGLint *value);
++#endif
++typedef EGLBoolean (EGLAPIENTRYP PFNEGLBINDWAYLANDDISPLAYWL) (EGLDisplay dpy, struct wl_display *display);
++typedef EGLBoolean (EGLAPIENTRYP PFNEGLUNBINDWAYLANDDISPLAYWL) (EGLDisplay dpy, struct wl_display *display);
++typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYWAYLANDBUFFERWL) (EGLDisplay dpy, struct wl_resource *buffer, EGLint attribute, EGLint *value);
++
++#endif
++
++
+ #ifdef __cplusplus
+ }
+ #endif
+diff --git a/interface/khronos/wayland-egl/wayland-egl-priv.h b/interface/khronos/wayland-egl/wayland-egl-priv.h
+new file mode 100644
+index 0000000..8e38d36
+--- /dev/null
++++ b/interface/khronos/wayland-egl/wayland-egl-priv.h
+@@ -0,0 +1,53 @@
++/* Copied from Mesa */
++
++#ifndef _WAYLAND_EGL_PRIV_H
++#define _WAYLAND_EGL_PRIV_H
++
++#ifdef  __cplusplus
++extern "C" {
++#endif
++
++/* GCC visibility */
++#if defined(__GNUC__) && __GNUC__ >= 4
++#define WL_EGL_EXPORT __attribute__ ((visibility("default")))
++#else
++#define WL_EGL_EXPORT
++#endif
++
++#include "interface/vmcs_host/vc_dispmanx.h"
++#include "interface/khronos/egl/egl_client_surface.h"
++
++#include <wayland-client.h>
++
++struct wl_dispmanx_client_buffer {
++	struct wl_buffer *wl_buffer;
++	DISPMANX_RESOURCE_HANDLE_T resource;
++
++	int pending_allocation;
++	int in_use;
++	int width;
++	int height;
++};
++
++struct wl_egl_window {
++	struct wl_surface *wl_surface;
++
++	int width;
++	int height;
++	int dx;
++	int dy;
++
++	int attached_width;
++	int attached_height;
++
++	/* XXX: The VC side seems to expect a valid element handle to be
++	   passed to eglIntCreateSurface_impl and/or eglIntSwapBuffers_impl,
++	   even for host-managed surfaces. */
++	DISPMANX_ELEMENT_HANDLE_T dummy_element;
++};
++
++#ifdef  __cplusplus
++}
++#endif
++
++#endif
+diff --git a/interface/khronos/wayland-egl/wayland-egl.c b/interface/khronos/wayland-egl/wayland-egl.c
+new file mode 100644
+index 0000000..b8f050b
+--- /dev/null
++++ b/interface/khronos/wayland-egl/wayland-egl.c
+@@ -0,0 +1,59 @@
++/* Copied from Mesa */
++
++#include <stdlib.h>
++
++#include <wayland-client.h>
++#include <wayland-egl.h>
++#include "wayland-egl-priv.h"
++
++WL_EGL_EXPORT void
++wl_egl_window_resize(struct wl_egl_window *egl_window,
++		     int width, int height,
++		     int dx, int dy)
++{
++        if (egl_window->width == width &&
++	    egl_window->height == height &&
++	    egl_window->dx == dx &&
++	    egl_window->dy == dy)
++		return;
++
++	egl_window->width = width;
++	egl_window->height = height;
++	egl_window->dx = dx;
++	egl_window->dy = dy;
++}
++
++WL_EGL_EXPORT struct wl_egl_window *
++wl_egl_window_create(struct wl_surface *surface,
++		     int width, int height)
++{
++	struct wl_egl_window *egl_window;
++
++	egl_window = calloc(1, sizeof *egl_window);
++	if (!egl_window)
++		return NULL;
++
++	egl_window->wl_surface = surface;
++	wl_egl_window_resize(egl_window, width, height, 0, 0);
++	egl_window->attached_width  = 0;
++	egl_window->attached_height = 0;
++	egl_window->dummy_element = PLATFORM_WIN_NONE;
++
++	return egl_window;
++}
++
++WL_EGL_EXPORT void
++wl_egl_window_destroy(struct wl_egl_window *egl_window)
++{
++	free(egl_window);
++}
++
++WL_EGL_EXPORT void
++wl_egl_window_get_attached_size(struct wl_egl_window *egl_window,
++				int *width, int *height)
++{
++	if (width)
++		*width = egl_window->attached_width;
++	if (height)
++		*height = egl_window->attached_height;
++}
+diff --git a/interface/khronos/wayland-egl/wayland-egl.pc.in b/interface/khronos/wayland-egl/wayland-egl.pc.in
+new file mode 100644
+index 0000000..8bafc15
+--- /dev/null
++++ b/interface/khronos/wayland-egl/wayland-egl.pc.in
+@@ -0,0 +1,10 @@
++prefix=@CMAKE_INSTALL_PREFIX@
++exec_prefix=${prefix}
++libdir=${exec_prefix}/lib
++includedir=${prefix}/include
++
++Name: wayland-egl
++Description: VideoCore wayland-egl library
++Version: @PROJECT_APIVER@
++Libs: -L${libdir} -lwayland-egl
++Cflags: -I${includedir}
+diff --git a/interface/vmcs_host/CMakeLists.txt b/interface/vmcs_host/CMakeLists.txt
+index e0c6e13..35150ed 100755
+--- a/interface/vmcs_host/CMakeLists.txt
++++ b/interface/vmcs_host/CMakeLists.txt
+@@ -9,13 +9,24 @@ add_definitions(-fno-strict-aliasing)
+ 
+ include_directories(${VMCS_TARGET}/vcfiled)
+ 
+-add_library(vchostif
+-            ${VMCS_TARGET}/vcfilesys.c ${VMCS_TARGET}/vcmisc.c
+-            vc_vchi_gencmd.c vc_vchi_filesys.c
+-            vc_vchi_tvservice.c vc_vchi_cecservice.c
+-            vc_vchi_dispmanx.c vc_service_common.c)
++set(VCHOSTIF_SOURCE
++    ${VMCS_TARGET}/vcfilesys.c ${VMCS_TARGET}/vcmisc.c
++    vc_vchi_gencmd.c vc_vchi_filesys.c
++    vc_vchi_tvservice.c vc_vchi_cecservice.c
++    vc_vchi_dispmanx.c vc_service_common.c)
+ #            ${VMCS_TARGET}/vmcs_main.c
+ #  vc_vchi_haud.c
++
++if (BUILD_WAYLAND)
++wayland_add_protocol_server(
++    VCHOSTIF_SOURCE
++    ../../interface/wayland/dispmanx.xml
++    dispmanx
++)
++endif ()
++
++add_library(vchostif ${VCHOSTIF_SOURCE})
++
+ #add_library(bufman            vc_vchi_bufman.c            )
+ 
+ # OpenMAX/IL component service
+diff --git a/interface/vmcs_host/vc_dispmanx.h b/interface/vmcs_host/vc_dispmanx.h
+index 37fdae1..fe3619a 100755
+--- a/interface/vmcs_host/vc_dispmanx.h
++++ b/interface/vmcs_host/vc_dispmanx.h
+@@ -39,6 +39,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ #ifdef __cplusplus
+ extern "C" {
+ #endif
++
++#ifdef BUILD_WAYLAND
++struct wl_resource;
++#endif
++
+ // Same function as above, to aid migration of code.
+ VCHPRE_ int VCHPOST_ vc_dispman_init( void );
+ // Stop the service from being used
+@@ -135,6 +140,11 @@ VCHPRE_ int VCHPOST_ vc_dispmanx_resource_set_palette( DISPMANX_RESOURCE_HANDLE_
+ // Start triggering callbacks synced to vsync
+ VCHPRE_ int VCHPOST_ vc_dispmanx_vsync_callback( DISPMANX_DISPLAY_HANDLE_T display, DISPMANX_CALLBACK_FUNC_T cb_func, void *cb_arg );
+ 
++#ifdef BUILD_WAYLAND
++VCHPRE_ DISPMANX_RESOURCE_HANDLE_T VCHPOST_ vc_dispmanx_get_handle_from_wl_buffer( struct wl_resource *_buffer );
++
++VCHPRE_ void VCHPOST_ vc_dispmanx_set_wl_buffer_in_use( struct wl_resource *_buffer, int in_use );
++#endif
+ #ifdef __cplusplus
+ }
+ #endif
+diff --git a/interface/vmcs_host/vc_vchi_dispmanx.c b/interface/vmcs_host/vc_vchi_dispmanx.c
+index d188068..3e668f5 100755
+--- a/interface/vmcs_host/vc_vchi_dispmanx.c
++++ b/interface/vmcs_host/vc_vchi_dispmanx.c
+@@ -1316,3 +1316,45 @@ static void *dispmanx_notify_func( void *arg ) {
+    }
+    return 0;
+ }
++
++
++#ifdef BUILD_WAYLAND
++/***********************************************************
++ * Name: vc_dispmanx_get_handle_from_wl_buffer
++ *
++ * Arguments:
++ *       struct wl_resource *_buffer
++ *
++ * Description: Return the handle of the resource associated to this Wayland buffer
++ *
++ * Returns: A resource handle
++ *
++ ***********************************************************/
++VCHPRE_ DISPMANX_RESOURCE_HANDLE_T VCHPOST_ vc_dispmanx_get_handle_from_wl_buffer( struct wl_resource *_buffer )
++{
++	struct wl_dispmanx_server_buffer *buffer = (struct wl_dispmanx_server_buffer*)_buffer->data;
++	if (!buffer)
++		return DISPMANX_NO_HANDLE;
++
++	return buffer->handle;
++}
++
++/***********************************************************
++ * Name: vc_dispmanx_set_wl_buffer_in_use
++ *
++ * Arguments:
++ *       struct wl_resource *_buffer
++ *       int in_use
++ *
++ * Description: Mark this Wayland buffer as being in use by the compositor
++ *
++ ***********************************************************/
++VCHPRE_ void VCHPOST_ vc_dispmanx_set_wl_buffer_in_use( struct wl_resource *_buffer, int in_use )
++{
++	struct wl_dispmanx_server_buffer *buffer = (struct wl_dispmanx_server_buffer*)_buffer->data;
++	if (!buffer)
++		return;
++
++	buffer->in_use = in_use;
++}
++#endif
+diff --git a/interface/vmcs_host/vc_vchi_dispmanx.h b/interface/vmcs_host/vc_vchi_dispmanx.h
+index b723b76..f0bae30 100644
+--- a/interface/vmcs_host/vc_vchi_dispmanx.h
++++ b/interface/vmcs_host/vc_vchi_dispmanx.h
+@@ -66,4 +66,19 @@ typedef struct {
+ #define ELEMENT_CHANGE_MASK_RESOURCE  (1<<4)
+ #define ELEMENT_CHANGE_TRANSFORM      (1<<5)
+ 
++#ifdef BUILD_WAYLAND
++/* XXX: This should be in a private header that can be included from EGL and vc_* */
++#include <wayland-server.h>
++#include "interface/vmcs_host/wayland-dispmanx-server-protocol.h"
++struct wl_dispmanx_server_buffer {
++	struct wl_resource *resource;
++	struct wl_dispmanx *dispmanx;
++	enum wl_dispmanx_format format;
++	DISPMANX_RESOURCE_HANDLE_T handle;
++	int32_t width;
++	int32_t height;
++	int in_use;
++};
++#endif
++
+ #endif
+diff --git a/interface/wayland/dispmanx.xml b/interface/wayland/dispmanx.xml
+new file mode 100644
+index 0000000..c18626d
+--- /dev/null
++++ b/interface/wayland/dispmanx.xml
+@@ -0,0 +1,123 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<protocol name="dispmanx">
++
++  <copyright>
++    Copyright © 2008-2011 Kristian Høgsberg
++    Copyright © 2010-2011 Intel Corporation
++    Copyright © 2013 Raspberry Pi Foundation
++
++    Permission to use, copy, modify, distribute, and sell this
++    software and its documentation for any purpose is hereby granted
++    without fee, provided that\n 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.
++  </copyright>
++
++  <!-- DispManX support. This object is created by the server and published
++       using the display's global event. -->
++  <interface name="wl_dispmanx" version="1">
++    <enum name="error">
++      <entry name="alloc_failed" value="0"/>
++      <entry name="invalid_format" value="1"/>
++    </enum>
++
++    <enum name="format">
++      <!-- The pixel format codes match the #defines in drm_fourcc.h.
++           The formats actually supported by the compositor will be
++           reported by the format event. -->
++      <entry name="c8" value="0x20203843"/>
++      <entry name="rgb332" value="0x38424752"/>
++      <entry name="bgr233" value="0x38524742"/>
++      <entry name="xrgb4444" value="0x32315258"/>
++      <entry name="xbgr4444" value="0x32314258"/>
++      <entry name="rgbx4444" value="0x32315852"/>
++      <entry name="bgrx4444" value="0x32315842"/>
++      <entry name="argb4444" value="0x32315241"/>
++      <entry name="abgr4444" value="0x32314241"/>
++      <entry name="rgba4444" value="0x32314152"/>
++      <entry name="bgra4444" value="0x32314142"/>
++      <entry name="xrgb1555" value="0x35315258"/>
++      <entry name="xbgr1555" value="0x35314258"/>
++      <entry name="rgbx5551" value="0x35315852"/>
++      <entry name="bgrx5551" value="0x35315842"/>
++      <entry name="argb1555" value="0x35315241"/>
++      <entry name="abgr1555" value="0x35314241"/>
++      <entry name="rgba5551" value="0x35314152"/>
++      <entry name="bgra5551" value="0x35314142"/>
++      <entry name="rgb565" value="0x36314752"/>
++      <entry name="bgr565" value="0x36314742"/>
++      <entry name="rgb888" value="0x34324752"/>
++      <entry name="bgr888" value="0x34324742"/>
++      <entry name="xrgb8888" value="0x34325258"/>
++      <entry name="xbgr8888" value="0x34324258"/>
++      <entry name="rgbx8888" value="0x34325852"/>
++      <entry name="bgrx8888" value="0x34325842"/>
++      <entry name="argb8888" value="0x34325241"/>
++      <entry name="abgr8888" value="0x34324241"/>
++      <entry name="rgba8888" value="0x34324152"/>
++      <entry name="bgra8888" value="0x34324142"/>
++      <entry name="xrgb2101010" value="0x30335258"/>
++      <entry name="xbgr2101010" value="0x30334258"/>
++      <entry name="rgbx1010102" value="0x30335852"/>
++      <entry name="bgrx1010102" value="0x30335842"/>
++      <entry name="argb2101010" value="0x30335241"/>
++      <entry name="abgr2101010" value="0x30334241"/>
++      <entry name="rgba1010102" value="0x30334152"/>
++      <entry name="bgra1010102" value="0x30334142"/>
++      <entry name="yuyv" value="0x56595559"/>
++      <entry name="yvyu" value="0x55595659"/>
++      <entry name="uyvy" value="0x59565955"/>
++      <entry name="vyuy" value="0x59555956"/>
++      <entry name="ayuv" value="0x56555941"/>
++      <entry name="nv12" value="0x3231564e"/>
++      <entry name="nv21" value="0x3132564e"/>
++      <entry name="nv16" value="0x3631564e"/>
++      <entry name="nv61" value="0x3136564e"/>
++      <entry name="yuv410" value="0x39565559"/>
++      <entry name="yvu410" value="0x39555659"/>
++      <entry name="yuv411" value="0x31315559"/>
++      <entry name="yvu411" value="0x31315659"/>
++      <entry name="yuv420" value="0x32315559"/>
++      <entry name="yvu420" value="0x32315659"/>
++      <entry name="yuv422" value="0x36315559"/>
++      <entry name="yvu422" value="0x36315659"/>
++      <entry name="yuv444" value="0x34325559"/>
++      <entry name="yvu444" value="0x34325659"/>
++    </enum>
++
++    <event name="format">
++      <arg name="format" type="uint"/>
++    </event>
++
++    <!-- Create a wayland buffer for the DispManX resource. -->
++    <request name="create_buffer">
++      <arg name="id" type="new_id" interface="wl_buffer"/>
++      <arg name="width" type="int"/>
++      <arg name="height" type="int"/>
++      <arg name="stride" type="uint"/>
++      <arg name="buffer_height" type="uint"/>
++      <arg name="format" type="uint"/>
++    </request>
++
++    <event name="buffer_allocated">
++      <arg name="buffer" type="object" interface="wl_buffer"/>
++      <arg name="handle" type="uint"/>
++    </event>
++  </interface>
++
++</protocol>
+diff --git a/makefiles/cmake/Wayland.cmake b/makefiles/cmake/Wayland.cmake
+new file mode 100644
+index 0000000..ad90d30
+--- /dev/null
++++ b/makefiles/cmake/Wayland.cmake
+@@ -0,0 +1,72 @@
++#=============================================================================
++# Copyright (C) 2012-2013 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
++# All rights reserved.
++#
++# Redistribution and use in source and binary forms, with or without
++# modification, are permitted provided that the following conditions
++# are met:
++#
++# * Redistributions of source code must retain the above copyright
++#   notice, this list of conditions and the following disclaimer.
++#
++# * Redistributions in binary form must reproduce the above copyright
++#   notice, this list of conditions and the following disclaimer in the
++#   documentation and/or other materials provided with the distribution.
++#
++# * Neither the name of Pier Luigi Fiorini nor the names of his
++#   contributors may be used to endorse or promote products derived
++#   from this software without specific prior written permission.
++#
++# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
++# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
++# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
++# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
++# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
++# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
++# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
++# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
++# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
++# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++#=============================================================================
++
++find_program(WAYLAND_SCANNER_EXECUTABLE NAMES wayland-scanner)
++
++# wayland_add_protocol_client(outfiles inputfile basename)
++function(WAYLAND_ADD_PROTOCOL_CLIENT _sources _protocol _basename)
++    if(NOT WAYLAND_SCANNER_EXECUTABLE)
++        message(FATAL "The wayland-scanner executable has nto been found on your system. You must install it.")
++    endif()
++
++    get_filename_component(_infile ${_protocol} ABSOLUTE)
++    set(_client_header "${CMAKE_CURRENT_BINARY_DIR}/wayland-${_basename}-client-protocol.h")
++    set(_code "${CMAKE_CURRENT_BINARY_DIR}/wayland-${_basename}-protocol.c")
++
++    add_custom_command(OUTPUT "${_client_header}"
++        COMMAND ${WAYLAND_SCANNER_EXECUTABLE} client-header < ${_infile} > ${_client_header}
++        DEPENDS ${_infile} VERBATIM)
++
++    add_custom_command(OUTPUT "${_code}"
++        COMMAND ${WAYLAND_SCANNER_EXECUTABLE} code < ${_infile} > ${_code}
++        DEPENDS ${_infile} VERBATIM)
++
++    list(APPEND ${_sources} "${_client_header}" "${_code}")
++    set(${_sources} ${${_sources}} PARENT_SCOPE)
++endfunction()
++
++# wayland_add_protocol_server(outfiles inputfile basename)
++function(WAYLAND_ADD_PROTOCOL_SERVER _sources _protocol _basename)
++    if(NOT WAYLAND_SCANNER_EXECUTABLE)
++        message(FATAL "The wayland-scanner executable has nto been found on your system. You must install it.")
++    endif()
++
++    get_filename_component(_infile ${_protocol} ABSOLUTE)
++    set(_server_header "${CMAKE_CURRENT_BINARY_DIR}/wayland-${_basename}-server-protocol.h")
++
++    add_custom_command(OUTPUT "${_server_header}"
++        COMMAND ${WAYLAND_SCANNER_EXECUTABLE} server-header < ${_infile} > ${_server_header}
++        DEPENDS ${_infile} VERBATIM)
++
++    list(APPEND ${_sources} "${_server_header}")
++    set(${_sources} ${${_sources}} PARENT_SCOPE)
++endfunction()
+-- 
+2.9.0
+
diff --git a/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0003-wayland-Add-Wayland-example.patch b/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0003-wayland-Add-Wayland-example.patch
new file mode 100644
index 0000000..11befc3
--- /dev/null
+++ b/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0003-wayland-Add-Wayland-example.patch
Binary files differ
diff --git a/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0004-wayland-egl-Add-bcm_host-to-dependencies.patch b/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0004-wayland-egl-Add-bcm_host-to-dependencies.patch
new file mode 100644
index 0000000..2a44e26
--- /dev/null
+++ b/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0004-wayland-egl-Add-bcm_host-to-dependencies.patch
@@ -0,0 +1,28 @@
+From e3df3fec01aefac3ec301f6f3d5ec3e91652b9c5 Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Mon, 10 Aug 2015 02:38:27 -0700
+Subject: [PATCH 04/13] wayland-egl: Add bcm_host to dependencies
+
+It uses headers like vcos_platform_types.h but does not
+depend on module which should add the required include paths
+lets add the dependency on bcm_host module which should do it
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+---
+ interface/khronos/wayland-egl/wayland-egl.pc.in | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/interface/khronos/wayland-egl/wayland-egl.pc.in b/interface/khronos/wayland-egl/wayland-egl.pc.in
+index 8bafc15..fd259c9 100644
+--- a/interface/khronos/wayland-egl/wayland-egl.pc.in
++++ b/interface/khronos/wayland-egl/wayland-egl.pc.in
+@@ -6,5 +6,6 @@ includedir=${prefix}/include
+ Name: wayland-egl
+ Description: VideoCore wayland-egl library
+ Version: @PROJECT_APIVER@
++Requires: bcm_host
+ Libs: -L${libdir} -lwayland-egl
+ Cflags: -I${includedir}
+-- 
+2.9.0
+
diff --git a/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0005-interface-remove-faulty-assert-to-make-weston-happy-.patch b/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0005-interface-remove-faulty-assert-to-make-weston-happy-.patch
new file mode 100644
index 0000000..6f41932
--- /dev/null
+++ b/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0005-interface-remove-faulty-assert-to-make-weston-happy-.patch
@@ -0,0 +1,29 @@
+From 6c9d407c9ec0859380e7bcf35cf915cef4b3687b Mon Sep 17 00:00:00 2001
+From: "Yann E. MORIN" <yann.morin.1998@free.fr>
+Date: Sat, 24 Jan 2015 22:07:19 +0100
+Subject: [PATCH 05/13] interface: remove faulty assert() to make weston happy
+ at runtime
+
+This was removed after a discussion on IRC with the weston guys
+('daniels' on irc.freenode.net/#wayland).
+
+Signed-off-by: "Yann E. MORIN" <yann.morin.1998@free.fr>
+---
+ interface/vmcs_host/vc_vchi_dispmanx.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/interface/vmcs_host/vc_vchi_dispmanx.c b/interface/vmcs_host/vc_vchi_dispmanx.c
+index 3e668f5..8e065dc 100755
+--- a/interface/vmcs_host/vc_vchi_dispmanx.c
++++ b/interface/vmcs_host/vc_vchi_dispmanx.c
+@@ -1304,7 +1304,6 @@ static void *dispmanx_notify_func( void *arg ) {
+          // Decrement the use count - the corresponding "use" is in vc_dispmanx_update_submit.
+          vchi_service_release(dispmanx_client.notify_handle[0]);
+          if (dispmanx_client.update_callback ) {
+-            vcos_assert( dispmanx_client.pending_update_handle == handle);
+             dispmanx_client.update_callback(handle, dispmanx_client.update_callback_param);
+          }
+       } else {
+-- 
+2.9.0
+
diff --git a/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0006-zero-out-wl-buffers-in-egl_surface_free.patch b/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0006-zero-out-wl-buffers-in-egl_surface_free.patch
new file mode 100644
index 0000000..2d52266
--- /dev/null
+++ b/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0006-zero-out-wl-buffers-in-egl_surface_free.patch
@@ -0,0 +1,33 @@
+From e3ffe9438fe8417586d0045d00eb1368ca3a71b6 Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Sat, 6 Feb 2016 11:10:47 -0800
+Subject: [PATCH 06/13] zero-out wl buffers in egl_surface_free
+
+origins from buildroot
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+---
+ interface/khronos/egl/egl_client_surface.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/interface/khronos/egl/egl_client_surface.c b/interface/khronos/egl/egl_client_surface.c
+index 49cf7e5..512c83b 100644
+--- a/interface/khronos/egl/egl_client_surface.c
++++ b/interface/khronos/egl/egl_client_surface.c
+@@ -690,11 +690,13 @@ void egl_surface_free(EGL_SURFACE_T *surface)
+       if (surface->back_wl_buffer) {
+          wl_buffer_destroy(surface->back_wl_buffer->wl_buffer);
+          free(surface->back_wl_buffer);
++         surface->back_wl_buffer = 0;
+       }
+ 
+       if (surface->front_wl_buffer) {
+          wl_buffer_destroy(surface->front_wl_buffer->wl_buffer);
+          free(surface->front_wl_buffer);
++         surface->front_wl_buffer = 0;
+       }
+ #endif
+    }
+-- 
+2.9.0
+
diff --git a/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0007-initialize-front-back-wayland-buffers.patch b/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0007-initialize-front-back-wayland-buffers.patch
new file mode 100644
index 0000000..f54f77d
--- /dev/null
+++ b/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0007-initialize-front-back-wayland-buffers.patch
@@ -0,0 +1,34 @@
+From ed31a6a206c9e205bd5316e95788e5d7bb837e38 Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Sat, 6 Feb 2016 11:11:41 -0800
+Subject: [PATCH 07/13] initialize front back wayland buffers
+
+origins from metrological wayland support
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+---
+ interface/khronos/egl/egl_client_surface.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/interface/khronos/egl/egl_client_surface.c b/interface/khronos/egl/egl_client_surface.c
+index 512c83b..a429724 100644
+--- a/interface/khronos/egl/egl_client_surface.c
++++ b/interface/khronos/egl/egl_client_surface.c
+@@ -401,11 +401,14 @@ EGL_SURFACE_T *egl_surface_create(
+ #ifdef BUILD_WAYLAND
+    if (type == WINDOW && wl_display) {
+       surface->wl_egl_window = (struct wl_egl_window*)win;
++      surface->front_wl_buffer = NULL;
+       surface->back_wl_buffer = allocate_wl_buffer(
+             surface->wl_egl_window, color);
+       resource = surface->back_wl_buffer->resource;
+    } else {
+       surface->wl_egl_window = NULL;
++      surface->front_wl_buffer = NULL;
++      surface->back_wl_buffer = NULL;
+       resource = DISPMANX_NO_HANDLE;
+    }
+ #endif
+-- 
+2.9.0
+
diff --git a/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0008-Remove-RPC_FLUSH.patch b/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0008-Remove-RPC_FLUSH.patch
new file mode 100644
index 0000000..0206a08
--- /dev/null
+++ b/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0008-Remove-RPC_FLUSH.patch
@@ -0,0 +1,27 @@
+From 6e173040a825185013ccbbb33113442207f10eeb Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Sat, 6 Feb 2016 11:09:18 -0800
+Subject: [PATCH 08/13] Remove RPC_FLUSH
+
+Origins from buildroot
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+---
+ interface/khronos/ext/gl_oes_egl_image_client.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/interface/khronos/ext/gl_oes_egl_image_client.c b/interface/khronos/ext/gl_oes_egl_image_client.c
+index f9b7287..b04ffef 100644
+--- a/interface/khronos/ext/gl_oes_egl_image_client.c
++++ b/interface/khronos/ext/gl_oes_egl_image_client.c
+@@ -107,7 +107,6 @@ GL_API void GL_APIENTRY glEGLImageTargetTexture2DOES (GLenum target, GLeglImageO
+                    GLEGLIMAGETARGETTEXTURE2DOES_ID,
+                    RPC_ENUM(target),
+                    RPC_EGLID(image));
+-         RPC_FLUSH(thread);
+ #if EGL_BRCM_global_image
+       }
+ #endif
+-- 
+2.9.0
+
diff --git a/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0009-fix-cmake-dependency-race.patch b/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0009-fix-cmake-dependency-race.patch
new file mode 100644
index 0000000..87cfce4
--- /dev/null
+++ b/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0009-fix-cmake-dependency-race.patch
@@ -0,0 +1,78 @@
+From c4217231fd78daee83b0c0f312c1d392aa6e0f47 Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Sat, 6 Feb 2016 13:12:47 -0800
+Subject: [PATCH 09/13] fix cmake dependency race
+
+Fixes errors like
+
+/a/builder/mnt/build-oe/tmp-glibc/work/raspberrypi2-oe-linux-gnueabi/userland/git-r5/git/interface/vmcs_host/vc_vchi_dispmanx.h:72:66:
+fatal error: interface/vmcs_host/wayland-dispmanx-server-protocol.h: No
+such file or directory
+compilation terminated.
+interface/khronos/CMakeFiles/EGL_static.dir/build.make:773: recipe for
+target 'interface/khronos/CMakeFiles/EGL_static.dir/ext/egl_wayland.c.o'
+failed
+make[2]: ***
+[interface/khronos/CMakeFiles/EGL_static.dir/ext/egl_wayland.c.o] Error 1
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+---
+ interface/vcos/pthreads/CMakeLists.txt | 8 ++++++++
+ interface/vmcs_host/CMakeLists.txt     | 8 --------
+ interface/vmcs_host/vc_vchi_dispmanx.h | 2 +-
+ 3 files changed, 9 insertions(+), 9 deletions(-)
+
+diff --git a/interface/vcos/pthreads/CMakeLists.txt b/interface/vcos/pthreads/CMakeLists.txt
+index 1d81ca3..d6cd415 100644
+--- a/interface/vcos/pthreads/CMakeLists.txt
++++ b/interface/vcos/pthreads/CMakeLists.txt
+@@ -33,6 +33,14 @@ set (SOURCES
+    ../generic/vcos_generic_blockpool.c
+ )
+ 
++if (BUILD_WAYLAND)
++wayland_add_protocol_server(
++    SOURCES
++    ../../../interface/wayland/dispmanx.xml
++    dispmanx
++)
++endif ()
++
+ if (VCOS_PTHREADS_BUILD_SHARED)
+    add_library (vcos SHARED ${SOURCES})
+    target_link_libraries (vcos pthread dl rt)
+diff --git a/interface/vmcs_host/CMakeLists.txt b/interface/vmcs_host/CMakeLists.txt
+index 35150ed..22949a8 100755
+--- a/interface/vmcs_host/CMakeLists.txt
++++ b/interface/vmcs_host/CMakeLists.txt
+@@ -17,14 +17,6 @@ set(VCHOSTIF_SOURCE
+ #            ${VMCS_TARGET}/vmcs_main.c
+ #  vc_vchi_haud.c
+ 
+-if (BUILD_WAYLAND)
+-wayland_add_protocol_server(
+-    VCHOSTIF_SOURCE
+-    ../../interface/wayland/dispmanx.xml
+-    dispmanx
+-)
+-endif ()
+-
+ add_library(vchostif ${VCHOSTIF_SOURCE})
+ 
+ #add_library(bufman            vc_vchi_bufman.c            )
+diff --git a/interface/vmcs_host/vc_vchi_dispmanx.h b/interface/vmcs_host/vc_vchi_dispmanx.h
+index f0bae30..8c44c58 100644
+--- a/interface/vmcs_host/vc_vchi_dispmanx.h
++++ b/interface/vmcs_host/vc_vchi_dispmanx.h
+@@ -69,7 +69,7 @@ typedef struct {
+ #ifdef BUILD_WAYLAND
+ /* XXX: This should be in a private header that can be included from EGL and vc_* */
+ #include <wayland-server.h>
+-#include "interface/vmcs_host/wayland-dispmanx-server-protocol.h"
++#include "interface/vcos/pthreads/wayland-dispmanx-server-protocol.h"
+ struct wl_dispmanx_server_buffer {
+ 	struct wl_resource *resource;
+ 	struct wl_dispmanx *dispmanx;
+-- 
+2.9.0
+
diff --git a/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0010-Fix-enum-conversion-warnings.patch b/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0010-Fix-enum-conversion-warnings.patch
new file mode 100644
index 0000000..d4e8825
--- /dev/null
+++ b/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0010-Fix-enum-conversion-warnings.patch
@@ -0,0 +1,99 @@
+From 377f6aada3b7569e3d662fc830e01b8c5ba8a15d Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Thu, 18 Feb 2016 09:04:46 +0000
+Subject: [PATCH 10/13] Fix enum conversion warnings
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+---
+ interface/mmal/openmaxil/mmalomx_core.c              | 4 ++--
+ interface/mmal/openmaxil/mmalomx_parameters.c        | 6 +++---
+ interface/mmal/openmaxil/mmalomx_util_params_video.c | 8 ++++----
+ 3 files changed, 9 insertions(+), 9 deletions(-)
+
+diff --git a/interface/mmal/openmaxil/mmalomx_core.c b/interface/mmal/openmaxil/mmalomx_core.c
+index 9bc632b..20d4fc7 100644
+--- a/interface/mmal/openmaxil/mmalomx_core.c
++++ b/interface/mmal/openmaxil/mmalomx_core.c
+@@ -281,7 +281,7 @@ static OMX_ERRORTYPE mmalomx_ComponentGetParameter(
+       {
+          OMX_PARAM_PORTDEFINITIONTYPE *param = (OMX_PARAM_PORTDEFINITIONTYPE *)pParam;
+          PARAM_GET_PORT(port, component, param->nPortIndex);
+-         return mmalil_error_to_mmal(mmalomx_get_port_settings(port, param));
++         return mmalil_error_to_omx(mmalomx_get_port_settings(port, param));
+       }
+       return OMX_ErrorNone;
+       break;
+@@ -475,7 +475,7 @@ static OMX_ERRORTYPE mmalomx_ComponentSetParameter(
+       {
+          OMX_PARAM_PORTDEFINITIONTYPE *param = (OMX_PARAM_PORTDEFINITIONTYPE *)pParam;
+          PARAM_GET_PORT(port, component, param->nPortIndex);
+-         return mmalil_error_to_mmal(mmalomx_set_port_settings(port, param));
++         return mmalil_error_to_omx(mmalomx_set_port_settings(port, param));
+       }
+       return OMX_ErrorNone;
+       break;
+diff --git a/interface/mmal/openmaxil/mmalomx_parameters.c b/interface/mmal/openmaxil/mmalomx_parameters.c
+index a20a5bd..c4f97d4 100644
+--- a/interface/mmal/openmaxil/mmalomx_parameters.c
++++ b/interface/mmal/openmaxil/mmalomx_parameters.c
+@@ -170,7 +170,7 @@ static OMX_ERRORTYPE mmalomx_parameter_get_xlat(MMALOMX_COMPONENT_T *component,
+ 
+    if (xlat->fn.custom)
+    {
+-      return mmalil_error_to_mmal(xlat->fn.custom(MMALOMX_PARAM_MAPPING_TO_OMX, xlat, mmal_header,
++      return mmalil_error_to_omx(xlat->fn.custom(MMALOMX_PARAM_MAPPING_TO_OMX, xlat, mmal_header,
+          pParam, mmal_port));
+    }
+ 
+@@ -554,14 +554,14 @@ OMX_ERRORTYPE mmalomx_parameter_set(MMALOMX_COMPONENT_T *component,
+          port->mmal->format->es->video.par.num = param->nX;
+          port->mmal->format->es->video.par.den = param->nY;
+          mmal_rational_simplify(&port->mmal->format->es->video.par);
+-         return mmalil_error_to_mmal(mmal_port_format_commit(port->mmal));
++         return mmalil_error_to_omx(mmal_port_format_commit(port->mmal));
+       }
+    case OMX_IndexParamColorSpace:
+       {
+          OMX_PARAM_COLORSPACETYPE *param = (OMX_PARAM_COLORSPACETYPE *)pParam;
+          PARAM_GET_PORT(port, component, param->nPortIndex);
+          port->mmal->format->es->video.color_space = mmalil_omx_color_space_to_mmal(param->eColorSpace);
+-         return mmalil_error_to_mmal(mmal_port_format_commit(port->mmal));
++         return mmalil_error_to_omx(mmal_port_format_commit(port->mmal));
+       }
+    case OMX_IndexParamBrcmVideoCroppingDisable:
+       {
+diff --git a/interface/mmal/openmaxil/mmalomx_util_params_video.c b/interface/mmal/openmaxil/mmalomx_util_params_video.c
+index f088296..83e3724 100644
+--- a/interface/mmal/openmaxil/mmalomx_util_params_video.c
++++ b/interface/mmal/openmaxil/mmalomx_util_params_video.c
+@@ -56,11 +56,11 @@ static MMAL_STATUS_T mmalomx_param_mapping_displayregion(MMALOMX_PARAM_MAPPING_D
+       mmal->set = omx->set;
+       mmal->display_num = omx->num;
+       mmal->fullscreen = omx->fullscreen;
+-      mmal->transform = omx->transform;
++      mmal->transform = (MMAL_DISPLAYTRANSFORM_T)omx->transform;
+       rect_to_mmal(&mmal->dest_rect, &omx->dest_rect);
+       rect_to_mmal(&mmal->src_rect, &omx->src_rect);
+       mmal->noaspect = omx->noaspect;
+-      mmal->mode = omx->mode;
++      mmal->mode = (MMAL_DISPLAYMODE_T)omx->mode;
+       mmal->pixel_x = omx->pixel_x;
+       mmal->pixel_y = omx->pixel_y;
+       mmal->layer = omx->layer;
+@@ -72,11 +72,11 @@ static MMAL_STATUS_T mmalomx_param_mapping_displayregion(MMALOMX_PARAM_MAPPING_D
+       omx->set        = mmal->set;
+       omx->num        = mmal->display_num;
+       omx->fullscreen = mmal->fullscreen;
+-      omx->transform  = mmal->transform;
++      omx->transform  = (OMX_DISPLAYTRANSFORMTYPE)mmal->transform;
+       rect_to_omx(&omx->dest_rect, &mmal->dest_rect);
+       rect_to_omx(&omx->src_rect, &mmal->src_rect);
+       omx->noaspect   = mmal->noaspect;
+-      omx->mode       = mmal->mode;
++      omx->mode       = (OMX_DISPLAYMODETYPE)mmal->mode;
+       omx->pixel_x    = mmal->pixel_x;
+       omx->pixel_y    = mmal->pixel_y;
+       omx->layer      = mmal->layer;
+-- 
+2.9.0
+
diff --git a/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0011-Fix-for-framerate-with-nested-composition.patch b/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0011-Fix-for-framerate-with-nested-composition.patch
new file mode 100644
index 0000000..5e97571
--- /dev/null
+++ b/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0011-Fix-for-framerate-with-nested-composition.patch
@@ -0,0 +1,60 @@
+From 6e634184ee4b3d2c98c3213a3931845ec3014754 Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Tue, 29 Mar 2016 20:38:30 -0700
+Subject: [PATCH 11/13] Fix for framerate with nested composition
+
+frame rate appears irregular and lower than expected when using nested composition.
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+---
+ interface/khronos/egl/egl_client.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/interface/khronos/egl/egl_client.c b/interface/khronos/egl/egl_client.c
+index 024f3ed..83970ec 100644
+--- a/interface/khronos/egl/egl_client.c
++++ b/interface/khronos/egl/egl_client.c
+@@ -2342,6 +2342,9 @@ EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers(EGLDisplay dpy, EGLSurface surf)
+                      surface->back_wl_buffer = buffer;
+                   }
+ 
++                  glFlush();
++                  glFinish();
++
+                   RPC_CALL7(eglIntSwapBuffers_impl,
+                         thread,
+                         EGLINTSWAPBUFFERS_ID_V2,
+@@ -2353,6 +2356,8 @@ EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers(EGLDisplay dpy, EGLSurface surf)
+                         RPC_UINT(khrn_platform_get_window_position(surface->win)),
+                         RPC_INT(surface->back_wl_buffer->resource));
+ 
++                  RPC_FLUSH(thread);
++
+                   surface->front_wl_buffer->in_use = 1;
+                   wl_surface_attach(wl_egl_window->wl_surface,
+                                     surface->front_wl_buffer->wl_buffer,
+@@ -2360,11 +2365,13 @@ EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers(EGLDisplay dpy, EGLSurface surf)
+                   wl_surface_damage(wl_egl_window->wl_surface, 0, 0,
+                                     surface->width, surface->height);
+                   wl_surface_commit(wl_egl_window->wl_surface);
++                  wl_display_flush(wl_display);
+ 
+                   while(ret != -1 && surface->back_wl_buffer->in_use)
+                      ret = wl_display_dispatch_queue(wl_display, process->wl_queue);
+                } else
+ #endif
++               {
+                RPC_CALL6(eglIntSwapBuffers_impl,
+                      thread,
+                      EGLINTSWAPBUFFERS_ID,
+@@ -2376,6 +2383,7 @@ EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers(EGLDisplay dpy, EGLSurface surf)
+                      RPC_UINT(khrn_platform_get_window_position(surface->win)));
+ 
+                RPC_FLUSH(thread);
++               }
+ 
+ #ifdef ANDROID
+                CLIENT_UNLOCK();
+-- 
+2.9.0
+
diff --git a/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0012-build-shared-library-for-vchostif.patch b/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0012-build-shared-library-for-vchostif.patch
new file mode 100644
index 0000000..44815c5
--- /dev/null
+++ b/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0012-build-shared-library-for-vchostif.patch
@@ -0,0 +1,28 @@
+From 559209ce15027b3370466ccb56223a7a66d2a40c Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Sat, 2 Apr 2016 10:37:24 -0700
+Subject: [PATCH 12/13] build shared library for vchostif
+
+Fixes #149
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+---
+ interface/vmcs_host/CMakeLists.txt | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/interface/vmcs_host/CMakeLists.txt b/interface/vmcs_host/CMakeLists.txt
+index 22949a8..f8c2f2f 100755
+--- a/interface/vmcs_host/CMakeLists.txt
++++ b/interface/vmcs_host/CMakeLists.txt
+@@ -17,7 +17,7 @@ set(VCHOSTIF_SOURCE
+ #            ${VMCS_TARGET}/vmcs_main.c
+ #  vc_vchi_haud.c
+ 
+-add_library(vchostif ${VCHOSTIF_SOURCE})
++add_library(vchostif SHARED ${VCHOSTIF_SOURCE})
+ 
+ #add_library(bufman            vc_vchi_bufman.c            )
+ 
+-- 
+2.9.0
+
diff --git a/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0013-implement-buffer-wrapping-interface-for-dispmanx.patch b/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0013-implement-buffer-wrapping-interface-for-dispmanx.patch
new file mode 100644
index 0000000..8f36048
--- /dev/null
+++ b/import-layers/meta-raspberrypi/recipes-graphics/userland/userland/0013-implement-buffer-wrapping-interface-for-dispmanx.patch
@@ -0,0 +1,92 @@
+From 5b55a152651eece345d9ea1e0e40ecd9fc4ca2d5 Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Sat, 2 Apr 2016 10:54:59 -0700
+Subject: [PATCH 13/13] implement buffer wrapping interface for dispmanx
+
+Courtesy: Zan Dobersek
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+---
+ interface/khronos/ext/egl_wayland.c | 42 +++++++++++++++++++++++++++++++++++++
+ interface/wayland/dispmanx.xml      | 10 +++++++++
+ 2 files changed, 52 insertions(+)
+
+diff --git a/interface/khronos/ext/egl_wayland.c b/interface/khronos/ext/egl_wayland.c
+index 5730743..9ef89cd 100644
+--- a/interface/khronos/ext/egl_wayland.c
++++ b/interface/khronos/ext/egl_wayland.c
+@@ -133,8 +133,50 @@ dispmanx_create_buffer(struct wl_client *client, struct wl_resource *resource,
+                                      buffer->handle);
+ }
+ 
++static void
++dispmanx_wrap_buffer(struct wl_client *client, struct wl_resource *resource,
++                     uint32_t id, uint32_t handle, int32_t width, int32_t height,
++                     uint32_t stride, uint32_t buffer_height, uint32_t format)
++{
++   struct wl_dispmanx_server_buffer *buffer;
++   VC_IMAGE_TYPE_T vc_format = get_vc_format(format);
++   uint32_t dummy;
++
++   if(vc_format == VC_IMAGE_MIN) {
++      wl_resource_post_error(resource,
++                             WL_DISPMANX_ERROR_INVALID_FORMAT,
++                             "invalid format");
++      return;
++   }
++
++   buffer = calloc(1, sizeof *buffer);
++   if (buffer == NULL) {
++      wl_resource_post_no_memory(resource);
++      return;
++   }
++
++   buffer->handle = handle;
++   buffer->width = width;
++   buffer->height = height;
++   buffer->format = format;
++
++   buffer->resource = wl_resource_create(resource->client, &wl_buffer_interface,
++                                         1, id);
++   if (!buffer->resource) {
++      wl_resource_post_no_memory(resource);
++      vc_dispmanx_resource_delete(buffer->handle);
++      free(buffer);
++      return;
++   }
++
++   wl_resource_set_implementation(buffer->resource,
++				       (void (**)(void)) &dispmanx_buffer_interface,
++				       buffer, destroy_buffer);
++}
++
+ static const struct wl_dispmanx_interface dispmanx_interface = {
+    dispmanx_create_buffer,
++   dispmanx_wrap_buffer,
+ };
+ 
+ static void
+diff --git a/interface/wayland/dispmanx.xml b/interface/wayland/dispmanx.xml
+index c18626d..11ed1ef 100644
+--- a/interface/wayland/dispmanx.xml
++++ b/interface/wayland/dispmanx.xml
+@@ -118,6 +118,16 @@
+       <arg name="buffer" type="object" interface="wl_buffer"/>
+       <arg name="handle" type="uint"/>
+     </event>
++
++    <request name="wrap_buffer">
++      <arg name="id" type="new_id" interface="wl_buffer"/>
++      <arg name="handle" type="uint"/>
++      <arg name="width" type="int"/>
++      <arg name="height" type="int"/>
++      <arg name="stride" type="uint"/>
++      <arg name="buffer_height" type="uint"/>
++      <arg name="format" type="uint"/>
++    </request>
+   </interface>
+ 
+ </protocol>
+-- 
+2.9.0
+
diff --git a/import-layers/meta-raspberrypi/recipes-graphics/userland/userland_git.bb b/import-layers/meta-raspberrypi/recipes-graphics/userland/userland_git.bb
new file mode 100644
index 0000000..6e73ca7
--- /dev/null
+++ b/import-layers/meta-raspberrypi/recipes-graphics/userland/userland_git.bb
@@ -0,0 +1,73 @@
+DESCRIPTION = "This repository contains the source code for the ARM side \
+libraries used on Raspberry Pi. These typically are installed in /opt/vc/lib \
+and includes source for the ARM side code to interface to: EGL, mmal, GLESv2,\
+vcos, openmaxil, vchiq_arm, bcm_host, WFC, OpenVG."
+LICENSE = "BSD-3-Clause"
+LIC_FILES_CHKSUM = "file://LICENCE;md5=0448d6488ef8cc380632b1569ee6d196"
+
+PR = "r5"
+
+PROVIDES = "virtual/libgles2 \
+            virtual/egl"
+
+RPROVIDES_${PN} += "libgles2 libgl"
+
+COMPATIBLE_MACHINE = "raspberrypi"
+
+SRCBRANCH = "master"
+SRCFORK = "raspberrypi"
+SRCREV = "0147f98bdd4fdc822d25d8a70cf5adc5adb89096"
+
+SRC_URI = "\
+    git://github.com/${SRCFORK}/userland.git;protocol=git;branch=${SRCBRANCH} \
+    file://0001-Allow-applications-to-set-next-resource-handle.patch \
+    file://0002-wayland-Add-support-for-the-Wayland-winsys.patch \
+    file://0003-wayland-Add-Wayland-example.patch \
+    file://0004-wayland-egl-Add-bcm_host-to-dependencies.patch \
+    file://0005-interface-remove-faulty-assert-to-make-weston-happy-.patch \
+    file://0006-zero-out-wl-buffers-in-egl_surface_free.patch \
+    file://0007-initialize-front-back-wayland-buffers.patch \
+    file://0008-Remove-RPC_FLUSH.patch \
+    file://0009-fix-cmake-dependency-race.patch \
+    file://0010-Fix-enum-conversion-warnings.patch \
+    file://0011-Fix-for-framerate-with-nested-composition.patch \
+    file://0012-build-shared-library-for-vchostif.patch \
+    file://0013-implement-buffer-wrapping-interface-for-dispmanx.patch \
+"
+S = "${WORKDIR}/git"
+
+inherit cmake pkgconfig
+
+EXTRA_OECMAKE = "-DCMAKE_BUILD_TYPE=Release -DCMAKE_EXE_LINKER_FLAGS='-Wl,--no-as-needed' \
+                 -DVMCS_INSTALL_PREFIX=${exec_prefix} \
+"
+
+PACKAGECONFIG ?= "${@bb.utils.contains('DISTRO_FEATURES', 'wayland', 'wayland', '', d)}"
+
+PACKAGECONFIG[wayland] = "-DBUILD_WAYLAND=TRUE -DWAYLAND_SCANNER_EXECUTABLE:FILEPATH=${STAGING_BINDIR_NATIVE}/wayland-scanner,,wayland-native wayland"
+
+CFLAGS_append = " -fPIC"
+
+do_install_append () {
+	for f in `find ${D}${includedir}/interface/vcos/ -name "*.h"`; do
+		sed -i 's/include "vcos_platform.h"/include "pthreads\/vcos_platform.h"/g' ${f}
+		sed -i 's/include "vcos_futex_mutex.h"/include "pthreads\/vcos_futex_mutex.h"/g' ${f}
+		sed -i 's/include "vcos_platform_types.h"/include "pthreads\/vcos_platform_types.h"/g' ${f}
+	done
+}
+
+# Shared libs from userland package  build aren't versioned, so we need
+# to force the .so files into the runtime package (and keep them
+# out of -dev package).
+FILES_SOLIBSDEV = ""
+INSANE_SKIP_${PN} += "dev-so"
+
+FILES_${PN} += " \
+    ${libdir}/*.so \
+    ${libdir}/plugins"
+FILES_${PN}-dev += "${includedir} \
+                   ${prefix}/src"
+FILES_${PN}-doc += "${datadir}/install"
+FILES_${PN}-dbg += "${libdir}/plugins/.debug"
+
+PACKAGE_ARCH = "${MACHINE_ARCH}"
diff --git a/import-layers/meta-raspberrypi/recipes-graphics/vc-graphics/files/egl.pc b/import-layers/meta-raspberrypi/recipes-graphics/vc-graphics/files/egl.pc
new file mode 100644
index 0000000..c314202
--- /dev/null
+++ b/import-layers/meta-raspberrypi/recipes-graphics/vc-graphics/files/egl.pc
@@ -0,0 +1,10 @@
+prefix=/usr
+exec_prefix=${prefix}
+libdir=${exec_prefix}/lib
+includedir=${prefix}/include
+
+Name: egl
+Description: egl for RaspberryPI
+Version: 0.0
+Libs: -L${libdir} -lEGL -lGLESv2
+Cflags: -I${includedir}/vc -I${includedir}/interface -I${includedir}/interface/vcos -I${includedir}/interface/vcos/pthreads
diff --git a/import-layers/meta-raspberrypi/recipes-graphics/vc-graphics/files/vchiq.sh b/import-layers/meta-raspberrypi/recipes-graphics/vc-graphics/files/vchiq.sh
new file mode 100644
index 0000000..c73e3a9
--- /dev/null
+++ b/import-layers/meta-raspberrypi/recipes-graphics/vc-graphics/files/vchiq.sh
@@ -0,0 +1,24 @@
+#!/bin/sh
+### BEGIN INIT INFO
+# Provides:          vchiq.sh
+# Required-Start:    $remote_fs rmnologin
+# Required-Stop:
+# Default-Start:     S
+# Default-Stop:
+# Short-Description: Create /dev/vchiq.
+# Description:       Get the major number from /proc/devices and use it
+#                    ti create /dev/vchiq
+### END INIT INFO
+
+rm -f /dev/vchiq
+
+#Get the major number
+major=$(awk "\$2==\"vchiq\" {print \$1}" /proc/devices)
+
+if [ -z "$major" ]; then
+	echo "Error: Cannot find vchiq in /proc/devices"
+	exit 2
+else
+	mknod /dev/vchiq c "$major" 0
+	chmod a+w /dev/vchiq
+fi
diff --git a/import-layers/meta-raspberrypi/recipes-graphics/vc-graphics/vc-graphics-hardfp.bb b/import-layers/meta-raspberrypi/recipes-graphics/vc-graphics/vc-graphics-hardfp.bb
new file mode 100644
index 0000000..0db71fd
--- /dev/null
+++ b/import-layers/meta-raspberrypi/recipes-graphics/vc-graphics/vc-graphics-hardfp.bb
@@ -0,0 +1,6 @@
+CONFLICTS = "vc-graphics"
+
+VCDIR = "hardfp/opt/vc"
+require vc-graphics.inc
+
+PR = "${INCPR}.0"
diff --git a/import-layers/meta-raspberrypi/recipes-graphics/vc-graphics/vc-graphics.bb b/import-layers/meta-raspberrypi/recipes-graphics/vc-graphics/vc-graphics.bb
new file mode 100644
index 0000000..a1bce56
--- /dev/null
+++ b/import-layers/meta-raspberrypi/recipes-graphics/vc-graphics/vc-graphics.bb
@@ -0,0 +1,6 @@
+CONFLICTS = "vc-graphics-hardfp"
+
+VCDIR = "opt/vc"
+require vc-graphics.inc
+
+PR = "${INCPR}.0"
diff --git a/import-layers/meta-raspberrypi/recipes-graphics/vc-graphics/vc-graphics.inc b/import-layers/meta-raspberrypi/recipes-graphics/vc-graphics/vc-graphics.inc
new file mode 100644
index 0000000..a1c8d29
--- /dev/null
+++ b/import-layers/meta-raspberrypi/recipes-graphics/vc-graphics/vc-graphics.inc
@@ -0,0 +1,56 @@
+DESCRIPTION = "Graphics libraries for BCM2835."
+LICENSE = "Proprietary"
+
+LIC_FILES_CHKSUM = "file://LICENCE;md5=86e53f5f5909ee66900418028de11780"
+
+PROVIDES = "virtual/libgles2 virtual/egl"
+COMPATIBLE_MACHINE = "raspberrypi"
+
+include recipes-bsp/common/firmware.inc
+
+SRC_URI += " \
+    file://egl.pc \
+    file://vchiq.sh \
+"
+
+S = "${RPIFW_S}/${VCDIR}"
+
+INCPR = "r1"
+
+inherit pkgconfig update-rc.d
+
+do_install () {
+  install -d ${D}${bindir}
+  cp -R bin/* ${D}${bindir}
+
+  install -d ${D}${sbindir}
+  cp -R sbin/* ${D}${sbindir}
+
+  install -d ${D}${libdir}
+  # note: -H option to deref symlinked .so
+  cp -R -H lib/* ${D}${libdir}
+
+  install -d ${D}${includedir}
+  cp -R include/* ${D}${includedir}
+
+  install -d ${D}${libdir}/pkgconfig
+  install -m 0644 ${WORKDIR}/egl.pc ${D}${libdir}/pkgconfig/
+
+  install -d ${D}/${sysconfdir}/init.d
+  install -m 0755 ${WORKDIR}/vchiq.sh ${D}${sysconfdir}/init.d/
+}
+
+# These are proprietary binaries generated elsewhere so don't check ldflags
+INSANE_SKIP_${PN} = "ldflags"
+
+INITSCRIPT_NAME = "vchiq.sh"
+INITSCRIPT_PARAMS = "start 03 S ."
+
+FILES_${PN} = "${bindir}/* \
+               ${sbindir}/* \
+               ${libdir}/lib*.so \
+               ${sysconfdir}/init.d \
+               ${libdir}/plugins"
+FILES_${PN}-dev = "${libdir}/pkgconfig \
+                   ${includedir}"
+FILES_${PN}-dbg += "${libdir}/plugins/.debug"
diff --git a/import-layers/meta-raspberrypi/recipes-graphics/wayland/weston_%.bbappend b/import-layers/meta-raspberrypi/recipes-graphics/wayland/weston_%.bbappend
new file mode 100644
index 0000000..c3a7421
--- /dev/null
+++ b/import-layers/meta-raspberrypi/recipes-graphics/wayland/weston_%.bbappend
@@ -0,0 +1,4 @@
+EXTRA_OECONF_append_rpi = "\
+        --enable-rpi-compositor \
+        WESTON_NATIVE_BACKEND=rpi-backend.so \
+       "
diff --git a/import-layers/meta-raspberrypi/recipes-graphics/weston/weston_%.bbappend b/import-layers/meta-raspberrypi/recipes-graphics/weston/weston_%.bbappend
new file mode 100644
index 0000000..3ec311d
--- /dev/null
+++ b/import-layers/meta-raspberrypi/recipes-graphics/weston/weston_%.bbappend
@@ -0,0 +1,7 @@
+EXTRA_OECONF += "--enable-rpi-compositor \
+             --disable-resize-optimization \
+             --disable-setuid-install \
+             --disable-xwayland-test \
+             --disable-simple-egl-clients \
+             WESTON_NATIVE_BACKEND=rpi-backend.so \
+"
diff --git a/import-layers/meta-raspberrypi/recipes-graphics/xorg-xserver/xserver-xf86-config/rpi/xorg.conf b/import-layers/meta-raspberrypi/recipes-graphics/xorg-xserver/xserver-xf86-config/rpi/xorg.conf
new file mode 100644
index 0000000..6fd5298
--- /dev/null
+++ b/import-layers/meta-raspberrypi/recipes-graphics/xorg-xserver/xserver-xf86-config/rpi/xorg.conf
@@ -0,0 +1,6 @@
+# Initial xorg.conf for the RaspberryPi
+# Most things are setup automatically by magic pixies in the system.
+# 
+# It is suggested this file is not used any more and configuration 
+# snippets are placed in xorg.conf.d instead.
+#
diff --git a/import-layers/meta-raspberrypi/recipes-graphics/xorg-xserver/xserver-xf86-config/rpi/xorg.conf.d/10-evdev.conf b/import-layers/meta-raspberrypi/recipes-graphics/xorg-xserver/xserver-xf86-config/rpi/xorg.conf.d/10-evdev.conf
new file mode 100644
index 0000000..cc83ab2
--- /dev/null
+++ b/import-layers/meta-raspberrypi/recipes-graphics/xorg-xserver/xserver-xf86-config/rpi/xorg.conf.d/10-evdev.conf
@@ -0,0 +1,40 @@
+#
+# Catch-all evdev loader for udev-based systems
+# We don't simply match on any device since that also adds accelerometers
+# and other devices that we don't really want to use. The list below
+# matches everything but joysticks.
+
+Section "InputClass"
+        Identifier "evdev pointer catchall"
+        MatchIsPointer "on"
+        MatchDevicePath "/dev/input/event*"
+        Driver "evdev"
+EndSection
+
+Section "InputClass"
+        Identifier "evdev keyboard catchall"
+        MatchIsKeyboard "on"
+        MatchDevicePath "/dev/input/event*"
+        Driver "evdev"
+EndSection
+
+Section "InputClass"
+        Identifier "evdev touchpad catchall"
+        MatchIsTouchpad "on"
+        MatchDevicePath "/dev/input/event*"
+        Driver "evdev"
+EndSection
+
+Section "InputClass"
+        Identifier "evdev tablet catchall"
+        MatchIsTablet "on"
+        MatchDevicePath "/dev/input/event*"
+        Driver "evdev"
+EndSection
+
+Section "InputClass"
+        Identifier "evdev touchscreen catchall"
+        MatchIsTouchscreen "on"
+        MatchDevicePath "/dev/input/event*"
+        Driver "evdev"
+EndSection
diff --git a/import-layers/meta-raspberrypi/recipes-graphics/xorg-xserver/xserver-xf86-config/rpi/xorg.conf.d/98-pitft.conf b/import-layers/meta-raspberrypi/recipes-graphics/xorg-xserver/xserver-xf86-config/rpi/xorg.conf.d/98-pitft.conf
new file mode 100644
index 0000000..0d2b36b
--- /dev/null
+++ b/import-layers/meta-raspberrypi/recipes-graphics/xorg-xserver/xserver-xf86-config/rpi/xorg.conf.d/98-pitft.conf
@@ -0,0 +1,5 @@
+Section "Device"
+    Identifier "Adafruit PiTFT"
+    Driver "fbdev"
+    Option "fbdev" "/dev/fb1"
+EndSection
diff --git a/import-layers/meta-raspberrypi/recipes-graphics/xorg-xserver/xserver-xf86-config/rpi/xorg.conf.d/99-calibration.conf b/import-layers/meta-raspberrypi/recipes-graphics/xorg-xserver/xserver-xf86-config/rpi/xorg.conf.d/99-calibration.conf
new file mode 100644
index 0000000..f8b578c
--- /dev/null
+++ b/import-layers/meta-raspberrypi/recipes-graphics/xorg-xserver/xserver-xf86-config/rpi/xorg.conf.d/99-calibration.conf
@@ -0,0 +1,6 @@
+Section "InputClass"
+        Identifier      "calibration"
+        MatchProduct    "stmpe-ts"
+        Option  "Calibration"   "3800 200 200 3800"
+        Option  "SwapAxes"      "1"
+EndSection
diff --git a/import-layers/meta-raspberrypi/recipes-graphics/xorg-xserver/xserver-xf86-config_0.1.bbappend b/import-layers/meta-raspberrypi/recipes-graphics/xorg-xserver/xserver-xf86-config_0.1.bbappend
new file mode 100644
index 0000000..062de2d
--- /dev/null
+++ b/import-layers/meta-raspberrypi/recipes-graphics/xorg-xserver/xserver-xf86-config_0.1.bbappend
@@ -0,0 +1,19 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
+
+SRC_URI_append_rpi = " file://xorg.conf.d/10-evdev.conf \
+                       file://xorg.conf.d/98-pitft.conf \
+                       file://xorg.conf.d/99-calibration.conf \
+                     "
+
+do_install_append_rpi () {
+	install -d ${D}/${sysconfdir}/X11/xorg.conf.d/
+	install -m 0644 ${WORKDIR}/xorg.conf.d/10-evdev.conf ${D}/${sysconfdir}/X11/xorg.conf.d/
+
+	PITFT="${@bb.utils.contains("MACHINE_FEATURES", "pitft", "1", "0", d)}"
+	if [ "${PITFT}" = "1" ]; then
+		install -m 0644 ${WORKDIR}/xorg.conf.d/98-pitft.conf ${D}/${sysconfdir}/X11/xorg.conf.d/
+		install -m 0644 ${WORKDIR}/xorg.conf.d/99-calibration.conf ${D}/${sysconfdir}/X11/xorg.conf.d/
+	fi
+}
+
+FILES_${PN}_rpi += "${sysconfdir}/X11/xorg.conf ${sysconfdir}/X11/xorg.conf.d/*"