[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
gEDA-cvs: gaf.git: branch: master updated (1.6.1-20100214-153-g700d8c7)
The branch, master has been updated
via 700d8c7bb6ed397185f4aee5e857979af07d2d96 (commit)
from 49fb65103d192a462edb5f0db8ace851c675b749 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
=========
Summary
=========
gschem/src/gschem.c | 6 +-
gschem/src/i_callbacks.c | 6 +-
gschem/src/x_preview.c | 8 +-
libgeda/include/libgeda/prototype.h | 3 +-
libgeda/include/libgeda/struct.h | 4 +-
libgeda/src/o_basic.c | 129 ++++++++++++++++++++++++++++++----
libgeda/src/s_toplevel.c | 13 +++-
7 files changed, 136 insertions(+), 33 deletions(-)
=================
Commit Messages
=================
commit 700d8c7bb6ed397185f4aee5e857979af07d2d96
Author: Peter TB Brett <peter@xxxxxxxxxxxxx>
Commit: Peter TB Brett <peter@xxxxxxxxxxxxx>
libgeda: Allow registration of multiple change notify functions.
A mechanism for getting notifications when OBJECTs are changed was
added in commit 8b1faf85362b, but this only allowed one set of change
handlers to be added to a TOPLEVEL. This patch allows the multiple
sets of handlers to be registered, and also fleshes out the API
documentation.
:100644 100644 b47d503... d957e73... M gschem/src/gschem.c
:100644 100644 bcc3525... fb084fe... M gschem/src/i_callbacks.c
:100644 100644 47bab5c... b584163... M gschem/src/x_preview.c
:100644 100644 47a0fbb... 2860d04... M libgeda/include/libgeda/prototype.h
:100644 100644 fef18c7... 1ea9bca... M libgeda/include/libgeda/struct.h
:100644 100644 31e08f6... fdebc21... M libgeda/src/o_basic.c
:100644 100644 00a9225... 3633bc8... M libgeda/src/s_toplevel.c
=========
Changes
=========
commit 700d8c7bb6ed397185f4aee5e857979af07d2d96
Author: Peter TB Brett <peter@xxxxxxxxxxxxx>
Commit: Peter TB Brett <peter@xxxxxxxxxxxxx>
libgeda: Allow registration of multiple change notify functions.
A mechanism for getting notifications when OBJECTs are changed was
added in commit 8b1faf85362b, but this only allowed one set of change
handlers to be added to a TOPLEVEL. This patch allows the multiple
sets of handlers to be registered, and also fleshes out the API
documentation.
diff --git a/gschem/src/gschem.c b/gschem/src/gschem.c
index b47d503..d957e73 100644
--- a/gschem/src/gschem.c
+++ b/gschem/src/gschem.c
@@ -233,9 +233,9 @@ void main_prog(void *closure, int argc, char *argv[])
o_text_get_rendered_bounds, w_current);
/* Damage notifications should invalidate the object on screen */
- o_set_change_notify_funcs (w_current->toplevel,
- (ChangeNotifyFunc) o_invalidate,
- (ChangeNotifyFunc) o_invalidate, w_current);
+ o_add_change_notify (w_current->toplevel,
+ (ChangeNotifyFunc) o_invalidate,
+ (ChangeNotifyFunc) o_invalidate, w_current);
/* Now read in RC files. */
g_rc_parse_gtkrc();
diff --git a/gschem/src/i_callbacks.c b/gschem/src/i_callbacks.c
index bcc3525..fb084fe 100644
--- a/gschem/src/i_callbacks.c
+++ b/gschem/src/i_callbacks.c
@@ -160,9 +160,9 @@ DEFINE_I_CALLBACK(file_new_window)
o_text_get_rendered_bounds, w_current);
/* Damage notifications should invalidate the object on screen */
- o_set_change_notify_funcs (w_current->toplevel,
- (ChangeNotifyFunc) o_invalidate,
- (ChangeNotifyFunc) o_invalidate, w_current);
+ o_add_change_notify (w_current->toplevel,
+ (ChangeNotifyFunc) o_invalidate,
+ (ChangeNotifyFunc) o_invalidate, w_current);
x_window_setup (w_current);
diff --git a/gschem/src/x_preview.c b/gschem/src/x_preview.c
index 47bab5c..b584163 100644
--- a/gschem/src/x_preview.c
+++ b/gschem/src/x_preview.c
@@ -376,10 +376,10 @@ preview_init (Preview *preview)
o_text_get_rendered_bounds,
preview_w_current);
- o_set_change_notify_funcs (preview_w_current->toplevel,
- (ChangeNotifyFunc) o_invalidate,
- (ChangeNotifyFunc) o_invalidate,
- preview_w_current);
+ o_add_change_notify (preview_w_current->toplevel,
+ (ChangeNotifyFunc) o_invalidate,
+ (ChangeNotifyFunc) o_invalidate,
+ preview_w_current);
i_vars_set (preview_w_current);
diff --git a/libgeda/include/libgeda/prototype.h b/libgeda/include/libgeda/prototype.h
index 47a0fbb..2860d04 100644
--- a/libgeda/include/libgeda/prototype.h
+++ b/libgeda/include/libgeda/prototype.h
@@ -119,7 +119,8 @@ void o_mirror_world(TOPLEVEL *toplevel, int world_centerx, int world_centery, OB
double o_shortest_distance(OBJECT *object, int x, int y);
void o_set_color(TOPLEVEL *toplevel, OBJECT *object, int color);
PAGE *o_get_page (TOPLEVEL *toplevel, OBJECT *object);
-void o_set_change_notify_funcs(TOPLEVEL *toplevel, ChangeNotifyFunc pre_change_func, ChangeNotifyFunc change_func, void *user_data);
+void o_add_change_notify(TOPLEVEL *toplevel, ChangeNotifyFunc pre_change_func, ChangeNotifyFunc change_func, void *user_data);
+void o_remove_change_notify(TOPLEVEL *toplevel, ChangeNotifyFunc pre_change_func, ChangeNotifyFunc change_func, void *user_data);
/* o_box_basic.c */
OBJECT *o_box_new(TOPLEVEL *toplevel, char type, int color, int x1, int y1, int x2, int y2);
diff --git a/libgeda/include/libgeda/struct.h b/libgeda/include/libgeda/struct.h
index fef18c7..1ea9bca 100644
--- a/libgeda/include/libgeda/struct.h
+++ b/libgeda/include/libgeda/struct.h
@@ -549,9 +549,7 @@ struct st_toplevel {
void *rendered_text_bounds_data;
/* Callback functions for object change notification */
- ChangeNotifyFunc pre_change_notify_func;
- ChangeNotifyFunc change_notify_func;
- void *change_notify_data;
+ GList *change_notify_funcs;
/* Callback function for deciding whether to load a backup file. */
LoadBackupQueryFunc load_newer_backup_func;
diff --git a/libgeda/src/o_basic.c b/libgeda/src/o_basic.c
index 31e08f6..fdebc21 100644
--- a/libgeda/src/o_basic.c
+++ b/libgeda/src/o_basic.c
@@ -645,30 +645,127 @@ o_get_page_compat (TOPLEVEL *toplevel, OBJECT *object) {
}
}
-void o_set_change_notify_funcs (TOPLEVEL *toplevel,
- ChangeNotifyFunc pre_change_func,
- ChangeNotifyFunc change_func,
- void *user_data)
+/* Structure for each entry in a TOPLEVEL's list of registered change
+ * notification handlers */
+struct change_notify_entry {
+ ChangeNotifyFunc pre_change_func;
+ ChangeNotifyFunc change_func;
+ void *user_data;
+};
+
+/*! \brief Add change notification handlers to a TOPLEVEL.
+ * \par Function Description
+ * Adds a set of change notification handlers to a #TOPLEVEL instance.
+ * \a pre_change_func will be called just before an object is
+ * modified, and \a change_func will be called just after an object is
+ * modified, with the affected object and the given \a user_data.
+ *
+ * \param toplevel #TOPLEVEL structure to add handlers to.
+ * \param pre_change_func Function to be called just before changes.
+ * \param change_func Function to be called just after changes.
+ * \param user_data User data to be passed to callback functions.
+ */
+void
+o_add_change_notify (TOPLEVEL *toplevel,
+ ChangeNotifyFunc pre_change_func,
+ ChangeNotifyFunc change_func,
+ void *user_data)
{
- toplevel->pre_change_notify_func = pre_change_func;
- toplevel->change_notify_func = change_func;
- toplevel->change_notify_data = user_data;
+ struct change_notify_entry *entry = g_new0 (struct change_notify_entry, 1);
+ entry->pre_change_func = pre_change_func;
+ entry->change_func = change_func;
+ entry->user_data = user_data;
+ toplevel->change_notify_funcs =
+ g_list_prepend (toplevel->change_notify_funcs, entry);
}
+/*! \brief Remove change notification handlers from a TOPLEVEL.
+ * \par Function Description
+ * Removes a set of change notification handlers and their associated
+ * \a user_data from \a toplevel. If no registered set of handlers
+ * matches the given \a pre_change_func, \a change_func and \a
+ * user_data, does nothing.
+ *
+ * \see o_add_change_notify()
+ *
+ * \param toplevel #TOPLEVEL structure to remove handlers from.
+ * \param pre_change_func Function called just before changes.
+ * \param change_func Function called just after changes.
+ * \param user_data User data passed to callback functions.
+ */
+void
+o_remove_change_notify (TOPLEVEL *toplevel,
+ ChangeNotifyFunc pre_change_func,
+ ChangeNotifyFunc change_func,
+ void *user_data)
+{
+ GList *iter;
+ for (iter = toplevel->change_notify_funcs;
+ iter != NULL; iter = g_list_next (iter)) {
+
+ struct change_notify_entry *entry =
+ (struct change_notify_entry *) iter->data;
+
+ if ((entry != NULL)
+ && (entry->pre_change_func == pre_change_func)
+ && (entry->change_func == change_func)
+ && (entry->user_data == user_data)) {
+ g_free (entry);
+ iter->data = NULL;
+ }
+ }
+ toplevel->change_notify_funcs =
+ g_list_remove_all (toplevel->change_notify_funcs, NULL);
+}
-void o_emit_pre_change_notify (TOPLEVEL *toplevel, OBJECT *object)
+/*! \brief Emit an object pre-change notification.
+ * \par Function Description
+ * Calls each pre-change callback function registered with #TOPLEVEL
+ * to notify listeners that \a object is about to be modified. All
+ * libgeda functions that modify #OBJECT structures should call this
+ * just before making a change to an #OBJECT.
+ *
+ * \param toplevel #TOPLEVEL structure to emit notifications from.
+ * \param object #OBJECT structure to emit notifications for.
+ */
+void
+o_emit_pre_change_notify (TOPLEVEL *toplevel, OBJECT *object)
{
- if (toplevel->pre_change_notify_func == NULL)
- return;
+ GList *iter;
+ for (iter = toplevel->change_notify_funcs;
+ iter != NULL; iter = g_list_next (iter)) {
- toplevel->pre_change_notify_func (toplevel->change_notify_data, object);
-}
+ struct change_notify_entry *entry =
+ (struct change_notify_entry *) iter->data;
+ if ((entry != NULL) && (entry->pre_change_func != NULL)) {
+ entry->pre_change_func (entry->user_data, object);
+ }
+ }
+}
-void o_emit_change_notify (TOPLEVEL *toplevel, OBJECT *object)
+/*! \brief Emit an object change notification.
+ * \par Function Description
+ * Calls each change callback function registered with #TOPLEVEL to
+ * notify listeners that \a object has just been modified. All
+ * libgeda functions that modify #OBJECT structures should call this
+ * just after making a change to an #OBJECT.
+ *
+ * \param toplevel #TOPLEVEL structure to emit notifications from.
+ * \param object #OBJECT structure to emit notifications for.
+ */
+void
+o_emit_change_notify (TOPLEVEL *toplevel, OBJECT *object)
{
- if (toplevel->change_notify_func == NULL)
- return;
+ GList *iter;
+ for (iter = toplevel->change_notify_funcs;
+ iter != NULL; iter = g_list_next (iter)) {
- toplevel->change_notify_func (toplevel->change_notify_data, object);
+ struct change_notify_entry *entry =
+ (struct change_notify_entry *) iter->data;
+
+ if ((entry != NULL) && (entry->change_func != NULL)) {
+ entry->change_func (entry->user_data, object);
+ }
+ }
}
diff --git a/libgeda/src/s_toplevel.c b/libgeda/src/s_toplevel.c
index 00a9225..3633bc8 100644
--- a/libgeda/src/s_toplevel.c
+++ b/libgeda/src/s_toplevel.c
@@ -134,9 +134,7 @@ TOPLEVEL *s_toplevel_new (void)
toplevel->rendered_text_bounds_func = NULL;
toplevel->rendered_text_bounds_data = NULL;
- toplevel->pre_change_notify_func = NULL;
- toplevel->change_notify_func = NULL;
- toplevel->change_notify_data = NULL;
+ toplevel->change_notify_funcs = NULL;
toplevel->load_newer_backup_func = NULL;
toplevel->load_newer_backup_data = NULL;
@@ -159,6 +157,8 @@ TOPLEVEL *s_toplevel_new (void)
*/
void s_toplevel_delete (TOPLEVEL *toplevel)
{
+ GList *iter;
+
if (toplevel->auto_save_timeout != 0) {
/* Assume this works */
g_source_remove (toplevel->auto_save_timeout);
@@ -181,6 +181,13 @@ void s_toplevel_delete (TOPLEVEL *toplevel)
/* Delete the page list */
g_object_unref(toplevel->pages);
+ /* Remove all change notification handlers */
+ for (iter = toplevel->change_notify_funcs;
+ iter != NULL; iter = g_list_next (iter)) {
+ g_free (iter->data);
+ }
+ g_list_free (toplevel->change_notify_funcs);
+
s_weakref_notify (toplevel, toplevel->weak_refs);
g_free (toplevel);
_______________________________________________
geda-cvs mailing list
geda-cvs@xxxxxxxxxxxxxx
http://www.seul.org/cgi-bin/mailman/listinfo/geda-cvs