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

gEDA-cvs: branch: master updated (1.1.1.20070708-10-g1dfb3a4)



The branch, master has been updated
       via  1dfb3a4b9907ff81552de57080d2897ab40e512c (commit)
       via  c06b6684296a2ec6765036b28e8c48a50c2b8928 (commit)
       via  cb9c4ee19ca58158308a234782fdad6fb60257da (commit)
       via  10e79873064a096f8af4b0b6dcb9f957be0f6859 (commit)
      from  b5caa78a6dd9227d328397cb77ac4b0731c7d1c9 (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
=========

 gattrib/src/s_object.c         |    4 +-
 gschem/include/prototype.h     |    2 +-
 gschem/include/x_multiattrib.h |    1 +
 gschem/src/i_basic.c           |    2 +-
 gschem/src/i_callbacks.c       |   85 ++++++++---------
 gschem/src/o_attrib.c          |   33 ++++---
 gschem/src/o_basic.c           |   19 ++--
 gschem/src/o_buffer.c          |   18 ++--
 gschem/src/o_complex.c         |    8 +-
 gschem/src/o_copy.c            |  207 ++++++++++++++++++---------------------
 gschem/src/o_delete.c          |    9 +-
 gschem/src/o_find.c            |   10 +-
 gschem/src/o_grips.c           |    2 +-
 gschem/src/o_misc.c            |   10 +-
 gschem/src/o_move.c            |   22 ++--
 gschem/src/o_picture.c         |    4 +-
 gschem/src/o_select.c          |   61 +++++-------
 gschem/src/o_text.c            |   15 +--
 gschem/src/x_attribedit.c      |    6 +-
 gschem/src/x_autonumber.c      |    3 +-
 gschem/src/x_dialog.c          |    8 +-
 gschem/src/x_event.c           |   38 ++++----
 gschem/src/x_image.c           |    7 +-
 gschem/src/x_multiattrib.c     |   43 +++++----
 gschem/src/x_print.c           |    4 +-
 libgeda/include/Makefile.am    |    3 +-
 libgeda/include/geda_list.h    |   61 ++++++++++++
 libgeda/include/libgeda.h      |    1 +
 libgeda/include/prototype.h    |   10 +-
 libgeda/include/struct.h       |    5 +-
 libgeda/src/Makefile.am        |    3 +-
 libgeda/src/geda_list.c        |  213 ++++++++++++++++++++++++++++++++++++++++
 libgeda/src/o_net_basic.c      |   21 ++---
 libgeda/src/o_selection.c      |  108 +++++++++++----------
 libgeda/src/s_page.c           |   13 +--
 35 files changed, 652 insertions(+), 407 deletions(-)
 create mode 100644 libgeda/include/geda_list.h
 create mode 100644 libgeda/src/geda_list.c


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

commit 1dfb3a4b9907ff81552de57080d2897ab40e512c
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Date:   Thu Jul 19 15:13:03 2007 +0100

    Make the Escape key cancel editing in the multiattrib dialog.
    
    The previous behaviour where it would quit editing but save the changes is
    counter-intuitive for the user.

:100644 100644 e53f06e... 3339b4d... M	gschem/include/x_multiattrib.h
:100644 100644 f0fe51f... bf396c2... M	gschem/src/x_multiattrib.c

commit c06b6684296a2ec6765036b28e8c48a50c2b8928
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Date:   Thu Jul 19 15:13:00 2007 +0100

    Remove workaround for an unknown property with GTK 2.2 in x_multiattrib.c

:100644 100644 8d103ac... f0fe51f... M	gschem/src/x_multiattrib.c

commit cb9c4ee19ca58158308a234782fdad6fb60257da
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Date:   Thu Jul 19 15:09:56 2007 +0100

    Change selection code to use a generic GedaList typecast to SELECTION.
    
    GedaList allows various parts of the program to keep track of changes
    to the selection via callbacks attached to the GedaList object.

:100644 100644 0068aae... 953aa47... M	gattrib/src/s_object.c
:100644 100644 131100d... e2eb4b9... M	gschem/include/prototype.h
:100644 100644 254e5f6... e0e8ab3... M	gschem/src/i_basic.c
:100644 100644 266e74c... e32c53a... M	gschem/src/i_callbacks.c
:100644 100644 c847cd8... a18a37d... M	gschem/src/o_attrib.c
:100644 100644 24639aa... c599759... M	gschem/src/o_basic.c
:100644 100644 4b8d375... 44429fc... M	gschem/src/o_buffer.c
:100644 100644 d2ee71a... f2ec4b2... M	gschem/src/o_complex.c
:100644 100644 1f63437... a78b810... M	gschem/src/o_copy.c
:100644 100644 73991ed... 0db8599... M	gschem/src/o_delete.c
:100644 100644 488160e... e0e60e1... M	gschem/src/o_find.c
:100644 100644 698a0d4... 0c6e8a8... M	gschem/src/o_grips.c
:100644 100644 908e906... 246e65b... M	gschem/src/o_misc.c
:100644 100644 2f80d81... d15fad2... M	gschem/src/o_move.c
:100644 100644 247ba75... 9265ea7... M	gschem/src/o_picture.c
:100644 100644 f90c1b9... 388e268... M	gschem/src/o_select.c
:100644 100644 e81de34... 47bb182... M	gschem/src/o_text.c
:100644 100644 0cd7571... 0fb8f5a... M	gschem/src/x_attribedit.c
:100644 100644 30b21cf... b3f5504... M	gschem/src/x_autonumber.c
:100644 100644 44bf763... f0eab7c... M	gschem/src/x_dialog.c
:100644 100644 5730ef7... fcf553e... M	gschem/src/x_event.c
:100644 100644 43f4267... 1846155... M	gschem/src/x_image.c
:100644 100644 498e3ff... 8d103ac... M	gschem/src/x_multiattrib.c
:100644 100644 dbde684... d96bb36... M	gschem/src/x_print.c
:100644 100644 471d209... 5f4560c... M	libgeda/include/prototype.h
:100644 100644 de47c1e... 6f0befa... M	libgeda/include/struct.h
:100644 100644 9e2b275... 5386ee1... M	libgeda/src/o_net_basic.c
:100644 100644 19a947f... 5d048cd... M	libgeda/src/o_selection.c
:100644 100644 e2e2f41... a7a2b92... M	libgeda/src/s_page.c

commit 10e79873064a096f8af4b0b6dcb9f957be0f6859
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Date:   Thu Jul 19 15:06:57 2007 +0100

    Added new GedaList class derived from GObject
    
    This abstracts a GList with API for write access. Its main use is in list
    change notification, as it emits a "changed" g_signal when modified.
    Read only access to the underlying GList is provided by an accessor,
    currenly implemented as a macro.

:100644 100644 eb5420f... 8357985... M	libgeda/include/Makefile.am
:000000 100644 0000000... 492c78c... A	libgeda/include/geda_list.h
:100644 100644 e458a7a... 074fe0a... M	libgeda/include/libgeda.h
:100644 100644 8d7495b... 3015c90... M	libgeda/src/Makefile.am
:000000 100644 0000000... b6792c6... A	libgeda/src/geda_list.c

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

commit 1dfb3a4b9907ff81552de57080d2897ab40e512c
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Date:   Thu Jul 19 15:13:03 2007 +0100

    Make the Escape key cancel editing in the multiattrib dialog.
    
    The previous behaviour where it would quit editing but save the changes is
    counter-intuitive for the user.

diff --git a/gschem/include/x_multiattrib.h b/gschem/include/x_multiattrib.h
index e53f06e..3339b4d 100644
--- a/gschem/include/x_multiattrib.h
+++ b/gschem/include/x_multiattrib.h
@@ -83,6 +83,7 @@ struct _CellTextViewClass {
 struct _CellTextView {
   GtkTextView parent_instance;
 
+  gboolean editing_canceled;
 };
 
 
diff --git a/gschem/src/x_multiattrib.c b/gschem/src/x_multiattrib.c
index f0fe51f..bf396c2 100644
--- a/gschem/src/x_multiattrib.c
+++ b/gschem/src/x_multiattrib.c
@@ -97,19 +97,21 @@ static void celltextview_cell_editable_init (GtkCellEditableIface *iface);
  *
  */
 static gboolean celltextview_key_press_event (GtkWidget   *widget,
-					      GdkEventKey *event,
-					      gpointer     data)
+                                              GdkEventKey *key_event,
+                                              gpointer     data)
 {
   CellTextView *celltextview = (CellTextView*)widget;
 
-  /* ends editing of cell if one of these keys are pressed */
-  if (
-    /* the Escape key */
-    event->keyval == GDK_Escape ||
-    /* the Enter key without the Control modifier */
-    (!(event->state & GDK_CONTROL_MASK) &&
-     (event->keyval == GDK_Return ||
-      event->keyval == GDK_KP_Enter))) {
+  /* If the Escape key is pressed, we flag the edit as canceled */
+  if (key_event->keyval == GDK_Escape)
+      celltextview->editing_canceled = TRUE;
+
+  /* ends editing of cell if one of these keys are pressed or editing is canceled */
+  if (celltextview->editing_canceled == TRUE ||
+      /* the Enter key without the Control modifier */
+      (!(key_event->state & GDK_CONTROL_MASK) &&
+       (key_event->keyval == GDK_Return ||
+        key_event->keyval == GDK_KP_Enter))) {
     gtk_cell_editable_editing_done  (GTK_CELL_EDITABLE (celltextview));
     gtk_cell_editable_remove_widget (GTK_CELL_EDITABLE (celltextview));
     return TRUE;
@@ -187,8 +189,9 @@ static void celltextview_class_init(CellTextViewClass *klass)
  *  \par Function Description
  *
  */
-static void celltextview_init(CellTextView *self)
+static void celltextview_init(CellTextView *celltextview)
 {
+  celltextview->editing_canceled = FALSE;
 }
 
 /*! \todo Finish function documentation
@@ -296,17 +299,22 @@ static void cellrenderermultilinetext_editing_done(GtkCellEditable *cell_editabl
     cell->focus_out_id = 0;
   }
 
+  gtk_cell_renderer_stop_editing (GTK_CELL_RENDERER (cell),
+                                  CELL_TEXT_VIEW (cell_editable)->editing_canceled);
+  if (CELL_TEXT_VIEW (cell_editable)->editing_canceled)
+    return;
+
   buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (cell_editable));
   gtk_text_buffer_get_start_iter (buffer, &start);
   gtk_text_buffer_get_end_iter   (buffer, &end);
   new_text = gtk_text_buffer_get_text (buffer, &start, &end, TRUE);
-  
+
   path = g_object_get_data (G_OBJECT (cell_editable),
                             CELL_RENDERER_MULTI_LINE_TEXT_PATH);
   g_signal_emit_by_name (cell, "edited", path, new_text);
 
   g_free (new_text);
-  
+
 }
 
 /*! \todo Finish function documentation

commit c06b6684296a2ec6765036b28e8c48a50c2b8928
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Date:   Thu Jul 19 15:13:00 2007 +0100

    Remove workaround for an unknown property with GTK 2.2 in x_multiattrib.c

diff --git a/gschem/src/x_multiattrib.c b/gschem/src/x_multiattrib.c
index 8d103ac..f0fe51f 100644
--- a/gschem/src/x_multiattrib.c
+++ b/gschem/src/x_multiattrib.c
@@ -249,17 +249,14 @@ static GtkCellEditable* cellrenderermultilinetext_start_editing(GtkCellRenderer
   gtk_text_buffer_set_text (textbuffer,
                             cell_text->text,
                             strlen (cell_text->text));
-  
+
   textview = GTK_WIDGET (g_object_new (TYPE_CELL_TEXT_VIEW,
                                        /* GtkTextView */
-				       /* unknown property in GTK 2.2, use
-					* gtk_text_view_set_buffer() instead */
-				       /* "buffer",   textbuffer, */
+                                       "buffer",   textbuffer,
                                        "editable", TRUE,
                                        /* GtkWidget */
                                        "height-request", cell_area->height,
                                        NULL));
-  gtk_text_view_set_buffer (GTK_TEXT_VIEW (textview), textbuffer);
   g_object_set_data_full (G_OBJECT (textview),
                           CELL_RENDERER_MULTI_LINE_TEXT_PATH,
                           g_strdup (path), g_free);

commit cb9c4ee19ca58158308a234782fdad6fb60257da
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Date:   Thu Jul 19 15:09:56 2007 +0100

    Change selection code to use a generic GedaList typecast to SELECTION.
    
    GedaList allows various parts of the program to keep track of changes
    to the selection via callbacks attached to the GedaList object.

diff --git a/gattrib/src/s_object.c b/gattrib/src/s_object.c
index 0068aae..953aa47 100644
--- a/gattrib/src/s_object.c
+++ b/gattrib/src/s_object.c
@@ -322,8 +322,8 @@ OBJECT *s_object_attrib_add_attrib_in_object(TOPLEVEL * pr_current, char *text_s
 		    pr_current->page_current->object_tail, o_current);
   }
 
-  o_selection_add(&(pr_current->page_current->selection_list),
-		  pr_current->page_current->object_tail);
+  o_selection_add( pr_current->page_current->selection_list,
+                   pr_current->page_current->object_tail);
 
 
   pr_current->page_current->CHANGED = 1;
diff --git a/gschem/include/prototype.h b/gschem/include/prototype.h
index 131100d..e2eb4b9 100644
--- a/gschem/include/prototype.h
+++ b/gschem/include/prototype.h
@@ -473,7 +473,7 @@ void o_arc_rubberarc_xor(TOPLEVEL *w_current);
 void o_arc_draw_grips(TOPLEVEL *w_current, OBJECT *o_current);
 void o_arc_erase_grips(TOPLEVEL *w_current, OBJECT *o_current);
 /* o_attrib.c */
-void o_attrib_add_selected(TOPLEVEL *w_current, GList **selection_list, OBJECT *selected);
+void o_attrib_add_selected(TOPLEVEL *w_current, SELECTION *selection, OBJECT *selected);
 void o_attrib_toggle_visibility(TOPLEVEL *w_current, GList *list);
 void o_attrib_toggle_show_name_value(TOPLEVEL *w_current, GList *list, int new_show_name_value);
 void o_attrib_start(TOPLEVEL *w_current, int screen_x, int screen_y);
diff --git a/gschem/src/i_basic.c b/gschem/src/i_basic.c
index 254e5f6..e0e8ab3 100644
--- a/gschem/src/i_basic.c
+++ b/gschem/src/i_basic.c
@@ -388,7 +388,7 @@ void i_update_menus(TOPLEVEL *w_current)
   g_assert(w_current != NULL);
   g_assert(w_current->page_current != NULL);
 
-  if (w_current->page_current->selection_list != NULL) {
+  if ( geda_list_get_glist( w_current->page_current->selection_list ) != NULL ) {
     /* since one or more things are selected, we set these TRUE */
     /* These strings should NOT be internationalized */
     x_menus_sensitivity(w_current, "Edit/Cut Buffer", TRUE);
diff --git a/gschem/src/i_callbacks.c b/gschem/src/i_callbacks.c
index 266e74c..e32c53a 100644
--- a/gschem/src/i_callbacks.c
+++ b/gschem/src/i_callbacks.c
@@ -728,7 +728,7 @@ DEFINE_I_CALLBACK(edit_edit)
   exit_if_null(w_current);
 
   i_update_middle_button(w_current, i_callback_edit_edit, _("Edit"));
-  o_edit(w_current, w_current->page_current->selection_list);
+  o_edit(w_current, geda_list_get_glist( w_current->page_current->selection_list ) );
 }
 
 /*! \todo Finish function documentation!!!
@@ -868,7 +868,7 @@ DEFINE_I_CALLBACK(edit_rotate_90_hotkey)
   
   o_redraw_cleanstates(w_current);	
 
-  object_list = w_current->page_current->selection_list;    
+  object_list = geda_list_get_glist( w_current->page_current->selection_list );
 
   if (object_list) {
     i_update_middle_button(w_current,
@@ -917,7 +917,7 @@ DEFINE_I_CALLBACK(edit_mirror_hotkey)
 
   o_redraw_cleanstates(w_current);	
 
-  object_list = w_current->page_current->selection_list;    
+  object_list = geda_list_get_glist( w_current->page_current->selection_list );
 
   if (object_list) {
     i_update_middle_button(w_current,
@@ -1024,7 +1024,7 @@ DEFINE_I_CALLBACK(edit_embed)
   if (o_select_selected(w_current)) {
     /* yes, embed each selected component */
     GList *s_current =
-      w_current->page_current->selection_list;
+      geda_list_get_glist( w_current->page_current->selection_list );
 
     while (s_current != NULL) {
       o_current = (OBJECT *) s_current->data;
@@ -1062,7 +1062,7 @@ DEFINE_I_CALLBACK(edit_unembed)
   if (o_select_selected(w_current)) {
     /* yes, unembed each selected component */
     GList *s_current =
-      w_current->page_current->selection_list;
+      geda_list_get_glist( w_current->page_current->selection_list );
 
     while (s_current != NULL) {
       o_current = (OBJECT *) s_current->data;
@@ -1108,7 +1108,7 @@ DEFINE_I_CALLBACK(edit_update)
     /* left selected. */
 
     /* g_list_copy does a shallow copy which is exactly what we need here */
-    selection_copy = g_list_copy(w_current->page_current->selection_list);
+    selection_copy = g_list_copy( geda_list_get_glist( w_current->page_current->selection_list ));
     s_current = selection_copy;
     while (s_current != NULL) {
       o_current = (OBJECT *) s_current->data;
@@ -1119,13 +1119,12 @@ DEFINE_I_CALLBACK(edit_update)
       else
       {
         /* object was not a OBJ_COMPLEX, so unselect it. */
-        o_selection_remove (&(w_current->page_current->selection_list),
-                            o_current);
+        o_selection_remove( w_current->page_current->selection_list, o_current);
       }
       s_current = s_current->next;
     }
     g_list_free(selection_copy);
-   
+
     /* Make sure the display is up to date */
     o_redraw_all(w_current);
   } else {
@@ -1273,7 +1272,7 @@ DEFINE_I_CALLBACK(edit_linetype)
   /* anything selected ? */
   if (o_select_selected(w_current)) {
     GList *s_current =
-      w_current->page_current->selection_list;
+      geda_list_get_glist( w_current->page_current->selection_list );
     GList *objects = NULL;
 
     /* yes, build a list of relevant objects */
@@ -1316,7 +1315,7 @@ DEFINE_I_CALLBACK(edit_filltype)
   /* anything selected ? */
   if (o_select_selected(w_current)) {
     GList *s_current =
-      w_current->page_current->selection_list;
+      geda_list_get_glist( w_current->page_current->selection_list );
     GList *objects = NULL;
 
     /* yes, build a list of relevant objects */
@@ -1830,8 +1829,8 @@ DEFINE_I_CALLBACK(buffer_copy1)
 
   exit_if_null(w_current);
 
-  if (w_current->page_current->selection_list == NULL)
-  return;
+  if ( geda_list_get_glist( w_current->page_current->selection_list ) == NULL )
+    return;
 
   i_update_middle_button(w_current, i_callback_buffer_copy1, _("Copy 1"));
   o_buffer_copy(w_current, 0);
@@ -1849,8 +1848,8 @@ DEFINE_I_CALLBACK(buffer_copy2)
 
   exit_if_null(w_current);
 
-  if (w_current->page_current->selection_list == NULL)
-  return;
+  if ( geda_list_get_glist( w_current->page_current->selection_list ) == NULL )
+    return;
 
   i_update_middle_button(w_current, i_callback_buffer_copy2, _("Copy 2"));
   o_buffer_copy(w_current, 1);
@@ -1868,8 +1867,8 @@ DEFINE_I_CALLBACK(buffer_copy3)
 
   exit_if_null(w_current);
 
-  if (w_current->page_current->selection_list == NULL)
-  return;
+  if ( geda_list_get_glist( w_current->page_current->selection_list ) == NULL )
+    return;
 
   i_update_middle_button(w_current, i_callback_buffer_copy3, _("Copy 3"));
   o_buffer_copy(w_current, 2);
@@ -1887,8 +1886,8 @@ DEFINE_I_CALLBACK(buffer_copy4)
 
   exit_if_null(w_current);
 
-  if (w_current->page_current->selection_list == NULL)
-  return;
+  if ( geda_list_get_glist( w_current->page_current->selection_list ) == NULL )
+    return;
 
   i_update_middle_button(w_current, i_callback_buffer_copy4, _("Copy 4"));
   o_buffer_copy(w_current, 3);
@@ -1906,8 +1905,8 @@ DEFINE_I_CALLBACK(buffer_copy5)
 
   exit_if_null(w_current);
 
-  if (w_current->page_current->selection_list == NULL)
-  return;
+  if ( geda_list_get_glist( w_current->page_current->selection_list ) == NULL )
+    return;
 
   i_update_middle_button(w_current, i_callback_buffer_copy5, _("Copy 5"));
   o_buffer_copy(w_current, 4);
@@ -1925,8 +1924,8 @@ DEFINE_I_CALLBACK(buffer_cut1)
 
   exit_if_null(w_current);
 
-  if (w_current->page_current->selection_list == NULL)
-  return;
+  if ( geda_list_get_glist( w_current->page_current->selection_list ) == NULL )
+    return;
 
   i_update_middle_button(w_current, i_callback_buffer_cut1, _("Cut 1"));
   o_buffer_cut(w_current, 0);
@@ -1944,8 +1943,8 @@ DEFINE_I_CALLBACK(buffer_cut2)
 
   exit_if_null(w_current);
 
-  if (w_current->page_current->selection_list == NULL)
-  return;
+  if ( geda_list_get_glist( w_current->page_current->selection_list ) == NULL )
+    return;
 
   i_update_middle_button(w_current, i_callback_buffer_cut2, _("Cut 2"));
   o_buffer_cut(w_current, 1);
@@ -1963,8 +1962,8 @@ DEFINE_I_CALLBACK(buffer_cut3)
 
   exit_if_null(w_current);
 
-  if (w_current->page_current->selection_list == NULL)
-  return;
+  if ( geda_list_get_glist( w_current->page_current->selection_list ) == NULL )
+    return;
 
   i_update_middle_button(w_current, i_callback_buffer_cut3, _("Cut 3"));
   o_buffer_cut(w_current, 2);
@@ -1982,8 +1981,8 @@ DEFINE_I_CALLBACK(buffer_cut4)
 
   exit_if_null(w_current);
 
-  if (w_current->page_current->selection_list == NULL)
-  return;
+  if ( geda_list_get_glist( w_current->page_current->selection_list ) == NULL )
+    return;
 
   i_update_middle_button(w_current, i_callback_buffer_cut4, _("Cut 4"));
   o_buffer_cut(w_current, 3);
@@ -2001,8 +2000,8 @@ DEFINE_I_CALLBACK(buffer_cut5)
 
   exit_if_null(w_current);
 
-  if (w_current->page_current->selection_list == NULL)
-  return;
+  if ( geda_list_get_glist( w_current->page_current->selection_list ) == NULL )
+    return;
 
   i_update_middle_button(w_current, i_callback_buffer_cut5, _("Cut 5"));
   o_buffer_cut(w_current, 4);
@@ -2991,7 +2990,7 @@ DEFINE_I_CALLBACK(attributes_attach)
                          _("Attach"));
 
   /* skip over head */
-  s_current = w_current->page_current->selection_list;
+  s_current = geda_list_get_glist( w_current->page_current->selection_list );
   if (!s_current) {
     return;
   }
@@ -3040,7 +3039,7 @@ DEFINE_I_CALLBACK(attributes_detach)
                          _("Detach"));
 
   /* skip over head */
-  s_current = w_current->page_current->selection_list;
+  s_current = geda_list_get_glist( w_current->page_current->selection_list );
   while (s_current != NULL) {
     o_current = (OBJECT *) s_current->data;
     if (o_current) {
@@ -3080,9 +3079,8 @@ DEFINE_I_CALLBACK(attributes_show_name)
                          _("ShowN"));
 
   if (object != NULL) {
-    o_attrib_toggle_show_name_value(w_current, 
-                                    w_current->page_current->
-                                    selection_list,
+    o_attrib_toggle_show_name_value(w_current,
+                                    geda_list_get_glist( w_current->page_current->selection_list ),
                                     SHOW_NAME);
   }
 }
@@ -3111,9 +3109,8 @@ DEFINE_I_CALLBACK(attributes_show_value)
                          _("ShowV"));
 
   if (object != NULL) {
-    o_attrib_toggle_show_name_value(w_current, 
-                                    w_current->page_current->
-                                    selection_list,
+    o_attrib_toggle_show_name_value(w_current,
+                                    geda_list_get_glist( w_current->page_current->selection_list ),
                                     SHOW_VALUE);
   }
 }
@@ -3142,9 +3139,8 @@ DEFINE_I_CALLBACK(attributes_show_both)
                          _("ShowB"));
 
   if (object != NULL) {
-    o_attrib_toggle_show_name_value(w_current, 
-                                    w_current->page_current->
-                                    selection_list,
+    o_attrib_toggle_show_name_value(w_current,
+                                    geda_list_get_glist( w_current->page_current->selection_list ),
                                     SHOW_NAME_VALUE);
   }
 }
@@ -3174,9 +3170,8 @@ DEFINE_I_CALLBACK(attributes_visibility_toggle)
                          _("VisToggle"));
 
   if (object != NULL) {
-    o_attrib_toggle_visibility(w_current, 
-                               w_current->page_current->
-                               selection_list);
+    o_attrib_toggle_visibility(w_current,
+                               geda_list_get_glist( w_current->page_current->selection_list ) );
   }
 }
 
diff --git a/gschem/src/o_attrib.c b/gschem/src/o_attrib.c
index c847cd8..a18a37d 100644
--- a/gschem/src/o_attrib.c
+++ b/gschem/src/o_attrib.c
@@ -52,12 +52,12 @@
  *
  *  \todo get a better name
  */
-void o_attrib_add_selected(TOPLEVEL *w_current, GList** selection_list_ptr,
-			   OBJECT *selected)
+void o_attrib_add_selected(TOPLEVEL *w_current, SELECTION *selection,
+                           OBJECT *selected)
 {
   ATTRIB *a_current;
 
-  if (!(*selection_list_ptr)) return;
+  g_assert( selection != NULL );
 
   /* deal with attributes here? */
   if (selected->attribs != NULL) {
@@ -68,12 +68,9 @@ void o_attrib_add_selected(TOPLEVEL *w_current, GList** selection_list_ptr,
 
       if (a_current->object) {
 
-				/* make sure object isn't selected already */
+        /* make sure object isn't selected already */
         if (a_current->object->saved_color == -1) {
-          o_selection_add(selection_list_ptr,
-			  /* w_current->page_current->
-			     selection2_head,*/
-			  a_current->object);
+          o_selection_add(selection, a_current->object);
           o_redraw_single(w_current, a_current->object);
         }
 
@@ -334,8 +331,14 @@ void o_attrib_end(TOPLEVEL *w_current)
 
   /* here is where you attach the stuff */
   /* if an object is selected, else just place it */
-  /* selection_head should never be null since it has a head struct */
-  object = (OBJECT *) g_list_first (w_current->page_current->selection_list)->data;
+
+  GList *iter = geda_list_get_glist( w_current->page_current->selection_list );
+
+  if ( iter == NULL )
+    object = NULL;
+  else
+    object = (OBJECT *)iter->data;
+
   if (object != NULL) {
     /* should attribute be selected? probably */
     /* this is probably okay, NEWSEL, since tail is a single obj */
@@ -345,9 +348,9 @@ void o_attrib_end(TOPLEVEL *w_current)
                     object);
   }
 
-  o_selection_add(&(w_current->page_current->selection_list),
-		  w_current->page_current->object_tail);
-  o_undo_savestate(w_current, UNDO_ALL);
+  o_selection_add( w_current->page_current->selection_list,
+                   w_current->page_current->object_tail );
+  o_undo_savestate( w_current, UNDO_ALL );
 }
 
 /*! \todo Finish function documentation!!!
@@ -466,8 +469,8 @@ OBJECT *o_attrib_add_attrib(TOPLEVEL *w_current,
                     o_current);
   }
 
-  o_selection_add(&(w_current->page_current->selection_list),
-		  w_current->page_current->object_tail);
+  o_selection_add( w_current->page_current->selection_list,
+                   w_current->page_current->object_tail );
 
   o_text_erase(w_current, w_current->page_current->object_tail); 
   o_text_draw(w_current, w_current->page_current->object_tail);
diff --git a/gschem/src/o_basic.c b/gschem/src/o_basic.c
index 24639aa..c599759 100644
--- a/gschem/src/o_basic.c
+++ b/gschem/src/o_basic.c
@@ -52,21 +52,21 @@ void o_redraw_all(TOPLEVEL *w_current)
     switch(w_current->event_state) {
       case(MOVE):
       case(ENDMOVE):
-	o_erase_selected(w_current);	
-	/* continue */
+        o_erase_selected(w_current);
+        /* continue */
       case(ENDCOPY):
       case(ENDMCOPY):
-	o_drawbounding(w_current, NULL,
-                       w_current->page_current->selection_list,
+        o_drawbounding(w_current, NULL,
+                       geda_list_get_glist( w_current->page_current->selection_list ),
                        x_get_darkcolor(w_current->bb_color), FALSE);
 
         break;
 
       case(DRAWCOMP):
       case(ENDCOMP):
-        o_drawbounding(w_current, 
+        o_drawbounding(w_current,
                        NULL,
-		       w_current->page_current->complex_place_list,
+                       w_current->page_current->complex_place_list,
                        x_get_darkcolor(w_current->bb_color), FALSE);
         break;
 
@@ -148,7 +148,7 @@ void o_unselect_all(TOPLEVEL *w_current)
   if (!w_current->SHIFTKEY) {
     o_select_run_hooks(w_current, NULL, 2);
     o_selection_unselect_list(w_current,
-			      &(w_current->page_current->selection_list));
+                              w_current->page_current->selection_list );
   }
 }
 
@@ -192,14 +192,13 @@ void o_draw_selected(TOPLEVEL *w_current)
     return;
   }
 
-  s_current = w_current->page_current->selection_list;
+  s_current = geda_list_get_glist( w_current->page_current->selection_list );
   while (s_current != NULL) {
     o_current = (OBJECT *) s_current->data;
 
     if (o_current) {
       o_redraw_single(w_current, o_current);
     }
-    
     s_current=s_current->next;
   }
 
@@ -218,7 +217,7 @@ void o_erase_selected(TOPLEVEL *w_current)
     return;
   }
 
-  s_current = w_current->page_current->selection_list;
+  s_current = geda_list_get_glist( w_current->page_current->selection_list );
   while (s_current != NULL) {
     o_current = (OBJECT *) s_current->data;
 
diff --git a/gschem/src/o_buffer.c b/gschem/src/o_buffer.c
index 4b8d375..44429fc 100644
--- a/gschem/src/o_buffer.c
+++ b/gschem/src/o_buffer.c
@@ -43,7 +43,7 @@ void o_buffer_copy(TOPLEVEL *w_current, int buf_num)
     return;
   }
 
-  s_current = w_current->page_current->selection_list;
+  s_current = geda_list_get_glist( w_current->page_current->selection_list );
 
   if (object_buffer[buf_num] == NULL) {
     object_buffer[buf_num] = s_basic_init_object("buffer0_head");
@@ -81,7 +81,7 @@ void o_buffer_cut(TOPLEVEL *w_current, int buf_num)
     return;
   }
 
-  s_current = w_current->page_current->selection_list;
+  s_current = geda_list_get_glist( w_current->page_current->selection_list );
 
   if (object_buffer[buf_num] == NULL) {
     object_buffer[buf_num] = s_basic_init_object("buffer0_head");
@@ -173,7 +173,7 @@ void o_buffer_paste_end(TOPLEVEL *w_current, int screen_x, int screen_y,
   int w_diff_x, w_diff_y;
   OBJECT *o_current;
   OBJECT *o_saved;
-  GList *temp_list;
+  SELECTION *temp_list = o_selection_new();
   PAGE *p_current;
   GList *connected_objects = NULL;
 
@@ -217,11 +217,10 @@ void o_buffer_paste_end(TOPLEVEL *w_current, int screen_x, int screen_y,
 
   p_current->object_tail = return_tail(p_current->object_head);
   o_current = o_saved->next;
-  temp_list = NULL;
 
   /* now add new objects to the selection list */
   while (o_current != NULL) {
-    o_selection_add(&temp_list, o_current);
+    o_selection_add( temp_list, o_current );
     s_conn_update_object(w_current, o_current);
     if (o_current->type == OBJ_COMPLEX || o_current->type == OBJ_PLACEHOLDER) {
       connected_objects = s_conn_return_complex_others(
@@ -239,12 +238,13 @@ void o_buffer_paste_end(TOPLEVEL *w_current, int screen_x, int screen_y,
   o_cue_draw_list(w_current, connected_objects);
   g_list_free(connected_objects);
   connected_objects = NULL;
-    
+
   o_select_run_hooks(w_current, NULL, 2); 
 
-  o_selection_unselect_list(w_current,
-			    &(w_current->page_current->selection_list));
-  w_current->page_current->selection_list = temp_list;
+  o_selection_unselect_list( w_current, w_current->page_current->selection_list );
+  geda_list_add_glist( w_current->page_current->selection_list, geda_list_get_glist( temp_list ) );
+
+  g_object_unref( temp_list );
 
   w_current->page_current->CHANGED = 1;
   o_redraw(w_current, o_saved->next, TRUE); /* only redraw new objects */
diff --git a/gschem/src/o_complex.c b/gschem/src/o_complex.c
index d2ee71a..f2ec4b2 100644
--- a/gschem/src/o_complex.c
+++ b/gschem/src/o_complex.c
@@ -438,13 +438,11 @@ void o_complex_end(TOPLEVEL *w_current, int screen_x, int screen_y)
   /* This doesn't allow anything else to be in the selection
    * list when you add a component */
 
-  o_selection_unselect_list(w_current,
-			    &(w_current->page_current->selection_list));
-  o_selection_add(&(w_current->page_current->selection_list), 
-		    w_current->page_current->object_tail);
+  o_selection_unselect_list( w_current, w_current->page_current->selection_list );
+  o_selection_add( w_current->page_current->selection_list, w_current->page_current->object_tail);
   /* the o_redraw_selected is in x_events.c after this call
    * returns */
-  o_attrib_add_selected(w_current, &(w_current->page_current->selection_list),
+  o_attrib_add_selected(w_current, w_current->page_current->selection_list,
                         w_current->page_current->object_tail);
 
   s_conn_update_complex(w_current, o_current->complex->prim_objs);
diff --git a/gschem/src/o_copy.c b/gschem/src/o_copy.c
index 1f63437..a78b810 100644
--- a/gschem/src/o_copy.c
+++ b/gschem/src/o_copy.c
@@ -38,7 +38,7 @@
  */
 void o_copy_start(TOPLEVEL *w_current, int x, int y)
 {
-  if (w_current->page_current->selection_list != NULL) {
+  if (geda_list_get_glist( w_current->page_current->selection_list ) != NULL) {
 
   /* This is commented out since it breaks the copy of objects.  See below. */
 #if 0
@@ -54,7 +54,7 @@ void o_copy_start(TOPLEVEL *w_current, int x, int y)
     w_current->last_x = w_current->start_x = fix_x(w_current, x);
     w_current->last_y = w_current->start_y = fix_y(w_current, y);
     o_drawbounding(w_current, NULL,
-                   w_current->page_current->selection_list,
+                   geda_list_get_glist( w_current->page_current->selection_list ),
                    x_get_darkcolor(w_current->bb_color), TRUE);
     w_current->inside_action = 1;
   }
@@ -67,7 +67,7 @@ void o_copy_start(TOPLEVEL *w_current, int x, int y)
  */
 void o_copy_end(TOPLEVEL *w_current)
 {
-  GList *temp_list = NULL;
+  SELECTION *temp_list = o_selection_new();
   GList *s_current = NULL;
   GList *new_objects = NULL;
   GList *connected_objects=NULL;
@@ -95,15 +95,11 @@ void o_copy_end(TOPLEVEL *w_current)
   screen_diff_y = w_current->last_y - w_current->start_y;
 
   SCREENtoWORLD(w_current,
-                w_current->last_x,
-                w_current->last_y,
-                &lx,
-                &ly);
+                w_current->last_x, w_current->last_y,
+                &lx, &ly);
   SCREENtoWORLD(w_current,
-                w_current->start_x,
-                w_current->start_y,
-                &sx,
-                &sy);
+                w_current->start_x, w_current->start_y,
+                &sx, &sy);
   lx = snap_grid(w_current,lx);
   ly = snap_grid(w_current,ly);
   sx = snap_grid(w_current,sx);
@@ -112,9 +108,7 @@ void o_copy_end(TOPLEVEL *w_current)
   diff_x = lx - sx;
   diff_y = ly - sy;
 
-  /* skip over head node */
-  s_current = w_current->page_current->selection_list;
-  temp_list = NULL;
+  s_current = geda_list_get_glist( w_current->page_current->selection_list );
   new_objects_head = s_basic_init_object("object_head");
 
   while(s_current != NULL) {
@@ -130,13 +124,13 @@ void o_copy_end(TOPLEVEL *w_current)
 
       case(OBJ_NET):
 
-	/* ADDING_SEL is a bad name, rename hack */
-	/* basically I don't want to add the */
-	/* connections till much later */
+        /* ADDING_SEL is a bad name, rename hack */
+        /* basically I don't want to add the */
+        /* connections till much later */
         w_current->ADDING_SEL=1;
-        new_object = (OBJECT *) o_net_copy(w_current,
-					   return_tail(new_objects_head),
-                                           object);
+        new_object = (OBJECT *) o_net_copy( w_current,
+                                            return_tail(new_objects_head),
+                                            object );
         w_current->ADDING_SEL=0; 
 
         if (w_current->actionfeedback_mode == OUTLINE) {
@@ -149,7 +143,7 @@ void o_copy_end(TOPLEVEL *w_current)
                               diff_x, diff_y,
                               new_object);
 
-        o_selection_add(&temp_list, new_object);
+        o_selection_add( temp_list, new_object );
         new_object->saved_color = object->saved_color;
         o_net_draw(w_current, new_object);
 
@@ -158,11 +152,11 @@ void o_copy_end(TOPLEVEL *w_current)
         connected_objects = s_conn_return_others(connected_objects,
                                                  new_object);
         break;
-        
+
       case(OBJ_PIN):
-	/* ADDING_SEL is a bad name, rename hack */
-	/* basically I don't want to add the */
-	/* connections till much later */
+        /* ADDING_SEL is a bad name, rename hack */
+        /* basically I don't want to add the */
+        /* connections till much later */
         w_current->ADDING_SEL=1; 
         new_object = (OBJECT *) o_pin_copy(w_current,
                                            return_tail(new_objects_head), 
@@ -171,19 +165,18 @@ void o_copy_end(TOPLEVEL *w_current)
 
         if (w_current->actionfeedback_mode == OUTLINE) {
           o_pin_draw_xor(w_current,
-                         screen_diff_x,
-                         screen_diff_y,
+                         screen_diff_x, screen_diff_y,
                          object);
         }
 
         o_pin_translate_world(w_current,
                               diff_x, diff_y,
                               new_object);
-        
-	o_selection_add(&temp_list, new_object);
+
+        o_selection_add( temp_list, new_object );
         new_object->saved_color = object->saved_color;
         o_pin_draw(w_current, new_object);
-        
+
         s_conn_update_object(w_current, new_object);
         new_objects = g_list_append(new_objects, new_object);
         connected_objects = s_conn_return_others(connected_objects,
@@ -191,9 +184,9 @@ void o_copy_end(TOPLEVEL *w_current)
         break;
 
       case(OBJ_BUS):
-	/* ADDING_SEL is a bad name, rename hack */
-	/* basically I don't want to add the */
-	/* connections till much later */
+        /* ADDING_SEL is a bad name, rename hack */
+        /* basically I don't want to add the */
+        /* connections till much later */
         w_current->ADDING_SEL=1; 
         new_object = (OBJECT *) o_bus_copy(w_current,
                                            return_tail(new_objects_head),
@@ -209,25 +202,25 @@ void o_copy_end(TOPLEVEL *w_current)
         o_bus_translate_world(w_current,
                               diff_x, diff_y,
                               new_object);
-        
-	o_selection_add(&temp_list, new_object);
+
+        o_selection_add( temp_list, new_object );
         new_object->saved_color = object->saved_color;
         o_bus_draw(w_current, new_object);
-        
+
         s_conn_update_object(w_current, new_object);
         new_objects = g_list_append(new_objects, new_object);
         connected_objects = s_conn_return_others(connected_objects,
                                                  new_object);
         break;
-        
+
       case(OBJ_COMPLEX):
       case(OBJ_PLACEHOLDER):
         w_current->ADDING_SEL=1; 
         if (o_complex_is_embedded(object)) {
 
           new_object = (OBJECT *) 
-            o_complex_copy_embedded(w_current, 
-				    return_tail(new_objects_head), 
+            o_complex_copy_embedded(w_current,
+                                    return_tail(new_objects_head),
                                     object);
 
         } else {
@@ -236,7 +229,7 @@ void o_copy_end(TOPLEVEL *w_current)
                                                  object);
         }
         w_current->ADDING_SEL=0; 
-				
+
         complex_object = new_object;
 
         if (w_current->actionfeedback_mode == OUTLINE) {
@@ -245,14 +238,13 @@ void o_copy_end(TOPLEVEL *w_current)
         }
 
         o_complex_world_translate_toplevel(w_current,
-                                           diff_x,
-                                           diff_y,
+                                           diff_x, diff_y,
                                            new_object);
 
-        o_selection_add(&temp_list, new_object);
+        o_selection_add( temp_list, new_object );
 
-	/* NEWSEL: this needs to be fixed too */
-	/* this may not be needed anymore? */
+        /* NEWSEL: this needs to be fixed too */
+        /* this may not be needed anymore? */
         o_attrib_slot_copy(w_current, object, 
                            new_object);
         new_object->saved_color = object->saved_color;
@@ -274,13 +266,13 @@ void o_copy_end(TOPLEVEL *w_current)
                           object);
         }
 
-        w_current->ADDING_SEL=1; 
+        w_current->ADDING_SEL=1;
         o_line_translate_world(w_current,
                                diff_x, diff_y,
                                new_object);
         w_current->ADDING_SEL=0; 
 
-        o_selection_add(&temp_list, new_object);
+        o_selection_add( temp_list, new_object );
         new_object->saved_color = object->saved_color;
         o_line_draw(w_current, new_object);
         break;
@@ -291,44 +283,42 @@ void o_copy_end(TOPLEVEL *w_current)
                                            object);
         if (w_current->actionfeedback_mode == OUTLINE) {
           o_box_draw_xor(w_current,
-                         screen_diff_x,
-                         screen_diff_y,
+                         screen_diff_x, screen_diff_y,
                          object);
         }
 
-        w_current->ADDING_SEL=1; 
+        w_current->ADDING_SEL=1;
         o_box_translate_world(w_current,
                               diff_x, diff_y,
                               new_object);
-        w_current->ADDING_SEL=0; 
-        
-        o_selection_add(&temp_list, new_object);
+        w_current->ADDING_SEL=0;
+
+        o_selection_add( temp_list, new_object );
         new_object->saved_color = object->saved_color;
         o_box_draw(w_current, new_object);
-        
+
         break;
 
       case(OBJ_PICTURE):
         new_object = (OBJECT *) o_picture_copy(w_current,
-					       return_tail(new_objects_head),
-					       object);
+                                               return_tail(new_objects_head),
+                                               object);
         if (w_current->actionfeedback_mode == OUTLINE) {
           o_picture_draw_xor(w_current,
-			     screen_diff_x,
-			     screen_diff_y,
-			     object);
+                             screen_diff_x, screen_diff_y,
+                             object);
         }
 
-        w_current->ADDING_SEL=1; 
+        w_current->ADDING_SEL=1;
         o_picture_translate_world(w_current,
-				  diff_x, diff_y,
-				  new_object);
-        w_current->ADDING_SEL=0; 
-        
-        o_selection_add(&temp_list, new_object);
+                                  diff_x, diff_y,
+                                  new_object);
+        w_current->ADDING_SEL=0;
+
+        o_selection_add( temp_list, new_object );
         new_object->saved_color = object->saved_color;
         o_picture_draw(w_current, new_object);
-        
+
         break;
 
       case(OBJ_CIRCLE):
@@ -338,41 +328,39 @@ void o_copy_end(TOPLEVEL *w_current)
 
         if (w_current->actionfeedback_mode == OUTLINE) {
           o_circle_draw_xor(w_current,
-                            screen_diff_x,
-                            screen_diff_y,
+                            screen_diff_x, screen_diff_y,
                             object);
         }
 
-        w_current->ADDING_SEL=1; 
+        w_current->ADDING_SEL=1;
         o_circle_translate_world(w_current,
                                  diff_x, diff_y,
                                  new_object);
-        w_current->ADDING_SEL=0; 
+        w_current->ADDING_SEL=0;
 
-        o_selection_add(&temp_list, new_object);
+        o_selection_add( temp_list, new_object );
         new_object->saved_color = object->saved_color;
         o_circle_draw(w_current, new_object);
         break;
 
       case(OBJ_ARC):
-        new_object = (OBJECT *) o_arc_copy(w_current,
-					   return_tail(new_objects_head), 
-                                           object);
+        new_object = (OBJECT *) o_arc_copy( w_current,
+                                            return_tail(new_objects_head),
+                                            object );
 
         if (w_current->actionfeedback_mode == OUTLINE) {
           o_arc_draw_xor(w_current,
-                         screen_diff_x,
-                         screen_diff_y,
+                         screen_diff_x, screen_diff_y,
                          object);
         }
 
-        w_current->ADDING_SEL=1; 
+        w_current->ADDING_SEL=1;
         o_arc_translate_world(w_current,
                               diff_x, diff_y,
                               new_object);
-        w_current->ADDING_SEL=0; 
-        
-        o_selection_add(&temp_list, new_object);
+        w_current->ADDING_SEL=0;
+
+        o_selection_add( temp_list, new_object );
         new_object->saved_color = object->saved_color;
         o_arc_draw(w_current, new_object);
         break;
@@ -385,8 +373,7 @@ void o_copy_end(TOPLEVEL *w_current)
     s_current = s_current->next;
   }
 
-  /* skip over head */
-  s_current = w_current->page_current->selection_list;
+  s_current = geda_list_get_glist( w_current->page_current->selection_list );
   while(s_current != NULL) {
 
     object = (OBJECT *) s_current->data;
@@ -410,7 +397,7 @@ void o_copy_end(TOPLEVEL *w_current)
           if (object->attached_to->copied_to) {
             o_attrib_attach(w_current, new_objects_head,
                             new_object, object->attached_to-> copied_to);
-	    	    
+
             /*! \todo I have no idea if this is
                really needed.... ? */
 #if 0
@@ -423,20 +410,20 @@ void o_copy_end(TOPLEVEL *w_current)
             object->attached_to->copied_to = NULL;
           }
         }
-	
+
         if (w_current->actionfeedback_mode == OUTLINE) {
           o_text_draw_xor(w_current,
                           screen_diff_x,
                           screen_diff_y,
                           object);
-			  }
+        }
 
         w_current->ADDING_SEL=1; 
         o_text_translate_world(w_current, diff_x, diff_y, new_object);
         w_current->ADDING_SEL=0; 
 
-				/* old object was attr */
-        if (!new_object->attribute && 
+        /* old object was attr */
+        if (!new_object->attribute &&
             object->attribute) {
           new_object->color = w_current-> detachedattr_color;
           o_complex_set_color(new_object, new_object->color);
@@ -446,21 +433,19 @@ void o_copy_end(TOPLEVEL *w_current)
           color = object->saved_color;
         }
 
-        o_selection_add(&temp_list, new_object);
+        o_selection_add( temp_list, new_object );
         new_object->saved_color = color;
-        
-	/* signify that object is no longer an attribute */
-	o_text_draw(w_current, new_object);
 
-        o_complex_set_saved_color_only(
-                                       new_object->text->prim_objs, 
-                                       color);
+        /* signify that object is no longer an attribute */
+        o_text_draw(w_current, new_object);
+
+        o_complex_set_saved_color_only( new_object->text->prim_objs, 
+                                        color);
         break;
     }
 
     w_current->page_current->object_tail =
-      (OBJECT *) return_tail(w_current->page_current->
-                             object_head);
+      (OBJECT *) return_tail( w_current->page_current->object_head );
     s_current = s_current->next;
   }
 
@@ -479,29 +464,29 @@ void o_copy_end(TOPLEVEL *w_current)
 
   /* Add the new objects */
   w_current->page_current->object_tail = (OBJECT *)
-  return_tail(w_current->page_current->object_head);
+    return_tail(w_current->page_current->object_head);
 
   s_basic_link_object(new_objects_head, w_current->page_current->object_tail);
 
   /* Run the copy component hook */
   object = new_objects_head->next;
   while (object != NULL) {
-    if ((object->type == OBJ_COMPLEX) &&
-	(scm_hook_empty_p(copy_component_hook) == SCM_BOOL_F)) {
+    if ( (object->type == OBJ_COMPLEX) &&
+         (scm_hook_empty_p(copy_component_hook) == SCM_BOOL_F)) {
       scm_run_hook(copy_component_hook,
-		   scm_cons (g_make_attrib_smob_list(w_current, object),
-		   SCM_EOL));
+                   scm_cons (g_make_attrib_smob_list(w_current, object),
+                   SCM_EOL));
     }
     object = object->next;
   }
-  
+
   /* And redraw them */
   object = new_objects_head;
   while (object) {
     o_redraw_single(w_current, object);
     object=object->next;
   }
-  
+
   /* Delete the new object head */
   /*  new_objects_head->next = NULL;
       s_delete_list_fromstart(w_current, new_objects_head); */
@@ -512,15 +497,15 @@ void o_copy_end(TOPLEVEL *w_current)
   /* erase the bounding box */
   if (w_current->actionfeedback_mode == BOUNDINGBOX) {
     o_drawbounding(w_current, NULL,
-                   w_current->page_current->selection_list,
+                   geda_list_get_glist( w_current->page_current->selection_list ),
                    x_get_darkcolor(w_current->bb_color), TRUE);
   }
 
-  o_select_run_hooks(w_current, NULL, 2); 
-  o_selection_unselect_list(w_current, 
-			    &(w_current->page_current->selection_list));
-  w_current->page_current->selection_list = NULL;
-  w_current->page_current->selection_list = temp_list;
+  o_select_run_hooks( w_current, NULL, 2 );
+  o_selection_unselect_list( w_current, w_current->page_current->selection_list );
+  geda_list_add_glist( w_current->page_current->selection_list, geda_list_get_glist( temp_list ) );
+
+  g_object_unref( temp_list );
 
   w_current->page_current->CHANGED = 1;
 
@@ -528,11 +513,11 @@ void o_copy_end(TOPLEVEL *w_current)
   o_cue_draw_list(w_current, new_objects);
   o_cue_undraw_list(w_current, connected_objects);
   o_cue_draw_list(w_current, connected_objects);
-  
+
   g_list_free(new_objects);
   g_list_free(connected_objects);
   new_objects = NULL;
   connected_objects = NULL;
-  
+
   o_undo_savestate(w_current, UNDO_ALL);
 }
diff --git a/gschem/src/o_delete.c b/gschem/src/o_delete.c
index 73991ed..0db8599 100644
--- a/gschem/src/o_delete.c
+++ b/gschem/src/o_delete.c
@@ -246,7 +246,7 @@ void o_delete(TOPLEVEL *w_current)
 
 
   /* skip over head node */
-  s_current = w_current->page_current->selection_list;
+  s_current = geda_list_get_glist( w_current->page_current->selection_list );
 
   while(s_current != NULL) {
 
@@ -300,10 +300,9 @@ void o_delete(TOPLEVEL *w_current)
 
   w_current->inside_action = 0;
 
-  /* Objects have been deleted. Free the list, without freeing again 
-     the objects */
-  g_list_free(w_current->page_current->selection_list);
-  w_current->page_current->selection_list = NULL;
+  /* Objects in the selection list have been deleted. Empty the list without touching the objects */
+  geda_list_remove_all( w_current->page_current->selection_list );
+
   w_current->page_current->CHANGED=1;
 
   /* no longer needed */
diff --git a/gschem/src/o_find.c b/gschem/src/o_find.c
index 488160e..e0e60e1 100644
--- a/gschem/src/o_find.c
+++ b/gschem/src/o_find.c
@@ -115,14 +115,12 @@ gboolean o_find_object(TOPLEVEL *w_current, int screen_x, int screen_y,
   /* deselect everything only if shift key isn't pressed and 
      the caller allows it */	
   if (change_selection && (!w_current->SHIFTKEY)) {
-
-    o_select_run_hooks(w_current, NULL, 2); 
-    o_selection_unselect_list (w_current,
-			       &(w_current->page_current->selection_list));
+    o_select_run_hooks(w_current, NULL, 2);
+    o_selection_unselect_list (w_current, w_current->page_current->selection_list );
   }
 
   i_update_menus(w_current);
-  
+
   return (object_found);
 }
 
@@ -141,7 +139,7 @@ gboolean o_find_selected_object(TOPLEVEL *w_current,
   SCREENtoWORLD( w_current, screen_x, screen_y, &w_x, &w_y );
   w_slack = WORLDabs( w_current, w_current->select_slack_pixels );
 
-  s_current = w_current->page_current->selection_list;
+  s_current = geda_list_get_glist( w_current->page_current->selection_list );
   /* do first search */
   while (s_current != NULL) {
     o_current = (OBJECT *) s_current->data;
diff --git a/gschem/src/o_grips.c b/gschem/src/o_grips.c
index 698a0d4..0c6e8a8 100644
--- a/gschem/src/o_grips.c
+++ b/gschem/src/o_grips.c
@@ -103,7 +103,7 @@ OBJECT *o_grips_search_world(TOPLEVEL *w_current, int x, int y, int *whichone)
   w_size = WORLDabs( w_current, size );
 	
   /* skip over head */
-  s_current = w_current->page_current->selection_list;
+  s_current = geda_list_get_glist( w_current->page_current->selection_list );
   while (s_current != NULL) {
     object = (OBJECT *) s_current->data;
     if (object) {
diff --git a/gschem/src/o_misc.c b/gschem/src/o_misc.c
index 908e906..246e65b 100644
--- a/gschem/src/o_misc.c
+++ b/gschem/src/o_misc.c
@@ -129,7 +129,7 @@ void o_lock(TOPLEVEL *w_current)
   GList *s_current = NULL;
 
   /* skip over head */
-  s_current = w_current->page_current->selection_list;
+  s_current = geda_list_get_glist( w_current->page_current->selection_list );
 
   while(s_current != NULL) {
     object = (OBJECT *) s_current->data;
@@ -167,7 +167,7 @@ void o_unlock(TOPLEVEL *w_current)
   OBJECT *object = NULL;
   GList *s_current = NULL;
 
-  s_current = w_current->page_current->selection_list;
+  s_current = geda_list_get_glist( w_current->page_current->selection_list );
 
   while(s_current != NULL) {
     object = (OBJECT *) s_current->data;
@@ -1065,8 +1065,7 @@ void o_update_component(TOPLEVEL *w_current, OBJECT *o_current)
   /* delete its connections */
   s_conn_remove_complex (w_current, o_current);
   /* and unselect it */
-  o_selection_remove (&(w_current->page_current->selection_list),
-		      o_current);
+  o_selection_remove( w_current->page_current->selection_list, o_current);
 
   /* build a temporary list and add a complex to this list */
   tmp_list = s_basic_init_object ("update component");
@@ -1143,8 +1142,7 @@ void o_update_component(TOPLEVEL *w_current, OBJECT *o_current)
 
   /* reconnect, re-select and redraw */
   s_conn_update_complex (w_current, o_current->complex->prim_objs);
-  o_selection_add (&(w_current->page_current->selection_list),
-		   o_current);
+  o_selection_add( w_current->page_current->selection_list, o_current );
   o_redraw_single (w_current, o_current);
 
   /* Re-flag as embedded if necessary */
diff --git a/gschem/src/o_move.c b/gschem/src/o_move.c
index 2f80d81..d15fad2 100644
--- a/gschem/src/o_move.c
+++ b/gschem/src/o_move.c
@@ -37,7 +37,7 @@
  */
 void o_move_start(TOPLEVEL * w_current, int x, int y)
 {
-  if (w_current->page_current->selection_list != NULL) {
+  if ( geda_list_get_glist( w_current->page_current->selection_list ) != NULL) {
 
     /* Save the current state. When rotating the selection when moving,
        we have to come back to here */
@@ -49,18 +49,18 @@ void o_move_start(TOPLEVEL * w_current, int x, int y)
     w_current->last_y = w_current->start_y = fix_y(w_current, y);
 
     o_erase_selected(w_current);
-    
+
     o_drawbounding(w_current, NULL,
-                   w_current->page_current->selection_list,
+                   geda_list_get_glist( w_current->page_current->selection_list ),
                    x_get_darkcolor(w_current->bb_color), TRUE);
 
     if (w_current->netconn_rubberband) {
       o_move_prep_rubberband(w_current);
       o_move_stretch_rubberband(w_current);
     }
-    
-    o_select_move_to_place_list(w_current); 
-    w_current->inside_action = 1;    
+
+    o_select_move_to_place_list(w_current);
+    w_current->inside_action = 1;
   }
 }
 
@@ -209,12 +209,12 @@ void o_move_end(TOPLEVEL * w_current)
 
   if (w_current->actionfeedback_mode == OUTLINE) {
     o_drawbounding(w_current, NULL,
-                   w_current->page_current->selection_list,
+                   geda_list_get_glist( w_current->page_current->selection_list ),
                    x_get_darkcolor(w_current->bb_color), TRUE);
   }
-  
+
   /* skip over head node */
-  s_current = w_current->page_current->selection_list;
+  s_current = geda_list_get_glist( w_current->page_current->selection_list );
 
   while (s_current != NULL) {
 
@@ -280,7 +280,7 @@ void o_move_end(TOPLEVEL * w_current)
   /* erase the bounding box */
   if (w_current->actionfeedback_mode == BOUNDINGBOX) {
     o_drawbounding(w_current, NULL,
-                   w_current->page_current->selection_list,
+                   geda_list_get_glist( w_current->page_current->selection_list ),
                    x_get_darkcolor(w_current->bb_color), FALSE);
   }
 
@@ -431,7 +431,7 @@ void o_move_prep_rubberband(TOPLEVEL * w_current)
   printf("\n\n\n");
 #endif
 
-  s_current = w_current->page_current->selection_list;
+  s_current = geda_list_get_glist( w_current->page_current->selection_list );
   while (s_current != NULL) {
     object = (OBJECT *) s_current->data;
     if (object) {
diff --git a/gschem/src/o_picture.c b/gschem/src/o_picture.c
index 247ba75..9265ea7 100644
--- a/gschem/src/o_picture.c
+++ b/gschem/src/o_picture.c
@@ -649,10 +649,10 @@ void o_picture_exchange (TOPLEVEL *w_current, GdkPixbuf *pixbuf,
 {
   GList *list;  
 
-  list = w_current->page_current->selection_list;
+  list = geda_list_get_glist( w_current->page_current->selection_list );
   while (list != NULL) {
     OBJECT *object;
-    
+
     object = (OBJECT *) list->data;
     if (object == NULL) {
       fprintf(stderr, _("ERROR: NULL object!\n"));
diff --git a/gschem/src/o_select.c b/gschem/src/o_select.c
index f90c1b9..388e268 100644
--- a/gschem/src/o_select.c
+++ b/gschem/src/o_select.c
@@ -162,18 +162,16 @@ void o_select_object(TOPLEVEL *w_current, OBJECT *o_current,
           /* condition: for both multiple and single object added */
           /* result: remove all objects from selection */
           if (count == 0 && !CONTROLKEY) {
-            o_select_run_hooks(w_current, NULL, 2);
-	    o_selection_unselect_list (w_current,
-				       &(w_current->page_current->selection_list));
+            o_select_run_hooks( w_current, NULL, 2 );
+            o_selection_unselect_list (w_current,w_current->page_current->selection_list);
           }
           break;
 
       } /* end shift key switch */
 
       /* object not select, add it to the selection list */
-      o_select_run_hooks(w_current, o_current, 1);
-      o_selection_add(&(w_current->page_current->selection_list),
-		      o_current);
+      o_select_run_hooks( w_current, o_current, 1 );
+      o_selection_add( w_current->page_current->selection_list, o_current);
 
       break;
 
@@ -187,9 +185,8 @@ void o_select_object(TOPLEVEL *w_current, OBJECT *o_current,
           /* condition: not doing multiple */
           /* result: remove object from selection */
           if (type != MULTIPLE) {
-            o_select_run_hooks(w_current, o_current, 0);
-            o_selection_remove(&(w_current->page_current->selection_list),
-                               o_current);
+            o_select_run_hooks( w_current, o_current, 0 );
+            o_selection_remove( w_current->page_current->selection_list, o_current );
           }
 
           break;
@@ -202,13 +199,11 @@ void o_select_object(TOPLEVEL *w_current, OBJECT *o_current,
           /* 1st result: remove all objects from selection */
           /* 2nd result: add object to selection */
           if (type == MULTIPLE && count == 0 && !CONTROLKEY) {
-            o_select_run_hooks(w_current, NULL, 2);
-	    o_selection_unselect_list (w_current,
-				       &(w_current->page_current->selection_list));
-	    
-	    o_select_run_hooks(w_current, o_current, 1);
-	    o_selection_add(&(w_current->page_current->selection_list),
-			    o_current);
+            o_select_run_hooks( w_current, NULL, 2 );
+            o_selection_unselect_list (w_current, w_current->page_current->selection_list );
+
+            o_select_run_hooks( w_current, o_current, 1 );
+            o_selection_add( w_current->page_current->selection_list, o_current);
           }	
 
           /* condition: doing single object add */
@@ -216,19 +211,16 @@ void o_select_object(TOPLEVEL *w_current, OBJECT *o_current,
           /* 1st result: remove all objects from selection */
           /* 2nd result: add object to selection list */
           if (type == SINGLE && !CONTROLKEY) {
-            o_select_run_hooks(w_current, NULL, 2);
-	    o_selection_unselect_list (w_current,
-				       &(w_current->page_current->selection_list));
+            o_select_run_hooks( w_current, NULL, 2 );
+            o_selection_unselect_list( w_current, w_current->page_current->selection_list );
 
             o_select_run_hooks (w_current, o_current, 1);
-	    o_selection_add(&(w_current->page_current->selection_list),
-			    o_current);
+            o_selection_add( w_current->page_current->selection_list, o_current);
           }
 
           if (CONTROLKEY) {
             o_select_run_hooks(w_current, o_current, 0);
-            o_selection_remove(&(w_current->page_current->selection_list),
-                               o_current);
+            o_selection_remove( w_current->page_current->selection_list, o_current);
           }
 
           break;
@@ -237,8 +229,7 @@ void o_select_object(TOPLEVEL *w_current, OBJECT *o_current,
   }
 
   /* do the attributes */
-  o_attrib_add_selected(w_current, &(w_current->page_current->selection_list),
-                        o_current);
+  o_attrib_add_selected(w_current, w_current->page_current->selection_list, o_current);
 
   /* finally redraw object */
   o_redraw_single(w_current, o_current);
@@ -418,9 +409,8 @@ void o_select_box_search(TOPLEVEL *w_current)
   /* zero, and you need to deselect anything remaining (unless the shift */
   /* key was pressed */
   if (count == 0 && !SHIFTKEY) {
-    o_select_run_hooks(w_current, NULL, 2);
-    o_selection_unselect_list( w_current,
-                               &(w_current->page_current->selection_list) );
+    o_select_run_hooks( w_current, NULL, 2 );
+    o_selection_unselect_list( w_current, w_current->page_current->selection_list );
   }
   i_update_menus(w_current);
 }
@@ -429,10 +419,10 @@ void o_select_box_search(TOPLEVEL *w_current)
 /* This function always looks at the current page selection list */ 
 OBJECT *o_select_return_first_object(TOPLEVEL *w_current) 
 {
-  if (! (w_current && w_current->page_current && w_current->page_current->selection_list))
+  if (! (w_current && w_current->page_current && geda_list_get_glist( w_current->page_current->selection_list )))
     return NULL;
   else
-    return((OBJECT *) g_list_first(w_current->page_current->selection_list)->data);
+    return (OBJECT *)g_list_first( geda_list_get_glist( w_current->page_current->selection_list ))->data;
 }
 
 /*! \todo Finish function documentation!!!
@@ -444,7 +434,7 @@ OBJECT *o_select_return_first_object(TOPLEVEL *w_current)
  */
 int o_select_selected(TOPLEVEL *w_current)
 {
-  if (w_current->page_current->selection_list) {
+  if ( geda_list_get_glist( w_current->page_current->selection_list )) {
     return(TRUE);
   }
   return(FALSE);
@@ -457,9 +447,8 @@ int o_select_selected(TOPLEVEL *w_current)
  */
 void o_select_unselect_all(TOPLEVEL *w_current)
 {
-  o_select_run_hooks(w_current, NULL, 2);
-  o_selection_unselect_list (w_current,
-			     &(w_current->page_current->selection_list));
+  o_select_run_hooks( w_current, NULL, 2 );
+  o_selection_unselect_list( w_current, w_current->page_current->selection_list );
 }
 
 /*! \todo Finish function documentation!!!
@@ -472,8 +461,8 @@ o_select_move_to_place_list(TOPLEVEL *w_current)
 {
   GList *selection;
   OBJECT *o_current;
-  
-  selection= w_current->page_current->selection_list;
+
+  selection = geda_list_get_glist( w_current->page_current->selection_list );
 
   if (!selection) {
     return;
diff --git a/gschem/src/o_text.c b/gschem/src/o_text.c
index e81de34..47bb182 100644
--- a/gschem/src/o_text.c
+++ b/gschem/src/o_text.c
@@ -415,7 +415,7 @@ void o_text_end(TOPLEVEL *w_current)
   /*! \todo make this VIS and SHOW default configurable */
   w_current->page_current->object_tail =
   o_text_add(w_current, w_current->page_current->object_tail,
-				/* type changed from TEXT to TEXT */
+             /* type changed from TEXT to TEXT */
              OBJ_TEXT,
              w_current->text_color,
              world_x, world_y, LOWER_LEFT, 
@@ -454,12 +454,9 @@ void o_text_end(TOPLEVEL *w_current)
   w_current->override_color = -1;
 
   w_current->page_current->CHANGED=1;
-  o_select_run_hooks(w_current, NULL, 2); 
-  o_selection_unselect_list(w_current,
-			    &(w_current->page_current->selection_list));
-  o_selection_add(&(w_current->page_current->selection_list), 
-		  w_current->page_current->object_tail);
-	
+  o_select_run_hooks( w_current, NULL, 2 );
+  o_selection_unselect_list( w_current, w_current->page_current->selection_list );
+  o_selection_add( w_current->page_current->selection_list, w_current->page_current->object_tail );
 
   /* object_tail is the object that was just added */
   if (w_current->page_current->object_tail->draw_func != NULL &&
@@ -514,8 +511,8 @@ void o_text_edit_end(TOPLEVEL *w_current, char *string, int len, int text_size,
   int numselect;
 
   /* skip over head */
-  s_current = w_current->page_current->selection_list;
-  numselect = g_list_length(w_current->page_current->selection_list);
+  s_current = geda_list_get_glist( w_current->page_current->selection_list );
+  numselect = g_list_length( geda_list_get_glist( w_current->page_current->selection_list ));
   
   while(s_current != NULL) {
     object = (OBJECT *) s_current->data;
diff --git a/gschem/src/x_attribedit.c b/gschem/src/x_attribedit.c
index 0cd7571..0fb8f5a 100644
--- a/gschem/src/x_attribedit.c
+++ b/gschem/src/x_attribedit.c
@@ -132,7 +132,7 @@ void attrib_edit_dialog_ok(GtkWidget * w, TOPLEVEL * w_current)
     int world_x, world_y;
     OBJECT *new = NULL;
 
-    s_current = w_current->page_current->selection_list;
+    s_current = geda_list_get_glist( w_current->page_current->selection_list );
     while (s_current != NULL) {
       object = (OBJECT *)s_current->data;
       if (object == NULL) {
@@ -144,7 +144,7 @@ void attrib_edit_dialog_ok(GtkWidget * w, TOPLEVEL * w_current)
       }
       s_current = s_current->next;
     }
-    s_current = w_current->page_current->selection_list;
+    s_current = geda_list_get_glist( w_current->page_current->selection_list );
     if (nsel > 1) {
 
       addtoallbutton =
@@ -316,7 +316,7 @@ void attrib_edit_dialog(TOPLEVEL * w_current, OBJECT * list, int flag)
     return;
 
   /* gschem specific: What do we count here? (Werner)  */
-  for (s_current = w_current->page_current->selection_list;
+  for (s_current = geda_list_get_glist( w_current->page_current->selection_list );
        s_current != NULL;
        s_current = s_current->next) {
     if (!((OBJECT *) s_current->data)->attached_to) {
diff --git a/gschem/src/x_autonumber.c b/gschem/src/x_autonumber.c
index 30b21cf..b3f5504 100644
--- a/gschem/src/x_autonumber.c
+++ b/gschem/src/x_autonumber.c
@@ -588,8 +588,7 @@ void autonumber_remove_number(AUTONUMBER_TEXT * autotext, OBJECT *o_current)
       if (slot_str != NULL && o_slot != NULL) {
 	g_free(slot_str);
 	/* delete the slot attribute */
-	o_selection_remove (&(autotext->toplevel->page_current->selection_list), 
-			    o_slot);
+	o_selection_remove (autotext->toplevel->page_current->selection_list, o_slot);
 	o_delete_text (autotext->toplevel, o_slot);
 	/* redraw the slotted object. So that the pinnumbers appear as with slot=1 */
 	/* --> No: should be done by o_delete_text as several dialog use it. */
diff --git a/gschem/src/x_dialog.c b/gschem/src/x_dialog.c
index 44bf763..f0eab7c 100644
--- a/gschem/src/x_dialog.c
+++ b/gschem/src/x_dialog.c
@@ -425,7 +425,7 @@ void text_edit_dialog_ok(GtkWidget *w, TOPLEVEL *w_current)
   GtkTextIter start, end;
   GtkWidget *widget;
 
-  num_selected = g_list_length(w_current->page_current->selection_list);
+  num_selected = g_list_length( geda_list_get_glist( w_current->page_current->selection_list ));
 
   /* text string entry will only show up if one object is selected */
   if (num_selected == 1) {
@@ -539,7 +539,7 @@ void text_edit_dialog (TOPLEVEL *w_current, char *string, int text_size,
     gtk_box_set_spacing(GTK_BOX(vbox), DIALOG_V_SPACING);
 
     /* add a text box if only one object is selected */
-    num_selected = g_list_length(w_current->page_current->selection_list);
+    num_selected = g_list_length( geda_list_get_glist( w_current->page_current->selection_list ));
 
     if (num_selected == 1) {
       label = gtk_label_new (_("<b>Text Content</b>"));
@@ -2275,7 +2275,7 @@ static GtkWidget *create_color_menu (TOPLEVEL * w_current, int * select_index)
   menu = gtk_menu_new ();
   group = NULL;
 
-  s_current = w_current->page_current->selection_list;
+  s_current = geda_list_get_glist( w_current->page_current->selection_list );
 
   if (s_current != NULL) {
 
@@ -2351,7 +2351,7 @@ void color_edit_dialog_apply(GtkWidget *w, TOPLEVEL *w_current)
   GList *s_current = NULL;
   OBJECT *object = NULL;
 
-  s_current = w_current->page_current->selection_list;
+  s_current = geda_list_get_glist( w_current->page_current->selection_list );
 
   while(s_current != NULL) {
 
diff --git a/gschem/src/x_event.c b/gschem/src/x_event.c
index 5730ef7..fcf553e 100644
--- a/gschem/src/x_event.c
+++ b/gschem/src/x_event.c
@@ -89,7 +89,7 @@ gint x_event_expose(GtkWidget *widget, GdkEventExpose *event,
       case(ENDCOPY):
       case(ENDMCOPY):
         o_drawbounding(w_current, NULL,
-                       w_current->page_current->selection_list,
+                       geda_list_get_glist( w_current->page_current->selection_list ),
                        x_get_darkcolor(w_current->bb_color), FALSE);
         break;
       case(DRAWCOMP):
@@ -170,8 +170,8 @@ gint x_event_button_pressed(GtkWidget *widget, GdkEventButton *event,
       (w_current->event_state == STARTSELECT || 
        w_current->event_state == SELECT)) {
     o_find_object(w_current, (int) event->x, (int) event->y, TRUE);
-    if (w_current->page_current->selection_list) {
-       o_edit(w_current, w_current->page_current->selection_list);
+    if ( geda_list_get_glist( w_current->page_current->selection_list )) {
+       o_edit(w_current, geda_list_get_glist( w_current->page_current->selection_list ));
        return(0);
     }
   }
@@ -421,40 +421,40 @@ gint x_event_button_pressed(GtkWidget *widget, GdkEventButton *event,
         break;
 
       case(ENDROTATEP):
-	prev_state = w_current->DONT_REDRAW;
-	w_current->DONT_REDRAW = 0;
-        
+        prev_state = w_current->DONT_REDRAW;
+        w_current->DONT_REDRAW = 0;
+
         SCREENtoWORLD( w_current,
-  	       (int) event->x,
-  	       (int) event->y,
-               &w_x, &w_y );
+                       (int) event->x,
+                       (int) event->y,
+                       &w_x, &w_y );
         w_x = snap_grid(w_current, w_x);
         w_y = snap_grid(w_current, w_y);
 
         o_rotate_90_world(
                     w_current,
-                    w_current->page_current->selection_list,
+                    geda_list_get_glist( w_current->page_current->selection_list ),
                     w_x, w_y);
-	w_current->DONT_REDRAW = prev_state;
+        w_current->DONT_REDRAW = prev_state;
 
         w_current->inside_action = 0;
-	i_set_state(w_current, SELECT);
+        i_set_state(w_current, SELECT);
         i_update_toolbar(w_current);
         break;
 
       case(ENDMIRROR):
         SCREENtoWORLD( w_current,
-  	       (int) event->x,
-  	       (int) event->y,
+                       (int) event->x,
+                       (int) event->y,
                &w_x, &w_y );
         o_mirror_world(w_current,
-                 w_current->page_current->selection_list,
-                 w_x, w_y);
+                       geda_list_get_glist( w_current->page_current->selection_list ),
+                       w_x, w_y);
         w_x = snap_grid(w_current, w_x);
         w_y = snap_grid(w_current, w_y);
 
         w_current->inside_action = 0;
-	i_set_state(w_current, SELECT);
+        i_set_state(w_current, SELECT);
         i_update_toolbar(w_current);
         break;
 
@@ -1103,12 +1103,12 @@ gint x_event_motion(GtkWidget *widget, GdkEventMotion *event,
     case(MCOPY):
     if (w_current->inside_action) {
       o_drawbounding(w_current, NULL,
-                     w_current->page_current->selection_list,
+                     geda_list_get_glist( w_current->page_current->selection_list ),
                      x_get_darkcolor(w_current->bb_color), FALSE);
       w_current->last_x = fix_x(w_current,  (int) event->x);
       w_current->last_y = fix_y(w_current,  (int) event->y);
       o_drawbounding(w_current, NULL,
-                     w_current->page_current->selection_list,
+                     geda_list_get_glist( w_current->page_current->selection_list ),
                      x_get_darkcolor(w_current->bb_color), FALSE);
     }
     break;
diff --git a/gschem/src/x_image.c b/gschem/src/x_image.c
index 43f4267..1846155 100644
--- a/gschem/src/x_image.c
+++ b/gschem/src/x_image.c
@@ -364,10 +364,9 @@ void x_image_lowlevel(TOPLEVEL *w_current, const char* filename,
              page_center_top + (page_height / 2));
 
   /* de select everything first */
-  o_select_run_hooks(w_current, NULL, 2); 
-  o_selection_unselect_list(w_current,
-			    &(w_current->page_current->selection_list));
-		
+  o_select_run_hooks( w_current, NULL, 2 );
+  o_selection_unselect_list( w_current, w_current->page_current->selection_list );
+
  if (strcmp(filetype, "eps") == 0) /*WK - catch EPS export case*/
     x_image_write_eps(w_current, filename);
  else {    
diff --git a/gschem/src/x_multiattrib.c b/gschem/src/x_multiattrib.c
index 498e3ff..8d103ac 100644
--- a/gschem/src/x_multiattrib.c
+++ b/gschem/src/x_multiattrib.c
@@ -465,7 +465,7 @@ static void multiattrib_action_delete_attribute(TOPLEVEL *toplevel,
 						OBJECT *o_attrib) 
 {
   /* actually deletes the attribute */
-  o_selection_remove (&(toplevel->page_current->selection_list), o_attrib);
+  o_selection_remove ( toplevel->page_current->selection_list, o_attrib);
   o_delete_text (toplevel, o_attrib);
   toplevel->page_current->CHANGED=1;
   o_undo_savestate (toplevel, UNDO_ALL);
diff --git a/gschem/src/x_print.c b/gschem/src/x_print.c
index dbde684..d96bb36 100644
--- a/gschem/src/x_print.c
+++ b/gschem/src/x_print.c
@@ -727,8 +727,8 @@ x_print_setup (TOPLEVEL * w_current, char *filename)
 			     &w_current->paper_height);
 		
       /* de select everything first */
-      o_selection_unselect_list( w_current,
-                                 &w_current->page_current->selection_list );
+      o_select_run_hooks( w_current, NULL, 2 );
+      o_selection_unselect_list( w_current, w_current->page_current->selection_list );
 
       if (usefile && filename[0])
 	/* Print to file */
diff --git a/libgeda/include/prototype.h b/libgeda/include/prototype.h
index 471d209..5f4560c 100644
--- a/libgeda/include/prototype.h
+++ b/libgeda/include/prototype.h
@@ -402,12 +402,14 @@ 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 */
-void o_selection_add(GList **head, OBJECT *o_selected);
-void o_selection_print_all(const GList **head);
+SELECTION *o_selection_new( void );
+void o_selection_add(SELECTION *selection, OBJECT *o_selected);
+void o_selection_print_all(const SELECTION *selection);
+void o_selection_remove(SELECTION *selection, OBJECT *o_selected);
+void o_selection_unselect_list(TOPLEVEL *w_current, SELECTION *selection);
+
 void o_selection_select(OBJECT *object, int color); /* DEPRECATED */
 void o_selection_unselect(OBJECT *object);          /* DEPRECATED */
-void o_selection_remove(GList **head, OBJECT *o_selected);
-void o_selection_unselect_list(TOPLEVEL *w_current, GList **head);
 
 /* o_text_basic.c */
 int world_get_text_bounds(TOPLEVEL *w_current, OBJECT *o_current, int *left, int *top, int *right, int *bottom);
diff --git a/libgeda/include/struct.h b/libgeda/include/struct.h
index de47c1e..6f0befa 100644
--- a/libgeda/include/struct.h
+++ b/libgeda/include/struct.h
@@ -22,6 +22,9 @@
 
 #include <glib.h>  /* Include needed to make GList work. */
 
+/* Wrappers around a new list mechanism */
+typedef struct _GedaList SELECTION;
+
 /* gschem structures (gschem) */
 typedef struct st_complex COMPLEX;
 typedef struct st_line LINE;
@@ -345,7 +348,7 @@ struct st_page {
   OBJECT *object_head;
   OBJECT *object_tail;
   OBJECT *object_parent;
-  GList *selection_list; /* new selection mechanism */
+  SELECTION *selection_list; /* new selection mechanism */
   GList *complex_place_list;
   OBJECT *attrib_place_head;
   OBJECT *attrib_place_tail; 
diff --git a/libgeda/src/o_net_basic.c b/libgeda/src/o_net_basic.c
index 9e2b275..5386ee1 100644
--- a/libgeda/src/o_net_basic.c
+++ b/libgeda/src/o_net_basic.c
@@ -592,7 +592,7 @@ int o_net_consolidate_segments(TOPLEVEL *w_current, OBJECT *object)
   OBJECT *other_object;
   int changed = 0;
   int reselect_new=FALSE;
-  
+
   if (object == NULL) {
     return(0);
   }
@@ -615,7 +615,7 @@ int o_net_consolidate_segments(TOPLEVEL *w_current, OBJECT *object)
     if (other_object != NULL && conn->type == CONN_ENDPOINT &&
         conn->other_whichone != -1 && conn->whichone != -1 &&
         o_net_consolidate_nomidpoint(object, conn->x, conn->y) ) {
-      
+
       if (other_object->type == OBJ_NET) {
         other_orient = o_net_orientation(other_object);
 
@@ -625,26 +625,23 @@ int o_net_consolidate_segments(TOPLEVEL *w_current, OBJECT *object)
             object->sid != other_object->sid &&
             other_orient != NEITHER) {
 
-#if DEBUG          
+#if DEBUG
           printf("consolidating %s to %s\n", object->name, other_object->name);
-#endif          
-          
+#endif
+
           o_net_consolidate_lowlevel(object, other_object, other_orient);
 
           changed++;
           if (other_object->selected == TRUE ) {
-            o_selection_remove(&(w_current->page_current->selection_list), 
-                               other_object);
+            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->selection_list), 
-                               object);
-	    o_selection_add(&(w_current->page_current->selection_list), 
-			    object);
+            o_selection_remove( w_current->page_current->selection_list, object );
+            o_selection_add( w_current->page_current->selection_list, object );
           }
-				
+
           s_conn_remove(w_current, other_object);
           s_delete(w_current, other_object);
           o_net_recalc(w_current, object);
diff --git a/libgeda/src/o_selection.c b/libgeda/src/o_selection.c
index 19a947f..5d048cd 100644
--- a/libgeda/src/o_selection.c
+++ b/libgeda/src/o_selection.c
@@ -41,46 +41,92 @@
 #include "o_types.h"
 #include "colors.h"
 
+#include "geda_list.h"
+
 #include "../include/prototype.h"
 
 #ifdef HAVE_LIBDMALLOC
 #include <dmalloc.h>
 #endif
 
+/*! \brief Returns a pointer to a new SELECTION object.
+ *  \par Returns a pointer to a new SELECTION object.
+ *  \return pointer to the new SELECTION object.
+ */
+SELECTION *o_selection_new( void )
+{
+  return (SELECTION*)geda_list_new();
+}
+
 /*! \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 Pointer to the selection list
+ *  \param [in] selection Pointer to the selection list
  *  \param [in] o_selected Object to select.
  */
-void o_selection_add(GList **head, OBJECT *o_selected)
+void o_selection_add(SELECTION *selection, OBJECT *o_selected)
+{
+  o_selection_select( o_selected, SELECT_COLOR );
+  geda_list_add( (GedaList *)selection, o_selected );
+}
+
+/*! \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] selection Pointer to the selection list
+ *  \param [in] o_selected Object to unselect and remove from the list.
+ */
+void o_selection_remove(SELECTION *selection, OBJECT *o_selected )
 {
-  o_selection_select(o_selected, SELECT_COLOR);
-  *head = g_list_append(*head, o_selected);
+  if (o_selected == NULL) {
+    fprintf(stderr, "Got NULL for o_selected in o_selection_remove\n");
+    return;
+  }
+  o_selection_unselect( o_selected );
+  geda_list_remove( (GedaList *)selection, o_selected );
+}
+
+/*! \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
+ */
+void o_selection_unselect_list(TOPLEVEL *w_current, SELECTION *selection)
+{
+  const GList *list = geda_list_get_glist( selection );
+
+  while ( list != NULL ) {
+    o_selection_unselect( (OBJECT *)list->data );
+    o_redraw_single( w_current, (OBJECT *)list->data );
+   list = g_list_next( list );
+  }
+
+  geda_list_remove_all( (GedaList *)selection );
 }
 
 /*! \brief Prints the given selection list.
  *  \par Prints the given selection list.
- *  \param [in] head Pointer to selection list to print.
+ *  \param [in] selection Pointer to selection list to print.
  *
  */
-void o_selection_print_all(const GList **head)
+void o_selection_print_all(const SELECTION *selection)
 {
   const GList *s_current;
 
-  s_current = *head;
+  s_current = geda_list_get_glist( selection );
 
   printf("START printing selection ********************\n");
   while(s_current != NULL) {
     if (s_current->data) {
-      printf("Selected object: %d\n", 
-	     ( (OBJECT *) s_current->data)->sid);
+      printf("Selected object: %d\n", ((OBJECT *)s_current->data)->sid );
     }
     s_current = s_current->next;
   }
   printf("DONE printing selection ********************\n");
   printf("\n");
-
 }
 
 /*! \brief Selects the given object.
@@ -142,45 +188,3 @@ void o_selection_unselect(OBJECT *object)
   object->saved_color = -1;
 }
 
-/*! \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.
- */
-void
-o_selection_remove(GList **head, OBJECT *o_selected)
-{
-  if (o_selected == NULL) {
-    fprintf(stderr, "Got NULL for o_selected in o_selection_remove\n");
-    return;
-  }
-
-  if (g_list_find(*head, o_selected) != NULL) {
-    o_selection_unselect(o_selected);
-    *head = g_list_remove(*head, o_selected);
-  }
-}
-
-/*! \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
- */
-void
-o_selection_unselect_list(TOPLEVEL *w_current, GList **head)
-{
-  GList *list = *head;
-  
-  while (list != NULL) {
-    o_selection_unselect((OBJECT *) list->data);
-    o_redraw_single(w_current, (OBJECT *) list->data);
-   list = list->next;
-  }
-  
-  g_list_free(*head);
-  *head = NULL;  
-}
diff --git a/libgeda/src/s_page.c b/libgeda/src/s_page.c
index e2e2f41..a7a2b92 100644
--- a/libgeda/src/s_page.c
+++ b/libgeda/src/s_page.c
@@ -101,7 +101,7 @@ PAGE *s_page_new (TOPLEVEL *toplevel, const gchar *filename)
   page->object_head->type = OBJ_HEAD;
 
   /* new selection mechanism */
-  page->selection_list = NULL;
+  page->selection_list = o_selection_new();
 
   /* net/pin/bus stretch when doing moves */
   page->stretch_head = page->stretch_tail = s_stretch_new_head();
@@ -167,7 +167,6 @@ 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);
 
@@ -210,21 +209,19 @@ void s_page_delete (TOPLEVEL *toplevel, PAGE *page)
   }
   g_free(real_filename);
 
-  /* first unselect the objects, without redrawing them */
-  toplevel->DONT_REDRAW = 1;
-  o_selection_unselect_list(toplevel, &(page->selection_list));
-  toplevel->DONT_REDRAW = redraw_status;
+  /* Free the selection object */
+  g_object_unref( page->selection_list );
 
   /* then delete objects of page */
   s_delete_list_fromstart (toplevel, page->object_head);
-  
+
   toplevel->REMOVING_SEL = 1;
   /* 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);
-  toplevel->REMOVING_SEL = 0;  
+  toplevel->REMOVING_SEL = 0;
 
 #if DEBUG
   printf("Freeing page: %s\n", page->page_filename);

commit 10e79873064a096f8af4b0b6dcb9f957be0f6859
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Date:   Thu Jul 19 15:06:57 2007 +0100

    Added new GedaList class derived from GObject
    
    This abstracts a GList with API for write access. Its main use is in list
    change notification, as it emits a "changed" g_signal when modified.
    Read only access to the underlying GList is provided by an accessor,
    currenly implemented as a macro.

diff --git a/libgeda/include/Makefile.am b/libgeda/include/Makefile.am
index eb5420f..8357985 100644
--- a/libgeda/include/Makefile.am
+++ b/libgeda/include/Makefile.am
@@ -3,7 +3,8 @@
 libgedaincludedir = $(includedir)/libgeda
 libgedainclude_HEADERS = \
 	colors.h defines.h funcs.h globals.h o_types.h \
-	prototype.h struct.h libgeda.h i_vars.h papersizes.h
+	prototype.h struct.h libgeda.h i_vars.h papersizes.h \
+	geda_list.h
 
 MOSTLYCLEANFILES = *.log core FILE *~
 CLEANFILES = *.log core FILE *~
diff --git a/libgeda/include/geda_list.h b/libgeda/include/geda_list.h
new file mode 100644
index 0000000..492c78c
--- /dev/null
+++ b/libgeda/include/geda_list.h
@@ -0,0 +1,61 @@
+/* gEDA - GPL Electronic Design Automation
+ * gschem - gEDA Schematic Capture
+ * Copyright (C) 1998-2004 Ales V. Hvezda
+ * Copyright (C)      2007 Peter Clifton
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#ifndef __GEDA_LIST_H__
+#define __GEDA_LIST_H__
+
+
+#define GEDA_TYPE_LIST            (geda_list_get_type())
+#define GEDA_LIST(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), GEDA_TYPE_LIST, GedaList))
+#define GEDA_LIST_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass),  GEDA_TYPE_LIST, GedaListClass))
+#define GEDA_IS_LIST(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), GEDA_TYPE_LIST))
+#define GEDA_IS_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),  GEDA_TYPE_LIST))
+#define GEDA_LIST_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj),  GEDA_TYPE_LIST, GedaListClass))
+
+
+typedef struct _GedaList      GedaList;
+typedef struct _GedaListClass GedaListClass;
+
+struct _GedaList {
+  GObject parent;
+  GList *glist;
+};
+
+struct _GedaListClass {
+  GObjectClass parent;
+};
+
+GType geda_list_get_type (void);
+
+/* It would be nice to add const qualifiers to some of these, but GLib
+ * is buggy in this respect, and doesn't have const where necessary. */
+GedaList *geda_list_new( void );
+void geda_list_add( GedaList *list, gpointer item );
+void geda_list_add_glist( GedaList *list, GList *items );
+void geda_list_remove( GedaList *list, gpointer item );
+/*void geda_list_remove_glist( GedaList *list, GList *items ); */ /* Undemanded as yet */
+void geda_list_remove_all( GedaList *list );
+
+/*const GList *geda_list_get_glist( GedaList *list ); */
+#define geda_list_get_glist(list) (list->glist)
+
+#endif /* __GEDA_LIST_H__ */
+
diff --git a/libgeda/include/libgeda.h b/libgeda/include/libgeda.h
index e458a7a..074fe0a 100644
--- a/libgeda/include/libgeda.h
+++ b/libgeda/include/libgeda.h
@@ -36,6 +36,7 @@
 #include <libgeda/papersizes.h>
 #include <libgeda/i_vars.h>
 #include <libgeda/prototype.h>
+#include <libgeda/geda_list.h>
 
 #include <gdk-pixbuf/gdk-pixbuf.h>
 
diff --git a/libgeda/src/Makefile.am b/libgeda/src/Makefile.am
index 8d7495b..3015c90 100644
--- a/libgeda/src/Makefile.am
+++ b/libgeda/src/Makefile.am
@@ -23,7 +23,8 @@ libgeda_la_SOURCES = \
 	s_log.c s_textbuffer.c \
 	s_page.c s_slib.c s_color.c s_undo.c s_conn.c \
 	s_cue.c s_tile.c s_menu.c s_toplevel.c g_smob.c libgeda.c \
-	g_register.c g_rc.c i_vars.c o_picture.c gdk-pixbuf-hacks.c
+	g_register.c g_rc.c i_vars.c o_picture.c gdk-pixbuf-hacks.c \
+	geda_list.c
 
 INCLUDES = -I$(top_srcdir)/include @LIBGEDA_CFLAGS@
 libgeda_la_LDFLAGS = @LIBTOOL_FLAGS@ @LIBGEDA_LDFLAGS@
diff --git a/libgeda/src/geda_list.c b/libgeda/src/geda_list.c
new file mode 100644
index 0000000..b6792c6
--- /dev/null
+++ b/libgeda/src/geda_list.c
@@ -0,0 +1,213 @@
+/* gEDA - GPL Electronic Design Automation
+ * libgeda - gEDA's library
+ * Copyright (C) 1998-2000 Ales V. Hvezda
+ * Copyright (C)      2007 Peter Clifton
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
+ */
+
+
+#include <config.h>
+
+#include <glib-object.h>
+
+#include "geda_list.h"
+
+#ifdef HAVE_LIBDMALLOC
+#include <dmalloc.h>
+#endif
+
+
+enum {
+  CHANGED,
+  LAST_SIGNAL
+};
+
+static guint geda_list_signals[ LAST_SIGNAL ] = { 0 };
+static GObjectClass *geda_list_parent_class = NULL;
+
+
+/*! \brief GType instance initialiser for GedaList
+ *
+ *  \par Function Description
+ *  GType instance initialiser for GedaList.
+ *
+ *  \param [in]  instance       The GedaList we are initialising.
+ *  \param [in]  g_class        The class of the type the instance is created for.
+ */
+static void geda_list_instance_init( GTypeInstance *instance, gpointer g_class )
+{
+  GedaList *list = (GedaList *)instance;
+
+  /* Strictly un-necessary, as the memory is zero'd after allocation */
+  list->glist = NULL;
+}
+
+
+/*! \brief GObject finalise handler
+ *
+ *  \par Function Description
+ *  Just before the GedaList GObject is finalized, free our
+ *  allocated data, and then chain up to the parent's finalize handler.
+ *
+ *  \param [in] widget  The GObject being finalized.
+ */
+static void geda_list_finalize( GObject *object )
+{
+  GedaList *list = GEDA_LIST( object );
+  g_list_free( list->glist );
+
+  G_OBJECT_CLASS( geda_list_parent_class )->finalize( object );
+}
+
+
+/*! \brief GType class initialiser for GedaList
+ *
+ *  \par Function Description
+ *  GType class initialiser for GedaList. We override our parents
+ *  virtual class methods as needed and register our GObject signals.
+ *
+ *  \param [in]  klass       The GedaList we are initialising
+ */
+static void geda_list_class_init( gpointer g_class, gpointer g_class_data )
+{
+  GedaListClass *klass = GEDA_LIST_CLASS( g_class );
+  GObjectClass *gobject_class = G_OBJECT_CLASS( klass );
+  geda_list_parent_class = g_type_class_peek_parent( klass );
+
+  gobject_class->finalize = geda_list_finalize;
+
+  geda_list_signals[ CHANGED ] =
+    g_signal_new ("changed",
+                  G_OBJECT_CLASS_TYPE( gobject_class ),
+                  0     /*signal_flags */,
+                  0     /*class_offset */,
+                  NULL, /* accumulator */
+                  NULL, /* accu_data */
+                  g_cclosure_marshal_VOID__VOID,
+                  G_TYPE_NONE,
+                  0     /* n_params */
+                 );
+}
+
+
+/*! \brief Function to retrieve GedaList's GType identifier.
+ *
+ *  \par Function Description
+ *  Function to retrieve GedaList's GType identifier.
+ *  Upon first call, this registers the GedaList in the GType system.
+ *  Subsequently it returns the saved value from its first execution.
+ *
+ *  \return the GType identifier associated with GedaList.
+ */
+GType geda_list_get_type(void)
+{
+  static GType type = 0;
+  if (type == 0) {
+    static const GTypeInfo info = {
+      sizeof (GedaListClass),
+      NULL,                         /* base_init */
+      NULL,                         /* base_finalize */
+      geda_list_class_init,         /* class_init */
+      NULL,                         /* class_finalize */
+      NULL,                         /* class_data */
+      sizeof (GedaList),
+      0,                            /* n_preallocs */
+      geda_list_instance_init       /* instance_init */
+    };
+    type = g_type_register_static (G_TYPE_OBJECT, "GedaList", &info, 0);
+  }
+  return type;
+}
+
+
+/*! \brief Returns a pointer to a new GedaList object.
+ *
+ *  \par Function Description
+ *  Returns a pointer to a new GedaList object.
+ *
+ *  \return pointer to the new GedaList object.
+ */
+GedaList *geda_list_new( void ) {
+  return g_object_new( GEDA_TYPE_LIST, NULL );
+}
+
+
+/*! \brief Adds the given item to the GedaList
+ *
+ *  \par Function Description
+ *  Adds the given item to the GedaList
+ *
+ *  \param [in] list Pointer to the GedaList
+ *  \param [in] item item to add to the GedaList.
+ */
+void geda_list_add( GedaList *list, gpointer item )
+{
+  list->glist = g_list_append(list->glist, item );
+  g_signal_emit( list, geda_list_signals[ CHANGED ], 0 );
+}
+
+
+/*! \brief Adds the given glist of items to the GedaList
+ *
+ *  \par Function Description
+ *  Adds the given glist of items to the GedaList
+ *  A copy is made, so the original GList is not modified.
+ *
+ *  \param [in] list Pointer to the GedaList
+ *  \param [in] items GList of items to add to the GedaList.
+ */
+void geda_list_add_glist( GedaList *list, GList *items )
+{
+  GList *glist_copy = g_list_copy( items );
+  list->glist = g_list_concat(list->glist, glist_copy );
+  g_signal_emit( list, geda_list_signals[ CHANGED ], 0 );
+}
+
+
+/*! \brief Removes the given item from the GedaList
+ *
+ *  \par Function Description
+ *  Removes the given item from the GedaList.
+ *  It's ok to call this function with an item which
+ *  is not necessarily in the list.
+ *
+ *  \param [in] list Pointer to the GedaList
+ *  \param [in] item to remove from the GedaList.
+ */
+void geda_list_remove( GedaList *list, gpointer item )
+{
+  if (g_list_find(list->glist, item) == NULL)
+    return;
+
+  list->glist = g_list_remove(list->glist, item);
+  g_signal_emit( list, geda_list_signals[ CHANGED ], 0 );
+}
+
+
+/*! \brief Removes all the items in the given GedaList.
+ *
+ *  \par Function Description
+ *  Removes all items in the given GedaList.
+ *
+ *  \param [in] list Pointer to the GedaList
+ */
+void geda_list_remove_all( GedaList *list )
+{
+  g_list_free(list->glist);
+  list->glist = NULL;
+  g_signal_emit( list, geda_list_signals[ CHANGED ], 0 );
+}
+




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