2 * $Id: hook.h 662 2008-03-02 11:38:08Z nkeynes $
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 let 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_HOOKS( name, args... ) FOREACH_HOOK(h, name) { h->fn(args, h->user_data); }
51 #define DEFINE_HOOK( name, fn_type ) \
52 struct name##_hook_struct { \
55 struct name##_hook_struct *next; \
56 } *name##_hook_list = NULL; \
57 void register_##name( fn_type fn, void *user_data ) { \
58 struct name##_hook_struct *h = malloc(sizeof(struct name##_hook_struct)); \
61 h->user_data = user_data; \
62 h->next = name##_hook_list; \
63 name##_hook_list = h; \
65 void unregister_##name( fn_type fn, void *user_data ) { \
66 struct name##_hook_struct *last = NULL, *h = name##_hook_list; \
67 while( h != NULL ) { \
68 if( h->fn == fn && h->user_data == user_data ) { \
69 if( last == NULL ) { \
70 name##_hook_list = h->next; \
72 last->next = h->next; \
82 #endif /* !lxdream_hook_H */
.