+
+bool python_exec(const std::string &path)
+{
+ FILE *rcpyfd = fopen(path.c_str(), "r");
+ if (!rcpyfd) {
+ printf("failed to load python file %s\n", path.c_str());
+ return false;
+ }
+ PyRun_SimpleFile(rcpyfd, const_cast<char*>(path.c_str()));
+ fclose(rcpyfd);
+ return true;
+}
+
+bool python_get_long(const char *name, long *value)
+{
+ PyObject *val = PyDict_GetItemString(obdict, const_cast<char*>(name));
+ if (!(val && PyLong_Check(val))) return false;
+
+ *value = PyLong_AsLong(val);
+ return true;
+}
+
+bool python_get_string(const char *name, std::string *value)
+{
+ PyObject *val = PyDict_GetItemString(obdict, const_cast<char*>(name));
+ if (!(val && PyString_Check(val))) return false;
+
+ *value = PyString_AsString(val);
+ return true;
+}
+
+bool python_get_stringlist(const char *name, std::vector<std::string> *value)
+{
+ PyObject *val = PyDict_GetItemString(obdict, const_cast<char*>(name));
+ if (!(val && PyList_Check(val))) return false;
+
+ for (int i = 0, end = PyList_Size(val); i < end; ++i) {
+ PyObject *str = PyList_GetItem(val, i);
+ if (PyString_Check(str))
+ value->push_back(PyString_AsString(str));
+ }
+ return true;
+}
+
+// ************************************* //
+// Stuff for calling from Python scripts //
+// ************************************* //
+
+PyObject *mbind(const std::string &button, ob::MouseContext context,
+ ob::MouseAction action, PyObject *func)
+{
+ if (!PyCallable_Check(func)) {
+ PyErr_SetString(PyExc_TypeError, "Invalid callback function.");
+ return NULL;
+ }