4 * Copyright (c) Tuomo Valkonen 1999-2007.
6 * Ion is free software; you can redistribute it and/or modify it under
7 * the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation; either version 2.1 of the License, or
9 * (at your option) any later version.
12 #include <libtu/types.h>
13 #include <libtu/misc.h>
14 #include <libtu/dlist.h>
15 #include <libtu/output.h>
17 #include <libtu/objp.h>
18 #include <libtu/locale.h>
19 #include <libextl/extl.h>
24 IMPLCLASS(WHook, Obj, hook_deinit, NULL);
26 static Rb_node named_hooks=NULL;
32 /* If hk==NULL to register, new is attempted to be created. */
33 WHook *mainloop_register_hook(const char *name, WHook *hk)
41 if(named_hooks==NULL){
42 named_hooks=make_rb();
52 if(!rb_insert(named_hooks, nnm, hk)){
54 destroy_obj((Obj*)hk);
61 WHook *mainloop_unregister_hook(const char *name, WHook *hk)
71 node=rb_find_key_n(named_hooks, name, &found);
73 rb_traverse(node, named_hooks){
74 if((WHook*)rb_val(node)==hk){
82 hk=(WHook*)rb_val(node);
83 free((char*)node->k.key);
92 * Find named hook \var{name}.
96 WHook *mainloop_get_hook(const char *name)
101 if(named_hooks!=NULL){
103 Rb_node node=rb_find_key_n(named_hooks, name, &found);
105 return (WHook*)rb_val(node);
118 static void destroy_item(WHook *hk, WHookItem *item)
121 extl_unref_fn(item->efn);
122 UNLINK_ITEM(hk->items, item, next, prev);
127 static WHookItem *create_item(WHook *hk)
129 WHookItem *item=ALLOC(WHookItem);
131 LINK_ITEM_FIRST(hk->items, item, next, prev);
133 item->efn=extl_fn_none();
140 bool hook_init(WHook *hk)
149 CREATEOBJ_IMPL(WHook, hook, (p));
153 void hook_deinit(WHook *hk)
155 mainloop_unregister_hook(NULL, hk);
156 while(hk->items!=NULL)
157 destroy_item(hk, hk->items);
164 /*{{{ Find/add/remove */
167 WHookItem *hook_find(WHook *hk, WHookDummy *fn)
171 for(hi=hk->items; hi!=NULL; hi=hi->next){
180 WHookItem *hook_find_extl(WHook *hk, ExtlFn efn)
184 for(hi=hk->items; hi!=NULL; hi=hi->next){
185 if(extl_fn_eq(hi->efn, efn))
194 * Is \var{fn} hooked to hook \var{hk}?
198 bool hook_listed(WHook *hk, ExtlFn efn)
200 return hook_find_extl(hk, efn)!=NULL;
204 bool hook_add(WHook *hk, WHookDummy *fn)
208 if(hook_find(hk, fn))
211 item=create_item(hk);
220 * Add \var{efn} to the list of functions to be called when the
221 * hook \var{hk} is triggered.
223 EXTL_EXPORT_AS(WHook, add)
224 bool hook_add_extl(WHook *hk, ExtlFn efn)
228 if(efn==extl_fn_none()){
229 warn(TR("No function given."));
233 if(hook_find_extl(hk, efn))
236 item=create_item(hk);
241 item->efn=extl_ref_fn(efn);
247 bool hook_remove(WHook *hk, WHookDummy *fn)
249 WHookItem *item=hook_find(hk, fn);
251 destroy_item(hk, item);
257 * Remove \var{efn} from the list of functions to be called when the
258 * hook \var{hk} is triggered.
260 EXTL_EXPORT_AS(WHook, remove)
261 bool hook_remove_extl(WHook *hk, ExtlFn efn)
263 WHookItem *item=hook_find_extl(hk, efn);
265 destroy_item(hk, item);
273 /*{{{ Basic marshallers */
276 static bool marshall_v(WHookDummy *fn, void *param)
283 static bool marshall_extl_v(ExtlFn fn, void *param)
285 extl_call(fn, NULL, NULL);
290 static bool marshall_o(WHookDummy *fn, void *param)
297 static bool marshall_extl_o(ExtlFn fn, void *param)
299 return extl_call(fn, "o", NULL, (Obj*)param);
303 static bool marshall_p(WHookDummy *fn, void *param)
310 static bool marshall_alt_v(bool (*fn)(), void *param)
316 static bool marshall_extl_alt_v(ExtlFn fn, void *param)
319 extl_call(fn, NULL, "b", &ret);
324 static bool marshall_alt_o(bool (*fn)(), void *param)
326 return fn((Obj*)param);
330 static bool marshall_extl_alt_o(ExtlFn fn, void *param)
333 extl_call(fn, "o", "b", (Obj*)param, &ret);
338 static bool marshall_alt_p(bool (*fn)(), void *param)
350 void hook_call(const WHook *hk, void *p,
351 WHookMarshall *m, WHookMarshallExtl *em)
353 WHookItem *hi, *next;
355 for(hi=hk->items; hi!=NULL; hi=next){
365 bool hook_call_alt(const WHook *hk, void *p,
366 WHookMarshall *m, WHookMarshallExtl *em)
368 WHookItem *hi, *next;
371 for(hi=hk->items; hi!=NULL; hi=next){
385 void hook_call_v(const WHook *hk)
387 hook_call(hk, NULL, marshall_v, marshall_extl_v);
391 void hook_call_o(const WHook *hk, Obj *o)
393 hook_call(hk, o, marshall_o, marshall_extl_o);
397 void hook_call_p(const WHook *hk, void *p, WHookMarshallExtl *em)
399 hook_call(hk, p, marshall_p, em);
403 bool hook_call_alt_v(const WHook *hk)
405 return hook_call_alt(hk, NULL, (WHookMarshall*)marshall_alt_v,
406 (WHookMarshallExtl*)marshall_extl_alt_v);
410 bool hook_call_alt_o(const WHook *hk, Obj *o)
412 return hook_call_alt(hk, o, (WHookMarshall*)marshall_alt_o,
413 (WHookMarshallExtl*)marshall_extl_alt_o);
417 bool hook_call_alt_p(const WHook *hk, void *p, WHookMarshallExtl *em)
419 return hook_call_alt(hk, p, (WHookMarshall*)marshall_alt_p, em);