4 * Copyright (c) Tuomo Valkonen 1999-2007.
6 * See the included file LICENSE for details.
9 #include <libtu/types.h>
10 #include <libtu/misc.h>
11 #include <libtu/dlist.h>
12 #include <libtu/output.h>
14 #include <libtu/objp.h>
15 #include <libtu/locale.h>
16 #include <libextl/extl.h>
21 IMPLCLASS(WHook, Obj, hook_deinit, NULL);
23 static Rb_node named_hooks=NULL;
29 /* If hk==NULL to register, new is attempted to be created. */
30 WHook *mainloop_register_hook(const char *name, WHook *hk)
38 if(named_hooks==NULL){
39 named_hooks=make_rb();
49 if(!rb_insert(named_hooks, nnm, hk)){
51 destroy_obj((Obj*)hk);
58 WHook *mainloop_unregister_hook(const char *name, WHook *hk)
68 node=rb_find_key_n(named_hooks, name, &found);
70 rb_traverse(node, named_hooks){
71 if((WHook*)rb_val(node)==hk){
79 hk=(WHook*)rb_val(node);
80 free((char*)node->k.key);
89 * Find named hook \var{name}.
93 WHook *mainloop_get_hook(const char *name)
98 if(named_hooks!=NULL){
100 Rb_node node=rb_find_key_n(named_hooks, name, &found);
102 return (WHook*)rb_val(node);
115 static void destroy_item(WHook *hk, WHookItem *item)
118 extl_unref_fn(item->efn);
119 UNLINK_ITEM(hk->items, item, next, prev);
124 static WHookItem *create_item(WHook *hk)
126 WHookItem *item=ALLOC(WHookItem);
128 LINK_ITEM_FIRST(hk->items, item, next, prev);
130 item->efn=extl_fn_none();
137 bool hook_init(WHook *hk)
146 CREATEOBJ_IMPL(WHook, hook, (p));
150 void hook_deinit(WHook *hk)
152 mainloop_unregister_hook(NULL, hk);
153 while(hk->items!=NULL)
154 destroy_item(hk, hk->items);
161 /*{{{ Find/add/remove */
164 WHookItem *hook_find(WHook *hk, WHookDummy *fn)
168 for(hi=hk->items; hi!=NULL; hi=hi->next){
177 WHookItem *hook_find_extl(WHook *hk, ExtlFn efn)
181 for(hi=hk->items; hi!=NULL; hi=hi->next){
182 if(extl_fn_eq(hi->efn, efn))
191 * Is \var{fn} hooked to hook \var{hk}?
195 bool hook_listed(WHook *hk, ExtlFn efn)
197 return hook_find_extl(hk, efn)!=NULL;
201 bool hook_add(WHook *hk, WHookDummy *fn)
205 if(hook_find(hk, fn))
208 item=create_item(hk);
217 * Add \var{efn} to the list of functions to be called when the
218 * hook \var{hk} is triggered.
220 EXTL_EXPORT_AS(WHook, add)
221 bool hook_add_extl(WHook *hk, ExtlFn efn)
225 if(efn==extl_fn_none()){
226 warn(TR("No function given."));
230 if(hook_find_extl(hk, efn))
233 item=create_item(hk);
238 item->efn=extl_ref_fn(efn);
244 bool hook_remove(WHook *hk, WHookDummy *fn)
246 WHookItem *item=hook_find(hk, fn);
248 destroy_item(hk, item);
254 * Remove \var{efn} from the list of functions to be called when the
255 * hook \var{hk} is triggered.
257 EXTL_EXPORT_AS(WHook, remove)
258 bool hook_remove_extl(WHook *hk, ExtlFn efn)
260 WHookItem *item=hook_find_extl(hk, efn);
262 destroy_item(hk, item);
270 /*{{{ Basic marshallers */
273 static bool marshall_v(WHookDummy *fn, void *param)
280 static bool marshall_extl_v(ExtlFn fn, void *param)
282 extl_call(fn, NULL, NULL);
287 static bool marshall_o(WHookDummy *fn, void *param)
294 static bool marshall_extl_o(ExtlFn fn, void *param)
296 return extl_call(fn, "o", NULL, (Obj*)param);
300 static bool marshall_p(WHookDummy *fn, void *param)
307 static bool marshall_alt_v(bool (*fn)(), void *param)
313 static bool marshall_extl_alt_v(ExtlFn fn, void *param)
316 extl_call(fn, NULL, "b", &ret);
321 static bool marshall_alt_o(bool (*fn)(), void *param)
323 return fn((Obj*)param);
327 static bool marshall_extl_alt_o(ExtlFn fn, void *param)
330 extl_call(fn, "o", "b", (Obj*)param, &ret);
335 static bool marshall_alt_p(bool (*fn)(), void *param)
347 void hook_call(const WHook *hk, void *p,
348 WHookMarshall *m, WHookMarshallExtl *em)
350 WHookItem *hi, *next;
352 for(hi=hk->items; hi!=NULL; hi=next){
362 bool hook_call_alt(const WHook *hk, void *p,
363 WHookMarshall *m, WHookMarshallExtl *em)
365 WHookItem *hi, *next;
368 for(hi=hk->items; hi!=NULL; hi=next){
382 void hook_call_v(const WHook *hk)
384 hook_call(hk, NULL, marshall_v, marshall_extl_v);
388 void hook_call_o(const WHook *hk, Obj *o)
390 hook_call(hk, o, marshall_o, marshall_extl_o);
394 void hook_call_p(const WHook *hk, void *p, WHookMarshallExtl *em)
396 hook_call(hk, p, marshall_p, em);
400 bool hook_call_alt_v(const WHook *hk)
402 return hook_call_alt(hk, NULL, (WHookMarshall*)marshall_alt_v,
403 (WHookMarshallExtl*)marshall_extl_alt_v);
407 bool hook_call_alt_o(const WHook *hk, Obj *o)
409 return hook_call_alt(hk, o, (WHookMarshall*)marshall_alt_o,
410 (WHookMarshallExtl*)marshall_extl_alt_o);
414 bool hook_call_alt_p(const WHook *hk, void *p, WHookMarshallExtl *em)
416 return hook_call_alt(hk, p, (WHookMarshall*)marshall_alt_p, em);