[Jahshaka-cvs] openlibraries/src/openpluginlib/pl Makefile.am, 1.15, 1.16 openplugin.hpp, 1.6, 1.7
Status: Beta
Brought to you by:
jahshaka
From: Goncalo N. M. de C. <gl...@us...> - 2007-04-01 16:36:58
|
Update of /cvsroot/openlibraries/openlibraries/src/openpluginlib/pl In directory sc8-pr-cvs3.sourceforge.net:/tmp/cvs-serv2859/src/openpluginlib/pl Modified Files: Makefile.am openplugin.hpp openpluginlib.cpp registry.cpp Log Message: + OFX bootstrapping (see comments in code and follow-up email) Index: openplugin.hpp =================================================================== RCS file: /cvsroot/openlibraries/openlibraries/src/openpluginlib/pl/openplugin.hpp,v retrieving revision 1.6 retrieving revision 1.7 diff -u -d -r1.6 -r1.7 --- openplugin.hpp 13 Sep 2006 13:55:23 -0000 1.6 +++ openplugin.hpp 1 Apr 2007 16:36:55 -0000 1.7 @@ -45,14 +45,13 @@ openplugin_uninit uninit; openplugin_create_plugin create_plugin; openplugin_destroy_plugin destroy_plugin; - + # ifdef WIN32 HMODULE dl_handle; # else void* dl_handle; # endif - - bool dlopened; + bool dlopened; }; bool acquire_shared_symbols( plugin_resolver& resolver, const std::vector<wstring>& shared_name ); @@ -61,12 +60,16 @@ { explicit plugin_item( ) : merit( 0 ) + , context( 0 ) { } std::vector<wstring> extension, filename; wstring name, type, mime, category, libname, in_filter, out_filter; int merit; + // 3rd party plugin API support. + void* context; + plugin_resolver resolver; }; } Index: Makefile.am =================================================================== RCS file: /cvsroot/openlibraries/openlibraries/src/openpluginlib/pl/Makefile.am,v retrieving revision 1.15 retrieving revision 1.16 diff -u -d -r1.15 -r1.16 --- Makefile.am 4 Jan 2007 13:44:25 -0000 1.15 +++ Makefile.am 1 Apr 2007 16:36:55 -0000 1.16 @@ -62,11 +62,12 @@ pcos/isubject.hpp \ pcos/iclonable.hpp -libopenpluginlib_pl_la_CXXFLAGS = \ - $(OLIB_CXXFLAGS) \ - $(BOOST_INCLUDE_PATH) \ - $(GLEW_INCLUDE_PATH) \ - $(XML2_CXXFLAGS) \ +libopenpluginlib_pl_la_CXXFLAGS = \ + $(OLIB_CXXFLAGS) \ + $(BOOST_INCLUDE_PATH) \ + $(GLEW_INCLUDE_PATH) \ + $(XML2_CXXFLAGS) \ + $(OFX_INCLUDE_PATH) \ -DOPENEFFECTSLIB_SHADERS=\"$(OPENEFFECTSLIB_SHADERSPATH)/\" \ -DOPENIMAGELIB_PLUGINS=\"$(OPENIMAGELIB_PLUGINPATH)\" \ -DOPENMEDIALIB_PLUGINS=\"$(OPENMEDIALIB_PLUGINPATH)\" \ @@ -78,7 +79,8 @@ $(BOOST_REGEX_LIBS) \ $(BOOST_THREAD_LIBS) \ $(GLEW_LIBS) \ - $(XML2_LIBS) + $(XML2_LIBS) \ + $(OFX_LIBS) libopenpluginlib_pl_la_LDFLAGS = \ $(OLIB_LDFLAGS) \ Index: registry.cpp =================================================================== RCS file: /cvsroot/openlibraries/openlibraries/src/openpluginlib/pl/registry.cpp,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- registry.cpp 13 Sep 2006 13:55:23 -0000 1.3 +++ registry.cpp 1 Apr 2007 16:36:55 -0000 1.4 @@ -1,15 +1,27 @@ // openpluginlib - A plugin interface to openlibraries. -// Copyright (C) 2005-2006 VM Inc. +// Copyright (C) 2005-2007 VM Inc. // Released under the LGPL. // For more information, see http://www.openlibraries.org. +#ifdef HAVE_CONFIG_H +#include <openlibraries_global_config.hpp> +#endif + +#ifdef __APPLE__ +#include <CoreFoundation/CoreFoundation.h> +#endif + #include <boost/filesystem/operations.hpp> #include <boost/filesystem/path.hpp> #include <boost/regex.hpp> #include <boost/tokenizer.hpp> +#ifdef HAVE_OFX +#include <OfxCore.h> +#endif + #include <openpluginlib/pl/registry.hpp> #include <openpluginlib/pl/utf8_utils.hpp> #include <openpluginlib/pl/opl_importer.hpp> @@ -18,6 +30,87 @@ namespace olib { namespace openpluginlib { namespace detail { +namespace +{ + // Code replication due to OFX. There are some + // differences in how OFX plugins are specified. + // Refactoring is left as an exercise to the reader. +#ifdef WIN32 + typedef HMODULE module_t; + HMODULE dlopen_( const char* path ) +#elif defined __APPLE__ + typedef CFBundleRef module_t; + CFBundleRef dlopen_( const char* path ) +#else + typedef void* module_t; + void* dlopen_( const char* path ) +#endif + { +#ifdef WIN32 + return LoadLibrary( to_wstring( path ).c_str( ) ); +#elif defined __APPLE__ + CFStringRef bundle_str = CFStringCreateWithCString( kCFAllocatorDefault, path, kCFStringEncodingASCII ); + CFURLRef url_ref = CFURLCreateWithFileSystemPath( kCFAllocatorDefault, bundle_str, kCFURLPOSIXPathStyle, true ); + + CFBundleRef bundle = CFBundleCreate( kCFAllocatorDefault, url_ref ); + + CFRelease( url_ref ); + CFRelease( bundle_str ); + + return bundle; +#else + return dlopen( path, RTLD_GLOBAL | RTLD_NOW ); +#endif + } + + void* dlsym_( module_t shared, const char* entry_point ) + { +#ifdef WIN32 + return GetProcAddress( shared, entry_point ); +#elif defined __APPLE__ + CFStringRef entry_str = CFStringCreateWithCString( kCFAllocatorDefault, entry_point, kCFStringEncodingASCII ); + + void* entry = CFBundleGetFunctionPointerForName( shared, entry_str ); + CFRelease( entry_str ); + + return entry; +#else + return dlsym( shared, entry_point ); +#endif + } + +#ifdef WIN32 + // Replicate some of OFX types on Win32 to avoid an include dependency. + // In the unlikely event that they will change then this will have to be + // updated. + typedef struct OfxPropertySetStruct* OfxPropertySetHandle; + typedef int OfxStatus; + typedef OfxStatus ( OfxPluginEntryPoint )( const char* action, const void* handle, OfxPropertySetHandle inArgs, OfxPropertySetHandle outArgs ); + + typedef struct OfxHost + { + OfxPropertySetHandle host; + void *( *fetchSuite )( OfxPropertySetHandle host, const char* suiteName, int suiteVersion ); + } OfxHost; + + typedef struct OfxPlugin + { + const char* pluginApi; + int apiVersion; + const char* pluginIdentifier; + unsigned int pluginVersionMajor; + unsigned int pluginVersionMinor; + void ( *setHost )( OfxHost* host ); + OfxPluginEntryPoint *mainEntry; + } OfxPlugin; +#endif + +#if defined( HAVE_OFX ) || defined( WIN32 ) + typedef OfxPlugin* ( *OfxGetPluginFunc )( int ); + typedef int ( *OfxGetNumPluginsFunc )( ); +#endif +} + registry* registry::instance_ = 0; bool registry::destroyed_ = false; bool registry::was_destroyed_ = false; @@ -38,6 +131,7 @@ return false; boost::regex opl_ex( ".*\\.opl", boost::regex::extended | boost::regex::icase ); + boost::regex ofx_ex( ".*\\.ofx\\.bundle", boost::regex::extended | boost::regex::icase ); typedef boost::tokenizer<boost::char_separator<char> > tokenizer; @@ -57,6 +151,7 @@ fs::directory_iterator end_iter; for( fs::directory_iterator dir_iter( fs::path( *I, fs::native ) ); dir_iter != end_iter; ++dir_iter ) { + // OLIBs native plugins. if( boost::regex_match( ( *dir_iter ).string( ), opl_ex ) ) { opl_importer importer; @@ -64,6 +159,56 @@ std::copy( importer.plugins.begin( ), importer.plugins.end( ), std::inserter( db_, db_.begin( ) ) ); } + +# if defined( HAVE_OFX ) || defined( WIN32 ) + // OPL has support for a 3rd party API (OFX). In order to maintain + // consistency and uniformity within the framework when dealing with + // plugins, the discovery mechanism has been extended to incorporate + // discovery of OFX plugins. + // Subdirectories are not being checked - a must for OFX. + if( ( *dir_iter ).string( )[ 0 ] != '@' && boost::regex_match( ( *dir_iter ).string( ), ofx_ex ) ) + { + std::string plugin_shared = ( *dir_iter ).string( ); +# ifdef WIN32 + plugin_shared += "/Contents/Win32/" + + std::string( plugin_shared.begin( ) + plugin_shared.find_last_of( '/' ), + plugin_shared.begin( ) + plugin_shared.rfind( ".bundle" ) ); +# elif defined __APPLE__ +# else + plugin_shared += "/Contents/Linux-x86/" + + std::string( plugin_shared.begin( ) + plugin_shared.find_last_of( '/' ), + plugin_shared.begin( ) + plugin_shared.rfind( ".bundle" ) ); +# endif + module_t module = dlopen_( plugin_shared.c_str( ) ); + if( module ) + { + OfxGetNumPluginsFunc num_plugins = ( OfxGetNumPluginsFunc ) dlsym_( module, "OfxGetNumberOfPlugins" ); + OfxGetPluginFunc get_plugin = ( OfxGetPluginFunc ) dlsym_( module, "OfxGetPlugin" ); + + // OFX plugin instantiation is a little bit more complicated than shown here. + // What's below is a simplification. Please check the spec for full details. + if( num_plugins && get_plugin ) + { + int n = num_plugins( ); + for( int i = 0; i < n; ++i ) + { + OfxPlugin* plugin = get_plugin( i ); + + // For each plugin build the opl item struct. + plugin_item item; + + item.name = L"ofx_" + to_wstring( plugin->pluginIdentifier ); + item.extension.push_back( item.name ); + item.type = L"ofx"; + item.category = to_wstring( plugin->pluginApi ); + item.context = plugin; + + db_.insert( container::value_type( L"openmedialib", item ) ); + } + } + } + } +# endif } } Index: openpluginlib.cpp =================================================================== RCS file: /cvsroot/openlibraries/openlibraries/src/openpluginlib/pl/openpluginlib.cpp,v retrieving revision 1.13 retrieving revision 1.14 diff -u -d -r1.13 -r1.14 --- openpluginlib.cpp 11 Jan 2007 16:12:36 -0000 1.13 +++ openpluginlib.cpp 1 Apr 2007 16:36:55 -0000 1.14 @@ -6,17 +6,22 @@ // For more information, see http://www.openlibraries.org. #ifdef WIN32 +#define STRICT #define WIN32_LEAN_AND_MEAN #include <windows.h> +#include <shlobj.h> #endif #include <algorithm> #include <cassert> #include <functional> +#include <boost/bind.hpp> #include <boost/filesystem/path.hpp> +#include <boost/filesystem/operations.hpp> #include <boost/regex.hpp> #include <boost/thread/recursive_mutex.hpp> +#include <boost/tokenizer.hpp> #include <openpluginlib/pl/openpluginlib.hpp> #include <openpluginlib/pl/registry.hpp> @@ -59,7 +64,53 @@ wstring& str_; bool in_filter_; }; - + + // OFX search paths. + string_list get_ofx_plugin_path( ) + { + string_list paths; + + // Follow the discovery algorithm as in the OFX spec: + // search for paths in the OFX_PLUGIN_PATH + // environment variable, look in Common Files (both + // localised and non-localised locations). + char* ofx_path_env = getenv( "OFX_PLUGIN_PATH" ); + if( ofx_path_env ) + { + std::string plugin_path( ofx_path_env ); + + typedef boost::tokenizer<boost::char_separator<char> > tokenizer; +# ifdef WIN32 + boost::char_separator<char> sep( ";" ); +# else + boost::char_separator<char> sep( ":" ); +# endif + tokenizer tok( plugin_path.begin( ), plugin_path.end( ), sep ); + for( tokenizer::const_iterator I = tok.begin( ); I != tok.end( ); ++I ) + { + if( !fs::exists( fs::path( *I, fs::native ) ) || !fs::is_directory( fs::path( *I, fs::native ) ) ) continue; + paths.push_back( *I ); + } + } + +# ifdef WIN32 + TCHAR buffer[ MAX_PATH ]; + SHGetFolderPath( NULL, CSIDL_PROGRAM_FILES_COMMON, NULL, SHGFP_TYPE_CURRENT, buffer ); + + paths.push_back( to_string( wstring( buffer ) ) + "\\OFX\\Plugins" ); + + // Check non-localised path for backward compatibility reasons. + if( wcscmp( buffer, L"C:\\Program Files\\Common Files" ) ) + paths.push_back( "C:\\Program Files\\Common Files\\OFX\\Plugins" ); +# elif defined __APPLE__ + paths.push_back( "/Library/OFX/Plugins" ); +# else + paths.push_back( "/usr/OFX/Plugins" ); +# endif + + return paths; + } + void reflib( int init, const string& lookup_path = "" ) { static long refs = 0; @@ -70,7 +121,6 @@ if( init > 0 && ++refs ) { - if( refs == 1 ) { # ifdef WIN32 @@ -81,6 +131,8 @@ el_reg.insert( OPENOBJECTLIB_PLUGINS ); el_reg.insert( OPENASSETLIB_PLUGINS ); # endif + string_list ofx_paths = get_ofx_plugin_path( ); + std::for_each( ofx_paths.begin( ), ofx_paths.end( ), boost::bind( &detail::registry::insert, boost::ref( el_reg ), _1 ) ); # ifdef HAVE_CG_RUNTIME shader_manager_instance( ).create_Cg_context( ); @@ -156,9 +208,8 @@ if( item_.resolver.init( ) ) { openplugin* plugin = 0; - item_.resolver.create_plugin( options.c_str( ), &plugin ); - + if( plugin ) return opl_ptr( plugin, item_.resolver.destroy_plugin ); } } |