Просмотр исходного кода

Hooked up dynamic loading for Mir.

Ryan C. Gordon 11 лет назад
Родитель
Сommit
89fd0faf5e

+ 2 - 0
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)

+ 130 - 104
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 <EGL/egl.h>
-             #include <xkbcommon/xkbcommon.h>
-             #include <mir_toolkit/mir_client_library.h>
-
-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()
 {
 

+ 66 - 40
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 <EGL/egl.h>
-             #include <xkbcommon/xkbcommon.h>
-             #include <mir_toolkit/mir_client_library.h>
-            ],[
-            ],[
-            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()
 {

+ 12 - 0
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@

+ 2 - 0
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

+ 177 - 0
src/video/mir/SDL_mirdyn.c

@@ -0,0 +1,177 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
+
+  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: */

+ 53 - 0
src/video/mir/SDL_mirdyn.h

@@ -0,0 +1,53 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
+
+  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 <EGL/egl.h>
+#include <mir_toolkit/mir_client_library.h>
+#include <xkbcommon/xkbcommon.h>
+
+#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: */

+ 3 - 1
src/video/mir/SDL_mirevents.c

@@ -37,13 +37,15 @@
 
 #include <xkbcommon/xkbcommon.h>
 
+#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';

+ 8 - 6
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, &region);
+    MIR_mir_surface_get_graphics_region(mir_window->surface, &region);
 
     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;
 }

+ 2 - 0
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()
 {

+ 4 - 3
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:

+ 48 - 0
src/video/mir/SDL_mirsym.h

@@ -0,0 +1,48 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
+
+  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: */

+ 30 - 12
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;
 }

+ 17 - 16
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 */