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

gEDA-cvs: branch: master updated (1.4.0-20080127-62-g4cace92)



The branch, master has been updated
       via  4cace928604a9b799e761a80d7b0424d45d554ce (commit)
       via  c4abffeb78305f3c7ede736b027def82c3171181 (commit)
       via  6cfafdaf3c09dde2aedfa7fc3f57662dd0b25ba9 (commit)
       via  ef2871ee0ee34af000205cdfe889fb2bad3a74bb (commit)
       via  60b734ed80d7ccefba7a78a878714261a9637a67 (commit)
       via  f003de85165f11280f909acd6b785ebf38bacf39 (commit)
       via  6efa4f6c16894852b409f130d50acef88d78aa22 (commit)
       via  bdcb6e63c3ed1b19f0d1d854536b0e51aad85429 (commit)
       via  87aeb1ee33995af7645aa4d72265254d217f62ef (commit)
       via  0720815ae4594ae3a73ca96d6392ae35c2172e4a (commit)
       via  4f5cf44b196790dbf5cf318977463b487a17ec89 (commit)
       via  693d7fbb8630bcb846ee72bb594a6c8612ec2f17 (commit)
      from  1b05cbfcbb07970159c58b2b18d583516e257a45 (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 |    3 +-
 gschem/include/prototype.h     |    7 +-
 gschem/src/a_pan.c             |    9 +-
 gschem/src/gschem_toplevel.c   |    6 +-
 gschem/src/i_callbacks.c       |   12 +-
 gschem/src/o_arc.c             |  305 +++------------
 gschem/src/o_basic.c           |    4 +-
 gschem/src/o_box.c             |  159 ++++----
 gschem/src/o_bus.c             |  262 +++++--------
 gschem/src/o_circle.c          |  149 +++-----
 gschem/src/o_grips.c           |  845 +++++++++++++++++-----------------------
 gschem/src/o_line.c            |  176 +++------
 gschem/src/o_net.c             |    8 +-
 gschem/src/o_picture.c         |  159 +++-----
 gschem/src/o_pin.c             |  154 +++-----
 gschem/src/x_event.c           |   88 +----
 16 files changed, 876 insertions(+), 1470 deletions(-)


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

commit 4cace928604a9b799e761a80d7b0424d45d554ce
Author: Werner Hoch <werner.ho@xxxxxx>
Date:   Mon Apr 14 20:52:15 2008 +0200

    fixed rubber color for pin and bus, fixed line erase
    
    The color of the rubber wasn't correct for pins and buses.
    The o_line_eraserubber function still used start_x.

:100644 100644 af55530... 0b5fe21... M	gschem/src/o_box.c
:100644 100644 b014bfe... c709207... M	gschem/src/o_bus.c
:100644 100644 1f4b38c... 5f319dd... M	gschem/src/o_line.c
:100644 100644 b46931b... 6dd89d7... M	gschem/src/o_picture.c
:100644 100644 5725118... 6427232... M	gschem/src/o_pin.c

commit c4abffeb78305f3c7ede736b027def82c3171181
Author: Werner Hoch <werner.ho@xxxxxx>
Date:   Sun Apr 13 12:00:24 2008 +0200

    switched picture rubber and manipulation to world coords
    
    Call all picture functions with world coords.

:100644 100644 be836bb... 9a723d3... M	gschem/src/o_grips.c
:100644 100644 c5a379c... b46931b... M	gschem/src/o_picture.c
:100644 100644 2047eb2... f71c60a... M	gschem/src/x_event.c

commit 6cfafdaf3c09dde2aedfa7fc3f57662dd0b25ba9
Author: Werner Hoch <werner.ho@xxxxxx>
Date:   Tue Apr 8 21:15:36 2008 +0200

    switched pin rubber drawing to world coordinates
    
    Call all pin functions with world coordinates. Replaced some of the
    gdk drawing functions with object drawing functions.

:100644 100644 61f8e53... 2f3a9f0... M	gschem/include/prototype.h
:100644 100644 26dba7e... 7eaecc8... M	gschem/src/i_callbacks.c
:100644 100644 f76cefa... 5725118... M	gschem/src/o_pin.c
:100644 100644 c6cc131... 2047eb2... M	gschem/src/x_event.c

commit ef2871ee0ee34af000205cdfe889fb2bad3a74bb
Author: Werner Hoch <werner.ho@xxxxxx>
Date:   Mon Apr 7 20:47:44 2008 +0200

    removed redundant x event state code from o_grips.c
    
    The removed code for updating the state and the toolbar is already
    present in the state code in x_event.c after the o_grips_end()
    call. Reseting the state variables first_wx, second_wx, ... is not
    required at all.

:100644 100644 d8946a6... be836bb... M	gschem/src/o_grips.c

commit 60b734ed80d7ccefba7a78a878714261a9637a67
Author: Werner Hoch <werner.ho@xxxxxx>
Date:   Mon Apr 7 20:32:01 2008 +0200

    fixed o_grips_end manipulation for net/line and pin
    
    Fixed the code for the end of the net line and pin manipulations.
    Extracted the functionality to three new functions and switched them
    to world coordinates. Removed some gdk drawing code and replaced it
    with object drawing functions.

:100644 100644 0b801b6... 61f8e53... M	gschem/include/prototype.h
:100644 100644 e705b2f... d8946a6... M	gschem/src/o_grips.c

commit f003de85165f11280f909acd6b785ebf38bacf39
Author: Werner Hoch <werner.ho@xxxxxx>
Date:   Sun Apr 6 21:41:19 2008 +0200

    switched grips for line manipulation to world coords
    
    This also affects the line/bus and pin manipulation.
    While start and motion is identical, the end point of the
    manipulation has to be fixed separatly.

:100644 100644 aaad72c... e705b2f... M	gschem/src/o_grips.c

commit 6efa4f6c16894852b409f130d50acef88d78aa22
Author: Werner Hoch <werner.ho@xxxxxx>
Date:   Sun Apr 6 20:05:25 2008 +0200

    switched line rubber drawing to world coords
    
    Call all line functions with world coordinates. Removed
    some unused code.

:100644 100644 385face... 26dba7e... M	gschem/src/i_callbacks.c
:100644 100644 3edbcc0... 83b62af... M	gschem/src/o_arc.c
:100644 100644 69f640a... b014bfe... M	gschem/src/o_bus.c
:100644 100644 82c5f75... 1f4b38c... M	gschem/src/o_line.c
:100644 100644 236d460... c6cc131... M	gschem/src/x_event.c

commit bdcb6e63c3ed1b19f0d1d854536b0e51aad85429
Author: Werner Hoch <werner.ho@xxxxxx>
Date:   Sun Apr 6 19:10:31 2008 +0200

    switched bus rubber drawing to world coords
    
    Call all bus function with world coordinates. Added rubberbus_xor
    function to simplify code. Added some function documentations.

:100644 100644 0a2ec1c... 0b801b6... M	gschem/include/prototype.h
:100644 100644 17c6667... 385face... M	gschem/src/i_callbacks.c
:100644 100644 0fb48a3... 69f640a... M	gschem/src/o_bus.c
:100644 100644 4815430... 236d460... M	gschem/src/x_event.c

commit 87aeb1ee33995af7645aa4d72265254d217f62ef
Author: Werner Hoch <werner.ho@xxxxxx>
Date:   Sun Apr 6 17:29:40 2008 +0200

    switched arc rubber drawing and manipulation to world coords
    
    Call all arc function with world coords. Removed obsolete loc_x/y
    variables. Removed unused functions o_arc_end2 and o_arc_end3.

:100644 100644 408bf77... 74676a2... M	gschem/include/gschem_struct.h
:100644 100644 b320e11... 0a2ec1c... M	gschem/include/prototype.h
:100644 100644 c32c794... c076479... M	gschem/src/a_pan.c
:100644 100644 a5c4c52... 2e954ba... M	gschem/src/gschem_toplevel.c
:100644 100644 5caec36... 17c6667... M	gschem/src/i_callbacks.c
:100644 100644 8bbc682... 3edbcc0... M	gschem/src/o_arc.c
:100644 100644 0745702... 4fef35b... M	gschem/src/o_basic.c
:100644 100644 204ecec... aaad72c... M	gschem/src/o_grips.c
:100644 100644 142e0f3... 4815430... M	gschem/src/x_event.c

commit 0720815ae4594ae3a73ca96d6392ae35c2172e4a
Author: Werner Hoch <werner.ho@xxxxxx>
Date:   Sun Apr 6 15:03:22 2008 +0200

    switched circle rubber drawing and manipulation to world coords
    
    Call all cirle functions in world coords. Use rubber_visible variable
    to protect the drawing code from erasing errors.

:100644 100644 c684bb9... c32c794... M	gschem/src/a_pan.c
:100644 100644 82f0347... a5c4c52... M	gschem/src/gschem_toplevel.c
:100644 100644 3f196e8... 5caec36... M	gschem/src/i_callbacks.c
:100644 100644 996af59... dc020a8... M	gschem/src/o_circle.c
:100644 100644 9a4eeb4... 204ecec... M	gschem/src/o_grips.c
:100644 100644 748871d... 142e0f3... M	gschem/src/x_event.c

commit 4f5cf44b196790dbf5cf318977463b487a17ec89
Author: Werner Hoch <werner.ho@xxxxxx>
Date:   Sun Apr 6 13:09:35 2008 +0200

    switched box grips to world coordinates
    
    This fixes the manipulation of a box, that broke in the previous
    commit.

:100644 100644 77ab2cb... af55530... M	gschem/src/o_box.c
:100644 100644 0482e0c... 9a4eeb4... M	gschem/src/o_grips.c

commit 693d7fbb8630bcb846ee72bb594a6c8612ec2f17
Author: Werner Hoch <werner.ho@xxxxxx>
Date:   Sun Apr 6 12:15:21 2008 +0200

    switched box rubber drawing to world coordinates
    
    Call all box functions with world coordinates. Protect the rubber box
    from erasing if the rubber box has been erased by the redraw_all
    function. This happend if the user zoomed while drawing the box.
    The variable w_current->rubber_visible is used for this purpose.

:100644 100644 d8d139c... 408bf77... M	gschem/include/gschem_struct.h
:100644 100644 2726f7c... 82f0347... M	gschem/src/gschem_toplevel.c
:100644 100644 782b8a9... 3f196e8... M	gschem/src/i_callbacks.c
:100644 100644 8122e24... 0745702... M	gschem/src/o_basic.c
:100644 100644 712c37d... 77ab2cb... M	gschem/src/o_box.c
:100644 100644 29bedc7... d366f52... M	gschem/src/o_net.c
:100644 100644 ca4c2c4... 748871d... M	gschem/src/x_event.c

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

commit 4cace928604a9b799e761a80d7b0424d45d554ce
Author: Werner Hoch <werner.ho@xxxxxx>
Date:   Mon Apr 14 20:52:15 2008 +0200

    fixed rubber color for pin and bus, fixed line erase
    
    The color of the rubber wasn't correct for pins and buses.
    The o_line_eraserubber function still used start_x.

diff --git a/gschem/src/o_box.c b/gschem/src/o_box.c
index af55530..0b5fe21 100644
--- a/gschem/src/o_box.c
+++ b/gschem/src/o_box.c
@@ -1028,7 +1028,7 @@ void o_box_rubberbox_xor(GSCHEM_TOPLEVEL *w_current)
   box_left   = min(x1, x2);
   box_top    = min(y1, y2);
   
-	/* draw the box from the previous variables */
+  /* draw the box from the previous variables */
   gdk_gc_set_foreground(w_current->xor_gc, 
 			x_get_darkcolor(w_current->select_color));
   gdk_gc_set_line_attributes(w_current->xor_gc, 0, 
diff --git a/gschem/src/o_bus.c b/gschem/src/o_bus.c
index b014bfe..c709207 100644
--- a/gschem/src/o_bus.c
+++ b/gschem/src/o_bus.c
@@ -372,6 +372,8 @@ void o_bus_rubberbus_xor(GSCHEM_TOPLEVEL *w_current)
                                GDK_JOIN_MITER);
   }
 
