[glibmm] DBusConnection: Add signal_subscribe() and add_filter().
- From: José Alburquerque <jaalburqu src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glibmm] DBusConnection: Add signal_subscribe() and add_filter().
- Date: Mon, 6 Dec 2010 02:59:25 +0000 (UTC)
commit 62dc94ca3c604a9e70e32498ccd392291a657960
Author: José Alburquerque <jaalburqu svn gnome org>
Date: Sun Dec 5 20:46:06 2010 -0500
DBusConnection: Add signal_subscribe() and add_filter().
* gio/src/dbusconnection.{ccg,hg}: Add signal_subscribe(),
signal_unsubscribe(), add_filter() and remove_filter() methods.
Wrapped GDBusSignalFlags (reordered enums in alphabetical order).
([get|set]_exit_on_close):
(get_capabilities): Reordered declarations (by moving the _WRAP_METHOD
macros) according to where they are declared in the C API.
ChangeLog | 11 ++++
gio/src/dbusconnection.ccg | 85 +++++++++++++++++++++++++++++++++
gio/src/dbusconnection.hg | 113 ++++++++++++++++++++++++++++++++++++++++++--
3 files changed, 204 insertions(+), 5 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 45ab535..0d5add9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2010-12-05 José Alburquerque <jaalburqu svn gnome org>
+
+ DBusConnection: Add signal_subscribe() and add_filter().
+
+ * gio/src/dbusconnection.{ccg,hg}: Add signal_subscribe(),
+ signal_unsubscribe(), add_filter() and remove_filter() methods.
+ Wrapped GDBusSignalFlags (reordered enums in alphabetical order).
+ ([get|set]_exit_on_close):
+ (get_capabilities): Reordered declarations (by moving the _WRAP_METHOD
+ macros) according to where they are declared in the C API.
+
2.27.4:
2010-11-30 José Alburquerque <jaalburqu svn gnome org>
diff --git a/gio/src/dbusconnection.ccg b/gio/src/dbusconnection.ccg
index 28fb2a0..7687d41 100644
--- a/gio/src/dbusconnection.ccg
+++ b/gio/src/dbusconnection.ccg
@@ -21,6 +21,63 @@
#include <giomm/dbusauthobserver.h>
#include "slot_async.h"
+namespace
+{
+
+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)
+{
+ Gio::DBusConnection::SlotSignal* the_slot =
+ static_cast<Gio::DBusConnection::SlotSignal*>(user_data);
+
+ try
+ {
+ (*the_slot)(Glib::wrap(connection, true), Glib::ustring(sender_name),
+ Glib::ustring(object_path), Glib::ustring(interface_name),
+ Glib::ustring(signal_name), Glib::VariantBase(parameters, true));
+ }
+ catch(...)
+ {
+ Glib::exception_handlers_invoke();
+ }
+}
+
+static void DBusConnection_Signal_giomm_callback_destroy(void* data)
+{
+ delete static_cast<Gio::DBusConnection::SlotSignal*>(data);
+}
+
+static GDBusMessage* DBusConnection_Message_Filter_giomm_callback(GDBusConnection* connection, GDBusMessage* message, gboolean incoming, gpointer user_data)
+{
+ Gio::DBusConnection::SlotMessageFilter* the_slot =
+ static_cast<Gio::DBusConnection::SlotMessageFilter*>(user_data);
+
+ try
+ {
+ Glib::RefPtr<Gio::DBusMessage> result = (*the_slot)(
+ Glib::wrap(connection, true), Glib::wrap(message, true),
+ static_cast<bool>(incoming));
+ return (result) ? result->gobj_copy() : 0;
+ }
+ catch(...)
+ {
+ Glib::exception_handlers_invoke();
+ }
+
+ return message;
+}
+
+static void DBusConnection_Message_Filter_giomm_callback_destroy(void* data)
+{
+ delete static_cast<Gio::DBusConnection::SlotMessageFilter*>(data);
+}
+
+} // extern "C"
+
+}
+
namespace Gio
{
@@ -479,4 +536,32 @@ void DBusConnection::emit_singal(
::Glib::Error::throw_exception(gerror);
}
+guint DBusConnection::signal_subscribe(
+ const SlotSignal& slot,
+ const Glib::ustring& sender,
+ const Glib::ustring& interface_name,
+ const Glib::ustring& member,
+ const Glib::ustring& object_path,
+ const Glib::ustring& arg0,
+ DBusSignalFlags flags
+)
+{
+ SlotSignal* slot_copy = new SlotSignal(slot);
+
+ return g_dbus_connection_signal_subscribe(gobj(), sender.c_str(),
+ interface_name.c_str(), member.c_str(), object_path.c_str(), arg0.c_str(),
+ static_cast<GDBusSignalFlags>(flags),
+ &DBusConnection_Signal_giomm_callback, slot_copy,
+ &DBusConnection_Signal_giomm_callback_destroy);
+}
+
+guint DBusConnection::add_filter(const SlotMessageFilter& slot)
+{
+ SlotMessageFilter* slot_copy = new SlotMessageFilter(slot);
+
+ return g_dbus_connection_add_filter(gobj(),
+ &DBusConnection_Message_Filter_giomm_callback, slot_copy,
+ DBusConnection_Message_Filter_giomm_callback_destroy);
+}
+
} // namespace Gio
diff --git a/gio/src/dbusconnection.hg b/gio/src/dbusconnection.hg
index 321de49..22ba833 100644
--- a/gio/src/dbusconnection.hg
+++ b/gio/src/dbusconnection.hg
@@ -33,9 +33,10 @@ namespace Gio
{
_WRAP_ENUM(BusType, GBusType)
+_WRAP_ENUM(DBusCallFlags, GDBusCallFlags, NO_GTYPE)
_WRAP_ENUM(DBusConnectionFlags, GDBusConnectionFlags, NO_GTYPE)
_WRAP_ENUM(DBusSendMessageFlags, GDBusSendMessageFlags, NO_GTYPE)
-_WRAP_ENUM(DBusCallFlags, GDBusCallFlags, NO_GTYPE)
+_WRAP_ENUM(DBusSignalFlags, GDBusSignalFlags, NO_GTYPE)
class DBusAuthObserver;
@@ -108,6 +109,37 @@ protected:
public:
+ /** Signature for slot used in signal_subscribe().
+ * For example,
+ * @code
+ * void on_signal(const Glib::RefPtr<DBusConnection>&, const
+ * Glib::ustring& sender_name, const Glib::ustring& object_path, const
+ * Glib::ustring& object_path, const Glib::ustring& interface_name, const
+ * Glib::ustring& signal_name, const Glib::VariantBase& parameters);.
+ * @endcode
+ */
+ typedef sigc::slot<void, const Glib::RefPtr<DBusConnection>&,
+ const Glib::ustring&, const Glib::ustring&, const Glib::ustring&,
+ const Glib::ustring&, const Glib::VariantBase&> SlotSignal;
+
+ /** Signature for slot used in add_filter().
+ * For example,
+ * @code
+ * Glib::RefPtr<DBusMessage> on_message_filter(const
+ * Glib::RefPtr<DBusConnection>, const Glib::RefPtr<DBusMessage>& bool
+ * incoming);.
+ * @endcode
+ *
+ * A filter function is passed a DBusMessage and expected to return a
+ * DBusMessage too. Passive filter functions that don't modify the message
+ * can simply return the message object. Filter functions that wants to
+ * drop a message can simply return <tt>0</tt>. And filter function may
+ * modify a message by copying it and return the copy.
+ */
+ typedef sigc::slot<Glib::RefPtr<DBusMessage>,
+ const Glib::RefPtr<DBusConnection>&,
+ const Glib::RefPtr<DBusMessage>&, bool> SlotMessageFilter;
+
/** Asynchronously connects to the message bus specified by @a bus_type.
*
* When the operation is finished, @a slot will be invoked. You can then
@@ -363,6 +395,9 @@ public:
_WRAP_METHOD(void flush_sync(const Glib::RefPtr<Cancellable>& cancellable), g_dbus_connection_flush_sync, errthrow)
+ _WRAP_METHOD(bool get_exit_on_close() const, g_dbus_connection_get_exit_on_close)
+ _WRAP_METHOD(void set_exit_on_close(bool exit_on_close = true), g_dbus_connection_set_exit_on_close)
+
//TODO: In the C API, out_serial is volatile, but gmmproc can't parse that.
#m4 _CONVERSION(`guint32*',`volatile guint32*',`($3)')
_WRAP_METHOD(bool send_message(const Glib::RefPtr<DBusMessage>& message, DBusSendMessageFlags flags, guint32* out_serial), g_dbus_connection_send_message, errthrow)
@@ -421,6 +456,8 @@ public:
_WRAP_METHOD(Glib::ustring get_guid() const, g_dbus_connection_get_guid)
_WRAP_METHOD(Glib::ustring get_unique_name() const, g_dbus_connection_get_unique_name)
+ _WRAP_METHOD(DBusCapabilityFlags get_capabilities() const, g_dbus_connection_get_capabilities)
+
_WRAP_METHOD(Glib::RefPtr<Credentials> get_peer_credentials(), g_dbus_connection_get_peer_credentials, refreturn)
_WRAP_METHOD(Glib::RefPtr<const Credentials> get_peer_credentials() const, g_dbus_connection_get_peer_credentials, refreturn, constversion)
@@ -584,10 +621,76 @@ public:
const Glib::VariantBase& parameters = Glib::VariantBase()
);
- _WRAP_METHOD(bool get_exit_on_close() const, g_dbus_connection_get_exit_on_close)
- _WRAP_METHOD(void set_exit_on_close(bool exit_on_close = true), g_dbus_connection_set_exit_on_close)
- _WRAP_METHOD(DBusCapabilityFlags get_capabilities() const, g_dbus_connection_get_capabilities)
-};
+ /** Subscribes to signals on the connection and invokes @a slot with a
+ * whenever the signal is received. Note that @a slot will be invoked in the
+ * thread-default main loop of the thread you are calling this method from.
+ *
+ * If the connection is not a message bus connection, @a sender must be
+ * <tt>0</tt>.
+ *
+ * If @a sender is a well-known name note that @a slot is invoked with the
+ * unique name for the owner of @a sender, not the well-known name as one
+ * would expect. This is because the message bus rewrites the name. As such,
+ * to avoid certain race conditions, users should be tracking the name owner
+ * of the well-known name and use that when processing the received signal.
+ *
+ * @param slot Slot to invoke when there is a signal matching the requested
+ * data.
+ * @param sender Sender name to match on (unique or well-known name) or
+ * <tt>0</tt> to listen from all senders.
+ * @param interface_name D-Bus interface name to match on or <tt>0</tt> to
+ * match on all interfaces.
+ * @param member D-Bus signal name to match on or <tt>0</tt> to match on all
+ * signals.
+ * @param object_path Object path to match on or <tt>0</tt> to match on all
+ * object paths.
+ * @param arg0 Contents of first string argument to match on or <tt>0</tt>
+ * to match on all kinds of arguments.
+ * @param flags Flags describing how to subscribe to the signal (currently
+ * unused).
+ * @return A subscription identifier that can be used with
+ * signal_unsubscribe().
+ * @newin{2,28}
+ */
+ guint signal_subscribe(
+ const SlotSignal& slot,
+ const Glib::ustring& sender = Glib::ustring(),
+ const Glib::ustring& interface_name = Glib::ustring(),
+ const Glib::ustring& member = Glib::ustring(),
+ const Glib::ustring& object_path = Glib::ustring(),
+ const Glib::ustring& arg0 = Glib::ustring(),
+ DBusSignalFlags flags = Gio::DBUS_SIGNAL_FLAGS_NONE
+ );
+ _IGNORE(g_dbus_connection_signal_subscribe)
+
+ _WRAP_METHOD(void signal_unsubscribe(guint subscription_id), g_dbus_connection_signal_unsubscribe)
+
+ /** Adds a message filter. Filters are handlers that are run on all incoming
+ * and outgoing messages, prior to standard dispatch. Filters are run in the
+ * order that they were added. The same handler can be added as a filter
+ * more than once, in which case it will be run more than once. Filters
+ * added during a filter slot won't be run on the message being processed.
+ * Filter slots are allowed to modify and even drop messages.
+ *
+ * Note that filters are run in a dedicated message handling thread so they
+ * can't block and, generally, can't do anything but signal a worker thread.
+ * Also note that filters are rarely needed - use API such as
+ * send_message_with_reply(), signal_subscribe() or call() instead.
+ *
+ * If a filter consumes an incoming message the message is not dispatched
+ * anywhere else - not even the standard dispatch machinery (that API such
+ * as signal_subscribe() and send_message_with_reply() relies on) will see
+ * the message. Similary, if a filter consumes an outgoing message, the
+ * message will not be sent to the other peer.
+ *
+ * @param slot A filter slot.
+ * @return A filter identifier that can be used with remove_filter().
+ * @newin{2,28}
+ */
+ guint add_filter(const SlotMessageFilter& slot);
+ _IGNORE(g_dbus_connection_add_filter)
+ _WRAP_METHOD(void remove_filter(guint filter_id), g_dbus_connection_remove_filter)
+};
} // namespace Gio
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]