summaryrefslogtreecommitdiffstatshomepage
path: root/src/osd/modules/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/osd/modules/lib')
-rw-r--r--src/osd/modules/lib/osdlib.h46
-rw-r--r--src/osd/modules/lib/osdlib_macosx.cpp74
-rw-r--r--src/osd/modules/lib/osdlib_unix.cpp75
-rw-r--r--src/osd/modules/lib/osdlib_win32.cpp84
4 files changed, 278 insertions, 1 deletions
diff --git a/src/osd/modules/lib/osdlib.h b/src/osd/modules/lib/osdlib.h
index f4a632dbbd1..64bd556cd3c 100644
--- a/src/osd/modules/lib/osdlib.h
+++ b/src/osd/modules/lib/osdlib.h
@@ -19,6 +19,10 @@
#ifndef __OSDLIB__
#define __OSDLIB__
+#include <string>
+#include <type_traits>
+#include <vector>
+
/*-----------------------------------------------------------------------------
osd_process_kill: kill the current process
@@ -30,8 +34,10 @@
None.
-----------------------------------------------------------------------------*/
+
void osd_process_kill(void);
+
/*-----------------------------------------------------------------------------
osd_setenv: set environment variable
@@ -48,14 +54,52 @@ void osd_process_kill(void);
int osd_setenv(const char *name, const char *value, int overwrite);
+
/*-----------------------------------------------------------------------------
osd_get_clipboard_text: retrieves text from the clipboard
Return value:
the returned string needs to be osd_free()-ed!
-
-----------------------------------------------------------------------------*/
+
char *osd_get_clipboard_text(void);
+
+/*-----------------------------------------------------------------------------
+ dynamic_module: load functions from optional shared libraries
+
+ Notes:
+
+ - Supports Mac OS X, Unix and Windows (both desktop and Windows
+ Store universal applications)
+ - A symbol can be searched in a list of libraries (e.g. more
+ revisions of a same library)
+-----------------------------------------------------------------------------*/
+
+namespace osd {
+
+class dynamic_module
+{
+public:
+ typedef std::unique_ptr<dynamic_module> ptr;
+
+ static ptr open(std::vector<std::string> &&libraries);
+
+ virtual ~dynamic_module() { };
+
+ template <typename T>
+ typename std::enable_if<std::is_pointer<T>::value, T>::type bind(char const *symbol)
+ {
+ return reinterpret_cast<T>(get_symbol_address(symbol));
+ }
+
+protected:
+ typedef void (*generic_fptr_t)();
+
+ virtual generic_fptr_t get_symbol_address(char const *symbol) = 0;
+};
+
+} // namespace osd
+
#endif /* __OSDLIB__ */
diff --git a/src/osd/modules/lib/osdlib_macosx.cpp b/src/osd/modules/lib/osdlib_macosx.cpp
index 07cfa05226a..b3a7ed642e3 100644
--- a/src/osd/modules/lib/osdlib_macosx.cpp
+++ b/src/osd/modules/lib/osdlib_macosx.cpp
@@ -13,6 +13,12 @@
#include <sys/mman.h>
#include <sys/types.h>
#include <signal.h>
+#include <dlfcn.h>
+
+#include <codecvt>
+#include <iomanip>
+#include <memory>
+
#include <mach/mach.h>
#include <mach/mach_time.h>
@@ -215,3 +221,71 @@ char *osd_get_clipboard_text(void)
return result;
}
+
+//============================================================
+// dynamic_module_posix_impl
+//============================================================
+
+namespace osd {
+
+class dynamic_module_posix_impl : public dynamic_module
+{
+public:
+ dynamic_module_posix_impl(std::vector<std::string> &libraries)
+ : m_module(nullptr)
+ {
+ m_libraries = libraries;
+ }
+
+ virtual ~dynamic_module_posix_impl() override
+ {
+ if (m_module != nullptr)
+ dlclose(m_module);
+ };
+
+protected:
+ virtual generic_fptr_t get_symbol_address(char const *symbol) override
+ {
+ /*
+ * given a list of libraries, if a first symbol is successfully loaded from
+ * one of them, all additional symbols will be loaded from the same library
+ */
+ if (m_module)
+ {
+ return reinterpret_cast<generic_fptr_t>(dlsym(m_module, symbol));
+ }
+
+ for (auto const &library : m_libraries)
+ {
+ void *module = dlopen(library.c_str(), RTLD_LAZY);
+
+ if (module != nullptr)
+ {
+ generic_fptr_t function = reinterpret_cast<generic_fptr_t>(dlsym(module, symbol));
+
+ if (function != nullptr)
+ {
+ m_module = module;
+ return function;
+ }
+ else
+ {
+ dlclose(module);
+ }
+ }
+ }
+
+ return nullptr;
+ }
+
+private:
+ std::vector<std::string> m_libraries;
+ void * m_module;
+};
+
+dynamic_module::ptr dynamic_module::open(std::vector<std::string> &&names)
+{
+ return std::make_unique<dynamic_module_posix_impl>(names);
+}
+
+} // namespace osd
diff --git a/src/osd/modules/lib/osdlib_unix.cpp b/src/osd/modules/lib/osdlib_unix.cpp
index 52999835a1c..81d9967ff64 100644
--- a/src/osd/modules/lib/osdlib_unix.cpp
+++ b/src/osd/modules/lib/osdlib_unix.cpp
@@ -13,12 +13,19 @@
#include <sys/mman.h>
#include <sys/types.h>
#include <signal.h>
+#include <dlfcn.h>
+
+#include <codecvt>
+#include <iomanip>
+#include <memory>
+
// MAME headers
#include "osdcore.h"
#include "osdlib.h"
#include <SDL2/SDL.h>
+
//============================================================
// osd_getenv
//============================================================
@@ -159,3 +166,71 @@ char *osd_get_clipboard_text(void)
}
#endif
+
+//============================================================
+// dynamic_module_posix_impl
+//============================================================
+
+namespace osd {
+
+class dynamic_module_posix_impl : public dynamic_module
+{
+public:
+ dynamic_module_posix_impl(std::vector<std::string> &libraries)
+ : m_module(nullptr)
+ {
+ m_libraries = libraries;
+ }
+
+ virtual ~dynamic_module_posix_impl() override
+ {
+ if (m_module != nullptr)
+ dlclose(m_module);
+ };
+
+protected:
+ virtual generic_fptr_t get_symbol_address(char const *symbol) override
+ {
+ /*
+ * given a list of libraries, if a first symbol is successfully loaded from
+ * one of them, all additional symbols will be loaded from the same library
+ */
+ if (m_module)
+ {
+ return reinterpret_cast<generic_fptr_t>(dlsym(m_module, symbol));
+ }
+
+ for (auto const &library : m_libraries)
+ {
+ void *module = dlopen(library.c_str(), RTLD_LAZY);
+
+ if (module != nullptr)
+ {
+ generic_fptr_t function = reinterpret_cast<generic_fptr_t>(dlsym(module, symbol));
+
+ if (function != nullptr)
+ {
+ m_module = module;
+ return function;
+ }
+ else
+ {
+ dlclose(module);
+ }
+ }
+ }
+
+ return nullptr;
+ }
+
+private:
+ std::vector<std::string> m_libraries;
+ void * m_module;
+};
+
+dynamic_module::ptr dynamic_module::open(std::vector<std::string> &&names)
+{
+ return std::make_unique<dynamic_module_posix_impl>(names);
+}
+
+} // namespace osd
diff --git a/src/osd/modules/lib/osdlib_win32.cpp b/src/osd/modules/lib/osdlib_win32.cpp
index f778977614a..e65509cc436 100644
--- a/src/osd/modules/lib/osdlib_win32.cpp
+++ b/src/osd/modules/lib/osdlib_win32.cpp
@@ -17,6 +17,8 @@
#include <unistd.h>
#endif
+#include <memory>
+
// MAME headers
#include "osdlib.h"
#include "osdcomm.h"
@@ -314,3 +316,85 @@ char *osd_get_clipboard_text(void)
return result;
}
+
+//============================================================
+// osd_dynamic_bind
+//============================================================
+
+#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
+// for classic desktop applications
+#define load_library(filename) LoadLibrary(filename)
+#else
+// for Windows Store universal applications
+#define load_library(filename) LoadPackagedLibrary(filename, 0)
+#endif
+
+namespace osd {
+
+class dynamic_module_win32_impl : public dynamic_module
+{
+public:
+ dynamic_module_win32_impl(std::vector<std::string> &libraries)
+ : m_module(nullptr)
+ {
+ m_libraries = libraries;
+ }
+
+ virtual ~dynamic_module_win32_impl() override
+ {
+ if (m_module != nullptr)
+ FreeLibrary(m_module);
+ };
+
+protected:
+ virtual generic_fptr_t get_symbol_address(char const *symbol) override
+ {
+ /*
+ * given a list of libraries, if a first symbol is successfully loaded from
+ * one of them, all additional symbols will be loaded from the same library
+ */
+ if (m_module)
+ {
+ return reinterpret_cast<generic_fptr_t>(GetProcAddress(m_module, symbol));
+ }
+
+ for (auto const &library : m_libraries)
+ {
+ TCHAR *tempstr = tstring_from_utf8(library.c_str());
+ if (!tempstr)
+ return nullptr;
+
+ HMODULE module = load_library(tempstr);
+
+ osd_free(tempstr);
+
+ if (module != nullptr)
+ {
+ generic_fptr_t function = reinterpret_cast<generic_fptr_t>(GetProcAddress(module, symbol));
+
+ if (function != nullptr)
+ {
+ m_module = module;
+ return function;
+ }
+ else
+ {
+ FreeLibrary(module);
+ }
+ }
+ }
+
+ return nullptr;
+ }
+
+private:
+ std::vector<std::string> m_libraries;
+ HMODULE m_module;
+};
+
+dynamic_module::ptr dynamic_module::open(std::vector<std::string> &&names)
+{
+ return std::make_unique<dynamic_module_win32_impl>(names);
+}
+
+} // namespace osd