kwin/plugins.cpp

168 lines
4.7 KiB
C++

/*****************************************************************
kwin - the KDE window manager
Copyright (C) 1999, 2000 Daniel M. Duley <mosfet@kde.org>
******************************************************************/
#include <kglobal.h>
#include <kconfig.h>
#include <kstandarddirs.h>
#include <kdesktopfile.h>
#include <kdebug.h>
#include <ksimpleconfig.h>
#include <klocale.h>
#include <klibloader.h>
// X11/Qt conflict
#undef Unsorted
#include <qdir.h>
#include <qfile.h>
#include "plugins.h"
using namespace KWinInternal;
PluginMgr::PluginMgr()
: QObject()
{
create_ptr = NULL;
old_create_ptr = NULL;
library = 0;
pluginStr = "kwin_undefined";
defaultPlugin = (QPixmap::defaultDepth() > 8) ?
"kwin_keramik" : "kwin_quartz";
KConfig *config = KGlobal::config();
config->setGroup("Style");
loadPlugin( config->readEntry("PluginLib", defaultPlugin) );
}
PluginMgr::~PluginMgr()
{
if(library) {
// Call the plugin's cleanup function
if( library->hasSymbol("deinit")) {
void *deinit_func = library->symbol("deinit");
if (deinit_func)
((void (*)())deinit_func)();
}
library->unload();
library = 0;
}
}
void PluginMgr::updatePlugin()
{
KConfig *config = KGlobal::config();
config->reparseConfiguration();
config->setGroup("Style");
if ( !loadPlugin( config->readEntry("PluginLib", defaultPlugin )) && library ) {
if( library->hasSymbol("reset")) {
void *reset_func = library->symbol("reset");
if (reset_func)
((void (*)())reset_func)();
}
}
}
Client* PluginMgr::createClient(Workspace *ws, WId w, NET::WindowType type)
{
if (create_ptr) // prefer the newer function which accepts exact window type
return(create_ptr(ws, w, type));
if (old_create_ptr)
return(old_create_ptr(ws, w, type == NET::Tool || type == NET::Menu));
// We are guaranteed to have a plugin loaded,
// otherwise, kwin exits during loadPlugin - but verify anyway
return NULL;
}
// returns true if plugin was loaded successfully
bool PluginMgr::loadPlugin(QString nameStr)
{
KLibrary *oldLibrary = library;
QString path = KLibLoader::findLibrary(QFile::encodeName(nameStr));
// If the plugin was not found, try to find the default
if (path.isEmpty()) {
nameStr = defaultPlugin;
path = KLibLoader::findLibrary(QFile::encodeName(nameStr));
}
// If no library was found, exit kwin with an error message
if (path.isEmpty())
shutdownKWin(i18n("No window decoration plugin library was found!"));
// Check if this library is not already loaded.
if(pluginStr == nameStr)
return FALSE;
// Try loading the requested plugin
library = KLibLoader::self()->library(QFile::encodeName(path));
// If that fails, fall back to the default plugin
if (!library) {
kdDebug() << " could not load library, try default plugin again" << endl;
nameStr = defaultPlugin;
if ( pluginStr == nameStr )
return FALSE;
path = KLibLoader::findLibrary(QFile::encodeName(nameStr));
if (!path.isEmpty())
library = KLibLoader::self()->library(QFile::encodeName(path));
}
if (!library)
shutdownKWin(i18n("The default decoration plugin is corrupt "
"and could not be loaded!"));
// Call the plugin's initialisation function
if( library->hasSymbol("init")) {
void *init_func = library->symbol("init");
if (init_func)
((void (*)())init_func)();
}
if( library->hasSymbol("create")) {
void* create_func = library->symbol("create");
if(create_func) {
create_ptr = (Client* (*)(Workspace *ws, WId w, NET::WindowType))create_func;
}
}
if( library->hasSymbol("allocate")) {
void* allocate_func = library->symbol("allocate");
if(allocate_func) {
old_create_ptr = (Client* (*)(Workspace *ws, WId w, int tool))allocate_func;
}
}
if(!create_ptr && !old_create_ptr) {
kdWarning() << "KWin: The library " << path << " is not a KWin plugin." << endl;
library->unload();
exit(1);
}
pluginStr = nameStr;
emit resetAllClients();
// Call the old plugin's cleanup function
if(oldLibrary) {
if( library->hasSymbol("deinit")) {
void *deinit_func = oldLibrary->symbol("deinit");
if (deinit_func)
((void (*)())deinit_func)();
}
oldLibrary->unload();
}
return TRUE;
}
void PluginMgr::shutdownKWin(const QString &error_msg)
{
qWarning( (i18n("KWin: ") + error_msg +
i18n("\nKWin will now exit...")).latin1() );
exit(1);
}
#include "plugins.moc"