diff options
Diffstat (limited to 'libindicate/server.c')
-rw-r--r-- | libindicate/server.c | 445 |
1 files changed, 416 insertions, 29 deletions
diff --git a/libindicate/server.c b/libindicate/server.c index 39753d2..9e33516 100644 --- a/libindicate/server.c +++ b/libindicate/server.c @@ -28,7 +28,9 @@ License version 3 and version 2.1 along with this program. If not, see */ #include "server.h" -#include "dbus-indicate-server.h" +#include "interests-priv.h" +#include <dbus/dbus-glib.h> +#include <dbus/dbus-glib-lowlevel.h> /* Errors */ enum { @@ -42,6 +44,10 @@ enum { NO_GET_INDICATOR_PROPERTIES, NO_SHOW_INDICATOR_TO_USER, INVALID_INDICATOR_ID, + NO_SHOW_INTEREST, + NO_REMOVE_INTEREST, + SHOW_INTEREST_FAILED, + REMOVE_INTEREST_FAILED, LAST_ERROR }; @@ -53,6 +59,8 @@ enum { SERVER_SHOW, SERVER_HIDE, SERVER_DISPLAY, + INTEREST_ADDED, + INTEREST_REMOVED, LAST_SIGNAL }; @@ -70,21 +78,33 @@ typedef struct _IndicateServerPrivate IndicateServerPrivate; struct _IndicateServerPrivate { DBusGConnection *connection; + DBusGProxy * dbus_proxy; + gchar * path; GSList * indicators; gboolean visible; guint current_id; + gboolean registered; gchar * desktop; gchar * type; // TODO: Should have a more robust way to track this, but this'll work for now guint num_hidden; + + gboolean interests[INDICATE_INTEREST_LAST]; + GList * interestedfolks; }; #define INDICATE_SERVER_GET_PRIVATE(o) \ (G_TYPE_INSTANCE_GET_PRIVATE ((o), INDICATE_TYPE_SERVER, IndicateServerPrivate)) +typedef struct _IndicateServerInterestedFolk IndicateServerInterestedFolk; +struct _IndicateServerInterestedFolk { + gchar * sender; + gboolean interests[INDICATE_INTEREST_LAST]; +}; + /* Define Type */ G_DEFINE_TYPE (IndicateServer, indicate_server, G_TYPE_OBJECT); @@ -94,14 +114,40 @@ static void indicate_server_finalize (GObject * obj); static gboolean get_indicator_count (IndicateServer * server, guint * count, GError **error); static gboolean get_indicator_count_by_type (IndicateServer * server, gchar * type, guint * count, GError **error); static gboolean get_indicator_list (IndicateServer * server, GArray ** indicators, GError ** error); -static gboolean get_indicator_list_by_type (IndicateServer * server, gchar * type, guint ** indicators, GError ** error); +static gboolean get_indicator_list_by_type (IndicateServer * server, gchar * type, GArray ** indicators, GError ** error); static gboolean get_indicator_property (IndicateServer * server, guint id, gchar * property, gchar ** value, GError **error); static gboolean get_indicator_property_group (IndicateServer * server, guint id, GPtrArray * properties, gchar *** value, GError **error); static gboolean get_indicator_properties (IndicateServer * server, guint id, gchar *** properties, GError **error); static gboolean show_indicator_to_user (IndicateServer * server, guint id, GError ** error); +static void dbus_owner_change (DBusGProxy * proxy, const gchar * name, const gchar * prev, const gchar * new, IndicateServer * server); static guint get_next_id (IndicateServer * server); static void set_property (GObject * obj, guint id, const GValue * value, GParamSpec * pspec); static void get_property (GObject * obj, guint id, GValue * value, GParamSpec * pspec); +static gboolean show_interest (IndicateServer * server, gchar * sender, IndicateInterests interest); +static gboolean remove_interest (IndicateServer * server, gchar * sender, IndicateInterests interest); +static gboolean check_interest (IndicateServer * server, IndicateInterests intrest); +static gint indicate_server_interested_folks_equal (gconstpointer a, gconstpointer b); +static void indicate_server_interested_folks_init (IndicateServerInterestedFolk * folk, gchar * sender); +static void indicate_server_interested_folks_set (IndicateServerInterestedFolk * folk, IndicateInterests interest, gboolean value); +static void indicate_server_interested_folks_copy (IndicateServerInterestedFolk * folk, gboolean * interests); +static void indicate_server_interested_folks_destroy(IndicateServerInterestedFolk * folk); + +/* DBus API */ +gboolean _indicate_server_get_indicator_count (IndicateServer * server, guint * count, GError **error); +gboolean _indicate_server_get_indicator_count_by_type (IndicateServer * server, gchar * type, guint * count, GError **error); +gboolean _indicate_server_get_indicator_list (IndicateServer * server, GArray ** indicators, GError ** error); +gboolean _indicate_server_get_indicator_list_by_type (IndicateServer * server, gchar * type, GArray ** indicators, GError ** error); +gboolean _indicate_server_get_indicator_property (IndicateServer * server, guint id, gchar * property, gchar ** value, GError **error); +gboolean _indicate_server_get_indicator_property_group (IndicateServer * server, guint id, GPtrArray * properties, gchar *** value, GError **error); +gboolean _indicate_server_get_indicator_properties (IndicateServer * server, guint id, gchar *** properties, GError **error); +gboolean _indicate_server_show_indicator_to_user (IndicateServer * server, guint id, GError ** error); +gboolean _indicate_server_show_interest (IndicateServer * server, gchar * interest, DBusGMethodInvocation * method); +gboolean _indicate_server_remove_interest (IndicateServer * server, gchar * interest, DBusGMethodInvocation * method); + +/* Has to be after the dbus prototypes */ +#include "dbus-indicate-server.h" + + /* Code */ static void @@ -159,6 +205,20 @@ indicate_server_class_init (IndicateServerClass * class) NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); + signals[INTEREST_ADDED] = g_signal_new(INDICATE_SERVER_SIGNAL_INTEREST_ADDED, + G_TYPE_FROM_CLASS (class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (IndicateServerClass, interest_added), + NULL, NULL, + g_cclosure_marshal_VOID__UINT, + G_TYPE_NONE, 1, G_TYPE_UINT); + signals[INTEREST_REMOVED] = g_signal_new(INDICATE_SERVER_SIGNAL_INTEREST_REMOVED, + G_TYPE_FROM_CLASS (class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (IndicateServerClass, interest_removed), + NULL, NULL, + g_cclosure_marshal_VOID__UINT, + G_TYPE_NONE, 1, G_TYPE_UINT); g_object_class_install_property (gobj, PROP_DESKTOP, g_param_spec_string("desktop", "Desktop File", @@ -172,7 +232,7 @@ indicate_server_class_init (IndicateServerClass * class) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); dbus_g_object_type_install_info(INDICATE_TYPE_SERVER, - &dbus_glib_indicate_server_object_info); + &dbus_glib__indicate_server_object_info); class->get_indicator_count = get_indicator_count; class->get_indicator_count_by_type = get_indicator_count_by_type; @@ -183,6 +243,9 @@ indicate_server_class_init (IndicateServerClass * class) class->get_indicator_properties = get_indicator_properties; class->show_indicator_to_user = show_indicator_to_user; class->get_next_id = get_next_id; + class->show_interest = show_interest; + class->remove_interest = remove_interest; + class->check_interest = check_interest; return; } @@ -198,10 +261,18 @@ indicate_server_init (IndicateServer * server) priv->indicators = NULL; priv->num_hidden = 0; priv->visible = FALSE; + priv->registered = FALSE; priv->current_id = 0; priv->type = NULL; priv->desktop = NULL; + guint i; + for (i = INDICATE_INTEREST_NONE; i < INDICATE_INTEREST_LAST; i++) { + priv->interests[i] = FALSE; + } + priv->interestedfolks = NULL; + + return; } @@ -302,12 +373,27 @@ indicate_server_show (IndicateServer * server) priv->connection = dbus_g_bus_get(DBUS_BUS_SESSION, NULL); - dbus_g_connection_register_g_object(priv->connection, - priv->path, - G_OBJECT(server)); + if (!priv->registered) { + dbus_g_connection_register_g_object(priv->connection, + priv->path, + G_OBJECT(server)); + priv->registered = TRUE; + } + priv->visible = TRUE; g_signal_emit(server, signals[SERVER_SHOW], 0, priv->type ? priv->type : "", TRUE); + + priv->dbus_proxy = dbus_g_proxy_new_for_name_owner (priv->connection, + DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS, + NULL); + dbus_g_proxy_add_signal(priv->dbus_proxy, "NameOwnerChanged", + G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, + G_TYPE_INVALID); + dbus_g_proxy_connect_signal(priv->dbus_proxy, "NameOwnerChanged", + G_CALLBACK(dbus_owner_change), server, NULL); return; } @@ -323,14 +409,86 @@ indicate_server_hide (IndicateServer * server) priv->visible = FALSE; + /* Delete interested parties */ + g_list_foreach(priv->interestedfolks, (GFunc)indicate_server_interested_folks_destroy, NULL); + g_list_free(priv->interestedfolks); + priv->interestedfolks = NULL; + + /* Signal the lack of interest */ + guint i; + for (i = INDICATE_INTEREST_NONE; i < INDICATE_INTEREST_LAST; i++) { + if (priv->interests[i]) { + g_signal_emit(G_OBJECT(server), signals[INTEREST_REMOVED], 0, i, TRUE); + } + priv->interests[i] = FALSE; + } + g_signal_emit(server, signals[SERVER_HIDE], 0, priv->type ? priv->type : "", TRUE); - dbus_g_connection_unref (priv->connection); - priv->connection = NULL; + if (priv->dbus_proxy != NULL) { + g_object_unref(G_OBJECT(priv->dbus_proxy)); + priv->dbus_proxy = NULL; + } + + if (priv->connection != NULL) { + dbus_g_connection_unref (priv->connection); + priv->connection = NULL; + } return; } +static void +dbus_owner_change (DBusGProxy * proxy, const gchar * name, const gchar * prev, const gchar * new, IndicateServer * server) +{ + /* g_debug("DBus Owner change (%s, %s, %s)", name, prev, new); */ + if (prev == NULL || prev[0] == '\0') { + /* We only care about people leaving the bus */ + return; + } + + /* g_debug("\tBeing removed, interesting"); */ + IndicateServerPrivate * priv = INDICATE_SERVER_GET_PRIVATE(server); + + IndicateServerInterestedFolk searchitem; + searchitem.sender = (gchar *)name; + GList * entry = g_list_find_custom(priv->interestedfolks, &searchitem, indicate_server_interested_folks_equal); + + if (entry == NULL) { + /* g_debug("\tWe don't have it, not interesting"); */ + return; + } + + IndicateServerInterestedFolk * folk = (IndicateServerInterestedFolk *)entry->data; + priv->interestedfolks = g_list_remove(priv->interestedfolks, entry->data); + + guint i; + for (i = INDICATE_INTEREST_NONE; i < INDICATE_INTEREST_LAST; i++) { + priv->interests[i] = FALSE; + } + + GList * listi = NULL; + for (listi = priv->interestedfolks ; listi != NULL ; listi = listi->next) { + IndicateServerInterestedFolk * folkpointer = (IndicateServerInterestedFolk *)listi->data; + /* g_debug("\tRebuild list from folk: %s", folkpointer->sender); */ + indicate_server_interested_folks_copy(folkpointer, priv->interests); + } + + for (i = INDICATE_INTEREST_NONE; i < INDICATE_INTEREST_LAST; i++) { + /* g_debug("\tComparing interests. Interest: %d Folk: %d Everyone: %d", i, folk->interests[i], priv->interests[i]); */ + if (folk->interests[i] && !priv->interests[i]) { + /* We can only remove interest here. Think about it for a + moment and I think you'll be cool with it. */ + /* g_debug("\tOh, and it was interested in %d. Not anymore.", i); */ + g_signal_emit(G_OBJECT(server), signals[INTEREST_REMOVED], 0, i, TRUE); + } + } + + g_free(folk); + + return; +} + static guint get_next_id (IndicateServer * server) { @@ -339,6 +497,89 @@ get_next_id (IndicateServer * server) return priv->current_id; } +static gboolean +show_interest (IndicateServer * server, gchar * sender, IndicateInterests interest) +{ + if (!(interest > INDICATE_INTEREST_NONE && interest < INDICATE_INTEREST_LAST)) { + return FALSE; + } + + /* g_debug("Someone is showing interest. %s in %d", sender, interest); */ + IndicateServerInterestedFolk localfolk; + localfolk.sender = sender; + + IndicateServerPrivate * priv = INDICATE_SERVER_GET_PRIVATE(server); + + GList * entry = g_list_find_custom(priv->interestedfolks, &localfolk, indicate_server_interested_folks_equal); + IndicateServerInterestedFolk * folkpointer = NULL; + if (entry == NULL) { + folkpointer = g_new(IndicateServerInterestedFolk, 1); + indicate_server_interested_folks_init(folkpointer, sender); + priv->interestedfolks = g_list_append(priv->interestedfolks, folkpointer); + } else { + folkpointer = (IndicateServerInterestedFolk *)entry->data; + } + + indicate_server_interested_folks_set(folkpointer, interest, TRUE); + if (!priv->interests[interest]) { + g_signal_emit(G_OBJECT(server), signals[INTEREST_ADDED], 0, interest, TRUE); + priv->interests[interest] = TRUE; + } + + return TRUE; +} + +static gboolean +remove_interest (IndicateServer * server, gchar * sender, IndicateInterests interest) +{ + if (!(interest > INDICATE_INTEREST_NONE && interest < INDICATE_INTEREST_LAST)) { + return FALSE; + } + + IndicateServerInterestedFolk localfolk; + localfolk.sender = sender; + + IndicateServerPrivate * priv = INDICATE_SERVER_GET_PRIVATE(server); + + GList * entry = g_list_find_custom(priv->interestedfolks, &localfolk, indicate_server_interested_folks_equal); + IndicateServerInterestedFolk * folkpointer = NULL; + if (entry == NULL) { + folkpointer = g_new(IndicateServerInterestedFolk, 1); + indicate_server_interested_folks_init(folkpointer, sender); + priv->interestedfolks = g_list_append(priv->interestedfolks, folkpointer); + } else { + folkpointer = (IndicateServerInterestedFolk *)entry->data; + } + + indicate_server_interested_folks_set(folkpointer, interest, FALSE); + + if (priv->interests[interest]) { + guint i; + for (i = INDICATE_INTEREST_NONE; i < INDICATE_INTEREST_LAST; i++) { + priv->interests[i] = FALSE; + } + + GList * listi = NULL; + for (listi = priv->interestedfolks ; listi != NULL ; listi = listi->next) { + folkpointer = (IndicateServerInterestedFolk *)listi->data; + indicate_server_interested_folks_copy(folkpointer, priv->interests); + } + + if (!priv->interests[interest]) { + g_signal_emit(G_OBJECT(server), signals[INTEREST_REMOVED], 0, interest, TRUE); + } + } + + return TRUE; +} + +static gboolean +check_interest (IndicateServer * server, IndicateInterests interest) +{ + IndicateServerPrivate * priv = INDICATE_SERVER_GET_PRIVATE(server); + return priv->interests[interest]; +} + static void indicator_show_cb (IndicateIndicator * indicator, IndicateServer * server) { @@ -369,8 +610,10 @@ indicate_server_add_indicator (IndicateServer * server, IndicateIndicator * indi { IndicateServerPrivate * priv = INDICATE_SERVER_GET_PRIVATE(server); - g_object_ref(indicator); - priv->indicators = g_slist_prepend(priv->indicators, indicator); + if (g_slist_find (priv->indicators, indicator) != NULL) + return; + + priv->indicators = g_slist_prepend(priv->indicators, indicator); if (!indicate_indicator_is_visible(indicator)) { priv->num_hidden++; @@ -390,6 +633,9 @@ indicate_server_remove_indicator (IndicateServer * server, IndicateIndicator * i { IndicateServerPrivate * priv = INDICATE_SERVER_GET_PRIVATE(server); + if (g_slist_find (priv->indicators, indicator) == NULL) + return; + priv->indicators = g_slist_remove(priv->indicators, indicator); if (indicate_indicator_is_visible(indicator)) { g_signal_emit(server, signals[INDICATOR_REMOVED], 0, indicate_indicator_get_id(indicator), indicate_indicator_get_indicator_type(indicator), TRUE); @@ -401,7 +647,6 @@ indicate_server_remove_indicator (IndicateServer * server, IndicateIndicator * i g_signal_handlers_disconnect_by_func(indicator, indicator_hide_cb, server); g_signal_handlers_disconnect_by_func(indicator, indicator_modified_cb, server); - g_object_unref(indicator); return; } @@ -553,7 +798,7 @@ get_indicator_list (IndicateServer * server, GArray ** indicators, GError ** err } static gboolean -get_indicator_list_by_type (IndicateServer * server, gchar * type, guint ** indicators, GError ** error) +get_indicator_list_by_type (IndicateServer * server, gchar * type, GArray ** indicators, GError ** error) { g_return_val_if_fail(INDICATE_IS_SERVER(server), TRUE); @@ -686,11 +931,11 @@ show_indicator_to_user (IndicateServer * server, guint id, GError ** error) /* Virtual Functions */ gboolean -indicate_server_get_indicator_count (IndicateServer * server, guint * count, GError **error) +_indicate_server_get_indicator_count (IndicateServer * server, guint * count, GError **error) { IndicateServerClass * class = INDICATE_SERVER_GET_CLASS(server); - if (class != NULL) { + if (class != NULL && class->get_indicator_count != NULL) { return class->get_indicator_count (server, count, error); } @@ -707,11 +952,11 @@ indicate_server_get_indicator_count (IndicateServer * server, guint * count, GEr } gboolean -indicate_server_get_indicator_count_by_type (IndicateServer * server, gchar * type, guint * count, GError **error) +_indicate_server_get_indicator_count_by_type (IndicateServer * server, gchar * type, guint * count, GError **error) { IndicateServerClass * class = INDICATE_SERVER_GET_CLASS(server); - if (class != NULL) { + if (class != NULL && class->get_indicator_count_by_type != NULL) { return class->get_indicator_count_by_type (server, type, count, error); } @@ -728,11 +973,11 @@ indicate_server_get_indicator_count_by_type (IndicateServer * server, gchar * ty } gboolean -indicate_server_get_indicator_list (IndicateServer * server, GArray ** indicators, GError ** error) +_indicate_server_get_indicator_list (IndicateServer * server, GArray ** indicators, GError ** error) { IndicateServerClass * class = INDICATE_SERVER_GET_CLASS(server); - if (class != NULL) { + if (class != NULL && class->get_indicator_list != NULL) { return class->get_indicator_list (server, indicators, error); } @@ -749,11 +994,11 @@ indicate_server_get_indicator_list (IndicateServer * server, GArray ** indicator } gboolean -indicate_server_get_indicator_list_by_type (IndicateServer * server, gchar * type, guint ** indicators, GError ** error) +_indicate_server_get_indicator_list_by_type (IndicateServer * server, gchar * type, GArray ** indicators, GError ** error) { IndicateServerClass * class = INDICATE_SERVER_GET_CLASS(server); - if (class != NULL) { + if (class != NULL && class->get_indicator_list_by_type != NULL) { return class->get_indicator_list_by_type (server, type, indicators, error); } @@ -770,11 +1015,11 @@ indicate_server_get_indicator_list_by_type (IndicateServer * server, gchar * typ } gboolean -indicate_server_get_indicator_property (IndicateServer * server, guint id, gchar * property, gchar ** value, GError **error) +_indicate_server_get_indicator_property (IndicateServer * server, guint id, gchar * property, gchar ** value, GError **error) { IndicateServerClass * class = INDICATE_SERVER_GET_CLASS(server); - if (class != NULL) { + if (class != NULL && class->get_indicator_property != NULL) { return class->get_indicator_property (server, id, property, value, error); } @@ -791,11 +1036,11 @@ indicate_server_get_indicator_property (IndicateServer * server, guint id, gchar } gboolean -indicate_server_get_indicator_property_group (IndicateServer * server, guint id, GPtrArray * properties, gchar *** value, GError **error) +_indicate_server_get_indicator_property_group (IndicateServer * server, guint id, GPtrArray * properties, gchar *** value, GError **error) { IndicateServerClass * class = INDICATE_SERVER_GET_CLASS(server); - if (class != NULL) { + if (class != NULL && class->get_indicator_property_group != NULL) { return class->get_indicator_property_group (server, id, properties, value, error); } @@ -812,11 +1057,11 @@ indicate_server_get_indicator_property_group (IndicateServer * server, guint id, } gboolean -indicate_server_get_indicator_properties (IndicateServer * server, guint id, gchar *** properties, GError **error) +_indicate_server_get_indicator_properties (IndicateServer * server, guint id, gchar *** properties, GError **error) { IndicateServerClass * class = INDICATE_SERVER_GET_CLASS(server); - if (class != NULL) { + if (class != NULL && class->get_indicator_properties != NULL) { return class->get_indicator_properties (server, id, properties, error); } @@ -833,11 +1078,11 @@ indicate_server_get_indicator_properties (IndicateServer * server, guint id, gch } gboolean -indicate_server_show_indicator_to_user (IndicateServer * server, guint id, GError ** error) +_indicate_server_show_indicator_to_user (IndicateServer * server, guint id, GError ** error) { IndicateServerClass * class = INDICATE_SERVER_GET_CLASS(server); - if (class != NULL) { + if (class != NULL && class->show_indicator_to_user != NULL) { return class->show_indicator_to_user (server, id, error); } @@ -858,13 +1103,105 @@ indicate_server_get_next_id (IndicateServer * server) { IndicateServerClass * class = INDICATE_SERVER_GET_CLASS(server); - if (class != NULL) { + if (class != NULL && class->get_next_id != NULL) { return class->get_next_id (server); } return 0; } +static IndicateInterests +interest_string_to_enum (gchar * interest_string) +{ + if (!g_strcmp0(interest_string, INDICATE_INTEREST_STRING_SERVER_DISPLAY)) { + return INDICATE_INTEREST_SERVER_DISPLAY; + } + + if (!g_strcmp0(interest_string, INDICATE_INTEREST_STRING_SERVER_SIGNAL)) { + return INDICATE_INTEREST_SERVER_SIGNAL; + } + + if (!g_strcmp0(interest_string, INDICATE_INTEREST_STRING_INDICATOR_DISPLAY)) { + return INDICATE_INTEREST_INDICATOR_DISPLAY; + } + + if (!g_strcmp0(interest_string, INDICATE_INTEREST_STRING_INDICATOR_SIGNAL)) { + return INDICATE_INTEREST_INDICATOR_SIGNAL; + } + + if (!g_strcmp0(interest_string, INDICATE_INTEREST_STRING_INDICATOR_COUNT)) { + return INDICATE_INTEREST_INDICATOR_COUNT; + } + + return INDICATE_INTEREST_NONE; +} + +gboolean +_indicate_server_show_interest (IndicateServer * server, gchar * interest, DBusGMethodInvocation * method) +{ + IndicateServerClass * class = INDICATE_SERVER_GET_CLASS(server); + + if (class != NULL && class->show_interest != NULL) { + if (class->show_interest (server, dbus_g_method_get_sender(method), interest_string_to_enum(interest))){ + dbus_g_method_return(method); + return TRUE; + } else { + GError * error; + g_set_error(&error, + indicate_server_error_quark(), + SHOW_INTEREST_FAILED, + "Unable to show interest: %s", + interest); + dbus_g_method_return_error(method, error); + g_error_free(error); + return FALSE; + } + } + + GError * error; + g_set_error(&error, + indicate_server_error_quark(), + NO_SHOW_INTEREST, + "show_interest function doesn't exist for this server class: %s", + G_OBJECT_TYPE_NAME(server)); + dbus_g_method_return_error(method, error); + g_error_free(error); + return FALSE; +} + +gboolean +_indicate_server_remove_interest (IndicateServer * server, gchar * interest, DBusGMethodInvocation * method) +{ + IndicateServerClass * class = INDICATE_SERVER_GET_CLASS(server); + + if (class != NULL && class->remove_interest != NULL) { + if (class->remove_interest (server, dbus_g_method_get_sender(method), interest_string_to_enum(interest))){ + dbus_g_method_return(method); + return TRUE; + } else { + GError * error; + g_set_error(&error, + indicate_server_error_quark(), + REMOVE_INTEREST_FAILED, + "Unable to remove interest: %s", + interest); + dbus_g_method_return_error(method, error); + g_error_free(error); + return FALSE; + } + } + + GError * error; + g_set_error(&error, + indicate_server_error_quark(), + NO_REMOVE_INTEREST, + "remove_interest function doesn't exist for this server class: %s", + G_OBJECT_TYPE_NAME(server)); + dbus_g_method_return_error(method, error); + g_error_free(error); + return FALSE; +} + /* Signal emission functions for sub-classes of the server */ void indicate_server_emit_indicator_added (IndicateServer *server, guint id, const gchar *type) @@ -900,3 +1237,53 @@ indicate_server_emit_server_display (IndicateServer *server) g_signal_emit(server, signals[SERVER_DISPLAY], 0, TRUE); } + +/* *** Folks stuff *** */ + +static gint +indicate_server_interested_folks_equal (gconstpointer a, gconstpointer b) +{ + return g_strcmp0(((IndicateServerInterestedFolk *)a)->sender,((IndicateServerInterestedFolk *)b)->sender); +} + +static void +indicate_server_interested_folks_init (IndicateServerInterestedFolk * folk, gchar * sender) +{ + folk->sender = g_strdup(sender); + + guint i; + for (i = INDICATE_INTEREST_NONE; i < INDICATE_INTEREST_LAST; i++) { + folk->interests[i] = FALSE; + } + + return; +} + +static void +indicate_server_interested_folks_set (IndicateServerInterestedFolk * folk, IndicateInterests interest, gboolean value) +{ + folk->interests[interest] = value; + return; +} + +static void +indicate_server_interested_folks_copy (IndicateServerInterestedFolk * folk, gboolean * interests) +{ + guint i; + for (i = INDICATE_INTEREST_NONE; i < INDICATE_INTEREST_LAST; i++) { + if (folk->interests[i]) { + interests[i] = TRUE; + } + } + + return; +} + +static void +indicate_server_interested_folks_destroy(IndicateServerInterestedFolk * folk) +{ + g_free(folk->sender); + g_free(folk); + return; +} +/* *** End Folks *** */ |