Added initial support for displaying on Wayland compositors.
authorSam Spilsbury <smspillaz@gmail.com>
Tue, 16 Jul 2013 01:11:20 +0000 (18:11 -0700)
committerSam Spilsbury <smspillaz@gmail.com>
Fri, 11 Oct 2013 16:34:31 +0000 (00:34 +0800)
SDL and X11 builds are disabled when using the --enable-wayland
switch.

EGLNativeTypeWayland is an implementation of EGLNativeType which
connects to a running wayland compositor if possible and starts
rendering in a new surface.

WinEventsWayland polls the wayland display for new events and updates
the main surface.

The wayland client libraries are loaded dynamically and their functions
should not be used directly. Instead, IDllWaylandClient should be injected
into any objects that need to call functions in those libraries. Because
the autogenerated protocol functions are inline in the header files
and not available to be looked up, the protocol needs to be used directly.

Some of the helpers there are:

 1. wayland::protocol::CreateWaylandObject -> creates a wl_proxy casted
    to the result type with a specific wl_interface as looked up in
    the client library.
 2. wayland::protocol::CallMethodOnWaylandObject -> calls wl_proxy_marshal
    with on the proxy with the specified opcode and arguments
 3. wayland::protocol::AddListenerOnWaylandObject -> adds a wl_listener
    to the wl_proxy
 4. wayland::protocol::DestroyWaylandObject -> calls wl_proxy_destroy
    on the proxy.

There may be some cases where additional constructor or destructor functions
might need to be called before or after CreateWaylandObject and
DestroyWaylandObject. Developers should consult the autogenerated
wayland-*-protocol.h headers to determine the expected call order.

XBMCSurface and XBMCConnection wrap most of the wayland connection
and surface creation / destruction and provide outputs for getting
the current resolution and EGL surface.

There is currently no support for keyboard input, mouse input or
multiple monitors.

42 files changed:
.gitignore
configure.in
xbmc/DllPaths_generated.h.in
xbmc/windowing/DllWaylandClient.h [new file with mode: 0644]
xbmc/windowing/DllWaylandEgl.h [new file with mode: 0644]
xbmc/windowing/DllXKBCommon.h [new file with mode: 0644]
xbmc/windowing/Makefile [deleted file]
xbmc/windowing/Makefile.in [new file with mode: 0644]
xbmc/windowing/WaylandProtocol.h [new file with mode: 0644]
xbmc/windowing/WinEvents.cpp
xbmc/windowing/WinEvents.h
xbmc/windowing/WinEventsWayland.cpp [new file with mode: 0644]
xbmc/windowing/WinEventsWayland.h [new file with mode: 0644]
xbmc/windowing/egl/EGLNativeTypeWayland.cpp [new file with mode: 0644]
xbmc/windowing/egl/EGLNativeTypeWayland.h [new file with mode: 0644]
xbmc/windowing/egl/EGLWrapper.cpp
xbmc/windowing/egl/Makefile [deleted file]
xbmc/windowing/egl/Makefile.in [new file with mode: 0644]
xbmc/windowing/egl/wayland/Callback.cpp [new file with mode: 0644]
xbmc/windowing/egl/wayland/Callback.h [new file with mode: 0644]
xbmc/windowing/egl/wayland/Compositor.cpp [new file with mode: 0644]
xbmc/windowing/egl/wayland/Compositor.h [new file with mode: 0644]
xbmc/windowing/egl/wayland/Display.cpp [new file with mode: 0644]
xbmc/windowing/egl/wayland/Display.h [new file with mode: 0644]
xbmc/windowing/egl/wayland/OpenGLSurface.cpp [new file with mode: 0644]
xbmc/windowing/egl/wayland/OpenGLSurface.h [new file with mode: 0644]
xbmc/windowing/egl/wayland/Region.cpp [new file with mode: 0644]
xbmc/windowing/egl/wayland/Region.h [new file with mode: 0644]
xbmc/windowing/egl/wayland/Registry.cpp [new file with mode: 0644]
xbmc/windowing/egl/wayland/Registry.h [new file with mode: 0644]
xbmc/windowing/egl/wayland/Shell.cpp [new file with mode: 0644]
xbmc/windowing/egl/wayland/Shell.h [new file with mode: 0644]
xbmc/windowing/egl/wayland/ShellSurface.cpp [new file with mode: 0644]
xbmc/windowing/egl/wayland/ShellSurface.h [new file with mode: 0644]
xbmc/windowing/egl/wayland/Surface.cpp [new file with mode: 0644]
xbmc/windowing/egl/wayland/Surface.h [new file with mode: 0644]
xbmc/windowing/egl/wayland/WaylandLibraries.cpp [new file with mode: 0644]
xbmc/windowing/egl/wayland/WaylandLibraries.h [new file with mode: 0644]
xbmc/windowing/egl/wayland/XBMCConnection.cpp [new file with mode: 0644]
xbmc/windowing/egl/wayland/XBMCConnection.h [new file with mode: 0644]
xbmc/windowing/egl/wayland/XBMCSurface.cpp [new file with mode: 0644]
xbmc/windowing/egl/wayland/XBMCSurface.h [new file with mode: 0644]

index 5109742..187fab7 100644 (file)
@@ -717,6 +717,10 @@ lib/cmyth/Makefile
 # no longer used
 /xbmc/win32/git_rev.h
 
+# /xbmc/windowing/
+/xbmc/windowing/Makefile
+/xbmc/windowing/egl/Makefile
+
 # /lib/ffmpeg/
 /lib/ffmpeg/config.h
 /lib/ffmpeg/config.err
index 9d635d4..4b09ddd 100644 (file)
@@ -131,6 +131,8 @@ fishbmc_enabled="== FishBMC enabled. =="
 fishbmc_disabled="== FishBMC disabled. =="
 projectm_enabled="== ProjectM enabled. =="
 projectm_disabled="== ProjectM disabled. =="
+wayland_enabled="== Wayland enabled. =="
+wayland_disabled="== Wayland disabled. =="
 x11_enabled="== X11 enabled. =="
 x11_disabled="== X11 disabled. =="
 pulse_not_found="== Could not find libpulse. PulseAudio support disabled. =="
@@ -342,6 +344,12 @@ AC_ARG_ENABLE([projectm],
   [use_projectm=$enableval],
   [use_projectm=yes])
 
+AC_ARG_ENABLE([wayland],
+  [AS_HELP_STRING([--enable-wayland],
+  [enable wayland (default is no) 'Linux Only'])],
+  [use_wayland=$enableval],
+  [use_wayland=no])
+
 AC_ARG_ENABLE([x11],
   [AS_HELP_STRING([--enable-x11],
   [enable x11 (default is yes) 'Linux Only'])],
@@ -593,6 +601,7 @@ AC_PROG_LIBTOOL
 AC_PROG_AWK
 AC_PROG_LN_S
 AC_PROG_MAKE_SET
+PKG_PROG_PKG_CONFIG
 MAKE="${MAKE:-make}"
 OBJDUMP="${OBJDUMP:-objdump}"
 
@@ -686,6 +695,7 @@ case $host in
      use_gles=yes
      use_sdl=no
      use_x11=no
+     use_wayland=no
      ;;
   arm*-*linux-android*)
      target_platform=target_android
@@ -699,6 +709,7 @@ case $host in
      use_optical_drive=no
      use_sdl=no
      use_x11=no
+     use_wayland=no
      build_shared_lib=yes
      ;;
   *)
@@ -953,6 +964,39 @@ else
   AC_MSG_NOTICE([Using Python $PYTHON_VERSION])
 fi
 
+# Wayland
+if test "$use_wayland" = "yes" && test "$host_vendor" != "apple"; then
+  AC_MSG_NOTICE($wayland_enabled)
+  PKG_CHECK_MODULES([WAYLAND_CLIENT],    [wayland-client],
+    [INCLUDES="$INCLUDES $WAYLAND_CLIENT_CFLAGS";
+     WAYLAND_CLIENT_LIBRARY_LINE=`LIBRARY=\`${PKG_CONFIG} --libs-only-l wayland-client\`; echo ${LIBRARY:2}`;
+     XB_FIND_SONAME([WAYLAND_CLIENT_LIBRARY], ${WAYLAND_CLIENT_LIBRARY_LINE})],
+     AC_MSG_ERROR($missing_library))
+  PKG_CHECK_MODULES([WAYLAND_EGL],    [wayland-egl],
+    [INCLUDES="$INCLUDES $WAYLAND_EGL_CFLAGS";
+     WAYLAND_EGL_LIBRARY_LINE=`LIBRARY=\`${PKG_CONFIG} --libs-only-l wayland-egl\`; echo ${LIBRARY:2}`
+     XB_FIND_SONAME([WAYLAND_EGL_LIBRARY], ${WAYLAND_EGL_LIBRARY_LINE})],
+    AC_MSG_ERROR($missing_library))
+  PKG_CHECK_MODULES([XKBCOMMON],    [xkbcommon],
+    [INCLUDES="$INCLUDES $XKBCOMMON_CFLAGS";
+     XKBCOMMON_LIBRARY_LINE=`LIBRARY=\`${PKG_CONFIG} --libs-only-l xkbcommon\`; echo ${LIBRARY:2}`
+     XB_FIND_SONAME([XKBCOMMON_LIBRARY], $XKBCOMMON_LIBRARY_LINE)],
+    AC_MSG_ERROR($missing_library))
+  AC_DEFINE([HAVE_WAYLAND], [1], [Define to 1 if you have Wayland libs installed.])
+
+  # Disable SDL and X11 builds
+  use_sdl=no
+  use_joystick=no
+  use_x11=no
+
+
+  # Wayland requires the EGL "window system" which in turn only supports
+  # the OpenGL ES API, so enable gles support
+  use_gles=yes
+else
+  AC_MSG_RESULT($wayland_disabled)
+fi
+
 # Checks for platforms libraries.
 if test "$use_gles" = "yes"; then
   use_gl="no"
@@ -2116,6 +2160,13 @@ else
   final_message="$final_message\n  X11:\t\tNo"
 fi
 
+if test "$use_wayland" = "yes"; then
+  final_message="$final_message\n  Wayland:\tYes"
+  USE_WAYLAND=1
+else
+  final_message="$final_message\n  Wayland:\tNo"
+fi
+
 if test "$use_libbluray" = "yes"; then
   final_message="$final_message\n  Bluray:\tYes"
 else
@@ -2458,6 +2509,8 @@ OUTPUT_FILES="Makefile \
     xbmc/visualizations/OpenGLSpectrum/Makefile \
     xbmc/visualizations/fishBMC/Makefile \
     xbmc/visualizations/WaveForm/Makefile \
+    xbmc/windowing/Makefile \
+    xbmc/windowing/egl/Makefile \
     lib/addons/library.xbmc.addon/Makefile \
     lib/addons/library.xbmc.codec/Makefile \
     lib/addons/library.xbmc.gui/Makefile \
@@ -2545,6 +2598,7 @@ AC_SUBST(USE_LIBUDEV)
 AC_SUBST(USE_LIBUSB)
 AC_SUBST(USE_LIBCEC)
 AC_SUBST(USE_MYSQL)
+AC_SUBST(USE_WAYLAND)
 AC_SUBST(USE_WEB_SERVER)
 AC_SUBST(USE_UPNP)
 AC_SUBST(USE_OMXLIB)
index fca6ac9..d35ea97 100644 (file)
 /* libbluray */
 #define DLL_PATH_LIBBLURAY     "@BLURAY_SONAME@"
 
+/* wayland */
+#define DLL_PATH_WAYLAND_CLIENT "@WAYLAND_CLIENT_LIBRARY_SONAME@"
+#define DLL_PATH_WAYLAND_EGL "@WAYLAND_EGL_LIBRARY_SONAME@"
+
+/* xkbcommon */
+#define DLL_PATH_XKBCOMMON "@XKBCOMMON_LIBRARY_SONAME@"
+
 #endif
