diff options
author | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-03-13 05:43:39 +0000 |
---|---|---|
committer | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-03-13 05:43:39 +0000 |
commit | 19ae07d0d443ff8b777f46bcbe97119483356bfd (patch) | |
tree | dae169167c23ba7c61814101995de21d6abac2e8 /wineconfig/kcm_wineconfig.cpp | |
download | tde-guidance-19ae07d0d443ff8b777f46bcbe97119483356bfd.tar.gz tde-guidance-19ae07d0d443ff8b777f46bcbe97119483356bfd.zip |
Added KDE3 version of KDE Guidance utilities
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/kde-guidance@1102646 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'wineconfig/kcm_wineconfig.cpp')
-rw-r--r-- | wineconfig/kcm_wineconfig.cpp | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/wineconfig/kcm_wineconfig.cpp b/wineconfig/kcm_wineconfig.cpp new file mode 100644 index 0000000..bfd9217 --- /dev/null +++ b/wineconfig/kcm_wineconfig.cpp @@ -0,0 +1,156 @@ + +/* + * pykcm_launcher.cpp + * + * Launch Control Centre modules written in Python using an embedded Python + * interpreter. + * Based on David Boddie's PyKDE-components. + */ + +// pythonize.h must be included first. +#include <pythonize.h> +#include <kcmodule.h> +#include <kglobal.h> +#include <klocale.h> +#include <klibloader.h> +#include <kstandarddirs.h> +#include <ksimpleconfig.h> +#include <qstring.h> +#include <sip.h> + +#define MODULE_DIR "/opt/kde3/share/apps/guidance" +#define EXTRA_MODULE_DIR "/opt/kde3/share/python-support/kde-guidance-kde3" +#define EXTRA_MODULE_DIR_TWO "/opt/kde3/share/python-support/guidance-backends-kde3" +#define EXTRA_MODULE_DIR_THREE "/opt/kde3/share/python-support/kde-guidance-powermanager-kde3" +#define MODULE_NAME "wineconfig" +#define FACTORY "create_wineconfig" +#define CPP_FACTORY create_wineconfig +#define LIB_PYTHON "libpython2.5.so" +#define debug 1 + +static KCModule *report_error(char *msg) { + if (debug) printf ("error: %s\n", msg); + return NULL; +} + +static KCModule* return_instance( QWidget *parent, const char *name ) { + KCModule* kcmodule; + PyObject *pyKCModuleTuple; + PyObject *pyKCModule; + Pythonize *pyize; // Pythonize object to manage the Python interpreter. + int isErr; + + // Try to determine what py script we're loading. Note that "name" + // typically appears to be NULL. + QString script(MODULE_NAME); + + // Reload libpython, but this time tell the runtime linker to make the + // symbols global and available for later loaded libraries/module. + KLibLoader::self()->globalLibrary(LIB_PYTHON); + + // Start the interpreter. + pyize = initialize(); + if (!pyize) { + return report_error ("***Failed to start interpreter\n"); + } + + // Add the path to the python script to the interpreter search path. + QString path = QString(MODULE_DIR); + if(path == QString::null) { + return report_error ("***Failed to locate script path"); + } + if(!pyize->appendToSysPath (path.latin1 ())) { + return report_error ("***Failed to set sys.path\n"); + } + QString extrapath = QString(EXTRA_MODULE_DIR); + if(!pyize->appendToSysPath (extrapath.latin1 ())) { + return report_error ("***Failed to set extra sys.path\n"); + } + QString extrapath_two = QString(EXTRA_MODULE_DIR_TWO); + if(!pyize->appendToSysPath (extrapath_two.latin1 ())) { + return report_error ("***Failed to set extra 2 sys.path\n"); + } + QString extrapath_three = QString(EXTRA_MODULE_DIR_THREE); + if(!pyize->appendToSysPath (extrapath_three.latin1 ())) { + return report_error ("***Failed to set extra 3 sys.path\n"); + } + + // Load the Python script. + PyObject *pyModule = pyize->importModule ((char *)script.latin1 ()); + if(!pyModule) { + PyErr_Print(); + return report_error ("***failed to import module\n"); + } + + // Inject a helper function + QString bridge = QString("import sip\n" + "import qt\n" + "def kcontrol_bridge_" FACTORY "(parent,name):\n" + " if parent!=0:\n" +#if SIP_VERSION >= 0x040200 + " wparent = sip.wrapinstance(parent,qt.QWidget)\n" +#else + " wparent = sip.wrapinstance(parent,'QWidget')\n" +#endif + " else:\n" + " wparent = None\n" + " inst = " FACTORY "(wparent, name)\n" + " return (inst,sip.unwrapinstance(inst))\n"); + PyRun_String(bridge.latin1(),Py_file_input,PyModule_GetDict(pyModule),PyModule_GetDict(pyModule)); + + // Get the Python module's factory function. + PyObject *kcmFactory = pyize->getNewObjectRef(pyModule, "kcontrol_bridge_" FACTORY); + if(!kcmFactory) { + return report_error ("***failed to find module factory\n"); + } + + // Call the factory function. Set up the args. + PyObject *pyParent = PyLong_FromVoidPtr(parent); + PyObject *pyName = PyString_FromString(MODULE_NAME); + // Using NN here is effect gives our references to the arguement away. + PyObject *args = Py_BuildValue ("NN", pyParent, pyName); + if(pyName && pyParent && args) { + // run the factory function + pyKCModuleTuple = pyize->runFunction(kcmFactory, args); + if(!pyKCModuleTuple) { + PyErr_Print(); + return report_error ("*** runFunction failure\n;"); + } + } else { + return report_error ("***failed to create args\n"); + } + // cleanup a bit + pyize->decref(args); + pyize->decref(kcmFactory); + + // Stop this from getting garbage collected. + Py_INCREF(PyTuple_GET_ITEM(pyKCModuleTuple,0)); + + // convert the KCModule PyObject to a real C++ KCModule *. + isErr = 0; + pyKCModule = PyTuple_GET_ITEM(pyKCModuleTuple,1); + kcmodule = (KCModule *)PyLong_AsVoidPtr(pyKCModule); + if(!kcmodule) { + return report_error ("***failed sip conversion to C++ pointer\n"); + } + pyize->decref(pyKCModuleTuple); + + // PyKDE can't run the module without this - Pythonize + // grabs the lock at initialization and we have to give + // it back before exiting. At this point, we no longer need + // it. + //pyize->releaseLock (); + + // take care of any translation info + KGlobal::locale()->insertCatalogue(script); + + // Return the pointer to our new KCModule + return kcmodule; +} + +extern "C" { + // Factory function that kcontrol will call. + KCModule* CPP_FACTORY(QWidget *parent, const char *name) { + return return_instance(parent, name); + } +} |