sout/rtsp: remove senseless free
[vlc.git] / lib / event.c
blob9f0d1b661bd9b825e7e11c89c3052c1e91acb6bd
1 /*****************************************************************************
2 * event.c: New libvlc event control API
3 *****************************************************************************
4 * Copyright (C) 2007-2010 VLC authors and VideoLAN
5 * $Id $
7 * Authors: Filippo Carone <filippo@carone.org>
8 * Pierre d'Herbemont <pdherbemont # videolan.org>
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU Lesser General Public License as published by
12 * the Free Software Foundation; either version 2.1 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with this program; if not, write to the Free Software Foundation,
22 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23 *****************************************************************************/
25 #ifdef HAVE_CONFIG_H
26 # include "config.h"
27 #endif
29 #include <assert.h>
30 #include <errno.h>
32 #include <vlc/libvlc.h>
33 #include "libvlc_internal.h"
35 #include <vlc_common.h>
38 * Event Handling
41 /* Example usage
43 * struct libvlc_cool_object_t
44 * {
45 * ...
46 * libvlc_event_manager_t * p_event_manager;
47 * ...
48 * }
50 * libvlc_my_cool_object_new()
51 * {
52 * ...
53 * p_self->p_event_manager = libvlc_event_manager_new( p_self )
54 * ...
55 * }
57 * libvlc_my_cool_object_release()
58 * {
59 * ...
60 * libvlc_event_manager_release( p_self->p_event_manager );
61 * ...
62 * }
64 * libvlc_my_cool_object_do_something()
65 * {
66 * ...
67 * libvlc_event_t event;
68 * event.type = libvlc_MyCoolObjectDidSomething;
69 * event.u.my_cool_object_did_something.what_it_did = kSomething;
70 * libvlc_event_send( p_self->p_event_manager, &event );
71 * }
72 * */
74 typedef struct libvlc_event_listener_t
76 libvlc_event_type_t event_type;
77 void * p_user_data;
78 libvlc_callback_t pf_callback;
79 } libvlc_event_listener_t;
81 typedef struct libvlc_event_manager_t
83 void * p_obj;
84 vlc_array_t listeners;
85 vlc_mutex_t lock;
86 } libvlc_event_sender_t;
89 * Internal libvlc functions
92 /**************************************************************************
93 * libvlc_event_manager_new (internal) :
95 * Init an object's event manager.
96 **************************************************************************/
97 libvlc_event_manager_t *
98 libvlc_event_manager_new( void * p_obj )
100 libvlc_event_manager_t * p_em;
102 p_em = malloc(sizeof( libvlc_event_manager_t ));
103 if( !p_em )
105 libvlc_printerr( "Not enough memory" );
106 return NULL;
109 p_em->p_obj = p_obj;
110 vlc_array_init(&p_em->listeners);
111 vlc_mutex_init_recursive(&p_em->lock);
112 return p_em;
115 /**************************************************************************
116 * libvlc_event_manager_release (internal) :
118 * Release an object's event manager.
119 **************************************************************************/
120 void libvlc_event_manager_release( libvlc_event_manager_t * p_em )
122 vlc_mutex_destroy(&p_em->lock);
124 for (int i = 0; i < vlc_array_count(&p_em->listeners); i++)
125 free(vlc_array_item_at_index(&p_em->listeners, i));
127 vlc_array_clear(&p_em->listeners);
128 free( p_em );
131 /**************************************************************************
132 * libvlc_event_send (internal) :
134 * Send a callback.
135 **************************************************************************/
136 void libvlc_event_send( libvlc_event_manager_t * p_em,
137 libvlc_event_t * p_event )
139 /* Fill event with the sending object now */
140 p_event->p_obj = p_em->p_obj;
142 vlc_mutex_lock(&p_em->lock);
143 for (int i = 0; i < vlc_array_count(&p_em->listeners); i++)
145 libvlc_event_listener_t *listener;
147 listener = vlc_array_item_at_index(&p_em->listeners, i);
148 if (listener->event_type == p_event->type)
149 listener->pf_callback(p_event, listener->p_user_data);
151 vlc_mutex_unlock(&p_em->lock);
155 * Public libvlc functions
158 #define DEF( a ) { libvlc_##a, #a, },
160 typedef struct
162 int type;
163 const char name[40];
164 } event_name_t;
166 static const event_name_t event_list[] = {
167 DEF(MediaMetaChanged)
168 DEF(MediaSubItemAdded)
169 DEF(MediaDurationChanged)
170 DEF(MediaParsedChanged)
171 DEF(MediaFreed)
172 DEF(MediaStateChanged)
173 DEF(MediaSubItemTreeAdded)
175 DEF(MediaPlayerMediaChanged)
176 DEF(MediaPlayerNothingSpecial)
177 DEF(MediaPlayerOpening)
178 DEF(MediaPlayerBuffering)
179 DEF(MediaPlayerPlaying)
180 DEF(MediaPlayerPaused)
181 DEF(MediaPlayerStopped)
182 DEF(MediaPlayerForward)
183 DEF(MediaPlayerBackward)
184 DEF(MediaPlayerEndReached)
185 DEF(MediaPlayerEncounteredError)
186 DEF(MediaPlayerTimeChanged)
187 DEF(MediaPlayerPositionChanged)
188 DEF(MediaPlayerSeekableChanged)
189 DEF(MediaPlayerPausableChanged)
190 DEF(MediaPlayerTitleChanged)
191 DEF(MediaPlayerSnapshotTaken)
192 DEF(MediaPlayerLengthChanged)
193 DEF(MediaPlayerVout)
194 DEF(MediaPlayerScrambledChanged)
195 DEF(MediaPlayerESAdded)
196 DEF(MediaPlayerESDeleted)
197 DEF(MediaPlayerESSelected)
198 DEF(MediaPlayerCorked)
199 DEF(MediaPlayerUncorked)
200 DEF(MediaPlayerMuted)
201 DEF(MediaPlayerUnmuted)
202 DEF(MediaPlayerAudioVolume)
203 DEF(MediaPlayerAudioDevice)
205 DEF(MediaListItemAdded)
206 DEF(MediaListWillAddItem)
207 DEF(MediaListItemDeleted)
208 DEF(MediaListWillDeleteItem)
210 DEF(MediaListViewItemAdded)
211 DEF(MediaListViewWillAddItem)
212 DEF(MediaListViewItemDeleted)
213 DEF(MediaListViewWillDeleteItem)
215 DEF(MediaListPlayerPlayed)
216 DEF(MediaListPlayerNextItemSet)
217 DEF(MediaListPlayerStopped)
219 DEF(MediaDiscovererStarted)
220 DEF(MediaDiscovererEnded)
222 DEF(VlmMediaAdded)
223 DEF(VlmMediaRemoved)
224 DEF(VlmMediaChanged)
225 DEF(VlmMediaInstanceStarted)
226 DEF(VlmMediaInstanceStopped)
227 DEF(VlmMediaInstanceStatusInit)
228 DEF(VlmMediaInstanceStatusOpening)
229 DEF(VlmMediaInstanceStatusPlaying)
230 DEF(VlmMediaInstanceStatusPause)
231 DEF(VlmMediaInstanceStatusEnd)
232 DEF(VlmMediaInstanceStatusError)
234 #undef DEF
236 static const char unknown_event_name[] = "Unknown Event";
238 static int evcmp( const void *a, const void *b )
240 return (*(const int *)a) - ((event_name_t *)b)->type;
243 const char * libvlc_event_type_name( int event_type )
245 const event_name_t *p;
247 p = bsearch( &event_type, event_list,
248 sizeof(event_list)/sizeof(event_list[0]), sizeof(*p),
249 evcmp );
250 return p ? p->name : unknown_event_name;
253 /**************************************************************************
254 * libvlc_event_attach (public) :
256 * Add a callback for an event.
257 **************************************************************************/
258 int libvlc_event_attach(libvlc_event_manager_t *em, libvlc_event_type_t type,
259 libvlc_callback_t callback, void *opaque)
261 libvlc_event_listener_t *listener = malloc(sizeof (*listener));
262 if (unlikely(listener == NULL))
263 return ENOMEM;
265 listener->event_type = type;
266 listener->p_user_data = opaque;
267 listener->pf_callback = callback;
269 vlc_mutex_lock(&em->lock);
270 vlc_array_append(&em->listeners, listener);
271 vlc_mutex_unlock(&em->lock);
272 return 0;
275 /**************************************************************************
276 * libvlc_event_detach (public) :
278 * Remove a callback for an event.
279 **************************************************************************/
280 void libvlc_event_detach(libvlc_event_manager_t *em, libvlc_event_type_t type,
281 libvlc_callback_t callback, void *opaque)
283 vlc_mutex_lock(&em->lock);
284 for (int i = 0; i < vlc_array_count(&em->listeners); i++)
286 libvlc_event_listener_t *listener;
288 listener = vlc_array_item_at_index(&em->listeners, i);
290 if (listener->event_type == type
291 && listener->pf_callback == callback
292 && listener->p_user_data == opaque)
293 { /* that's our listener */
294 vlc_array_remove(&em->listeners, i);
295 vlc_mutex_unlock(&em->lock);
296 free(listener);
297 return;
300 abort();