? glibmm.kdevprj
? glibmm.kdevses
? glibmm.spec
? temp.patch
? glib/glibmm-2.4.pc
? tools/gmmproc
Index: glib/glibmm/object.cc
===================================================================
RCS file: /cvs/gnome/glibmm/glib/glibmm/object.cc,v
retrieving revision 1.1.1.1
diff -u -p -r1.1.1.1 object.cc
--- glib/glibmm/object.cc	7 Jan 2003 16:58:50 -0000	1.1.1.1
+++ glib/glibmm/object.cc	28 Jan 2003 09:48:41 -0000
@@ -224,7 +224,6 @@ Object::Object(GObject* castitem)
 
 Object::~Object()
 {
-  cpp_destruction_in_progress_ = true;
 }
 
 /*
Index: glib/glibmm/objectbase.cc
===================================================================
RCS file: /cvs/gnome/glibmm/glib/glibmm/objectbase.cc,v
retrieving revision 1.2
diff -u -p -r1.2 objectbase.cc
--- glib/glibmm/objectbase.cc	22 Jan 2003 12:08:52 -0000	1.2
+++ glib/glibmm/objectbase.cc	28 Jan 2003 09:48:42 -0000
@@ -1,5 +1,5 @@
 // -*- c++ -*-
-/* $Id: objectbase.cc,v 1.2 2003/01/22 12:08:52 murrayc Exp $ */
+/* $Id: objectbase.cc,v 1.11 2002/12/20 21:39:39 daniel Exp $ */
 
 /* Copyright 2002 The gtkmm Development Team
  *
@@ -19,10 +19,147 @@
  */
 
 #include <glib-object.h>
-
-#include <glibmm/quark.h>
 #include <glibmm/objectbase.h>
+#include <glibmm/refptr.h>
 
