239 lines
3.9 KiB
C++
Executable File
239 lines
3.9 KiB
C++
Executable File
/*
|
|
* This file is a part of Winix
|
|
* and is not publicly distributed
|
|
*
|
|
* Copyright (c) 2008-2010, Tomasz Sowa
|
|
* All rights reserved.
|
|
*
|
|
*/
|
|
|
|
#include <dlfcn.h>
|
|
#include "plugin.h"
|
|
#include "pluginmsg.h"
|
|
|
|
|
|
|
|
|
|
void Plugin::UnloadPlugins()
|
|
{
|
|
size_t i;
|
|
|
|
slots.clear();
|
|
|
|
for(i=0 ; i<plugins.size() ; ++i)
|
|
dlclose(plugins[i].handle);
|
|
|
|
plugins.clear();
|
|
}
|
|
|
|
|
|
Plugin::Plugin()
|
|
{
|
|
current_plugin = -1;
|
|
}
|
|
|
|
|
|
Plugin::~Plugin()
|
|
{
|
|
UnloadPlugins();
|
|
}
|
|
|
|
|
|
void Plugin::LoadPlugins(const std::vector<std::string> & plugins)
|
|
{
|
|
size_t i;
|
|
|
|
for(i=0 ; i<plugins.size() ; ++i)
|
|
LoadPlugin(plugins[i]);
|
|
}
|
|
|
|
|
|
void Plugin::LoadPlugin(const std::string & filename)
|
|
{
|
|
LoadPlugin(filename.c_str());
|
|
}
|
|
|
|
|
|
void * Plugin::LoadInitFun(const char * filename, Fun1 & fun_init)
|
|
{
|
|
void * p = dlopen(filename, RTLD_NOW | RTLD_LOCAL);
|
|
|
|
if( !p )
|
|
{
|
|
log << log1 << "Plugin: cannot load a plugin: " << filename << logend;
|
|
return 0;
|
|
}
|
|
|
|
fun_init = (Fun1)dlfunc(p, "Init");
|
|
|
|
if( !fun_init )
|
|
{
|
|
log << log1 << "Plugin: cannot load a plugin: " << filename
|
|
<< " (there is no Init() function)" << logend;
|
|
|
|
dlclose(p);
|
|
return 0;
|
|
}
|
|
|
|
log << log1 << "Plugin: plugin loaded"
|
|
<< ", file: " << filename
|
|
<< ", index: " << plugins.size() << logend;
|
|
|
|
return p;
|
|
}
|
|
|
|
|
|
|
|
void Plugin::LoadPlugin(const char * filename)
|
|
{
|
|
Fun1 fun_init;
|
|
void * plugin_handle;
|
|
int old_current_plugin;
|
|
|
|
if( !(plugin_handle = LoadInitFun(filename, fun_init)) )
|
|
return;
|
|
|
|
info.Clear();
|
|
old_current_plugin = current_plugin;
|
|
current_plugin = (int)plugins.size();
|
|
info.plugin_id = current_plugin;
|
|
|
|
fun_init(info);
|
|
|
|
PluginsItem item;
|
|
item.handle = plugin_handle;
|
|
item.plugin_name = (const char *)info.p1;
|
|
|
|
plugins.push_back(item);
|
|
|
|
current_plugin = old_current_plugin;
|
|
}
|
|
|
|
|
|
|
|
void Plugin::Call(int message, Slots::iterator & slot)
|
|
{
|
|
current_plugin = slot->second.index;
|
|
info.plugin_id = current_plugin;
|
|
|
|
if( request.session && current_plugin != -1 )
|
|
info.plugin_data_base = request.session->plugin_data.Get(current_plugin);
|
|
else
|
|
info.plugin_data_base = 0;
|
|
|
|
if( !slot->second.is_running )
|
|
{
|
|
slot->second.is_running = true;
|
|
|
|
if( slot->second.fun1 )
|
|
slot->second.fun1(info);
|
|
|
|
if( slot->second.fun2 )
|
|
slot->second.fun2();
|
|
|
|
slot->second.is_running = false;
|
|
}
|
|
else
|
|
{
|
|
log << log1 << "Plugin: id: " << slot->second.index
|
|
<< ", message: " << message
|
|
<< ", recurrences are not allowed" << logend;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void Plugin::Call(int message, void * p1_, void * p2_, long l1_, long l2_)
|
|
{
|
|
Slots::iterator i = slots.lower_bound(message);
|
|
int old_current_plugin = current_plugin;
|
|
|
|
for( ; i!=slots.end() && i->first==message ; ++i )
|
|
{
|
|
info.Clear();
|
|
info.p1 = p1_;
|
|
info.p2 = p2_;
|
|
info.l1 = l1_;
|
|
info.l2 = l2_;
|
|
|
|
Call(message, i);
|
|
}
|
|
|
|
current_plugin = old_current_plugin;
|
|
}
|
|
|
|
|
|
void Plugin::Call(int message)
|
|
{
|
|
Call(message, 0, 0, 0, 0);
|
|
}
|
|
|
|
void Plugin::Call(int message, void * p1_)
|
|
{
|
|
Call(message, p1_, 0, 0, 0);
|
|
}
|
|
|
|
void Plugin::Call(int message, void * p1_, void * p2_)
|
|
{
|
|
Call(message, p1_, p2_, 0, 0);
|
|
}
|
|
|
|
void Plugin::Call(int message, long l1_)
|
|
{
|
|
Call(message, 0, 0, l1_, 0);
|
|
}
|
|
|
|
void Plugin::Call(int message, long l1_, long l2_)
|
|
{
|
|
Call(message, 0, 0, l1_, l2_);
|
|
}
|
|
|
|
void Plugin::Call(int message, void * p1_, long l1_)
|
|
{
|
|
Call(message, p1_, 0, l1_, 0);
|
|
}
|
|
|
|
void Plugin::Call(int message, void * p1_, long l1_, long l2_)
|
|
{
|
|
Call(message, p1_, 0, l1_, l2_);
|
|
}
|
|
|
|
void Plugin::Call(int message, void * p1_, void * p2_, long l1_)
|
|
{
|
|
Call(message, p1_, p2_, l1_, 0);
|
|
}
|
|
|
|
|
|
|
|
|
|
size_t Plugin::Size()
|
|
{
|
|
return plugins.size();
|
|
}
|
|
|
|
|
|
|
|
void Plugin::Assign(int message, Fun1 fun1)
|
|
{
|
|
Slot s;
|
|
|
|
s.fun1 = fun1;
|
|
s.index = current_plugin;
|
|
|
|
slots.insert( std::make_pair(message, s) );
|
|
log << log3 << "Plugin: added function for message: " << message << ", plugin index: " << s.index << logend;
|
|
}
|
|
|
|
|
|
void Plugin::Assign(int message, Fun2 fun2)
|
|
{
|
|
Slot s;
|
|
|
|
s.fun2 = fun2;
|
|
s.index = current_plugin;
|
|
|
|
slots.insert( std::make_pair(message, s) );
|
|
log << log3 << "Plugin: added function for message: " << message << ", plugin index: " << s.index << logend;
|
|
}
|
|
|