summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSadrul Habib Chowdhury <sadrul@users.sourceforge.net>2009-06-17 03:45:08 -0400
committerSadrul Habib Chowdhury <sadrul@users.sourceforge.net>2009-06-17 03:45:08 -0400
commit9faed3a12789f225f614059035b202cc1006de61 (patch)
treeb1bb0321cb2a30ea8f7e995cb1ede911ac733517
parentc106029959fe3fbaa956729e1960c241fed868af (diff)
downloadscreen-9faed3a12789f225f614059035b202cc1006de61.tar.gz
Allow hooking to object-specific events (partial).
-rw-r--r--src/python.c142
1 files changed, 98 insertions, 44 deletions
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);