aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--e-util/ChangeLog5
-rw-r--r--e-util/Makefile.am2
-rw-r--r--e-util/e-component-listener.c227
-rw-r--r--e-util/e-component-listener.h50
4 files changed, 284 insertions, 0 deletions
diff --git a/e-util/ChangeLog b/e-util/ChangeLog
index 9dfc021ecb..bac53db150 100644
--- a/e-util/ChangeLog
+++ b/e-util/ChangeLog
@@ -1,3 +1,8 @@
+2002-08-14 Rodrigo Moya <rodrigo@ximian.com>
+
+ * e-component-listener.[ch]: new class for controlling a component,
+ to detect when it dies.
+
2002-08-01 Dan Winship <danw@ximian.com>
* e-html-utils.c (is_citation): Remove the logic that assumes
diff --git a/e-util/Makefile.am b/e-util/Makefile.am
index f7b4bb4d8c..f2283b3a0f 100644
--- a/e-util/Makefile.am
+++ b/e-util/Makefile.am
@@ -22,6 +22,7 @@ eutilinclude_HEADERS = \
e-bonobo-factory-util.h \
e-categories-master-list-wombat.h \
e-categories-config.h \
+ e-component-listener.h \
e-corba-utils.h \
e-dialog-utils.h \
e-dialog-widgets.h \
@@ -49,6 +50,7 @@ libeutil_la_SOURCES = \
e-bonobo-factory-util.c \
e-categories-master-list-wombat.c \
e-categories-config.c \
+ e-component-listener.c \
e-corba-utils.c \
e-dialog-utils.c \
e-dialog-widgets.c \
diff --git a/e-util/e-component-listener.c b/e-util/e-component-listener.c
new file mode 100644
index 0000000000..d58f44e577
--- /dev/null
+++ b/e-util/e-component-listener.c
@@ -0,0 +1,227 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Component listener.
+ *
+ * Author:
+ * Rodrigo Moya <rodrigo@ximian.com>
+ *
+ * Copyright 2002, Ximian, Inc.
+ */
+
+#include <gtk/gtksignal.h>
+#include <bonobo/bonobo-exception.h>
+#include <bonobo/bonobo-object.h>
+#include <gal/util/e-util.h>
+#include "e-component-listener.h"
+#include <libgnome/gnome-i18n.h>
+
+#define PARENT_TYPE GTK_TYPE_OBJECT
+#define DEFAULT_PING_DELAY 10000
+
+struct _EComponentListenerPrivate {
+ Bonobo_Unknown component;
+ int ping_delay;
+ int ping_timeout_id;
+};
+
+static void e_component_listener_class_init (EComponentListenerClass *klass);
+static void e_component_listener_init (EComponentListener *cl);
+static void e_component_listener_destroy (GtkObject *object);
+
+static GtkObjectClass *parent_class = NULL;
+
+enum {
+ COMPONENT_DIED,
+ LAST_SIGNAL
+};
+
+static guint comp_listener_signals[LAST_SIGNAL];
+
+static void
+e_component_listener_class_init (EComponentListenerClass *klass)
+{
+ GtkObjectClass *object_class = GTK_OBJECT_CLASS (klass);
+
+ parent_class = gtk_type_class (PARENT_TYPE);
+
+ object_class->destroy = e_component_listener_destroy;
+ klass->component_died = NULL;
+
+ comp_listener_signals[COMPONENT_DIED] =
+ gtk_signal_new ("component_died",
+ GTK_RUN_FIRST,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (EComponentListenerClass, component_died),
+ gtk_marshal_NONE__NONE,
+ GTK_TYPE_NONE, 0);
+ gtk_object_class_add_signals (object_class, comp_listener_signals, LAST_SIGNAL);
+}
+
+static void
+e_component_listener_init (EComponentListener *cl)
+{
+ /* allocate internal structure */
+ cl->priv = g_new (EComponentListenerPrivate, 1);
+ cl->priv->component = CORBA_OBJECT_NIL;
+ cl->priv->ping_delay = DEFAULT_PING_DELAY;
+ cl->priv->ping_timeout_id = -1;
+}
+
+static void
+e_component_listener_destroy (GtkObject *object)
+{
+ EComponentListener *cl = (EComponentListener *) object;
+
+ g_return_if_fail (E_IS_COMPONENT_LISTENER (cl));
+
+ cl->priv->component = CORBA_OBJECT_NIL;
+
+ if (cl->priv->ping_timeout_id != -1) {
+ g_source_remove (cl->priv->ping_timeout_id);
+ cl->priv->ping_timeout_id = -1;
+ }
+
+ /* free memory */
+ g_free (cl->priv);
+ cl->priv = NULL;
+
+ if (GTK_OBJECT_CLASS (parent_class)->destroy)
+ (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+GtkType
+e_component_listener_get_type (void)
+{
+ static GtkType type = 0;
+
+ if (!type) {
+ static const GtkTypeInfo info = {
+ "EComponentListener",
+ sizeof (EComponentListener),
+ sizeof (EComponentListenerClass),
+ (GtkClassInitFunc) e_component_listener_class_init,
+ (GtkObjectInitFunc) e_component_listener_init,
+ NULL, /* reserved_1 */
+ NULL, /* reserved_2 */
+ (GtkClassInitFunc) NULL
+ };
+
+ type = gtk_type_unique (PARENT_TYPE, &info);
+ }
+
+ return type;
+}
+
+static gboolean
+ping_component_callback (gpointer user_data)
+{
+ gboolean alive;
+ int is_nil;
+ CORBA_Environment ev;
+ EComponentListener *cl = (EComponentListener *) user_data;
+
+ g_return_val_if_fail (E_IS_COMPONENT_LISTENER (cl), FALSE);
+
+ if (cl->priv->component == CORBA_OBJECT_NIL)
+ return FALSE;
+
+ CORBA_exception_init (&ev);
+ is_nil = CORBA_Object_is_nil (cl->priv->component, &ev);
+ if (BONOBO_EX (&ev)) {
+ g_message (_("ping_timeout_callback: could not determine if the "
+ "CORBA object is nil or not"));
+ goto out;
+ }
+ CORBA_exception_free (&ev);
+
+ if (is_nil)
+ goto out;
+
+ alive = bonobo_unknown_ping (cl->priv->component);
+ if (alive)
+ return TRUE;
+
+ out:
+ /* the component has died, so we notify and close the timeout */
+ gtk_signal_emit (GTK_OBJECT (cl), comp_listener_signals[COMPONENT_DIED]);
+
+ cl->priv->component = CORBA_OBJECT_NIL;
+ cl->priv->ping_timeout_id = -1;
+
+ return FALSE;
+}
+
+static void
+setup_ping_timeout (EComponentListener *cl)
+{
+ if (cl->priv->ping_timeout_id != -1)
+ g_source_remove (cl->priv->ping_timeout_id);
+
+ cl->priv->ping_timeout_id = g_timeout_add (cl->priv->ping_delay,
+ ping_component_callback,
+ cl);
+}
+
+/**
+ * e_component_listener_new
+ * @comp: Component to listen for.
+ * @ping_delay: Delay (in ms) for pinging the component.
+ *
+ * Create a new #EComponentListener object, which allows to listen
+ * for a given component and get notified when that component dies.
+ *
+ * Returns: a component listener object.
+ */
+EComponentListener *
+e_component_listener_new (Bonobo_Unknown comp, int ping_delay)
+{
+ EComponentListener *cl;
+
+ cl = gtk_type_new (E_COMPONENT_LISTENER_TYPE);
+ cl->priv->component = comp;
+
+ /* set up the timeout function */
+ cl->priv->ping_delay = ping_delay > 0 ? ping_delay : DEFAULT_PING_DELAY;
+ setup_ping_timeout (cl);
+
+ return cl;
+}
+
+/**
+ * e_component_listener_get_ping_delay
+ * @cl: A #EComponentListener object.
+ *
+ * Get the ping delay being used to listen for an object.
+ */
+int
+e_component_listener_get_ping_delay (EComponentListener *cl)
+{
+ g_return_val_if_fail (E_IS_COMPONENT_LISTENER (cl), -1);
+ return cl->priv->ping_delay;
+}
+
+void
+e_component_listener_set_ping_delay (EComponentListener *cl, int ping_delay)
+{
+ g_return_if_fail (E_IS_COMPONENT_LISTENER (cl));
+ g_return_if_fail (ping_delay > 0);
+
+ cl->priv->ping_delay = ping_delay;
+ setup_ping_timeout (cl);
+}
+
+Bonobo_Unknown
+e_component_listener_get_component (EComponentListener *cl)
+{
+ g_return_val_if_fail (E_IS_COMPONENT_LISTENER (cl), CORBA_OBJECT_NIL);
+ return cl->priv->component;
+}
+
+void
+e_component_listener_set_component (EComponentListener *cl, Bonobo_Unknown comp)
+{
+ g_return_if_fail (E_IS_COMPONENT_LISTENER (cl));
+
+ cl->priv->component = comp;
+ setup_ping_timeout (cl);
+}
diff --git a/e-util/e-component-listener.h b/e-util/e-component-listener.h
new file mode 100644
index 0000000000..8194476cf2
--- /dev/null
+++ b/e-util/e-component-listener.h
@@ -0,0 +1,50 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Component listener
+ *
+ * Author:
+ * Rodrigo Moya <rodrigo@ximian.com>
+ *
+ * Copyright 2002, Ximian, Inc.
+ */
+
+#ifndef __E_COMPONENT_LISTENER_H__
+#define __E_COMPONENT_LISTENER_H__
+
+#include <bonobo/Bonobo.h>
+#include <gtk/gtkobject.h>
+#include <libgnome/gnome-defs.h>
+
+BEGIN_GNOME_DECLS
+
+#define E_COMPONENT_LISTENER_TYPE (e_component_listener_get_type ())
+#define E_COMPONENT_LISTENER(o) (GTK_CHECK_CAST ((o), E_COMPONENT_LISTENER_TYPE, EComponentListener))
+#define E_COMPONENT_LISTENER_CLASS(k) (GTK_CHECK_CLASS_CAST((k), E_COMPONENT_LISTENER_TYPE, EComponentListenerClass))
+#define E_IS_COMPONENT_LISTENER(o) (GTK_CHECK_TYPE ((o), E_COMPONENT_LISTENER_TYPE))
+#define E_IS_COMPONENT_LISTENER_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_COMPONENT_LISTENER_TYPE))
+
+typedef struct _EComponentListenerPrivate EComponentListenerPrivate;
+
+typedef struct {
+ GtkObject object;
+ EComponentListenerPrivate *priv;
+} EComponentListener;
+
+typedef struct {
+ GtkObjectClass parent_class;
+
+ void (* component_died) (EComponentListener *cl);
+} EComponentListenerClass;
+
+GtkType e_component_listener_get_type (void);
+EComponentListener *e_component_listener_new (Bonobo_Unknown comp, int ping_delay);
+
+int e_component_listener_get_ping_delay (EComponentListener *cl);
+void e_component_listener_set_ping_delay (EComponentListener *cl, int ping_delay);
+Bonobo_Unknown e_component_listener_get_component (EComponentListener *cl);
+void e_component_listener_set_component (EComponentListener *cl,
+ Bonobo_Unknown comp);
+
+END_GNOME_DECLS
+
+#endif