aboutsummaryrefslogtreecommitdiffstats
path: root/calendar/gui/alarm-notify/alarm-notify.c
diff options
context:
space:
mode:
Diffstat (limited to 'calendar/gui/alarm-notify/alarm-notify.c')
-rw-r--r--calendar/gui/alarm-notify/alarm-notify.c107
1 files changed, 89 insertions, 18 deletions
diff --git a/calendar/gui/alarm-notify/alarm-notify.c b/calendar/gui/alarm-notify/alarm-notify.c
index 9d64bfd4a8..fa70a1d236 100644
--- a/calendar/gui/alarm-notify/alarm-notify.c
+++ b/calendar/gui/alarm-notify/alarm-notify.c
@@ -27,12 +27,29 @@
#include <libgnomevfs/gnome-vfs.h>
#include <cal-client/cal-client.h>
#include "alarm-notify.h"
+#include "alarm-queue.h"
+/* A loaded client */
+typedef struct {
+ /* The actual client */
+ CalClient *client;
+
+ /* The URI of the client in gnome-vfs's format. This *is* the key that
+ * is stored in the uri_client_hash hash table below.
+ */
+ GnomeVFSURI *uri;
+
+ /* Number of times clients have requested this URI to be added to the
+ * alarm notification system.
+ */
+ int refcount;
+} LoadedClient;
+
/* Private part of the AlarmNotify structure */
struct _AlarmNotifyPrivate {
- /* Mapping from GnomeVFSURIs to loaded clients */
+ /* Mapping from GnomeVFSURIs to LoadedClient structures */
GHashTable *uri_client_hash;
};
@@ -114,6 +131,19 @@ alarm_notify_init (AlarmNotify *an)
priv->uri_client_hash = g_hash_table_new (gnome_vfs_uri_hash, gnome_vfs_uri_hequal);
}
+/* Callback used from g_hash-table_forach(), used to destroy a loade client */
+static void
+destroy_loaded_client_cb (gpointer key, gpointer value, gpointer data)
+{
+ LoadedClient *lc;
+
+ lc = value;
+
+ gtk_object_unref (GTK_OBJECT (lc->client));
+ gnome_vfs_uri_unref (lc->uri);
+ g_free (lc);
+}
+
/* Destroy handler for the alarm notify system */
static void
alarm_notify_destroy (GtkObject *object)
@@ -127,7 +157,7 @@ alarm_notify_destroy (GtkObject *object)
an = ALARM_NOTIFY (object);
priv = an->priv;
- /* FIXME */
+ g_hash_table_foreach (priv->uri_client_hash, destroy_loaded_client_cb, NULL);
g_hash_table_destroy (priv->uri_client_hash);
priv->uri_client_hash = NULL;
@@ -153,6 +183,7 @@ AlarmNotify_addCalendar (PortableServer_Servant servant,
AlarmNotifyPrivate *priv;
GnomeVFSURI *uri;
CalClient *client;
+ LoadedClient *lc;
an = ALARM_NOTIFY (bonobo_object_from_servant (servant));
priv = an->priv;
@@ -165,26 +196,33 @@ AlarmNotify_addCalendar (PortableServer_Servant servant,
return;
}
- client = g_hash_table_lookup (priv->uri_client_hash, uri);
+ lc = g_hash_table_lookup (priv->uri_client_hash, uri);
- if (client) {
+ if (lc) {
gnome_vfs_uri_unref (uri);
-
- gtk_object_ref (GTK_OBJECT (client));
+ g_assert (lc->refcount > 0);
+ lc->refcount++;
return;
}
client = cal_client_new ();
if (client) {
- g_hash_table_insert (priv->uri_client_hash, uri);
- alarm_queue_add_client (client);
-
- if (!cal_client_open_calendar (client, str_uri, FALSE)) {
+ if (cal_client_open_calendar (client, str_uri, FALSE)) {
+ lc = g_new (LoadedClient, 1);
+ lc->client = client;
+ lc->uri = uri;
+ lc->refcount = 1;
+ g_hash_table_insert (priv->uri_client_hash, uri, lc);
+
+ alarm_queue_add_client (client);
+ } else {
gtk_object_unref (GTK_OBJECT (client));
client = NULL;
}
- } else {
+ }
+
+ if (!client) {
gnome_vfs_uri_unref (uri);
CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
@@ -197,26 +235,59 @@ AlarmNotify_addCalendar (PortableServer_Servant servant,
/* AlarmNotify::removeCalendar method */
static void
AlarmNotify_removeCalendar (PortableServer_Servant servant,
- const CORBA_char *uri,
+ const CORBA_char *str_uri,
CORBA_Environment *ev)
{
AlarmNotify *an;
AlarmNotifyPrivate *priv;
- CalClient *client;
- char *orig_uri;
+ LoadedClient *lc;
+ GnomeVFSURI *uri;
an = ALARM_NOTIFY (bonobo_object_from_servant (servant));
priv = an->priv;
- if (!g_hash_table_lookup_extended (priv->uri_client_hash, uri, &orig_uri, &client)) {
+ uri = gnome_vfs_uri_new (str_uri);
+ if (!uri) {
CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
- ex_GNOME_Evolution_Calendar_AlarmNotify_NotFound);
+ ex_GNOME_Evolution_Calendar_AlarmNotify_InvalidURI,
+ NULL);
return;
}
- gtk_object_unref (client);
+ lc = g_hash_table_lookup (priv->uri_client_hash, uri);
+ gnome_vfs_uri_unref (uri);
+
+ if (!lc) {
+ CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
+ ex_GNOME_Evolution_Calendar_AlarmNotify_NotFound,
+ NULL);
+ return;
+ }
- /* FIXME: do we need to do anything else? */
+ g_assert (lc->refcount > 0);
+
+ lc->refcount--;
+ if (lc->refcount > 0)
+ return;
+
+ g_hash_table_remove (priv->uri_client_hash, lc->uri);
+
+ gtk_object_unref (GTK_OBJECT (lc->client));
+ gnome_vfs_uri_unref (lc->uri);
+ g_free (lc);
+}
+
+static void
+AlarmNotify_die (PortableServer_Servant servant,
+ CORBA_Environment *ev)
+{
+ AlarmNotify *an;
+ AlarmNotifyPrivate *priv;
+
+ an = ALARM_NOTIFY (bonobo_object_from_servant (servant));
+ priv = an->priv;
+
+ /* FIXME */
}
/**