]> git.sesse.net Git - vlc/blob - modules/gui/beos/VlcWrapper.cpp
* Makefile.am: fixed 'make package-beos'
[vlc] / modules / gui / beos / VlcWrapper.cpp
1 /*****************************************************************************
2  * VlcWrapper.cpp: BeOS plugin for vlc (derived from MacOS X port)
3  *****************************************************************************
4  * Copyright (C) 2001 VideoLAN
5  * $Id: VlcWrapper.cpp,v 1.27 2003/04/22 16:36:16 titer Exp $
6  *
7  * Authors: Florian G. Pflug <fgp@phlo.org>
8  *          Jon Lech Johansen <jon-vl@nanocrew.net>
9  *          Tony Casltey <tony@castley.net>
10  *          Stephan Aßmus <stippi@yellowbites.com>
11  *          Eric Petit <titer@videolan.org>
12  *
13  * This program is free software{} you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License as published by
15  * the Free Software Foundation{} either version 2 of the License, or
16  * (at your option) any later version.
17  * 
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY{} without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program{} if not, write to the Free Software
25  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
26  *****************************************************************************/
27 #include <AppKit.h>
28 #include <InterfaceKit.h>
29 #include <SupportKit.h>
30
31 #include <vlc/vlc.h>
32 #include <vlc/intf.h>
33 #include <vlc/vout.h>
34 extern "C"
35 {
36   #include <input_ext-plugins.h>        // needed here when compiling without plugins
37   #include <audio_output.h>
38   #include <aout_internal.h>
39 }
40
41 #include "VlcWrapper.h"
42 #include "MsgVals.h"
43
44 const char * _AddEllipsis( char * string )
45 {
46     BString newString( string );
47     newString << B_UTF8_ELLIPSIS;
48     return newString.String();
49 }
50
51 /* constructor */
52 VlcWrapper::VlcWrapper( intf_thread_t *p_interface )
53 {
54     p_intf = p_interface;
55     p_input = NULL;
56     p_playlist = (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
57                                                 FIND_ANYWHERE );
58 }
59
60 /* destructor */
61 VlcWrapper::~VlcWrapper()
62 {
63     if( p_input )
64     {
65         vlc_object_release( p_input );
66     }
67     if( p_playlist )
68     {
69         vlc_object_release( p_playlist );
70     }
71 }
72
73 /* UpdateInput: updates p_input, returns true if the interface needs to
74    be updated */
75 bool VlcWrapper::UpdateInput()
76 {
77     if( p_input == NULL )
78     {
79         p_input = (input_thread_t *)vlc_object_find( p_intf, VLC_OBJECT_INPUT,
80                                                      FIND_ANYWHERE );
81     }
82         
83     if( p_input != NULL )
84     {
85         if( p_input->b_dead )
86         {
87             vlc_object_release( p_input );
88             p_input = NULL;
89         }
90         return true;
91     }
92     return false;
93 }
94
95
96 /***************************
97  * input infos and control *
98  ***************************/
99
100 bool VlcWrapper::HasInput()
101 {
102     return ( p_input != NULL );
103 }
104
105 int VlcWrapper::InputStatus()
106 {
107     if( !p_input )
108     {
109         return UNDEF_S;
110     }
111     return p_input->stream.control.i_status;
112 }
113
114 int VlcWrapper::InputRate()
115 {
116     if( !p_input )
117     {
118         return DEFAULT_RATE;
119     }
120     return p_input->stream.control.i_rate;
121 }
122
123 void VlcWrapper::InputSlower()
124 {
125     if( p_input != NULL )
126     {
127         input_SetStatus( p_input, INPUT_STATUS_SLOWER );
128     }
129 }
130
131 void VlcWrapper::InputFaster()
132 {
133     if( p_input != NULL )
134     {
135         input_SetStatus( p_input, INPUT_STATUS_FASTER );
136     }
137 }
138
139 BList * VlcWrapper::GetChannels( int i_cat )
140 {
141     if( p_input )
142     {
143         unsigned int i;
144         uint32 what;
145         const char* fieldName;
146
147         switch( i_cat )
148         {
149             case AUDIO_ES:
150             {
151                 what = SELECT_CHANNEL;
152                 fieldName = "channel";
153                 break;
154             }
155             case SPU_ES:
156             {
157                 what = SELECT_SUBTITLE;
158                 fieldName = "subtitle";
159                 break;
160             }
161             default:
162             return NULL;
163        }
164
165         vlc_mutex_lock( &p_input->stream.stream_lock );
166       
167         /* find which track is currently playing */
168         es_descriptor_t *p_es = NULL;
169         for( i = 0; i < p_input->stream.i_selected_es_number; i++ )
170         {
171             if( p_input->stream.pp_selected_es[i]->i_cat == i_cat )
172                 p_es = p_input->stream.pp_selected_es[i];
173         }
174         
175         /* build a list of all tracks */
176         BList *list = new BList( p_input->stream.i_es_number );
177         BMenuItem *menuItem;
178         BMessage *message;
179         char *trackName;
180         
181         /* "None" */
182         message = new BMessage( what );
183         message->AddInt32( fieldName, -1 );
184         menuItem = new BMenuItem( _("None"), message );
185         if( !p_es )
186             menuItem->SetMarked( true );
187         list->AddItem( menuItem );
188         
189         for( i = 0; i < p_input->stream.i_es_number; i++ )
190         {
191             if( p_input->stream.pp_es[i]->i_cat == i_cat )
192             {
193                 message = new BMessage( what );
194                 message->AddInt32( fieldName, i );
195                 if( strlen( p_input->stream.pp_es[i]->psz_desc ) )
196                     trackName = strdup( p_input->stream.pp_es[i]->psz_desc );
197                 else
198                     trackName = _("<unknown>");
199                 menuItem = new BMenuItem( trackName, message );
200                 if( p_input->stream.pp_es[i] == p_es )
201                     menuItem->SetMarked( true );
202                 list->AddItem( menuItem );
203             }
204         }
205         
206         vlc_mutex_unlock( &p_input->stream.stream_lock );
207
208         return list;
209     }
210     return NULL;
211 }
212
213 void VlcWrapper::ToggleLanguage( int i_language )
214 {
215     es_descriptor_t * p_es = NULL;
216     es_descriptor_t * p_es_old = NULL;
217
218     vlc_mutex_lock( &p_input->stream.stream_lock );
219     for( unsigned int i = 0; i < p_input->stream.i_selected_es_number ; i++ )
220     {
221         if( p_input->stream.pp_selected_es[i]->i_cat == AUDIO_ES )
222         {
223             p_es_old = p_input->stream.pp_selected_es[i];
224             break;
225         }
226     }
227     vlc_mutex_unlock( &p_input->stream.stream_lock );
228     
229     if( i_language != -1 )
230     {
231         p_es = p_input->stream.pp_es[i_language];
232     }
233     if( p_es == p_es_old )
234     {
235         return;
236     }
237     if( p_es_old )
238     {
239         input_ToggleES( p_input, p_es_old, VLC_FALSE );
240     }
241     if( p_es )
242     {
243         input_ToggleES( p_input, p_es, VLC_TRUE );
244     }
245 }
246
247 void VlcWrapper::ToggleSubtitle( int i_subtitle )
248 {
249     es_descriptor_t * p_es = NULL;
250     es_descriptor_t * p_es_old = NULL;
251
252     vlc_mutex_lock( &p_input->stream.stream_lock );
253     for( unsigned int i = 0; i < p_input->stream.i_selected_es_number ; i++ )
254     {
255         if( p_input->stream.pp_selected_es[i]->i_cat == SPU_ES )
256         {
257             p_es_old = p_input->stream.pp_selected_es[i];
258             break;
259         }
260     }
261     vlc_mutex_unlock( &p_input->stream.stream_lock );
262     
263     if( i_subtitle != -1 )
264     {
265         p_es = p_input->stream.pp_es[i_subtitle];
266     }
267     if( p_es == p_es_old )
268     {
269         return;
270     }
271     if( p_es_old )
272     {
273         input_ToggleES( p_input, p_es_old, VLC_FALSE );
274     }
275     if( p_es )
276     {
277         input_ToggleES( p_input, p_es, VLC_TRUE );
278     }
279 }
280
281 const char * VlcWrapper::GetTimeAsString()
282 {
283     static char psz_currenttime[ OFFSETTOTIME_MAX_SIZE ];
284         
285     if( p_input == NULL )
286     {
287         return ("-:--:--");
288     }     
289    
290     input_OffsetToTime( p_input, 
291                         psz_currenttime, 
292                         p_input->stream.p_selected_area->i_tell );        
293
294     return(psz_currenttime);
295 }
296
297 float VlcWrapper::GetTimeAsFloat()
298 {
299     float f_time = 0.0;
300
301     if( p_input != NULL )
302     {
303         f_time = (float)p_input->stream.p_selected_area->i_tell / 
304                  (float)p_input->stream.p_selected_area->i_size;
305     }    
306     else
307     {
308         f_time = 0.0;
309     }
310     return( f_time );
311 }
312
313 void VlcWrapper::SetTimeAsFloat( float f_position )
314 {
315     if( p_input != NULL )
316     {
317         input_Seek( p_input, 
318                    (long long int)(p_input->stream.p_selected_area->i_size
319                        * f_position / SEEKSLIDER_RANGE ), 
320                    INPUT_SEEK_SET);
321     }
322 }
323
324 bool VlcWrapper::IsPlaying()
325 {
326
327         bool playing = false;
328         if ( p_input )
329         {
330                 switch ( p_input->stream.control.i_status )
331                 {
332                         case PLAYING_S:
333                         case FORWARD_S:
334                         case BACKWARD_S:
335                         case START_S:
336                                 playing = true;
337                     break;
338                         case PAUSE_S:
339                         case UNDEF_S:
340                         case NOT_STARTED_S:
341                         default:
342                                 break;
343                 }
344         }
345         return playing;
346
347 }
348
349 /************
350  * playlist *
351  ************/
352
353 void VlcWrapper::OpenFiles( BList* o_files, bool replace, int32 index )
354 {
355         if ( o_files && o_files->CountItems() > 0)
356         {
357             int size = PlaylistSize();
358                 bool wasEmpty = ( size < 1 );
359                 if ( index == -1 )
360                         index = PLAYLIST_END;
361                 int mode = index == PLAYLIST_END ? PLAYLIST_APPEND : PLAYLIST_INSERT;
362         
363             /* delete current playlist */
364             if( replace )
365             {
366                 for( int i = 0; i < size; i++ )
367                 {
368                     playlist_Delete( p_playlist, 0 );
369                 }
370             }
371         
372             /* insert files */
373             int32 count = o_files->CountItems();
374             for ( int32 i = count - 1; i >= 0; i-- )
375             {
376                 if ( BString* o_file = (BString *)o_files->RemoveItem( i ) )
377                 {
378                         playlist_Add( p_playlist, o_file->String(),
379                                       mode, index );
380                         if ( mode == PLAYLIST_INSERT )
381                                 index++;
382                         delete o_file;
383                 }
384             }
385             // TODO: implement a user setting
386             // if to start automatically
387             /* eventually restart playing */
388             if( replace || wasEmpty )
389             {
390                 playlist_Stop( p_playlist );
391                 playlist_Play( p_playlist );
392             }
393         }
394 }
395  
396 void VlcWrapper::OpenDisc(BString o_type, BString o_device, int i_title, int i_chapter)
397 {
398     if( p_intf->p_sys->b_dvdmenus )
399         o_device.Prepend( "dvd:" );
400     else
401         o_device.Prepend( "dvdold:" );
402     playlist_Add( p_playlist, o_device.String(),
403                   PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
404 }
405
406 int VlcWrapper::PlaylistSize()
407 {
408     vlc_mutex_lock( &p_playlist->object_lock );
409     int i_size = p_playlist->i_size;
410     vlc_mutex_unlock( &p_playlist->object_lock );
411     return i_size;
412 }
413
414 char * VlcWrapper::PlaylistItemName( int i )
415 {
416    return p_playlist->pp_items[i]->psz_name;
417 }
418
419 int VlcWrapper::PlaylistCurrent()
420 {
421     return p_playlist->i_index;
422 }
423
424 bool VlcWrapper::PlaylistPlay()
425 {
426     if( PlaylistSize() )
427     {
428         playlist_Play( p_playlist );
429     }
430     return( true );
431 }
432
433 void VlcWrapper::PlaylistPause()
434 {
435     if( p_input )
436     {
437         input_SetStatus( p_input, INPUT_STATUS_PAUSE );
438     }
439 }
440
441 void VlcWrapper::PlaylistStop()
442 {
443     playlist_Stop( p_playlist );
444 }
445
446 void VlcWrapper::PlaylistNext()
447 {
448     playlist_Next( p_playlist );
449 }
450
451 void VlcWrapper::PlaylistPrev()
452 {
453     playlist_Prev( p_playlist );
454 }
455
456 void VlcWrapper::GetPlaylistInfo( int32& currentIndex, int32& maxIndex )
457 {
458         currentIndex = -1;
459         maxIndex = -1;
460         if ( p_playlist )
461         {
462             vlc_mutex_lock( &p_playlist->object_lock );
463
464                 maxIndex = p_playlist->i_size;
465                 if ( maxIndex > 0 )
466                         currentIndex = p_playlist->i_index/* + 1 -> why?!?*/;
467                 else
468                         maxIndex = -1;
469
470             vlc_mutex_unlock( &p_playlist->object_lock );
471         }
472 }
473
474 void VlcWrapper::PlaylistJumpTo( int pos )
475 {
476     playlist_Goto( p_playlist, pos );
477 }
478
479 void VlcWrapper::GetNavCapabilities( bool *canSkipPrev, bool *canSkipNext )
480 {
481         if ( canSkipPrev && canSkipNext )
482         {
483                 // init the parameters
484                 *canSkipPrev = false;
485                 *canSkipNext = false;
486                 // get playlist info
487                 int pos = PlaylistCurrent();
488                 int size = PlaylistSize();
489
490                 // see if we have got a stream going            
491                 if ( p_input )
492                 {
493                         vlc_mutex_lock( &p_input->stream.stream_lock );
494
495                         bool hasTitles = p_input->stream.i_area_nb > 1;
496                         int numChapters = p_input->stream.p_selected_area->i_part_nb;
497                         bool hasChapters = numChapters > 1;
498                         // first, look for chapters
499                         if ( hasChapters )
500                         {
501                                 *canSkipPrev = p_input->stream.p_selected_area->i_part > 0;
502                                 *canSkipNext = p_input->stream.p_selected_area->i_part <
503                                                                          p_input->stream.p_selected_area->i_part_nb - 1;
504                         }
505                         // if one of the skip capabilities is false,
506                         // make it depend on titles instead
507                         if ( !*canSkipPrev && hasTitles )
508                                 *canSkipPrev = p_input->stream.p_selected_area->i_id > 1;
509                         if ( !*canSkipNext && hasTitles )
510                                 *canSkipNext = p_input->stream.p_selected_area->i_id <
511                                                    p_input->stream.i_area_nb - 1;
512
513                         vlc_mutex_unlock( &p_input->stream.stream_lock );
514                 }
515                 // last but not least, make capabilities depend on playlist
516                 if ( !*canSkipPrev )
517                         *canSkipPrev = pos > 0;
518                 if ( !*canSkipNext )
519                         *canSkipNext = pos < size - 1;
520         }
521 }
522
523 void VlcWrapper::NavigatePrev()
524 {
525         bool hasSkiped = false;
526
527         // see if we have got a stream going            
528         if ( p_input )
529         {
530                 // get information from stream (lock it while looking at it)
531                 vlc_mutex_lock( &p_input->stream.stream_lock );
532
533                 int currentTitle = p_input->stream.p_selected_area->i_id;
534                 int currentChapter = p_input->stream.p_selected_area->i_part;
535                 int numTitles = p_input->stream.i_area_nb;
536                 bool hasTitles = numTitles > 1;
537                 int numChapters = p_input->stream.p_selected_area->i_part_nb;
538                 bool hasChapters = numChapters > 1;
539
540                 vlc_mutex_unlock( &p_input->stream.stream_lock );
541
542                 // first, look for chapters
543                 if ( hasChapters )
544                 {
545                         // skip to the previous chapter
546                         currentChapter--;
547
548                         if ( currentChapter >= 0 )
549                         {
550                                 ToggleChapter( currentChapter );
551                                 hasSkiped = true;
552                         }
553                 }
554                 // if we couldn't skip chapters, try titles instead
555                 if ( !hasSkiped && hasTitles )
556                 {
557                         // skip to the previous title
558                         currentTitle--;
559                         // disallow area 0 since it is used for video_ts.vob
560                         if( currentTitle > 0 )
561                         {
562                                 ToggleTitle(currentTitle);
563                                 hasSkiped = true;
564                         }
565                 }
566
567         }
568         // last but not least, skip to previous file
569         if ( !hasSkiped )
570                 PlaylistPrev();
571 }
572
573 void VlcWrapper::NavigateNext()
574 {
575         bool hasSkiped = false;
576
577         // see if we have got a stream going            
578         if ( p_input )
579         {
580                 // get information from stream (lock it while looking at it)
581                 vlc_mutex_lock( &p_input->stream.stream_lock );
582
583                 int currentTitle = p_input->stream.p_selected_area->i_id;
584                 int currentChapter = p_input->stream.p_selected_area->i_part;
585                 int numTitles = p_input->stream.i_area_nb;
586                 bool hasTitles = numTitles > 1;
587                 int numChapters = p_input->stream.p_selected_area->i_part_nb;
588                 bool hasChapters = numChapters > 1;
589
590                 vlc_mutex_unlock( &p_input->stream.stream_lock );
591
592                 // first, look for chapters
593                 if ( hasChapters )
594                 {
595                         // skip to the next chapter
596                         currentChapter++;
597                         if ( currentChapter < numChapters )
598                         {
599                                 ToggleChapter( currentChapter );
600                                 hasSkiped = true;
601                         }
602                 }
603                 // if we couldn't skip chapters, try titles instead
604                 if ( !hasSkiped && hasTitles )
605                 {
606                         // skip to the next title
607                         currentTitle++;
608                         // disallow area 0 since it is used for video_ts.vob
609                         if ( currentTitle < numTitles - 1 )
610                         {
611                                 ToggleTitle(currentTitle);
612                                 hasSkiped = true;
613                         }
614                 }
615
616         }
617         // last but not least, skip to next file
618         if ( !hasSkiped )
619                 PlaylistNext();
620 }
621
622 /*************************
623  * Playlist manipulation *
624  *************************/
625
626 // PlaylistLock
627 bool
628 VlcWrapper::PlaylistLock() const
629 {
630 // TODO: search and destroy -> deadlock!
631 return true;
632         if ( p_playlist )
633         {
634                 vlc_mutex_lock( &p_playlist->object_lock );
635                 return true;
636         }
637         return false;
638 }
639
640 // PlaylistUnlock
641 void
642 VlcWrapper::PlaylistUnlock() const
643 {
644 // TODO: search and destroy -> deadlock!
645 return;
646         vlc_mutex_unlock( &p_playlist->object_lock );
647 }
648
649 // PlaylistItemAt
650 void*
651 VlcWrapper::PlaylistItemAt( int index ) const
652 {
653         playlist_item_t* item = NULL;
654         if ( index >= 0 && index < p_playlist->i_size )
655                 item = p_playlist->pp_items[index];
656         return (void*)item;
657 }
658
659 // PlaylistRemoveItem
660 void*
661 VlcWrapper::PlaylistRemoveItem( int index ) const
662 {
663         playlist_item_t* copy = NULL;
664         // check if item exists at the provided index
665         if ( index >= 0 && index < p_playlist->i_size )
666         {
667                 playlist_item_t* item = p_playlist->pp_items[index];
668                 if ( item )
669                 {
670                         // make a copy of the removed item
671                         copy = (playlist_item_t*)PlaylistCloneItem( (void*)item );
672                         // remove item from playlist (unfortunately, this frees it)
673                         playlist_Delete( p_playlist, index );
674                 }
675         }
676         return (void*)copy;
677 }
678
679 // PlaylistRemoveItem
680 void*
681 VlcWrapper::PlaylistRemoveItem( void* item ) const
682 {
683         playlist_item_t* copy = NULL;
684         for ( int32 i = 0; i < p_playlist->i_size; i++ )
685         {
686                 if ( p_playlist->pp_items[i] == item )
687                 {
688                         copy = (playlist_item_t*)PlaylistRemoveItem( i );
689                         break;
690                 }
691         }
692         return (void*)copy;
693 }
694
695 // PlaylistAddItem
696 bool
697 VlcWrapper::PlaylistAddItem( void* item, int index ) const
698 {
699         if ( item )
700         {
701                 playlist_AddItem( p_playlist, (playlist_item_t*)item,
702                                                   PLAYLIST_INSERT, index );
703         }
704         // TODO: once playlist is returning useful info, return that instead
705         return true;
706 }
707
708 // PlaylistCloneItem
709 void*
710 VlcWrapper::PlaylistCloneItem( void* castToItem ) const
711 {
712         playlist_item_t* copy = NULL;
713         playlist_item_t* item = (playlist_item_t*)castToItem;
714         if ( item )
715         {
716                 copy = (playlist_item_t*)malloc( sizeof( playlist_item_t ) );
717                 if ( copy )
718                 {
719                         // make a copy of the item at index
720                         copy->psz_name = strdup( item->psz_name );
721                         copy->psz_uri  = strdup( item->psz_uri );
722                         copy->i_type = item->i_type;
723                         copy->i_status = item->i_status;
724                         copy->b_autodeletion = item->b_autodeletion;
725                 }
726         }
727         return (void*)copy;
728 }
729
730 // Careful! You need to know what you're doing here!
731 // The reason for having it, is to be able to deal with
732 // the rather lame list implementation of the playlist.
733 // It is meant to help manipulate the playlist with the above
734 // methods while keeping it valid.
735 //
736 // PlaylistSetPlaying
737 void
738 VlcWrapper::PlaylistSetPlaying( int index ) const
739 {
740         if ( index < 0 )
741                 index = 0;
742         if ( index >= p_playlist->i_size )
743                 index = p_playlist->i_size - 1;
744         p_playlist->i_index = index;
745 }
746
747
748 /*********
749  * audio *
750  *********/
751
752 unsigned short VlcWrapper::GetVolume()
753 {
754     unsigned short i_volume;
755     aout_VolumeGet( p_intf, (audio_volume_t*)&i_volume );
756     return i_volume;
757 }
758
759 void VlcWrapper::SetVolume( int value )
760 {
761     if ( p_intf->p_sys->b_mute )
762     {
763         p_intf->p_sys->b_mute = 0;
764     }
765     aout_VolumeSet( p_intf, value );
766 }
767
768 void VlcWrapper::VolumeMute()
769 {
770         aout_VolumeGet( p_intf, &p_intf->p_sys->i_saved_volume );
771     aout_VolumeMute( p_intf, NULL );
772     p_intf->p_sys->b_mute = 1;
773 }
774
775 void VlcWrapper::VolumeRestore()
776 {
777     aout_VolumeSet( p_intf, p_intf->p_sys->i_saved_volume );
778     p_intf->p_sys->b_mute = 0;
779 }
780
781 bool VlcWrapper::IsMuted()
782 {
783     return p_intf->p_sys->b_mute;
784 }
785
786 /*******
787  * DVD *
788  *******/
789
790 bool VlcWrapper::HasTitles()
791 {
792     if( !p_input )
793     {
794         return false;
795     }
796     return ( p_input->stream.i_area_nb > 1 );
797 }
798
799 BList * VlcWrapper::GetTitles()
800 {
801     if( p_input )
802     {
803         vlc_mutex_lock( &p_input->stream.stream_lock );
804       
805         BList *list = new BList( p_input->stream.i_area_nb );
806         BMenuItem *menuItem;
807         BMessage *message;
808         
809         for( unsigned int i = 1; i < p_input->stream.i_area_nb; i++ )
810         {
811             message = new BMessage( TOGGLE_TITLE );
812             message->AddInt32( "index", i );
813             BString helper( "" );
814             helper << i;
815             menuItem = new BMenuItem( helper.String(), message );
816             menuItem->SetMarked( p_input->stream.p_selected_area->i_id == i );
817             list->AddItem( menuItem );
818         }
819         
820         vlc_mutex_unlock( &p_input->stream.stream_lock );
821
822         return list;
823     }
824     return NULL;
825 }
826
827 void VlcWrapper::PrevTitle()
828 {
829     int i_id;
830     i_id = p_input->stream.p_selected_area->i_id - 1;
831     if( i_id > 0 )
832     {
833         ToggleTitle(i_id);
834     }
835 }
836
837 void VlcWrapper::NextTitle()
838 {
839     unsigned int i_id;
840     i_id = p_input->stream.p_selected_area->i_id + 1;
841     if( i_id < p_input->stream.i_area_nb )
842     {
843         ToggleTitle(i_id);
844     }
845 }
846
847 void VlcWrapper::ToggleTitle(int i_title)
848 {
849     if( p_input != NULL )
850     {
851         input_ChangeArea( p_input,
852                           p_input->stream.pp_areas[i_title] );
853
854         vlc_mutex_lock( &p_input->stream.stream_lock );
855
856         vlc_mutex_unlock( &p_input->stream.stream_lock );
857     }
858 }
859
860 void VlcWrapper::TitleInfo( int32 &currentIndex, int32 &maxIndex )
861 {
862         currentIndex = -1;
863         maxIndex = -1;
864         if ( p_input )
865         {
866                 vlc_mutex_lock( &p_input->stream.stream_lock );
867
868                 maxIndex = p_input->stream.i_area_nb - 1;
869                 if ( maxIndex > 0)
870                         currentIndex = p_input->stream.p_selected_area->i_id;
871                 else
872                         maxIndex = -1;
873
874                 vlc_mutex_unlock( &p_input->stream.stream_lock );
875         }
876 }
877
878 bool VlcWrapper::HasChapters()
879 {
880     if( !p_input )
881     {
882         return false;
883     }
884     return ( p_input->stream.p_selected_area->i_part_nb > 1 );
885 }
886
887 BList * VlcWrapper::GetChapters()
888 {
889     if( p_input )
890     {
891         vlc_mutex_lock( &p_input->stream.stream_lock );
892       
893         BList *list = new BList( p_input->stream.p_selected_area->i_part_nb );
894         BMenuItem *menuItem;
895         BMessage *message;
896         
897         for( unsigned int i = 1;
898              i < p_input->stream.p_selected_area->i_part_nb + 1; i++ )
899         {
900             message = new BMessage( TOGGLE_CHAPTER );
901             message->AddInt32( "index", i );
902             BString helper( "" );
903             helper << i;
904             menuItem = new BMenuItem( helper.String(), message );
905             menuItem->SetMarked( p_input->stream.p_selected_area->i_part == i );
906             list->AddItem( menuItem );
907         }
908         
909         vlc_mutex_unlock( &p_input->stream.stream_lock );
910
911         return list;
912     }
913     return NULL;
914 }
915
916 void VlcWrapper::PrevChapter()
917 {
918     int i_id;
919     i_id = p_input->stream.p_selected_area->i_part - 1;
920     if( i_id >= 0 )
921     {
922         ToggleChapter(i_id);
923     }
924 }
925
926 void VlcWrapper::NextChapter()
927 {
928     int i_id;
929     i_id = p_input->stream.p_selected_area->i_part + 1;
930     if( i_id >= 0 )
931     {
932         ToggleChapter(i_id);
933     }
934 }
935
936 void VlcWrapper::ToggleChapter(int i_chapter)
937 {
938     if( p_input != NULL )
939     {
940         p_input->stream.p_selected_area->i_part = i_chapter;
941         input_ChangeArea( p_input,
942                           p_input->stream.p_selected_area );
943
944         vlc_mutex_lock( &p_input->stream.stream_lock );
945         vlc_mutex_unlock( &p_input->stream.stream_lock );
946     }
947 }
948
949 void VlcWrapper::ChapterInfo( int32 &currentIndex, int32 &maxIndex )
950 {
951         currentIndex = -1;
952         maxIndex = -1;
953         if ( p_input )
954         {
955                 vlc_mutex_lock( &p_input->stream.stream_lock );
956
957                 maxIndex = p_input->stream.p_selected_area->i_part_nb - 1;
958                 if ( maxIndex > 0)
959                         currentIndex = p_input->stream.p_selected_area->i_part;
960                 else
961                         maxIndex = -1;
962
963                 vlc_mutex_unlock( &p_input->stream.stream_lock );
964         }
965 }
966
967 /****************
968  * Miscellanous *
969  ****************/
970  
971 void VlcWrapper::LoadSubFile( const char * psz_file )
972 {
973     config_PutPsz( p_intf, "sub-file", strdup( psz_file ) );
974 }
975
976 void VlcWrapper::FilterChange()
977 {
978     if( !p_input )
979         return;
980     
981     vout_thread_t * p_vout;
982     vlc_mutex_lock( &p_input->stream.stream_lock );
983
984     // Warn the vout we are about to change the filter chain
985     p_vout = (vout_thread_t*)vlc_object_find( p_intf, VLC_OBJECT_VOUT,
986                                               FIND_ANYWHERE );
987     if( p_vout )
988     {
989         p_vout->b_filter_change = VLC_TRUE;
990         vlc_object_release( p_vout );
991     }
992
993     // restart all video stream
994     for( unsigned int i = 0; i < p_input->stream.i_es_number; i++ )
995     {
996         if( ( p_input->stream.pp_es[i]->i_cat == VIDEO_ES ) &&
997             ( p_input->stream.pp_es[i]->p_decoder_fifo != NULL ) )
998         {
999             input_UnselectES( p_input, p_input->stream.pp_es[i] );
1000             input_SelectES( p_input, p_input->stream.pp_es[i] );
1001         }
1002     }
1003     vlc_mutex_unlock( &p_input->stream.stream_lock );
1004 }