[glibmm] DBusConnection: Add register/unregister_object() methods.



commit 739b2e5f7e8b334282e010e9df4527103e0d303a
Author: José Alburquerque <jaalburqu svn gnome org>
Date:   Thu Dec 23 15:34:32 2010 -0500

    DBusConnection: Add register/unregister_object() methods.
    
    	* gio/src/dbusconnection.{ccg,hg}: Add register_object() and
    	unregister_object() methods.  Use a C++ wrapper class for the
    	GDBusInterfaceVTable structure so that it is possible to use slots for
    	the registration.
    
    	Fixes Bug #637587 (Yannick Guesnet)

 ChangeLog                  |   11 +++
 gio/src/dbusconnection.ccg |  182 +++++++++++++++++++++++++++++++++++++++++++-
 gio/src/dbusconnection.hg  |  147 +++++++++++++++++++++++++++++++++++
 3 files changed, 336 insertions(+), 4 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 166d0d0..7ec20a0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2010-12-23  José Alburquerque  <jaalburqu svn gnome org>
+
+	DBusConnection: Add register/unregister_object() methods.
+
+	* gio/src/dbusconnection.{ccg,hg}: Add register_object() and
+	unregister_object() methods.  Use a C++ wrapper class for the
+	GDBusInterfaceVTable structure so that it is possible to use slots for
+	the registration.
+
+	Fixes Bug #637587 (Yannick Guesnet)
+
 2010-12-22  José Alburquerque  <jaalburqu svn gnome org>
 
 	gmmproc: _CLASS_GOBJECT: Remove __REAL_* additional arguments.
diff --git a/gio/src/dbusconnection.ccg b/gio/src/dbusconnection.ccg
index ca94e3f..a415ad5 100644
--- a/gio/src/dbusconnection.ccg
+++ b/gio/src/dbusconnection.ccg
@@ -19,18 +19,29 @@
 
 #include <gio/gio.h>
 #include <giomm/dbusauthobserver.h>
