4 * This file defines some useful generic macros for hooks
6 * Copyright (c) 2008 Nathan Keynes.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
19 #ifndef lxdream_hook_H
20 #define lxdream_hook_H 1
25 * Hook functions are generally useful, so we'd like to limit the overhead (and
26 * opportunity for stupid bugs) by minimizing the amount of code involved. Glib
27 * has GHook (and of course signals), but they don't actually simplify anything
30 * Hence, the gratuitous macro abuse here.
36 * DECLARE_HOOK( hook_name, hook_fn_type );
38 * In implementation file:
40 * DEFINE_HOOK( hook_name, hook_fn_type );
43 #define DECLARE_HOOK( name, fn_type ) \
44 void register_##name( fn_type fn, void *user_data ); \
45 void unregister_##name( fn_type fn, void *user_data )
47 #define FOREACH_HOOK( h, name ) struct name##_hook_struct *h; for( h = name##_hook_list; h != NULL; h = h->next )
49 #define CALL_HOOKS0( name ) FOREACH_HOOK(h,name) { h->fn(h->user_data); }
50 #define CALL_HOOKS( name, args... ) FOREACH_HOOK(h, name) { h->fn(args, h->user_data); }
52 #define DEFINE_HOOK( name, fn_type ) \
53 struct name##_hook_struct { \
56 struct name##_hook_struct *next; \
57 } *name##_hook_list = NULL; \
58 void register_##name( fn_type fn, void *user_data ) { \
59 struct name##_hook_struct *h = malloc(sizeof(struct name##_hook_struct)); \
62 h->user_data = user_data; \
63 h->next = name##_hook_list; \
64 name##_hook_list = h; \
66 void unregister_##name( fn_type fn, void *user_data ) { \
67 struct name##_hook_struct *last = NULL, *h = name##_hook_list; \
68 while( h != NULL ) { \
69 if( h->fn == fn && h->user_data == user_data ) { \
70 if( last == NULL ) { \
71 name##_hook_list = h->next; \
73 last->next = h->next; \
83 #endif /* !lxdream_hook_H */
.