diff --git a/xbmc/windowing/DllWaylandClient.h b/xbmc/windowing/DllWaylandClient.h
new file mode 100644 (file)
index 0000000..1155818
--- /dev/null
@@ -0,0 +1,175 @@
+#pragma once
+
+/*
+ *      Copyright (C) 2005-2013 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, see
+ *  <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#if (defined HAVE_CONFIG_H) && (!defined TARGET_WINDOWS)
+  #include "config.h"
+#endif
+
+#include <cstdarg>
+
+#include "utils/log.h"
+#include "DynamicDll.h"
+
+struct wl_proxy;
+struct wl_interface;
+
+struct wl_display;
+struct wl_registry;
+struct wl_callback;
+struct wl_compositor;
+struct wl_shell;
+struct wl_shell_surface;
+struct wl_surface;
+struct wl_seat;
+struct wl_pointer;
+struct wl_keyboard;
+struct wl_output;
+struct wl_region;
+
+extern const struct wl_interface wl_display_interface;
+extern const struct wl_interface wl_registry_interface;
+extern const struct wl_interface wl_callback_interface;
+extern const struct wl_interface wl_compositor_interface;
+extern const struct wl_interface wl_shell_interface;
+extern const struct wl_interface wl_shell_surface_interface;
+extern const struct wl_interface wl_surface_interface;
+extern const struct wl_interface wl_seat_interface;
+extern const struct wl_interface wl_pointer_interface;
+extern const struct wl_interface wl_keyboard_interface;
+extern const struct wl_interface wl_output_interface;
+extern const struct wl_interface wl_region_interface;
+
+class IDllWaylandClient
+{
+public:
+  typedef void(*wl_proxy_marshal_func)(struct wl_proxy *,
+                                       uint32_t,
+                                       ...);
+  typedef void(*wl_proxy_listener_func)(void);
+
+  virtual struct wl_interface ** Get_wl_display_interface() = 0;
+  virtual struct wl_interface ** Get_wl_registry_interface() = 0;
+  virtual struct wl_interface ** Get_wl_callback_interface() = 0;
+  virtual struct wl_interface ** Get_wl_compositor_interface() = 0;
+  virtual struct wl_interface ** Get_wl_shell_interface() = 0;
+  virtual struct wl_interface ** Get_wl_shell_surface_interface() = 0;
+  virtual struct wl_interface ** Get_wl_surface_interface() = 0;
+  virtual struct wl_interface ** Get_wl_seat_interface() = 0;
+  virtual struct wl_interface ** Get_wl_pointer_interface() = 0;
+  virtual struct wl_interface ** Get_wl_keyboard_interface() = 0;
+  virtual struct wl_interface ** Get_wl_output_interface() = 0;
+  virtual struct wl_interface ** Get_wl_region_interface() = 0;
+
+  virtual struct wl_display * wl_display_connect(const char *) = 0;
+  virtual void wl_display_disconnect(struct wl_display *) = 0;
+  virtual int wl_display_get_fd(struct wl_display *) = 0;
+  virtual int wl_display_dispatch(struct wl_display *) = 0;
+  virtual int wl_display_dispatch_pending(struct wl_display *) = 0;
+  virtual int wl_display_flush(struct wl_display *) = 0;
+  
+  virtual wl_proxy_marshal_func wl_proxy_marshaller() = 0;
+
+  virtual struct wl_proxy * wl_proxy_create(struct wl_proxy *,
+                                            const struct wl_interface *) = 0;
+  virtual void wl_proxy_destroy(struct wl_proxy *) = 0;
+  virtual int wl_proxy_add_listener(struct wl_proxy *,
+                                    wl_proxy_listener_func *,
+                                    void *) = 0;
+
+  virtual ~IDllWaylandClient() {}
+};
+
+class DllWaylandClient : public DllDynamic, public IDllWaylandClient
+{
+  DECLARE_DLL_WRAPPER(DllWaylandClient, DLL_PATH_WAYLAND_CLIENT)
+  
+  DEFINE_GLOBAL_PTR(struct wl_interface *, wl_display_interface);
+  DEFINE_GLOBAL_PTR(struct wl_interface *, wl_registry_interface);
+  DEFINE_GLOBAL_PTR(struct wl_interface *, wl_callback_interface);
+  DEFINE_GLOBAL_PTR(struct wl_interface *, wl_compositor_interface);
+  DEFINE_GLOBAL_PTR(struct wl_interface *, wl_shell_interface);
+  DEFINE_GLOBAL_PTR(struct wl_interface *, wl_shell_surface_interface);
+  DEFINE_GLOBAL_PTR(struct wl_interface *, wl_surface_interface);
+  DEFINE_GLOBAL_PTR(struct wl_interface *, wl_seat_interface);
+  DEFINE_GLOBAL_PTR(struct wl_interface *, wl_pointer_interface);
+  DEFINE_GLOBAL_PTR(struct wl_interface *, wl_keyboard_interface);
+  DEFINE_GLOBAL_PTR(struct wl_interface *, wl_output_interface);
+  DEFINE_GLOBAL_PTR(struct wl_interface *, wl_region_interface);
+  
+  DEFINE_METHOD1(struct wl_display *, wl_display_connect, (const char *p1));
+  DEFINE_METHOD1(void, wl_display_disconnect, (struct wl_display *p1));
+  DEFINE_METHOD1(int, wl_display_get_fd, (struct wl_display *p1));
+  DEFINE_METHOD1(int, wl_display_dispatch, (struct wl_display *p1));
+  DEFINE_METHOD1(int, wl_display_dispatch_pending, (struct wl_display *p1));
+  DEFINE_METHOD1(int, wl_display_flush, (struct wl_display *p1));
+  
+  /* We need to resolve wl_proxy_marshal as a function pointer as it
+   * takes varargs */
+  DEFINE_METHOD_FP(void,
+                   wl_proxy_marshal,
+                   (struct wl_proxy *p1, uint32_t p2, ...));
+
+  DEFINE_METHOD2(struct wl_proxy *,
+                 wl_proxy_create,
+                 (struct wl_proxy *p1, const struct wl_interface *p2));
+  DEFINE_METHOD1(void, wl_proxy_destroy, (struct wl_proxy *p1));
+  DEFINE_METHOD3(int,
+                 wl_proxy_add_listener,
+                 (struct wl_proxy *p1,
+                  wl_proxy_listener_func *p2,
+                  void *p3));
+  
+  BEGIN_METHOD_RESOLVE()
+    RESOLVE_METHOD(wl_display_interface)
+    RESOLVE_METHOD(wl_registry_interface)
+    RESOLVE_METHOD(wl_callback_interface)
+    RESOLVE_METHOD(wl_compositor_interface)
+    RESOLVE_METHOD(wl_shell_interface)
+    RESOLVE_METHOD(wl_shell_surface_interface)
+    RESOLVE_METHOD(wl_surface_interface)
+    RESOLVE_METHOD(wl_seat_interface)
+    RESOLVE_METHOD(wl_pointer_interface)
+    RESOLVE_METHOD(wl_keyboard_interface)
+    RESOLVE_METHOD(wl_output_interface)
+    RESOLVE_METHOD(wl_region_interface)
+  
+    RESOLVE_METHOD(wl_display_connect)
+    RESOLVE_METHOD(wl_display_disconnect)
+    RESOLVE_METHOD(wl_display_get_fd)
+    RESOLVE_METHOD(wl_display_dispatch)
+    RESOLVE_METHOD(wl_display_dispatch_pending)
+    RESOLVE_METHOD(wl_display_flush)
+    RESOLVE_METHOD_FP(wl_proxy_marshal)
+    RESOLVE_METHOD(wl_proxy_create)
+    RESOLVE_METHOD(wl_proxy_destroy)
+    RESOLVE_METHOD(wl_proxy_add_listener)
+  END_METHOD_RESOLVE()
+  
+public:
+
+  /* This overload returns the function pointer to wl_proxy_marshal
+   * so that clients can call it directly */
+  wl_proxy_marshal_func wl_proxy_marshaller()
+  {
+    return DllWaylandClient::wl_proxy_marshal;
+  }
+};
diff --git a/xbmc/windowing/DllWaylandEgl.h b/xbmc/windowing/DllWaylandEgl.h
new file mode 100644 (file)
index 0000000..1919cfa
--- /dev/null
@@ -0,0 +1,65 @@
+#pragma once
+
+/*
+ *      Copyright (C) 2005-2013 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, see
+ *  <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#if (defined HAVE_CONFIG_H) && (!defined TARGET_WINDOWS)
+  #include "config.h"
+#endif
+#include "utils/log.h"
+#include "DynamicDll.h"
+
+struct wl_surface;
+struct wl_egl_window;
+
+class IDllWaylandEGL
+{
+public:
+  virtual ~IDllWaylandEGL() {}
+  virtual struct wl_egl_window * wl_egl_window_create(struct wl_surface *,
+                                                      int width,
+                                                      int height) = 0;
+  virtual void wl_egl_window_destroy(struct wl_egl_window *) = 0;
+  virtual void wl_egl_window_resize(struct wl_egl_window *,
+                                    int width, int height,
+                                    int dx, int dy) = 0;
+};
+
+class DllWaylandEGL : public DllDynamic, public IDllWaylandEGL
+{
+  DECLARE_DLL_WRAPPER(DllWaylandEGL, DLL_PATH_WAYLAND_EGL)
+  
+  DEFINE_METHOD3(struct wl_egl_window *,
+                 wl_egl_window_create,
+                 (struct wl_surface *p1, int p2, int p3));
+  DEFINE_METHOD1(void, wl_egl_window_destroy, (struct wl_egl_window *p1));
+  DEFINE_METHOD5(void,
+                 wl_egl_window_resize,
+                 (struct wl_egl_window *p1,
+                  int p2,
+                  int p3,
+                  int p4,
+                  int p5));
+  BEGIN_METHOD_RESOLVE()
+    RESOLVE_METHOD(wl_egl_window_create)
+    RESOLVE_METHOD(wl_egl_window_destroy)
+    RESOLVE_METHOD(wl_egl_window_resize)
+  END_METHOD_RESOLVE()
+};
diff --git a/xbmc/windowing/DllXKBCommon.h b/xbmc/windowing/DllXKBCommon.h
new file mode 100644 (file)
index 0000000..cdeefea
--- /dev/null
@@ -0,0 +1,41 @@
+#pragma once
+
+/*
+ *      Copyright (C) 2005-2013 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, see
+ *  <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#if (defined HAVE_CONFIG_H) && (!defined TARGET_WINDOWS)
+  #include "config.h"
+#endif
+#include <xkbcommon/xkbcommon.h>
+#include "utils/log.h"
+#include "DynamicDll.h"
+
+class IDllXKBCommon
+{
+public:
+  virtual ~IDllXKBCommon() {}
+};
+
+class DllXKBCommon : public DllDynamic, public IDllXKBCommon
+{
+  DECLARE_DLL_WRAPPER(DllXKBCommon, DLL_PATH_XKBCOMMON)
+  BEGIN_METHOD_RESOLVE()
+  END_METHOD_RESOLVE()
+};
diff --git a/xbmc/windowing/Makefile b/xbmc/windowing/Makefile
deleted file mode 100644 (file)
index b52d16c..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-SRCS=WinEventsSDL.cpp \
-     WinEventsLinux.cpp \
-     WinSystem.cpp \
-     WinEvents.cpp
-     
-LIB=windowing.a
-
-include ../../Makefile.include
--include $(patsubst %.cpp,%.P,$(patsubst %.c,%.P,$(SRCS)))
diff --git a/xbmc/windowing/Makefile.in b/xbmc/windowing/Makefile.in
new file mode 100644 (file)
index 0000000..b00e280
--- /dev/null
@@ -0,0 +1,10 @@
+SRCS=WinEventsSDL.cpp \
+     WinEventsLinux.cpp \
+     WinEventsWayland.cpp \
+     WinSystem.cpp \
+     WinEvents.cpp
+     
+LIB=windowing.a
+
+include ../../Makefile.include
+-include $(patsubst %.cpp,%.P,$(patsubst %.c,%.P,$(SRCS)))
diff --git a/xbmc/windowing/WaylandProtocol.h b/xbmc/windowing/WaylandProtocol.h
new file mode 100644 (file)
index 0000000..424754b
--- /dev/null
@@ -0,0 +1,244 @@
+#pragma once
+
+/*
+ *      Copyright (C) 2005-2013 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, see
+ *  <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <iomanip>
+#include <stdexcept>
+#include <sstream>
+
+#include "DllWaylandClient.h"
+
+/* These functions are wrappers around using the wayland protocol
+ * directly. Unfortunately, since most of the protocol has autogenerated
+ * binding code, and that binding code assumes that we're directly
+ * linked to the client library (we're not), we can't use it. So
+ * we need to use wl_proxy_create, wl_proxy_marshal and wl_proxy_destory
+ * directly.
+ * 
+ * These functions effectively exist to reduce some of the duplication
+ * that surrounds using these functions directly. You should look
+ * at the autogenerated binding code to determine how wl_proxy_marshal
+ * should be used to call a particular method.
+ * 
+ * Also note that there may be some cases where additional constructor
+ * or destructor functions might need to be called before or after
+ * CreateWaylandObject and DestroyWaylandObject.
+ * 
+ * If you need to call a method with more than six arguments,
+ * you'll need to add a new overload here */
+namespace xbmc
+{
+namespace wayland
+{
+namespace protocol
+{
+/* These functions call a method on a specifed wayland object
+ * (you should use the pointer provided by the client library
+ *  and not the wrapper) with the specified opcode and
+ * arguments.
+ * 
+ * THERE IS NO TYPE CHECKING so you should be especially sure that
+ * you're calling it with the right arguments. Failure to do so
+ * will result in very strange behaviour
+ */
+template <typename Object>
+void CallMethodOnWaylandObject(IDllWaylandClient &clientLibrary,
+                               Object object,
+                               uint32_t opcode)
+{
+  struct wl_proxy *proxy =
+    reinterpret_cast<struct wl_proxy *>(object);
+  clientLibrary.wl_proxy_marshaller()(proxy,
+                                      opcode);
+}
+template <typename Object,
+          typename A1>
+void CallMethodOnWaylandObject(IDllWaylandClient &clientLibrary,
+                               Object object,
+                               uint32_t opcode,
+                               A1 arg1)
+{
+  struct wl_proxy *proxy =
+    reinterpret_cast<struct wl_proxy *>(object);
+  clientLibrary.wl_proxy_marshaller()(proxy,
+                                      opcode,
+                                      arg1);
+}
+
+template <typename Object,
+          typename A1,
+          typename A2>
+void CallMethodOnWaylandObject(IDllWaylandClient &clientLibrary,
+                               Object object,
+                               uint32_t opcode,
+                               A1 arg1,
+                               A2 arg2)
+{
+  struct wl_proxy *proxy =
+    reinterpret_cast<struct wl_proxy *>(object);
+  clientLibrary.wl_proxy_marshaller()(proxy,
+                                      opcode,
+                                      arg1,
+                                      arg2);
+}
+
+template <typename Object,
+          typename A1,
+          typename A2,
+          typename A3>
+void CallMethodOnWaylandObject(IDllWaylandClient &clientLibrary,
+                               Object object,
+                               uint32_t opcode,
+                               A1 arg1,
+                               A2 arg2,
+                               A3 arg3)
+{
+  struct wl_proxy *proxy =
+    reinterpret_cast<struct wl_proxy *>(object);
+  clientLibrary.wl_proxy_marshaller()(proxy,
+                                      opcode,
+                                      arg1,
+                                      arg2,
+                                      arg3);
+}
+
+template <typename Object,
+          typename A1,
+          typename A2,
+          typename A3,
+          typename A4>
+void CallMethodOnWaylandObject(IDllWaylandClient &clientLibrary,
+                               Object object,
+                               uint32_t opcode,
+                               A1 arg1,
+                               A2 arg2,
+                               A3 arg3,
+                               A4 arg4)
+{
+  struct wl_proxy *proxy =
+    reinterpret_cast<struct wl_proxy *>(object);
+  clientLibrary.wl_proxy_marshaller()(proxy,
+                                      opcode,
+                                      arg1,
+                                      arg2,
+                                      arg3,
+                                      arg4);
+}
+
+template <typename Object,
+          typename A1,
+          typename A2,
+          typename A3,
+          typename A4,
+          typename A5>
+void CallMethodOnWaylandObject(IDllWaylandClient &clientLibrary,
+                               Object object,
+                               uint32_t opcode,
+                               A1 arg1,
+                               A2 arg2,
+                               A3 arg3,
+                               A4 arg4,
+                               A5 arg5)
+{
+  struct wl_proxy *proxy =
+    reinterpret_cast<struct wl_proxy *>(object);
+  clientLibrary.wl_proxy_marshaller()(proxy,
+                                      opcode,
+                                      arg1,
+                                      arg2,
+                                      arg3,
+                                      arg4,
+                                      arg5);
+}
+
+/* This function template returns a new unmanaged object pointer
+ * as specified by Create with the RPC interface as specified
+ * as a child in the server ownership hierarchy of factory.
+ * 
+ * Create must be castable to struct wl_proxy *, which
+ * means that struct wl_proxy should be its first member. Generally
+ * all wayland library proxy objects satisfy this criteria
+ */ 
+template <typename Create, typename Factory>
+Create CreateWaylandObject(IDllWaylandClient &clientLibrary,
+                           Factory factory,
+                           struct wl_interface **interface)
+{
+  struct wl_proxy *pfactory =
+    reinterpret_cast<struct wl_proxy *>(factory);
+  struct wl_proxy *proxy =
+    clientLibrary.wl_proxy_create(pfactory,
+                                  reinterpret_cast<struct wl_interface *>(interface));
+
+  if (!proxy)
+  {
+    std::stringstream ss;
+    ss << "Failed to create "
+       << typeid(Create).name()
+       << " from factory "
+       << typeid(Factory).name()
+       << " at 0x"
+       << std::hex
+       << reinterpret_cast<void *>(pfactory)
+       << std::dec;
+    throw std::runtime_error(ss.str());
+  }
+
+  return reinterpret_cast<Create>(proxy);
+}
+
+/* This function adds a new "listener" to the object specified.
+ * A "listener" is generally a struct of function pointers as specified
+ * by the object's RPC interface for each event it can generate. These
+ * can usually be found in the protocol header. "data" is passed
+ * to each callback to make it a full closure. */
+template <typename Object, typename Listener>
+int AddListenerOnWaylandObject(IDllWaylandClient &clientLibrary,
+                               Object object,
+                               Listener listener,
+                               void *data)
+{
+  struct wl_proxy *proxy =
+    reinterpret_cast<struct wl_proxy *>(object);
+  
+  /* C-style casts are bad, but there is no equavilent to
+   * std::remove_const in C++98 and we are reinterpret_cast'ing
+   * anyways */
+  IDllWaylandClient::wl_proxy_listener_func *listenerFunc =
+    (IDllWaylandClient::wl_proxy_listener_func *)((void *)listener);
+  return clientLibrary.wl_proxy_add_listener(proxy, listenerFunc, data);
+}
+
+/* This function destroys the proxy object and releases its resources
+ * on the client side. There may be an additional destroy request to
+ * release resources on the server side. That must be called
+ * prior to this. */
+template <typename Object>
+void DestroyWaylandObject(IDllWaylandClient &clientLibrary,
+                          Object *object)
+{
+  struct wl_proxy *proxy =
+    reinterpret_cast<struct wl_proxy *>(object);
+  clientLibrary.wl_proxy_destroy(proxy);
+}
+}
+}
+}
index d47784c..1022ad2 100644 (file)
 #include "WinEventsSDL.h"
 #define WinEventsType CWinEventsSDL
 
