[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

gEDA-cvs: gaf.git: branch: master updated (1.6.1-20100214-112-g8531f91)



The branch, master has been updated
       via  8531f91cdf9862ac7f4211b3070fa28be759d0c5 (commit)
       via  cc0ced2f6d765e5be43de4cd8d0e7caacee9478d (commit)
       via  5e8f2be04fd2a1371dcfc2dd595ca319749fe7e2 (commit)
       via  b59058138ce5057b3520f70754a610a99fb440a7 (commit)
       via  cf6ea830c56a04ebb47e958dc1f8895dcc8f60e7 (commit)
       via  5e43eb790eee741c861862d27435fac0cca55df2 (commit)
       via  51461b59d30487e9c1c2dbf3beb6883bd66314e1 (commit)
       via  ca60bcbdab636a6ee28a004d5ce802a57933e6bb (commit)
       via  51c180d137513668925fe2f5834f8ec5cb1d4563 (commit)
       via  47ebe0bb0145d95946d05fa1fd8d9bab7bd08175 (commit)
       via  5c14a649bd633950624dfda4128bd83ed77ef4bc (commit)
       via  0a93ef44cea25ec2bed559d8a05488fd3badd63c (commit)
       via  ccf8b757df96f9eafb676a8ab0960c76f9692238 (commit)
       via  8b1faf85362bb30c392e2b9ebc5d8ccb800b85f2 (commit)
      from  6e5fa46cc04db09e0fa0fee54985fa98413c339e (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/include/prototype.h          |    4 +-
 gschem/src/g_hook.c                 |   16 +--------
 gschem/src/gschem.c                 |    5 +++
 gschem/src/i_callbacks.c            |   13 +++----
 gschem/src/o_arc.c                  |    3 --
 gschem/src/o_attrib.c               |   13 +------
 gschem/src/o_box.c                  |    3 --
 gschem/src/o_bus.c                  |    2 -
 gschem/src/o_circle.c               |    3 --
 gschem/src/o_delete.c               |   26 -------------
 gschem/src/o_grips.c                |   42 +---------------------
 gschem/src/o_line.c                 |    3 --
 gschem/src/o_misc.c                 |   61 +++++--------------------------
 gschem/src/o_move.c                 |   67 +++++------------------------------
 gschem/src/o_net.c                  |   38 ++++----------------
 gschem/src/o_picture.c              |    3 --
 gschem/src/o_pin.c                  |    7 ----
 gschem/src/o_select.c               |    6 +---
 gschem/src/o_slot.c                 |   11 ------
 gschem/src/o_text.c                 |    7 ----
 gschem/src/x_attribedit.c           |    1 -
 gschem/src/x_autonumber.c           |   11 ------
 gschem/src/x_dialog.c               |    8 ----
 gschem/src/x_multiattrib.c          |    5 ---
 gschem/src/x_preview.c              |    5 +++
 libgeda/include/libgeda/prototype.h |    1 +
 libgeda/include/libgeda/struct.h    |    8 ++++
 libgeda/include/prototype_priv.h    |    2 +
 libgeda/src/o_arc_basic.c           |    4 ++-
 libgeda/src/o_basic.c               |   37 +++++++++++++++++++-
 libgeda/src/o_box_basic.c           |    5 ++-
 libgeda/src/o_circle_basic.c        |    4 ++-
 libgeda/src/o_line_basic.c          |    3 ++
 libgeda/src/o_path_basic.c          |    3 ++
 libgeda/src/o_picture.c             |    5 ++-
 libgeda/src/o_pin_basic.c           |    2 +
 libgeda/src/o_selection.c           |    4 ++
 libgeda/src/o_text_basic.c          |    2 +
 libgeda/src/s_conn.c                |    8 ++++
 libgeda/src/s_page.c                |   14 +++++---
 libgeda/src/s_toplevel.c            |    4 ++
 41 files changed, 145 insertions(+), 324 deletions(-)


=================
 Commit Messages
=================

commit cc0ced2f6d765e5be43de4cd8d0e7caacee9478d
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    gschem: Remove o_invalidate_glist() call from i_callback_edit_(un)embed
    
    This invalidate calls are not required, as any relevant changes will
    cause change notifications from within libgeda to trigger redraws of
    specific areas of the page.
    
    NB: Changing the embedded status of an object doesn't actually cause a
    change notification at present, since it should not affect the how the
    objects are rendered.

:100644 100644 ea2b81c... 4e664ec... M	gschem/src/i_callbacks.c

commit 5e8f2be04fd2a1371dcfc2dd595ca319749fe7e2
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    gschem: Remove o_invalidate_all() call from i_callback_edit_update
    
    This invalidate call is not required, as any changes will cause
    change notifications from within libgeda to trigger specific areas
    of the page to be redrawn.

:100644 100644 65898f8... ea2b81c... M	gschem/src/i_callbacks.c

commit b59058138ce5057b3520f70754a610a99fb440a7
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    Use change notification to redraw objects when connectivity changes
    
    Emit change notifications in the connectivity tracking functions
    s_conn_remove_other() and s_conn_update_line_object(). This frees
    gschem from the somewhat complex task of tracking which objects were
    connected to a given object before and after a particular set of
    operations.
    
    This change leads to a significant simplification of many operations,
    and removes quantities of code from:
    
      o_pin_end()
      o_net_end()
      o_move_end()
      o_move_end_rubberband()
      o_move_end_lowlevel()
      o_mirror_world_update()
      o_rotate_world_update()
      o_grips_end_bus()
      o_grips_end_pin()
      o_grips_end_net()
      o_delete()

:100644 100644 4123acf... e018101... M	gschem/include/prototype.h
:100644 100644 09f1fab... 8389e4f... M	gschem/src/o_delete.c
:100644 100644 f688981... 66d1995... M	gschem/src/o_grips.c
:100644 100644 870137a... fe84603... M	gschem/src/o_misc.c
:100644 100644 0b295c6... 93f53c1... M	gschem/src/o_move.c
:100644 100644 fa08a54... 3a03118... M	gschem/src/o_net.c
:100644 100644 bc625e2... 14345d7... M	gschem/src/o_pin.c
:100644 100644 4985071... 184cf4e... M	libgeda/src/s_conn.c

commit cf6ea830c56a04ebb47e958dc1f8895dcc8f60e7
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    Use change notification to redraw when a pin's type is modified
    
    Emit change notifications in o_pin_set_type(), and remove
    o_invalidate() calls where this function is used in gschem.

:100644 100644 4c758a9... 507919c... M	gschem/src/x_dialog.c
:100644 100644 c865313... 6e38587... M	libgeda/src/o_pin_basic.c

commit 5e43eb790eee741c861862d27435fac0cca55df2
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    Add change notification when objects are modified via o_*_modify()
    
    Emit change notification in the o_*_modify() functions, and remove
    some o_invalidate() calls where o_arc_modify() is also used in
    gschem's arc editing dialog.
    
    The o_*_modify() routines are also used in o_grips.c, where there
    is no explicit o_invalidate() call after them. o_grips_end() calls
    o_invalidate(), which is strictly un-necessary, but I've left it for
    clarity, as it comes after resetting the OBJECT's dont_redraw flag.

:100644 100644 2a68e5b... 4c758a9... M	gschem/src/x_dialog.c
:100644 100644 baeb169... 761a347... M	libgeda/src/o_arc_basic.c
:100644 100644 3260864... 0556d79... M	libgeda/src/o_box_basic.c
:100644 100644 9da6077... c9b9b68... M	libgeda/src/o_circle_basic.c
:100644 100644 c6316ef... b35a705... M	libgeda/src/o_line_basic.c
:100644 100644 ed502c1... 1e3b7dd... M	libgeda/src/o_path_basic.c
:100644 100644 aae9ba1... 513af00... M	libgeda/src/o_picture.c

commit 51461b59d30487e9c1c2dbf3beb6883bd66314e1
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    Use change notification to redraw when an object's fill properties change
    
    Emit change notifications in o_set_fill_options(), and remove
    o_invalidate() calls where this function is used in gschem.

:100644 100644 575540f... 2a68e5b... M	gschem/src/x_dialog.c
:100644 100644 17ddbc9... 31e08f6... M	libgeda/src/o_basic.c

commit ca60bcbdab636a6ee28a004d5ce802a57933e6bb
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    Use change notification to redraw when an object's line properties change
    
    Emit change notification in o_set_line_options(), and remove
    o_invalidate() calls where this function is used in gschem.

:100644 100644 62099cb... 575540f... M	gschem/src/x_dialog.c
:100644 100644 2748a19... 17ddbc9... M	libgeda/src/o_basic.c

commit 51c180d137513668925fe2f5834f8ec5cb1d4563
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    Use change notifications to redraw objects with selection changes
    
    Emit change notifications when an OBJECT's selected flag is changed,
    and removes o_invalidate() calls where the selection is manipulated
    in gschem.

:100644 100644 444e11d... 348d631... M	gschem/src/o_attrib.c
:100644 100644 48fac8f... 870137a... M	gschem/src/o_misc.c
:100644 100644 9c8d05b... 597c334... M	gschem/src/o_select.c
:100644 100644 8e8f9c9... 8687211... M	libgeda/src/o_selection.c

commit 47ebe0bb0145d95946d05fa1fd8d9bab7bd08175
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    Use change notifications for redraw when text is recreated
    
    Emit change notifications in the o_text_recreate() function, and
    remove o_invalidate() calls from gschem where o_text_recreate(),
    or other functions calling it are made.

:100644 100644 1b029cd... d75baf4... M	gschem/src/g_hook.c
:100644 100644 6052b6d... 444e11d... M	gschem/src/o_attrib.c
:100644 100644 19fbbe8... 48fac8f... M	gschem/src/o_misc.c
:100644 100644 91774e3... dbf454a... M	gschem/src/o_slot.c
:100644 100644 596b81b... 4984641... M	gschem/src/o_text.c
:100644 100644 dd98c06... 2a78dfc... M	gschem/src/x_attribedit.c
:100644 100644 b6768e8... 073f916... M	gschem/src/x_autonumber.c
:100644 100644 3266a71... 3b611de... M	gschem/src/x_multiattrib.c
:100644 100644 c1e3858... 6830674... M	libgeda/src/o_text_basic.c

commit 5c14a649bd633950624dfda4128bd83ed77ef4bc
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    Use change notifications for objects added / removed from the page
    
    Adds emission of the change and pre-change notify events for adding
    and removing objects from the page respectively.
    
    Remove explicit invalidation calls after performing these actions
    in gschem.

:100644 100644 9866eaf... 1b029cd... M	gschem/src/g_hook.c
:100644 100644 16c5b1a... 336a910... M	gschem/src/o_arc.c
:100644 100644 4c7dadf... 820e615... M	gschem/src/o_box.c
:100644 100644 7ef8141... 94e0201... M	gschem/src/o_bus.c
:100644 100644 5590a68... 9c36a95... M	gschem/src/o_circle.c
:100644 100644 d7d323a... 09f1fab... M	gschem/src/o_delete.c
:100644 100644 4eb59d1... 80b89f4... M	gschem/src/o_line.c
:100644 100644 276f168... 19fbbe8... M	gschem/src/o_misc.c
:100644 100644 14bd87d... fa08a54... M	gschem/src/o_net.c
:100644 100644 d738cad... 47d3a83... M	gschem/src/o_picture.c
:100644 100644 2229a5e... bc625e2... M	gschem/src/o_pin.c
:100644 100644 7b89ecc... 3266a71... M	gschem/src/x_multiattrib.c
:100644 100644 28e529e... d486734... M	libgeda/src/s_page.c

commit 0a93ef44cea25ec2bed559d8a05488fd3badd63c
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    libgeda: Process updates prior to removing an object from the page.
    
    Renames the private function object_removed to pre_object_removed,
    and moves its calls prior to removing the object from the page.
    
    For the existing  updates, the order doesn't matter, however other
    things we might like to do per-object when removing them from the
    page, such as emitting notifications of what we're about to do,
    must be done before the object is actually removed.

:100644 100644 0ef30d0... 28e529e... M	libgeda/src/s_page.c

commit ccf8b757df96f9eafb676a8ab0960c76f9692238
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    gschem: Hookup change notify functions to invalidate on-screen objects
    
    When change pre-change and change notifications are emitted on objects,
    we need to invalidate their on-screen representation.
    
    The pre-change notification is used to invalidate the area where an
    object is currently drawn, which is expected (usually) to be followed
    by a change notification - so the new object bounds are invalidated
    to be repainted.
    
    Certain operations might skip one of these events. For cases where the
    bounding box of an object is known to remain constant, the "pre-change"
    notification could potentially be omitted. Adding an object to the page
    will (obviously) only be able to generate a "change" notification, and
    removing an object will only generate a "pre-change" notification.

:100644 100644 216db31... b47d503... M	gschem/src/gschem.c
:100644 100644 37f8823... 65898f8... M	gschem/src/i_callbacks.c
:100644 100644 271b545... 47bab5c... M	gschem/src/x_preview.c

commit 8b1faf85362bb30c392e2b9ebc5d8ccb800b85f2
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    libgeda: Add mechanism to call hook function when an object changes.
    
    Introduces two new functions wihin libgeda, o_emit_pre_change_notify()
    and o_emit_change_notify(), intended to be called prior to and after
    an object being modified, respectively. This mechanism is primarily
    intended as a means for libgeda to trigger on-screen updates when
    objects are changed, and as such - at present, only a single pair of
    call-backs can be registered (per TOPLEVEL). These call-backs are
    registered via the new public function o_set_change_notify_funcs().
    
    The o_emit_pre_change_notify() function gives the GUI an opportunity to
    queue a redraw for the screen region where an object used to reside,
    prior to operations which change its bounding box, and similarly, the
    o_emit_change_notify() allows the GUI to trigger a redraw of the
    modified object.

:100644 100644 5d03e5b... 8021199... M	libgeda/include/libgeda/prototype.h
:100644 100644 84d996b... 03e70e6... M	libgeda/include/libgeda/struct.h
:100644 100644 5868842... 531afa9... M	libgeda/include/prototype_priv.h
:100644 100644 146f7e5... 2748a19... M	libgeda/src/o_basic.c
:100644 100644 0bec65b... 94a3857... M	libgeda/src/s_toplevel.c

=========
 Changes
=========

commit cc0ced2f6d765e5be43de4cd8d0e7caacee9478d
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    gschem: Remove o_invalidate_glist() call from i_callback_edit_(un)embed
    
    This invalidate calls are not required, as any relevant changes will
    cause change notifications from within libgeda to trigger redraws of
    specific areas of the page.
    
    NB: Changing the embedded status of an object doesn't actually cause a
    change notification at present, since it should not affect the how the
    objects are rendered.

diff --git a/gschem/src/i_callbacks.c b/gschem/src/i_callbacks.c
index ea2b81c..4e664ec 100644
--- a/gschem/src/i_callbacks.c
+++ b/gschem/src/i_callbacks.c
@@ -1021,8 +1021,6 @@ DEFINE_I_CALLBACK(edit_embed)
       }
       s_current = g_list_next(s_current);
     }
