diff options
author | José Alburquerque <jaalburqu@svn.gnome.org> | 2010-12-23 15:34:32 -0500 |
---|---|---|
committer | José Alburquerque <jaalburqu@svn.gnome.org> | 2010-12-23 15:34:32 -0500 |
commit | 739b2e5f7e8b334282e010e9df4527103e0d303a (patch) | |
tree | 3d1e51fa361d5c7967296707cc64c2c633462213 /gio/src/dbusconnection.ccg | |
parent | d1474424acaa3364442e1fb31254a6da338a3645 (diff) | |
download | glibmm-739b2e5f7e8b334282e010e9df4527103e0d303a.tar.gz |
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)
Diffstat (limited to 'gio/src/dbusconnection.ccg')
-rw-r--r-- | gio/src/dbusconnection.ccg | 182 |
1 files changed, 178 insertions, 4 deletions
diff --git a/gio/src/dbusconnection.ccg b/gio/src/dbusconnection.ccg index ca94e3f5..a415ad5d 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 |