+#elif defined(HAVE_WAYLAND)
+#include "WinEventsWayland.h"
+#define WinEventsType CWinEventsWayland
+
 #elif defined(TARGET_LINUX) && defined(HAS_LINUX_EVENTS)
 #include "WinEventsLinux.h"
 #define WinEventsType CWinEventsLinux
index 8ae126a..e04631f 100644 (file)
@@ -45,5 +45,4 @@ class CWinEvents
     static size_t GetQueueSize();
 };
 
-
 #endif // WINDOW_EVENTS_H
diff --git a/xbmc/windowing/WinEventsWayland.cpp b/xbmc/windowing/WinEventsWayland.cpp
new file mode 100644 (file)
index 0000000..d8bff06
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+*      Copyright (C) 2005-2013 Team XBMC
+*      http://www.xbmc.org
+*
+*  This Program is free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2, or (at your option)
+*  any later version.
+*
+*  This Program is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+*  GNU General Public License for more details.
+*
+*  You should have received a copy of the GNU General Public License
+*  along with XBMC; see the file COPYING.  If not, see
+*  <http://www.gnu.org/licenses/>.
+*
+*/
+#include "system.h"
+
+#if defined (HAVE_WAYLAND)
+
+#include <memory>
+#include <sstream>
+
+#include <boost/noncopyable.hpp>
+#include <boost/scope_exit.hpp>
+#include <boost/scoped_ptr.hpp>
+
+#include <sys/mman.h>
+
+#include <wayland-client.h>
+#include <xkbcommon/xkbcommon.h>
+
+#include "Application.h"
+#include "WindowingFactory.h"
+#include "WinEvents.h"
+#include "WinEventsWayland.h"
+
+#include "DllWaylandClient.h"
+#include "DllXKBCommon.h"
+#include "WaylandProtocol.h"
+
+namespace
+{
+IDllWaylandClient *g_clientLibrary = NULL;
+struct wl_display *g_display = NULL;
+}
+
+CWinEventsWayland::CWinEventsWayland()
+{
+}
+
+void CWinEventsWayland::RefreshDevices()
+{
+}
+
+bool CWinEventsWayland::IsRemoteLowBattery()
+{
+  return false;
+}
+
+/* This function reads the display connection and dispatches
+ * any events through the specified object listeners */
+bool CWinEventsWayland::MessagePump()
+{
+  if (!g_display)
+    return false;
+
+  /* It is very important that these functions occurr in this order.
+   * Deadlocks might occurr otherwise.
+   * 
+   * The first function dispatches any pending events that have been
+   * determined from prior reads of the event queue without *also*
+   * reading the event queue.
+   * 
+   * The second function flushes the output buffer of any requests
+   * to be made to the server, including requests that should have
+   * been made in response to just-dispatched events earlier.
+   * 
+   * The third function reads the input buffer and dispatches any events
+   * that occurred.
+   * 
+   * If the functions are not called in this order, you might run into
+   * a situation where pending-dispatch events might have generated a
+   * write to the event queue in order to keep us awake (frame events
+   * are a particular culprit here), or where events that we need to
+   * dispatch in order to keep going are never read.
+   */
+  g_clientLibrary->wl_display_dispatch_pending(g_display);
+  g_clientLibrary->wl_display_flush(g_display);
+  g_clientLibrary->wl_display_dispatch(g_display);
+
+  return true;
+}
+
+size_t CWinEventsWayland::GetQueueSize()
+{
+  /* We can't query the size of the queue */
+  return 0;
+}
+
+void CWinEventsWayland::SetWaylandDisplay(IDllWaylandClient *clientLibrary,
+                                          struct wl_display *d)
+{
+  g_clientLibrary = clientLibrary;
+  g_display = d;
+}
+
+void CWinEventsWayland::DestroyWaylandDisplay()
+{
+  /* We should make sure that everything else is gone first before
+   * destroying the display */
+  MessagePump();
+  g_display = NULL;
+}
+
+#endif
diff --git a/xbmc/windowing/WinEventsWayland.h b/xbmc/windowing/WinEventsWayland.h
new file mode 100644 (file)
index 0000000..487a962
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+*      Copyright (C) 2005-2013 Team XBMC
+*      http://www.xbmc.org
+*
+*  This Program is free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2, or (at your option)
+*  any later version.
+*
+*  This Program is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+*  GNU General Public License for more details.
+*
+*  You should have received a copy of the GNU General Public License
+*  along with XBMC; see the file COPYING.  If not, see
+*  <http://www.gnu.org/licenses/>.
+*
+*/
+
+#ifndef WINDOW_EVENTS_WAYLAND_H
+#define WINDOW_EVENTS_WAYLAND_H
+
+#pragma once
+#include "windowing/WinEvents.h"
+
+struct wl_display;
+struct wl_seat;
+struct wl_surface;
+
+class IDllWaylandClient;
+class IDllWaylandCursor;
+class IDllXKBCommon;
+
+class CWinEventsWayland : public IWinEvents
+{
+public:
+  CWinEventsWayland();
+  bool MessagePump();
+  size_t GetQueueSize();
+  static void RefreshDevices();
+  static bool IsRemoteLowBattery();
+
+  static void SetWaylandDisplay(IDllWaylandClient *clientLibrary,
+                                struct wl_display *d);
+  static void DestroyWaylandDisplay();
+};
+
+#endif
diff --git a/xbmc/windowing/egl/EGLNativeTypeWayland.cpp b/xbmc/windowing/egl/EGLNativeTypeWayland.cpp
new file mode 100644 (file)
index 0000000..fed9da3
--- /dev/null
@@ -0,0 +1,347 @@
+/*
+ *      Copyright (C) 2011-2013 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, see
+ *  <http://www.gnu.org/licenses/>.
+ *
+ */
+#include "system.h"
+
+#if defined(HAVE_WAYLAND)
+
+#define WL_EGL_PLATFORM
+#include <sstream>
+#include <iostream>
+#include <stdexcept>
+
+#include <boost/noncopyable.hpp>
+#include <boost/function.hpp>
+#include <boost/bind.hpp>
+#include <boost/scoped_ptr.hpp>
+#include <boost/shared_ptr.hpp>
+
+#include <cstdlib>
+
+#include <wayland-client.h>
+#include <wayland-version.h>
+
+#include "windowing/DllWaylandClient.h"
+#include "windowing/DllWaylandEgl.h"
+#include "windowing/DllXKBCommon.h"
+#include "windowing/WaylandProtocol.h"
+
+#include "guilib/gui3d.h"
+#include "utils/log.h"
+#include "windowing/WinEvents.h"
+#include "windowing/WinEventsWayland.h"
+
+#include "wayland/WaylandLibraries.h"
+#include "wayland/XBMCConnection.h"
+#include "wayland/XBMCSurface.h"
+
+#endif
+
+#include "EGLNativeTypeWayland.h"
+
+#if defined(HAVE_WAYLAND)
+namespace xw = xbmc::wayland;
+
+class CEGLNativeTypeWayland::Private
+{
+public:
+
+  boost::scoped_ptr<xw::Libraries> m_libraries;
+  boost::scoped_ptr<xw::XBMCConnection> m_connection;
+  boost::scoped_ptr<xw::XBMCSurface> m_surface;
+
+  bool LoadWaylandLibraries();
+  void UnloadWaylandLibraries();
+};
+
+bool CEGLNativeTypeWayland::Private::LoadWaylandLibraries()
+{
+  try
+  {
+    m_libraries.reset(new xw::Libraries());
+  }
+  catch (const std::runtime_error &err)
+  {
+    CLog::Log(LOGWARNING, "%s: %s\n",
+              __FUNCTION__, err.what());
+    return false;
+  }
+  
+  return true;
+}
+
+void CEGLNativeTypeWayland::Private::UnloadWaylandLibraries()
+{
+  m_libraries.reset();
+}
+
+#else
+class CEGLNativeTypeWayland::Private
+{
+};
+#endif
+
+CEGLNativeTypeWayland::CEGLNativeTypeWayland() :
+  priv(new Private())
+{
+}
+
+CEGLNativeTypeWayland::~CEGLNativeTypeWayland()
+{
+} 
+
+bool CEGLNativeTypeWayland::CheckCompatibility()
+{
+#if defined(HAVE_WAYLAND)
+  if (!getenv("WAYLAND_DISPLAY"))
+  {
+    CLog::Log(LOGWARNING, "%s:, WAYLAND_DISPLAY is not set",
+              __FUNCTION__);
+    return false;
+  }
+  
+  /* FIXME:
+   * There appears to be a bug in DllDynamic::CanLoad() which causes
+   * it to always return false. We are just loading the library 
+   * directly at CheckCompatibility time now */
+  if (!priv->LoadWaylandLibraries())
+    return false;
+
+  return true;
+#else
+  return false;
+#endif
+}
+
+void CEGLNativeTypeWayland::Initialize()
+{
+}
+
+void CEGLNativeTypeWayland::Destroy()
+{
+#if defined(HAVE_WAYLAND)
+  priv->UnloadWaylandLibraries();
+#endif
+}
+
+bool CEGLNativeTypeWayland::CreateNativeDisplay()
+{
+#if defined(HAVE_WAYLAND)
+
+  /* On CreateNativeDisplay we connect to the running wayland
+   * compositor on our current socket (as specified by WAYLAND_DISPLAY)
+   * and then do some initial set up like registering event handlers.
+   * 
+   * xbmc::wayland::XBMCConnection is an encapsulation of all of our
+   * current global state with regards to a wayland connection. We
+   * need to give it access to the wayland client libraries and
+   * libxkbcommon for it to do its work.
+   * 
+   * We also inject an xbmc::wayland::XBMCConnection::EventInjector
+   * which is basically just a table of function pointers to functions
+   * in CWinEventsWayland, which are all static. CWinEvents is still
+   * effectively a static, singleton class, and depending on it
+   * means that testing becomes substantially more difficult. As such
+   * we just inject the bits that we need here so that they can be
+   * stubbed out later in testing environments if need be.
+   * 
+   * xbmc::wayland::XBMCConnection's constructor will throw an
+   * std::runtime_error in case it runs into any trouble in connecting
+   * to the wayland compositor or getting the initial global objects.
+   * 
+   * The best we can do when that happens is just report the error
+   * and bail out, possibly to try another (fallback) windowing system.
+   */
+  try
+  {
+    xw::XBMCConnection::EventInjector injector =
+    {
+      CWinEventsWayland::SetWaylandDisplay,
+      CWinEventsWayland::DestroyWaylandDisplay,
+      CWinEvents::MessagePump
+    };
+      
+    priv->m_connection.reset(new xw::XBMCConnection(priv->m_libraries->ClientLibrary(),
+                                                    priv->m_libraries->XKBCommonLibrary(),
+                                                    injector));
+  }
+  catch (const std::runtime_error &err)
+  {
+    CLog::Log(LOGERROR, "%s: %s", __FUNCTION__, err.what());
+    return false;
+  }
+
+  return true;
+#else
+  return false;
+#endif
+}
+
+bool CEGLNativeTypeWayland::CreateNativeWindow()
+{
+#if defined(HAVE_WAYLAND)
+
+  /* CreateNativeWindow is where we allocate a new wayland surface
+   * using libwayland-egl and ask the compositor to display it by
+   * creating a new remote surface object.
+   * 
+   * xbmc::wayland::XBMCSurface encapsulates all of this information. It
+   * needs access to various client libraries, as well as the compositor
+   * and shell global interfaces from xbmc::wayland::XBMCConnection
+   * in order to actually create the internal "surface" and "shell
+   * surface" representations.
+   * 
+   * Once xbmc::wayland::XBMCSurface is created, an EGL bindable
+   * surface will be available for later use.
+   * 
+   * The last two parameters are the requested width and height of
+   * the surface.
+   * 
+   * If any problems are encountered in creating the surface
+   * an std::runtime_error is thrown. Like above, we catch it and
+   * report the error, since there's not much we can do about it.
+   */
+  try
+  {
+    priv->m_surface.reset(new xw::XBMCSurface(priv->m_libraries->ClientLibrary(),
+                                              priv->m_libraries->EGLLibrary(),
+                                              priv->m_connection->GetCompositor(),
+                                              priv->m_connection->GetShell(),
+                                              640,
+                                              480));
+  }
+  catch (const std::runtime_error &err)
+  {
+    CLog::Log(LOGERROR, "%s: %s", __FUNCTION__, err.what());
+    return false;
+  }
+
+  return true;
+#else
+  return false;
+#endif
+}
+
+bool CEGLNativeTypeWayland::GetNativeDisplay(XBNativeDisplayType **nativeDisplay) const
+{
+#if defined(HAVE_WAYLAND)
+  /* We need to return a pointer to the wl_display * (eg wl_display **),
+   * as EGLWrapper needs to dereference our return value to get the
+   * actual display and not its first member */
+  *nativeDisplay =
+      reinterpret_cast <XBNativeDisplayType *>(priv->m_connection->NativeDisplay());
+  return true;
+#else
+  return false;
+#endif
+}
+
+bool CEGLNativeTypeWayland::GetNativeWindow(XBNativeDisplayType **nativeWindow) const
+{
+#if defined(HAVE_WAYLAND)
+  *nativeWindow =
+      reinterpret_cast <XBNativeWindowType *>(priv->m_surface->EGLNativeWindow());
+  return true;
+#else
+  return false;
+#endif
+}  
+
+/* DestroyNativeDisplay and DestroyNativeWindow simply just call
+ * reset on the relevant scoped_ptr. This will effectively destroy
+ * the encapsulating objects which cleans up all of the relevant
+ * connections and surfaces */
+bool CEGLNativeTypeWayland::DestroyNativeDisplay()
+{
+#if defined(HAVE_WAYLAND)
+  priv->m_connection.reset();
+  return true;
+#else
+  return false;
+#endif
+}
+
+bool CEGLNativeTypeWayland::DestroyNativeWindow()
+{
+#if defined(HAVE_WAYLAND)
+  priv->m_surface.reset();
+  return true;  
+#else
+  return false;
+#endif
+}
+
+/* The connection knowns about the resolution size, so we ask it
+ * about it. This information is all cached locally, but stored in
+ * the xbmc::wayland::XBMCConnection object */
+bool CEGLNativeTypeWayland::GetNativeResolution(RESOLUTION_INFO *res) const
+{
+#if defined(HAVE_WAYLAND)
+  priv->m_connection->CurrentResolution(*res);
+
+  return true;
+#else
+  return false;
+#endif
+}
+
+bool CEGLNativeTypeWayland::SetNativeResolution(const RESOLUTION_INFO &res)
+{
+#if defined(HAVE_WAYLAND)
+  priv->m_surface->Resize(res.iScreenWidth, res.iScreenHeight);
+  return true;
+#else
+  return false;
+#endif
+}
+
+bool CEGLNativeTypeWayland::ProbeResolutions(std::vector<RESOLUTION_INFO> &resolutions)
+{
+#if defined(HAVE_WAYLAND)
+  priv->m_connection->AvailableResolutions(resolutions);
+  return true;
+#else
+  return false;
+#endif
+}
+
+bool CEGLNativeTypeWayland::GetPreferredResolution(RESOLUTION_INFO *res) const
+{
+#if defined(HAVE_WAYLAND)
+  priv->m_connection->PreferredResolution(*res);
+  return true;
+#else
+  return false;
+#endif
+}
+
+bool CEGLNativeTypeWayland::ShowWindow(bool show)
+{
+#if defined(HAVE_WAYLAND)
+  if (show)
+    priv->m_surface->Show();
+  else
+    return false;
+
+  return true;
+#else
+  return false;
+#endif
+}
diff --git a/xbmc/windowing/egl/EGLNativeTypeWayland.h b/xbmc/windowing/egl/EGLNativeTypeWayland.h
new file mode 100644 (file)
index 0000000..4f68366
--- /dev/null
@@ -0,0 +1,58 @@
+#pragma once
+
+/*
+ *      Copyright (C) 2011-2013 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, see
+ *  <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <boost/scoped_ptr.hpp>
+
+#include <EGL/egl.h>
+#include "EGLNativeType.h"
+
+class CEGLNativeTypeWayland : public CEGLNativeType
+{
+public:
+  CEGLNativeTypeWayland();
+  virtual ~CEGLNativeTypeWayland();
+  virtual std::string GetNativeName() const { return "wayland"; };
+  virtual bool  CheckCompatibility();
+  virtual void  Initialize();
+  virtual void  Destroy();
+  virtual int   GetQuirks() { return EGL_QUIRK_NONE; };
+
+  virtual bool  CreateNativeDisplay();
+  virtual bool  CreateNativeWindow();
+  virtual bool  GetNativeDisplay(XBNativeDisplayType **nativeDisplay) const;
+  virtual bool  GetNativeWindow(XBNativeWindowType **nativeWindow) const;
+
+  virtual bool  DestroyNativeWindow();
+  virtual bool  DestroyNativeDisplay();
+
+  virtual bool  GetNativeResolution(RESOLUTION_INFO *res) const;
+  virtual bool  SetNativeResolution(const RESOLUTION_INFO &res);
+  virtual bool  ProbeResolutions(std::vector<RESOLUTION_INFO> &resolutions);
+  virtual bool  GetPreferredResolution(RESOLUTION_INFO *res) const;
+
+  virtual bool  ShowWindow(bool show);
+private:
+
+  class Private;
+
+  boost::scoped_ptr <Private> priv;
+};
index 5284b4f..917f4fb 100644 (file)
@@ -26,6 +26,7 @@
 #include "EGLNativeTypeAndroid.h"
 #include "EGLNativeTypeAmlogic.h"
 #include "EGLNativeTypeRaspberryPI.h"
+#include "EGLNativeTypeWayland.h"
 #include "EGLWrapper.h"
 
 #define CheckError() m_result = eglGetError(); if(m_result != EGL_SUCCESS) CLog::Log(LOGERROR, "EGL error in %s: %x",__FUNCTION__, m_result);
@@ -79,7 +80,8 @@ bool CEGLWrapper::Initialize(const std::string &implementation)
 
   // Try to create each backend in sequence and go with the first one
   // that we know will work
-  if ((nativeGuess = CreateEGLNativeType<CEGLNativeTypeAndroid>(implementation)) ||
+  if ((nativeGuess = CreateEGLNativeType<CEGLNativeTypeWayland>(implementation)) ||
+      (nativeGuess = CreateEGLNativeType<CEGLNativeTypeAndroid>(implementation)) ||
       (nativeGuess = CreateEGLNativeType<CEGLNativeTypeAmlogic>(implementation)) ||
       (nativeGuess = CreateEGLNativeType<CEGLNativeTypeRaspberryPI>(implementation)))
   {
diff --git a/xbmc/windowing/egl/Makefile b/xbmc/windowing/egl/Makefile
deleted file mode 100644 (file)
index 241220a..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-INCLUDES=-I.
-
-SRCS = WinSystemEGL.cpp
-SRCS+= EGLNativeTypeAmlogic.cpp
-SRCS+= EGLNativeTypeAndroid.cpp
-SRCS+= EGLNativeTypeRaspberryPI.cpp
-SRCS+= EGLWrapper.cpp
-
-LIB = windowing_egl.a
-
-include ../../../Makefile.include
--include $(patsubst %.cpp,%.P,$(patsubst %.c,%.P,$(SRCS)))
diff --git a/xbmc/windowing/egl/Makefile.in b/xbmc/windowing/egl/Makefile.in
new file mode 100644 (file)
index 0000000..5b7ff89
--- /dev/null
@@ -0,0 +1,29 @@
+INCLUDES=-I.
+
+SRCS = WinSystemEGL.cpp
+SRCS+= EGLNativeTypeAmlogic.cpp
+SRCS+= EGLNativeTypeAndroid.cpp
+SRCS+= EGLNativeTypeRaspberryPI.cpp
+SRCS+= EGLNativeTypeWayland.cpp
+SRCS+= EGLWrapper.cpp
+
+# Wayland specific detail
+ifeq (@USE_WAYLAND@,1)
+SRCS+= wayland/Callback.cpp \
+       wayland/Compositor.cpp \
+       wayland/Display.cpp \
+       wayland/OpenGLSurface.cpp \
+       wayland/Region.cpp \
+       wayland/Registry.cpp \
+       wayland/Shell.cpp \
+       wayland/ShellSurface.cpp \
+       wayland/Surface.cpp \
+       wayland/WaylandLibraries.cpp \
+       wayland/XBMCConnection.cpp \
+       wayland/XBMCSurface.cpp
+endif
+
+LIB = windowing_egl.a
+
+include ../../../Makefile.include
+-include $(patsubst %.cpp,%.P,$(patsubst %.c,%.P,$(SRCS)))
diff --git a/xbmc/windowing/egl/wayland/Callback.cpp b/xbmc/windowing/egl/wayland/Callback.cpp
new file mode 100644 (file)
index 0000000..86a288a
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ *      Copyright (C) 2011-2013 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, see
+ *  <http://www.gnu.org/licenses/>.
+ *
+ */
+#include <wayland-client.h>
+
+#include <boost/function.hpp>
+#include <boost/bind.hpp>
+
+#include "windowing/DllWaylandClient.h"
+#include "windowing/WaylandProtocol.h"
+#include "Callback.h"
+
+namespace xw = xbmc::wayland;
+
+const wl_callback_listener xw::Callback::m_listener =
+{
+  Callback::OnCallback
+};
+
+xw::Callback::Callback(IDllWaylandClient &clientLibrary,
+                       struct wl_callback *callback,
+                       const Func &func) :
+  m_clientLibrary(clientLibrary),
+  m_callback(callback),
+  m_func(func)
+{
+  protocol::AddListenerOnWaylandObject(m_clientLibrary,
+                                       m_callback,
+                                       &m_listener,
+                                       reinterpret_cast<void *>(this));
+}
+
+xw::Callback::~Callback()
+{
+  protocol::DestroyWaylandObject(m_clientLibrary,
+                                 m_callback);
+}
+
+struct wl_callback *
+xw::Callback::GetWlCallback()
+{
+  return m_callback;
+}
+
+void
+xw::Callback::OnCallback(void *data,
+                         struct wl_callback *callback,
+                         uint32_t time)
+{
+  static_cast<Callback *>(data)->m_func(time);
+}
diff --git a/xbmc/windowing/egl/wayland/Callback.h b/xbmc/windowing/egl/wayland/Callback.h
new file mode 100644 (file)
index 0000000..9b184a2
--- /dev/null
@@ -0,0 +1,65 @@
+#pragma once
+
+/*
+ *      Copyright (C) 2011-2013 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, see
+ *  <http://www.gnu.org/licenses/>.
+ *
+ */
+#include <boost/noncopyable.hpp>
+#include <boost/function.hpp>
+
+#include <wayland-client.h>
+
+class IDllWaylandClient;
+
+namespace xbmc
+{
+namespace wayland
+{
+/* Callback encapsulates a callback object that might be called
+ * by the compositor through the client library at an arbitrary point
+ * in time. A custom closure can be provided as func to be called
+ * whenever this callback is fired
+ */
+class Callback :
+  boost::noncopyable
+{
+public:
+
+  typedef boost::function<void(uint32_t)> Func;
+
+  Callback(IDllWaylandClient &clientLibrary,
+           struct wl_callback *callback,
+           const Func &func);
+  ~Callback();
+
+  struct wl_callback * GetWlCallback();
+
+  static const struct wl_callback_listener m_listener;
+
+  static void OnCallback(void *,
+                         struct wl_callback *,
+                         uint32_t);
+
+private:
+
+  IDllWaylandClient &m_clientLibrary;
+  struct wl_callback *m_callback;
+  Func m_func;
+};
+}
+}
diff --git a/xbmc/windowing/egl/wayland/Compositor.cpp b/xbmc/windowing/egl/wayland/Compositor.cpp
new file mode 100644 (file)
index 0000000..c1a4258
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ *      Copyright (C) 2011-2013 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, see
+ *  <http://www.gnu.org/licenses/>.
+ *
+ */
+#include <wayland-client.h>
+
+#include "windowing/DllWaylandClient.h"
+#include "windowing/WaylandProtocol.h"
+#include "Compositor.h"
+
+namespace xw = xbmc::wayland;
+
+xw::Compositor::Compositor(IDllWaylandClient &clientLibrary,
+                           struct wl_compositor *compositor) :
+  m_clientLibrary(clientLibrary),
+  m_compositor(compositor)
+{
+}
+
+xw::Compositor::~Compositor()
+{
+  protocol::DestroyWaylandObject(m_clientLibrary,
+                                 m_compositor);
+}
+
+struct wl_compositor *
+xw::Compositor::GetWlCompositor()
+{
+  return m_compositor;
+}
+
+struct wl_surface *
+xw::Compositor::CreateSurface() const
+{
+  struct wl_surface *surface =
+    protocol::CreateWaylandObject<struct wl_surface *,
+                                  struct wl_compositor *>(m_clientLibrary,
+                                                          m_compositor,
+                                                          m_clientLibrary.Get_wl_surface_interface());
+  protocol::CallMethodOnWaylandObject(m_clientLibrary,
+                                      m_compositor,
+                                      WL_COMPOSITOR_CREATE_SURFACE,
+                                      surface);
+  return surface;
+}
+
+struct wl_region *
+xw::Compositor::CreateRegion() const
+{
+  struct wl_region *region =
+    protocol::CreateWaylandObject<struct wl_region *,
+                                  struct wl_compositor *>(m_clientLibrary,
+                                                          m_compositor,
+                                                          m_clientLibrary.Get_wl_region_interface ());
+  protocol::CallMethodOnWaylandObject(m_clientLibrary,
+                                      m_compositor,
+                                      WL_COMPOSITOR_CREATE_REGION,
+                                      region);
+  return region;
+}
diff --git a/xbmc/windowing/egl/wayland/Compositor.h b/xbmc/windowing/egl/wayland/Compositor.h
new file mode 100644 (file)
index 0000000..e2955d6
--- /dev/null
@@ -0,0 +1,61 @@
+#pragma once
+
+/*
+ *      Copyright (C) 2011-2013 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, see
+ *  <http://www.gnu.org/licenses/>.
+ *
+ */
+#include <boost/noncopyable.hpp>
+
+struct wl_compositor;
+struct wl_surface;
+struct wl_region;
+
+class IDllWaylandClient;
+
+namespace xbmc
+{
+namespace wayland
+{
+class Compositor :
+  boost::noncopyable
+{
+public:
+
+  Compositor(IDllWaylandClient &clientLibrary,
+             struct wl_compositor *compositor);
+  ~Compositor();
+
+  struct wl_compositor * GetWlCompositor();
+  
+  /* Creates a "surface" on the compositor. This is not a renderable
+   * surface immediately, a renderable "buffer" must be bound to it
+   * (usually an EGL Window) */
+  struct wl_surface * CreateSurface() const;
+  
+  /* Creates a "region" on the compositor side. Server side regions
+   * are manipulated on the client side and then can be used to
+   * affect rendering and input on the server side */
+  struct wl_region * CreateRegion() const;
+
+private:
+
+  IDllWaylandClient &m_clientLibrary;
+  struct wl_compositor *m_compositor;
+};
+}
+}
diff --git a/xbmc/windowing/egl/wayland/Display.cpp b/xbmc/windowing/egl/wayland/Display.cpp
new file mode 100644 (file)
index 0000000..fb37d4a
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ *      Copyright (C) 2011-2013 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, see
+ *  <http://www.gnu.org/licenses/>.
+ *
+ */
+#include <sstream>
+#include <iostream>
+#include <stdexcept>
+
+#include <cstdlib>
+
+#include <wayland-client.h>
+
+#include "windowing/DllWaylandClient.h"
+#include "windowing/WaylandProtocol.h"
+#include "Display.h"
+
+namespace xw = xbmc::wayland;
+
+xw::Display::Display(IDllWaylandClient &clientLibrary) :
+  m_clientLibrary(clientLibrary),
+  m_display(m_clientLibrary.wl_display_connect(NULL))
+{
+  /* wl_display_connect won't throw when it fails, but it does
+   * return NULL on failure. If this object would be incomplete
+   * then that is a fatal error for the backend and we should
+   * throw a runtime_error for the main connection manager to handle
+   */
+  if (!m_display)
+  {
+    std::stringstream ss;
+    ss << "Failed to connect to "
+       << getenv("WAYLAND_DISPLAY");
+    throw std::runtime_error(ss.str());
+  }
+}
+
+xw::Display::~Display()
+{
+  m_clientLibrary.wl_display_flush(m_display);
+  m_clientLibrary.wl_display_disconnect(m_display);
+}
+
+struct wl_display *
+xw::Display::GetWlDisplay()
+{
+  return m_display;
+}
+
+EGLNativeDisplayType *
+xw::Display::GetEGLNativeDisplay()
+{
+  return &m_display;
+}
+
+/* Create a sync callback object. This can be wrapped in an
+ * xbmc::wayland::Callback object to call an arbitrary function
+ * as soon as the display has finished processing all commands.
+ * 
+ * This does not block until a synchronization is complete -
+ * consider using a function like WaitForSynchronize to do that */
+struct wl_callback *
+xw::Display::Sync()
+{
+  struct wl_callback *callback =
+      protocol::CreateWaylandObject<struct wl_callback *,
+                                    struct wl_display *> (m_clientLibrary,
+                                                          m_display,
+                                                          m_clientLibrary.Get_wl_callback_interface());
+  protocol::CallMethodOnWaylandObject(m_clientLibrary,
+                                      m_display,
+                                      WL_DISPLAY_SYNC,
+                                      callback);
+  return callback;
+}
diff --git a/xbmc/windowing/egl/wayland/Display.h b/xbmc/windowing/egl/wayland/Display.h
new file mode 100644 (file)
index 0000000..bb38259
--- /dev/null
@@ -0,0 +1,53 @@
+#pragma once
+
+/*
+ *      Copyright (C) 2011-2013 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, see
+ *  <http://www.gnu.org/licenses/>.
+ *
+ */
+#include <boost/noncopyable.hpp>
+
+class IDllWaylandClient;
+
+struct wl_display;
+struct wl_callback;
+
+typedef struct wl_display * EGLNativeDisplayType;
+
+namespace xbmc
+{
+namespace wayland
+{
+class Display :
+  boost::noncopyable
+{
+  public:
+
+    Display(IDllWaylandClient &clientLibrary);
+    ~Display();
+
+    struct wl_display * GetWlDisplay();
+    EGLNativeDisplayType* GetEGLNativeDisplay();
+    struct wl_callback * Sync();
+
+  private:
+
+    IDllWaylandClient &m_clientLibrary;
+    struct wl_display *m_display;
+};
+}
+}
diff --git a/xbmc/windowing/egl/wayland/OpenGLSurface.cpp b/xbmc/windowing/egl/wayland/OpenGLSurface.cpp
new file mode 100644 (file)
index 0000000..1b8b3b1
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ *      Copyright (C) 2011-2013 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, see
+ *  <http://www.gnu.org/licenses/>.
+ *
+ */
+#include <wayland-client.h>
+#include <wayland-egl.h>
+
+#include "windowing/DllWaylandEgl.h"
+#include "OpenGLSurface.h"
+
+namespace xw = xbmc::wayland;
+
+xw::OpenGLSurface::OpenGLSurface(IDllWaylandEGL &eglLibrary,
+                                 struct wl_surface *surface,
+                                 int width,
+                                 int height) :
+  m_eglLibrary(eglLibrary),
+  m_eglWindow(m_eglLibrary.wl_egl_window_create(surface,
+                                                width,
+                                                height))
+{
+}
+
+xw::OpenGLSurface::~OpenGLSurface()
+{
+  m_eglLibrary.wl_egl_window_destroy(m_eglWindow);
+}
+
+struct wl_egl_window *
+xw::OpenGLSurface::GetWlEglWindow()
+{
+  return m_eglWindow;
+}
+
+EGLNativeWindowType *
+xw::OpenGLSurface::GetEGLNativeWindow()
+{
+  return &m_eglWindow;
+}
+
+void
+xw::OpenGLSurface::Resize(int width, int height)
+{
+  m_eglLibrary.wl_egl_window_resize(m_eglWindow,
+                                    width,
+                                    height,
+                                    0,
+                                    0);
+}
diff --git a/xbmc/windowing/egl/wayland/OpenGLSurface.h b/xbmc/windowing/egl/wayland/OpenGLSurface.h
new file mode 100644 (file)
index 0000000..915934d
--- /dev/null
@@ -0,0 +1,56 @@
+#pragma once
+
+/*
+ *      Copyright (C) 2011-2013 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, see
+ *  <http://www.gnu.org/licenses/>.
+ *
+ */
+#include <boost/noncopyable.hpp>
+
+class IDllWaylandEGL;
+
+struct wl_surface;
+struct wl_egl_window;
+
+typedef struct wl_egl_window * EGLNativeWindowType;
+
+namespace xbmc
+{
+namespace wayland
+{
+class OpenGLSurface :
+  boost::noncopyable
+{
+public:
+
+  OpenGLSurface(IDllWaylandEGL &eglLibrary,
+                struct wl_surface *surface,
+                int32_t width,
+                int32_t height);
+  ~OpenGLSurface();
+
+  struct wl_egl_window * GetWlEglWindow();
+  EGLNativeWindowType * GetEGLNativeWindow();
+  void Resize(int width, int height);
+
+private:
+
+  IDllWaylandEGL &m_eglLibrary;
+  struct wl_egl_window *m_eglWindow;
+};
+}
+}
diff --git a/xbmc/windowing/egl/wayland/Region.cpp b/xbmc/windowing/egl/wayland/Region.cpp
new file mode 100644 (file)
index 0000000..d1d2907
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ *      Copyright (C) 2011-2013 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, see
+ *  <http://www.gnu.org/licenses/>.
+ *
+ */
+#include <wayland-client.h>
+
+#include "windowing/DllWaylandClient.h"
+#include "windowing/WaylandProtocol.h"
+#include "Region.h"
+
+namespace xw = xbmc::wayland;
+
+xw::Region::Region(IDllWaylandClient &clientLibrary,
+                   struct wl_region *region) :
+  m_clientLibrary(clientLibrary),
+  m_region(region)
+{
+}
+
+xw::Region::~Region()
+{
+  protocol::CallMethodOnWaylandObject(m_clientLibrary,
+                                      m_region,
+                                      WL_REGION_DESTROY);
+  protocol::DestroyWaylandObject(m_clientLibrary,
+                                 m_region);
+}
+
+struct wl_region *
+xw::Region::GetWlRegion()
+{
+  return m_region;
+}
+
+void
+xw::Region::AddRectangle(int32_t x,
+                         int32_t y,
+                         int32_t width,
+                         int32_t height)
+{
+  protocol::CallMethodOnWaylandObject(m_clientLibrary,
+                                      m_region,
+                                      WL_REGION_ADD,
+                                      x,
+                                      y,
+                                      width,
+                                      height);
+}
diff --git a/xbmc/windowing/egl/wayland/Region.h b/xbmc/windowing/egl/wayland/Region.h
new file mode 100644 (file)
index 0000000..205bd03
--- /dev/null
@@ -0,0 +1,54 @@
+#pragma once
+
+/*
+ *      Copyright (C) 2011-2013 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, see
+ *  <http://www.gnu.org/licenses/>.
+ *
+ */
+#include <boost/noncopyable.hpp>
+
+class IDllWaylandClient;
+
+struct wl_region;
+
+namespace xbmc
+{
+namespace wayland
+{
+class Region :
+  boost::noncopyable
+{
+public:
+
+  Region(IDllWaylandClient &clientLibrary,
+         struct wl_region *);
+  ~Region();
+  
+  struct wl_region * GetWlRegion();
+
+  void AddRectangle(int32_t x,
+                    int32_t y,
+                    int32_t width,
+                    int32_t height);
+
+private:
+
+  IDllWaylandClient &m_clientLibrary;
+  struct wl_region *m_region;
+};
+}
+}
diff --git a/xbmc/windowing/egl/wayland/Registry.cpp b/xbmc/windowing/egl/wayland/Registry.cpp
new file mode 100644 (file)
index 0000000..77a8a26
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ *      Copyright (C) 2011-2013 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, see
+ *  <http://www.gnu.org/licenses/>.
+ *
+ */
+#include <wayland-client.h>
+
+#include "windowing/DllWaylandClient.h"
+#include "windowing/WaylandProtocol.h"
+#include "Registry.h"
+
+namespace
+{
+const std::string CompositorName("wl_compositor");
+const std::string ShellName("wl_shell");
+const std::string SeatName("wl_seat");
+}
+
+namespace xw = xbmc::wayland;
+
+const struct wl_registry_listener xw::Registry::m_listener =
+{
+  Registry::HandleGlobalCallback,
+  Registry::HandleRemoveGlobalCallback
+};
+
+/* We inject an IWaylandRegistration here which is a virtual
+ * class which a series of callbacks for the global objects
+ * used by xbmc. Once one of those objects becomes
+ * available, we call the specified callback function on that
+ * interface */
+xw::Registry::Registry(IDllWaylandClient &clientLibrary,
+                       struct wl_display *display,
+                       IWaylandRegistration &registration) :
+  m_clientLibrary(clientLibrary),
+  m_registry(protocol::CreateWaylandObject<struct wl_registry *,
+                                           struct wl_display *> (m_clientLibrary,
+                                                                 display,
+                                                                 m_clientLibrary.Get_wl_registry_interface())),
+  m_registration(registration)
+{
+  protocol::CallMethodOnWaylandObject(m_clientLibrary,
+                                      display,
+                                      WL_DISPLAY_GET_REGISTRY,
+                                      m_registry);
+  protocol::AddListenerOnWaylandObject(m_clientLibrary,
+                                       m_registry,
+                                       &m_listener,
+                                       reinterpret_cast<void *>(this));
+}
+
+xw::Registry::~Registry()
+{
+  protocol::DestroyWaylandObject(m_clientLibrary, m_registry);
+}
+
+/* Once a global becomes available, we immediately bind to it here
+ * and then notify the injected listener interface that the global
+ * is available on a named object. This allows that interface to
+ * respond to the arrival of the new global how it wishes */
+void
+xw::Registry::HandleGlobal(uint32_t name,
+                           const char *interface,
+                           uint32_t version)
+{
+  if (interface == CompositorName)
+  {
+    struct wl_compositor *compositor =
+      static_cast<struct wl_compositor *>(protocol::CreateWaylandObject<struct wl_compositor *,
+                                                                        struct wl_registry *>(m_clientLibrary,
+                                                                                              m_registry,
+                                                                                              m_clientLibrary.Get_wl_compositor_interface()));
+    protocol::CallMethodOnWaylandObject(m_clientLibrary,
+                                        m_registry,
+                                        WL_REGISTRY_BIND,
+                                        name,
+                                        reinterpret_cast<struct wl_interface *>(m_clientLibrary.Get_wl_compositor_interface())->name,
+                                        1,
+                                        compositor);
+    m_registration.OnCompositorAvailable(compositor);
+  }
+  else if (interface == ShellName)
+  {
+    struct wl_shell *shell =
+      static_cast<struct wl_shell *>(protocol::CreateWaylandObject<struct wl_shell *,
+                                                                   struct wl_registry *>(m_clientLibrary,
+                                                                                         m_registry,
+                                                                                         m_clientLibrary.Get_wl_shell_interface()));
+    protocol::CallMethodOnWaylandObject(m_clientLibrary,
+                                        m_registry,
+                                        WL_REGISTRY_BIND,
+                                        name,
+                                        reinterpret_cast<struct wl_interface *>(m_clientLibrary.Get_wl_shell_interface())->name,
+                                        1,
+                                        shell);
+    m_registration.OnShellAvailable(shell);
+  }
+  else if (interface == SeatName)
+  {
+    struct wl_seat *seat =
+      static_cast<struct wl_seat *>(protocol::CreateWaylandObject<struct wl_seat *,
+                                                                  struct wl_registry *>(m_clientLibrary,
+                                                                                        m_registry,
+                                                                                        m_clientLibrary.Get_wl_seat_interface()));
+    protocol::CallMethodOnWaylandObject(m_clientLibrary,
+                                        m_registry,
+                                        WL_REGISTRY_BIND,
+                                        name,
+                                        reinterpret_cast<struct wl_interface *>(m_clientLibrary.Get_wl_seat_interface())->name,
+                                        1,
+                                        seat);
+    m_registration.OnSeatAvailable(seat);
+  }
+}
+
+void
+xw::Registry::HandleRemoveGlobal(uint32_t name)
+{
+}
+
+void
+xw::Registry::HandleGlobalCallback(void *data,
+                                   struct wl_registry *registry,
+                                   uint32_t name,
+                                   const char *interface,
+                                   uint32_t version)
+{
+  static_cast<Registry *>(data)->HandleGlobal(name, interface, version);
+}
+
+void
+xw::Registry::HandleRemoveGlobalCallback(void *data,
+                                         struct wl_registry *registry,
+                                         uint32_t name)
+{
+  static_cast<Registry *>(data)->HandleRemoveGlobal(name);
+}
diff --git a/xbmc/windowing/egl/wayland/Registry.h b/xbmc/windowing/egl/wayland/Registry.h
new file mode 100644 (file)
index 0000000..e346a9b
--- /dev/null
@@ -0,0 +1,74 @@
+#pragma once
+
+/*
+ *      Copyright (C) 2011-2013 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, see
+ *  <http://www.gnu.org/licenses/>.
+ *
+ */
+#include <string>
+
+#include <boost/noncopyable.hpp>
+
+#include <wayland-client.h>
+
+class IDllWaylandClient;
+
+namespace xbmc
+{
+namespace wayland
+{
+class IWaylandRegistration
+{
+public:
+
+  virtual ~IWaylandRegistration() {};
+
+  virtual bool OnCompositorAvailable(struct wl_compositor *) = 0;
+  virtual bool OnShellAvailable(struct wl_shell *) = 0;
+  virtual bool OnSeatAvailable(struct wl_seat *) = 0;
+};
+
+class Registry :
+  boost::noncopyable
+{
+public:
+
+  Registry(IDllWaylandClient &clientLibrary,
+           struct wl_display   *display,
+           IWaylandRegistration &registration);
+  ~Registry();
+
+  struct wl_registry * GetWlRegistry();
+
+  static void HandleGlobalCallback(void *, struct wl_registry *,
+                                   uint32_t, const char *, uint32_t);
+  static void HandleRemoveGlobalCallback(void *, struct wl_registry *,
+                                         uint32_t name);
+
+private:
+
+  static const struct wl_registry_listener m_listener;
+
+  IDllWaylandClient &m_clientLibrary;
+  struct wl_registry *m_registry;
+  IWaylandRegistration &m_registration;
+
+  void HandleGlobal(uint32_t, const char *, uint32_t);
+  void HandleRemoveGlobal(uint32_t);
+};
+}
+}
diff --git a/xbmc/windowing/egl/wayland/Shell.cpp b/xbmc/windowing/egl/wayland/Shell.cpp
new file mode 100644 (file)
index 0000000..281ecb0
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ *      Copyright (C) 2011-2013 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, see
+ *  <http://www.gnu.org/licenses/>.
+ *
+ */
+#include <wayland-client.h>
+
+#include "windowing/DllWaylandClient.h"
+#include "windowing/WaylandProtocol.h"
+#include "Shell.h"
+
+namespace xw = xbmc::wayland;
+
+xw::Shell::Shell(IDllWaylandClient &clientLibrary,
+                 struct wl_shell *shell) :
+  m_clientLibrary(clientLibrary),
+  m_shell(shell)
+{
+}
+
+xw::Shell::~Shell()
+{
+  protocol::DestroyWaylandObject(m_clientLibrary,
+                                 m_shell);
+}
+
+struct wl_shell *
+xw::Shell::GetWlShell()
+{
+  return m_shell;
+}
+
+struct wl_shell_surface *
+xw::Shell::CreateShellSurface(struct wl_surface *surface)
+{
+  struct wl_shell_surface *shellSurface =
+    protocol::CreateWaylandObject<struct wl_shell_surface *,
+                                  struct wl_shell *>(m_clientLibrary,
+                                                     m_shell,
+                                                     m_clientLibrary.Get_wl_shell_surface_interface ());
+  protocol::CallMethodOnWaylandObject(m_clientLibrary,
+                                      m_shell,
+                                      WL_SHELL_GET_SHELL_SURFACE,
+                                      shellSurface,
+                                      surface);
+  return shellSurface;
+}
diff --git a/xbmc/windowing/egl/wayland/Shell.h b/xbmc/windowing/egl/wayland/Shell.h
new file mode 100644 (file)
index 0000000..00f12e0
--- /dev/null
@@ -0,0 +1,52 @@
+#pragma once
+
+/*
+ *      Copyright (C) 2011-2013 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, see
+ *  <http://www.gnu.org/licenses/>.
+ *
+ */
+#include <boost/noncopyable.hpp>
+
+class IDllWaylandClient;
+
+struct wl_shell;
+struct wl_shell_surface;
+struct wl_surface;
+
+namespace xbmc
+{
+namespace wayland
+{
+class Shell :
+  boost::noncopyable
+{
+public:
+
+  Shell(IDllWaylandClient &clientLibrary,
+        struct wl_shell *shell);
+  ~Shell();
+
+  struct wl_shell * GetWlShell();
+  struct wl_shell_surface * CreateShellSurface(struct wl_surface *);
+
+private:
+
+  IDllWaylandClient &m_clientLibrary;
+  struct wl_shell *m_shell;
+};
+}
+}
diff --git a/xbmc/windowing/egl/wayland/ShellSurface.cpp b/xbmc/windowing/egl/wayland/ShellSurface.cpp
new file mode 100644 (file)
index 0000000..59a077f
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ *      Copyright (C) 2011-2013 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, see
+ *  <http://www.gnu.org/licenses/>.
+ *
+ */
+#include <wayland-client.h>
+
+#include "windowing/DllWaylandClient.h"
+#include "windowing/WaylandProtocol.h"
+#include "ShellSurface.h"
+
+namespace xw = xbmc::wayland;
+
+const wl_shell_surface_listener xw::ShellSurface::m_listener =
+{
+  ShellSurface::HandlePingCallback,
+  ShellSurface::HandleConfigureCallback,
+  ShellSurface::HandlePopupDoneCallback
+};
+
+xw::ShellSurface::ShellSurface(IDllWaylandClient &clientLibrary,
+                               struct wl_shell_surface *shell_surface) :
+  m_clientLibrary(clientLibrary),
+  m_shellSurface(shell_surface)
+{
+  protocol::AddListenerOnWaylandObject(m_clientLibrary,
+                                       m_shellSurface,
+                                       &m_listener,
+                                       reinterpret_cast<void *>(this));
+}
+
+xw::ShellSurface::~ShellSurface()
+{
+  protocol::DestroyWaylandObject(m_clientLibrary, m_shellSurface);
+}
+
+struct wl_shell_surface *
+xw::ShellSurface::GetWlShellSurface()
+{
+  return m_shellSurface;
+}
+
+void
+xw::ShellSurface::SetFullscreen(enum wl_shell_surface_fullscreen_method method,
+                                uint32_t framerate,
+                                struct wl_output *output)
+{
+  protocol::CallMethodOnWaylandObject(m_clientLibrary,
+                                      m_shellSurface,
+                                      WL_SHELL_SURFACE_SET_FULLSCREEN,
+                                      method,
+                                      framerate,
+                                      output);
+}
+
+void
+xw::ShellSurface::HandlePingCallback(void *data,
+                                     struct wl_shell_surface *shell_surface,
+                                     uint32_t serial)
+{
+  return static_cast<ShellSurface *>(data)->HandlePing(serial);
+}
+
+void
+xw::ShellSurface::HandleConfigureCallback(void *data,
+                                          struct wl_shell_surface *shell_surface,
+                                          uint32_t edges,
+                                          int32_t width,
+                                          int32_t height)
+{
+  return static_cast<ShellSurface *>(data)->HandleConfigure(edges,
+                                                            width,
+                                                            height);
+}
+
+void
+xw::ShellSurface::HandlePopupDoneCallback(void *data,
+                                          struct wl_shell_surface *shell_surface)
+{
+  return static_cast<ShellSurface *>(data)->HandlePopupDone();
+}
+
+void
+xw::ShellSurface::HandlePing(uint32_t serial)
+{
+  protocol::CallMethodOnWaylandObject(m_clientLibrary,
+                                      m_shellSurface,
+                                      WL_SHELL_SURFACE_PONG,
+                                      serial);
+}
+
+void
+xw::ShellSurface::HandleConfigure(uint32_t edges,
+                                  int32_t width,
+                                  int32_t height)
+{
+}
+
+void
+xw::ShellSurface::HandlePopupDone()
+{
+}
diff --git a/xbmc/windowing/egl/wayland/ShellSurface.h b/xbmc/windowing/egl/wayland/ShellSurface.h
new file mode 100644 (file)
index 0000000..d052891
--- /dev/null
@@ -0,0 +1,71 @@
+#pragma once
+
+/*
+ *      Copyright (C) 2011-2013 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, see
+ *  <http://www.gnu.org/licenses/>.
+ *
+ */
+#include <wayland-client.h>
+
+#include <boost/noncopyable.hpp>
+
+class IDllWaylandClient;
+
+namespace xbmc
+{
+namespace wayland
+{
+class ShellSurface :
+  boost::noncopyable
+{
+public:
+
+  ShellSurface(IDllWaylandClient &clientLibrary,
+               struct wl_shell_surface *shellSurface);
+  ~ShellSurface();
+
+  struct wl_shell_surface * GetWlShellSurface();
+  void SetFullscreen(enum wl_shell_surface_fullscreen_method method,
+                     uint32_t framerate,
+                     struct wl_output *output);
+
+  static const wl_shell_surface_listener m_listener;
+
+  static void HandlePingCallback(void *,
+                                 struct wl_shell_surface *,
+                                 uint32_t);
+  static void HandleConfigureCallback(void *,
+                                      struct wl_shell_surface *,
+                                      uint32_t,
+                                      int32_t,
+                                      int32_t);
+  static void HandlePopupDoneCallback(void *,
+                                      struct wl_shell_surface *);
+
+private:
+
+  void HandlePing(uint32_t serial);
+  void HandleConfigure(uint32_t edges,
+                       int32_t width,
+                       int32_t height);
+  void HandlePopupDone();
+
+  IDllWaylandClient &m_clientLibrary;
+  struct wl_shell_surface *m_shellSurface;
+};
+}
+}
diff --git a/xbmc/windowing/egl/wayland/Surface.cpp b/xbmc/windowing/egl/wayland/Surface.cpp
new file mode 100644 (file)
index 0000000..b3c8165
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ *      Copyright (C) 2011-2013 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, see
+ *  <http://www.gnu.org/licenses/>.
+ *
+ */
+#include <wayland-client.h>
+
+#include "windowing/DllWaylandClient.h"
+#include "windowing/WaylandProtocol.h"
+#include "Surface.h"
+
+namespace xw = xbmc::wayland;
+
+xw::Surface::Surface(IDllWaylandClient &clientLibrary,
+                     struct wl_surface *surface) :
+  m_clientLibrary(clientLibrary),
+  m_surface(surface)
+{
+}
+
+xw::Surface::~Surface()
+{
+  protocol::CallMethodOnWaylandObject(m_clientLibrary,
+                                      m_surface,
+                                      WL_SURFACE_DESTROY);
+  protocol::DestroyWaylandObject(m_clientLibrary,
+                                 m_surface);
+}
+
+struct wl_surface *
+xw::Surface::GetWlSurface()
+{
+  return m_surface;
+}
+
+struct wl_callback *
+xw::Surface::CreateFrameCallback()
+{
+  struct wl_callback *callback =
+    protocol::CreateWaylandObject<struct wl_callback *,
+                                  struct wl_surface *>(m_clientLibrary,
+                                                       m_surface,
+                                                       m_clientLibrary.Get_wl_callback_interface());
+  protocol::CallMethodOnWaylandObject(m_clientLibrary,
+                                      m_surface,
+                                      WL_SURFACE_FRAME, callback);
+  return callback;
+}
+
+void
+xw::Surface::SetOpaqueRegion(struct wl_region *region)
+{
+  protocol::CallMethodOnWaylandObject(m_clientLibrary,
+                                      m_surface,
+                                      WL_SURFACE_SET_OPAQUE_REGION,
+                                      region);
+}
+
+void
+xw::Surface::Commit()
+{
+  protocol::CallMethodOnWaylandObject(m_clientLibrary,
+                                      m_surface,
+                                      WL_SURFACE_COMMIT);
+}
diff --git a/xbmc/windowing/egl/wayland/Surface.h b/xbmc/windowing/egl/wayland/Surface.h
new file mode 100644 (file)
index 0000000..2e805a1
--- /dev/null
@@ -0,0 +1,54 @@
+#pragma once
+
+/*
+ *      Copyright (C) 2011-2013 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, see
+ *  <http://www.gnu.org/licenses/>.
+ *
+ */
+#include <boost/noncopyable.hpp>
+
+struct wl_surface;
+struct wl_callback;
+struct wl_region;
+
+class IDllWaylandClient;
+
+namespace xbmc
+{
+namespace wayland
+{
+class Surface :
+  boost::noncopyable
+{
+public:
+
+  Surface(IDllWaylandClient &clientLibrary,
+          struct wl_surface *surface);
+  ~Surface();
+
+  struct wl_surface * GetWlSurface();
+  struct wl_callback * CreateFrameCallback();
+  void SetOpaqueRegion(struct wl_region *region);
+  void Commit();
+
+private:
+
+  IDllWaylandClient &m_clientLibrary;
+  struct wl_surface *m_surface;
+};
+}
+}
diff --git a/xbmc/windowing/egl/wayland/WaylandLibraries.cpp b/xbmc/windowing/egl/wayland/WaylandLibraries.cpp
new file mode 100644 (file)
index 0000000..0e77f86
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ *      Copyright (C) 2011-2013 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, see
+ *  <http://www.gnu.org/licenses/>.
+ *
+ */
+#include <sstream>
+#include <stdexcept>
+
+#include <wayland-client.h>
+#include "WaylandLibraries.h"
+
+namespace xw = xbmc::wayland;
+
+void
+xw::LoadLibrary(DllDynamic &dll)
+{
+  if (!dll.Load())
+  {
+    std::stringstream ss;
+    ss << "Failed to load library "
+       << dll.GetFile().c_str();
+
+    throw std::runtime_error(ss.str());
+  }
+}
+
+IDllWaylandClient &
+xw::Libraries::ClientLibrary()
+{
+  return m_clientLibrary.Get();
+}
+
+IDllWaylandEGL &
+xw::Libraries::EGLLibrary()
+{
+  return m_eglLibrary.Get();
+}
+
+IDllXKBCommon &
+xw::Libraries::XKBCommonLibrary()
+{
+  return m_xkbCommonLibrary.Get();
+}
diff --git a/xbmc/windowing/egl/wayland/WaylandLibraries.h b/xbmc/windowing/egl/wayland/WaylandLibraries.h
new file mode 100644 (file)
index 0000000..32f12aa
--- /dev/null
@@ -0,0 +1,84 @@
+#pragma once
+
+/*
+ *      Copyright (C) 2011-2013 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, see
+ *  <http://www.gnu.org/licenses/>.
+ *
+ */
+#include <boost/noncopyable.hpp>
+
+#include "windowing/DllWaylandClient.h"
+#include "windowing/DllWaylandEgl.h"
+#include "windowing/DllXKBCommon.h"
+
+namespace xbmc
+{
+namespace wayland
+{
+template <class DllInterface, class Dll>
+class AutoloadDll :
+  boost::noncopyable
+{
+  public:
+
+    AutoloadDll();
+    ~AutoloadDll();
+    DllInterface & Get();
+
+  private:
+
+    Dll m_dll;
+};
+
+class Libraries :
+  boost::noncopyable
+{
+public:
+
+  IDllWaylandClient & ClientLibrary();
+  IDllWaylandEGL & EGLLibrary();
+  IDllXKBCommon & XKBCommonLibrary();
+
+private:
+
+  AutoloadDll<IDllWaylandClient, DllWaylandClient> m_clientLibrary;
+  AutoloadDll<IDllWaylandEGL, DllWaylandEGL> m_eglLibrary;
+  AutoloadDll<IDllXKBCommon, DllXKBCommon> m_xkbCommonLibrary;
+};
+
+void LoadLibrary(DllDynamic &dll);
+
+template <class DllInterface, class Dll>
+AutoloadDll<DllInterface, Dll>::AutoloadDll()
+{
+  LoadLibrary(m_dll);
+}
+
+template <class DllInterface, class Dll>
+DllInterface &
+AutoloadDll<DllInterface, Dll>::Get()
+{
+  return m_dll;
+}
+
+template <class DllInterface, class Dll>
+AutoloadDll<DllInterface, Dll>::~AutoloadDll()
+{
+  m_dll.Unload();
+}
+}
+}
diff --git a/xbmc/windowing/egl/wayland/XBMCConnection.cpp b/xbmc/windowing/egl/wayland/XBMCConnection.cpp
new file mode 100644 (file)
index 0000000..b3918d7
--- /dev/null
@@ -0,0 +1,244 @@
+/*
+ *      Copyright (C) 2011-2013 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, see
+ *  <http://www.gnu.org/licenses/>.
+ *
+ */
+#include <sstream>
+#include <stdexcept>
+
+#include <boost/bind.hpp>
+#include <boost/function.hpp>
+#include <boost/scoped_ptr.hpp>
+
+#include <wayland-client.h>
+
+#include "guilib/Resolution.h"
+#include "guilib/gui3d.h"
+
+#include "windowing/DllWaylandClient.h"
+#include "windowing/DllXKBCommon.h"
+
+#include "Callback.h"
+#include "Compositor.h"
+#include "Display.h"
+#include "Registry.h"
+#include "Region.h"
+#include "Shell.h"
+
+#include "windowing/WaylandProtocol.h"
+#include "XBMCConnection.h"
+
+namespace xbmc
+{
+namespace wayland
+{
+class XBMCConnection::Private :
+  public IWaylandRegistration
+{
+public:
+
+  Private(IDllWaylandClient &clientLibrary,
+          IDllXKBCommon &xkbCommonLibrary,
+          EventInjector &eventInjector);
+  ~Private();
+
+  IDllWaylandClient &m_clientLibrary;
+  IDllXKBCommon &m_xkbCommonLibrary;
+  
+  EventInjector &m_eventInjector;
+
+  boost::scoped_ptr<Display> m_display;
+  boost::scoped_ptr<Registry> m_registry;
+  boost::scoped_ptr<Compositor> m_compositor;
+  boost::scoped_ptr<Shell> m_shell;
+
+  /* Synchronization logic - these variables should not be touched
+   * outside the scope of WaitForSynchronize() */
+  bool synchronized;
+  boost::scoped_ptr<Callback> synchronizeCallback;
+
+  /* Synchronization entry point - call this function to issue a
+   * wl_display.sync request to the server. All this does is cause
+   * the server to send back an event that acknowledges the receipt
+   * of the request. However, it is useful in a number of circumstances
+   * - all request processing in wayland is sequential and guarunteed
+   * to be in the same order as requests were made. That means that
+   * once the event is received from the server, it is guarunteed
+   * that all requests made prior to the sync request have finished
+   * processing on the server and events have been issued to us. */
+  void WaitForSynchronize();
+  
+  /* Callback function for synchronize event, do not call directly */
+  void Synchronize();
+
+  bool OnCompositorAvailable(struct wl_compositor *);
+  bool OnShellAvailable(struct wl_shell *);
+  bool OnSeatAvailable(struct wl_seat *);
+  bool OnOutputAvailable(struct wl_output *);
+};
+}
+}
+
+namespace xw = xbmc::wayland;
+
+/* Creating a new xbmc::wayland::XBMCConnection effectively creates
+ * a new xbmc::wayland::Display object, which in turn will connect
+ * to the running wayland compositor and encapsulate the return value
+ * from the client library. Then it creates a new
+ * xbmc::wayland::Registry object which is responsible for managing
+ * all of the global objects on the wayland connection that we might
+ * want to use. On creation of this object, a request is sent to
+ * the compositor to send back an event for every available global
+ * object. Once we know which objects exist, we can easily
+ * bind to them.
+ * 
+ * The WaitForSynchronize call at the end of the constructor is
+ * important. Once we make a request to the server for all of the
+ * available global objects, we need to know what they all are
+ * by the time this constructor finishes running so that the
+ * object will be complete. The only way to do that is to know
+ * when our wl_registry.add_listener request has finished processing
+ * on both the server and client side
+ */
+xw::XBMCConnection::Private::Private(IDllWaylandClient &clientLibrary,
+                                     IDllXKBCommon &xkbCommonLibrary,
+                                     EventInjector &eventInjector) :
+  m_clientLibrary(clientLibrary),
+  m_xkbCommonLibrary(xkbCommonLibrary),
+  m_eventInjector(eventInjector),
+  m_display(new xw::Display(clientLibrary)),
+  m_registry(new xw::Registry(clientLibrary,
+                              m_display->GetWlDisplay(),
+                              *this))
+{
+  /* Tell CWinEvents what our display is. That way
+   * CWinEvents::MessagePump is now able to dispatch events from
+   * the display whenever it is called */ 
+  (*m_eventInjector.setDisplay)(&clientLibrary,
+                                m_display->GetWlDisplay());
+       
+  WaitForSynchronize();
+}
+
+xw::XBMCConnection::Private::~Private()
+{
+  (*m_eventInjector.destroyDisplay)();
+}
+
+xw::XBMCConnection::XBMCConnection(IDllWaylandClient &clientLibrary,
+                                   IDllXKBCommon &xkbCommonLibrary,
+                                   EventInjector &eventInjector) :
+  priv(new Private (clientLibrary, xkbCommonLibrary, eventInjector))
+{
+}
+
+/* A defined destructor is required such that
+ * boost::scoped_ptr<Private>::~scoped_ptr is generated here */
+xw::XBMCConnection::~XBMCConnection()
+{
+}
+
+/* These are all registry callbacks. Once an object becomes available
+ * (generally speaking at construction time) then we need to
+ * create an internal representation for it so that we can use it
+ * later */
+bool xw::XBMCConnection::Private::OnCompositorAvailable(struct wl_compositor *c)
+{
+  m_compositor.reset(new xw::Compositor(m_clientLibrary, c));
+  return true;
+}
+
+bool xw::XBMCConnection::Private::OnShellAvailable(struct wl_shell *s)
+{
+  m_shell.reset(new xw::Shell(m_clientLibrary, s));
+  return true;
+}
+
+bool xw::XBMCConnection::Private::OnSeatAvailable(struct wl_seat *s)
+{
+  return true;
+}
+
+void xw::XBMCConnection::Private::WaitForSynchronize()
+{
+  boost::function<void(uint32_t)> func(boost::bind(&Private::Synchronize,
+                                                   this));
+  
+  synchronized = false;
+  synchronizeCallback.reset(new xw::Callback(m_clientLibrary,
+                                             m_display->Sync(),
+                                             func));
+  while (!synchronized)
+    (*m_eventInjector.messagePump)();
+}
+
+void xw::XBMCConnection::Private::Synchronize()
+{
+  synchronized = true;
+  synchronizeCallback.reset();
+}
+
+void
+xw::XBMCConnection::CurrentResolution(RESOLUTION_INFO &res) const
+{
+  res.iWidth = 640;
+  res.iHeight = 480;
+  res.fRefreshRate = 60;
+  res.dwFlags = D3DPRESENTFLAG_PROGRESSIVE;
+  res.iScreen = 0;
+  res.bFullScreen = true;
+  res.iSubtitles = static_cast<int>(0.965 * res.iHeight);
+  res.fPixelRatio = 1.0f;
+  res.iScreenWidth = res.iWidth;
+  res.iScreenHeight = res.iHeight;
+  res.strMode.Format("%dx%d @ %.2fp",
+                     res.iScreenWidth,
+                     res.iScreenHeight,
+                     res.fRefreshRate);
+}
+
+void
+xw::XBMCConnection::PreferredResolution(RESOLUTION_INFO &res) const
+{
+  CurrentResolution(res);
+}
+
+void
+xw::XBMCConnection::AvailableResolutions(std::vector<RESOLUTION_INFO> &res) const
+{
+  RESOLUTION_INFO resolution;
+  CurrentResolution(resolution);
+  res.push_back(resolution);
+}
+
+EGLNativeDisplayType *
+xw::XBMCConnection::NativeDisplay() const
+{
+  return priv->m_display->GetEGLNativeDisplay();
+}
+
+const boost::scoped_ptr<xw::Compositor> &
+xw::XBMCConnection::GetCompositor() const
+{
+  return priv->m_compositor;
+}
+
+const boost::scoped_ptr<xw::Shell> &
+xw::XBMCConnection::GetShell() const
+{
+  return priv->m_shell;
+}
diff --git a/xbmc/windowing/egl/wayland/XBMCConnection.h b/xbmc/windowing/egl/wayland/XBMCConnection.h
new file mode 100644 (file)
index 0000000..2c8014a
--- /dev/null
@@ -0,0 +1,80 @@
+#pragma once
+
+/*
+ *      Copyright (C) 2011-2013 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, see
+ *  <http://www.gnu.org/licenses/>.
+ *
+ */
+#include <boost/noncopyable.hpp>
+#include <boost/scoped_ptr.hpp>
+
+class IDllWaylandClient;
+class IDllXKBCommon;
+
+struct wl_compositor;
+struct wl_display;
+struct wl_output;
+struct wl_shell;
+
+typedef struct wl_egl_window * EGLNativeWindowType;
+
+struct RESOLUTION_INFO;
+
+namespace xbmc
+{
+namespace wayland
+{
+class Compositor;
+class Shell;
+
+class XBMCConnection
+{
+public:
+
+  struct EventInjector
+  {
+    typedef void (*SetWaylandDisplay)(IDllWaylandClient *clientLibrary,
+                                      struct wl_display *display);
+    typedef void (*DestroyWaylandDisplay)();
+    typedef bool (*MessagePump)();
+    
+    SetWaylandDisplay setDisplay;
+    DestroyWaylandDisplay destroyDisplay;
+    MessagePump messagePump;
+  };
+
+  XBMCConnection(IDllWaylandClient &clientLibrary,
+                 IDllXKBCommon &xkbCommonLibrary,
+                 EventInjector &injector);
+  ~XBMCConnection();
+  
+  void PreferredResolution(RESOLUTION_INFO &res) const;
+  void CurrentResolution(RESOLUTION_INFO &res) const;
+  void AvailableResolutions(std::vector<RESOLUTION_INFO> &res) const;
+  
+  EGLNativeDisplayType * NativeDisplay() const;
+  
+  const boost::scoped_ptr<Compositor> & GetCompositor() const;
+  const boost::scoped_ptr<Shell> & GetShell() const;
+  
+private:
+
+  class Private;
+  boost::scoped_ptr<Private> priv;
+};
+}
+}
diff --git a/xbmc/windowing/egl/wayland/XBMCSurface.cpp b/xbmc/windowing/egl/wayland/XBMCSurface.cpp
new file mode 100644 (file)
index 0000000..6066857
--- /dev/null
@@ -0,0 +1,200 @@
+/*
+ *      Copyright (C) 2011-2013 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, see
+ *  <http://www.gnu.org/licenses/>.
+ *
+ */
+#include <sstream>
+#include <stdexcept>
+
+#include <boost/bind.hpp>
+#include <boost/function.hpp>
+#include <boost/scoped_ptr.hpp>
+
+#include <wayland-client.h>
+
+#include "windowing/DllWaylandClient.h"
+#include "windowing/DllWaylandEgl.h"
+
+#include "Callback.h"
+#include "Compositor.h"
+#include "OpenGLSurface.h"
+#include "Region.h"
+#include "Shell.h"
+#include "ShellSurface.h"
+#include "Surface.h"
+
+#include "windowing/WaylandProtocol.h"
+#include "XBMCSurface.h"
+
+namespace xbmc
+{
+namespace wayland
+{
+class XBMCSurface::Private
+{
+public:
+
+  Private(IDllWaylandClient &clientLibrary,
+          IDllWaylandEGL &eglLibrary,
+          const boost::scoped_ptr<Compositor> &compositor,
+          const boost::scoped_ptr<Shell> &shell,
+          uint32_t width,
+          uint32_t height);
+
+  typedef boost::function<struct wl_region * ()> RegionFactory;
+
+  IDllWaylandClient &m_clientLibrary;
+  IDllWaylandEGL &m_eglLibrary;
+
+  /* We only care about xbmc::Compositor's CreateRegion function
+   * and don't want to store a pointer to the compositor to create
+   * a region later */ 
+  RegionFactory m_regionFactory;
+
+  boost::scoped_ptr<Surface> m_surface;
+  boost::scoped_ptr<ShellSurface> m_shellSurface;
+  boost::scoped_ptr<OpenGLSurface> m_glSurface;
+  boost::scoped_ptr<Callback> m_frameCallback;
+  
+  void OnFrameCallback(uint32_t);
+  void AddFrameCallback();
+};
+}
+}
+
+namespace xw = xbmc::wayland;
+
+/* Creating a new xbmc::wayland::XBMCSurface effectively creates
+ * an OpenGL ES bindable EGL Window and a corresponding 
+ * surface object for the compositor to display it on-screen. It also
+ * creates a "shell surface", which is a special extension to a normal
+ * surface which adds window-management functionality to a surface.
+ * 
+ * If there are any errors in creating the surface they will be thrown
+ * as std::runtime_errors and the object that creates this one
+ * needs to handle catching them.
+ */
+xw::XBMCSurface::Private::Private(IDllWaylandClient &clientLibrary,
+                                  IDllWaylandEGL &eglLibrary,
+                                  const boost::scoped_ptr<Compositor> &compositor,
+                                  const boost::scoped_ptr<Shell> &shell,
+                                  uint32_t width,
+                                  uint32_t height) :
+  m_clientLibrary(clientLibrary),
+  m_eglLibrary(eglLibrary),
+  m_regionFactory(boost::bind(&Compositor::CreateRegion,
+                              compositor.get())),
+  m_surface(new xw::Surface(m_clientLibrary,
+                            compositor->CreateSurface())),
+  m_shellSurface(new xw::ShellSurface(m_clientLibrary,
+                                      shell->CreateShellSurface(
+                                        m_surface->GetWlSurface()))),
+  /* Creating a new xbmc::wayland::OpenGLSurface will manage the
+   * attach-and-commit process on eglSwapBuffers */
+  m_glSurface(new xw::OpenGLSurface(m_eglLibrary,
+                                    m_surface->GetWlSurface(),
+                                    width,
+                                    height))
+{
+  /* SetOpaqueRegion here is an important optimization for the
+   * compositor. It effectively tells it that this window is completely
+   * opaque. This means that the window can be rendered without
+   * the use of GL_BLEND which represents a substantial rendering
+   * speedup, especially for larger surfaces. It also means that
+   * this window can be placed in an overlay plane, so it can
+   * skip compositing alltogether */
+  xw::Region region(m_clientLibrary, m_regionFactory());
+  
+  region.AddRectangle(0, 0, 640, 480);
+  
+  m_surface->SetOpaqueRegion(region.GetWlRegion());
+  m_surface->Commit();
+  
+  /* The compositor is responsible for letting us know when to
+   * draw things. This is effectively to conserve battery life
+   * where drawing our surface would be a futile operation. Its not
+   * entirely applicable to the xbmc case because we use a game loop,
+   * but some compositor expect it, so we must add a frame callback
+   * as soon as the surface is ready to be rendered to */ 
+  AddFrameCallback();
+}
+
+xw::XBMCSurface::XBMCSurface(IDllWaylandClient &clientLibrary,
+                             IDllWaylandEGL &eglLibrary,
+                             const boost::scoped_ptr<Compositor> &compositor,
+                             const boost::scoped_ptr<Shell> &shell,
+                             uint32_t width,
+                             uint32_t height) :
+  priv(new Private(clientLibrary,
+                   eglLibrary,
+                   compositor,
+                   shell,
+                   width,
+                   height))
+{
+}
+
+/* A defined destructor is required such that
+ * boost::scoped_ptr<Private>::~scoped_ptr is generated here */
+xw::XBMCSurface::~XBMCSurface()
+{
+}
+
+void
+xw::XBMCSurface::Show()
+{
+  protocol::CallMethodOnWaylandObject(priv->m_clientLibrary,
+                                      priv->m_shellSurface->GetWlShellSurface(),
+                                      WL_SHELL_SURFACE_SET_TOPLEVEL);
+}
+
+void
+xw::XBMCSurface::Resize(uint32_t width, uint32_t height)
+{
+  /* Since the xbmc::wayland::OpenGLSurface owns the buffer, it is
+   * responsible for changing its size. When the size changes, the
+   * opaque region must also change */
+  priv->m_glSurface->Resize(width, height);
+  
+  xw::Region region(priv->m_clientLibrary,
+                    priv->m_regionFactory());
+  
+  region.AddRectangle(0, 0, width, height);
+  
+  priv->m_surface->SetOpaqueRegion(region.GetWlRegion());
+  priv->m_surface->Commit();
+}
+
+EGLNativeWindowType *
+xw::XBMCSurface::EGLNativeWindow() const
+{
+  return priv->m_glSurface->GetEGLNativeWindow();
+}
+
+void xw::XBMCSurface::Private::OnFrameCallback(uint32_t time)
+{
+  AddFrameCallback();
+}
+
+void xw::XBMCSurface::Private::AddFrameCallback()
+{
+  m_frameCallback.reset(new xw::Callback(m_clientLibrary,
+                                         m_surface->CreateFrameCallback(),
+                                         boost::bind(&Private::OnFrameCallback,
+                                                     this,
+                                                     _1)));
+}
diff --git a/xbmc/windowing/egl/wayland/XBMCSurface.h b/xbmc/windowing/egl/wayland/XBMCSurface.h
new file mode 100644 (file)
index 0000000..ef72791
--- /dev/null
@@ -0,0 +1,66 @@
+#pragma once
+
+/*
+ *      Copyright (C) 2011-2013 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, see
+ *  <http://www.gnu.org/licenses/>.
+ *
+ */
+#include <boost/function.hpp>
+#include <boost/noncopyable.hpp>
+#include <boost/scoped_ptr.hpp>
+
+class IDllWaylandClient;
+class IDllWaylandEGL;
+
+struct wl_region;
+
+typedef struct wl_egl_window * EGLNativeWindowType;
+
+namespace xbmc
+{
+namespace wayland
+{
+class Callback;
+class Compositor;
+class OpenGLSurface;
+class Shell;
+class ShellSurface;
+class Surface;
+
+class XBMCSurface
+{
+public:
+
+  XBMCSurface(IDllWaylandClient &clientLibrary,
+              IDllWaylandEGL &eglLibrary,
+              const boost::scoped_ptr<Compositor> &compositor,
+              const boost::scoped_ptr<Shell> &shell,
+              uint32_t width,
+              uint32_t height);
+  ~XBMCSurface();
+
+  void Show();
+  void Resize(uint32_t width, uint32_t height);
+  EGLNativeWindowType * EGLNativeWindow() const;
+
+private:
+
+  class Private;
+  boost::scoped_ptr<Private> priv;
+};
+}
+}