Logo Search packages:      
Sourcecode: galago-daemon version File versions  Download package

presence.c

Go to the documentation of this file.
/**
 * @file presence.c Galago Presence message processor
 *
 * Copyright (C) 2004-2006 Christian Hammond.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public
 * License along with this program; if not, write to the Free
 * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA  02111-1307  USA
 */
#include "filter.h"
#include "meta-presence.h"
#include "utils.h"

static char *
galagod_status_generate_path(GalagoPresence *presence, GalagoStatus *status)
{
      return g_strdup_printf("%s/%s",
            galago_object_get_dbus_path(GALAGO_OBJECT(presence)),
            galago_status_get_id(status));
}

static void
_galagod_dbus_presence_emit_status_added(GalagoPresence *presence,
                                                             GalagoStatus *status)
{
      DBusMessage *message;
      DBusMessageIter iter;

      g_return_if_fail(presence != NULL);
      g_return_if_fail(status   != NULL);

      message = dbus_message_new_signal(
            galago_object_get_dbus_path(GALAGO_OBJECT(presence)),
            GALAGO_DBUS_PRESENCE_INTERFACE,
            "StatusAdded");

      dbus_message_iter_init_append(message, &iter);
      galago_dbus_message_iter_append_object(&iter, GALAGO_OBJECT(status));

      dbus_connection_send(galago_get_dbus_conn(), message, NULL);
      dbus_message_unref(message);
}

static void
_galagod_dbus_presence_emit_status_removed(GalagoPresence *presence,
                                                               const char *status_id)
{
      DBusMessage *message;
      DBusMessageIter iter;

      g_return_if_fail(presence  != NULL);
      g_return_if_fail(status_id != NULL && *status_id != '\0');

      message = dbus_message_new_signal(
            galago_object_get_dbus_path(GALAGO_OBJECT(presence)),
            GALAGO_DBUS_PRESENCE_INTERFACE,
            "StatusRemoved");

      dbus_message_iter_init_append(message, &iter);
      dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &status_id);

      dbus_connection_send(galago_get_dbus_conn(), message, NULL);
      dbus_message_unref(message);
}

static DBusHandlerResult
presence_add_status(DBusConnection *dbus_conn, DBusMessage *message,
                              GalagodCoCo *coco, GalagoPresence *presence)
{
      GalagoStatus *status;
      GalagodMetaPresence *meta_presence = GALAGOD_META_PRESENCE(presence);
      GalagoPresence *main_presence;
      DBusMessageIter iter;
      DBusMessage *reply;
      const GList* l;
      const char *status_id;
      int status_weight = 0;
      char *obj_path;

      dbus_message_iter_init(message, &iter);
      status = galago_dbus_message_iter_get_object(&iter, GALAGO_TYPE_STATUS);

      /* Pull out the status ID and object path, and set it back on the status */
      status_id = galago_status_get_id(status);
      obj_path = galagod_status_generate_path(presence, status);
      galago_object_set_dbus_path(GALAGO_OBJECT(status), obj_path);

      /* Send the reply containing the object path. */
      reply = dbus_message_new_method_return(message);
      dbus_message_iter_init_append(reply, &iter);
      dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &obj_path);
      dbus_connection_send(dbus_conn, reply, NULL);
      dbus_message_unref(reply);
      g_free(obj_path);

      if (!galago_presence_has_status(presence, status_id))
      {
            GalagoStatus *dup_status = galago_status_duplicate(status);

            obj_path = galagod_status_generate_path(presence, dup_status);
            galago_object_set_dbus_path(GALAGO_OBJECT(dup_status), obj_path);
            g_free(obj_path);
            galago_presence_add_status(presence, dup_status);
      }

      for (l = galagod_meta_presence_get_presences(meta_presence);
             l != NULL;
             l = l->next)
      {
            GalagoPresence *temp_presence = (GalagoPresence *)l->data;

            if (galago_presence_has_status(temp_presence, status_id))
                  status_weight++;
            else
                  status_weight--;
      }

      main_presence = galagod_meta_presence_get_presence(meta_presence);

      if (status_weight > 0 &&
            !galago_presence_has_status(main_presence, status_id))
      {
            GalagoStatus *dup_status;

            galago_context_push(galagod_get_context());
            dup_status = galago_status_duplicate(status);
            obj_path = galagod_status_generate_path(main_presence, dup_status);
            galago_object_set_dbus_path(GALAGO_OBJECT(dup_status), obj_path);
            g_free(obj_path);
            galago_presence_add_status(main_presence, dup_status);
            galago_context_pop();

            _galagod_dbus_presence_emit_status_added(main_presence, status);
      }

      g_object_unref(status);

      return DBUS_HANDLER_RESULT_HANDLED;
}

