summaryrefslogtreecommitdiffstats
path: root/templates/kcm_module_stub.cpp.cmake
diff options
context:
space:
mode:
Diffstat (limited to 'templates/kcm_module_stub.cpp.cmake')
-rw-r--r--templates/kcm_module_stub.cpp.cmake151
1 files changed, 151 insertions, 0 deletions
diff --git a/templates/kcm_module_stub.cpp.cmake b/templates/kcm_module_stub.cpp.cmake
new file mode 100644
index 0000000..91536c7
--- /dev/null
+++ b/templates/kcm_module_stub.cpp.cmake
@@ -0,0 +1,151 @@
+/*
+ * 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 <pythonize.h>
+#include <tdecmodule.h>
+#include <tdeglobal.h>
+#include <tdelocale.h>
+#include <klibloader.h>
+#include <kstandarddirs.h>
+#include <ksimpleconfig.h>
+#include <tqstring.h>
+#include <sip-tqt.h>
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif // _GNU_SOURCE
+#include <dlfcn.h>
+
+#define MODULE_DIR "@_MODULEDIR_@"
+#define EXTRA_MODULE_DIR "@_EXTRAMODULE_@"
+#define MODULE_NAME "@_MODULENAME_@"
+#define FACTORY "@_FACTORYFUNCTION_@"
+#define CPP_FACTORY @_FACTORYFUNCTION_@
+#define debug 1
+
+static TDECModule *report_error(const 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.
+
+ // Try to determine what py script we're loading. Note that "name"
+ // typically appears to be NULL.
+ TQString script(MODULE_NAME);
+
+ // Reload this module, but this time tell the runtime linker to make the
+ // symbols global and available for later loaded libraries/module.
+ Dl_info info;
+ if (!dladdr((const void *)(&return_instance), &info) || !info.dli_fname || !dlopen(info.dli_fname, RTLD_GLOBAL|RTLD_NOW)) {
+ return report_error ("***Unable to export symbols\n");
+ }
+
+ // 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 PyTQt import tqt\n"
+ "def kcontrol_bridge_" FACTORY "(parent,name):\n"
+ " if parent!=0:\n"
+ " wparent = sip_tqt.wrapinstance(parent,tqt.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 = PyBytes_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 *.
+ pyTDECModule = PyTuple_GET_ITEM(pyTDECModuleTuple,1);
+ tdecmodule = (TDECModule *)PyLong_AsVoidPtr(pyTDECModule);
+ if(!tdecmodule) {
+ return report_error ("***failed sip-tqt 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.
+ KDE_EXPORT TDECModule* CPP_FACTORY(TQWidget *parent, const char *name)
+ {
+ return return_instance(parent, name);
+ }
+}
+