/* * pykcm_launcher.cpp * * Launch Control Centre modules written in Python using an embedded Python * interpreter. * Based on David Boddie's PyTDE-components. */ // pythonize.h must be included first. #include #include #include #include #include #include #include #include #include #define MODULE_DIR "/root/TEMP5/tde-guidance-trinity-14.0.0-r131/debian/tmp/opt/trinity/share/apps/guidance" #define EXTRA_MODULE_DIR "None" #define MODULE_NAME "wineconfig" #define FACTORY "create_wineconfig" #define CPP_FACTORY create_wineconfig #define LIB_PYTHON "libpython2.7.so" #define debug 1 static TDECModule *report_error(char *msg) { if (debug) printf ("error: %s\n", msg); return NULL; } static TDECModule* return_instance( TQWidget *parent, const char *name ) { TDECModule* tdecmodule; PyObject *pyTDECModuleTuple; PyObject *pyTDECModule; 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. TQString 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. TQString path = TQString(MODULE_DIR); if(path == TQString::null) { return report_error ("***Failed to locate script path"); } if(!pyize->appendToSysPath (path.latin1 ())) { return report_error ("***Failed to set sys.path\n"); } // Add the extra path to the python script to the interpreter search path. TQString extrapath = TQString(EXTRA_MODULE_DIR); if(!pyize->appendToSysPath (extrapath.latin1 ())) { return report_error ("***Failed to set extra 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 TQString bridge = TQString("import sip_tqt\n" "from python_tqt import qt\n" "def kcontrol_bridge_" FACTORY "(parent,name):\n" " if parent!=0:\n" " wparent = sip_tqt.wrapinstance(parent,qt.TQWidget)\n" " else:\n" " wparent = None\n" " inst = " FACTORY "(wparent, name)\n" " return (inst,sip_tqt.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 pyTDECModuleTuple = pyize->runFunction(kcmFactory, args); if(!pyTDECModuleTuple) { 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(pyTDECModuleTuple,0)); // convert the TDECModule PyObject to a real C++ TDECModule *. isErr = 0; pyTDECModule = PyTuple_GET_ITEM(pyTDECModuleTuple,1); tdecmodule = (TDECModule *)PyLong_AsVoidPtr(pyTDECModule); if(!tdecmodule) { return report_error ("***failed sip conversion to C++ pointer\n"); } pyize->decref(pyTDECModuleTuple); // PyTDE 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 TDEGlobal::locale()->insertCatalogue(script); // Return the pointer to our new TDECModule return tdecmodule; } extern "C" { // Factory function that kcontrol will call. TDECModule* CPP_FACTORY(TQWidget *parent, const char *name) { return return_instance(parent, name); } }