aboutsummaryrefslogtreecommitdiff
path: root/util/fbcompose/PluginManager.cc
diff options
context:
space:
mode:
authorGediminas Liktaras <gliktaras@gmail.com>2011-12-08 13:34:09 (GMT)
committerPaul Tagliamonte <paultag@fluxbox.org>2011-12-10 16:13:19 (GMT)
commitcd339169d1961eb508ea89cee2609ec6d0fc0c15 (patch)
tree01acd158a03fb17a72e067ff0b36701da75e49dc /util/fbcompose/PluginManager.cc
parent85ac5c4b2c6a526992f483a6e91867dc2f82a19e (diff)
downloadfluxbox_paul-cd339169d1961eb508ea89cee2609ec6d0fc0c15.zip
fluxbox_paul-cd339169d1961eb508ea89cee2609ec6d0fc0c15.tar.bz2
fbcompose - A compositing addon for fluxbox window manager.
fbcompose(1) is an optional compositing addon for fluxbox window manager. It augments fluxbox with a number of graphical features. Most notably, fbcompose allows fluxbox to properly display applications that require compositing (docky, for example), adds support for true window transparency (as opposed to fluxbox's pseudo transparency) and provides a plugin framework to extend the compositor's functionality. As this is still a beta version of the compositor, the bugs are likely.
Diffstat (limited to 'util/fbcompose/PluginManager.cc')
-rw-r--r--util/fbcompose/PluginManager.cc197
1 files changed, 197 insertions, 0 deletions
diff --git a/util/fbcompose/PluginManager.cc b/util/fbcompose/PluginManager.cc
new file mode 100644
index 0000000..cca1c5c
--- /dev/null
+++ b/util/fbcompose/PluginManager.cc
@@ -0,0 +1,197 @@
1/** PluginManager.cc file for the fluxbox compositor. */
2
3// Copyright (c) 2011 Gediminas Liktaras (gliktaras at gmail dot com)
4//
5// Permission is hereby granted, free of charge, to any person obtaining a copy
6// of this software and associated documentation files (the "Software"), to deal
7// in the Software without restriction, including without limitation the rights
8// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9// copies of the Software, and to permit persons to whom the Software is
10// furnished to do so, subject to the following conditions:
11//
12// The above copyright notice and this permission notice shall be included in
13// all copies or substantial portions of the Software.
14//
15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21// THE SOFTWARE.
22
23
24#ifdef HAVE_CONFIG_H
25 #include "config.h"
26#endif // HAVE_CONFIG_H
27
28#include "PluginManager.hh"
29
30#include "BasePlugin.hh"
31#include "BaseScreen.hh"
32#include "Exceptions.hh"
33#include "Logging.hh"
34#include "Utility.hh"
35
36#include <algorithm>
37#include <dlfcn.h>
38#include <sstream>
39
40using namespace FbCompositor;
41
42
43//--- CONSTRUCTORS AND DESTRUCTORS ---------------------------------------------
44
45// Costructor.
46PluginManager::PluginManager(PluginType plugin_type, const BaseScreen &screen,
47 const FbTk::FbString user_plugin_dir) :
48 m_screen(screen) {
49
50 m_plugin_type = plugin_type;
51 m_user_plugin_dir = user_plugin_dir;
52}
53
54// Destructor.
55PluginManager::~PluginManager() {
56 for (size_t i = 0; i < m_plugin_objects.size(); i++) {
57 delete m_plugin_objects[i];
58 }
59
60 std::map<FbTk::FbString, PluginLibData>::iterator it = m_plugin_libs.begin();
61 while (it != m_plugin_libs.end()) {
62 unloadPlugin(it);
63 ++it;
64 }
65}
66
67
68//--- PLUGIN MANIPULATION ------------------------------------------------------
69
70// Create a plugin object, load the appropriate library if needed.
71void PluginManager::createPluginObject(FbTk::FbString name, std::vector<FbTk::FbString> args) {
72 if (m_plugin_libs.find(name) == m_plugin_libs.end()) {
73 loadPlugin(name);
74 }
75
76 CreatePluginFunction create_function = m_plugin_libs.find(name)->second.create_function;
77 BasePlugin *new_plugin_object = (*create_function)(m_screen, args);
78 m_plugin_objects.push_back(new_plugin_object);
79}
80
81
82//--- INTERNAL PLUGIN MANIPULATION ---------------------------------------------
83
84// Load a plugin.
85void PluginManager::loadPlugin(FbTk::FbString name) {
86 static union {
87 void *void_ptr;
88 PluginTypeFunction plugin_type_func;
89 CreatePluginFunction create_plugin_func;
90 } obj_union;
91
92 std::vector<FbTk::FbString> paths = buildPluginPaths(name);
93
94 // Get the handle to the plugin so object.
95 void *handle = NULL;
96 for (size_t i = 0; i < paths.size(); i++) {
97 handle = dlopen(paths[i].c_str(), RTLD_LAZY | RTLD_LOCAL);
98 if (handle) {
99 break;
100 }
101 }
102 if (!handle) {
103 std::stringstream ss;
104 ss << "Could not find/load plugin \"" << name << "\".";
105 throw PluginException(ss.str());
106 }
107
108 // Check for the correct plugin type.
109 obj_union.void_ptr = getLibraryObject(handle, "pluginType", name.c_str(), "type function");
110 PluginTypeFunction type_func = obj_union.plugin_type_func;
111
112 if ((*(type_func))() != m_plugin_type) {
113 std::stringstream ss;
114 ss << "Plugin \"" << name << "\" is of the wrong type.";
115 throw PluginException(ss.str());
116 }
117
118 // Get the plugin creation function.
119 obj_union.void_ptr = getLibraryObject(handle, "createPlugin", name.c_str(), "creation function");
120 CreatePluginFunction create_func = obj_union.create_plugin_func;
121
122 // Track the loaded plugin.
123 PluginLibData plugin_data = { handle, create_func };
124 m_plugin_libs.insert(make_pair(name, plugin_data));
125}
126
127// Unload a plugin.
128void PluginManager::unloadPlugin(FbTk::FbString name) {
129 std::map<FbTk::FbString, PluginLibData>::iterator it = m_plugin_libs.find(name);
130
131 if (it == m_plugin_libs.end()) {
132 std::stringstream ss;
133 ss << "Plugin \"" << name << "\" is not loaded (unloadPlugin).";
134 throw PluginException(ss.str());
135 } else {
136 unloadPlugin(it);
137 }
138}
139
140// Unload a plugin (actual worker function).
141void PluginManager::unloadPlugin(std::map<FbTk::FbString, PluginLibData>::iterator it) {
142 dlclose(it->second.handle);
143
144 it->second.handle = NULL;
145 it->second.create_function = NULL;
146}
147
148
149//--- CONVENIENCE FUNCTIONS ----------------------------------------------------
150
151// Build a vector of search paths for a given plugin.
152std::vector<FbTk::FbString> PluginManager::buildPluginPaths(const FbTk::FbString &name) {
153 std::stringstream ss;
154 std::vector<FbTk::FbString> paths;
155
156 FbTk::FbString type_dir = "";
157 if (m_plugin_type == Plugin_OpenGL) {
158 type_dir = "opengl/";
159 } else if (m_plugin_type == Plugin_XRender) {
160 type_dir = "xrender/";
161 }
162
163 ss << "./plugins/" << type_dir << name << "/.libs/" << name << ".so";
164 paths.push_back(ss.str());
165 ss.str("");
166
167 ss << m_user_plugin_dir << type_dir << name << ".so";
168 paths.push_back(ss.str());
169 ss.str("");
170
171#ifdef FBCOMPOSE_PATH
172 ss << FBCOMPOSE_PATH << "/plugins/" << type_dir << name << ".so";
173 paths.push_back(ss.str());
174 ss.str("");
175#endif
176
177 paths.push_back(name);
178
179 return paths;
180}
181
182// Returns some object from the given library handle.
183void *PluginManager::getLibraryObject(void *handle, const char *object_name, const char *plugin_name,
184 const char *verbose_object_name) {
185 dlerror();
186 void *raw_object = dlsym(handle, object_name);
187 const char *error = dlerror();
188
189 if (error) {
190 dlclose(handle);
191 std::stringstream ss;
192 ss << "Error in loading " << verbose_object_name << " for \"" << plugin_name << "\" plugin: " << error;
193 throw PluginException(ss.str());
194 } else {
195 return raw_object;
196 }
197}