+}
+
+PyObject *BindingData_time(BindingData *self, PyObject *args)
+{
+ if(!PyArg_ParseTuple(args,":time")) return NULL;
+ return PyLong_FromLong(self->time);
+}
+
+static PyMethodDef BindingData_methods[] = {
+ {"window", (PyCFunction)BindingData_window, METH_VARARGS,
+ "Return the client window id."},
+ {"modifiers", (PyCFunction)BindingData_modifiers, METH_VARARGS,
+ "Return the modifier keys state."},
+ {"key", (PyCFunction)BindingData_key, METH_VARARGS,
+ "Return the name of the pressed key."},
+ {"time", (PyCFunction)BindingData_time, METH_VARARGS,
+ "Return the time at which the event occured."},
+ {NULL, NULL, 0, NULL}
+};
+
+static PyObject *ActionDataGetAttr(PyObject *obj, char *name)
+{
+ return Py_FindMethod(ActionData_methods, obj, name);
+}
+
+static PyObject *BindingDataGetAttr(PyObject *obj, char *name)
+{
+ return Py_FindMethod(BindingData_methods, obj, name);
+}
+
+static PyTypeObject ActionData_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0,
+ "ActionData",
+ sizeof(ActionData),
+ 0,
+ (destructor)ActionDataDealloc,
+ 0,
+ (getattrfunc)ActionDataGetAttr,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+};
+
+static PyTypeObject BindingData_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0,
+ "BindingData",
+ sizeof(BindingData),
+ 0,
+ (destructor)BindingDataDealloc,
+ 0,
+ (getattrfunc)BindingDataGetAttr,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+};
+
+// **************** //
+// End custom types //
+// **************** //
+
+void python_init(char *argv0)
+{
+ Py_SetProgramName(argv0);
+ Py_Initialize();
+ init_otk();
+ init_openbox();
+ PyRun_SimpleString("from _otk import *; from _openbox import *;");
+ PyRun_SimpleString("openbox = Openbox_instance()");
+
+ // set up access to the python global variables
+ PyObject *obmodule = PyImport_AddModule("__main__");
+ obdict = PyModule_GetDict(obmodule);
+
+ // set up the custom types
+ ActionData_Type.ob_type = &PyType_Type;
+ BindingData_Type.ob_type = &PyType_Type;
+}
+
+void python_destroy()
+{
+ Py_DECREF(obdict);
+}
+
+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;