1 /*****************************************************************************
2 * events.c: events interface
3 * This library provides an interface to the send and receive events.
4 * It is more lightweight than variable based callback.
5 *****************************************************************************
6 * Copyright (C) 1998-2005 VLC authors and VideoLAN
9 * Authors: Pierre d'Herbemont <pdherbemont # videolan.org >
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU Lesser General Public License as published by
13 * the Free Software Foundation; either version 2.1 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public License
22 * along with this program; if not, write to the Free Software Foundation,
23 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
24 *****************************************************************************/
26 /*****************************************************************************
28 *****************************************************************************/
34 #include <vlc_common.h>
38 #include <vlc_events.h>
39 #include <vlc_arrays.h>
41 /*****************************************************************************
42 * Documentation : Read vlc_events.h
43 *****************************************************************************/
45 /*****************************************************************************
47 *****************************************************************************/
49 typedef struct vlc_event_listener_t
52 vlc_event_callback_t pf_callback
;
53 } vlc_event_listener_t
;
55 /*****************************************************************************
57 *****************************************************************************/
59 #undef vlc_event_manager_init
61 * Initialize event manager object
62 * p_obj is the object that contains the event manager. But not
63 * necessarily a vlc_object_t (an input_item_t is not a vlc_object_t
66 void vlc_event_manager_init( vlc_event_manager_t
* p_em
, void * p_obj
)
69 /* This is an unsafe work-around for a long-standing playlist bug.
70 * Do not rely on this. */
71 vlc_mutex_init_recursive( &p_em
->lock
);
73 for( size_t i
= 0; i
< ARRAY_SIZE(p_em
->events
); i
++ )
74 ARRAY_INIT( p_em
->events
[i
].listeners
);
78 * Destroy the event manager
80 void vlc_event_manager_fini( vlc_event_manager_t
* p_em
)
82 struct vlc_event_listener_t
* listener
;
84 vlc_mutex_destroy( &p_em
->lock
);
86 for( size_t i
= 0; i
< ARRAY_SIZE(p_em
->events
); i
++ )
88 struct vlc_event_listeners_group_t
*slot
= p_em
->events
+ i
;
90 ARRAY_FOREACH( listener
, slot
->listeners
)
93 ARRAY_RESET( slot
->listeners
);
98 * Send an event to the listener attached to this p_em.
100 void vlc_event_send( vlc_event_manager_t
* p_em
,
101 vlc_event_t
* p_event
)
103 vlc_event_listeners_group_t
*slot
= &p_em
->events
[p_event
->type
];
104 vlc_event_listener_t
* listener
;
106 /* Fill event with the sending object now */
107 p_event
->p_obj
= p_em
->p_obj
;
109 vlc_mutex_lock( &p_em
->lock
) ;
111 ARRAY_FOREACH( listener
, slot
->listeners
)
112 listener
->pf_callback( p_event
, listener
->p_user_data
);
114 vlc_mutex_unlock( &p_em
->lock
);
117 #undef vlc_event_attach
119 * Add a callback for an event.
121 int vlc_event_attach( vlc_event_manager_t
* p_em
,
122 vlc_event_type_t event_type
,
123 vlc_event_callback_t pf_callback
,
126 vlc_event_listener_t
* listener
;
127 vlc_event_listeners_group_t
*slot
= &p_em
->events
[event_type
];
129 listener
= malloc(sizeof(vlc_event_listener_t
));
133 listener
->p_user_data
= p_user_data
;
134 listener
->pf_callback
= pf_callback
;
136 vlc_mutex_lock( &p_em
->lock
);
137 ARRAY_APPEND( slot
->listeners
, listener
);
138 vlc_mutex_unlock( &p_em
->lock
);
143 * Remove a callback for an event.
146 void vlc_event_detach( vlc_event_manager_t
*p_em
,
147 vlc_event_type_t event_type
,
148 vlc_event_callback_t pf_callback
,
151 vlc_event_listeners_group_t
*slot
= &p_em
->events
[event_type
];
153 vlc_mutex_lock( &p_em
->lock
);
155 for (int i
= 0; i
< slot
->listeners
.i_size
; ++i
)
157 struct vlc_event_listener_t
*listener
= slot
->listeners
.p_elems
[i
];
158 if( listener
->pf_callback
== pf_callback
&&
159 listener
->p_user_data
== p_user_data
)
161 /* that's our listener */
162 ARRAY_REMOVE( slot
->listeners
, i
);
163 vlc_mutex_unlock( &p_em
->lock
);
169 vlc_assert_unreachable();