Use LinkableValueNode members functions when possible in the derived valuenodes.
[synfig.git] / synfig-core / src / synfig / module.cpp
1 /* === S Y N F I G ========================================================= */
2 /*!     \file synfig/module.cpp
3 **      \brief writeme
4 **
5 **      $Id$
6 **
7 **      \legal
8 **      Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
9 **
10 **      This package is free software; you can redistribute it and/or
11 **      modify it under the terms of the GNU General Public License as
12 **      published by the Free Software Foundation; either version 2 of
13 **      the License, or (at your option) any later version.
14 **
15 **      This package is distributed in the hope that it will be useful,
16 **      but WITHOUT ANY WARRANTY; without even the implied warranty of
17 **      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 **      General Public License for more details.
19 **      \endlegal
20 */
21 /* ========================================================================= */
22
23 /* === H E A D E R S ======================================================= */
24
25 #ifdef USING_PCH
26 #       include "pch.h"
27 #else
28 #ifdef HAVE_CONFIG_H
29 #       include <config.h>
30 #endif
31
32 #include "module.h"
33 #include "general.h"
34 #include <ETL/stringf>
35
36 #ifndef USE_CF_BUNDLES
37 #include <ltdl.h>
38 #endif
39
40 #endif
41
42 /* === M A C R O S ========================================================= */
43
44 /* === G L O B A L S ======================================================= */
45
46 using namespace std;
47 using namespace etl;
48 using namespace synfig;
49
50 Module::Book *synfig::Module::book_;
51
52 /* === P R O C E D U R E S ================================================= */
53
54 bool
55 Module::subsys_init(const String &prefix)
56 {
57 #ifndef USE_CF_BUNDLES
58         #ifndef SYNFIG_LTDL_NO_STATIC
59         //LTDL_SET_PRELOADED_SYMBOLS();
60         #endif
61
62         if(lt_dlinit())
63         {
64                 error(_("Errors on lt_dlinit()"));
65                 error(lt_dlerror());
66                 return false;
67         }
68
69         lt_dladdsearchdir(".");
70         if(getenv("HOME"))
71                 lt_dladdsearchdir(strprintf("%s/.synfig/modules", getenv("HOME")).c_str());
72         lt_dladdsearchdir((prefix+"/lib/synfig/modules").c_str());
73 #ifdef LIBDIR
74         lt_dladdsearchdir(LIBDIR"/synfig/modules");
75 #endif
76 #ifdef __APPLE__
77         lt_dladdsearchdir("/Library/Frameworks/synfig.framework/Resources/modules");
78 #endif
79         lt_dladdsearchdir("/usr/local/lib/synfig/modules");
80         lt_dladdsearchdir(".");
81 #endif
82         book_=new Book;
83         return true;
84 }
85
86 bool
87 Module::subsys_stop()
88 {
89         delete book_;
90
91 #ifndef USE_CF_BUNDLES
92         lt_dlexit();
93 #endif
94         return true;
95 }
96
97 void
98 Module::register_default_modules(ProgressCallback *callback)
99 {
100         #define REGISTER_MODULE(module) if (!Register(module, callback)) \
101                                                                                 throw std::runtime_error(strprintf(_("Unable to load module '%s'"), module))
102         REGISTER_MODULE("lyr_freetype");
103         REGISTER_MODULE("mod_geometry");
104         REGISTER_MODULE("mod_gradient");
105         REGISTER_MODULE("mod_particle");
106 }
107
108 Module::Book&
109 Module::book()
110 {
111         return *book_;
112 }
113
114 void
115 synfig::Module::Register(Module::Handle mod)
116 {
117         book()[mod->Name()]=mod;
118 }
119
120 bool
121 synfig::Module::Register(const String &module_name, ProgressCallback *callback)
122 {
123 #ifndef USE_CF_BUNDLES
124         lt_dlhandle module;
125
126         if(callback)callback->task(strprintf(_("Attempting to register \"%s\""),module_name.c_str()));
127
128         module=lt_dlopenext((string("lib")+module_name).c_str());
129         if(!module)module=lt_dlopenext(module_name.c_str());
130
131         if(!module)
132         {
133                 if(callback)callback->warning(strprintf(_("Unable to find module \"%s\" (%s)"),module_name.c_str(),lt_dlerror()));
134                 return false;
135         }
136
137         if(callback)callback->task(strprintf(_("Found module \"%s\""),module_name.c_str()));
138
139         Module::constructor_type constructor=NULL;
140         Handle mod;
141
142         if(!constructor)
143         {
144 //              if(callback)callback->task(string("looking for -> ")+module_name+"_LTX_new_instance()");
145                 constructor=(Module::constructor_type )lt_dlsym(module,(module_name+"_LTX_new_instance").c_str());
146         }
147
148         if(!constructor)
149         {
150 //              if(callback)callback->task(string("looking for -> lib")+module_name+"_LTX_new_instance()");
151                 constructor=(Module::constructor_type )lt_dlsym(module,(string("lib")+module_name+"_LTX_new_instance").c_str());
152         }
153         if(!constructor)
154         {
155 //              if(callback)callback->task(string("looking for -> lib")+module_name+"_LTX_new_instance()");
156                 constructor=(Module::constructor_type )lt_dlsym(module,(string("_lib")+module_name+"_LTX_new_instance").c_str());
157         }
158         if(!constructor)
159         {
160 //              if(callback)callback->task(string("looking for -> lib")+module_name+"_LTX_new_instance()");
161                 constructor=(Module::constructor_type )lt_dlsym(module,(string("_")+module_name+"_LTX_new_instance").c_str());
162         }
163
164         if(constructor)
165         {
166 //              if(callback)callback->task(strprintf("Executing callback for \"%s\"",module_name.c_str()));
167                 mod=handle<Module>((*constructor)(callback));
168         }
169         else
170         {
171                 if(callback)callback->error(strprintf(_("Unable to find entrypoint in module \"%s\" (%s)"),module_name.c_str(),lt_dlerror()));
172                 return false;
173         }
174
175 //      if(callback)callback->task(strprintf("Done executing callback for \"%s\"",module_name.c_str()));
176
177         if(mod)
178         {
179 //              if(callback)callback->task(strprintf("Registering \"%s\"",module_name.c_str()));
180                 Register(mod);
181         }
182         else
183         {
184                 if(callback)callback->error(_("Entrypoint did not return a module."));
185                 return false;
186     }
187
188         if(callback)callback->task(strprintf(_("Success for \"%s\""),module_name.c_str()));
189
190 #endif
191         return true;
192 }