-    o_invalidate_glist (w_current, geda_list_get_glist (
-                          w_current->toplevel->page_current->selection_list));
     o_undo_savestate(w_current, UNDO_ALL);
   } else {
     /* nothing selected, go back to select state */
@@ -1062,8 +1060,6 @@ DEFINE_I_CALLBACK(edit_unembed)
       }
       s_current = g_list_next(s_current);
     }
-    o_invalidate_glist (w_current, geda_list_get_glist (
-                          w_current->toplevel->page_current->selection_list));
     o_undo_savestate(w_current, UNDO_ALL);
   } else {
     /* nothing selected, go back to select state */

commit 5e8f2be04fd2a1371dcfc2dd595ca319749fe7e2
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    gschem: Remove o_invalidate_all() call from i_callback_edit_update
    
    This invalidate call is not required, as any changes will cause
    change notifications from within libgeda to trigger specific areas
    of the page to be redrawn.

diff --git a/gschem/src/i_callbacks.c b/gschem/src/i_callbacks.c
index 65898f8..ea2b81c 100644
--- a/gschem/src/i_callbacks.c
+++ b/gschem/src/i_callbacks.c
@@ -1119,9 +1119,6 @@ DEFINE_I_CALLBACK(edit_update)
       s_current = g_list_next(s_current);
     }
     g_list_free(selection_copy);
-
-    /* Make sure the display is up to date */
-    o_invalidate_all (w_current);
   } else {
     /* nothing selected, go back to select state */
     o_redraw_cleanstates(w_current);	

commit b59058138ce5057b3520f70754a610a99fb440a7
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    Use change notification to redraw objects when connectivity changes
    
    Emit change notifications in the connectivity tracking functions
    s_conn_remove_other() and s_conn_update_line_object(). This frees
    gschem from the somewhat complex task of tracking which objects were
    connected to a given object before and after a particular set of
    operations.
    
    This change leads to a significant simplification of many operations,
    and removes quantities of code from:
    
      o_pin_end()
      o_net_end()
      o_move_end()
      o_move_end_rubberband()
      o_move_end_lowlevel()
      o_mirror_world_update()
      o_rotate_world_update()
      o_grips_end_bus()
      o_grips_end_pin()
      o_grips_end_net()
      o_delete()

diff --git a/gschem/include/prototype.h b/gschem/include/prototype.h
index 4123acf..e018101 100644
--- a/gschem/include/prototype.h
+++ b/gschem/include/prototype.h
@@ -608,7 +608,7 @@ void o_update_component(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current);
 void o_autosave_backups(GSCHEM_TOPLEVEL *w_current);
 /* o_move.c */
 void o_move_start(GSCHEM_TOPLEVEL *w_current, int x, int y);
-void o_move_end_lowlevel(GSCHEM_TOPLEVEL *w_current, OBJECT *object, int diff_x, int diff_y, GList **other_objects, GList **connected_objects);
+void o_move_end_lowlevel(GSCHEM_TOPLEVEL *w_current, OBJECT *object, int diff_x, int diff_y);
 void o_move_end(GSCHEM_TOPLEVEL *w_current);
 void o_move_cancel(GSCHEM_TOPLEVEL *w_current);
 void o_move_motion(GSCHEM_TOPLEVEL *w_current, int x, int y);
@@ -618,7 +618,7 @@ int o_move_return_whichone(OBJECT *object, int x, int y);
 void o_move_check_endpoint(GSCHEM_TOPLEVEL *w_current, OBJECT *object);
 void o_move_prep_rubberband(GSCHEM_TOPLEVEL *w_current);
 int o_move_zero_length(OBJECT *object);
-void o_move_end_rubberband(GSCHEM_TOPLEVEL *w_current, int world_diff_x, int world_diff_y, GList **objects, GList **other_objects, GList **connected_objects);
+void o_move_end_rubberband(GSCHEM_TOPLEVEL *w_current, int world_diff_x, int world_diff_y, GList **objects);
 /* o_net.c */
 void o_net_reset(GSCHEM_TOPLEVEL *w_current); 
 void o_net_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current);
diff --git a/gschem/src/o_delete.c b/gschem/src/o_delete.c
index 09f1fab..8389e4f 100644
--- a/gschem/src/o_delete.c
+++ b/gschem/src/o_delete.c
@@ -38,34 +38,9 @@
 void o_delete (GSCHEM_TOPLEVEL *w_current, OBJECT *object)
 {
   TOPLEVEL *toplevel = w_current->toplevel;
-  GList *prev_conn_objects = NULL;
-  GList *iter, *iter_next;
-  gboolean do_conn;
 
   g_return_if_fail (object != NULL);
 
-  do_conn =
-    object->type == OBJ_NET || object->type == OBJ_BUS ||
-    object->type == OBJ_PIN || object->type == OBJ_COMPLEX;
-  
-  if (do_conn) {
-    prev_conn_objects = s_conn_return_others (prev_conn_objects, object);
-
-    /* Check for complex which self-connects, e.g. coincident pins.
-     * Remove any prev_conn_objects which are inside the complex.
-     */
-    if (object->type == OBJ_COMPLEX) {
-      for (iter = prev_conn_objects; iter != NULL; iter = iter_next) {
-        OBJECT *conn_obj = iter->data;
-        iter_next = g_list_next (iter);
-        if (conn_obj->parent == object)
-          prev_conn_objects = g_list_delete_link (prev_conn_objects, iter);
-      }
-    }
-    o_invalidate_glist (w_current, prev_conn_objects);
-    g_list_free (prev_conn_objects);
-  }
-
   s_page_remove (toplevel, toplevel->page_current, object);
   s_delete_object (toplevel, object);
 
diff --git a/gschem/src/o_grips.c b/gschem/src/o_grips.c
index f688981..66d1995 100644
--- a/gschem/src/o_grips.c
+++ b/gschem/src/o_grips.c
@@ -1242,7 +1242,6 @@ static void o_grips_end_net(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current,
                             int whichone)
 {
   TOPLEVEL *toplevel = w_current->toplevel;
-  GList *prev_conn_objects;
   GList *connected_objects;
 
   /* erase the temporary line */
@@ -1257,26 +1256,14 @@ static void o_grips_end_net(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current,
     return;
   }
 
-  prev_conn_objects = s_conn_return_others (NULL, o_current);
-
   s_conn_remove_object (toplevel, o_current);
   o_net_modify (toplevel, o_current, w_current->second_wx,
                 w_current->second_wy, w_current->which_grip);
   s_conn_update_object (toplevel, o_current);
 
-  /* get the other connected objects and redraw them */
-  connected_objects = s_conn_return_others (NULL, o_current);
   /* add bus rippers if necessary */
-  o_net_add_busrippers (w_current, o_current, connected_objects);
-  g_list_free (connected_objects);
-
-  /* draw the object objects */
-  o_invalidate_glist (w_current, prev_conn_objects);
-  g_list_free (prev_conn_objects);
-
-  /* get the other connected objects and redraw them */
   connected_objects = s_conn_return_others (NULL, o_current);
-  o_invalidate_glist (w_current, connected_objects);
+  o_net_add_busrippers (w_current, o_current, connected_objects);
   g_list_free (connected_objects);
 }
 
@@ -1300,8 +1287,6 @@ static void o_grips_end_pin(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current,
                             int whichone)
 {
   TOPLEVEL *toplevel = w_current->toplevel;
-  GList *prev_conn_objects;
-  GList *connected_objects;
 
   /* erase the temporary line */
   /* o_line_invalidate_rubber (w_current); */
@@ -1315,22 +1300,10 @@ static void o_grips_end_pin(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current,
     return;
   }
 
-  prev_conn_objects = s_conn_return_others (NULL, o_current);
-
   s_conn_remove_object (toplevel, o_current);
   o_pin_modify (toplevel, o_current, w_current->second_wx,
                 w_current->second_wy, w_current->which_grip);
   s_conn_update_object (toplevel, o_current);
-
-  /* redraw the object connections */
-  o_invalidate_glist (w_current, prev_conn_objects);
-  g_list_free (prev_conn_objects);
-
-  /* get the other connected objects and redraw them */
-  connected_objects = s_conn_return_others (NULL, o_current);
-  o_invalidate_glist (w_current, connected_objects);
-  g_list_free (connected_objects);
-
 }
 
 /*! \brief End process of modifying bus object with grip.
@@ -1353,8 +1326,6 @@ static void o_grips_end_bus(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current,
                             int whichone)
 {
   TOPLEVEL *toplevel = w_current->toplevel;
-  GList *prev_conn_objects;
-  GList *connected_objects;
 
   /* erase the temporary line */
   /* o_line_invalidate_rubber (w_current); */
@@ -1368,21 +1339,10 @@ static void o_grips_end_bus(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current,
     return;
   }
 
-  prev_conn_objects = s_conn_return_others (NULL, o_current);
-
   s_conn_remove_object (toplevel, o_current);
   o_bus_modify (toplevel, o_current, w_current->second_wx,
                 w_current->second_wy, w_current->which_grip);
   s_conn_update_object (toplevel, o_current);
-
-  /* redraw the connected objects */
-  o_invalidate_glist (w_current, prev_conn_objects);
-  g_list_free (prev_conn_objects);
-
-  /* get the other connected objects and redraw them */
-  connected_objects = s_conn_return_others (NULL, o_current);
-  o_invalidate_glist (w_current, connected_objects);
-  g_list_free (connected_objects);
 }
 
 