+  gdk_gc_set_foreground(w_current->xor_gc, 
+			x_get_darkcolor(w_current->select_color));
   gdk_draw_line(w_current->backingstore, w_current->xor_gc, 
 		x1, y1, x2, y2);
   o_invalidate_rect(w_current, 
diff --git a/gschem/src/o_line.c b/gschem/src/o_line.c
index 1f4b38c..5f319dd 100644
--- a/gschem/src/o_line.c
+++ b/gschem/src/o_line.c
@@ -700,11 +700,7 @@ void o_line_draw_phantom(GdkWindow *w, GdkGC *gc, GdkColor *color,
  */
 void o_line_eraserubber(GSCHEM_TOPLEVEL *w_current)
 {
-  TOPLEVEL *toplevel = w_current->toplevel;
-  gdk_gc_set_foreground(w_current->gc,
-			x_get_color(toplevel->background_color) );
-  gdk_draw_line(w_current->backingstore, w_current->gc, w_current->start_x,
-                w_current->start_y, w_current->last_x, w_current->last_y);
+  o_line_rubberline_xor(w_current);
 }
 
 /*! \brief Draw a line object after applying translation.
@@ -847,8 +843,8 @@ void o_line_rubberline(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
 
   /*
    * The current temporary line is described by the two points
-   * (<B>w_current->start_x</B>,<B>w_current->start_y</B>) and
-   * (<B>w_current->last_x</B>,<B>w_current->last_y</B>) as end of the line.
+   * (<B>w_current->first_wx</B>,<B>w_current->first_wy</B>) and
+   * (<B>w_current->second_wx</B>,<B>w_current->second_wy</B>) as end of the line.
    *
    * This line is xor-drawn : if the line was already displayed, it is
    * erased. If the line was not already displayed it is drawn.
diff --git a/gschem/src/o_picture.c b/gschem/src/o_picture.c
index b46931b..6dd89d7 100644
--- a/gschem/src/o_picture.c
+++ b/gschem/src/o_picture.c
@@ -286,8 +286,8 @@ void o_picture_rubberbox_xor(GSCHEM_TOPLEVEL *w_current)
 #if DEBUG
   printf("o_picture_rubberbox_xor called:\n");
   printf("pixbuf wh ratio: %i\n", w_current->pixbuf_wh_ratio);
-  printf("start: %i, %i\n", w_current->start_x, w_current->start_y);
-  printf("last: %i, %i\n", w_current->last_x, w_current->last_y);
+  printf("first: %i, %i\n", w_current->first_wx, w_current->first_wy);
+  printf("second: %i, %i\n", w_current->second_wx, w_current->second_wy);
   printf("Left: %i\nTop: %i\nWidth: %i\nHeight: %i\n",
 	 picture_left, picture_top, picture_width, picture_height);
 #endif
diff --git a/gschem/src/o_pin.c b/gschem/src/o_pin.c
index 5725118..6427232 100644
--- a/gschem/src/o_pin.c
+++ b/gschem/src/o_pin.c
@@ -292,6 +292,8 @@ void o_pin_rubberpin_xor(GSCHEM_TOPLEVEL *w_current)
                                GDK_JOIN_MITER);
   }
 
+  gdk_gc_set_foreground(w_current->xor_gc, 
+			x_get_darkcolor(w_current->select_color));
   gdk_draw_line(w_current->backingstore, w_current->xor_gc, x1, y1, x2, y2);
   o_invalidate_rect(w_current, 
 		    min(x1, x2) - size/2, min(y1, y2) - size/2,

commit c4abffeb78305f3c7ede736b027def82c3171181
Author: Werner Hoch <werner.ho@xxxxxx>
Date:   Sun Apr 13 12:00:24 2008 +0200

    switched picture rubber and manipulation to world coords
    
    Call all picture functions with world coords.

diff --git a/gschem/src/o_grips.c b/gschem/src/o_grips.c
index be836bb..9a723d3 100644
--- a/gschem/src/o_grips.c
+++ b/gschem/src/o_grips.c
@@ -35,12 +35,15 @@
 #define GET_BOX_WIDTH(w)  abs((w)->second_wx - (w)->first_wx)
 #define GET_BOX_HEIGHT(w) abs((w)->second_wy - (w)->second_wy)
 
-#define GET_PICTURE_WIDTH(w) abs((w)->last_x - (w)->start_x)
-#define GET_PICTURE_HEIGHT(w) (w)->pixbuf_wh_ratio == 0 ? 0 : \
-          abs((w)->last_x - (w)->start_x)/(w)->pixbuf_wh_ratio
-#define GET_PICTURE_LEFT(w) min((w)->start_x, (w)->last_x);
-#define GET_PICTURE_TOP(w)  (w)->start_y < (w)->last_y ? (w)->start_y : \
-          (w)->start_y-abs((w)->last_x - (w)->start_x)/(w)->pixbuf_wh_ratio;
+#define GET_PICTURE_WIDTH(w)			\
+  abs((w)->second_wx - (w)->first_wx) 
+#define GET_PICTURE_HEIGHT(w)						\
+  (w)->pixbuf_wh_ratio == 0 ? 0 : abs((w)->second_wx - (w)->first_wx)/(w)->pixbuf_wh_ratio
+#define GET_PICTURE_LEFT(w)			\
+  min((w)->first_wx, (w)->second_wx)
+#define GET_PICTURE_TOP(w)						\
+  (w)->first_wy > (w)->second_wy ? (w)->first_wy  :			\
+  (w)->first_wy+abs((w)->second_wx - (w)->first_wx)/(w)->pixbuf_wh_ratio
 
 /*! \brief
  *  This variable holds the identifier of the grip currently under
@@ -660,10 +663,10 @@ void o_grips_start_box(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current,
  *  The function first erases the grips.
  *
  *  The coordinates of the selected corner are put in
- *  (<B>w_current->last_x</B>,<B>w_current->last_y</B>).
+ *  (<B>w_current->second_wx</B>,<B>w_current->second_wy</B>).
  *
  *  The coordinates of the opposite corner go in
- *  (<B>w_current->start_x</B>,<B>w_current->start_y</B>). They are not
+ *  (<B>w_current->first_wx</B>,<B>w_current->first_wy</B>). They are not
  *  suppose to change during the action.
  *
  *  \param [in]  w_current  The GSCHEM_TOPLEVEL object.
@@ -675,7 +678,6 @@ void o_grips_start_box(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current,
 void o_grips_start_picture(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current,
                            int x, int y, int whichone)
 {
-  TOPLEVEL *toplevel = w_current->toplevel;
   w_current->last_drawb_mode = -1;
 
   /* erase the picture before */
@@ -684,32 +686,32 @@ void o_grips_start_picture(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current,
   w_current->pixbuf_filename = o_current->picture->filename;
   w_current->pixbuf_wh_ratio = o_current->picture->ratio;
 
-  /* (last_x,last_y)    is the selected corner */
-  /* (start_x, start_y) is the opposite corner */
+  /* (second_wx,second_wy) is the selected corner */
+  /* (first_wx, first_wy) is the opposite corner */
   switch(whichone) {
     case PICTURE_UPPER_LEFT:
-      WORLDtoSCREEN( toplevel, o_current->picture->upper_x, o_current->picture->upper_y,
-                     &w_current->last_x, &w_current->last_y );
-      WORLDtoSCREEN( toplevel, o_current->picture->lower_x, o_current->picture->lower_y,
-                     &w_current->start_x, &w_current->start_y );
+      w_current->second_wx = o_current->picture->upper_x;
+      w_current->second_wy = o_current->picture->upper_y;
+      w_current->first_wx = o_current->picture->lower_x; 
+      w_current->first_wy = o_current->picture->lower_y;
       break;
     case PICTURE_LOWER_RIGHT:
-      WORLDtoSCREEN( toplevel, o_current->picture->lower_x, o_current->picture->lower_y,
-                     &w_current->last_x, &w_current->last_y );
-      WORLDtoSCREEN( toplevel, o_current->picture->upper_x, o_current->picture->upper_y,
-                     &w_current->start_x, &w_current->start_y );
+      w_current->second_wx = o_current->picture->lower_x;
+      w_current->second_wy = o_current->picture->lower_y;
+      w_current->first_wx = o_current->picture->upper_x; 
+      w_current->first_wy = o_current->picture->upper_y;
       break;
     case PICTURE_UPPER_RIGHT:
-      WORLDtoSCREEN( toplevel, o_current->picture->lower_x, o_current->picture->upper_y,
-                     &w_current->last_x, &w_current->last_y );
-      WORLDtoSCREEN( toplevel, o_current->picture->upper_x, o_current->picture->lower_y,
-                     &w_current->start_x, &w_current->start_y );
+      w_current->second_wx = o_current->picture->lower_x;
+      w_current->second_wy = o_current->picture->upper_y;
+      w_current->first_wx = o_current->picture->upper_x; 
+      w_current->first_wy = o_current->picture->lower_y;
       break;
     case PICTURE_LOWER_LEFT:
-      WORLDtoSCREEN( toplevel, o_current->picture->upper_x, o_current->picture->lower_y,
-                     &w_current->last_x, &w_current->last_y );
-      WORLDtoSCREEN( toplevel, o_current->picture->lower_x, o_current->picture->upper_y,
-                     &w_current->start_x, &w_current->start_y );
+      w_current->second_wx = o_current->picture->upper_x;
+      w_current->second_wy = o_current->picture->lower_y;
+      w_current->first_wx = o_current->picture->lower_x; 
+      w_current->first_wy = o_current->picture->upper_y;
       break;
     default:
       return; /* error */
@@ -717,7 +719,7 @@ void o_grips_start_picture(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current,
 
   /* draw the first temporary picture */
   o_picture_rubberbox_xor(w_current);
-
+  w_current->rubber_visible = 1;
 }
 
 /*! \brief Initialize grip motion process for a circle.
@@ -841,7 +843,7 @@ void o_grips_motion(GSCHEM_TOPLEVEL *w_current, int x, int y)
 
     case(OBJ_PICTURE):
     /* erase, update and draw a box */
-    o_grips_motion_picture(w_current, x, y, whichone_changing);
+    o_grips_motion_picture(w_current, w_x, w_y, whichone_changing);
     break;
 
     case(OBJ_CIRCLE):
@@ -931,14 +933,14 @@ void o_grips_motion_box(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y, int whicho
  *   picture and draw the new temporary picture.
  *
  *  \param [in] w_current  The GSCHEM_TOPLEVEL object.
- *  \param [in] x          Current x coordinate of pointer in screen units.
- *  \param [in] y          Current y coordinate of pointer in screen units.
+ *  \param [in] w_x        Current x coordinate of pointer in world units.
+ *  \param [in] w_y        Current y coordinate of pointer in world units.
  *  \param [in] whichone   Which grip to start motion with.
  */
-void o_grips_motion_picture(GSCHEM_TOPLEVEL *w_current, int x, int y, int whichone)
+void o_grips_motion_picture(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y, int whichone)
 {
   /* erase, update and draw the temporary picture */
-  o_picture_rubberbox(w_current, x, y);
+  o_picture_rubberbox(w_current, w_x, w_y);
 }
 
 /*! \brief Modify previously selected circle according to mouse position.
@@ -1174,30 +1176,20 @@ void o_grips_end_box(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int whichone
 void o_grips_end_picture(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int whichone)
 {
   TOPLEVEL *toplevel = w_current->toplevel;
-  int picture_width, picture_height;
-  int x, y;
 
-  picture_width  = GET_PICTURE_WIDTH (w_current);
-  picture_height = GET_PICTURE_HEIGHT(w_current);
+  /* erase the temporary picture */
+  o_picture_rubberbox_xor(w_current);
 
   /* don't allow zero width/height picturees
    * this ends the picture drawing behavior
    * we want this? hack */
-  if ((picture_width == 0) && (picture_height == 0)) {
+  if ((GET_PICTURE_WIDTH(w_current) == 0) || (GET_PICTURE_HEIGHT(w_current) == 0)) {
     o_redraw_single(w_current, o_current);
     return;
   }
 
-  SCREENtoWORLD(toplevel,
-                w_current->last_x, w_current->last_y,
-                &x, &y);
-  x = snap_grid(toplevel, x);
-  y = snap_grid(toplevel, y);
-
-  o_picture_modify(toplevel, o_current, x, y, whichone);
-
-  /* erase the temporary picture */
-  o_picture_rubberbox_xor(w_current);
+  o_picture_modify(toplevel, o_current, 
+		   w_current->second_wx, w_current->second_wy, whichone);
 
   /* draw the modified picture */
   o_redraw_single(w_current, o_current);
diff --git a/gschem/src/o_picture.c b/gschem/src/o_picture.c
index c5a379c..b46931b 100644
--- a/gschem/src/o_picture.c
+++ b/gschem/src/o_picture.c
@@ -29,80 +29,67 @@
 
 /* This works, but using one macro inside of other doesn't */
 #define GET_PICTURE_WIDTH(w)			\
-	abs((w)->last_x - (w)->start_x) 
-#define GET_PICTURE_HEIGHT(w)			\
-	(w)->pixbuf_wh_ratio == 0 ? 0 : abs((w)->last_x - (w)->start_x)/(w)->pixbuf_wh_ratio
-#define GET_PICTURE_LEFT(w)				\
-	min((w)->start_x, (w)->last_x);
-#define GET_PICTURE_TOP(w)				\
-	(w)->start_y < (w)->last_y ? (w)->start_y  : \
-                                     (w)->start_y-abs((w)->last_x - (w)->start_x)/(w)->pixbuf_wh_ratio;
+  abs((w)->second_wx - (w)->first_wx) 
+#define GET_PICTURE_HEIGHT(w)						\
+  (w)->pixbuf_wh_ratio == 0 ? 0 : abs((w)->second_wx - (w)->first_wx)/(w)->pixbuf_wh_ratio
+#define GET_PICTURE_LEFT(w)			\
+  min((w)->first_wx, (w)->second_wx)
+#define GET_PICTURE_TOP(w)						\
+  (w)->first_wy > (w)->second_wy ? (w)->first_wy  :			\
+  (w)->first_wy+abs((w)->second_wx - (w)->first_wx)/(w)->pixbuf_wh_ratio
 
 /*! \brief Start process to input a new picture.
  *  \par Function Description
  *  This function starts the process to input a new picture. Parameters
  *  for this picture are put into/extracted from the <B>w_current</B> toplevel
  *  structure.
- *  <B>x</B> and <B>y</B> are current coordinates of the pointer in screen
+ *  <B>w_x</B> and <B>w_y</B> are current coordinates of the pointer in world
  *  coordinates.
  *
  *  The first step is to input one corner of the picture. This corner is
- *  (<B>x</B>,<B>y</B>) snapped to the grid and saved in
- *  <B>w_current->start_x</B> and <B>w_current->start_y</B>.
+ *  (<B>w_x</B>,<B>w_y</B>) snapped to the grid and saved in
+ *  <B>w_current->first_wx</B> and <B>w_current->first_wy</B>.
  *
- *  The other corner will be saved in (<B>w_current->last_x</B>,
- *  <B>w_current->last_y</B>).
+ *  The other corner will be saved in (<B>w_current->second_wx</B>,
+ *  <B>w_current->second_wy</B>).
  *
  *  \param [in] w_current  The GSCHEM_TOPLEVEL object.
- *  \param [in] x          Current x coordinate of pointer in screen units.    
- *  \param [in] y          Current y coordinate of pointer in screen units.
+ *  \param [in] w_x        Current x coordinate of pointer in world units.    
+ *  \param [in] w_y        Current y coordinate of pointer in world units.
  */
-void o_picture_start(GSCHEM_TOPLEVEL *w_current, int x, int y)
+void o_picture_start(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
 {
-  TOPLEVEL *toplevel = w_current->toplevel;
-#if DEBUG
-  printf("o_picture_start called\n");
-#endif
-  /* init start_[x|y], last_[x|y] to describe box */
-  w_current->last_x = w_current->start_x = fix_x(toplevel, x);
-  w_current->last_y = w_current->start_y = fix_y(toplevel, y);
+  /* init first_w[x|y], second_w[x|y] to describe box */
+  w_current->first_wx = w_current->second_wx = w_x;
+  w_current->first_wy = w_current->second_wy = w_y;
 
   /* start to draw the box */
   o_picture_rubberbox_xor(w_current);
-
+  w_current->rubber_visible = 1;
 }
 
 /*! \brief End the input of a circle.
  *  \par Function Description
  *  This function ends the input of the second corner of a picture.
- *  The (<B>x</B>,<B>y</B>) point is set to be this second corner. The picture
- *  is then defined by (<B>w_current->start_x</B>,<B>w_current->start_y</B>
- *  and (<B>w_current->last_x</B>,<B>w_current->last_y</B> that is a snapped
- *  version of (<B>x</B>,<B>y</B>).
- *  <B>x</B> and <B>y</B> are in screen unit.
+ *  The picture is defined by (<B>w_current->first_wx</B>,<B>w_current->first_wy</B>
+ *  and (<B>w_current->second_wx</B>,<B>w_current->second_wy</B>.
  *
- *  The temporary picture is erased ; a new picture object is allocated,
+ *  The temporary picture frame is erased ; a new picture object is allocated,
  *  initialized and linked to the object list ; The object is finally
  *  drawn on the current sheet.
  *
  *  \param [in] w_current  The GSCHEM_TOPLEVEL object.
- *  \param [in] x          Current x coordinate of pointer in screen units.
- *  \param [in] y          Current y coordinate of pointer in screen units.
+ *  \param [in] w_x        (unused)
+ *  \param [in] w_y        (unused)
  */
-void o_picture_end(GSCHEM_TOPLEVEL *w_current, int x, int y)
+void o_picture_end(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
 {
   TOPLEVEL *toplevel = w_current->toplevel;
-  int x1, y1;
-  int x2, y2;
   int picture_width, picture_height;
   int picture_left, picture_top;
 
   g_assert( w_current->inside_action != 0 );
 
-  /* get the last coords of the pointer */
-  w_current->last_x = fix_x(toplevel, x);
-  w_current->last_y = fix_y(toplevel, y);
-
   /* erase the temporary picture */
   o_picture_rubberbox_xor(w_current);
   
@@ -114,49 +101,27 @@ void o_picture_end(GSCHEM_TOPLEVEL *w_current, int x, int y)
   /* pictures with null width and height are not allowed */
   if ((picture_width == 0) && (picture_height == 0)) {
     /* cancel the object creation */
-    w_current->start_x = (-1);
-    w_current->start_y = (-1);
-    w_current->last_x  = (-1);
-    w_current->last_y  = (-1);
     return;
   }
 
-  /* calculate the world coords of the upper left and lower right corners */
-  SCREENtoWORLD(toplevel, picture_left, picture_top, &x1, &y1);
-  SCREENtoWORLD(toplevel,
-                picture_left + picture_width,
-		picture_top + picture_height, &x2, &y2);
-  x1 = snap_grid(toplevel, x1);
-  y1 = snap_grid(toplevel, y1);
-  x2 = snap_grid(toplevel, x2);
-  y2 = snap_grid(toplevel, y2);
-
   /* create the object */
   toplevel->page_current->object_tail =
-  o_picture_add(toplevel,
-                toplevel->page_current->object_tail,
-		w_current->current_pixbuf,
-		NULL, 0,
-		w_current->pixbuf_filename,
-		w_current->pixbuf_wh_ratio,
-                OBJ_PICTURE, x1, y1, x2, y2, 0, FALSE, FALSE);
+    o_picture_add(toplevel,
+		  toplevel->page_current->object_tail,
+		  w_current->current_pixbuf,
+		  NULL, 0,
+		  w_current->pixbuf_filename,
+		  w_current->pixbuf_wh_ratio,
+		  OBJ_PICTURE, 
+		  picture_left, picture_top,
+		  picture_left + picture_width, picture_top - picture_height,
+		  0, FALSE, FALSE);
 
   /* draw it */
   o_redraw_single(w_current, toplevel->page_current->object_tail);
   
-#if DEBUG
-  printf("coords: %d %d %d %d\n", x1, y2, x2, y2);
-#endif
-	
-  w_current->start_x = (-1);
-  w_current->start_y = (-1);
-  w_current->last_x  = (-1);
-  w_current->last_y  = (-1);
-	
   toplevel->page_current->CHANGED = 1;
-
   o_undo_savestate(w_current, UNDO_ALL);
-
 }
 
 /*! \brief Creates the add image dialog
@@ -256,7 +221,7 @@ void o_picture_eraserubber(GSCHEM_TOPLEVEL *w_current)
  *  \par Function Description
  *  This function is used to draw the box while dragging one of its edge or
  *  angle. It erases the previous temporary box drawn before, and draws
- *  a new updated one. <B>x</B> and <B>y</B> are the new position of the mobile
+ *  a new updated one. <B>w_x</B> and <B>w_y</B> are the new position of the mobile
  *  point, ie the mouse.
  *
  *  The old values are inside the <B>w_current</B> pointed structure. Old
@@ -267,38 +232,39 @@ void o_picture_eraserubber(GSCHEM_TOPLEVEL *w_current)
  *  \param [in] x          Current x coordinate of pointer in screen units.
  *  \param [in] y          Current y coordinate of pointer in screen units.
  */
-void o_picture_rubberbox(GSCHEM_TOPLEVEL *w_current, int x, int y)
+void o_picture_rubberbox(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
 {
-  TOPLEVEL *toplevel = w_current->toplevel;
 #if DEBUG
   printf("o_picture_rubberbox called\n");
 #endif
   g_assert( w_current->inside_action != 0 );
 
   /* erase the previous temporary box */
-  o_picture_rubberbox_xor(w_current);
+  if (w_current->rubber_visible)
+    o_picture_rubberbox_xor(w_current);
 
   /*
-   * New values are fixed according to the <B>x</B> and <B>y</B> parameters. These are saved in <B>w_current</B> pointed structure as new temporary values. The new box is then drawn.
-
+   * New values are fixed according to the <B>w_x</B> and <B>w_y</B> parameters. 
+   * These are saved in <B>w_current</B> pointed structure as new temporary values. 
+   * The new box is then drawn.
    */
 
   /* update the coords of the corner */
-  w_current->last_x = fix_x(toplevel, x);
-  w_current->last_y = fix_y(toplevel, y);
+  w_current->second_wx = w_x;
+  w_current->second_wy = w_y;
 
   /* draw the new temporary box */
   o_picture_rubberbox_xor(w_current);
-  
+  w_current->rubber_visible = 1;
 }
 
 /*! \brief Draw picture from GSCHEM_TOPLEVEL object.
  *  \par Function Description
  *  This function draws the box from the variables in the GSCHEM_TOPLEVEL
  *  structure <B>*w_current</B>.
- *  One corner of the box is at (<B>w_current->start_x</B>,
- *  <B>w_current->start_y</B>) and the second corner is at
- *  (<B>w_current->last_x</B>,<B>w_current->last_y</B>.
+ *  One corner of the box is at (<B>w_current->first_wx</B>,
+ *  <B>w_current->first_wy</B>) and the second corner is at
+ *  (<B>w_current->second_wx</B>,<B>w_current->second_wy</B>.
  *
  *  The box is drawn with a xor-function over the current sheet with the
  *  selection color.
@@ -307,14 +273,16 @@ void o_picture_rubberbox(GSCHEM_TOPLEVEL *w_current, int x, int y)
  */
 void o_picture_rubberbox_xor(GSCHEM_TOPLEVEL *w_current)
 {
-  int picture_width, picture_height, picture_left, picture_top;
-  
+  TOPLEVEL *toplevel = w_current->toplevel;
+  int left, top, width, height;
+
   /* get the width/height and the upper left corner of the picture */
-  picture_width  = GET_PICTURE_WIDTH (w_current);
-  picture_height = GET_PICTURE_HEIGHT(w_current);
-  picture_left   = GET_PICTURE_LEFT  (w_current);
-  picture_top    = GET_PICTURE_TOP   (w_current);
-  
+  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));
+
 #if DEBUG
   printf("o_picture_rubberbox_xor called:\n");
   printf("pixbuf wh ratio: %i\n", w_current->pixbuf_wh_ratio);
@@ -330,10 +298,9 @@ void o_picture_rubberbox_xor(GSCHEM_TOPLEVEL *w_current)
 			     GDK_LINE_SOLID, GDK_CAP_NOT_LAST, 
 			     GDK_JOIN_MITER);
   gdk_draw_rectangle(w_current->backingstore, w_current->xor_gc,
-		     FALSE, picture_left, picture_top,
-		     picture_width, picture_height);
-  o_invalidate_rect(w_current, picture_left, picture_top,
-                    picture_left + picture_width, picture_top + picture_height);
+		     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/x_event.c b/gschem/src/x_event.c
index 2047eb2..f71c60a 100644
--- a/gschem/src/x_event.c
+++ b/gschem/src/x_event.c
@@ -215,17 +215,13 @@ gint x_event_button_pressed(GtkWidget *widget, GdkEventButton *event,
         break;
 
       case(DRAWPICTURE):
-        o_picture_start(w_current,
-                    (int) event->x,
-                    (int) event->y);
+        o_picture_start(w_current, w_x, w_y);
         w_current->event_state = ENDPICTURE;
         w_current->inside_action = 1;
         break;
 
       case(ENDPICTURE):
-        o_picture_end(w_current,
-                  (int) event->x,
-                  (int) event->y);
+        o_picture_end(w_current, w_x, w_y);
         w_current->inside_action = 0;
         w_current->event_state = DRAWPICTURE;
         break;
@@ -1029,9 +1025,7 @@ gint x_event_motion(GtkWidget *widget, GdkEventMotion *event,
 
     case(ENDPICTURE):
     if (w_current->inside_action)
-    o_picture_rubberbox( w_current,
-                        (int) event->x,
-                        (int) event->y);
+      o_picture_rubberbox( w_current, w_x, w_y);
     break;
 
     case(ENDCIRCLE):

commit 6cfafdaf3c09dde2aedfa7fc3f57662dd0b25ba9
Author: Werner Hoch <werner.ho@xxxxxx>
Date:   Tue Apr 8 21:15:36 2008 +0200

    switched pin rubber drawing to world coordinates
    
    Call all pin functions with world coordinates. Replaced some of the
    gdk drawing functions with object drawing functions.

diff --git a/gschem/include/prototype.h b/gschem/include/prototype.h
index 61f8e53..2f3a9f0 100644
--- a/gschem/include/prototype.h
+++ b/gschem/include/prototype.h
@@ -676,6 +676,7 @@ void o_pin_draw_xor(GSCHEM_TOPLEVEL *w_current, int dx, int dy, OBJECT *o_curren
 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_rubberpin(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);
 /* o_select.c */
 void o_select_run_hooks(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int flag);
diff --git a/gschem/src/i_callbacks.c b/gschem/src/i_callbacks.c
index 26dba7e..7eaecc8 100644
--- a/gschem/src/i_callbacks.c
+++ b/gschem/src/i_callbacks.c
@@ -2732,7 +2732,7 @@ DEFINE_I_CALLBACK(add_pin_hotkey)
 
   i_update_middle_button(w_current, i_callback_add_pin_hotkey, _("Pin"));
 
-  o_pin_start(w_current, mouse_x, mouse_y);
+  o_pin_start(w_current, mouse_wx, mouse_wy);
 
   w_current->inside_action = 1;
   i_set_state(w_current, ENDPIN);
diff --git a/gschem/src/o_pin.c b/gschem/src/o_pin.c
index f76cefa..5725118 100644
--- a/gschem/src/o_pin.c
+++ b/gschem/src/o_pin.c
@@ -161,35 +161,10 @@ void o_pin_draw_xor(GSCHEM_TOPLEVEL *w_current, int dx, int dy, OBJECT *o_curren
  *  \par Function Description
  *
  */
-void o_pin_start(GSCHEM_TOPLEVEL *w_current, int x, int y)
+void o_pin_start(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
 {
-  TOPLEVEL *toplevel = w_current->toplevel;
-  int size;
-  w_current->last_x = w_current->start_x = fix_x(toplevel, x);
-  w_current->last_y = w_current->start_y = fix_y(toplevel, y);
-
-  if (toplevel->pin_style == THICK ) {
-    size = SCREENabs(toplevel, PIN_WIDTH);
-    gdk_gc_set_line_attributes(w_current->xor_gc, size,
-                               GDK_LINE_SOLID,
-                               GDK_CAP_NOT_LAST,
-                               GDK_JOIN_MITER);
-  }
-
-  gdk_gc_set_foreground(w_current->xor_gc, 
-			x_get_darkcolor(w_current->select_color) );
-  gdk_draw_line(w_current->backingstore, w_current->xor_gc,
-		w_current->start_x, w_current->start_y, 
-		w_current->last_x, w_current->last_y);
-  o_invalidate_rect(w_current, w_current->start_x, w_current->start_y,
-                               w_current->last_x, w_current->last_y);
-
-  if (toplevel->pin_style == THICK ) {
-    gdk_gc_set_line_attributes(w_current->xor_gc, 0,
-                               GDK_LINE_SOLID,
-                               GDK_CAP_NOT_LAST,
-                               GDK_JOIN_MITER);
-  }
+  w_current->first_wx = w_current->second_wx = w_x;
+  w_current->first_wy = w_current->second_wy = w_y;
 }
 
 /*! \todo Finish function documentation!!!
@@ -200,8 +175,6 @@ void o_pin_start(GSCHEM_TOPLEVEL *w_current, int x, int y)
 void o_pin_end(GSCHEM_TOPLEVEL *w_current, int x, int y)
 {
   TOPLEVEL *toplevel = w_current->toplevel;
-  int x1, y1;
-  int x2, y2;
   int color;
   GList *other_objects = NULL;
   OBJECT *o_current, *o_current_pin;
@@ -214,33 +187,22 @@ void o_pin_end(GSCHEM_TOPLEVEL *w_current, int x, int y)
     color = toplevel->override_pin_color;
   }
 
-  /* removed 3/15 to see if we can get pins to be ortho only */
-  /* w_current->last_x = fix_x(toplevel, x);
-     w_current->last_y = fix_y(toplevel, y);*/
+  /* undraw rubber line */
+  o_pin_rubberpin_xor(w_current);
 
   /* don't allow zero length pins */
-  if ( (w_current->start_x == w_current->last_x) &&
-       (w_current->start_y == w_current->last_y) ) {
-         w_current->start_x = (-1);
-         w_current->start_y = (-1);
-         w_current->last_x = (-1);
-         w_current->last_y = (-1);
-         return;
+  if ((w_current->first_wx == w_current->second_wx) &&
+      (w_current->first_wy == w_current->second_wy)) {
+    return;
   }
 
-  SCREENtoWORLD(toplevel, w_current->start_x,w_current->start_y, &x1, &y1);
-  SCREENtoWORLD(toplevel, w_current->last_x, w_current->last_y, &x2, &y2);
-  x1 = snap_grid(toplevel, x1);
-  y1 = snap_grid(toplevel, y1);
-  x2 = snap_grid(toplevel, x2);
-  y2 = snap_grid(toplevel, y2);
-
   toplevel->page_current->object_tail =
-  o_pin_add(toplevel,
-            toplevel->page_current->object_tail,
-            OBJ_PIN, color,
-            x1, y1, x2, y2,
-            PIN_TYPE_NET, 0);
+    o_pin_add(toplevel,
+	      toplevel->page_current->object_tail,
+	      OBJ_PIN, color,
+	      w_current->first_wx, w_current->first_wy,
+	      w_current->second_wx, w_current->second_wy,
+	      PIN_TYPE_NET, 0);
 
   o_current = o_current_pin = toplevel->page_current->object_tail;
 
@@ -251,6 +213,7 @@ void o_pin_end(GSCHEM_TOPLEVEL *w_current, int x, int y)
 			  SCM_EOL));
   }
 
+  /* look for connected objects */
   other_objects = s_conn_return_others(other_objects, o_current_pin);
   o_cue_undraw_list(w_current, other_objects);
   o_cue_draw_list(w_current, other_objects);
@@ -258,12 +221,7 @@ void o_pin_end(GSCHEM_TOPLEVEL *w_current, int x, int y)
   o_cue_draw_single(w_current, o_current_pin); 
   o_pin_draw(w_current, o_current_pin);
 
-  w_current->start_x = (-1);
-  w_current->start_y = (-1);
-  w_current->last_x = (-1);
-  w_current->last_y = (-1);
   toplevel->page_current->CHANGED=1;
-
   o_undo_savestate(w_current, UNDO_ALL);
 }
 
@@ -272,57 +230,27 @@ void o_pin_end(GSCHEM_TOPLEVEL *w_current, int x, int y)
  *  \par Function Description
  *
  */
-void o_pin_rubberpin(GSCHEM_TOPLEVEL *w_current, int x, int y)
+void o_pin_rubberpin(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
 {
-  TOPLEVEL *toplevel = w_current->toplevel;
-  int size;
-  int diff_x, diff_y;
-
   g_assert( w_current->inside_action != 0 );
 
-  size = SCREENabs(toplevel, PIN_WIDTH);
-
-  if (toplevel->pin_style == THICK ) {
-    gdk_gc_set_line_attributes(w_current->xor_gc, size,
-                               GDK_LINE_SOLID,
-                               GDK_CAP_NOT_LAST,
-                               GDK_JOIN_MITER);
-  }
-
-  gdk_gc_set_foreground(w_current->xor_gc, 
-			x_get_darkcolor(w_current->select_color) );
-  gdk_draw_line(w_current->backingstore, w_current->xor_gc,
-		w_current->start_x, w_current->start_y, 
-		w_current->last_x, w_current->last_y);
-  o_invalidate_rect(w_current, w_current->start_x, w_current->start_y,
-                    w_current->last_x, w_current->last_y);
-
-  w_current->last_x = fix_x(toplevel, x);
-  w_current->last_y = fix_y(toplevel, y);
+  /* erase the rubberpin if it is visible */
+  if (w_current->rubber_visible)
+    o_pin_rubberpin_xor(w_current);
 
-  diff_x = abs(w_current->last_x - w_current->start_x);
-  diff_y = abs(w_current->last_y - w_current->start_y);
+  w_current->second_wx = w_x;
+  w_current->second_wy = w_y;
 
-  if (diff_x >= diff_y) {
-    w_current->last_y = w_current->start_y;
+  /* decide whether to draw the pin vertical or horizontal */
+  if (abs(w_current->second_wx - w_current->first_wx)
+      >= abs(w_current->second_wy - w_current->first_wy)) {
+    w_current->second_wy = w_current->first_wy;
   } else {
-    w_current->last_x = w_current->start_x;
+    w_current->second_wx = w_current->first_wx;
   }
 
-  gdk_gc_set_foreground(w_current->xor_gc, 
-			x_get_darkcolor(w_current->select_color) );
-  gdk_draw_line(w_current->backingstore, w_current->xor_gc,
-		w_current->start_x, w_current->start_y, 
-		w_current->last_x, w_current->last_y);
-  o_invalidate_rect(w_current, w_current->start_x, w_current->start_y,
-                    w_current->last_x, w_current->last_y);
-
-  if (toplevel->pin_style == THICK ) {
-    gdk_gc_set_line_attributes(w_current->xor_gc, 0,
-                               GDK_LINE_SOLID,
-                               GDK_CAP_NOT_LAST,
-                               GDK_JOIN_MITER);
-  }
+  o_pin_rubberpin_xor(w_current);
+  w_current->rubber_visible = 1;
 }
 
 /*! \todo Finish function documentation!!!
@@ -334,8 +262,23 @@ void o_pin_rubberpin(GSCHEM_TOPLEVEL *w_current, int x, int y)
  */
 void o_pin_eraserubber(GSCHEM_TOPLEVEL *w_current)
 {
+  o_pin_rubberpin_xor(w_current);
+}
+
+
+/*! \todo Finish function documentation!!!
+ *  \brief
+ *  \par Function Description
+ *
+ */
+void o_pin_rubberpin_xor(GSCHEM_TOPLEVEL *w_current) 
+{
   TOPLEVEL *toplevel = w_current->toplevel;
-  int size;
+  int x1, y1, x2, y2;
+  int size = 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 ) {
     size = SCREENabs(toplevel, PIN_WIDTH);
@@ -349,9 +292,10 @@ void o_pin_eraserubber(GSCHEM_TOPLEVEL *w_current)
                                GDK_JOIN_MITER);
   }
 
-  gdk_draw_line(w_current->backingstore, w_current->xor_gc, w_current->start_x, w_current->start_y, w_current->last_x, w_current->last_y);
-  o_invalidate_rect(w_current, w_current->start_x, w_current->start_y,
-                    w_current->last_x, w_current->last_y);
+  gdk_draw_line(w_current->backingstore, 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/x_event.c b/gschem/src/x_event.c
index c6cc131..2047eb2 100644
--- a/gschem/src/x_event.c
+++ b/gschem/src/x_event.c
@@ -255,17 +255,13 @@ gint x_event_button_pressed(GtkWidget *widget, GdkEventButton *event,
         break;
 
       case(DRAWPIN):
-        o_pin_start(w_current,
-                    (int) event->x,
-                    (int) event->y);
+        o_pin_start(w_current, w_x, w_y);
         w_current->event_state = ENDPIN;
         w_current->inside_action = 1;
         break;
 
       case(ENDPIN):
-        o_pin_end(w_current,
-                  (int) event->x,
-                  (int) event->y);
+        o_pin_end(w_current, w_x, w_y);
         w_current->inside_action = 0;
         w_current->event_state = DRAWPIN;
         break;
@@ -1069,9 +1065,7 @@ gint x_event_motion(GtkWidget *widget, GdkEventMotion *event,
 
     case(ENDPIN):
     if (w_current->inside_action)
-    o_pin_rubberpin(w_current,
-                    (int) event->x,
-                    (int) event->y);
+      o_pin_rubberpin(w_current, w_x, w_y);
     break;
 
     case(DRAWCOMP):

commit ef2871ee0ee34af000205cdfe889fb2bad3a74bb
Author: Werner Hoch <werner.ho@xxxxxx>
Date:   Mon Apr 7 20:47:44 2008 +0200

    removed redundant x event state code from o_grips.c
    
    The removed code for updating the state and the toolbar is already
    present in the state code in x_event.c after the o_grips_end()
    call. Reseting the state variables first_wx, second_wx, ... is not
    required at all.

diff --git a/gschem/src/o_grips.c b/gschem/src/o_grips.c
index d8946a6..be836bb 100644
--- a/gschem/src/o_grips.c
+++ b/gschem/src/o_grips.c
@@ -1150,17 +1150,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)) {
-    w_current->first_wx = (-1);
-    w_current->first_wy = (-1);
-    w_current->second_wx  = (-1);
-    w_current->second_wy  = (-1);
-
-    w_current->inside_action=0;
-    i_set_state(w_current, SELECT);
-
     o_redraw_single(w_current, o_current);
-    i_update_toolbar(w_current);
-
     return;
   }
 
@@ -1194,17 +1184,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 ((picture_width == 0) && (picture_height == 0)) {
-    w_current->start_x = (-1);
-    w_current->start_y = (-1);
-    w_current->last_x  = (-1);
-    w_current->last_y  = (-1);
-
-    w_current->inside_action=0;
-    i_set_state(w_current, SELECT);
-
     o_redraw_single(w_current, o_current);
-    i_update_toolbar(w_current);
-
     return;
   }
 
@@ -1253,14 +1233,6 @@ 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) {
-    w_current->start_x = (-1);
-    w_current->start_y = (-1);
-
-    /* return to select mode */
-    w_current->inside_action = 0;
-    i_set_state(w_current, SELECT);
-    i_update_toolbar(w_current);
-
     o_redraw_single(w_current, o_current);
     return;
   }
@@ -1300,16 +1272,6 @@ 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)) {
-    w_current->first_wx = -1;
-    w_current->first_wy = -1;
-    w_current->second_wx = -1;
-    w_current->second_wy = -1;
-
-    /* return to select mode */
-    w_current->inside_action=0;
-    i_set_state(w_current, SELECT);
-    i_update_toolbar(w_current);
-
     o_redraw_single(w_current, o_current);
     return;
   }
@@ -1353,14 +1315,7 @@ 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)) {
-    w_current->first_wx = -1;
-    w_current->first_wy = -1;
-    w_current->second_wx = -1;
-    w_current->second_wy = -1;
-    w_current->inside_action=0;
-    i_set_state(w_current, SELECT);
     o_redraw_single(w_current, o_current);
-    i_update_toolbar(w_current);
     return;
   }
 
@@ -1442,14 +1397,7 @@ 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)) {
-    w_current->first_wx = -1;
-    w_current->first_wy = -1;
-    w_current->second_wx = -1;
-    w_current->second_wy = -1;
-    w_current->inside_action=0;
-    i_set_state(w_current, SELECT);
     o_redraw_single(w_current, o_current);
-    i_update_toolbar(w_current);
     return;
   }
 
@@ -1463,7 +1411,6 @@ 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, whichone_changing);
   s_conn_update_object(toplevel, o_current);
-
   o_redraw_single(w_current, o_current);
 
   /* redraw the object connections */
@@ -1516,14 +1463,7 @@ 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)) {
-    w_current->first_wx = -1;
-    w_current->first_wy = -1;
-    w_current->second_wx = -1;
-    w_current->second_wy = -1;
-    w_current->inside_action=0;
-    i_set_state(w_current, SELECT);
     o_redraw_single(w_current, o_current);
-    i_update_toolbar(w_current);
     return;
   }
 

commit 60b734ed80d7ccefba7a78a878714261a9637a67
Author: Werner Hoch <werner.ho@xxxxxx>
Date:   Mon Apr 7 20:32:01 2008 +0200

    fixed o_grips_end manipulation for net/line and pin
    
    Fixed the code for the end of the net line and pin manipulations.
    Extracted the functionality to three new functions and switched them
    to world coordinates. Removed some gdk drawing code and replaced it
    with object drawing functions.

diff --git a/gschem/include/prototype.h b/gschem/include/prototype.h
index 0b801b6..61f8e53 100644
--- a/gschem/include/prototype.h
+++ b/gschem/include/prototype.h
@@ -595,6 +595,9 @@ void o_grips_end_box(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int whichone
 void o_grips_end_picture(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int whichone);
 void o_grips_end_circle(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int whichone);
 void o_grips_end_line(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int whichone);
+void o_grips_end_net(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int whichone);
+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);
diff --git a/gschem/src/o_grips.c b/gschem/src/o_grips.c
index e705b2f..d8946a6 100644
--- a/gschem/src/o_grips.c
+++ b/gschem/src/o_grips.c
@@ -1002,10 +1002,6 @@ void o_grips_end(GSCHEM_TOPLEVEL *w_current)
 {
   TOPLEVEL *toplevel = w_current->toplevel;
   OBJECT *object=NULL;
-  int x, y;
-  GList *other_objects = NULL;
-  GList *connected_objects = NULL;
-  int size;
 
   object = object_changing;
 
@@ -1044,226 +1040,19 @@ void o_grips_end(GSCHEM_TOPLEVEL *w_current)
     break;
 
     case(OBJ_NET):
-    /* don't allow zero length nets / lines / pins
-     * this ends the net drawing behavior
-     * we want this? hack */
-    if ((w_current->start_x == w_current->last_x) &&
-        (w_current->start_y == w_current->last_y)) {
-      w_current->start_x = (-1);
-      w_current->start_y = (-1);
-      w_current->last_x = (-1);
-      w_current->last_y = (-1);
-      w_current->inside_action=0;
-      i_set_state(w_current, SELECT);
-      o_redraw_single(w_current, object);
-      i_update_toolbar(w_current);
-      return;
-    }
-
-    SCREENtoWORLD(toplevel,
-                  w_current->last_x,
-                  w_current->last_y, &x, &y);
-
-    x = snap_grid(toplevel, x);
-    y = snap_grid(toplevel, y);
-
-    o_cue_undraw(w_current, object);
-    o_erase_single(w_current, object);
-    /* erase xor line */
-    gdk_gc_set_foreground(w_current->xor_gc,
-                          x_get_darkcolor(w_current->select_color));
-    gdk_draw_line(w_current->backingstore, w_current->xor_gc,
-                  w_current->start_x, w_current->start_y,
-                  w_current->last_x, w_current->last_y);
-    o_invalidate_rect(w_current, w_current->start_x, w_current->start_y,
-                      w_current->last_x, w_current->last_y);
-    o_line_erase_grips(w_current, object);
-
-    other_objects = s_conn_return_others(other_objects, object);
-    s_conn_remove(toplevel, object);
-
-    o_net_modify(toplevel, object, x, y, whichone_changing);
-
-    s_conn_update_object(toplevel, object);
-
-    /* get the other connected objects and redraw them */
-    connected_objects = s_conn_return_others(connected_objects,
-                                             object);
-
-    /* add bus rippers if necessary */
-    if (o_net_add_busrippers(w_current, object, connected_objects)) {
-
-      o_erase_single(w_current, object);
-      /*o_line_erase_grips(w_current, object); */
-
-      if (toplevel->net_style == THICK ) {
-        size = SCREENabs(toplevel, 10);
-
-        if (size < 0)
-          size=0;
-
-        gdk_gc_set_line_attributes(w_current->gc, size,
-                                   GDK_LINE_SOLID,
-                                   GDK_CAP_BUTT,
-                                   GDK_JOIN_MITER);
-      }
-
-      gdk_gc_set_foreground(w_current->gc,
-                          x_get_color(toplevel->background_color));
-      gdk_draw_line(w_current->backingstore, w_current->gc,
-                    w_current->start_x, w_current->start_y,
-                    w_current->last_x, w_current->last_y);
-      o_invalidate_rect(w_current, w_current->start_x, w_current->start_y,
-                        w_current->last_x, w_current->last_y);
-
-      o_cue_undraw(w_current, object);
-      o_net_draw(w_current, object);
-      o_cue_draw_single(w_current, object);
-
-      if (toplevel->net_style == THICK ) {
-        gdk_gc_set_line_attributes(w_current->gc, 0,
-                                   GDK_LINE_SOLID,
-                                   GDK_CAP_NOT_LAST,
-                                   GDK_JOIN_MITER);
-      }
-    }
-
-    /* draw the object objects */
-    o_cue_undraw_list(w_current, other_objects);
-    o_cue_draw_list(w_current, other_objects);
-
-    o_redraw_single(w_current, object);
-
-    if (connected_objects) {
-      g_list_free(connected_objects);
-      connected_objects = NULL;
-    }
-
-    /* get the other connected objects and redraw them */
-    connected_objects = s_conn_return_others(connected_objects,
-                                             object);
-
-    o_cue_undraw_list(w_current, connected_objects);
-    o_cue_draw_list(w_current, connected_objects);
-    /* finally draw this objects cues */
-    o_cue_draw_single(w_current, object);
-    break;
+      /* modify a net object */
+      o_grips_end_net(w_current, object, whichone_changing);
+      break;
 
     case(OBJ_PIN):
-    /* don't allow zero length nets / lines / pins
-     * this ends the net drawing behavior
-     * we want this? hack */
-    if ((w_current->start_x == w_current->last_x) &&
-        (w_current->start_y == w_current->last_y)) {
-      w_current->start_x = (-1);
-      w_current->start_y = (-1);
-      w_current->last_x = (-1);
-      w_current->last_y = (-1);
-      o_redraw_single(w_current, object);
-      w_current->inside_action=0;
-      i_set_state(w_current, SELECT);
-      i_update_toolbar(w_current);
-      return;
-    }
-
-    SCREENtoWORLD(toplevel,
-                  w_current->last_x,
-                  w_current->last_y, &x, &y);
-
-    x = snap_grid(toplevel, x);
-    y = snap_grid(toplevel, y);
-
-    o_cue_undraw(w_current, object);
-    o_erase_single(w_current, object);
-    /* erase xor line */
-    gdk_gc_set_foreground(w_current->xor_gc,
-                          x_get_darkcolor(w_current->select_color));
-    gdk_draw_line(w_current->backingstore, w_current->xor_gc,
-                  w_current->start_x, w_current->start_y,
-                  w_current->last_x, w_current->last_y);
-    o_invalidate_rect(w_current, w_current->start_x, w_current->start_y,
-                      w_current->last_x, w_current->last_y);
-    o_line_erase_grips(w_current, object);
-
-    other_objects = s_conn_return_others(other_objects, object);
-    s_conn_remove(toplevel, object);
-
-    o_pin_modify(toplevel, object, x, y,
-                 whichone_changing);
-    s_conn_update_object(toplevel, object);
-    o_redraw_single(w_current, object);
-
-    /* draw the object objects */
-    o_cue_undraw_list(w_current, other_objects);
-    o_cue_draw_list(w_current, other_objects);
-
-    /* get the other connected objects and redraw them */
-    connected_objects = s_conn_return_others(connected_objects,
-                                             object);
-    o_cue_undraw_list(w_current, connected_objects);
-    o_cue_draw_list(w_current, connected_objects);
-
-    /* finally draw this objects cues */
-    o_cue_draw_single(w_current, object);
-    break;
+      /* modify a pin object */
+      o_grips_end_pin(w_current, object, whichone_changing);
+      break;
 
     case(OBJ_BUS):
-    /* don't allow zero length nets / lines / pins
-     * this ends the net drawing behavior
-     * we want this? hack */
-    if ((w_current->start_x == w_current->last_x) &&
-        (w_current->start_y == w_current->last_y)) {
-      w_current->start_x = (-1);
-      w_current->start_y = (-1);
-      w_current->last_x = (-1);
-      w_current->last_y = (-1);
-      o_redraw_single(w_current, object);
-      w_current->inside_action=0;
-      i_set_state(w_current, SELECT);
-      i_update_toolbar(w_current);
-      return;
-    }
-
-    SCREENtoWORLD(toplevel,
-                  w_current->last_x,
-                  w_current->last_y, &x, &y);
-
-    x = snap_grid(toplevel, x);
-    y = snap_grid(toplevel, y);
-
-    o_cue_undraw(w_current, object);
-    o_erase_single(w_current, object);
-    /* erase xor line */
-    gdk_gc_set_foreground(w_current->xor_gc,
-                          x_get_darkcolor(w_current->select_color));
-    gdk_draw_line(w_current->backingstore, w_current->xor_gc,
-                  w_current->start_x, w_current->start_y,
-                  w_current->last_x, w_current->last_y);
-    o_invalidate_rect(w_current, w_current->start_x, w_current->start_y,
-                      w_current->last_x, w_current->last_y);
-    o_line_erase_grips(w_current, object);
-
-    other_objects = s_conn_return_others(other_objects, object);
-    s_conn_remove(toplevel, object);
-
-    o_bus_modify(toplevel, object, x, y,
-                 whichone_changing);
-    s_conn_update_object(toplevel, object);
-    o_redraw_single(w_current, object);
-
-    /* draw the object objects */
-    o_cue_undraw_list(w_current, other_objects);
-    o_cue_draw_list(w_current, other_objects);
-
-    /* get the other connected objects and redraw them */
-    connected_objects = s_conn_return_others(connected_objects,
-                                             object);
-    o_cue_undraw_list(w_current, connected_objects);
-    o_cue_draw_list(w_current, connected_objects);
-
-    /* finally draw this objects cues */
-    o_cue_draw_single(w_current, object);
-    break;
+      /* modify a bus object */
+      o_grips_end_bus(w_current, object, whichone_changing);
+      break;
 
     default:
     return;
@@ -1271,11 +1060,6 @@ void o_grips_end(GSCHEM_TOPLEVEL *w_current)
 
   toplevel->page_current->CHANGED=1;
 
-  g_list_free(other_objects);
-  other_objects = NULL;
-  g_list_free(connected_objects);
-  connected_objects = NULL;
-
   /* reset global variables */
   whichone_changing = -1;
   object_changing = NULL;
@@ -1501,7 +1285,7 @@ void o_grips_end_circle(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int which
  *  allowed. In this case, the process is stopped and the line unchanged.
  *
  *  \param [in] w_current  The GSCHEM_TOPLEVEL object.
- *  \param [in] o_current  Circle OBJECT to end modification on.
+ *  \param [in] o_current  Line OBJECT to end modification on.
  *  \param [in] whichone   Which grip is pointed to.
  */
 void o_grips_end_line(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int whichone)
@@ -1538,6 +1322,244 @@ void o_grips_end_line(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int whichon
   o_redraw_single(w_current, o_current);
 }
 
+
+/*! \brief End process of modifying net object with grip.
+ *  \par Function Description
+ *  This function ends the process of modifying one end of the net
+ *  object <B>*o_current</B>.
+ *  This end is identified by <B>whichone</B>. The line object is modified
+ *  according to the <B>whichone</B> parameter and the last position of the
+ *  line end.
+ *  The connections to the modified net are checked and recreated if neccessary.
+ *
+ *  A net with zero length, i.e. when both ends are identical, is not
+ *  allowed. In this case, the process is stopped and the line unchanged.
+ *
+ *  \param [in] w_current  The GSCHEM_TOPLEVEL object.
+ *  \param [in] o_current  Net OBJECT to end modification on.
+ *  \param [in] whichone   Which grip is pointed to.
+ */
+void o_grips_end_net(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int whichone)
+{
+  TOPLEVEL *toplevel = w_current->toplevel;
+  GList *other_objects = NULL;
+  GList *connected_objects = NULL;
+
+  /* erase the temporary line */
+  o_line_rubberline_xor(w_current);
+
+  /* don't allow zero length net
+   * this ends the net drawing behavior
+   * we want this? hack */
+  if ((w_current->first_wx == w_current->second_wx) &&
+      (w_current->first_wy == w_current->second_wy)) {
+    w_current->first_wx = -1;
+    w_current->first_wy = -1;
+    w_current->second_wx = -1;
+    w_current->second_wy = -1;
+    w_current->inside_action=0;
+    i_set_state(w_current, SELECT);
+    o_redraw_single(w_current, o_current);
+    i_update_toolbar(w_current);
+    return;
+  }
+
+  /* remove the old net */
+  o_cue_undraw(w_current, o_current);
+  o_erase_single(w_current, o_current);
+
+  other_objects = s_conn_return_others(other_objects, o_current);
+
+  s_conn_remove(toplevel, o_current);
+  o_net_modify(toplevel, o_current, 
+	       w_current->second_wx, w_current->second_wy, whichone_changing);
+  s_conn_update_object(toplevel, o_current);
+
+  /* get the other connected objects and redraw them */
+  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_erase_single(w_current, o_current);
+    o_cue_undraw(w_current, o_current);
+
+    o_net_draw(w_current, o_current);
+    o_cue_draw_single(w_current, o_current);
+  }
+
+  /* draw the object objects */
+  o_cue_undraw_list(w_current, other_objects);
+  o_cue_draw_list(w_current, other_objects);
+  
+  o_redraw_single(w_current, o_current);
+  
+  g_list_free(connected_objects);
+  connected_objects = NULL;
+  
+  /* 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);
+  /* finally draw this objects cues */
+  o_cue_draw_single(w_current, o_current);
+
+  g_list_free(other_objects);
+  other_objects = NULL;
+  g_list_free(connected_objects);
+  connected_objects = NULL;
+}
+
+/*! \brief End process of modifying pin object with grip.
+ *  \par Function Description
+ *  This function ends the process of modifying one end of the pin
+ *  object <B>*o_current</B>.
+ *  This end is identified by <B>whichone</B>. The pin object is modified
+ *  according to the <B>whichone</B> parameter and the last position of the
+ *  pin end.
+ *  The connections to the modified pin are checked and recreated if neccessary.
+ *
+ *  A pin with zero length, i.e. when both ends are identical, is not
+ *  allowed. In this case, the process is stopped and the line unchanged.
+ *
+ *  \param [in] w_current  The GSCHEM_TOPLEVEL object.
+ *  \param [in] o_current  Net OBJECT to end modification on.
+ *  \param [in] whichone   Which grip is pointed to.
+ */
+void o_grips_end_pin(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int whichone)
+{
+  TOPLEVEL *toplevel = w_current->toplevel;
+  GList *other_objects = NULL;
+  GList *connected_objects = NULL;
+
+  /* erase the temporary line */
+  o_line_rubberline_xor(w_current);
+
+  /* don't allow zero length pin
+   * this ends the pin changing behavior
+   * we want this? hack */
+  if ((w_current->first_wx == w_current->second_wx) &&
+      (w_current->first_wy == w_current->second_wy)) {
+    w_current->first_wx = -1;
+    w_current->first_wy = -1;
+    w_current->second_wx = -1;
+    w_current->second_wy = -1;
+    w_current->inside_action=0;
+    i_set_state(w_current, SELECT);
+    o_redraw_single(w_current, o_current);
+    i_update_toolbar(w_current);
+    return;
+  }
+
+  /* erase old pin object */
+  o_cue_undraw(w_current, o_current);
+  o_erase_single(w_current, o_current);
+
+  other_objects = s_conn_return_others(other_objects, o_current);
+
+  s_conn_remove(toplevel, o_current);
+  o_pin_modify(toplevel, o_current, 
+	       w_current->second_wx, w_current->second_wy, whichone_changing);
+  s_conn_update_object(toplevel, o_current);
+
+  o_redraw_single(w_current, o_current);
+
+  /* redraw the object connections */
+  o_cue_undraw_list(w_current, other_objects);
+  o_cue_draw_list(w_current, other_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);
+
+  /* finally draw this objects cues */
+  o_cue_draw_single(w_current, o_current);
+
+  /* free the two lists */
+  g_list_free(other_objects);
+  other_objects = NULL;
+  g_list_free(connected_objects);
+  connected_objects = NULL;
+}
+
+/*! \brief End process of modifying bus object with grip.
+ *  \par Function Description
+ *  This function ends the process of modifying one end of the bus
+ *  object <B>*o_current</B>.
+ *  This end is identified by <B>whichone</B>. The line object is modified
+ *  according to the <B>whichone</B> parameter and the last position of the
+ *  bus end.
+ *  The connections to the modified bus are checked and recreated if neccessary.
+ *
+ *  A bus with zero length, i.e. when both ends are identical, is not
+ *  allowed. In this case, the process is stopped and the bus unchanged.
+ *
+ *  \param [in] w_current  The GSCHEM_TOPLEVEL object.
+ *  \param [in] o_current  bus OBJECT to end modification on.
+ *  \param [in] whichone   Which grip is pointed to.
+ */
+void o_grips_end_bus(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int whichone)
+{
+  TOPLEVEL *toplevel = w_current->toplevel;
+  GList *other_objects = NULL;
+  GList *connected_objects = NULL;
+
+  /* erase the temporary line */
+  o_line_rubberline_xor(w_current);
+
+  /* don't allow zero length bus
+   * this ends the bus changing behavior
+   * we want this? hack */
+  if ((w_current->first_wx == w_current->second_wx) &&
+      (w_current->first_wy == w_current->second_wy)) {
+    w_current->first_wx = -1;
+    w_current->first_wy = -1;
+    w_current->second_wx = -1;
+    w_current->second_wy = -1;
+    w_current->inside_action=0;
+    i_set_state(w_current, SELECT);
+    o_redraw_single(w_current, o_current);
+    i_update_toolbar(w_current);
+    return;
+  }
+
+  /* erase the old bus and it's cues */
+  o_cue_undraw(w_current, o_current);
+  o_erase_single(w_current, o_current);
+
+  other_objects = s_conn_return_others(other_objects, o_current);
+  s_conn_remove(toplevel, o_current);
+
+  o_bus_modify(toplevel, o_current, 
+	       w_current->second_wx, w_current->second_wy, whichone_changing);
+  s_conn_update_object(toplevel, o_current);
+  o_redraw_single(w_current, o_current);
+
+  /* redraw the connected objects */
+  o_cue_undraw_list(w_current, other_objects);
+  o_cue_draw_list(w_current, other_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);
+
+  /* finally draw this objects cues */
+  o_cue_draw_single(w_current, o_current);
+
+  /* free the two lists */
+  g_list_free(other_objects);
+  other_objects = NULL;
+  g_list_free(connected_objects);
+  connected_objects = NULL;
+}
+
+
 /*! \brief Get half the width and height of grip in screen units.
  *  \par Function Description
  *  According to the current zoom level, the function returns half the width

commit f003de85165f11280f909acd6b785ebf38bacf39
Author: Werner Hoch <werner.ho@xxxxxx>
Date:   Sun Apr 6 21:41:19 2008 +0200

    switched grips for line manipulation to world coords
    
    This also affects the line/bus and pin manipulation.
    While start and motion is identical, the end point of the
    manipulation has to be fixed separatly.

diff --git a/gschem/src/o_grips.c b/gschem/src/o_grips.c
index aaad72c..e705b2f 100644
--- a/gschem/src/o_grips.c
+++ b/gschem/src/o_grips.c
@@ -522,68 +522,12 @@ int o_grips_start(GSCHEM_TOPLEVEL *w_current, int x, int y)
       return(TRUE);
 
     case(OBJ_LINE):
-      /* start the modification of a grip on a line */
-      o_grips_start_line(w_current, object, x, y, whichone);
-      return(TRUE);
-
     case(OBJ_NET):
-      w_current->last_drawb_mode = -1;
-      WORLDtoSCREEN( toplevel, object->line->x[whichone], object->line->y[whichone],
-                     &w_current->last_x, &w_current->last_y );
-      WORLDtoSCREEN( toplevel, object->line->x[!whichone], object->line->y[!whichone],
-                     &w_current->start_x, &w_current->start_y );
-
-      o_erase_single(w_current, object);
-      gdk_gc_set_foreground(w_current->xor_gc,
-                            x_get_darkcolor(w_current->select_color) );
-      gdk_draw_line(w_current->backingstore, w_current->xor_gc,
-                    w_current->start_x, w_current->start_y,
-                    w_current->last_x, w_current->last_y);
-      o_invalidate_rect(w_current, w_current->start_x, w_current->start_y,
-                        w_current->last_x, w_current->last_y);
-      o_line_erase_grips(w_current, object);
-
-      gdk_gc_set_foreground(w_current->gc,
-                            x_get_color(toplevel->background_color));
-      return(TRUE);
-
     case(OBJ_PIN):
-      w_current->last_drawb_mode = -1;
-      WORLDtoSCREEN( toplevel, object->line->x[whichone], object->line->y[whichone],
-                     &w_current->last_x, &w_current->last_y );
-      WORLDtoSCREEN( toplevel, object->line->x[!whichone], object->line->y[!whichone],
-                     &w_current->start_x, &w_current->start_y );
-
-      o_erase_single(w_current, object);
-      gdk_gc_set_foreground(w_current->xor_gc,
-                            x_get_darkcolor(w_current->select_color) );
-      gdk_draw_line(w_current->backingstore, w_current->xor_gc,
-                    w_current->start_x, w_current->start_y,
-                    w_current->last_x, w_current->last_y);
-      o_invalidate_rect(w_current, w_current->start_x, w_current->start_y,
-                        w_current->last_x, w_current->last_y);
-      o_line_erase_grips(w_current, object);
-      return(TRUE);
-
     case(OBJ_BUS):
-      w_current->last_drawb_mode = -1;
-      WORLDtoSCREEN( toplevel, object->line->x[whichone], object->line->y[whichone],
-                     &w_current->last_x, &w_current->last_y );
-      WORLDtoSCREEN( toplevel, object->line->x[!whichone], object->line->y[!whichone],
-                     &w_current->start_x, &w_current->start_y );
-
-      o_erase_single(w_current, object);
-      gdk_gc_set_foreground(w_current->xor_gc,
-                            x_get_darkcolor(w_current->select_color) );
-      gdk_draw_line(w_current->backingstore, w_current->xor_gc,
-                    w_current->start_x, w_current->start_y,
-                    w_current->last_x, w_current->last_y);
-      o_invalidate_rect(w_current, w_current->start_x, w_current->start_y,
-                        w_current->last_x, w_current->last_y);
-      o_line_erase_grips(w_current, object);
-
-      gdk_gc_set_foreground(w_current->gc,
-                            x_get_color(toplevel->background_color));
+      /* identical for line/net/pin/bus */
+      /* start the modification of a grip on a line */
+      o_grips_start_line(w_current, object, x, y, whichone);
       return(TRUE);
 
     default:
@@ -824,11 +768,11 @@ void o_grips_start_circle(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current,
  *  sheet with an xor-function.
  *
  *  During the move of the grip, the line is described by
- *  (<B>w_current->start_x</B>,<B>w_current->start_y</B>) and
- *  (<B>w_current->last_x</B>,<B>w_current->last_y</B>).
+ *  (<B>w_current->first_wx</B>,<B>w_current->first_wy</B>) and
+ *  (<B>w_current->second_wx</B>,<B>w_current->second_wy</B>).
  *
  *  The line end that corresponds to the moving grip is in
- *  (<B>w_current->last_x</B>,<B>w_current->last_y</B>).
+ *  (<B>w_current->second_wx</B>,<B>w_current->second_wy</B>).
  *
  *  \param [in]  w_current  The GSCHEM_TOPLEVEL object.
  *  \param [in]  o_current  Line OBJECT to check.
@@ -839,20 +783,20 @@ void o_grips_start_circle(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current,
 void o_grips_start_line(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current,
                         int x, int y, int whichone)
 {
-  TOPLEVEL *toplevel = w_current->toplevel;
   w_current->last_drawb_mode = -1;
 
   /* erase the line before */
   o_erase_single(w_current, o_current);
 
   /* describe the line with GSCHEM_TOPLEVEL variables */
-  WORLDtoSCREEN( toplevel, o_current->line->x[whichone], o_current->line->y[whichone],
-                 &w_current->last_x, &w_current->last_y );
-  WORLDtoSCREEN( toplevel, o_current->line->x[!whichone], o_current->line->y[!whichone],
-                 &w_current->start_x, &w_current->start_y );
+  w_current->second_wx = o_current->line->x[whichone];
+  w_current->second_wy = o_current->line->y[whichone];
+  w_current->first_wx = o_current->line->x[!whichone];
+  w_current->first_wy = o_current->line->y[!whichone];
 
   /* draw the first temporary line */
   o_line_rubberline_xor(w_current);
+  w_current->rubber_visible = 1;
 }
 
 /*! \brief Modify previously selected object according to mouse position.
@@ -911,7 +855,7 @@ void o_grips_motion(GSCHEM_TOPLEVEL *w_current, int x, int y)
     case(OBJ_BUS):
     /* erase, update and draw a line */
     /* same for net, pin and bus as they share the same internal rep. */
-    o_grips_motion_line(w_current, x, y, whichone_changing);
+    o_grips_motion_line(w_current, w_x, w_y, whichone_changing);
     break;
 
     default:
@@ -1025,17 +969,17 @@ void o_grips_motion_circle(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y, int whi
  *  \par Function Description
  *  This function is called during the move of the grip to update the
  *  temporary line drawn under the mouse pointer.
- *  The current position of the mouse is in <B>x</B> and <B>y</B> in screen coords.
+ *  The current position of the mouse is in <B>w_x</B> and <B>w_y</B> in world coords.
  *
  *  \param [in] w_current  The GSCHEM_TOPLEVEL object.
- *  \param [in] x          Current x coordinate of pointer in screen units.
- *  \param [in] y          Current y coordinate of pointer in screen units.
+ *  \param [in] w_x        Current x coordinate of pointer in world units.
+ *  \param [in] w_y        Current y coordinate of pointer in world units.
  *  \param [in] whichone   Which grip to start motion with.
  */
-void o_grips_motion_line(GSCHEM_TOPLEVEL *w_current, int x, int y, int whichone)
+void o_grips_motion_line(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y, int whichone)
 {
   /* erase, update and draw the temporary line */
-  o_line_rubberline(w_current, x, y);
+  o_line_rubberline(w_current, w_x, w_y);
 }
 
 /*! \brief End process of modifying object with grip.
@@ -1563,7 +1507,6 @@ void o_grips_end_circle(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int which
 void o_grips_end_line(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int whichone)
 {
   TOPLEVEL *toplevel = w_current->toplevel;
-  int x, y;
 
   /* erase the temporary line */
   o_line_rubberline_xor(w_current);
@@ -1571,12 +1514,12 @@ void o_grips_end_line(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int whichon
   /* don't allow zero length nets / lines / pins
    * this ends the net drawing behavior
    * we want this? hack */
-  if ((w_current->start_x == w_current->last_x) &&
-      (w_current->start_y == w_current->last_y)) {
-    w_current->start_x = (-1);
-    w_current->start_y = (-1);
-    w_current->last_x  = (-1);
-    w_current->last_y  = (-1);
+  if ((w_current->first_wx == w_current->second_wx) &&
+      (w_current->first_wy == w_current->second_wy)) {
+    w_current->first_wx = -1;
+    w_current->first_wy = -1;
+    w_current->second_wx = -1;
+    w_current->second_wy = -1;
 
     /* return to select mode */
     w_current->inside_action=0;
@@ -1587,15 +1530,9 @@ void o_grips_end_line(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int whichon
     return;
   }
 
-  /* convert the line end coords in world unit */
-  SCREENtoWORLD(toplevel,
-                w_current->last_x, w_current->last_y,
-                &x, &y);
-  x = snap_grid(toplevel, x);
-  y = snap_grid(toplevel, y);
-
   /* modify the right line end according to whichone */
-  o_line_modify(toplevel, o_current, x, y, whichone);
+  o_line_modify(toplevel, o_current, 
+		w_current->second_wx, w_current->second_wy, whichone);
 
   /* display the new line */
   o_redraw_single(w_current, o_current);

commit 6efa4f6c16894852b409f130d50acef88d78aa22
Author: Werner Hoch <werner.ho@xxxxxx>
Date:   Sun Apr 6 20:05:25 2008 +0200

    switched line rubber drawing to world coords
    
    Call all line functions with world coordinates. Removed
    some unused code.

diff --git a/gschem/src/i_callbacks.c b/gschem/src/i_callbacks.c
index 385face..26dba7e 100644
--- a/gschem/src/i_callbacks.c
+++ b/gschem/src/i_callbacks.c
@@ -2533,7 +2533,7 @@ DEFINE_I_CALLBACK(add_line_hotkey)
 
   i_update_middle_button(w_current, i_callback_add_line_hotkey, _("Line"));
 
-  o_line_start(w_current, mouse_x, mouse_y);
+  o_line_start(w_current, mouse_wx, mouse_wy);
 
   w_current->inside_action = 1;
   i_set_state(w_current, ENDLINE);
diff --git a/gschem/src/o_arc.c b/gschem/src/o_arc.c
index 3edbcc0..83b62af 100644
--- a/gschem/src/o_arc.c
+++ b/gschem/src/o_arc.c
@@ -31,25 +31,12 @@
 #include <dmalloc.h>
 #endif
 
-/* Kazu on July 8, 1999 - added these macros to simplify the code */
-/*! \brief */
-#define GET_BOX_WIDTH(w)			\
-	abs((w)->last_x - (w)->start_x)
-/*! \brief */
-#define GET_BOX_HEIGHT(w)			\
-	abs((w)->last_y - (w)->start_y)
 
 typedef void (*DRAW_FUNC)( GdkDrawable *w, GdkGC *gc, GdkColor *color,
                            GdkCapStyle cap, gint x, gint y, gint radius,
                            gint angle1, gint angle2,
                            gint arc_width, gint length, gint space );
 
-/*! \brief
- *  \note pb20011011 - added this macro to compute distance
- */
-#define GET_DISTANCE(w)             \
-    sqrt(pow((w)->last_x-(w)->start_x,2)+pow((w)->last_y-(w)->start_y,2))
-
 /*! \brief Draw an arc on the screen.
  *  \par Function Description
  *  This function is used to draw an arc on screen. The arc is described
diff --git a/gschem/src/o_bus.c b/gschem/src/o_bus.c
index 69f640a..b014bfe 100644
--- a/gschem/src/o_bus.c
+++ b/gschem/src/o_bus.c
@@ -281,7 +281,7 @@ int o_bus_end(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
 
   o_bus_draw(w_current, bus_new);
 
-  /* connect the new bus to the  stuff */
+  /* connect the new bus to the other busses */
   other_objects = s_conn_return_others(other_objects,
                                        toplevel->page_current->
                                        object_tail);
diff --git a/gschem/src/o_line.c b/gschem/src/o_line.c
index 82c5f75..1f4b38c 100644
--- a/gschem/src/o_line.c
+++ b/gschem/src/o_line.c
@@ -479,43 +479,6 @@ void o_line_draw_center(GdkWindow *w, GdkGC *gc, GdkColor *color,
   }
 }
 
-/*! \note This code was not inserted in the no web file, but it was present.
-If the above condition is not satisfied, it may still be possible to continue drawing a part of the initial pattern. Here two cases are possible :
-@itemize @bullet
-@item
-it is possible to draw a dash and a dot ;
-@item
-it is possible to draw a dash or a part of the original dash ;
-@end itemize
-
-<<o_line.c : o_line_center()>>=
-  if((d + length + space) < l) {
-    d = d + length;
-    xb = xa + dx1;
-    yb = ya + dy1;
-    gdk_draw_line(w, gc, (int) xa, (int) ya, (int) xb, (int) yb);
-		
-    d = d + space;
-    xa = xb + dx2;
-    ya = yb + dy2;
-		
-    <<o_line_draw_center() : drawing a dot>>
-		
-  } else {
-    if(d + length < l) {
-      xb = xa + dx1;
-      yb = ya + dy1;
-    } else {
-      xb = x2;
-      yb = y2;
-    }
-		
-    gdk_draw_line(w, gc, (int) xa, (int) ya, (int) xb, (int) yb);
-	
-  }
-
-}
-*/
 
 /*! \brief Draw a line with a phantom line type.
  *  \par Function Description
@@ -789,21 +752,25 @@ void o_line_draw_xor(GSCHEM_TOPLEVEL *w_current, int dx, int dy, OBJECT *o_curre
  *  the current sheet.
  *
  *  During all the process, the line is internally represented by the two
- *  ends of the line as (<B>w_current->start_x</B>,<B>w_current->start_y</B>) and
- *  (<B>w_current->last_x</B>,<B>w_current->last_y</B>).
+ *  ends of the line as (<B>w_current->first_wx</B>,<B>w_current->first_wy</B>) and
+ *  (<B>w_current->second_wx</B>,<B>w_current->second_wy</B>).
  *
  *  A temporary line is xor-drawn during the process with the selection color
  *  and changed according to the position of the mouse pointer.
+ *
+ *  \param [in] w_current  The GSCHEM_TOPLEVEL object.
+ *  \param [in] w_x        Current x coordinate of pointer in world units.
+ *  \param [in] w_y        Current y coordinate of pointer in world units.
  */
-void o_line_start(GSCHEM_TOPLEVEL *w_current, int x, int y)
+void o_line_start(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
 {
-  TOPLEVEL *toplevel = w_current->toplevel;
-  /* init start_[x|y], last_[x|y] to describe line */
-  w_current->last_x = w_current->start_x = fix_x(toplevel, x);
-  w_current->last_y = w_current->start_y = fix_y(toplevel, y);
+  /* init first_w[x|y], second_w[x|y] to describe line */
+  w_current->first_wx = w_current->second_wx = w_x;
+  w_current->first_wy = w_current->second_wy = w_y;
   
   /* draw init xor */
   o_line_rubberline_xor(w_current);
+  w_current->rubber_visible = 1;
 }
 
 /*! \brief End the input of a line.
@@ -817,62 +784,42 @@ void o_line_start(GSCHEM_TOPLEVEL *w_current, int x, int y)
  *  sheet.
  *
  *  \param [in] w_current  The GSCHEM_TOPLEVEL object.
- *  \param [in] x          Current x coordinate of pointer in screen units.
- *  \param [in] y          Current y coordinate of pointer in screen units.
+ *  \param [in] w_x        (unused)
+ *  \param [in] w_y        (unused)
  */
-void o_line_end(GSCHEM_TOPLEVEL *w_current, int x, int y)
+void o_line_end(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
 {
   TOPLEVEL *toplevel = w_current->toplevel;
-  int x1, y1;
-  int x2, y2;
 
   g_assert( w_current->inside_action != 0 );
 
-  /* Use last_x and _y from the last time you moved the mouse from the
-     rubber function, so in otherwords... comment these out...
-     w_current->last_x = fix_x(toplevel, x);
-     w_current->last_y = fix_y(toplevel, y);
-  */
-
   /* erase xor image */
   o_line_rubberline_xor(w_current);
 
   /* don't allow zero length lines */
-  if ( (w_current->start_x == w_current->last_x) &&
-       (w_current->start_y == w_current->last_y) ) {
-    w_current->start_x = (-1);
-    w_current->start_y = (-1);
-    w_current->last_x = (-1);
-    w_current->last_y = (-1);
+  if ( (w_current->first_wx == w_current->second_wx) &&
+       (w_current->first_wy == w_current->second_wy) ) {
+    w_current->first_wx = -1;
+    w_current->first_wy = -1;
+    w_current->second_wx = -1;
+    w_current->second_wy = -1;
     return;
   }
 
-  /* calculate the world coords of the two ends of the line */
-  SCREENtoWORLD(toplevel,
-				w_current->start_x, w_current->start_y,
-				&x1, &y1);
-  SCREENtoWORLD(toplevel,
-				w_current->last_x, w_current->last_y,
-				&x2, &y2);
-  x1 = snap_grid(toplevel, x1);
-  y1 = snap_grid(toplevel, y1);
-  x2 = snap_grid(toplevel, x2);
-  y2 = snap_grid(toplevel, y2);
-	
-  /* create the object */
-  /* PB : modification in o_line_add() prototype */	
+  /* create the line object and draw it */
   toplevel->page_current->object_tail =
-  o_line_add(toplevel,
-             toplevel->page_current->object_tail,
-             OBJ_LINE, w_current->graphic_color, x1, y1, x2, y2);
+    o_line_add(toplevel,
+	       toplevel->page_current->object_tail,
+	       OBJ_LINE, w_current->graphic_color, 
+	       w_current->first_wx, w_current->first_wy,
+	       w_current->second_wx, w_current->second_wy);
 
-  /* draw it */
   o_redraw_single(w_current, toplevel->page_current->object_tail);
   
-  w_current->start_x = (-1);
-  w_current->start_y = (-1);
-  w_current->last_x = (-1);
-  w_current->last_y = (-1);
+  w_current->first_wx = -1;
+  w_current->first_wy = -1;
+  w_current->second_wx = -1;
+  w_current->second_wy = -1;
   
   toplevel->page_current->CHANGED=1;
 
@@ -884,17 +831,16 @@ void o_line_end(GSCHEM_TOPLEVEL *w_current, int x, int y)
  *  This function manages the erase/update/draw process of temporary line
  *  when modifying one end of the line.
  *  The line is described by four <B>*w_current</B> variables : the first end
- *  of the line is (<B>start_x</B>,<B>start_y</B>), the second end is
- *  (<B>last_x</B>,<B>last_y</B>).
- *  The first end is constant. The second end is updated to the (<B>x</B>,<B>y</B>).
+ *  of the line is (<B>first_wx</B>,<B>first_wy</B>), the second end is
+ *  (<B>second_wx</B>,<B>second_wy</B>).
+ *  The first end is constant. The second end is updated to the (<B>w_x</B>,<B>w_y</B>).
  * 
  *  \param [in] w_current  The GSCHEM_TOPLEVEL object.
- *  \param [in] x          Current x coordinate of pointer in screen units.
- *  \param [in] y          Current y coordinate of pointer in screen units.
+ *  \param [in] w_x        Current x coordinate of pointer in world units.
+ *  \param [in] w_y        Current y coordinate of pointer in world units.
  */
-void o_line_rubberline(GSCHEM_TOPLEVEL *w_current, int x, int y)
+void o_line_rubberline(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
 {
-  TOPLEVEL *toplevel = w_current->toplevel;
   int diff_x, diff_y;
 
   g_assert( w_current->inside_action != 0 );
@@ -907,28 +853,26 @@ void o_line_rubberline(GSCHEM_TOPLEVEL *w_current, int x, int y)
    * This line is xor-drawn : if the line was already displayed, it is
    * erased. If the line was not already displayed it is drawn.
    */
-  /* xor-draw a line at the old location */
-  o_line_rubberline_xor(w_current);
+  if (w_current->rubber_visible)
+    o_line_rubberline_xor(w_current);
 
   /*
    * The coordinates of the moving end of the line are updated. Its new
-   * coordinates are in <B>x</B> and <B>y</B> parameters and saved to
-   * <B>w_current->last_x</B> and <B>w_current->last_y</B> respectively - after
-   * being snapped to grid.
+   * coordinates are in <B>w_x</B> and <B>w_y</B> parameters and saved to
+   * <B>w_current->second_wx</B> and <B>w_current->second_wy</B> respectively.
    */ 
-  /* update the coordinate of the modified end */
-  w_current->last_x = fix_x(toplevel, x);
-  w_current->last_y = fix_y(toplevel, y);
+  w_current->second_wx = w_x;
+  w_current->second_wy = w_y;
   
   /* if the control key was pressed then draw ortho lines */
   if (w_current->CONTROLKEY) {
-    diff_x = abs(w_current->last_x - w_current->start_x);
-    diff_y = abs(w_current->last_y - w_current->start_y);
+    diff_x = abs(w_current->second_wx - w_current->first_wx);
+    diff_y = abs(w_current->second_wy - w_current->first_wy);
     
     if (diff_x >= diff_y) {
-      w_current->last_y = w_current->start_y;
+      w_current->second_wy = w_current->first_wy;
     } else {
-      w_current->last_x = w_current->start_x;
+      w_current->second_wx = w_current->first_wx;
     }
   }
   
@@ -937,21 +881,27 @@ void o_line_rubberline(GSCHEM_TOPLEVEL *w_current, int x, int y)
    * function, if the line was displayed, it has been erased, updated and
    * displayed again.
    */
-  /* xor-draw the updated line */
   o_line_rubberline_xor(w_current);
+  w_current->rubber_visible = 1;
 }
 
 /*! \brief Draw line from GSCHEM_TOPLEVEL object.
  *  \par Function Description
  *  This function draws a line with an exclusive or function over the sheet.
  *  The color of the box is <B>w_current->select_color</B>. The line is
- *  described by the two points (<B>w_current->start_x</B>,
- *  <B>w_current->start_y</B>) and (<B>w_current->last_x</B>,<B>w_current->last_y</B>).
+ *  described by the two points (<B>w_current->first_wx</B>,
+ *  <B>w_current->first_wy</B>) and (<B>w_current->second_wx</B>,<B>w_current->second_wy</B>).
  *
  *  \param [in] w_current  The GSCHEM_TOPLEVEL object.
  */
 void o_line_rubberline_xor(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);
+
   /* draw the circle from the w_current variables */
   /* with xor-function */
   gdk_gc_set_foreground(w_current->xor_gc, 
@@ -960,10 +910,8 @@ void o_line_rubberline_xor(GSCHEM_TOPLEVEL *w_current)
 			     GDK_LINE_SOLID, GDK_CAP_NOT_LAST, 
 			     GDK_JOIN_MITER);
   gdk_draw_line(w_current->backingstore, w_current->xor_gc,
-		w_current->start_x, w_current->start_y,
-		w_current->last_x,  w_current->last_y);  
-  o_invalidate_rect(w_current,w_current->start_x, w_current->start_y,
-                              w_current->last_x,  w_current->last_y);
+		x1, y1, x2, y2);
+  o_invalidate_rect(w_current, x1, y1, x2, y2);
 }
 
 /*! \brief Draw grip marks on line.
diff --git a/gschem/src/x_event.c b/gschem/src/x_event.c
index 236d460..c6cc131 100644
--- a/gschem/src/x_event.c
+++ b/gschem/src/x_event.c
@@ -191,17 +191,13 @@ gint x_event_button_pressed(GtkWidget *widget, GdkEventButton *event,
         break;
 
       case(DRAWLINE):
-        o_line_start(w_current,
-                     (int) event->x,
-                     (int) event->y);
+        o_line_start(w_current, w_x, w_y);
         w_current->event_state = ENDLINE;
         w_current->inside_action = 1;
         break;
 
       case(ENDLINE):
-        o_line_end(w_current,
-                   (int) event->x,
-                   (int) event->y);
+        o_line_end(w_current, w_x, w_y);
         w_current->inside_action = 0;
         w_current->event_state = DRAWLINE;
         break;
@@ -1027,9 +1023,7 @@ gint x_event_motion(GtkWidget *widget, GdkEventMotion *event,
 
     case(ENDLINE):
     if (w_current->inside_action)
-    o_line_rubberline(w_current,
-                      (int) event->x,
-                      (int) event->y);
+      o_line_rubberline(w_current, w_x, w_y);
     break;
 
     case(ENDBOX):

commit bdcb6e63c3ed1b19f0d1d854536b0e51aad85429
Author: Werner Hoch <werner.ho@xxxxxx>
Date:   Sun Apr 6 19:10:31 2008 +0200

    switched bus rubber drawing to world coords
    
    Call all bus function with world coordinates. Added rubberbus_xor
    function to simplify code. Added some function documentations.

diff --git a/gschem/include/prototype.h b/gschem/include/prototype.h
index 0a2ec1c..0b801b6 100644
--- a/gschem/include/prototype.h
+++ b/gschem/include/prototype.h
@@ -520,6 +520,7 @@ void o_bus_draw_xor_single(GSCHEM_TOPLEVEL *w_current, int dx, int dy, int which
 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_rubberbus(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);
 /* o_circle.c */
 void o_circle_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current);
diff --git a/gschem/src/i_callbacks.c b/gschem/src/i_callbacks.c
index 17c6667..385face 100644
--- a/gschem/src/i_callbacks.c
+++ b/gschem/src/i_callbacks.c
@@ -2435,7 +2435,7 @@ DEFINE_I_CALLBACK(add_bus_hotkey)
   i_set_state(w_current, STARTDRAWBUS);
   i_update_toolbar(w_current);
 
-  o_bus_start(w_current, mouse_x, mouse_y);
+  o_bus_start(w_current, mouse_wx, mouse_wy);
 
   w_current->event_state=DRAWBUS;
   w_current->inside_action = 1;
diff --git a/gschem/src/o_bus.c b/gschem/src/o_bus.c
index 0fb48a3..69f640a 100644
--- a/gschem/src/o_bus.c
+++ b/gschem/src/o_bus.c
@@ -209,54 +209,43 @@ void o_bus_draw_xor_single(GSCHEM_TOPLEVEL *w_current,
                     sx[0] + dx1, sy[0] + dy1, sx[1] + dx2, sy[1] + dy2);
 }
 
-/*! \todo Finish function documentation!!!
- *  \brief
+/*! \brief set the start point of a new bus
  *  \par Function Description
- *
+ *  This function sets the start point (<B>w_x</B>,<B>w_y</B>) of a new bus
+ *  in the <B>GSCHEM_TOPLEVEL</B> structure.
+ *  
+ *  The start point is stored in <B>first_wx</B>, <B>first_wy</B>.
+ *  
+ *  \param [in] w_current  The GSCHEM_TOPLEVEL object.
+ *  \param [in] w_x        the x position in world coords
+ *  \param [in] w_x        the y position in world coords
  */
-void o_bus_start(GSCHEM_TOPLEVEL *w_current, int x, int y)
+void o_bus_start(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
 {
-  TOPLEVEL *toplevel = w_current->toplevel;
-  int size;
-
-  w_current->last_x = w_current->start_x = fix_x(toplevel, x);
-  w_current->last_y = w_current->start_y = fix_y(toplevel, y);
-
-  if (toplevel->bus_style == THICK ) {
-    size = SCREENabs(toplevel, BUS_WIDTH);
-    gdk_gc_set_line_attributes(w_current->xor_gc, size,
-                               GDK_LINE_SOLID,
-                               GDK_CAP_NOT_LAST,
-                               GDK_JOIN_MITER);
-  }
-
-  gdk_gc_set_foreground(w_current->xor_gc,
-			x_get_darkcolor(w_current->select_color) );
-  gdk_draw_line(w_current->backingstore, w_current->xor_gc, w_current->start_x, w_current->start_y, w_current->last_x, w_current->last_y);
-  o_invalidate_rect(w_current, w_current->start_x, w_current->start_y,
-                    w_current->last_x, w_current->last_y);
-
-  if (toplevel->bus_style == THICK ) {
-    gdk_gc_set_line_attributes(w_current->xor_gc, 0,
-                               GDK_LINE_SOLID,
-                               GDK_CAP_NOT_LAST,
-                               GDK_JOIN_MITER);
-  }
+  w_current->first_wx = w_current->second_wx = w_x;
+  w_current->first_wy = w_current->second_wy = w_y;
 }
 
-/*! \todo Finish function documentation!!!
- *  \brief
+/*! \brief finish a bus drawing action
  *  \par Function Description
+ *  This function finishes a net drawing action. The function draws
+ *  a bus from the point (<B>first_wx</B>,<B>first_wy</B>) to 
+ *  (<B>second_wx</B>,<B>second_wy</B>). Both points are taken from
+ *  the <B>GSCHEM_TOPLEVEL</B> structure.
+ *
+ *  The function returns TRUE if a bus object has been created and 
+ *  FALSE if no bus object has been created.
  *
+ *  \param [in] w_current  The GSCHEM_TOPLEVEL object.
+ *  \param [in] w_x        (unused)
+ *  \param [in] w_x        (unused)
  */
-int o_bus_end(GSCHEM_TOPLEVEL *w_current, int x, int y)
+int o_bus_end(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
 {
   TOPLEVEL *toplevel = w_current->toplevel;
-  int x1, y1;
-  int x2, y2;
   int color;
-  int size;
   GList *other_objects = NULL;
+  OBJECT *bus_new;
 
   g_assert( w_current->inside_action != 0 );
 
@@ -266,79 +255,33 @@ int o_bus_end(GSCHEM_TOPLEVEL *w_current, int x, int y)
     color = toplevel->override_bus_color;
   }
 
-  size = SCREENabs(toplevel, BUS_WIDTH);
-
-  if (toplevel->bus_style == THICK ) {
-    gdk_gc_set_line_attributes(w_current->xor_gc, size,
-                               GDK_LINE_SOLID,
-                               GDK_CAP_NOT_LAST,
-                               GDK_JOIN_MITER);
-  }
-
-  gdk_gc_set_foreground(w_current->xor_gc,
-			x_get_darkcolor(w_current->select_color) );
-  gdk_draw_line(w_current->backingstore, w_current->xor_gc,
-		w_current->start_x, w_current->start_y, 
-		w_current->last_x, w_current->last_y);
-  o_invalidate_rect(w_current, w_current->start_x, w_current->start_y,
-                    w_current->last_x, w_current->last_y);
-
-  if (toplevel->bus_style == THICK ) {
-    gdk_gc_set_line_attributes(w_current->xor_gc, 0,
-                               GDK_LINE_SOLID,
-                               GDK_CAP_NOT_LAST,
-                               GDK_JOIN_MITER);
-    gdk_gc_set_line_attributes(w_current->gc, size,
-                               GDK_LINE_SOLID,
-                               GDK_CAP_NOT_LAST,
-                               GDK_JOIN_MITER);
-  }
+  /* erase the rubberbus */
+  o_bus_rubberbus_xor(w_current);
 
   /* don't allow zero length bus */
   /* this ends the bus drawing behavior we want this? hack */
-  if ( (w_current->start_x == w_current->last_x) &&
-       (w_current->start_y == w_current->last_y) ) {
-         w_current->start_x = (-1);
-         w_current->start_y = (-1);
-         w_current->last_x = (-1);
-         w_current->last_y = (-1);
-         w_current->inside_action=0;
-	 i_set_state(w_current, STARTDRAWBUS);
-         o_bus_eraserubber(w_current);
-         return(FALSE);
-       }
-
-  gdk_gc_set_foreground(w_current->gc,
-			x_get_color(color));
-  gdk_draw_line(w_current->backingstore, w_current->gc, w_current->start_x, w_current->start_y, w_current->last_x, w_current->last_y);
-  o_invalidate_rect(w_current, w_current->start_x, w_current->start_y,
-                    w_current->last_x, w_current->last_y);
-
-  if (toplevel->bus_style == THICK ) {
-    gdk_gc_set_line_attributes(w_current->gc, 0,
-                               GDK_LINE_SOLID,
-                               GDK_CAP_NOT_LAST,
-                               GDK_JOIN_MITER);
+  if ( (w_current->first_wx == w_current->second_wx) &&
+       (w_current->first_wy == w_current->second_wy) ) {
+    w_current->first_wx = -1;
+    w_current->first_wy = -1;
+    w_current->second_wx = -1;
+    w_current->second_wy = -1;
+    w_current->inside_action=0;
+    i_set_state(w_current, STARTDRAWBUS);
+    return FALSE;
   }
 
-  SCREENtoWORLD(toplevel, w_current->start_x, w_current->start_y, &x1, &y1);
-  SCREENtoWORLD(toplevel, w_current->last_x, w_current->last_y, &x2, &y2);
-  x1 = snap_grid(toplevel, x1);
-  y1 = snap_grid(toplevel, y1);
-  x2 = snap_grid(toplevel, x2);
-  y2 = snap_grid(toplevel, y2);
+  /* create a new bus object and draw it */
+  bus_new = toplevel->page_current->object_tail =
+    o_bus_add(toplevel,
+	      toplevel->page_current->object_tail,
+	      OBJ_BUS, color,
+	      w_current->first_wx, w_current->first_wy, 
+	      w_current->second_wx, w_current->second_wy, 0);
 
-  w_current->save_x = w_current->last_x;
-  w_current->save_y = w_current->last_y;
+  o_bus_draw(w_current, bus_new);
 
-  toplevel->page_current->object_tail =
-  o_bus_add(toplevel,
-            toplevel->page_current->object_tail,
-            OBJ_BUS,
-            color,
-            x1, y1, x2, y2, 0);
-
-  /* conn stuff */
+  /* connect the new bus to the  stuff */
   other_objects = s_conn_return_others(other_objects,
                                        toplevel->page_current->
                                        object_tail);
@@ -348,89 +291,78 @@ int o_bus_end(GSCHEM_TOPLEVEL *w_current, int x, int y)
   o_cue_draw_single(w_current, toplevel->page_current->object_tail);
 
   toplevel->page_current->CHANGED=1;
-  w_current->start_x = w_current->save_x;
-  w_current->start_y = w_current->save_y;
+  w_current->first_wx = w_current->second_wx;
+  w_current->first_wy = w_current->second_wy;
   o_undo_savestate(w_current, UNDO_ALL);
-  return(TRUE);
+  return TRUE;
 }
 
-/*! \todo Finish function documentation!!!
- *  \brief
+/*! \brief draw the bus rubber when creating a bus
  *  \par Function Description
+ *  This function draws
+ *  a bus rubber from the point (<B>first_wx</B>,<B>first_wy</B>) from  
+ *  the <B>GSCHEM_TOPLEVEL</B> structure to the input parameter
+ *  (<B>w_x</B>, <B>w_y</B>).
  *
+ *  The function stores creates an non-orthogonal bus segment if the 
+ *  CONTROLKEY is pressed. The coordinates of the second rubberbus point
+ *  is stored as (<B>second_wx</B>,<B>second_wy</B>) in the 
+ *  <B>GSCHEM_TOPLEVEL</B> structure.
+ *
+ *  \param [in] w_current  The GSCHEM_TOPLEVEL object.
+ *  \param [in] w_x        current x position in world units
+ *  \param [in] w_y        current y position in world units
  */
-void o_bus_rubberbus(GSCHEM_TOPLEVEL *w_current, int x, int y)
+void o_bus_rubberbus(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
 {
-  TOPLEVEL *toplevel = w_current->toplevel;
   int diff_x, diff_y;
-  int size;
 
   g_assert( w_current->inside_action != 0 );
 
-  if (toplevel->bus_style == THICK ) {
-    size = SCREENabs(toplevel, BUS_WIDTH);
-    gdk_gc_set_line_attributes(w_current->xor_gc, size,
-                               GDK_LINE_SOLID,
-                               GDK_CAP_NOT_LAST,
-                               GDK_JOIN_MITER);
-  }
-
-  gdk_gc_set_foreground(w_current->xor_gc, 
-			x_get_darkcolor(w_current->select_color) );
-  gdk_draw_line(w_current->backingstore, w_current->xor_gc, w_current->start_x, w_current->start_y, w_current->last_x, w_current->last_y);
-  o_invalidate_rect(w_current, w_current->start_x, w_current->start_y,
-                    w_current->last_x, w_current->last_y);
-
-  /* going into ortho mode (control key not pressed) */
-  /* erase non-ortho line */
+  if (w_current->rubber_visible)
+    o_bus_rubberbus_xor(w_current);
 
-  /* going into non-ortho mode (control key pressed) */
-  /* erase ortho line */
-
-  w_current->last_x = fix_x(toplevel, x);
-  w_current->last_y = fix_y(toplevel, y);
+  w_current->second_wx = w_x;
+  w_current->second_wy = w_y;
 
   /* If you press the control key then you can draw non-ortho bus */
   if (!w_current->CONTROLKEY) {
-    diff_x = abs(w_current->last_x - w_current->start_x);
-    diff_y = abs(w_current->last_y - w_current->start_y);
+    diff_x = abs(w_current->second_wx - w_current->first_wx);
+    diff_y = abs(w_current->second_wy - w_current->first_wy);
 
     if (diff_x >= diff_y) {
-      w_current->last_y = w_current->start_y;
+      w_current->second_wy = w_current->first_wy;
     } else {
-      w_current->last_x = w_current->start_x;
+      w_current->second_wx = w_current->first_wx;
     }
   }
 
-  gdk_gc_set_foreground(w_current->xor_gc,
-			x_get_darkcolor(w_current->select_color) );
-  gdk_draw_line(w_current->backingstore, w_current->xor_gc, w_current->start_x, w_current->start_y, w_current->last_x, w_current->last_y);
-  o_invalidate_rect(w_current, w_current->start_x, w_current->start_y,
-                    w_current->last_x, w_current->last_y);
-
-  if (toplevel->bus_style == THICK ) {
-    gdk_gc_set_line_attributes(w_current->xor_gc, 0,
-                               GDK_LINE_SOLID,
-                               GDK_CAP_NOT_LAST,
-                               GDK_JOIN_MITER);
-  }
+  o_bus_rubberbus_xor(w_current);
+  w_current->rubber_visible = 1;
 }
 
-/*! \todo Finish function documentation!!!
- *  \brief
+/*! \brief draw a rubberbus segment in XOR mode
  *  \par Function Description
+ *  This function draws a bus segment in XOR mode from the point
+ *  (<B>first_wx</B>,<B>first_wy</B>) to the point 
+ *  (<B>second_wx</B>,<B>second_wy</B>) from the <B>GSCHEM_TOPLEVEL</B>
+ *   structure.
  *
- *  \note
- *  used in button cancel code in x_events.c
+ *  The function can be used to draw or erase the rubberbus on the screen.
+ *
+ *  \param [in] w_current  The GSCHEM_TOPLEVEL object
  */
-void o_bus_eraserubber(GSCHEM_TOPLEVEL *w_current)
+void o_bus_rubberbus_xor(GSCHEM_TOPLEVEL *w_current)
 {
   TOPLEVEL *toplevel = w_current->toplevel;
-  int size;
+  int x1, y1, x2, y2, size=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 ) {
     size = SCREENabs(toplevel, BUS_WIDTH);
-
+    
     if (size < 0)
       size=0;
 
@@ -440,9 +372,11 @@ void o_bus_eraserubber(GSCHEM_TOPLEVEL *w_current)
                                GDK_JOIN_MITER);
   }
 
-  gdk_draw_line(w_current->backingstore, w_current->xor_gc, w_current->start_x, w_current->start_y, w_current->last_x, w_current->last_y);
-  o_invalidate_rect(w_current, w_current->start_x, w_current->start_y,
-                    w_current->last_x, w_current->last_y);
+  gdk_draw_line(w_current->backingstore, 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,
@@ -451,3 +385,15 @@ void o_bus_eraserubber(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/x_event.c b/gschem/src/x_event.c
index 4815430..236d460 100644
--- a/gschem/src/x_event.c
+++ b/gschem/src/x_event.c
@@ -282,9 +282,7 @@ gint x_event_button_pressed(GtkWidget *widget, GdkEventButton *event,
         break;
 
       case(STARTDRAWBUS):  
-        o_bus_start(w_current,
-                    (int) event->x,
-                    (int) event->y);
+        o_bus_start(w_current, w_x, w_y);
         w_current->inside_action = 1;
         w_current->event_state=DRAWBUS;
 
@@ -308,11 +306,8 @@ gint x_event_button_pressed(GtkWidget *widget, GdkEventButton *event,
       case(DRAWBUS):
       case(BUSCONT):
         /* Only continue the net if net end worked */
-        if (o_bus_end(w_current, (int) event->x,
-                      (int) event->y)) {
-          o_bus_start(w_current,
-                      (int) w_current->save_x,
-                      (int) w_current->save_y);
+        if (o_bus_end(w_current, w_x, w_y)) {
+	  o_bus_start(w_current, w_current->first_wx, w_current->first_wy);
           w_current->event_state=BUSCONT;
         }
         break;
@@ -1075,9 +1070,7 @@ gint x_event_motion(GtkWidget *widget, GdkEventMotion *event,
     case(DRAWBUS):
     case(BUSCONT):
     if (w_current->inside_action)
-    o_bus_rubberbus(w_current,
-                    (int) event->x,
-                    (int) event->y);
+      o_bus_rubberbus(w_current, w_x, w_y);
     break;
 
     case(ENDPIN):

commit 87aeb1ee33995af7645aa4d72265254d217f62ef
Author: Werner Hoch <werner.ho@xxxxxx>
Date:   Sun Apr 6 17:29:40 2008 +0200

    switched arc rubber drawing and manipulation to world coords
    
    Call all arc function with world coords. Removed obsolete loc_x/y
    variables. Removed unused functions o_arc_end2 and o_arc_end3.

diff --git a/gschem/include/gschem_struct.h b/gschem/include/gschem_struct.h
index 408bf77..74676a2 100644
--- a/gschem/include/gschem_struct.h
+++ b/gschem/include/gschem_struct.h
@@ -96,7 +96,6 @@ struct st_gschem_toplevel {
   int first_wx, first_wy;
   int second_wx, second_wy;
   int third_wx, third_wy;
-  int loc_x, loc_y;
   int magnetic_wx, magnetic_wy;         /* Position of the magnetic marker*/
   int distance;
   int inside_action;                    /* Are we doing an action? */
diff --git a/gschem/include/prototype.h b/gschem/include/prototype.h
index b320e11..0a2ec1c 100644
--- a/gschem/include/prototype.h
+++ b/gschem/include/prototype.h
@@ -460,8 +460,6 @@ void o_arc_eraserubber(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);
-void o_arc_end2(GSCHEM_TOPLEVEL *w_current, int x, int y);
-void o_arc_end3(GSCHEM_TOPLEVEL *w_current, int x, int y);
 void o_arc_end4(GSCHEM_TOPLEVEL *w_current, int start_angle, int end_angle);
 void o_arc_rubberarc(GSCHEM_TOPLEVEL *w_current, int x, int y, int whichone);
 void o_arc_rubberarc_xor(GSCHEM_TOPLEVEL *w_current);
diff --git a/gschem/src/a_pan.c b/gschem/src/a_pan.c
index c32c794..c076479 100644
--- a/gschem/src/a_pan.c
+++ b/gschem/src/a_pan.c
@@ -73,7 +73,7 @@ void a_pan_general(GSCHEM_TOPLEVEL *w_current, double world_cx, double world_cy,
      this will be the same as w_current->page_current->to_screen_x/y_constant*/
   int zoom_max = 5;	
   int start_x, start_y, last_x, last_y, second_x, second_y;
-  int loc_x, loc_y, save_x, save_y;
+  int save_x, save_y;
   int diff;
   double zx, zy, zoom_old, zoom_new, zoom_min;
 
@@ -119,8 +119,6 @@ void a_pan_general(GSCHEM_TOPLEVEL *w_current, double world_cx, double world_cy,
                                         &last_x,             &last_y);
     SCREENtoWORLD(toplevel, w_current->second_x, w_current->second_y,
                                       &second_x,           &second_y);
-    SCREENtoWORLD(toplevel,    w_current->loc_x,    w_current->loc_y,
-                                         &loc_x,              &loc_y);
     SCREENtoWORLD(toplevel,   w_current->save_x,   w_current->save_y,
                                         &save_x,             &save_y);
     start_x = snap_grid(toplevel, start_x);
@@ -212,8 +210,6 @@ void a_pan_general(GSCHEM_TOPLEVEL *w_current, double world_cx, double world_cy,
                     &w_current->last_x,   &w_current->last_y);
     WORLDtoSCREEN(toplevel,   second_x,             second_y,
                   &w_current->second_x, &w_current->second_y);
-    WORLDtoSCREEN(toplevel,      loc_x,                loc_y,
-                     &w_current->loc_x,    &w_current->loc_y);
     WORLDtoSCREEN(toplevel,     save_x,               save_y,
                     &w_current->save_x,   &w_current->save_y);
   }
diff --git a/gschem/src/gschem_toplevel.c b/gschem/src/gschem_toplevel.c
index a5c4c52..2e954ba 100644
--- a/gschem/src/gschem_toplevel.c
+++ b/gschem/src/gschem_toplevel.c
@@ -120,8 +120,6 @@ GSCHEM_TOPLEVEL *gschem_toplevel_new ()
   w_current->first_wx = w_current->first_wy = -1;
   w_current->second_wx = w_current->second_wy = -1;
   w_current->third_wx = w_current->third_wy = -1;
-  w_current->loc_x = -1;
-  w_current->loc_y = -1;
   w_current->distance = 0;
   w_current->magnetic_wx = -1;
   w_current->magnetic_wy = -1;
diff --git a/gschem/src/i_callbacks.c b/gschem/src/i_callbacks.c
index 5caec36..17c6667 100644
--- a/gschem/src/i_callbacks.c
+++ b/gschem/src/i_callbacks.c
@@ -2691,7 +2691,7 @@ DEFINE_I_CALLBACK(add_arc_hotkey)
 
   i_update_middle_button(w_current, i_callback_add_arc_hotkey, _("Arc"));
 
-  o_arc_start(w_current, mouse_x, mouse_y);
+  o_arc_start(w_current, mouse_wx, mouse_wy);
 
   w_current->inside_action = 1;
   i_set_state(w_current, ENDARC);
diff --git a/gschem/src/o_arc.c b/gschem/src/o_arc.c
index 8bbc682..3edbcc0 100644
--- a/gschem/src/o_arc.c
+++ b/gschem/src/o_arc.c
@@ -879,74 +879,57 @@ void o_arc_draw_xor(GSCHEM_TOPLEVEL *w_current, int dx, int dy, OBJECT *o_curren
  *  \par Function Description
  *  This function starts the process to input a new arc. Parameters for
  *  this arc are put into/extracted from the <B>w_current</B> toplevel structure.
- *  <B>x</B> and <B>y</B> are current coordinates of the pointer in screen unit.
+ *  <B>w_x</B> and <B>w_y</B> are current coordinates of the pointer in screen unit.
  *
  *  First step of the arc input is to set the radius of the arc. The center
- *  of the arc is kept in (<B>w_current->start_x</B>,<B>w_current->start_y</B>).
- *  The other point of the radius, i.e. on the arc, in
- *  (<B>w_current->last_x</B>,<B>w_current->last_y</B>). The radius of the arc is
- *  in <B>w_current->distance</B>.
+ *  of the arc is kept in (<B>w_current->first_wx</B>,<B>w_current->first_wy</B>).
+ *  The radius of the arc is in <B>w_current->distance</B>.
  *
  *  \param [in] w_current  The GSCHEM_TOPLEVEL object.
- *  \param [in] x          Current x coordinate of pointer in screen units.
- *  \param [in] y          Current y coordinate of pointer in screen units.
+ *  \param [in] w_x        Current x coordinate of pointer in world units.
+ *  \param [in] w_y        Current y coordinate of pointer in world units.
  */
-void o_arc_start(GSCHEM_TOPLEVEL *w_current, int x, int y)
+void o_arc_start(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
 {
-  TOPLEVEL *toplevel = w_current->toplevel;
   /* set the center of the arc */
-  w_current->last_x = w_current->start_x = fix_x(toplevel, x);
-  w_current->last_y = w_current->start_y = fix_y(toplevel, y);
+  w_current->first_wx = w_x;
+  w_current->first_wy = w_y;
 
   /* set the radius */
   w_current->distance = 0;
 
   /* set the start and end angles */
-  w_current->loc_x = w_current->loc_y = 0;
+  w_current->second_wx = w_current->second_wy = 0;
 
   /* start the rubberbanding process of the radius */
   o_arc_rubberarc_xor(w_current);
-  
+  w_current->rubber_visible = 1;
 }
 
 /*! \brief End the input of an arc.
  *  \par Function Description
  *  This function ends the input of the radius of the arc.
- *  The (<B>x</B>,<B>y</B>) point is taken as the other end of the radius segment.
+ *  The (<B>w_x</B>,<B>w_y</B>) point is taken as the other end of the radius segment.
  *  The distance between this point and the center is the radius of the arc.
- *  <B>x</B> and <B>y</B> are in screen coords.
+ *  <B>w_x</B> and <B>w_y</B> are in world coords.
  *
  *  At the end of this function, the center of the arc is at
- *  (<B>w_current->start_x</B>,<B>w_current->start_y</B>) and its radius is
+ *  (<B>w_current->first_wx</B>,<B>w_current->first_wy</B>) and its radius is
  *  <B>w_current->distance</B>.
  *
  *  The two angles needs to be input to fully define the arc.
  *
  *  \param [in] w_current  The GSCHEM_TOPLEVEL object.
- *  \param [in] x          Current x coordinate of pointer in screen units.
- *  \param [in] y          Current y coordinate of pointer in screen units.
+ *  \param [in] w_x        (unused)
+ *  \param [in] w_y        (unused)
  */
-void o_arc_end1(GSCHEM_TOPLEVEL *w_current, int x, int y)
+void o_arc_end1(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
 {
-  TOPLEVEL *toplevel = w_current->toplevel;
-  int diff_x, diff_y;
-
   g_assert( w_current->inside_action != 0 );
 
   /* erases the previous temporary radius segment */
   o_arc_rubberarc_xor(w_current);
 
-  w_current->last_x = fix_x(toplevel, x);
-  w_current->last_y = fix_y(toplevel, y);
-  /* compute the radius */
-  diff_x = GET_BOX_WIDTH (w_current);
-  diff_y = GET_BOX_HEIGHT(w_current);
-  if (diff_x >= diff_y) {
-    w_current->distance = diff_x;
-  } else {
-    w_current->distance = diff_y;
-  }
-
   /* ack! zero length radius */
   if (w_current->distance == 0) {
     return;
@@ -961,130 +944,6 @@ void o_arc_end1(GSCHEM_TOPLEVEL *w_current, int x, int y)
   
 }
 
-/*! \brief Set the start angle of a temporary arc.
- *  \par Function Description
- *  This function sets the start angle of the temporary representation of
- *  an arc. This angle is determined from the current mouse position
- *  described by <B>x</B> and <B>y</B> in screen coords, and the arc center
- *  previously set as (<B>w_current->start_x</B>,<B>w_current->start_y</B>).
- *
- *  The previous temporary arc is erased, the start angle is then updated
- *  and finally, the temporary arc is drawn again.
- *
- *  This function is used when the input of an arc is fully interactive,
- *  not through a dialog box.
- *
- *  \param [in] w_current  The GSCHEM_TOPLEVEL object.
- *  \param [in] x          Current x coordinate of pointer in screen units.
- *  \param [in] y          Current y coordinate of pointer in screen units.
- */
-void o_arc_end2(GSCHEM_TOPLEVEL *w_current, int x, int y)
-{
-  double dx, dy, d, cos_a_, sin_a_, a;
-  
-  /* erase the previous temporary arc */
-  o_arc_rubberarc_xor(w_current);
-
-  /* compute the start angle */
-  dx =   ((double) x) - ((double) w_current->start_x);
-  dy = - ((double) y) + ((double) w_current->start_y);
-  d  = sqrt((dx * dx) + (dy * dy));
-
-  sin_a_ = dy / ((double) d);
-  cos_a_ = dx / ((double) d);
-  a = asin(sin_a_) * 180 / M_PI;
-  if(a < 0) a *= -1;
-
-  /* find the right quadrant */
-  if(sin_a_ >= 0) {
-    if(cos_a_ >= 0) a = a;
-    else            a = 180 - a;
-  } else {
-    if(cos_a_ >= 0) a = 360 - a;
-    else            a = 180 + a;
-  }
-
-  /* start angle in degree is in a */
-  w_current->loc_x = (int) a;
-
-  /* draw the new temporary arc */
-  o_arc_rubberarc_xor(w_current);
-	
-}
-
-/*! \brief Set the end angle during the input of a new arc object.
- *  \par Function Description
- *  This function sets the end angle during the input of a new arc object.
- *  The angle is computed from the current mouse position in <B>x</B> and
- *  <B>y</B> and the center of the arc. The arc is internally represented
- *  with its center in (<B>w_current->start_x</B>,<B>w_current->start_y</B>),
- *  its radius in <B>w_current->distance</B> and its start angle in
- *  <B>w_current->loc_x</B>.
- *
- *  The temporary arc is erased, a new object is initialized and drawn.
- *
- *  This function is used when the input of an arc is fully interactive,
- *  i.e. not through a dialog box.
- *
- *  \param [in] w_current  The GSCHEM_TOPLEVEL object.
- *  \param [in] x          Current x coordinate of pointer in screen units.
- *  \param [in] y          Current x coordinate of pointer in screen units.
- */
-void o_arc_end3(GSCHEM_TOPLEVEL *w_current, int x, int y)
-{
-  TOPLEVEL *toplevel = w_current->toplevel;
-  double d, dx, dy, cos_a_, sin_a_, a;
-  
-  /* erase the previous temporary arc */
-  o_arc_rubberarc_xor(w_current);
-
-  /* compute the end angle */
-  dx =   ((double) x) - ((double) w_current->start_x);
-  dy = - ((double) y) + ((double) w_current->start_y);
-  d  = sqrt((dx * dx) + (dy * dy));
-
-  sin_a_ = dy / ((double) d);
-  cos_a_ = dx / ((double) d);
-  a = asin(sin_a_) * 180 / M_PI;
-  if(a < 0) a *= -1;
-
-  /* find the right quadrant */
-  if(sin_a_ >= 0) {
-    if(cos_a_ >= 0) a = a;
-    else            a = 180 - a;
-  } else {
-    if(cos_a_ >= 0) a = 360 - a;
-    else            a = 180 + a;
-  }
-
-  /* end angle in degree is in a */
-  w_current->loc_y = (int) a;
-
-  /* create, initialize and link the new arc object */
-  toplevel->page_current->object_tail =
-    o_arc_add(toplevel, toplevel->page_current->object_tail,
-	      OBJ_ARC, w_current->graphic_color,
-	      w_current->start_x, w_current->start_y,
-	      w_current->distance,
-	      w_current->loc_x, w_current->loc_y);
-
-  /* draw the new object */
-  o_redraw_single(w_current, toplevel->page_current->object_tail);
-
-  w_current->start_x  = (-1);
-  w_current->start_y  = (-1);
-  w_current->last_x   = (-1);
-  w_current->last_y   = (-1);
-  w_current->loc_x    = -1;
-  w_current->loc_y    = -1;
-  w_current->distance = -1;
-
-  toplevel->page_current->CHANGED = 1;
-  
-  o_undo_savestate(w_current, UNDO_ALL);
-	
-}
-
 /*! \brief Ends the process of arc input.
  *  \par Function Description
  *  The #o_arc_end4() function ends the process of the input of an arc.
@@ -1100,38 +959,24 @@ void o_arc_end3(GSCHEM_TOPLEVEL *w_current, int x, int y)
 void o_arc_end4(GSCHEM_TOPLEVEL *w_current, int start_angle, int end_angle)
 {
   TOPLEVEL *toplevel = w_current->toplevel;
-  int x1, y1;
-  int radius;
-
-  /* get the center in world coords */
-  SCREENtoWORLD(toplevel,
-		w_current->start_x, w_current->start_y,
-		&x1, &y1);
-
-  /* get the radius in world coords */
-  radius = snap_grid(toplevel, WORLDabs(toplevel, w_current->distance));
 
   /* create, initialize and link the new arc object */
   toplevel->page_current->object_tail =
     o_arc_add(toplevel, toplevel->page_current->object_tail,
 	      OBJ_ARC, w_current->graphic_color,
-	      x1, y1, radius, start_angle, end_angle);
+	      w_current->first_wx, w_current->first_wy,
+	      w_current->distance, start_angle, end_angle);
 
   /* draw the new object */
   o_redraw_single(w_current, toplevel->page_current->object_tail);
 
-  w_current->start_x  = (-1);
-  w_current->start_y  = (-1);
-  w_current->last_x   = (-1);
-  w_current->last_y   = (-1);
-  w_current->loc_x    = -1;
-  w_current->loc_y    = -1;
-  w_current->distance = -1;
+  w_current->first_wx  = -1;
+  w_current->first_wy  = -1;
+  w_current->distance = 0;
 
   toplevel->page_current->CHANGED = 1;
   
   o_undo_savestate(w_current, UNDO_ALL);
-	
 }
 
 /*! \brief Draw an arc using one angle modification.
@@ -1146,16 +991,16 @@ void o_arc_end4(GSCHEM_TOPLEVEL *w_current, int start_angle, int end_angle)
  *
  *  The arc is internally described by :
  *  <DL>
- *    <DT>*</DT><DD>(<B>w_current->start_x</B>,<B>w_current->start_y</B>) as
+ *    <DT>*</DT><DD>(<B>w_current->first_wx</B>,<B>w_current->first_wy</B>) as
  *                   its center.
  *    <DT>*</DT><DD><B>w_current->distance</B> as its radius.
- *    <DT>*</DT><DD><B>w_current->loc_x</B> and <B>w_current->loc_y</B> as its
+ *    <DT>*</DT><DD><B>w_current->second_wx</B> and <B>w_current->second_wx</B> as its
  *                  start and end angle respectively.
  *  </DL>
  *
  *  \param [in] w_current  The GSCHEM_TOPLEVEL object.
- *  \param [in] x          Current x coordinate of pointer in screen units.
- *  \param [in] y          Current y coordinate of pointer in screen units.
+ *  \param [in] w_x        Current x coordinate of pointer in world units.
+ *  \param [in] w_y        Current y coordinate of pointer in world units.
  *  \param [in] whichone   Which angle to change.
  *
  *  <B>whichone</B> can have one of the following values:
@@ -1164,49 +1009,38 @@ void o_arc_end4(GSCHEM_TOPLEVEL *w_current, int start_angle, int end_angle)
  *    <DT>*</DT><DD>ARC_END_ANGLE
  *  </DL>
  */
-void o_arc_rubberarc(GSCHEM_TOPLEVEL *w_current, int x, int y, int whichone)
+void o_arc_rubberarc(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y, int whichone)
 {
-  TOPLEVEL *toplevel = w_current->toplevel;
-  double  dx, dy, a;
-  int diff_x, diff_y;
+  int diff_x, diff_y, angle_deg;
 
   /* erase the previous temporary arc */
-  o_arc_rubberarc_xor(w_current);
+  if (w_current->rubber_visible)
+    o_arc_rubberarc_xor(w_current);
 
   if(whichone == ARC_RADIUS) {
-
     /*
      * The radius is taken as the biggest distance on the x and y
      * axis between the center of the arc and the mouse position.
      */		
-    /* update the radius */
-    w_current->last_x = fix_x(toplevel, x);
-    w_current->last_y = fix_y(toplevel, y);
-
-    diff_x = GET_BOX_WIDTH (w_current);
-    diff_y = GET_BOX_HEIGHT(w_current);
-    if (diff_x >= diff_y) {
-      w_current->distance = diff_x;
-    } else {
-      w_current->distance = diff_y;
-    }
-
+    diff_x = abs(w_current->first_wx - w_x);
+    diff_y = abs(w_current->first_wy - w_y);
+    w_current->distance = max(diff_x, diff_y);
   }
   else if((whichone == ARC_START_ANGLE) || (whichone == ARC_END_ANGLE)) {
 		
     /* compute the angle */
-    dx =   ((double) x) - ((double) w_current->start_x);
-    dy = - ((double) y) + ((double) w_current->start_y);
-    a = atan2(dy,dx) * 180 / M_PI;
+    diff_x = w_current->first_wx - w_x;
+    diff_y = w_current->first_wy - w_y;
+    angle_deg = atan2(diff_y, diff_x) * 180 / M_PI;
 
     /* set the start or end angle with this angle */
     switch(whichone) {
     case ARC_START_ANGLE:
-      w_current->loc_x = ((int) a + 360) % 360;
+      w_current->second_wx = (angle_deg + 360 + 180) % 360;
       break;
 	
     case ARC_END_ANGLE:
-      w_current->loc_y = ((int) a - w_current->loc_x + 720) % 360;
+      w_current->second_wy = (angle_deg - w_current->second_wx + 720 + 180) % 360;
       break;
 	
     default:
@@ -1217,17 +1051,17 @@ void o_arc_rubberarc(GSCHEM_TOPLEVEL *w_current, int x, int y, int whichone)
 	
   /* draw the new temporary arc */
   o_arc_rubberarc_xor(w_current);
-
+  w_current->rubber_visible = 1;
 }
 
 /*! \brief Draw arc from GSCHEM_TOPLEVEL object.
  *  \par Function Description
  *  This function draws the arc from the variables in the GSCHEM_TOPLEVEL
  *  structure <B>*w_current</B>.
- *  The center of the arc is at (<B>w_current->start_x</B>,
- *  <B>w_current->start_y</B>), its radius equal to <B>w_current->radius</B>,
- *  and the start and end angle are given by <B>w_current->loc_x</B> and
- *  <B>w_current->loc_y</B>.
+ *  The center of the arc is at (<B>w_current->first_wx</B>,
+ *  <B>w_current->first_wy</B>), its radius equal to <B>w_current->distance</B>,
+ *  and the start and end angle are given by <B>w_current->second_wx</B> and
+ *  <B>w_current->second_wy</B>.
  *
  *  The arc is drawn with a xor function over the current sheet with the
  *  selection color.
@@ -1236,38 +1070,42 @@ void o_arc_rubberarc(GSCHEM_TOPLEVEL *w_current, int x, int y, int whichone)
  */
 void o_arc_rubberarc_xor(GSCHEM_TOPLEVEL *w_current)
 {
-  double tmp;
-  int x1, y1;
-	
-  gdk_gc_set_foreground(w_current->xor_gc, 
+  TOPLEVEL *toplevel = w_current->toplevel;
+
+  double rad_angle;
+  int cx, cy, x1, y1, radius;
+
+  WORLDtoSCREEN(toplevel, w_current->first_wx, w_current->first_wy, &cx, &cy);
+  radius = SCREENabs(toplevel, w_current->distance);
+  
+  gdk_gc_set_foreground(w_current->xor_gc,
 			x_get_darkcolor(w_current->select_color));
   gdk_gc_set_line_attributes(w_current->xor_gc, 0, 
 			     GDK_LINE_SOLID, GDK_CAP_NOT_LAST, 
 			     GDK_JOIN_MITER);
+
   /* draw the arc from the w_current variables */
   gdk_draw_arc(w_current->backingstore, w_current->xor_gc, FALSE,
-	       w_current->start_x - w_current->distance,
-	       w_current->start_y - w_current->distance,
-	       w_current->distance * 2,
-	       w_current->distance * 2,
-	       w_current->loc_x * 64,
-	       w_current->loc_y * 64);
+	       cx - radius, cy - radius,
+	       radius * 2, radius * 2,
+	       w_current->second_wx * 64,
+	       w_current->second_wy * 64);
+
   /* draw the radius segment from the w_current variables */
-  tmp = ((double) w_current->loc_x) * M_PI / 180;
-  x1 = w_current->start_x + w_current->distance*cos(tmp);
-  y1 = w_current->start_y - w_current->distance*sin(tmp);
+  rad_angle = ((double) w_current->second_wx) * M_PI / 180;
+  x1 = cx + radius*cos(rad_angle);
+  y1 = cy - radius*sin(rad_angle);
   gdk_draw_line(w_current->backingstore, w_current->xor_gc,
-		w_current->start_x, w_current->start_y,
-		x1, y1);
+		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, w_current->start_x - w_current->distance,
-                               w_current->start_y - w_current->distance,
-                               w_current->start_x + w_current->distance,
-                               w_current->start_y + w_current->distance);
+  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 0745702..4fef35b 100644
--- a/gschem/src/o_basic.c
+++ b/gschem/src/o_basic.c
@@ -562,7 +562,7 @@ int o_redraw_cleanstates(GSCHEM_TOPLEVEL *w_current)
       /* reset all rubberband variables and touch the select state */
       w_current->start_x = w_current->second_x = w_current->last_x = -1;
       w_current->start_y = w_current->second_y = w_current->last_y = -1;
-      w_current->loc_x = w_current->loc_y = w_current->distance = -1;
+      w_current->distance = 0;
       i_set_state(w_current, SELECT);
 
       /* from i_callback_cancel() */
diff --git a/gschem/src/o_grips.c b/gschem/src/o_grips.c
index 204ecec..aaad72c 100644
--- a/gschem/src/o_grips.c
+++ b/gschem/src/o_grips.c
@@ -602,20 +602,16 @@ int o_grips_start(GSCHEM_TOPLEVEL *w_current, int x, int y)
  *  the grip process.
  *
  *  The coordinates of the center of the arc on x- and y-axis are stored
- *  into the <B>loc_x</B> and <B>loc_y</B> fields of the GSCHEM_TOPLEVEL
+ *  into the <B>first_wx</B> and <B>first_wy</B> fields of the GSCHEM_TOPLEVEL
  *  structure in screen units.
  *
  *  The radius of the center is stored into the <B>distance</B> field of
  *  the GSCHEM_TOPLEVEL structure in screen units.
  *
  *  The two angles describing the arc on a circle are stored into the
- *  <B>start_x</B> for the starting angle and <B>start_y</B> for the ending angle.
+ *  <B>second_wx</B> for the starting angle and <B>second_wy</B> for the ending angle.
  *  These angles are expressed in degrees.
  *
- *  Depending on which grips has been selected on the arc, the
- *  corresponding variables in its original state is duplicated in
- *  <B>last_x</B> and/or <B>last_y</B> of the GSCHEM_TOPLEVEL structure.
- *
  *  \param [in]  w_current  The GSCHEM_TOPLEVEL object.
  *  \param [in]  o_current  Arc OBJECT to check.
  *  \param [in]  x          (unused)
@@ -625,7 +621,6 @@ int o_grips_start(GSCHEM_TOPLEVEL *w_current, int x, int y)
 void o_grips_start_arc(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current,
                        int x, int y, int whichone)
 {
-  TOPLEVEL *toplevel = w_current->toplevel;
   w_current->last_drawb_mode = -1;
 
   /* erase the arc before */
@@ -633,16 +628,17 @@ void o_grips_start_arc(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current,
 
   /* describe the arc with GSCHEM_TOPLEVEL variables */
   /* center */
-  WORLDtoSCREEN( toplevel, o_current->arc->x, o_current->arc->y, &w_current->start_x, &w_current->start_y );
+  w_current->first_wx = o_current->arc->x;
+  w_current->first_wy = o_current->arc->y;
   /* radius */
-  w_current->distance = SCREENabs( toplevel, o_current->arc->width / 2 );
+  w_current->distance = o_current->arc->width / 2;
   /* angles */
-  w_current->loc_x = o_current->arc->start_angle;
-  w_current->loc_y = o_current->arc->end_angle;
+  w_current->second_wx = o_current->arc->start_angle;
+  w_current->second_wy = o_current->arc->end_angle;
 
   /* draw the first temporary arc */
   o_arc_rubberarc_xor(w_current);
-
+  w_current->rubber_visible = 1;
 }
 
 /*! \brief Initialize grip motion process for a box.
@@ -891,7 +887,7 @@ void o_grips_motion(GSCHEM_TOPLEVEL *w_current, int x, int y)
   switch(object_changing->type) {
     case(OBJ_ARC):
     /* erase, update and draw an arc */
-    o_grips_motion_arc(w_current, x, y, whichone_changing);
+    o_grips_motion_arc(w_current, w_x, w_y, whichone_changing);
     break;
 
     case(OBJ_BOX):
@@ -939,18 +935,18 @@ void o_grips_motion(GSCHEM_TOPLEVEL *w_current, int x, int y)
  *  obtained.
  *
  *  If one of the end of arc grip has been moved - modifying the arc
- *  describing the arc -, the <B>w_current->start_x</B> or
- *  <B>w_current->start_y</B> are updated according to which of the grip
+ *  describing the arc -, the <B>w_current->second_wx</B> or
+ *  <B>w_current->second_wy</B> are updated according to which of the grip
  *  has been selected.
  *
  *  \param [in] w_current  The GSCHEM_TOPLEVEL object.
- *  \param [in] x          Current x coordinate of pointer in screen units.
- *  \param [in] y          Current y coordinate of pointer in screen units.
+ *  \param [in] w_x        Current x coordinate of pointer in world units.
+ *  \param [in] w_y        Current y coordinate of pointer in world units.
  *  \param [in] whichone   Which grip to start motion with.
  */
-void o_grips_motion_arc(GSCHEM_TOPLEVEL *w_current, int x, int y, int whichone)
+void o_grips_motion_arc(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y, int whichone)
 {
-  o_arc_rubberarc(w_current, x, y, whichone);
+  o_arc_rubberarc(w_current, w_x, w_y, whichone);
 }
 
 /*! \brief Modify previously selected box according to mouse position.
@@ -1374,22 +1370,22 @@ void o_grips_end_arc(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int whichone
   /* determination of the parameters to give to o_arc_modify() */
   switch(whichone) {
     case ARC_RADIUS:
-      /* convert the radius in world coords */
-      arg1 = WORLDabs(toplevel, w_current->distance);
+      /* get the radius from w_current */
+      arg1 = w_current->distance;
       /* second parameter is not used */
       arg2 = -1;
       break;
 
     case ARC_START_ANGLE:
       /* get the start angle from w_current */
-      arg1 = w_current->loc_x;
+      arg1 = w_current->second_wx;
       /* second parameter is not used */
       arg2 = -1;
       break;
 
     case ARC_END_ANGLE:
       /* get the end angle from w_current */
-      arg1 = w_current->loc_y;
+      arg1 = w_current->second_wy;
       /* second parameter is not used */
       arg2 = -1;
       break;
diff --git a/gschem/src/x_event.c b/gschem/src/x_event.c
index 142e0f3..4815430 100644
--- a/gschem/src/x_event.c
+++ b/gschem/src/x_event.c
@@ -247,17 +247,13 @@ gint x_event_button_pressed(GtkWidget *widget, GdkEventButton *event,
         break;
 
       case(DRAWARC):
-        o_arc_start(w_current,
-                    (int) event->x,
-                    (int) event->y);
+        o_arc_start(w_current, w_x, w_y);
         w_current->event_state = ENDARC;
         w_current->inside_action = 1;
         break;
 
       case(ENDARC):
-        o_arc_end1(w_current,
-                   (int) event->x,
-                   (int) event->y);
+        o_arc_end1(w_current, w_x, w_y);
         w_current->inside_action = 0;
         w_current->event_state = DRAWARC;
         break;
@@ -1060,10 +1056,7 @@ gint x_event_motion(GtkWidget *widget, GdkEventMotion *event,
 
     case(ENDARC):
     if (w_current->inside_action)
-	/* pb20011022 - changed name to _rubberarc() and added a parameter */
-    o_arc_rubberarc(w_current,
-					(int) event->x,
-					(int) event->y, ARC_RADIUS);
+      o_arc_rubberarc(w_current, w_x, w_y, ARC_RADIUS);
     break;
 
 

commit 0720815ae4594ae3a73ca96d6392ae35c2172e4a
Author: Werner Hoch <werner.ho@xxxxxx>
Date:   Sun Apr 6 15:03:22 2008 +0200

    switched circle rubber drawing and manipulation to world coords
    
    Call all cirle functions in world coords. Use rubber_visible variable
    to protect the drawing code from erasing errors.

diff --git a/gschem/src/a_pan.c b/gschem/src/a_pan.c
index c684bb9..c32c794 100644
--- a/gschem/src/a_pan.c
+++ b/gschem/src/a_pan.c
@@ -74,7 +74,6 @@ void a_pan_general(GSCHEM_TOPLEVEL *w_current, double world_cx, double world_cy,
   int zoom_max = 5;	
   int start_x, start_y, last_x, last_y, second_x, second_y;
   int loc_x, loc_y, save_x, save_y;
-  int distance = 0; /* Initialise to quiet compiler warning */
   int diff;
   double zx, zy, zoom_old, zoom_new, zoom_min;
 
@@ -124,7 +123,6 @@ void a_pan_general(GSCHEM_TOPLEVEL *w_current, double world_cx, double world_cy,
                                          &loc_x,              &loc_y);
     SCREENtoWORLD(toplevel,   w_current->save_x,   w_current->save_y,
                                         &save_x,             &save_y);
-    distance = WORLDabs(toplevel, w_current->distance);
     start_x = snap_grid(toplevel, start_x);
     start_y = snap_grid(toplevel, start_y);
   }
@@ -218,7 +216,6 @@ void a_pan_general(GSCHEM_TOPLEVEL *w_current, double world_cx, double world_cy,
                      &w_current->loc_x,    &w_current->loc_y);
     WORLDtoSCREEN(toplevel,     save_x,               save_y,
                     &w_current->save_x,   &w_current->save_y);
-    w_current->distance = SCREENabs(toplevel, distance);
   }
 
   /* redraw */
diff --git a/gschem/src/gschem_toplevel.c b/gschem/src/gschem_toplevel.c
index 82f0347..a5c4c52 100644
--- a/gschem/src/gschem_toplevel.c
+++ b/gschem/src/gschem_toplevel.c
@@ -122,7 +122,7 @@ GSCHEM_TOPLEVEL *gschem_toplevel_new ()
   w_current->third_wx = w_current->third_wy = -1;
   w_current->loc_x = -1;
   w_current->loc_y = -1;
-  w_current->distance = -1;
+  w_current->distance = 0;
   w_current->magnetic_wx = -1;
   w_current->magnetic_wy = -1;
   w_current->inside_action = 0;
diff --git a/gschem/src/i_callbacks.c b/gschem/src/i_callbacks.c
index 3f196e8..5caec36 100644
--- a/gschem/src/i_callbacks.c
+++ b/gschem/src/i_callbacks.c
@@ -2650,7 +2650,7 @@ DEFINE_I_CALLBACK(add_circle_hotkey)
   i_update_middle_button(w_current, i_callback_add_circle_hotkey,
                          _("Circle"));
 
-  o_circle_start(w_current, mouse_x, mouse_y);
+  o_circle_start(w_current, mouse_wx, mouse_wy);
 
   w_current->inside_action = 1;
   i_set_state(w_current, ENDCIRCLE);
diff --git a/gschem/src/o_circle.c b/gschem/src/o_circle.c
index 996af59..dc020a8 100644
--- a/gschem/src/o_circle.c
+++ b/gschem/src/o_circle.c
@@ -31,11 +31,6 @@
 #include <dmalloc.h>
 #endif
 
-/* Kazu on July 16, 1999 - Added these macros to simplify the code */
-#define GET_BOX_WIDTH(w)			\
-	abs((w)->last_x - (w)->start_x)
-#define GET_BOX_HEIGHT(w)			\
-	abs((w)->last_y - (w)->start_y)
 
 typedef void (*DRAW_FUNC)( GdkDrawable *w, GdkGC *gc, GdkColor *color,
                            GdkCapStyle cap, gint x, gint y, gint radius,
@@ -571,104 +566,80 @@ void o_circle_draw_xor(GSCHEM_TOPLEVEL *w_current, int dx, int dy, OBJECT *o_cur
  *  This function starts the process to input a new circle. Parameters for
  *  this circle are pu into/extracted from the <B>w_current</B> toplevel
  *  structure.
- *  <B>x</B> and <B>y</B> are current coordinates of the mouse pointer in
- *  screen units.
+ *  <B>w_x</B> and <B>w_y</B> are current coordinates of the mouse pointer in
+ *  world units.
  *
  *  The first step of the circle input is to set the center of the arc.
- *  This center is kept in (<B>w_current->start_x</B>,<B>w_current->start_y</B>). 
+ *  This center is kept in (<B>w_current->first_wx</B>,<B>w_current->first_wy</B>). 
  *
  *  \param [in] w_current  The GSCHEM_TOPLEVEL object.
- *  \param [in] x          Current x coordinate of pointer in screen units.
- *  \param [in] y          Current y coordinate of pointer in screen units.
+ *  \param [in] w_x        Current x coordinate of pointer in world units.
+ *  \param [in] w_y        Current y coordinate of pointer in world units.
  */
-void o_circle_start(GSCHEM_TOPLEVEL *w_current, int x, int y)
+void o_circle_start(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
 {
-  TOPLEVEL *toplevel = w_current->toplevel;
-	/* center of circle */
-	w_current->last_x = w_current->start_x = fix_x(toplevel, x);
-	w_current->last_y = w_current->start_y = fix_y(toplevel, y);
-	/* radius */
-	w_current->distance = 0;
+  /* center of circle */
+  w_current->first_wx = w_x;
+  w_current->first_wy = w_y;
 
-	/* first temporary circle */
-	o_circle_rubbercircle_xor(w_current);
+  /* radius */
+  w_current->distance = 0;
 
+  /* first temporary circle */
+  o_circle_rubbercircle_xor(w_current);
+  w_current->rubber_visible = 1;
 }
 
 /*! \brief End the input of a circle.
  *  \par Function Description
  *  This function ends the input of the radius of the circle.
- *  The (<B>x</B>,<B>y</B>) point is taken as the other end of the radius
+ *  The (<B>w_x</B>,<B>w_y</B>) point is taken as the other end of the radius
  *  segment, i.e. on the circle. The distance between this point and the
  *  center is the radius of the circle.
- *  <B>x</B> and <B>y</B> are in screen coords.
+ *  <B>w_x</B> and <B>w_y</B> are in world coords.
  *
  *  The center has previously been input and saved as
- *  (<B>w_current->start_x</B>,<B>w_current->start_y</B>).
+ *  (<B>w_current->first_wx</B>,<B>w_current->first_wy</B>).
  *
  *  The temporary circle drawn during the input of the radius is erased.
  *  A new object is allocated, initialized and linked in the object list.
  *  This new object is finally drawn.
  *
  *  \param [in] w_current  The GSCHEM_TOPLEVEL object.
- *  \param [in] x          Current x coordinate of pointer in screen units.
- *  \param [in] y          Current y coordinate of pointer in screen units.
+ *  \param [in] w_x        (unused)
+ *  \param [in] w_y        (unused)
  */
-void o_circle_end(GSCHEM_TOPLEVEL *w_current, int x, int y)
+void o_circle_end(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
 {
   TOPLEVEL *toplevel = w_current->toplevel;
-  int center_x, center_y;
-  int fx, fy;
-  int radius;
 
   g_assert( w_current->inside_action != 0 );
 
   /* erase the temporary circle */
   o_circle_rubbercircle_xor(w_current);
   
-  /* get the last coords of the pointer */
-  fx = fix_x(toplevel, x);
-  fy = fix_y(toplevel, y);
-  /* compute the radius in screen unit */
-  w_current->distance = dist(w_current->start_x, w_current->start_y,
-                             fx, fy);
-
   /* circle with null radius are not allowed */
   if (w_current->distance == 0) {
     /* cancel the object creation */
-    w_current->start_x  = -1;
-    w_current->start_y  = -1;
-    w_current->last_x   = -1;
-    w_current->last_y   = -1;
-    w_current->distance = -1;
+    w_current->first_wx  = -1;
+    w_current->first_wy  = -1;
     return;
   }
 
-  /* get center coords in world unit */
-  SCREENtoWORLD(toplevel,
-                w_current->start_x, w_current->start_y,
-                &center_x, &center_y);
-  /* get radius in world unit */
-  radius = snap_grid(toplevel,
-                     WORLDabs(toplevel, w_current->distance));
-
   /* create the object */
   toplevel->page_current->object_tail =
-  o_circle_add(toplevel,
-               toplevel->page_current->object_tail,
-               OBJ_CIRCLE, w_current->graphic_color,
-               center_x, center_y, radius);
+    o_circle_add(toplevel,
+		 toplevel->page_current->object_tail,
+		 OBJ_CIRCLE, w_current->graphic_color,
+		 w_current->first_wx, w_current->first_wy, 
+		 w_current->distance);
 
   /* draw it */
   o_redraw_single(w_current, toplevel->page_current->object_tail);
   
-  w_current->start_x = (-1);
-  w_current->start_y = (-1);
-  w_current->last_x  = (-1);
-  w_current->last_y  = (-1);
-  w_current->loc_x   = (-1);
-  w_current->loc_y   = (-1);
-  w_current->distance = (-1);
+  w_current->first_wx = -1;
+  w_current->first_wy = -1;
+  w_current->distance = 0;
   
   toplevel->page_current->CHANGED = 1;
 
@@ -679,7 +650,7 @@ void o_circle_end(GSCHEM_TOPLEVEL *w_current, int x, int y)
  *  \par Function Description
  *  This function draws a circle according to its internal representation and
  *  allows the modification of its radius. The radius is updated according to
- *  the current mouse position in <B>x</B> and <B>y</B>.
+ *  the current mouse position in <B>w_x</B> and <B>w_y</B>.
  *  It draws a full circle and the horizontal segment of the radius in the
  *  right half of the circle.
  *
@@ -688,54 +659,44 @@ void o_circle_end(GSCHEM_TOPLEVEL *w_current, int x, int y)
  *
  *  The arc is internally described by :
  *  <DL>
- *    <DT>*</DT><DD>(<B>w_current->start_x</B>,<B>w_current->start_y</B>) as its
+ *    <DT>*</DT><DD>(<B>w_current->first_wx</B>,<B>w_current->first_wy</B>) as its
  *                   center ;
  *    <DT>*</DT><DD><B>w_current->distance</B> as its radius.
  *  </DL>
  *
  *  \param [in] w_current  The GSCHEM_TOPLEVEL object.
- *  \param [in] x          Current x coordinate of pointer in screen units.
- *  \param [in] y          Current y coordinate of pointer in screen units.
+ *  \param [in] w_x        Current x coordinate of pointer in world units.
+ *  \param [in] w_y        Current y coordinate of pointer in world units.
  */
-void o_circle_rubbercircle(GSCHEM_TOPLEVEL *w_current, int x, int y)
+void o_circle_rubbercircle(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
 {
-  TOPLEVEL *toplevel = w_current->toplevel;
   int diff_x, diff_y;
 
   g_assert( w_current->inside_action != 0 );
 
-  /* erase the previous temporary circle */
-  o_circle_rubbercircle_xor(w_current);
+  /* erase the previous temporary circle if it is visible */
+  if (w_current->rubber_visible)
+    o_circle_rubbercircle_xor(w_current);
 
   /*
    * The radius is taken as the biggest distance on the x and y axis between
    * the center of the circle and the mouse position.
    */
-  /* update the radius */
-  w_current->last_x = fix_x(toplevel, x);
-  w_current->last_y = fix_y(toplevel, y);
-  
-  diff_x = GET_BOX_WIDTH (w_current);
-  diff_y = GET_BOX_HEIGHT(w_current);
-  if (diff_x >= diff_y) {
-    w_current->last_y   = w_current->start_y;
-    w_current->distance = diff_x;
-  } else {
-    w_current->last_x   = w_current->start_x;
-    w_current->distance = diff_y;
-  }
+  diff_x = abs(w_current->first_wx - w_x);
+  diff_y = abs(w_current->first_wy - w_y);
+  w_current->distance = max(diff_x, diff_y);
 
   /* draw the new temporary circle */
   o_circle_rubbercircle_xor(w_current);
-
+  w_current->rubber_visible =1;
 }
 
 /*! \brief Draw circle from GSCHEM_TOPLEVEL object.
  *  \par Function Description
  *  This function draws the circle from the variables in the GSCHEM_TOPLEVEL
  *  structure <B>*w_current</B>.
- *  The center of the circle is at (<B>w_current->start_x</B>,
- *  <B>w_current->start_y</B>) and its radius is in <B>w_current->distance</B>.
+ *  The center of the circle is at (<B>w_current->first_wx</B>,
+ *  <B>w_current->first_wy</B>) and its radius is in <B>w_current->distance</B>.
  *
  *  It draws a horizontal radius segment on the right half of the circle and
  *  the circle with the selection color and an xor-function over the current
@@ -745,23 +706,23 @@ void o_circle_rubbercircle(GSCHEM_TOPLEVEL *w_current, int x, int y)
  */
 void o_circle_rubbercircle_xor(GSCHEM_TOPLEVEL *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);
+
   /* draw the circle from the w_current variables */
   gdk_gc_set_foreground(w_current->xor_gc, 
 			x_get_darkcolor(w_current->select_color));
   gdk_draw_line(w_current->backingstore, w_current->xor_gc,
-		w_current->start_x, w_current->start_y,
-		w_current->start_x + w_current->distance,
-		w_current->start_y);
+		cx, cy, cx + radius, cy);
   gdk_draw_arc(w_current->backingstore, w_current->xor_gc, FALSE,
-	       w_current->start_x - w_current->distance,
-	       w_current->start_y - w_current->distance,
-	       w_current->distance * 2,
-	       w_current->distance * 2,
+	       cx - radius, cy - radius, 2 * radius, 2* radius,
 	       0, FULL_CIRCLE);
-  o_invalidate_rect(w_current, w_current->start_x - w_current->distance,
-                               w_current->start_y - w_current->distance,
-                               w_current->start_x + w_current->distance,
-                               w_current->start_y + w_current->distance);
+  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_grips.c b/gschem/src/o_grips.c
index 9a4eeb4..204ecec 100644
--- a/gschem/src/o_grips.c
+++ b/gschem/src/o_grips.c
@@ -497,7 +497,6 @@ int o_grips_start(GSCHEM_TOPLEVEL *w_current, int x, int y)
 
   whichone_changing = whichone;
   object_changing = object;
-  w_current->rubber_visible = 1;
 
   /* there is one */
   /* depending on its type, start the modification process */
@@ -708,7 +707,7 @@ void o_grips_start_box(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current,
 
   /* draw the first temporary box */
   o_box_rubberbox_xor(w_current);
-
+  w_current->rubber_visible = 1;
 }
 
 /*! \brief Initialize grip motion process for a picture.
@@ -791,11 +790,10 @@ void o_grips_start_picture(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current,
  *  The function first erases the grips.
  *
  *  The coordinates of the center are put in
- *  (<B>w_current->start_x</B>,<B>w_current->start_y</B>). They are not suppose
+ *  (<B>w_current->first_wx</B>,<B>w_current->first_wy</B>). They are not suppose
  *  to change during the action.
  *
- *  The coordinates of the point on the circle to the right of the center
- *  go in (<B>w_current->last_x</B>,<B>w_current->last_y</B>).
+ *  The radius of the circle is stored in <B>w_current->distance<B>.
  *
  *  \param [in]  w_current  The GSCHEM_TOPLEVEL object.
  *  \param [in]  o_current  Circle OBJECT to check.
@@ -806,25 +804,20 @@ void o_grips_start_picture(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current,
 void o_grips_start_circle(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current,
                           int x, int y, int whichone)
 {
-  TOPLEVEL *toplevel = w_current->toplevel;
+
   w_current->last_drawb_mode = -1;
 
   /* erase the circle before */
   o_erase_single(w_current, o_current);
 
-  /* describe the circle with GSCHEM_TOPLEVEL variables */
-  /* (start_x, start_y) is the center of the circle */
-  WORLDtoSCREEN( toplevel, o_current->circle->center_x, o_current->circle->center_y,
-                 &w_current->start_x, &w_current->start_y );
-  /* (last_x,last_y)    is the point on circle on the right of center */
-  WORLDtoSCREEN( toplevel, o_current->circle->center_x + o_current->circle->radius, o_current->circle->center_y,
-                 &w_current->last_x, &w_current->last_y );
-  /* distance           is the radius of the circle */
-  w_current->distance = SCREENabs( toplevel, o_current->circle->radius );
+  /* store circle center and radius in GSCHEM_TOPLEVEL structure */
+  w_current->first_wx = o_current->circle->center_x;
+  w_current->first_wy = o_current->circle->center_y;
+  w_current->distance = o_current->circle->radius;
 
   /* draw the first temporary circle */
   o_circle_rubbercircle_xor(w_current);
-
+  w_current->rubber_visible = 1;
 }
 
 /*! \brief Initialize grip motion process for a line.
@@ -913,7 +906,7 @@ void o_grips_motion(GSCHEM_TOPLEVEL *w_current, int x, int y)
 
     case(OBJ_CIRCLE):
     /* erase, update and draw a circle */
-    o_grips_motion_circle(w_current, x, y, whichone_changing);
+    o_grips_motion_circle(w_current, w_x, w_y, whichone_changing);
     break;
 
     case(OBJ_LINE):
@@ -1022,14 +1015,14 @@ void o_grips_motion_picture(GSCHEM_TOPLEVEL *w_current, int x, int y, int whicho
  *  draw the new temporary circle.
  *
  *  \param [in] w_current  The GSCHEM_TOPLEVEL object.
- *  \param [in] x          Current x coordinate of pointer in screen units.
- *  \param [in] y          Current y coordinate of pointer in screen units.
+ *  \param [in] w_x        Current x coordinate of pointer in world units.
+ *  \param [in] w_y        Current y coordinate of pointer in world units.
  *  \param [in] whichone   Which grip to start motion with.
  */
-void o_grips_motion_circle(GSCHEM_TOPLEVEL *w_current, int x, int y, int whichone)
+void o_grips_motion_circle(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y, int whichone)
 {
   /* erase, update and draw the temporary circle */
-  o_circle_rubbercircle(w_current, x, y);
+  o_circle_rubbercircle(w_current, w_x, w_y);
 }
 
 /*! \brief Modify previously selected line according to mouse position.
@@ -1528,7 +1521,6 @@ void o_grips_end_picture(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int whic
 void o_grips_end_circle(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int whichone)
 {
   TOPLEVEL *toplevel = w_current->toplevel;
-  int radius;
 
   /* erase the temporary circle */
   o_circle_rubbercircle_xor(w_current);
@@ -1536,12 +1528,9 @@ void o_grips_end_circle(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int which
   /* don't allow zero radius circles
    * this ends the circle drawing behavior
    * we want this? hack */
-  if ((w_current->start_x == w_current->last_x) &&
-      (w_current->start_y == w_current->last_y)) {
+  if (w_current->distance == 0) {
     w_current->start_x = (-1);
     w_current->start_y = (-1);
-    w_current->last_x  = (-1);
-    w_current->last_y  = (-1);
 
     /* return to select mode */
     w_current->inside_action = 0;
@@ -1552,11 +1541,8 @@ void o_grips_end_circle(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int which
     return;
   }
 
-  /* convert the radius in world unit */
-  radius = WORLDabs(toplevel, w_current->distance);
-
   /* modify the radius of the circle */
-  o_circle_modify(toplevel, o_current, radius, -1, CIRCLE_RADIUS);
+  o_circle_modify(toplevel, o_current, w_current->distance, -1, CIRCLE_RADIUS);
 
   /* display the new circle */
   o_redraw_single(w_current, o_current);
diff --git a/gschem/src/x_event.c b/gschem/src/x_event.c
index 748871d..142e0f3 100644
--- a/gschem/src/x_event.c
+++ b/gschem/src/x_event.c
@@ -235,17 +235,13 @@ gint x_event_button_pressed(GtkWidget *widget, GdkEventButton *event,
         break;
 
       case(DRAWCIRCLE):
-        o_circle_start(w_current,
-                       (int) event->x,
-                       (int) event->y);
+        o_circle_start(w_current, w_x, w_y);
         w_current->event_state = ENDCIRCLE;
         w_current->inside_action = 1;
         break;
 
       case(ENDCIRCLE):
-        o_circle_end(w_current,
-                     (int) event->x,
-                     (int) event->y);
+        o_circle_end(w_current, w_x, w_y);
         w_current->inside_action = 0;
         w_current->event_state = DRAWCIRCLE;
         break;
@@ -1059,9 +1055,7 @@ gint x_event_motion(GtkWidget *widget, GdkEventMotion *event,
 
     case(ENDCIRCLE):
     if (w_current->inside_action)
-    o_circle_rubbercircle(w_current,
-                          (int) event->x,
-                          (int) event->y);
+      o_circle_rubbercircle(w_current, w_x, w_y);
     break;
 
     case(ENDARC):

commit 4f5cf44b196790dbf5cf318977463b487a17ec89
Author: Werner Hoch <werner.ho@xxxxxx>
Date:   Sun Apr 6 13:09:35 2008 +0200

    switched box grips to world coordinates
    
    This fixes the manipulation of a box, that broke in the previous
    commit.

diff --git a/gschem/src/o_box.c b/gschem/src/o_box.c
index 77ab2cb..af55530 100644
--- a/gschem/src/o_box.c
+++ b/gschem/src/o_box.c
@@ -974,7 +974,6 @@ void o_box_end(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
  */
 void o_box_rubberbox(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
 {
-  TOPLEVEL *toplevel = w_current->toplevel;
 
   g_assert( w_current->inside_action != 0 );
 
diff --git a/gschem/src/o_grips.c b/gschem/src/o_grips.c
index 0482e0c..9a4eeb4 100644
--- a/gschem/src/o_grips.c
+++ b/gschem/src/o_grips.c
@@ -32,10 +32,8 @@
 #include <dmalloc.h>
 #endif
 
-#define GET_BOX_WIDTH(w)  abs((w)->last_x - (w)->start_x)
-#define GET_BOX_HEIGHT(w) abs((w)->last_y - (w)->start_y)
-#define GET_BOX_LEFT(w)   min((w)->start_x, (w)->last_x);
-#define GET_BOX_TOP(w)    min((w)->start_y, (w)->last_y);
+#define GET_BOX_WIDTH(w)  abs((w)->second_wx - (w)->first_wx)
+#define GET_BOX_HEIGHT(w) abs((w)->second_wy - (w)->second_wy)
 
 #define GET_PICTURE_WIDTH(w) abs((w)->last_x - (w)->start_x)
 #define GET_PICTURE_HEIGHT(w) (w)->pixbuf_wh_ratio == 0 ? 0 : \
@@ -499,6 +497,7 @@ int o_grips_start(GSCHEM_TOPLEVEL *w_current, int x, int y)
 
   whichone_changing = whichone;
   object_changing = object;
+  w_current->rubber_visible = 1;
 
   /* there is one */
   /* depending on its type, start the modification process */
@@ -656,10 +655,10 @@ void o_grips_start_arc(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current,
  *  The function first erases the grips.
  *
  *  The coordinates of the selected corner are put in
- *  (<B>w_current->last_x</B>,<B>w_current->last_y</B>).
+ *  (<B>w_current->second_wx</B>,<B>w_current->second_wx</B>).
  *
  *  The coordinates of the opposite corner go in
- *  (<B>w_current->start_x</B>,<B>w_current->start_y</B>). They are not suppose
+ *  (<B>w_current->first_wx</B>,<B>w_current->first_wy</B>). They are not suppose
  *  to change during the action.
  *
  *  \param [in]  w_current  The GSCHEM_TOPLEVEL object.
@@ -671,38 +670,37 @@ void o_grips_start_arc(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current,
 void o_grips_start_box(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current,
                        int x, int y, int whichone)
 {
-  TOPLEVEL *toplevel = w_current->toplevel;
   w_current->last_drawb_mode = -1;
 
   /* erase the box before */
   o_erase_single(w_current, o_current);
 
-  /* (last_x,last_y)    is the selected corner */
-  /* (start_x, start_y) is the opposite corner */
+  /* (second_wx, second_wy) is the selected corner */
+  /* (first_wx, first_wy) is the opposite corner */
   switch(whichone) {
     case BOX_UPPER_LEFT:
-      WORLDtoSCREEN( toplevel, o_current->box->upper_x, o_current->box->upper_y,
-                     &w_current->last_x, &w_current->last_y );
-      WORLDtoSCREEN( toplevel, o_current->box->lower_x, o_current->box->lower_y,
-                     &w_current->start_x, &w_current->start_y );
+      w_current->second_wx = o_current->box->upper_x;
+      w_current->second_wy = o_current->box->upper_y;
+      w_current->first_wx = o_current->box->lower_x;
+      w_current->first_wy = o_current->box->lower_y;
       break;
     case BOX_LOWER_RIGHT:
-      WORLDtoSCREEN( toplevel, o_current->box->lower_x, o_current->box->lower_y,
-                     &w_current->last_x, &w_current->last_y );
-      WORLDtoSCREEN( toplevel, o_current->box->upper_x, o_current->box->upper_y,
-                     &w_current->start_x, &w_current->start_y );
+      w_current->second_wx = o_current->box->lower_x;
+      w_current->second_wy = o_current->box->lower_y;
+      w_current->first_wx = o_current->box->upper_x;
+      w_current->first_wy = o_current->box->upper_y;
       break;
     case BOX_UPPER_RIGHT:
-      WORLDtoSCREEN( toplevel, o_current->box->lower_x, o_current->box->upper_y,
-                     &w_current->last_x, &w_current->last_y );
-      WORLDtoSCREEN( toplevel, o_current->box->upper_x, o_current->box->lower_y,
-                     &w_current->start_x, &w_current->start_y );
+      w_current->second_wx = o_current->box->lower_x;
+      w_current->second_wy = o_current->box->upper_y;
+      w_current->first_wx = o_current->box->upper_x;
+      w_current->first_wy = o_current->box->lower_y;
       break;
     case BOX_LOWER_LEFT:
-      WORLDtoSCREEN( toplevel, o_current->box->upper_x, o_current->box->lower_y,
-                     &w_current->last_x, &w_current->last_y );
-      WORLDtoSCREEN( toplevel, o_current->box->lower_x, o_current->box->upper_y,
-                     &w_current->start_x, &w_current->start_y );
+      w_current->second_wx = o_current->box->upper_x;
+      w_current->second_wy = o_current->box->lower_y;
+      w_current->first_wx = o_current->box->lower_x;
+      w_current->first_wy = o_current->box->upper_y;
       break;
     default:
       return; /* error */
@@ -887,6 +885,13 @@ void o_grips_start_line(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current,
  */
 void o_grips_motion(GSCHEM_TOPLEVEL *w_current, int x, int y)
 {
+  TOPLEVEL *toplevel = w_current->toplevel;
+  int w_x, w_y;
+
+  SCREENtoWORLD(toplevel, x, y, &w_x, &w_y);
+  w_x = snap_grid(toplevel, w_x);
+  w_y = snap_grid(toplevel, w_y);
+
   g_assert( w_current->inside_action != 0 );
   g_return_if_fail( object_changing != NULL );
 
@@ -898,7 +903,7 @@ void o_grips_motion(GSCHEM_TOPLEVEL *w_current, int x, int y)
 
     case(OBJ_BOX):
     /* erase, update and draw a box */
-    o_grips_motion_box(w_current, x, y, whichone_changing);
+    o_grips_motion_box(w_current, w_x, w_y, whichone_changing);
     break;
 
     case(OBJ_PICTURE):
@@ -969,14 +974,14 @@ void o_grips_motion_arc(GSCHEM_TOPLEVEL *w_current, int x, int y, int whichone)
  *  the new temporary box.
  *
  *  \param [in] w_current  The GSCHEM_TOPLEVEL object.
- *  \param [in] x          Current x coordinate of pointer in screen units.
- *  \param [in] y          Current y coordinate of pointer in screen units.
+ *  \param [in] w_x        Current x coordinate of pointer in world units.
+ *  \param [in] w_y        Current y coordinate of pointer in world units.
  *  \param [in] whichone   Which grip to start motion with.
  */
-void o_grips_motion_box(GSCHEM_TOPLEVEL *w_current, int x, int y, int whichone)
+void o_grips_motion_box(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y, int whichone)
 {
   /* erase, update and draw the temporary box */
-  o_box_rubberbox(w_current, x, y);
+  o_box_rubberbox(w_current, w_x, w_y);
 }
 
 /*! \brief Modify previously selected picture according to mouse position.
@@ -1420,7 +1425,6 @@ void o_grips_end_box(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int whichone
 {
   TOPLEVEL *toplevel = w_current->toplevel;
   int box_width, box_height;
-  int x, y;
 
   box_width  = GET_BOX_WIDTH (w_current);
   box_height = GET_BOX_HEIGHT(w_current);
@@ -1429,10 +1433,10 @@ 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)) {
-    w_current->start_x = (-1);
-    w_current->start_y = (-1);
-    w_current->last_x  = (-1);
-    w_current->last_y  = (-1);
+    w_current->first_wx = (-1);
+    w_current->first_wy = (-1);
+    w_current->second_wx  = (-1);
+    w_current->second_wy  = (-1);
 
     w_current->inside_action=0;
     i_set_state(w_current, SELECT);
@@ -1443,13 +1447,7 @@ void o_grips_end_box(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, int whichone
     return;
   }
 
-  SCREENtoWORLD(toplevel,
-                w_current->last_x, w_current->last_y,
-                &x, &y);
-  x = snap_grid(toplevel, x);
-  y = snap_grid(toplevel, y);
-
-  o_box_modify(toplevel, o_current, x, y, 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);

commit 693d7fbb8630bcb846ee72bb594a6c8612ec2f17
Author: Werner Hoch <werner.ho@xxxxxx>
Date:   Sun Apr 6 12:15:21 2008 +0200

    switched box rubber drawing to world coordinates
    
    Call all box functions with world coordinates. Protect the rubber box
    from erasing if the rubber box has been erased by the redraw_all
    function. This happend if the user zoomed while drawing the box.
    The variable w_current->rubber_visible is used for this purpose.

diff --git a/gschem/include/gschem_struct.h b/gschem/include/gschem_struct.h
index d8d139c..408bf77 100644
--- a/gschem/include/gschem_struct.h
+++ b/gschem/include/gschem_struct.h
@@ -102,7 +102,7 @@ struct st_gschem_toplevel {
   int inside_action;                    /* Are we doing an action? */
   int rotated_inside;                   /* Was the selection rotated
                                            inside an action? */
-  int rubbernet_visible;                /* Is the rubbernet currently on
+  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 */
diff --git a/gschem/src/gschem_toplevel.c b/gschem/src/gschem_toplevel.c
index 2726f7c..82f0347 100644
--- a/gschem/src/gschem_toplevel.c
+++ b/gschem/src/gschem_toplevel.c
@@ -127,7 +127,7 @@ GSCHEM_TOPLEVEL *gschem_toplevel_new ()
   w_current->magnetic_wy = -1;
   w_current->inside_action = 0;
   w_current->rotated_inside = 0;
-  w_current->rubbernet_visible = 0;
+  w_current->rubber_visible = 0;
   w_current->magnetic_visible = 0;
   w_current->net_direction = 0;
 
diff --git a/gschem/src/i_callbacks.c b/gschem/src/i_callbacks.c
index 782b8a9..3f196e8 100644
--- a/gschem/src/i_callbacks.c
+++ b/gschem/src/i_callbacks.c
@@ -2574,7 +2574,7 @@ DEFINE_I_CALLBACK(add_box_hotkey)
 
   i_update_middle_button(w_current, i_callback_add_box_hotkey, _("Box"));
 
-  o_box_start(w_current, mouse_x, mouse_y);
+  o_box_start(w_current, mouse_wx, mouse_wy);
 
   w_current->inside_action = 1;
   i_set_state(w_current, ENDBOX);
diff --git a/gschem/src/o_basic.c b/gschem/src/o_basic.c
index 8122e24..0745702 100644
--- a/gschem/src/o_basic.c
+++ b/gschem/src/o_basic.c
@@ -89,10 +89,10 @@ void o_redraw_all(GSCHEM_TOPLEVEL *w_current)
       case(STARTDRAWNET):
       case(DRAWNET):
       case(NETCONT):
-        w_current->rubbernet_visible=0;
 	w_current->magnetic_visible=0;
         break;
     }
+    w_current->rubber_visible=0;
   }
 }
 
diff --git a/gschem/src/o_box.c b/gschem/src/o_box.c
index 712c37d..77ab2cb 100644
--- a/gschem/src/o_box.c
+++ b/gschem/src/o_box.c
@@ -31,15 +31,14 @@
 #include <dmalloc.h>
 #endif
 
-/* Kazu on July 16, 1999 - Added these macros to simplify the code */
 #define GET_BOX_WIDTH(w)			\
-	abs((w)->last_x - (w)->start_x)
+	abs((w)->second_wx - (w)->first_wx)
 #define GET_BOX_HEIGHT(w)			\
-	abs((w)->last_y - (w)->start_y)
+	abs((w)->second_wy - (w)->first_wy)
 #define GET_BOX_LEFT(w)				\
-	min((w)->start_x, (w)->last_x);
+	min((w)->first_wx, (w)->second_wx)
 #define GET_BOX_TOP(w)				\
-	min((w)->start_y, (w)->last_y);
+        max((w)->first_wy, (w)->second_wy)
 
 typedef void (*DRAW_FUNC)( GdkDrawable *w, GdkGC *gc, GdkColor *color,
                            GdkCapStyle cap, gint filled,
@@ -864,62 +863,57 @@ void o_box_draw_xor(GSCHEM_TOPLEVEL *w_current, int dx, int dy, OBJECT *o_curren
  *  \par Function Description
  *  This function starts the process to input a new box. Parameters for this
  *  box are put into/extracted from the <B>w_current</B> toplevel structure.
- *  <B>x</B> and <B>y</B> are current coordinates of the pointer in screen
+ *  <B>w_x</B> and <B>w_y</B> are current coordinates of the pointer in world
  *  coordinates.
  *
  *  The first step is to input one corner of the box. This corner is
- *  (<B>x</B>,<B>y</B>) snapped to the grid and saved in <B>w_current->start_x</B>
- *  and <B>w_current->start_y</B>.
+ *  (<B>w_x</B>,<B>w_y</B>) snapped to the grid and saved in <B>w_current->first_wx</B>
+ *  and <B>w_current->first_wy</B>.
  *
- *  The other corner will be saved in (<B>w_current->last_x</B>,
- *  <B>w_current->last_y</B>).
+ *  The other corner will be saved in (<B>w_current->second_wx</B>,
+ *  <B>w_current->second_wy</B>).
  *
  *  \param [in] w_current  The GSCHEM_TOPLEVEL object.
- *  \param [in] x          Current x coordinate of pointer in screen units.
- *  \param [in] y          Current y coordinate of pointer in screen units.
+ *  \param [in] w_x        Current x coordinate of pointer in world.
+ *  \param [in] w_y        Current y coordinate of pointer in world.
  */
-void o_box_start(GSCHEM_TOPLEVEL *w_current, int x, int y)
+void o_box_start(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
 {
-  TOPLEVEL *toplevel = w_current->toplevel;
-  /* init start_[x|y], last_[x|y] to describe box */
-  w_current->last_x = w_current->start_x = fix_x(toplevel, x);
-  w_current->last_y = w_current->start_y = fix_y(toplevel, y);
+  /* init first_w[x|y], second_w[x|y] to describe box */
+  w_current->first_wx = w_current->second_wx = w_x;
+  w_current->first_wy = w_current->second_wy = w_y;
 
   /* start to draw the box */
   o_box_rubberbox_xor(w_current);
-  
 }
 
 /*! \brief End the input of a box.
  *  \par Function Description
  *  This function ends the input of the second corner of a box.
- *  The (<B>x</B>,<B>y</B>) point is set to be this second corner. The box is
- *  then defined by (<B>w_current->start_x</B>,<B>w_current->start_y</B> and
- *  (<B>w_current->last_x</B>,<B>w_current->last_y</B> that is a snapped version
- *  of (<B>x</B>,<B>y</B>).
- *  <B>x</B> and <B>y</B> are in screen unit.
+ *  The (<B>w_x</B>,<B>w_y</B>) point is set to be this second corner. The box is
+ *  then defined by (<B>w_current->first_wx</B>,<B>w_current->first_wy</B> and
+ *  (<B>w_current->second_wx</B>,<B>w_current->second_wy</B>.
+ *  <B>w_x</B> and <B>w_y</B> are in screen unit.
  *
  *  The temporary box is erased ; a new box object is allocated, initialized
  *  and linked to the object list ; The object is finally drawn on the
  *  current sheet.
  *
  *  \param [in] w_current  The GSCHEM_TOPLEVEL object.
- *  \param [in] x          Current x coordinate of pointer in screen units.
- *  \param [in] y          Current y coordinate of pointer in screen units.
+ *  \param [in] w_x        Current x coordinate of pointer in world units.
+ *  \param [in] w_y        Current y coordinate of pointer in world units.
  */
-void o_box_end(GSCHEM_TOPLEVEL *w_current, int x, int y)
+void o_box_end(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
 {
   TOPLEVEL *toplevel = w_current->toplevel;
-  int x1, y1;
-  int x2, y2;
   int box_width, box_height;
   int box_left, box_top;
 
   g_assert( w_current->inside_action != 0 );
 
   /* get the last coords of the pointer */
-  w_current->last_x = fix_x(toplevel, x);
-  w_current->last_y = fix_y(toplevel, y);
+  w_current->second_wx = w_x;
+  w_current->second_wy = w_y;
 
   /* erase the temporary box */
   o_box_rubberbox_xor(w_current);
@@ -929,42 +923,34 @@ void o_box_end(GSCHEM_TOPLEVEL *w_current, int x, int y)
   box_left   = GET_BOX_LEFT  (w_current);
   box_top    = GET_BOX_TOP   (w_current);
 
-  /* boxes with null width and height are not allowed */
-  if ((box_width == 0) && (box_height == 0)) {
+  /* boxes with null width or height are not allowed */
+  if ((box_width == 0) || (box_height == 0)) {
 	  /* cancel the object creation */
-	  w_current->start_x = (-1);
-	  w_current->start_y = (-1);
-	  w_current->last_x  = (-1);
-	  w_current->last_y  = (-1);
+	  w_current->first_wx = (-1);
+	  w_current->first_wy = (-1);
+	  w_current->second_wx  = (-1);
+	  w_current->second_wy  = (-1);
 	  return;
   }
 
-  /* calculate the world coords of the upper left and lower right corners */
-  SCREENtoWORLD(toplevel, box_left, box_top, &x1, &y1);
-  SCREENtoWORLD(toplevel,
-                box_left + box_width, box_top  + box_height, &x2, &y2);
-  x1 = snap_grid(toplevel, x1);
-  y1 = snap_grid(toplevel, y1);
-  x2 = snap_grid(toplevel, x2);
-  y2 = snap_grid(toplevel, y2);
-
   /* create the object */
   toplevel->page_current->object_tail =
   o_box_add(toplevel,
             toplevel->page_current->object_tail,
-            OBJ_BOX, w_current->graphic_color, x1, y1, x2, y2);
+            OBJ_BOX, w_current->graphic_color, 
+	    box_left, box_top, box_left + box_width, box_top - box_height);
 
   /* draw it */
   o_redraw_single(w_current, toplevel->page_current->object_tail);
   
 #if DEBUG
-  printf("coords: %d %d %d %d\n", x1, y2, x2, y2);
+  printf("coords: %d %d %d %d\n", box_left, box_top, box_width, box_height);
 #endif
 	
-  w_current->start_x = (-1);
-  w_current->start_y = (-1);
-  w_current->last_x  = (-1);
-  w_current->last_y  = (-1);
+  w_current->first_wx = (-1);
+  w_current->first_wy = (-1);
+  w_current->second_wx  = (-1);
+  w_current->second_wy  = (-1);
 	
   toplevel->page_current->CHANGED = 1;
 
@@ -975,7 +961,7 @@ void o_box_end(GSCHEM_TOPLEVEL *w_current, int x, int y)
  *  \par Function Description
  *  This function is used to draw the box while dragging one of its edge or
  *  angle. It erases the previous temporary box drawn before, and draws a new
- *  updated one. <B>x</B> and <B>y</B> are the new position of the mobile point,
+ *  updated one. <B>w_x</B> and <B>w_y</B> are the new position of the mobile point,
  *  ie the mouse.
  *
  *  The old values are inside the <B>w_current</B> pointed structure. Old width,
@@ -983,30 +969,33 @@ void o_box_end(GSCHEM_TOPLEVEL *w_current, int x, int y)
  *  The box is then erased by performing a xor-drawing over the box.
  *
  *  \param [in] w_current  The GSCHEM_TOPLEVEL object.
- *  \param [in] x          Current x coordinate of pointer in screen units.
- *  \param [in] y          Current y coordinate of pointer in screen units.
+ *  \param [in] w_x        Current x coordinate of pointer in world units.
+ *  \param [in] w_y        Current y coordinate of pointer in world units.
  */
-void o_box_rubberbox(GSCHEM_TOPLEVEL *w_current, int x, int y)
+void o_box_rubberbox(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y)
 {
   TOPLEVEL *toplevel = w_current->toplevel;
 
   g_assert( w_current->inside_action != 0 );
 
-  /* erase the previous temporary box */
-  o_box_rubberbox_xor(w_current);
+  /* erase the previous temporary box if it is visible */
+  if (w_current->rubber_visible)
+    o_box_rubberbox_xor(w_current);
 
   /*
-   * New values are fixed according to the <B>x</B> and <B>y</B> parameters.
+   * New values are fixed according to the <B>w_x</B> and <B>w_y</B> parameters.
    * These are saved in <B>w_current</B> pointed structure as new temporary
    * values. The new box is then drawn.
    */
 
   /* update the coords of the corner */
-  w_current->last_x = fix_x(toplevel, x);
-  w_current->last_y = fix_y(toplevel, y);
+  w_current->second_wx = w_x;
+  w_current->second_wy = w_y;
 
   /* draw the new temporary box */
   o_box_rubberbox_xor(w_current);
+
+  w_current->rubber_visible = 1;
   
 }
 
@@ -1014,9 +1003,9 @@ void o_box_rubberbox(GSCHEM_TOPLEVEL *w_current, int x, int y)
  *  \par Function Description
  *  This function draws the box from the variables in the GSCHEM_TOPLEVEL
  *  structure <B>*w_current</B>.
- *  One corner of the box is at (<B>w_current->start_x</B>,
- *  <B>w_current->start_y</B>) and the second corner is at
- *  (<B>w_current->last_x</B>,<B>w_current->last_y</B>.
+ *  One corner of the box is at (<B>w_current->first_wx</B>,
+ *  <B>w_current->first_wy</B>) and the second corner is at
+ *  (<B>w_current->second_wx</B>,<B>w_current->second_wy</B>.
  *
  *  The box is drawn with a xor-function over the current sheet with the
  *  selection color.
@@ -1025,24 +1014,31 @@ void o_box_rubberbox(GSCHEM_TOPLEVEL *w_current, int x, int y)
  */
 void o_box_rubberbox_xor(GSCHEM_TOPLEVEL *w_current)
 {
-	int box_width, box_height, box_left, box_top;
-
-	/* get the width/height and the upper left corner of the box */
-	box_width  = GET_BOX_WIDTH (w_current);
-	box_height = GET_BOX_HEIGHT(w_current);
-	box_left   = GET_BOX_LEFT  (w_current);
-	box_top    = GET_BOX_TOP   (w_current);
-
+  TOPLEVEL *toplevel = w_current->toplevel;
+  int x1, y1, x2, y2;
+  int box_width, box_height, box_left, box_top;
+  
+  WORLDtoSCREEN(toplevel, w_current->first_wx, w_current->first_wy,
+		&x1, &y1);
+  WORLDtoSCREEN(toplevel, w_current->second_wx, w_current->second_wy, 
+		&x2, &y2);
+
+  /* get the width/height and the upper left corner of the box */
+  box_width  = abs(x2 - x1);
+  box_height = abs(y2 - y1);
+  box_left   = min(x1, x2);
+  box_top    = min(y1, y2);
+  
 	/* draw the box from the previous variables */
-	gdk_gc_set_foreground(w_current->xor_gc, 
-			      x_get_darkcolor(w_current->select_color));
-	gdk_gc_set_line_attributes(w_current->xor_gc, 0, 
-				   GDK_LINE_SOLID, GDK_CAP_NOT_LAST, 
-				   GDK_JOIN_MITER);
-	gdk_draw_rectangle(w_current->backingstore, 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);
+  gdk_gc_set_foreground(w_current->xor_gc, 
+			x_get_darkcolor(w_current->select_color));
+  gdk_gc_set_line_attributes(w_current->xor_gc, 0, 
+			     GDK_LINE_SOLID, GDK_CAP_NOT_LAST, 
+			     GDK_JOIN_MITER);
+  gdk_draw_rectangle(w_current->backingstore, 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_net.c b/gschem/src/o_net.c
index 29bedc7..d366f52 100644
--- a/gschem/src/o_net.c
+++ b/gschem/src/o_net.c
@@ -66,7 +66,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->rubbernet_visible = 0;
+  w_current->magnetic_visible = w_current->rubber_visible = 0;
 }
 
 /*! \todo Finish function documentation!!!
@@ -941,7 +941,7 @@ void o_net_drawrubber(GSCHEM_TOPLEVEL *w_current)
   WORLDtoSCREEN(toplevel, w_current->second_wx, w_current->second_wy,
 		&second_x, &second_y);
 
-  w_current->rubbernet_visible = 1;
+  w_current->rubber_visible = 1;
 
   if (toplevel->net_style == THICK) {
     size = SCREENabs(toplevel, NET_WIDTH);
@@ -1012,7 +1012,7 @@ void o_net_eraserubber(GSCHEM_TOPLEVEL *w_current)
   int magnetic_x, magnetic_y;
   int first_x, first_y, third_x, third_y, second_x, second_y;
 
-  if (! w_current->rubbernet_visible)
+  if (! w_current->rubber_visible)
     return;
 
   WORLDtoSCREEN(toplevel, w_current->magnetic_wx, w_current->magnetic_wy,
@@ -1024,7 +1024,7 @@ void o_net_eraserubber(GSCHEM_TOPLEVEL *w_current)
   WORLDtoSCREEN(toplevel, w_current->second_wx, w_current->second_wy,
 		&second_x, &second_y);
 
-  w_current->rubbernet_visible = 0;
+  w_current->rubber_visible = 0;
 
   if (toplevel->net_style == THICK) {
     size = SCREENabs(toplevel, NET_WIDTH);
diff --git a/gschem/src/x_event.c b/gschem/src/x_event.c
index ca4c2c4..748871d 100644
--- a/gschem/src/x_event.c
+++ b/gschem/src/x_event.c
@@ -207,17 +207,13 @@ gint x_event_button_pressed(GtkWidget *widget, GdkEventButton *event,
         break;
 
       case(DRAWBOX):
-        o_box_start(w_current,
-                    (int) event->x,
-                    (int) event->y);
+        o_box_start(w_current, w_x, w_y);
         w_current->event_state = ENDBOX;
         w_current->inside_action = 1;
         break;
 
       case(ENDBOX):
-        o_box_end(w_current,
-                  (int) event->x,
-                  (int) event->y);
+        o_box_end(w_current, w_x, w_y);
         w_current->inside_action = 0;
         w_current->event_state = DRAWBOX;
         break;
@@ -1051,9 +1047,7 @@ gint x_event_motion(GtkWidget *widget, GdkEventMotion *event,
 
     case(ENDBOX):
     if (w_current->inside_action)
-    o_box_rubberbox( w_current,
-                     (int) event->x,
-                     (int) event->y);
+      o_box_rubberbox( w_current, w_x, w_y);
     break;
 
     case(ENDPICTURE):




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