diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2015-06-07 07:24:06 +0200 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2015-06-07 08:09:31 +0200 |
commit | 71856701c8bedad3d992cb63620e695df8727812 (patch) | |
tree | fd84ea540955df1510aa0cfd24b599008ad13219 /opentrack/plugin-support.cpp | |
parent | aa2de50523257778474c9c2ec8da8edbcb31cd8b (diff) |
plugin-support: make header-only, expose as public API
Issue: #151
Some global namespace macros are now prefixed with "OPENTRACK_" to avoid
namespace clashes.
This header is now safe to include in third-party projects.
Diffstat (limited to 'opentrack/plugin-support.cpp')
-rw-r--r-- | opentrack/plugin-support.cpp | 223 |
1 files changed, 0 insertions, 223 deletions
diff --git a/opentrack/plugin-support.cpp b/opentrack/plugin-support.cpp deleted file mode 100644 index 403798de..00000000 --- a/opentrack/plugin-support.cpp +++ /dev/null @@ -1,223 +0,0 @@ -#include <cstdio> -#include <cinttypes> -#include "plugin-support.h" -#include <QCoreApplication> -#include <QFile> -#include <QDir> - -#include <iostream> - -#ifndef _WIN32 -# include <dlfcn.h> -#endif - -SelectedLibraries::~SelectedLibraries() -{ -} - -template<typename t> -static mem<t> make_instance(mem<dylib> lib) -{ - mem<t> ret; - if (lib != nullptr && lib->Constructor) - { - qDebug() << "dylib" << (lib ? lib->filename : "<null>") << "ptr" << (intptr_t) lib->Constructor; - std::cout.flush(); - ret = mem<t>(reinterpret_cast<t*>(reinterpret_cast<CTOR_FUNPTR>(lib->Constructor)())); - } - return ret; -} - -SelectedLibraries::SelectedLibraries(QFrame* frame, dylibptr t, dylibptr p, dylibptr f) : - pTracker(nullptr), - pFilter(nullptr), - pProtocol(nullptr), - correct(false) -{ - pTracker = make_instance<ITracker>(t); - pProtocol = make_instance<IProtocol>(p); - pFilter = make_instance<IFilter>(f); - - if (!pTracker || !pProtocol) - { - qDebug() << "dylib load failure"; - return; - } - - if(!pProtocol->correct()) - { - qDebug() << "protocol load failure"; - return; - } - - pTracker->start_tracker(frame); - - correct = true; -} - -#if defined(__APPLE__) -# define SONAME "dylib" -#elif defined(_WIN32) -# define SONAME "dll" -#else -# define SONAME "so" -#endif - -#include <iostream> - -#ifdef _MSC_VER -# error "No support for MSVC anymore" -#else -# define LIB_PREFIX "lib" -#endif - -static bool get_metadata(mem<dylib> lib, QString& name, QIcon& icon) -{ - Metadata* meta; - if (!lib->Meta || ((meta = lib->Meta()), !meta)) - return false; - name = meta->name(); - icon = meta->icon(); - delete meta; - return true; -} - -QList<mem<dylib>> dylib::enum_libraries() -{ -#define BASE "opentrack-" -#define SUFF "-*." - const char* filters_n[] = { BASE "filter" SUFF, - BASE "tracker" SUFF, - BASE "proto" SUFF }; - const Type filters_t[] = { Filter, Tracker, Protocol }; - - QDir settingsDir( QCoreApplication::applicationDirPath() ); - - QList<mem<dylib>> ret; - - for (int i = 0; i < 3; i++) - { - QString filter = filters_n[i]; - auto t = filters_t[i]; - QStringList filenames = settingsDir.entryList(QStringList { LIB_PREFIX + filter + SONAME }, - QDir::Files, - QDir::Name); - for (int i = 0; i < filenames.size(); i++) { - QIcon icon; - QString longName; - QString str = filenames.at(i); - auto lib = std::make_shared<dylib>(str, t); - qDebug() << "Loading" << str; - std::cout.flush(); - if (!get_metadata(lib, longName, icon)) - continue; - ret.push_back(lib); - } - } - - return ret; -} - -dylib::dylib(const QString& filename, Type t) : - type(t), - filename(filename), - Dialog(nullptr), - Constructor(nullptr), - Meta(nullptr), - handle(nullptr) -{ - // otherwise dlopen opens the calling executable - if (filename.size() == 0) - return; - -#if defined(_WIN32) - QString fullPath = QCoreApplication::applicationDirPath() + "/" + this->filename; - handle = new QLibrary(fullPath); - - struct _foo { - static bool die(QLibrary*& l, bool failp) - { - if (failp) - { - qDebug() << "failed" << l->errorString(); - delete l; - l = nullptr; - } - return failp; - } - }; - - if (_foo::die(handle, !handle->load())) - return; - - Dialog = (CTOR_FUNPTR) handle->resolve("GetDialog"); - if (_foo::die(handle, !Dialog)) - return; - - Constructor = (CTOR_FUNPTR) handle->resolve("GetConstructor"); - if (_foo::die(handle, !Constructor)) - return; - - Meta = (METADATA_FUNPTR) handle->resolve("GetMetadata"); - if (_foo::die(handle, !Meta)) - return; -#else - QByteArray latin1 = QFile::encodeName(filename); - handle = dlopen(latin1.constData(), RTLD_NOW | -# if defined(__APPLE__) - RTLD_LOCAL|RTLD_FIRST|RTLD_NOW -# else - RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE -# endif - ); - - struct _foo { - static bool err(void*& handle) - { - const char* err = dlerror(); - if (err) - { - fprintf(stderr, "Error, ignoring: %s\n", err); - fflush(stderr); - dlclose(handle); - handle = nullptr; - return true; - } - return false; - } - }; - - if (handle) - { - if (_foo::err(handle)) - return; - Dialog = (CTOR_FUNPTR) dlsym(handle, "GetDialog"); - if (_foo::err(handle)) - return; - Constructor = (CTOR_FUNPTR) dlsym(handle, "GetConstructor"); - if (_foo::err(handle)) - return; - Meta = (METADATA_FUNPTR) dlsym(handle, "GetMetadata"); - if (_foo::err(handle)) - return; - } else { - (void) _foo::err(handle); - } -#endif - - auto m = mem<Metadata>(Meta()); - - icon = m->icon(); - name = m->name(); -} - -dylib::~dylib() -{ -#if defined(_WIN32) - if (handle) - delete handle; -#else - if (handle) - (void) dlclose(handle); -#endif -} |