# 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
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. =="
[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'])],
AC_PROG_AWK
AC_PROG_LN_S
AC_PROG_MAKE_SET
+PKG_PROG_PKG_CONFIG
MAKE="${MAKE:-make}"
OBJDUMP="${OBJDUMP:-objdump}"
use_gles=yes
use_sdl=no
use_x11=no
+ use_wayland=no
;;
arm*-*linux-android*)
target_platform=target_android
use_optical_drive=no
use_sdl=no
use_x11=no
+ use_wayland=no
build_shared_lib=yes
;;
*)
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"
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
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 \
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)
/* 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
--- /dev/null
+#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;
+ }
+};
--- /dev/null
+#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()
+};
--- /dev/null
+#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()
+};
+++ /dev/null
-SRCS=WinEventsSDL.cpp \
- WinEventsLinux.cpp \
- WinSystem.cpp \
- WinEvents.cpp
-
-LIB=windowing.a
-
-include ../../Makefile.include
--include $(patsubst %.cpp,%.P,$(patsubst %.c,%.P,$(SRCS)))
--- /dev/null
+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)))
--- /dev/null
+#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);
+}
+}
+}
+}
#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
static size_t GetQueueSize();
};
-
#endif // WINDOW_EVENTS_H
--- /dev/null
+/*
+* 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
--- /dev/null
+/*
+* 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
--- /dev/null
+/*
+ * 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
+}
--- /dev/null
+#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;
+};
#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);
// 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)))
{
+++ /dev/null
-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)))
--- /dev/null
+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)))
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+#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;
+};
+}
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+#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;
+};
+}
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+#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;
+};
+}
+}
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+#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;
+};
+}
+}
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+#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;
+};
+}
+}
--- /dev/null
+/*
+ * 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 ®istration) :
+ 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);
+}
--- /dev/null
+#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 ®istration);
+ ~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);
+};
+}
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+#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;
+};
+}
+}
--- /dev/null
+/*
+ * 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()
+{
+}
--- /dev/null
+#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;
+};
+}
+}
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+#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;
+};
+}
+}
--- /dev/null
+/*
+ * 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();
+}
--- /dev/null
+#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();
+}
+}
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+#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;
+};
+}
+}
--- /dev/null
+/*
+ * 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)));
+}
--- /dev/null
+#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;
+};
+}
+}