diff --git a/CMakeLists.txt b/CMakeLists.txt index a7b32279..4977cc64 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -76,7 +76,7 @@ if (UNIX) # warnings as errors: # we have a problem with people checking in code with warnings. - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -fPIC") # For config.h, detect the libraries, functions, etc. include(CheckIncludeFiles) @@ -174,7 +174,7 @@ if (UNIX) CACHE STRING "" FORCE) else() # >= 10.6: Intel only - set(CMAKE_OSX_ARCHITECTURES "i386;x86_64" + set(CMAKE_OSX_ARCHITECTURES "i386" CACHE STRING "" FORCE) endif() diff --git a/src/lib/arch/CMakeLists.txt b/src/lib/arch/CMakeLists.txt index 131bec78..12946107 100644 --- a/src/lib/arch/CMakeLists.txt +++ b/src/lib/arch/CMakeLists.txt @@ -50,5 +50,5 @@ endif() add_library(arch STATIC ${sources}) if (UNIX) - target_link_libraries(arch ${libs}) + target_link_libraries(arch dl ${libs}) endif() diff --git a/src/lib/arch/unix/ArchPluginUnix.cpp b/src/lib/arch/unix/ArchPluginUnix.cpp index 5cdacf3c..18d21345 100644 --- a/src/lib/arch/unix/ArchPluginUnix.cpp +++ b/src/lib/arch/unix/ArchPluginUnix.cpp @@ -18,6 +18,22 @@ #include "arch/unix/ArchPluginUnix.h" +#include "arch/unix/XArchUnix.h" +#include "base/IEventQueue.h" +#include "base/Event.h" +#include "base/Log.h" + +#include +#include +#include +#include + +typedef int (*initFunc)(void (*sendEvent)(const char*, void*), void (*log)(const char*)); +typedef void* (*invokeFunc)(const char*, void*); + +void* g_eventTarget = NULL; +IEventQueue* g_events = NULL; + ArchPluginUnix::ArchPluginUnix() { } @@ -26,7 +42,109 @@ ArchPluginUnix::~ArchPluginUnix() { } +void +ArchPluginUnix::load() +{ + String pluginsDir = getPluginsDir(); + LOG((CLOG_DEBUG "plugins dir: %s", pluginsDir.c_str())); + + struct dirent* de = NULL; + DIR* dir = NULL; + + dir = opendir(pluginsDir.c_str()); + if (dir == NULL) { + LOG((CLOG_DEBUG "can't open plugins dir: %s", + pluginsDir.c_str())); + return; + } + + std::vector plugins; + while ((de = readdir(dir)) != NULL) { + // ignore hidden files and diretories like .. and . + if (de->d_name[0] != '.') { + LOG((CLOG_DEBUG "load plugin %s", de->d_name)); + plugins.push_back(de->d_name); + } + } + closedir(dir); + + std::vector::iterator it; + for (it = plugins.begin(); it != plugins.end(); ++it) { + LOG((CLOG_DEBUG "loading plugin: %s", (*it).c_str())); + String path = String(getPluginsDir()).append("/").append(*it); + void* library = dlopen(path.c_str(), RTLD_LAZY); + + if (library == NULL) { + throw XArch(dlerror()); + } + + String filename = synergy::string::removeFileExt(*it); + m_pluginTable.insert(std::make_pair(filename, library)); + } +} + void ArchPluginUnix::init(void* eventTarget, IEventQueue* events) { + g_eventTarget = eventTarget; + g_events = events; + + PluginTable::iterator it; + for (it = m_pluginTable.begin(); it != m_pluginTable.end(); it++) { + initFunc initPlugin = (initFunc)dlsym(it->second, "init"); + initPlugin(&sendEvent, &log); + } } + +bool +ArchPluginUnix::exists(const char* name) +{ + PluginTable::iterator it; + it = m_pluginTable.find(name); + return it != m_pluginTable.end() ? true : false; +} + +void* +ArchPluginUnix::invoke( + const char* plugin, + const char* command, + void* args) +{ + PluginTable::iterator it; + it = m_pluginTable.find(plugin); + if (it != m_pluginTable.end()) { + invokeFunc invokePlugin = (invokeFunc)dlsym(it->second, "invoke"); + return invokePlugin(command, args); + } + else { + LOG((CLOG_DEBUG "invoke command failed, plugin: %s command: %s", + plugin, command)); + return NULL; + } +} + +String +ArchPluginUnix::getPluginsDir() +{ +#if WINAPI_XWINDOWS + return "/usr/lib/synergy/plugin"; +#else + // TODO: pluging should be in bundle in the final release + return "/Users/xinyu/Projects/synergy/bin/plugins"; +#endif +} + +void +sendEvent(const char* eventName, void* data) +{ + LOG((CLOG_DEBUG5 "plugin sending event")); + Event::Type type = g_events->getRegisteredType(eventName); + g_events->addEvent(Event(type, g_eventTarget, data)); +} + +void +log(const char* text) +{ + LOG((CLOG_DEBUG "plugin: %s", text)); +} + diff --git a/src/lib/arch/unix/ArchPluginUnix.h b/src/lib/arch/unix/ArchPluginUnix.h index f75274e4..d9b30922 100644 --- a/src/lib/arch/unix/ArchPluginUnix.h +++ b/src/lib/arch/unix/ArchPluginUnix.h @@ -31,5 +31,19 @@ public: virtual ~ArchPluginUnix(); // IArchPlugin overrides + void load(); void init(void* eventTarget, IEventQueue* events); + bool exists(const char* name); + virtual void* invoke(const char* pluginName, + const char* functionName, + void* args); + + private: + String getPluginsDir(); + +private: + PluginTable m_pluginTable; }; + +void sendEvent(const char* text, void* data); +void log(const char* text); diff --git a/src/plugin/ns/CMakeLists.txt b/src/plugin/ns/CMakeLists.txt index fb497ed6..b8396bc7 100644 --- a/src/plugin/ns/CMakeLists.txt +++ b/src/plugin/ns/CMakeLists.txt @@ -30,6 +30,7 @@ endif() include_directories( ../../lib/ + ../../.. ${OPENSSL_INCLUDE} ) @@ -65,11 +66,28 @@ if (WIN32) ..\\..\\..\\..\\bin\\${CMAKE_CFG_INTDIR}\\plugins\\ ) else() - add_custom_command( - TARGET ns - POST_BUILD - COMMAND cp - ..\\..\\..\\..\\lib\\${CMAKE_CFG_INTDIR}\\ns.so - ..\\..\\..\\..\\bin\\${CMAKE_CFG_INTDIR}\\plugins\\ - ) + if (APPLE) + add_custom_command( + TARGET ns + POST_BUILD + COMMAND + mkdir -p + ${CMAKE_SOURCE_DIR}/bin/plugins + && + cp + ${CMAKE_SOURCE_DIR}/lib/${CMAKE_CFG_INTDIR}/libns.dylib + ${CMAKE_SOURCE_DIR}/bin/plugins/ + ) + else() + add_custom_command( + TARGET ns + POST_BUILD + COMMAND mkdir -p + ../../../../../bin/plugins + && + cp + ../../../../../lib/libns.so + ../../../../../bin/plugins/ + ) + endif() endif()