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
)
115 gboolean stop
= FALSE
;
117 if (!IS_HOOK(self
)) {
118 PyErr_SetString(PyExc_TypeError
,
119 "descriptor '__call__' requires a 'Hook' object");
123 for (it
= self
->funcs
; !stop
&& it
!= NULL
;) {
124 next
= it
->next
; /* incase the hook removes itself */
126 PyObject
*ret
= PyObject_CallObject(it
->data
, args
);
140 static PyTypeObject HookType
= {
141 PyObject_HEAD_INIT(NULL
)
146 (destructor
) hook_dealloc
, /*tp_dealloc*/
153 0, /*tp_as_sequence*/
158 static PyMethodDef HookMethods
[] = {
159 {"append", (PyCFunction
)hook_append
, METH_VARARGS
,
160 "hook.add(func) -- Add a function to the hook." },
161 {"remove", (PyCFunction
)hook_remove
, METH_VARARGS
,
162 "hook.remove(func) -- Remove a function from the hook." },
163 { NULL
, NULL
, 0, NULL
}
169 * Module initialization/finalization
173 static PyObject
*hooks
, *hooksdict
;
175 static PyMethodDef HooksMethods
[] = {
176 { NULL
, NULL
, 0, NULL
}
179 struct HookObject
*hooks_create(char *name
)
184 hook
= PyObject_New(HookObject
, &HookType
);
187 /* add it to the hooks module */
188 ret
= PyDict_SetItemString(hooksdict
, name
, (PyObject
*) hook
);
196 HookType
.ob_type
= &PyType_Type
;
197 HookType
.tp_methods
= HookMethods
;
198 HookType
.tp_alloc
= PyType_GenericAlloc
;
199 HookType
.tp_new
= PyType_GenericNew
;
200 HookType
.tp_init
= (initproc
) hook_init
;
201 HookType
.tp_call
= (ternaryfunc
) hook_call
;
202 PyType_Ready(&HookType
);
204 Py_InitModule("hooks", HooksMethods
);
206 /* get the hooks module/dict */
207 hooks
= PyImport_ImportModule("hooks"); /* new */
208 g_assert(hooks
!= NULL
);
209 hooksdict
= PyModule_GetDict(hooks
); /* borrowed */
210 g_assert(hooksdict
!= NULL
);
212 /* add the Hook type to the hooks module */
213 PyDict_SetItemString(hooksdict
, "Hook", (PyObject
*) &HookType
);
215 hook_startup
= hooks_create("startup");
216 hook_shutdown
= hooks_create("shutdown");
217 hook_visibledesktop
= hooks_create("visibledesktop");
218 hook_numdesktops
= hooks_create("numdesktops");
219 hook_desktopnames
= hooks_create("desktopnames");
220 hook_showdesktop
= hooks_create("showdesktop");
221 hook_screenconfiguration
= hooks_create("screenconfiguration");
222 hook_screenarea
= hooks_create("screenarea");
223 hook_managed
= hooks_create("managed");
224 hook_closed
= hooks_create("closed");
225 hook_bell
= hooks_create("bell");
226 hook_urgent
= hooks_create("urgent");
227 hook_pointerenter
= hooks_create("pointerenter");
228 hook_pointerleave
= hooks_create("pointerleave");
229 hook_focused
= hooks_create("focused");
230 hook_requestactivate
= hooks_create("requestactivate");
231 hook_title
= hooks_create("title");
232 hook_desktop
= hooks_create("desktop");
233 hook_iconic
= hooks_create("iconic");
234 hook_shaded
= hooks_create("shaded");
235 hook_maximized
= hooks_create("maximized");
236 hook_fullscreen
= hooks_create("fullscreen");
237 hook_visible
= hooks_create("visible");
238 hook_configuration
= hooks_create("configuration");
241 void hooks_shutdown()
243 Py_DECREF(hook_startup
);
244 Py_DECREF(hook_shutdown
);
245 Py_DECREF(hook_visibledesktop
);
246 Py_DECREF(hook_numdesktops
);
247 Py_DECREF(hook_desktopnames
);
248 Py_DECREF(hook_showdesktop
);
249 Py_DECREF(hook_screenconfiguration
);
250 Py_DECREF(hook_screenarea
);
251 Py_DECREF(hook_managed
);
252 Py_DECREF(hook_closed
);
253 Py_DECREF(hook_bell
);
254 Py_DECREF(hook_urgent
);
255 Py_DECREF(hook_pointerenter
);
256 Py_DECREF(hook_pointerleave
);
257 Py_DECREF(hook_focused
);
258 Py_DECREF(hook_requestactivate
);
259 Py_DECREF(hook_title
);
260 Py_DECREF(hook_desktop
);
261 Py_DECREF(hook_iconic
);
262 Py_DECREF(hook_shaded
);
263 Py_DECREF(hook_maximized
);
264 Py_DECREF(hook_fullscreen
);
265 Py_DECREF(hook_visible
);
266 Py_DECREF(hook_configuration
);
271 void hooks_fire(struct HookObject
*hook
, PyObject
*args
)
273 PyObject
*ret
= hook_call(hook
, args
);
279 void hooks_fire_client(struct HookObject
*hook
, struct Client
*client
)
283 if (client
!= NULL
) {
284 PyObject
*c
= clientwrap_new(client
);
286 args
= Py_BuildValue("(O)", c
);
289 args
= Py_BuildValue("(O)", Py_None
);
292 g_assert(args
!= NULL
);
293 hooks_fire(hook
, args
);