From 89fd0faf5e0c8f7ea82803e0378c3a248f09e0ce Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 3 Feb 2014 11:52:54 -0500 Subject: [PATCH] Hooked up dynamic loading for Mir. --- cmake/sdlchecks.cmake | 2 + configure | 234 ++++++++++++++++------------- configure.in | 106 ++++++++----- include/SDL_config.h.cmake | 12 ++ include/SDL_config.h.in | 2 + src/video/mir/SDL_mirdyn.c | 177 ++++++++++++++++++++++ src/video/mir/SDL_mirdyn.h | 53 +++++++ src/video/mir/SDL_mirevents.c | 4 +- src/video/mir/SDL_mirframebuffer.c | 14 +- src/video/mir/SDL_mirmouse.c | 2 + src/video/mir/SDL_miropengl.c | 7 +- src/video/mir/SDL_mirsym.h | 48 ++++++ src/video/mir/SDL_mirvideo.c | 42 ++++-- src/video/mir/SDL_mirwindow.c | 33 ++-- 14 files changed, 554 insertions(+), 182 deletions(-) create mode 100644 src/video/mir/SDL_mirdyn.c create mode 100644 src/video/mir/SDL_mirdyn.h create mode 100644 src/video/mir/SDL_mirsym.h diff --git a/cmake/sdlchecks.cmake b/cmake/sdlchecks.cmake index 2e48d27bb733d..15f06b05f1cd0 100644 --- a/cmake/sdlchecks.cmake +++ b/cmake/sdlchecks.cmake @@ -506,6 +506,7 @@ macro(CheckX11) endmacro(CheckX11) macro(CheckMir) +# !!! FIXME: hook up dynamic loading here. if(VIDEO_MIR) find_library(MIR_LIB mirclient mircommon egl) pkg_check_modules(MIR_TOOLKIT mirclient mircommon) @@ -529,6 +530,7 @@ endmacro(CheckMir) # Requires: # - EGL macro(CheckWayland) +# !!! FIXME: hook up dynamic loading here. if(VIDEO_WAYLAND) pkg_check_modules(WAYLAND wayland-client wayland-cursor wayland-egl egl xkbcommon) if(WAYLAND_FOUND) diff --git a/configure b/configure index c2630311c3e58..b3e256646b3a9 100755 --- a/configure +++ b/configure @@ -817,10 +817,11 @@ enable_sndio enable_sndio_shared enable_diskaudio enable_dummyaudio -enable_video_mir enable_video_wayland enable_video_wayland_qt_touch enable_wayland_shared +enable_video_mir +enable_mir_shared enable_video_x11 with_x enable_x11_shared @@ -1535,12 +1536,13 @@ Optional Features: --enable-sndio-shared dynamically load sndio audio support [[default=yes]] --enable-diskaudio support the disk writer audio driver [[default=yes]] --enable-dummyaudio support the dummy audio driver [[default=yes]] - --enable-video-mir use Mir video driver [[default=yes]] --enable-video-wayland use Wayland video driver [[default=yes]] --enable-video-wayland-qt-touch QtWayland server support for Wayland video driver [[default=yes]] --enable-wayland-shared dynamically load Wayland support [[default=maybe]] + --enable-video-mir use Mir video driver [[default=yes]] + --enable-mir-shared dynamically load Mir support [[default=maybe]] --enable-video-x11 use X11 video driver [[default=yes]] --enable-x11-shared dynamically load X11 support [[default=maybe]] --enable-video-x11-xcursor @@ -18629,105 +18631,6 @@ $as_echo "$have_gcc_preferred_stack_boundary" >&6; } fi } -CheckMir() -{ - # Check whether --enable-video-mir was given. -if test "${enable_video_mir+set}" = set; then : - enableval=$enable_video_mir; -else - enable_video_mir=yes -fi - - - if test x$enable_video = xyes -a x$enable_video_mir = xyes; then - # Extract the first word of "pkg-config", so it can be a program name with args. -set dummy pkg-config; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_PKG_CONFIG+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $PKG_CONFIG in - [\\/]* | ?:[\\/]*) - ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - test -z "$ac_cv_path_PKG_CONFIG" && ac_cv_path_PKG_CONFIG="no" - ;; -esac -fi -PKG_CONFIG=$ac_cv_path_PKG_CONFIG -if test -n "$PKG_CONFIG"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 -$as_echo "$PKG_CONFIG" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - - if test x$PKG_CONFIG != xno; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Mir support" >&5 -$as_echo_n "checking for Mir support... " >&6; } - video_mir=no - tmp_CFLAGS="$CFLAGS" - CFLAGS="$EXTRA_CFLAGS `$PKG_CONFIG --cflags egl mirclient xkbcommon`" - - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - #include - #include - #include - -int -main () -{ - - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - - video_mir=yes - -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - CFLAGS="$tmp_CFLAGS" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $video_mir" >&5 -$as_echo "$video_mir" >&6; } - - if test x$video_mir = xyes; then - $as_echo "#define SDL_VIDEO_DRIVER_MIR 1" >>confdefs.h - - SOURCES="$SOURCES $srcdir/src/video/mir/*.c" - EXTRA_CFLAGS="$EXTRA_CFLAGS `$PKG_CONFIG --cflags egl mirclient xkbcommon`" - EXTRA_LDFLAGS="$EXTRA_LDFLAGS `$PKG_CONFIG --libs egl mirclient xkbcommon`" - have_video=yes - SUMMARY_video="${SUMMARY_video} mir" - fi - fi - fi -} - CheckWarnAll() { { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GCC -Wall option" >&5 @@ -18888,8 +18791,8 @@ fi fi if test x$have_loadso != xyes && \ test x$enable_wayland_shared = xyes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: You must have SDL_LoadObject() support for dynamic WAYLAND loading" >&5 -$as_echo "$as_me: WARNING: You must have SDL_LoadObject() support for dynamic WAYLAND loading" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: You must have SDL_LoadObject() support for dynamic Wayland loading" >&5 +$as_echo "$as_me: WARNING: You must have SDL_LoadObject() support for dynamic Wayland loading" >&2;} enable_wayland_shared=no fi if test x$have_loadso = xyes && \ @@ -18901,7 +18804,7 @@ $as_echo "$as_me: WARNING: You must have SDL_LoadObject() support for dynamic WA echo "-- dynamic libwayland-client -> $wayland_client_lib" echo "-- dynamic libwayland-egl -> $wayland_egl_lib" echo "-- dynamic libwayland-cursor -> $wayland_cursor_lib" - echo "-- dynamic xkbcommon -> $xkbcommon_lib" + echo "-- dynamic libxkbcommon -> $xkbcommon_lib" cat >>confdefs.h <<_ACEOF #define SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC "$wayland_client_lib" @@ -18933,6 +18836,129 @@ _ACEOF fi } +CheckMir() +{ + # Check whether --enable-video-mir was given. +if test "${enable_video_mir+set}" = set; then : + enableval=$enable_video_mir; +else + enable_video_mir=yes +fi + + + if test x$enable_video = xyes -a x$enable_video_mir = xyes; then + # Extract the first word of "pkg-config", so it can be a program name with args. +set dummy pkg-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_PKG_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_path_PKG_CONFIG" && ac_cv_path_PKG_CONFIG="no" + ;; +esac +fi +PKG_CONFIG=$ac_cv_path_PKG_CONFIG +if test -n "$PKG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 +$as_echo "$PKG_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Mir support" >&5 +$as_echo_n "checking for Mir support... " >&6; } + video_mir=no + if test x$PKG_CONFIG != xno; then + if $PKG_CONFIG --exists mirclient egl xkbcommon ; then + MIR_CFLAGS=`$PKG_CONFIG --cflags mirclient egl xkbcommon` + MIR_LIBS=`$PKG_CONFIG --libs mirclient egl xkbcommon` + video_mir=yes + fi + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $video_mir" >&5 +$as_echo "$video_mir" >&6; } + + if test x$video_mir = xyes; then + +$as_echo "#define SDL_VIDEO_DRIVER_MIR 1" >>confdefs.h + + SOURCES="$SOURCES $srcdir/src/video/mir/*.c" + EXTRA_CFLAGS="$EXTRA_CFLAGS $MIR_CFLAGS" + # Check whether --enable-mir-shared was given. +if test "${enable_mir_shared+set}" = set; then : + enableval=$enable_mir_shared; +else + enable_mir_shared=maybe +fi + + + case "$host" in + *) + mirclient_lib=`find_lib "libmirclient.so.*" "$MIR_LIBS" | sed 's/.*\/\(.*\)/\1/; q'` + xkbcommon_lib=`find_lib "libxkbcommon.so.*" "$MIR_LIBS" | sed 's/.*\/\(.*\)/\1/; q'` + ;; + esac + + if test x$enable_mir_shared = xmaybe; then + enable_mir_shared=yes + fi + if test x$have_loadso != xyes && \ + test x$enable_mir_shared = xyes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: You must have SDL_LoadObject() support for dynamic Mir loading" >&5 +$as_echo "$as_me: WARNING: You must have SDL_LoadObject() support for dynamic Mir loading" >&2;} + enable_mir_shared=no + fi + if test x$have_loadso = xyes && \ + test x$enable_mir_shared = xyes && \ + test x$mirclient_lib != x && \ + test x$xkbcommon_lib != x; then + echo "-- dynamic libmirclient -> $mirclient_lib" + echo "-- dynamic libxkbcommon -> $xkbcommon_lib" + +cat >>confdefs.h <<_ACEOF +#define SDL_VIDEO_DRIVER_MIR_DYNAMIC "$mirclient_lib" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define SDL_VIDEO_DRIVER_MIR_DYNAMIC_XKBCOMMON "$xkbcommon_lib" +_ACEOF + + SUMMARY_video="${SUMMARY_video} mir(dynamic)" + else + enable_mir_shared=no + EXTRA_LDFLAGS="$EXTRA_LDFLAGS $MIR_LIBS" + SUMMARY_video="${SUMMARY_video} mir" + fi + have_video=yes + fi + fi +} + + CheckX11() { diff --git a/configure.in b/configure.in index 16c42fd949bb2..4af3d27de1cee 100644 --- a/configure.in +++ b/configure.in @@ -1124,44 +1124,6 @@ CheckStackBoundary() fi } -CheckMir() -{ - AC_ARG_ENABLE(video-mir, - AC_HELP_STRING([--enable-video-mir], [use Mir video driver [[default=yes]]]), - , enable_video_mir=yes) - - if test x$enable_video = xyes -a x$enable_video_mir = xyes; then - AC_PATH_PROG(PKG_CONFIG, pkg-config, no) - - if test x$PKG_CONFIG != xno; then - AC_MSG_CHECKING(for Mir support) - video_mir=no - tmp_CFLAGS="$CFLAGS" - CFLAGS="$EXTRA_CFLAGS `$PKG_CONFIG --cflags egl mirclient xkbcommon`" - - AC_TRY_COMPILE([ - #include - #include - #include - ],[ - ],[ - video_mir=yes - ]) - CFLAGS="$tmp_CFLAGS" - AC_MSG_RESULT($video_mir) - - if test x$video_mir = xyes; then - AC_DEFINE(SDL_VIDEO_DRIVER_MIR) - SOURCES="$SOURCES $srcdir/src/video/mir/*.c" - EXTRA_CFLAGS="$EXTRA_CFLAGS `$PKG_CONFIG --cflags egl mirclient xkbcommon`" - EXTRA_LDFLAGS="$EXTRA_LDFLAGS `$PKG_CONFIG --libs egl mirclient xkbcommon`" - have_video=yes - SUMMARY_video="${SUMMARY_video} mir" - fi - fi - fi -} - dnl See if GCC's -Wall is supported. CheckWarnAll() { @@ -1251,7 +1213,7 @@ AC_HELP_STRING([--enable-wayland-shared], [dynamically load Wayland support [[de fi if test x$have_loadso != xyes && \ test x$enable_wayland_shared = xyes; then - AC_MSG_WARN([You must have SDL_LoadObject() support for dynamic WAYLAND loading]) + AC_MSG_WARN([You must have SDL_LoadObject() support for dynamic Wayland loading]) enable_wayland_shared=no fi if test x$have_loadso = xyes && \ @@ -1263,7 +1225,7 @@ AC_HELP_STRING([--enable-wayland-shared], [dynamically load Wayland support [[de echo "-- dynamic libwayland-client -> $wayland_client_lib" echo "-- dynamic libwayland-egl -> $wayland_egl_lib" echo "-- dynamic libwayland-cursor -> $wayland_cursor_lib" - echo "-- dynamic xkbcommon -> $xkbcommon_lib" + echo "-- dynamic libxkbcommon -> $xkbcommon_lib" AC_DEFINE_UNQUOTED(SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC, "$wayland_client_lib", [ ]) AC_DEFINE_UNQUOTED(SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_EGL, "$wayland_egl_lib", [ ]) AC_DEFINE_UNQUOTED(SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_CURSOR, "$wayland_cursor_lib", [ ]) @@ -1279,6 +1241,70 @@ AC_HELP_STRING([--enable-wayland-shared], [dynamically load Wayland support [[de fi } +dnl Check for Mir +CheckMir() +{ + AC_ARG_ENABLE(video-mir, +AC_HELP_STRING([--enable-video-mir], [use Mir video driver [[default=yes]]]), + ,enable_video_mir=yes) + + if test x$enable_video = xyes -a x$enable_video_mir = xyes; then + AC_PATH_PROG(PKG_CONFIG, pkg-config, no) + AC_MSG_CHECKING(for Mir support) + video_mir=no + if test x$PKG_CONFIG != xno; then + if $PKG_CONFIG --exists mirclient egl xkbcommon ; then + MIR_CFLAGS=`$PKG_CONFIG --cflags mirclient egl xkbcommon` + MIR_LIBS=`$PKG_CONFIG --libs mirclient egl xkbcommon` + video_mir=yes + fi + fi + AC_MSG_RESULT($video_mir) + + if test x$video_mir = xyes; then + AC_DEFINE(SDL_VIDEO_DRIVER_MIR, 1, [ ]) + SOURCES="$SOURCES $srcdir/src/video/mir/*.c" + EXTRA_CFLAGS="$EXTRA_CFLAGS $MIR_CFLAGS" + AC_ARG_ENABLE(mir-shared, +AC_HELP_STRING([--enable-mir-shared], [dynamically load Mir support [[default=maybe]]]), + , enable_mir_shared=maybe) + + dnl FIXME: Do BSD and OS X need special cases? + case "$host" in + *) + mirclient_lib=[`find_lib "libmirclient.so.*" "$MIR_LIBS" | sed 's/.*\/\(.*\)/\1/; q'`] + xkbcommon_lib=[`find_lib "libxkbcommon.so.*" "$MIR_LIBS" | sed 's/.*\/\(.*\)/\1/; q'`] + ;; + esac + + if test x$enable_mir_shared = xmaybe; then + enable_mir_shared=yes + fi + if test x$have_loadso != xyes && \ + test x$enable_mir_shared = xyes; then + AC_MSG_WARN([You must have SDL_LoadObject() support for dynamic Mir loading]) + enable_mir_shared=no + fi + if test x$have_loadso = xyes && \ + test x$enable_mir_shared = xyes && \ + test x$mirclient_lib != x && \ + test x$xkbcommon_lib != x; then + echo "-- dynamic libmirclient -> $mirclient_lib" + echo "-- dynamic libxkbcommon -> $xkbcommon_lib" + AC_DEFINE_UNQUOTED(SDL_VIDEO_DRIVER_MIR_DYNAMIC, "$mirclient_lib", [ ]) + AC_DEFINE_UNQUOTED(SDL_VIDEO_DRIVER_MIR_DYNAMIC_XKBCOMMON, "$xkbcommon_lib", [ ]) + SUMMARY_video="${SUMMARY_video} mir(dynamic)" + else + enable_mir_shared=no + EXTRA_LDFLAGS="$EXTRA_LDFLAGS $MIR_LIBS" + SUMMARY_video="${SUMMARY_video} mir" + fi + have_video=yes + fi + fi +} + + dnl Find the X11 include and library directories CheckX11() { diff --git a/include/SDL_config.h.cmake b/include/SDL_config.h.cmake index ca731f3f96718..41bc9e1a5e0f1 100644 --- a/include/SDL_config.h.cmake +++ b/include/SDL_config.h.cmake @@ -259,7 +259,19 @@ #cmakedefine SDL_VIDEO_DRIVER_DUMMY @SDL_VIDEO_DRIVER_DUMMY@ #cmakedefine SDL_VIDEO_DRIVER_WINDOWS @SDL_VIDEO_DRIVER_WINDOWS@ #cmakedefine SDL_VIDEO_DRIVER_WAYLAND @SDL_VIDEO_DRIVER_WAYLAND@ + +#if 0 +/* !!! FIXME: in configure script version, missing here: */ +#undef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH +#undef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC +#undef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_EGL +#undef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_CURSOR +#undef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_XKBCOMMON +#endif + #cmakedefine SDL_VIDEO_DRIVER_MIR @SDL_VIDEO_DRIVER_MIR@ +#cmakedefine SDL_VIDEO_DRIVER_MIR_DYNAMIC @SDL_VIDEO_DRIVER_MIR_DYNAMIC@ +#cmakedefine SDL_VIDEO_DRIVER_MIR_DYNAMIC_XKBCOMMON @SDL_VIDEO_DRIVER_MIR_DYNAMIC_XKBCOMMON@ #cmakedefine SDL_VIDEO_DRIVER_X11 @SDL_VIDEO_DRIVER_X11@ #cmakedefine SDL_VIDEO_DRIVER_X11_DYNAMIC @SDL_VIDEO_DRIVER_X11_DYNAMIC@ #cmakedefine SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT @SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT@ diff --git a/include/SDL_config.h.in b/include/SDL_config.h.in index eb9d805c36a84..9ad2d3d27fc52 100644 --- a/include/SDL_config.h.in +++ b/include/SDL_config.h.in @@ -268,6 +268,8 @@ #undef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_CURSOR #undef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_XKBCOMMON #undef SDL_VIDEO_DRIVER_MIR +#undef SDL_VIDEO_DRIVER_MIR_DYNAMIC +#undef SDL_VIDEO_DRIVER_MIR_DYNAMIC_XKBCOMMON #undef SDL_VIDEO_DRIVER_X11 #undef SDL_VIDEO_DRIVER_RPI #undef SDL_VIDEO_DRIVER_X11_DYNAMIC diff --git a/src/video/mir/SDL_mirdyn.c b/src/video/mir/SDL_mirdyn.c new file mode 100644 index 0000000000000..f544d06ec5f10 --- /dev/null +++ b/src/video/mir/SDL_mirdyn.c @@ -0,0 +1,177 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2014 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_MIR + +#define DEBUG_DYNAMIC_MIR 0 + +#include "SDL_mirdyn.h" + +#if DEBUG_DYNAMIC_MIR +#include "SDL_log.h" +#endif + +#ifdef SDL_VIDEO_DRIVER_MIR_DYNAMIC + +#include "SDL_name.h" +#include "SDL_loadso.h" + +typedef struct +{ + void *lib; + const char *libname; +} mirdynlib; + +#ifndef SDL_VIDEO_DRIVER_MIR_DYNAMIC +#define SDL_VIDEO_DRIVER_MIR_DYNAMIC NULL +#endif +#ifndef SDL_VIDEO_DRIVER_MIR_DYNAMIC_XKBCOMMON +#define SDL_VIDEO_DRIVER_MIR_DYNAMIC_XKBCOMMON NULL +#endif + +static mirdynlib mirlibs[] = { + {NULL, SDL_VIDEO_DRIVER_MIR_DYNAMIC}, + {NULL, SDL_VIDEO_DRIVER_MIR_DYNAMIC_XKBCOMMON} +}; + +static void * +MIR_GetSym(const char *fnname, int *pHasModule) +{ + int i; + void *fn = NULL; + for (i = 0; i < SDL_TABLESIZE(mirlibs); i++) { + if (mirlibs[i].lib != NULL) { + fn = SDL_LoadFunction(mirlibs[i].lib, fnname); + if (fn != NULL) + break; + } + } + +#if DEBUG_DYNAMIC_MIR + if (fn != NULL) + SDL_Log("MIR: Found '%s' in %s (%p)\n", fnname, mirlibs[i].libname, fn); + else + SDL_Log("MIR: Symbol '%s' NOT FOUND!\n", fnname); +#endif + + if (fn == NULL) + *pHasModule = 0; /* kill this module. */ + + return fn; +} + +#endif /* SDL_VIDEO_DRIVER_MIR_DYNAMIC */ + +/* Define all the function pointers and wrappers... */ +#define SDL_MIR_MODULE(modname) int SDL_MIR_HAVE_##modname = 0; +#define SDL_MIR_SYM(rc,fn,params) SDL_DYNMIRFN_##fn MIR_##fn = NULL; +#include "SDL_mirsym.h" +#undef SDL_MIR_MODULE +#undef SDL_MIR_SYM + +static int mir_load_refcount = 0; + +void +SDL_MIR_UnloadSymbols(void) +{ + /* Don't actually unload if more than one module is using the libs... */ + if (mir_load_refcount > 0) { + if (--mir_load_refcount == 0) { +#ifdef SDL_VIDEO_DRIVER_MIR_DYNAMIC + int i; +#endif + + /* set all the function pointers to NULL. */ +#define SDL_MIR_MODULE(modname) SDL_MIR_HAVE_##modname = 0; +#define SDL_MIR_SYM(rc,fn,params) MIR_##fn = NULL; +#include "SDL_mirsym.h" +#undef SDL_MIR_MODULE +#undef SDL_MIR_SYM + + +#ifdef SDL_VIDEO_DRIVER_MIR_DYNAMIC + for (i = 0; i < SDL_TABLESIZE(mirlibs); i++) { + if (mirlibs[i].lib != NULL) { + SDL_UnloadObject(mirlibs[i].lib); + mirlibs[i].lib = NULL; + } + } +#endif + } + } +} + +/* returns non-zero if all needed symbols were loaded. */ +int +SDL_MIR_LoadSymbols(void) +{ + int rc = 1; /* always succeed if not using Dynamic MIR stuff. */ + + /* deal with multiple modules (dga, wayland, mir, etc) needing these symbols... */ + if (mir_load_refcount++ == 0) { +#ifdef SDL_VIDEO_DRIVER_MIR_DYNAMIC + int i; + int *thismod = NULL; + for (i = 0; i < SDL_TABLESIZE(mirlibs); i++) { + if (mirlibs[i].libname != NULL) { + mirlibs[i].lib = SDL_LoadObject(mirlibs[i].libname); + } + } + +#define SDL_MIR_MODULE(modname) SDL_MIR_HAVE_##modname = 1; /* default yes */ +#define SDL_MIR_SYM(rc,fn,params) +#include "SDL_mirsym.h" +#undef SDL_MIR_MODULE +#undef SDL_MIR_SYM + +#define SDL_MIR_MODULE(modname) thismod = &SDL_MIR_HAVE_##modname; +#define SDL_MIR_SYM(rc,fn,params) MIR_##fn = (SDL_DYNMIRFN_##fn) MIR_GetSym(#fn,thismod); +#include "SDL_mirsym.h" +#undef SDL_MIR_MODULE +#undef SDL_MIR_SYM + + if ((SDL_MIR_HAVE_MIR_CLIENT) && (SDL_MIR_HAVE_XKBCOMMON)) { + /* all required symbols loaded. */ + SDL_ClearError(); + } else { + /* in case something got loaded... */ + SDL_MIR_UnloadSymbols(); + rc = 0; + } + +#else /* no dynamic MIR */ + +#define SDL_MIR_MODULE(modname) SDL_MIR_HAVE_##modname = 1; /* default yes */ +#define SDL_MIR_SYM(rc,fn,params) MIR_##fn = fn; +#include "SDL_mirsym.h" +#undef SDL_MIR_MODULE +#undef SDL_MIR_SYM + +#endif + } + + return rc; +} + +#endif /* SDL_VIDEO_DRIVER_MIR */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/mir/SDL_mirdyn.h b/src/video/mir/SDL_mirdyn.h new file mode 100644 index 0000000000000..3bd62e14e9cec --- /dev/null +++ b/src/video/mir/SDL_mirdyn.h @@ -0,0 +1,53 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2014 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef _SDL_mirdyn_h +#define _SDL_mirdyn_h + +#include "../../SDL_internal.h" + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +int SDL_MIR_LoadSymbols(void); +void SDL_MIR_UnloadSymbols(void); + +/* Declare all the function pointers and wrappers... */ +#define SDL_MIR_MODULE(modname) +#define SDL_MIR_SYM(rc,fn,params) \ + typedef rc (*SDL_DYNMIRFN_##fn) params; \ + extern SDL_DYNMIRFN_##fn MIR_##fn; +#include "SDL_mirsym.h" +#undef SDL_MIR_MODULE +#undef SDL_MIR_SYM + +#ifdef __cplusplus +} +#endif + +#endif /* !defined _SDL_mirdyn_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/mir/SDL_mirevents.c b/src/video/mir/SDL_mirevents.c index 9339a3ca64ab1..f2d3ef38234be 100644 --- a/src/video/mir/SDL_mirevents.c +++ b/src/video/mir/SDL_mirevents.c @@ -37,13 +37,15 @@ #include +#include "SDL_mirdyn.h" + static void HandleKeyText(int32_t key_code) { char text[8]; int size = 0; - size = xkb_keysym_to_utf8(key_code, text, sizeof text); + size = MIR_xkb_keysym_to_utf8(key_code, text, sizeof text); if (size > 0) { text[size] = '\0'; diff --git a/src/video/mir/SDL_mirframebuffer.c b/src/video/mir/SDL_mirframebuffer.c index 26badf9ff582c..22f290b9184f6 100644 --- a/src/video/mir/SDL_mirframebuffer.c +++ b/src/video/mir/SDL_mirframebuffer.c @@ -31,6 +31,8 @@ #include "SDL_mirframebuffer.h" #include "SDL_mirwindow.h" +#include "SDL_mirdyn.h" + static const Uint32 mir_pixel_format_to_sdl_format[] = { SDL_PIXELFORMAT_UNKNOWN, /* mir_pixel_format_invalid */ SDL_PIXELFORMAT_ABGR8888, /* mir_pixel_format_abgr_8888 */ @@ -59,7 +61,7 @@ MIR_CreateWindowFramebuffer(_THIS, SDL_Window* window, Uint32* format, mir_window = window->driverdata; - mir_surface_get_parameters(mir_window->surface, &surfaceparm); + MIR_mir_surface_get_parameters(mir_window->surface, &surfaceparm); *format = MIR_GetSDLPixelFormat(surfaceparm.pixel_format); if (*format == SDL_PIXELFORMAT_UNKNOWN) @@ -71,9 +73,9 @@ MIR_CreateWindowFramebuffer(_THIS, SDL_Window* window, Uint32* format, if (*pixels == NULL) return SDL_OutOfMemory(); - mir_window->surface = mir_connection_create_surface_sync(mir_data->connection, &surfaceparm); - if (!mir_surface_is_valid(mir_window->surface)) { - const char* error = mir_surface_get_error_message(mir_window->surface); + mir_window->surface = MIR_mir_connection_create_surface_sync(mir_data->connection, &surfaceparm); + if (!MIR_mir_surface_is_valid(mir_window->surface)) { + const char* error = MIR_mir_surface_get_error_message(mir_window->surface); return SDL_SetError("Failed to created a mir surface: %s", error); } @@ -90,7 +92,7 @@ MIR_UpdateWindowFramebuffer(_THIS, SDL_Window* window, int i, j, x, y, w, h, start; int bytes_per_pixel, bytes_per_row, s_stride, d_stride; - mir_surface_get_graphics_region(mir_window->surface, ®ion); + MIR_mir_surface_get_graphics_region(mir_window->surface, ®ion); char* s_dest = region.vaddr; char* pixels = (char*)window->surface->pixels; @@ -138,7 +140,7 @@ MIR_UpdateWindowFramebuffer(_THIS, SDL_Window* window, } } - mir_surface_swap_buffers_sync(mir_window->surface); + MIR_mir_surface_swap_buffers_sync(mir_window->surface); return 0; } diff --git a/src/video/mir/SDL_mirmouse.c b/src/video/mir/SDL_mirmouse.c index 27976a5f6d1c9..def9dbd06d5c7 100644 --- a/src/video/mir/SDL_mirmouse.c +++ b/src/video/mir/SDL_mirmouse.c @@ -32,6 +32,8 @@ #include "../../events/SDL_mouse_c.h" #include "SDL_assert.h" +#include "SDL_mirdyn.h" + static SDL_Cursor* MIR_CreateDefaultCursor() { diff --git a/src/video/mir/SDL_miropengl.c b/src/video/mir/SDL_miropengl.c index c5b36a3ae59a2..510ad3c0e6207 100644 --- a/src/video/mir/SDL_miropengl.c +++ b/src/video/mir/SDL_miropengl.c @@ -33,6 +33,8 @@ #define DEFAULT_OGL_ES2 "libGLESv2.so" +#include "SDL_mirdyn.h" + void* MIR_GLHandle = NULL; void @@ -70,8 +72,7 @@ MIR_GL_LoadLibrary(_THIS, const char* path) { MIR_Data* mir_data = _this->driverdata; - SDL_EGL_LoadLibrary(_this, path, - mir_connection_get_egl_native_display(mir_data->connection)); + SDL_EGL_LoadLibrary(_this, path, MIR_mir_connection_get_egl_native_display(mir_data->connection)); SDL_EGL_ChooseConfig(_this); @@ -103,7 +104,7 @@ Ensure_GL_HandleOpen() void* MIR_GL_GetProcAddress(_THIS, const char* proc) { - void* proc_addr = eglGetProcAddress(proc); + void* proc_addr = SDL_EGL_GetProcAddress(_this, proc); /* FIXME when on the phone/tablet eglGetProcAddress returns NULL through libhybris, seems to be a problem in android. Also looks like a problem in the android video driver: diff --git a/src/video/mir/SDL_mirsym.h b/src/video/mir/SDL_mirsym.h new file mode 100644 index 0000000000000..fe495e3e55dc9 --- /dev/null +++ b/src/video/mir/SDL_mirsym.h @@ -0,0 +1,48 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2014 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/* *INDENT-OFF* */ + +SDL_MIR_MODULE(MIR_CLIENT) +SDL_MIR_SYM(MirDisplayConfiguration*,mir_connection_create_display_config,(MirConnection *connection)) +SDL_MIR_SYM(MirSurface *,mir_connection_create_surface_sync,(MirConnection *connection, MirSurfaceParameters const *params)) +SDL_MIR_SYM(void,mir_connection_get_available_surface_formats,(MirConnection* connection, MirPixelFormat* formats, unsigned const int format_size, unsigned int *num_valid_formats)) +SDL_MIR_SYM(MirEGLNativeDisplayType,mir_connection_get_egl_native_display,(MirConnection *connection)) +SDL_MIR_SYM(int,mir_connection_is_valid,(MirConnection *connection)) +SDL_MIR_SYM(void,mir_connection_release,(MirConnection *connection)) +SDL_MIR_SYM(MirConnection *,mir_connect_sync,(char const *server, char const *app_name)) +SDL_MIR_SYM(void,mir_display_config_destroy,(MirDisplayConfiguration* display_configuration)) +SDL_MIR_SYM(MirEGLNativeWindowType,mir_surface_get_egl_native_window,(MirSurface *surface)) +SDL_MIR_SYM(char const *,mir_surface_get_error_message,(MirSurface *surface)) +SDL_MIR_SYM(void,mir_surface_get_graphics_region,(MirSurface *surface, MirGraphicsRegion *graphics_region)) +SDL_MIR_SYM(void,mir_surface_get_parameters,(MirSurface *surface, MirSurfaceParameters *parameters)) +SDL_MIR_SYM(int,mir_surface_is_valid,(MirSurface *surface)) +SDL_MIR_SYM(void,mir_surface_release_sync,(MirSurface *surface)) +SDL_MIR_SYM(void,mir_surface_set_event_handler,(MirSurface *surface, MirEventDelegate const *event_handler)) +SDL_MIR_SYM(MirWaitHandle*,mir_surface_set_type,(MirSurface *surface, MirSurfaceType type)) +SDL_MIR_SYM(void,mir_surface_swap_buffers_sync,(MirSurface *surface)) + +SDL_MIR_MODULE(XKBCOMMON) +SDL_MIR_SYM(int,xkb_keysym_to_utf8,(xkb_keysym_t keysym, char *buffer, size_t size)) + +/* *INDENT-ON* */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/mir/SDL_mirvideo.c b/src/video/mir/SDL_mirvideo.c index c160f37431c03..ad6de151bf9d0 100644 --- a/src/video/mir/SDL_mirvideo.c +++ b/src/video/mir/SDL_mirvideo.c @@ -35,6 +35,8 @@ #include "SDL_mirvideo.h" #include "SDL_mirwindow.h" +#include "SDL_mirdyn.h" + #define MIR_DRIVER_NAME "mir" static int @@ -74,13 +76,23 @@ MIR_ResizeWindowShape(SDL_Window* window) static int MIR_Available() { - return 1; + int available = 0; + + if (SDL_MIR_LoadSymbols()) { + /* !!! FIXME: try to make a MirConnection here. */ + available = 1; + SDL_MIR_UnloadSymbols(); + + } + + return available; } static void MIR_DeleteDevice(SDL_VideoDevice* device) { SDL_free(device); + SDL_MIR_UnloadSymbols(); } void @@ -92,16 +104,24 @@ static SDL_VideoDevice* MIR_CreateDevice(int device_index) { MIR_Data* mir_data; - SDL_VideoDevice* device = SDL_calloc(1, sizeof(SDL_VideoDevice)); + SDL_VideoDevice* device = NULL; + + if (!SDL_MIR_LoadSymbols()) { + return NULL; + } + + device = SDL_calloc(1, sizeof(SDL_VideoDevice)); if (!device) { + SDL_MIR_UnloadSymbols(); SDL_OutOfMemory(); return NULL; } mir_data = SDL_calloc(1, sizeof(MIR_Data)); if (!mir_data) { - SDL_OutOfMemory(); SDL_free(device); + SDL_MIR_UnloadSymbols(); + SDL_OutOfMemory(); return NULL; } @@ -225,8 +245,7 @@ MIR_InitDisplays(_THIS) MIR_Data* mir_data = _this->driverdata; int d; - MirDisplayConfiguration* display_config = - mir_connection_create_display_config(mir_data->connection); + MirDisplayConfiguration* display_config = MIR_mir_connection_create_display_config(mir_data->connection); for (d = 0; d < display_config->num_outputs; d++) { MirDisplayOutput const* out = display_config->outputs + d; @@ -246,7 +265,7 @@ MIR_InitDisplays(_THIS) } } - mir_display_config_destroy(display_config); + MIR_mir_display_config_destroy(display_config); } int @@ -254,9 +273,9 @@ MIR_VideoInit(_THIS) { MIR_Data* mir_data = _this->driverdata; - mir_data->connection = mir_connect_sync(NULL, __PRETTY_FUNCTION__); + mir_data->connection = MIR_mir_connect_sync(NULL, __PRETTY_FUNCTION__); - if (!mir_connection_is_valid(mir_data->connection)) + if (!MIR_mir_connection_is_valid(mir_data->connection)) return SDL_SetError("Failed to connect to the Mir Server"); MIR_InitDisplays(_this); @@ -275,7 +294,7 @@ MIR_VideoQuit(_THIS) MIR_GL_DeleteContext(_this, NULL); MIR_GL_UnloadLibrary(_this); - mir_connection_release(mir_data->connection); + MIR_mir_connection_release(mir_data->connection); SDL_free(mir_data); _this->driverdata = NULL; @@ -287,8 +306,7 @@ MIR_GetDisplayBounds(_THIS, SDL_VideoDisplay* display, SDL_Rect* rect) MIR_Data* mir_data = _this->driverdata; int d; - MirDisplayConfiguration* display_config = - mir_connection_create_display_config(mir_data->connection); + MirDisplayConfiguration* display_config = MIR_mir_connection_create_display_config(mir_data->connection); for (d = 0; d < display_config->num_outputs; d++) { MirDisplayOutput const* out = display_config->outputs + d; @@ -305,7 +323,7 @@ MIR_GetDisplayBounds(_THIS, SDL_VideoDisplay* display, SDL_Rect* rect) } } - mir_display_config_destroy(display_config); + MIR_mir_display_config_destroy(display_config); return 0; } diff --git a/src/video/mir/SDL_mirwindow.c b/src/video/mir/SDL_mirwindow.c index 519f8b3ce3dda..d233db47ffdce 100644 --- a/src/video/mir/SDL_mirwindow.c +++ b/src/video/mir/SDL_mirwindow.c @@ -33,11 +33,13 @@ #include "SDL_mirevents.h" #include "SDL_mirwindow.h" +#include "SDL_mirdyn.h" + int IsSurfaceValid(MIR_Window* mir_window) { - if (!mir_surface_is_valid(mir_window->surface)) { - const char* error = mir_surface_get_error_message(mir_window->surface); + if (!MIR_mir_surface_is_valid(mir_window->surface)) { + const char* error = MIR_mir_surface_get_error_message(mir_window->surface); return SDL_SetError("Failed to created a mir surface: %s", error); } @@ -52,7 +54,7 @@ FindValidPixelFormat(MIR_Data* mir_data) unsigned int f; MirPixelFormat formats[pf_size]; - mir_connection_get_available_surface_formats(mir_data->connection, formats, + MIR_mir_connection_get_available_surface_formats(mir_data->connection, formats, pf_size, &valid_formats); for (f = 0; f < valid_formats; f++) { @@ -111,15 +113,15 @@ MIR_CreateWindow(_THIS, SDL_Window* window) return SDL_SetError("Failed to find a valid pixel format."); } - mir_window->surface = mir_connection_create_surface_sync(mir_data->connection, &surfaceparm); - if (!mir_surface_is_valid(mir_window->surface)) { - const char* error = mir_surface_get_error_message(mir_window->surface); + mir_window->surface = MIR_mir_connection_create_surface_sync(mir_data->connection, &surfaceparm); + if (!MIR_mir_surface_is_valid(mir_window->surface)) { + const char* error = MIR_mir_surface_get_error_message(mir_window->surface); return SDL_SetError("Failed to created a mir surface: %s", error); } if (window->flags & SDL_WINDOW_OPENGL) { EGLNativeWindowType egl_native_window = - (EGLNativeWindowType)mir_surface_get_egl_native_window(mir_window->surface); + (EGLNativeWindowType)MIR_mir_surface_get_egl_native_window(mir_window->surface); mir_window->egl_surface = SDL_EGL_CreateSurface(_this, egl_native_window); @@ -132,7 +134,7 @@ MIR_CreateWindow(_THIS, SDL_Window* window) mir_window->egl_surface = EGL_NO_SURFACE; } - mir_surface_set_event_handler(mir_window->surface, &delegate); + MIR_mir_surface_set_event_handler(mir_window->surface, &delegate); return 0; } @@ -147,7 +149,7 @@ MIR_DestroyWindow(_THIS, SDL_Window* window) if (mir_data) { SDL_EGL_DestroySurface(_this, mir_window->egl_surface); - mir_surface_release_sync(mir_window->surface); + MIR_mir_surface_release_sync(mir_window->surface); SDL_free(mir_window); } @@ -181,10 +183,9 @@ MIR_SetWindowFullscreen(_THIS, SDL_Window* window, return; if (fullscreen) { - mir_surface_set_type(mir_window->surface, mir_surface_state_fullscreen); - } - else { - mir_surface_set_type(mir_window->surface, mir_surface_state_restored); + MIR_mir_surface_set_type(mir_window->surface, mir_surface_state_fullscreen); + } else { + MIR_mir_surface_set_type(mir_window->surface, mir_surface_state_restored); } } @@ -196,7 +197,7 @@ MIR_MaximizeWindow(_THIS, SDL_Window* window) if (IsSurfaceValid(mir_window) < 0) return; - mir_surface_set_type(mir_window->surface, mir_surface_state_maximized); + MIR_mir_surface_set_type(mir_window->surface, mir_surface_state_maximized); } void @@ -207,7 +208,7 @@ MIR_MinimizeWindow(_THIS, SDL_Window* window) if (IsSurfaceValid(mir_window) < 0) return; - mir_surface_set_type(mir_window->surface, mir_surface_state_minimized); + MIR_mir_surface_set_type(mir_window->surface, mir_surface_state_minimized); } void @@ -218,7 +219,7 @@ MIR_RestoreWindow(_THIS, SDL_Window * window) if (IsSurfaceValid(mir_window) < 0) return; - mir_surface_set_type(mir_window->surface, mir_surface_state_restored); + MIR_mir_surface_set_type(mir_window->surface, mir_surface_state_restored); } #endif /* SDL_VIDEO_DRIVER_MIR */