This patch contains the modifications to libgeda from the 'glist_dev' branch 
required to support GList selection lists.

SHA1: 8ddd1c679d4891467b97389f0629b2c73ce73e7a  glist-libgeda-merge.patch

-- 
Fisher Society committee                    http://tinyurl.com/o39w2
CUSBC novices, match and league secretary   http://tinyurl.com/mwrc9
CU Spaceflight                              http://tinyurl.com/ognu2

v3sw6YChw7$ln3pr6$ck3ma8u7+Lw3+2m0l7Ci6e4+8t4Gb8en6g6Pa2Xs5Mr4p4
  hackerkey.com                                  peter-b.co.uk
diff --git a/libgeda/ChangeLog b/libgeda/ChangeLog
index 6c694f5..6f0c217 100644
--- a/libgeda/ChangeLog
+++ b/libgeda/ChangeLog
@@ -63,6 +63,33 @@
 	* include/prototype.h, src/g_smob.c: Added new "get-attribute-bounds"
 	  scheme function.
 
+2006-10-22 Carlos Nieves Onega <[EMAIL PROTECTED]>
+
+	* src/s_page.c: Don't free objects in the complex place list. It is
+	  only a reference to the objects in the page.
+
+2006-10-21 Carlos Nieves Onega <[EMAIL PROTECTED]>
+
+        * include/prototype.h, include/struct.h, src/o_basic.c, 
+	  src/o_complex_basic.c, src/o_list.c, src/o_net_basic.c, 
+	  src/o_selection.c, src/s_basic.c, src/s_page.c, 
+	  Convert the SELECTION list into a GList.
+	  Added new functions o_recalc_object_glist, 
+	  get_object_glist_bounds to handle glists.
+
+        * include/prototype.h, src/o_basic.c:
+	  Rename o_recalc to o_recalc_object_list, and make it
+	  to call a new function o_recalc_single_object, for each object
+	  in the list.
+
+        * include/prototype.h, src/o_complex_basic.c, src/o_text_basic.c:
+	  Rename get_complex_bounds to get_object_list_bounds, and make it
+	  to call a new function get_single_object_bounds, for each object
+	  in the list.
+	
+        * src/o_complex_basic.c: Fixed logic level of some checks.
+	* src/o_complex_basic.c: Added some sanity checks.
+
 2006-10-20 Ales Hvezda   <[EMAIL PROTECTED]>
 
         * configure.ac: Bumped package version to 20061020.
diff --git a/libgeda/include/prototype.h b/libgeda/include/prototype.h
index 72f897f..0064e63 100644
--- a/libgeda/include/prototype.h
+++ b/libgeda/include/prototype.h
@@ -198,7 +198,9 @@ void o_attrib_free_returned(OBJECT **found_objects);
 /* o_basic.c */
 int inside_region(int left, int top, int right, int bottom, int x, int y);
 void o_redraw_single(TOPLEVEL *w_current, OBJECT *o_current);
-void o_recalc(TOPLEVEL *w_current, OBJECT *object_list);
+void o_recalc_single_object(TOPLEVEL *w_current, OBJECT *o_current);
+void o_recalc_object_list(TOPLEVEL *w_current, OBJECT *object_list);
+void o_recalc_object_glist(TOPLEVEL *w_current, GList *object_glist);
 void o_set_line_options(TOPLEVEL *w_current, OBJECT *o_current, OBJECT_END end, OBJECT_TYPE type, int width, int length, int space);
 void o_set_fill_options(TOPLEVEL *w_current, OBJECT *o_current, OBJECT_FILLING type, int width, int pitch1, int angle1, int pitch2, int angle2);
 void o_object_recalc(TOPLEVEL *w_current, OBJECT *o_current);