+//----------------------------------------------------------------------
+// Notes on inheritance and management of underlying GTK+ objects.
+//
+// 1) Reference counting as lifetime management.
+//
+//    In the class hierarchy descended from Glib::ObjectBase, some of
+//    the classes always use reference counting to manage the lifetime of
+//    object instances. All such classes have protected constructors and
+//    can only be created by calling a static create() method of the
+//    class, which allocates an instance of the class on the heap with
+//    new and returns a smart pointer that serves as a reference to the
+//    instance. Some classes do not provide a create() method (they must
+//    be instantiated by derived classes or friends) or provide a method
+//    with a different name, but the basic principle still holds.
+//
+//    All classes in this category must be referenced through the use of
+//    smart pointers that maintain the reference count of each instance.
+//    When there are no more references to an instance (i.e. its reference
+//    count is reduced to zero) then the instance is deleted.
+//
+//    Other classes do not always use reference counting to manage the
+//    lifetime of object instances. They have public constructors. These
+//    classes may be allocated on the stack or as members of another
+//    class. Classes in this category normally are not referenced by smart
+//    pointers.
+//
+// 2) Wrapping of GLib objects.
+//
+//    Glib::ObjectBase is the base class for all classes that wrap a
+//    GLib object (a GObject). There is a one-to-one relationship
+//    between a C++ wrapper instance and its associated GObject. The
+//    wrapper instance holds a pointer to the GObject, and the GObject
+//    holds a pointer to the wrapper instance.
+//
+//    A GObject has a reference count of one when it is created, and the
+//    creator (in this case, the wrapper) is assumed to own this
+//    reference and thus the GObject.
+//
+//    The wrapper and the GObject both need to persist so long as there
+//    are external references (references held by a third entity) to
+//    either of them. The objects cannot mutually hold references to
+//    each other, because then they would keep each other alive when no
+//    more external references exist.
+//
+//    To accomplish this, one of the two objects holds a reference to
+//    the other at any given time. The object holding the reference is
+//    the anchor. With one exception, there will always be at least one
+//    external reference to the anchor. The exception is when a wrapper
+//    is newly constructed and has a reference to a GObject, but has not
+//    yet been referenced itself.
+//
+//    Normally, the wrapper is the anchor. The only time that the
+//    GObject is the anchor is when there are no external references to
+//    the wrapper (except for the case described above).
+//
+//    If the wrapper is the anchor and the last external reference to it
+//    is released, then the GObject becomes the anchor. The GObject is
+//    given a reference to the wrapper and the wrapper's reference to
+//    the GObject is released. This happens in the wrapper's
+//    unreference() method.
+//
+//    If the GObject is the anchor and an external reference to the
+//    wrapper is acquired, then the wrapper again becomes the anchor.
+//    The wrapper acquires a reference to the GObject and the reference
+//    to the wrapper is removed from the GObject. This happens in the
+//    wrapper's reference() method.
+//
+//    If the GObject is the anchor and its reference count goes to zero,
+//    then the GObject is destroyed and destroy_notify_callback_() is
+//    invoked.
+//
+//    The destroy_notify_callback_() acquires a temporary reference to
+//    the wrapper (which makes it the anchor) and calls the wrapper's
+//    destroy_notify_() virtual method. The destroy_notify_() method
+//    clears the wrapper's pointer to the GObject. Upon return from
+//    destroy_notify_() the temporary reference to the wrapper is
+//    released. Since it is the last reference to the wrapper, the
+//    wrapper is then deleted.
+//
+// 3) Inheritance hierarchy classifications.
+//
+//    There are only two classes that inherit directly from
+//    Glib::ObjectBase, which are Glib::Interface and Glib::Object.
+//
+//    Relatively few classes inherit directly from Glib::Interface. None
+//    of these can be instantiated directly. The use of reference
+//    counting is indeterminate for these classes, because the nature
+//    of derived classes will dictate how the lifetime of an instance is
+//    determined.
+//
+//    A large number of classes inherit directly from Glib::Object. Of
+//    these, all but one use reference counting to manage the lifetime
+//    of object instances. The one exception is Gtk::Object.
+//
+// 4) Wrapping of GTK+ objects.
+//
+//    Gtk::Object is the base class for all classes that wrap a GTK+
+//    object (a GtkObject). GtkObject is a subclass of GObject that has
+//    a different set of rules for managing references. Gtk::Object is
+//    a subclass of Glib::Object that accounts for those rules.
+//
+//    The inheritance hierarchy of Gtk::Object includes all of the Gtk
+//    and Gnome widgets as well as a small number of utility classes
+//    including Gtk::Adjustment, Gtk::CellRenderer, Gtk::Tooltips and
+//    Gtk::TreeViewColumn.
+//
+//    Like a GObject, a GtkObject is created with an initial reference
+//    count of one. Unlike a GtkObject, this reference is not owned by
+//    the creating entity. It is considered a "floating" reference. To
+//    take ownership of a GtkObject, an entity must acquire a
+//    non-floating reference using g_object_ref() and then remove the
+//    floating reference by calling gtk_object_sink() on the GtkObject.
+//
+//    Normally, the Gtk::Object class does not use reference counting,
+//    nor do any classes that inherit from it. A Gtk::Object instance in
+//    this state is considered "unmanaged". An unmanaged Gtk::Object
+//    always has a non-floating reference to the GtkObject, which it
+//    acquires during initialization. An unmanaged Gtk::Object owns the
+//    GtkObject it wraps.
+//
+//    It is possible (though potentially perilous) to enable reference
+//    counting for a specific instance of a Gtk::Object by calling the
+//    set_manage() method directly or by using the Gtk::manage() function
+//    on the instance. This must only be done with a Gtk::Object instance
+//    that has been allocated with new. Once this is done, a Gtk::Object
+//    is considered "managed".
+//
+//    A managed Gtk::Object gives up its initial non-floating reference
+//    to the GtkObject. The GtkObject is then floating (if it was "sunk"
+//    by the Gtk::Object) or is owned by some other entity (usually a
+//    container widget) or is destroyed, if no more references to the
+//    GtkObject exist after the set_manage() call. A managed Gtk::Object
+//    gives up ownership of the GtkObject it wraps.
+//
+//    For detailed information on how Gtk::Object uses reference counting,
+//    see the Gtk::Object implementation.
+//
+//----------------------------------------------------------------------
 
 namespace
 {
@@ -41,26 +178,36 @@ namespace Glib
 
 /**** Glib::ObjectBase *****************************************************/
 
+GQuark ObjectBase::quark_ = 0;
+GQuark ObjectBase::quark_anchor_ = 0;
+GQuark ObjectBase::quark_disconnected_ = 0;
+
 ObjectBase::ObjectBase()
 :
   gobject_                      (0),
   custom_type_name_             (anonymous_custom_type_name),
-  cpp_destruction_in_progress_  (false)
-{}
+  referenced_                   (true)
+{
+  set_manage(); // Arrange for delete to be called when no more references exist
+}
 
 ObjectBase::ObjectBase(const char* custom_type_name)
 :
   gobject_                      (0),
   custom_type_name_             (custom_type_name),
-  cpp_destruction_in_progress_  (false)
-{}
+  referenced_                   (true)
+{
+  set_manage(); // Arrange for delete to be called when no more references exist
+}
 
 ObjectBase::ObjectBase(const std::type_info& custom_type_info)
 :
   gobject_                      (0),
   custom_type_name_             (custom_type_info.name()),
-  cpp_destruction_in_progress_  (false)
-{}
+  referenced_                   (true)
+{
+  set_manage(); // Arrange for delete to be called when no more references exist
+}
 
 // initialize() actually initializes the wrapper.  Glib::ObjectBase is used
 // as virtual base class, which means the most-derived class' ctor invokes
@@ -68,6 +215,13 @@ ObjectBase::ObjectBase(const std::type_i
 //
 void ObjectBase::initialize(GObject* castitem)
 {
+  if(quark_ == 0)
+  {
+    quark_ = g_quark_from_static_string("glibmm__Glib::ObjectBase::quark_");
+    quark_anchor_ = g_quark_from_static_string("glibmm__Glib::ObjectBase::quark_anchor_");
+    quark_disconnected_ = g_quark_from_static_string("glibmm__Glib::ObjectBase::quark_disconnected_");
+  }
+
   if(gobject_)
   {
     // initialize() might be called twice when used with MI, e.g. by the ctors
@@ -100,158 +254,224 @@ ObjectBase::~ObjectBase()
   //    on a Glib::Object is a programming error.
   //
   // The *only* situation where gobject_ is validly not 0 at this point
-  // happens if a derived class's ctor throws an exception.  In that case
-  // we have to call g_object_unref() on our own.
+  // is if a derived class's constructor throws an exception. However, in that
+  // case this destructor will never be called, because C++ does not call the
+  // destructor for an object that has not been completely constructed. See
+  // Scott Meyers "More Effective C++" item 10 for details:
+  // http://www.awprofessional.com/content/images/020163371x/items/item10.html
   //
-  if(GObject *const gobject = gobject_)
-  {
-#ifdef GLIBMM_DEBUG_REFCOUNTING
-    g_warning("(Glib::ObjectBase::~ObjectBase): gobject_ = %p", (void*) gobject_);
-#endif
-
-    gobject_ = 0;
+  // However, we can at least gracefully handle the case where someone calls
+  // delete on a Glib::ObjectBase instance. Their code may fail later when
+  // they attempt to access the deleted object, but we will have done the right
+  // thing here.
 
-#ifdef GLIBMM_DEBUG_REFCOUNTING
-    g_warning("(Glib::ObjectBase::~ObjectBase): before g_object_steal_qdata()");
-#endif
-
-    // Remove the pointer to the wrapper from the underlying instance.
-    // This does _not_ cause invocation of the destroy_notify callback.
-    g_object_steal_qdata(gobject, quark_);
-
-#ifdef GLIBMM_DEBUG_REFCOUNTING
-    g_warning("(Glib::ObjectBase::~ObjectBase): calling g_object_unref()");
-#endif
+  if(GObject* const gobject = gobj())
+  {
+    // Disconnect the wrapper from the underlying instance. This does _not_
+    // cause invocation of destroy_notify_callback_
+    disconnect_wrapper_();
 
-    g_object_unref(gobject);
+    // Release our reference to the GObject, if we're holding one
+    if (referenced_) g_object_unref(gobject);
   }
 }
 
+//----------------------------------------------------------------------
+// public methods
+//----------------------------------------------------------------------
+
+// override
 void ObjectBase::reference() const
 {
-  // Completely replace the SigC::Object refcounting.
-  GLIBMM_DEBUG_REFERENCE(this, gobject_);
-  g_object_ref(gobject_);
+  GLIBMM_DEBUG_REFERENCE(this, gobj());
+
+  //TODO: Explain this. murrayc:
+  if (gobj_is_anchor())
+    gobj_set_anchor(false);
+  else
+    SigC::Object::reference();
 }
 
+// override
 void ObjectBase::unreference() const
 {
-  // Completely replace the SigC::Object refcounting.
-  GLIBMM_DEBUG_UNREFERENCE(this, gobject_);
-  g_object_unref(gobject_);
+  GLIBMM_DEBUG_UNREFERENCE(this, gobj());
+
+  //TODO: Explain this. murrayc:
+  if (gobj_can_anchor())
+    gobj_set_anchor(true);
+  else
+    SigC::Object::unreference();
 }
 
 GObject* ObjectBase::gobj_copy() const
 {
-  reference();
+  g_object_ref(gobject_);
   return gobject_;
 }
 
-void ObjectBase::_set_current_wrapper(GObject* object)
-{
-  // Store a pointer to this wrapper in the underlying instance, so that we
-  // never create a second wrapper for the same underlying instance.  Also,
-  // specify a callback that will tell us when it's time to delete this C++
-  // wrapper instance:
-
-  if(object)
-  {
-    if(!g_object_get_qdata(object, Glib::quark_))
-    {
-      g_object_set_qdata_full(object, Glib::quark_, this, &destroy_notify_callback_);
-    }
-    else
-    {
-      g_warning("This object, of type %s, already has a wrapper.\n"
-                "You should use wrap() instead of a constructor.",
-                G_OBJECT_TYPE_NAME(object));
-    }
-  }
-}
-
 // static
 ObjectBase* ObjectBase::_get_current_wrapper(GObject* object)
 {
   if(object)
-    return static_cast<ObjectBase*>(g_object_get_qdata(object, Glib::quark_));
+    return static_cast<ObjectBase*>(g_object_get_qdata(object, quark_));
   else
     return 0;
 }
 
 // static
-void ObjectBase::destroy_notify_callback_(void* data)
+bool ObjectBase::_wrapper_disconnected(GObject* object)
 {
-  //GLIBMM_LIFECYCLE
+  // This function is used to prevent calling wrap() on a GObject whose wrapper
+  // instance has been (or is being) destroyed.
 
-  // This method is called (indirectly) from g_object_run_dispose().
-  // Get the C++ instance associated with the C instance:
-  ObjectBase* cppObject = static_cast<ObjectBase*>(data); //Previously set with g_object_set_qdata_full().
+  if(object)
+    return g_object_get_qdata(object, quark_disconnected_);
+  return false;
+}
+
+bool ObjectBase::is_anonymous_custom_() const
+{
+  // Doing high-speed pointer comparison is OK here.
+  return (custom_type_name_ == anonymous_custom_type_name);
+}
+
+bool ObjectBase::is_derived_() const
+{
+  // gtkmmproc-generated classes initialize this to 0 by default.
+  return (custom_type_name_ != 0);
+}
+
+// virtual
+void ObjectBase::release_reference_()
+{
+  // This method is called by Gtk::Object::set_manage() when converting an
+  // unmanaged wrapper to a managed wrapper.
 
-#ifdef GLIBMM_DEBUG_REFCOUNTING
-  g_warning("ObjectBase::destroy_notify_callback_: cppObject=%10X, gobject_=%10X\n", cppObject, cppObject->gobject_);
-  g_warning("  gtypename=%s\n", cppObject->gobject_);
-#endif
+  referenced_ = false;
+  if (gobj())
+    g_object_unref(gobj());
+}
+
+// virtual
+void ObjectBase::disconnect_wrapper_()
+{
+  // This method is called by Gtk::Object::destroy_(), which in turn is called
+  // by Gtk::Object::~Object(), to dissociate the wrapper from the GtkObject
+  // prior to destroying it. This ensures that the wrapper is not referenced
+  // after it has been destroyed.
 
-  if(cppObject) //This will be 0 if the C++ destructor has already run.
+  if(gobj())
   {
-    cppObject->destroy_notify_(); //Virtual - it does different things for GObject and GtkObject.
+    g_object_steal_qdata(gobj(), quark_); // Disconnect wrapper
+    g_object_set_qdata(gobj(), quark_disconnected_, (gpointer)true); // Prevent re-wrapping
+    gobject_ = 0; // Clear our pointer to the GObject
   }
 }
 
-void ObjectBase::destroy_notify_()
-{
-  // The C instance is about to be disposed, making it unusable.  Now is a
-  // good time to delete the C++ wrapper of the C instance.  There is no way
-  // to force the disposal of the GObject (though GtkObject  has
-  // gtk_object_destroy()), So this is the *only* place where we delete the
-  // C++ wrapper.
-  //
-  // This will only happen after the last unreference(), which will be done by
-  // the RefPtr<> destructor.  There should be no way to access the wrapper or
-  // the undobjecterlying instance after that, so it's OK to delete this.
+// It would be better if the following three methods did not need to know
+// the implementation of reference counting in SigC::ObjectBase, but we
+// can at least keep this knowledge as far up the class hierarchy as possible.
+// If SigC::ObjectBase changes to provide accessors for this information,
+// then we can change the implementations here.
 
-#ifdef GLIBMM_DEBUG_REFCOUNTING
-  g_warning("Glib::ObjectBase::destroy_notify_: gobject_=%10X\n", gobject_);
-#endif
+bool ObjectBase::is_managed_() const
+{
+  return const_cast<ObjectBase*>(this)->control()->manage_;
+}
 
-  gobject_ = 0; // Make sure we don't unref it again in the dtor.
+void ObjectBase::set_manage(bool manage)
+{
+  if (manage)
+    set_manage();
+  else
+    control()->manage_ = 0;
+}
 
-  delete this;
+unsigned long ObjectBase::get_refcount_() const
+{
+  return const_cast<ObjectBase*>(this)->control()->count_;
 }
 
-bool ObjectBase::is_anonymous_custom_() const
+// virtual
+void ObjectBase::destroy_notify_()
 {
-  // Doing high-speed pointer comparison is OK here.
-  return (custom_type_name_ == anonymous_custom_type_name);
+  // The GObject is about to be disposed, making it unusable. We need to
+  // get rid of our pointer to the GObject. This method will _never_ be
+  // called from ~ObjectBase() because we clear the GObject's pointer to
+  // the wrapper before dereferencing it in ~ObjectBase().
+
+  gobject_ = 0; // Clear our pointer to the GObject
 }
 
-bool ObjectBase::is_derived_() const
+void ObjectBase::_set_current_wrapper(GObject* object)
 {
-  // gtkmmproc-generated classes initialize this to 0 by default.
-  return (custom_type_name_ != 0);
+  // Store a pointer to this wrapper in the GObject, so that we never
+  // create a second wrapper for the same GObject. Also specify a
+  // callback that will tell us if the GObject is destroyed.
+
+  if(object)
+  {
+    if(!g_object_get_qdata(object, quark_))
+      g_object_set_qdata_full(object, quark_, this, &destroy_notify_callback_);
+    else
+      g_warning("This object, of type %s, already has a wrapper.\n"
+                "You should use wrap() instead of a constructor.",
+                G_OBJECT_TYPE_NAME(object));
+  }
 }
 
-void ObjectBase::set_manage()
+// static
+void ObjectBase::destroy_notify_callback_(void* data)
 {
-  // This is a private method and SigC::manage() is a template function.
-  // Thus this will probably never run, unless you do something like:
+  // This method is called (indirectly) from g_object_run_dispose().
   //
-  // manage(static_cast<SigC::Object*>(refptr.operator->()));
+  // The data argument is a pointer to the wrapper associated with
+  // the GObject. This is set by the initialize() method through a call
+  // to _set_current_wrapper and is cleared to 0 in the ObjectBase
+  // destructor.
 
-  g_error("Glib::ObjectBase::set_manage(): "
-          "only Gtk::Object instances can be managed");
+  if (data)
+  { // Inside this scope, the wrapper is always the anchor
+    RefPtr<ObjectBase> self(static_cast<ObjectBase*>(data));
+
+    #ifdef GLIBMM_DEBUG_REFCOUNTING
+      g_warning("Glib::ObjectBase::destroy_notify_callback_: cppObject=%10X, gobject_=%10X\n",
+        data, self->gobj());
+      g_warning("  gtypename=%s\n", G_OBJECT_TYPE_NAME(self->gobj()));
+    #endif
+
+    self->destroy_notify_(); // virtual method; can be overridden to add behaviors
+
+  } // The wrapper may be deleted when we leave this scope
 }
 
-bool _gobject_cppinstance_already_deleted(GObject* gobject)
+//----------------------------------------------------------------------
+// private methods related to anchoring
+//----------------------------------------------------------------------
+
+bool ObjectBase::gobj_is_anchor() const
 {
-  //This function is used to prevent calling wrap() on a GTK+ instance whose gtkmm instance has been deleted.
+  return gobj() && g_object_get_qdata(gobject_,quark_anchor_);
+}
 
-  if(gobject)
-    return (bool)g_object_get_qdata(gobject, Glib::quark_cpp_wrapper_deleted_); //true means that something is odd.
-  else
-    return false; //Nothing is particularly wrong.
+bool ObjectBase::gobj_can_anchor() const
+{
+  return gobj() && is_managed_() && get_refcount_() == 1 && !gobj_is_anchor();
 }
 
+void ObjectBase::gobj_set_anchor(bool anchor) const
+{
+  if (anchor)
+  {
+    g_object_set_qdata(gobject_, quark_anchor_, (gpointer)true);
+    if (referenced_ && gobj()->ref_count > 0) g_object_unref(gobject_);
+  }
+  else
+  {
+    g_object_steal_qdata(gobject_, quark_anchor_);
+    if (referenced_ && gobj()->ref_count > 0) g_object_ref(gobject_);
+  }
+}
 
 } // namespace Glib
-
Index: glib/glibmm/objectbase.h
===================================================================
RCS file: /cvs/gnome/glibmm/glib/glibmm/objectbase.h,v
retrieving revision 1.2
diff -u -p -r1.2 objectbase.h
--- glib/glibmm/objectbase.h	22 Jan 2003 12:08:52 -0000	1.2
+++ glib/glibmm/objectbase.h	28 Jan 2003 09:48:42 -0000
@@ -25,6 +25,7 @@
 #include <typeinfo>
 #include <glibmmconfig.h>
 #include <glibmm/debug.h>
+#include <glibmm/quark.h>
 
 GLIBMM_USING_STD(type_info)
 
@@ -77,8 +78,8 @@ protected:
   void initialize(GObject* castitem);
 
 public:
-  virtual void reference()   const; // overrides SigC::ObjectBase::reference()
-  virtual void unreference() const; // overrides SigC::ObjectBase::unreference()
+  virtual void reference()   const; // overrides SigC::Object::reference()
+  virtual void unreference() const; // overrides SigC::Object::unreference()
 
   inline GObject*       gobj()       { return gobject_; }
   inline const GObject* gobj() const { return gobject_; }
@@ -90,32 +91,53 @@ public:
   static ObjectBase* _get_current_wrapper(GObject* object);
 #endif
 
+  static bool _wrapper_disconnected(GObject* object);
+
 protected:
   GObject*            gobject_; // the GLib/GDK/GTK+ object instance
   const char*         custom_type_name_;
-  bool                cpp_destruction_in_progress_;
 
   bool is_anonymous_custom_() const;
   bool is_derived_() const;
 
-  static  void destroy_notify_callback_(void* data);
-  virtual void destroy_notify_();
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+  virtual void release_reference_();
+  virtual void disconnect_wrapper_();
 
-  void _set_current_wrapper(GObject* object);
+  bool is_managed_() const;
+  void set_manage(bool manage);
+  unsigned long get_refcount_() const;
+  using SigC::Object::set_manage;
+#endif
+
+  virtual void destroy_notify_();
 
 private:
   // noncopyable
-  ObjectBase(const ObjectBase&);
-  ObjectBase& operator=(const ObjectBase&);
+  ObjectBase(const ObjectBase&); // not implemented
+  ObjectBase& operator=(const ObjectBase&); // not implemented
+
+  void _set_current_wrapper(GObject* object);
+  static void destroy_notify_callback_(void* data);
 
-  virtual void set_manage(); // calls g_error()
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+  bool gobj_is_anchor() const;
+  bool gobj_can_anchor() const;
+  void gobj_set_anchor(bool anchor) const;
+#endif
 
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
   friend class Glib::GSigConnectionNode; // for GSigConnectionNode::notify()
 #endif
-};
 
-bool _gobject_cppinstance_already_deleted(GObject* gobject);
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+  bool referenced_;
+  static GQuark quark_;
+  static GQuark quark_anchor_;
+  static GQuark quark_disconnected_;
+#endif
+
+};
 
 } // namespace Glib
 
Index: glib/glibmm/quark.cc
===================================================================
RCS file: /cvs/gnome/glibmm/glib/glibmm/quark.cc,v
retrieving revision 1.1.1.1
diff -u -p -r1.1.1.1 quark.cc
--- glib/glibmm/quark.cc	7 Jan 2003 16:58:52 -0000	1.1.1.1
+++ glib/glibmm/quark.cc	28 Jan 2003 09:48:42 -0000
@@ -59,8 +59,4 @@ Quark::Quark(const char* s)
 Quark::~Quark()
 {}
 
-
-GQuark quark_ = 0;
-GQuark quark_cpp_wrapper_deleted_ = 0;
-
 } /* namespace Glib */
