glib_mc5_observer/example-observer.c

Source File

#include <telepathy-glib/interfaces.h>
#include <telepathy-glib/gtypes.h>
#include <telepathy-glib/svc-generic.h>
#include <telepathy-glib/svc-client.h>

#include "example-observer.h"

static void client_iface_init (gpointer, gpointer);
static void observer_iface_init (gpointer, gpointer);

// #define EXAMPLE_OBSERVER_GET_PRIVATE(obj)	(G_TYPE_INSTANCE_GET_PRIVATE ((obj), EXAMPLE_TYPE_OBSERVER, ExampleObserverPrivate))

/* Begin Example 12-1 */
G_DEFINE_TYPE_WITH_CODE (ExampleObserver, example_observer, G_TYPE_OBJECT,
    G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_DBUS_PROPERTIES,
      tp_dbus_properties_mixin_iface_init);
    G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CLIENT, NULL);
    G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CLIENT_OBSERVER, observer_iface_init);
    );
/* End Example 12-1 */

static const char *client_interfaces[] = {
    TP_IFACE_CLIENT_OBSERVER,
    NULL
};

enum
{
  PROP_0,
  PROP_INTERFACES,
  PROP_CHANNEL_FILTER
};

// typedef struct _ExampleObserverPrivate ExampleObserverPrivate;
// struct _ExampleObserverPrivate
// {
// };

/* Begin Example 12-4 */
static void
example_observer_observe_channels (TpSvcClientObserver   *self,
                                   const char            *account,
                                   const char            *connection,
                                   const GPtrArray       *channels,
                                   const char            *dispatch_op,
                                   const GPtrArray       *requests_satisfied,
                                   GHashTable            *observer_info,
                                   DBusGMethodInvocation *context)
{
  g_print (" > example_observer_observe_channels\n");
  g_print ("     account    = %s\n", account);
  g_print ("     connection = %s\n", connection);
  g_print ("     dispatchop = %s\n", dispatch_op);

  /* channels is of type a(oa{sv}) */
  int i;
  for (i = 0; i < channels->len; i++)
    {
      GValueArray *channel = g_ptr_array_index (channels, i);
      char *path;
      GHashTable *map;

      tp_value_array_unpack (channel, 2,
          &path, &map);

      g_print ("     channel    = %s\n", path);
    }

  tp_svc_client_observer_return_from_observe_channels (context);
}
/* End Example 12-4 */

static void
example_observer_get_property (GObject    *self,
                               guint       property_id,
                               GValue     *value,
                               GParamSpec *pspec)
{
  switch (property_id)
    {
      case PROP_INTERFACES:
        g_print (" :: interfaces\n");
        g_value_set_boxed (value, client_interfaces);
        break;

      case PROP_CHANNEL_FILTER:
        g_print (" :: channel-filter\n");

        /* create an empty filter - which means all channels */
        GPtrArray *array = g_ptr_array_new ();
        GHashTable *map = g_hash_table_new (NULL, NULL);

        g_ptr_array_add (array, map);
        g_value_set_boxed (value, array);
        break;

      default:
        G_OBJECT_WARN_INVALID_PROPERTY_ID (self, property_id, pspec);
        break;
    }
}

static void
example_observer_class_init (ExampleObserverClass *klass)
{
  GObjectClass *object_class = G_OBJECT_CLASS (klass);

  object_class->get_property = example_observer_get_property;

  /* Begin Example 12-6 */
  /* D-Bus properties are exposed as GObject properties through the
   * TpDBusPropertiesMixin */
  /* properties on the Client interface */
  static TpDBusPropertiesMixinPropImpl client_props[] = {
        { "Interfaces", "interfaces", NULL },
        { NULL }
  };

  /* properties on the Client.Observer interface */
  static TpDBusPropertiesMixinPropImpl client_observer_props[] = {
        { "ObserverChannelFilter", "channel-filter", NULL },
        { NULL }
  };

  /* complete list of interfaces with properties */
  static TpDBusPropertiesMixinIfaceImpl prop_interfaces[] = {
        { TP_IFACE_CLIENT,
          tp_dbus_properties_mixin_getter_gobject_properties,
          NULL,
          client_props
        },
        { TP_IFACE_CLIENT_OBSERVER,
          tp_dbus_properties_mixin_getter_gobject_properties,
          NULL,
          client_observer_props
        },
        { NULL }
  };
  /* End Example 12-6 */

  g_object_class_install_property (object_class, PROP_INTERFACES,
      g_param_spec_boxed ("interfaces",
                          "Interfaces",
                          "Available D-Bus Interfaces",
                          G_TYPE_STRV,
                          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (object_class, PROP_CHANNEL_FILTER,
      g_param_spec_boxed ("channel-filter",
                          "Channel Filter",
                          "Filter for channels we observe",
                          TP_ARRAY_TYPE_CHANNEL_CLASS_LIST,
                          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));

  /* Begin Example 12-7 */
  /* call our mixin class init */
  klass->dbus_props_class.interfaces = prop_interfaces;
  tp_dbus_properties_mixin_class_init (object_class,
      G_STRUCT_OFFSET (ExampleObserverClass, dbus_props_class));
  /* End Example 12-7 */
}

static void
example_observer_init (ExampleObserver *self)
{
}

/* Begin Example 12-3 */
static void
observer_iface_init (gpointer g_iface, gpointer iface_data)
{
  TpSvcClientObserverClass *klass = (TpSvcClientObserverClass *) g_iface;

#define IMPLEMENT(x) tp_svc_client_observer_implement_##x (klass, \
    example_observer_##x)
  IMPLEMENT (observe_channels);
#undef IMPLEMENT
}
/* End Example 12-3 */

ExampleObserver *
example_observer_new (void)
{
  return g_object_new (TYPE_EXAMPLE_OBSERVER, NULL);
}