@@ -279,8 +281,14 @@ void o_circle_print_hatch(TOPLEVEL *w_current, FILE *fp, int x, int y, int radiu
 void o_circle_image_write(TOPLEVEL *w_current, OBJECT *o_current, int origin_x, int origin_y, int color_mode);
 
 /* o_complex_basic.c */
-void get_complex_bounds(TOPLEVEL *w_current, OBJECT *complex, int *left, int *top, int *right, int *bottom);
-void get_complex_bounds_selection(TOPLEVEL *w_current, SELECTION *head, int *left, int *top, int *right, int *bottom);
+void get_single_object_bounds(TOPLEVEL *w_current, OBJECT *complex, 
+			      int *rleft, int *rtop, 
+			      int *rright, int *rbottom);
+void get_object_list_bounds(TOPLEVEL *w_current, OBJECT *complex, 
+			    int *left, int *top, int *right, int *bottom);
+void get_object_glist_bounds(TOPLEVEL *w_current, GList *o_list, 
+			     int *left, int *top, 
+			     int *right, int *bottom);
 void world_get_single_object_bounds(TOPLEVEL *w_current, OBJECT *o_current, 
 				    int *left, int *top, 
 				    int *right, int *bottom);
@@ -288,7 +296,10 @@ void world_get_complex_bounds(TOPLEVEL *w_current, OBJECT *complex, int *left, i
 OBJECT *add_head(void);
 int o_complex_is_eligible_attribute(TOPLEVEL *w_current, OBJECT *object, int promote_invisible);
 int o_complex_is_embedded(OBJECT *o_current);
-OBJECT *o_complex_add(TOPLEVEL *w_current, OBJECT *object_list, char type, int color, int x, int y, int angle, int mirror, char *clib, char *basename, int selectable, int attribute_promotion);
+OBJECT *o_complex_add(TOPLEVEL *w_current, OBJECT *object_list, 
+		      GList **object_glist, char type, int color, 
+		      int x, int y, int angle, int mirror, char *clib, 
+		      char *basename, int selectable, int attribute_promotion);
 OBJECT *o_complex_add_embedded(TOPLEVEL *w_current, OBJECT *object_list, char type, int color, int x, int y, int angle, char *clib, char *basename, int selectable);
 void o_complex_recalc(TOPLEVEL *w_current, OBJECT *o_current);
 OBJECT *o_complex_read(TOPLEVEL *w_current, OBJECT *object_list, char buf[], unsigned int release_ver, unsigned int fileformat_ver);
@@ -349,7 +360,7 @@ double o_line_length(OBJECT *object);
 /* o_list.c */
 OBJECT *o_list_copy_to(TOPLEVEL *w_current, OBJECT *list_head, OBJECT *selected, int flag, OBJECT **return_end);
 OBJECT *o_list_copy_all(TOPLEVEL *w_current, OBJECT *src_list_head, OBJECT *dest_list_head, int flag);
-OBJECT *o_list_copy_all_selection2(TOPLEVEL *w_current, SELECTION *src_list_head, OBJECT *dest_list_head, int flag);
+OBJECT *o_list_copy_all_selection2(TOPLEVEL *w_current, GList *src_list_head, OBJECT *dest_list_head, int flag);
 OBJECT *o_list_search(OBJECT *list, OBJECT *current);
 void o_list_delete(TOPLEVEL *w_current, OBJECT *list, OBJECT *delete);
 void o_list_delete_rest(TOPLEVEL *w_current, OBJECT *list);
@@ -422,20 +433,12 @@ void o_pin_modify(TOPLEVEL *w_current, OBJECT *object, int x, int y, int whichon
 void o_pin_update_whichend(TOPLEVEL *w_current, OBJECT *object_list, int num_pins);
 
 /* o_selection.c */
-SELECTION *o_selection_return_tail(SELECTION *head);
-SELECTION *o_selection_return_head(SELECTION *tail);
-SELECTION *o_selection_new_head(void);
-void o_selection_destroy_head(SELECTION *s_head);
-SELECTION *o_selection_add(SELECTION *head, OBJECT *o_selected);
-void o_selection_remove(SELECTION *head, OBJECT *o_selected);
-void o_selection_remove_most(TOPLEVEL *w_current, SELECTION *head);
-void o_selection_print_all(SELECTION *head);
-void o_selection_destroy_all(SELECTION *head);
+GList *o_selection_add(GList *head, OBJECT *o_selected);
+void o_selection_print_all( GList *head );
 void o_selection_select(OBJECT *object, int color);
 void o_selection_unselect(OBJECT *object);
-OBJECT *o_selection_return_first_object(SELECTION *head);
-OBJECT *o_selection_return_nth_object(SELECTION *head, int count);
-int o_selection_return_num(SELECTION *head);
+void o_selection_remove(GList **head, OBJECT *o_selected);
+void o_selection_unselect_list(TOPLEVEL *w_current, GList **head);
 
 /* o_text_basic.c */
 void get_text_bounds(TOPLEVEL *w_current, OBJECT *o_current, int *left, int *top, int *right, int *bottom);
@@ -486,8 +489,10 @@ OBJECT *s_basic_link_object(OBJECT *new_node, OBJECT *ptr);
 void print_struct_forw(OBJECT *ptr);
 void print_struct_back(OBJECT *ptr);
 void print_struct(OBJECT *ptr);
+void s_delete_object(TOPLEVEL *w_current, OBJECT *o_current);
 void s_delete(TOPLEVEL *w_current, OBJECT *o_current);
 void s_delete_list_fromstart(TOPLEVEL *w_current, OBJECT *start);
+void s_delete_object_glist(TOPLEVEL *w_current, GList *list);
 OBJECT *s_remove(TOPLEVEL *w_current, OBJECT *object);
 void string_toupper(char *in, char *out);
 void string_tolower(char *in, char *out);
diff --git a/libgeda/include/struct.h b/libgeda/include/struct.h
index 94d36a6..ae8835c 100644
--- a/libgeda/include/struct.h
+++ b/libgeda/include/struct.h
@@ -36,7 +36,6 @@ typedef struct st_object OBJECT;
 typedef struct st_page PAGE;
 typedef struct st_toplevel TOPLEVEL;
 typedef struct st_color COLOR;
-typedef struct st_selection SELECTION;
 typedef struct st_undo UNDO;
 typedef struct st_tile TILE;
 typedef struct st_tile_loc TILE_LOC;
@@ -293,13 +292,6 @@ struct st_bus_ripper
   int y[2];
 };
 
-struct st_selection {
-  OBJECT *selected_object;
-
-  SELECTION *prev;
-  SELECTION *next;
-};
-
 struct st_stretch
 {
   OBJECT *object;
@@ -350,10 +342,8 @@ struct st_page {
   OBJECT *object_head;
   OBJECT *object_tail;
   OBJECT *object_parent;
-  SELECTION *selection2_head; /* new selection mechanism */
-  SELECTION *selection2_tail; 
-  OBJECT *complex_place_head;  /* used to place complex's and text */
-  OBJECT *complex_place_tail; 
+  GList *selection_list; /* new selection mechanism */
+  GList *complex_place_list;
   OBJECT *attrib_place_head;
   OBJECT *attrib_place_tail; 
   OBJECT *object_lastplace;
diff --git a/libgeda/src/o_basic.c b/libgeda/src/o_basic.c
index ab9dcdd..49362e4 100644
--- a/libgeda/src/o_basic.c
+++ b/libgeda/src/o_basic.c
@@ -87,24 +87,18 @@ void o_redraw_single(TOPLEVEL *w_current, OBJECT *o_current)
   }
 }
 
-/*! \brief Recalculate position of all objects.
+/*! \brief Recalculate position of the given object.
  *  \par Function Description
- *  This function will take a list of objects and recalculate their
- *  positions on the screen.
+ *  This function will take an object and recalculate its
+ *  position on the screen.
  *
  *  \param [in]     w_current    The TOPLEVEL object.
- *  \param [in,out] object_list  OBJECT list to recalculate.
+ *  \param [in,out] o_current    OBJECT to recalculate.
  *
  */
-void o_recalc(TOPLEVEL *w_current, OBJECT *object_list)
+void o_recalc_single_object(TOPLEVEL *w_current, OBJECT *o_current)
 {
-  OBJECT *o_current;
-
-  if (object_list == NULL)
-  return;
-	
-  o_current = object_list;
-  while (o_current != NULL) {
+  if (o_current != NULL) {
     switch(o_current->type) {
 
       case(OBJ_LINE):
@@ -144,10 +138,54 @@ void o_recalc(TOPLEVEL *w_current, OBJECT *object_list)
         o_arc_recalc(w_current, o_current);
         break;
     }
+  }
+}
+
+/*! \brief Recalculate position of a list of objects.
+ *  \par Function Description
+ *  This function will take a list of objects and recalculate their
+ *  positions on the screen.
+ *
+ *  \param [in]     w_current    The TOPLEVEL object.
+ *  \param [in,out] object_list  OBJECT list to recalculate.
+ *
+ */
+void
+o_recalc_object_list(TOPLEVEL *w_current, OBJECT *object_list)
+{
+  OBJECT *o_current;
 
+  o_current = object_list;
+  while (o_current != NULL) {
+    o_recalc_single_object(w_current, o_current);
     o_current = o_current->next;
   }
 }
+ 
+/*! \brief Recalculate position of a list (GList) of objects.
+ *  \par Function Description
+ *  This function will take a list (GList) of objects and recalculate their
+ *  positions on the screen.
+ *
+ *  \param [in]     w_current    The TOPLEVEL object.
+ *  \param [in,out] object_glist  OBJECT list to recalculate.
+ *
+ */
+void
+o_recalc_object_glist(TOPLEVEL *w_current, GList *object_glist)
+{
+  GList *list = object_glist;
+  OBJECT *o_current;
+
+  while (list != NULL) {
+    o_current = (OBJECT *) list->data;
+    o_recalc_single_object(w_current, o_current);
+   list = list->next;
+  }
+}
+
+
+
 
 /*! \brief Set an #OBJECT's line options.
  *  \par Function Description
diff --git a/libgeda/src/o_complex_basic.c b/libgeda/src/o_complex_basic.c
index 4a406ed..94290a9 100644
--- a/libgeda/src/o_complex_basic.c
+++ b/libgeda/src/o_complex_basic.c
@@ -43,57 +43,51 @@
 #include <dmalloc.h>
 #endif
 
-/*! \brief
- *  \par Function Description
+/*! \brief Return the bounds of the given object.
+ *  \par Given an object, calcule the bounds coordinates.
+ *  \param [in] w_current The toplevel structure.
+ *  \param [in] o_current The object to look the bounds for.
+ *  \param [out] rleft   pointer to the left coordinate of the object.
+ *  \param [out] rtop    pointer to the top coordinate of the object.
+ *  \param [out] rright  pointer to the right coordinate of the object.
+ *  \param [out] rbottom pointer to the bottom coordinate of the object.
  *
  */
-void get_complex_bounds(TOPLEVEL *w_current, OBJECT *complex, 
-			int *left, int *top, int *right, int *bottom)
+void get_single_object_bounds(TOPLEVEL *w_current, OBJECT *o_current, 
+			      int *rleft, int *rtop, int *rright, int *rbottom)
 {
-  OBJECT *o_current=NULL;
-  int rleft, rtop, rright, rbottom;
-	
-  *left = rleft = 999999;
-  *top = rtop = 9999999;
-  *right = rright = 0;
-  *bottom = rbottom = 0;
-	
-
-
-  o_current = complex;
-	
-  while ( o_current != NULL ) {
+  if (o_current != NULL) {
     switch(o_current->type) {
       case(OBJ_LINE):
-        get_line_bounds(w_current, o_current->line, &rleft, &rtop, &rright, &rbottom);
+        get_line_bounds(w_current, o_current->line, rleft, rtop, rright, rbottom);
         break;
 
       case(OBJ_NET):
         /* same as a line (diff name)*/
-        get_net_bounds(w_current, o_current->line, &rleft, &rtop, &rright, &rbottom);
+        get_net_bounds(w_current, o_current->line, rleft, rtop, rright, rbottom);
         break;
 
       case(OBJ_BUS):
         /* same as a line (diff name)*/
-        get_bus_bounds(w_current, o_current->line, &rleft, &rtop, &rright, &rbottom);
+        get_bus_bounds(w_current, o_current->line, rleft, rtop, rright, rbottom);
         break;
 	
       case(OBJ_BOX):
-        get_box_bounds(w_current, o_current->box, &rleft, &rtop, &rright, &rbottom);
+        get_box_bounds(w_current, o_current->box, rleft, rtop, rright, rbottom);
         break;
 
       case(OBJ_PICTURE):
-        get_picture_bounds(w_current, o_current->picture, &rleft, &rtop, &rright, &rbottom);
+        get_picture_bounds(w_current, o_current->picture, rleft, rtop, rright, rbottom);
         break;
 
       case(OBJ_CIRCLE):
-        get_circle_bounds(w_current, o_current->circle, &rleft, &rtop, &rright, &rbottom);
+        get_circle_bounds(w_current, o_current->circle, rleft, rtop, rright, rbottom);
         break;
 
       case(OBJ_COMPLEX):
       case(OBJ_PLACEHOLDER):
         /* recursive objects ?*/
-        get_complex_bounds(w_current, o_current->complex->prim_objs, &rleft, &rtop, &rright, &rbottom);
+        get_object_list_bounds(w_current, o_current->complex->prim_objs, rleft, rtop, rright, rbottom);
         break;
 
       case(OBJ_TEXT):
@@ -101,22 +95,51 @@ void get_complex_bounds(TOPLEVEL *w_current, OBJECT *complex,
         /* you might lose some attrs though */
         if (o_current->visibility == VISIBLE ||
             (o_current->visibility == INVISIBLE && w_current->show_hidden_text)) {
-          get_text_bounds(w_current, o_current, &rleft, &rtop, &rright, &rbottom);
+          get_text_bounds(w_current, o_current, rleft, rtop, rright, rbottom);
         }
         break;
 
       case(OBJ_PIN):
-        get_pin_bounds(w_current, o_current->line, &rleft, &rtop, &rright, &rbottom);
+        get_pin_bounds(w_current, o_current->line, rleft, rtop, rright, rbottom);
         break;
 
       case(OBJ_ARC):
-        get_arc_bounds(w_current, o_current, &rleft, &rtop, &rright, &rbottom);
+        get_arc_bounds(w_current, o_current, rleft, rtop, rright, rbottom);
         break;
 
       default:
         break;
     }
+  }
+}
+
+/*! \brief Return the bounds of the given list of objects.
+ *  \par Given a list of objects, calcule the bounds coordinates.
+ *  \param [in] w_current The toplevel structure.
+ *  \param [in] complex   The list of objects to look the bounds for.
+ *  \param [out] left   pointer to the left coordinate of the object.
+ *  \param [out] top    pointer to the top coordinate of the object.
+ *  \param [out] right  pointer to the right coordinate of the object.
+ *  \param [out] bottom pointer to the bottom coordinate of the object.
+ */
+void
+get_object_list_bounds(TOPLEVEL *w_current, OBJECT *complex, 
+		       int *left, int *top, int *right, int *bottom)
+{
+  OBJECT *o_current=NULL;
+  int rleft, rtop, rright, rbottom;
+	
+  *left = rleft = 999999;
+  *top = rtop = 9999999;
+  *right = rright = 0;
+  *bottom = rbottom = 0;
+	
 
+  o_current = complex;
+	
+  while ( o_current != NULL ) {
+    get_single_object_bounds(w_current, o_current, &rleft, &rtop, 
+			     &rright, &rbottom);
     if (rleft < *left) *left = rleft;
     if (rtop < *top) *top = rtop;
     if (rright > *right) *right = rright;
@@ -128,14 +151,19 @@ void get_complex_bounds(TOPLEVEL *w_current, OBJECT *complex,
 
 }
 
-/*! \brief
- *  \par Function Description
- *
+/*! \brief Return the bounds of the given GList of objects.
+ *  \par Given a list of objects, calcule the bounds coordinates.
+ *  \param [in] w_current The toplevel structure.
+ *  \param [in] complex   The list of objects to look the bounds for.
+ *  \param [out] left   pointer to the left coordinate of the object.
+ *  \param [out] top    pointer to the top coordinate of the object.
+ *  \param [out] right  pointer to the right coordinate of the object.
+ *  \param [out] bottom pointer to the bottom coordinate of the object.
  */
-void get_complex_bounds_selection(TOPLEVEL *w_current, SELECTION *head, 
-				  int *left, int *top, int *right, int *bottom)
+void get_object_glist_bounds(TOPLEVEL *w_current, GList *head, 
+			     int *left, int *top, int *right, int *bottom)
 {
-  SELECTION *s_current=NULL;
+  GList *s_current=NULL;
   OBJECT *o_current=NULL;
   int rleft, rtop, rright, rbottom;
 	
@@ -148,66 +176,12 @@ void get_complex_bounds_selection(TOPLEVEL *w_current, SELECTION *head,
 	
   while ( s_current != NULL ) {
 
-    o_current = s_current->selected_object;
-
-    if (!o_current) {
-      fprintf(stderr, "Got NULL in get_complex_bounds_selection\n");
-      exit(-1);
-    }
-
-    switch(o_current->type) {
-      case(OBJ_LINE):
-        get_line_bounds(w_current, o_current->line, &rleft, &rtop, &rright, &rbottom);
-        break;
+    o_current = (OBJECT *) s_current->data;
 
-      case(OBJ_NET):
-        /* same as a line (diff name)*/
-        get_net_bounds(w_current, o_current->line, &rleft, &rtop, &rright, &rbottom);
-        break;
+    g_assert (o_current != NULL);
 
-      case(OBJ_BUS):
-        /* same as a line (diff name)*/
-        get_bus_bounds(w_current, o_current->line, &rleft, &rtop, &rright, &rbottom);
-        break;
-	
-      case(OBJ_BOX):
-        get_box_bounds(w_current, o_current->box, &rleft, &rtop, &rright, &rbottom);
-        break;
-
-      case(OBJ_PICTURE):
-        get_picture_bounds(w_current, o_current->picture, &rleft, &rtop, &rright, &rbottom);
-        break;
-
-      case(OBJ_CIRCLE):
-        get_circle_bounds(w_current, o_current->circle, &rleft, &rtop, &rright, &rbottom);
-        break;
-
-      case(OBJ_COMPLEX):
-      case(OBJ_PLACEHOLDER):
-        /* recursive objects ?*/
-        get_complex_bounds(w_current, o_current->complex->prim_objs, &rleft, &rtop, &rright, &rbottom);
-        break;
-
-      case(OBJ_TEXT):
-        /* only do bounding boxes for visible or doing show hidden text */
-        /* you might lose some attrs though */
-        if (o_current->visibility == VISIBLE ||
-            (o_current->visibility == INVISIBLE && w_current->show_hidden_text)) {
-          get_text_bounds(w_current, o_current, &rleft, &rtop, &rright, &rbottom);
-        }
-        break;
-
-      case(OBJ_PIN):
-        get_pin_bounds(w_current, o_current->line, &rleft, &rtop, &rright, &rbottom);
-        break;
-
-      case(OBJ_ARC):
-        get_arc_bounds(w_current, o_current, &rleft, &rtop, &rright, &rbottom);
-        break;
-
-      default:
-        break;
-    }
+    get_single_object_bounds(w_current, o_current, &rleft, &rtop, 
+			     &rright, &rbottom);
 
     if (rleft < *left) *left = rleft;
     if (rtop < *top) *top = rtop;
@@ -372,6 +346,8 @@ int o_complex_is_eligible_attribute (TOPLEVEL *w_current, OBJECT *object,
   int promotableAttribute = FALSE;
   char *ptr;
 
+  g_return_val_if_fail(object != NULL, FALSE);
+
   if (object->type != OBJ_TEXT || object->attribute || object->attached_to)
   {
     return FALSE; /* not a text item or is already attached */
@@ -428,6 +404,8 @@ int o_complex_is_eligible_attribute (TOPLEVEL *w_current, OBJECT *object,
  */
 int o_complex_is_embedded(OBJECT *o_current)
 {
+  g_return_val_if_fail(o_current != NULL, 0);
+
   if(o_current->complex == NULL)
   return 0;
 
@@ -445,7 +423,8 @@ int o_complex_is_embedded(OBJECT *o_current)
  *  \par Function Description
  *
  */
-OBJECT *o_complex_add(TOPLEVEL *w_current, OBJECT *object_list, char type,
+OBJECT *o_complex_add(TOPLEVEL *w_current, OBJECT *object_list, 
+		      GList **object_glist, char type,
 		      int color, int x, int y, int angle,
 		      int mirror, char *clib,
 		      char *basename, int selectable,
@@ -457,8 +436,15 @@ OBJECT *o_complex_add(TOPLEVEL *w_current, OBJECT *object_list, char type,
   OBJECT *temp_parent=NULL;
   int save_adding_sel = 0;
   int loaded_normally = FALSE;
-	
+  gboolean use_object_list;
   char *filename;
+  GList *glist_ptr;
+
+  if (object_list) {
+    use_object_list = TRUE;
+  } else {
+    use_object_list = FALSE;
+  }
 
   new_node = s_basic_init_object("complex");
   new_node->type = type;
@@ -634,9 +620,35 @@ OBJECT *o_complex_add(TOPLEVEL *w_current, OBJECT *object_list, char type,
 
           /* Isolate tmp completely, now that it's removed from list */
           tmp->next=tmp->prev=NULL;
-		
-          object_list = (OBJECT *) s_basic_link_object(tmp, object_list);
-          o_attrib_attach (w_current, object_list, tmp, new_node);
+	  if (use_object_list) {
+	    object_list = (OBJECT *) s_basic_link_object(tmp, object_list);
+	    o_attrib_attach (w_current, object_list, tmp, new_node);
+	  }
+	  else {
+	    if (object_glist) {
+	      *object_glist = g_list_append (*object_glist, tmp);
+	      
+	      glist_ptr = *object_glist;
+	      while (glist_ptr) {
+		if (glist_ptr->prev == NULL) {
+		  ((OBJECT *) glist_ptr->data)->prev = NULL;
+		} else {
+		  ((OBJECT *) glist_ptr->data)->prev = glist_ptr->prev->data;
+		}
+		if (glist_ptr->next == NULL) {
+		  ((OBJECT *) glist_ptr->data)->next = NULL;
+		} else {
+		  ((OBJECT *) glist_ptr->data)->next = glist_ptr->next->data;
+		}
+		glist_ptr = glist_ptr->next;
+	      }
+	      
+	      o_attrib_attach (w_current, ((OBJECT *) g_list_last(*object_glist)->data), 
+			       tmp, new_node);
+	    } else {
+	      o_attrib_attach (w_current, NULL, tmp, new_node);
+	    }
+	  }
           o_text_translate_world(w_current, x, y, tmp);
 
         } else { /* not promoting now, but deal with floating attribs */
@@ -659,19 +671,45 @@ OBJECT *o_complex_add(TOPLEVEL *w_current, OBJECT *object_list, char type,
   w_current->page_current->object_tail = temp_tail;
   w_current->page_current->object_parent = temp_parent;
 
-  object_list = (OBJECT *) s_basic_link_object(new_node, object_list);
-  object_list->complex->prim_objs = prim_objs;
-
+  if (use_object_list) {
+    object_list = (OBJECT *) s_basic_link_object(new_node, object_list);
+    object_list->complex->prim_objs = prim_objs;
+  }
+  else {
+    new_node->complex->prim_objs = prim_objs;
+    if (object_glist) {
+      *object_glist = g_list_append (*object_glist, new_node);
+
+      glist_ptr = *object_glist;
+      while (glist_ptr) {
+	if (glist_ptr->prev == NULL) {
+	  ((OBJECT *) glist_ptr->data)->prev = NULL;
+	} else {
+	  ((OBJECT *) glist_ptr->data)->prev = glist_ptr->prev->data;
+	}
+	if (glist_ptr->next == NULL) {
+	  ((OBJECT *) glist_ptr->data)->next = NULL;
+	} else {
+	  ((OBJECT *) glist_ptr->data)->next = glist_ptr->next->data;
+	}
+	glist_ptr = glist_ptr->next;
+      }
+      object_list = (OBJECT *) (g_list_last(*object_glist)->data);
+    } else {
+      object_list = new_node;
+    }
+    
+  }
 
   /* do not mirror/rotate/translate/connect the primitive objects if the
    * component was not loaded via o_read 
    */
   if (loaded_normally == TRUE) {
     if (mirror) {
-      o_complex_mirror_lowlevel(w_current, x, y, object_list);
+      o_complex_mirror_lowlevel(w_current, x, y, new_node);
     } 
-
-    o_complex_rotate_lowlevel(w_current, x, y, angle, angle, object_list); 
+    
+    o_complex_rotate_lowlevel(w_current, x, y, angle, angle, new_node); 
     o_complex_world_translate(w_current, x, y, prim_objs);
 
     if (!w_current->ADDING_SEL) {
@@ -750,7 +788,10 @@ void o_complex_recalc(TOPLEVEL *w_current, OBJECT *o_current)
   /* libhack */
   /* o_recalc(w_current, o_current->complex);*/
 
-  get_complex_bounds(w_current, o_current->complex->prim_objs, &left, &top, &right, &bottom);
+  if ((!o_current) || (o_current->type != OBJ_COMPLEX && o_current->type != OBJ_PLACEHOLDER))
+    return;
+
+  get_object_list_bounds(w_current, o_current->complex->prim_objs, &left, &top, &right, &bottom);
   o_current->left = left;
   o_current->top = top;
   o_current->right = right;
@@ -761,6 +802,7 @@ void o_complex_recalc(TOPLEVEL *w_current, OBJECT *o_current)
                 o_current->complex->y,
                 &o_current->complex->screen_x, 
                 &o_current->complex->screen_y);
+
 }
 
 /*! \brief
@@ -836,7 +878,7 @@ OBJECT *o_complex_read(TOPLEVEL *w_current, OBJECT *object_list,
       clib = (gchar*)clibs->data;
     }
     
-    object_list = o_complex_add(w_current, object_list, type, 
+    object_list = o_complex_add(w_current, object_list, NULL, type, 
 				WHITE, 
 				x1, y1, 
 				angle, mirror,
@@ -855,6 +897,8 @@ char *o_complex_save(OBJECT *object)
   int selectable;
   char *buf = NULL;
 
+  g_return_val_if_fail (object != NULL, NULL);
+
   if (object->sel_func != NULL) 
   selectable = 1;
   else 
@@ -1049,6 +1093,10 @@ void o_complex_world_translate_toplevel(TOPLEVEL *w_current,
 {
   int left, right, top, bottom;
 
+  g_return_if_fail(object != NULL);
+  g_return_if_fail((object->type == OBJ_COMPLEX) ||
+		   (object->type == OBJ_PLACEHOLDER));
+
   object->complex->x = object->complex->x + x1;
   object->complex->y = object->complex->y + y1;
 
@@ -1060,8 +1108,8 @@ void o_complex_world_translate_toplevel(TOPLEVEL *w_current,
   o_complex_world_translate(w_current, x1, y1, 
                             object->complex->prim_objs);
 
-  get_complex_bounds(w_current, object->complex->prim_objs, 
-                     &left, &top, &right, &bottom);
+  get_object_list_bounds(w_current, object->complex->prim_objs, 
+			 &left, &top, &right, &bottom);
 	
   object->left = left;
   object->top = top;
@@ -1081,6 +1129,8 @@ OBJECT *o_complex_copy(TOPLEVEL *w_current, OBJECT *list_tail,
   int color;
   int selectable;
 
+  g_return_val_if_fail(o_current != NULL, NULL);
+
   if (o_current->saved_color == -1) {
     color = o_current->color;
   } else {
@@ -1093,7 +1143,7 @@ OBJECT *o_complex_copy(TOPLEVEL *w_current, OBJECT *list_tail,
     selectable = FALSE;	
   }
 
-  new_obj = o_complex_add(w_current, list_tail, o_current->type, color,
+  new_obj = o_complex_add(w_current, list_tail, NULL, o_current->type, color,
                           o_current->complex->x, o_current->complex->y, 
                           o_current->complex->angle, o_current->complex->mirror,
                           o_current->complex_clib, o_current->complex_basename, 
@@ -1135,6 +1185,8 @@ OBJECT *o_complex_copy_embedded(TOPLEVEL *w_current, OBJECT *list_tail,
   int color;
   int selectable;
 
+  g_return_val_if_fail(o_current != NULL, NULL);
+
   if (o_current->saved_color == -1) {
     color = o_current->color;
   } else {
@@ -1188,6 +1240,8 @@ OBJECT *o_complex_copy_embedded(TOPLEVEL *w_current, OBJECT *list_tail,
  */
 void o_complex_delete(TOPLEVEL *w_current, OBJECT *delete)
 {
+  g_return_if_fail(delete != NULL);
+
   /* first remove complex pointer */
   if (delete->complex) {
     if (delete->complex->prim_objs) {
@@ -1249,6 +1303,8 @@ void o_complex_set_color(OBJECT *prim_objs, int color)
  */
 void o_complex_set_color_single(OBJECT *o_current, int color)
 {
+  g_return_if_fail(o_current != NULL);
+
   switch(o_current->type) {
     case(OBJ_LINE):
     case(OBJ_NET):
@@ -1372,6 +1428,8 @@ void o_complex_unset_color(OBJECT *complex)
  */
 void o_complex_unset_color_single(OBJECT *o_current)
 {
+  g_return_if_fail(o_current != NULL);
+
   switch(o_current->type) {
     case(OBJ_LINE):
     case(OBJ_NET):
@@ -1485,6 +1543,12 @@ void o_complex_rotate_lowlevel(TOPLEVEL *w_current, int world_centerx,
   printf("------- a %d ac %d\n", angle, angle_change);
 #endif
 
+  g_return_if_fail(object != NULL);
+  g_return_if_fail(((object->type == OBJ_COMPLEX) ||
+		    (object->type == OBJ_PLACEHOLDER)));
+  g_return_if_fail(object->complex != NULL);
+
+
   /* do individual complex objects */
   o_current = object->complex->prim_objs;
 
@@ -1547,6 +1611,11 @@ void o_complex_mirror_lowlevel(TOPLEVEL *w_current,
 {
   OBJECT *o_current=NULL;
 
+  g_return_if_fail(object != NULL);
+  g_return_if_fail(((object->type == OBJ_COMPLEX) ||
+		    (object->type == OBJ_PLACEHOLDER)));
+  g_return_if_fail(object->complex != NULL);
+
   /* do individual complex objects */
   o_current = object->complex->prim_objs;
 
@@ -1611,6 +1680,12 @@ OBJECT *o_complex_return_pin_object(OBJECT *object, char *pin)
   OBJECT *o_current=NULL;
   OBJECT *found;
 
+  g_return_val_if_fail(object != NULL, NULL);
+  g_return_val_if_fail(((object->type == OBJ_COMPLEX) ||
+			(object->type == OBJ_PLACEHOLDER)) , NULL);
+  g_return_val_if_fail(object->complex != NULL, NULL);
+
+
   /* go inside complex objects */
   o_current = object->complex->prim_objs;
 
@@ -1655,10 +1730,10 @@ o_complex_check_symversion(TOPLEVEL* w_current, OBJECT* object)
   double inside_major, inside_minor;
   double outside_major, outside_minor;
   
-  if (object->type != OBJ_COMPLEX && object->type != OBJ_PLACEHOLDER)
-  {
-    return;
-  }
+  g_return_if_fail (object != NULL);
+  g_return_if_fail ((object->type == OBJ_COMPLEX || 
+		     object->type == OBJ_PLACEHOLDER));
+  g_return_if_fail (object->complex != NULL);
 
   /* first look on the inside for the symversion= attribute */
   inside = o_attrib_search_name(object->complex->prim_objs, "symversion", 0);
diff --git a/libgeda/src/o_list.c b/libgeda/src/o_list.c
index 09665dd..5c77f8d 100644
--- a/libgeda/src/o_list.c
+++ b/libgeda/src/o_list.c
@@ -253,10 +253,10 @@ OBJECT *o_list_copy_all(TOPLEVEL *w_current, OBJECT *src_list_head,
  *  \return OBJECT pointer.
  */
 OBJECT *o_list_copy_all_selection2(TOPLEVEL *w_current,
-				   SELECTION *src_list_head, 
+				   GList *src_list_head, 
 				   OBJECT *dest_list_head, int flag)
 {
-  SELECTION *src;
+  GList *src;
   OBJECT *object;
   OBJECT *dest;
   OBJECT *temp_parent=NULL;
@@ -283,7 +283,7 @@ OBJECT *o_list_copy_all_selection2(TOPLEVEL *w_current,
   /* first do all NON text items */
   while(src != NULL) {
 
-    object = src->selected_object;
+    object = (OBJECT *) src->data;
 
     /* unselect the object before the copy */
     o_selection_unselect(object);	
@@ -318,7 +318,7 @@ OBJECT *o_list_copy_all_selection2(TOPLEVEL *w_current,
   /* then do all text items */
   while(src != NULL) {
 
-    object = src->selected_object;
+    object = (OBJECT *) src->data;
 
     /* unselect the object before the copy */
     o_selection_unselect(object);	
diff --git a/libgeda/src/o_net_basic.c b/libgeda/src/o_net_basic.c
index 0a1ed5b..01a0bb6 100644
--- a/libgeda/src/o_net_basic.c
+++ b/libgeda/src/o_net_basic.c
@@ -917,17 +917,18 @@ int o_net_consolidate_segments(TOPLEVEL *w_current, OBJECT *object)
 
           changed++;
           if (other_object->selected == TRUE ) {
-            o_selection_remove(w_current->page_current->selection2_head, 
+            o_selection_remove(&(w_current->page_current->selection_list), 
                                other_object);
             reselect_new=TRUE;
           }
 
           if (reselect_new == TRUE) {
-            o_selection_remove(w_current->page_current->selection2_head, 
+            o_selection_remove(&(w_current->page_current->selection_list), 
                                object);
 
-            o_selection_add(w_current->page_current->selection2_head, 
-                            object);
+            w_current->page_current->selection_list = 
+	      o_selection_add(w_current->page_current->selection_list, 
+			      object);
           }
 				
           s_conn_remove(w_current, other_object);
diff --git a/libgeda/src/o_selection.c b/libgeda/src/o_selection.c
index ba898b0..88a107e 100644
--- a/libgeda/src/o_selection.c
+++ b/libgeda/src/o_selection.c
@@ -46,195 +46,35 @@
 #include <dmalloc.h>
 #endif
 
-/*! \todo Finish function documentation!!!
- *  \brief
- *  \par Function Description
- *
- */
-SELECTION *o_selection_return_tail(SELECTION *head)
-{
-  SELECTION *s_current=NULL;
-  SELECTION *ret_struct=NULL;
-
-  s_current = head;
-  while ( s_current != NULL ) { /* goto end of list */
-    ret_struct = s_current;
-    s_current = s_current->next;
-  }
-
-  return(ret_struct);
-}
-
-/*! \todo Finish function documentation!!!
- *  \brief
- *  \par Function Description
- *
- */
-SELECTION *o_selection_return_head(SELECTION *tail)
-{
-  SELECTION *s_current=NULL;
-  SELECTION *ret_struct=NULL;
-
-  s_current = tail;
-  while ( s_current != NULL ) { /* goto end of list */
-    ret_struct = s_current;
-    s_current = s_current->prev;
-  }
-
-  return(ret_struct);
-}
-
-/*! \todo Finish function documentation!!!
- *  \brief
- *  \par Function Description
- *
- */
-SELECTION *o_selection_new_head(void)
-{
-  SELECTION *s_new;
-
-  s_new = (SELECTION *) g_malloc(sizeof(SELECTION));
-  s_new->selected_object = NULL;
-  s_new->prev = NULL;
-  s_new->next = NULL;
-
-  return(s_new);
-}
-
-/*! \todo Finish function documentation!!!
- *  \brief
- *  \par Function Description
- *
+/*! \brief Selects the given object and adds it to the selection list
+ *  \par Selects the given object and does the needed work to make the
+ *  object visually selected.
+ *  \param [in] head Selection list
+ *  \param [in] o_selected Object to select.
+ *  \returns a pointer to the selection list, with the object added.
  */
-void o_selection_destroy_head(SELECTION *s_head)
+GList *o_selection_add(GList *head, OBJECT *o_selected)
 {
-  g_free(s_head);
-}
-
-/*! \todo Finish function documentation!!!
- *  \brief
- *  \par Function Description
- *
- */
-/* also does the needed work to make the object visually selected */
-SELECTION *o_selection_add(SELECTION *head, OBJECT *o_selected)
-{
-  SELECTION *tail;
-  SELECTION *s_new;
-	
-  s_new = (SELECTION *) g_malloc(sizeof(SELECTION));
-
-  if (o_selected != NULL) {
-    s_new->selected_object = o_selected;
-  } else {
-    fprintf(stderr, "Got NULL passed to o_selection_new\n");
-  }
-
   o_selection_select(o_selected, SELECT_COLOR);
-
-  if (head == NULL) {
-    s_new->prev = NULL; /* setup previous link */
-    s_new->next = NULL;
-    return(s_new);
-  } else {
-    tail = o_selection_return_tail(head);
-    s_new->prev = tail; /* setup previous link */
-    s_new->next = NULL;
-    tail->next = s_new;
-    return(tail->next);
-  }
+  return (g_list_append(head, o_selected));
 }
 
-/*! \todo Finish function documentation!!!
- *  \brief
- *  \par Function Description
+/*! \brief Prints the given selection list.
+ *  \par Prints the given selection list.
+ *  \param [in] head Selection list to print.
  *
  */
-/* it's okay to call this with an o_selected which is not necessarily */
-/* selected */
-void o_selection_remove(SELECTION *head, OBJECT *o_selected)
+void o_selection_print_all( GList *head )
 {
-  SELECTION *s_current;
-
-  if (o_selected == NULL) {
-    fprintf(stderr, "Got NULL for o_selected in o_selection_remove\n");
-    return;
-  }
-
-  s_current = head;	
-
-  while (s_current != NULL) {
-    if (s_current->selected_object == o_selected) {
-      if (s_current->next)
-        s_current->next->prev = s_current->prev;
-      else
-        s_current->next = NULL;
-
-      if (s_current->prev)
-        s_current->prev->next = s_current->next;
-      else
-        s_current->prev = NULL;
-
-      o_selection_unselect(s_current->selected_object);
-
-      s_current->selected_object = NULL;
-      g_free(s_current);
-      return;
-    }
-    s_current = s_current->next;
-  }
-}
-
-/*! \todo Finish function documentation!!!
- *  \brief
- *  \par Function Description
- *
- */
-/* removes all but the head node */
-void o_selection_remove_most(TOPLEVEL *w_current, SELECTION *head)
-{
-  SELECTION *s_current;
-  SELECTION *s_prev;
-
-  s_current = o_selection_return_tail(head);
-
-  while (s_current != NULL) {
-    if (s_current->selected_object != NULL) {
-      s_prev = s_current->prev;	
-
-      o_selection_unselect(s_current->selected_object);
-
-      o_redraw_single(w_current,  
-                      s_current->selected_object);
-	
-      s_current->selected_object = NULL;
-      g_free(s_current);
-      s_current = s_prev;
-    } else {
-      break;
-    }
-  }
-
-  /* clear out any dangling pointers */
-  head->next=NULL;
-}
-
-/*! \todo Finish function documentation!!!
- *  \brief
- *  \par Function Description
- *
- */
-void o_selection_print_all( SELECTION *head )
-{
-  SELECTION *s_current;
+  GList *s_current;
 
   s_current = head;
 
   printf("START printing selection ********************\n");
   while(s_current != NULL) {
-    if (s_current->selected_object) {
+    if (s_current->data) {
       printf("Selected object: %d\n", 
-             s_current->selected_object->sid);
+	     ( (OBJECT *) s_current->data)->sid);
     }
     s_current = s_current->next;
   }
@@ -243,32 +83,12 @@ void o_selection_print_all( SELECTION *head )
 
 }
 
-/*! \todo Finish function documentation!!!
- *  \brief
- *  \par Function Description
- *
+/*! \brief Selects the given object.
+ *  \par Sets the select flag, saves the color, and then selects the 
+ *  given object
+ *  \param [in] o_selected Object to select.
+ *  \param [in] color color of the selected object.
  */
-void o_selection_destroy_all(SELECTION *head) 
-{
-  SELECTION *s_current;
-  SELECTION *s_prev;
-
-  s_current = o_selection_return_tail(head);
-
-  while (s_current != NULL) {
-    s_prev = s_current->prev;	
-    s_current->selected_object = NULL;
-    g_free(s_current);
-    s_current = s_prev;
-  }
-}
-
-/*! \todo Finish function documentation!!!
- *  \brief
- *  \par Function Description
- *
- */
-/* this sets the select flag, saves the color, and then sets the color */
 void o_selection_select(OBJECT *object, int color)
 {
   if (object->selected == TRUE) {
@@ -292,13 +112,12 @@ void o_selection_select(OBJECT *object, int color)
   }
 }
 
-/*! \todo Finish function documentation!!!
- *  \brief
- *  \par Function Description
- *
+/*! \brief Unselects the given object.
+ *  \par Unsets the select flag, restores the original color of the
+ *  given object.
+ *  This function should not be called by anybody outside of this file.
+ *  \param [in] object Object to unselect.
  */
-/* this unsets the select flag and restores the original color */
-/* this function should not be called by anybody outside of this file */
 void o_selection_unselect(OBJECT *object)
 {
   object->selected = FALSE;
@@ -307,81 +126,61 @@ void o_selection_unselect(OBJECT *object)
   /* grips are erase */
   object->color = object->saved_color;
   if (object->type == OBJ_COMPLEX || object->type == OBJ_PLACEHOLDER) { 
+    if (!object->complex) {
+      fprintf(stderr, "o_selection_unselect: Called with NULL object.\n");
+      return;
+    }
     o_complex_unset_color(object->complex->prim_objs);
   } else if (object->type == OBJ_TEXT) {
+    if (!object->text) {
+      fprintf(stderr, "o_selection_unselect: Called with NULL object.\n");
+      return;
+    }
     o_complex_unset_color(object->text->prim_objs);
   }
 
   object->saved_color = -1;
 }
 
-/*! \todo Finish function documentation!!!
- *  \brief
- *  \par Function Description
- *
+/*! \brief Removes the given object from the selection list
+ *  \par Removes the given object from the selection list and does the 
+ *  needed work to make the object visually unselected.
+ *  It's ok to call this function with an object which is not necessarily
+ *  selected.
+ *  \param [in] head Pointer to the selection list
+ *  \param [in] o_selected Object to unselect and remove from the list.
  */
-OBJECT *o_selection_return_first_object(SELECTION *head) 
+void
+o_selection_remove(GList **head, OBJECT *o_selected)
 {
-  if (!head)
-  return(NULL);
-
-  if (!head->next)  
-  return(NULL);
-
-  if (!head->next->selected_object) 
-  return(NULL);
-
-  return(head->next->selected_object);
-}
-
-/*! \todo Finish function documentation!!!
- *  \brief
- *  \par Function Description
- *
- */
-/* Nth starts counting a ZERO */
-/* doesn't consider the head node an object */
-OBJECT *o_selection_return_nth_object(SELECTION *head, int count) 
-{
-  int internal_counter = 0;
-  SELECTION *s_current;
-
-  s_current = head->next;
-
-  while (s_current != NULL) {
-    if (internal_counter == count) {
-      if (s_current->selected_object) {
-        return(s_current->selected_object);
-      }
-    }
-    internal_counter++;
+  if (o_selected == NULL) {
+    fprintf(stderr, "Got NULL for o_selected in o_selection_remove\n");
+    return;
+  }
 
-    s_current = s_current->next;
+  if (g_list_find(*head, o_selected) != NULL) {
+    o_selection_unselect(o_selected);
+    *head = g_list_remove(*head, o_selected);
   }
-  return(NULL);
 }
 
-/*! \todo Finish function documentation!!!
- *  \brief
- *  \par Function Description
- *
+/*! \brief Unselects all the objects in the given list.
+ *  \par Unselects all objects in the given list, does the 
+ *  needed work to make the objects visually unselected, and redraw them.
+ *  \param [in] w_current TOPLEVEL struct.
+ *  \param [in] head Pointer to the selection list
  */
-int o_selection_return_num(SELECTION *head)
+void
+o_selection_unselect_list(TOPLEVEL *w_current, GList **head)
 {
-  int counter = 0;
-  SELECTION *s_current;
-
-  if (!head) {
-    return 0;
-  }
+  GList *list = *head;
   
-  /* skip over head */
-  s_current = head->next;
-
-  while (s_current != NULL) {
-    counter++;
-    s_current = s_current->next;
+  while (list != NULL) {
+    o_selection_unselect((OBJECT *) list->data);
+    o_redraw_single(w_current, (OBJECT *) list->data);
+   list = list->next;
   }
   
-  return(counter);
+  g_list_free(*head);
+  *head = NULL;  
 }
diff --git a/libgeda/src/o_text_basic.c b/libgeda/src/o_text_basic.c
index 36070ef..4e6553c 100644
--- a/libgeda/src/o_text_basic.c
+++ b/libgeda/src/o_text_basic.c
@@ -69,8 +69,8 @@ int tab_in_chars = 8;
 void get_text_bounds(TOPLEVEL *w_current, OBJECT *o_current,
 		     int *left, int *top, int *right, int *bottom)
 {
-  get_complex_bounds(w_current, o_current->text->prim_objs, left, top,
-                     right, bottom);
+  get_object_list_bounds(w_current, o_current->text->prim_objs, left, top,
+			 right, bottom);
 }
 
 /*! \todo Finish function documentation!!!
@@ -1017,8 +1017,8 @@ void o_text_recalc(TOPLEVEL *w_current, OBJECT *o_current)
     return;
   }
 
-  get_complex_bounds(w_current, o_current->text->prim_objs, 
-                     &left, &top, &right, &bottom);
+  get_object_list_bounds(w_current, o_current->text->prim_objs, 
+			 &left, &top, &right, &bottom);
   o_current->left = left;
   o_current->top = top;
   o_current->right = right;
diff --git a/libgeda/src/s_basic.c b/libgeda/src/s_basic.c
index 4d7d844..140c90b 100644
--- a/libgeda/src/s_basic.c
+++ b/libgeda/src/s_basic.c
@@ -362,26 +362,10 @@ void print_struct(OBJECT *ptr)
  *  \par Function Description
  *
  */
-void s_delete(TOPLEVEL *w_current, OBJECT *o_current)
+void
+s_delete_object(TOPLEVEL *w_current, OBJECT *o_current)
 {
   if (o_current != NULL) {
-
-
-#if DEBUG
-    printf("sdel: %s\n", o_current->name);
-    printf("sdel: %d\n", o_current->sid);
-#endif
-
-    if (o_current->next) 
-    o_current->next->prev = o_current->prev;
-    else
-    o_current->next = NULL;
-
-    if (o_current->prev) 
-    o_current->prev->next = o_current->next;
-    else
-    o_current->prev = NULL;
-
     s_conn_remove(w_current, o_current);
 	
     /* second half of if is odd that we need it? hack */
@@ -512,6 +496,36 @@ void s_delete(TOPLEVEL *w_current, OBJECT *o_current)
  *  \par Function Description
  *
  */
+void
+s_delete(TOPLEVEL *w_current, OBJECT *o_current)
+{
+  if (o_current != NULL) {
+
+
+#if DEBUG
+    printf("sdel: %s\n", o_current->name);
+    printf("sdel: %d\n", o_current->sid);
+#endif
+
+    if (o_current->next) 
+    o_current->next->prev = o_current->prev;
+    else
+    o_current->next = NULL;
+
+    if (o_current->prev) 
+    o_current->prev->next = o_current->next;
+    else
+    o_current->prev = NULL;
+    
+    s_delete_object(w_current, o_current);
+  }
+}
+
+/*! \todo Finish function documentation!!!
+ *  \brief
+ *  \par Function Description
+ *
+ */
 /* deletes everything include the head */
 void s_delete_list_fromstart(TOPLEVEL *w_current, OBJECT *start)
 {
@@ -561,6 +575,30 @@ void s_delete_list_fromstart(OBJECT *start)
 /*! \todo Finish function documentation!!!
  *  \brief
  *  \par Function Description
+ *
+ */
+/* deletes everything include the head */
+void
+s_delete_object_glist(TOPLEVEL *w_current, GList *list)
+{
+  OBJECT *o_current=NULL;
+  GList *ptr;
+
+  ptr = g_list_last(list);
+
+  /* do the delete backwards */
+  while(ptr != NULL) {
+    o_current = (OBJECT *) ptr->data;
+    s_delete_object(w_current, o_current);
+    ptr = ptr->prev;
+  }
+
+}
+
+
+/*! \todo Finish function documentation!!!
+ *  \brief
+ *  \par Function Description
  *  This function removes one object pointed by parameter <B>object</B> from
  *  a list as far as it does not represents a head. If so the function returns
  *  NULL. If not it returns the pointer on the object, i.e. the same as the
diff --git a/libgeda/src/s_page.c b/libgeda/src/s_page.c
index eaa407d..9d1619c 100644
--- a/libgeda/src/s_page.c
+++ b/libgeda/src/s_page.c
@@ -100,15 +100,12 @@ PAGE *s_page_new (TOPLEVEL *toplevel, const gchar *filename)
   page->object_head->type = OBJ_HEAD;
 
   /* new selection mechanism */
-  page->selection2_head = page->selection2_tail = 
-  o_selection_new_head();
+  page->selection_list = NULL;
 
   /* net/pin/bus stretch when doing moves */
   page->stretch_head = page->stretch_tail = s_stretch_new_head();
 
-  page->complex_place_tail = page->complex_place_head = 
-  s_basic_init_object("complex_place_head");
-  page->complex_place_tail->type = OBJ_HEAD;
+  page->complex_place_list = NULL;
 
   /* add p_attrib and p_attached_to */
   page->attrib_place_tail = page->attrib_place_head = 
@@ -169,7 +166,8 @@ void s_page_delete (TOPLEVEL *toplevel, PAGE *page)
   gchar *real_filename;
   gchar *only_filename;
   gchar *dirname;
-  
+  int redraw_status=toplevel->DONT_REDRAW;
+
   g_assert (page->pid != -1);
 
   /* we need to play with page_current because s_delete_list_fromstart() */
@@ -211,13 +209,20 @@ void s_page_delete (TOPLEVEL *toplevel, PAGE *page)
   }
   g_free(real_filename);
 
-  /* first delete objects of page */
+  /* first unselect the objects, without redrawing them */
+  toplevel->DONT_REDRAW = 1;
+  o_selection_unselect_list(toplevel, &(page->selection_list));
+  toplevel->DONT_REDRAW = redraw_status;
+
+  /* then delete objects of page */
   s_delete_list_fromstart (toplevel, page->object_head);
   
   toplevel->REMOVING_SEL = 1;
-  s_delete_list_fromstart (toplevel, page->complex_place_head);
+  /* The complex place list contain a reference to the objects in the page */
+  /* So don't free the objects there. */
+  g_list_free (page->complex_place_list);
+  page->complex_place_list = NULL;
   s_delete_list_fromstart (toplevel, page->attrib_place_head);
-  o_selection_destroy_all (page->selection2_head);
   toplevel->REMOVING_SEL = 0;  
 
 #if DEBUG

_______________________________________________
geda-dev mailing list
[email protected]
http://www.seul.org/cgi-bin/mailman/listinfo/geda-dev

Reply via email to