source: trunk/third/bonobo/bonobo/bonobo-listener.c @ 16750

Revision 16750, 6.8 KB checked in by ghudson, 23 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r16749, 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 * bonobo-listener.c: Generic listener interface for callbacks.
4 *
5 * Authors:
6 *      Alex Graveley (alex@helixcode.com)
7 *      Mike Kestner  (mkestner@ameritech.net)
8 *
9 * Copyright (C) 2000, Helix Code, Inc.
10 */
11#include <config.h>
12#include <gtk/gtksignal.h>
13
14#include <bonobo/bonobo-exception.h>
15#include <bonobo/bonobo-listener.h>
16
17#define PARENT_TYPE BONOBO_X_OBJECT_TYPE
18
19static GtkObjectClass *bonobo_listener_parent_class;
20
21struct _BonoboListenerPrivate {
22        BonoboListenerCallbackFn event_callback;
23        gpointer                 user_data;
24};
25
26enum SIGNALS {
27        EVENT_NOTIFY,
28        LAST_SIGNAL
29};
30static guint signals [LAST_SIGNAL] = { 0 };
31
32static void
33impl_Bonobo_Listener_event (PortableServer_Servant servant,
34                            const CORBA_char      *event_name,
35                            const CORBA_any       *args,
36                            CORBA_Environment     *ev)
37{
38        BonoboListener *listener;
39
40        listener = BONOBO_LISTENER (bonobo_object_from_servant (servant));
41
42        bonobo_object_ref (BONOBO_OBJECT (listener));
43        if (listener->priv->event_callback)
44                listener->priv->event_callback (
45                        listener, (CORBA_char *) event_name,
46                        (CORBA_any *) args, ev,
47                        listener->priv->user_data);
48
49        gtk_signal_emit (GTK_OBJECT (listener),
50                         signals [EVENT_NOTIFY],
51                         event_name, args, ev);
52        bonobo_object_unref (BONOBO_OBJECT (listener));
53}
54
55static void
56bonobo_listener_finalize (GtkObject *object)
57{
58        BonoboListener *listener;
59
60        listener = BONOBO_LISTENER (object);
61        g_free (listener->priv);
62
63        bonobo_listener_parent_class->finalize (object);
64}
65
66static void
67bonobo_listener_class_init (BonoboListenerClass *klass)
68{
69        GtkObjectClass *oclass = (GtkObjectClass *)klass;
70        POA_Bonobo_Listener__epv *epv = &klass->epv;
71
72        bonobo_listener_parent_class = gtk_type_class (PARENT_TYPE);
73
74        oclass->finalize = bonobo_listener_finalize;
75
76        signals [EVENT_NOTIFY] = gtk_signal_new (
77                "event_notify", GTK_RUN_LAST, oclass->type,
78                GTK_SIGNAL_OFFSET (BonoboListenerClass, event_notify),
79                gtk_marshal_NONE__POINTER_POINTER_POINTER, GTK_TYPE_NONE, 3,
80                GTK_TYPE_POINTER, GTK_TYPE_POINTER, GTK_TYPE_POINTER);
81
82        gtk_object_class_add_signals (oclass, signals, LAST_SIGNAL);
83
84        epv->event = impl_Bonobo_Listener_event;
85}
86
87static void
88bonobo_listener_init (GtkObject *object)
89{
90        BonoboListener *listener;
91
92        listener = BONOBO_LISTENER(object);
93        listener->priv = g_new (BonoboListenerPrivate, 1);
94        listener->priv->event_callback = NULL;
95        listener->priv->user_data = NULL;
96}
97
98BONOBO_X_TYPE_FUNC_FULL (BonoboListener,
99                           Bonobo_Listener,
100                           PARENT_TYPE,
101                           bonobo_listener);
102
103/**
104 * bonobo_listener_new:
105 * @event_callback: function to be invoked when an event is emitted by the EventSource.
106 * @user_data: data passed to the functioned pointed by @event_call.
107 *
108 * Creates a generic event listener.  The listener calls the @event_callback
109 * function and emits an "event_notify" signal when notified of an event. 
110 * The signal callback should be of the form:
111 *
112 * <informalexample>
113 * <programlisting>
114 *      void some_callback (BonoboListener *listener,
115 *                          char *event_name,
116 *                          CORBA_any *any,
117 *                          CORBA_Environment *ev,
118 *                          gpointer user_data);
119 * </programlisting>
120 * </informalexample>
121 *
122 * You will typically pass the CORBA_Object reference in the return value
123 * to an EventSource (by invoking EventSource::addListener).
124 *
125 * Returns: A BonoboListener object.
126 */
127BonoboListener*
128bonobo_listener_new (BonoboListenerCallbackFn event_callback,
129                     gpointer                 user_data)
130{
131        BonoboListener *listener;
132
133        listener = gtk_type_new (BONOBO_LISTENER_TYPE);
134       
135        listener->priv->event_callback = event_callback;
136        listener->priv->user_data = user_data;
137
138        return listener;
139}
140
141
142/**
143 * bonobo_event_make_name:
144 * @idl_path: the IDL part of the event name.
145 * @kind: the kind of the event
146 * @subtype: an optional subtype
147 *
148 * Creates an event name. Event names consist of three parts. The @idl_path is
149 * mainly to create a unique namespace, and should identify the interface
150 * which triggered the event, for example "Bonobo/Property". The @kind denotes
151 * what happened, for example "change". Finally you can use the optional
152 * @subtype to make events more specific. All three parts of the name are
153 * joined together separated by colons. "Bonobo/Property:change" or
154 * "Bonobo/Property:change:autosave" are examples of valid event names.
155 *
156 * Returns: A valid event_name, or NULL on error.
157 */
158char *
159bonobo_event_make_name (const char *idl_path,
160                        const char *kind,
161                        const char *subtype)
162{
163        g_return_val_if_fail (idl_path != NULL, NULL);
164        g_return_val_if_fail (kind != NULL, NULL);
165        g_return_val_if_fail (!strchr (idl_path, ':'), NULL);
166        g_return_val_if_fail (!strchr (kind, ':'), NULL);
167        g_return_val_if_fail (!subtype || !strchr (subtype, ':'), NULL);
168        g_return_val_if_fail (strlen (idl_path), NULL);
169        g_return_val_if_fail (strlen (kind), NULL);
170
171        if (subtype)
172                return g_strconcat (idl_path, ":", kind, ":",
173                                    subtype, NULL);
174        else
175                return g_strconcat (idl_path, ":", kind, NULL);
176}
177
178static gboolean
179bonobo_event_name_valid (const char *event_name)
180{
181        gint i = 0, c = 0, l = -1;
182
183        g_return_val_if_fail (event_name != NULL, FALSE);
184        g_return_val_if_fail (strlen (event_name), FALSE);
185
186        if (event_name [0] == ':')
187                return FALSE;
188
189        if (event_name [strlen (event_name) - 1] == ':')
190                return FALSE;
191
192        while (event_name [i]) {
193                if (event_name [i] == ':') {
194                        if (l == (i -1))
195                                return FALSE;
196                        l = i;
197                        c++;
198                }
199                i++;
200        }
201
202        if ((c == 1) || (c == 2))
203                return TRUE;
204
205        return FALSE;
206}
207
208static char *
209bonobo_event_token (const char *event_name, gint pos)
210{
211        char **str_array, *res;
212
213        if (!bonobo_event_name_valid (event_name))
214                return NULL;
215
216        str_array = g_strsplit (event_name, ":", 3);
217
218        res = g_strdup (str_array [pos]);
219
220        g_strfreev (str_array);
221
222        return res;
223}
224
225/**
226 * bonobo_event_type:
227 * @event_name: the event name
228 *
229 * The event type consists of the first two parts of the event name, the idl_path
230 * combined with the kind.
231 *
232 * Returns: The event type, or NULL on error.
233 */
234char *
235bonobo_event_type (const char *event_name)
236{
237        gint i = 0, c = 0;
238       
239        if (!bonobo_event_name_valid (event_name))
240                return NULL;
241
242        while (event_name [i]) {
243                if (event_name [i] == ':')
244                        c++;
245                if (c == 2)
246                        break;
247                i++;
248        }
249
250        return g_strndup (event_name, i);
251}
252
253/**
254 * bonobo_event_type:
255 * @event_name: the event name
256 *
257 * Returns: The event subtype, or NULL on error.
258 */
259char *
260bonobo_event_subtype (const char *event_name)
261{
262        return bonobo_event_token (event_name, 2);
263}
264
265/**
266 * bonobo_event_kind:
267 * @event_name: the event name
268 *
269 * Returns: The event kind, or NULL on error.
270 */
271char *
272bonobo_event_kind (const char *event_name)
273{
274        return bonobo_event_token (event_name, 1);
275}
276
277/**
278 * bonobo_event_idl_path:
279 * @event_name: the event name
280 *
281 * Returns: The event idl path, or NULL on error.
282 */
283char *
284bonobo_event_idl_path (const char *event_name)
285{
286        return bonobo_event_token (event_name, 0);
287}
Note: See TracBrowser for help on using the repository browser.