glib_mc5_observer/example2.c

Source File

#include <telepathy-glib/telepathy-glib.h>


static guint
increment_pending (gpointer proxy)
{
  guint pending;

  pending = GPOINTER_TO_UINT (g_object_get_data (proxy, "pending"));
  pending++;
  g_object_set_data (proxy, "pending", GUINT_TO_POINTER (pending));

  g_debug ("%u calls pending", pending);

  return pending;
}


static guint
decrement_pending (gpointer proxy)
{
  guint pending;

  pending = GPOINTER_TO_UINT (g_object_get_data (proxy, "pending"));
  pending--;
  g_object_set_data (proxy, "pending", GUINT_TO_POINTER (pending));

  g_debug ("%u calls pending", pending);

  return pending;
}


static void
respond_to_context (TpObserveChannelsContext *context)
{
  if (decrement_pending (context) == 0)
    {
      g_debug ("ObserveChannels complete");

      tp_observe_channels_context_accept (context);

      g_object_unref (context);
    }
}


static void
list_pending_messaged_cb (TpChannel *channel,
    const GPtrArray *pending,
    const GError *in_error,
    gpointer user_data,
    GObject *context)
{
  respond_to_context (TP_OBSERVE_CHANNELS_CONTEXT (context));

  if (in_error != NULL)
    {
      g_warning ("%s", in_error->message);
      return;
    }
}


static void
channel_group_prepared (GObject *channel,
    GAsyncResult *res,
    gpointer user_data)
{
  TpObserveChannelsContext *context = user_data;
  GError *error = NULL;

  respond_to_context (context);

  if (!tp_proxy_prepare_finish (channel, res, &error))
    {
      g_warning ("%s", error->message);
      g_error_free (error);
      return;
    }
}


static void
channel_invalided (TpProxy *channel,
    guint domain,
    guint code,
    const char *message,
    gpointer user_data)
{
  /* release our reference to this channel proxy */
  g_object_unref (channel);
}


/* Begin Example 4-3 */
static void
observe_channels (TpSimpleObserver *observer,
    TpAccount *account,
    TpConnection *connection,
    GList *channels,
    TpChannelDispatchOperation *dispatch,
    GList *requests,
    TpObserveChannelsContext *context,
    gpointer user_data)
{
  GList *l;

  g_debug ("ObserveChannels");

  for (l = channels; l != NULL; l = l->next)
    {
      TpChannel *channel = l->data;
      TpHandleType handle_type;

      /* request the pending message queue */
      tp_cli_channel_type_text_call_list_pending_messages (channel, -1,
          FALSE,
          list_pending_messaged_cb, NULL, NULL, G_OBJECT (context));
      increment_pending (context);

      tp_channel_get_handle (channel, &handle_type);
      if (handle_type == TP_HANDLE_TYPE_ROOM)
        {
          /* prepare the group property */
          GQuark features[] = { TP_CHANNEL_FEATURE_GROUP, 0 };

          tp_proxy_prepare_async (channel, features, channel_group_prepared,
              context);
          increment_pending (context);
        }

      /* hold a reference to the channel, that we release on invalidation */
      g_object_ref (channel);
      g_signal_connect (channel, "invalidated",
          G_CALLBACK (channel_invalided), NULL);
    }

  /* hold a reference to @context */
  g_object_ref (context);
  /* delay responding to @context until our callbacks have finished */
  tp_observe_channels_context_delay (context);
}
/* End Example 4-3 */


int
main (int argc,
    const char **argv)
{
  TpDBusDaemon *dbus;
  TpBaseClient *observer;
  GMainLoop *loop;
  GError *error = NULL;

  g_type_init ();

  dbus = tp_dbus_daemon_dup (&error);
  if (dbus == NULL)
    g_error ("%s", error->message);

  observer = tp_simple_observer_new (dbus, TRUE, "ExampleObserver", TRUE,
      observe_channels, NULL, NULL);

  /* Observe both 1-to-1 text channels and MUCs */
  tp_base_client_take_observer_filter (observer, tp_asv_new (
        TP_PROP_CHANNEL_CHANNEL_TYPE,
        G_TYPE_STRING,
        TP_IFACE_CHANNEL_TYPE_TEXT,

        TP_PROP_CHANNEL_TARGET_HANDLE_TYPE,
        G_TYPE_UINT,
        TP_HANDLE_TYPE_CONTACT,

        NULL));

  tp_base_client_take_observer_filter (observer, tp_asv_new (
        TP_PROP_CHANNEL_CHANNEL_TYPE,
        G_TYPE_STRING,
        TP_IFACE_CHANNEL_TYPE_TEXT,

        TP_PROP_CHANNEL_TARGET_HANDLE_TYPE,
        G_TYPE_UINT,
        TP_HANDLE_TYPE_ROOM,

        NULL));

  if (!tp_base_client_register (observer, &error))
    g_error ("%s", error->message);

  loop = g_main_loop_new (NULL, FALSE);

  g_main_loop_run (loop);

  g_main_loop_unref (loop);
  g_object_unref (observer);
  g_object_unref (dbus);
}