29 #include <guile-mappings.h>
30 #include "swig-runtime.h"
31 #include "gnc-hooks.h"
32 #include "gnc-hooks-scm.h"
37 static GHashTable* gnc_hooks_list = NULL;
38 static gboolean gnc_hooks_initialized = FALSE;
43 GHookList *c_danglers;
44 GHookList *scm_danglers;
54 gnc_hook_create (
const gchar *name, gint num_args,
const gchar *desc)
58 g_return_val_if_fail(name != NULL, NULL);
59 g_return_val_if_fail(num_args <= 1, NULL);
60 g_return_val_if_fail(desc != NULL, NULL);
62 ENTER(
"name %s", name);
63 if (gnc_hooks_list == NULL)
65 gnc_hooks_list = g_hash_table_new(g_str_hash, g_str_equal);
68 if (!gnc_hooks_initialized)
72 hook_list = g_hash_table_lookup(gnc_hooks_list, name);
75 LEAVE(
"List %s(%p) already exists", name, hook_list);
80 hook_list->desc = g_strdup(desc);
81 hook_list->c_danglers = g_malloc(
sizeof(GHookList));
82 g_hook_list_init(hook_list->c_danglers,
sizeof(GHook));
83 hook_list->scm_danglers = g_malloc(
sizeof(GHookList));
84 hook_list->num_args = num_args;
85 g_hook_list_init(hook_list->scm_danglers,
sizeof(GHook));
86 g_hash_table_insert(gnc_hooks_list, (gchar *)name, hook_list);
88 LEAVE(
"created list %s(%p)", name, hook_list);
93 gnc_hook_lookup (
const gchar *name)
97 ENTER(
"name %s", name);
98 if (gnc_hooks_list == NULL)
100 PINFO(
"no hook lists");
104 hook = g_hash_table_lookup(gnc_hooks_list, name);
105 LEAVE(
"hook list %p", hook);
110 gnc_hook_add_dangler (
const gchar *name, GFunc callback, gpointer cb_arg)
115 ENTER(
"list %s, function %p, cbarg %p", name, callback, cb_arg);
116 gnc_hook = gnc_hook_lookup(name);
117 g_return_if_fail(gnc_hook != NULL);
118 hook = g_hook_alloc(gnc_hook->c_danglers);
119 hook->func = callback;
121 hook->destroy = NULL;
122 g_hook_append(gnc_hook->c_danglers, hook);
127 hook_remove_runner (GHook *hook, gpointer data)
129 return(hook->func == data);
133 gnc_hook_remove_dangler (
const gchar *name, GFunc callback)
138 ENTER(
"name %s, function %p", name, callback);
139 gnc_hook = gnc_hook_lookup(name);
140 if (gnc_hook == NULL)
142 LEAVE(
"Unknown hook list %s", name);
146 hook = g_hook_find(gnc_hook->c_danglers, TRUE, hook_remove_runner, callback);
149 LEAVE(
"Hook %p not found in %s", callback, name);
153 g_hook_destroy_link(gnc_hook->c_danglers, hook);
154 LEAVE(
"Removed %p from %s", hook, name);
158 delete_scm_hook (gpointer data)
161 scm_gc_unprotect_object(scm->proc);
166 call_scm_hook (GHook *hook, gpointer data)
170 ENTER(
"hook %p, data %p, cbarg %p", hook, data, hook->data);
172 scm_call_0 (scm->proc);
178 call_scm_hook_1 (GHook *hook, gpointer data)
182 ENTER(
"hook %p, data %p, cbarg %p", hook, data, hook->data);
185 scm_call_1 (scm->proc,
186 SWIG_NewPointerObj(data, SWIG_TypeQuery(
"_p_QofSession"), 0));
192 gnc_hook_add_scm_dangler (
const gchar *name, SCM proc)
198 ENTER(
"list %s, proc ???", name);
199 gnc_hook = gnc_hook_lookup(name);
200 g_return_if_fail(gnc_hook != NULL);
202 scm_gc_protect_object(proc);
204 hook = g_hook_alloc(gnc_hook->scm_danglers);
205 hook->func = call_scm_hook;
207 hook->destroy = delete_scm_hook;
208 g_hook_append(gnc_hook->scm_danglers, hook);
213 call_c_hook (GHook *hook, gpointer data)
215 ENTER(
"hook %p (func %p), data %p, cbarg %p", hook, hook->func, data,
217 ((GFunc)hook->func)(data, hook->data);
222 gnc_hook_run (
const gchar *name, gpointer data)
226 ENTER(
"list %s, data %p", (name == NULL ?
"(null)" : name), data);
227 hook = gnc_hook_lookup(name);
230 LEAVE(
"No such hook list");
233 g_hook_list_marshal(hook->c_danglers, TRUE, call_c_hook, data);
234 if (hook->num_args == 0)
235 g_hook_list_marshal(hook->scm_danglers, TRUE, call_scm_hook, data);
237 g_hook_list_marshal(hook->scm_danglers, TRUE, call_scm_hook_1, data);
246 if (gnc_hooks_initialized)
248 LEAVE(
"Hooks already initialized");
252 gnc_hooks_initialized = TRUE;
254 gnc_hook_create(HOOK_STARTUP, 0,
255 "Functions to run at startup. Hook args: ()");
256 gnc_hook_create(HOOK_SHUTDOWN, 0,
257 "Functions to run at guile shutdown. Hook args: ()");
258 gnc_hook_create(HOOK_UI_STARTUP, 0,
259 "Functions to run when the ui comes up. Hook args: ()");
260 gnc_hook_create(HOOK_UI_POST_STARTUP, 0,
261 "Functions to run after the ui comes up. Hook args: ()");
262 gnc_hook_create(HOOK_UI_SHUTDOWN, 0,
263 "Functions to run at ui shutdown. Hook args: ()");
264 gnc_hook_create(HOOK_NEW_BOOK, 0,
265 "Run after a new (empty) book is opened, before the"
266 " book-opened-hook. Hook args: ()");
267 gnc_hook_create(HOOK_REPORT, 0,
268 "Run just before the reports are pushed into the menus."
270 gnc_hook_create(HOOK_CURRENCY_CHANGED, 0,
271 "Functions to run when the user changes currency settings. Hook args: ()");
272 gnc_hook_create(HOOK_SAVE_OPTIONS, 0,
273 "Functions to run when saving options. Hook args: ()");
274 gnc_hook_create(HOOK_ADD_EXTENSION, 0,
275 "Functions to run when the extensions menu is created."
278 gnc_hook_create(HOOK_BOOK_OPENED, 1,
279 "Run after book open. Hook args: <gnc:Session*>.");
280 gnc_hook_create(HOOK_BOOK_CLOSED, 1,
281 "Run before file close. Hook args: <gnc:Session*>");
282 gnc_hook_create(HOOK_BOOK_SAVED, 1,
283 "Run after file saved. Hook args: <gnc:Session*>");
#define PINFO(format, args...)
#define ENTER(format, args...)
All type declarations for the whole Gnucash engine.
#define LEAVE(format, args...)
const gchar * QofLogModule