Index: glib/glibmm/quark.h
===================================================================
RCS file: /cvs/gnome/glibmm/glib/glibmm/quark.h,v
retrieving revision 1.1.1.1
diff -u -p -r1.1.1.1 quark.h
--- glib/glibmm/quark.h	7 Jan 2003 16:58:52 -0000	1.1.1.1
+++ glib/glibmm/quark.h	28 Jan 2003 09:48:42 -0000
@@ -75,14 +75,6 @@ inline bool operator==(const QueryQuark&
 inline bool operator!=(const QueryQuark& a, const QueryQuark& b)
   { return a.id() != b.id(); }
 
-#ifndef DOXYGEN_SHOULD_SKIP_THIS
-// TODO: Put this somewhere else.
-// (internal) The quark for C++ wrappers.
-extern GLIBMM_API GQuark quark_;
-extern GLIBMM_API GQuark quark_cpp_wrapper_deleted_;
-#endif
-
 } /* namespace Glib */
 
 #endif /* _GLIBMM_QUARK_H */
-
Index: glib/glibmm/refptr.h
===================================================================
RCS file: /cvs/gnome/glibmm/glib/glibmm/refptr.h,v
retrieving revision 1.3
diff -u -p -r1.3 refptr.h
--- glib/glibmm/refptr.h	27 Jan 2003 16:14:36 -0000	1.3
+++ glib/glibmm/refptr.h	28 Jan 2003 09:48:42 -0000
@@ -86,6 +86,19 @@ public:
   /// Copy from another RefPtr:
   inline RefPtr<T_CppObject>& operator=(const RefPtr<T_CppObject>& src);
 
