[Gnucash-changes] Implement C side hook lists in parallel with the
existing Scheme hook
David Hampton
hampton at cvs.gnucash.org
Tue Jun 7 11:47:59 EDT 2005
Log Message:
-----------
Implement C side hook lists in parallel with the existing Scheme
hook lists. Allows hooks to be easily installed from either
Scheme or C code.
Tags:
----
gnucash-gnome2-dev
Modified Files:
--------------
gnucash:
ChangeLog
gnucash/src/app-file:
gnc-file.c
gnucash/src/app-utils:
prefs.scm
gnucash/src/core-utils:
Makefile.am
gw-core-utils-spec.scm
gnucash/src/gnome:
dialog-new-user.c
top-level.c
gnucash/src/gnome-utils:
gnc-menu-extensions.scm
gnucash/src/report/report-gnome:
report-gnome.scm
gnucash/src/scm:
main.scm
Added Files:
-----------
gnucash/src/core-utils:
gnc-hooks.c
gnc-hooks.h
Revision Data
-------------
Index: ChangeLog
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/ChangeLog,v
retrieving revision 1.1487.2.217
retrieving revision 1.1487.2.218
diff -LChangeLog -LChangeLog -u -r1.1487.2.217 -r1.1487.2.218
--- ChangeLog
+++ ChangeLog
@@ -1,3 +1,10 @@
+2005-06-07 David Hampton <hampton at employees.org>
+
+ * src/core-utils/gnc-hooks.[ch]: Implement C side hook lists. Will
+ allow hooks to be easily installed from either Scheme or C code.
+
+ * various files: Call the C hooks whenever a Scheme hook is called.
+
2005-06-06 David Hampton <hampton at employees.org>
* src/gnome/gnc-plugin-basic-commands.c: Forgot to change the
Index: prefs.scm
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/app-utils/prefs.scm,v
retrieving revision 1.28.4.4
retrieving revision 1.28.4.5
diff -Lsrc/app-utils/prefs.scm -Lsrc/app-utils/prefs.scm -u -r1.28.4.4 -r1.28.4.5
--- src/app-utils/prefs.scm
+++ src/app-utils/prefs.scm
@@ -19,6 +19,7 @@
(require 'sort)
(require 'hash-table)
+(use-modules (g-wrapped gw-core-utils))
;; (define gnc:*double-entry-restriction*
;; (gnc:make-config-var
@@ -80,7 +81,8 @@
;; hook should probably revert back to just save-global-options.
(define (gnc:save-all-options)
(gnc:save-global-options)
- (gnc:hook-run-danglers gnc:*save-options-hook*))
+ (gnc:hook-run-danglers gnc:*save-options-hook*)
+ (gnc:run-c-hook "save-options-hook" #f))
(define (gnc:save-global-options)
(gnc:make-home-dir)
--- /dev/null
+++ src/core-utils/gnc-hooks.h
@@ -0,0 +1,40 @@
+/*
+ * gnc-hooks.h -- helpers for using Glib hook functions
+ * Copyright (C) 2005 David Hampton <hampton at employees.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, contact:
+ *
+ * Free Software Foundation Voice: +1-617-542-5942
+ * 59 Temple Place - Suite 330 Fax: +1-617-542-2652
+ * Boston, MA 02111-1307, USA gnu at gnu.org
+ *
+ */
+
+void gnc_run_c_hook(const gchar *name, gpointer data);
+void gnc_add_to_c_hook(const gchar *name, GHookFunc callback);
+void gnc_remove_from_c_hook(const gchar *name, GHookFunc callback);
+
+
+/* Common hook name */
+#define HOOK_STARTUP "hook_startup"
+#define HOOK_SHUTDOWN "hook_shutdown"
+#define HOOK_UI_STARTUP "ui-startup-hook"
+#define HOOK_UI_POST_STARTUP "hook_ui_post_startup"
+#define HOOK_UI_SHUTDOWN "hook_ui_shutdown"
+#define HOOK_NEW_BOOK "new-book-hook"
+#define HOOK_REPORT "report-hook"
+
+/* Common session hook names */
+#define HOOK_BOOK_OPENED "book-opened-hook"
+#define HOOK_BOOK_CLOSED "book-closed-hook"
--- /dev/null
+++ src/core-utils/gnc-hooks.c
@@ -0,0 +1,138 @@
+/*
+ * gnc-hooks.c -- helpers for using Glib hook functions
+ * Copyright (C) 2005 David Hampton <hampton at employees.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, contact:
+ *
+ * Free Software Foundation Voice: +1-617-542-5942
+ * 59 Temple Place - Suite 330 Fax: +1-617-542-2652
+ * Boston, MA 02111-1307, USA gnu at gnu.org
+ */
+
+#include "config.h"
+
+#include <glib.h>
+#include <stdio.h>
+#include "gnc-hooks.h"
+
+GHashTable* all_hook_lists = NULL;
+
+static GHookList *
+gnc_lookup_hook_list (const gchar *name)
+{
+ GHookList *hook_list;
+
+ //printf("Enter %s: name %s\n", __FUNCTION__, name);
+ if (all_hook_lists == NULL) {
+ //printf("Leave %s: no hook lists\n", __FUNCTION__);
+ return NULL;
+ }
+
+ hook_list = g_hash_table_lookup(all_hook_lists, name);
+ //printf("Leave %s: hook list %p\n", __FUNCTION__, hook_list);
+ return(hook_list);
+}
+
+static GHookList *
+gnc_create_hook_list (const gchar *name)
+{
+ GHookList *hook_list;
+
+ //printf("Enter %s: name %s\n", __FUNCTION__, name);
+ if (all_hook_lists == NULL)
+ all_hook_lists = g_hash_table_new(g_str_hash, g_str_equal);
+
+ hook_list = g_hash_table_lookup(all_hook_lists, name);
+ if (hook_list) {
+ //printf("Leave %s: list %s(%p) already exists\n\n", __FUNCTION__, name, hook_list);
+ return(hook_list);
+ }
+
+ hook_list = g_malloc(sizeof(GHookList));
+ g_hook_list_init(hook_list, sizeof(GHook));
+ g_hash_table_insert(all_hook_lists, (gchar *)name, hook_list);
+ //printf("Leave %s: created list %s(%p)\n", __FUNCTION__, name, hook_list);
+ return(hook_list);
+}
+
+void
+gnc_add_to_c_hook (const gchar *name,
+ GHookFunc callback)
+{
+ GHookList *hook_list;
+ GHook *hook;
+
+ //printf("Enter %s: list %s, function %p\n\n", __FUNCTION__, name, callback);
+ hook_list = gnc_create_hook_list(name);
+ hook = g_hook_alloc(hook_list);
+ hook->func = callback;
+ g_hook_append(hook_list, hook);
+ //printf("Leave %s: \n", __FUNCTION__);
+}
+
+static gboolean
+hook_remove_runner (GHook *hook,
+ gpointer data)
+{
+ return(hook->func == data);
+}
+
+
+void
+gnc_remove_from_c_hook (const gchar *name,
+ GHookFunc callback)
+{
+ GHookList *hook_list;
+ GHook *hook;
+
+ //printf("Enter %s: name %s, function %p\n\n", __FUNCTION__, name, callback);
+ hook_list = gnc_lookup_hook_list(name);
+ if (hook_list == NULL) {
+ //printf("Leave %s: Unknown hook list %s\n", __FUNCTION__, name);
+ return;
+ }
+
+ hook = g_hook_find(hook_list, TRUE, hook_remove_runner, callback);
+ if (hook == NULL) {
+ //printf("Leave %s: Hook %p not found in %s\n", __FUNCTION__, callback, name);
+ return;
+ }
+
+ g_hook_unref(hook_list, hook);
+ //printf("Leave %s: Removed %p from %s\n", __FUNCTION__ , hook, name);
+}
+
+
+static void
+call_hook (GHook *hook, gpointer data)
+{
+ //printf("Enter %s: hook %p (func %p), data %p\n", __FUNCTION__, hook, hook->func, data);
+ ((GHookFunc)hook->func)(data);
+ //printf("Leave %s: \n", __FUNCTION__);
+}
+
+void
+gnc_run_c_hook (const gchar *name, gpointer data)
+{
+ GHookList *hook_list;
+
+ //printf("Enter %s: list %s, data %p\n", __FUNCTION__, name, data);
+ hook_list = gnc_lookup_hook_list(name);
+ if (!hook_list) {
+ //printf("Leave %s: No such hook list\n", __FUNCTION__);
+ return;
+ }
+ g_hook_list_marshal(hook_list, TRUE, call_hook, data);
+ //printf("Leave %s: \n", __FUNCTION__);
+}
Index: Makefile.am
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/core-utils/Makefile.am,v
retrieving revision 1.7.4.1
retrieving revision 1.7.4.2
diff -Lsrc/core-utils/Makefile.am -Lsrc/core-utils/Makefile.am -u -r1.7.4.1 -r1.7.4.2
--- src/core-utils/Makefile.am
+++ src/core-utils/Makefile.am
@@ -3,7 +3,8 @@
libcore_utils_la_SOURCES = \
core-utils.c \
- gnc-gconf-utils.c
+ gnc-gconf-utils.c \
+ gnc-hooks.c
libcore_utils_la_LDFLAGS = -module
@@ -21,6 +22,8 @@
noinst_HEADERS = \
core-utils.h \
+ gnc-gconf-utils.h \
+ gnc-hooks.h \
gw-core-utils.h
EXTRA_DIST = .cvsignore ${gwmod_DATA}
Index: gw-core-utils-spec.scm
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/core-utils/gw-core-utils-spec.scm,v
retrieving revision 1.2
retrieving revision 1.2.4.1
diff -Lsrc/core-utils/gw-core-utils-spec.scm -Lsrc/core-utils/gw-core-utils-spec.scm -u -r1.2 -r1.2.4.1
--- src/core-utils/gw-core-utils-spec.scm
+++ src/core-utils/gw-core-utils-spec.scm
@@ -6,16 +6,42 @@
(define-module (g-wrapped gw-core-utils-spec))
(use-modules (g-wrap))
+(use-modules (g-wrap simple-type))
-(display "**** NOTE: this wrapset appears to be empty !?\n")
+(use-modules (g-wrap gw-standard-spec))
+(use-modules (g-wrap gw-wct-spec))
+(use-modules (g-wrap gw-glib-spec))
(let ((ws (gw:new-wrapset "gw-core-utils")))
+ (gw:wrapset-depends-on ws "gw-standard")
+ (gw:wrapset-depends-on ws "gw-wct")
+ (gw:wrapset-depends-on ws "gw-glib")
+
(gw:wrapset-set-guile-module! ws '(g-wrapped gw-core-utils))
(gw:wrapset-add-cs-declarations!
ws
(lambda (wrapset client-wrapset)
- (if client-wrapset
- '()
- "#include <core-utils.h>\n"))))
+ (list
+ "#include <core-utils.h>\n"
+ "#include <gnc-gconf-utils.h>\n"
+ "#include <gnc-hooks.h>\n")))
+
+ (gw:wrap-function
+ ws
+ 'gnc:gconf-get-bool
+ '<gw:bool>
+ "gnc_gconf_get_bool_no_error"
+ '(((<gw:mchars> caller-owned) section)
+ ((<gw:mchars> caller-owned) name))
+ "Get a boolean value from gconf.")
+
+ (gw:wrap-function
+ ws
+ 'gnc:run-c-hook
+ '<gw:void>
+ "gnc_run_c_hook"
+ '(((<gw:mchars> caller-owned) name) (<gw:void*> data))
+ "Run a callback hook in the C domain.")
+)
Index: gnc-menu-extensions.scm
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/gnome-utils/gnc-menu-extensions.scm,v
retrieving revision 1.4.4.2
retrieving revision 1.4.4.3
diff -Lsrc/gnome-utils/gnc-menu-extensions.scm -Lsrc/gnome-utils/gnc-menu-extensions.scm -u -r1.4.4.2 -r1.4.4.3
--- src/gnome-utils/gnc-menu-extensions.scm
+++ src/gnome-utils/gnc-menu-extensions.scm
@@ -62,7 +62,8 @@
(define (gnc:extensions-menu-setup)
(define menu (gnc:make-menu (N_ "Extensions") (list "_Tools")))
(gnc:add-extension menu)
- (gnc:hook-run-danglers gnc:*add-extension-hook*))
+ (gnc:hook-run-danglers gnc:*add-extension-hook*)
+ (gnc:run-c-hook "add-extension-hook") #f)
(if (gnc:debugging?)
(gnc:hook-add-dangler gnc:*ui-startup-hook*
Index: report-gnome.scm
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/report/report-gnome/report-gnome.scm,v
retrieving revision 1.9.4.5
retrieving revision 1.9.4.6
diff -Lsrc/report/report-gnome/report-gnome.scm -Lsrc/report/report-gnome/report-gnome.scm -u -r1.9.4.5 -r1.9.4.6
--- src/report/report-gnome/report-gnome.scm
+++ src/report/report-gnome/report-gnome.scm
@@ -12,6 +12,7 @@
(use-modules (ice-9 slib))
(require 'printf)
+(use-modules (g-wrapped gw-core-utils))
(use-modules (g-wrapped gw-report-gnome))
(gnc:module-load "gnucash/gnome-utils" 0)
@@ -113,6 +114,7 @@
;; run report-hook danglers
(gnc:hook-run-danglers gnc:*report-hook*)
+ (gnc:run-c-hook "report-hook" #f)
;; push reports (new items added on top of menu)
(gnc:add-report-template-menu-items))
Index: gnc-file.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/app-file/gnc-file.c,v
retrieving revision 1.25.4.14
retrieving revision 1.25.4.15
diff -Lsrc/app-file/gnc-file.c -Lsrc/app-file/gnc-file.c -u -r1.25.4.14 -r1.25.4.15
--- src/app-file/gnc-file.c
+++ src/app-file/gnc-file.c
@@ -38,6 +38,7 @@
#include "gnc-file-p.h"
#include "gnc-filepath-utils.h"
#include "gnc-gui-query.h"
+#include "gnc-hooks.h"
#include "gnc-splash.h"
#include "gnc-ui.h"
#include "gnc-ui-util.h"
@@ -354,6 +355,7 @@
(session ?
gw_wcp_assimilate_ptr (session, scm_c_eval_string("<gnc:Session*>")) :
SCM_BOOL_F));
+ gnc_run_c_hook(HOOK_BOOK_OPENED, session);
}
void
@@ -378,6 +380,7 @@
(session ?
gw_wcp_assimilate_ptr (session, scm_c_eval_string("<gnc:Session*>")) :
SCM_BOOL_F));
+ gnc_run_c_hook(HOOK_BOOK_CLOSED, session);
gnc_close_gui_component_by_session (session);
xaccLogDisable();
@@ -389,6 +392,7 @@
scm_call_1(scm_c_eval_string("gnc:hook-run-danglers"),
scm_c_eval_string("gnc:*new-book-hook*"));
+ gnc_run_c_hook(HOOK_NEW_BOOK, NULL);
gnc_book_opened ();
@@ -471,6 +475,7 @@
gw_wcp_assimilate_ptr (current_session,
scm_c_eval_string("<gnc:Session*>")) :
SCM_BOOL_F));
+ gnc_run_c_hook(HOOK_BOOK_CLOSED, current_session);
xaccLogDisable();
qof_session_destroy (current_session);
xaccLogEnable();
@@ -965,6 +970,7 @@
(session ?
gw_wcp_assimilate_ptr (session, scm_c_eval_string("<gnc:Session*>")) :
SCM_BOOL_F));
+ gnc_run_c_hook(HOOK_BOOK_CLOSED, session);
xaccLogDisable();
qof_session_destroy (session);
Index: dialog-new-user.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/gnome/dialog-new-user.c,v
retrieving revision 1.4.4.9
retrieving revision 1.4.4.10
diff -Lsrc/gnome/dialog-new-user.c -Lsrc/gnome/dialog-new-user.c -u -r1.4.4.9 -r1.4.4.10
--- src/gnome/dialog-new-user.c
+++ src/gnome/dialog-new-user.c
@@ -31,6 +31,7 @@
#include "global-options.h"
#include "gnc-engine-util.h"
#include "gnc-gconf-utils.h"
+#include "gnc-hooks.h"
#include "gnc-ui.h"
#define GCONF_SECTION "dialogs/new_user"
@@ -136,4 +137,5 @@
gncp_new_user_finish (void)
{
scm_c_eval_string("(gnc:hook-run-danglers gnc:*book-opened-hook* #f)");
+ gnc_run_c_hook(HOOK_BOOK_OPENED, NULL);
}
Index: top-level.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/gnome/top-level.c,v
retrieving revision 1.140.4.19
retrieving revision 1.140.4.20
diff -Lsrc/gnome/top-level.c -Lsrc/gnome/top-level.c -u -r1.140.4.19 -r1.140.4.20
--- src/gnome/top-level.c
+++ src/gnome/top-level.c
@@ -45,6 +45,7 @@
#include "gnc-date.h"
#include "gnc-engine-util.h"
#include "gnc-file.h"
+#include "gnc-hooks.h"
#include "gnc-main-window.h"
#include "gnc-menu-extensions.h"
#include "gnc-plugin-menu-additions.h" /* FIXME Remove this line*/
@@ -402,6 +403,7 @@
SCM run_danglers = scm_c_eval_string("gnc:hook-run-danglers");
SCM hook = scm_c_eval_string("gnc:*ui-startup-hook*");
scm_call_1(run_danglers, hook);
+ gnc_run_c_hook(HOOK_UI_STARTUP, NULL);
}
// return ( main_window . command_line )
Index: main.scm
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/scm/main.scm,v
retrieving revision 1.109.2.17
retrieving revision 1.109.2.18
diff -Lsrc/scm/main.scm -Lsrc/scm/main.scm -u -r1.109.2.17 -r1.109.2.18
--- src/scm/main.scm
+++ src/scm/main.scm
@@ -20,7 +20,7 @@
(use-modules (ice-9 slib))
(use-modules (g-wrap gw-wct))
-
+(use-modules (g-wrapped gw-core-utils))
(use-modules (g-wrapped gw-gnc))
;; Load the srfis (eventually, we should see where these are needed
@@ -503,6 +503,7 @@
(gnc:main-window-open-report (gnc:make-welcome-report) window))))
(gnc:hook-run-danglers gnc:*startup-hook*)
+ (gnc:run-c-hook "startup-hook" #f)
(if (gnc:config-var-value-get gnc:*loglevel*)
(gnc:set-log-level-global (gnc:config-var-value-get gnc:*loglevel*))))
@@ -516,10 +517,12 @@
(if (gnc:file-query-save)
(begin
(gnc:hook-run-danglers gnc:*ui-shutdown-hook*)
+ (gnc:run-c-hook "ui-shutdown-hook" #f)
(gnc:gui-shutdown)))))
(else
(gnc:gui-destroy)
(gnc:hook-run-danglers gnc:*shutdown-hook*)
+ (gnc:run-c-hook "shutdown-hook" #f)
(gnc:engine-shutdown)
(exit exit-status))))
@@ -578,8 +581,10 @@
(begin
(gnc:update-splash-screen (_ "Loading data..."))
(and (not (gnc:file-open-file file))
- (gnc:hook-run-danglers gnc:*book-opened-hook* #f)))
- (gnc:hook-run-danglers gnc:*book-opened-hook* #f))))
+ (gnc:hook-run-danglers gnc:*book-opened-hook* #f)
+ (gnc:run-c-hook "book-opened-hook" #f)))
+ (and (gnc:hook-run-danglers gnc:*book-opened-hook* #f)
+ (gnc:run-c-hook "book-opened-hook" #f)))))
(define (gnc:main)
@@ -641,6 +646,7 @@
;; no matter how or what we loaded, ensure the main-window title is valid...
(gnc:main-window-update-title main-window)
(gnc:hook-run-danglers gnc:*ui-post-startup-hook*)
+ (gnc:run-c-hook "ui-post-startup-hook" #f)
(gnc:start-ui-event-loop)
(gnc:hook-remove-dangler gnc:*ui-shutdown-hook* gnc:gui-finish)))
More information about the gnucash-changes
mailing list