static DBusHandlerResult
presence_remove_status(DBusConnection *dbus_conn, DBusMessage *message,
                                 GalagodCoCo *coco, GalagoPresence *presence)
{
      const char *status_id;
      GalagodMetaPresence *meta_presence;
      GalagoPresence *main_presence;
      DBusMessageIter iter;

      meta_presence = GALAGOD_META_PRESENCE(presence);

      dbus_message_iter_init(message, &iter);
      dbus_message_iter_get_basic(&iter, &status_id);

      galago_presence_remove_status(presence, status_id);

      main_presence = galagod_meta_presence_get_presence(meta_presence);

      if (galago_presence_has_status(main_presence, status_id))
      {
            galago_presence_remove_status(main_presence, status_id);

            _galagod_dbus_presence_emit_status_removed(main_presence, status_id);
      }

      galagod_dbus_send_empty_reply(dbus_conn, message);

      return DBUS_HANDLER_RESULT_HANDLED;
}

static DBusHandlerResult
presence_set_statuses(DBusConnection *dbus_conn, DBusMessage *message,
                                GalagodCoCo *coco, GalagoPresence *presence)
{
      GalagodMetaPresence *meta_presence;
      GList *list, *list2 = NULL, *l;
      DBusMessageIter iter;

      meta_presence = GALAGOD_META_PRESENCE(presence);

      dbus_message_iter_init(message, &iter);
      list = galago_dbus_message_iter_get_object_list(&iter,
                                                                              GALAGO_TYPE_STATUS);

      galago_presence_set_statuses(presence, list);

      galago_context_push(galagod_get_context());

      for (l = list; l != NULL; l = l->next)
      {
            list2 = g_list_append(list2,
                  galago_status_duplicate((GalagoStatus *)l->data));
      }

      galago_presence_set_statuses(
            galagod_meta_presence_get_presence(meta_presence), list2);

      galago_context_pop();

      galagod_dbus_send_empty_reply(dbus_conn, message);

      return DBUS_HANDLER_RESULT_HANDLED;
}

static DBusHandlerResult
presence_set_idle(DBusConnection *dbus_conn, DBusMessage *message,
                          GalagodCoCo *coco, GalagoPresence *presence)
{
      GalagodMetaPresence *meta_presence;
      GalagoPresence *main_presence;
      DBusMessageIter iter;
      gboolean idle;
      dbus_uint32_t idle_start_time;

      meta_presence = GALAGOD_META_PRESENCE(presence);

      dbus_message_iter_init(message, &iter);
      dbus_message_iter_get_basic(&iter, &idle);
      dbus_message_iter_next(&iter);
      dbus_message_iter_get_basic(&iter, &idle_start_time);

      main_presence = galagod_meta_presence_get_presence(meta_presence);

      galago_presence_set_idle(presence,      idle, idle_start_time);
      galago_presence_set_idle(main_presence, idle, idle_start_time);

      galagod_dbus_send_empty_reply(dbus_conn, message);

      return DBUS_HANDLER_RESULT_HANDLED;
}

static const GalagodCommand commands[] =
{
      GALAGOD_COMMAND("AddStatus",    presence_add_status),
      GALAGOD_COMMAND("RemoveStatus", presence_remove_status),
      GALAGOD_COMMAND("SetStatuses",  presence_set_statuses),
      GALAGOD_COMMAND("SetIdle",      presence_set_idle),
      GALAGOD_COMMAND_LAST
};

char *
galagod_presence_generate_path(GalagoPresence *presence)
{
      return g_strdup_printf("%s/presence",
            galago_object_get_dbus_path(
                  GALAGO_OBJECT(galago_presence_get_account(presence))));
}

void
galagod_presence_add_filter(GalagoPresence *presence)
{
      galagod_filters_add(presence, commands, GALAGO_DBUS_PRESENCE_INTERFACE);
}

void
galagod_presence_remove_filter(GalagoPresence *presence)
{
      galagod_filters_remove(presence);
}

Generated by  Doxygen 1.6.0   Back to index