diff options
Diffstat (limited to 'src/empathy-event-manager.c')
-rw-r--r-- | src/empathy-event-manager.c | 175 |
1 files changed, 94 insertions, 81 deletions
diff --git a/src/empathy-event-manager.c b/src/empathy-event-manager.c index 1ee619e58..1a7ec09cb 100644 --- a/src/empathy-event-manager.c +++ b/src/empathy-event-manager.c @@ -26,6 +26,7 @@ #include <telepathy-glib/util.h> +#include <libempathy/empathy-account-manager.h> #include <libempathy/empathy-dispatcher.h> #include <libempathy/empathy-tp-contact-factory.h> #include <libempathy/empathy-contact-manager.h> @@ -37,9 +38,10 @@ #include <extensions/extensions.h> +#include <libempathy-gtk/empathy-conf.h> #include <libempathy-gtk/empathy-images.h> #include <libempathy-gtk/empathy-contact-dialogs.h> -#include <libempathy-gtk/empathy-ui-utils.h> +#include <libempathy-gtk/empathy-sound.h> #include "empathy-event-manager.h" #include "empathy-main-window.h" @@ -50,6 +52,11 @@ #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyEventManager) +#define NOTIFICATION_TIMEOUT 2 /* seconds */ + +/* The time interval in milliseconds between 2 incoming rings */ +#define MS_BETWEEN_RING 500 + typedef struct { EmpathyEventManager *manager; EmpathyDispatchOperation *operation; @@ -74,8 +81,6 @@ typedef struct { /* Ongoing approvals */ GSList *approvals; - /* voip ringing sound */ - guint voip_timeout; gint ringing; } EmpathyEventManagerPriv; @@ -161,81 +166,6 @@ event_free (EventPriv *event) g_slice_free (EventPriv, event); } -static void event_manager_ringing_finished_cb (ca_context *c, guint id, - int error_code, gpointer user_data); - -static gboolean -event_manager_ringing_timeout_cb (gpointer data) -{ - EmpathyEventManager *manager = EMPATHY_EVENT_MANAGER (data); - EmpathyEventManagerPriv *priv = GET_PRIV (manager); - - priv->voip_timeout = 0; - - empathy_sound_play_full (empathy_main_window_get (), - EMPATHY_SOUND_PHONE_INCOMING, event_manager_ringing_finished_cb, - manager); - - return FALSE; -} - -static gboolean -event_manager_ringing_idle_cb (gpointer data) -{ - EmpathyEventManager *manager = EMPATHY_EVENT_MANAGER (data); - EmpathyEventManagerPriv *priv = GET_PRIV (manager); - - if (priv->ringing > 0) - priv->voip_timeout = g_timeout_add (500, event_manager_ringing_timeout_cb, - data); - - return FALSE; -} - -static void -event_manager_ringing_finished_cb (ca_context *c, guint id, int error_code, - gpointer user_data) -{ - if (error_code == CA_ERROR_CANCELED) - return; - - g_idle_add (event_manager_ringing_idle_cb, user_data); -} - -static void -event_manager_start_ringing (EmpathyEventManager *manager) -{ - EmpathyEventManagerPriv *priv = GET_PRIV (manager); - - priv->ringing++; - - if (priv->ringing == 1) - { - empathy_sound_play_full (empathy_main_window_get (), - EMPATHY_SOUND_PHONE_INCOMING, event_manager_ringing_finished_cb, - manager); - } -} - -static void -event_manager_stop_ringing (EmpathyEventManager *manager) -{ - EmpathyEventManagerPriv *priv = GET_PRIV (manager); - - priv->ringing--; - - if (priv->ringing > 0) - return; - - empathy_sound_stop (EMPATHY_SOUND_PHONE_INCOMING); - - if (priv->voip_timeout != 0) - { - g_source_remove (priv->voip_timeout); - priv->voip_timeout = 0; - } -} - static void event_remove (EventPriv *event) { @@ -247,6 +177,13 @@ event_remove (EventPriv *event) event_free (event); } +static gboolean +autoremove_event_timeout_cb (EventPriv *event) +{ + event_remove (event); + return FALSE; +} + static void event_manager_add (EmpathyEventManager *manager, EmpathyContact *contact, const gchar *icon_name, const gchar *header, const gchar *message, @@ -260,6 +197,7 @@ event_manager_add (EmpathyEventManager *manager, EmpathyContact *contact, event->public.icon_name = g_strdup (icon_name); event->public.header = g_strdup (header); event->public.message = g_strdup (message); + event->public.must_ack = (func != NULL); event->inhibit = FALSE; event->func = func; event->user_data = user_data; @@ -269,6 +207,12 @@ event_manager_add (EmpathyEventManager *manager, EmpathyContact *contact, DEBUG ("Adding event %p", event); priv->events = g_slist_prepend (priv->events, event); g_signal_emit (event->manager, signals[EVENT_ADDED], 0, event); + + if (!event->public.must_ack) + { + g_timeout_add_seconds (NOTIFICATION_TIMEOUT, + (GSourceFunc) autoremove_event_timeout_cb, event); + } } static void @@ -455,7 +399,9 @@ event_manager_approval_done (EventManagerApproval *approval) approval->operation); if (channel_type == TP_IFACE_QUARK_CHANNEL_TYPE_STREAMED_MEDIA) { - event_manager_stop_ringing (approval->manager); + priv->ringing--; + if (priv->ringing == 0) + empathy_sound_stop (EMPATHY_SOUND_PHONE_INCOMING); } } @@ -500,6 +446,7 @@ event_manager_operation_invalidated_cb (EmpathyDispatchOperation *operation, static void event_manager_media_channel_got_contact (EventManagerApproval *approval) { + EmpathyEventManagerPriv *priv = GET_PRIV (approval->manager); gchar *header; header = g_strdup_printf (_("Incoming call from %s"), @@ -510,7 +457,11 @@ event_manager_media_channel_got_contact (EventManagerApproval *approval) approval, event_channel_process_voip_func, NULL); g_free (header); - event_manager_start_ringing (approval->manager); + + priv->ringing++; + if (priv->ringing == 1) + empathy_sound_start_playing (empathy_main_window_get (), + EMPATHY_SOUND_PHONE_INCOMING, MS_BETWEEN_RING); } static void @@ -956,6 +907,58 @@ event_manager_pendings_changed_cb (EmpathyContactList *list, g_free (header); } +static void +event_manager_presence_changed_cb (EmpathyContactMonitor *monitor, + EmpathyContact *contact, + TpConnectionPresenceType current, + TpConnectionPresenceType previous, + EmpathyEventManager *manager) +{ + EmpathyAccount *account; + gchar *header = NULL; + gboolean preference = FALSE; + + account = empathy_contact_get_account (contact); + if (empathy_account_is_just_connected (account)) + return; + + if (tp_connection_presence_type_cmp_availability (previous, + TP_CONNECTION_PRESENCE_TYPE_OFFLINE) > 0) + { + /* contact was online */ + empathy_conf_get_bool (empathy_conf_get (), + EMPATHY_PREFS_NOTIFICATIONS_CONTACT_SIGNOUT, &preference); + if (preference && tp_connection_presence_type_cmp_availability (current, + TP_CONNECTION_PRESENCE_TYPE_OFFLINE) <= 0) + { + /* someone is logging off */ + header = g_strdup_printf (_("%s is now offline."), + empathy_contact_get_name (contact)); + + event_manager_add (manager, contact, GTK_STOCK_DIALOG_INFO, header, + NULL, NULL, NULL, NULL); + } + } + else + { + /* contact was offline */ + empathy_conf_get_bool (empathy_conf_get (), + EMPATHY_PREFS_NOTIFICATIONS_CONTACT_SIGNIN, &preference); + if (preference && tp_connection_presence_type_cmp_availability (current, + TP_CONNECTION_PRESENCE_TYPE_OFFLINE) > 0) + { + /* someone is logging in */ + header = g_strdup_printf (_("%s is now online."), + empathy_contact_get_name (contact)); + + event_manager_add (manager, contact, GTK_STOCK_DIALOG_INFO, header, + NULL, NULL, NULL, NULL); + } + } + g_free (header); +} + + static GObject * event_manager_constructor (GType type, guint n_props, @@ -981,6 +984,9 @@ event_manager_finalize (GObject *object) { EmpathyEventManagerPriv *priv = GET_PRIV (object); + if (priv->ringing > 0) + empathy_sound_stop (EMPATHY_SOUND_PHONE_INCOMING); + g_slist_foreach (priv->events, (GFunc) event_free, NULL); g_slist_free (priv->events); g_slist_foreach (priv->approvals, (GFunc) event_manager_approval_free, NULL); @@ -1034,6 +1040,12 @@ empathy_event_manager_init (EmpathyEventManager *manager) { EmpathyEventManagerPriv *priv = G_TYPE_INSTANCE_GET_PRIVATE (manager, EMPATHY_TYPE_EVENT_MANAGER, EmpathyEventManagerPriv); + EmpathyContactMonitor *monitor; + EmpathyContactList *list_iface; + + list_iface = EMPATHY_CONTACT_LIST (empathy_contact_manager_dup_singleton ()); + monitor = empathy_contact_list_get_monitor (list_iface); + g_object_unref (list_iface); manager->priv = priv; @@ -1043,6 +1055,8 @@ empathy_event_manager_init (EmpathyEventManager *manager) G_CALLBACK (event_manager_approve_channel_cb), manager); g_signal_connect (priv->contact_manager, "pendings-changed", G_CALLBACK (event_manager_pendings_changed_cb), manager); + g_signal_connect (monitor, "contact-presence-changed", + G_CALLBACK (event_manager_presence_changed_cb), manager); } EmpathyEventManager * @@ -1093,4 +1107,3 @@ empathy_event_inhibit_updates (EmpathyEvent *event_public) event->inhibit = TRUE; } - |