/* ksim - a system monitor for kde * * Copyright (C) 2001 Robbie Ward * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "pluginloader.h" #include "pluginloader.moc" #include #include #include #include #include #include #include #include class KSim::PluginInfo::Private { public: }; KSim::PluginInfo::~PluginInfo() { } const TQString &KSim::PluginInfo::name() const { return m_name; } TQCString KSim::PluginInfo::libName(bool includePrefix) const { return (includePrefix ? "ksim_" + m_libName : m_libName); } const TQString &KSim::PluginInfo::location() const { return m_location; } KSim::PluginInfo::PluginInfo() { } class KSim::PluginLoader::Private { public: typedef KSim::PluginObject *(PluginPtr)(const char *); KSim::PluginList pluginList; TQString error; TQString lib; bool lastLoaded; static const char *const ksimString; }; const char *const KSim::PluginLoader::Private::ksimString = "ksim_"; KSim::PluginLoader *KSim::PluginLoader::m_instance = 0; // initialize pointer KSim::PluginLoader &KSim::PluginLoader::self() { if (!m_instance) // is it the first call? m_instance = new PluginLoader; // create sole instance return *m_instance; // address of sole instance } KSim::PluginLoader::~PluginLoader() { unloadAllPlugins(); delete d; } bool KSim::PluginLoader::loadPlugin(const KDesktopFile &file) { switch (createPlugin(file)) { case KSim::PluginLoader::EmptyLibName: KMessageBox::error(0, i18n("KSim was unable to load the plugin %1" " due to the X-KSIM-LIBRARY property being empty in the" " plugins desktop file").tqarg(file.readName())); return false; break; case KSim::PluginLoader::LibNotFound: KMessageBox::error(0, i18n("KSim was unable to load the plugin %1" " due to not being able to find the plugin, check that the plugin" " is installed and is in your $KDEDIR/lib path").tqarg(file.readName())); return false; break; case KSim::PluginLoader::UnSymbols: KMessageBox::error(0, i18n("An error occurred while trying \n" "to load the plugin '%1'. \nThis could be caused by the" " following:
    \n
  • The plugin doesn't have the %2" " macro
  • \n
  • The plugin has been damaged or has" " some unresolved symbols
  • \n
\nLast" " error message that occurred: \n%3
") .tqarg(d->lib.prepend("ksim_")).tqarg("KSIM_INIT_PLUGIN") .tqarg(d->error)); return false; break; default: break; } return true; } bool KSim::PluginLoader::unloadPlugin(const TQCString &name) { if (name.isEmpty()) return false; // see if our plugin is loaded KSim::Plugin plugin = find(name); if (plugin.isNull()) return false; // try to unload the library kdDebug(2003) << "Unloading plugin " << plugin.libName() << endl; KLibLoader::self()->unloadLibrary(plugin.libName()); d->pluginList.remove(plugin); return true; } void KSim::PluginLoader::unloadAllPlugins() { kdDebug(2003) << "Unloading all plugins" << endl; // Go through the plugin list and unload each plugin; KSim::PluginList::ConstIterator it; for (it = d->pluginList.begin(); it != d->pluginList.end(); ++it) { KLibLoader::self()->unloadLibrary((*it).libName()); } // Clear the plugin list; d->pluginList.clear(); KLibLoader::cleanUp(); } bool KSim::PluginLoader::isLoaded(const KSim::Plugin &info) const { return isLoaded(info.libName()); } bool KSim::PluginLoader::isLoaded(const TQCString &library) const { if (library.isEmpty()) return false; return !find(library).isNull(); } KSim::PluginInfo KSim::PluginLoader::findPluginInfo(const TQString &name, SearchType type) const { TQString location; switch (type) { case Name: { TQStringList files = KGlobal::dirs()->findAllResources("data", "ksim/monitors/*.desktop"); TQStringList::ConstIterator it; for (it = files.begin(); it != files.end(); ++it) { KDesktopFile file((*it)); if (file.readName() == name) { location = (*it); break; } } break; } case LibName: { TQStringList files = KGlobal::dirs()->findAllResources("data", "ksim/monitors/*.desktop"); TQStringList::ConstIterator it; for (it = files.begin(); it != files.end(); ++it) { KDesktopFile file((*it)); if (file.readEntry("X-KSIM-LIBRARY") == name) { location = (*it); break; } } break; } case DesktopFile: { if (!KDesktopFile::isDesktopFile(name)) return KSim::PluginInfo(); location = name; break; } } KDesktopFile file(location); KSim::PluginInfo info; info.m_name = file.readName(); info.m_libName = file.readEntry("X-KSIM-LIBRARY").local8Bit(); info.m_location = location; return info; } KSim::Plugin &KSim::PluginLoader::find(const TQCString &libName) { if (libName.isEmpty()) return KSim::Plugin::null; TQCString library(libName); if (libName.find(Private::ksimString) == -1) library.prepend(Private::ksimString); KSim::PluginList::Iterator it; for (it = d->pluginList.begin(); it != d->pluginList.end(); ++it) { if ((*it).libName() == library) return (*it); } return KSim::Plugin::null; } const KSim::Plugin &KSim::PluginLoader::find(const TQCString &libName) const { if (libName.isEmpty()) return KSim::Plugin::null; TQCString library(libName); if (libName.find(Private::ksimString) == -1) library.prepend(Private::ksimString); KSim::PluginList::ConstIterator it; for (it = d->pluginList.begin(); it != d->pluginList.end(); ++it) { if ((*it).libName() == library) return (*it); } return KSim::Plugin::null; } KSim::Plugin &KSim::PluginLoader::find(const KSim::PluginInfo &info) { return find(info.libName()); } const KSim::Plugin &KSim::PluginLoader::find(const KSim::PluginInfo &info) const { return find(info.libName()); } const KSim::PluginList &KSim::PluginLoader::pluginList() const { return d->pluginList; } KSim::PluginList &KSim::PluginLoader::pluginList() { return d->pluginList; } const KSim::Plugin &KSim::PluginLoader::plugin() const { return (d->lastLoaded ? d->pluginList.last() : KSim::Plugin::null); } KSim::Plugin &KSim::PluginLoader::plugin() { return (d->lastLoaded ? d->pluginList.last() : KSim::Plugin::null); } KSim::PluginLoader::PluginLoader() : TQObject(0, "PluginLoader") { d = new KSim::PluginLoader::Private; d->lastLoaded = false; } void KSim::PluginLoader::cleanup() { if (!m_instance) return; delete m_instance; m_instance = 0; } KSim::PluginLoader::ErrorCode KSim::PluginLoader::createPlugin(const KDesktopFile &file) { d->error = TQString(); TQCString pluginName(file.readEntry("X-KSIM-LIBRARY").local8Bit()); if (pluginName.isEmpty()) return EmptyLibName; TQCString libName(Private::ksimString + pluginName); KLibrary *library = KLibLoader::self()->library(libName); if (!library) return LibNotFound; TQCString symbol("init_plugin"); if (Private::PluginPtr *create = (Private::PluginPtr *)(library->symbol(symbol))) { d->pluginList.append(KSim::Plugin(create(pluginName), file)); d->lib = TQString(); d->lastLoaded = true; } else { d->error = KLibLoader::self()->lastErrorMessage().isEmpty() ? i18n("Unable to get last error message") : KLibLoader::self()->lastErrorMessage(); KLibLoader::self()->unloadLibrary(libName); d->lib = pluginName; d->lastLoaded = false; return UnSymbols; } emit pluginLoaded(d->pluginList.last()); return LibLoaded; }