kdecoration_plugins_p.cpp

00001 /*****************************************************************
00002 This file is part of the KDE project.
00003 
00004 Copyright (C) 1999, 2000    Daniel M. Duley <mosfet@kde.org>
00005 Copyright (C) 2003 Lubos Lunak <l.lunak@kde.org>
00006 
00007 Permission is hereby granted, free of charge, to any person obtaining a
00008 copy of this software and associated documentation files (the "Software"),
00009 to deal in the Software without restriction, including without limitation
00010 the rights to use, copy, modify, merge, publish, distribute, sublicense,
00011 and/or sell copies of the Software, and to permit persons to whom the
00012 Software is furnished to do so, subject to the following conditions:
00013 
00014 The above copyright notice and this permission notice shall be included in
00015 all copies or substantial portions of the Software.
00016 
00017 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00018 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00019 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
00020 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00021 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
00022 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
00023 DEALINGS IN THE SOFTWARE.
00024 ******************************************************************/
00025 
00026 #include "kdecoration_plugins_p.h"
00027 
00028 #include <kconfig.h>
00029 #include <kdebug.h>
00030 #include <klocale.h>
00031 #include <klibloader.h>
00032 #include <assert.h>
00033 
00034 #include <qdir.h>
00035 #include <qfile.h>
00036 
00037 #include "kdecorationfactory.h"
00038 
00039 KDecorationPlugins::KDecorationPlugins( KConfig* cfg )
00040     :   create_ptr( NULL ),
00041         library( NULL ),
00042         fact( NULL ),
00043         old_library( NULL ),
00044         old_fact( NULL ),
00045         pluginStr( "kwin3_undefined " ),
00046         config( cfg )
00047     {
00048     }
00049 
00050 KDecorationPlugins::~KDecorationPlugins()
00051     {
00052     if(library)
00053         {
00054         assert( fact != NULL );
00055         delete fact;
00056     library->unload();
00057         }
00058     if(old_library)
00059         {
00060         assert( old_fact != NULL );
00061         delete old_fact;
00062     old_library->unload();
00063         }
00064     }
00065 
00066 bool KDecorationPlugins::reset( unsigned long changed )
00067     {
00068     QString oldPlugin = pluginStr;
00069     config->reparseConfiguration();
00070     bool ret = false;
00071     if(( !loadPlugin( "" ) && library ) // "" = read the one in cfg file
00072         || oldPlugin == pluginStr )
00073         { // no new plugin loaded, reset the old one
00074         assert( fact != NULL );
00075         ret = fact->reset( changed );
00076         }
00077     return ret || oldPlugin != pluginStr;
00078     }
00079 
00080 KDecorationFactory* KDecorationPlugins::factory()
00081     {
00082     return fact;
00083     }
00084 
00085 // convenience
00086 KDecoration* KDecorationPlugins::createDecoration( KDecorationBridge* bridge )
00087     {
00088     if( fact != NULL )
00089         return fact->createDecoration( bridge );
00090     return NULL;
00091     }
00092     
00093 // returns true if plugin was loaded successfully
00094 bool KDecorationPlugins::loadPlugin( QString nameStr )
00095     {
00096     if( nameStr.isEmpty())
00097         {
00098         KConfigGroupSaver saver( config, "Style" );
00099         nameStr = config->readEntry("PluginLib", defaultPlugin );
00100         }
00101     // make sure people can switch between HEAD and kwin_iii branch
00102     if( nameStr.startsWith( "kwin_" ))
00103     nameStr = "kwin3_" + nameStr.mid( 5 );
00104 
00105     KLibrary *oldLibrary = library;
00106     KDecorationFactory* oldFactory = fact;
00107 
00108     QString path = KLibLoader::findLibrary(QFile::encodeName(nameStr));
00109 
00110     // If the plugin was not found, try to find the default
00111     if (path.isEmpty())
00112         {
00113         nameStr = defaultPlugin;
00114         path = KLibLoader::findLibrary(QFile::encodeName(nameStr));
00115         }
00116 
00117     // If no library was found, exit kwin with an error message
00118     if (path.isEmpty())
00119         {
00120         error( i18n("No window decoration plugin library was found." ));
00121         return false;
00122         }
00123 
00124     // Check if this library is not already loaded.
00125     if(pluginStr == nameStr)
00126     return true;
00127 
00128     // Try loading the requested plugin
00129     library = KLibLoader::self()->library(QFile::encodeName(path));
00130 
00131     // If that fails, fall back to the default plugin
00132     if (!library)
00133         {
00134     kdDebug() << " could not load library, try default plugin again" << endl;
00135         nameStr = defaultPlugin;
00136     if ( pluginStr == nameStr )
00137         return true;
00138         path = KLibLoader::findLibrary(QFile::encodeName(nameStr));
00139     if (!path.isEmpty())
00140             library = KLibLoader::self()->library(QFile::encodeName(path));
00141         }
00142 
00143     if (!library)
00144         {
00145         error( i18n("The default decoration plugin is corrupt "
00146                           "and could not be loaded." ));
00147         return false;
00148         }
00149 
00150     create_ptr = NULL;
00151     if( library->hasSymbol("create_factory"))
00152         {
00153         void* create_func = library->symbol("create_factory");
00154         if(create_func)
00155             create_ptr = (KDecorationFactory* (*)())create_func;
00156         }
00157     if(!create_ptr)
00158         {
00159         error( i18n( "The library %1 is not a KWin plugin." ).arg( path ));
00160         library->unload();
00161         return false;
00162         }
00163     fact = create_ptr();
00164     fact->checkRequirements( this ); // let it check what is supported
00165 
00166     pluginStr = nameStr;
00167 
00168     // For clients in kdeartwork    
00169     QString catalogue = nameStr;
00170     catalogue.replace( "kwin3_", "kwin_" );
00171     KGlobal::locale()->insertCatalogue( catalogue );
00172     // For KCommonDecoration based clients
00173     KGlobal::locale()->insertCatalogue( "kwin_lib" );
00174     // For clients in kdebase
00175     KGlobal::locale()->insertCatalogue( "kwin_clients" );
00176     // For clients in kdeartwork
00177     KGlobal::locale()->insertCatalogue( "kwin_art_clients" );
00178 
00179     old_library = oldLibrary; // save for delayed destroying
00180     old_fact = oldFactory;
00181     
00182     return true;
00183 }
00184 
00185 void KDecorationPlugins::destroyPreviousPlugin()
00186 {
00187     // Destroy the old plugin
00188     if(old_library)
00189         {
00190         delete old_fact;
00191         old_fact = NULL;
00192     old_library->unload();
00193         old_library = NULL;
00194         }
00195 }
00196 
00197 void KDecorationPlugins::error( const QString& )
00198     {
00199     }
KDE Home | KDE Accessibility Home | Description of Access Keys