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

gEDA-cvs: gaf.git: branch: master updated (1.5.0-20080706-424-g9f65e2f)



The branch, master has been updated
       via  9f65e2f99a8c4658fab1b048d76089fc6897384d (commit)
       via  0fe820aa442bba02d164832ce771932f2189d231 (commit)
       via  883bb3377a83623fe47792aabe8023c556de25f3 (commit)
       via  b64b7ce3970d819173e20578e9adf91b19179068 (commit)
       via  0a9650f1c5877d68c792f4c37bc0d47132425c49 (commit)
       via  978a127bf1f7174fd5146371d0cbbfc6a8f2baf8 (commit)
       via  c9b89c259334c0f310afcc1dc3fb2b752078caad (commit)
       via  111e9e78fded24189f58e420b291ba444323ac25 (commit)
       via  20b87f17855b3a0cd09b1865d661de8e039ae903 (commit)
       via  4287b770933148477d613c97f7b0d60bd9236603 (commit)
       via  1deba1aba224cd2e87a34148949edaaeec630ed0 (commit)
       via  c7c5a24102474d6d9c607c4592736c8f93fe090b (commit)
       via  68f782583cc41b542dc237cb9173f64ffc01ce76 (commit)
      from  c914c30f8bbb72e5d0df635947055e642b972f0b (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/gschem_struct.h |    1 -
 gschem/include/prototype.h     |   47 ++----
 gschem/src/a_pan.c             |    2 +-
 gschem/src/a_zoom.c            |   27 +++-
 gschem/src/g_hook.c            |    6 +-
 gschem/src/gschem.c            |   10 --
 gschem/src/gschem_toplevel.c   |    1 -
 gschem/src/i_callbacks.c       |   60 ++++----
 gschem/src/o_arc.c             |   88 ++--------
 gschem/src/o_attrib.c          |   17 +-
 gschem/src/o_basic.c           |  348 +++++++++++++++++----------------------
 gschem/src/o_box.c             |   80 +++-------
 gschem/src/o_bus.c             |   67 ++++----
 gschem/src/o_circle.c          |   66 ++------
 gschem/src/o_complex.c         |    4 +-
 gschem/src/o_cue.c             |  162 -------------------
 gschem/src/o_delete.c          |   12 +-
 gschem/src/o_grips.c           |  144 ++++++-----------
 gschem/src/o_line.c            |   64 ++------
 gschem/src/o_misc.c            |   44 ++---
 gschem/src/o_move.c            |   80 +++++++---
 gschem/src/o_net.c             |  170 +++++++-------------
 gschem/src/o_path.c            |  119 +++++---------
 gschem/src/o_picture.c         |  102 ++++---------
 gschem/src/o_pin.c             |   52 +++---
 gschem/src/o_place.c           |   99 +++++++++++-
 gschem/src/o_select.c          |   31 +++-
 gschem/src/o_slot.c            |    8 +-
 gschem/src/o_text.c            |    8 +-
 gschem/src/o_undo.c            |    2 +-
 gschem/src/x_attribedit.c      |    4 +-
 gschem/src/x_autonumber.c      |   14 +-
 gschem/src/x_basic.c           |   10 +-
 gschem/src/x_compselect.c      |    2 +-
 gschem/src/x_dialog.c          |   24 ++--
 gschem/src/x_event.c           |   67 ++++-----
 gschem/src/x_grid.c            |   30 ++--
 gschem/src/x_image.c           |   11 +-
 gschem/src/x_multiattrib.c     |   12 +-
 gschem/src/x_pagesel.c         |    2 +-
 gschem/src/x_preview.c         |   37 ++---
 gschem/src/x_window.c          |   13 +--
 libgeda/include/prototype.h    |    1 +
 libgeda/include/struct.h       |    3 -
 libgeda/src/o_selection.c      |    4 -
 libgeda/src/s_basic.c          |    1 -
 libgeda/src/s_page.c           |   35 ++++-
 47 files changed, 871 insertions(+), 1320 deletions(-)


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

commit 0fe820aa442bba02d164832ce771932f2189d231
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Date:   Sat Dec 20 08:25:12 2008 +0000

    gschem: Make rubberbanding operations use the invalidate / expose model
    
    Introduce a new function for each rubberbanding operation,
    o_*_invaldate_rubber() which invalidates an on-screen area matching
    the area where the rubberbanding operation would paint.
    
    The actual drawing happens from the expose handler, which already
    had appropriate code to ensure any damaged rubberband objects were
    re-painted during an expose event.

:100644 100644 cf61370... 324693e... M	gschem/include/gschem_struct.h
:100644 100644 04ff977... 7c455be... M	gschem/include/prototype.h
:100644 100644 52ccb0b... 708b37d... M	gschem/src/a_zoom.c
:100644 100644 d504bb2... 92aae37... M	gschem/src/gschem_toplevel.c
:100644 100644 4af1852... 5c9dda3... M	gschem/src/i_callbacks.c
:100644 100644 2c25ca5... 51b7926... M	gschem/src/o_arc.c
:100644 100644 f05c436... 30c4abd... M	gschem/src/o_basic.c
:100644 100644 e48d473... fc02172... M	gschem/src/o_box.c
:100644 100644 b0f58ed... d5234ee... M	gschem/src/o_bus.c
:100644 100644 e743844... 56eb8ed... M	gschem/src/o_circle.c
:100644 100644 bac236a... e65ca0b... M	gschem/src/o_grips.c
:100644 100644 01eb452... 2bf01c6... M	gschem/src/o_line.c
:100644 100644 0582844... 558aafa... M	gschem/src/o_move.c
:100644 100644 ea918db... d1a7bd5... M	gschem/src/o_net.c
:100644 100644 a828e92... fee9ff1... M	gschem/src/o_path.c
:100644 100644 86c8ee5... 2511bfa... M	gschem/src/o_picture.c
:100644 100644 2be22da... 2479ffe... M	gschem/src/o_pin.c
:100644 100644 318de9f... 83db526... M	gschem/src/o_place.c
:100644 100644 4372fb0... b913a41... M	gschem/src/o_select.c
:100644 100644 bbbbc88... 0b4d1fc... M	gschem/src/x_compselect.c
:100644 100644 2fb864c... 6132165... M	gschem/src/x_event.c

commit 883bb3377a83623fe47792aabe8023c556de25f3
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Date:   Sat Dec 20 08:25:10 2008 +0000

    gschem: Remove the dummy o_cue_invalidate*() functions
    
    Actually invalidate the objects which would have had their cues
    redrawn using o_invalidate() and o_invalidate_glist() instead.
    
    We're probably invalidating more than we need to in some cases,
    since just invalidating a single object will be enough to update
    any cues it is touching. We don't really need to invalidate its
    connected objects as well.

:100644 100644 d609a23... 04ff977... M	gschem/include/prototype.h
:100644 100644 22a5b73... b0f58ed... M	gschem/src/o_bus.c
:100644 100644 8203700... 1cbed30... M	gschem/src/o_cue.c
:100644 100644 1f63c10... 9766a2b... M	gschem/src/o_delete.c
:100644 100644 d5f7420... bac236a... M	gschem/src/o_grips.c
:100644 100644 d5f308e... 3444600... M	gschem/src/o_misc.c
:100644 100644 bbee4bd... 0582844... M	gschem/src/o_move.c
:100644 100644 e2cd89b... ea918db... M	gschem/src/o_net.c
:100644 100644 07386c4... 2be22da... M	gschem/src/o_pin.c
:100644 100644 002213f... 318de9f... M	gschem/src/o_place.c

commit b64b7ce3970d819173e20578e9adf91b19179068
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Date:   Sat Dec 20 08:25:09 2008 +0000

    gschem: Replace o_cue_erase_single() by o_cue_invalidate()
    
    We don't want to be drawing anything onto the screen outside of the
    expose handler. o_cue_invalidate() is actually a NOP, since we actually
    invalidate enough around a given object to encompass redrawing of its
    cues.

:100644 100644 a28d728... d609a23... M	gschem/include/prototype.h
:100644 100644 3a5bb57... 22a5b73... M	gschem/src/o_bus.c
:100644 100644 0d65a8e... 8203700... M	gschem/src/o_cue.c
:100644 100644 8ad40a7... 1f63c10... M	gschem/src/o_delete.c
:100644 100644 5f27339... d5f7420... M	gschem/src/o_grips.c
:100644 100644 0c6112b... d5f308e... M	gschem/src/o_misc.c
:100644 100644 b3a4d8e... bbee4bd... M	gschem/src/o_move.c
:100644 100644 2ebd3e8... e2cd89b... M	gschem/src/o_net.c
:100644 100644 3fa3b97... 07386c4... M	gschem/src/o_pin.c
:100644 100644 83a6b9c... 002213f... M	gschem/src/o_place.c

commit 0a9650f1c5877d68c792f4c37bc0d47132425c49
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Date:   Sat Dec 20 08:25:07 2008 +0000

    gschem: Move invalidate call from o_move_check_endpoint to o_move_start
    
    This invalidate ensure rubberbanded objects are removed from their old
    position on screen. It is more suited to living in o_move_start() than
    a function supposed to find objects to rubberband.

:100644 100644 af0f18e... b3a4d8e... M	gschem/src/o_move.c

commit 978a127bf1f7174fd5146371d0cbbfc6a8f2baf8
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Date:   Sat Dec 20 08:25:06 2008 +0000

    Avoid and remove OBJECT variable draw_grips
    
    We can infer the required logic from OBJECT->selected, and the
    resulting code is cleaner.

:100644 100644 fd569eb... 2c25ca5... M	gschem/src/o_arc.c
:100644 100644 d08da82... e48d473... M	gschem/src/o_box.c
:100644 100644 57715be... 3a5bb57... M	gschem/src/o_bus.c
:100644 100644 7ad823e... e743844... M	gschem/src/o_circle.c
:100644 100644 3e55c13... 01eb452... M	gschem/src/o_line.c
:100644 100644 7685791... 2ebd3e8... M	gschem/src/o_net.c
:100644 100644 a7ecef2... a828e92... M	gschem/src/o_path.c
:100644 100644 ae8097f... 86c8ee5... M	gschem/src/o_picture.c
:100644 100644 75b0a1e... 3fa3b97... M	gschem/src/o_pin.c
:100644 100644 5683897... e686716... M	libgeda/include/struct.h
:100644 100644 616353f... aa7762f... M	libgeda/src/o_selection.c
:100644 100644 34ac573... ec5118a... M	libgeda/src/s_basic.c

commit c9b89c259334c0f310afcc1dc3fb2b752078caad
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Date:   Sat Dec 20 08:25:04 2008 +0000

    Don't ever erase grips, we invalidate things to get rid of them.
    
    Delete now unused function o_erase_grips(), along with the object
    specific routines o_*_erase_grips()

:100644 100644 4305db4... a28d728... M	gschem/include/prototype.h
:100644 100644 eebdb87... fd569eb... M	gschem/src/o_arc.c
:100644 100644 2793f13... f05c436... M	gschem/src/o_basic.c
:100644 100644 c7264cf... d08da82... M	gschem/src/o_box.c
:100644 100644 c1b63f0... 57715be... M	gschem/src/o_bus.c
:100644 100644 b886adf... 7ad823e... M	gschem/src/o_circle.c
:100644 100644 a91a529... 5f27339... M	gschem/src/o_grips.c
:100644 100644 de25fb0... 3e55c13... M	gschem/src/o_line.c
:100644 100644 7b77537... 7685791... M	gschem/src/o_net.c
:100644 100644 13176b0... a7ecef2... M	gschem/src/o_path.c
:100644 100644 0498378... ae8097f... M	gschem/src/o_picture.c
:100644 100644 2285668... 75b0a1e... M	gschem/src/o_pin.c

commit 111e9e78fded24189f58e420b291ba444323ac25
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Date:   Sat Dec 20 08:25:03 2008 +0000

    Remove now unused functions o_{draw,erase}_list() and o_erase_single()

:100644 100644 1ee1486... 4305db4... M	gschem/include/prototype.h
:100644 100644 31e25be... 2793f13... M	gschem/src/o_basic.c

commit 20b87f17855b3a0cd09b1865d661de8e039ae903
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Date:   Sat Dec 20 08:25:01 2008 +0000

    Changed caller of o_{erase,draw}_selected() to use o_invalidate_glist()
    
    Remove the now unused functions o_{erase,draw}_selected().

:100644 100644 d3f8a54... 1ee1486... M	gschem/include/prototype.h
:100644 100644 681c9d7... 31e25be... M	gschem/src/o_basic.c
:100644 100644 220b1a8... af0f18e... M	gschem/src/o_move.c

commit 4287b770933148477d613c97f7b0d60bd9236603
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Date:   Sat Dec 20 08:11:03 2008 +0000

    gschem: Change redraw and erase calls to invalidate calls
    
    In the new drawing model, "invalidate" calls actually specify which
    primitives or areas of the screen need redrawing. The redraw code called
    from the expose event handler then draws objects directly onto the screen.
    
    Remove the now unused function o_redraw_all()

:100644 100644 ec6ec35... d3f8a54... M	gschem/include/prototype.h
:100644 100644 85d2f9a... e6fbd6d... M	gschem/src/a_pan.c
:100644 100644 6a5c2dc... 5c37e69... M	gschem/src/g_hook.c
:100644 100644 b2a5a9f... 4af1852... M	gschem/src/i_callbacks.c
:100644 100644 779670a... eebdb87... M	gschem/src/o_arc.c
:100644 100644 17c20cc... c0ddf17... M	gschem/src/o_attrib.c
:100644 100644 17b94f6... 681c9d7... M	gschem/src/o_basic.c
:100644 100644 de5e259... c7264cf... M	gschem/src/o_box.c
:100644 100644 ba31e96... c1b63f0... M	gschem/src/o_bus.c
:100644 100644 8e32325... b886adf... M	gschem/src/o_circle.c
:100644 100644 837270b... 11e897d... M	gschem/src/o_complex.c
:100644 100644 a88055d... 0d65a8e... M	gschem/src/o_cue.c
:100644 100644 7f6220f... 8ad40a7... M	gschem/src/o_delete.c
:100644 100644 84fddd5... a91a529... M	gschem/src/o_grips.c
:100644 100644 9ff9b85... de25fb0... M	gschem/src/o_line.c
:100644 100644 cf5e873... 0c6112b... M	gschem/src/o_misc.c
:100644 100644 8da5c36... 220b1a8... M	gschem/src/o_move.c
:100644 100644 f39ce10... 7b77537... M	gschem/src/o_net.c
:100644 100644 88488df... 0498378... M	gschem/src/o_picture.c
:100644 100644 e24b852... 2285668... M	gschem/src/o_pin.c
:100644 100644 174ff51... 83a6b9c... M	gschem/src/o_place.c
:100644 100644 35d3d1b... 4372fb0... M	gschem/src/o_select.c
:100644 100644 16825fa... 4b10ea9... M	gschem/src/o_slot.c
:100644 100644 7759c6a... 6077308... M	gschem/src/o_text.c
:100644 100644 b86fc67... d092272... M	gschem/src/o_undo.c
:100644 100644 b771f2f... 83263a5... M	gschem/src/x_attribedit.c
:100644 100644 48fa497... c1b2ffd... M	gschem/src/x_autonumber.c
:100644 100644 8923505... ce09b88... M	gschem/src/x_dialog.c
:100644 100644 bd5927a... 2fb864c... M	gschem/src/x_event.c
:100644 100644 e274ff4... b2a7b9c... M	gschem/src/x_image.c
:100644 100644 6d40610... d01e29a... M	gschem/src/x_multiattrib.c
:100644 100644 372a386... 8e4e9dc... M	gschem/src/x_pagesel.c
:100644 100644 92fb8e0... 5b8e48a... M	gschem/src/x_preview.c
:100644 100644 5d198b4... 249cdec... M	gschem/src/x_window.c

commit 1deba1aba224cd2e87a34148949edaaeec630ed0
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Date:   Sat Dec 20 08:10:47 2008 +0000

    gschem: Change object specific redraw calls to o_redraw_single()
    
    Makes switching redraw calls to invalidate calls more formulic.

:100644 100644 af4288c... 6a5c2dc... M	gschem/src/g_hook.c
:100644 100644 ded6913... 17c20cc... M	gschem/src/o_attrib.c
:100644 100644 569cf9c... ba31e96... M	gschem/src/o_bus.c
:100644 100644 fe8f07c... 84fddd5... M	gschem/src/o_grips.c
:100644 100644 cdf2231... cf5e873... M	gschem/src/o_misc.c
:100644 100644 4589eda... f39ce10... M	gschem/src/o_net.c
:100644 100644 b3e02ca... 88488df... M	gschem/src/o_picture.c
:100644 100644 529072b... e24b852... M	gschem/src/o_pin.c
:100644 100644 e2dcff8... 7759c6a... M	gschem/src/o_text.c
:100644 100644 67eff1f... b771f2f... M	gschem/src/x_attribedit.c
:100644 100644 81a56ce... 48fa497... M	gschem/src/x_autonumber.c
:100644 100644 8daff33... 6d40610... M	gschem/src/x_multiattrib.c

commit c7c5a24102474d6d9c607c4592736c8f93fe090b
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Date:   Sat Dec 20 08:10:43 2008 +0000

    gschem: Add size of grip (or cue) to invalidate and redraw regions.
    
    Adding to the invalidated region cures screen artifacts left due
    to the bounds of an object not including the area occupied by its
    rubberbanding grips.
    
    Adding to the coordinates used with s_page_objects_in_region() ensures
    that grips / cues from adjacent objects are drawn correctly when repainting
    a damaged region from the expose handler.
    
    This is a bit of a hack and could be better catered for by invalidating
    the grip regions separately from an object specific invalidate function.
    s_page_objects_in_region() would also have to return objects with grips
    or cues touching the passed region.

:100644 100644 77253a2... 17b94f6... M	gschem/src/o_basic.c

commit 68f782583cc41b542dc237cb9173f64ffc01ce76
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Date:   Sat Dec 20 08:09:57 2008 +0000

    gschem: Just redraw everything when we get an expose event
    
    Disable generation of our backing pixmap and remove o_invalidate_rect()
    calls from various drawing functions. The backingstore is straight to the
    screen, so there is no need to make that call (it causes a redraw loop).

:100644 100644 bf28467... ec6ec35... M	gschem/include/prototype.h
:100644 100644 1125ed2... 52ccb0b... M	gschem/src/a_zoom.c
:100644 100644 9b3384a... e7b3a6a... M	gschem/src/gschem.c
:100644 100644 890b8f9... 779670a... M	gschem/src/o_arc.c
:100644 100644 b78a18f... 77253a2... M	gschem/src/o_basic.c
:100644 100644 949cec4... de5e259... M	gschem/src/o_box.c
:100644 100644 dae8067... 569cf9c... M	gschem/src/o_bus.c
:100644 100644 31a5ff5... 8e32325... M	gschem/src/o_circle.c
:100644 100644 891265a... a88055d... M	gschem/src/o_cue.c
:100644 100644 ffc4026... fe8f07c... M	gschem/src/o_grips.c
:100644 100644 21f386e... 9ff9b85... M	gschem/src/o_line.c
:100644 100644 c9fd2fd... 4589eda... M	gschem/src/o_net.c
:100644 100644 f1421e7... 13176b0... M	gschem/src/o_path.c
:100644 100644 3deb8ac... b3e02ca... M	gschem/src/o_picture.c
:100644 100644 9a08100... 529072b... M	gschem/src/o_pin.c
:100644 100644 a5a677f... 35d3d1b... M	gschem/src/o_select.c
:100644 100644 1ede713... 90436ac... M	gschem/src/x_basic.c
:100644 100644 d3662fd... bd5927a... M	gschem/src/x_event.c
:100644 100644 2fd441c... e5e9c2d... M	gschem/src/x_grid.c
:100644 100644 2218293... 92fb8e0... M	gschem/src/x_preview.c
:100644 100644 47e2e81... 5d198b4... M	gschem/src/x_window.c
:100644 100644 f6d4249... 76ed88b... M	libgeda/include/prototype.h
:100644 100644 98cedf1... 70305e3... M	libgeda/src/s_page.c

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

commit 0fe820aa442bba02d164832ce771932f2189d231
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Date:   Sat Dec 20 08:25:12 2008 +0000

    gschem: Make rubberbanding operations use the invalidate / expose model
    
    Introduce a new function for each rubberbanding operation,
    o_*_invaldate_rubber() which invalidates an on-screen area matching
    the area where the rubberbanding operation would paint.
    
    The actual drawing happens from the expose handler, which already
    had appropriate code to ensure any damaged rubberband objects were
    re-painted during an expose event.

diff --git a/gschem/include/gschem_struct.h b/gschem/include/gschem_struct.h
index cf61370..324693e 100644
--- a/gschem/include/gschem_struct.h
+++ b/gschem/include/gschem_struct.h
@@ -98,7 +98,6 @@ struct st_gschem_toplevel {
   int inside_action;                    /* Are we doing an action? */
   int rubber_visible;                   /* Are there any rubber lines on
 					   the screen? */
-  int magnetic_visible;                 /* Is the magnetic marker visible */
   int net_direction;                    /* bit field to guess the best net direction */
   int which_grip;                       /* Which grip is being manipulated.
                                            Its range of values depends on the
diff --git a/gschem/include/prototype.h b/gschem/include/prototype.h
index 04ff977..7c455be 100644
--- a/gschem/include/prototype.h
+++ b/gschem/include/prototype.h
@@ -14,6 +14,7 @@ void a_zoom_box(GSCHEM_TOPLEVEL *w_current, int pan_flags);
 void a_zoom_box_start(GSCHEM_TOPLEVEL *w_current, int x, int y);
 void a_zoom_box_end(GSCHEM_TOPLEVEL *w_current, int x, int y);
 void a_zoom_box_motion(GSCHEM_TOPLEVEL *w_current, int x, int y);
+void a_zoom_box_invalidate_rubber(GSCHEM_TOPLEVEL *w_current);
 void a_zoom_box_rubberband_xor(GSCHEM_TOPLEVEL *w_current);
 void correct_aspect(GSCHEM_TOPLEVEL *w_current);
 /* g_funcs.c */
@@ -465,7 +466,7 @@ void o_arc_draw_dotted(GdkWindow *w, GdkGC *gc, GdkColor *color, GdkCapStyle cap
 void o_arc_draw_dashed(GdkWindow *w, GdkGC *gc, GdkColor *color, GdkCapStyle cap, gint x, gint y, gint radius, gint angle1, gint angle2, gint arc_width, gint length, gint space);
 void o_arc_draw_center(GdkWindow *w, GdkGC *gc, GdkColor *color, GdkCapStyle cap, gint x, gint y, gint radius, gint angle1, gint angle2, gint arc_width, gint length, gint space);
 void o_arc_draw_phantom(GdkWindow *w, GdkGC *gc, GdkColor *color, GdkCapStyle cap, gint x, gint y, gint radius, gint angle1, gint angle2, gint arc_width, gint length, gint space);
-void o_arc_eraserubber(GSCHEM_TOPLEVEL *w_current);
+void o_arc_invalidate_rubber(GSCHEM_TOPLEVEL *w_current);
 void o_arc_draw_xor(GSCHEM_TOPLEVEL *w_current, int dx, int dy, OBJECT *o_current);
 void o_arc_start(GSCHEM_TOPLEVEL *w_current, int x, int y);
 void o_arc_end1(GSCHEM_TOPLEVEL *w_current, int x, int y);
@@ -482,7 +483,7 @@ OBJECT *o_attrib_add_attrib(GSCHEM_TOPLEVEL *w_current, const char *text_string,
 void o_redraw_rects(GSCHEM_TOPLEVEL *w_current, GdkRectangle *rectangles, int n_rectangles);
 void o_redraw(GSCHEM_TOPLEVEL *w_current, GList *object_list, gboolean draw_selected);
 void o_redraw_single(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current);
-int o_erase_rubber(GSCHEM_TOPLEVEL *w_current);
+int o_invalidate_rubber(GSCHEM_TOPLEVEL *w_current);
 int o_redraw_cleanstates(GSCHEM_TOPLEVEL *w_current);
 void o_draw_xor(GSCHEM_TOPLEVEL *w_current, int dx, int dy, OBJECT *object);
 void o_glist_draw_xor(GSCHEM_TOPLEVEL *w_current, int dx, int dy, GList *list);
@@ -501,7 +502,7 @@ void o_box_fill_hollow(GdkDrawable *w, GdkGC *gc, GdkColor *color, GSCHEM_TOPLEV
 void o_box_fill_fill(GdkDrawable *w, GdkGC *gc, GdkColor *color, GSCHEM_TOPLEVEL *w_current, BOX *box, gint fill_width, gint angle1, gint pitch1, gint angle2, gint pitch2);
 void o_box_fill_hatch(GdkDrawable *w, GdkGC *gc, GdkColor *color, GSCHEM_TOPLEVEL *w_current, BOX *box, gint fill_width, gint angle1, gint pitch1, gint angle2, gint pitch2);
 void o_box_fill_mesh(GdkDrawable *w, GdkGC *gc, GdkColor *color, GSCHEM_TOPLEVEL *w_current, BOX *box, gint fill_width, gint angle1, gint pitch1, gint angle2, gint pitch2);
-void o_box_eraserubber(GSCHEM_TOPLEVEL *w_current);
+void o_box_invalidate_rubber(GSCHEM_TOPLEVEL *w_current);
 void o_box_draw_xor(GSCHEM_TOPLEVEL *w_current, int dx, int dy, OBJECT *o_current);
 void o_box_start(GSCHEM_TOPLEVEL *w_current, int x, int y);
 void o_box_end(GSCHEM_TOPLEVEL *w_current, int x, int y);
@@ -522,14 +523,14 @@ void o_bus_start(GSCHEM_TOPLEVEL *w_current, int x, int y);
 int o_bus_end(GSCHEM_TOPLEVEL *w_current, int x, int y);
 void o_bus_motion(GSCHEM_TOPLEVEL *w_current, int x, int y);
 void o_bus_rubberbus_xor(GSCHEM_TOPLEVEL *w_current);
-void o_bus_eraserubber(GSCHEM_TOPLEVEL *w_current);
+void o_bus_invalidate_rubber(GSCHEM_TOPLEVEL *w_current);
 /* o_circle.c */
 void o_circle_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current);
 void o_circle_fill_hollow(GdkDrawable *w, GdkGC *gc, GdkColor *color, GSCHEM_TOPLEVEL *w_current, CIRCLE *circle, gint fill_width, gint angle1, gint pitch1, gint angle2, gint pitch2);
 void o_circle_fill_fill(GdkDrawable *w, GdkGC *gc, GdkColor *color, GSCHEM_TOPLEVEL *w_current, CIRCLE *circle, gint fill_width, gint angle1, gint pitch1, gint angle2, gint pitch2);
 void o_circle_fill_hatch(GdkDrawable *w, GdkGC *gc, GdkColor *color, GSCHEM_TOPLEVEL *w_current, CIRCLE *circle, gint fill_width, gint angle1, gint pitch1, gint angle2, gint pitch2);
 void o_circle_fill_mesh(GdkDrawable *w, GdkGC *gc, GdkColor *color, GSCHEM_TOPLEVEL *w_current, CIRCLE *circle, gint fill_width, gint angle1, gint pitch1, gint angle2, gint pitch2);
-void o_circle_eraserubber(GSCHEM_TOPLEVEL *w_current);
+void o_circle_invalidate_rubber(GSCHEM_TOPLEVEL *w_current);
 void o_circle_draw_xor(GSCHEM_TOPLEVEL *w_current, int dx, int dy, OBJECT *o_current);
 void o_circle_start(GSCHEM_TOPLEVEL *w_current, int x, int y);
 void o_circle_end(GSCHEM_TOPLEVEL *w_current, int x, int y);
@@ -596,7 +597,7 @@ void o_line_draw_dotted(GdkWindow *w, GdkGC *gc, GdkColor *color, GdkCapStyle ca
 void o_line_draw_dashed(GdkWindow *w, GdkGC *gc, GdkColor *color, GdkCapStyle cap, gint x1, gint y1, gint x2, gint y2, gint line_width, gint length, gint space);
 void o_line_draw_center(GdkWindow *w, GdkGC *gc, GdkColor *color, GdkCapStyle cap, gint x1, gint y1, gint x2, gint y2, gint line_width, gint length, gint space);
 void o_line_draw_phantom(GdkWindow *w, GdkGC *gc, GdkColor *color, GdkCapStyle cap, gint x1, gint y1, gint x2, gint y2, gint line_width, gint length, gint space);
-void o_line_eraserubber(GSCHEM_TOPLEVEL *w_current);
+void o_line_invalidate_rubber(GSCHEM_TOPLEVEL *w_current);
 void o_line_draw_xor(GSCHEM_TOPLEVEL *w_current, int dx, int dy, OBJECT *o_current);
 void o_line_start(GSCHEM_TOPLEVEL *w_current, int x, int y);
 void o_line_end(GSCHEM_TOPLEVEL *w_current, int x, int y);
@@ -623,6 +624,7 @@ void o_move_end_lowlevel(GSCHEM_TOPLEVEL *w_current, OBJECT *object, int diff_x,
 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);
+void o_move_invalidate_rubber(GSCHEM_TOPLEVEL *w_current, int drawing);
 void o_move_rubbermove_xor(GSCHEM_TOPLEVEL *w_current, int drawing);
 int o_move_return_whichone(OBJECT *object, int x, int y);
 void o_move_check_endpoint(GSCHEM_TOPLEVEL *w_current, OBJECT *object);
@@ -643,14 +645,14 @@ void o_net_start(GSCHEM_TOPLEVEL *w_current, int x, int y);
 int o_net_end(GSCHEM_TOPLEVEL *w_current, int x, int y);
 void o_net_motion(GSCHEM_TOPLEVEL *w_current, int x, int y);
 void o_net_drawrubber(GSCHEM_TOPLEVEL *w_current);
-void o_net_eraserubber(GSCHEM_TOPLEVEL *w_current);
+void o_net_invalidate_rubber(GSCHEM_TOPLEVEL *w_current);
 int o_net_add_busrippers(GSCHEM_TOPLEVEL *w_current, OBJECT *net_obj, GList *other_objects);
 /* o_picture.c */
 void o_picture_start(GSCHEM_TOPLEVEL *w_current, int x, int y);
 void o_picture_end(GSCHEM_TOPLEVEL *w_current, int x, int y);
 void o_picture_motion(GSCHEM_TOPLEVEL *w_current, int x, int y);
 void picture_selection_dialog (GSCHEM_TOPLEVEL *w_current);
-void o_picture_eraserubber(GSCHEM_TOPLEVEL *w_current);
+void o_picture_invalidate_rubber(GSCHEM_TOPLEVEL *w_current);
 void o_picture_rubberbox_xor(GSCHEM_TOPLEVEL *w_current);
 void o_picture_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current);
 void o_picture_draw_grips(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current);
@@ -661,7 +663,7 @@ void o_picture_set_pixbuf(GSCHEM_TOPLEVEL *w_current, GdkPixbuf *pixbuf, char *f
 
 /* o_path.c */
 void o_path_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current);
-void o_path_eraserubber(GSCHEM_TOPLEVEL *w_current);
+void o_path_invalidate_rubber(GSCHEM_TOPLEVEL *w_current);
 void o_path_draw_xor(GSCHEM_TOPLEVEL *w_current, int dx, int dy, OBJECT *o_current);
 void o_path_start(GSCHEM_TOPLEVEL *w_current, int x, int y);
 void o_path_end(GSCHEM_TOPLEVEL *w_current, int x, int y);
@@ -676,11 +678,12 @@ void o_pin_start(GSCHEM_TOPLEVEL *w_current, int x, int y);
 void o_pin_end(GSCHEM_TOPLEVEL *w_current, int x, int y);
 void o_pin_motion(GSCHEM_TOPLEVEL *w_current, int x, int y);
 void o_pin_rubberpin_xor(GSCHEM_TOPLEVEL *w_current);
-void o_pin_eraserubber(GSCHEM_TOPLEVEL *w_current);
+void o_pin_invalidate_rubber(GSCHEM_TOPLEVEL *w_current);
 /* o_place.c */
 void o_place_start(GSCHEM_TOPLEVEL *w_current, int x, int y);
 void o_place_end(GSCHEM_TOPLEVEL *w_current, int x, int y, int continue_placing, GList **ret_new_objects);
 void o_place_motion(GSCHEM_TOPLEVEL *w_current, int x, int y);
+void o_place_invalidate_rubber(GSCHEM_TOPLEVEL *w_current, int drawing);
 void o_place_rubberplace_xor(GSCHEM_TOPLEVEL *w_current, int drawing);
 void o_place_rotate(GSCHEM_TOPLEVEL *w_current);
 /* o_select.c */
@@ -689,6 +692,7 @@ void o_select_object(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int type, in
 int o_select_box_start(GSCHEM_TOPLEVEL *w_current, int x, int y);
 void o_select_box_end(GSCHEM_TOPLEVEL *w_current, int x, int y);
 void o_select_box_motion(GSCHEM_TOPLEVEL *w_current, int x, int y);
+void o_select_box_invalidate_rubber(GSCHEM_TOPLEVEL *w_current);
 void o_select_box_rubberband_xor(GSCHEM_TOPLEVEL *w_current);
 void o_select_box_search(GSCHEM_TOPLEVEL *w_current);
 void o_select_connected_nets(GSCHEM_TOPLEVEL *w_current, OBJECT* o_current);
diff --git a/gschem/src/a_zoom.c b/gschem/src/a_zoom.c
index 52ccb0b..708b37d 100644
--- a/gschem/src/a_zoom.c
+++ b/gschem/src/a_zoom.c
@@ -246,7 +246,7 @@ void a_zoom_box_end(GSCHEM_TOPLEVEL *w_current, int x, int y)
 {
   g_assert( w_current->inside_action != 0 );
 
-  a_zoom_box_rubberband_xor(w_current);
+  a_zoom_box_invalidate_rubber (w_current);
   w_current->rubber_visible = 0;
 
   a_zoom_box(w_current, 0);
@@ -266,15 +266,32 @@ void a_zoom_box_motion (GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
   g_assert( w_current->inside_action != 0 );
 
   if (w_current->rubber_visible)
-    a_zoom_box_rubberband_xor(w_current);
+    a_zoom_box_invalidate_rubber (w_current);
 
   w_current->second_wx = w_x;
   w_current->second_wy = w_y;
 
-  a_zoom_box_rubberband_xor(w_current);
+  a_zoom_box_invalidate_rubber (w_current);
   w_current->rubber_visible = 1;
 }
 
+/*! \todo Finish function documentation!!!
+ *  \brief
+ *  \par Function Description
+ */
+void a_zoom_box_invalidate_rubber (GSCHEM_TOPLEVEL *w_current)
+{
+  TOPLEVEL *toplevel = w_current->toplevel;
+  int x1, y1, x2, y2;
+
+  WORLDtoSCREEN(toplevel, w_current->first_wx, w_current->first_wy, &x1, &y1);
+  WORLDtoSCREEN(toplevel, w_current->second_wx, w_current->second_wy, &x2, &y2);
+
+  o_invalidate_rect (w_current, x1, y1, x2, y1);
+  o_invalidate_rect (w_current, x1, y1, x1, y2);
+  o_invalidate_rect (w_current, x2, y1, x2, y2);
+  o_invalidate_rect (w_current, x1, y2, x2, y2);
+}
 
 /*! \todo Finish function documentation!!!
  *  \brief
diff --git a/gschem/src/gschem_toplevel.c b/gschem/src/gschem_toplevel.c
index d504bb2..92aae37 100644
--- a/gschem/src/gschem_toplevel.c
+++ b/gschem/src/gschem_toplevel.c
@@ -117,7 +117,6 @@ GSCHEM_TOPLEVEL *gschem_toplevel_new ()
   w_current->magnetic_wy = -1;
   w_current->inside_action = 0;
   w_current->rubber_visible = 0;
-  w_current->magnetic_visible = 0;
   w_current->net_direction = 0;
   w_current->which_grip = -1;
   w_current->which_object = NULL;
diff --git a/gschem/src/i_callbacks.c b/gschem/src/i_callbacks.c
index 4af1852..5c9dda3 100644
--- a/gschem/src/i_callbacks.c
+++ b/gschem/src/i_callbacks.c
@@ -511,7 +511,7 @@ void i_callback_toolbar_edit_select(GtkWidget* widget, gpointer data)
   if (!w_current->window) return;
 
   if (GTK_TOGGLE_BUTTON (widget)->active) {
-    if (!o_erase_rubber(w_current)) {
+    if (!o_invalidate_rubber (w_current)) {
       i_callback_cancel(w_current, 0, NULL);
     }
     i_callback_edit_select(data, 0, NULL);
@@ -2299,7 +2299,7 @@ DEFINE_I_CALLBACK(add_net)
   exit_if_null(w_current);
 
   o_redraw_cleanstates(w_current);	
-  o_erase_rubber(w_current);
+  o_invalidate_rubber (w_current);
   o_net_reset(w_current);
 
   /* need to click */
@@ -2326,7 +2326,7 @@ DEFINE_I_CALLBACK(add_net_hotkey)
     return;
 
   o_redraw_cleanstates(w_current);	
-  o_erase_rubber(w_current);
+  o_invalidate_rubber (w_current);
   o_net_reset(w_current);
 
   /* need to click */
@@ -2371,7 +2371,7 @@ DEFINE_I_CALLBACK(add_bus)
   exit_if_null(w_current);
 
   o_redraw_cleanstates(w_current);	
-  o_erase_rubber(w_current);
+  o_invalidate_rubber (w_current);
 
   /* need to click */
   i_update_middle_button(w_current, i_callback_add_bus, _("Bus"));
@@ -2398,7 +2398,7 @@ DEFINE_I_CALLBACK(add_bus_hotkey)
     return;
 
   o_redraw_cleanstates(w_current);	
-  o_erase_rubber(w_current);
+  o_invalidate_rubber (w_current);
 
   /* need to click */
   i_update_middle_button(w_current, i_callback_add_bus_hotkey, _("Bus"));
@@ -2442,7 +2442,7 @@ DEFINE_I_CALLBACK(add_text)
   exit_if_null(w_current);
   
   o_redraw_cleanstates(w_current);	
-  o_erase_rubber(w_current);
+  o_invalidate_rubber (w_current);
 
   w_current->inside_action = 0;
   i_set_state(w_current, SELECT);
@@ -2480,7 +2480,7 @@ DEFINE_I_CALLBACK(add_line)
   exit_if_null(w_current);
 
   o_redraw_cleanstates(w_current);	
-  o_erase_rubber(w_current);
+  o_invalidate_rubber (w_current);
 
   i_update_middle_button(w_current, i_callback_add_line, _("Line"));
   i_set_state(w_current, DRAWLINE);
@@ -2503,7 +2503,7 @@ DEFINE_I_CALLBACK(add_line_hotkey)
     return;
 
   o_redraw_cleanstates(w_current);	
-  o_erase_rubber(w_current);
+  o_invalidate_rubber (w_current);
 
   i_update_middle_button(w_current, i_callback_add_line_hotkey, _("Line"));
 
@@ -2525,7 +2525,7 @@ DEFINE_I_CALLBACK(add_box)
   exit_if_null(w_current);
 
   o_redraw_cleanstates(w_current);	
-  o_erase_rubber(w_current);
+  o_invalidate_rubber (w_current);
 
   i_update_middle_button(w_current, i_callback_add_box, _("Box"));
   w_current->inside_action = 0;
@@ -2548,7 +2548,7 @@ DEFINE_I_CALLBACK(add_box_hotkey)
     return;
 
   o_redraw_cleanstates(w_current);	
-  o_erase_rubber(w_current);
+  o_invalidate_rubber (w_current);
 
   i_update_middle_button(w_current, i_callback_add_box_hotkey, _("Box"));
 
@@ -2570,7 +2570,7 @@ DEFINE_I_CALLBACK(add_picture)
   exit_if_null(w_current);
 
   o_redraw_cleanstates(w_current);	
-  o_erase_rubber(w_current);
+  o_invalidate_rubber (w_current);
 
   w_current->inside_action = 0;
   i_set_state(w_current, SELECT);
@@ -2604,7 +2604,7 @@ DEFINE_I_CALLBACK(add_circle)
   exit_if_null(w_current);
 
   o_redraw_cleanstates(w_current);	
-  o_erase_rubber(w_current);
+  o_invalidate_rubber (w_current);
 
   i_update_middle_button(w_current, i_callback_add_circle, _("Circle"));
   w_current->inside_action = 0;
@@ -2627,7 +2627,7 @@ DEFINE_I_CALLBACK(add_circle_hotkey)
     return;
 
   o_redraw_cleanstates(w_current);	
-  o_erase_rubber(w_current);
+  o_invalidate_rubber (w_current);
 
   i_update_middle_button(w_current, i_callback_add_circle_hotkey,
                          _("Circle"));
@@ -2650,7 +2650,7 @@ DEFINE_I_CALLBACK(add_arc)
   exit_if_null(w_current);
   
   o_redraw_cleanstates(w_current);	
-  o_erase_rubber(w_current);
+  o_invalidate_rubber (w_current);
 
   i_update_middle_button(w_current, i_callback_add_arc, _("Arc"));
   w_current->inside_action = 0;
@@ -2673,7 +2673,7 @@ DEFINE_I_CALLBACK(add_arc_hotkey)
     return;
 
   o_redraw_cleanstates(w_current);	
-  o_erase_rubber(w_current);
+  o_invalidate_rubber (w_current);
 
   i_update_middle_button(w_current, i_callback_add_arc_hotkey, _("Arc"));
 
@@ -2695,7 +2695,7 @@ DEFINE_I_CALLBACK(add_pin)
   exit_if_null(w_current);
 
   o_redraw_cleanstates(w_current);	
-  o_erase_rubber(w_current);
+  o_invalidate_rubber (w_current);
 
   i_update_middle_button(w_current, i_callback_add_pin, _("Pin"));
   w_current->inside_action = 0;
@@ -2718,7 +2718,7 @@ DEFINE_I_CALLBACK(add_pin_hotkey)
     return;
 
   o_redraw_cleanstates(w_current);	
-  o_erase_rubber(w_current);
+  o_invalidate_rubber (w_current);
 
   i_update_middle_button(w_current, i_callback_add_pin_hotkey, _("Pin"));
 
@@ -3465,8 +3465,8 @@ DEFINE_I_CALLBACK(cancel)
       w_current->cswindow) {
     /* user hit escape key when placing components */
 
-    /* Undraw any XOR outline of the place list */
-    o_place_rubberplace_xor(w_current, FALSE);
+    /* Undraw any outline of the place list */
+    o_place_invalidate_rubber (w_current, FALSE);
     w_current->rubber_visible = 0;
 
     /* De-select the lists in the component selector */
diff --git a/gschem/src/o_arc.c b/gschem/src/o_arc.c
index 2c25ca5..51b7926 100644
--- a/gschem/src/o_arc.c
+++ b/gschem/src/o_arc.c
@@ -779,9 +779,18 @@ void o_arc_draw_phantom(GdkWindow *w, GdkGC *gc,
  *  \par Function Description
  *
  */
-void o_arc_eraserubber(GSCHEM_TOPLEVEL *w_current)
+void o_arc_invalidate_rubber (GSCHEM_TOPLEVEL *w_current)
 {
-  o_arc_rubberarc_xor(w_current);
+  TOPLEVEL *toplevel = w_current->toplevel;
+
+  int cx, cy, radius;
+
+  WORLDtoSCREEN(toplevel, w_current->first_wx, w_current->first_wy, &cx, &cy);
+  radius = SCREENabs(toplevel, w_current->distance);
+
+  /* FIXME: This isn't a tight bounding box */
+  o_invalidate_rect (w_current, cx - radius, cy - radius,
+                                cx + radius, cy + radius);
 }
 
 /*! \brief Draw an arc described by OBJECT with translation
@@ -873,7 +882,7 @@ void o_arc_start(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
   w_current->second_wx = w_current->second_wy = 0;
 
   /* start the rubberbanding process of the radius */
-  o_arc_rubberarc_xor(w_current);
+  o_arc_invalidate_rubber (w_current);
   w_current->rubber_visible = 1;
 }
 
@@ -899,7 +908,7 @@ void o_arc_end1(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
   g_assert( w_current->inside_action != 0 );
 
   /* erases the previous temporary radius segment */
-  o_arc_rubberarc_xor(w_current);
+  /* o_arc_invalidate_rubber (w_current); */
   w_current->rubber_visible = 0;
 
   /* ack! zero length radius */
@@ -995,7 +1004,7 @@ void o_arc_motion (GSCHEM_TOPLEVEL *w_current, int w_x, int w_y, int whichone)
 
   /* erase the previous temporary arc */
   if (w_current->rubber_visible)
-    o_arc_rubberarc_xor(w_current);
+    o_arc_invalidate_rubber (w_current);
 
   if(whichone == ARC_RADIUS) {
     /*
@@ -1029,7 +1038,7 @@ void o_arc_motion (GSCHEM_TOPLEVEL *w_current, int w_x, int w_y, int whichone)
   }
 	
   /* draw the new temporary arc */
-  o_arc_rubberarc_xor(w_current);
+  o_arc_invalidate_rubber (w_current);
   w_current->rubber_visible = 1;
 }
 
diff --git a/gschem/src/o_basic.c b/gschem/src/o_basic.c
index f05c436..30c4abd 100644
--- a/gschem/src/o_basic.c
+++ b/gschem/src/o_basic.c
@@ -107,10 +107,13 @@ void o_redraw_rects (GSCHEM_TOPLEVEL *w_current,
   o_cue_redraw_all (w_current, obj_list, draw_selected);
 
   if (w_current->inside_action) {
+    /* Redraw the rubberband objects (if they were previously visible) */
     switch (w_current->event_state) {
       case MOVE:
       case ENDMOVE:
-        o_move_rubbermove_xor (w_current, TRUE);
+        if (w_current->last_drawb_mode != -1) {
+          o_move_rubbermove_xor (w_current, TRUE);
+        }
         break;
 
       case ENDCOPY:
@@ -118,7 +121,6 @@ void o_redraw_rects (GSCHEM_TOPLEVEL *w_current,
       case ENDCOMP:
       case ENDTEXT:
       case ENDPASTE:
-        /* Redraw the rubberband objects (if they were previously visible) */
         if (w_current->rubber_visible)
           o_place_rubberplace_xor (w_current, TRUE);
         break;
@@ -244,7 +246,7 @@ void o_redraw_single(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
  *  \par Function Description
  *
  */
-int o_erase_rubber(GSCHEM_TOPLEVEL *w_current)
+int o_invalidate_rubber (GSCHEM_TOPLEVEL *w_current)
 {
   /* return FALSE if it did not erase anything */
 
@@ -256,43 +258,43 @@ int o_erase_rubber(GSCHEM_TOPLEVEL *w_current)
     case(STARTDRAWBUS):
     case(DRAWBUS):
     case(BUSCONT):
-      o_bus_eraserubber(w_current);
+      o_bus_invalidate_rubber (w_current);
     break;
 
     case(STARTDRAWNET):
     case(DRAWNET):
     case(NETCONT):
-      o_net_eraserubber(w_current);
+      o_net_invalidate_rubber (w_current);
     break;
 
     case(DRAWPIN):
     case(ENDPIN):
-      o_pin_eraserubber(w_current);
+      o_pin_invalidate_rubber (w_current);
     break;
 
     case(DRAWLINE):
     case(ENDLINE):
-      o_line_eraserubber(w_current);
+      o_line_invalidate_rubber (w_current);
     break;
 
     case(DRAWBOX):
     case(ENDBOX):
-      o_box_eraserubber(w_current);
+      o_box_invalidate_rubber (w_current);
     break;
 
     case(DRAWPICTURE):
     case(ENDPICTURE):
-      o_picture_eraserubber(w_current);
+      o_picture_invalidate_rubber (w_current);
     break;
 
     case(DRAWCIRCLE):
     case(ENDCIRCLE):
-      o_circle_eraserubber(w_current);
+      o_circle_invalidate_rubber (w_current);
     break;
 
     case(DRAWARC):
     case(ENDARC):
-      o_arc_eraserubber(w_current);
+      o_arc_invalidate_rubber (w_current);
     break;
 
     default:
diff --git a/gschem/src/o_box.c b/gschem/src/o_box.c
index e48d473..fc02172 100644
--- a/gschem/src/o_box.c
+++ b/gschem/src/o_box.c
@@ -691,13 +691,20 @@ void o_box_fill_mesh (GdkDrawable *w, GdkGC *gc, GdkColor *color,
 /*! \todo Finish function documentation!!!
  *  \brief 
  *  \par Function Description
- * 
- *  \note
- *  used in button cancel code in x_events.c
+ *
  */
-void o_box_eraserubber(GSCHEM_TOPLEVEL *w_current)
+void o_box_invalidate_rubber (GSCHEM_TOPLEVEL *w_current)
 {
-  o_box_rubberbox_xor(w_current);
+  TOPLEVEL *toplevel = w_current->toplevel;
+  int x1, y1, x2, y2;
+
+  WORLDtoSCREEN (toplevel, w_current->first_wx, w_current->first_wy, &x1, &y1);
+  WORLDtoSCREEN (toplevel, w_current->second_wx, w_current->second_wy, &x2, &y2);
+
+  o_invalidate_rect (w_current, x1, y1, x2, y1);
+  o_invalidate_rect (w_current, x1, y1, x1, y2);
+  o_invalidate_rect (w_current, x2, y1, x2, y2);
+  o_invalidate_rect (w_current, x1, y2, x2, y2);
 }
 
 /*! \brief Draw a box described by OBJECT with translation
@@ -770,7 +777,7 @@ void o_box_start(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
   w_current->first_wy = w_current->second_wy = w_y;
 
   /* start to draw the box */
-  o_box_rubberbox_xor(w_current);
+  o_box_invalidate_rubber (w_current);
 }
 
 /*! \brief End the input of a box.
@@ -803,7 +810,7 @@ void o_box_end(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
   w_current->second_wy = w_y;
 
   /* erase the temporary box */
-  o_box_rubberbox_xor(w_current);
+  /* o_box_invalidate_rubber (w_current); */
   w_current->rubber_visible = 0;
   
   box_width  = GET_BOX_WIDTH (w_current);
@@ -866,7 +873,7 @@ void o_box_motion (GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
 
   /* erase the previous temporary box if it is visible */
   if (w_current->rubber_visible)
-    o_box_rubberbox_xor(w_current);
+    o_box_invalidate_rubber (w_current);
 
   /*
    * New values are fixed according to the <B>w_x</B> and <B>w_y</B> parameters.
@@ -879,10 +886,8 @@ void o_box_motion (GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
   w_current->second_wy = w_y;
 
   /* draw the new temporary box */
-  o_box_rubberbox_xor(w_current);
-
+  o_box_invalidate_rubber (w_current);
   w_current->rubber_visible = 1;
-  
 }
 
 /*! \brief Draw box from GSCHEM_TOPLEVEL object.
diff --git a/gschem/src/o_bus.c b/gschem/src/o_bus.c
index b0f58ed..d5234ee 100644
--- a/gschem/src/o_bus.c
+++ b/gschem/src/o_bus.c
@@ -237,7 +237,7 @@ int o_bus_end(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
   }
 
   /* erase the rubberbus */
-  o_bus_rubberbus_xor(w_current);
+  /* o_bus_invalidate_rubber (w_current); */
   w_current->rubber_visible = 0;
 
   /* don't allow zero length bus */
@@ -289,7 +289,7 @@ void o_bus_motion (GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
   g_assert( w_current->inside_action != 0 );
 
   if (w_current->rubber_visible)
-    o_bus_rubberbus_xor(w_current);
+    o_bus_invalidate_rubber (w_current);
 
   w_current->second_wx = w_x;
   w_current->second_wy = w_y;
@@ -306,10 +306,37 @@ void o_bus_motion (GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
     }
   }
 
-  o_bus_rubberbus_xor(w_current);
+  o_bus_invalidate_rubber (w_current);
   w_current->rubber_visible = 1;
 }
 
+/*! \todo Finish function documentation!!!
+ *  \brief
+ *  \par Function Description
+ *
+ */
+void o_bus_invalidate_rubber (GSCHEM_TOPLEVEL *w_current)
+{
+  TOPLEVEL *toplevel = w_current->toplevel;
+  int x1, y1, x2, y2;
+  int min_x, min_y, max_x, max_y;
+  int bloat = 0;
+
+  WORLDtoSCREEN (toplevel, w_current->first_wx, w_current->first_wy, &x1, &y1);
+  WORLDtoSCREEN (toplevel, w_current->second_wx, w_current->second_wy, &x2, &y2);
+
+  if (toplevel->bus_style == THICK ) {
+    bloat = SCREENabs(toplevel, BUS_WIDTH) / 2;
+  }
+
+  min_x = min (x1, x2) - bloat;
+  max_x = max (x1, x2) + bloat;
+  min_y = min (y1, y2) - bloat;
+  max_y = max (y1, y2) + bloat;
+
+  o_invalidate_rect (w_current, min_x, min_y, max_x, max_y);
+}
+
 /*! \brief draw a rubberbus segment in XOR mode
  *  \par Function Description
  *  This function draws a bus segment in XOR mode from the point
@@ -352,15 +379,3 @@ void o_bus_rubberbus_xor(GSCHEM_TOPLEVEL *w_current)
                                GDK_JOIN_MITER);
   }
 }
-
-/*! \todo Finish function documentation!!!
- *  \brief
- *  \par Function Description
- *
- *  \note
- *  used in button cancel code in x_events.c
- */
-void o_bus_eraserubber(GSCHEM_TOPLEVEL *w_current)
-{
-  o_bus_rubberbus_xor(w_current);
-}
diff --git a/gschem/src/o_circle.c b/gschem/src/o_circle.c
index e743844..56eb8ed 100644
--- a/gschem/src/o_circle.c
+++ b/gschem/src/o_circle.c
@@ -452,9 +452,16 @@ void o_circle_fill_mesh (GdkDrawable *w, GdkGC *gc, GdkColor *color,
  *  \par Function Description
  *
  */
-void o_circle_eraserubber(GSCHEM_TOPLEVEL *w_current)
+void o_circle_invalidate_rubber (GSCHEM_TOPLEVEL *w_current)
 {
-   o_circle_rubbercircle_xor(w_current);
+  TOPLEVEL *toplevel = w_current->toplevel;
+  int cx, cy, radius;
+
+  WORLDtoSCREEN(toplevel, w_current->first_wx, w_current->first_wy, &cx, &cy);
+  radius = SCREENabs(toplevel, w_current->distance);
+
+  o_invalidate_rect (w_current, cx - radius, cy - radius,
+                                cx + radius, cy + radius);
 }
 
 /*! \brief Draw a circle described by OBJECT with translation
@@ -536,7 +543,7 @@ void o_circle_start(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
   w_current->distance = 0;
 
   /* first temporary circle */
-  o_circle_rubbercircle_xor(w_current);
+  o_circle_invalidate_rubber (w_current);
   w_current->rubber_visible = 1;
 }
 
@@ -567,7 +574,7 @@ void o_circle_end(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
   g_assert( w_current->inside_action != 0 );
 
   /* erase the temporary circle */
-  o_circle_rubbercircle_xor(w_current);
+  /* o_circle_invalidate_rubber (w_current); */
   w_current->rubber_visible = 0;
   
   /* circle with null radius are not allowed */
@@ -619,7 +626,7 @@ void o_circle_motion (GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
 
   /* erase the previous temporary circle if it is visible */
   if (w_current->rubber_visible)
-    o_circle_rubbercircle_xor(w_current);
+    o_circle_invalidate_rubber (w_current);
 
   /*
    * The radius is taken as the biggest distance on the x and y axis between
@@ -630,7 +637,7 @@ void o_circle_motion (GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
   w_current->distance = max(diff_x, diff_y);
 
   /* draw the new temporary circle */
-  o_circle_rubbercircle_xor(w_current);
+  o_circle_invalidate_rubber (w_current);
   w_current->rubber_visible =1;
 }
 
diff --git a/gschem/src/o_grips.c b/gschem/src/o_grips.c
index bac236a..e65ca0b 100644
--- a/gschem/src/o_grips.c
+++ b/gschem/src/o_grips.c
@@ -649,7 +649,7 @@ void o_grips_start_arc(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current,
   w_current->second_wy = o_current->arc->end_angle;
 
   /* draw the first temporary arc */
-  o_arc_rubberarc_xor(w_current);
+  /* o_arc_invalidate_rubber (w_current); */
   w_current->rubber_visible = 1;
 }
 
@@ -714,7 +714,7 @@ void o_grips_start_box(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current,
   }
 
   /* draw the first temporary box */
-  o_box_rubberbox_xor(w_current);
+  /* o_box_invalidate_rubber (w_current); */
   w_current->rubber_visible = 1;
 }
 
@@ -787,7 +787,7 @@ void o_grips_start_path(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current,
   w_current->first_wy = w_current->second_wy = gy;
 
   /* draw the first temporary path */
-  o_path_rubberpath_xor(w_current);
+  /* o_path_invalidate_rubber (w_current); */
   w_current->rubber_visible = 1;
 }
 
@@ -856,7 +856,7 @@ void o_grips_start_picture(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current,
   }
 
   /* draw the first temporary picture */
-  o_picture_rubberbox_xor(w_current);
+  /* o_picture_invalidate_rubber (w_current); */
   w_current->rubber_visible = 1;
 }
 
@@ -896,7 +896,7 @@ void o_grips_start_circle(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current,
   w_current->distance = o_current->circle->radius;
 
   /* draw the first temporary circle */
-  o_circle_rubbercircle_xor(w_current);
+  /* o_circle_invalidate_rubber (w_current); */
   w_current->rubber_visible = 1;
 }
 
@@ -935,7 +935,7 @@ void o_grips_start_line(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current,
   w_current->first_wy = o_current->line->y[!whichone];
 
   /* draw the first temporary line */
-  o_line_rubberline_xor(w_current);
+  /* o_line_invalidate_rubber (w_current); */
   w_current->rubber_visible = 1;
 }
 
@@ -1116,7 +1116,7 @@ void o_grips_end_arc(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int whichone
   int arg1, arg2;
 
   /* erase the temporary arc */
-  o_arc_rubberarc_xor(w_current);
+  /* o_arc_invalidate_rubber (w_current); */
 
   /* determination of the parameters to give to o_arc_modify() */
   switch(whichone) {
@@ -1180,7 +1180,7 @@ void o_grips_end_box(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int whichone
   o_box_modify(toplevel, o_current, w_current->second_wx, w_current->second_wy, whichone);
 
   /* erase the temporary box */
-  o_box_rubberbox_xor(w_current);
+  /* o_box_invalidate_rubber (w_current); */
 
   /* draw the modified box */
   o_invalidate (w_current, o_current);
@@ -1197,8 +1197,8 @@ void o_grips_end_box(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int whichone
 void o_grips_end_path(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int whichone)
 {
   /* erase the temporary path */
-  if (w_current->rubber_visible)
-    o_path_rubberpath_xor(w_current);
+  /* if (w_current->rubber_visible) */
+  /*  o_path_invalidate_rubber (w_current); */
 
   o_path_modify (w_current->toplevel, o_current,
                  w_current->second_wx, w_current->second_wy, whichone);
@@ -1220,7 +1220,7 @@ void o_grips_end_picture(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int whic
   TOPLEVEL *toplevel = w_current->toplevel;
 
   /* erase the temporary picture */
-  o_picture_rubberbox_xor(w_current);
+  /* o_picture_invalidate_rubber (w_current); */
 
   /* don't allow zero width/height picturees
    * this ends the picture drawing behavior
@@ -1261,7 +1261,7 @@ void o_grips_end_circle(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int which
   TOPLEVEL *toplevel = w_current->toplevel;
 
   /* erase the temporary circle */
-  o_circle_rubbercircle_xor(w_current);
+  /* o_circle_invalidate_rubber (w_current); */
 
   /* don't allow zero radius circles
    * this ends the circle drawing behavior
@@ -1299,7 +1299,7 @@ void o_grips_end_line(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int whichon
   TOPLEVEL *toplevel = w_current->toplevel;
 
   /* erase the temporary line */
-  o_line_rubberline_xor(w_current);
+  /* o_line_invalidate_rubber (w_current); */
 
   /* don't allow zero length nets / lines / pins
    * this ends the net drawing behavior
@@ -1342,7 +1342,7 @@ void o_grips_end_net(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int whichone
   GList *connected_objects = NULL;
 
   /* erase the temporary line */
-  o_line_rubberline_xor(w_current);
+  /* o_line_invalidate_rubber (w_current); */
 
   /* don't allow zero length net
    * this ends the net drawing behavior
@@ -1412,7 +1412,7 @@ void o_grips_end_pin(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int whichone
   GList *connected_objects = NULL;
 
   /* erase the temporary line */
-  o_line_rubberline_xor(w_current);
+  /* o_line_invalidate_rubber (w_current); */
 
   /* don't allow zero length pin
    * this ends the pin changing behavior
@@ -1472,7 +1472,7 @@ void o_grips_end_bus(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int whichone
   GList *connected_objects = NULL;
 
   /* erase the temporary line */
-  o_line_rubberline_xor(w_current);
+  /* o_line_invalidate_rubber (w_current); */
 
   /* don't allow zero length bus
    * this ends the bus changing behavior
diff --git a/gschem/src/o_line.c b/gschem/src/o_line.c
index 01eb452..2bf01c6 100644
--- a/gschem/src/o_line.c
+++ b/gschem/src/o_line.c
@@ -682,13 +682,16 @@ void o_line_draw_phantom(GdkWindow *w, GdkGC *gc, GdkColor *color,
 /*! \todo Finish function documentation
  *  \brief
  *  \par Function Description
- *
- *  \note
- *  used in button cancel code in x_events.c
  */
-void o_line_eraserubber(GSCHEM_TOPLEVEL *w_current)
+void o_line_invalidate_rubber (GSCHEM_TOPLEVEL *w_current)
 {
-  o_line_rubberline_xor(w_current);
+  TOPLEVEL *toplevel = w_current->toplevel;
+  int x1, y1, x2, y2;
+
+  WORLDtoSCREEN(toplevel, w_current->first_wx, w_current->first_wy, &x1, &y1);
+  WORLDtoSCREEN(toplevel, w_current->second_wx, w_current->second_wy, &x2, &y2);
+
+  o_invalidate_rect (w_current, x1, y1, x2, y2);
 }
 
 /*! \brief Draw a line object after applying translation.
@@ -753,7 +756,7 @@ void o_line_start(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
   w_current->first_wy = w_current->second_wy = w_y;
   
   /* draw init xor */
-  o_line_rubberline_xor(w_current);
+  o_line_invalidate_rubber (w_current);
   w_current->rubber_visible = 1;
 }
 
@@ -779,7 +782,8 @@ void o_line_end(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
   g_assert( w_current->inside_action != 0 );
 
   /* erase xor image */
-  o_line_rubberline_xor(w_current);
+  /* Don't bother.. the real object is invalidated, its in the same place */
+  /* o_line_invalidate_rubber (w_current); */
   w_current->rubber_visible = 0;
 
   /* don't allow zero length lines */
@@ -830,7 +834,7 @@ void o_line_motion (GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
    * erased. If the line was not already displayed it is drawn.
    */
   if (w_current->rubber_visible)
-    o_line_rubberline_xor(w_current);
+    o_line_invalidate_rubber (w_current);
 
   /*
    * The coordinates of the moving end of the line are updated. Its new
@@ -857,7 +861,7 @@ void o_line_motion (GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
    * function, if the line was displayed, it has been erased, updated and
    * displayed again.
    */
-  o_line_rubberline_xor(w_current);
+  o_line_invalidate_rubber (w_current);
   w_current->rubber_visible = 1;
 }
 
diff --git a/gschem/src/o_move.c b/gschem/src/o_move.c
index 0582844..558aafa 100644
--- a/gschem/src/o_move.c
+++ b/gschem/src/o_move.c
@@ -301,10 +301,55 @@ void o_move_cancel (GSCHEM_TOPLEVEL *w_current)
  */
 void o_move_motion (GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
 {
-  o_move_rubbermove_xor (w_current, FALSE);
+  o_move_invalidate_rubber (w_current, FALSE);
   w_current->second_wx = w_x;
   w_current->second_wy = w_y;
-  o_move_rubbermove_xor (w_current, TRUE);
+  o_move_invalidate_rubber (w_current, TRUE);
+}
+
+
+/*! \todo Finish function documentation!!!
+ *  \brief
+ *  \par Function Description
+ *
+ */
+void o_move_invalidate_rubber (GSCHEM_TOPLEVEL *w_current, int drawing)
+{
+  TOPLEVEL *toplevel = w_current->toplevel;
+  GList *s_iter;
+  int dx1, dx2, dy1, dy2;
+  int x1, y1, x2, y2;
+
+  o_place_invalidate_rubber (w_current, drawing);
+  if (w_current->netconn_rubberband) {
+
+    for (s_iter = toplevel->page_current->stretch_list;
+         s_iter != NULL; s_iter = g_list_next (s_iter)) {
+      STRETCH *s_current = s_iter->data;
+      OBJECT *object = s_current->object;
+
+      switch (object->type) {
+        case (OBJ_NET):
+        case (OBJ_BUS):
+          if (s_current->whichone == 0) {
+            dx1 = w_current->second_wx - w_current->first_wx;
+            dy1 = w_current->second_wy - w_current->first_wy;
+            dx2 = dy2 = 0;
+          } else {
+            dx1 = dy1 = 0;
+            dx2 = w_current->second_wx - w_current->first_wx;
+            dy2 = w_current->second_wy - w_current->first_wy;
+          }
+
+          WORLDtoSCREEN (toplevel, object->line->x[0] + dx1,
+                                   object->line->y[0] + dy1, &x1, &y1);
+          WORLDtoSCREEN (toplevel, object->line->x[1] + dx2,
+                                   object->line->y[1] + dy2, &x2, &y2);
+
+          o_invalidate_rect (w_current, x1, y1, x2, y2);
+      }
+    }
+  }
 }
 
 
diff --git a/gschem/src/o_net.c b/gschem/src/o_net.c
index ea918db..d1a7bd5 100644
--- a/gschem/src/o_net.c
+++ b/gschem/src/o_net.c
@@ -62,7 +62,7 @@ void o_net_reset(GSCHEM_TOPLEVEL *w_current)
   w_current->second_wx = w_current->second_wy = -1;
   w_current->third_wx = w_current->third_wy = -1;
   w_current->magnetic_wx = w_current->magnetic_wy = -1;
-  w_current->magnetic_visible = w_current->rubber_visible = 0;
+  w_current->rubber_visible = 0;
 }
 
 /*! \todo Finish function documentation!!!
@@ -588,9 +588,7 @@ void o_net_finishmagnetic(GSCHEM_TOPLEVEL *w_current)
  */
 void o_net_start_magnetic(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
 {
-  o_net_eraserubber(w_current);
-  /* the dc is completely clean now, reset inside_action. */
-  w_current->inside_action = 0;
+  o_net_invalidate_rubber (w_current);
 
   if (w_current->CONTROLKEY) {
     w_current->magnetic_wx = w_x;
@@ -600,7 +598,9 @@ void o_net_start_magnetic(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
     o_net_find_magnetic(w_current, w_x, w_y);
   }
 
-  o_net_drawrubber(w_current);
+  o_net_invalidate_rubber (w_current);
+  w_current->rubber_visible = 1;
+  w_current->inside_action = 1;
 }
 
 /*! \brief set the start point of a new net
@@ -613,7 +613,7 @@ void o_net_start(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
 {
   TOPLEVEL *toplevel = w_current->toplevel;
 
-  if (w_current->magnetic_visible) {
+  if (w_current->magnetic_wx != -1 && w_current->magnetic_wy != -1) {
     w_current->first_wx = w_current->magnetic_wx;
     w_current->first_wy = w_current->magnetic_wy;
   }
@@ -650,22 +650,20 @@ int o_net_end(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
   int color;
   int primary_zero_length, secondary_zero_length;
   int found_primary_connection = FALSE;
-  int save_magnetic, save_wx, save_wy;
+  int save_wx, save_wy;
 
   GList *prev_conn_objects = NULL;
   OBJECT *new_net = NULL;
 
   g_assert( w_current->inside_action != 0 );
 
-  /* I've to store that because o_net_eraserubber would delete it
-     but I need it for o_net_finish_magnetic */
-  save_magnetic = w_current->magnetic_visible;
-
-  o_net_eraserubber(w_current);
+  o_net_invalidate_rubber (w_current);
 
-  if (save_magnetic)
+  if (w_current->magnetic_wx != -1 && w_current->magnetic_wy != -1)
     o_net_finishmagnetic(w_current);
 
+  w_current->rubber_visible = 0;
+
   /* See if either of the nets are zero length.  We'll only add */
   /* the non-zero ones */
   primary_zero_length = (w_current->first_wx == w_current->second_wx) &&
@@ -801,7 +799,8 @@ void o_net_motion (GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
      if we are using magnetic mode */
   ortho = !w_current->CONTROLKEY || w_current->magneticnet_mode;
 
-  o_net_eraserubber(w_current);
+  if (w_current->rubber_visible)
+    o_net_invalidate_rubber (w_current);
 
   if (w_current->magneticnet_mode) {
     if (w_current->CONTROLKEY) {
@@ -849,7 +848,8 @@ void o_net_motion (GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
     }
   }
 
-  o_net_drawrubber(w_current);
+  o_net_invalidate_rubber (w_current);
+  w_current->rubber_visible = 1;
 }
 
 /*! \brief draw rubbernet lines to the gc
@@ -872,8 +872,6 @@ void o_net_drawrubber(GSCHEM_TOPLEVEL *w_current)
   WORLDtoSCREEN(toplevel, w_current->second_wx, w_current->second_wy,
 		&second_x, &second_y);
 
-  w_current->rubber_visible = 1;
-
   if (toplevel->net_style == THICK) {
     size = SCREENabs(toplevel, NET_WIDTH);
     gdk_gc_set_line_attributes(w_current->xor_gc, size,
@@ -887,8 +885,6 @@ void o_net_drawrubber(GSCHEM_TOPLEVEL *w_current)
 
   if (w_current->magneticnet_mode) {
     if (w_current->magnetic_wx != -1 && w_current->magnetic_wy != -1) {
-      w_current->magnetic_visible = 1;
-      w_current->inside_action = 1;
       magnetic_halfsize = max(4*size, MAGNETIC_HALFSIZE);
       gdk_draw_arc (w_current->drawable, w_current->xor_gc, FALSE,
                     magnetic_x - magnetic_halfsize,
@@ -918,61 +914,53 @@ void o_net_drawrubber(GSCHEM_TOPLEVEL *w_current)
  *  \brief
  *  \par Function Description
  *
- *  \note
- *  used in button cancel code in x_events.c
  */
-void o_net_eraserubber(GSCHEM_TOPLEVEL *w_current)
+void o_net_invalidate_rubber (GSCHEM_TOPLEVEL *w_current)
 {
   TOPLEVEL *toplevel = w_current->toplevel;
-  int size=0, magnetic_halfsize;
+  int size = 0, magnetic_halfsize;
+  int bloat;
   int magnetic_x, magnetic_y;
   int first_x, first_y, third_x, third_y, second_x, second_y;
+  int x1, y1, x2, y2;
 
-  if (! w_current->rubber_visible)
-    return;
-
-  WORLDtoSCREEN(toplevel, w_current->magnetic_wx, w_current->magnetic_wy,
-		&magnetic_x, &magnetic_y);
-  WORLDtoSCREEN(toplevel, w_current->first_wx, w_current->first_wy,
-		&first_x, &first_y);
-  WORLDtoSCREEN(toplevel, w_current->third_wx, w_current->third_wy,
-		&third_x, &third_y);
-  WORLDtoSCREEN(toplevel, w_current->second_wx, w_current->second_wy,
-		&second_x, &second_y);
-
-  w_current->rubber_visible = 0;
+  WORLDtoSCREEN (toplevel, w_current->magnetic_wx, w_current->magnetic_wy,
+                 &magnetic_x, &magnetic_y);
+  WORLDtoSCREEN (toplevel, w_current->first_wx, w_current->first_wy,
+                 &first_x, &first_y);
+  WORLDtoSCREEN (toplevel, w_current->third_wx, w_current->third_wy,
+                 &third_x, &third_y);
+  WORLDtoSCREEN (toplevel, w_current->second_wx, w_current->second_wy,
+                 &second_x, &second_y);
 
   if (toplevel->net_style == THICK) {
-    size = SCREENabs(toplevel, NET_WIDTH);
-    gdk_gc_set_line_attributes(w_current->xor_gc, size,
-			       GDK_LINE_SOLID,
-			       GDK_CAP_NOT_LAST, GDK_JOIN_MITER);
+    size = SCREENabs (toplevel, NET_WIDTH);
   }
-  size = max(size, 0);
-
-  if (w_current->magnetic_visible) {
-    w_current->magnetic_visible = 0;
-    magnetic_halfsize = max(4*size, MAGNETIC_HALFSIZE);
-    gdk_draw_arc (w_current->drawable, w_current->xor_gc, FALSE,
-                 magnetic_x - magnetic_halfsize,
-                 magnetic_y - magnetic_halfsize,
-                 2 * magnetic_halfsize, 2 * magnetic_halfsize,
-                 0, FULL_CIRCLE);
-  }
-
-  /* Erase primary primary rubber net line */
-  gdk_draw_line (w_current->drawable, w_current->xor_gc,
-                 first_x, first_y, second_x, second_y);
+  size = max (size, 0);
+  bloat = size / 2;
 
-  /* Erase secondary rubber net line */
-  gdk_draw_line (w_current->drawable, w_current->xor_gc,
-                 second_x, second_y, third_x, third_y);
+  if (w_current->magneticnet_mode) {
+    if (w_current->magnetic_wx != -1 && w_current->magnetic_wy != -1) {
+      magnetic_halfsize = max (4 * size, MAGNETIC_HALFSIZE);
 
-  if (toplevel->net_style == THICK) {
-    gdk_gc_set_line_attributes(w_current->xor_gc, 0,
-			       GDK_LINE_SOLID,
-			       GDK_CAP_NOT_LAST, GDK_JOIN_MITER);
+      o_invalidate_rect (w_current, magnetic_x - magnetic_halfsize,
+                                    magnetic_y - magnetic_halfsize,
+                                    magnetic_x + magnetic_halfsize,
+                                    magnetic_y + magnetic_halfsize);
+    }
   }
+
+  x1 = min (first_x, second_x) - bloat;
+  x2 = max (first_x, second_x) + bloat;
+  y1 = min (first_y, second_y) - bloat;
+  y2 = max (first_y, second_y) + bloat;
+  o_invalidate_rect (w_current, x1, y1, x2, y2);
+
+  x1 = min (second_x, third_x) - bloat;
+  x2 = max (second_x, third_x) + bloat;
+  y1 = min (second_y, third_y) - bloat;
+  y2 = max (second_y, third_y) + bloat;
+  o_invalidate_rect (w_current, x1, y1, x2, y2);
 }
 
 
diff --git a/gschem/src/o_path.c b/gschem/src/o_path.c
index a828e92..fee9ff1 100644
--- a/gschem/src/o_path.c
+++ b/gschem/src/o_path.c
@@ -609,16 +609,45 @@ void o_path_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
 }
 
 
+static void find_points_bounds (GdkPoint *points, int num_points,
+                                int *min_x, int *min_y, int *max_x, int *max_y)
+{
+  int i;
+  int found_bound = FALSE;
+
+  for (i = 0; i < num_points; i++) {
+    *min_x = (found_bound) ? min (*min_x, points[i].x) : points[i].x;
+    *min_y = (found_bound) ? min (*min_y, points[i].y) : points[i].y;
+    *max_x = (found_bound) ? max (*max_x, points[i].x) : points[i].x;
+    *max_y = (found_bound) ? max (*max_y, points[i].y) : points[i].y;
+    found_bound = TRUE;
+  }
+}
+
+
 /*! \todo Finish function documentation
  *  \brief
  *  \par Function Description
- *
- *  \note
- *  used in button cancel code in x_events.c
  */
-void o_path_eraserubber(GSCHEM_TOPLEVEL *w_current)
+void o_path_invalidate_rubber (GSCHEM_TOPLEVEL *w_current)
 {
-  o_path_rubberpath_xor (w_current);
+  PATH *path = w_current->which_object->path;
+  int num_points;
+  GdkPoint *points;
+  int min_x = 0, min_y = 0, max_x = 0, max_y = 0;
+
+  path_to_points_modify (w_current, path, 0, 0,
+                         w_current->second_wx, w_current->second_wy,
+                         w_current->which_grip, &points, &num_points);
+  if (num_points == 0) {
+    g_free (points);
+    return;
+  }
+
+  find_points_bounds (points, num_points, &min_x, &min_y, &max_x, &max_y);
+  g_free (points);
+
+  o_invalidate_rect (w_current, min_x, min_y, max_x, max_y);
 }
 
 
@@ -728,12 +757,12 @@ void o_path_end(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
 void o_path_motion (GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
 {
   if (w_current->rubber_visible)
-    o_path_rubberpath_xor (w_current);
+    o_path_invalidate_rubber (w_current);
 
   w_current->second_wx = w_x;
   w_current->second_wy = w_y;
 
-  o_path_rubberpath_xor (w_current);
+  o_path_invalidate_rubber (w_current);
   w_current->rubber_visible = 1;
 }
 
diff --git a/gschem/src/o_picture.c b/gschem/src/o_picture.c
index 86c8ee5..2511bfa 100644
--- a/gschem/src/o_picture.c
+++ b/gschem/src/o_picture.c
@@ -60,7 +60,7 @@ void o_picture_start(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
   w_current->first_wy = w_current->second_wy = w_y;
 
   /* start to draw the box */
-  o_picture_rubberbox_xor(w_current);
+  o_picture_invalidate_rubber (w_current);
   w_current->rubber_visible = 1;
 }
 
@@ -88,7 +88,7 @@ void o_picture_end(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
   g_assert( w_current->inside_action != 0 );
 
   /* erase the temporary picture */
-  o_picture_rubberbox_xor(w_current);
+  /* o_picture_rubberbox_xor(w_current); */
   w_current->rubber_visible = 0;
   
   picture_width  = GET_PICTURE_WIDTH (w_current);
@@ -176,7 +176,7 @@ void picture_selection_dialog (GSCHEM_TOPLEVEL *w_current)
       printf("Picture loaded succesfully.\n");
 #endif
       
-      o_erase_rubber(w_current);
+      o_invalidate_rubber(w_current);
       i_update_middle_button(w_current, i_callback_add_picture, _("Picture"));
       w_current->inside_action = 0;
       
@@ -202,12 +202,21 @@ void picture_selection_dialog (GSCHEM_TOPLEVEL *w_current)
  *  \note
  * used in button cancel code in x_events.c
  */
-void o_picture_eraserubber(GSCHEM_TOPLEVEL *w_current)
+void o_picture_invalidate_rubber (GSCHEM_TOPLEVEL *w_current)
 {
-#if DEBUG
-  printf("o_picture_eraserubber called\n");
-#endif
-  o_picture_rubberbox_xor(w_current);
+  TOPLEVEL *toplevel = w_current->toplevel;
+  int left, top, width, height;
+
+  WORLDtoSCREEN (toplevel,
+                 GET_PICTURE_LEFT(w_current), GET_PICTURE_TOP(w_current),
+                 &left, &top);
+  width = SCREENabs(toplevel, GET_PICTURE_WIDTH (w_current));
+  height = SCREENabs(toplevel, GET_PICTURE_HEIGHT(w_current));
+
+  o_invalidate_rect (w_current, left, top, left + width, top);
+  o_invalidate_rect (w_current, left, top, left, top + height);
+  o_invalidate_rect (w_current, left + width, top, left + width, top + height);
+  o_invalidate_rect (w_current, left, top + height, left + width, top + height);
 }
 
 /*! \brief Draw temporary picture while dragging edge.
@@ -234,7 +243,7 @@ void o_picture_motion (GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
 
   /* erase the previous temporary box */
   if (w_current->rubber_visible)
-    o_picture_rubberbox_xor(w_current);
+    o_picture_invalidate_rubber (w_current);
 
   /*
    * New values are fixed according to the <B>w_x</B> and <B>w_y</B> parameters. 
@@ -247,7 +256,7 @@ void o_picture_motion (GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
   w_current->second_wy = w_y;
 
   /* draw the new temporary box */
-  o_picture_rubberbox_xor(w_current);
+  o_picture_invalidate_rubber (w_current);
   w_current->rubber_visible = 1;
 }
 
@@ -632,7 +641,7 @@ void picture_change_filename_dialog (GSCHEM_TOPLEVEL *w_current)
       printf("Picture loaded succesfully.\n");
 #endif
 
-      o_erase_rubber(w_current);
+      o_invalidate_rubber(w_current);
       w_current->inside_action = 0;
 
       /* \FIXME Should we set the pixbuf buffer in GSCHEM_TOPLEVEL to store
diff --git a/gschem/src/o_pin.c b/gschem/src/o_pin.c
index 2be22da..2479ffe 100644
--- a/gschem/src/o_pin.c
+++ b/gschem/src/o_pin.c
@@ -172,7 +172,7 @@ void o_pin_end(GSCHEM_TOPLEVEL *w_current, int x, int y)
   }
 
   /* undraw rubber line */
-  o_pin_rubberpin_xor(w_current);
+  /* o_pin_invalidate_rubber (w_current); */
   w_current->rubber_visible = 0;
 
   /* don't allow zero length pins */
@@ -217,7 +217,7 @@ void o_pin_motion (GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
 
   /* erase the rubberpin if it is visible */
   if (w_current->rubber_visible)
-    o_pin_rubberpin_xor(w_current);
+    o_pin_invalidate_rubber (w_current);
 
   w_current->second_wx = w_x;
   w_current->second_wy = w_y;
@@ -230,20 +230,34 @@ void o_pin_motion (GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
     w_current->second_wx = w_current->first_wx;
   }
 
-  o_pin_rubberpin_xor(w_current);
+  o_pin_invalidate_rubber (w_current);
   w_current->rubber_visible = 1;
 }
 
 /*! \todo Finish function documentation!!!
  *  \brief
  *  \par Function Description
- *
- *  \note
- *  used in o_stretch.c
  */
-void o_pin_eraserubber(GSCHEM_TOPLEVEL *w_current)
+void o_pin_invalidate_rubber (GSCHEM_TOPLEVEL *w_current)
 {
-  o_pin_rubberpin_xor(w_current);
+  TOPLEVEL *toplevel = w_current->toplevel;
+  int x1, y1, x2, y2;
+  int min_x, min_y, max_x, max_y;
+  int bloat = 0;
+
+  WORLDtoSCREEN(toplevel, w_current->first_wx, w_current->first_wy, &x1, &y1);
+  WORLDtoSCREEN(toplevel, w_current->second_wx, w_current->second_wy, &x2, &y2);
+
+  if (toplevel->net_style == THICK ) {
+    bloat = SCREENabs (toplevel, PIN_WIDTH) / 2;
+  }
+
+  min_x = min (x1, x2) - bloat;
+  max_x = max (x1, x2) + bloat;
+  min_y = min (y1, y2) - bloat;
+  max_y = max (y1, y2) + bloat;
+
+  o_invalidate_rect (w_current, min_x, min_y, max_x, max_y);
 }
 
 
diff --git a/gschem/src/o_place.c b/gschem/src/o_place.c
index 318de9f..83db526 100644
--- a/gschem/src/o_place.c
+++ b/gschem/src/o_place.c
@@ -36,7 +36,7 @@ void o_place_start (GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
   w_current->second_wx = w_x;
   w_current->second_wy = w_y;
 
-  o_place_rubberplace_xor (w_current, TRUE);
+  o_place_invalidate_rubber (w_current, TRUE);
   w_current->rubber_visible = 1;
 }
 
@@ -59,7 +59,7 @@ void o_place_end (GSCHEM_TOPLEVEL *w_current,
   GList *iter;
 
   /* erase old image */
-  o_place_rubberplace_xor (w_current, FALSE);
+  /* o_place_invaidate_rubber (w_current, FALSE); */
   w_current->rubber_visible = 0;
 
   /* Calc final object positions */
@@ -128,10 +128,10 @@ void o_place_end (GSCHEM_TOPLEVEL *w_current,
 void o_place_motion (GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
 {
   if (w_current->rubber_visible)
-    o_place_rubberplace_xor (w_current, FALSE);
+    o_place_invalidate_rubber (w_current, FALSE);
   w_current->second_wx = w_x;
   w_current->second_wy = w_y;
-  o_place_rubberplace_xor (w_current, TRUE);
+  o_place_invalidate_rubber (w_current, TRUE);
   w_current->rubber_visible = 1;
 }
 
@@ -170,6 +170,91 @@ void o_place_motion (GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
  *  \param [in] drawing     Set to FALSE for undraw operations to ensure
  *                            matching conditions to a previous draw operation.
  */
+void o_place_invalidate_rubber (GSCHEM_TOPLEVEL *w_current, int drawing)
+{
+  TOPLEVEL *toplevel = w_current->toplevel;
+  int diff_x, diff_y;
+  int left, top, bottom, right;
+  int s_left, s_top, s_bottom, s_right;
+
+  g_return_if_fail (toplevel->page_current->place_list != NULL);
+
+  /* If drawing is true, then don't worry about the previous drawing
+   * method and movement constraints, use with the current settings */
+  if (drawing) {
+    /* Ensure we set this to flag there is "something" supposed to be
+     * drawn when the invaliate call below causes an expose event. */
+    w_current->last_drawb_mode = w_current->actionfeedback_mode;
+    w_current->drawbounding_action_mode = (w_current->CONTROLKEY)
+                                            ? CONSTRAINED : FREE;
+  }
+
+  /* Calculate delta of X-Y positions from buffer's origin */
+  diff_x = w_current->second_wx - w_current->first_wx;
+  diff_y = w_current->second_wy - w_current->first_wy;
+
+  /* Adjust the coordinates according to the movement constraints */
+
+  /* Need to update the w_current->{first,second}_w{x,y} coords even
+   * though we're only invalidating, because the move rubberband code
+   * (which may execute right after this function) expects these
+   * coordinates to be correct. It then XORs directly onto the screen,
+   * not via an invalidation / redraw.
+   */
+  if (w_current->drawbounding_action_mode == CONSTRAINED) {
+    if (abs (diff_x) >= abs (diff_y)) {
+      w_current->second_wy = w_current->first_wy;
+      diff_y = 0;
+    } else {
+      w_current->second_wx = w_current->first_wx;
+      diff_x = 0;
+    }
+  }
+
+  /* Find the bounds of the drawing to be done */
+  world_get_object_glist_bounds (toplevel, toplevel->page_current->place_list,
+                                 &left, &top, &right, &bottom);
+  WORLDtoSCREEN (toplevel, left + diff_x, top + diff_y, &s_left, &s_top);
+  WORLDtoSCREEN (toplevel, right + diff_x, bottom + diff_y, &s_right, &s_bottom);
+
+  o_invalidate_rect (w_current, s_left, s_top, s_right, s_bottom);
+}
+
+
+/*! \brief XOR draw a bounding box or outline for OBJECT placement
+ *
+ *  \par Function Description
+ *  This function XOR draws either the OBJECTS in the place list
+ *  or a rectangle around their bounding box, depending upon the
+ *  currently selected w_current->actionfeedback_mode. This takes the
+ *  value BOUNDINGBOX or OUTLINE.
+ *
+ * The function applies manhatten mode constraints to the coordinates
+ * before drawing if the CONTROL key is recording as being pressed in
+ * the w_current structure.
+ *
+ * The "drawing" parameter is used to indicate if this drawing should
+ * immediately use the selected feedback mode and positioning constraints.
+ *
+ * With drawing=TRUE, the selected conditions are used immediately,
+ * otherwise the conditions from the last drawing operation are used,
+ * saving the new state for next time.
+ *
+ * This function should be called with drawing=TRUE when starting a
+ * rubberbanding operation and when otherwise refreshing the rubberbanded
+ * outline (e.g. after a screen redraw). For any undraw operation, should
+ * be called with drawing=FALSE, ensuring that the undraw XOR matches the
+ * mode and constraints of the corresponding "draw" operation.
+ *
+ * If any mode / constraint changes are made between a undraw, redraw XOR
+ * pair, the latter (draw) operation must be called with drawing=TRUE. If
+ * no mode / constraint changes were made between the pair, it is not
+ * harmful to call the draw operation with "drawing=FALSE".
+ *
+ *  \param [in] w_current   GSCHEM_TOPLEVEL which we're drawing for.
+ *  \param [in] drawing     Set to FALSE for undraw operations to ensure
+ *                            matching conditions to a previous draw operation.
+ */
 void o_place_rubberplace_xor (GSCHEM_TOPLEVEL *w_current, int drawing)
 {
   TOPLEVEL *toplevel = w_current->toplevel;
diff --git a/gschem/src/o_select.c b/gschem/src/o_select.c
index 4372fb0..b913a41 100644
--- a/gschem/src/o_select.c
+++ b/gschem/src/o_select.c
@@ -266,7 +266,7 @@ int o_select_box_start(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
  */
 void o_select_box_end(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
 {
-  o_select_box_rubberband_xor(w_current);
+  o_select_box_invalidate_rubber (w_current);
   w_current->rubber_visible = 0;
 
   o_select_box_search(w_current);
@@ -280,18 +280,36 @@ void o_select_box_end(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
 void o_select_box_motion (GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
 {
   if (w_current->rubber_visible)
-    o_select_box_rubberband_xor(w_current);
+    o_select_box_invalidate_rubber (w_current);
     
   w_current->second_wx = w_x; 
   w_current->second_wy = w_y;
 
-  o_select_box_rubberband_xor(w_current);
+  o_select_box_invalidate_rubber (w_current);
   w_current->rubber_visible = 1;
 }
 
 /*! \todo Finish function documentation!!!
  *  \brief
  *  \par Function Description
+ */
+void o_select_box_invalidate_rubber (GSCHEM_TOPLEVEL *w_current)
+{
+  TOPLEVEL *toplevel = w_current->toplevel;
+  int x1, y1, x2, y2;
+
+  WORLDtoSCREEN(toplevel, w_current->first_wx, w_current->first_wy, &x1, &y1);
+  WORLDtoSCREEN(toplevel, w_current->second_wx, w_current->second_wy, &x2, &y2);
+
+  o_invalidate_rect (w_current, x1, y1, x2, y1);
+  o_invalidate_rect (w_current, x1, y1, x1, y2);
+  o_invalidate_rect (w_current, x2, y1, x2, y2);
+  o_invalidate_rect (w_current, x1, y2, x2, y2);
+}
+
+/*! \todo Finish function documentation!!!
+ *  \brief
+ *  \par Function Description
  *
  */
 void o_select_box_rubberband_xor(GSCHEM_TOPLEVEL *w_current)
diff --git a/gschem/src/x_compselect.c b/gschem/src/x_compselect.c
index bbbbc88..0b4d1fc 100644
--- a/gschem/src/x_compselect.c
+++ b/gschem/src/x_compselect.c
@@ -140,7 +140,7 @@ x_compselect_callback_response (GtkDialog *dialog,
         if (w_current->event_state == ENDCOMP) {
           /* Delete the component which was being placed */
           if (w_current->rubber_visible)
-            o_place_rubberplace_xor (w_current, FALSE);
+            o_place_invalidate_rubber (w_current, FALSE);
           w_current->rubber_visible = 0;
           s_delete_object_glist (toplevel,
                                  toplevel->page_current->place_list);
diff --git a/gschem/src/x_event.c b/gschem/src/x_event.c
index 2fb864c..6132165 100644
--- a/gschem/src/x_event.c
+++ b/gschem/src/x_event.c
@@ -258,7 +258,7 @@ gint x_event_button_pressed(GtkWidget *widget, GdkEventButton *event,
           o_net_start(w_current, w_current->first_wx, w_current->first_wy);
           w_current->event_state=NETCONT;
         } else { /* cleanup and start a new net */
-          o_net_eraserubber(w_current);
+          o_net_invalidate_rubber (w_current);
           o_net_reset(w_current);
           i_set_state(w_current, STARTDRAWNET);
           w_current->inside_action = 0;
@@ -283,7 +283,7 @@ gint x_event_button_pressed(GtkWidget *widget, GdkEventButton *event,
           i_set_state(w_current, SELECT);
           i_update_toolbar(w_current);
         } else {
-          o_place_rubberplace_xor (w_current, TRUE);
+          o_place_invalidate_rubber (w_current, TRUE);
           w_current->rubber_visible = 1;
         }
         break;
@@ -438,7 +438,7 @@ gint x_event_button_pressed(GtkWidget *widget, GdkEventButton *event,
         case(NETCONT):
           w_current->inside_action = 0;
           i_set_state(w_current, STARTDRAWNET);
-          o_net_eraserubber(w_current);
+          o_net_invalidate_rubber (w_current);
           o_net_reset(w_current);
           break;
 
@@ -447,49 +447,49 @@ gint x_event_button_pressed(GtkWidget *widget, GdkEventButton *event,
         case(BUSCONT):
           w_current->inside_action = 0;
           i_set_state(w_current, STARTDRAWBUS);
-          o_bus_eraserubber(w_current);
+          o_bus_invalidate_rubber (w_current);
           break;
 
         case(DRAWPIN):
         case(ENDPIN):
           w_current->inside_action = 0;
           i_set_state(w_current, DRAWPIN);
-          o_pin_eraserubber(w_current);
+          o_pin_invalidate_rubber (w_current);
           break;
 
         case(DRAWLINE):
         case(ENDLINE):
           w_current->inside_action = 0;
           i_set_state(w_current, DRAWLINE);
-          o_line_eraserubber(w_current);
+          o_line_invalidate_rubber (w_current);
           break;
 
         case(DRAWBOX):
         case(ENDBOX):
           w_current->inside_action = 0;
           i_set_state(w_current, DRAWBOX);
-          o_box_eraserubber(w_current);
+          o_box_invalidate_rubber (w_current);
           break;
 
         case(DRAWPICTURE):
         case(ENDPICTURE):
           w_current->inside_action = 0;
           i_set_state(w_current, DRAWPICTURE);
-          o_picture_eraserubber(w_current);
+          o_picture_invalidate_rubber (w_current);
           break;
 
         case(DRAWCIRCLE):
         case(ENDCIRCLE):
           w_current->inside_action = 0;
           i_set_state(w_current, DRAWCIRCLE);
-          o_circle_eraserubber(w_current);
+          o_circle_invalidate_rubber (w_current);
           break;
 
         case(DRAWARC):
         case(ENDARC):
           w_current->inside_action = 0;
           i_set_state(w_current, DRAWARC);
-          o_arc_eraserubber(w_current);
+          o_arc_invalidate_rubber (w_current);
           break;
 
         default:
@@ -574,7 +574,7 @@ gint x_event_button_released(GtkWidget *widget, GdkEventButton *event,
         /* having this stay in copy was driving me nuts*/
         w_current->inside_action = 1;
         /* Keep the state and the inside_action, as the copy has not finished. */
-        o_place_rubberplace_xor (w_current, TRUE);
+        o_place_invalidate_rubber (w_current, TRUE);
         w_current->rubber_visible = 1;
         i_set_state(w_current, ENDMCOPY);
         i_update_toolbar(w_current);
@@ -621,10 +621,11 @@ gint x_event_button_released(GtkWidget *widget, GdkEventButton *event,
           w_current->event_state == ENDPASTE ) {
 
         if (w_current->event_state == ENDMOVE) {
-          o_move_rubbermove_xor (w_current, FALSE);
+          o_move_invalidate_rubber (w_current, FALSE);
         } else {
-          o_place_rubberplace_xor (w_current, FALSE);
+          o_place_invalidate_rubber (w_current, FALSE);
         }
+        w_current->rubber_visible = 0;
 
         o_place_rotate(w_current);
 
@@ -638,10 +639,11 @@ gint x_event_button_released(GtkWidget *widget, GdkEventButton *event,
         }
 
         if (w_current->event_state == ENDMOVE) {
-          o_move_rubbermove_xor (w_current, TRUE);
+          o_move_invalidate_rubber (w_current, TRUE);
         } else {
-          o_place_rubberplace_xor (w_current, TRUE);
+          o_place_invalidate_rubber (w_current, TRUE);
         }
+        w_current->rubber_visible = 1;
         return(0);
       }
     }

commit 883bb3377a83623fe47792aabe8023c556de25f3
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Date:   Sat Dec 20 08:25:10 2008 +0000

    gschem: Remove the dummy o_cue_invalidate*() functions
    
    Actually invalidate the objects which would have had their cues
    redrawn using o_invalidate() and o_invalidate_glist() instead.
    
    We're probably invalidating more than we need to in some cases,
    since just invalidating a single object will be enough to update
    any cues it is touching. We don't really need to invalidate its
    connected objects as well.

diff --git a/gschem/include/prototype.h b/gschem/include/prototype.h
index d609a23..04ff977 100644
--- a/gschem/include/prototype.h
+++ b/gschem/include/prototype.h
@@ -553,8 +553,6 @@ void o_cue_draw_lowlevel(GSCHEM_TOPLEVEL *w_current, OBJECT *object, int whichon
 void o_cue_draw_lowlevel_midpoints(GSCHEM_TOPLEVEL *w_current, OBJECT *object);
 void o_cue_draw_single(GSCHEM_TOPLEVEL *w_current, OBJECT *object);
 void o_cue_draw_list(GSCHEM_TOPLEVEL *w_current, GList *object_list);
-void o_cue_invalidate(GSCHEM_TOPLEVEL *w_current, OBJECT *object);
-void o_cue_invalidate_glist(GSCHEM_TOPLEVEL *w_current, GList *obj_list);
 /* o_delete.c */
 void o_delete(GSCHEM_TOPLEVEL *w_current, OBJECT *object);
 void o_delete_selected(GSCHEM_TOPLEVEL *w_current);
diff --git a/gschem/src/o_bus.c b/gschem/src/o_bus.c
index 22a5b73..b0f58ed 100644
--- a/gschem/src/o_bus.c
+++ b/gschem/src/o_bus.c
@@ -256,9 +256,8 @@ int o_bus_end(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
 
   /* connect the new bus to the other busses */
   prev_conn_objects = s_conn_return_others (prev_conn_objects, new_obj);
-  o_cue_invalidate_glist (w_current, prev_conn_objects);
+  o_invalidate_glist (w_current, prev_conn_objects);
   g_list_free (prev_conn_objects);
-  o_cue_invalidate (w_current, new_obj);
 
   toplevel->page_current->CHANGED=1;
   w_current->first_wx = w_current->second_wx;
diff --git a/gschem/src/o_cue.c b/gschem/src/o_cue.c
index 8203700..1cbed30 100644
--- a/gschem/src/o_cue.c
+++ b/gschem/src/o_cue.c
@@ -377,33 +377,3 @@ void o_cue_draw_list(GSCHEM_TOPLEVEL *w_current, GList *object_list)
     ol_current = g_list_next(ol_current);
   }
 }
-
-
-/*! \brief Invalidate the area where an OBJECT's cues would be drawn
- *
- *  \par Function Description
- *  NOP: At present, cue invalidation is accounted for by a bloat applied
- *       when invalidating the world bounds of an object.
- *
- *  \param [in] w_current  The GSCHEM_TOPLEVEL
- *  \param [in] object     The OBJECT whos cues are being invalidated
- */
-void o_cue_invalidate (GSCHEM_TOPLEVEL *w_current, OBJECT *object)
-{
-  /* NOP */
-}
-
-
-/*! \brief Invalidate the area where cues would be drawn for a GList of OBJECTS
- *
- *  \par Function Description
- *  NOP: At present, cue invalidation is accounted for by a bloat applied
- *       when invalidating the world bounds of object lists.
- *
- *  \param [in] w_current  The GSCHEM_TOPLEVEL
- *  \param [in] object     The OBJECT whos cues are being invalidated
- */
-void o_cue_invalidate_glist (GSCHEM_TOPLEVEL *w_current, GList *obj_list)
-{
-  /* NOP */
-}
diff --git a/gschem/src/o_delete.c b/gschem/src/o_delete.c
index 1f63c10..9766a2b 100644
--- a/gschem/src/o_delete.c
+++ b/gschem/src/o_delete.c
@@ -49,7 +49,6 @@ void o_delete (GSCHEM_TOPLEVEL *w_current, OBJECT *object)
     object->type == OBJ_PIN || object->type == OBJ_COMPLEX;
   
   if (do_conn) {
-    o_cue_invalidate (w_current, object);
     prev_conn_objects = s_conn_return_others (prev_conn_objects, object);
 
     /* Check for complex which self-connects, e.g. coincident pins.
@@ -63,7 +62,7 @@ void o_delete (GSCHEM_TOPLEVEL *w_current, OBJECT *object)
           prev_conn_objects = g_list_delete_link (prev_conn_objects, iter);
       }
     }
-    o_cue_invalidate_glist (w_current, prev_conn_objects);
+    o_invalidate_glist (w_current, prev_conn_objects);
     g_list_free (prev_conn_objects);
   }
   o_invalidate (w_current, object);
diff --git a/gschem/src/o_grips.c b/gschem/src/o_grips.c
index d5f7420..bac236a 100644
--- a/gschem/src/o_grips.c
+++ b/gschem/src/o_grips.c
@@ -1354,7 +1354,6 @@ void o_grips_end_net(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int whichone
   }
 
   /* remove the old net */
-  o_cue_invalidate (w_current, o_current);
   o_invalidate (w_current, o_current);
 
   prev_conn_objects = s_conn_return_others (prev_conn_objects, o_current);
@@ -1368,17 +1367,10 @@ void o_grips_end_net(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int whichone
   connected_objects = s_conn_return_others(connected_objects,
 					   o_current);
   /* add bus rippers if necessary */
-  if (o_net_add_busrippers(w_current, o_current, connected_objects)) {
-
-    o_invalidate (w_current, o_current);
-    o_cue_invalidate(w_current, o_current);
-
-    o_invalidate (w_current, o_current);
-    o_cue_invalidate(w_current, o_current);
-  }
+  o_net_add_busrippers(w_current, o_current, connected_objects);
 
   /* draw the object objects */
-  o_cue_invalidate_glist (w_current, prev_conn_objects);
+  o_invalidate_glist (w_current, prev_conn_objects);
   
   o_invalidate (w_current, o_current);
   
@@ -1389,9 +1381,7 @@ void o_grips_end_net(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int whichone
   connected_objects = s_conn_return_others(connected_objects,
 					   o_current);
   
-  o_cue_invalidate_glist (w_current, connected_objects);
-  /* finally draw this objects cues */
-  o_cue_invalidate (w_current, o_current);
+  o_invalidate_glist (w_current, connected_objects);
 
   g_list_free (prev_conn_objects);
   prev_conn_objects = NULL;
@@ -1434,7 +1424,6 @@ void o_grips_end_pin(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int whichone
   }
 
   /* erase old pin object */
-  o_cue_invalidate (w_current, o_current);
   o_invalidate (w_current, o_current);
 
   prev_conn_objects = s_conn_return_others (prev_conn_objects, o_current);
@@ -1446,15 +1435,12 @@ void o_grips_end_pin(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int whichone
   o_invalidate (w_current, o_current);
 
   /* redraw the object connections */
-  o_cue_invalidate_glist (w_current, prev_conn_objects);
+  o_invalidate_glist (w_current, prev_conn_objects);
 
   /* get the other connected objects and redraw them */
   connected_objects = s_conn_return_others(connected_objects,
 					   o_current);
-  o_cue_invalidate_glist (w_current, connected_objects);
-
-  /* finally draw this objects cues */
-  o_cue_invalidate (w_current, o_current);
+  o_invalidate_glist (w_current, connected_objects);
 
   /* free the two lists */
   g_list_free (prev_conn_objects);
@@ -1498,7 +1484,6 @@ void o_grips_end_bus(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int whichone
   }
 
   /* erase the old bus and it's cues */
-  o_cue_invalidate (w_current, o_current);
   o_invalidate (w_current, o_current);
 
   prev_conn_objects = s_conn_return_others (prev_conn_objects, o_current);
@@ -1510,15 +1495,12 @@ void o_grips_end_bus(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int whichone
   o_invalidate (w_current, o_current);
 
   /* redraw the connected objects */
-  o_cue_invalidate_glist (w_current, prev_conn_objects);
+  o_invalidate_glist (w_current, prev_conn_objects);
 
   /* get the other connected objects and redraw them */
   connected_objects = s_conn_return_others(connected_objects,
 					   o_current);
-  o_cue_invalidate_glist (w_current, connected_objects);
-
-  /* finally draw this objects cues */
-  o_cue_invalidate (w_current, o_current);
+  o_invalidate_glist (w_current, connected_objects);
 
   /* free the two lists */
   g_list_free (prev_conn_objects);
diff --git a/gschem/src/o_misc.c b/gschem/src/o_misc.c
index d5f308e..3444600 100644
--- a/gschem/src/o_misc.c
+++ b/gschem/src/o_misc.c
@@ -202,7 +202,6 @@ void o_rotate_world_update(GSCHEM_TOPLEVEL *w_current,
   }
 
   if (!toplevel->DONT_REDRAW) {
-    o_cue_invalidate_glist (w_current, list);
     o_invalidate_glist (w_current, list);
   }
 
@@ -232,9 +231,8 @@ void o_rotate_world_update(GSCHEM_TOPLEVEL *w_current,
 
   if (!toplevel->DONT_REDRAW) {
     o_invalidate_glist (w_current, list);
-    o_cue_invalidate_glist (w_current, prev_conn_objects);
-    o_cue_invalidate_glist (w_current, connected_objects);
-    o_cue_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);
@@ -305,7 +303,6 @@ void o_mirror_world_update(GSCHEM_TOPLEVEL *w_current, int centerx, int centery,
     return;
   }
 
-  o_cue_invalidate_glist (w_current, list);
   o_invalidate_glist (w_current, list);
 
   /* Find connected objects, removing each object in turn from the
@@ -333,9 +330,8 @@ void o_mirror_world_update(GSCHEM_TOPLEVEL *w_current, int centerx, int centery,
   }
 
   o_invalidate_glist (w_current, list);
-  o_cue_invalidate_glist (w_current, prev_conn_objects);
-  o_cue_invalidate_glist (w_current, connected_objects);
-  o_cue_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;
diff --git a/gschem/src/o_move.c b/gschem/src/o_move.c
index bbee4bd..0582844 100644
--- a/gschem/src/o_move.c
+++ b/gschem/src/o_move.c
@@ -239,14 +239,13 @@ void o_move_end(GSCHEM_TOPLEVEL *w_current)
   /* Draw the objects that were moved (and connected/disconnected objects) */
   o_invalidate_glist (w_current,
     geda_list_get_glist (toplevel->page_current->selection_list));
-  o_cue_invalidate_glist (w_current, prev_conn_objects);
-  o_cue_invalidate_glist (w_current, connected_objects);
+  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_cue_invalidate_glist (w_current, rubbernet_objects);
-  o_cue_invalidate_glist (w_current, rubbernet_prev_conn_objects);
-  o_cue_invalidate_glist (w_current, rubbernet_connected_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);
diff --git a/gschem/src/o_net.c b/gschem/src/o_net.c
index e2cd89b..ea918db 100644
--- a/gschem/src/o_net.c
+++ b/gschem/src/o_net.c
@@ -717,8 +717,7 @@ int o_net_end(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
 
       o_invalidate (w_current, new_net);
 
-      o_cue_invalidate_glist (w_current, prev_conn_objects);
-      o_cue_invalidate (w_current, new_net);
+      o_invalidate_glist (w_current, prev_conn_objects);
 
       g_list_free (prev_conn_objects);
       prev_conn_objects = NULL;
@@ -767,8 +766,7 @@ int o_net_end(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
 
       o_invalidate (w_current, new_net);
 
-      o_cue_invalidate_glist (w_current, prev_conn_objects);
-      o_cue_invalidate (w_current, new_net);
+      o_invalidate_glist (w_current, prev_conn_objects);
 
       g_list_free (prev_conn_objects);
       prev_conn_objects = NULL;
diff --git a/gschem/src/o_pin.c b/gschem/src/o_pin.c
index 07386c4..2be22da 100644
--- a/gschem/src/o_pin.c
+++ b/gschem/src/o_pin.c
@@ -198,9 +198,8 @@ void o_pin_end(GSCHEM_TOPLEVEL *w_current, int x, int y)
 
   /* look for connected objects */
   prev_conn_objects = s_conn_return_others(prev_conn_objects, o_current_pin);
-  o_cue_invalidate_glist (w_current, prev_conn_objects);
+  o_invalidate_glist (w_current, prev_conn_objects);
   g_list_free (prev_conn_objects);
-  o_cue_invalidate (w_current, o_current_pin);
   o_invalidate (w_current, o_current_pin);
 
   toplevel->page_current->CHANGED=1;
diff --git a/gschem/src/o_place.c b/gschem/src/o_place.c
index 002213f..318de9f 100644
--- a/gschem/src/o_place.c
+++ b/gschem/src/o_place.c
@@ -108,8 +108,7 @@ void o_place_end (GSCHEM_TOPLEVEL *w_current,
     connected_objects = s_conn_return_others (connected_objects, o_current);
   }
 
-  o_cue_invalidate_glist (w_current, temp_dest_list);
-  o_cue_invalidate_glist (w_current, connected_objects);
+  o_invalidate_glist (w_current, connected_objects);
   g_list_free (connected_objects);
   connected_objects = NULL;
 

commit b64b7ce3970d819173e20578e9adf91b19179068
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Date:   Sat Dec 20 08:25:09 2008 +0000

    gschem: Replace o_cue_erase_single() by o_cue_invalidate()
    
    We don't want to be drawing anything onto the screen outside of the
    expose handler. o_cue_invalidate() is actually a NOP, since we actually
    invalidate enough around a given object to encompass redrawing of its
    cues.

diff --git a/gschem/include/prototype.h b/gschem/include/prototype.h
index a28d728..d609a23 100644
--- a/gschem/include/prototype.h
+++ b/gschem/include/prototype.h
@@ -550,13 +550,11 @@ void o_copy_multiple_end(GSCHEM_TOPLEVEL *w_current);
 /* o_cue.c */
 void o_cue_redraw_all(GSCHEM_TOPLEVEL *w_current, GList *list, gboolean draw_selected);
 void o_cue_draw_lowlevel(GSCHEM_TOPLEVEL *w_current, OBJECT *object, int whichone);
-void o_cue_erase_lowlevel(GSCHEM_TOPLEVEL *w_current, OBJECT *object, int whichone);
 void o_cue_draw_lowlevel_midpoints(GSCHEM_TOPLEVEL *w_current, OBJECT *object);
 void o_cue_draw_single(GSCHEM_TOPLEVEL *w_current, OBJECT *object);
-void o_cue_erase_single(GSCHEM_TOPLEVEL *w_current, OBJECT *object);
-void o_cue_undraw(GSCHEM_TOPLEVEL *w_current, OBJECT *object);
 void o_cue_draw_list(GSCHEM_TOPLEVEL *w_current, GList *object_list);
-void o_cue_undraw_list(GSCHEM_TOPLEVEL *w_current, GList *object_list);
+void o_cue_invalidate(GSCHEM_TOPLEVEL *w_current, OBJECT *object);
+void o_cue_invalidate_glist(GSCHEM_TOPLEVEL *w_current, GList *obj_list);
 /* o_delete.c */
 void o_delete(GSCHEM_TOPLEVEL *w_current, OBJECT *object);
 void o_delete_selected(GSCHEM_TOPLEVEL *w_current);
diff --git a/gschem/src/o_bus.c b/gschem/src/o_bus.c
index 3a5bb57..22a5b73 100644
--- a/gschem/src/o_bus.c
+++ b/gschem/src/o_bus.c
@@ -256,10 +256,9 @@ int o_bus_end(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
 
   /* connect the new bus to the other busses */
   prev_conn_objects = s_conn_return_others (prev_conn_objects, new_obj);
-  o_cue_undraw_list (w_current, prev_conn_objects);
-  o_cue_draw_list (w_current, prev_conn_objects);
+  o_cue_invalidate_glist (w_current, prev_conn_objects);
   g_list_free (prev_conn_objects);
-  o_cue_draw_single (w_current, new_obj);
+  o_cue_invalidate (w_current, new_obj);
 
   toplevel->page_current->CHANGED=1;
   w_current->first_wx = w_current->second_wx;
diff --git a/gschem/src/o_cue.c b/gschem/src/o_cue.c
index 0d65a8e..8203700 100644
--- a/gschem/src/o_cue.c
+++ b/gschem/src/o_cue.c
@@ -272,41 +272,6 @@ void o_cue_draw_lowlevel(GSCHEM_TOPLEVEL *w_current, OBJECT *object, int whichon
   
 }
 
-/*! \brief Lowlevel endpoint erase.
- *  \par Function Description
- *  This function erases OBJECT endpoints forceably.
- *
- *  \param [in] w_current  The GSCHEM_TOPLEVEL object.
- *  \param [in] object     OBJECT to forceably erase endpoint from.
- *  \param [in] whichone   Which endpoint to erase from OBJECT.
- */
-void o_cue_erase_lowlevel(GSCHEM_TOPLEVEL *w_current, OBJECT *object, int whichone)
-{
-  TOPLEVEL *toplevel = w_current->toplevel;
-  int x, y, screen_x, screen_y;
-  int size, x2size;
-  
-  x = object->line->x[whichone];
-  y = object->line->y[whichone];
-
-  size = SCREENabs(toplevel, CUE_BOX_SIZE);
-  x2size = 2 * size;
-
-  gdk_gc_set_foreground(w_current->gc,
-                        x_get_color(toplevel->background_color));
- 
-  WORLDtoSCREEN(toplevel, x, y, &screen_x, &screen_y);
-  
-  if (toplevel->DONT_REDRAW == 0) {
-    gdk_draw_rectangle (w_current->drawable,
-                        w_current->gc, TRUE,
-                        screen_x - size,
-                        screen_y - size,
-                        x2size,
-                        x2size);
-  }
-
-}
 
 /*! \todo Finish function documentation!!!
  *  \brief
@@ -392,102 +357,6 @@ void o_cue_draw_single(GSCHEM_TOPLEVEL *w_current, OBJECT *object)
   }
 }
 
-/*! \todo Finish function documentation!!!
- *  \brief
- *  \par Function Description
- *
- */
-void o_cue_erase_single(GSCHEM_TOPLEVEL *w_current, OBJECT *object)
-{
-  TOPLEVEL *toplevel = w_current->toplevel;
-  if (!object) {
-    return;
-  }
-
-  if (object->type != OBJ_NET && object->type != OBJ_PIN &&
-      object->type != OBJ_BUS)
-  {
-    return;
-  }
-
-  if (object->type != OBJ_PIN) {
-    o_cue_erase_lowlevel(w_current, object, 0);
-    o_cue_erase_lowlevel(w_current, object, 1);
-    toplevel->override_color = toplevel->background_color;
-    o_cue_draw_lowlevel_midpoints(w_current, object);
-    toplevel->override_color = -1;
-  } else {
-    o_cue_erase_lowlevel(w_current, object, object->whichend);
-  }
-}
-
-/*! \brief Erase the cues of an object and redraw connected objects.
- *  \par Function Description
- *  This function erases the cues on object \a object. It then redraws
- *  the cues of its connected objects.
- *
- *  \param [in] w_current The GSCHEM_TOPLEVEL object.
- *  \param [in] object    The object to redraw with no cue.
- */
-static void o_cue_undraw_lowlevel(GSCHEM_TOPLEVEL *w_current, OBJECT *object)
-{
-  GList *cl_current;
-  CONN *conn;
-
-  o_cue_erase_single(w_current, object);
-
-  cl_current = object->conn_list;
-  while(cl_current != NULL) {
-    conn = (CONN *) cl_current->data;
-
-    if (conn->other_object) {
-      o_invalidate (w_current, conn->other_object);
-    }
-
-    cl_current = g_list_next(cl_current);
-  }
-}
-
-/*! \brief Hide the cues of an object.
- *  \par Function Description
- *  This function takes an object and redraws it without its cues. It
- *  also manages the redraw of connected objects.
- *
- *  \note
- *  The connections of the object are unchanged by this function.
- *
- *  \param [in] w_current The GSCHEM_TOPLEVEL object.
- *  \param [in] object    The object to redraw with no cue.
- */
-void o_cue_undraw(GSCHEM_TOPLEVEL *w_current, OBJECT *object)
-{
-  GList *iter;
-  switch (object->type) {
-    case OBJ_PIN:
-    case OBJ_NET:
-    case OBJ_BUS:
-      o_cue_undraw_lowlevel (w_current, object);
-      break;
-    case OBJ_COMPLEX:
-    case OBJ_PLACEHOLDER:
-    {
-      OBJECT *o_current;
-      iter = object->complex->prim_objs;
-      for (iter = object->complex->prim_objs;
-           iter != NULL;
-           iter = g_list_next (iter)) {
-        o_current = iter->data;
-        if (o_current->type == OBJ_PIN ||
-            o_current->type == OBJ_NET ||
-            o_current->type == OBJ_BUS) {
-          o_cue_undraw_lowlevel (w_current, o_current);
-        }
-      }
-    }
-  }
-
-  o_invalidate (w_current, object);
-}
 
 /*! \todo Finish function documentation!!!
  *  \brief
@@ -509,23 +378,32 @@ void o_cue_draw_list(GSCHEM_TOPLEVEL *w_current, GList *object_list)
   }
 }
 
-/*! \todo Finish function documentation!!!
- *  \brief
+
+/*! \brief Invalidate the area where an OBJECT's cues would be drawn
+ *
  *  \par Function Description
+ *  NOP: At present, cue invalidation is accounted for by a bloat applied
+ *       when invalidating the world bounds of an object.
  *
+ *  \param [in] w_current  The GSCHEM_TOPLEVEL
+ *  \param [in] object     The OBJECT whos cues are being invalidated
  */
-void o_cue_undraw_list(GSCHEM_TOPLEVEL *w_current, GList *object_list)
+void o_cue_invalidate (GSCHEM_TOPLEVEL *w_current, OBJECT *object)
 {
-  OBJECT *object;
-  GList *ol_current;
+  /* NOP */
+}
 
-  ol_current = object_list;
-  while(ol_current != NULL) {
-    object = (OBJECT *) ol_current->data;
 
-    o_cue_undraw(w_current, object);
-    
-    ol_current = g_list_next(ol_current);
-  }
+/*! \brief Invalidate the area where cues would be drawn for a GList of OBJECTS
+ *
+ *  \par Function Description
+ *  NOP: At present, cue invalidation is accounted for by a bloat applied
+ *       when invalidating the world bounds of object lists.
+ *
+ *  \param [in] w_current  The GSCHEM_TOPLEVEL
+ *  \param [in] object     The OBJECT whos cues are being invalidated
+ */
+void o_cue_invalidate_glist (GSCHEM_TOPLEVEL *w_current, GList *obj_list)
+{
+  /* NOP */
 }
-
diff --git a/gschem/src/o_delete.c b/gschem/src/o_delete.c
index 8ad40a7..1f63c10 100644
--- a/gschem/src/o_delete.c
+++ b/gschem/src/o_delete.c
@@ -49,7 +49,7 @@ void o_delete (GSCHEM_TOPLEVEL *w_current, OBJECT *object)
     object->type == OBJ_PIN || object->type == OBJ_COMPLEX;
   
   if (do_conn) {
-    o_cue_undraw (w_current, object);
+    o_cue_invalidate (w_current, object);
     prev_conn_objects = s_conn_return_others (prev_conn_objects, object);
 
     /* Check for complex which self-connects, e.g. coincident pins.
@@ -63,18 +63,14 @@ void o_delete (GSCHEM_TOPLEVEL *w_current, OBJECT *object)
           prev_conn_objects = g_list_delete_link (prev_conn_objects, iter);
       }
     }
+    o_cue_invalidate_glist (w_current, prev_conn_objects);
+    g_list_free (prev_conn_objects);
   }
   o_invalidate (w_current, object);
 
   s_page_remove (toplevel->page_current, object);
   s_delete_object (toplevel, object);
 
-  if (do_conn) {
-    o_cue_undraw_list (w_current, prev_conn_objects);
-    o_cue_draw_list (w_current, prev_conn_objects);
-    g_list_free (prev_conn_objects);
-  }
-
   toplevel->page_current->CHANGED = 1;
 }
 
diff --git a/gschem/src/o_grips.c b/gschem/src/o_grips.c
index 5f27339..d5f7420 100644
--- a/gschem/src/o_grips.c
+++ b/gschem/src/o_grips.c
@@ -1354,7 +1354,7 @@ void o_grips_end_net(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int whichone
   }
 
   /* remove the old net */
-  o_cue_undraw(w_current, o_current);
+  o_cue_invalidate (w_current, o_current);
   o_invalidate (w_current, o_current);
 
   prev_conn_objects = s_conn_return_others (prev_conn_objects, o_current);
@@ -1371,15 +1371,14 @@ void o_grips_end_net(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int whichone
   if (o_net_add_busrippers(w_current, o_current, connected_objects)) {
 
     o_invalidate (w_current, o_current);
-    o_cue_undraw(w_current, o_current);
+    o_cue_invalidate(w_current, o_current);
 
     o_invalidate (w_current, o_current);
-    o_cue_draw_single(w_current, o_current);
+    o_cue_invalidate(w_current, o_current);
   }
 
   /* draw the object objects */
-  o_cue_undraw_list (w_current, prev_conn_objects);
-  o_cue_draw_list (w_current, prev_conn_objects);
+  o_cue_invalidate_glist (w_current, prev_conn_objects);
   
   o_invalidate (w_current, o_current);
   
@@ -1390,10 +1389,9 @@ void o_grips_end_net(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int whichone
   connected_objects = s_conn_return_others(connected_objects,
 					   o_current);
   
-  o_cue_undraw_list(w_current, connected_objects);
-  o_cue_draw_list(w_current, connected_objects);
+  o_cue_invalidate_glist (w_current, connected_objects);
   /* finally draw this objects cues */
-  o_cue_draw_single(w_current, o_current);
+  o_cue_invalidate (w_current, o_current);
 
   g_list_free (prev_conn_objects);
   prev_conn_objects = NULL;
@@ -1436,7 +1434,7 @@ void o_grips_end_pin(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int whichone
   }
 
   /* erase old pin object */
-  o_cue_undraw(w_current, o_current);
+  o_cue_invalidate (w_current, o_current);
   o_invalidate (w_current, o_current);
 
   prev_conn_objects = s_conn_return_others (prev_conn_objects, o_current);
@@ -1448,17 +1446,15 @@ void o_grips_end_pin(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int whichone
   o_invalidate (w_current, o_current);
 
   /* redraw the object connections */
-  o_cue_undraw_list (w_current, prev_conn_objects);
-  o_cue_draw_list (w_current, prev_conn_objects);
+  o_cue_invalidate_glist (w_current, prev_conn_objects);
 
   /* get the other connected objects and redraw them */
   connected_objects = s_conn_return_others(connected_objects,
 					   o_current);
-  o_cue_undraw_list(w_current, connected_objects);
-  o_cue_draw_list(w_current, connected_objects);
+  o_cue_invalidate_glist (w_current, connected_objects);
 
   /* finally draw this objects cues */
-  o_cue_draw_single(w_current, o_current);
+  o_cue_invalidate (w_current, o_current);
 
   /* free the two lists */
   g_list_free (prev_conn_objects);
@@ -1502,7 +1498,7 @@ void o_grips_end_bus(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int whichone
   }
 
   /* erase the old bus and it's cues */
-  o_cue_undraw(w_current, o_current);
+  o_cue_invalidate (w_current, o_current);
   o_invalidate (w_current, o_current);
 
   prev_conn_objects = s_conn_return_others (prev_conn_objects, o_current);
@@ -1514,17 +1510,15 @@ void o_grips_end_bus(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int whichone
   o_invalidate (w_current, o_current);
 
   /* redraw the connected objects */
-  o_cue_undraw_list (w_current, prev_conn_objects);
-  o_cue_draw_list (w_current, prev_conn_objects);
+  o_cue_invalidate_glist (w_current, prev_conn_objects);
 
   /* get the other connected objects and redraw them */
   connected_objects = s_conn_return_others(connected_objects,
 					   o_current);
-  o_cue_undraw_list(w_current, connected_objects);
-  o_cue_draw_list(w_current, connected_objects);
+  o_cue_invalidate_glist (w_current, connected_objects);
 
   /* finally draw this objects cues */
-  o_cue_draw_single(w_current, o_current);
+  o_cue_invalidate (w_current, o_current);
 
   /* free the two lists */
   g_list_free (prev_conn_objects);
diff --git a/gschem/src/o_misc.c b/gschem/src/o_misc.c
index 0c6112b..d5f308e 100644
--- a/gschem/src/o_misc.c
+++ b/gschem/src/o_misc.c
@@ -202,7 +202,7 @@ void o_rotate_world_update(GSCHEM_TOPLEVEL *w_current,
   }
 
   if (!toplevel->DONT_REDRAW) {
-    o_cue_undraw_list (w_current, list);
+    o_cue_invalidate_glist (w_current, list);
     o_invalidate_glist (w_current, list);
   }
 
@@ -232,11 +232,9 @@ void o_rotate_world_update(GSCHEM_TOPLEVEL *w_current,
 
   if (!toplevel->DONT_REDRAW) {
     o_invalidate_glist (w_current, list);
-    o_cue_undraw_list (w_current, prev_conn_objects);
-    o_cue_draw_list (w_current, prev_conn_objects);
-    o_cue_undraw_list(w_current, connected_objects);
-    o_cue_draw_list(w_current, connected_objects);
-    o_cue_draw_list(w_current, list);
+    o_cue_invalidate_glist (w_current, prev_conn_objects);
+    o_cue_invalidate_glist (w_current, connected_objects);
+    o_cue_invalidate_glist (w_current, list);
   }
 
   g_list_free (prev_conn_objects);
@@ -307,7 +305,7 @@ void o_mirror_world_update(GSCHEM_TOPLEVEL *w_current, int centerx, int centery,
     return;
   }
 
-  o_cue_undraw_list (w_current, list);
+  o_cue_invalidate_glist (w_current, list);
   o_invalidate_glist (w_current, list);
 
   /* Find connected objects, removing each object in turn from the
@@ -335,11 +333,9 @@ void o_mirror_world_update(GSCHEM_TOPLEVEL *w_current, int centerx, int centery,
   }
 
   o_invalidate_glist (w_current, list);
-  o_cue_undraw_list (w_current, prev_conn_objects);
-  o_cue_draw_list (w_current, prev_conn_objects);
-  o_cue_undraw_list(w_current, connected_objects);
-  o_cue_draw_list(w_current, connected_objects);
-  o_cue_draw_list(w_current, list);
+  o_cue_invalidate_glist (w_current, prev_conn_objects);
+  o_cue_invalidate_glist (w_current, connected_objects);
+  o_cue_invalidate_glist (w_current, list);
 
   g_list_free (prev_conn_objects);
   prev_conn_objects = NULL;
diff --git a/gschem/src/o_move.c b/gschem/src/o_move.c
index b3a4d8e..bbee4bd 100644
--- a/gschem/src/o_move.c
+++ b/gschem/src/o_move.c
@@ -239,19 +239,14 @@ void o_move_end(GSCHEM_TOPLEVEL *w_current)
   /* Draw the objects that were moved (and connected/disconnected objects) */
   o_invalidate_glist (w_current,
     geda_list_get_glist (toplevel->page_current->selection_list));
-  o_cue_undraw_list(w_current, prev_conn_objects);
-  o_cue_draw_list(w_current, prev_conn_objects);
-  o_cue_undraw_list(w_current, connected_objects);
-  o_cue_draw_list(w_current, connected_objects);
+  o_cue_invalidate_glist (w_current, prev_conn_objects);
+  o_cue_invalidate_glist (w_current, connected_objects);
 
   /* Draw the connected nets/buses that were also changed */
   o_invalidate_glist (w_current, rubbernet_objects);
-  o_cue_undraw_list(w_current, rubbernet_objects);
-  o_cue_draw_list(w_current, rubbernet_objects);
-  o_cue_undraw_list(w_current, rubbernet_prev_conn_objects);
-  o_cue_draw_list(w_current, rubbernet_prev_conn_objects);
-  o_cue_undraw_list(w_current, rubbernet_connected_objects);
-  o_cue_draw_list(w_current, rubbernet_connected_objects);
+  o_cue_invalidate_glist (w_current, rubbernet_objects);
+  o_cue_invalidate_glist (w_current, rubbernet_prev_conn_objects);
+  o_cue_invalidate_glist (w_current, rubbernet_connected_objects);
  
   toplevel->page_current->CHANGED = 1;
   o_undo_savestate(w_current, UNDO_ALL);
diff --git a/gschem/src/o_net.c b/gschem/src/o_net.c
index 2ebd3e8..e2cd89b 100644
--- a/gschem/src/o_net.c
+++ b/gschem/src/o_net.c
@@ -717,9 +717,8 @@ int o_net_end(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
 
       o_invalidate (w_current, new_net);
 
-      o_cue_undraw_list (w_current, prev_conn_objects);
-      o_cue_draw_list (w_current, prev_conn_objects);
-      o_cue_draw_single(w_current, new_net);
+      o_cue_invalidate_glist (w_current, prev_conn_objects);
+      o_cue_invalidate (w_current, new_net);
 
       g_list_free (prev_conn_objects);
       prev_conn_objects = NULL;
@@ -768,9 +767,8 @@ int o_net_end(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
 
       o_invalidate (w_current, new_net);
 
-      o_cue_undraw_list (w_current, prev_conn_objects);
-      o_cue_draw_list (w_current, prev_conn_objects);
-      o_cue_draw_single(w_current, new_net);
+      o_cue_invalidate_glist (w_current, prev_conn_objects);
+      o_cue_invalidate (w_current, new_net);
 
       g_list_free (prev_conn_objects);
       prev_conn_objects = NULL;
diff --git a/gschem/src/o_pin.c b/gschem/src/o_pin.c
index 3fa3b97..07386c4 100644
--- a/gschem/src/o_pin.c
+++ b/gschem/src/o_pin.c
@@ -197,11 +197,10 @@ void o_pin_end(GSCHEM_TOPLEVEL *w_current, int x, int y)
   }
 
   /* look for connected objects */
-  prev_conn_objects = s_conn_return_others (prev_conn_objects, o_current_pin);
-  o_cue_undraw_list (w_current, prev_conn_objects);
-  o_cue_draw_list (w_current, prev_conn_objects);
+  prev_conn_objects = s_conn_return_others(prev_conn_objects, o_current_pin);
+  o_cue_invalidate_glist (w_current, prev_conn_objects);
   g_list_free (prev_conn_objects);
-  o_cue_draw_single(w_current, o_current_pin); 
+  o_cue_invalidate (w_current, o_current_pin);
   o_invalidate (w_current, o_current_pin);
 
   toplevel->page_current->CHANGED=1;
diff --git a/gschem/src/o_place.c b/gschem/src/o_place.c
index 83a6b9c..002213f 100644
--- a/gschem/src/o_place.c
+++ b/gschem/src/o_place.c
@@ -108,9 +108,8 @@ void o_place_end (GSCHEM_TOPLEVEL *w_current,
     connected_objects = s_conn_return_others (connected_objects, o_current);
   }
 
-  o_cue_redraw_all (w_current, temp_dest_list, TRUE);
-  o_cue_undraw_list (w_current, connected_objects);
-  o_cue_draw_list (w_current, connected_objects);
+  o_cue_invalidate_glist (w_current, temp_dest_list);
+  o_cue_invalidate_glist (w_current, connected_objects);
   g_list_free (connected_objects);
   connected_objects = NULL;
 

commit 0a9650f1c5877d68c792f4c37bc0d47132425c49
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Date:   Sat Dec 20 08:25:07 2008 +0000

    gschem: Move invalidate call from o_move_check_endpoint to o_move_start
    
    This invalidate ensure rubberbanded objects are removed from their old
    position on screen. It is more suited to living in o_move_start() than
    a function supposed to find objects to rubberband.

diff --git a/gschem/src/o_move.c b/gschem/src/o_move.c
index af0f18e..b3a4d8e 100644
--- a/gschem/src/o_move.c
+++ b/gschem/src/o_move.c
@@ -54,13 +54,14 @@ void o_move_start(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
     if (w_current->netconn_rubberband) {
       o_move_prep_rubberband(w_current);
 
-      /* Set the dont_redraw flag on rubberbanded objects.
-       * This ensures that they are not drawn (in their
-       * un-stretched position) during screen updates. */
+      /* Set the dont_redraw flag on rubberbanded objects and invalidate them.
+       * This ensures that they are not drawn (in their un-stretched position)
+       * during screen updates. */
       for (s_iter = toplevel->page_current->stretch_list;
            s_iter != NULL; s_iter = g_list_next (s_iter)) {
         STRETCH *stretch = s_iter->data;
         stretch->object->dont_redraw = TRUE;
+        o_invalidate (w_current, stretch->object);
       }
     }
 
@@ -411,8 +412,6 @@ void o_move_check_endpoint(GSCHEM_TOPLEVEL *w_current, OBJECT * object)
         s_stretch_add (toplevel->page_current->stretch_list,
                        c_current->other_object,
                        c_current, whichone);
-
-      o_invalidate (w_current, c_current->other_object);
     }
   }
 

commit 978a127bf1f7174fd5146371d0cbbfc6a8f2baf8
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Date:   Sat Dec 20 08:25:06 2008 +0000

    Avoid and remove OBJECT variable draw_grips
    
    We can infer the required logic from OBJECT->selected, and the
    resulting code is cleaner.

diff --git a/gschem/src/o_arc.c b/gschem/src/o_arc.c
index fd569eb..2c25ca5 100644
--- a/gschem/src/o_arc.c
+++ b/gschem/src/o_arc.c
@@ -172,13 +172,8 @@ void o_arc_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
                 arc_width, length, space);
 
 
-  if (o_current->draw_grips && w_current->draw_grips == TRUE) {
-    if(!o_current->selected) {
-      o_current->draw_grips = FALSE;
-    } else {
-      /* object is selected, draw the grips on the arc */
-      o_arc_draw_grips(w_current, o_current);
-    }
+  if (o_current->selected && w_current->draw_grips == TRUE) {
+    o_arc_draw_grips (w_current, o_current);
   }
 
 #if DEBUG
diff --git a/gschem/src/o_box.c b/gschem/src/o_box.c
index d08da82..e48d473 100644
--- a/gschem/src/o_box.c
+++ b/gschem/src/o_box.c
@@ -270,13 +270,8 @@ void o_box_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
                 w_current, o_current->box,
                 fill_width, angle1, pitch1, angle2, pitch2);
 
-  if ((o_current->draw_grips == TRUE) && (w_current->draw_grips == TRUE)) {
-    if (!o_current->selected) {
-      o_current->draw_grips = FALSE;
-    } else {
-      /* object is selected, draw the grips on the box */
-      o_box_draw_grips(w_current, o_current);
-    }
+  if (o_current->selected && w_current->draw_grips) {
+    o_box_draw_grips (w_current, o_current);
   }
 }
 
diff --git a/gschem/src/o_bus.c b/gschem/src/o_bus.c
index 57715be..3a5bb57 100644
--- a/gschem/src/o_bus.c
+++ b/gschem/src/o_bus.c
@@ -88,13 +88,8 @@ void o_bus_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
   printf("drawing bus\n");
 #endif
 
-  if (o_current->draw_grips && w_current->draw_grips == TRUE) {
-    if (!o_current->selected) {
-      o_current->draw_grips = FALSE;
-    } else {
-      /* object is selected, draw the grips */
-      o_line_draw_grips(w_current, o_current);
-    }
+  if (o_current->selected && w_current->draw_grips) {
+    o_line_draw_grips (w_current, o_current);
   }
 }
 
diff --git a/gschem/src/o_circle.c b/gschem/src/o_circle.c
index 7ad823e..e743844 100644
--- a/gschem/src/o_circle.c
+++ b/gschem/src/o_circle.c
@@ -259,13 +259,8 @@ void o_circle_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
   printf("drawing circle\n");
 #endif
 
-  if (o_current->draw_grips && w_current->draw_grips == TRUE) {
-    if (!o_current->selected) {
-      o_current->draw_grips = FALSE;
-    } else {
-      /* object is selected, draw the grips */
-      o_circle_draw_grips(w_current, o_current);
-    }
+  if (o_current->selected && w_current->draw_grips) {
+    o_circle_draw_grips (w_current, o_current);
   }
 }
 
diff --git a/gschem/src/o_line.c b/gschem/src/o_line.c
index 3e55c13..01eb452 100644
--- a/gschem/src/o_line.c
+++ b/gschem/src/o_line.c
@@ -165,13 +165,8 @@ void o_line_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
                              GDK_CAP_NOT_LAST,
                              GDK_JOIN_MITER);
 
-  if (o_current->draw_grips && w_current->draw_grips == TRUE) {
-    if (!o_current->selected) {
-      o_current->draw_grips = FALSE;
-    } else {
-      /* object is selected, draw the grips */
-      o_line_draw_grips(w_current, o_current);
-    }
+  if (o_current->selected && w_current->draw_grips) {
+    o_line_draw_grips (w_current, o_current);
   }
 
 #if DEBUG
diff --git a/gschem/src/o_net.c b/gschem/src/o_net.c
index 7685791..2ebd3e8 100644
--- a/gschem/src/o_net.c
+++ b/gschem/src/o_net.c
@@ -160,13 +160,8 @@ void o_net_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
                                GDK_JOIN_MITER);
   }
 
-  if (o_current->draw_grips && w_current->draw_grips == TRUE) {
-    if (!o_current->selected) {
-      o_current->draw_grips = FALSE;
-    } else {
-      /* object is selected, draw the grips */
-      o_line_draw_grips(w_current, o_current);
-    }
+  if (o_current->selected && w_current->draw_grips) {
+    o_line_draw_grips (w_current, o_current);
   }
 }
 
diff --git a/gschem/src/o_path.c b/gschem/src/o_path.c
index a7ecef2..a828e92 100644
--- a/gschem/src/o_path.c
+++ b/gschem/src/o_path.c
@@ -603,13 +603,8 @@ void o_path_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
   (*fill_func) (w_current->drawable, w_current->gc, color,
                 w_current, path, fill_width, angle1, pitch1, angle2, pitch2);
 
-  if (o_current->draw_grips && w_current->draw_grips == TRUE) {
-    if (!o_current->selected) {
-      o_current->draw_grips = FALSE;
-    } else {
-      /* object is selected, draw the grips */
-      o_path_draw_grips(w_current, o_current);
-    }
+  if (o_current->selected && w_current->draw_grips) {
+    o_path_draw_grips (w_current, o_current);
   }
 }
 
diff --git a/gschem/src/o_picture.c b/gschem/src/o_picture.c
index ae8097f..86c8ee5 100644
--- a/gschem/src/o_picture.c
+++ b/gschem/src/o_picture.c
@@ -404,15 +404,10 @@ void o_picture_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
   }
 
   /* Grip specific stuff */
-  if ((o_current->draw_grips == TRUE) && (w_current->draw_grips == TRUE)) {
-      if (!o_current->selected) {
-	o_current->draw_grips = FALSE;
-      } else {
-	/* object is selected, draw the grips on the picture */
-	if (toplevel->DONT_REDRAW == 0) {
-	  o_picture_draw_grips(w_current, o_current); 
-	}
-      }
+  if (o_current->selected && w_current->draw_grips) {
+    if (toplevel->DONT_REDRAW == 0) {
+      o_picture_draw_grips (w_current, o_current);
+    }
   }
 }
 
diff --git a/gschem/src/o_pin.c b/gschem/src/o_pin.c
index 75b0a1e..3fa3b97 100644
--- a/gschem/src/o_pin.c
+++ b/gschem/src/o_pin.c
@@ -87,13 +87,8 @@ void o_pin_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
   printf("drawing pin\n");
 #endif
 
-  if (o_current->draw_grips && w_current->draw_grips == TRUE) {
-    if (!o_current->selected) {
-      o_current->draw_grips = FALSE;
-    } else {
-      /* object is selected, draw the grips */
-      o_line_draw_grips(w_current, o_current);
-    }
+  if (o_current->selected && w_current->draw_grips) {
+    o_line_draw_grips (w_current, o_current);
   }
 }
 
diff --git a/libgeda/include/struct.h b/libgeda/include/struct.h
index 5683897..e686716 100644
--- a/libgeda/include/struct.h
+++ b/libgeda/include/struct.h
@@ -280,9 +280,6 @@ struct st_object {
   /* the object's real color */
   /* when the object is locked) */
 
-  int draw_grips;				/* if selected, enables 
-						   drawing of grips */
-
   /* controls which direction bus rippers go */
   /* it is either 0 for un-inited, */
   /* 1 for right, -1 for left (horizontal bus) */
diff --git a/libgeda/src/o_selection.c b/libgeda/src/o_selection.c
index 616353f..aa7762f 100644
--- a/libgeda/src/o_selection.c
+++ b/libgeda/src/o_selection.c
@@ -115,7 +115,6 @@ void o_selection_select(OBJECT *object, int color)
   }
 
   object->selected = TRUE;
-  object->draw_grips = TRUE;
   object->saved_color = object->color;
   object->color = color;
   if (object->type == OBJ_COMPLEX || object->type == OBJ_PLACEHOLDER) { 
@@ -134,9 +133,6 @@ void o_selection_select(OBJECT *object, int color)
 void o_selection_unselect(OBJECT *object)
 {
   object->selected = FALSE;
-  /* object->draw_grips = FALSE; can't do this here... */
-  /* draw_grips is cleared in the individual draw functions after the */
-  /* grips are erase */
   object->color = object->saved_color;
   if (object->type == OBJ_COMPLEX || object->type == OBJ_PLACEHOLDER) { 
     if (!object->complex) {
diff --git a/libgeda/src/s_basic.c b/libgeda/src/s_basic.c
index 34ac573..ec5118a 100644
--- a/libgeda/src/s_basic.c
+++ b/libgeda/src/s_basic.c
@@ -113,7 +113,6 @@ OBJECT *s_basic_init_object(OBJECT *new_node, int type, char const *name)
   new_node->selected = FALSE;
   new_node->dont_redraw = FALSE;
   new_node->locked_color = -1;
-  new_node->draw_grips = FALSE;
 
   new_node->bus_ripper_direction = 0;
 

commit c9b89c259334c0f310afcc1dc3fb2b752078caad
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Date:   Sat Dec 20 08:25:04 2008 +0000

    Don't ever erase grips, we invalidate things to get rid of them.
    
    Delete now unused function o_erase_grips(), along with the object
    specific routines o_*_erase_grips()

diff --git a/gschem/include/prototype.h b/gschem/include/prototype.h
index 4305db4..a28d728 100644
--- a/gschem/include/prototype.h
+++ b/gschem/include/prototype.h
@@ -473,7 +473,6 @@ void o_arc_end4(GSCHEM_TOPLEVEL *w_current, int radius, int start_angle, int end
 void o_arc_motion(GSCHEM_TOPLEVEL *w_current, int x, int y, int whichone);
 void o_arc_rubberarc_xor(GSCHEM_TOPLEVEL *w_current);
 void o_arc_draw_grips(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current);
-void o_arc_erase_grips(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current);
 /* o_attrib.c */
 void o_attrib_add_selected(GSCHEM_TOPLEVEL *w_current, SELECTION *selection, OBJECT *selected);
 void o_attrib_toggle_visibility(GSCHEM_TOPLEVEL *w_current, OBJECT *object);
@@ -491,7 +490,6 @@ void o_invalidate_rect(GSCHEM_TOPLEVEL *w_current, int x1, int y1, int x2, int y
 void o_invalidate_all(GSCHEM_TOPLEVEL *w_current);
 void o_invalidate(GSCHEM_TOPLEVEL *w_current, OBJECT *object);
 void o_invalidate_glist(GSCHEM_TOPLEVEL *w_current, GList *list);
-void o_erase_grips (GSCHEM_TOPLEVEL *w_current, OBJECT *object);
 /* o_box.c */
 void o_box_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current);
 void o_box_draw_solid(GdkDrawable *w, GdkGC *gc, GdkColor *color, GdkCapStyle cap, gint filled, gint x, gint y, gint width, gint height, gint line_width, gint length, gint space);
@@ -510,7 +508,6 @@ void o_box_end(GSCHEM_TOPLEVEL *w_current, int x, int y);
 void o_box_motion(GSCHEM_TOPLEVEL *w_current, int x, int y);
 void o_box_rubberbox_xor(GSCHEM_TOPLEVEL *w_current);
 void o_box_draw_grips(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current);
-void o_box_erase_grips(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current);
 /* o_buffer.c */
 void o_buffer_copy(GSCHEM_TOPLEVEL *w_current, int buf_num);
 void o_buffer_cut(GSCHEM_TOPLEVEL *w_current, int buf_num);
@@ -539,7 +536,6 @@ void o_circle_end(GSCHEM_TOPLEVEL *w_current, int x, int y);
 void o_circle_motion(GSCHEM_TOPLEVEL *w_current, int x, int y);
 void o_circle_rubbercircle_xor(GSCHEM_TOPLEVEL *w_current);
 void o_circle_draw_grips(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current);
-void o_circle_erase_grips(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current);
 /* o_complex.c */
 void o_complex_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current);
 void o_complex_draw_xor(GSCHEM_TOPLEVEL *w_current, int dx, int dy, OBJECT *complex);
@@ -596,7 +592,6 @@ void o_grips_end_pin(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int whichone
 void o_grips_end_bus(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int whichone);
 int o_grips_size(GSCHEM_TOPLEVEL *w_current);
 void o_grips_draw(GSCHEM_TOPLEVEL *w_current, int x, int y);
-void o_grips_erase(GSCHEM_TOPLEVEL *w_current, int x, int y);
 void o_grips_rubbergrip_xor(GSCHEM_TOPLEVEL *w_current);
 /* o_line.c */
 void o_line_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current);
@@ -612,7 +607,6 @@ void o_line_end(GSCHEM_TOPLEVEL *w_current, int x, int y);
 void o_line_motion(GSCHEM_TOPLEVEL *w_current, int x, int y);
 void o_line_rubberline_xor(GSCHEM_TOPLEVEL *w_current);
 void o_line_draw_grips(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current);
-void o_line_erase_grips(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current);
 /* o_misc.c */
 void o_edit(GSCHEM_TOPLEVEL *w_current, GList *list);
 void o_lock(GSCHEM_TOPLEVEL *w_current);
@@ -664,7 +658,6 @@ void o_picture_eraserubber(GSCHEM_TOPLEVEL *w_current);
 void o_picture_rubberbox_xor(GSCHEM_TOPLEVEL *w_current);
 void o_picture_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current);
 void o_picture_draw_grips(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current);
-void o_picture_erase_grips(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current);
 void o_picture_draw_xor(GSCHEM_TOPLEVEL *w_current, int dx, int dy, OBJECT *o_current);
 void o_picture_exchange(GSCHEM_TOPLEVEL *w_current, GdkPixbuf *pixbuf, const gchar *filename);
 void picture_change_filename_dialog (GSCHEM_TOPLEVEL *w_current);
@@ -679,7 +672,6 @@ void o_path_end(GSCHEM_TOPLEVEL *w_current, int x, int y);
 void o_path_motion(GSCHEM_TOPLEVEL *w_current, int x, int y);
 void o_path_rubberpath_xor(GSCHEM_TOPLEVEL *w_current);
 void o_path_draw_grips(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current);
-void o_path_erase_grips(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current);
 
 /* o_pin.c */
 void o_pin_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current);
diff --git a/gschem/src/o_arc.c b/gschem/src/o_arc.c
index eebdb87..fd569eb 100644
--- a/gschem/src/o_arc.c
+++ b/gschem/src/o_arc.c
@@ -174,9 +174,7 @@ void o_arc_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
 
   if (o_current->draw_grips && w_current->draw_grips == TRUE) {
     if(!o_current->selected) {
-      /* object is no more selected, erase the grips */
       o_current->draw_grips = FALSE;
-      o_arc_erase_grips(w_current, o_current);
     } else {
       /* object is selected, draw the grips on the arc */
       o_arc_draw_grips(w_current, o_current);
@@ -1130,48 +1128,3 @@ void o_arc_draw_grips(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
   o_grips_draw(w_current, x2, y2);
 
 }
-
-/*! \brief Erase grip marks from arc.
- *  \par Function Description
- *  This function erases the three grips displayed on the <B>o_current</B>
- *  arc object. These grips are on the center of the arc and on each end
- *  of the arc.
- *
- *  \param [in] w_current  The GSCHEM_TOPLEVEL object.
- *  \param [in] o_current  Arc OBJECT to remove grip marks from.
- */
-void o_arc_erase_grips(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
-{
-  TOPLEVEL *toplevel = w_current->toplevel;
-  int radius, x, y, start_angle, end_angle;
-  int x1, y1, x2, y2;
-
-  if (w_current->draw_grips == FALSE)
-    return;
-
-  /*
-   * The coordinates of the three grips are determined by the parameters
-   * of the arc. The grips are centered at (<B>x</B>,<B>y</B>), (<B>x1</B>,<B>y1</B>)
-   * and (<B>x2</B>,<B>y2</B>).
-   */
-
-  WORLDtoSCREEN( toplevel, o_current->arc->x, o_current->arc->y, &x, &y );
-  radius      = SCREENabs( toplevel, o_current->arc->width / 2 );
-  start_angle = o_current->arc->start_angle;
-  end_angle   = o_current->arc->end_angle;
-
-  x1 = x + radius * cos(((double) start_angle) * M_PI / 180);
-  y1 = y - radius * sin(((double) start_angle) * M_PI / 180);
-  x2 = x + radius * cos(((double) start_angle + end_angle) * M_PI / 180);
-  y2 = y - radius * sin(((double) start_angle + end_angle) * M_PI / 180);
-
-  /* erase the grip at the center */
-  o_grips_erase(w_current,  x,  y);
-
-  /* erase the grip at the start_angle end of the arc */
-  o_grips_erase(w_current, x1, y1);
-
-  /* erase the grip at the end_angle end of the arc */
-  o_grips_erase(w_current, x2, y2);
-
-}
diff --git a/gschem/src/o_basic.c b/gschem/src/o_basic.c
index 2793f13..f05c436 100644
--- a/gschem/src/o_basic.c
+++ b/gschem/src/o_basic.c
@@ -568,34 +568,3 @@ void o_invalidate_glist (GSCHEM_TOPLEVEL *w_current, GList *list)
     o_invalidate_rect (w_current, s_left, s_top, s_right, s_bottom);
   }
 }
-
-
-/*! \brief Erase grip marks on object.
- *  \par Function Description
- *  This function erases the grips on the object \a object.
- *
- *  \param [in] w_current  The GSCHEM_TOPLEVEL object.
- *  \param [in] object     The object of which to erase the grips.
- */
-void o_erase_grips (GSCHEM_TOPLEVEL *w_current, OBJECT *object)
-{
-  void (*func) (GSCHEM_TOPLEVEL*, OBJECT*) = NULL;
-
-  g_return_if_fail (object != NULL);
-
-  switch (object->type) {
-      case OBJ_ARC:     func = o_arc_erase_grips;     break;
-      case OBJ_BOX:     func = o_box_erase_grips;     break;
-      case OBJ_BUS:
-      case OBJ_LINE:
-      case OBJ_NET:
-      case OBJ_PIN:     func = o_line_erase_grips;    break;
-      case OBJ_CIRCLE:  func = o_circle_erase_grips;  break;
-      case OBJ_PICTURE: func = o_picture_erase_grips; break;
-      case OBJ_PATH:    func = o_path_erase_grips;    break;
-  }
-
-  if (func != NULL) {
-    (*func) (w_current, object);
-  }
-}
diff --git a/gschem/src/o_box.c b/gschem/src/o_box.c
index c7264cf..d08da82 100644
--- a/gschem/src/o_box.c
+++ b/gschem/src/o_box.c
@@ -272,9 +272,7 @@ void o_box_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
 
   if ((o_current->draw_grips == TRUE) && (w_current->draw_grips == TRUE)) {
     if (!o_current->selected) {
-      /* object is no more selected, erase the grips */
       o_current->draw_grips = FALSE;
-      o_box_erase_grips(w_current, o_current);
     } else {
       /* object is selected, draw the grips on the box */
       o_box_draw_grips(w_current, o_current);
@@ -969,39 +967,3 @@ void o_box_draw_grips(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
   o_grips_draw(w_current, s_lower_x, s_lower_y);
 
 }
-
-/*! \brief Erase grip marks from box.
- *  \par Function Description
- *  This function erases the four grips displayed on the <B>*o_current</B>
- *  box object. These grips are on each of the corner.
- * 
- *  \param [in] w_current  The GSCHEM_TOPLEVEL object.
- *  \param [in] o_current  Box OBJECT to erase grip marks from.
- */
-void o_box_erase_grips(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
-{
-  TOPLEVEL *toplevel = w_current->toplevel;
-  int s_upper_x, s_upper_y, s_lower_x, s_lower_y;
-
-  if (w_current->draw_grips == FALSE)
-	  return;
-  
-  WORLDtoSCREEN( toplevel, o_current->box->upper_x, o_current->box->upper_y,
-                 &s_upper_x, &s_upper_y );
-  WORLDtoSCREEN( toplevel, o_current->box->lower_x, o_current->box->lower_y,
-                 &s_lower_x, &s_lower_y );
-
-  /* grip on upper left corner (whichone = BOX_UPPER_LEFT) */
-  o_grips_erase(w_current, s_upper_x, s_upper_y);
-
-  /* grip on upper right corner (whichone = BOX_UPPER_RIGHT) */
-  o_grips_erase(w_current, s_lower_x, s_upper_y);
-  
-  /* grip on lower left corner (whichone = BOX_LOWER_LEFT) */
-  o_grips_erase(w_current, s_upper_x, s_lower_y);
-
-  /* grip on lower right corner (whichone = BOX_LOWER_RIGHT) */
-  o_grips_erase(w_current, s_lower_x, s_lower_y);
-
-}
-
diff --git a/gschem/src/o_bus.c b/gschem/src/o_bus.c
index c1b63f0..57715be 100644
--- a/gschem/src/o_bus.c
+++ b/gschem/src/o_bus.c
@@ -90,9 +90,7 @@ void o_bus_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
 
   if (o_current->draw_grips && w_current->draw_grips == TRUE) {
     if (!o_current->selected) {
-      /* object is no more selected, erase the grips */
       o_current->draw_grips = FALSE;
-      o_line_erase_grips(w_current, o_current);
     } else {
       /* object is selected, draw the grips */
       o_line_draw_grips(w_current, o_current);
diff --git a/gschem/src/o_circle.c b/gschem/src/o_circle.c
index b886adf..7ad823e 100644
--- a/gschem/src/o_circle.c
+++ b/gschem/src/o_circle.c
@@ -261,9 +261,7 @@ void o_circle_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
 
   if (o_current->draw_grips && w_current->draw_grips == TRUE) {
     if (!o_current->selected) {
-      /* object is no more selected, erase the grips */
       o_current->draw_grips = FALSE;
-      o_circle_erase_grips(w_current, o_current);
     } else {
       /* object is selected, draw the grips */
       o_circle_draw_grips(w_current, o_current);
@@ -697,32 +695,3 @@ void o_circle_draw_grips(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
   o_grips_draw(w_current, x, y);
 
 }
-
-/*! \brief Erase grip marks from circle.
- *  \par Function Description
- *  The function erases the grips displayed on a circle object.
- *
- *  A circle has a single grip on the lower right corner of the square it
- *  is inscribed in.
- *
- *  \param [in] w_current  The GSCHEM_TOPLEVEL object.
- *  \param [in] o_current  Circle OBJECT to erase grip marks from.
- */
-void o_circle_erase_grips(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
-{
-  TOPLEVEL *toplevel = w_current->toplevel;
-  int x, y;
-
-  if (w_current->draw_grips == FALSE)
-	  return;
-
-  /* coords of the lower right corner of square */
-  WORLDtoSCREEN( toplevel,
-                 o_current->circle->center_x + o_current->circle->radius,
-                 o_current->circle->center_y - o_current->circle->radius,
-                 &x, &y );
-  
-  /* grip on lower right corner of the square */
-  o_grips_erase(w_current, x, y);
-
-}
diff --git a/gschem/src/o_grips.c b/gschem/src/o_grips.c
index a91a529..5f27339 100644
--- a/gschem/src/o_grips.c
+++ b/gschem/src/o_grips.c
@@ -1628,29 +1628,6 @@ void o_grips_draw(GSCHEM_TOPLEVEL *w_current, int x, int y)
   }
 }
 
-/*! \brief Erase grip centered at <B>x</B>,<B>y</B>
- *  \par Function Description
- *  This function erases a grip centered at (<B>x</B>,<B>y</B>).
- *  The size of the grip depends on the current zoom factor.
- *
- *  The grip is erased by drawing with the background color over the
- *  visible grip.
- *
- *  \param [in] w_current  The GSCHEM_TOPLEVEL object.
- *  \param [in] x          Center x screen coordinate for drawing grip.
- *  \param [in] y          Center y screen coordinate for drawing grip.
- */
-void o_grips_erase(GSCHEM_TOPLEVEL *w_current, int x, int y)
-{
-  TOPLEVEL *toplevel = w_current->toplevel;
-  /* set overriding color */
-  toplevel->override_color = toplevel->background_color;
-  /* draw a grip with backgound color : erase grip */
-  o_grips_draw(w_current, x, y);
-  /* return to default */
-  toplevel->override_color = -1;
-}
-
 
 /*! \brief Draw objects being grip maniuplated from GSCHEM_TOPLEVEL object.
  *
diff --git a/gschem/src/o_line.c b/gschem/src/o_line.c
index de25fb0..3e55c13 100644
--- a/gschem/src/o_line.c
+++ b/gschem/src/o_line.c
@@ -167,9 +167,7 @@ void o_line_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
 
   if (o_current->draw_grips && w_current->draw_grips == TRUE) {
     if (!o_current->selected) {
-      /* object is no more selected, erase the grips */
       o_current->draw_grips = FALSE;
-      o_line_erase_grips(w_current, o_current);
     } else {
       /* object is selected, draw the grips */
       o_line_draw_grips(w_current, o_current);
@@ -921,31 +919,3 @@ void o_line_draw_grips(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
   /* draw the grip on line end 2 */
   o_grips_draw(w_current, x[LINE_END2], y[LINE_END2]);
 }
-
-/*! \brief Erase grip marks from line.
- *  \par Function Description
- *  This function erases the grips on the line object <B>o_current</B>.
- *
- *  A line has a grip at each end.
- *
- *  \param [in] w_current  The GSCHEM_TOPLEVEL object.
- *  \param [in] o_current  Line OBJECT to erase grip marks from.
- */
-void o_line_erase_grips(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
-{
-  TOPLEVEL *toplevel = w_current->toplevel;
-  int x[2], y[2];
-
-  if (w_current->draw_grips == FALSE)
-    return;
-  
-  WORLDtoSCREEN( toplevel, o_current->line->x[0], o_current->line->y[0], &x[0], &y[0] );
-  WORLDtoSCREEN( toplevel, o_current->line->x[1], o_current->line->y[1], &x[1], &y[1] );
-  
-  /* erase the grip on line end 1 */
-  o_grips_erase(w_current, x[LINE_END1], y[LINE_END1]);
-  
-  /* erase the grip on line end 2 */
-  o_grips_erase(w_current, x[LINE_END2], y[LINE_END2]);
-  
-}
diff --git a/gschem/src/o_net.c b/gschem/src/o_net.c
index 7b77537..7685791 100644
--- a/gschem/src/o_net.c
+++ b/gschem/src/o_net.c
@@ -162,9 +162,7 @@ void o_net_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
 
   if (o_current->draw_grips && w_current->draw_grips == TRUE) {
     if (!o_current->selected) {
-      /* object is no more selected, erase the grips */
       o_current->draw_grips = FALSE;
-      o_line_erase_grips(w_current, o_current);
     } else {
       /* object is selected, draw the grips */
       o_line_draw_grips(w_current, o_current);
diff --git a/gschem/src/o_path.c b/gschem/src/o_path.c
index 13176b0..a7ecef2 100644
--- a/gschem/src/o_path.c
+++ b/gschem/src/o_path.c
@@ -605,9 +605,7 @@ void o_path_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
 
   if (o_current->draw_grips && w_current->draw_grips == TRUE) {
     if (!o_current->selected) {
-      /* object is no more selected, erase the grips */
       o_current->draw_grips = FALSE;
-      o_path_erase_grips(w_current, o_current);
     } else {
       /* object is selected, draw the grips */
       o_path_draw_grips(w_current, o_current);
@@ -900,49 +898,3 @@ void o_path_draw_grips(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
     }
   }
 }
-
-
-/*! \brief Erase grip marks from path.
- *  \par Function Description
- *  This function erases the grips on the path object <B>o_current</B>.
- *
- *  A path has a grip at each end.
- *
- *  \param [in] w_current  The GSCHEM_TOPLEVEL object.
- *  \param [in] o_current  Line OBJECT to erase grip marks from.
- */
-void o_path_erase_grips(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
-{
-  TOPLEVEL *toplevel = w_current->toplevel;
-  PATH_SECTION *section;
-  int i;
-  int x, y;
-
-  if (w_current->draw_grips == FALSE)
-    return;
-
-  for (i = 0; i <  o_current->path->num_sections; i++) {
-    section = &o_current->path->sections[i];
-
-    switch (section->code) {
-    case PATH_CURVETO:
-      /* Two control point grips */
-      WORLDtoSCREEN (toplevel, section->x1, section->y1, &x, &y);
-      o_grips_erase (w_current, x, y);
-      WORLDtoSCREEN (toplevel, section->x2, section->y2, &x, &y);
-      o_grips_erase (w_current, x, y);
-      /* Fall through */
-    case PATH_MOVETO:
-    case PATH_MOVETO_OPEN:
-    case PATH_LINETO:
-      /* Destination point grip */
-      WORLDtoSCREEN (toplevel, section->x3, section->y3, &x, &y);
-      o_grips_erase (w_current, x, y);
-      break;
-    case PATH_END:
-      break;
-    }
-  }
-
-  o_path_xor_control_lines (w_current, o_current);
-}
diff --git a/gschem/src/o_picture.c b/gschem/src/o_picture.c
index 0498378..ae8097f 100644
--- a/gschem/src/o_picture.c
+++ b/gschem/src/o_picture.c
@@ -406,11 +406,7 @@ void o_picture_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
   /* Grip specific stuff */
   if ((o_current->draw_grips == TRUE) && (w_current->draw_grips == TRUE)) {
       if (!o_current->selected) {
-	/* object is no more selected, erase the grips */
 	o_current->draw_grips = FALSE;
-	if (toplevel->DONT_REDRAW == 0) {
-	  o_picture_erase_grips(w_current, o_current); 
-	}
       } else {
 	/* object is selected, draw the grips on the picture */
 	if (toplevel->DONT_REDRAW == 0) {
@@ -464,50 +460,6 @@ void o_picture_draw_grips(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
                       abs(s_upper_y - s_lower_y));
 }
 
-/*! \brief Erase grip marks from box.
- *  \par Function Description
- *  This function erases the four grips displayed on the <B>*o_current</B>
- *  picture object. These grips are on each of the corner.
- *
- *  \param [in] w_current  The GSCHEM_TOPLEVEL object.
- *  \param [in] o_current  Picture OBJECT to erase grip marks from.
- */
-void o_picture_erase_grips(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
-{
-  TOPLEVEL *toplevel = w_current->toplevel;
-  int s_upper_x, s_upper_y, s_lower_x, s_lower_y;
-
-#if DEBUG
-  printf("o_picture_erase_grips called\n");
-#endif
-  if (w_current->draw_grips == FALSE)
-	  return;
-
-  WORLDtoSCREEN( toplevel, o_current->picture->upper_x, o_current->picture->upper_y,
-                 &s_upper_x, &s_upper_y );
-  WORLDtoSCREEN( toplevel, o_current->picture->lower_x, o_current->picture->lower_y,
-                 &s_lower_x, &s_lower_y );
-  
-  /* grip on upper left corner (whichone = PICTURE_UPPER_LEFT) */
-  o_grips_erase(w_current, s_upper_x, s_upper_y);
-  
-  /* grip on upper right corner (whichone = PICTURE_UPPER_RIGHT) */
-  o_grips_erase(w_current, s_lower_x, s_upper_y);
-  
-  /* grip on lower left corner (whichone = PICTURE_LOWER_LEFT) */
-  o_grips_erase(w_current, s_upper_x, s_lower_y);
-  
-  /* grip on lower right corner (whichone = PICTURE_LOWER_RIGHT) */
-  o_grips_erase(w_current, s_lower_x, s_lower_y);
-  
-  /* Box surrounding the picture */
-  gdk_draw_rectangle (w_current->drawable, w_current->gc, FALSE,
-                      s_upper_x, s_upper_y,
-                      abs(s_upper_x - s_lower_x),
-                      abs(s_upper_y - s_lower_y));
-  
-}
-
 
 /*! \brief Draw a picture described by OBJECT with translation
  *  \par Function Description
diff --git a/gschem/src/o_pin.c b/gschem/src/o_pin.c
index 2285668..75b0a1e 100644
--- a/gschem/src/o_pin.c
+++ b/gschem/src/o_pin.c
@@ -89,9 +89,7 @@ void o_pin_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
 
   if (o_current->draw_grips && w_current->draw_grips == TRUE) {
     if (!o_current->selected) {
-      /* object is no more selected, erase the grips */
       o_current->draw_grips = FALSE;
-      o_line_erase_grips(w_current, o_current);
     } else {
       /* object is selected, draw the grips */
       o_line_draw_grips(w_current, o_current);

commit 111e9e78fded24189f58e420b291ba444323ac25
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Date:   Sat Dec 20 08:25:03 2008 +0000

    Remove now unused functions o_{draw,erase}_list() and o_erase_single()

diff --git a/gschem/include/prototype.h b/gschem/include/prototype.h
index 1ee1486..4305db4 100644
--- a/gschem/include/prototype.h
+++ b/gschem/include/prototype.h
@@ -483,9 +483,6 @@ OBJECT *o_attrib_add_attrib(GSCHEM_TOPLEVEL *w_current, const char *text_string,
 void o_redraw_rects(GSCHEM_TOPLEVEL *w_current, GdkRectangle *rectangles, int n_rectangles);
 void o_redraw(GSCHEM_TOPLEVEL *w_current, GList *object_list, gboolean draw_selected);
 void o_redraw_single(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current);
-void o_draw_list(GSCHEM_TOPLEVEL *w_current, GList *list);
-void o_erase_single(GSCHEM_TOPLEVEL *w_current, OBJECT *object);
-void o_erase_list(GSCHEM_TOPLEVEL *w_current, GList *list);
 int o_erase_rubber(GSCHEM_TOPLEVEL *w_current);
 int o_redraw_cleanstates(GSCHEM_TOPLEVEL *w_current);
 void o_draw_xor(GSCHEM_TOPLEVEL *w_current, int dx, int dy, OBJECT *object);
diff --git a/gschem/src/o_basic.c b/gschem/src/o_basic.c
index 31e25be..2793f13 100644
--- a/gschem/src/o_basic.c
+++ b/gschem/src/o_basic.c
@@ -238,78 +238,6 @@ void o_redraw_single(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
   }
 }
 
-/*! \todo Finish function documentation!!!
- *  \brief
- *  \par Function Description
- *
- */
-void o_draw_list(GSCHEM_TOPLEVEL *w_current, GList* list)
-{
-  OBJECT* o_current;
-  GList *l_current;
-
-  l_current = list;
-  while (l_current != NULL) {
-
-    o_current = (OBJECT *) l_current->data;
-
-    if (o_current) {
-      o_redraw_single(w_current, o_current);
-    }
-
-    l_current = g_list_next(l_current);
-  }
-}
-
-
-/*! \brief Erase a given OBJECT
- *
- *  \par Function Description
- *  This function erases the passed OBJECT, <B>object</B>.
- *
- *  It makes a call to object's draw function after having set a
- *  color override to the background color. The object is drawn in
- *  the background color, causing it to dissapear.
- *
- *  \bug No redrawing is done of occluded objects, including the grid.
- *
- *  \param [in] w_current  The GSCHEM_TOPLEVEL object.
- *  \param [in] o_current  Circle OBJECT to erase.
- */
-void o_erase_single(GSCHEM_TOPLEVEL *w_current, OBJECT *object)
-{
-  TOPLEVEL *toplevel = w_current->toplevel;
-  OBJECT *o_current;
-
-  o_current = object;
-
-  toplevel->override_color = toplevel->background_color;
-  if (o_current != NULL) {
-    if (o_current->draw_func) {
-      (*o_current->draw_func)(w_current, o_current);
-    }
-  }
-  toplevel->override_color = -1;
-}
-
-/*! \todo Finish function documentation!!!
- *  \brief
- *  \par Function Description
- *
- */
-void o_erase_list(GSCHEM_TOPLEVEL *w_current, GList* list)
-{
-  OBJECT *o_current;
-  GList *iter;
-
-  iter = list;
-  while (iter != NULL) {
-    o_current = iter->data;
-    o_erase_single(w_current, o_current);
-    iter = g_list_next(iter);
-  }
-}
-
 
 /*! \todo Finish function documentation!!!
  *  \brief

commit 20b87f17855b3a0cd09b1865d661de8e039ae903
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Date:   Sat Dec 20 08:25:01 2008 +0000

    Changed caller of o_{erase,draw}_selected() to use o_invalidate_glist()
    
    Remove the now unused functions o_{erase,draw}_selected().

diff --git a/gschem/include/prototype.h b/gschem/include/prototype.h
index d3f8a54..1ee1486 100644
--- a/gschem/include/prototype.h
+++ b/gschem/include/prototype.h
@@ -484,8 +484,6 @@ void o_redraw_rects(GSCHEM_TOPLEVEL *w_current, GdkRectangle *rectangles, int n_
 void o_redraw(GSCHEM_TOPLEVEL *w_current, GList *object_list, gboolean draw_selected);
 void o_redraw_single(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current);
 void o_draw_list(GSCHEM_TOPLEVEL *w_current, GList *list);
-void o_draw_selected(GSCHEM_TOPLEVEL *w_current);
-void o_erase_selected(GSCHEM_TOPLEVEL *w_current);
 void o_erase_single(GSCHEM_TOPLEVEL *w_current, OBJECT *object);
 void o_erase_list(GSCHEM_TOPLEVEL *w_current, GList *list);
 int o_erase_rubber(GSCHEM_TOPLEVEL *w_current);
diff --git a/gschem/src/o_basic.c b/gschem/src/o_basic.c
index 681c9d7..31e25be 100644
--- a/gschem/src/o_basic.c
+++ b/gschem/src/o_basic.c
@@ -261,54 +261,6 @@ void o_draw_list(GSCHEM_TOPLEVEL *w_current, GList* list)
   }
 }
 
-/*! \todo Finish function documentation!!!
- *  \brief
- *  \par Function Description
- *
- */
-void o_draw_selected(GSCHEM_TOPLEVEL *w_current)
-{
-  TOPLEVEL *toplevel = w_current->toplevel;
-  GList* s_current;
-  OBJECT* o_current;
-
-  s_current = geda_list_get_glist( toplevel->page_current->selection_list );
-  while (s_current != NULL) {
-    o_current = (OBJECT *) s_current->data;
-
-    if (o_current) {
-      o_redraw_single(w_current, o_current);
-      o_cue_draw_single(w_current, o_current);
-    }
-    s_current=g_list_next(s_current);
-  }
-
-}
-
-/*! \todo Finish function documentation!!!
- *  \brief
- *  \par Function Description
- *
- */
-void o_erase_selected(GSCHEM_TOPLEVEL *w_current)
-{
-  TOPLEVEL *toplevel = w_current->toplevel;
-  GList *list;
-  GList *iter;
-  OBJECT* o_current;
-
-  list = iter = geda_list_get_glist( toplevel->page_current->selection_list );
-  while (iter != NULL) {
-    o_current = iter->data;
-
-    if (o_current) {
-      o_cue_erase_single(w_current, o_current);
-      o_erase_single(w_current, o_current);
-    }
-
-    iter = g_list_next( iter );
-  }
-}
 
 /*! \brief Erase a given OBJECT
  *
diff --git a/gschem/src/o_move.c b/gschem/src/o_move.c
index 220b1a8..af0f18e 100644
--- a/gschem/src/o_move.c
+++ b/gschem/src/o_move.c
@@ -48,7 +48,8 @@ void o_move_start(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
     w_current->first_wx = w_current->second_wx = w_x;
     w_current->first_wy = w_current->second_wy = w_y;
 
-    o_erase_selected(w_current);
+    o_invalidate_glist (w_current,
+       geda_list_get_glist (toplevel->page_current->selection_list));
 
     if (w_current->netconn_rubberband) {
       o_move_prep_rubberband(w_current);
@@ -235,7 +236,8 @@ void o_move_end(GSCHEM_TOPLEVEL *w_current)
   o_undo_remove_last_undo(w_current);
 
   /* Draw the objects that were moved (and connected/disconnected objects) */
-  o_draw_selected(w_current);
+  o_invalidate_glist (w_current,
+    geda_list_get_glist (toplevel->page_current->selection_list));
   o_cue_undraw_list(w_current, prev_conn_objects);
   o_cue_draw_list(w_current, prev_conn_objects);
   o_cue_undraw_list(w_current, connected_objects);

commit 4287b770933148477d613c97f7b0d60bd9236603
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Date:   Sat Dec 20 08:11:03 2008 +0000

    gschem: Change redraw and erase calls to invalidate calls
    
    In the new drawing model, "invalidate" calls actually specify which
    primitives or areas of the screen need redrawing. The redraw code called
    from the expose event handler then draws objects directly onto the screen.
    
    Remove the now unused function o_redraw_all()

diff --git a/gschem/include/prototype.h b/gschem/include/prototype.h
index ec6ec35..d3f8a54 100644
--- a/gschem/include/prototype.h
+++ b/gschem/include/prototype.h
@@ -480,7 +480,6 @@ void o_attrib_toggle_visibility(GSCHEM_TOPLEVEL *w_current, OBJECT *object);
 void o_attrib_toggle_show_name_value(GSCHEM_TOPLEVEL *w_current, OBJECT *object, int new_show_name_value);
 OBJECT *o_attrib_add_attrib(GSCHEM_TOPLEVEL *w_current, const char *text_string, int visibility, int show_name_value, OBJECT *object);
 /* o_basic.c */
-void o_redraw_all(GSCHEM_TOPLEVEL *w_current);
 void o_redraw_rects(GSCHEM_TOPLEVEL *w_current, GdkRectangle *rectangles, int n_rectangles);
 void o_redraw(GSCHEM_TOPLEVEL *w_current, GList *object_list, gboolean draw_selected);
 void o_redraw_single(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current);
diff --git a/gschem/src/a_pan.c b/gschem/src/a_pan.c
index 85d2f9a..e6fbd6d 100644
--- a/gschem/src/a_pan.c
+++ b/gschem/src/a_pan.c
@@ -162,7 +162,7 @@ void a_pan_general(GSCHEM_TOPLEVEL *w_current, double world_cx, double world_cy,
   /* redraw */
   if (!(flags & A_PAN_DONT_REDRAW)) {
     x_scrollbars_update(w_current);
-    o_redraw_all(w_current);
+    o_invalidate_all (w_current);
   }
 }
 
diff --git a/gschem/src/g_hook.c b/gschem/src/g_hook.c
index 6a5c2dc..5c37e69 100644
--- a/gschem/src/g_hook.c
+++ b/gschem/src/g_hook.c
@@ -346,7 +346,7 @@ SCM g_set_attrib_text_properties(SCM attrib_smob, SCM scm_coloridx,
     object = attribute->attribute;
     if (object &&
 	object->text) {
-      o_erase_single(w_current, object);
+      o_invalidate (w_current, object);
       if (x != -1) {
 	object->text->x = x;
       }
@@ -364,7 +364,7 @@ SCM g_set_attrib_text_properties(SCM attrib_smob, SCM scm_coloridx,
       }
       o_text_recreate(toplevel, object);
       if (!toplevel->DONT_REDRAW) {
-        o_redraw_single (w_current, object);
+        o_invalidate (w_current, object);
       }
     }
   }
@@ -716,7 +716,7 @@ SCM g_add_component(SCM page_smob, SCM scm_comp_name, SCM scm_x, SCM scm_y,
 #if 0 
   /* Now the new component should be added to the object's list and 
      drawn in the screen */
-  o_redraw_single(toplevel, new_object);
+  o_invalidate (toplevel, new_object);
 #endif
   
   return SCM_BOOL_T;        
diff --git a/gschem/src/i_callbacks.c b/gschem/src/i_callbacks.c
index b2a5a9f..4af1852 100644
--- a/gschem/src/i_callbacks.c
+++ b/gschem/src/i_callbacks.c
@@ -991,8 +991,8 @@ DEFINE_I_CALLBACK(edit_embed)
       }
       s_current = g_list_next(s_current);
     }
-    o_draw_list (w_current, geda_list_get_glist (
-                   w_current->toplevel->page_current->selection_list));
+    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 */
@@ -1032,8 +1032,8 @@ DEFINE_I_CALLBACK(edit_unembed)
       }
       s_current = g_list_next(s_current);
     }
-    o_draw_list (w_current, geda_list_get_glist (
-                   w_current->toplevel->page_current->selection_list));
+    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 */
@@ -1088,7 +1088,7 @@ DEFINE_I_CALLBACK(edit_update)
     g_list_free(selection_copy);
 
     /* Make sure the display is up to date */
-    o_redraw_all(w_current);
+    o_invalidate_all (w_current);
   } else {
     /* nothing selected, go back to select state */
     o_redraw_cleanstates(w_current);	
@@ -1320,7 +1320,7 @@ DEFINE_I_CALLBACK(view_redraw)
   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
 
   exit_if_null(w_current);
-  o_redraw_all(w_current);
+  o_invalidate_all (w_current);
 }
 
 /*! \todo Finish function documentation!!!
@@ -1594,7 +1594,7 @@ DEFINE_I_CALLBACK(view_update_cues)
   i_update_middle_button(w_current,
                          i_callback_view_update_cues, _("Update Cues"));
 
-  o_redraw_all(w_current);
+  o_invalidate_all (w_current);
 }
 
 /*! \section page-menu Page Menu Callback Functions */
@@ -3269,7 +3269,7 @@ DEFINE_I_CALLBACK(options_scale_up_snap_size)
   w_current->toplevel->page_current->CHANGED=1;  /* maybe remove those two lines */
   o_undo_savestate(w_current, UNDO_ALL);
 
-  o_redraw_all(w_current);
+  o_invalidate_all (w_current);
 }
 
 /*! \brief Divide by two the snap grid size.
@@ -3288,7 +3288,7 @@ DEFINE_I_CALLBACK(options_scale_down_snap_size)
   w_current->toplevel->page_current->CHANGED=1;  /* maybe remove those two lines */
   o_undo_savestate(w_current, UNDO_ALL);
 
-  o_redraw_all(w_current);
+  o_invalidate_all (w_current);
 
 }
 
@@ -3334,7 +3334,7 @@ DEFINE_I_CALLBACK(options_grid)
     s_log_message(_("Grid ON\n"));
   }
 
-  o_redraw_all(w_current);
+  o_invalidate_all (w_current);
 }
 
 /*! \todo Finish function documentation!!!
@@ -3502,7 +3502,7 @@ DEFINE_I_CALLBACK(cancel)
   scm_c_eval_string ("(set! current-command-sequence '())");
 
   if (w_current->inside_action) { 
-     o_redraw_all(w_current); 
+     o_invalidate_all (w_current);
   }
 
   w_current->inside_action=0;
diff --git a/gschem/src/o_arc.c b/gschem/src/o_arc.c
index 779670a..eebdb87 100644
--- a/gschem/src/o_arc.c
+++ b/gschem/src/o_arc.c
@@ -948,7 +948,7 @@ void o_arc_end4(GSCHEM_TOPLEVEL *w_current, int radius,
   s_page_append (toplevel->page_current, new_obj);
 
   /* draw the new object */
-  o_redraw_single (w_current, new_obj);
+  o_invalidate (w_current, new_obj);
 
   w_current->first_wx  = -1;
   w_current->first_wy  = -1;
diff --git a/gschem/src/o_attrib.c b/gschem/src/o_attrib.c
index 17c20cc..c0ddf17 100644
--- a/gschem/src/o_attrib.c
+++ b/gschem/src/o_attrib.c
@@ -68,7 +68,7 @@ void o_attrib_add_selected(GSCHEM_TOPLEVEL *w_current, SELECTION *selection,
       /* make sure object isn't selected already */
       if (a_current->saved_color == -1) {
         o_selection_add(selection, a_current);
-        o_redraw_single(w_current, a_current);
+        o_invalidate (w_current, a_current);
       }
 
       a_iter = g_list_next (a_iter);
@@ -96,21 +96,21 @@ void o_attrib_toggle_visibility(GSCHEM_TOPLEVEL *w_current, OBJECT *object)
   if (object->visibility == VISIBLE) {
     /* only erase if we are not showing hidden text */
     if (!toplevel->show_hidden_text) {
-      o_erase_single(w_current, object);
+      o_invalidate (w_current, object);
     }
 
     object->visibility = INVISIBLE;
 
     if (toplevel->show_hidden_text) {
       /* draw text so that little I is drawn */
-      o_redraw_single (w_current, object);
+      o_invalidate (w_current, object);
     }
 
   } else {
     /* if we are in the special show hidden mode, then erase text first */
     /* to get rid of the little I */
     if (toplevel->show_hidden_text) {
-      o_erase_single(w_current, object);
+      o_invalidate (w_current, object);
     }
 
     object->visibility = VISIBLE;
@@ -121,7 +121,7 @@ void o_attrib_toggle_visibility(GSCHEM_TOPLEVEL *w_current, OBJECT *object)
       o_text_recreate(toplevel, object);
     }
 
-    o_redraw_single (w_current, object);
+    o_invalidate (w_current, object);
   }
 
   toplevel->page_current->CHANGED = 1;
@@ -144,10 +144,10 @@ void o_attrib_toggle_show_name_value(GSCHEM_TOPLEVEL *w_current,
 
   g_return_if_fail (object != NULL && object->type == OBJ_TEXT);
 
-  o_erase_single(w_current, object);
+  o_invalidate (w_current, object);
   object->show_name_value = show_name_value;
   o_text_recreate(toplevel, object);
-  o_redraw_single (w_current, object);
+  o_invalidate (w_current, object);
 
   toplevel->page_current->CHANGED = 1;
 }
@@ -251,8 +251,7 @@ OBJECT *o_attrib_add_attrib(GSCHEM_TOPLEVEL *w_current,
 
   o_selection_add (toplevel->page_current->selection_list, new_obj);
 
-  o_erase_single (w_current, new_obj);
-  o_redraw_single (w_current, new_obj);
+  o_invalidate (w_current, new_obj);
 
   /* handle slot= attribute, it's a special case */
   if (g_ascii_strncasecmp (text_string, "slot=", 5) == 0) {
diff --git a/gschem/src/o_basic.c b/gschem/src/o_basic.c
index 17b94f6..681c9d7 100644
--- a/gschem/src/o_basic.c
+++ b/gschem/src/o_basic.c
@@ -193,59 +193,6 @@ void o_redraw_rects (GSCHEM_TOPLEVEL *w_current,
  *  \par Function Description
  *
  */
-void o_redraw_all(GSCHEM_TOPLEVEL *w_current)
-{
-  TOPLEVEL *toplevel = w_current->toplevel;
-  gboolean draw_selected = TRUE;
-
-  if (!toplevel->DONT_REDRAW) {
-    x_repaint_background(w_current);
-  }
-
-  draw_selected = !(w_current->inside_action &&
-                    ((w_current->event_state == MOVE) ||
-                     (w_current->event_state == ENDMOVE) ||
-                     (w_current->event_state == GRIPS)));
-  g_return_if_fail (toplevel != NULL);
-  g_return_if_fail (toplevel->page_current != NULL);
-  g_warn_if_fail (toplevel->page_current->object_list != NULL);
-  o_redraw (w_current, toplevel->page_current->object_list, draw_selected);
-  o_cue_redraw_all(w_current,
-                   toplevel->page_current->object_list, draw_selected);
-
-  if (w_current->inside_action) {
-    switch(w_current->event_state) {
-      case(MOVE):
-      case(ENDMOVE):
-        o_move_rubbermove_xor (w_current, TRUE);
-        break;
-
-      case(ENDCOPY):
-      case(ENDMCOPY):
-      case(ENDCOMP):
-      case(ENDTEXT):
-      case(ENDPASTE):
-        /* Redraw the rubberband objects (if they were previously visible) */
-        if (w_current->rubber_visible)
-          o_place_rubberplace_xor (w_current, TRUE);
-        break;
-
-      case(STARTDRAWNET):
-      case(DRAWNET):
-      case(NETCONT):
-        w_current->magnetic_visible=0;
-        w_current->rubber_visible = 0;
-        break;
-    }
-  }
-}
-
-
-/*! \todo Finish function documentation!!!
- *  \brief
- *  \par Function Description
- *
- */
 void o_redraw (GSCHEM_TOPLEVEL *w_current, GList *object_list, gboolean draw_selected)
 {
   TOPLEVEL *toplevel = w_current->toplevel;
@@ -542,7 +489,7 @@ int o_redraw_cleanstates(GSCHEM_TOPLEVEL *w_current)
       i_set_state(w_current, SELECT);
 
       /* from i_callback_cancel() */
-      o_redraw_all(w_current);
+      o_invalidate_all (w_current);
       return TRUE;
 
     /* all remaining states without dc changes */
diff --git a/gschem/src/o_box.c b/gschem/src/o_box.c
index de5e259..c7264cf 100644
--- a/gschem/src/o_box.c
+++ b/gschem/src/o_box.c
@@ -835,8 +835,8 @@ void o_box_end(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
   s_page_append (toplevel->page_current, new_obj);
 
   /* draw it */
-  o_redraw_single (w_current, new_obj);
-  
+  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 ba31e96..c1b63f0 100644
--- a/gschem/src/o_bus.c
+++ b/gschem/src/o_bus.c
@@ -259,7 +259,7 @@ 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->page_current, new_obj);
 
-  o_redraw_single (w_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);
diff --git a/gschem/src/o_circle.c b/gschem/src/o_circle.c
index 8e32325..b886adf 100644
--- a/gschem/src/o_circle.c
+++ b/gschem/src/o_circle.c
@@ -590,8 +590,8 @@ void o_circle_end(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
   s_page_append (toplevel->page_current, new_obj);
 
   /* draw it */
-  o_redraw_single (w_current, new_obj);
-  
+  o_invalidate (w_current, new_obj);
+
   toplevel->page_current->CHANGED = 1;
   o_undo_savestate(w_current, UNDO_ALL);
 }
diff --git a/gschem/src/o_complex.c b/gschem/src/o_complex.c
index 837270b..11e897d 100644
--- a/gschem/src/o_complex.c
+++ b/gschem/src/o_complex.c
@@ -224,7 +224,7 @@ void o_complex_translate_all(GSCHEM_TOPLEVEL *w_current, int offset)
   /* first zoom extents */
   a_zoom_extents (w_current, toplevel->page_current->object_list,
                  A_PAN_DONT_REDRAW);
-  o_redraw_all(w_current);
+  o_invalidate_all (w_current);
 
   world_get_object_glist_bounds (toplevel, toplevel->page_current->object_list,
                                  &w_rleft,
@@ -274,7 +274,7 @@ void o_complex_translate_all(GSCHEM_TOPLEVEL *w_current, int offset)
   a_zoom_extents (w_current, toplevel->page_current->object_list,
                  A_PAN_DONT_REDRAW);
   if (!w_current->SHIFTKEY) o_select_unselect_all(w_current);
-  o_redraw_all(w_current);
+  o_invalidate_all (w_current);
   toplevel->page_current->CHANGED=1;
   o_undo_savestate(w_current, UNDO_ALL);
   i_update_menus(w_current);
diff --git a/gschem/src/o_cue.c b/gschem/src/o_cue.c
index a88055d..0d65a8e 100644
--- a/gschem/src/o_cue.c
+++ b/gschem/src/o_cue.c
@@ -441,7 +441,7 @@ static void o_cue_undraw_lowlevel(GSCHEM_TOPLEVEL *w_current, OBJECT *object)
     conn = (CONN *) cl_current->data;
 
     if (conn->other_object) {
-      o_redraw_single(w_current, conn->other_object);
+      o_invalidate (w_current, conn->other_object);
     }
 
     cl_current = g_list_next(cl_current);
@@ -486,7 +486,7 @@ void o_cue_undraw(GSCHEM_TOPLEVEL *w_current, OBJECT *object)
     }
   }
 
-  o_redraw_single(w_current, object);
+  o_invalidate (w_current, object);
 }
 
 /*! \todo Finish function documentation!!!
diff --git a/gschem/src/o_delete.c b/gschem/src/o_delete.c
index 7f6220f..8ad40a7 100644
--- a/gschem/src/o_delete.c
+++ b/gschem/src/o_delete.c
@@ -64,8 +64,7 @@ void o_delete (GSCHEM_TOPLEVEL *w_current, OBJECT *object)
       }
     }
   }
-  o_erase_single (w_current, object);
-  o_erase_grips (w_current, object);
+  o_invalidate (w_current, object);
 
   s_page_remove (toplevel->page_current, object);
   s_delete_object (toplevel, object);
diff --git a/gschem/src/o_grips.c b/gschem/src/o_grips.c
index 84fddd5..a91a529 100644
--- a/gschem/src/o_grips.c
+++ b/gschem/src/o_grips.c
@@ -636,7 +636,7 @@ void o_grips_start_arc(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current,
   w_current->last_drawb_mode = LAST_DRAWB_MODE_NONE;
 
   /* erase the arc before */
-  o_erase_single(w_current, o_current);
+  o_invalidate (w_current, o_current);
 
   /* describe the arc with GSCHEM_TOPLEVEL variables */
   /* center */
@@ -680,7 +680,7 @@ void o_grips_start_box(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current,
   w_current->last_drawb_mode = LAST_DRAWB_MODE_NONE;
 
   /* erase the box before */
-  o_erase_single(w_current, o_current);
+  o_invalidate (w_current, o_current);
 
   /* (second_wx, second_wy) is the selected corner */
   /* (first_wx, first_wy) is the opposite corner */
@@ -752,7 +752,7 @@ void o_grips_start_path(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current,
   w_current->last_drawb_mode = -1;
 
   /* erase the path before */
-  o_erase_single(w_current, o_current);
+  o_invalidate (w_current, o_current);
 
   for (i = 0; i <  o_current->path->num_sections; i++) {
     section = &o_current->path->sections[i];
@@ -819,7 +819,7 @@ void o_grips_start_picture(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current,
   w_current->last_drawb_mode = LAST_DRAWB_MODE_NONE;
 
   /* erase the picture before */
-  o_erase_single(w_current, o_current);
+  o_invalidate (w_current, o_current);
   w_current->current_pixbuf = o_current->picture->original_picture;
   w_current->pixbuf_filename = o_current->picture->filename;
   w_current->pixbuf_wh_ratio = o_current->picture->ratio;
@@ -888,7 +888,7 @@ void o_grips_start_circle(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current,
   w_current->last_drawb_mode = LAST_DRAWB_MODE_NONE;
 
   /* erase the circle before */
-  o_erase_single(w_current, o_current);
+  o_invalidate (w_current, o_current);
 
   /* store circle center and radius in GSCHEM_TOPLEVEL structure */
   w_current->first_wx = o_current->circle->center_x;
@@ -926,7 +926,7 @@ void o_grips_start_line(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current,
   w_current->last_drawb_mode = LAST_DRAWB_MODE_NONE;
 
   /* erase the line before */
-  o_erase_single(w_current, o_current);
+  o_invalidate (w_current, o_current);
 
   /* describe the line with GSCHEM_TOPLEVEL variables */
   w_current->second_wx = o_current->line->x[whichone];
@@ -1149,7 +1149,7 @@ void o_grips_end_arc(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int whichone
   o_arc_modify(toplevel, o_current, arg1, arg2, whichone);
 
   /* display the new arc */
-  o_redraw_single(w_current, o_current);
+  o_invalidate (w_current, o_current);
 
 }
 
@@ -1173,7 +1173,7 @@ void o_grips_end_box(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int whichone
    * this ends the box drawing behavior
    * we want this? hack */
   if ((box_width == 0) && (box_height == 0)) {
-    o_redraw_single(w_current, o_current);
+    o_invalidate (w_current, o_current);
     return;
   }
 
@@ -1183,7 +1183,7 @@ void o_grips_end_box(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int whichone
   o_box_rubberbox_xor(w_current);
 
   /* draw the modified box */
-  o_redraw_single(w_current, o_current);
+  o_invalidate (w_current, o_current);
 }
 
 /*! \todo Finish function documentation!!!
@@ -1204,7 +1204,7 @@ void o_grips_end_path(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int whichon
                  w_current->second_wx, w_current->second_wy, whichone);
 
   /* draw the modified path */
-  o_redraw_single(w_current, o_current);
+  o_invalidate (w_current, o_current);
 }
 
 /*! \todo Finish function documentation!!!
@@ -1226,7 +1226,7 @@ void o_grips_end_picture(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int whic
    * this ends the picture drawing behavior
    * we want this? hack */
   if ((GET_PICTURE_WIDTH(w_current) == 0) || (GET_PICTURE_HEIGHT(w_current) == 0)) {
-    o_redraw_single(w_current, o_current);
+    o_invalidate (w_current, o_current);
     return;
   }
 
@@ -1234,7 +1234,7 @@ void o_grips_end_picture(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int whic
 		   w_current->second_wx, w_current->second_wy, whichone);
 
   /* draw the modified picture */
-  o_redraw_single(w_current, o_current);
+  o_invalidate (w_current, o_current);
 
   w_current->current_pixbuf = NULL;
   w_current->pixbuf_filename = NULL;
@@ -1267,7 +1267,7 @@ void o_grips_end_circle(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int which
    * this ends the circle drawing behavior
    * we want this? hack */
   if (w_current->distance == 0) {
-    o_redraw_single(w_current, o_current);
+    o_invalidate (w_current, o_current);
     return;
   }
 
@@ -1275,7 +1275,7 @@ void o_grips_end_circle(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int which
   o_circle_modify(toplevel, o_current, w_current->distance, -1, CIRCLE_RADIUS);
 
   /* display the new circle */
-  o_redraw_single(w_current, o_current);
+  o_invalidate (w_current, o_current);
 }
 
 /*! \brief End process of modifying line object with grip.
@@ -1306,7 +1306,7 @@ void o_grips_end_line(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int whichon
    * we want this? hack */
   if ((w_current->first_wx == w_current->second_wx) &&
       (w_current->first_wy == w_current->second_wy)) {
-    o_redraw_single(w_current, o_current);
+    o_invalidate (w_current, o_current);
     return;
   }
 
@@ -1315,7 +1315,7 @@ void o_grips_end_line(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int whichon
 		w_current->second_wx, w_current->second_wy, whichone);
 
   /* display the new line */
-  o_redraw_single(w_current, o_current);
+  o_invalidate (w_current, o_current);
 }
 
 
@@ -1349,13 +1349,13 @@ void o_grips_end_net(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int whichone
    * we want this? hack */
   if ((w_current->first_wx == w_current->second_wx) &&
       (w_current->first_wy == w_current->second_wy)) {
-    o_redraw_single(w_current, o_current);
+    o_invalidate (w_current, o_current);
     return;
   }
 
   /* remove the old net */
   o_cue_undraw(w_current, o_current);
-  o_erase_single(w_current, o_current);
+  o_invalidate (w_current, o_current);
 
   prev_conn_objects = s_conn_return_others (prev_conn_objects, o_current);
 
@@ -1370,10 +1370,10 @@ void o_grips_end_net(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int whichone
   /* add bus rippers if necessary */
   if (o_net_add_busrippers(w_current, o_current, connected_objects)) {
 
-    o_erase_single(w_current, o_current);
+    o_invalidate (w_current, o_current);
     o_cue_undraw(w_current, o_current);
 
-    o_redraw_single (w_current, o_current);
+    o_invalidate (w_current, o_current);
     o_cue_draw_single(w_current, o_current);
   }
 
@@ -1381,7 +1381,7 @@ void o_grips_end_net(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int whichone
   o_cue_undraw_list (w_current, prev_conn_objects);
   o_cue_draw_list (w_current, prev_conn_objects);
   
-  o_redraw_single(w_current, o_current);
+  o_invalidate (w_current, o_current);
   
   g_list_free(connected_objects);
   connected_objects = NULL;
@@ -1431,13 +1431,13 @@ void o_grips_end_pin(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int whichone
    * we want this? hack */
   if ((w_current->first_wx == w_current->second_wx) &&
       (w_current->first_wy == w_current->second_wy)) {
-    o_redraw_single(w_current, o_current);
+    o_invalidate (w_current, o_current);
     return;
   }
 
   /* erase old pin object */
   o_cue_undraw(w_current, o_current);
-  o_erase_single(w_current, o_current);
+  o_invalidate (w_current, o_current);
 
   prev_conn_objects = s_conn_return_others (prev_conn_objects, o_current);
 
@@ -1445,7 +1445,7 @@ void o_grips_end_pin(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int whichone
   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);
-  o_redraw_single(w_current, o_current);
+  o_invalidate (w_current, o_current);
 
   /* redraw the object connections */
   o_cue_undraw_list (w_current, prev_conn_objects);
@@ -1497,13 +1497,13 @@ void o_grips_end_bus(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int whichone
    * we want this? hack */
   if ((w_current->first_wx == w_current->second_wx) &&
       (w_current->first_wy == w_current->second_wy)) {
-    o_redraw_single(w_current, o_current);
+    o_invalidate (w_current, o_current);
     return;
   }
 
   /* erase the old bus and it's cues */
   o_cue_undraw(w_current, o_current);
-  o_erase_single(w_current, o_current);
+  o_invalidate (w_current, o_current);
 
   prev_conn_objects = s_conn_return_others (prev_conn_objects, o_current);
   s_conn_remove_object (toplevel, o_current);
@@ -1511,7 +1511,7 @@ void o_grips_end_bus(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int whichone
   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);
-  o_redraw_single(w_current, o_current);
+  o_invalidate (w_current, o_current);
 
   /* redraw the connected objects */
   o_cue_undraw_list (w_current, prev_conn_objects);
diff --git a/gschem/src/o_line.c b/gschem/src/o_line.c
index 9ff9b85..de25fb0 100644
--- a/gschem/src/o_line.c
+++ b/gschem/src/o_line.c
@@ -803,7 +803,7 @@ void o_line_end(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
   s_page_append (toplevel->page_current, new_obj);
 
   /* draw it */
-  o_redraw_single (w_current, new_obj);
+  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 cf5e873..0c6112b 100644
--- a/gschem/src/o_misc.c
+++ b/gschem/src/o_misc.c
@@ -203,7 +203,7 @@ void o_rotate_world_update(GSCHEM_TOPLEVEL *w_current,
 
   if (!toplevel->DONT_REDRAW) {
     o_cue_undraw_list (w_current, list);
-    o_erase_list (w_current, list);
+    o_invalidate_glist (w_current, list);
   }
 
   /* Find connected objects, removing each object in turn from the
@@ -231,7 +231,7 @@ void o_rotate_world_update(GSCHEM_TOPLEVEL *w_current,
   }
 
   if (!toplevel->DONT_REDRAW) {
-    o_draw_list (w_current, list);
+    o_invalidate_glist (w_current, list);
     o_cue_undraw_list (w_current, prev_conn_objects);
     o_cue_draw_list (w_current, prev_conn_objects);
     o_cue_undraw_list(w_current, connected_objects);
@@ -308,7 +308,7 @@ void o_mirror_world_update(GSCHEM_TOPLEVEL *w_current, int centerx, int centery,
   }
 
   o_cue_undraw_list (w_current, list);
-  o_erase_list (w_current, list);
+  o_invalidate_glist (w_current, list);
 
   /* Find connected objects, removing each object in turn from the
    * connection list. We only _really_ want those objects connected
@@ -334,7 +334,7 @@ void o_mirror_world_update(GSCHEM_TOPLEVEL *w_current, int centerx, int centery,
     connected_objects = s_conn_return_others (connected_objects, o_current);
   }
 
-  o_draw_list (w_current, list);
+  o_invalidate_glist (w_current, list);
   o_cue_undraw_list (w_current, prev_conn_objects);
   o_cue_draw_list (w_current, prev_conn_objects);
   o_cue_undraw_list(w_current, connected_objects);
@@ -409,7 +409,7 @@ void o_edit_show_hidden_lowlevel (GSCHEM_TOPLEVEL *w_current, GList *o_list)
           o_text_recreate(toplevel, o_current);
         }
         o_recalc_single_object(toplevel, o_current);
-        o_redraw_single (w_current, 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 */
@@ -446,7 +446,7 @@ void o_edit_show_hidden (GSCHEM_TOPLEVEL *w_current, GList *o_list)
   i_show_state(w_current, NULL); /* update screen status */
 
   o_edit_show_hidden_lowlevel(w_current, o_list);
-  o_redraw_all(w_current);
+  o_invalidate_all (w_current);
 
   if (w_current->toplevel->show_hidden_text) {
     s_log_message(_("Hidden text is now visible\n"));
@@ -479,7 +479,7 @@ void o_edit_make_visible (GSCHEM_TOPLEVEL *w_current, GList *o_list)
           o_text_recreate(toplevel, o_current);
         }
 
-        o_redraw_single (w_current, o_current);
+        o_invalidate (w_current, o_current);
 
         toplevel->page_current->CHANGED = 1;
       }
@@ -544,7 +544,7 @@ int o_edit_find_text (GSCHEM_TOPLEVEL *w_current, GList * o_list, char *stext,
                                                 parent,
                                                 page_control,
                                                 HIERARCHY_NORMAL_LOAD);
-            /* o_redraw_all(w_current); */
+            /* o_invalidate_all (w_current); */
 
             rv = o_edit_find_text(w_current,
                                   toplevel->page_current->object_list,
@@ -633,7 +633,7 @@ void o_edit_hide_specific_text (GSCHEM_TOPLEVEL *w_current, GList * o_list,
     iter = g_list_next (iter);
   }
   o_undo_savestate(w_current, UNDO_ALL);
-  o_redraw_all(w_current);
+  o_invalidate_all (w_current);
 }
 
 /*! \todo Finish function documentation!!!
@@ -661,7 +661,7 @@ void o_edit_show_specific_text (GSCHEM_TOPLEVEL *w_current, GList * o_list,
           if (o_current->text->prim_objs == NULL) {
             o_text_recreate(toplevel, o_current);
           }
-          o_redraw_single (w_current, o_current);
+          o_invalidate (w_current, o_current);
           toplevel->page_current->CHANGED = 1;
         }
       }
@@ -704,8 +704,8 @@ void o_update_component(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
     return;
   }
 
-  /* erase the complex object */
-  o_erase_single (w_current, o_current);
+  /* ensure we repaint where the complex object was */
+  o_invalidate (w_current, o_current);
   /* delete its connections */
   s_conn_remove_object (toplevel, o_current);
   /* and unselect it */
@@ -769,7 +769,7 @@ void o_update_component(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
       /* add the attribute to old */
       o_attrib_add (toplevel, o_current, o_attrib);
       /* redraw the attribute object */
-      o_redraw_single (w_current, o_attrib);
+      o_invalidate (w_current, o_attrib);
       /* note: this object is unselected (not added to selection). */
     }
     else
@@ -791,7 +791,7 @@ void o_update_component(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
   /* reconnect, re-select and redraw */
   s_conn_update_object (toplevel, o_current);
   o_selection_add( toplevel->page_current->selection_list, o_current );
-  o_redraw_single (w_current, 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_move.c b/gschem/src/o_move.c
index 8da5c36..220b1a8 100644
--- a/gschem/src/o_move.c
+++ b/gschem/src/o_move.c
@@ -242,7 +242,7 @@ void o_move_end(GSCHEM_TOPLEVEL *w_current)
   o_cue_draw_list(w_current, connected_objects);
 
   /* Draw the connected nets/buses that were also changed */
-  o_draw_list(w_current, rubbernet_objects);
+  o_invalidate_glist (w_current, rubbernet_objects);
   o_cue_undraw_list(w_current, rubbernet_objects);
   o_cue_draw_list(w_current, rubbernet_objects);
   o_cue_undraw_list(w_current, rubbernet_prev_conn_objects);
@@ -410,7 +410,7 @@ void o_move_check_endpoint(GSCHEM_TOPLEVEL *w_current, OBJECT * object)
                        c_current->other_object,
                        c_current, whichone);
 
-      o_erase_single(w_current, c_current->other_object);
+      o_invalidate (w_current, c_current->other_object);
     }
   }
 
diff --git a/gschem/src/o_net.c b/gschem/src/o_net.c
index f39ce10..7b77537 100644
--- a/gschem/src/o_net.c
+++ b/gschem/src/o_net.c
@@ -722,7 +722,7 @@ int o_net_end(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
       s_conn_print(new_net->conn_list);
 #endif
 
-      o_redraw_single (w_current, new_net);
+      o_invalidate (w_current, new_net);
 
       o_cue_undraw_list (w_current, prev_conn_objects);
       o_cue_draw_list (w_current, prev_conn_objects);
@@ -773,7 +773,7 @@ int o_net_end(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
       s_conn_print(new_net->conn_list);
 #endif
 
-      o_redraw_single (w_current, new_net);
+      o_invalidate (w_current, new_net);
 
       o_cue_undraw_list (w_current, prev_conn_objects);
       o_cue_draw_list (w_current, prev_conn_objects);
@@ -1312,7 +1312,7 @@ int o_net_add_busrippers(GSCHEM_TOPLEVEL *w_current, OBJECT *net_obj,
           o_complex_promote_attribs (toplevel, new_obj,
                                      &toplevel->page_current->object_list);
 
-          o_redraw_single (w_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 88488df..0498378 100644
--- a/gschem/src/o_picture.c
+++ b/gschem/src/o_picture.c
@@ -113,8 +113,8 @@ void o_picture_end(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
   s_page_append (toplevel->page_current, new_obj);
 
   /* draw it */
-  o_redraw_single (w_current, new_obj);
-  
+  o_invalidate (w_current, new_obj);
+
   toplevel->page_current->CHANGED = 1;
   o_undo_savestate(w_current, UNDO_ALL);
 }
@@ -588,7 +588,7 @@ void o_picture_exchange (GSCHEM_TOPLEVEL *w_current, GdkPixbuf *pixbuf,
       if (object->type == OBJ_PICTURE) {
 
         /* Erase previous picture */
-        o_erase_single(w_current, object);
+        o_invalidate (w_current, object);
 
         g_free(object->picture->filename);
 
@@ -617,7 +617,7 @@ void o_picture_exchange (GSCHEM_TOPLEVEL *w_current, GdkPixbuf *pixbuf,
         object->picture->ratio = (double)gdk_pixbuf_get_width(pixbuf) /
                                          gdk_pixbuf_get_height(pixbuf);
         /* Draw new picture */
-        o_redraw_single (w_current, object);
+        o_invalidate (w_current, object);
       }
     }
     list = g_list_next(list);
diff --git a/gschem/src/o_pin.c b/gschem/src/o_pin.c
index e24b852..2285668 100644
--- a/gschem/src/o_pin.c
+++ b/gschem/src/o_pin.c
@@ -209,7 +209,7 @@ void o_pin_end(GSCHEM_TOPLEVEL *w_current, int x, int y)
   o_cue_draw_list (w_current, prev_conn_objects);
   g_list_free (prev_conn_objects);
   o_cue_draw_single(w_current, o_current_pin); 
-  o_redraw_single (w_current, o_current_pin);
+  o_invalidate (w_current, o_current_pin);
 
   toplevel->page_current->CHANGED=1;
   o_undo_savestate(w_current, UNDO_ALL);
diff --git a/gschem/src/o_place.c b/gschem/src/o_place.c
index 174ff51..83a6b9c 100644
--- a/gschem/src/o_place.c
+++ b/gschem/src/o_place.c
@@ -115,7 +115,7 @@ void o_place_end (GSCHEM_TOPLEVEL *w_current,
   connected_objects = NULL;
 
   toplevel->page_current->CHANGED = 1;
-  o_redraw (w_current, temp_dest_list, TRUE); /* only redraw new objects */
+  o_invalidate_glist (w_current, temp_dest_list); /* only redraw new objects */
   g_list_free (temp_dest_list);
 
   o_undo_savestate (w_current, UNDO_ALL);
diff --git a/gschem/src/o_select.c b/gschem/src/o_select.c
index 35d3d1b..4372fb0 100644
--- a/gschem/src/o_select.c
+++ b/gschem/src/o_select.c
@@ -232,7 +232,7 @@ 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_redraw_single(w_current, o_current);
+  o_invalidate (w_current, o_current);
 }
 
 /*! \todo Finish function documentation!!!
@@ -495,7 +495,7 @@ void o_select_unselect_list(GSCHEM_TOPLEVEL *w_current, SELECTION *selection)
 
   while ( list != NULL ) {
     o_selection_unselect( (OBJECT *)list->data );
-    o_redraw_single( w_current, (OBJECT *)list->data );
+    o_invalidate (w_current, (OBJECT *)list->data);
    list = g_list_next( list );
   }
 
diff --git a/gschem/src/o_slot.c b/gschem/src/o_slot.c
index 16825fa..4b10ea9 100644
--- a/gschem/src/o_slot.c
+++ b/gschem/src/o_slot.c
@@ -158,7 +158,7 @@ void o_slot_end(GSCHEM_TOPLEVEL *w_current, const char *string, int len)
 
       if (temp->visibility == VISIBLE ||
           (temp->visibility == INVISIBLE && toplevel->show_hidden_text)) {
-        o_erase_single(w_current,temp);
+        o_invalidate (w_current,temp);
       }
 
       o_text_recreate(toplevel, temp);
@@ -167,7 +167,7 @@ void o_slot_end(GSCHEM_TOPLEVEL *w_current, const char *string, int len)
        * item */
       if (temp->visibility == VISIBLE ||
           (temp->visibility == INVISIBLE && toplevel->show_hidden_text)) {
-        o_redraw_single(w_current,temp);
+        o_invalidate (w_current,temp);
       }
 
       g_free(slot_value);
@@ -187,10 +187,10 @@ void o_slot_end(GSCHEM_TOPLEVEL *w_current, const char *string, int len)
       slot_text_object = new_obj;
     }
 
-    o_erase_single(w_current, object);
+    o_invalidate (w_current, object);
     o_attrib_slot_update(toplevel, object);
 
-    o_redraw_single(w_current,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 7759c6a..6077308 100644
--- a/gschem/src/o_text.c
+++ b/gschem/src/o_text.c
@@ -337,7 +337,7 @@ void o_text_edit_end(GSCHEM_TOPLEVEL *w_current, char *string, int len, int text
 
     if (object) {
       if (object->type == OBJ_TEXT) {
-        o_erase_single(w_current, object);
+        o_invalidate (w_current, object);
 
         object->text->size = text_size;
         object->text->alignment = text_alignment;
@@ -355,7 +355,7 @@ void o_text_edit_end(GSCHEM_TOPLEVEL *w_current, char *string, int len, int text
 	  }
         }
         o_text_recreate(toplevel, object);
-        o_redraw_single (w_current, object);
+        o_invalidate (w_current, object);
       } 
     }
     
@@ -387,7 +387,7 @@ void o_text_change(GSCHEM_TOPLEVEL *w_current, OBJECT *object, char *string,
   }
 
   /* erase old object */
-  o_erase_single(w_current, object);
+  o_invalidate (w_current, object);
 
   /* second change the real object */
   o_text_set_string (toplevel, object, string);
@@ -395,7 +395,7 @@ void o_text_change(GSCHEM_TOPLEVEL *w_current, OBJECT *object, char *string,
   object->visibility = visibility;
   object->show_name_value = show;
   o_text_recreate(toplevel, object);
-  o_redraw_single (w_current, object);
+  o_invalidate (w_current, object);
 
   /* handle slot= attribute, it's a special case */
   if (g_ascii_strncasecmp (string, "slot=", 5) == 0) {
diff --git a/gschem/src/o_undo.c b/gschem/src/o_undo.c
index b86fc67..d092272 100644
--- a/gschem/src/o_undo.c
+++ b/gschem/src/o_undo.c
@@ -407,7 +407,7 @@ void o_undo_callback(GSCHEM_TOPLEVEL *w_current, int type)
   toplevel->DONT_REDRAW = prev_status;
 
   if (!toplevel->DONT_REDRAW) {
-    o_redraw_all(w_current);
+    o_invalidate_all (w_current);
   }
   i_update_menus(w_current);
 
diff --git a/gschem/src/x_attribedit.c b/gschem/src/x_attribedit.c
index b771f2f..83263a5 100644
--- a/gschem/src/x_attribedit.c
+++ b/gschem/src/x_attribedit.c
@@ -235,11 +235,11 @@ void attrib_edit_dialog_ok(GtkWidget * w, GSCHEM_TOPLEVEL *w_current)
 #endif
       if (invocation_flag == FROM_HOTKEY
 	  && wx != -1 && wy != -1) {
-	o_erase_single(w_current, new);
+	o_invalidate (w_current, new);
 	new->text->x = wx;
 	new->text->y = wy;
 	o_text_recreate(toplevel, new);
-	o_redraw_single (w_current, 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 48fa497..c1b2ffd 100644
--- a/gschem/src/x_autonumber.c
+++ b/gschem/src/x_autonumber.c
@@ -573,9 +573,9 @@ void autonumber_remove_number(AUTONUMBER_TEXT * autotext, OBJECT *o_current)
   g_free (str);
 
   /* redraw the text */
-  o_erase_single(autotext->w_current, o_current);
+  o_invalidate (autotext->w_current, o_current);
   o_text_recreate(autotext->w_current->toplevel, o_current);
-  o_redraw_single (autotext->w_current, o_current);
+  o_invalidate (autotext->w_current, o_current);
 
   /* remove the slot attribute if slotting is active */
   if (autotext->slotting) {
@@ -617,9 +617,9 @@ void autonumber_apply_new_text(AUTONUMBER_TEXT * autotext, OBJECT *o_current,
       slot_str = g_strdup_printf("slot=%d",slot);
       o_text_set_string (autotext->w_current->toplevel, o_slot, slot_str);
       g_free (slot_str);
-      o_erase_single(autotext->w_current, o_slot);
+      o_invalidate (autotext->w_current, o_slot);
       o_text_recreate(autotext->w_current->toplevel, o_slot);
-      o_redraw_single (autotext->w_current, o_slot);
+      o_invalidate (autotext->w_current, o_slot);
     }
     else {
       /* create a new attribute and attach it */
@@ -637,9 +637,9 @@ void autonumber_apply_new_text(AUTONUMBER_TEXT * autotext, OBJECT *o_current,
   g_free (str);
 
   /* redraw the text */
-  o_erase_single(autotext->w_current, o_current);
+  o_invalidate (autotext->w_current, o_current);
   o_text_recreate(autotext->w_current->toplevel, o_current);
-  o_redraw_single (autotext->w_current, o_current);
+  o_invalidate (autotext->w_current, o_current);
   autotext->w_current->toplevel->page_current->CHANGED = 1;
 }
 
@@ -836,7 +836,7 @@ void autonumber_text_autonumber(AUTONUMBER_TEXT *autotext)
   g_list_foreach(searchtext_list, (GFunc) g_free, NULL);
   g_list_free(searchtext_list);
   s_page_goto(w_current->toplevel, pages->data); /* go back to the root page */
-  o_redraw_all(w_current);
+  o_invalidate_all (w_current);
   g_list_free(pages);
   o_undo_savestate(w_current, UNDO_ALL);
 }
diff --git a/gschem/src/x_dialog.c b/gschem/src/x_dialog.c
index 8923505..ce09b88 100644
--- a/gschem/src/x_dialog.c
+++ b/gschem/src/x_dialog.c
@@ -760,14 +760,14 @@ static void line_type_dialog_ok(GtkWidget *w, gpointer data)
     space  = atoi (space_str);
 
     /* apply the new line options to object */
-    o_erase_single (w_current, o_current);
+    o_invalidate (w_current, o_current);
     o_set_line_options (toplevel, o_current,
                         o_current->line_end,
                         type,
                         width,
                         length,
                         space);
-    o_redraw_single (w_current, o_current);
+    o_invalidate (w_current, o_current);
 
   } else {
     /* more than one object in the list */
@@ -787,14 +787,14 @@ static void line_type_dialog_ok(GtkWidget *w, gpointer data)
     while (object != NULL) {
       OBJECT *o_current = (OBJECT*)object->data;
 
-      o_erase_single (w_current, o_current);
+      o_invalidate (w_current, o_current);
       o_set_line_options (toplevel, o_current,
                           o_current->line_end,
                           type   == -1 ? o_current->line_type : type,
                           width  == -1 ? o_current->line_width  : width,
                           length == -1 ? o_current->line_length : length,
                           space  == -1 ? o_current->line_space  : space);
-      o_redraw_single (w_current, o_current);
+      o_invalidate (w_current, o_current);
 
       object = g_list_next(object);
     }
@@ -1140,12 +1140,12 @@ static void fill_type_dialog_ok(GtkWidget *w, gpointer data)
     pitch2 = atoi (pitch2_str);
 
     /* apply the new line options to object */
-    o_erase_single (w_current, o_current);
+    o_invalidate (w_current, o_current);
     o_set_fill_options(toplevel, o_current,
                        type, width,
                        pitch1, angle1,
                        pitch2, angle2);
-    o_redraw_single (w_current, o_current);
+    o_invalidate (w_current, o_current);
 
   } else {
     /* more than one object in the list */
@@ -1169,7 +1169,7 @@ static void fill_type_dialog_ok(GtkWidget *w, gpointer data)
     while (object != NULL) {
       OBJECT *o_current = (OBJECT*)object->data;
 
-      o_erase_single (w_current, o_current);
+      o_invalidate (w_current, o_current);
       o_set_fill_options (toplevel, o_current,
                           type   == -1 ? o_current->fill_type   : type,
                           width  == -1 ? o_current->fill_width  : width,
@@ -1177,7 +1177,7 @@ static void fill_type_dialog_ok(GtkWidget *w, gpointer data)
                           angle1 == -1 ? o_current->fill_angle1 : angle1,
                           pitch2 == -1 ? o_current->fill_pitch2 : pitch2,
                           angle2 == -1 ? o_current->fill_angle2 : angle2);
-      o_redraw_single (w_current, o_current);
+      o_invalidate (w_current, o_current);
 
       object = g_list_next(object);
     }
@@ -1442,11 +1442,11 @@ 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_erase_single (w_current, arc_object);
+      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_redraw_single (w_current, arc_object);
+      o_invalidate (w_current, arc_object);
     } else {
       o_arc_end4(w_current, radius, start_angle, sweep_angle);
     }
@@ -1793,7 +1793,7 @@ void snap_size_dialog_response(GtkWidget *w, gint response,
     size = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(spin_size));
 
     w_current->toplevel->snap_size = size;
-    o_redraw_all(w_current);
+    o_invalidate_all (w_current);
     w_current->toplevel->page_current->CHANGED=1;  /* maybe remove those two lines */
     o_undo_savestate(w_current, UNDO_ALL);
     break;
@@ -2877,7 +2877,7 @@ void find_text_dialog_response(GtkWidget *w, gint response,
                                                     (checkdescend)),
                        !start_find);
     if (done) {
-      o_redraw_all(w_current);
+      o_invalidate_all (w_current);
       close = 1;
     }
     start_find = 0;
diff --git a/gschem/src/x_event.c b/gschem/src/x_event.c
index bd5927a..2fb864c 100644
--- a/gschem/src/x_event.c
+++ b/gschem/src/x_event.c
@@ -674,7 +674,7 @@ gint x_event_button_released(GtkWidget *widget, GdkEventButton *event,
 
       case(MID_MOUSEPAN_ENABLED):
       w_current->doing_pan=FALSE;
-      o_redraw_all(w_current);
+      o_invalidate_all (w_current);
       if (w_current->undo_panzoom) {
         o_undo_savestate(w_current, UNDO_VIEWPORT_ONLY);
       }
@@ -690,7 +690,7 @@ gint x_event_button_released(GtkWidget *widget, GdkEventButton *event,
   } else if (event->button == 3) {
     if (w_current->doing_pan) { /* just for ending a mouse pan */
       w_current->doing_pan=FALSE;
-      o_redraw_all(w_current);
+      o_invalidate_all (w_current);
 
       if (w_current->undo_panzoom) {
         o_undo_savestate(w_current, UNDO_VIEWPORT_ONLY);
@@ -983,7 +983,7 @@ x_event_configure (GtkWidget         *widget,
 
   if (!toplevel->DONT_REDRAW) {
     /* redraw the current page and update UI */
-    o_redraw_all (w_current);
+    o_invalidate_all (w_current);
     x_scrollbars_update (w_current);
   }
 
@@ -1060,7 +1060,7 @@ void x_event_hschanged (GtkAdjustment *adj, GSCHEM_TOPLEVEL *w_current)
     (current_left - new_left);
 
   if (!toplevel->DONT_REDRAW) {
-    o_redraw_all(w_current);
+    o_invalidate_all (w_current);
   }
 }
 
@@ -1102,7 +1102,7 @@ void x_event_vschanged (GtkAdjustment *adj, GSCHEM_TOPLEVEL *w_current)
 #endif
 
   if (!toplevel->DONT_REDRAW) {
-    o_redraw_all(w_current);
+    o_invalidate_all (w_current);
   }
 }
 
diff --git a/gschem/src/x_image.c b/gschem/src/x_image.c
index e274ff4..b2a7b9c 100644
--- a/gschem/src/x_image.c
+++ b/gschem/src/x_image.c
@@ -424,8 +424,7 @@ void x_image_lowlevel(GSCHEM_TOPLEVEL *w_current, const char* filename,
       save_page_top,
       save_page_bottom);
 
-  /* try to use recalc here... */
-  o_redraw_all(w_current);
+  o_invalidate_all (w_current);
 
 }
 
@@ -705,16 +704,16 @@ GdkPixbuf *x_image_get_pixbuf (GSCHEM_TOPLEVEL *w_current)
   
   /* If there are no objects, can't use zoom_extents */
   if (object_found) {
-    o_redraw_all (&toplevel); 
+    o_invalidate_all (&toplevel);
     get_object_glist_bounds (&toplevel,
                              toplevel.page_current->object_list,
-			   &origin_x, &origin_y, 
-			   &right, &bottom);
+                             &origin_x, &origin_y,
+                             &right, &bottom);
   }
 #endif
   /* ------------------  End optional code ------------------------ */
   
-  o_redraw_all (&new_w_current);
+  o_invalidate_all (&new_w_current);
 
   /* Get the pixbuf */
   pixbuf = gdk_pixbuf_get_from_drawable (NULL,new_w_current.drawable, NULL,
diff --git a/gschem/src/x_multiattrib.c b/gschem/src/x_multiattrib.c
index 6d40610..d01e29a 100644
--- a/gschem/src/x_multiattrib.c
+++ b/gschem/src/x_multiattrib.c
@@ -970,14 +970,14 @@ static void multiattrib_callback_toggled_visible(GtkCellRendererToggle *cell_ren
                       COLUMN_ATTRIBUTE, &o_attrib,
                       -1);
   g_assert (o_attrib->type == OBJ_TEXT);
-  o_erase_single (w_current, o_attrib);
+  o_invalidate (w_current, o_attrib);
 
   visibility = o_attrib->visibility == VISIBLE ? INVISIBLE : VISIBLE;
 
   /* actually modifies the attribute */
   o_attrib->visibility = visibility;
   o_text_recreate (w_current->toplevel, o_attrib);
-  o_redraw_single (w_current, o_attrib);
+  o_invalidate (w_current, o_attrib);
   o_undo_savestate (w_current, UNDO_ALL);
 
   /* request an update of display for this row */
@@ -1012,7 +1012,7 @@ static void multiattrib_callback_toggled_show_name(GtkCellRendererToggle *cell_r
                       COLUMN_ATTRIBUTE, &o_attrib,
                       -1);
   g_assert (o_attrib->type == OBJ_TEXT);
-  o_erase_single (w_current, o_attrib);
+  o_invalidate (w_current, o_attrib);
 
   switch (o_attrib->show_name_value) {
       case SHOW_NAME_VALUE: new_snv = SHOW_VALUE;      break;
@@ -1026,7 +1026,7 @@ 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_redraw_single (w_current, o_attrib);
+  o_invalidate (w_current, o_attrib);
   o_undo_savestate (w_current, UNDO_ALL);
 
   /* request an update of display for this row */
@@ -1061,7 +1061,7 @@ static void multiattrib_callback_toggled_show_value(GtkCellRendererToggle *cell_
                       COLUMN_ATTRIBUTE, &o_attrib,
                       -1);
   g_assert (o_attrib->type == OBJ_TEXT);
-  o_erase_single (w_current, o_attrib);
+  o_invalidate (w_current, o_attrib);
 
   switch (o_attrib->show_name_value) {
       case SHOW_NAME_VALUE: new_snv = SHOW_NAME;       break;
@@ -1075,7 +1075,7 @@ 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_redraw_single (w_current, 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/gschem/src/x_pagesel.c b/gschem/src/x_pagesel.c
index 372a386..8e4e9dc 100644
--- a/gschem/src/x_pagesel.c
+++ b/gschem/src/x_pagesel.c
@@ -170,7 +170,7 @@ static void pagesel_callback_selection_changed (GtkTreeSelection *selection,
   s_page_goto (w_current->toplevel, page);
   i_set_filename (w_current, w_current->toplevel->page_current->page_filename);
   x_scrollbars_update (w_current);
-  o_redraw_all (w_current);
+  o_invalidate_all (w_current);
 
   /* We would like to use the following call, but since it calls 
    * x_pagesel_update() it would cause an infinite loop.
diff --git a/gschem/src/x_preview.c b/gschem/src/x_preview.c
index 92fb8e0..5b8e48a 100644
--- a/gschem/src/x_preview.c
+++ b/gschem/src/x_preview.c
@@ -101,7 +101,7 @@ preview_callback_realize (GtkWidget *widget,
                  preview_page->object_list,
                  A_PAN_DONT_REDRAW);
 
-  o_redraw_all(preview_w_current);
+  o_invalidate_all (preview_w_current);
 
 }
 
@@ -159,7 +159,7 @@ preview_callback_button_press (GtkWidget *widget,
       case 1: /* left mouse button: zoom in */
         a_zoom (preview_w_current, ZOOM_IN, HOTKEY,
                 A_PAN_DONT_REDRAW);
-        o_redraw_all (preview_w_current);
+        o_invalidate_all (preview_w_current);
         break;
       case 2: /* middle mouse button: pan */
 	if (!x_event_get_pointer_position(preview_w_current, FALSE, &wx, &wy))
@@ -169,7 +169,7 @@ preview_callback_button_press (GtkWidget *widget,
       case 3: /* right mouse button: zoom out */
         a_zoom (preview_w_current, ZOOM_OUT, HOTKEY,
                 A_PAN_DONT_REDRAW);
-        o_redraw_all (preview_w_current);
+        o_invalidate_all (preview_w_current);
         break;
   }
   
@@ -243,7 +243,7 @@ preview_update (Preview *preview)
   a_zoom_extents (preview_w_current,
                   preview_toplevel->page_current->object_list,
                   A_PAN_DONT_REDRAW);
-  o_redraw_all (preview_w_current);
+  o_invalidate_all (preview_w_current);
   
 }
 
diff --git a/gschem/src/x_window.c b/gschem/src/x_window.c
index 5d198b4..249cdec 100644
--- a/gschem/src/x_window.c
+++ b/gschem/src/x_window.c
@@ -865,7 +865,7 @@ x_window_set_current_page (GSCHEM_TOPLEVEL *w_current, PAGE *page)
   x_vscrollbar_update (w_current);
   toplevel->DONT_REDRAW = 0;
 
-  o_redraw_all (w_current);
+  o_invalidate_all (w_current);
 }
 
 /*! \brief Saves a page to a file.

commit 1deba1aba224cd2e87a34148949edaaeec630ed0
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Date:   Sat Dec 20 08:10:47 2008 +0000

    gschem: Change object specific redraw calls to o_redraw_single()
    
    Makes switching redraw calls to invalidate calls more formulic.

diff --git a/gschem/src/g_hook.c b/gschem/src/g_hook.c
index af4288c..6a5c2dc 100644
--- a/gschem/src/g_hook.c
+++ b/gschem/src/g_hook.c
@@ -364,7 +364,7 @@ SCM g_set_attrib_text_properties(SCM attrib_smob, SCM scm_coloridx,
       }
       o_text_recreate(toplevel, object);
       if (!toplevel->DONT_REDRAW) {
-	o_text_draw(w_current, object);
+        o_redraw_single (w_current, object);
       }
     }
   }
diff --git a/gschem/src/o_attrib.c b/gschem/src/o_attrib.c
index ded6913..17c20cc 100644
--- a/gschem/src/o_attrib.c
+++ b/gschem/src/o_attrib.c
@@ -103,7 +103,7 @@ void o_attrib_toggle_visibility(GSCHEM_TOPLEVEL *w_current, OBJECT *object)
 
     if (toplevel->show_hidden_text) {
       /* draw text so that little I is drawn */
-      o_text_draw(w_current, object);
+      o_redraw_single (w_current, object);
     }
 
   } else {
@@ -121,7 +121,7 @@ void o_attrib_toggle_visibility(GSCHEM_TOPLEVEL *w_current, OBJECT *object)
       o_text_recreate(toplevel, object);
     }
 
-    o_text_draw(w_current, object);
+    o_redraw_single (w_current, object);
   }
 
   toplevel->page_current->CHANGED = 1;
@@ -147,7 +147,7 @@ void o_attrib_toggle_show_name_value(GSCHEM_TOPLEVEL *w_current,
   o_erase_single(w_current, object);
   object->show_name_value = show_name_value;
   o_text_recreate(toplevel, object);
-  o_text_draw(w_current, object);
+  o_redraw_single (w_current, object);
 
   toplevel->page_current->CHANGED = 1;
 }
@@ -252,7 +252,7 @@ OBJECT *o_attrib_add_attrib(GSCHEM_TOPLEVEL *w_current,
   o_selection_add (toplevel->page_current->selection_list, new_obj);
 
   o_erase_single (w_current, new_obj);
-  o_text_draw (w_current, new_obj);
+  o_redraw_single (w_current, new_obj);
 
   /* handle slot= attribute, it's a special case */
   if (g_ascii_strncasecmp (text_string, "slot=", 5) == 0) {
diff --git a/gschem/src/o_bus.c b/gschem/src/o_bus.c
index 569cf9c..ba31e96 100644
--- a/gschem/src/o_bus.c
+++ b/gschem/src/o_bus.c
@@ -259,7 +259,7 @@ 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->page_current, new_obj);
 
-  o_bus_draw(w_current, new_obj);
+  o_redraw_single (w_current, new_obj);
 
   /* connect the new bus to the other busses */
   prev_conn_objects = s_conn_return_others (prev_conn_objects, new_obj);
diff --git a/gschem/src/o_grips.c b/gschem/src/o_grips.c
index fe8f07c..84fddd5 100644
--- a/gschem/src/o_grips.c
+++ b/gschem/src/o_grips.c
@@ -1373,7 +1373,7 @@ void o_grips_end_net(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int whichone
     o_erase_single(w_current, o_current);
     o_cue_undraw(w_current, o_current);
 
-    o_net_draw(w_current, o_current);
+    o_redraw_single (w_current, o_current);
     o_cue_draw_single(w_current, o_current);
   }
 
diff --git a/gschem/src/o_misc.c b/gschem/src/o_misc.c
index cdf2231..cf5e873 100644
--- a/gschem/src/o_misc.c
+++ b/gschem/src/o_misc.c
@@ -409,7 +409,7 @@ void o_edit_show_hidden_lowlevel (GSCHEM_TOPLEVEL *w_current, GList *o_list)
           o_text_recreate(toplevel, o_current);
         }
         o_recalc_single_object(toplevel, o_current);
-        o_text_draw(w_current, o_current);
+        o_redraw_single (w_current, o_current);
       } else {
         /* object is hidden and we are now NOT drawing it, so */
         /* get rid of the extra primitive data */
@@ -479,7 +479,7 @@ void o_edit_make_visible (GSCHEM_TOPLEVEL *w_current, GList *o_list)
           o_text_recreate(toplevel, o_current);
         }
 
-        o_text_draw(w_current, o_current);
+        o_redraw_single (w_current, o_current);
 
         toplevel->page_current->CHANGED = 1;
       }
@@ -661,7 +661,7 @@ void o_edit_show_specific_text (GSCHEM_TOPLEVEL *w_current, GList * o_list,
           if (o_current->text->prim_objs == NULL) {
             o_text_recreate(toplevel, o_current);
           }
-          o_text_draw(w_current, o_current);
+          o_redraw_single (w_current, o_current);
           toplevel->page_current->CHANGED = 1;
         }
       }
diff --git a/gschem/src/o_net.c b/gschem/src/o_net.c
index 4589eda..f39ce10 100644
--- a/gschem/src/o_net.c
+++ b/gschem/src/o_net.c
@@ -1312,7 +1312,7 @@ int o_net_add_busrippers(GSCHEM_TOPLEVEL *w_current, OBJECT *net_obj,
           o_complex_promote_attribs (toplevel, new_obj,
                                      &toplevel->page_current->object_list);
 
-          o_complex_draw (w_current, new_obj);
+          o_redraw_single (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 b3e02ca..88488df 100644
--- a/gschem/src/o_picture.c
+++ b/gschem/src/o_picture.c
@@ -617,7 +617,7 @@ void o_picture_exchange (GSCHEM_TOPLEVEL *w_current, GdkPixbuf *pixbuf,
         object->picture->ratio = (double)gdk_pixbuf_get_width(pixbuf) /
                                          gdk_pixbuf_get_height(pixbuf);
         /* Draw new picture */
-        o_picture_draw(w_current, object);
+        o_redraw_single (w_current, object);
       }
     }
     list = g_list_next(list);
diff --git a/gschem/src/o_pin.c b/gschem/src/o_pin.c
index 529072b..e24b852 100644
--- a/gschem/src/o_pin.c
+++ b/gschem/src/o_pin.c
@@ -209,7 +209,7 @@ void o_pin_end(GSCHEM_TOPLEVEL *w_current, int x, int y)
   o_cue_draw_list (w_current, prev_conn_objects);
   g_list_free (prev_conn_objects);
   o_cue_draw_single(w_current, o_current_pin); 
-  o_pin_draw(w_current, o_current_pin);
+  o_redraw_single (w_current, o_current_pin);
 
   toplevel->page_current->CHANGED=1;
   o_undo_savestate(w_current, UNDO_ALL);
diff --git a/gschem/src/o_text.c b/gschem/src/o_text.c
index e2dcff8..7759c6a 100644
--- a/gschem/src/o_text.c
+++ b/gschem/src/o_text.c
@@ -355,7 +355,7 @@ void o_text_edit_end(GSCHEM_TOPLEVEL *w_current, char *string, int len, int text
 	  }
         }
         o_text_recreate(toplevel, object);
-        o_text_draw(w_current, object);
+        o_redraw_single (w_current, object);
       } 
     }
     
@@ -395,7 +395,7 @@ void o_text_change(GSCHEM_TOPLEVEL *w_current, OBJECT *object, char *string,
   object->visibility = visibility;
   object->show_name_value = show;
   o_text_recreate(toplevel, object);
-  o_text_draw(w_current, object);
+  o_redraw_single (w_current, object);
 
   /* handle slot= attribute, it's a special case */
   if (g_ascii_strncasecmp (string, "slot=", 5) == 0) {
diff --git a/gschem/src/x_attribedit.c b/gschem/src/x_attribedit.c
index 67eff1f..b771f2f 100644
--- a/gschem/src/x_attribedit.c
+++ b/gschem/src/x_attribedit.c
@@ -239,7 +239,7 @@ 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_text_draw(w_current, new);
+	o_redraw_single (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 81a56ce..48fa497 100644
--- a/gschem/src/x_autonumber.c
+++ b/gschem/src/x_autonumber.c
@@ -575,7 +575,7 @@ void autonumber_remove_number(AUTONUMBER_TEXT * autotext, OBJECT *o_current)
   /* redraw the text */
   o_erase_single(autotext->w_current, o_current);
   o_text_recreate(autotext->w_current->toplevel, o_current);
-  o_text_draw(autotext->w_current, o_current);
+  o_redraw_single (autotext->w_current, o_current);
 
   /* remove the slot attribute if slotting is active */
   if (autotext->slotting) {
@@ -619,7 +619,7 @@ void autonumber_apply_new_text(AUTONUMBER_TEXT * autotext, OBJECT *o_current,
       g_free (slot_str);
       o_erase_single(autotext->w_current, o_slot);
       o_text_recreate(autotext->w_current->toplevel, o_slot);
-      o_text_draw(autotext->w_current, o_slot);
+      o_redraw_single (autotext->w_current, o_slot);
     }
     else {
       /* create a new attribute and attach it */
@@ -639,7 +639,7 @@ void autonumber_apply_new_text(AUTONUMBER_TEXT * autotext, OBJECT *o_current,
   /* redraw the text */
   o_erase_single(autotext->w_current, o_current);
   o_text_recreate(autotext->w_current->toplevel, o_current);
-  o_text_draw(autotext->w_current, o_current);
+  o_redraw_single (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 8daff33..6d40610 100644
--- a/gschem/src/x_multiattrib.c
+++ b/gschem/src/x_multiattrib.c
@@ -977,7 +977,7 @@ 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_text_draw (w_current, o_attrib);
+  o_redraw_single (w_current, o_attrib);
   o_undo_savestate (w_current, UNDO_ALL);
 
   /* request an update of display for this row */
@@ -1026,7 +1026,7 @@ 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_text_draw (w_current, o_attrib);
+  o_redraw_single (w_current, o_attrib);
   o_undo_savestate (w_current, UNDO_ALL);
 
   /* request an update of display for this row */
@@ -1075,7 +1075,7 @@ 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_text_draw (w_current, o_attrib);
+  o_redraw_single (w_current, o_attrib);
   o_undo_savestate (w_current, UNDO_ALL);
   
   /* request an update of display for this row */

commit c7c5a24102474d6d9c607c4592736c8f93fe090b
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Date:   Sat Dec 20 08:10:43 2008 +0000

    gschem: Add size of grip (or cue) to invalidate and redraw regions.
    
    Adding to the invalidated region cures screen artifacts left due
    to the bounds of an object not including the area occupied by its
    rubberbanding grips.
    
    Adding to the coordinates used with s_page_objects_in_region() ensures
    that grips / cues from adjacent objects are drawn correctly when repainting
    a damaged region from the expose handler.
    
    This is a bit of a hack and could be better catered for by invalidating
    the grip regions separately from an object specific invalidate function.
    s_page_objects_in_region() would also have to return objects with grips
    or cues touching the passed region.

diff --git a/gschem/src/o_basic.c b/gschem/src/o_basic.c
index 77253a2..17b94f6 100644
--- a/gschem/src/o_basic.c
+++ b/gschem/src/o_basic.c
@@ -43,6 +43,9 @@ void o_redraw_rects (GSCHEM_TOPLEVEL *w_current,
   TOPLEVEL *toplevel = w_current->toplevel;
   gboolean draw_selected = TRUE;
   int redraw_state = toplevel->DONT_REDRAW;
+  int grip_half_size;
+  int cue_half_size;
+  int bloat;
   int i;
   GList *obj_list;
   GList *iter;
@@ -58,6 +61,10 @@ void o_redraw_rects (GSCHEM_TOPLEVEL *w_current,
   g_return_if_fail (toplevel != NULL);
   g_return_if_fail (toplevel->page_current != NULL);
 
+  grip_half_size = o_grips_size (w_current);
+  cue_half_size = SCREENabs (toplevel, CUE_BOX_SIZE);
+  bloat = MAX (grip_half_size, cue_half_size);
+
   world_rects = g_new (BOX, n_rectangles);
 
   for (i = 0; i < n_rectangles; i++) {
@@ -68,9 +75,9 @@ void o_redraw_rects (GSCHEM_TOPLEVEL *w_current,
     width = rectangles[i].width;
     height = rectangles[i].height;
 
-    SCREENtoWORLD (toplevel, x, y + height,
+    SCREENtoWORLD (toplevel, x - bloat, y + height + bloat,
                    &world_rects[i].lower_x, &world_rects[i].lower_y);
-    SCREENtoWORLD (toplevel, x + width, y,
+    SCREENtoWORLD (toplevel, x + width + bloat, y - bloat,
                    &world_rects[i].upper_x, &world_rects[i].upper_y);
   }
 
@@ -635,6 +642,9 @@ void o_glist_draw_xor(GSCHEM_TOPLEVEL *w_current, int dx, int dy, GList *list)
  *  to expand the invalidated region if anti-aliased drawing is ever
  *  used.
  *
+ *  A further, larger margin is added to account for invalidating the
+ *  size occupied by an object's grips.
+ *
  *  If the GSCHEM_TOPLEVEL in question is not rendering to a GDK_WINDOW,
  *  (e.g. image export), this function call is a no-op. A test is used:
  *  GDK_IS_WINDOW(), which should be safe since in either case,
@@ -651,16 +661,23 @@ void o_invalidate_rect (GSCHEM_TOPLEVEL *w_current,
                         int x1, int y1, int x2, int y2)
 {
   GdkRectangle rect;
+  int grip_half_size;
+  int cue_half_size;
+  int bloat;
 
   /* BUG: We get called when rendering an image, and w_current->window
    *      is a GdkPixmap. Ensure we only invalidate GdkWindows. */
   if (!GDK_IS_WINDOW( w_current->window ))
     return;
 
-  rect.x = MIN(x1, x2) - INVALIDATE_MARGIN;
-  rect.y = MIN(y1, y2) - INVALIDATE_MARGIN;
-  rect.width = 1 + abs( x1 - x2 ) + 2 * INVALIDATE_MARGIN;
-  rect.height = 1 + abs( y1 - y2 ) + 2 * INVALIDATE_MARGIN;
+  grip_half_size = o_grips_size (w_current);
+  cue_half_size = SCREENabs (w_current->toplevel, CUE_BOX_SIZE);
+  bloat = MAX (grip_half_size, cue_half_size) + INVALIDATE_MARGIN;
+
+  rect.x = MIN(x1, x2) - bloat;
+  rect.y = MIN(y1, y2) - bloat;
+  rect.width = 1 + abs( x1 - x2 ) + 2 * bloat;
+  rect.height = 1 + abs( y1 - y2 ) + 2 * bloat;
   gdk_window_invalidate_rect( w_current->window, &rect, FALSE );
 }
 

commit 68f782583cc41b542dc237cb9173f64ffc01ce76
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Date:   Sat Dec 20 08:09:57 2008 +0000

    gschem: Just redraw everything when we get an expose event
    
    Disable generation of our backing pixmap and remove o_invalidate_rect()
    calls from various drawing functions. The backingstore is straight to the
    screen, so there is no need to make that call (it causes a redraw loop).

diff --git a/gschem/include/prototype.h b/gschem/include/prototype.h
index bf28467..ec6ec35 100644
--- a/gschem/include/prototype.h
+++ b/gschem/include/prototype.h
@@ -481,6 +481,7 @@ void o_attrib_toggle_show_name_value(GSCHEM_TOPLEVEL *w_current, OBJECT *object,
 OBJECT *o_attrib_add_attrib(GSCHEM_TOPLEVEL *w_current, const char *text_string, int visibility, int show_name_value, OBJECT *object);
 /* o_basic.c */
 void o_redraw_all(GSCHEM_TOPLEVEL *w_current);
+void o_redraw_rects(GSCHEM_TOPLEVEL *w_current, GdkRectangle *rectangles, int n_rectangles);
 void o_redraw(GSCHEM_TOPLEVEL *w_current, GList *object_list, gboolean draw_selected);
 void o_redraw_single(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current);
 void o_draw_list(GSCHEM_TOPLEVEL *w_current, GList *list);
@@ -744,7 +745,7 @@ void attrib_edit_dialog(GSCHEM_TOPLEVEL *w_current, OBJECT *attr_obj, int flag);
 /* x_autonumber.c */
 void autonumber_text_dialog(GSCHEM_TOPLEVEL *w_current);
 /* x_basic.c */
-void x_repaint_background(GSCHEM_TOPLEVEL *w_current);
+void x_repaint_background_region(GSCHEM_TOPLEVEL *w_current, int x, int y, int width, int height);
 void x_hscrollbar_set_ranges(GSCHEM_TOPLEVEL *w_current);
 void x_hscrollbar_update(GSCHEM_TOPLEVEL *w_current);
 void x_vscrollbar_set_ranges(GSCHEM_TOPLEVEL *w_current);
@@ -816,7 +817,7 @@ void x_fileselect_open(GSCHEM_TOPLEVEL *w_current);
 void x_fileselect_save(GSCHEM_TOPLEVEL *w_current);
 int x_fileselect_load_backup(TOPLEVEL *toplevel, GString *message);
 /* x_grid.c */
-void x_grid_draw(GSCHEM_TOPLEVEL *w_current);
+void x_grid_draw_region(GSCHEM_TOPLEVEL *w_current, int x, int y, int width, int height);
 void x_draw_tiles(GSCHEM_TOPLEVEL *w_current);
 /* x_image.c */
 void x_image_lowlevel(GSCHEM_TOPLEVEL *w_current, const char* filename,
diff --git a/gschem/src/a_zoom.c b/gschem/src/a_zoom.c
index 1125ed2..52ccb0b 100644
--- a/gschem/src/a_zoom.c
+++ b/gschem/src/a_zoom.c
@@ -300,10 +300,6 @@ void a_zoom_box_rubberband_xor(GSCHEM_TOPLEVEL *w_current)
 			x_get_darkcolor(w_current->zoom_box_color));
   gdk_draw_rectangle (w_current->drawable, w_current->xor_gc, FALSE,
                       box_left, box_top, box_width, box_height);
-  o_invalidate_rect(w_current, box_left,
-                               box_top,
-                               box_left + box_width,
-		               box_top + box_height);
 }
 
 /*! \todo Finish function documentation!!!
diff --git a/gschem/src/gschem.c b/gschem/src/gschem.c
index 9b3384a..e7b3a6a 100644
--- a/gschem/src/gschem.c
+++ b/gschem/src/gschem.c
@@ -131,7 +131,6 @@ void main_prog(void *closure, int argc, char *argv[])
   int first_page = 1;
   char *geda_data = NULL;
   char *filename;
-  gboolean save_grid;
   SCM scm_tmp;
 
 #ifdef HAVE_GTHREAD
@@ -270,15 +269,6 @@ void main_prog(void *closure, int argc, char *argv[])
   x_color_init();
   x_window_setup (w_current);
 
-  /* Repaint the background in-case we have to throw up a "restore backup?"
-   * dialog box. Disable grid drawing as there is no page loaded, hence no
-   * scale factor to draw the grid at. (gschem will segfault otherwise.)
-   */
-  save_grid = w_current->grid;
-  w_current->grid = FALSE;
-  x_repaint_background (w_current);
-  w_current->grid = save_grid;
-
 #ifdef HAS_LIBSTROKE
   x_stroke_init ();
 #endif /* HAS_LIBSTROKE */
diff --git a/gschem/src/o_arc.c b/gschem/src/o_arc.c
index 890b8f9..779670a 100644
--- a/gschem/src/o_arc.c
+++ b/gschem/src/o_arc.c
@@ -1082,15 +1082,6 @@ void o_arc_rubberarc_xor(GSCHEM_TOPLEVEL *w_current)
   x1 = cx + radius*cos(rad_angle);
   y1 = cy - radius*sin(rad_angle);
   gdk_draw_line (w_current->drawable, w_current->xor_gc, cx, cy, x1, y1);
-
-  /* FIXME: This isn't a tight bounding box for now, but the code
-   *        to compute a better bounds it complex, and might wait
-   *        until we're considered having real OBJECT data during
-   *        rubberbanding and using world_get_arc_bounds().
-   */
-  o_invalidate_rect(w_current, 
-		    cx - radius, cy - radius,
-		    cx + radius, cy + radius);
 }
 
 /*! \brief Draw grip marks on arc.
diff --git a/gschem/src/o_basic.c b/gschem/src/o_basic.c
index b78a18f..77253a2 100644
--- a/gschem/src/o_basic.c
+++ b/gschem/src/o_basic.c
@@ -37,6 +37,155 @@
  *  \par Function Description
  *
  */
+void o_redraw_rects (GSCHEM_TOPLEVEL *w_current,
+                     GdkRectangle *rectangles, int n_rectangles)
+{
+  TOPLEVEL *toplevel = w_current->toplevel;
+  gboolean draw_selected = TRUE;
+  int redraw_state = toplevel->DONT_REDRAW;
+  int i;
+  GList *obj_list;
+  GList *iter;
+  BOX *world_rects;
+
+  if (!toplevel->DONT_REDRAW) {
+    for (i = 0; i < n_rectangles; i++) {
+      x_repaint_background_region (w_current, rectangles[i].x, rectangles[i].y,
+                                   rectangles[i].width, rectangles[i].height);
+    }
+  }
+
+  g_return_if_fail (toplevel != NULL);
+  g_return_if_fail (toplevel->page_current != NULL);
+
+  world_rects = g_new (BOX, n_rectangles);
+
+  for (i = 0; i < n_rectangles; i++) {
+    int x, y, width, height;
+
+    x = rectangles[i].x;
+    y = rectangles[i].y;
+    width = rectangles[i].width;
+    height = rectangles[i].height;
+
+    SCREENtoWORLD (toplevel, x, y + height,
+                   &world_rects[i].lower_x, &world_rects[i].lower_y);
+    SCREENtoWORLD (toplevel, x + width, y,
+                   &world_rects[i].upper_x, &world_rects[i].upper_y);
+  }
+
+  obj_list = s_page_objects_in_regions (toplevel->page_current,
+                                        world_rects, n_rectangles);
+  g_free (world_rects);
+
+  draw_selected = !(w_current->inside_action &&
+                    ((w_current->event_state == MOVE) ||
+                     (w_current->event_state == ENDMOVE) ||
+                     (w_current->event_state == GRIPS)));
+
+  w_current->inside_redraw = 1;
+  for (iter = obj_list; iter != NULL; iter = g_list_next (iter)) {
+    OBJECT *o_current = iter->data;
+
+    if (o_current->draw_func != NULL) {
+      toplevel->DONT_REDRAW = redraw_state ||
+                              o_current->dont_redraw ||
+                              (!draw_selected && o_current->selected);
+      (*o_current->draw_func)(w_current, o_current);
+    }
+  }
+  w_current->inside_redraw = 0;
+  toplevel->DONT_REDRAW = redraw_state;
+
+  o_cue_redraw_all (w_current, obj_list, draw_selected);
+
+  if (w_current->inside_action) {
+    switch (w_current->event_state) {
+      case MOVE:
+      case ENDMOVE:
+        o_move_rubbermove_xor (w_current, TRUE);
+        break;
+
+      case ENDCOPY:
+      case ENDMCOPY:
+      case ENDCOMP:
+      case ENDTEXT:
+      case ENDPASTE:
+        /* Redraw the rubberband objects (if they were previously visible) */
+        if (w_current->rubber_visible)
+          o_place_rubberplace_xor (w_current, TRUE);
+        break;
+
+      case STARTDRAWNET:
+      case DRAWNET:
+      case NETCONT:
+        if (w_current->rubber_visible)
+          o_net_drawrubber (w_current);
+        break;
+
+      case STARTDRAWBUS:
+      case DRAWBUS:
+      case BUSCONT:
+        if (w_current->rubber_visible)
+          o_bus_rubberbus_xor(w_current);
+        break;
+
+      case GRIPS:
+        if (w_current->rubber_visible)
+          o_grips_rubbergrip_xor (w_current);
+        break;
+
+      case SBOX:
+        if (w_current->rubber_visible)
+          o_select_box_rubberband_xor (w_current);
+        break;
+
+      case ZOOMBOXEND:
+        if (w_current->rubber_visible)
+          a_zoom_box_rubberband_xor (w_current);
+        break;
+
+      case ENDLINE:
+        if (w_current->rubber_visible)
+          o_line_rubberline_xor (w_current);
+        break;
+
+      case ENDBOX:
+        if (w_current->rubber_visible)
+          o_box_rubberbox_xor (w_current);
+        break;
+
+      case ENDPICTURE:
+        if (w_current->rubber_visible)
+          o_picture_rubberbox_xor (w_current);
+        break;
+
+      case ENDCIRCLE:
+        if (w_current->rubber_visible)
+          o_circle_rubbercircle_xor (w_current);
+        break;
+
+      case ENDARC:
+        if (w_current->rubber_visible)
+          o_arc_rubberarc_xor (w_current);
+        break;
+
+      case ENDPIN:
+        if (w_current->rubber_visible)
+          o_pin_rubberpin_xor (w_current);
+        break;
+    }
+  }
+
+  g_list_free (obj_list);
+}
+
+
+/*! \todo Finish function documentation!!!
+ *  \brief
+ *  \par Function Description
+ *
+ */
 void o_redraw_all(GSCHEM_TOPLEVEL *w_current)
 {
   TOPLEVEL *toplevel = w_current->toplevel;
@@ -110,8 +259,6 @@ void o_redraw (GSCHEM_TOPLEVEL *w_current, GList *object_list, gboolean draw_sel
     iter = g_list_next (iter);
   }
   toplevel->DONT_REDRAW = redraw_state;
-
-  o_invalidate_glist (w_current, object_list);
 }
 
 /*! \brief Redraw an object on the screen.
@@ -135,8 +282,6 @@ void o_redraw_single(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
   if (o_current->draw_func != NULL) {
     (*o_current->draw_func)(w_current, o_current);
   }
-
-  o_invalidate (w_current, o_current);
 }
 
 /*! \todo Finish function documentation!!!
@@ -209,8 +354,6 @@ void o_erase_selected(GSCHEM_TOPLEVEL *w_current)
 
     iter = g_list_next( iter );
   }
-
-  o_invalidate_glist (w_current, list);
 }
 
 /*! \brief Erase a given OBJECT
@@ -241,8 +384,6 @@ void o_erase_single(GSCHEM_TOPLEVEL *w_current, OBJECT *object)
     }
   }
   toplevel->override_color = -1;
-
-  o_invalidate (w_current, o_current);
 }
 
 /*! \todo Finish function documentation!!!
diff --git a/gschem/src/o_box.c b/gschem/src/o_box.c
index 949cec4..de5e259 100644
--- a/gschem/src/o_box.c
+++ b/gschem/src/o_box.c
@@ -930,8 +930,6 @@ void o_box_rubberbox_xor(GSCHEM_TOPLEVEL *w_current)
 			     GDK_JOIN_MITER);
   gdk_draw_rectangle (w_current->drawable, w_current->xor_gc,
                       FALSE, box_left, box_top, box_width, box_height);
-  o_invalidate_rect(w_current, box_left, box_top,
-		    box_left + box_width, box_top + box_height);
 }
 
 /*! \brief Draw grip marks on box.
diff --git a/gschem/src/o_bus.c b/gschem/src/o_bus.c
index dae8067..569cf9c 100644
--- a/gschem/src/o_bus.c
+++ b/gschem/src/o_bus.c
@@ -195,8 +195,6 @@ void o_bus_draw_xor_single(GSCHEM_TOPLEVEL *w_current,
 
   gdk_draw_line (w_current->drawable, w_current->outline_xor_gc,
                  sx[0], sy[0], sx[1], sy[1]);
-  o_invalidate_rect(w_current,
-                    sx[0], sy[0], sx[1], sy[1]);
 }
 
 /*! \brief set the start point of a new bus
@@ -355,9 +353,6 @@ void o_bus_rubberbus_xor(GSCHEM_TOPLEVEL *w_current)
   gdk_gc_set_foreground(w_current->xor_gc, 
 			x_get_darkcolor(w_current->select_color));
   gdk_draw_line (w_current->drawable, w_current->xor_gc, x1, y1, x2, y2);
-  o_invalidate_rect(w_current, 
-		    min(x1, x2) - size/2, min(y1, y2) - size/2,
-		    max(x1, x2) + size/2, max(y1, y2) + size/2);
 
   if (toplevel->bus_style == THICK ) {
     gdk_gc_set_line_attributes(w_current->xor_gc, 0,
diff --git a/gschem/src/o_circle.c b/gschem/src/o_circle.c
index 31a5ff5..8e32325 100644
--- a/gschem/src/o_circle.c
+++ b/gschem/src/o_circle.c
@@ -670,9 +670,6 @@ void o_circle_rubbercircle_xor(GSCHEM_TOPLEVEL *w_current)
   gdk_draw_arc (w_current->drawable, w_current->xor_gc, FALSE,
                 cx - radius, cy - radius, 2 * radius, 2* radius,
                 0, FULL_CIRCLE);
-  o_invalidate_rect(w_current, 
-		    cx - radius, cy - radius,
-		    cx + radius, cy + radius);
 }
 
 /*! \brief Draw grip marks on circle.
diff --git a/gschem/src/o_cue.c b/gschem/src/o_cue.c
index 891265a..a88055d 100644
--- a/gschem/src/o_cue.c
+++ b/gschem/src/o_cue.c
@@ -174,8 +174,6 @@ void o_cue_draw_lowlevel(GSCHEM_TOPLEVEL *w_current, OBJECT *object, int whichon
                                 screen_y - size,
                                 x2size,
                                 x2size);
-	    o_invalidate_rect(w_current, screen_x - size, screen_y - size,
-	                                 screen_x + size, screen_y + size);
 	  }
         
         } else if (count >= 2) {
@@ -194,8 +192,6 @@ void o_cue_draw_lowlevel(GSCHEM_TOPLEVEL *w_current, OBJECT *object, int whichon
                           screen_x - size,
                           screen_y - size,
                           x2size, x2size, 0, FULL_CIRCLE);
-	    o_invalidate_rect(w_current, screen_x - size, screen_y - size,
-                                   screen_x + size, screen_y + size);
 	  }
         }
       } else if (object->type == OBJ_PIN) {
@@ -267,8 +263,6 @@ void o_cue_draw_lowlevel(GSCHEM_TOPLEVEL *w_current, OBJECT *object, int whichon
                       screen_x - size,
                       screen_y - size,
                       x2size, x2size, 0, FULL_CIRCLE);
-	    o_invalidate_rect(w_current, screen_x - size, screen_y - size,
-                                   screen_x + size, screen_y + size);
       }
       break;
 
@@ -310,8 +304,6 @@ void o_cue_erase_lowlevel(GSCHEM_TOPLEVEL *w_current, OBJECT *object, int whicho
                         screen_y - size,
                         x2size,
                         x2size);
-	    o_invalidate_rect(w_current, screen_x - size, screen_y - size,
-                                   screen_x + size, screen_y + size);
   }
 
 }
@@ -367,8 +359,6 @@ void o_cue_draw_lowlevel_midpoints(GSCHEM_TOPLEVEL *w_current, OBJECT *object)
                         screen_x - size,
                         screen_y - size,
                         x2size, x2size, 0, FULL_CIRCLE);
-          o_invalidate_rect (w_current, screen_x - size, screen_y - size,
-                                        screen_x + size, screen_y + size);
         }
         break;
     }
diff --git a/gschem/src/o_grips.c b/gschem/src/o_grips.c
index ffc4026..fe8f07c 100644
--- a/gschem/src/o_grips.c
+++ b/gschem/src/o_grips.c
@@ -1625,7 +1625,6 @@ void o_grips_draw(GSCHEM_TOPLEVEL *w_current, int x, int y)
     /* draw the grip in backingstore */
     gdk_draw_rectangle (w_current->drawable, w_current->gc, FALSE,
                         x - size, y - size, x2size, x2size);
-    o_invalidate_rect(w_current, x - size, y - size, x + size, y + size);
   }
 }
 
diff --git a/gschem/src/o_line.c b/gschem/src/o_line.c
index 21f386e..9ff9b85 100644
--- a/gschem/src/o_line.c
+++ b/gschem/src/o_line.c
@@ -893,7 +893,6 @@ void o_line_rubberline_xor(GSCHEM_TOPLEVEL *w_current)
 			     GDK_LINE_SOLID, GDK_CAP_NOT_LAST, 
 			     GDK_JOIN_MITER);
   gdk_draw_line (w_current->drawable, w_current->xor_gc, x1, y1, x2, y2);
-  o_invalidate_rect(w_current, x1, y1, x2, y2);
 }
 
 /*! \brief Draw grip marks on line.
diff --git a/gschem/src/o_net.c b/gschem/src/o_net.c
index c9fd2fd..4589eda 100644
--- a/gschem/src/o_net.c
+++ b/gschem/src/o_net.c
@@ -265,9 +265,6 @@ void o_net_draw_xor_single(GSCHEM_TOPLEVEL *w_current, int dx, int dy, int which
 
   gdk_draw_line (w_current->drawable, w_current->outline_xor_gc,
                  sx[0], sy[0], sx[1], sy[1]);
-  o_invalidate_rect(w_current,
-                    sx[0], sy[0], sx[1], sy[1]);
-
 }
 
 
@@ -909,31 +906,16 @@ void o_net_drawrubber(GSCHEM_TOPLEVEL *w_current)
                     magnetic_y - magnetic_halfsize,
                     2 * magnetic_halfsize, 2 * magnetic_halfsize,
                     0, FULL_CIRCLE);
-      o_invalidate_rect(w_current, 
-			magnetic_x - magnetic_halfsize - size/2,
-			magnetic_y - magnetic_halfsize - size/2,
-			magnetic_x + magnetic_halfsize + size/2,
-			magnetic_y + magnetic_halfsize + size/2);
     }
   }
 
   /* draw primary line */
   gdk_draw_line (w_current->drawable, w_current->xor_gc,
                  first_x, first_y, second_x, second_y);
-  o_invalidate_rect(w_current, 
-		    min(first_x, second_x) - size/2,
-		    min(first_y, second_y) - size/2,
-		    max(first_x, second_x) + size/2,
-		    max(first_y, second_y) + size/2);
 
   /* Draw secondary line */
   gdk_draw_line (w_current->drawable, w_current->xor_gc,
                  second_x, second_y, third_x, third_y);
-  o_invalidate_rect(w_current, 
-		    min(second_x, third_x) - size/2,
-		    min(second_y, third_y) - size/2,
-		    max(second_x, third_x) + size/2,
-		    max(second_y, third_y) + size/2);
 
   if (toplevel->net_style == THICK) {
     gdk_gc_set_line_attributes(w_current->xor_gc, 0,
@@ -987,30 +969,15 @@ void o_net_eraserubber(GSCHEM_TOPLEVEL *w_current)
                  magnetic_y - magnetic_halfsize,
                  2 * magnetic_halfsize, 2 * magnetic_halfsize,
                  0, FULL_CIRCLE);
-      o_invalidate_rect(w_current, 
-			magnetic_x - magnetic_halfsize - size/2,
-			magnetic_y - magnetic_halfsize - size/2,
-			magnetic_x + magnetic_halfsize + size/2,
-			magnetic_y + magnetic_halfsize + size/2);
   }
 
   /* Erase primary primary rubber net line */
   gdk_draw_line (w_current->drawable, w_current->xor_gc,
                  first_x, first_y, second_x, second_y);
-  o_invalidate_rect(w_current, 
-		    min(first_x, second_x) - size/2,
-		    min(first_y, second_y) - size/2,
-		    max(first_x, second_x) + size/2,
-		    max(first_y, second_y) + size/2);
 
   /* Erase secondary rubber net line */
   gdk_draw_line (w_current->drawable, w_current->xor_gc,
                  second_x, second_y, third_x, third_y);
-  o_invalidate_rect(w_current, 
-		    min(second_x, third_x) - size/2,
-		    min(second_y, third_y) - size/2,
-		    max(second_x, third_x) + size/2,
-		    max(second_y, third_y) + size/2);
 
   if (toplevel->net_style == THICK) {
     gdk_gc_set_line_attributes(w_current->xor_gc, 0,
diff --git a/gschem/src/o_path.c b/gschem/src/o_path.c
index f1421e7..13176b0 100644
--- a/gschem/src/o_path.c
+++ b/gschem/src/o_path.c
@@ -138,21 +138,6 @@ static void path_to_points (GSCHEM_TOPLEVEL *w_current, PATH *path,
 }
 
 
-static void find_points_bounds (GdkPoint *points, int num_points,
-                                int *min_x, int *min_y, int *max_x, int *max_y)
-{
-  int i;
-  int found_bound = FALSE;
-
-  for (i = 0; i < num_points; i++) {
-    *min_x = (found_bound) ? min (*min_x, points[i].x) : points[i].x;
-    *min_y = (found_bound) ? min (*min_y, points[i].y) : points[i].y;
-    *max_x = (found_bound) ? max (*max_x, points[i].x) : points[i].x;
-    *max_y = (found_bound) ? max (*max_y, points[i].y) : points[i].y;
-    found_bound = TRUE;
-  }
-}
-
 /*! \brief Draw a path with a solid line type.
  *  \par Function Description
  *  This function draws a path with a solid line type. The length and space
@@ -774,7 +759,6 @@ void o_path_rubberpath_xor(GSCHEM_TOPLEVEL *w_current)
   PATH *path;
   int num_points;
   GdkPoint *points;
-  int left = 0, top = 0, right = 0, bottom = 0;
 
   g_return_if_fail (w_current->which_object != NULL);
   g_return_if_fail (w_current->which_object->path != NULL);
@@ -803,9 +787,6 @@ void o_path_rubberpath_xor(GSCHEM_TOPLEVEL *w_current)
     gdk_draw_lines (w_current->drawable, w_current->xor_gc,
                     points, num_points);
 
-  find_points_bounds (points, num_points, &left, &top, &right, &bottom);
-  o_invalidate_rect (w_current, left, top, right, bottom);
-
   g_free (points);
 }
 
diff --git a/gschem/src/o_picture.c b/gschem/src/o_picture.c
index 3deb8ac..b3e02ca 100644
--- a/gschem/src/o_picture.c
+++ b/gschem/src/o_picture.c
@@ -292,8 +292,6 @@ void o_picture_rubberbox_xor(GSCHEM_TOPLEVEL *w_current)
 			     GDK_JOIN_MITER);
   gdk_draw_rectangle (w_current->drawable, w_current->xor_gc,
                       FALSE, left, top, width, height);
-  o_invalidate_rect(w_current, 
-		    left, top, left + width, top + height);
 }
 
 /*! \brief Draw a picture on the screen.
diff --git a/gschem/src/o_pin.c b/gschem/src/o_pin.c
index 9a08100..529072b 100644
--- a/gschem/src/o_pin.c
+++ b/gschem/src/o_pin.c
@@ -285,9 +285,6 @@ void o_pin_rubberpin_xor(GSCHEM_TOPLEVEL *w_current)
   gdk_gc_set_foreground(w_current->xor_gc, 
 			x_get_darkcolor(w_current->select_color));
   gdk_draw_line (w_current->drawable, w_current->xor_gc, x1, y1, x2, y2);
-  o_invalidate_rect(w_current, 
-		    min(x1, x2) - size/2, min(y1, y2) - size/2,
-		    max(x1, x2) + size/2, max(y1, y2) + size/2);
 
   if (toplevel->net_style == THICK ) {
     gdk_gc_set_line_attributes(w_current->xor_gc, 0,
diff --git a/gschem/src/o_select.c b/gschem/src/o_select.c
index a5a677f..35d3d1b 100644
--- a/gschem/src/o_select.c
+++ b/gschem/src/o_select.c
@@ -313,9 +313,6 @@ void o_select_box_rubberband_xor(GSCHEM_TOPLEVEL *w_current)
   gdk_draw_rectangle (w_current->drawable, w_current->xor_gc,
                       FALSE,
                       box_left, box_top, box_width, box_height);
-  o_invalidate_rect(w_current, 
-		    box_left, box_top,
-		    box_left + box_width, box_top  + box_height);
 }
 
 /*! \todo Finish function documentation!!!
diff --git a/gschem/src/x_basic.c b/gschem/src/x_basic.c
index 1ede713..90436ac 100644
--- a/gschem/src/x_basic.c
+++ b/gschem/src/x_basic.c
@@ -33,7 +33,8 @@
  *  \par Function Description
  *
  */
-void x_repaint_background(GSCHEM_TOPLEVEL *w_current)
+void x_repaint_background_region (GSCHEM_TOPLEVEL *w_current,
+                                  int x, int y, int width, int height)
 {
   TOPLEVEL *toplevel = w_current->toplevel;
 
@@ -41,12 +42,9 @@ void x_repaint_background(GSCHEM_TOPLEVEL *w_current)
                          x_get_color (toplevel->background_color));
 
   gdk_draw_rectangle (w_current->drawable,
-                      w_current->gc, TRUE, 0, 0,
-                      w_current->win_width,
-                      w_current->win_height);
-  o_invalidate_all (w_current);
+                      w_current->gc, TRUE, x, y, width, height);
 
-  x_grid_draw (w_current);
+  x_grid_draw_region (w_current, x, y, width, height);
 }
 
 /*! \todo Finish function documentation!!!
diff --git a/gschem/src/x_event.c b/gschem/src/x_event.c
index d3662fd..bd5927a 100644
--- a/gschem/src/x_event.c
+++ b/gschem/src/x_event.c
@@ -50,6 +50,9 @@ static int DOING_STROKE = FALSE;
 gint x_event_expose(GtkWidget *widget, GdkEventExpose *event,
                     GSCHEM_TOPLEVEL *w_current)
 {
+  GdkRectangle *rectangles;
+  int n_rectangles;
+
 #if DEBUG
   printf("EXPOSE\n");
 #endif
@@ -58,12 +61,9 @@ gint x_event_expose(GtkWidget *widget, GdkEventExpose *event,
   /* nasty global variable */
   global_window_current = w_current;
 
-  gdk_draw_pixmap(widget->window,
-                  widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
-                  w_current->drawable,
-                  event->area.x, event->area.y,
-                  event->area.x, event->area.y,
-                  event->area.width, event->area.height);
+  gdk_region_get_rectangles (event->region, &rectangles, &n_rectangles);
+  o_redraw_rects (w_current, rectangles, n_rectangles);
+  g_free (rectangles);
 
   /* raise the dialog boxes if this feature is enabled */
   if (w_current->raise_dialog_boxes) {
@@ -937,14 +937,8 @@ x_event_configure (GtkWidget         *widget,
     return FALSE;
   }
 
-  /* update the backingstore of toplevel */
-  if (w_current->drawable != NULL) {
-    gdk_pixmap_unref (w_current->drawable);
-  }
-  w_current->drawable = gdk_pixmap_new (widget->window,
-                                        new_win_width,
-                                        new_win_height,
-                                        -1);
+  w_current->drawable = w_current->window;
+
   /* update the GSCHEM_TOPLEVEL with new size of drawing area */
   w_current->win_width   = toplevel->width  = new_win_width;
   w_current->win_height  = toplevel->height = new_win_height;
@@ -1033,9 +1027,6 @@ void x_manual_resize(GSCHEM_TOPLEVEL *w_current)
      printf("w: %d h: %d\n", width, height); */
   printf("aw: %d ah: %d\n", w_current->win_width, w_current->win_height);
 #endif
-
-  /* I'm assuming that the backingstore pixmap is of the right
-   * size */
 }
 
 /*! \todo Finish function documentation!!!
diff --git a/gschem/src/x_grid.c b/gschem/src/x_grid.c
index 2fd441c..e5e9c2d 100644
--- a/gschem/src/x_grid.c
+++ b/gschem/src/x_grid.c
@@ -37,12 +37,13 @@ static GdkPoint points[5000];
  *  \par Function Description
  *
  */
-void x_grid_draw(GSCHEM_TOPLEVEL *w_current)
+void x_grid_draw_region (GSCHEM_TOPLEVEL *w_current,
+                         int x, int y, int width, int height)
 {
   TOPLEVEL *toplevel = w_current->toplevel;
   int i, j;
-  int x, y;
-  int x_start, y_start;
+  int dot_x, dot_y;
+  int x_start, y_start, x_end, y_end;
   int count = 0;
 
   int incr = 100;
@@ -95,17 +96,18 @@ void x_grid_draw(GSCHEM_TOPLEVEL *w_current)
   gdk_gc_set_foreground(w_current->gc,
                         x_get_color(w_current->grid_color));
 
+  SCREENtoWORLD (toplevel, x - 1, y + height + 1, &x_start, &y_start);
+  SCREENtoWORLD (toplevel, x + width + 1, y - 1, &x_end, &y_end);
+
   /* figure starting grid coordinates, work by taking the start
    * and end coordinates and rounding down to the nearest
    * increment */
-  x_start = (toplevel->page_current->left -
-             (toplevel->page_current->left % incr));
-  y_start = (toplevel->page_current->top -
-             (toplevel->page_current->top  % incr));
-
-  for (i = x_start; i < toplevel->page_current->right; i = i + incr) {
-    for(j = y_start; j < toplevel->page_current->bottom; j = j + incr) {
-      WORLDtoSCREEN(toplevel, i,j, &x, &y);
+  x_start -= (x_start % incr);
+  y_start -= (y_start % incr);
+
+  for (i = x_start; i <= x_end; i = i + incr) {
+    for(j = y_start; j <= y_end; j = j + incr) {
+      WORLDtoSCREEN(toplevel, i,j, &dot_x, &dot_y);
       if (inside_region(toplevel->page_current->left,
                         toplevel->page_current->top,
                         toplevel->page_current->right,
@@ -114,8 +116,8 @@ void x_grid_draw(GSCHEM_TOPLEVEL *w_current)
 
 	if (w_current->grid_dot_size == 1)
         {
-          points[count].x = x;
-          points[count].y = y;
+          points[count].x = dot_x;
+          points[count].y = dot_y;
           count++;
 
           /* get out of loop if more than 1000 points */
@@ -128,7 +130,7 @@ void x_grid_draw(GSCHEM_TOPLEVEL *w_current)
         else
         {
           gdk_draw_arc (w_current->drawable, w_current->gc,
-                        TRUE, x, y,
+                        TRUE, dot_x, dot_y,
                         w_current->grid_dot_size,
                         w_current->grid_dot_size, 0, FULL_CIRCLE);
         }
diff --git a/gschem/src/x_preview.c b/gschem/src/x_preview.c
index 2218293..92fb8e0 100644
--- a/gschem/src/x_preview.c
+++ b/gschem/src/x_preview.c
@@ -88,18 +88,13 @@ preview_callback_realize (GtkWidget *widget,
   preview_w_current->win_width  = preview_toplevel->width;
   preview_w_current->win_height = preview_toplevel->height;
 
-  preview_w_current->drawable = gdk_pixmap_new (
-    preview_w_current->window,
-    preview_w_current->drawing_area->allocation.width,
-    preview_w_current->drawing_area->allocation.height, -1);
+  preview_w_current->drawable = preview_w_current->window;
 
   x_window_setup_gc (preview_w_current);
 
   preview_page = s_page_new (preview_toplevel, "unknown");
   s_page_goto (preview_toplevel, preview_page);
 
-  x_repaint_background(preview_w_current);
-
   preview_toplevel->DONT_REDRAW = 0;
 
   a_zoom_extents(preview_w_current,
@@ -126,13 +121,12 @@ preview_callback_expose (GtkWidget *widget,
 {
   Preview *preview = PREVIEW (widget);
   GSCHEM_TOPLEVEL *preview_w_current = preview->preview_w_current;
+  GdkRectangle *rectangles;
+  int n_rectangles;
 
-  gdk_draw_pixmap (widget->window,
-                   widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
-                   preview_w_current->drawable,
-                   event->area.x, event->area.y,
-                   event->area.x, event->area.y,
-                   event->area.width, event->area.height);
+  gdk_region_get_rectangles (event->region, &rectangles, &n_rectangles);
+  o_redraw_rects (preview_w_current, rectangles, n_rectangles);
+  g_free (rectangles);
 
   return FALSE;
 }
@@ -330,12 +324,7 @@ preview_event_configure (GtkWidget         *widget,
   retval = x_event_configure (widget, event, preview_w_current);
   preview_w_current->toplevel->DONT_REDRAW = save_redraw;
   if (preview_page != NULL) {
-    /* If we have an empty page without object, just redraw the background */
-    if (preview_page->object_list == NULL) {
-      x_repaint_background(preview_w_current);
-    } else {
-      a_zoom_extents (preview_w_current, preview_page->object_list, 0);
-    }
+    a_zoom_extents (preview_w_current, preview_page->object_list, 0);
   }
   return retval;
 }
@@ -482,10 +471,6 @@ preview_dispose (GObject *self)
   if (preview_w_current != NULL) {
     preview_w_current->drawing_area = NULL;
 
-    if (preview_w_current->drawable) {
-      gdk_pixmap_unref (preview_w_current->drawable);
-    }
-
     x_window_free_gc (preview_w_current);
     
     s_toplevel_delete (preview_w_current->toplevel);
diff --git a/gschem/src/x_window.c b/gschem/src/x_window.c
index 47e2e81..5d198b4 100644
--- a/gschem/src/x_window.c
+++ b/gschem/src/x_window.c
@@ -579,10 +579,8 @@ void x_window_create_main(GSCHEM_TOPLEVEL *w_current)
 
   w_current->window = w_current->drawing_area->window;
 
-  w_current->drawable = gdk_pixmap_new (w_current->window,
-                                        w_current->drawing_area->allocation.width,
-                                        w_current->drawing_area->allocation.height,
-                                        -1);
+  w_current->drawable = w_current->window;
+
   x_window_setup_gc(w_current);
 }
 
@@ -687,10 +685,6 @@ void x_window_close(GSCHEM_TOPLEVEL *w_current)
     o_buffer_free (w_current);
   }
 
-  if (w_current->drawable) {
-    gdk_pixmap_unref (w_current->drawable);
-  }
-
   x_window_free_gc(w_current);
 
   /* finally close the main window */
@@ -866,7 +860,6 @@ x_window_set_current_page (GSCHEM_TOPLEVEL *w_current, PAGE *page)
   x_multiattrib_update (w_current);
 
   toplevel->DONT_REDRAW = 1;
-  x_repaint_background (w_current);
   x_manual_resize (w_current);
   x_hscrollbar_update (w_current);
   x_vscrollbar_update (w_current);
diff --git a/libgeda/include/prototype.h b/libgeda/include/prototype.h
index f6d4249..76ed88b 100644
--- a/libgeda/include/prototype.h
+++ b/libgeda/include/prototype.h
@@ -413,6 +413,7 @@ void s_page_append (PAGE *page, OBJECT *object);
 void s_page_remove (PAGE *page, OBJECT *object);
 void s_page_delete_objects (TOPLEVEL *toplevel, PAGE *page);
 GList *s_page_objects_in_region (PAGE *page, int min_x, int min_y, int max_x, int max_y);
+GList *s_page_objects_in_regions (PAGE *page, BOX *rects, int n_rects);
 
 /* s_papersizes.c */
 int s_papersizes_add_entry(char *new_papersize, int width, int height);
diff --git a/libgeda/src/s_page.c b/libgeda/src/s_page.c
index 98cedf1..70305e3 100644
--- a/libgeda/src/s_page.c
+++ b/libgeda/src/s_page.c
@@ -567,15 +567,44 @@ void s_page_delete_objects (TOPLEVEL *toplevel, PAGE *page)
 GList *s_page_objects_in_region (PAGE *page, int min_x, int min_y,
                                              int max_x, int max_y)
 {
+  BOX rect;
+
+  rect.lower_x = min_x;
+  rect.lower_y = min_y;
+  rect.upper_x = max_x;
+  rect.upper_y = max_y;
+
+  return s_page_objects_in_regions (page, &rect, 1);
+}
+
+/*! \brief Find the objects in a given region
+ *
+ *  \par Function Description
+ *  Finds the objects which are inside, or intersect
+ *  the passed box shaped region.
+ *
+ *  \param [in] page     The PAGE the object is on.
+ *  \param [in] rects    The BOX regions to check.
+ *  \param [in] n_rects  The number of regions.
+ *  \return The GList of OBJECTs in the region.
+ */
+GList *s_page_objects_in_regions (PAGE *page, BOX *rects, int n_rects)
+{
   GList *iter;
   GList *list = NULL;
+  int i;
 
   for (iter = page->object_list; iter != NULL; iter = g_list_next (iter)) {
     OBJECT *object = iter->data;
 
-    if (object->w_right >= min_x && object->w_left   <= max_x &&
-        object->w_top   <= max_y && object->w_bottom >= min_y) {
-      list = g_list_prepend (list, object);
+    for (i = 0; i < n_rects; i++) {
+      if (object->w_right  >= rects[i].lower_x &&
+          object->w_left   <= rects[i].upper_x &&
+          object->w_top    <= rects[i].upper_y &&
+          object->w_bottom >= rects[i].lower_y) {
+        list = g_list_prepend (list, object);
+        break;
+      }
     }
   }
 




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