+#include <giomm/dbusintrospection.h>
+#include <giomm/dbusmethodinvocation.h>
 #include "slot_async.h"
 
 namespace
 {
 
+// struct to hold the slots in the DBusInterfaceVTable class.  This is used to
+// pass the slots to the callbacks and later destroy them.
+struct TypeDBusInterfaceVTableSlots
+{
+  Gio::DBusInterfaceVTable::SlotInterfaceMethodCall* slot_method_call;
+  Gio::DBusInterfaceVTable::SlotInterfaceGetProperty* slot_get_property;
+  Gio::DBusInterfaceVTable::SlotInterfaceSetProperty* slot_set_property;
+};
+
 extern "C"
 {
 
 static void DBusConnection_Signal_giomm_callback(GDBusConnection* connection,
-  const gchar* sender_name, const gchar* object_path,
-  const gchar* interface_name, const gchar* signal_name, GVariant* parameters,
-  gpointer user_data)
+  const char* sender_name, const char* object_path,
+  const char* interface_name, const char* signal_name, GVariant* parameters,
+  void* user_data)
 {
   Gio::DBusConnection::SlotSignal* the_slot =
     static_cast<Gio::DBusConnection::SlotSignal*>(user_data);
@@ -54,7 +65,7 @@ static void DBusConnection_Signal_giomm_callback_destroy(void* data)
 
 static GDBusMessage* DBusConnection_Message_Filter_giomm_callback(
   GDBusConnection* connection, GDBusMessage* message, gboolean incoming,
-  gpointer user_data)
+  void* user_data)
 {
   Gio::DBusConnection::SlotMessageFilter* the_slot =
     static_cast<Gio::DBusConnection::SlotMessageFilter*>(user_data);
@@ -79,6 +90,96 @@ static void DBusConnection_Message_Filter_giomm_callback_destroy(void* data)
   delete static_cast<Gio::DBusConnection::SlotMessageFilter*>(data);
 }
 
+static void DBusInterfaceVTable_MethodCall_giomm_callback(
+  GDBusConnection* connection, const char* sender, const char* object_path,
+  const char* interface_name, const char* method_name, GVariant* parameters,
+  GDBusMethodInvocation* invocation, void* user_data)
+{
+  TypeDBusInterfaceVTableSlots* the_slots =
+    static_cast<TypeDBusInterfaceVTableSlots*>(user_data);
+
+  Gio::DBusInterfaceVTable::SlotInterfaceMethodCall* the_slot =
+    the_slots->slot_method_call;
+
+  try
+  {
+    (*the_slot)(Glib::wrap(connection, true), Glib::ustring(sender),
+      Glib::ustring(object_path), Glib::ustring(interface_name),
+      Glib::ustring(method_name), Glib::VariantBase(parameters, true),
+      Glib::wrap(invocation, true));
+  }
+  catch(...)
+  {
+    Glib::exception_handlers_invoke();
+  }
+}
+
+static GVariant* DBusInterfaceVTable_GetProperty_giomm_callback(
+  GDBusConnection* connection, const char* sender, const char* object_path,
+  const char* interface_name, const char* property_name, GError**,
+  void* user_data)
+{
+  TypeDBusInterfaceVTableSlots* the_slots =
+    static_cast<TypeDBusInterfaceVTableSlots*>(user_data);
+
+  Gio::DBusInterfaceVTable::SlotInterfaceGetProperty* the_slot =
+    the_slots->slot_get_property;
+
+  try
+  {
+    Glib::VariantBase result;
+
+    (*the_slot)(result, Glib::wrap(connection, true),
+      Glib::ustring(sender), Glib::ustring(object_path),
+      Glib::ustring(interface_name), Glib::ustring(property_name));
+    return result.gobj_copy();
+  }
+  catch(...)
+  {
+    Glib::exception_handlers_invoke();
+  }
+
+  return 0;
+}
+
+static gboolean DBusInterfaceVTable_SetProperty_giomm_callback(
+  GDBusConnection* connection, const char* sender, const char* object_path,
+  const char* interface_name, const char* property_name, GVariant* value,
+  GError**, void* user_data)
+{
+  TypeDBusInterfaceVTableSlots* the_slots =
+    static_cast<TypeDBusInterfaceVTableSlots*>(user_data);
+
+  Gio::DBusInterfaceVTable::SlotInterfaceSetProperty* the_slot =
+    the_slots->slot_set_property;
+
+  try
+  {
+    return static_cast<gboolean>((*the_slot)(Glib::wrap(connection, true),
+      Glib::ustring(sender), Glib::ustring(object_path),
+      Glib::ustring(interface_name), Glib::ustring(property_name),
+      Glib::VariantBase(value, true)));
+  }
+  catch(...)
+  {
+    Glib::exception_handlers_invoke();
+  }
+
+  return false;
+}
+
+static void DBusInterfaceVTable_giomm_callback_destory(void* data)
+{
+  TypeDBusInterfaceVTableSlots* the_slots =
+    static_cast<TypeDBusInterfaceVTableSlots*>(data);
+
+  delete the_slots->slot_method_call;
+  delete the_slots->slot_get_property;
+  delete the_slots->slot_set_property;
+
+  delete the_slots;
+}
+
 } // extern "C"
 
 }
@@ -791,4 +892,77 @@ guint DBusConnection::add_filter(const SlotMessageFilter& slot)
     DBusConnection_Message_Filter_giomm_callback_destroy);
 }
 
