|
MythTV
0.26-pre
|
00001 // C includes 00002 #ifndef USING_MINGW 00003 #include <dlfcn.h> 00004 #else 00005 #include "compat.h" 00006 #endif 00007 00008 // Qt includes 00009 #include <QDir> 00010 00011 // MythTV includes 00012 #include "mythplugin.h" 00013 #include "mythcontext.h" 00014 #include "mythtranslation.h" 00015 00016 #include "mythdirs.h" 00017 #include "mythversion.h" 00018 #include "mythlogging.h" 00019 00020 using namespace std; 00021 00022 MythPlugin::MythPlugin(const QString &libname, const QString &plugname) 00023 : QLibrary(libname), m_plugName(plugname) 00024 { 00025 enabled = true; 00026 position = 0; 00027 } 00028 00029 MythPlugin::~MythPlugin() 00030 { 00031 // Commented out because it causes segfaults... dtk 2008-10-08 00032 //if (isLoaded()) 00033 // unload(); 00034 } 00035 00036 int MythPlugin::init(const char *libversion) 00037 { 00038 typedef int (*PluginInitFunc)(const char *); 00039 PluginInitFunc ifunc = (PluginInitFunc)QLibrary::resolve("mythplugin_init"); 00040 00041 if (ifunc) 00042 return ifunc(libversion); 00043 00044 QString error_msg(dlerror()); 00045 if (error_msg.isEmpty()) 00046 { 00047 QByteArray libname = QLibrary::fileName().toAscii(); 00048 (void)dlopen(libname.constData(), RTLD_LAZY); 00049 error_msg = dlerror(); 00050 } 00051 00052 LOG(VB_GENERAL, LOG_EMERG, QString("MythPlugin::init() dlerror: %1") 00053 .arg(error_msg)); 00054 00055 return -1; 00056 } 00057 00058 int MythPlugin::run(void) 00059 { 00060 typedef int (*PluginRunFunc)(); 00061 00062 int rVal = -1; 00063 PluginRunFunc rfunc = (PluginRunFunc)QLibrary::resolve("mythplugin_run"); 00064 00065 if (rfunc) 00066 rVal = rfunc(); 00067 00068 return rVal; 00069 } 00070 00071 int MythPlugin::config(void) 00072 { 00073 typedef int (*PluginConfigFunc)(); 00074 00075 int rVal = -1; 00076 PluginConfigFunc rfunc = (PluginConfigFunc)QLibrary::resolve( 00077 "mythplugin_config"); 00078 00079 if (rfunc) 00080 { 00081 rVal = rfunc(); 00082 gCoreContext->ClearSettingsCache(); 00083 } 00084 00085 return rVal; 00086 } 00087 00088 MythPluginType MythPlugin::type(void) 00089 { 00090 typedef MythPluginType (*PluginTypeFunc)(); 00091 PluginTypeFunc rfunc = (PluginTypeFunc)QLibrary::resolve("mythplugin_type"); 00092 00093 if (rfunc) 00094 return rfunc(); 00095 00096 return kPluginType_Module; 00097 } 00098 00099 void MythPlugin::destroy(void) 00100 { 00101 typedef void (*PluginDestFunc)(); 00102 PluginDestFunc rfunc = (PluginDestFunc)QLibrary::resolve("mythplugin_destroy"); 00103 00104 if (rfunc) 00105 rfunc(); 00106 } 00107 00108 int MythPlugin::setupMenuPlugin(void) 00109 { 00110 typedef int (*PluginSetup)(); 00111 PluginSetup rfunc = (PluginSetup)QLibrary::resolve("mythplugin_setupMenu"); 00112 00113 if (rfunc) 00114 return rfunc(); 00115 00116 return -1; 00117 } 00118 00119 void MythPlugin::drawMenuPlugin(QPainter *painter, int x, int y, int w, int h) 00120 { 00121 typedef void (*PluginDrawMenu)(QPainter *, int, int, int, int); 00122 PluginDrawMenu rfunc = (PluginDrawMenu)QLibrary::resolve("mythplugin_drawMenu"); 00123 00124 if (rfunc) 00125 rfunc(painter, x, y, w, h); 00126 } 00127 00128 MythPluginManager::MythPluginManager() 00129 { 00130 QString pluginprefix = GetPluginsDir(); 00131 00132 QDir filterDir(pluginprefix); 00133 00134 filterDir.setFilter(QDir::Files | QDir::Readable); 00135 QString filter = GetPluginsNameFilter(); 00136 filterDir.setNameFilters(QStringList(filter)); 00137 00138 gContext->SetDisableLibraryPopup(true); 00139 00140 if (filterDir.exists()) 00141 { 00142 int prefixLength = filter.indexOf("*"); 00143 int suffixLength = filter.length() - prefixLength - 1; 00144 00145 QStringList libraries = filterDir.entryList(); 00146 if (libraries.isEmpty()) 00147 LOG(VB_GENERAL, LOG_WARNING, 00148 "No libraries in plugins directory " + filterDir.path()); 00149 00150 for (QStringList::iterator i = libraries.begin(); i != libraries.end(); 00151 ++i) 00152 { 00153 QString library = *i; 00154 00155 // pull out the base library name 00156 library = library.right(library.length() - prefixLength); 00157 library = library.left(library.length() - suffixLength); 00158 00159 init_plugin(library); 00160 } 00161 } 00162 else 00163 LOG(VB_GENERAL, LOG_WARNING, 00164 "No plugins directory " + filterDir.path()); 00165 00166 gContext->SetDisableLibraryPopup(false); 00167 00168 orderMenuPlugins(); 00169 } 00170 00171 MythPluginManager::~MythPluginManager() 00172 { 00173 } 00174 00175 bool MythPluginManager::init_plugin(const QString &plugname) 00176 { 00177 QString newname = FindPluginName(plugname); 00178 00179 if (!m_dict[newname]) 00180 { 00181 m_dict.insert(newname, new MythPlugin(newname, plugname)); 00182 } 00183 00184 int result = m_dict[newname]->init(MYTH_BINARY_VERSION); 00185 00186 if (result == -1) 00187 { 00188 delete m_dict[newname]; 00189 m_dict.remove(newname); 00190 LOG(VB_GENERAL, LOG_ERR, 00191 QString("Unable to initialize plugin '%1'.") .arg(plugname)); 00192 return false; 00193 } 00194 00195 MythTranslation::load(plugname); 00196 00197 switch (m_dict[newname]->type()) 00198 { 00199 case kPluginType_MenuPlugin: 00200 menuPluginMap[newname] = m_dict[newname]; 00201 break; 00202 case kPluginType_Module: 00203 default: 00204 moduleMap[newname] = m_dict[newname]; 00205 break; 00206 } 00207 00208 return true; 00209 } 00210 00211 // return false on success, true on error 00212 bool MythPluginManager::run_plugin(const QString &plugname) 00213 { 00214 QString newname = FindPluginName(plugname); 00215 00216 if (!m_dict[newname] && !init_plugin(plugname)) 00217 { 00218 LOG(VB_GENERAL, LOG_ALERT, 00219 QString("Unable to run plugin '%1': not initialized") 00220 .arg(plugname)); 00221 return true; 00222 } 00223 00224 bool res = m_dict[newname]->run(); 00225 00226 return res; 00227 } 00228 00229 // return false on success, true on error 00230 bool MythPluginManager::config_plugin(const QString &plugname) 00231 { 00232 QString newname = FindPluginName(plugname); 00233 00234 if (!m_dict[newname] && !init_plugin(plugname)) 00235 { 00236 LOG(VB_GENERAL, LOG_ALERT, 00237 QString("Unable to configure plugin '%1': not initialized") 00238 .arg(plugname)); 00239 return true; 00240 } 00241 00242 bool res = m_dict[newname]->config(); 00243 00244 return res; 00245 } 00246 00247 bool MythPluginManager::destroy_plugin(const QString &plugname) 00248 { 00249 QString newname = FindPluginName(plugname); 00250 00251 if (!m_dict[newname] && !init_plugin(plugname)) 00252 { 00253 LOG(VB_GENERAL, LOG_ALERT, 00254 QString("Unable to destroy plugin '%1': not initialized") 00255 .arg(plugname)); 00256 return false; 00257 } 00258 00259 m_dict[newname]->destroy(); 00260 return true; 00261 } 00262 00263 MythPlugin *MythPluginManager::GetPlugin(const QString &plugname) 00264 { 00265 QString newname = FindPluginName(plugname); 00266 00267 if (moduleMap.find(newname) == moduleMap.end()) 00268 return NULL; 00269 00270 return moduleMap[newname]; 00271 } 00272 00273 MythPlugin *MythPluginManager::GetMenuPlugin(const QString &plugname) 00274 { 00275 QString newname = FindPluginName(plugname); 00276 00277 if (menuPluginMap.find(newname) == menuPluginMap.end()) 00278 return NULL; 00279 00280 return menuPluginMap[newname]; 00281 } 00282 00283 MythPlugin *MythPluginManager::GetMenuPluginAt(int pos) 00284 { 00285 if ((uint)pos >= menuPluginList.size()) 00286 return NULL; 00287 00288 return menuPluginList[pos]; 00289 } 00290 00291 void MythPluginManager::orderMenuPlugins(void) 00292 { 00293 // This needs to hit a db table for persistant ordering 00294 // For now, just use whatever order the map iterator returns 00295 00296 menuPluginList.clear(); 00297 00298 QMap<QString, MythPlugin *>::iterator iter = menuPluginMap.begin(); 00299 for (; iter != menuPluginMap.end(); ++iter) 00300 { 00301 if ((*iter)->isEnabled()) 00302 menuPluginList.push_back(*iter); 00303 } 00304 } 00305 00306 void MythPluginManager::DestroyAllPlugins(void) 00307 { 00308 QHash<QString, MythPlugin*>::iterator it = m_dict.begin(); 00309 for (; it != m_dict.end(); ++it) 00310 { 00311 (*it)->destroy(); 00312 delete *it; 00313 } 00314 00315 m_dict.clear(); 00316 moduleMap.clear(); 00317 menuPluginMap.clear(); 00318 menuPluginList.clear(); 00319 } 00320 00321 QStringList MythPluginManager::EnumeratePlugins(void) 00322 { 00323 QStringList ret; 00324 QHash<QString, MythPlugin*>::const_iterator it = m_dict.begin(); 00325 for (; it != m_dict.end(); ++it) 00326 ret << (*it)->getName(); 00327 return ret; 00328 } 00329
1.7.6.1