+  /** Copy directly from a pointer.
+   *
+   * Mimics usage of ordinary pointers:
+   * @code
+   *   ptr = new thing; // assign a new reference to the RefPtr<>
+   * @endcode
+   * As well as:
+   * @code
+   *   ptr = 0; // releases the object reference, sets the RefPtr<> to null
+   * @endcode
+   */
+  inline RefPtr<T_CppObject>& operator=(T_CppObject* pCppObject);
+    
   /** Copy from different, but castable type).
    *
    * Increments the reference count.
@@ -116,10 +129,6 @@ public:
    */
   inline operator bool() const;
 
-  /// Set underlying instance to 0, decrementing reference count of existing instance appropriately.
-  inline void clear();
-
-
   /** Dynamic cast to derived class.
    *
    * The RefPtr can't be cast with the usual notation so instead you can use
@@ -156,6 +165,16 @@ T_CppObject* RefPtr<T_CppObject>::operat
   return pCppObject_;
 }
 
+// Might as well keep the dereferencing operators together.
+
+/*
+template <class T_CppObject> inline
+T_CppObject& RefPtr<T_CppObject>::operator*() const
+{
+  return *pCppObject_;
+}
+*/
+
 template <class T_CppObject> inline
 RefPtr<T_CppObject>::RefPtr()
 :