+guint DBusConnection::register_object(const Glib::ustring& object_path,
+  const Glib::RefPtr<DBusInterfaceInfo>& interface_info,
+  const DBusInterfaceVTable& vtable)
+{
+  TypeDBusInterfaceVTableSlots* the_slots = new TypeDBusInterfaceVTableSlots();
+
+  the_slots->slot_method_call = vtable.get_slot_method_call();
+  the_slots->slot_get_property = vtable.get_slot_get_property();
+  the_slots->slot_set_property = vtable.get_slot_set_property();
+
+  GError* gerror = 0;
+
+  guint const result = g_dbus_connection_register_object(gobj(),
+    object_path.c_str(), Glib::unwrap(interface_info),
+    reinterpret_cast<GDBusInterfaceVTable*>(const_cast<DBusInterfaceVTable*>(&vtable)),
+    the_slots, &DBusInterfaceVTable_giomm_callback_destory, &gerror);
+
+  if(gerror)
+    ::Glib::Error::throw_exception(gerror);
+
+  const_cast<DBusInterfaceVTable&>(vtable).signal_slots_registered();
+
+  return result;
+}
+
+DBusInterfaceVTable::DBusInterfaceVTable(
+  const SlotInterfaceMethodCall& slot_method_call,
+  const SlotInterfaceGetProperty& slot_get_property,
+  const SlotInterfaceSetProperty& slot_set_property
+)
+: slot_method_call(new SlotInterfaceMethodCall(slot_method_call)),
+  slot_get_property(new SlotInterfaceGetProperty(slot_get_property)),
+  slot_set_property(new SlotInterfaceSetProperty(slot_set_property)),
+  slots_registered(false)
+{
+  gobject_.method_call = &DBusInterfaceVTable_MethodCall_giomm_callback;
+  gobject_.get_property = &DBusInterfaceVTable_GetProperty_giomm_callback;
+  gobject_.set_property = &DBusInterfaceVTable_SetProperty_giomm_callback;
+}
+
+DBusInterfaceVTable::~DBusInterfaceVTable()
+{
+  if(!slots_registered)
+  {
+    delete slot_method_call;
+    delete slot_get_property;
+    delete slot_set_property;
+  }
+}
+
+DBusInterfaceVTable::SlotInterfaceMethodCall*
+  DBusInterfaceVTable::get_slot_method_call() const
+{
+  return slot_method_call;
+}
+
+DBusInterfaceVTable::SlotInterfaceGetProperty*
+  DBusInterfaceVTable::get_slot_get_property() const
+{
+  return slot_get_property;
+}
+
+DBusInterfaceVTable::SlotInterfaceSetProperty*
+  DBusInterfaceVTable::get_slot_set_property() const
+{
+  return slot_set_property;
+}
+
+void DBusInterfaceVTable::signal_slots_registered()
+{
+  slots_registered = true;
+}
+
 } // namespace Gio
diff --git a/gio/src/dbusconnection.hg b/gio/src/dbusconnection.hg
index e10119f..726cbf3 100644
--- a/gio/src/dbusconnection.hg
+++ b/gio/src/dbusconnection.hg
@@ -24,6 +24,7 @@
 #include <giomm/asyncresult.h>
 #include <giomm/credentials.h>
 #include <giomm/dbusmessage.h>
+#include <gio/gio.h>
 
 _DEFS(giomm,gio)
 _PINCLUDE(glibmm/private/object_p.h)
@@ -39,6 +40,9 @@ _WRAP_ENUM(DBusSendMessageFlags, GDBusSendMessageFlags, NO_GTYPE)
 _WRAP_ENUM(DBusSignalFlags, GDBusSignalFlags, NO_GTYPE)
 
 class DBusAuthObserver;
+class DBusInterfaceInfo;
+class DBusInterfaceVTable;
+class DBusMethodInvocation;
 
 /// @defgroup DBus D-Bus Access Functionality
 
@@ -830,6 +834,149 @@ public:
   _IGNORE(g_dbus_connection_add_filter)
 
   _WRAP_METHOD(void remove_filter(guint filter_id), g_dbus_connection_remove_filter)
