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