Index: include/csutil/event.h
===================================================================
--- include/csutil/event.h	(revision 25072)
+++ include/csutil/event.h	(working copy)
@@ -24,6 +24,7 @@
 
 #include "csextern.h"
 #include "iutil/event.h"
+#include "iutil/eventhandlers.h"
 
 /**\file
  * Event system related helpers
@@ -236,6 +237,26 @@
 };
 
 /** @} */
+
+struct iEventQueue;
+struct iObjectRegistry;
+
+/**
+ * Helper function for registering an event handler using a weak reference.
+ * Use RemoveWeakListener() to remove an event handler registered with this
+ * function.
+ */
+csHandlerID RegisterWeakListener (iEventQueue *q, iEventHandler *listener);
+csHandlerID RegisterWeakListener (iEventQueue *q, iEventHandler *listener,
+  const csEventID &ename);
+csHandlerID RegisterWeakListener (iEventQueue *q, iEventHandler *listener,
+  const csEventID ename[]);
+
+/**
+ * Helper function for removing an event handler that was registered with
+ * RegisterWeakListener().
+ */
+void RemoveWeakListener (iEventQueue *q, iObjectRegistry *r, csHandlerID id);
  
 /** @} */
 
Index: libs/csutil/event.cpp
===================================================================
--- libs/csutil/event.cpp	(revision 25072)
+++ libs/csutil/event.cpp	(working copy)
@@ -483,3 +483,62 @@
   return true;
 }
 
+//---------------------------------------------------------------------------
+
+class csWeakEventHandler :
+  public scfImplementation1<csWeakEventHandler, iEventHandler>
+{
+private:
+  csWeakRef<iEventHandler> parent;
+public:
+  csWeakEventHandler (iEventHandler *parent) :
+    scfImplementationType (this), parent(parent) { }
+  bool HandleEvent (iEvent &e) { return parent->HandleEvent(e); }
+  const char * GenericName() const { return parent->GenericName(); }
+  csHandlerID GenericID (csRef<iEventHandlerRegistry> &r) const
+  { return parent->GenericID(r); }
+  const csHandlerID * GenericPrec (
+    csRef<iEventHandlerRegistry> &hr, csRef<iEventNameRegistry> &nr,
+    csEventID id) const
+  { return parent->GenericPrec(hr, nr, id); }
+  const csHandlerID * GenericSucc (
+    csRef<iEventHandlerRegistry> &hr, csRef<iEventNameRegistry> &nr,
+    csEventID id) const
+  { return parent->GenericSucc(hr, nr, id); }
+  const csHandlerID * InstancePrec (
+    csRef<iEventHandlerRegistry> &hr, csRef<iEventNameRegistry> &nr,
+    csEventID id) const
+  { return parent->InstancePrec(hr, nr, id); }
+  const csHandlerID * InstanceSucc (
+    csRef<iEventHandlerRegistry> &hr, csRef<iEventNameRegistry> &nr,
+    csEventID id) const
+  { return parent->InstanceSucc(hr, nr, id); }
+};
+
+csHandlerID RegisterWeakListener (iEventQueue *q, iEventHandler *listener)
+{
+  csRef<csWeakEventHandler> handler;
+  handler.AttachNew (new csWeakEventHandler (listener));
+  return q->RegisterListener (handler);
+}
+
+csHandlerID RegisterWeakListener (iEventQueue *q, iEventHandler *listener,
+  const csEventID &ename)
+{
+  csRef<csWeakEventHandler> handler;
+  handler.AttachNew (new csWeakEventHandler (listener));
+  return q->RegisterListener (handler, ename);
+}
+
+csHandlerID RegisterWeakListener (iEventQueue *q, iEventHandler *listener,
+  const csEventID ename[])
+{
+  csRef<csWeakEventHandler> handler;
+  handler.AttachNew (new csWeakEventHandler (listener));
+  return q->RegisterListener (handler, ename);
+}
+
+void RemoveWeakListener (iEventQueue *q, iObjectRegistry *r, csHandlerID id)
+{
+  q->RemoveListener(csEventHandlerRegistry::GetHandler(r, id));
+}