+
+  /** TODO.
+   */
+  guint register_object(const Glib::ustring& object_path,
+    const Glib::RefPtr<DBusInterfaceInfo>& interface_info,
+    const DBusInterfaceVTable& vtable);
+
+  _WRAP_METHOD(bool unregister_object(guint registration_id), g_dbus_connection_unregister_object)
+};
+
+/** DBusInterfaceVTable - A class used to represent a virtual table for
+ * handling properties and method calls for a D-Bus interface.
+ *
+ * If you want to handle getting/setting D-Bus properties asynchronously,
+ * simply register an object with the org.freedesktop.DBus.Properties D-Bus
+ * interface using Gio::DBusConnection::register_object().
+ *
+ * Only one DBusInterfaceVTable instance may be used per registration.
+ * @newin{2,28}
+ * @ingroup DBus
+ */
+class DBusInterfaceVTable
+{
+  _CLASS_GENERIC(DBusInterfaceVTable, GDBusInterfaceVTable)
+
+public:
+  /** The type for a slot which handles a method call for a D-Bus interface.
+   * for example,
+   * @code
+   * void on_interface_method_call(const Glib::RefPtr<Gio::DBusConnection>&
+   * connection, const Glib::ustring& sender, const Glib::ustring&
+   * object_path, const Glib::ustring& interface_name, const Glib::ustring&
+   * method_name, const Glib::VariantBase& parameters, const
+   * Glib::RefPtr<Gio::DBusInvocation>& invocation);
+   * @encode
+   */
+  typedef sigc::slot<
+    void,
+    const Glib::RefPtr<DBusConnection>&,
+    const Glib::ustring&,
+    const Glib::ustring&,
+    const Glib::ustring&,
+    const Glib::ustring&,
+    const Glib::VariantBase&,
+    const Glib::RefPtr<DBusMethodInvocation>&
+  > SlotInterfaceMethodCall;
+
+  /** The type for a slot which handles getting a property for a D-Bus
+   * interface.
+   * for example,
+   * @code
+   * void on_interface_get_property(Glib::VariantBase& property, const
+   * Glib::RefPtr<Gio::DBusConnection>& connection, const Glib::ustring&
+   * sender, const Glib::ustring& object_path, const Glib::ustring&
+   * interface_name, const Glib::ustring& property_name);
+   * @endcode
+   * @throw Glib::Error.
+   */
+  typedef sigc::slot<
+    void,
+    Glib::VariantBase&,
+    const Glib::RefPtr<DBusConnection>&,
+    const Glib::ustring&,
+    const Glib::ustring&,
+    const Glib::ustring&,
+    const Glib::ustring&
+  > SlotInterfaceGetProperty;
+
+  /** The type for a slot which handles setting a property for a D-Bus
+   * interface.
+   * for example,
+   * @code
+   * bool on_interface_set_property(const Glib::RefPtr<Gio::DBusConnection>&
+   * connection, const Glib::ustring& sender, const Glib::ustring&
+   * object_path, const Glib::ustring& interface_name, const Glib::ustring&
+   * property_name, const Glib::VariantBase& value);
+   * @endcode
+   * @throw Glib::Error.
+   */
+  typedef sigc::slot<
+    bool,
+    const Glib::RefPtr<DBusConnection>&,
+    const Glib::ustring&,
+    const Glib::ustring&,
+    const Glib::ustring&,
+    const Glib::ustring&,
+    const Glib::VariantBase&
+  > SlotInterfaceSetProperty;
+
+  /** Constructs a new DBusInterfaceVTable using specified slots.
+   * @param slot_method_call The slot for handling incoming method calls.
+   * @param slot_get_property The slot for getting a property.
+   * @param slot_set_property The slot for setting a property.
+   */
+  DBusInterfaceVTable(
+   const SlotInterfaceMethodCall& slot_method_call,
+   const SlotInterfaceGetProperty& slot_get_property,
+   const SlotInterfaceSetProperty& slot_set_property
+  );
+
+  /// Destructor.
+  virtual ~DBusInterfaceVTable();
+
+  /// Provides access to the underlying C object.
+  GDBusInterfaceVTable* gobj()
+    { return reinterpret_cast<GDBusInterfaceVTable*>(&gobject_); }
+
+  /// Provides access to the underlying C object.
+  const GDBusInterfaceVTable* gobj() const
+    { return reinterpret_cast<const GDBusInterfaceVTable*>(&gobject_); }
+
+
+private:
+  // Non-copyable.
+  DBusInterfaceVTable(const DBusInterfaceVTable& other);
+  DBusInterfaceVTable& operator=(const DBusInterfaceVTable& other);
+
+  friend class DBusConnection;
+
+protected:
+  // The underlying C instance.
+  GDBusInterfaceVTable          gobject_;
+
+  // Pointers to copies of the slots used to create an instance.
+  SlotInterfaceMethodCall*      slot_method_call;
+  SlotInterfaceGetProperty*     slot_get_property;
+  SlotInterfaceSetProperty*     slot_set_property;
+
+  // Boolean to signal whether the copies of the slots have been registered or
+  // not so the destructor can free them if they have not been registered.
+  bool slots_registered;
+
+protected:
+  // These are so the Gio::DBusConnection::register_object() method can have
+  // access to the copies of the slots used for creation when registering.
+  SlotInterfaceMethodCall*      get_slot_method_call() const;
+  SlotInterfaceGetProperty*     get_slot_get_property() const;
+  SlotInterfaceSetProperty*     get_slot_set_property() const;
+
+  // This method is used to signal that the copies of the slots have been
+  // registered thus not needing to be freed when a created instance of this
+  // class is destroyed.
+  void signal_slots_registered();
 };
 
 } // namespace Gio



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