diff --git a/gschem/src/o_misc.c b/gschem/src/o_misc.c
index 870137a..fe84603 100644
--- a/gschem/src/o_misc.c
+++ b/gschem/src/o_misc.c
@@ -191,8 +191,6 @@ void o_rotate_world_update(GSCHEM_TOPLEVEL *w_current,
   TOPLEVEL *toplevel = w_current->toplevel;
   OBJECT *o_current;
   GList *o_iter;
-  GList *prev_conn_objects=NULL;
-  GList *connected_objects=NULL;
 
   /* this is okay if you just hit rotate and have nothing selected */
   if (list == NULL) {
@@ -207,12 +205,11 @@ void o_rotate_world_update(GSCHEM_TOPLEVEL *w_current,
 
   /* Find connected objects, removing each object in turn from the
    * connection list. We only _really_ want those objects connected
-   * to the selection, not those within in it. The extra redraws
-   * don't _really_ hurt though. */
+   * to the selection, not those within in it.
+   */
   for (o_iter = list; o_iter != NULL; o_iter = g_list_next (o_iter)) {
     o_current = o_iter->data;
 
-    prev_conn_objects = s_conn_return_others (prev_conn_objects, o_current);
     s_conn_remove_object (toplevel, o_current);
   }
 
@@ -220,26 +217,18 @@ void o_rotate_world_update(GSCHEM_TOPLEVEL *w_current,
 
   /* Find connected objects, adding each object in turn back to the
    * connection list. We only _really_ want those objects connected
-   * to the selection, not those within in it. The extra redraws dont
-   * _really_ hurt though. */
+   * to the selection, not those within in it.
+   */
   for (o_iter = list; o_iter != NULL; o_iter = g_list_next (o_iter)) {
     o_current = o_iter->data;
 
     s_conn_update_object (toplevel, o_current);
-    connected_objects = s_conn_return_others (connected_objects, o_current);
   }
 
   if (!toplevel->DONT_REDRAW) {
     o_invalidate_glist (w_current, list);
-    o_invalidate_glist (w_current, prev_conn_objects);
-    o_invalidate_glist (w_current, connected_objects);
   }
 
-  g_list_free (prev_conn_objects);
-  prev_conn_objects = NULL;
-  g_list_free (connected_objects);
-  connected_objects = NULL;
-
   /* All objects were rotated. Run the rotate hooks */
   o_rotate_call_hooks (w_current, list);
 
@@ -299,8 +288,6 @@ void o_mirror_world_update(GSCHEM_TOPLEVEL *w_current, int centerx, int centery,
   TOPLEVEL *toplevel = w_current->toplevel;
   OBJECT *o_current;
   GList *o_iter;
-  GList *prev_conn_objects=NULL;
-  GList *connected_objects=NULL;
 
   if (list == NULL) {
     w_current->inside_action = 0;
@@ -312,12 +299,11 @@ void o_mirror_world_update(GSCHEM_TOPLEVEL *w_current, int centerx, int centery,
 
   /* Find connected objects, removing each object in turn from the
    * connection list. We only _really_ want those objects connected
-   * to the selection, not those within in it. The extra redraws
-   * don't _really_ hurt though. */
+   * to the selection, not those within in it.
+   */
   for (o_iter = list; o_iter != NULL; o_iter = g_list_next (o_iter)) {
     o_current = o_iter->data;
 
-    prev_conn_objects = s_conn_return_others (prev_conn_objects, o_current);
     s_conn_remove_object (toplevel, o_current);
   }
 
@@ -325,23 +311,15 @@ void o_mirror_world_update(GSCHEM_TOPLEVEL *w_current, int centerx, int centery,
 
   /* Find connected objects, adding each object in turn back to the
    * connection list. We only _really_ want those objects connected
-   * to the selection, not those within in it. The extra redraws dont
-   * _really_ hurt though. */
+   * to the selection, not those within in it.
+   */
   for (o_iter = list; o_iter != NULL; o_iter = g_list_next (o_iter)) {
     o_current = o_iter->data;
 
     s_conn_update_object (toplevel, o_current);
-    connected_objects = s_conn_return_others (connected_objects, o_current);
   }
 
   o_invalidate_glist (w_current, list);
-  o_invalidate_glist (w_current, prev_conn_objects);
-  o_invalidate_glist (w_current, connected_objects);
-
-  g_list_free (prev_conn_objects);
-  prev_conn_objects = NULL;
-  g_list_free (connected_objects);
-  connected_objects = NULL;
 
   /* All objects were mirrored. Do a 2nd pass to run the mirror hooks */
   /* Do not run any hooks for simple objects here, like text, since they
diff --git a/gschem/src/o_move.c b/gschem/src/o_move.c
index 0b295c6..93f53c1 100644
--- a/gschem/src/o_move.c
+++ b/gschem/src/o_move.c
@@ -79,9 +79,7 @@ void o_move_start(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
  */
 static void o_move_end_lowlevel_glist (GSCHEM_TOPLEVEL *w_current,
                                        GList *list,
-                                       int diff_x, int diff_y,
-                                       GList** prev_conn_objects,
-                                       GList** connected_objects)
+                                       int diff_x, int diff_y)
 {
   OBJECT *object;
   GList *iter;
@@ -89,8 +87,7 @@ static void o_move_end_lowlevel_glist (GSCHEM_TOPLEVEL *w_current,
   iter = list;
   while (iter != NULL) {
     object = (OBJECT *)iter->data;
-    o_move_end_lowlevel (w_current, object, diff_x, diff_y,
-                         prev_conn_objects, connected_objects);
+    o_move_end_lowlevel (w_current, object, diff_x, diff_y);
     iter = g_list_next (iter);
   }
 }
@@ -103,9 +100,7 @@ static void o_move_end_lowlevel_glist (GSCHEM_TOPLEVEL *w_current,
  */
 void o_move_end_lowlevel (GSCHEM_TOPLEVEL *w_current,
                          OBJECT *object,
-                         int diff_x, int diff_y,
-                         GList** prev_conn_objects,
-                         GList** connected_objects)
+                         int diff_x, int diff_y)
 {
   TOPLEVEL *toplevel = w_current->toplevel;
 
@@ -114,14 +109,9 @@ void o_move_end_lowlevel (GSCHEM_TOPLEVEL *w_current,
     case (OBJ_NET):
     case (OBJ_BUS):
     case (OBJ_PIN):
-      /* save the other objects and remove object's connections */
-      *prev_conn_objects = s_conn_return_others (*prev_conn_objects, object);
       s_conn_remove_object (toplevel, object);
-
-      /* do the actual translation */
       o_translate_world (toplevel, diff_x, diff_y, object);
       s_conn_update_object (toplevel, object);
-      *connected_objects = s_conn_return_others (*connected_objects, object);
       break;
 
     default:
@@ -143,11 +133,7 @@ void o_move_end(GSCHEM_TOPLEVEL *w_current)
   int diff_x, diff_y;
   int left, top, right, bottom;
   GList *s_iter;
-  GList *prev_conn_objects = NULL;
-  GList *connected_objects = NULL;
   GList *rubbernet_objects = NULL; 
-  GList *rubbernet_prev_conn_objects = NULL;
-  GList *rubbernet_connected_objects = NULL;
 
   object = o_select_return_first_object(w_current);
 
@@ -165,9 +151,7 @@ void o_move_end(GSCHEM_TOPLEVEL *w_current)
   w_current->rubber_visible = 0;
 
   if (w_current->netconn_rubberband) {
-    o_move_end_rubberband(w_current, diff_x, diff_y,
-                          &rubbernet_objects, &rubbernet_prev_conn_objects,
-                          &rubbernet_connected_objects);
+    o_move_end_rubberband (w_current, diff_x, diff_y, &rubbernet_objects);
   }
 
   /* Unset the dont_redraw flag on rubberbanded objects.
@@ -210,8 +194,7 @@ void o_move_end(GSCHEM_TOPLEVEL *w_current)
         object->complex->y = object->complex->y + diff_y;
 
         o_move_end_lowlevel_glist (w_current, object->complex->prim_objs,
-                                   diff_x, diff_y,
-                                   &prev_conn_objects, &connected_objects);
+                                   diff_x, diff_y);
 
 
         world_get_object_glist_bounds (toplevel, object->complex->prim_objs,
@@ -225,8 +208,7 @@ void o_move_end(GSCHEM_TOPLEVEL *w_current)
         break;
 
       default:
-        o_move_end_lowlevel (w_current, object, diff_x, diff_y,
-                            &prev_conn_objects, &connected_objects);
+        o_move_end_lowlevel (w_current, object, diff_x, diff_y);
         break;
     }
 
@@ -236,25 +218,17 @@ void o_move_end(GSCHEM_TOPLEVEL *w_current)
   /* Remove the undo saved in o_move_start */
   o_undo_remove_last_undo(w_current);
 
-  /* Draw the objects that were moved (and connected/disconnected objects) */
+  /* Draw the objects that were moved */
   o_invalidate_glist (w_current,
     geda_list_get_glist (toplevel->page_current->selection_list));
-  o_invalidate_glist (w_current, prev_conn_objects);
-  o_invalidate_glist (w_current, connected_objects);
 
   /* Draw the connected nets/buses that were also changed */
   o_invalidate_glist (w_current, rubbernet_objects);
-  o_invalidate_glist (w_current, rubbernet_prev_conn_objects);
-  o_invalidate_glist (w_current, rubbernet_connected_objects);
- 
+
   toplevel->page_current->CHANGED = 1;
   o_undo_savestate(w_current, UNDO_ALL);
 
-  g_list_free(prev_conn_objects);
-  g_list_free(connected_objects);
   g_list_free(rubbernet_objects);
-  g_list_free(rubbernet_prev_conn_objects);
-  g_list_free(rubbernet_connected_objects);
 
   g_list_free(toplevel->page_current->place_list);
   toplevel->page_current->place_list = NULL;
@@ -637,25 +611,10 @@ int o_move_zero_length(OBJECT * object)
  */
 void o_move_end_rubberband (GSCHEM_TOPLEVEL *w_current,
                             int w_dx, int w_dy,
-                            GList** objects,
-                            GList** prev_conn_objects,
-                            GList** connected_objects)
+                            GList** objects)
 {
   TOPLEVEL *toplevel = w_current->toplevel;
   GList *s_iter, *s_iter_next;
-  GList *iter;
-
-  /* save a list of objects the stretched objects
-     are connected to before we move them. */
-  for (s_iter = toplevel->page_current->stretch_list;
-       s_iter != NULL; s_iter = g_list_next (s_iter)) {
-    OBJECT *object = ((STRETCH *)s_iter->data)->object;
-
-    if (object->type == OBJ_NET ||
-        object->type == OBJ_BUS) {
-      *prev_conn_objects = s_conn_return_others (*prev_conn_objects, object);
-    }
-  }
 
   for (s_iter = toplevel->page_current->stretch_list;
        s_iter != NULL; s_iter = s_iter_next) {
@@ -678,7 +637,6 @@ void o_move_end_rubberband (GSCHEM_TOPLEVEL *w_current,
       if (o_move_zero_length (object)) {
         toplevel->page_current->stretch_list =
           s_stretch_remove (toplevel->page_current->stretch_list, object);
-        *prev_conn_objects = g_list_remove_all (*prev_conn_objects, object);
         o_delete (w_current, object);
         continue;
       }
@@ -689,11 +647,4 @@ void o_move_end_rubberband (GSCHEM_TOPLEVEL *w_current,
       *objects = g_list_append (*objects, object);
     }
   }
-
-  /* save a list of objects the stretched objects
-     are now connected to after we moved them. */
-  for (iter = *objects; iter != NULL; iter = g_list_next (iter)) {
-    OBJECT *object = iter->data;
-    *connected_objects = s_conn_return_others (*connected_objects, object);
-  }
 }
diff --git a/gschem/src/o_net.c b/gschem/src/o_net.c
index fa08a54..3a03118 100644
--- a/gschem/src/o_net.c
+++ b/gschem/src/o_net.c
@@ -558,7 +558,7 @@ int o_net_end(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
   int found_primary_connection = FALSE;
   int save_wx, save_wy;
 
-  GList *prev_conn_objects = NULL;
+  GList *prev_conn_objects;
   OBJECT *new_net = NULL;
 
   g_assert( w_current->inside_action != 0 );
@@ -606,24 +606,15 @@ int o_net_end(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
 
       /* conn stuff */
       /* LEAK CHECK 1 */
-      prev_conn_objects = s_conn_return_others (prev_conn_objects, new_net);
-
-      if (o_net_add_busrippers (w_current, new_net, prev_conn_objects)) {
-        g_list_free (prev_conn_objects);
-        prev_conn_objects = NULL;
-        prev_conn_objects = s_conn_return_others (prev_conn_objects, new_net);
-      }
+      prev_conn_objects = s_conn_return_others (NULL, new_net);
+      o_net_add_busrippers (w_current, new_net, prev_conn_objects);
+      g_list_free (prev_conn_objects);
 
 #if DEBUG 
       printf("primary:\n"); 
       s_conn_print(new_net->conn_list);
 #endif
 
-      o_invalidate_glist (w_current, prev_conn_objects);
-
-      g_list_free (prev_conn_objects);
-      prev_conn_objects = NULL;
-
       /* Go off and search for valid connection on this newly created net */
       found_primary_connection = s_conn_net_search(new_net, 1, 
                                                    new_net->conn_list);
@@ -648,21 +639,12 @@ int o_net_end(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
 
       /* conn stuff */
       /* LEAK CHECK 2 */
-      prev_conn_objects = s_conn_return_others (prev_conn_objects, new_net);
-
-      if (o_net_add_busrippers (w_current, new_net, prev_conn_objects)) {
-        g_list_free (prev_conn_objects);
-        prev_conn_objects = NULL;
-        prev_conn_objects = s_conn_return_others (prev_conn_objects, new_net);
-      }
+      prev_conn_objects = s_conn_return_others (NULL, new_net);
+      o_net_add_busrippers (w_current, new_net, prev_conn_objects);
+      g_list_free (prev_conn_objects);
 #if DEBUG
       s_conn_print(new_net->conn_list);
 #endif
-
-      o_invalidate_glist (w_current, prev_conn_objects);
-
-      g_list_free (prev_conn_objects);
-      prev_conn_objects = NULL;
   }
 
   toplevel->page_current->CHANGED = 1;
diff --git a/gschem/src/o_pin.c b/gschem/src/o_pin.c
index bc625e2..14345d7 100644
--- a/gschem/src/o_pin.c
+++ b/gschem/src/o_pin.c
@@ -120,7 +120,6 @@ void o_pin_end(GSCHEM_TOPLEVEL *w_current, int x, int y)
   TOPLEVEL *toplevel = w_current->toplevel;
   OBJECT *new_obj;
   int color;
-  GList *prev_conn_objects = NULL;
 
   g_assert( w_current->inside_action != 0 );
 
@@ -151,11 +150,6 @@ void o_pin_end(GSCHEM_TOPLEVEL *w_current, int x, int y)
                   scm_cons (g_make_object_smob (toplevel, new_obj), SCM_EOL));
   }
 
-  /* look for connected objects */
-  prev_conn_objects = s_conn_return_others (prev_conn_objects, new_obj);
-  o_invalidate_glist (w_current, prev_conn_objects);
-  g_list_free (prev_conn_objects);
-
   toplevel->page_current->CHANGED=1;
   o_undo_savestate(w_current, UNDO_ALL);
 }
diff --git a/libgeda/src/s_conn.c b/libgeda/src/s_conn.c
index 4985071..184cf4e 100644
--- a/libgeda/src/s_conn.c
+++ b/libgeda/src/s_conn.c
@@ -121,6 +121,8 @@ int s_conn_remove_other (TOPLEVEL *toplevel, OBJECT *other_object,
     GList *c_current = NULL;
     CONN *conn = NULL;
 
+    o_emit_pre_change_notify (toplevel, other_object);
+
     c_current = other_object->conn_list;
     while (c_current != NULL) {
 	conn = (CONN *) c_current->data;
@@ -155,6 +157,8 @@ int s_conn_remove_other (TOPLEVEL *toplevel, OBJECT *other_object,
 	c_current = g_list_next(c_current);
     }
 
+    o_emit_change_notify (toplevel, other_object);
+
     return (FALSE);
 }
 
@@ -391,6 +395,8 @@ static void s_conn_update_line_object (TOPLEVEL *toplevel, OBJECT *object)
               object->line->y[j] == other_object->line->y[k] &&
               check_direct_compat (object, other_object)) {
 
+            o_emit_pre_change_notify (toplevel, other_object);
+
             add_connection (object, other_object, CONN_ENDPOINT,
                             other_object->line->x[k],
                             other_object->line->y[k], j, k);
@@ -398,6 +404,8 @@ static void s_conn_update_line_object (TOPLEVEL *toplevel, OBJECT *object)
             add_connection (other_object, object, CONN_ENDPOINT,
                             object->line->x[j],
                             object->line->y[j], k, j);
+
+            o_emit_change_notify (toplevel, other_object);
           }
         }
       }

commit cf6ea830c56a04ebb47e958dc1f8895dcc8f60e7
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    Use change notification to redraw when a pin's type is modified
    
    Emit change notifications in o_pin_set_type(), and remove
    o_invalidate() calls where this function is used in gschem.

diff --git a/gschem/src/x_dialog.c b/gschem/src/x_dialog.c
index 4c758a9..507919c 100644
--- a/gschem/src/x_dialog.c
+++ b/gschem/src/x_dialog.c
@@ -4247,11 +4247,9 @@ void x_dialog_edit_pin_type (GSCHEM_TOPLEVEL *w_current, const GList *obj_list)
         if (object->type == OBJ_PIN &&
             object->pin_type != new_type) {
           changed_anything = TRUE;
-          o_invalidate (w_current, object);
           s_conn_remove_object (w_current->toplevel, object);
           o_pin_set_type (w_current->toplevel, object, new_type);
           s_conn_update_object (w_current->toplevel, object);
-          o_invalidate (w_current, object);
         }
       }
       if (changed_anything)
diff --git a/libgeda/src/o_pin_basic.c b/libgeda/src/o_pin_basic.c
index c865313..6e38587 100644
--- a/libgeda/src/o_pin_basic.c
+++ b/libgeda/src/o_pin_basic.c
@@ -565,6 +565,7 @@ void o_pin_update_whichend(TOPLEVEL *toplevel,
  */
 void o_pin_set_type (TOPLEVEL *toplevel, OBJECT *o_current, int pin_type)
 {
+  o_emit_pre_change_notify (toplevel, o_current);
   switch (pin_type) {
     default:
       g_critical ("o_pin_set_type: Got invalid pin type %i\n", pin_type);
@@ -578,4 +579,5 @@ void o_pin_set_type (TOPLEVEL *toplevel, OBJECT *o_current, int pin_type)
       o_current->pin_type = PIN_TYPE_BUS;
       break;
   }
+  o_emit_change_notify (toplevel, o_current);
 }

commit 5e43eb790eee741c861862d27435fac0cca55df2
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    Add change notification when objects are modified via o_*_modify()
    
    Emit change notification in the o_*_modify() functions, and remove
    some o_invalidate() calls where o_arc_modify() is also used in
    gschem's arc editing dialog.
    
    The o_*_modify() routines are also used in o_grips.c, where there
    is no explicit o_invalidate() call after them. o_grips_end() calls
    o_invalidate(), which is strictly un-necessary, but I've left it for
    clarity, as it comes after resetting the OBJECT's dont_redraw flag.

diff --git a/gschem/src/x_dialog.c b/gschem/src/x_dialog.c
index 2a68e5b..4c758a9 100644
--- a/gschem/src/x_dialog.c
+++ b/gschem/src/x_dialog.c
@@ -1555,11 +1555,9 @@ void arc_angle_dialog_response(GtkWidget *w, gint response,
     arc_object = (OBJECT*) g_object_get_data(G_OBJECT(w_current->aawindow),"arc_object");
 
     if (arc_object != NULL) {
-      o_invalidate (w_current, arc_object);
       o_arc_modify(w_current->toplevel, arc_object, radius, 0, ARC_RADIUS);
       o_arc_modify(w_current->toplevel, arc_object, start_angle, 0, ARC_START_ANGLE);
       o_arc_modify(w_current->toplevel, arc_object, sweep_angle, 0, ARC_END_ANGLE);
-      o_invalidate (w_current, arc_object);
     } else {
       o_arc_end4(w_current, radius, start_angle, sweep_angle);
     }
diff --git a/libgeda/src/o_arc_basic.c b/libgeda/src/o_arc_basic.c
index baeb169..761a347 100644
--- a/libgeda/src/o_arc_basic.c
+++ b/libgeda/src/o_arc_basic.c
@@ -178,6 +178,8 @@ void o_arc_modify(TOPLEVEL *toplevel, OBJECT *object,
 		  int x, int y, int whichone)
 {
 
+	o_emit_pre_change_notify (toplevel, object);
+
 	switch(whichone) {
 		case ARC_CENTER:
 		/* modify the center of arc object */
@@ -207,7 +209,7 @@ void o_arc_modify(TOPLEVEL *toplevel, OBJECT *object,
 
 	/* update the screen coords and the bounding box */
 	o_arc_recalc(toplevel, object);
-	
+	o_emit_change_notify (toplevel, object);
 }
 
 /*! \brief
diff --git a/libgeda/src/o_box_basic.c b/libgeda/src/o_box_basic.c
index 3260864..0556d79 100644
--- a/libgeda/src/o_box_basic.c
+++ b/libgeda/src/o_box_basic.c
@@ -168,7 +168,9 @@ void o_box_modify(TOPLEVEL *toplevel, OBJECT *object,
 		  int x, int y, int whichone)
 {
 	int tmp;
-	
+
+	o_emit_pre_change_notify (toplevel, object);
+
 	/* change the position of the selected corner */
 	switch(whichone) {
 		case BOX_UPPER_LEFT:
@@ -210,6 +212,7 @@ void o_box_modify(TOPLEVEL *toplevel, OBJECT *object,
 	
 	/* recalculate the world coords and the boundings */
 	o_box_recalc(toplevel, object);
+	o_emit_change_notify (toplevel, object);
   
 }
 
diff --git a/libgeda/src/o_circle_basic.c b/libgeda/src/o_circle_basic.c
index 9da6077..c9b9b68 100644
--- a/libgeda/src/o_circle_basic.c
+++ b/libgeda/src/o_circle_basic.c
@@ -185,6 +185,8 @@ OBJECT *o_circle_copy(TOPLEVEL *toplevel, OBJECT *o_current)
 void o_circle_modify(TOPLEVEL *toplevel, OBJECT *object,
 		     int x, int y, int whichone)
 {
+  o_emit_pre_change_notify (toplevel, object);
+
   switch(whichone) {
     case CIRCLE_CENTER:
       /* modify the center of the circle */
@@ -205,7 +207,7 @@ void o_circle_modify(TOPLEVEL *toplevel, OBJECT *object,
 
   /* recalculate the boundings */
   o_circle_recalc(toplevel, object);
-  
+  o_emit_change_notify (toplevel, object);
 }
 
 /*! \brief Create circle OBJECT from character string.
diff --git a/libgeda/src/o_line_basic.c b/libgeda/src/o_line_basic.c
index c6316ef..b35a705 100644
--- a/libgeda/src/o_line_basic.c
+++ b/libgeda/src/o_line_basic.c
@@ -168,6 +168,8 @@ OBJECT *o_line_copy(TOPLEVEL *toplevel, OBJECT *o_current)
 void o_line_modify(TOPLEVEL *toplevel, OBJECT *object,
                    int x, int y, int whichone)
 {
+  o_emit_pre_change_notify (toplevel, object);
+
   /* change one of the end of the line */
   switch (whichone) {
     case LINE_END1:
@@ -186,6 +188,7 @@ void o_line_modify(TOPLEVEL *toplevel, OBJECT *object,
 
   /* recalculate the bounding box */
   o_line_recalc(toplevel, object);
+  o_emit_change_notify (toplevel, object);
 }
 
 /*! \brief Create line OBJECT from character string.
diff --git a/libgeda/src/o_path_basic.c b/libgeda/src/o_path_basic.c
index ed502c1..1e3b7dd 100644
--- a/libgeda/src/o_path_basic.c
+++ b/libgeda/src/o_path_basic.c
@@ -303,6 +303,8 @@ void o_path_modify (TOPLEVEL *toplevel, OBJECT *object,
   int grip_no = 0;
   PATH_SECTION *section;
 
+  o_emit_pre_change_notify (toplevel, object);
+
   for (i = 0; i <  object->path->num_sections; i++) {
     section = &object->path->sections[i];
 
@@ -334,6 +336,7 @@ void o_path_modify (TOPLEVEL *toplevel, OBJECT *object,
 
   /* Update bounding box */
   o_path_recalc (toplevel, object);
+  o_emit_change_notify (toplevel, object);
 }
 
 
diff --git a/libgeda/src/o_picture.c b/libgeda/src/o_picture.c
index aae9ba1..513af00 100644
--- a/libgeda/src/o_picture.c
+++ b/libgeda/src/o_picture.c
@@ -448,7 +448,9 @@ void o_picture_modify(TOPLEVEL *toplevel, OBJECT *object,
 		      int x, int y, int whichone)
 {
   int tmp;
-  
+
+  o_emit_pre_change_notify (toplevel, object);
+
   /* change the position of the selected corner */
   switch(whichone) {
     case PICTURE_UPPER_LEFT:
@@ -510,6 +512,7 @@ void o_picture_modify(TOPLEVEL *toplevel, OBJECT *object,
 	
   /* recalculate the screen coords and the boundings */
   o_picture_recalc(toplevel, object);
+  o_emit_change_notify (toplevel, object);
 }
 
 /*! \brief Rotate picture OBJECT using WORLD coordinates.

commit 51461b59d30487e9c1c2dbf3beb6883bd66314e1
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    Use change notification to redraw when an object's fill properties change
    
    Emit change notifications in o_set_fill_options(), and remove
    o_invalidate() calls where this function is used in gschem.

diff --git a/gschem/src/x_dialog.c b/gschem/src/x_dialog.c
index 575540f..2a68e5b 100644
--- a/gschem/src/x_dialog.c
+++ b/gschem/src/x_dialog.c
@@ -1331,10 +1331,8 @@ static void fill_type_dialog_ok(GtkWidget *w, gpointer data)
       g_assert_not_reached();
     }
     
-    o_invalidate (w_current, object);
     o_set_fill_options (toplevel, object, otype, owidth,
                         opitch1, oangle1, opitch2, oangle2);
-    o_invalidate (w_current, object);
   }
 
   toplevel->page_current->CHANGED = 1;
diff --git a/libgeda/src/o_basic.c b/libgeda/src/o_basic.c
index 17ddbc9..31e08f6 100644
--- a/libgeda/src/o_basic.c
+++ b/libgeda/src/o_basic.c
@@ -290,6 +290,8 @@ void o_set_fill_options(TOPLEVEL *toplevel, OBJECT *o_current,
     return;
   }
 
+  o_emit_pre_change_notify (toplevel, o_current);
+
   o_current->fill_type = type;
   o_current->fill_width = width;
 
@@ -298,7 +300,8 @@ void o_set_fill_options(TOPLEVEL *toplevel, OBJECT *o_current,
 
   o_current->fill_pitch2 = pitch2;
   o_current->fill_angle2 = angle2;
-	
+
+  o_emit_change_notify (toplevel, o_current);
 }
 
 /*! \brief get #OBJECT's fill properties.

commit ca60bcbdab636a6ee28a004d5ce802a57933e6bb
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    Use change notification to redraw when an object's line properties change
    
    Emit change notification in o_set_line_options(), and remove
    o_invalidate() calls where this function is used in gschem.

diff --git a/gschem/src/x_dialog.c b/gschem/src/x_dialog.c
index 62099cb..575540f 100644
--- a/gschem/src/x_dialog.c
+++ b/gschem/src/x_dialog.c
@@ -843,10 +843,8 @@ static void line_type_dialog_ok(GtkWidget *w, gpointer data)
       g_assert_not_reached();
     }
 
-    o_invalidate (w_current, object);
     o_set_line_options (toplevel, object,
                         oend, otype, owidth, olength, ospace);
-    o_invalidate (w_current, object);
   }
 
   toplevel->page_current->CHANGED = 1;
diff --git a/libgeda/src/o_basic.c b/libgeda/src/o_basic.c
index 2748a19..17ddbc9 100644
--- a/libgeda/src/o_basic.c
+++ b/libgeda/src/o_basic.c
@@ -216,6 +216,8 @@ void o_set_line_options(TOPLEVEL *toplevel, OBJECT *o_current,
     break;
   }
   
+  o_emit_pre_change_notify (toplevel, o_current);
+
   o_current->line_width = width;
   o_current->line_end   = end;
   o_current->line_type  = type;
@@ -225,6 +227,8 @@ void o_set_line_options(TOPLEVEL *toplevel, OBJECT *o_current,
 
   /* Recalculate the object's bounding box */
   o_recalc_single_object( toplevel, o_current );
+  o_emit_change_notify (toplevel, o_current);
+
 }
 
 /*! \brief get #OBJECT's line properties.

commit 51c180d137513668925fe2f5834f8ec5cb1d4563
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    Use change notifications to redraw objects with selection changes
    
    Emit change notifications when an OBJECT's selected flag is changed,
    and removes o_invalidate() calls where the selection is manipulated
    in gschem.

diff --git a/gschem/src/o_attrib.c b/gschem/src/o_attrib.c
index 444e11d..348d631 100644
--- a/gschem/src/o_attrib.c
+++ b/gschem/src/o_attrib.c
@@ -62,10 +62,8 @@ void o_attrib_add_selected(GSCHEM_TOPLEVEL *w_current, SELECTION *selection,
     a_current = a_iter->data;
 
     /* make sure object isn't selected already */
-    if (!a_current->selected) {
+    if (!a_current->selected)
       o_selection_add (w_current->toplevel, selection, a_current);
-      o_invalidate (w_current, a_current);
-    }
   }
 }
 
@@ -96,10 +94,8 @@ void o_attrib_deselect_invisible (GSCHEM_TOPLEVEL *w_current,
        a_iter = g_list_next (a_iter)) {
     a_current = a_iter->data;
 
-    if (a_current->selected && a_current->visibility == INVISIBLE) {
+    if (a_current->selected && a_current->visibility == INVISIBLE)
       o_selection_remove (w_current->toplevel, selection, a_current);
-      o_invalidate (w_current, a_current);
-    }
   }
 }
 
@@ -268,8 +264,6 @@ OBJECT *o_attrib_add_attrib(GSCHEM_TOPLEVEL *w_current,
 
   o_selection_add (toplevel, toplevel->page_current->selection_list, new_obj);
 
-  o_invalidate (w_current, new_obj);
-
   /* handle slot= attribute, it's a special case */
   if (o_current != NULL &&
       g_ascii_strncasecmp (text_string, "slot=", 5) == 0) {
diff --git a/gschem/src/o_misc.c b/gschem/src/o_misc.c
index 48fac8f..870137a 100644
--- a/gschem/src/o_misc.c
+++ b/gschem/src/o_misc.c
@@ -768,10 +768,9 @@ void o_update_component(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
   /* Recalculate the bounds of the object */
   o_recalc_single_object(toplevel, o_current);
 
-  /* reconnect, re-select and redraw */
+  /* reconnect and re-select */
   s_conn_update_object (toplevel, o_current);
   o_selection_add (toplevel, toplevel->page_current->selection_list, o_current);
-  o_invalidate (w_current, o_current);
 
   /* Re-flag as embedded if necessary */
   o_current->complex_embedded = is_embedded;
diff --git a/gschem/src/o_select.c b/gschem/src/o_select.c
index 9c8d05b..597c334 100644
--- a/gschem/src/o_select.c
+++ b/gschem/src/o_select.c
@@ -248,9 +248,6 @@ void o_select_object(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current,
     o_attrib_add_selected (w_current, toplevel->page_current->selection_list,
                            o_current);
   }
-
-  /* finally redraw object */
-  o_invalidate (w_current, o_current);
 }
 
 /*! \todo Finish function documentation!!!
@@ -519,8 +516,7 @@ void o_select_unselect_list(GSCHEM_TOPLEVEL *w_current, SELECTION *selection)
 
   while ( list != NULL ) {
     o_selection_unselect (w_current->toplevel, (OBJECT *)list->data);
-    o_invalidate (w_current, (OBJECT *)list->data);
-   list = g_list_next( list );
+    list = g_list_next (list);
   }
 
   geda_list_remove_all( (GedaList *)selection );
diff --git a/libgeda/src/o_selection.c b/libgeda/src/o_selection.c
index 8e8f9c9..8687211 100644
--- a/libgeda/src/o_selection.c
+++ b/libgeda/src/o_selection.c
@@ -114,7 +114,9 @@ void o_selection_select(TOPLEVEL *toplevel, OBJECT *object)
     return;
   }
 
+  o_emit_pre_change_notify (toplevel, object);
   object->selected = TRUE;
+  o_emit_change_notify (toplevel, object);
 }
 
 /*! \brief Unselects the given object.
@@ -127,6 +129,8 @@ void o_selection_select(TOPLEVEL *toplevel, OBJECT *object)
  */
 void o_selection_unselect (TOPLEVEL *toplevel, OBJECT *object)
 {
+  o_emit_pre_change_notify (toplevel, object);
   object->selected = FALSE;
+  o_emit_change_notify (toplevel, object);
 }
 

commit 47ebe0bb0145d95946d05fa1fd8d9bab7bd08175
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    Use change notifications for redraw when text is recreated
    
    Emit change notifications in the o_text_recreate() function, and
    remove o_invalidate() calls from gschem where o_text_recreate(),
    or other functions calling it are made.

diff --git a/gschem/src/g_hook.c b/gschem/src/g_hook.c
index 1b029cd..d75baf4 100644
--- a/gschem/src/g_hook.c
+++ b/gschem/src/g_hook.c
@@ -347,7 +347,6 @@ SCM g_set_attrib_text_properties(SCM attrib_smob, SCM scm_coloridx,
     object = attribute->attribute;
     if (object &&
 	object->text) {
-      o_invalidate (w_current, object);
       if (x != -1) {
 	object->text->x = x;
       }
@@ -364,9 +363,6 @@ SCM g_set_attrib_text_properties(SCM attrib_smob, SCM scm_coloridx,
 	object->text->angle = rotation;
       }
       o_text_recreate(toplevel, object);
-      if (!toplevel->DONT_REDRAW) {
-        o_invalidate (w_current, object);
-      }
     }
   }
   return SCM_BOOL_T;
diff --git a/gschem/src/o_attrib.c b/gschem/src/o_attrib.c
index 6052b6d..444e11d 100644
--- a/gschem/src/o_attrib.c
+++ b/gschem/src/o_attrib.c
@@ -140,8 +140,6 @@ void o_attrib_toggle_visibility(GSCHEM_TOPLEVEL *w_current, OBJECT *object)
 
     object->visibility = VISIBLE;
     o_text_recreate(toplevel, object);
-
-    o_invalidate (w_current, object);
   }
 
   toplevel->page_current->CHANGED = 1;
@@ -167,7 +165,6 @@ void o_attrib_toggle_show_name_value(GSCHEM_TOPLEVEL *w_current,
   o_invalidate (w_current, object);
   object->show_name_value = show_name_value;
   o_text_recreate(toplevel, object);
-  o_invalidate (w_current, object);
 
   toplevel->page_current->CHANGED = 1;
 }
diff --git a/gschem/src/o_misc.c b/gschem/src/o_misc.c
index 19fbbe8..48fac8f 100644
--- a/gschem/src/o_misc.c
+++ b/gschem/src/o_misc.c
@@ -400,20 +400,7 @@ void o_edit_show_hidden_lowlevel (GSCHEM_TOPLEVEL *w_current,
     if (o_current->type == OBJ_TEXT && o_current->visibility == INVISIBLE) {
 
       /* don't toggle the visibility flag */
-
-      if (toplevel->show_hidden_text) {
-        /* draw the text object if it hidden  */
-        o_text_recreate(toplevel, o_current);
-        o_recalc_single_object(toplevel, o_current);
-        o_invalidate (w_current, o_current);
-      } else {
-        /* object is hidden and we are now NOT drawing it, so */
-        /* get rid of the extra primitive data */
-        o_text_recreate(toplevel, o_current);
-        o_recalc_single_object(toplevel, o_current);
-        /* unfortunately, you cannot erase the old visible text here */
-        /* because o_text_draw will just return */
-      }
+      o_text_recreate (toplevel, o_current);
     }
 
     if (o_current->type == OBJ_COMPLEX || o_current->type == OBJ_PLACEHOLDER) {
@@ -472,8 +459,6 @@ void o_edit_make_visible (GSCHEM_TOPLEVEL *w_current, const GList *o_list)
         o_current->visibility = VISIBLE;
         o_text_recreate(toplevel, o_current);
 
-        o_invalidate (w_current, o_current);
-
         toplevel->page_current->CHANGED = 1;
       }
     }
@@ -655,7 +640,6 @@ void o_edit_show_specific_text (GSCHEM_TOPLEVEL *w_current,
           o_current->visibility = VISIBLE;
           o_text_recreate(toplevel, o_current);
 
-          o_invalidate (w_current, o_current);
           toplevel->page_current->CHANGED = 1;
         }
       }
diff --git a/gschem/src/o_slot.c b/gschem/src/o_slot.c
index 91774e3..dbf454a 100644
--- a/gschem/src/o_slot.c
+++ b/gschem/src/o_slot.c
@@ -113,15 +113,7 @@ void o_slot_end(GSCHEM_TOPLEVEL *w_current, OBJECT *object, const char *string)
   g_free (slot_value);
 
   if (o_slot != NULL && !o_attrib_is_inherited (o_slot)) {
-
-    o_invalidate (w_current, o_slot);
-
     o_text_set_string (toplevel, o_slot, string);
-
-    /* this doesn't deal with the selection list
-     * item */
-    o_invalidate (w_current, o_slot);
-
   } else {
     /* here you need to do the add the slot
        attribute since it doesn't exist */
@@ -135,11 +127,8 @@ void o_slot_end(GSCHEM_TOPLEVEL *w_current, OBJECT *object, const char *string)
     o_attrib_attach (toplevel, new_obj, object, FALSE);
   }
 
-  o_invalidate (w_current, object);
   s_slot_update_object (toplevel, object);
 
-  o_invalidate (w_current,object);
-
   toplevel->page_current->CHANGED = 1;
   g_free (value);
 }
diff --git a/gschem/src/o_text.c b/gschem/src/o_text.c
index 596b81b..4984641 100644
--- a/gschem/src/o_text.c
+++ b/gschem/src/o_text.c
@@ -656,7 +656,6 @@ void o_text_edit_end(GSCHEM_TOPLEVEL *w_current, char *string, int len, int text
 
     if (object) {
       if (object->type == OBJ_TEXT) {
-        o_invalidate (w_current, object);
 
         object->text->size = text_size;
         object->text->alignment = text_alignment;
@@ -675,7 +674,6 @@ void o_text_edit_end(GSCHEM_TOPLEVEL *w_current, char *string, int len, int text
 	  }
         }
         o_text_recreate(toplevel, object);
-        o_invalidate (w_current, object);
       } 
     }
     
@@ -706,16 +704,11 @@ void o_text_change(GSCHEM_TOPLEVEL *w_current, OBJECT *object, char *string,
     return;
   }
 
-  /* erase old object */
-  o_invalidate (w_current, object);
-
-  /* second change the real object */
   o_text_set_string (toplevel, object, string);
 
   object->visibility = visibility;
   object->show_name_value = show;
   o_text_recreate(toplevel, object);
-  o_invalidate (w_current, object);
 
   /* handle slot= attribute, it's a special case */
   if (object->attached_to != NULL &&
diff --git a/gschem/src/x_attribedit.c b/gschem/src/x_attribedit.c
index dd98c06..2a78dfc 100644
--- a/gschem/src/x_attribedit.c
+++ b/gschem/src/x_attribedit.c
@@ -239,7 +239,6 @@ void attrib_edit_dialog_ok(GtkWidget * w, GSCHEM_TOPLEVEL *w_current)
 	new->text->x = wx;
 	new->text->y = wy;
 	o_text_recreate(toplevel, new);
-	o_invalidate (w_current, new);
 	toplevel->page_current->CHANGED = 1;
 	o_undo_savestate(w_current, UNDO_ALL);
       }
diff --git a/gschem/src/x_autonumber.c b/gschem/src/x_autonumber.c
index b6768e8..073f916 100644
--- a/gschem/src/x_autonumber.c
+++ b/gschem/src/x_autonumber.c
@@ -572,17 +572,11 @@ void autonumber_remove_number(AUTONUMBER_TEXT * autotext, OBJECT *o_current)
   gchar *slot_str;
   gchar *str = NULL;
 
-  /* invalidate the old text */
-  o_invalidate (autotext->w_current, o_current);
-
   /* replace old text */
   str = g_strdup_printf("%s?", autotext->current_searchtext);
   o_text_set_string (autotext->w_current->toplevel, o_current, str);
   g_free (str);
 
-  /* redraw the text */
-  o_invalidate (autotext->w_current, o_current);
-
   /* remove the slot attribute if slotting is active */
   if (autotext->slotting) {
     /* get the slot attribute */
@@ -619,16 +613,11 @@ void autonumber_apply_new_text(AUTONUMBER_TEXT * autotext, OBJECT *o_current,
   o_slot_end (autotext->w_current, o_current->attached_to, str);
   g_free (str);
 
-  /* invalidate the old text */
-  o_invalidate (autotext->w_current, o_current);
-
   /* replace old text */
   str = g_strdup_printf("%s%d", autotext->current_searchtext, number);
   o_text_set_string (autotext->w_current->toplevel, o_current, str);
   g_free (str);
 
-  /* redraw the text */
-  o_invalidate (autotext->w_current, o_current);
   autotext->w_current->toplevel->page_current->CHANGED = 1;
 }
 
diff --git a/gschem/src/x_multiattrib.c b/gschem/src/x_multiattrib.c
index 3266a71..3b611de 100644
--- a/gschem/src/x_multiattrib.c
+++ b/gschem/src/x_multiattrib.c
@@ -1023,7 +1023,6 @@ static void multiattrib_callback_toggled_visible(GtkCellRendererToggle *cell_ren
   /* actually modifies the attribute */
   o_attrib->visibility = visibility;
   o_text_recreate (w_current->toplevel, o_attrib);
-  o_invalidate (w_current, o_attrib);
   o_undo_savestate (w_current, UNDO_ALL);
 
   /* request an update of display for this row */
@@ -1072,7 +1071,6 @@ static void multiattrib_callback_toggled_show_name(GtkCellRendererToggle *cell_r
   /* actually modifies the attribute */
   o_attrib->show_name_value = new_snv;
   o_text_recreate (w_current->toplevel, o_attrib);
-  o_invalidate (w_current, o_attrib);
   o_undo_savestate (w_current, UNDO_ALL);
 
   /* request an update of display for this row */
@@ -1121,7 +1119,6 @@ static void multiattrib_callback_toggled_show_value(GtkCellRendererToggle *cell_
   /* actually modifies the attribute */
   o_attrib->show_name_value = new_snv;
   o_text_recreate (w_current->toplevel, o_attrib);
-  o_invalidate (w_current, o_attrib);
   o_undo_savestate (w_current, UNDO_ALL);
   
   /* request an update of display for this row */
diff --git a/libgeda/src/o_text_basic.c b/libgeda/src/o_text_basic.c
index c1e3858..6830674 100644
--- a/libgeda/src/o_text_basic.c
+++ b/libgeda/src/o_text_basic.c
@@ -507,8 +507,10 @@ char *o_text_save(OBJECT *object)
  */
 void o_text_recreate(TOPLEVEL *toplevel, OBJECT *o_current)
 {
+  o_emit_pre_change_notify (toplevel, o_current);
   update_disp_string (o_current);
   o_current->w_bounds_valid = FALSE;
+  o_emit_change_notify (toplevel, o_current);
 }
 
 /*! \brief move a text object

commit 5c14a649bd633950624dfda4128bd83ed77ef4bc
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    Use change notifications for objects added / removed from the page
    
    Adds emission of the change and pre-change notify events for adding
    and removing objects from the page respectively.
    
    Remove explicit invalidation calls after performing these actions
    in gschem.

diff --git a/gschem/src/g_hook.c b/gschem/src/g_hook.c
index 9866eaf..1b029cd 100644
--- a/gschem/src/g_hook.c
+++ b/gschem/src/g_hook.c
@@ -716,17 +716,7 @@ SCM g_add_component(SCM page_smob, SCM scm_comp_name, SCM scm_x, SCM scm_y,
 		 scm_cons(g_make_object_smob(toplevel,
 					     new_obj), SCM_EOL));
   }
-  
-  /* 
-   * For now, do not redraw the newly added complex, since this might cause
-   * flicker if you are zoom/panning right after this function executes 
-   */
-#if 0 
-  /* Now the new component should be added to the object's list and 
-     drawn in the screen */
-  o_invalidate (toplevel, new_object);
-#endif
-  
+
   return SCM_BOOL_T;        
 }
 
diff --git a/gschem/src/o_arc.c b/gschem/src/o_arc.c
index 16c5b1a..336a910 100644
--- a/gschem/src/o_arc.c
+++ b/gschem/src/o_arc.c
@@ -211,9 +211,6 @@ void o_arc_end4(GSCHEM_TOPLEVEL *w_current, int radius,
                        radius, start_angle, end_angle);
   s_page_append (toplevel, toplevel->page_current, new_obj);
 
-  /* draw the new object */
-  o_invalidate (w_current, new_obj);
-
   w_current->first_wx  = -1;
   w_current->first_wy  = -1;
   w_current->distance = 0;
diff --git a/gschem/src/o_box.c b/gschem/src/o_box.c
index 4c7dadf..820e615 100644
--- a/gschem/src/o_box.c
+++ b/gschem/src/o_box.c
@@ -458,9 +458,6 @@ void o_box_end(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
                        box_left + box_width, box_top - box_height);
   s_page_append (toplevel, toplevel->page_current, new_obj);
 
-  /* draw it */
-  o_invalidate (w_current, new_obj);
-
 #if DEBUG
   printf("coords: %d %d %d %d\n", box_left, box_top, box_width, box_height);
 #endif
diff --git a/gschem/src/o_bus.c b/gschem/src/o_bus.c
index 7ef8141..94e0201 100644
--- a/gschem/src/o_bus.c
+++ b/gschem/src/o_bus.c
@@ -189,8 +189,6 @@ int o_bus_end(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
                       w_current->second_wx, w_current->second_wy, 0);
   s_page_append (toplevel, toplevel->page_current, new_obj);
 
-  o_invalidate (w_current, new_obj);
-
   /* connect the new bus to the other busses */
   prev_conn_objects = s_conn_return_others (prev_conn_objects, new_obj);
   o_invalidate_glist (w_current, prev_conn_objects);
diff --git a/gschem/src/o_circle.c b/gschem/src/o_circle.c
index 5590a68..9c36a95 100644
--- a/gschem/src/o_circle.c
+++ b/gschem/src/o_circle.c
@@ -441,9 +441,6 @@ void o_circle_end(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
                           w_current->distance);
   s_page_append (toplevel, toplevel->page_current, new_obj);
 
-  /* draw it */
-  o_invalidate (w_current, new_obj);
-
   toplevel->page_current->CHANGED = 1;
   o_undo_savestate(w_current, UNDO_ALL);
 }
diff --git a/gschem/src/o_delete.c b/gschem/src/o_delete.c
index d7d323a..09f1fab 100644
--- a/gschem/src/o_delete.c
+++ b/gschem/src/o_delete.c
@@ -65,7 +65,6 @@ void o_delete (GSCHEM_TOPLEVEL *w_current, OBJECT *object)
     o_invalidate_glist (w_current, prev_conn_objects);
     g_list_free (prev_conn_objects);
   }
-  o_invalidate (w_current, object);
 
   s_page_remove (toplevel, toplevel->page_current, object);
   s_delete_object (toplevel, object);
diff --git a/gschem/src/o_line.c b/gschem/src/o_line.c
index 4eb59d1..80b89f4 100644
--- a/gschem/src/o_line.c
+++ b/gschem/src/o_line.c
@@ -175,9 +175,6 @@ void o_line_end(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
                         w_current->second_wx, w_current->second_wy);
   s_page_append (toplevel, toplevel->page_current, new_obj);
 
-  /* draw it */
-  o_invalidate (w_current, new_obj);
-  
   toplevel->page_current->CHANGED=1;
   o_undo_savestate(w_current, UNDO_ALL);
 }
diff --git a/gschem/src/o_misc.c b/gschem/src/o_misc.c
index 276f168..19fbbe8 100644
--- a/gschem/src/o_misc.c
+++ b/gschem/src/o_misc.c
@@ -766,8 +766,6 @@ void o_update_component(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
       s_page_append (toplevel, toplevel->page_current, o_attrib);
       /* add the attribute to old */
       o_attrib_add (toplevel, o_current, o_attrib);
-      /* redraw the attribute object */
-      o_invalidate (w_current, o_attrib);
       /* note: this object is unselected (not added to selection). */
     }
     else
diff --git a/gschem/src/o_net.c b/gschem/src/o_net.c
index 14bd87d..fa08a54 100644
--- a/gschem/src/o_net.c
+++ b/gschem/src/o_net.c
@@ -619,8 +619,6 @@ int o_net_end(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
       s_conn_print(new_net->conn_list);
 #endif
 
-      o_invalidate (w_current, new_net);
-
       o_invalidate_glist (w_current, prev_conn_objects);
 
       g_list_free (prev_conn_objects);
@@ -661,8 +659,6 @@ int o_net_end(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
       s_conn_print(new_net->conn_list);
 #endif
 
-      o_invalidate (w_current, new_net);
-
       o_invalidate_glist (w_current, prev_conn_objects);
 
       g_list_free (prev_conn_objects);
@@ -1160,8 +1156,6 @@ int o_net_add_busrippers(GSCHEM_TOPLEVEL *w_current, OBJECT *net_obj,
           s_page_append_list (toplevel, toplevel->page_current,
                               o_complex_promote_attribs (toplevel, new_obj));
           s_page_append (toplevel, toplevel->page_current, new_obj);
-
-          o_invalidate (w_current, new_obj);
         } else {
           s_log_message(_("Bus ripper symbol [%s] was not found in any component library\n"),
                         toplevel->bus_ripper_symname);
diff --git a/gschem/src/o_picture.c b/gschem/src/o_picture.c
index d738cad..47d3a83 100644
--- a/gschem/src/o_picture.c
+++ b/gschem/src/o_picture.c
@@ -112,9 +112,6 @@ void o_picture_end(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
                           0, FALSE, FALSE);
   s_page_append (toplevel, toplevel->page_current, new_obj);
 
-  /* draw it */
-  o_invalidate (w_current, new_obj);
-
   toplevel->page_current->CHANGED = 1;
   o_undo_savestate(w_current, UNDO_ALL);
 }
diff --git a/gschem/src/o_pin.c b/gschem/src/o_pin.c
index 2229a5e..bc625e2 100644
--- a/gschem/src/o_pin.c
+++ b/gschem/src/o_pin.c
@@ -155,7 +155,6 @@ void o_pin_end(GSCHEM_TOPLEVEL *w_current, int x, int y)
   prev_conn_objects = s_conn_return_others (prev_conn_objects, new_obj);
   o_invalidate_glist (w_current, prev_conn_objects);
   g_list_free (prev_conn_objects);
-  o_invalidate (w_current, new_obj);
 
   toplevel->page_current->CHANGED=1;
   o_undo_savestate(w_current, UNDO_ALL);
diff --git a/gschem/src/x_multiattrib.c b/gschem/src/x_multiattrib.c
index 7b89ecc..3266a71 100644
--- a/gschem/src/x_multiattrib.c
+++ b/gschem/src/x_multiattrib.c
@@ -678,8 +678,6 @@ static void multiattrib_action_promote_attribute (GSCHEM_TOPLEVEL *w_current,
       s_page_append (toplevel, toplevel->page_current, o_new);
       /* add the attribute its parent */
       o_attrib_attach (toplevel, o_new, object, TRUE);
-      /* redraw the attribute object */
-      o_invalidate (w_current, o_new);
       /* note: this object is unselected (not added to selection). */
   }
   w_current->toplevel->page_current->CHANGED = 1;
diff --git a/libgeda/src/s_page.c b/libgeda/src/s_page.c
index 28e529e..d486734 100644
--- a/libgeda/src/s_page.c
+++ b/libgeda/src/s_page.c
@@ -75,12 +75,16 @@ object_added (TOPLEVEL *toplevel, PAGE *page, OBJECT *object)
 
   /* Update object connection tracking */
   s_conn_update_object (toplevel, object);
+
+  o_emit_change_notify (toplevel, object);
 }
 
 /* Called just before removing an OBJECT from a PAGE. */
 static void
 pre_object_removed (TOPLEVEL *toplevel, PAGE *page, OBJECT *object)
 {
+  o_emit_pre_change_notify (toplevel, object);
+
   /* Clear object parent pointer */
 #ifndef NDEBUG
   if (object->page == NULL) {

commit 0a93ef44cea25ec2bed559d8a05488fd3badd63c
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    libgeda: Process updates prior to removing an object from the page.
    
    Renames the private function object_removed to pre_object_removed,
    and moves its calls prior to removing the object from the page.
    
    For the existing  updates, the order doesn't matter, however other
    things we might like to do per-object when removing them from the
    page, such as emitting notifications of what we're about to do,
    must be done before the object is actually removed.

diff --git a/libgeda/src/s_page.c b/libgeda/src/s_page.c
index 0ef30d0..28e529e 100644
--- a/libgeda/src/s_page.c
+++ b/libgeda/src/s_page.c
@@ -77,9 +77,9 @@ object_added (TOPLEVEL *toplevel, PAGE *page, OBJECT *object)
   s_conn_update_object (toplevel, object);
 }
 
-/* Called just after removing an OBJECT from a PAGE. */
+/* Called just before removing an OBJECT from a PAGE. */
 static void
-object_removed (TOPLEVEL *toplevel, PAGE *page, OBJECT *object)
+pre_object_removed (TOPLEVEL *toplevel, PAGE *page, OBJECT *object)
 {
   /* Clear object parent pointer */
 #ifndef NDEBUG
@@ -597,8 +597,8 @@ void s_page_append_list (TOPLEVEL *toplevel, PAGE *page, GList *obj_list)
  */
 void s_page_remove (TOPLEVEL *toplevel, PAGE *page, OBJECT *object)
 {
+  pre_object_removed (toplevel, page, object);
   page->_object_list = g_list_remove (page->_object_list, object);
-  object_removed (toplevel, page, object);
 }
 
 /*! \brief Remove and free all OBJECTs from the PAGE
@@ -613,10 +613,10 @@ void s_page_delete_objects (TOPLEVEL *toplevel, PAGE *page)
 {
   GList *objects = page->_object_list;
   GList *iter;
-  page->_object_list = NULL;
   for (iter = objects; iter != NULL; iter = g_list_next (iter)) {
-    object_removed (toplevel, page, iter->data);
+    pre_object_removed (toplevel, page, iter->data);
   }
+  page->_object_list = NULL;
   s_delete_object_glist (toplevel, objects);
 }
 

commit ccf8b757df96f9eafb676a8ab0960c76f9692238
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    gschem: Hookup change notify functions to invalidate on-screen objects
    
    When change pre-change and change notifications are emitted on objects,
    we need to invalidate their on-screen representation.
    
    The pre-change notification is used to invalidate the area where an
    object is currently drawn, which is expected (usually) to be followed
    by a change notification - so the new object bounds are invalidated
    to be repainted.
    
    Certain operations might skip one of these events. For cases where the
    bounding box of an object is known to remain constant, the "pre-change"
    notification could potentially be omitted. Adding an object to the page
    will (obviously) only be able to generate a "change" notification, and
    removing an object will only generate a "pre-change" notification.

diff --git a/gschem/src/gschem.c b/gschem/src/gschem.c
index 216db31..b47d503 100644
--- a/gschem/src/gschem.c
+++ b/gschem/src/gschem.c
@@ -232,6 +232,11 @@ void main_prog(void *closure, int argc, char *argv[])
   o_text_set_rendered_bounds_func (w_current->toplevel,
                                    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);
+
   /* Now read in RC files. */
   g_rc_parse_gtkrc();
   g_rc_parse(w_current->toplevel, "gschemrc", rc_filename);
diff --git a/gschem/src/i_callbacks.c b/gschem/src/i_callbacks.c
index 37f8823..65898f8 100644
--- a/gschem/src/i_callbacks.c
+++ b/gschem/src/i_callbacks.c
@@ -158,6 +158,12 @@ DEFINE_I_CALLBACK(file_new_window)
 
   o_text_set_rendered_bounds_func (w_current->toplevel,
                                    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);
+
   x_window_setup (w_current);
 
   page = x_window_open_page (w_current, NULL);
diff --git a/gschem/src/x_preview.c b/gschem/src/x_preview.c
index 271b545..47bab5c 100644
--- a/gschem/src/x_preview.c
+++ b/gschem/src/x_preview.c
@@ -376,6 +376,11 @@ 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);
+
   i_vars_set (preview_w_current);
 
   /* be sure to turn off scrollbars */

commit 8b1faf85362bb30c392e2b9ebc5d8ccb800b85f2
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Commit: Peter Clifton <pcjc2@xxxxxxxxx>

    libgeda: Add mechanism to call hook function when an object changes.
    
    Introduces two new functions wihin libgeda, o_emit_pre_change_notify()
    and o_emit_change_notify(), intended to be called prior to and after
    an object being modified, respectively. This mechanism is primarily
    intended as a means for libgeda to trigger on-screen updates when
    objects are changed, and as such - at present, only a single pair of
    call-backs can be registered (per TOPLEVEL). These call-backs are
    registered via the new public function o_set_change_notify_funcs().
    
    The o_emit_pre_change_notify() function gives the GUI an opportunity to
    queue a redraw for the screen region where an object used to reside,
    prior to operations which change its bounding box, and similarly, the
    o_emit_change_notify() allows the GUI to trigger a redraw of the
    modified object.

diff --git a/libgeda/include/libgeda/prototype.h b/libgeda/include/libgeda/prototype.h
index 5d03e5b..8021199 100644
--- a/libgeda/include/libgeda/prototype.h
+++ b/libgeda/include/libgeda/prototype.h
@@ -120,6 +120,7 @@ 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);
 
 /* 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 84d996b..03e70e6 100644
--- a/libgeda/include/libgeda/struct.h
+++ b/libgeda/include/libgeda/struct.h
@@ -431,6 +431,9 @@ struct st_page {
 /*! \brief Type of callback function for calculating text bounds */
 typedef int(*RenderedBoundsFunc)(void *, OBJECT *, int *, int *, int *, int *);
 
+/*! \brief Type of callback function for object damage notification */
+typedef int(*ChangeNotifyFunc)(void *, OBJECT *);
+
 /*! \brief Type of callback function for querying loading of backups */
 typedef gboolean(*LoadBackupQueryFunc)(void *, GString *);
 
@@ -555,6 +558,11 @@ struct st_toplevel {
   RenderedBoundsFunc rendered_text_bounds_func;
   void *rendered_text_bounds_data;
 
+  /* Callback functions for object change notification */
+  ChangeNotifyFunc pre_change_notify_func;
+  ChangeNotifyFunc change_notify_func;
+  void *change_notify_data;
+
   /* Callback function for deciding whether to load a backup file. */
   LoadBackupQueryFunc load_newer_backup_func;
   void *load_newer_backup_data;
diff --git a/libgeda/include/prototype_priv.h b/libgeda/include/prototype_priv.h
index 5868842..531afa9 100644
--- a/libgeda/include/prototype_priv.h
+++ b/libgeda/include/prototype_priv.h
@@ -112,6 +112,8 @@ OBJECT *o_attrib_find_attrib_by_name(const GList *list, char *name, int count);
 void o_bounds_invalidate(TOPLEVEL *toplevel, OBJECT *object);
 double o_shortest_distance_full(OBJECT *object, int x, int y, int force_solid);
 PAGE *o_get_page_compat (TOPLEVEL *toplevel, OBJECT *object);
+void o_emit_pre_change_notify(TOPLEVEL *toplevel, OBJECT *object);
+void o_emit_change_notify(TOPLEVEL *toplevel, OBJECT *object);
 
 /* o_box_basic.c */
 OBJECT *o_box_read(TOPLEVEL *toplevel, char buf[], unsigned int release_ver, unsigned int fileformat_ver);
diff --git a/libgeda/src/o_basic.c b/libgeda/src/o_basic.c
index 146f7e5..2748a19 100644
--- a/libgeda/src/o_basic.c
+++ b/libgeda/src/o_basic.c
@@ -637,3 +637,31 @@ o_get_page_compat (TOPLEVEL *toplevel, OBJECT *object) {
     return page;
   }
 }
+
+void o_set_change_notify_funcs (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;
+}
+
+
+void o_emit_pre_change_notify (TOPLEVEL *toplevel, OBJECT *object)
+{
+  if (toplevel->pre_change_notify_func == NULL)
+    return;
+
+  toplevel->pre_change_notify_func (toplevel->change_notify_data, object);
+}
+
+
+void o_emit_change_notify (TOPLEVEL *toplevel, OBJECT *object)
+{
+  if (toplevel->change_notify_func == NULL)
+    return;
+
+  toplevel->change_notify_func (toplevel->change_notify_data, object);
+}
diff --git a/libgeda/src/s_toplevel.c b/libgeda/src/s_toplevel.c
index 0bec65b..94a3857 100644
--- a/libgeda/src/s_toplevel.c
+++ b/libgeda/src/s_toplevel.c
@@ -134,6 +134,10 @@ 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->load_newer_backup_func = NULL;
   toplevel->load_newer_backup_data = NULL;
 




_______________________________________________
geda-cvs mailing list
geda-cvs@xxxxxxxxxxxxxx
http://www.seul.org/cgi-bin/mailman/listinfo/geda-cvs