@@ -173,7 +192,10 @@ template <class T_CppObject> inline
 RefPtr<T_CppObject>::RefPtr(T_CppObject* pCppObject)
 :
   pCppObject_ (pCppObject)
-{}
+{
+  if (pCppObject_)
+    pCppObject_->reference();
+}
 
 template <class T_CppObject> inline
 RefPtr<T_CppObject>::RefPtr(const RefPtr<T_CppObject>& src)
@@ -241,6 +263,14 @@ RefPtr<T_CppObject>& RefPtr<T_CppObject>
   return *this;
 }
 
+template <class T_CppObject> inline
+RefPtr<T_CppObject>& RefPtr<T_CppObject>::operator=(T_CppObject* pCppObject)
+{
+  RefPtr<T_CppObject> temp(pCppObject);
+  this->swap(temp);
+  return *this;
+}
+  
 template <class T_CppObject>
   template <class T_CastFrom>
 inline
@@ -269,23 +299,12 @@ RefPtr<T_CppObject>::operator bool() con
   return (pCppObject_ != 0);
 }
 
-template <class T_CppObject> inline
-void RefPtr<T_CppObject>::clear()
-{
-  RefPtr<T_CppObject> temp; // swap with an empty RefPtr<> to clear *this
-  this->swap(temp);
-}
-
 template <class T_CppObject>
   template <class T_CastFrom>
 inline
 RefPtr<T_CppObject> RefPtr<T_CppObject>::cast_dynamic(const RefPtr<T_CastFrom>& src)
 {
   T_CppObject *const pCppObject = dynamic_cast<T_CppObject*>(src.operator->());
-
-  if(pCppObject)
-    pCppObject->reference();
-
   return RefPtr<T_CppObject>(pCppObject);
 }
 
