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

gEDA-cvs: branch: master updated (1.4.0-20080127-30-gffd2298)



The branch, master has been updated
       via  ffd2298ca90e9e8616a2804c5708cb3d2ccb0a83 (commit)
       via  1a49d46192ff0e84e5727ba92829c56961119e5b (commit)
       via  855f29d44df73caef03ee49bd58f19897f31b69d (commit)
       via  c283e8416d058258bab90b176ee94bb96308c710 (commit)
       via  26883a66c3711ffe04eb5280c4b49c483ca50e95 (commit)
       via  aa26da60b8c2a7e66c8b4d6446e7b67de2c3537a (commit)
       via  6e092d15b6e1881789561653ded80f98c5bdc2f5 (commit)
       via  96fbd6214a4a364d0aa45b405293421623ea939c (commit)
       via  3a412167fe7e16526fafdfea273b3daf8be207b3 (commit)
       via  1d1c604d63bfe8f6eff91749953ba713f7b3745c (commit)
       via  20e0e015622bd57d9b0704d39593f209e49a3396 (commit)
       via  921ed5c0b907fb0f11cfff2233758a2c0169c3e0 (commit)
       via  3ebfd10448ffefd902325b115193cb95cbeeaaf5 (commit)
       via  cf7689c9b6950c1694edacf9d750a48d87d462be (commit)
      from  b62e01773459c0c5df66482aa71c623191242bfd (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 |    5 +
 gschem/include/i_vars.h        |    1 +
 gschem/include/prototype.h     |    8 +
 gschem/lib/system-gschemrc.in  |   10 +
 gschem/src/g_keys.c            |    1 +
 gschem/src/g_rc.c              |   18 ++
 gschem/src/g_register.c        |    2 +
 gschem/src/gschem_toplevel.c   |    5 +
 gschem/src/i_callbacks.c       |   21 ++
 gschem/src/i_vars.c            |    2 +
 gschem/src/o_basic.c           |    6 +
 gschem/src/o_net.c             |  450 +++++++++++++++++++++++++++++++---------
 gschem/src/x_event.c           |   17 ++
 libgeda/include/prototype.h    |    1 +
 libgeda/src/s_tile.c           |   53 +++++
 15 files changed, 498 insertions(+), 102 deletions(-)


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

commit 1a49d46192ff0e84e5727ba92829c56961119e5b
Author: Werner Hoch <werner.ho@xxxxxx>
Date:   Wed Feb 27 20:12:26 2008 +0100

    added configuration option for magnetic net mode in system-gschemrc
    
    Added a configuration option magnetic-net-mode and the g_rc function
    Set the default value to enabled.

:100644 100644 0ebf72a... 35037b2... M	gschem/include/i_vars.h
:100644 100644 99e2e40... 8e55574... M	gschem/include/prototype.h
:100644 100644 16aca18... 28aaf39... M	gschem/lib/system-gschemrc.in
:100644 100644 ec426cd... 17d52e0... M	gschem/src/g_rc.c
:100644 100644 1bb5f86... 35209af... M	gschem/src/g_register.c
:100644 100644 2f8f17a... 90a3912... M	gschem/src/i_vars.c

commit 855f29d44df73caef03ee49bd58f19897f31b69d
Author: Werner Hoch <werner.ho@xxxxxx>
Date:   Fri Feb 22 21:46:21 2008 +0100

    use tiles to find connections for magnetic net mode
    
    This commit changes the magnetic net code to use the tiles.  This
    reduces the load when checking all the possible connections for every
    mouse movement. The patch adds a library function to get object lists
    which may contain objects in the region of the magnetic reach. In
    o_net.c the object iterator code has been changed to use the new library
    function.

:100644 100644 ca2296d... c7404d5... M	gschem/src/o_net.c
:100644 100644 a4234a1... 49e3236... M	libgeda/include/prototype.h
:100644 100644 b22654e... 81d2379... M	libgeda/src/s_tile.c

commit c283e8416d058258bab90b176ee94bb96308c710
Author: Werner Hoch <werner.ho@xxxxxx>
Date:   Sun Feb 17 12:14:27 2008 +0100

    Only look for visible objects in magnetic net mode
    
    In a large circuit the cpu load can be quite large. Checking only
    visible objects decreases the cpu load.
    The magnetic reach area is now a circle (Pythagoras). A rectangle
    gives several points with the same distance at each side.

:100644 100644 79c48b7... ca2296d... M	gschem/src/o_net.c

commit 26883a66c3711ffe04eb5280c4b49c483ca50e95
Author: Werner Hoch <werner.ho@xxxxxx>
Date:   Thu Feb 14 21:49:25 2008 +0100

    added reset function to net drawing code
    
    This reset function cleans up all variables required to draw nets.
    It is used before entering net drawing mode and should be used
    whenever the STARTDRAWNET mode is entered.
    Fixed the last drawing artefact in STARTDRAWNET state.

:100644 100644 7626f4f... 99e2e40... M	gschem/include/prototype.h
:100644 100644 348d5da... 41e034a... M	gschem/src/i_callbacks.c
:100644 100644 eb57879... 79c48b7... M	gschem/src/o_net.c
:100644 100644 35e3f2f... 61cc1b2... M	gschem/src/x_event.c

commit aa26da60b8c2a7e66c8b4d6446e7b67de2c3537a
Author: Werner Hoch <werner.ho@xxxxxx>
Date:   Wed Feb 13 21:38:54 2008 +0100

    misc cosmetic corrections for the magnetic net
    
    Put the magnetic marker onto grid (fix_x/y)
    Changed the marker from a rectangle to a circle.
    Changed the calculation of the magnetic reach from x+y to max(x,y).
    This enlarges the reach into the 45° direction.

:100644 100644 3400e1e... eb57879... M	gschem/src/o_net.c

commit 6e092d15b6e1881789561653ded80f98c5bdc2f5
Author: Werner Hoch <werner.ho@xxxxxx>
Date:   Sat Feb 9 12:56:09 2008 +0100

    connect the magnetic net mode into the net drawing functions
    
    The magnetic net mode is now use to set the start net point, track the
    closest connection in the rubbernet function and to get the end point
    of the net. The endpoint in the magnetic mode is calculated in the new
    function o_net_finishmagnetic.
    
    This commit is based on the patch written by Franz Mottas and Thomas
    Arndt [#1824420].

:100644 100644 e3fb991... 7626f4f... M	gschem/include/prototype.h
:100644 100644 6d3adc6... 3400e1e... M	gschem/src/o_net.c

commit 96fbd6214a4a364d0aa45b405293421623ea939c
Author: Werner Hoch <werner.ho@xxxxxx>
Date:   Sat Feb 9 11:09:10 2008 +0100

    core code for magnetic net mode: find connections and draw marker
    
    When in STARTDRAWNET state, search for the closest connection.
    Added code to search for that connection and to draw and erase
    a rectangular magnetic net marker.
    
    This commit is based on the patch written by Franz Mottas and Thomas
    Arndt [#1824420].

:100644 100644 79c0979... e3fb991... M	gschem/include/prototype.h
:100644 100644 34f4999... 348d5da... M	gschem/src/i_callbacks.c
:100644 100644 ea5c279... 8122e24... M	gschem/src/o_basic.c
:100644 100644 aa3d07c... 6d3adc6... M	gschem/src/o_net.c
:100644 100644 716fe24... 35e3f2f... M	gschem/src/x_event.c

commit 3a412167fe7e16526fafdfea273b3daf8be207b3
Author: Werner Hoch <werner.ho@xxxxxx>
Date:   Sat Feb 9 08:54:45 2008 +0100

    added menu entry and callbacks for magnetic net mode
    
    Added a entry into the options menu to toggle the magnetic net mode.
    Added all required variables in GSCHEM_TOPLEVEL.
    
    This commit is based on the patch written by Franz Mottas and Thomas
    Arndt [#1824420].

:100644 100644 c7c7f50... f90e7af... M	gschem/include/gschem_struct.h
:100644 100644 5c63fa8... 79c0979... M	gschem/include/prototype.h
:100644 100644 a934ecd... 16aca18... M	gschem/lib/system-gschemrc.in
:100644 100644 b01db41... 20042a9... M	gschem/src/g_keys.c
:100644 100644 da021f1... 1bb5f86... M	gschem/src/g_register.c
:100644 100644 09dc5aa... 4825c3b... M	gschem/src/gschem_toplevel.c
:100644 100644 a4e0fa6... 34f4999... M	gschem/src/i_callbacks.c

commit 1d1c604d63bfe8f6eff91749953ba713f7b3745c
Author: Werner Hoch <werner.ho@xxxxxx>
Date:   Sat Feb 9 08:11:38 2008 +0100

    fix drawing artefact when drawing a net and zoom/pan
    
    Zooming and paning redraw everything and if there are rubbernets
    they get deleted, too. We have to tell the rubbernet function that
    the rubbernet is no longer on the screen.
    Thus I've added a flag rubbernet_visible as indicator. This flag needs
    to be set when drawing, and reset when the rubbernet gets erased.

:100644 100644 c99c29f... c7c7f50... M	gschem/include/gschem_struct.h
:100644 100644 bc8493c... 09dc5aa... M	gschem/src/gschem_toplevel.c
:100644 100644 ad205e8... ea5c279... M	gschem/src/o_basic.c
:100644 100644 9159b40... aa3d07c... M	gschem/src/o_net.c

commit 20e0e015622bd57d9b0704d39593f209e49a3396
Author: Werner Hoch <werner.ho@xxxxxx>
Date:   Fri Feb 8 20:57:09 2008 +0100

    moved rubbernet drawing code into a extra function

:100644 100644 0089a26... 5c63fa8... M	gschem/include/prototype.h
:100644 100644 028410e... 9159b40... M	gschem/src/o_net.c

commit 921ed5c0b907fb0f11cfff2233758a2c0169c3e0
Author: Werner Hoch <werner.ho@xxxxxx>
Date:   Fri Feb 8 20:40:43 2008 +0100

    Reuse common code from o_net_eraserubber in o_net_rubbernet
    
    The removal code or the rubbernets is the same in both cases, reuse
    it.

:100644 100644 63a9eda... 028410e... M	gschem/src/o_net.c

commit 3ebfd10448ffefd902325b115193cb95cbeeaaf5
Author: Werner Hoch <werner.ho@xxxxxx>
Date:   Fri Feb 8 20:24:14 2008 +0100

    reuse common code from o_net_eraserubber in o_net_end
    
    reuse the o_net_eraserubber function in o_net_end. o_net_end
    deleted a rubbernet the same way as o_net_eraserubber does.

:100644 100644 af9b3a1... 63a9eda... M	gschem/src/o_net.c

commit cf7689c9b6950c1694edacf9d750a48d87d462be
Author: Werner Hoch <werner.ho@xxxxxx>
Date:   Fri Feb 8 19:34:18 2008 +0100

    Remove unused drawing code from function o_net_start()
    
    This code was never used as the line lenght of both rubbernet
    segments was set to zero before drawing it.

:100644 100644 20154fc... af9b3a1... M	gschem/src/o_net.c

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

commit 1a49d46192ff0e84e5727ba92829c56961119e5b
Author: Werner Hoch <werner.ho@xxxxxx>
Date:   Wed Feb 27 20:12:26 2008 +0100

    added configuration option for magnetic net mode in system-gschemrc
    
    Added a configuration option magnetic-net-mode and the g_rc function
    Set the default value to enabled.

diff --git a/gschem/include/i_vars.h b/gschem/include/i_vars.h
index 0ebf72a..35037b2 100644
--- a/gschem/include/i_vars.h
+++ b/gschem/include/i_vars.h
@@ -73,6 +73,7 @@ extern int default_undo_type;
 extern int default_undo_panzoom;
 extern int default_draw_grips;
 extern int default_netconn_rubberband;
+extern int default_magnetic_net_mode;
 extern int default_sort_component_library;
 extern int default_warp_cursor;
 extern int default_toolbars;
diff --git a/gschem/include/prototype.h b/gschem/include/prototype.h
index 99e2e40..8e55574 100644
--- a/gschem/include/prototype.h
+++ b/gschem/include/prototype.h
@@ -256,6 +256,7 @@ SCM g_rc_undo_type(SCM mode);
 SCM g_rc_undo_panzoom(SCM mode);
 SCM g_rc_draw_grips(SCM mode);
 SCM g_rc_netconn_rubberband(SCM mode);
+SCM g_rc_magnetic_net_mode(SCM mode);
 SCM g_rc_sort_component_library(SCM mode);
 SCM g_rc_add_menu(SCM menu_name, SCM menu_items);
 SCM g_rc_window_size(SCM width, SCM height);
diff --git a/gschem/lib/system-gschemrc.in b/gschem/lib/system-gschemrc.in
index 16aca18..28aaf39 100644
--- a/gschem/lib/system-gschemrc.in
+++ b/gschem/lib/system-gschemrc.in
@@ -141,6 +141,14 @@
 (netconn-rubberband "enabled")
 ;(netconn-rubberband "disabled")
 
+; magnetic-net-mode string
+;
+; Controls the initial setting of the magnetic net mode. The magnetic
+; net mode marks a possible connection that is close to the current
+; cursor position
+(magnetic-net-mode "enabled")
+;(magnetic-net-mode "disabled")
+
 ;  bus-style string
 ;
 ;  Set to thin if you want thin buses.
diff --git a/gschem/src/g_rc.c b/gschem/src/g_rc.c
index ec426cd..17d52e0 100644
--- a/gschem/src/g_rc.c
+++ b/gschem/src/g_rc.c
@@ -1155,6 +1155,24 @@ SCM g_rc_netconn_rubberband(SCM mode)
 		   2);
 }
 
+
+/*! \todo Finish function documentation!!!
+ *  \brief
+ *  \par Function Description
+ *
+ */
+SCM g_rc_magnetic_net_mode(SCM mode)
+{
+  static const vstbl_entry mode_table[] = {
+    {TRUE , "enabled" },
+    {FALSE, "disabled"},
+  };
+
+  RETURN_G_RC_MODE("magnetic-net-mode",
+		   default_magnetic_net_mode,
+		   2);
+}
+
 /*! \todo Finish function documentation!!!
  *  \brief
  *  \par Function Description
diff --git a/gschem/src/g_register.c b/gschem/src/g_register.c
index 1bb5f86..35209af 100644
--- a/gschem/src/g_register.c
+++ b/gschem/src/g_register.c
@@ -134,6 +134,7 @@ static struct gsubr_t gschem_funcs[] = {
 
   { "draw-grips",                1, 0, 0, g_rc_draw_grips },
   { "netconn-rubberband",        1, 0, 0, g_rc_netconn_rubberband },
+  { "magnetic-net-mode",         1, 0, 0, g_rc_magnetic_net_mode },
   { "sort-component-library",    1, 0, 0, g_rc_sort_component_library },
   { "add-menu",                  2, 0, 0, g_rc_add_menu },
   { "window-size",               2, 0, 0, g_rc_window_size },
diff --git a/gschem/src/i_vars.c b/gschem/src/i_vars.c
index 2f8f17a..90a3912 100644
--- a/gschem/src/i_vars.c
+++ b/gschem/src/i_vars.c
@@ -102,6 +102,7 @@ int   default_undo_type = UNDO_DISK;
 int   default_undo_panzoom = FALSE;
 int   default_draw_grips = TRUE;
 int   default_netconn_rubberband = FALSE;
+int   default_magnetic_net_mode = TRUE;
 int   default_sort_component_library = FALSE;
 int   default_warp_cursor = TRUE;
 int   default_toolbars = TRUE;
@@ -230,6 +231,7 @@ void i_vars_set(GSCHEM_TOPLEVEL *w_current)
 
   w_current->draw_grips = default_draw_grips;
   w_current->netconn_rubberband = default_netconn_rubberband;
+  w_current->magneticnet_mode = default_magnetic_net_mode;
   w_current->sort_component_library = default_sort_component_library;
   w_current->warp_cursor = default_warp_cursor;
   w_current->toolbars = default_toolbars;

commit 855f29d44df73caef03ee49bd58f19897f31b69d
Author: Werner Hoch <werner.ho@xxxxxx>
Date:   Fri Feb 22 21:46:21 2008 +0100

    use tiles to find connections for magnetic net mode
    
    This commit changes the magnetic net code to use the tiles.  This
    reduces the load when checking all the possible connections for every
    mouse movement. The patch adds a library function to get object lists
    which may contain objects in the region of the magnetic reach. In
    o_net.c the object iterator code has been changed to use the new library
    function.

diff --git a/gschem/src/o_net.c b/gschem/src/o_net.c
index ca2296d..c7404d5 100644
--- a/gschem/src/o_net.c
+++ b/gschem/src/o_net.c
@@ -297,94 +297,90 @@ void o_net_find_magnetic(GSCHEM_TOPLEVEL *w_current,
   OBJECT *o_current;
   OBJECT *o_simple;
   OBJECT *o_magnetic = NULL;
+  GList *objectlists, *iter1, *iter2;
 
   minbest = min_x = min_y = 0;
   min_weight = 0;
 
-  for (o_current = toplevel->page_current->object_head->next;
-       o_current != NULL;
-       o_current = o_current->next) {
-
-    if (!visible(toplevel,  o_current->w_left, o_current->w_top, 
-		 o_current->w_right, o_current->w_bottom))
-      continue; /* skip invisible objects */
-
-    if (o_current->type == OBJ_COMPLEX) {
-      /* if the object is complex, then search for the pin that is
-	 closest to the cursor */
-      for  (o_simple = o_current->complex->prim_objs->next;
-	    o_simple != NULL;
-	    o_simple = o_simple->next) {
-	if (o_simple->type == OBJ_PIN) {
-	  if (!visible(toplevel,  o_current->w_left, o_current->w_top, 
-		       o_current->w_right, o_current->w_bottom))
-	    continue; /* skip invisible pins */
-
-	  WORLDtoSCREEN(toplevel,
-			o_simple->line->x[o_simple->whichend],
-			o_simple->line->y[o_simple->whichend],
-			&x1, &y1);
-	  mindist = sqrt((double) (x - x1)*(x - x1)
-			 + (double) (y - y1)*(y - y1));
-	  weight = mindist / MAGNETIC_PIN_WEIGHT;
-	  if (o_magnetic == NULL
-	      || weight < min_weight) {
-	    minbest = mindist;
-	    min_weight = weight;
-	    o_magnetic = o_simple;
-	    w_current->magnetic_x = x1;
-	    w_current->magnetic_y = y1;
-	  }
-	}
+  /* max distance of all the different reaches */
+  magnetic_reach = max(MAGNETIC_PIN_REACH, MAGNETIC_NET_REACH);
+  magnetic_reach = max(magnetic_reach, MAGNETIC_BUS_REACH);
+
+  /* get the objects of the tiles around the reach region */
+  SCREENtoWORLD(toplevel, x - magnetic_reach, y - magnetic_reach, &x1, &y1);
+  SCREENtoWORLD(toplevel, x + magnetic_reach, y + magnetic_reach, &x2, &y2);
+  objectlists = s_tile_get_objectlists(toplevel, x1, y1, x2, y2);
+
+  for (iter1 = objectlists; iter1 != NULL; iter1 = g_list_next(iter1)) {
+    for (iter2 = (GList*) iter1->data; iter2 != NULL; iter2 = g_list_next(iter2)) {
+      o_current = (OBJECT*) iter2->data;
+
+      if (!visible(toplevel,  o_current->w_left, o_current->w_top, 
+		   o_current->w_right, o_current->w_bottom))
+	continue; /* skip invisible objects */
+
+      if (o_current->type == OBJ_PIN) {
+	WORLDtoSCREEN(toplevel,
+		      o_current->line->x[o_current->whichend],
+		      o_current->line->y[o_current->whichend],
+		      &min_x, &min_y);
+	mindist = sqrt((double) (x - min_x)*(x - min_x)
+		       + (double) (y - min_y)*(y - min_y));
+	weight = mindist / MAGNETIC_PIN_WEIGHT;
       }
-    }
 
-    if (o_current->type == OBJ_NET
-	|| o_current->type == OBJ_BUS) {
-      /* we have 3 possible points to connect: 
-	 2 endpoints and 1 intersect point */
-      WORLDtoSCREEN(toplevel, o_current->line->x[0],
-		    o_current->line->y[0], &x1, &y1);
-      WORLDtoSCREEN(toplevel, o_current->line->x[1],
-		    o_current->line->y[1], &x2, &y2);
-      dist1 = sqrt((double) (x - x1)*(x - x1)
-		   + (double) (y - y1)*(y - y1));
-      dist2 = sqrt((double) (x - x2)*(x - x2)
-		   + (double) (y - y2)*(y - y2));
-      if (dist1 < dist2) {
-	min_x = x1;
-	min_y = y1;
-	mindist = dist1;
-      }
-      else {
-	min_x = x2;
-	min_y = y2;
-	mindist = dist2;
-      }
-      
-      if ((x1 == x2)  /* vertical net */
-	  && ((y1 >= y && y >= y2)
-	      || (y2 >= y && y >= y1))) {
-	if (abs(x - x1) < mindist) {
-	  mindist = abs(x - x1);
+      else if (o_current->type == OBJ_NET
+	       || o_current->type == OBJ_BUS) {
+	/* we have 3 possible points to connect: 
+	   2 endpoints and 1 midpoint point */
+	WORLDtoSCREEN(toplevel, o_current->line->x[0], 
+		      o_current->line->y[0], &x1, &y1);
+	WORLDtoSCREEN(toplevel, o_current->line->x[1],
+		      o_current->line->y[1], &x2, &y2);
+	/* endpoint tests */
+	dist1 = sqrt((double) (x - x1)*(x - x1)
+		     + (double) (y - y1)*(y - y1));
+	dist2 = sqrt((double) (x - x2)*(x - x2)
+		     + (double) (y - y2)*(y - y2));
+	if (dist1 < dist2) {
 	  min_x = x1;
-	  min_y = y;
-	}
-      } 
-      if ((y1 == y2)  /* horitontal net */
-	  && ((x1 >= x && x >= x2)
-	      || (x2 >= x && x >= x1))) {  
-	if (abs(y - y1) < mindist) {
-	  mindist = abs(y - y1);
-	  min_x = x;
 	  min_y = y1;
+	  mindist = dist1;
+	}
+	else {
+	  min_x = x2;
+	  min_y = y2;
+	  mindist = dist2;
+	}
+      
+	/* midpoint tests */
+	if ((x1 == x2)  /* vertical net */
+	    && ((y1 >= y && y >= y2)
+		|| (y2 >= y && y >= y1))) {
+	  if (abs(x - x1) < mindist) {
+	    mindist = abs(x - x1);
+	    min_x = x1;
+	    min_y = y;
+	  }
+	} 
+	if ((y1 == y2)  /* horitontal net */
+	    && ((x1 >= x && x >= x2)
+		|| (x2 >= x && x >= x1))) {  
+	  if (abs(y - y1) < mindist) {
+	    mindist = abs(y - y1);
+	    min_x = x;
+	    min_y = y1;
+	  }
 	}
-      }
 
-      if (o_current->type == OBJ_BUS)
-	weight = mindist / MAGNETIC_BUS_WEIGHT;
-      else /* OBJ_NET */
-	weight = mindist / MAGNETIC_NET_WEIGHT;
+	if (o_current->type == OBJ_BUS)
+	  weight = mindist / MAGNETIC_BUS_WEIGHT;
+	else /* OBJ_NET */
+	  weight = mindist / MAGNETIC_NET_WEIGHT;
+      }
+      else { /* neither pin nor net or bus */
+	continue;
+      }
 
       if (o_magnetic == NULL
 	  || weight < min_weight) {
@@ -395,7 +391,7 @@ void o_net_find_magnetic(GSCHEM_TOPLEVEL *w_current,
 	w_current->magnetic_y = min_y;
       }
     }
-  } 
+  }
 
   /* check whether we found an object and if it's close enough */
   if (o_magnetic != NULL) {
@@ -413,6 +409,8 @@ void o_net_find_magnetic(GSCHEM_TOPLEVEL *w_current,
     w_current->magnetic_x = -1;
     w_current->magnetic_y = -1;
   }
+
+  g_list_free(objectlists);
 }
 
 /*! \brief calcutates the net route to the magnetic marker
diff --git a/libgeda/include/prototype.h b/libgeda/include/prototype.h
index a4234a1..49e3236 100644
--- a/libgeda/include/prototype.h
+++ b/libgeda/include/prototype.h
@@ -492,6 +492,7 @@ void s_tile_add_object(TOPLEVEL *toplevel, OBJECT *object, int world_x1, int wor
 void s_tile_remove_object_all_crude(TOPLEVEL *toplevel, OBJECT *object);
 void s_tile_remove_object_all(TOPLEVEL *toplevel, PAGE *p_current, OBJECT *object);
 void s_tile_update_object(TOPLEVEL *toplevel, OBJECT *object);
+GList *s_tile_get_objectlists(TOPLEVEL *toplevel, int world_x1, int world_y1, int world_x2, int world_y2);
 void s_tile_print(TOPLEVEL *toplevel);
 void s_tile_free_all(PAGE *p_current);
 
diff --git a/libgeda/src/s_tile.c b/libgeda/src/s_tile.c
index b22654e..81d2379 100644
--- a/libgeda/src/s_tile.c
+++ b/libgeda/src/s_tile.c
@@ -387,6 +387,59 @@ void s_tile_update_object(TOPLEVEL * toplevel, OBJECT * object)
                     object->line->x[1], object->line->y[1]);
 }
 
+
+/*! \brief get a list of object lists of all tiles inside a region
+ *  \par Function Description
+ *  This functions collects all object lists of the tiles that are touched
+ *  by the given rectangle (x1,y1), (x2,y2).
+ *  Note: The caller has to g_list_free() the returned list.
+ */
+GList* s_tile_get_objectlists(TOPLEVEL *toplevel, int world_x1, int world_y1,
+			      int world_x2, int world_y2)
+{
+  TILE *t_current;
+  PAGE *p_current;
+  int x1, x2, y1, y2, x, y;
+  double x_size, y_size;
+  GList *objectlists = NULL;
+
+  p_current = toplevel->page_current;
+
+  x_size = (double) toplevel->init_right / (double) MAX_TILES_X;
+  y_size = (double) toplevel->init_bottom / (double) MAX_TILES_Y;
+
+  x1 = (int) (world_x1 / x_size);
+  x2 = (int) (world_x2 / x_size);
+  y1 = (int) (world_y1 / y_size);
+  y2 = (int) (world_y2 / y_size);
+
+  /* limit all tile ranges to [0, MAX_TILES-1]
+     (paranoid error checking) */
+  x1= max(x1, 0);  x1 = min(x1, MAX_TILES_X-1);
+  x2= max(x2, 0);  x2 = min(x2, MAX_TILES_X-1);
+  y1= max(y1, 0);  y1 = min(y1, MAX_TILES_Y-1);
+  y2= max(y2, 0);  y2 = min(y2, MAX_TILES_Y-1);
+
+  /* Check and correct the order of the coordinates */
+  if (x1 > x2) {
+    x = x1;  x1 = x2;  x2 = x;
+  }
+  if (y1 > y2) {
+    y = y1;  y1 = y2;  y2 = y;
+  }
+
+  /* finally, collect all object lists from the tiles */
+  for (x = x1; x <= x2; x++) {
+    for (y = y1; y <= y2; y++) {
+      t_current = &p_current->world_tiles[x][y];
+      objectlists = g_list_append(objectlists, t_current->objects);
+    }
+  }
+
+  return objectlists;
+}
+
+
 /*! \todo Finish function documentation!!!
  *  \brief
  *  \par Function Description

commit c283e8416d058258bab90b176ee94bb96308c710
Author: Werner Hoch <werner.ho@xxxxxx>
Date:   Sun Feb 17 12:14:27 2008 +0100

    Only look for visible objects in magnetic net mode
    
    In a large circuit the cpu load can be quite large. Checking only
    visible objects decreases the cpu load.
    The magnetic reach area is now a circle (Pythagoras). A rectangle
    gives several points with the same distance at each side.

diff --git a/gschem/src/o_net.c b/gschem/src/o_net.c
index 79c48b7..ca2296d 100644
--- a/gschem/src/o_net.c
+++ b/gschem/src/o_net.c
@@ -290,8 +290,8 @@ void o_net_find_magnetic(GSCHEM_TOPLEVEL *w_current,
 			 int x, int y)
 {
   TOPLEVEL *toplevel = w_current->toplevel;
-  int x1, x2, y1, y2, dist1, dist2;
-  int min_x, min_y, mindist, minbest;
+  int x1, x2, y1, y2, min_x, min_y;
+  double mindist, minbest, dist1, dist2;
   double weight, min_weight;
   int magnetic_reach = 0;
   OBJECT *o_current;
@@ -305,6 +305,10 @@ void o_net_find_magnetic(GSCHEM_TOPLEVEL *w_current,
        o_current != NULL;
        o_current = o_current->next) {
 
+    if (!visible(toplevel,  o_current->w_left, o_current->w_top, 
+		 o_current->w_right, o_current->w_bottom))
+      continue; /* skip invisible objects */
+
     if (o_current->type == OBJ_COMPLEX) {
       /* if the object is complex, then search for the pin that is
 	 closest to the cursor */
@@ -312,12 +316,16 @@ void o_net_find_magnetic(GSCHEM_TOPLEVEL *w_current,
 	    o_simple != NULL;
 	    o_simple = o_simple->next) {
 	if (o_simple->type == OBJ_PIN) {
+	  if (!visible(toplevel,  o_current->w_left, o_current->w_top, 
+		       o_current->w_right, o_current->w_bottom))
+	    continue; /* skip invisible pins */
+
 	  WORLDtoSCREEN(toplevel,
 			o_simple->line->x[o_simple->whichend],
 			o_simple->line->y[o_simple->whichend],
 			&x1, &y1);
-	  mindist = max(abs(x - x1), abs(y - y1));
-
+	  mindist = sqrt((double) (x - x1)*(x - x1)
+			 + (double) (y - y1)*(y - y1));
 	  weight = mindist / MAGNETIC_PIN_WEIGHT;
 	  if (o_magnetic == NULL
 	      || weight < min_weight) {
@@ -339,8 +347,10 @@ void o_net_find_magnetic(GSCHEM_TOPLEVEL *w_current,
 		    o_current->line->y[0], &x1, &y1);
       WORLDtoSCREEN(toplevel, o_current->line->x[1],
 		    o_current->line->y[1], &x2, &y2);
-      dist1 = max(abs(x - x1), abs(y - y1));
-      dist2 = max(abs(x - x2), abs(y - y2));
+      dist1 = sqrt((double) (x - x1)*(x - x1)
+		   + (double) (y - y1)*(y - y1));
+      dist2 = sqrt((double) (x - x2)*(x - x2)
+		   + (double) (y - y2)*(y - y2));
       if (dist1 < dist2) {
 	min_x = x1;
 	min_y = y1;

commit 26883a66c3711ffe04eb5280c4b49c483ca50e95
Author: Werner Hoch <werner.ho@xxxxxx>
Date:   Thu Feb 14 21:49:25 2008 +0100

    added reset function to net drawing code
    
    This reset function cleans up all variables required to draw nets.
    It is used before entering net drawing mode and should be used
    whenever the STARTDRAWNET mode is entered.
    Fixed the last drawing artefact in STARTDRAWNET state.

diff --git a/gschem/include/prototype.h b/gschem/include/prototype.h
index 7626f4f..99e2e40 100644
--- a/gschem/include/prototype.h
+++ b/gschem/include/prototype.h
@@ -637,6 +637,7 @@ int o_move_zero_length(OBJECT *object);
 void o_move_end_rubberband(GSCHEM_TOPLEVEL *w_current, int world_diff_x, int world_diff_y, GList **objects, GList **other_objects, GList **connected_objects);
 void o_move_stretch_rubberband(GSCHEM_TOPLEVEL *w_current);
 /* o_net.c */
+void o_net_reset(GSCHEM_TOPLEVEL *w_current); 
 void o_net_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current);
 void o_net_draw_xor(GSCHEM_TOPLEVEL *w_current, int dx, int dy, OBJECT *o_current);
 void o_net_draw_xor_single(GSCHEM_TOPLEVEL *w_current, int dx, int dy, int whichone, OBJECT *o_current);
diff --git a/gschem/src/i_callbacks.c b/gschem/src/i_callbacks.c
index 348d5da..41e034a 100644
--- a/gschem/src/i_callbacks.c
+++ b/gschem/src/i_callbacks.c
@@ -2338,6 +2338,7 @@ DEFINE_I_CALLBACK(add_net)
 
   o_redraw_cleanstates(w_current);	
   o_erase_rubber(w_current);
+  o_net_reset(w_current);
 
   /* need to click */
   i_update_middle_button(w_current, i_callback_add_net, _("Net"));
@@ -2360,6 +2361,7 @@ DEFINE_I_CALLBACK(add_net_hotkey)
 
   o_redraw_cleanstates(w_current);	
   o_erase_rubber(w_current);
+  o_net_reset(w_current);
 
   /* need to click */
   i_update_middle_button(w_current, i_callback_add_net_hotkey, _("Net"));
diff --git a/gschem/src/o_net.c b/gschem/src/o_net.c
index eb57879..79c48b7 100644
--- a/gschem/src/o_net.c
+++ b/gschem/src/o_net.c
@@ -48,6 +48,22 @@
 #define MAGNETIC_BUS_WEIGHT 3.0
 
 
+
+/*! \brief Reset all variables used for net drawing
+ *  \par Function Description
+ *  This function resets all variables from GSCHEM_TOPLEVEL that are used
+ *  for net drawing. This function should be called when escaping from
+ *  a net drawing action or before entering it.
+ */
+void o_net_reset(GSCHEM_TOPLEVEL *w_current) 
+{
+  w_current->start_x = w_current->start_y = -1;
+  w_current->last_x = w_current->last_y = -1;
+  w_current->second_x = w_current->second_y = -1;
+  w_current->magnetic_x = w_current->magnetic_y = -1;
+  w_current->magnetic_visible = w_current->rubbernet_visible = 0;
+}
+
 /*! \todo Finish function documentation!!!
  *  \brief
  *  \par Function Description
@@ -456,11 +472,9 @@ void o_net_finishmagnetic(GSCHEM_TOPLEVEL *w_current)
  */
 void o_net_start_magnetic(GSCHEM_TOPLEVEL *w_current, int x, int y)
 {
-  w_current->start_x = w_current->start_y = -1;
-  w_current->last_x = w_current->last_y = -1;
-  w_current->second_x = w_current->second_y = -1;
-
   o_net_eraserubber(w_current);
+  /* the dc is completely clean now, reset inside_action. */
+  w_current->inside_action = 0;
 
   o_net_find_magnetic(w_current, x, y);
 
@@ -497,6 +511,8 @@ void o_net_start(GSCHEM_TOPLEVEL *w_current, int x, int y)
  *
  * The rubber nets are removed, the nets and cues are drawn and the
  * net is added to the TOPLEVEL structure.  
+ *
+ * The function returns TRUE if it has drawn a net, FALSE otherwise.
  */
 int o_net_end(GSCHEM_TOPLEVEL *w_current, int x, int y)
 {
@@ -544,19 +560,9 @@ int o_net_end(GSCHEM_TOPLEVEL *w_current, int x, int y)
       (w_current->last_y == w_current->second_y);
 
   /* If both nets are zero length... */
-  /* this ends the net drawing behavior we want this? hack */
+  /* this ends the net drawing behavior */
   if ( primary_zero_length && secondary_zero_length ) {
-    w_current->start_x = (-1);
-    w_current->start_y = (-1);
-    w_current->last_x = (-1);
-    w_current->last_y = (-1);
-    w_current->second_x = (-1);
-    w_current->second_y = (-1);
-    w_current->inside_action = 0;
-    i_set_state(w_current, STARTDRAWNET);
-    o_net_eraserubber(w_current);
-    
-    return (FALSE);
+    return FALSE;
   }
 
   /* Primary net runs from (x1,y1)-(x2,y2) */
@@ -778,6 +784,7 @@ void o_net_drawrubber(GSCHEM_TOPLEVEL *w_current)
       w_current->magnetic_x = fix_x(toplevel, w_current->magnetic_x);
       w_current->magnetic_y = fix_y(toplevel, w_current->magnetic_y);
       w_current->magnetic_visible = 1;
+      w_current->inside_action = 1;
       gdk_draw_arc(w_current->backingstore, w_current->xor_gc, FALSE,
 		   w_current->magnetic_x - MAGNETIC_HALFSIZE,
 		   w_current->magnetic_y - MAGNETIC_HALFSIZE,
@@ -840,20 +847,18 @@ void o_net_eraserubber(GSCHEM_TOPLEVEL *w_current)
 
   w_current->rubbernet_visible = 0;
 
-  if (w_current->magneticnet_mode) {
-    if (w_current->magnetic_visible == 1) {
-      w_current->magnetic_visible = 0;
-      gdk_draw_arc(w_current->backingstore, w_current->xor_gc, FALSE,
-		   w_current->magnetic_x - MAGNETIC_HALFSIZE,
-		   w_current->magnetic_y - MAGNETIC_HALFSIZE,
-		   2*MAGNETIC_HALFSIZE, 2*MAGNETIC_HALFSIZE,
-		   0, FULL_CIRCLE);
-      o_invalidate_rect(w_current,
-			w_current->magnetic_x - MAGNETIC_HALFSIZE,
-			w_current->magnetic_y - MAGNETIC_HALFSIZE,
-			w_current->magnetic_x + MAGNETIC_HALFSIZE,
-			w_current->magnetic_y + MAGNETIC_HALFSIZE);
-    }
+  if (w_current->magnetic_visible) {
+    w_current->magnetic_visible = 0;
+    gdk_draw_arc(w_current->backingstore, w_current->xor_gc, FALSE,
+		 w_current->magnetic_x - MAGNETIC_HALFSIZE,
+		 w_current->magnetic_y - MAGNETIC_HALFSIZE,
+		 2*MAGNETIC_HALFSIZE, 2*MAGNETIC_HALFSIZE,
+		 0, FULL_CIRCLE);
+    o_invalidate_rect(w_current,
+		      w_current->magnetic_x - MAGNETIC_HALFSIZE,
+		      w_current->magnetic_y - MAGNETIC_HALFSIZE,
+		      w_current->magnetic_x + MAGNETIC_HALFSIZE,
+		      w_current->magnetic_y + MAGNETIC_HALFSIZE);
   }
 
   if (toplevel->net_style == THICK) {
diff --git a/gschem/src/x_event.c b/gschem/src/x_event.c
index 35e3f2f..61cc1b2 100644
--- a/gschem/src/x_event.c
+++ b/gschem/src/x_event.c
@@ -309,6 +309,12 @@ gint x_event_button_pressed(GtkWidget *widget, GdkEventButton *event,
                       (int) w_current->save_y);
           w_current->event_state=NETCONT;
         }
+	else { /* cleanup and start a new net */
+	  o_net_eraserubber(w_current);
+	  o_net_reset(w_current);
+	  i_set_state(w_current, STARTDRAWNET);
+	  w_current->inside_action = 0;
+	}
         break;
 
       case(DRAWBUS):
@@ -531,6 +537,7 @@ gint x_event_button_pressed(GtkWidget *widget, GdkEventButton *event,
         w_current->inside_action = 0;
 	i_set_state(w_current, STARTDRAWNET);
         o_net_eraserubber(w_current);
+	o_net_reset(w_current);
         break;
 
         case(STARTDRAWBUS):

commit aa26da60b8c2a7e66c8b4d6446e7b67de2c3537a
Author: Werner Hoch <werner.ho@xxxxxx>
Date:   Wed Feb 13 21:38:54 2008 +0100

    misc cosmetic corrections for the magnetic net
    
    Put the magnetic marker onto grid (fix_x/y)
    Changed the marker from a rectangle to a circle.
    Changed the calculation of the magnetic reach from x+y to max(x,y).
    This enlarges the reach into the 45° direction.

diff --git a/gschem/src/o_net.c b/gschem/src/o_net.c
index 3400e1e..eb57879 100644
--- a/gschem/src/o_net.c
+++ b/gschem/src/o_net.c
@@ -34,7 +34,7 @@
 
 
 /* magnetic options */
-/* size of the magnetic marker on the screen. */
+/* half size of the magnetic marker on the screen. */
 #define MAGNETIC_HALFSIZE 6
 
 /* define how far the cursor could be to activate magnetic */
@@ -43,9 +43,9 @@
 #define MAGNETIC_BUS_REACH 30
 
 /* weighting factors to tell that a pin is more important than a net */
-#define MAGNETIC_PIN_WEIGHT 3
-#define MAGNETIC_NET_WEIGHT 1
-#define MAGNETIC_BUS_WEIGHT 2
+#define MAGNETIC_PIN_WEIGHT 5.0
+#define MAGNETIC_NET_WEIGHT 2.0
+#define MAGNETIC_BUS_WEIGHT 3.0
 
 
 /*! \todo Finish function documentation!!!
@@ -276,7 +276,7 @@ void o_net_find_magnetic(GSCHEM_TOPLEVEL *w_current,
   TOPLEVEL *toplevel = w_current->toplevel;
   int x1, x2, y1, y2, dist1, dist2;
   int min_x, min_y, mindist, minbest;
-  int weight, min_weight;
+  double weight, min_weight;
   int magnetic_reach = 0;
   OBJECT *o_current;
   OBJECT *o_simple;
@@ -300,7 +300,7 @@ void o_net_find_magnetic(GSCHEM_TOPLEVEL *w_current,
 			o_simple->line->x[o_simple->whichend],
 			o_simple->line->y[o_simple->whichend],
 			&x1, &y1);
-	  mindist = abs(x - x1) + abs(y - y1);
+	  mindist = max(abs(x - x1), abs(y - y1));
 
 	  weight = mindist / MAGNETIC_PIN_WEIGHT;
 	  if (o_magnetic == NULL
@@ -323,8 +323,8 @@ void o_net_find_magnetic(GSCHEM_TOPLEVEL *w_current,
 		    o_current->line->y[0], &x1, &y1);
       WORLDtoSCREEN(toplevel, o_current->line->x[1],
 		    o_current->line->y[1], &x2, &y2);
-      dist1 = abs(x - x1) + abs(y - y1);
-      dist2 = abs(x - x2) + abs(y - y2);
+      dist1 = max(abs(x - x1), abs(y - y1));
+      dist2 = max(abs(x - x2), abs(y - y2));
       if (dist1 < dist2) {
 	min_x = x1;
 	min_y = y1;
@@ -775,12 +775,14 @@ void o_net_drawrubber(GSCHEM_TOPLEVEL *w_current)
 
   if (w_current->magneticnet_mode) {
     if (w_current->magnetic_x != -1 && w_current->magnetic_y != -1) {
+      w_current->magnetic_x = fix_x(toplevel, w_current->magnetic_x);
+      w_current->magnetic_y = fix_y(toplevel, w_current->magnetic_y);
       w_current->magnetic_visible = 1;
-      gdk_draw_rectangle(w_current->backingstore, w_current->xor_gc,
-			 TRUE,
-			 w_current->magnetic_x - MAGNETIC_HALFSIZE,
-			 w_current->magnetic_y - MAGNETIC_HALFSIZE,
-			 2*MAGNETIC_HALFSIZE, 2*MAGNETIC_HALFSIZE);
+      gdk_draw_arc(w_current->backingstore, w_current->xor_gc, FALSE,
+		   w_current->magnetic_x - MAGNETIC_HALFSIZE,
+		   w_current->magnetic_y - MAGNETIC_HALFSIZE,
+		   2*MAGNETIC_HALFSIZE, 2*MAGNETIC_HALFSIZE,
+		   0, FULL_CIRCLE);
       o_invalidate_rect(w_current, 
 			w_current->magnetic_x - MAGNETIC_HALFSIZE,
 			w_current->magnetic_y - MAGNETIC_HALFSIZE,
@@ -839,13 +841,13 @@ void o_net_eraserubber(GSCHEM_TOPLEVEL *w_current)
   w_current->rubbernet_visible = 0;
 
   if (w_current->magneticnet_mode) {
-    if (w_current->magnetic_x != -1 && w_current->magnetic_y != -1) {
+    if (w_current->magnetic_visible == 1) {
       w_current->magnetic_visible = 0;
-      gdk_draw_rectangle(w_current->backingstore, w_current->xor_gc,
-			 TRUE,
-			 w_current->magnetic_x - MAGNETIC_HALFSIZE,
-			 w_current->magnetic_y - MAGNETIC_HALFSIZE,
-			 2*MAGNETIC_HALFSIZE, 2*MAGNETIC_HALFSIZE);
+      gdk_draw_arc(w_current->backingstore, w_current->xor_gc, FALSE,
+		   w_current->magnetic_x - MAGNETIC_HALFSIZE,
+		   w_current->magnetic_y - MAGNETIC_HALFSIZE,
+		   2*MAGNETIC_HALFSIZE, 2*MAGNETIC_HALFSIZE,
+		   0, FULL_CIRCLE);
       o_invalidate_rect(w_current,
 			w_current->magnetic_x - MAGNETIC_HALFSIZE,
 			w_current->magnetic_y - MAGNETIC_HALFSIZE,

commit 6e092d15b6e1881789561653ded80f98c5bdc2f5
Author: Werner Hoch <werner.ho@xxxxxx>
Date:   Sat Feb 9 12:56:09 2008 +0100

    connect the magnetic net mode into the net drawing functions
    
    The magnetic net mode is now use to set the start net point, track the
    closest connection in the rubbernet function and to get the end point
    of the net. The endpoint in the magnetic mode is calculated in the new
    function o_net_finishmagnetic.
    
    This commit is based on the patch written by Franz Mottas and Thomas
    Arndt [#1824420].

diff --git a/gschem/include/prototype.h b/gschem/include/prototype.h
index e3fb991..7626f4f 100644
--- a/gschem/include/prototype.h
+++ b/gschem/include/prototype.h
@@ -641,6 +641,7 @@ void o_net_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current);
 void o_net_draw_xor(GSCHEM_TOPLEVEL *w_current, int dx, int dy, OBJECT *o_current);
 void o_net_draw_xor_single(GSCHEM_TOPLEVEL *w_current, int dx, int dy, int whichone, OBJECT *o_current);
 void o_net_find_magnetic(GSCHEM_TOPLEVEL *w_current, int event_x, int event_y);
+void o_net_finishmagnetic(GSCHEM_TOPLEVEL *w_current);
 void o_net_start_magnetic(GSCHEM_TOPLEVEL *w_current, int x, int y);
 void o_net_start(GSCHEM_TOPLEVEL *w_current, int x, int y);
 int o_net_end(GSCHEM_TOPLEVEL *w_current, int x, int y);
diff --git a/gschem/src/o_net.c b/gschem/src/o_net.c
index 6d3adc6..3400e1e 100644
--- a/gschem/src/o_net.c
+++ b/gschem/src/o_net.c
@@ -389,7 +389,65 @@ void o_net_find_magnetic(GSCHEM_TOPLEVEL *w_current,
   }
 }
 
+/*! \brief calcutates the net route to the magnetic marker
+ *  \par Function Description
+ *  Depending on the two rubbernet lines from start to last and from
+ *  last to second, the 3 coordinates are manipulated to find
+ *  a way to the magnetic marker.
+ */
+void o_net_finishmagnetic(GSCHEM_TOPLEVEL *w_current)
+{
+  int primary_zero_length, secondary_zero_length;
 
+  primary_zero_length = ((w_current->start_x == w_current->last_x) 
+			 && (w_current->start_y == w_current->last_y));
+ 
+  secondary_zero_length = ((w_current->last_x == w_current->second_x) 
+			   && (w_current->last_y == w_current->second_y));
+
+  if (!primary_zero_length && secondary_zero_length) {
+    if (w_current->start_x == w_current->last_x) {
+      /* expand vertical line to magnetic_y */
+      w_current->last_y = w_current->magnetic_y;
+    }
+    else if (w_current->start_y == w_current->last_y) {
+      /* expand horitontal line to vertical to magnetic_x */
+      w_current->last_x = w_current->magnetic_x;
+    }
+    /* connect to magnetic */
+    w_current->second_x = w_current->magnetic_x;
+    w_current->second_y = w_current->magnetic_y;
+  }
+
+  if (primary_zero_length && !secondary_zero_length) {
+    /* move second line to the first (empty line) */
+    w_current->start_x = w_current->last_x;
+    w_current->start_y = w_current->last_y;
+    if (w_current->last_x == w_current->second_x) {
+      /* expand vertical line to magnetic_y */
+      w_current->last_y = w_current->magnetic_y;
+    }
+    else if (w_current->last_y == w_current->second_y) {
+      /* expand horitontal line to magnetic_x */
+      w_current->last_x = w_current->magnetic_x;
+    }
+    /* connect to magnetic */
+    w_current->second_x = w_current->magnetic_x;
+    w_current->second_y = w_current->magnetic_y;
+  }
+
+  if (!primary_zero_length && !secondary_zero_length) {
+    /* expand line in both directions */
+    if (w_current->start_x == w_current->last_x) {
+      w_current->last_y = w_current->magnetic_y;
+    }
+    else {
+      w_current->last_x = w_current->magnetic_x;
+    }
+    w_current->second_x = w_current->magnetic_x;
+    w_current->second_y = w_current->magnetic_y;
+  }
+}
 
 /*! \brief callback function to draw a net marker in magnetic mode
  *  \par Function Description
@@ -412,13 +470,18 @@ void o_net_start_magnetic(GSCHEM_TOPLEVEL *w_current, int x, int y)
 /*! \brief set the start point of a new net
  *  \par Function Description
  *  This function sets the start point of a new net at the position of the 
- *  cursor.
+ *  cursor. If we have a visible magnetic marker, we use that instead of 
+ *  the cursor position
  */
 void o_net_start(GSCHEM_TOPLEVEL *w_current, int x, int y)
 {
   TOPLEVEL *toplevel = w_current->toplevel;
 
-  /* initalize all parameters used when drawing the new net */
+  if (w_current->magnetic_visible) {
+    x = w_current->magnetic_x;
+    y = w_current->magnetic_y;
+  }
+
   w_current->last_x = w_current->start_x = w_current->second_x = 
     fix_x(toplevel, x);
   w_current->last_y = w_current->start_y = w_current->second_y = 
@@ -426,11 +489,14 @@ void o_net_start(GSCHEM_TOPLEVEL *w_current, int x, int y)
 
 }
 
-/*! \brief finish a net drawing action
- *  \par Function Description
- *  This function finishes the drawing of a net. The rubber nets are
- *  removed, the nets and cues are drawn and the net is added to the
- *  TOPLEVEL structure.
+/*! \brief finish a net drawing action 
+ * \par Function Description 
+ * This function finishes the drawing of a net. If we have a visible
+ * magnetic marker, we use that instead of the current cursor
+ * position.
+ *
+ * The rubber nets are removed, the nets and cues are drawn and the
+ * net is added to the TOPLEVEL structure.  
  */
 int o_net_end(GSCHEM_TOPLEVEL *w_current, int x, int y)
 {
@@ -443,20 +509,25 @@ int o_net_end(GSCHEM_TOPLEVEL *w_current, int x, int y)
   int primary_zero_length, secondary_zero_length;
   int found_primary_connection = FALSE;
   int sx[2], sy[2];
+  int save_magnetic;
 
-  /*int temp_x, temp_y;*/
-  /* OBJECT *o_current;*/
   GList *other_objects = NULL;
   OBJECT *new_net = NULL;
 
   g_assert( w_current->inside_action != 0 );
 
+  /* I've to store that because o_net_eraserubber would delete it
+     but I need it for o_net_finish_magnetic */
+  save_magnetic = w_current->magnetic_visible;
 
   gdk_gc_set_foreground(w_current->xor_gc,
 			x_get_darkcolor(w_current->select_color) );
 
   o_net_eraserubber(w_current);
 
+  if (save_magnetic)
+    o_net_finishmagnetic(w_current);
+
   if (toplevel->net_style == THICK) {
     size = SCREENabs(toplevel, NET_WIDTH);
     gdk_gc_set_line_attributes(w_current->gc, size,
@@ -464,7 +535,6 @@ int o_net_end(GSCHEM_TOPLEVEL *w_current, int x, int y)
 			       GDK_CAP_NOT_LAST, GDK_JOIN_MITER);
   }
 
-
   /* See if either of the nets are zero length.  We'll only add */
   /* the non-zero ones */
   primary_zero_length = (w_current->start_x == w_current->last_x) &&
@@ -658,6 +728,9 @@ void o_net_rubbernet(GSCHEM_TOPLEVEL *w_current, int x, int y)
   
   o_net_eraserubber(w_current);
 
+  if (w_current->magneticnet_mode)
+    o_net_find_magnetic(w_current, x, y);
+
   /* In orthogonal mode secondary line is the same as the first */
   if (!ortho)
   {

commit 96fbd6214a4a364d0aa45b405293421623ea939c
Author: Werner Hoch <werner.ho@xxxxxx>
Date:   Sat Feb 9 11:09:10 2008 +0100

    core code for magnetic net mode: find connections and draw marker
    
    When in STARTDRAWNET state, search for the closest connection.
    Added code to search for that connection and to draw and erase
    a rectangular magnetic net marker.
    
    This commit is based on the patch written by Franz Mottas and Thomas
    Arndt [#1824420].

diff --git a/gschem/include/prototype.h b/gschem/include/prototype.h
index 79c0979..e3fb991 100644
--- a/gschem/include/prototype.h
+++ b/gschem/include/prototype.h
@@ -640,6 +640,8 @@ void o_move_stretch_rubberband(GSCHEM_TOPLEVEL *w_current);
 void o_net_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current);
 void o_net_draw_xor(GSCHEM_TOPLEVEL *w_current, int dx, int dy, OBJECT *o_current);
 void o_net_draw_xor_single(GSCHEM_TOPLEVEL *w_current, int dx, int dy, int whichone, OBJECT *o_current);
+void o_net_find_magnetic(GSCHEM_TOPLEVEL *w_current, int event_x, int event_y);
+void o_net_start_magnetic(GSCHEM_TOPLEVEL *w_current, int x, int y);
 void o_net_start(GSCHEM_TOPLEVEL *w_current, int x, int y);
 int o_net_end(GSCHEM_TOPLEVEL *w_current, int x, int y);
 void o_net_rubbernet(GSCHEM_TOPLEVEL *w_current, int x, int y);
diff --git a/gschem/src/i_callbacks.c b/gschem/src/i_callbacks.c
index 34f4999..348d5da 100644
--- a/gschem/src/i_callbacks.c
+++ b/gschem/src/i_callbacks.c
@@ -3361,7 +3361,7 @@ DEFINE_I_CALLBACK(options_magneticnet)
 {
   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
 
-  if (w_current->magneticnet_mode = ! w_current->magneticnet_mode){
+  if ((w_current->magneticnet_mode = !w_current->magneticnet_mode)) {
     s_log_message(_("magnetic net mode: ON\n"));
   }
   else {
diff --git a/gschem/src/o_basic.c b/gschem/src/o_basic.c
index ea5c279..8122e24 100644
--- a/gschem/src/o_basic.c
+++ b/gschem/src/o_basic.c
@@ -90,6 +90,7 @@ void o_redraw_all(GSCHEM_TOPLEVEL *w_current)
       case(DRAWNET):
       case(NETCONT):
         w_current->rubbernet_visible=0;
+	w_current->magnetic_visible=0;
         break;
     }
   }
diff --git a/gschem/src/o_net.c b/gschem/src/o_net.c
index aa3d07c..6d3adc6 100644
--- a/gschem/src/o_net.c
+++ b/gschem/src/o_net.c
@@ -32,6 +32,22 @@
 #include <dmalloc.h>
 #endif
 
+
+/* magnetic options */
+/* size of the magnetic marker on the screen. */
+#define MAGNETIC_HALFSIZE 6
+
+/* define how far the cursor could be to activate magnetic */
+#define MAGNETIC_PIN_REACH 50 
+#define MAGNETIC_NET_REACH 20
+#define MAGNETIC_BUS_REACH 30
+
+/* weighting factors to tell that a pin is more important than a net */
+#define MAGNETIC_PIN_WEIGHT 3
+#define MAGNETIC_NET_WEIGHT 1
+#define MAGNETIC_BUS_WEIGHT 2
+
+
 /*! \todo Finish function documentation!!!
  *  \brief
  *  \par Function Description
@@ -244,6 +260,155 @@ void o_net_draw_xor_single(GSCHEM_TOPLEVEL *w_current, int dx, int dy, int which
 
 }
 
+/*! \brief find the closest possible location to connect to
+ *  \par Function Description
+ *  This function calculates the distance to all connectable objects 
+ *  and searches the closest connection point.
+ *  It searches for pins, nets and busses.
+ *  
+ *  The connection point is stored in GSCHEM_TOPLEVEL->magnetic_x and
+ *  GSCHEM_TOPLEVEL->magnetic_y. If no connection is found. Both variables
+ *  are set to -1.
+ */
+void o_net_find_magnetic(GSCHEM_TOPLEVEL *w_current,
+			 int x, int y)
+{
+  TOPLEVEL *toplevel = w_current->toplevel;
+  int x1, x2, y1, y2, dist1, dist2;
+  int min_x, min_y, mindist, minbest;
+  int weight, min_weight;
+  int magnetic_reach = 0;
+  OBJECT *o_current;
+  OBJECT *o_simple;
+  OBJECT *o_magnetic = NULL;
+
+  minbest = min_x = min_y = 0;
+  min_weight = 0;
+
+  for (o_current = toplevel->page_current->object_head->next;
+       o_current != NULL;
+       o_current = o_current->next) {
+
+    if (o_current->type == OBJ_COMPLEX) {
+      /* if the object is complex, then search for the pin that is
+	 closest to the cursor */
+      for  (o_simple = o_current->complex->prim_objs->next;
+	    o_simple != NULL;
+	    o_simple = o_simple->next) {
+	if (o_simple->type == OBJ_PIN) {
+	  WORLDtoSCREEN(toplevel,
+			o_simple->line->x[o_simple->whichend],
+			o_simple->line->y[o_simple->whichend],
+			&x1, &y1);
+	  mindist = abs(x - x1) + abs(y - y1);
+
+	  weight = mindist / MAGNETIC_PIN_WEIGHT;
+	  if (o_magnetic == NULL
+	      || weight < min_weight) {
+	    minbest = mindist;
+	    min_weight = weight;
+	    o_magnetic = o_simple;
+	    w_current->magnetic_x = x1;
+	    w_current->magnetic_y = y1;
+	  }
+	}
+      }
+    }
+
+    if (o_current->type == OBJ_NET
+	|| o_current->type == OBJ_BUS) {
+      /* we have 3 possible points to connect: 
+	 2 endpoints and 1 intersect point */
+      WORLDtoSCREEN(toplevel, o_current->line->x[0],
+		    o_current->line->y[0], &x1, &y1);
+      WORLDtoSCREEN(toplevel, o_current->line->x[1],
+		    o_current->line->y[1], &x2, &y2);
+      dist1 = abs(x - x1) + abs(y - y1);
+      dist2 = abs(x - x2) + abs(y - y2);
+      if (dist1 < dist2) {
+	min_x = x1;
+	min_y = y1;
+	mindist = dist1;
+      }
+      else {
+	min_x = x2;
+	min_y = y2;
+	mindist = dist2;
+      }
+      
+      if ((x1 == x2)  /* vertical net */
+	  && ((y1 >= y && y >= y2)
+	      || (y2 >= y && y >= y1))) {
+	if (abs(x - x1) < mindist) {
+	  mindist = abs(x - x1);
+	  min_x = x1;
+	  min_y = y;
+	}
+      } 
+      if ((y1 == y2)  /* horitontal net */
+	  && ((x1 >= x && x >= x2)
+	      || (x2 >= x && x >= x1))) {  
+	if (abs(y - y1) < mindist) {
+	  mindist = abs(y - y1);
+	  min_x = x;
+	  min_y = y1;
+	}
+      }
+
+      if (o_current->type == OBJ_BUS)
+	weight = mindist / MAGNETIC_BUS_WEIGHT;
+      else /* OBJ_NET */
+	weight = mindist / MAGNETIC_NET_WEIGHT;
+
+      if (o_magnetic == NULL
+	  || weight < min_weight) {
+	minbest = mindist;
+	min_weight = weight;
+	o_magnetic = o_current;
+	w_current->magnetic_x = min_x;
+	w_current->magnetic_y = min_y;
+      }
+    }
+  } 
+
+  /* check whether we found an object and if it's close enough */
+  if (o_magnetic != NULL) {
+    switch (o_magnetic->type) {
+    case (OBJ_PIN): magnetic_reach = MAGNETIC_PIN_REACH; break;
+    case (OBJ_NET): magnetic_reach = MAGNETIC_NET_REACH; break;
+    case (OBJ_BUS): magnetic_reach = MAGNETIC_BUS_REACH; break;
+    }
+    if (minbest > magnetic_reach) {
+      w_current->magnetic_x = -1;
+      w_current->magnetic_y = -1;
+    }
+  }
+  else {
+    w_current->magnetic_x = -1;
+    w_current->magnetic_y = -1;
+  }
+}
+
+
+
+/*! \brief callback function to draw a net marker in magnetic mode
+ *  \par Function Description
+ *  If the mouse is moved, this function is called to update the 
+ *  position of the magnetic marker.
+ */
+void o_net_start_magnetic(GSCHEM_TOPLEVEL *w_current, int x, int y)
+{
+  w_current->start_x = w_current->start_y = -1;
+  w_current->last_x = w_current->last_y = -1;
+  w_current->second_x = w_current->second_y = -1;
+
+  o_net_eraserubber(w_current);
+
+  o_net_find_magnetic(w_current, x, y);
+
+  o_net_drawrubber(w_current);
+}
+
 /*! \brief set the start point of a new net
  *  \par Function Description
  *  This function sets the start point of a new net at the position of the 
@@ -535,6 +700,22 @@ void o_net_drawrubber(GSCHEM_TOPLEVEL *w_current)
 
   w_current->rubbernet_visible = 1;
 
+  if (w_current->magneticnet_mode) {
+    if (w_current->magnetic_x != -1 && w_current->magnetic_y != -1) {
+      w_current->magnetic_visible = 1;
+      gdk_draw_rectangle(w_current->backingstore, w_current->xor_gc,
+			 TRUE,
+			 w_current->magnetic_x - MAGNETIC_HALFSIZE,
+			 w_current->magnetic_y - MAGNETIC_HALFSIZE,
+			 2*MAGNETIC_HALFSIZE, 2*MAGNETIC_HALFSIZE);
+      o_invalidate_rect(w_current, 
+			w_current->magnetic_x - MAGNETIC_HALFSIZE,
+			w_current->magnetic_y - MAGNETIC_HALFSIZE,
+			w_current->magnetic_x + MAGNETIC_HALFSIZE,
+			w_current->magnetic_y + MAGNETIC_HALFSIZE);
+    }
+  }
+
   if (toplevel->net_style == THICK) {
     size = SCREENabs(toplevel, NET_WIDTH);
     gdk_gc_set_line_attributes(w_current->xor_gc, size,
@@ -584,6 +765,22 @@ void o_net_eraserubber(GSCHEM_TOPLEVEL *w_current)
 
   w_current->rubbernet_visible = 0;
 
+  if (w_current->magneticnet_mode) {
+    if (w_current->magnetic_x != -1 && w_current->magnetic_y != -1) {
+      w_current->magnetic_visible = 0;
+      gdk_draw_rectangle(w_current->backingstore, w_current->xor_gc,
+			 TRUE,
+			 w_current->magnetic_x - MAGNETIC_HALFSIZE,
+			 w_current->magnetic_y - MAGNETIC_HALFSIZE,
+			 2*MAGNETIC_HALFSIZE, 2*MAGNETIC_HALFSIZE);
+      o_invalidate_rect(w_current,
+			w_current->magnetic_x - MAGNETIC_HALFSIZE,
+			w_current->magnetic_y - MAGNETIC_HALFSIZE,
+			w_current->magnetic_x + MAGNETIC_HALFSIZE,
+			w_current->magnetic_y + MAGNETIC_HALFSIZE);
+    }
+  }
+
   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 716fe24..35e3f2f 100644
--- a/gschem/src/x_event.c
+++ b/gschem/src/x_event.c
@@ -1080,6 +1080,16 @@ gint x_event_motion(GtkWidget *widget, GdkEventMotion *event,
 					(int) event->y, ARC_RADIUS);
     break;
 
+
+    case(STARTDRAWNET):
+    if(w_current->magneticnet_mode == 1) {
+      o_net_start_magnetic(w_current,
+			   (int) event->x,
+			   (int) event->y);
+    }
+
+    break;
+
     case(DRAWNET):
     case(NETCONT):
     if (w_current->inside_action)

commit 3a412167fe7e16526fafdfea273b3daf8be207b3
Author: Werner Hoch <werner.ho@xxxxxx>
Date:   Sat Feb 9 08:54:45 2008 +0100

    added menu entry and callbacks for magnetic net mode
    
    Added a entry into the options menu to toggle the magnetic net mode.
    Added all required variables in GSCHEM_TOPLEVEL.
    
    This commit is based on the patch written by Franz Mottas and Thomas
    Arndt [#1824420].

diff --git a/gschem/include/gschem_struct.h b/gschem/include/gschem_struct.h
index c7c7f50..f90e7af 100644
--- a/gschem/include/gschem_struct.h
+++ b/gschem/include/gschem_struct.h
@@ -94,12 +94,14 @@ struct st_gschem_toplevel {
   int second_x;
   int second_y;
   int loc_x, loc_y;
+  int magnetic_x, magnetic_y;           /* Position of the magnetic marker*/
   int distance;
   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
-					   the drawing area? */
+					   the screen? */
+  int magnetic_visible;                 /* Is the magnetic marker visible */
 
   /* --------------------- */
   /* Gschem internal state */
@@ -185,6 +187,7 @@ struct st_gschem_toplevel {
   int bus_ripper_rotation;  /* sets if the the bus ripper is symmetric or not */
   int grid_dot_size;      /* sets the grid dot size */
   int grid_mode;      /* sets the mode of the grid (either variable or fixed) */
+  int magneticnet_mode; /* enables/disables the magnetic net mode ON/OFF */
 
   /* sets the mininum number of pixels necessary for the grid to be */
   /* displayed */
diff --git a/gschem/include/prototype.h b/gschem/include/prototype.h
index 5c63fa8..79c0979 100644
--- a/gschem/include/prototype.h
+++ b/gschem/include/prototype.h
@@ -172,6 +172,7 @@ SCM g_keys_options_snap_size(void);
 SCM g_keys_options_scale_up_snap_size(void);
 SCM g_keys_options_scale_down_snap_size(void);
 SCM g_keys_options_rubberband(void);
+SCM g_keys_options_magneticnet(void);
 SCM g_keys_options_show_log_window(void);
 SCM g_keys_options_show_coord_window(void);
 SCM g_keys_misc(void);
@@ -434,6 +435,7 @@ void i_callback_options_afeedback(gpointer data, guint callback_action, GtkWidge
 void i_callback_options_grid(gpointer data, guint callback_action, GtkWidget *widget);
 void i_callback_options_snap(gpointer data, guint callback_action, GtkWidget *widget);
 void i_callback_options_rubberband(gpointer data, guint callback_action, GtkWidget *widget);
+void i_callback_options_magneticnet(gpointer data, guint callback_action, GtkWidget *widget);
 void i_callback_options_show_log_window(gpointer data, guint callback_action, GtkWidget *widget);
 void i_callback_misc(gpointer data, guint callback_action, GtkWidget *widget);
 void i_callback_misc2(gpointer data, guint callback_action, GtkWidget *widget);
diff --git a/gschem/lib/system-gschemrc.in b/gschem/lib/system-gschemrc.in
index a934ecd..16aca18 100644
--- a/gschem/lib/system-gschemrc.in
+++ b/gschem/lib/system-gschemrc.in
@@ -1229,6 +1229,7 @@
     ("g" . options-grid)
     ("s" . options-snap)
     ("r" . options-rubberband)
+    ("m" . options-magneticnet)
     ("Shift S" . options-snap-size)
     ("l" . options-show-log-window)
     ("c" . options-show-coord-window)))
@@ -1480,6 +1481,7 @@
 	   ("Toggle Outline/Box"   options-action-feedback   	
 				   options-action-feedback)
 	   ("Toggle Net Rubberband" options-rubberband   options-rubberband)
+	   ("Toggle Magnetic Net" options-magneticnet options-magneticnet)
 	   ("Show Log Window..."    options-show-log-window   
 	 			    options-show-log-window)
 	   ("Show Coord Window..."   options-show-coord-window   
diff --git a/gschem/src/g_keys.c b/gschem/src/g_keys.c
index b01db41..20042a9 100644
--- a/gschem/src/g_keys.c
+++ b/gschem/src/g_keys.c
@@ -355,6 +355,7 @@ DEFINE_G_KEYS(options_snap_size)
 DEFINE_G_KEYS(options_scale_up_snap_size)
 DEFINE_G_KEYS(options_scale_down_snap_size)
 DEFINE_G_KEYS(options_rubberband)
+DEFINE_G_KEYS(options_magneticnet)
 DEFINE_G_KEYS(options_show_log_window)
 DEFINE_G_KEYS(options_show_coord_window)
 DEFINE_G_KEYS(misc)
diff --git a/gschem/src/g_register.c b/gschem/src/g_register.c
index da021f1..1bb5f86 100644
--- a/gschem/src/g_register.c
+++ b/gschem/src/g_register.c
@@ -299,6 +299,7 @@ static struct gsubr_t gschem_funcs[] = {
   { "options-grid",              0, 0, 0, g_keys_options_grid },
   { "options-snap",              0, 0, 0, g_keys_options_snap },
   { "options-rubberband",        0, 0, 0, g_keys_options_rubberband },
+  { "options-magneticnet",       0, 0, 0, g_keys_options_magneticnet },
   { "options-show-log-window",   0, 0, 0, g_keys_options_show_log_window },
   { "options-show-coord-window", 0, 0, 0, g_keys_options_show_coord_window },
   { "help-about",                0, 0, 0, g_keys_help_about },
diff --git a/gschem/src/gschem_toplevel.c b/gschem/src/gschem_toplevel.c
index 09dc5aa..4825c3b 100644
--- a/gschem/src/gschem_toplevel.c
+++ b/gschem/src/gschem_toplevel.c
@@ -120,9 +120,12 @@ GSCHEM_TOPLEVEL *gschem_toplevel_new ()
   w_current->loc_x = -1;
   w_current->loc_y = -1;
   w_current->distance = -1;
+  w_current->magnetic_x = -1;
+  w_current->magnetic_y = -1;
   w_current->inside_action = 0;
   w_current->rotated_inside = 0;
   w_current->rubbernet_visible = 0;
+  w_current->magnetic_visible = 0;
 
   /* --------------------- */
   /* Gschem internal state */
@@ -200,6 +203,7 @@ GSCHEM_TOPLEVEL *gschem_toplevel_new ()
   w_current->bus_ripper_rotation = 0;
   w_current->grid_dot_size = 1;
   w_current->grid_mode = GRID_VARIABLE_MODE;
+  w_current->magneticnet_mode = 0;
   w_current->grid_fixed_threshold = 10;
   w_current->add_attribute_offset = 50;
   w_current->drag_can_move = TRUE;
diff --git a/gschem/src/i_callbacks.c b/gschem/src/i_callbacks.c
index a4e0fa6..34f4999 100644
--- a/gschem/src/i_callbacks.c
+++ b/gschem/src/i_callbacks.c
@@ -3351,6 +3351,25 @@ DEFINE_I_CALLBACK(options_rubberband)
   }
 }
 
+
+/*! \brief callback function for setting the magnetic net option
+ *  \par Function Description
+ *  This function just toggles a variable to switch the magnetic net
+ *  mode ON and OFF
+ */
+DEFINE_I_CALLBACK(options_magneticnet)
+{
+  GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
+
+  if (w_current->magneticnet_mode = ! w_current->magneticnet_mode){
+    s_log_message(_("magnetic net mode: ON\n"));
+  }
+  else {
+    s_log_message(_("magnetic net mode: OFF\n"));
+  }
+}
+
+
 /*! \todo Finish function documentation!!!
  *  \brief
  *  \par Function Description

commit 1d1c604d63bfe8f6eff91749953ba713f7b3745c
Author: Werner Hoch <werner.ho@xxxxxx>
Date:   Sat Feb 9 08:11:38 2008 +0100

    fix drawing artefact when drawing a net and zoom/pan
    
    Zooming and paning redraw everything and if there are rubbernets
    they get deleted, too. We have to tell the rubbernet function that
    the rubbernet is no longer on the screen.
    Thus I've added a flag rubbernet_visible as indicator. This flag needs
    to be set when drawing, and reset when the rubbernet gets erased.

diff --git a/gschem/include/gschem_struct.h b/gschem/include/gschem_struct.h
index c99c29f..c7c7f50 100644
--- a/gschem/include/gschem_struct.h
+++ b/gschem/include/gschem_struct.h
@@ -98,6 +98,8 @@ 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
+					   the drawing area? */
 
   /* --------------------- */
   /* Gschem internal state */
diff --git a/gschem/src/gschem_toplevel.c b/gschem/src/gschem_toplevel.c
index bc8493c..09dc5aa 100644
--- a/gschem/src/gschem_toplevel.c
+++ b/gschem/src/gschem_toplevel.c
@@ -122,6 +122,7 @@ GSCHEM_TOPLEVEL *gschem_toplevel_new ()
   w_current->distance = -1;
   w_current->inside_action = 0;
   w_current->rotated_inside = 0;
+  w_current->rubbernet_visible = 0;
 
   /* --------------------- */
   /* Gschem internal state */
diff --git a/gschem/src/o_basic.c b/gschem/src/o_basic.c
index ad205e8..ea5c279 100644
--- a/gschem/src/o_basic.c
+++ b/gschem/src/o_basic.c
@@ -86,6 +86,11 @@ void o_redraw_all(GSCHEM_TOPLEVEL *w_current)
         o_drawbounding(w_current, toplevel->page_current->attrib_place_list,
                        x_get_darkcolor(w_current->bb_color), TRUE);
         break;
+      case(STARTDRAWNET):
+      case(DRAWNET):
+      case(NETCONT):
+        w_current->rubbernet_visible=0;
+        break;
     }
   }
 }
diff --git a/gschem/src/o_net.c b/gschem/src/o_net.c
index 9159b40..aa3d07c 100644
--- a/gschem/src/o_net.c
+++ b/gschem/src/o_net.c
@@ -533,6 +533,8 @@ void o_net_drawrubber(GSCHEM_TOPLEVEL *w_current)
   TOPLEVEL *toplevel = w_current->toplevel;
   int size;
 
+  w_current->rubbernet_visible = 1;
+
   if (toplevel->net_style == THICK) {
     size = SCREENabs(toplevel, NET_WIDTH);
     gdk_gc_set_line_attributes(w_current->xor_gc, size,
@@ -577,6 +579,11 @@ void o_net_eraserubber(GSCHEM_TOPLEVEL *w_current)
   TOPLEVEL *toplevel = w_current->toplevel;
   int size;
 
+  if (! w_current->rubbernet_visible)
+    return;
+
+  w_current->rubbernet_visible = 0;
+
   if (toplevel->net_style == THICK) {
     size = SCREENabs(toplevel, NET_WIDTH);
 

commit 20e0e015622bd57d9b0704d39593f209e49a3396
Author: Werner Hoch <werner.ho@xxxxxx>
Date:   Fri Feb 8 20:57:09 2008 +0100

    moved rubbernet drawing code into a extra function

diff --git a/gschem/include/prototype.h b/gschem/include/prototype.h
index 0089a26..5c63fa8 100644
--- a/gschem/include/prototype.h
+++ b/gschem/include/prototype.h
@@ -641,6 +641,7 @@ void o_net_draw_xor_single(GSCHEM_TOPLEVEL *w_current, int dx, int dy, int which
 void o_net_start(GSCHEM_TOPLEVEL *w_current, int x, int y);
 int o_net_end(GSCHEM_TOPLEVEL *w_current, int x, int y);
 void o_net_rubbernet(GSCHEM_TOPLEVEL *w_current, int x, int y);
+void o_net_drawrubber(GSCHEM_TOPLEVEL *w_current);
 void o_net_eraserubber(GSCHEM_TOPLEVEL *w_current);
 int o_net_add_busrippers(GSCHEM_TOPLEVEL *w_current, OBJECT *net_obj, GList *other_objects);
 /* o_picture.c */
diff --git a/gschem/src/o_net.c b/gschem/src/o_net.c
index 028410e..9159b40 100644
--- a/gschem/src/o_net.c
+++ b/gschem/src/o_net.c
@@ -481,7 +481,6 @@ void o_net_rubbernet(GSCHEM_TOPLEVEL *w_current, int x, int y)
 {
   TOPLEVEL *toplevel = w_current->toplevel;
   int diff_x, diff_y;
-  int size;
   int ortho;
 
   g_assert( w_current->inside_action != 0 );
@@ -522,6 +521,18 @@ void o_net_rubbernet(GSCHEM_TOPLEVEL *w_current, int x, int y)
     }
   }
 
+  o_net_drawrubber(w_current);
+}
+
+/*! \brief draw rubbernet lines to the gc
+ *  \par Function Description
+ *  This function draws the rubbernets to the graphic context
+ */
+void o_net_drawrubber(GSCHEM_TOPLEVEL *w_current)
+{
+  TOPLEVEL *toplevel = w_current->toplevel;
+  int size;
+
   if (toplevel->net_style == THICK) {
     size = SCREENabs(toplevel, NET_WIDTH);
     gdk_gc_set_line_attributes(w_current->xor_gc, size,
@@ -553,6 +564,7 @@ void o_net_rubbernet(GSCHEM_TOPLEVEL *w_current, int x, int y)
   }
 }
 
+
 /*! \todo Finish function documentation!!!
  *  \brief
  *  \par Function Description

commit 921ed5c0b907fb0f11cfff2233758a2c0169c3e0
Author: Werner Hoch <werner.ho@xxxxxx>
Date:   Fri Feb 8 20:40:43 2008 +0100

    Reuse common code from o_net_eraserubber in o_net_rubbernet
    
    The removal code or the rubbernets is the same in both cases, reuse
    it.

diff --git a/gschem/src/o_net.c b/gschem/src/o_net.c
index 63a9eda..028410e 100644
--- a/gschem/src/o_net.c
+++ b/gschem/src/o_net.c
@@ -473,10 +473,9 @@ int o_net_end(GSCHEM_TOPLEVEL *w_current, int x, int y)
   return (TRUE);
 }
 
-/*! \todo Finish function documentation!!!
- *  \brief
+/*! \brief erase and redraw the rubber lines when drawing a net
  *  \par Function Description
- *
+ *  This function draws the rubbernet lines when drawing a net.
  */
 void o_net_rubbernet(GSCHEM_TOPLEVEL *w_current, int x, int y)
 {
@@ -487,34 +486,14 @@ void o_net_rubbernet(GSCHEM_TOPLEVEL *w_current, int x, int y)
 
   g_assert( w_current->inside_action != 0 );
 
-  if (toplevel->net_style == THICK) {
-    size = SCREENabs(toplevel, NET_WIDTH);
-    gdk_gc_set_line_attributes(w_current->xor_gc, size,
-			       GDK_LINE_SOLID,
-			       GDK_CAP_NOT_LAST, GDK_JOIN_MITER);
-  }
-  gdk_gc_set_foreground(w_current->xor_gc,
-			x_get_darkcolor(w_current->select_color));
-
   /* Orthognal mode enabled when Control Key is NOT pressed */
   ortho = !w_current->CONTROLKEY;
 
-  /* Erase primary line */
-  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_gc_set_foreground(w_current->xor_gc,
+			x_get_darkcolor(w_current->select_color));
+  
+  o_net_eraserubber(w_current);
 
-  /* Erase secondary line*/
-  if ( w_current->second_x != -1 && w_current->second_y != -1 ) {
-      gdk_draw_line(w_current->backingstore, w_current->xor_gc,
-		    w_current->last_x, w_current->last_y,
-		    w_current->second_x, w_current->second_y);
-    o_invalidate_rect(w_current, w_current->last_x, w_current->last_y,
-                      w_current->second_x, w_current->second_y);
-  }
- 
   /* In orthogonal mode secondary line is the same as the first */
   if (!ortho)
   {
@@ -543,6 +522,13 @@ void o_net_rubbernet(GSCHEM_TOPLEVEL *w_current, int x, int y)
     }
   }
 
+  if (toplevel->net_style == THICK) {
+    size = SCREENabs(toplevel, NET_WIDTH);
+    gdk_gc_set_line_attributes(w_current->xor_gc, size,
+			       GDK_LINE_SOLID,
+			       GDK_CAP_NOT_LAST, GDK_JOIN_MITER);
+  }
+
   gdk_gc_set_foreground(w_current->xor_gc,
 			x_get_darkcolor(w_current->select_color));
   

commit 3ebfd10448ffefd902325b115193cb95cbeeaaf5
Author: Werner Hoch <werner.ho@xxxxxx>
Date:   Fri Feb 8 20:24:14 2008 +0100

    reuse common code from o_net_eraserubber in o_net_end
    
    reuse the o_net_eraserubber function in o_net_end. o_net_end
    deleted a rubbernet the same way as o_net_eraserubber does.

diff --git a/gschem/src/o_net.c b/gschem/src/o_net.c
index af9b3a1..63a9eda 100644
--- a/gschem/src/o_net.c
+++ b/gschem/src/o_net.c
@@ -261,10 +261,11 @@ void o_net_start(GSCHEM_TOPLEVEL *w_current, int x, int y)
 
 }
 
-/*! \todo Finish function documentation!!!
- *  \brief
+/*! \brief finish a net drawing action
  *  \par Function Description
- *
+ *  This function finishes the drawing of a net. The rubber nets are
+ *  removed, the nets and cues are drawn and the net is added to the
+ *  TOPLEVEL structure.
  */
 int o_net_end(GSCHEM_TOPLEVEL *w_current, int x, int y)
 {
@@ -285,43 +286,14 @@ int o_net_end(GSCHEM_TOPLEVEL *w_current, int x, int y)
 
   g_assert( w_current->inside_action != 0 );
 
-  if (toplevel->override_net_color == -1) {
-    color = w_current->net_color;
-  } else {
-    color = toplevel->override_net_color;
-  }
-
-  size = SCREENabs(toplevel, NET_WIDTH);
-
-  if (toplevel->net_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) );
 
-  /* Erase primary rubber net line */
-  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);
-
-
-  /* Erase secondary rubber net line */
-  gdk_draw_line(w_current->backingstore, w_current->xor_gc,
-		 w_current->last_x, w_current->last_y,
-		 w_current->second_x, w_current->second_y);
-  o_invalidate_rect(w_current, w_current->last_x, w_current->last_y,
-                               w_current->second_x, w_current->second_y);
+  o_net_eraserubber(w_current);
 
   if (toplevel->net_style == THICK) {
-    gdk_gc_set_line_attributes(w_current->xor_gc, 0,
-			       GDK_LINE_SOLID,
-			       GDK_CAP_NOT_LAST, GDK_JOIN_MITER);
+    size = SCREENabs(toplevel, NET_WIDTH);
     gdk_gc_set_line_attributes(w_current->gc, size,
 			       GDK_LINE_SOLID,
 			       GDK_CAP_NOT_LAST, GDK_JOIN_MITER);
@@ -369,6 +341,12 @@ int o_net_end(GSCHEM_TOPLEVEL *w_current, int x, int y)
   w_current->save_x = w_current->second_x;
   w_current->save_y = w_current->second_y;
 
+  if (toplevel->override_net_color == -1) {
+    color = w_current->net_color;
+  } else {
+    color = toplevel->override_net_color;
+  }
+
   if (!primary_zero_length ) {
   /* create primary net */
       toplevel->page_current->object_tail =

commit cf7689c9b6950c1694edacf9d750a48d87d462be
Author: Werner Hoch <werner.ho@xxxxxx>
Date:   Fri Feb 8 19:34:18 2008 +0100

    Remove unused drawing code from function o_net_start()
    
    This code was never used as the line lenght of both rubbernet
    segments was set to zero before drawing it.

diff --git a/gschem/src/o_net.c b/gschem/src/o_net.c
index 20154fc..af9b3a1 100644
--- a/gschem/src/o_net.c
+++ b/gschem/src/o_net.c
@@ -244,15 +244,14 @@ void o_net_draw_xor_single(GSCHEM_TOPLEVEL *w_current, int dx, int dy, int which
 
 }
 
-/*! \todo Finish function documentation!!!
- *  \brief
+/*! \brief set the start point of a new net
  *  \par Function Description
- *
+ *  This function sets the start point of a new net at the position of the 
+ *  cursor.
  */
 void o_net_start(GSCHEM_TOPLEVEL *w_current, int x, int y)
 {
   TOPLEVEL *toplevel = w_current->toplevel;
-  int size;
 
   /* initalize all parameters used when drawing the new net */
   w_current->last_x = w_current->start_x = w_current->second_x = 
@@ -260,27 +259,6 @@ void o_net_start(GSCHEM_TOPLEVEL *w_current, int x, int y)
   w_current->last_y = w_current->start_y = w_current->second_y = 
     fix_y(toplevel, y);
 
-  if (toplevel->net_style == THICK ) {
-    size = SCREENabs(toplevel, NET_WIDTH);
-    gdk_gc_set_line_attributes(w_current->xor_gc, size,
-                               GDK_LINE_SOLID,
-                               GDK_CAP_NOT_LAST,
-                               GDK_JOIN_MITER);
-  }
-
-  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->net_style == THICK ) {
-    gdk_gc_set_line_attributes(w_current->xor_gc, 0,
-                               GDK_LINE_SOLID,
-                               GDK_CAP_NOT_LAST,
-                               GDK_JOIN_MITER);
-  }
 }
 
 /*! \todo Finish function documentation!!!



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