1 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
2 *****************************************************************************/
4 /*****************************************************************************
6 *****************************************************************************/
12 #include <vlc_events.h>
13 #include <vlc_arrays.h>
15 /*****************************************************************************
16 * Documentation : Read vlc_events.h
17 *****************************************************************************/
19 /*****************************************************************************
21 *****************************************************************************/
23 typedef struct vlc_event_listener_t
26 vlc_event_callback_t pf_callback;
27 } vlc_event_listener_t;
29 typedef struct vlc_event_listeners_group_t
31 vlc_event_type_t event_type;
32 DECL_ARRAY(struct vlc_event_listener_t *) listeners;
33 } vlc_event_listeners_group_t;
35 /*****************************************************************************
37 *****************************************************************************/
40 * Initialize event manager object
41 * p_obj is the object that contains the event manager. But not
42 * necessarily a vlc_object_t (an input_item_t is not a vlc_object_t
44 * p_parent_obj gives a libvlc instance
46 int vlc_event_manager_init( vlc_event_manager_t * p_em, void * p_obj,
47 vlc_object_t * p_parent_obj )
50 vlc_mutex_init( p_parent_obj, &p_em->object_lock );
51 ARRAY_INIT( p_em->listeners_groups );
56 * Destroy the event manager
58 void vlc_event_manager_fini( vlc_event_manager_t * p_em )
60 struct vlc_event_listeners_group_t * listeners_group;
61 struct vlc_event_listener_t * listener;
63 vlc_mutex_destroy( &p_em->object_lock );
65 FOREACH_ARRAY( listeners_group, p_em->listeners_groups )
66 FOREACH_ARRAY( listener, listeners_group->listeners )
69 free( listeners_group );
74 * Destroy the event manager
76 int vlc_event_manager_register_event_type(
77 vlc_event_manager_t * p_em,
78 vlc_event_type_t event_type )
80 vlc_event_listeners_group_t * listeners_group;
81 listeners_group = malloc(sizeof(vlc_event_listeners_group_t));
83 if( !listeners_group )
86 listeners_group->event_type = event_type;
87 ARRAY_INIT( listeners_group->listeners );
89 vlc_mutex_lock( &p_em->object_lock );
90 ARRAY_APPEND( p_em->listeners_groups, listeners_group );
91 vlc_mutex_unlock( &p_em->object_lock );
97 * Send an event to the listener attached to this p_em.
99 void vlc_event_send( vlc_event_manager_t * p_em,
100 vlc_event_t * p_event )
102 vlc_event_listeners_group_t * listeners_group;
103 vlc_event_listener_t * listener;
104 vlc_event_callback_t func = NULL;
105 void * user_data = NULL;
107 /* Fill event with the sending object now */
108 p_event->p_obj = p_em->p_obj;
110 vlc_mutex_lock( &p_em->object_lock );
111 FOREACH_ARRAY( listeners_group, p_em->listeners_groups )
112 if( listeners_group->event_type == p_event->type )
114 /* We found the group, now send every one the event */
115 FOREACH_ARRAY( listener, listeners_group->listeners )
116 func = listener->pf_callback;
117 user_data = listener->p_user_data;
118 /* This is safe to do that because we are sure
119 * that there will be no object owned references
120 * used after the lock. */
121 vlc_mutex_unlock( &p_em->object_lock );
122 func( p_event, user_data );
123 vlc_mutex_lock( &p_em->object_lock );
128 vlc_mutex_unlock( &p_em->object_lock );
132 * Add a callback for an event.
134 int vlc_event_attach( vlc_event_manager_t * p_em,
135 vlc_event_type_t event_type,
136 vlc_event_callback_t pf_callback,
139 vlc_event_listeners_group_t * listeners_group;
140 vlc_event_listener_t * listener;
141 listener = malloc(sizeof(vlc_event_listener_t));
145 listener->p_user_data = p_user_data;
146 listener->pf_callback = pf_callback;
148 vlc_mutex_lock( &p_em->object_lock );
149 FOREACH_ARRAY( listeners_group, p_em->listeners_groups )
150 if( listeners_group->event_type == event_type )
152 ARRAY_APPEND( listeners_group->listeners, listener );
153 vlc_mutex_unlock( &p_em->object_lock );
157 vlc_mutex_unlock( &p_em->object_lock );
164 * Remove a callback for an event.
166 int vlc_event_detach( vlc_event_manager_t *p_em,
167 vlc_event_type_t event_type,
168 vlc_event_callback_t pf_callback,
171 vlc_event_listeners_group_t * listeners_group;
172 struct vlc_event_listener_t * listener;
174 vlc_mutex_lock( &p_em->object_lock );
175 FOREACH_ARRAY( listeners_group, p_em->listeners_groups )
176 if( listeners_group->event_type == event_type )
178 FOREACH_ARRAY( listener, listeners_group->listeners )
179 if( listener->pf_callback == pf_callback &&
180 listener->p_user_data == p_user_data )
182 /* that's our listener */
183 ARRAY_REMOVE( listeners_group->listeners,
184 fe_idx /* This comes from the macro (and that's why
187 vlc_mutex_unlock( &p_em->object_lock );
193 vlc_mutex_unlock( &p_em->object_lock );