source: trunk/third/evolution/e-util/e-component-listener.c @ 19030

Revision 19030, 5.6 KB checked in by ghudson, 21 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r19029, which included commits to RCS files with non-trunk default branches.
Line 
1/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2/*
3 * Component listener.
4 *
5 * Author:
6 *   Rodrigo Moya <rodrigo@ximian.com>
7 *
8 * Copyright 2002, Ximian, Inc.
9 */
10
11#ifdef HAVE_CONFIG_H
12#include <config.h>
13#endif
14
15#include <gtk/gtksignal.h>
16#include <bonobo/bonobo-exception.h>
17#include <bonobo/bonobo-object.h>
18#include <gal/util/e-util.h>
19#include "e-component-listener.h"
20#include <libgnome/gnome-i18n.h>
21
22#define PARENT_TYPE GTK_TYPE_OBJECT
23#define DEFAULT_PING_DELAY 10000
24
25struct _EComponentListenerPrivate {
26        Bonobo_Unknown component;
27        int ping_delay;
28        int ping_timeout_id;
29};
30
31static void e_component_listener_class_init (EComponentListenerClass *klass);
32static void e_component_listener_init       (EComponentListener *cl);
33static void e_component_listener_destroy    (GtkObject *object);
34
35static GtkObjectClass *parent_class = NULL;
36
37enum {
38        COMPONENT_DIED,
39        LAST_SIGNAL
40};
41
42static guint comp_listener_signals[LAST_SIGNAL];
43
44static void
45e_component_listener_class_init (EComponentListenerClass *klass)
46{
47        GtkObjectClass *object_class = GTK_OBJECT_CLASS (klass);
48
49        parent_class = gtk_type_class (PARENT_TYPE);
50
51        object_class->destroy = e_component_listener_destroy;
52        klass->component_died = NULL;
53
54        comp_listener_signals[COMPONENT_DIED] =
55                gtk_signal_new ("component_died",
56                                GTK_RUN_FIRST,
57                                object_class->type,
58                                GTK_SIGNAL_OFFSET (EComponentListenerClass, component_died),
59                                gtk_marshal_NONE__NONE,
60                                GTK_TYPE_NONE, 0);
61        gtk_object_class_add_signals (object_class, comp_listener_signals, LAST_SIGNAL);
62}
63
64static void
65e_component_listener_init (EComponentListener *cl)
66{
67        /* allocate internal structure */
68        cl->priv = g_new (EComponentListenerPrivate, 1);
69        cl->priv->component = CORBA_OBJECT_NIL;
70        cl->priv->ping_delay = DEFAULT_PING_DELAY;
71        cl->priv->ping_timeout_id = -1;
72}
73
74static void
75e_component_listener_destroy (GtkObject *object)
76{
77        EComponentListener *cl = (EComponentListener *) object;
78
79        g_return_if_fail (E_IS_COMPONENT_LISTENER (cl));
80
81        cl->priv->component = CORBA_OBJECT_NIL;
82
83        if (cl->priv->ping_timeout_id != -1) {
84                g_source_remove (cl->priv->ping_timeout_id);
85                cl->priv->ping_timeout_id = -1;
86        }
87
88        /* free memory */
89        g_free (cl->priv);
90        cl->priv = NULL;
91
92        if (GTK_OBJECT_CLASS (parent_class)->destroy)
93                (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
94}
95
96GtkType
97e_component_listener_get_type (void)
98{
99        static GtkType type = 0;
100
101        if (!type) {
102                static const GtkTypeInfo info = {
103                        "EComponentListener",
104                        sizeof (EComponentListener),
105                        sizeof (EComponentListenerClass),
106                        (GtkClassInitFunc) e_component_listener_class_init,
107                        (GtkObjectInitFunc) e_component_listener_init,
108                        NULL, /* reserved_1 */
109                        NULL, /* reserved_2 */
110                        (GtkClassInitFunc) NULL
111                };
112
113                type = gtk_type_unique (PARENT_TYPE, &info);
114        }
115
116        return type;
117}
118
119static gboolean
120ping_component_callback (gpointer user_data)
121{
122        gboolean alive;
123        int is_nil;
124        CORBA_Environment ev;
125        EComponentListener *cl = (EComponentListener *) user_data;
126
127        g_return_val_if_fail (E_IS_COMPONENT_LISTENER (cl), FALSE);
128
129        if (cl->priv->component == CORBA_OBJECT_NIL)
130                return FALSE;
131
132        CORBA_exception_init (&ev);
133        is_nil = CORBA_Object_is_nil (cl->priv->component, &ev);
134        if (BONOBO_EX (&ev)) {
135                g_message (_("ping_timeout_callback: could not determine if the "
136                             "CORBA object is nil or not"));
137                goto out;
138        }
139        CORBA_exception_free (&ev);
140
141        if (is_nil)
142                goto out;
143
144        alive = bonobo_unknown_ping (cl->priv->component);
145        if (alive)
146                return TRUE;
147
148 out:
149        /* the component has died, so we notify and close the timeout */
150
151        /* we ref the object just in case it gets destroyed in the callbacks */
152        gtk_object_ref (GTK_OBJECT (cl));
153        gtk_signal_emit (GTK_OBJECT (cl), comp_listener_signals[COMPONENT_DIED]);
154
155        cl->priv->component = CORBA_OBJECT_NIL;
156        cl->priv->ping_timeout_id = -1;
157
158        gtk_object_unref (GTK_OBJECT (cl));
159
160        return FALSE;
161}
162
163static void
164setup_ping_timeout (EComponentListener *cl)
165{
166        if (cl->priv->ping_timeout_id != -1)
167                g_source_remove (cl->priv->ping_timeout_id);
168
169        cl->priv->ping_timeout_id = g_timeout_add (cl->priv->ping_delay,
170                                                   ping_component_callback,
171                                                   cl);
172}
173
174/**
175 * e_component_listener_new
176 * @comp: Component to listen for.
177 * @ping_delay: Delay (in ms) for pinging the component.
178 *
179 * Create a new #EComponentListener object, which allows to listen
180 * for a given component and get notified when that component dies.
181 *
182 * Returns: a component listener object.
183 */
184EComponentListener *
185e_component_listener_new (Bonobo_Unknown comp, int ping_delay)
186{
187        EComponentListener *cl;
188
189        cl = gtk_type_new (E_COMPONENT_LISTENER_TYPE);
190        cl->priv->component = comp;
191
192        /* set up the timeout function */
193        cl->priv->ping_delay = ping_delay > 0 ? ping_delay : DEFAULT_PING_DELAY;
194        setup_ping_timeout (cl);
195
196        return cl;
197}
198
199/**
200 * e_component_listener_get_ping_delay
201 * @cl: A #EComponentListener object.
202 *
203 * Get the ping delay being used to listen for an object.
204 */
205int
206e_component_listener_get_ping_delay (EComponentListener *cl)
207{
208        g_return_val_if_fail (E_IS_COMPONENT_LISTENER (cl), -1);
209        return cl->priv->ping_delay;
210}
211
212void
213e_component_listener_set_ping_delay (EComponentListener *cl, int ping_delay)
214{
215        g_return_if_fail (E_IS_COMPONENT_LISTENER (cl));
216        g_return_if_fail (ping_delay > 0);
217
218        cl->priv->ping_delay = ping_delay;
219        setup_ping_timeout (cl);
220}
221
222Bonobo_Unknown
223e_component_listener_get_component (EComponentListener *cl)
224{
225        g_return_val_if_fail (E_IS_COMPONENT_LISTENER (cl), CORBA_OBJECT_NIL);
226        return cl->priv->component;
227}
228
229void
230e_component_listener_set_component (EComponentListener *cl, Bonobo_Unknown comp)
231{
232        g_return_if_fail (E_IS_COMPONENT_LISTENER (cl));
233
234        cl->priv->component = comp;
235        setup_ping_timeout (cl);
236}
Note: See TracBrowser for help on using the repository browser.