From: Sadrul Habib Chowdhury Date: Wed, 17 Jun 2009 07:45:08 +0000 (-0400) Subject: Allow hooking to object-specific events (partial). X-Git-Url: https://repo.or.cz/w/screen-lua.git/commitdiff_plain/9faed3a12789f225f614059035b202cc1006de61 Allow hooking to object-specific events (partial). --- diff --git a/src/python.c b/src/python.c index 29a4a27..1572450 100644 --- a/src/python.c +++ b/src/python.c @@ -46,6 +46,7 @@ extern struct layer *flayer; static PyObject * SPy_Get(PyObject *obj, void *closure); static PyObject * SPy_Set(PyObject *obj, PyObject *value, void *closure); static int PyDispatch(void *handler, const char *params, va_list va); +static PyObject * register_event_hook(PyObject *self, PyObject *args, PyObject *kw, void *object); typedef struct { @@ -82,6 +83,7 @@ register_##type(PyObject *module) \ getsets[i].get = SPy_Get; \ getsets[i].set = SPy_Set; \ } \ + PyType##Type.tp_base = &ScreenObjectType; \ PyType##Type.tp_getset = getsets; \ PyType##Type.tp_methods = methods; \ PyType##Type.tp_compare = compare_##type; \ @@ -95,7 +97,7 @@ register_##type(PyObject *module) \ #define DEFINE_TYPE(str, Type) \ typedef struct \ { \ - PyObject_HEAD \ + ScreenObject __parent; \ str *_obj; \ } Py##Type; \ \ @@ -127,6 +129,48 @@ PyString_FromStringSafe(const char *str) RETURN_NONE; } +/** Generic Object {{{ */ +typedef struct +{ + PyObject_HEAD + char *name; +} ScreenObject; + +static PyObject * +object_hook(PyObject *self, PyObject *args, PyObject *kw) +{ + char *object; + object = *(char **)((char *)self + sizeof(ScreenObject)); /* ugliness */ + return register_event_hook(self, args, kw, object); +} + +static PyMethodDef omethods[] = { + {"hook", (PyCFunction)object_hook, METH_VARARGS | METH_KEYWORDS, "Hook to an event on the object."}, + {NULL} +}; + +static PyTypeObject ScreenObjectType = +{ + PyObject_HEAD_INIT(NULL) + .ob_size = 0, + .tp_name = "screen.Object", + .tp_basicsize = sizeof(ScreenObject), + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + .tp_doc = "Generic object", + .tp_methods = omethods, + .tp_getset = NULL, +}; + +static int +register_object(PyObject *module) +{ + PyType_Ready(&ScreenObjectType); + Py_INCREF(&ScreenObjectType); + PyModule_AddObject(module, "Generic Object", (PyObject *)&ScreenObjectType); +} + +/** }}} */ + /** Window {{{ */ DEFINE_TYPE(struct win, Window) @@ -359,51 +403,11 @@ PyDispatch(void *handler, const char *params, va_list va) return retval; } -/** Screen {{{ */ -static PyObject * -screen_display(PyObject *self) -{ - if (!display) - { - RETURN_NONE; - } - return PyObject_FromDisplay(display); -} - -static PyObject * -screen_displays(PyObject *self) -{ - struct display *d = displays; - int count = 0; - for (; d; d = d->d_next) - ++count; - PyObject *tuple = PyTuple_New(count); - - for (d = displays, count = 0; d; d = d->d_next, ++count) - PyTuple_SetItem(tuple, count, PyObject_FromDisplay(d)); - - return tuple; -} - static PyObject * -screen_windows(PyObject *self) -{ - struct win *w = windows; - int count = 0; - for (; w; w = w->w_next) - ++count; - PyObject *tuple = PyTuple_New(count); - - for (w = windows, count = 0; w; w = w->w_next, ++count) - PyTuple_SetItem(tuple, count, PyObject_FromWindow(w)); - - return tuple; -} - -static PyObject * -hook_event(PyObject *self, PyObject *args, PyObject *kw) +register_event_hook(PyObject *self, PyObject *args, PyObject *kw, void *object) { static char *kwlist[] = {"event", "callback", NULL}; + PyObject *callback; char *name; @@ -421,7 +425,7 @@ hook_event(PyObject *self, PyObject *args, PyObject *kw) return NULL; } - sev = object_get_event(NULL, name); + sev = object_get_event(object, name); if (!sev) { LMsg(0, "No event named '%s'", name); @@ -451,6 +455,55 @@ hook_event(PyObject *self, PyObject *args, PyObject *kw) Py_INCREF((PyObject *)l->handler); return l->handler; + + RETURN_NONE; +} + +/** Screen {{{ */ +static PyObject * +screen_display(PyObject *self) +{ + if (!display) + { + RETURN_NONE; + } + return PyObject_FromDisplay(display); +} + +static PyObject * +screen_displays(PyObject *self) +{ + struct display *d = displays; + int count = 0; + for (; d; d = d->d_next) + ++count; + PyObject *tuple = PyTuple_New(count); + + for (d = displays, count = 0; d; d = d->d_next, ++count) + PyTuple_SetItem(tuple, count, PyObject_FromDisplay(d)); + + return tuple; +} + +static PyObject * +screen_windows(PyObject *self) +{ + struct win *w = windows; + int count = 0; + for (; w; w = w->w_next) + ++count; + PyObject *tuple = PyTuple_New(count); + + for (w = windows, count = 0; w; w = w->w_next, ++count) + PyTuple_SetItem(tuple, count, PyObject_FromWindow(w)); + + return tuple; +} + +static PyObject * +hook_event(PyObject *self, PyObject *args, PyObject *kw) +{ + return register_event_hook(self, args, kw, NULL); } static void @@ -514,6 +567,7 @@ SPyInit(void) Py_Initialize(); m = Py_InitModule3 ("screen", py_methods, NULL); + register_object(m); register_window(m); register_display(m); register_callback(m);