@@ -295,10 +314,6 @@ inline
 RefPtr<T_CppObject> RefPtr<T_CppObject>::cast_static(const RefPtr<T_CastFrom>& src)
 {
   T_CppObject *const pCppObject = static_cast<T_CppObject*>(src.operator->());
-
-  if(pCppObject)
-    pCppObject->reference();
-
   return RefPtr<T_CppObject>(pCppObject);
 }
 
Index: glib/glibmm/wrap.cc
===================================================================
RCS file: /cvs/gnome/glibmm/glib/glibmm/wrap.cc,v
retrieving revision 1.2
diff -u -p -r1.2 wrap.cc
--- glib/glibmm/wrap.cc	22 Jan 2003 12:08:52 -0000	1.2
+++ glib/glibmm/wrap.cc	28 Jan 2003 09:48:42 -0000
@@ -32,6 +32,13 @@
 #include <glibmmconfig.h>
 GLIBMM_USING_STD(vector)
 
+namespace Glib
+{
+  namespace Wrap
+  {
+    static GQuark quark_ = 0;
+  }
+}
 
 namespace
 {
@@ -50,8 +57,7 @@ Glib::ObjectBase* create_new_wrapper(GOb
 {
   g_return_val_if_fail(wrap_func_table != 0, 0);
 
-  bool gtkmm_wrapper_already_deleted = (bool)g_object_get_qdata((GObject*)object, Glib::quark_cpp_wrapper_deleted_);
-  if(gtkmm_wrapper_already_deleted)
+  if(Glib::ObjectBase::_wrapper_disconnected(object))
   {
     g_warning("Glib::create_new_wrapper: Attempted to create a 2nd C++ wrapper for a C instance whose C++ wrapper has been deleted.");
     return 0;
@@ -65,7 +71,7 @@ Glib::ObjectBase* create_new_wrapper(GOb
     // Look up the wrap table index stored in the type's static data.
     // If a wrap_new() has been registered for the type then call it.
     //
-    if(const gpointer idx = g_type_get_qdata(type, Glib::quark_))
+    if(const gpointer idx = g_type_get_qdata(type, Glib::Wrap::quark_))
     {
       const Glib::WrapNewFunction func = (*wrap_func_table)[GPOINTER_TO_UINT(idx)];
       return (*func)(object);
@@ -85,12 +91,6 @@ void wrap_register_init()
 {
   g_type_init();
 
-  if(!Glib::quark_)
-  {
-    Glib::quark_ = g_quark_from_static_string("glibmm__Glib::quark_");
-    Glib::quark_cpp_wrapper_deleted_ = g_quark_from_static_string("glibmm__Glib::quark_cpp_wrapper_deleted_");
-  }
-
   if(!wrap_func_table)
   {
     // Make the first element a dummy so we can detect unregistered types.
@@ -113,11 +113,14 @@ void wrap_register_cleanup()
 //
 void wrap_register(GType type, WrapNewFunction func)
 {
+  if(Glib::Wrap::quark_ == 0)
+    Glib::Wrap::quark_ = g_quark_from_static_string("glibmm__Glib::Wrap::quark_");
+
   const guint idx = wrap_func_table->size();
   wrap_func_table->push_back(func);
 
   // Store the table index in the type's static data.
-  g_type_set_qdata(type, Glib::quark_, GUINT_TO_POINTER(idx));
+  g_type_set_qdata(type, Glib::Wrap::quark_, GUINT_TO_POINTER(idx));
 }
 
 // This is a factory function that converts any type to
@@ -129,8 +132,7 @@ ObjectBase* wrap_auto(GObject* object, b
     return 0;
 
   // Look up current C++ wrapper instance:
-  ObjectBase* pCppObject =
-      static_cast<ObjectBase*>(g_object_get_qdata(object, Glib::quark_));
+  ObjectBase* pCppObject = ObjectBase::_get_current_wrapper(object);
 
   if(!pCppObject)
   {
@@ -147,7 +149,7 @@ ObjectBase* wrap_auto(GObject* object, b
   // take_copy=true is used where the GTK+ function doesn't do
   // an extra ref for us, and always for plain struct members.
   if(take_copy)
-    pCppObject->reference();
+    g_object_ref(object);
 
   return pCppObject;
 }
@@ -157,5 +159,4 @@ Glib::RefPtr<Object> wrap(GObject* objec
   return Glib::RefPtr<Object>(dynamic_cast<Object*>(wrap_auto(object, take_copy)));
 }
 
-} /* namespace Glib */
-
+} // namespace Glib
