]> git.sesse.net Git - vlc/blob - src/control/media_list.c
control/flat_media_list_view.c: Use the new media_list_view object. (Plus minor heade...
[vlc] / src / control / media_list.c
1 /*****************************************************************************
2  * media_list.c: libvlc new API media list functions
3  *****************************************************************************
4  * Copyright (C) 2007 the VideoLAN team
5  * $Id$
6  *
7  * Authors: Pierre d'Herbemont <pdherbemont # videolan.org>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22  *****************************************************************************/
23
24 #include "libvlc_internal.h"
25 #include <vlc/libvlc.h>
26 #include <assert.h>
27 #include "vlc_arrays.h"
28
29 /*
30  * Private functions
31  */
32
33
34
35 /**************************************************************************
36  *       notify_item_addition (private)
37  *
38  * Do the appropriate action when an item is deleted.
39  **************************************************************************/
40 static void
41 notify_item_addition( libvlc_media_list_t * p_mlist,
42                       libvlc_media_descriptor_t * p_md,
43                       int index )
44 {
45     libvlc_event_t event;
46
47     /* Construct the event */
48     event.type = libvlc_MediaListItemAdded;
49     event.u.media_list_item_added.item = p_md;
50     event.u.media_list_item_added.index = index;
51
52     /* Send the event */
53     libvlc_event_send( p_mlist->p_event_manager, &event );
54 }
55
56 /**************************************************************************
57  *       notify_item_deletion (private)
58  *
59  * Do the appropriate action when an item is added.
60  **************************************************************************/
61 static void
62 notify_item_deletion( libvlc_media_list_t * p_mlist,
63                       libvlc_media_descriptor_t * p_md,
64                       int index )
65 {
66     libvlc_event_t event;
67
68     /* Construct the event */
69     event.type = libvlc_MediaListItemDeleted;
70     event.u.media_list_item_deleted.item = p_md;
71     event.u.media_list_item_deleted.index = index;
72
73     /* Send the event */
74     libvlc_event_send( p_mlist->p_event_manager, &event );
75 }
76
77 /*
78  * Public libvlc functions
79  */
80
81 /**************************************************************************
82  *       libvlc_media_list_new (Public)
83  *
84  * Init an object.
85  **************************************************************************/
86 libvlc_media_list_t *
87 libvlc_media_list_new( libvlc_instance_t * p_inst,
88                        libvlc_exception_t * p_e )
89 {
90     libvlc_media_list_t * p_mlist;
91
92     p_mlist = malloc(sizeof(libvlc_media_list_t));
93
94     if( !p_mlist )
95         return NULL;
96  
97     p_mlist->p_libvlc_instance = p_inst;
98     p_mlist->p_event_manager = libvlc_event_manager_new( p_mlist, p_inst, p_e );
99
100     /* Code for that one should be handled in flat_media_list.c */
101     p_mlist->p_flat_mlist = NULL;
102
103     libvlc_event_manager_register_event_type( p_mlist->p_event_manager,
104             libvlc_MediaListItemAdded, p_e );
105     libvlc_event_manager_register_event_type( p_mlist->p_event_manager,
106             libvlc_MediaListItemDeleted, p_e );
107
108     if( libvlc_exception_raised( p_e ) )
109     {
110         libvlc_event_manager_release( p_mlist->p_event_manager );
111         free( p_mlist );
112         return NULL;
113     }
114
115     vlc_mutex_init( p_inst->p_libvlc_int, &p_mlist->object_lock );
116  
117     vlc_array_init( &p_mlist->items );
118     p_mlist->i_refcount = 1;
119     p_mlist->p_md = NULL;
120
121     return p_mlist;
122 }
123
124 /**************************************************************************
125  *       libvlc_media_list_release (Public)
126  *
127  * Release an object.
128  **************************************************************************/
129 void libvlc_media_list_release( libvlc_media_list_t * p_mlist )
130 {
131     libvlc_media_descriptor_t * p_md;
132     int i;
133
134     vlc_mutex_lock( &p_mlist->object_lock );
135     p_mlist->i_refcount--;
136     if( p_mlist->i_refcount > 0 )
137     {
138         vlc_mutex_unlock( &p_mlist->object_lock );
139         return;
140     }
141     vlc_mutex_unlock( &p_mlist->object_lock );
142
143     /* Refcount null, time to free */
144
145     libvlc_event_manager_release( p_mlist->p_event_manager );
146
147     if( p_mlist->p_md )
148         libvlc_media_descriptor_release( p_mlist->p_md );
149
150     for ( i = 0; i < vlc_array_count( &p_mlist->items ); i++ )
151     {
152         p_md = vlc_array_item_at_index( &p_mlist->items, i );
153         libvlc_media_descriptor_release( p_md );
154     }
155
156     vlc_mutex_destroy( &p_mlist->object_lock );
157     vlc_array_clear( &p_mlist->items );
158
159     free( p_mlist );
160 }
161
162 /**************************************************************************
163  *       libvlc_media_list_retain (Public)
164  *
165  * Increase an object refcount.
166  **************************************************************************/
167 void libvlc_media_list_retain( libvlc_media_list_t * p_mlist )
168 {
169     vlc_mutex_lock( &p_mlist->object_lock );
170     p_mlist->i_refcount++;
171     vlc_mutex_unlock( &p_mlist->object_lock );
172 }
173
174
175 /**************************************************************************
176  *       add_file_content (Public)
177  **************************************************************************/
178 void
179 libvlc_media_list_add_file_content( libvlc_media_list_t * p_mlist,
180                                     const char * psz_uri,
181                                     libvlc_exception_t * p_e )
182 {
183     input_item_t * p_input_item;
184     libvlc_media_descriptor_t * p_md;
185
186     p_input_item = input_ItemNewExt( p_mlist->p_libvlc_instance->p_libvlc_int, psz_uri,
187                                 _("Media Library"), 0, NULL, -1 );
188
189     if( !p_input_item )
190     {
191         libvlc_exception_raise( p_e, "Can't create an input item" );
192         return;
193     }
194
195     p_md = libvlc_media_descriptor_new_from_input_item(
196             p_mlist->p_libvlc_instance,
197             p_input_item, p_e );
198
199     if( !p_md )
200     {
201         vlc_gc_decref( p_input_item );
202         return;
203     }
204
205     libvlc_media_list_add_media_descriptor( p_mlist, p_md, p_e );
206     if( libvlc_exception_raised( p_e ) )
207         return;
208
209     input_Read( p_mlist->p_libvlc_instance->p_libvlc_int, p_input_item, VLC_TRUE );
210
211     return;
212 }
213
214 /**************************************************************************
215  *       set_media_descriptor (Public)
216  **************************************************************************/
217 void libvlc_media_list_set_media_descriptor( libvlc_media_list_t * p_mlist,
218                                              libvlc_media_descriptor_t * p_md,
219                                              libvlc_exception_t * p_e)
220
221 {
222     (void)p_e;
223     vlc_mutex_lock( &p_mlist->object_lock );
224     if( p_mlist->p_md )
225         libvlc_media_descriptor_release( p_mlist->p_md );
226     libvlc_media_descriptor_retain( p_md );
227     p_mlist->p_md = p_md;
228     vlc_mutex_unlock( &p_mlist->object_lock );
229 }
230
231 /**************************************************************************
232  *       media_descriptor (Public)
233  *
234  * If this media_list comes is a media_descriptor's subitems,
235  * This holds the corresponding media_descriptor.
236  * This md is also seen as the information holder for the media_list.
237  * Indeed a media_list can have meta information through this
238  * media_descriptor.
239  **************************************************************************/
240 libvlc_media_descriptor_t *
241 libvlc_media_list_media_descriptor( libvlc_media_list_t * p_mlist,
242                                     libvlc_exception_t * p_e)
243 {
244     libvlc_media_descriptor_t *p_md;
245     (void)p_e;
246
247     vlc_mutex_lock( &p_mlist->object_lock );
248     p_md = p_mlist->p_md;
249     if( p_md )
250         libvlc_media_descriptor_retain( p_md );
251     vlc_mutex_unlock( &p_mlist->object_lock );
252
253     return p_md;
254 }
255
256 /**************************************************************************
257  *       libvlc_media_list_count (Public)
258  *
259  * Lock should be hold when entering.
260  **************************************************************************/
261 int libvlc_media_list_count( libvlc_media_list_t * p_mlist,
262                              libvlc_exception_t * p_e )
263 {
264     (void)p_e;
265     return vlc_array_count( &p_mlist->items );
266 }
267
268 /**************************************************************************
269  *       libvlc_media_list_add_media_descriptor (Public)
270  *
271  * Lock should be hold when entering.
272  **************************************************************************/
273 void libvlc_media_list_add_media_descriptor(
274                                    libvlc_media_list_t * p_mlist,
275                                    libvlc_media_descriptor_t * p_md,
276                                    libvlc_exception_t * p_e )
277 {
278     (void)p_e;
279     libvlc_media_descriptor_retain( p_md );
280     vlc_array_append( &p_mlist->items, p_md );
281     notify_item_addition( p_mlist, p_md, vlc_array_count( &p_mlist->items )-1 );
282 }
283
284 /**************************************************************************
285  *       libvlc_media_list_insert_media_descriptor (Public)
286  *
287  * Lock should be hold when entering.
288  **************************************************************************/
289 void libvlc_media_list_insert_media_descriptor(
290                                    libvlc_media_list_t * p_mlist,
291                                    libvlc_media_descriptor_t * p_md,
292                                    int index,
293                                    libvlc_exception_t * p_e )
294 {
295     (void)p_e;
296     libvlc_media_descriptor_retain( p_md );
297
298     vlc_array_insert( &p_mlist->items, p_md, index );
299     notify_item_addition( p_mlist, p_md, index );
300 }
301
302 /**************************************************************************
303  *       libvlc_media_list_remove_index (Public)
304  *
305  * Lock should be hold when entering.
306  **************************************************************************/
307 void libvlc_media_list_remove_index( libvlc_media_list_t * p_mlist,
308                                      int index,
309                                      libvlc_exception_t * p_e )
310 {
311     libvlc_media_descriptor_t * p_md;
312
313     p_md = vlc_array_item_at_index( &p_mlist->items, index );
314
315     vlc_array_remove( &p_mlist->items, index );
316     notify_item_deletion( p_mlist, p_md, index );
317
318     libvlc_media_descriptor_release( p_md );
319 }
320
321 /**************************************************************************
322  *       libvlc_media_list_item_at_index (Public)
323  *
324  * Lock should be hold when entering.
325  **************************************************************************/
326 libvlc_media_descriptor_t *
327 libvlc_media_list_item_at_index( libvlc_media_list_t * p_mlist,
328                                  int index,
329                                  libvlc_exception_t * p_e )
330 {
331     libvlc_media_descriptor_t * p_md;
332     p_md = vlc_array_item_at_index( &p_mlist->items, index );
333     libvlc_media_descriptor_retain( p_md );
334     return p_md;
335 }
336
337 /**************************************************************************
338  *       libvlc_media_list_index_of_item (Public)
339  *
340  * Lock should be hold when entering.
341  * Warning: this function would return the first matching item
342  **************************************************************************/
343 int libvlc_media_list_index_of_item( libvlc_media_list_t * p_mlist,
344                                      libvlc_media_descriptor_t * p_searched_md,
345                                      libvlc_exception_t * p_e )
346 {
347     libvlc_media_descriptor_t * p_md;
348     int i;
349     for ( i = 0; i < vlc_array_count( &p_mlist->items ); i++ )
350     {
351         p_md = vlc_array_item_at_index( &p_mlist->items, i );
352         if( p_searched_md == p_md )
353             return i;
354     }
355     return -1;
356 }
357
358 /**************************************************************************
359  *       libvlc_media_list_lock (Public)
360  *
361  * The lock must be held in access operations. It is never used in the
362  * Public method.
363  **************************************************************************/
364 void libvlc_media_list_lock( libvlc_media_list_t * p_mlist )
365 {
366     vlc_mutex_lock( &p_mlist->object_lock );
367 }
368
369
370 /**************************************************************************
371  *       libvlc_media_list_unlock (Public)
372  *
373  * The lock must be held in access operations
374  **************************************************************************/
375 void libvlc_media_list_unlock( libvlc_media_list_t * p_mlist )
376 {
377     vlc_mutex_unlock( &p_mlist->object_lock );
378 }
379
380
381
382 /**************************************************************************
383  *       libvlc_media_list_p_event_manager (Public)
384  *
385  * The p_event_manager is immutable, so you don't have to hold the lock
386  **************************************************************************/
387 libvlc_event_manager_t *
388 libvlc_media_list_event_manager( libvlc_media_list_t * p_mlist,
389                                     libvlc_exception_t * p_e )
390 {
391     (void)p_e;
392     return p_mlist->p_event_manager;
393 }