[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