direct3d11: pick the best swapchain colorspace for the source video
[vlc.git] / lib / event.c
blobe6ec83c556cbf884c6ebb82d3823460e9641802d
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 (size_t 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 (size_t 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)
204 DEF(MediaPlayerChapterChanged)
206 DEF(MediaListItemAdded)
207 DEF(MediaListWillAddItem)
208 DEF(MediaListItemDeleted)
209 DEF(MediaListWillDeleteItem)
210 DEF(MediaListEndReached)
212 DEF(MediaListViewItemAdded)
213 DEF(MediaListViewWillAddItem)
214 DEF(MediaListViewItemDeleted)
215 DEF(MediaListViewWillDeleteItem)
217 DEF(MediaListPlayerPlayed)
218 DEF(MediaListPlayerNextItemSet)
219 DEF(MediaListPlayerStopped)
221 DEF(MediaDiscovererStarted)
222 DEF(MediaDiscovererEnded)
224 DEF(VlmMediaAdded)
225 DEF(VlmMediaRemoved)
226 DEF(VlmMediaChanged)
227 DEF(VlmMediaInstanceStarted)
228 DEF(VlmMediaInstanceStopped)
229 DEF(VlmMediaInstanceStatusInit)
230 DEF(VlmMediaInstanceStatusOpening)
231 DEF(VlmMediaInstanceStatusPlaying)
232 DEF(VlmMediaInstanceStatusPause)
233 DEF(VlmMediaInstanceStatusEnd)
234 DEF(VlmMediaInstanceStatusError)
236 #undef DEF
238 static const char unknown_event_name[] = "Unknown Event";
240 static int evcmp( const void *a, const void *b )
242 return (*(const int *)a) - ((event_name_t *)b)->type;
245 const char * libvlc_event_type_name( int event_type )
247 const event_name_t *p;
249 p = bsearch( &event_type, event_list,
250 sizeof(event_list)/sizeof(event_list[0]), sizeof(*p),
251 evcmp );
252 return p ? p->name : unknown_event_name;
255 /**************************************************************************
256 * libvlc_event_attach (public) :
258 * Add a callback for an event.
259 **************************************************************************/
260 int libvlc_event_attach(libvlc_event_manager_t *em, libvlc_event_type_t type,
261 libvlc_callback_t callback, void *opaque)
263 libvlc_event_listener_t *listener = malloc(sizeof (*listener));
264 if (unlikely(listener == NULL))
265 return ENOMEM;
267 listener->event_type = type;
268 listener->p_user_data = opaque;
269 listener->pf_callback = callback;
271 vlc_mutex_lock(&em->lock);
272 vlc_array_append(&em->listeners, listener);
273 vlc_mutex_unlock(&em->lock);
274 return 0;
277 /**************************************************************************
278 * libvlc_event_detach (public) :
280 * Remove a callback for an event.
281 **************************************************************************/
282 void libvlc_event_detach(libvlc_event_manager_t *em, libvlc_event_type_t type,
283 libvlc_callback_t callback, void *opaque)
285 vlc_mutex_lock(&em->lock);
286 for (size_t i = 0; i < vlc_array_count(&em->listeners); i++)
288 libvlc_event_listener_t *listener;
290 listener = vlc_array_item_at_index(&em->listeners, i);
292 if (listener->event_type == type
293 && listener->pf_callback == callback
294 && listener->p_user_data == opaque)
295 { /* that's our listener */
296 vlc_array_remove(&em->listeners, i);
297 vlc_mutex_unlock(&em->lock);
298 free(listener);
299 return;
302 abort();