6 * Define the 'Hook' class type
9 #define IS_HOOK(v) ((v)->ob_type == &HookType)
11 staticforward PyTypeObject HookType;
13 typedef struct HookObject {
18 static int hook_init(HookObject *self, PyObject *args, PyObject *kwds)
20 char *keywords[] = { 0 };
21 if (!PyArg_ParseTupleAndKeywords(args, kwds, ":__init__", keywords))
27 static void hook_dealloc(HookObject *self)
31 for (it = self->funcs; it != NULL; it = it->next)
32 Py_DECREF((PyObject*) it->data);
34 PyObject_Del((PyObject*) self);
37 static PyObject *hook_fire(HookObject *self, PyObject *args)
42 PyErr_SetString(PyExc_TypeError,
43 "descriptor 'fire' requires a 'Hook' object");
47 for (it = self->funcs; it != NULL; it = it->next) {
48 PyObject *ret = PyObject_CallObject(it->data, args);
58 static PyObject *hook_append(HookObject *self, PyObject *args)
63 PyErr_SetString(PyExc_TypeError,
64 "descriptor 'append' requires a 'Hook' object");
67 if (!PyArg_ParseTuple(args, "O:append", &func))
69 if (!PyCallable_Check(func)) {
70 PyErr_SetString(PyExc_TypeError,
71 "descriptor 'append' requires a callable argument");
74 self->funcs = g_slist_append(self->funcs, func);
81 static PyObject *hook_remove(HookObject *self, PyObject *args)
87 PyErr_SetString(PyExc_TypeError,
88 "descriptor 'remove' requires a 'Hook' object");
91 if (!PyArg_ParseTuple(args, "O:remove", &func))
93 if (!PyCallable_Check(func)) {
94 PyErr_SetString(PyExc_TypeError,
95 "descriptor 'remove' requires a callable argument");
99 it = g_slist_find(self->funcs, func);
101 self->funcs = g_slist_delete_link(self->funcs, it);
107 PyErr_SetString(PyExc_TypeError,
108 "given callable object was not found in Hook");
112 static PyObject *hook_call(HookObject *self, PyObject *args)
116 gboolean stop = FALSE;
118 if (!IS_HOOK(self)) {
119 PyErr_SetString(PyExc_TypeError,
120 "descriptor '__call__' requires a 'Hook' object");
124 for (it = self->funcs; !stop && it != NULL;) {
125 next = it->next; /* incase the hook removes itself */
127 ret = PyObject_CallObject(it->data, args);
141 static PyTypeObject HookType = {
142 PyObject_HEAD_INIT(NULL)
147 (destructor) hook_dealloc, /*tp_dealloc*/
154 0, /*tp_as_sequence*/
159 static PyMethodDef HookMethods[] = {
160 {"append", (PyCFunction)hook_append, METH_VARARGS,
161 "hook.add(func) -- Add a function to the hook." },
162 {"remove", (PyCFunction)hook_remove, METH_VARARGS,
163 "hook.remove(func) -- Remove a function from the hook." },
164 { NULL, NULL, 0, NULL }
170 * Module initialization/finalization
174 static PyObject *hooks, *hooksdict;
176 static PyMethodDef HooksMethods[] = {
177 { NULL, NULL, 0, NULL }
180 struct HookObject *hooks_create(char *name)
185 hook = PyObject_New(HookObject, &HookType);
188 /* add it to the hooks module */
189 ret = PyDict_SetItemString(hooksdict, name, (PyObject*) hook);
197 HookType.ob_type = &PyType_Type;
198 HookType.tp_methods = HookMethods;
199 HookType.tp_alloc = PyType_GenericAlloc;
200 HookType.tp_new = PyType_GenericNew;
201 HookType.tp_init = (initproc) hook_init;
202 HookType.tp_call = (ternaryfunc) hook_call;
203 PyType_Ready(&HookType);
205 Py_InitModule("hooks", HooksMethods);
207 /* get the hooks module/dict */
208 hooks = PyImport_ImportModule("hooks"); /* new */
209 g_assert(hooks != NULL);
210 hooksdict = PyModule_GetDict(hooks); /* borrowed */
211 g_assert(hooksdict != NULL);
213 /* add the Hook type to the hooks module */
214 PyDict_SetItemString(hooksdict, "Hook", (PyObject*) &HookType);
216 hook_startup = hooks_create("startup");
217 hook_shutdown = hooks_create("shutdown");
218 hook_visibledesktop = hooks_create("visibledesktop");
219 hook_numdesktops = hooks_create("numdesktops");
220 hook_desktopnames = hooks_create("desktopnames");
221 hook_showdesktop = hooks_create("showdesktop");
222 hook_screenconfiguration = hooks_create("screenconfiguration");
223 hook_screenarea = hooks_create("screenarea");
224 hook_managed = hooks_create("managed");
225 hook_closed = hooks_create("closed");
226 hook_bell = hooks_create("bell");
227 hook_urgent = hooks_create("urgent");
228 hook_pointerenter = hooks_create("pointerenter");
229 hook_pointerleave = hooks_create("pointerleave");
230 hook_focused = hooks_create("focused");
231 hook_requestactivate = hooks_create("requestactivate");
232 hook_title = hooks_create("title");
233 hook_desktop = hooks_create("desktop");
234 hook_iconic = hooks_create("iconic");
235 hook_shaded = hooks_create("shaded");
236 hook_maximized = hooks_create("maximized");
237 hook_fullscreen = hooks_create("fullscreen");
238 hook_visible = hooks_create("visible");
239 hook_configuration = hooks_create("configuration");
242 void hooks_shutdown()
244 Py_DECREF(hook_startup);
245 Py_DECREF(hook_shutdown);
246 Py_DECREF(hook_visibledesktop);
247 Py_DECREF(hook_numdesktops);
248 Py_DECREF(hook_desktopnames);
249 Py_DECREF(hook_showdesktop);
250 Py_DECREF(hook_screenconfiguration);
251 Py_DECREF(hook_screenarea);
252 Py_DECREF(hook_managed);
253 Py_DECREF(hook_closed);
254 Py_DECREF(hook_bell);
255 Py_DECREF(hook_urgent);
256 Py_DECREF(hook_pointerenter);
257 Py_DECREF(hook_pointerleave);
258 Py_DECREF(hook_focused);
259 Py_DECREF(hook_requestactivate);
260 Py_DECREF(hook_title);
261 Py_DECREF(hook_desktop);
262 Py_DECREF(hook_iconic);
263 Py_DECREF(hook_shaded);
264 Py_DECREF(hook_maximized);
265 Py_DECREF(hook_fullscreen);
266 Py_DECREF(hook_visible);
267 Py_DECREF(hook_configuration);
272 void hooks_fire(struct HookObject *hook, PyObject *args)
274 PyObject *ret = hook_call(hook, args);
280 void hooks_fire_client(struct HookObject *hook, struct Client *client)
284 if (client != NULL) {
285 PyObject *c = clientwrap_new(client);
287 args = Py_BuildValue("(O)", c);
290 args = Py_BuildValue("(O)", Py_None);
293 g_assert(args != NULL);
294 hooks_fire(hook, args);