Merged Michael's branch back into HEAD, and fixed a number of reference counting...
[platform/core/uifw/at-spi2-atk.git] / libspi / eventlistener.c
1 /*
2  * AT-SPI - Assistive Technology Service Provider Interface
3  * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
4  *
5  * Copyright 2001 Sun Microsystems Inc.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22
23 /* accessibleeventlistener.c: implementation of SpiListener.idl */
24
25 #include <config.h>
26 #ifdef SPI_DEBUG
27 #include <stdio.h>
28 #endif
29 #include <libspi/accessibleeventlistener.h>
30
31 /* Our parent Gtk object type */
32 #define PARENT_TYPE SPI_LISTENER_TYPE
33
34 /* A pointer to our parent object class */
35 static SpiListenerClass *spi_event_listener_parent_class;
36
37 enum {
38         EVENT,
39         LAST_SIGNAL
40 };
41 static guint signals [LAST_SIGNAL];
42
43 /*
44  * Implemented GObject::finalize
45  */
46 static void
47 spi_event_listener_object_finalize (GObject *object)
48 {
49         SpiEventListener *listener = SPI_ACCESSIBLE_EVENT_SPI_LISTENER (object);
50 #ifdef SPI_DEBUG
51         fprintf(stderr, "spi_listener_object_finalize called\n");
52 #endif
53         g_list_free (listener->callbacks);
54
55         ((GObjectClass *) spi_event_listener_parent_class)->finalize (object);
56 }
57
58 /*
59  * CORBA Accessibility::Listener::notifyEvent method implementation
60  */
61
62 static void
63 impl_accessible_event_notify_event (PortableServer_Servant     servant,
64                                     const Accessibility_Event *e,
65                                     CORBA_Environment         *ev)
66 {
67   GList *l;
68   VoidSpiEventListenerCB cb;
69   SpiEventListener *listener = SPI_ACCESSIBLE_EVENT_SPI_LISTENER (
70                                        bonobo_object_from_servant (servant));
71
72   for (l = listener->callbacks; l; l = l->next)
73     {
74       cb = (VoidSpiEventListenerCB) l->data;
75       if (cb)
76         {
77           (*cb) (e);
78         }
79     }
80
81   g_signal_emit (G_OBJECT (listener), signals [EVENT], 0, e); 
82 }
83
84 static void
85 spi_event_listener_class_init (SpiEventListenerClass *klass)
86 {
87         GObjectClass * object_class = (GObjectClass *) klass;
88         SpiListenerClass * spi_listener_class = (SpiListenerClass *) klass;
89         POA_Accessibility_EventListener__epv *epv = &spi_listener_class->epv;
90         spi_event_listener_parent_class = g_type_class_ref (SPI_LISTENER_TYPE);
91
92         signals [EVENT] = g_signal_new (
93                 "event",
94                 G_TYPE_FROM_CLASS (klass),
95                 G_SIGNAL_RUN_LAST,
96                 G_STRUCT_OFFSET (SpiEventListenerClass, event),
97                 NULL, NULL,
98                 g_cclosure_marshal_VOID__POINTER,
99                 G_TYPE_NONE, 1, G_TYPE_POINTER);
100
101         object_class->finalize = spi_event_listener_object_finalize;
102
103         epv->notifyEvent = impl_accessible_event_notify_event;
104 }
105
106 static void
107 spi_event_listener_init (SpiEventListener *listener)
108 {
109         listener->callbacks = NULL;
110 }
111
112 BONOBO_TYPE_FUNC (SpiEventListener,
113                   PARENT_TYPE,
114                   spi_event_listener);
115
116 SpiEventListener *
117 spi_event_listener_new ()
118 {
119     SpiEventListener *retval = g_object_new (
120             SPI_ACCESSIBLE_EVENT_SPI_LISTENER_TYPE, NULL);
121     return retval;
122 }
123
124 void
125 spi_event_listener_add_callback (SpiEventListener *listener,
126                                  VoidSpiEventListenerCB callback)
127 {
128   listener->callbacks = g_list_prepend (listener->callbacks, callback);
129 }
130
131 void
132 spi_event_listener_remove_callback (SpiEventListener *listener,
133                                     VoidSpiEventListenerCB callback)
134 {
135   listener->callbacks = g_list_remove (listener->callbacks, callback);
136 }