]> git.sesse.net Git - vlc/blob - modules/gui/beos/VlcWrapper.cpp
fixed flickering of skip buttons (and consequently crashing if you pressed them)
[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.16 2003/01/11 19:33:09 stippi 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 extern "C" {
34 #include <audio_output.h>
35 #include <aout_internal.h>
36 }
37
38 #include "VlcWrapper.h"
39 #include "MsgVals.h"
40
41 /* constructor */
42 VlcWrapper::VlcWrapper( intf_thread_t *p_interface )
43 {
44     p_intf = p_interface;
45     p_input = NULL;
46     p_aout = NULL;
47     p_playlist = (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
48                                                 FIND_ANYWHERE );
49 }
50
51 /* destructor */
52 VlcWrapper::~VlcWrapper()
53 {
54     if( p_input )
55     {
56         vlc_object_release( p_input );
57     }
58     if( p_playlist )
59     {
60         vlc_object_release( p_playlist );
61     }
62     if( p_aout )
63     {
64         vlc_object_release( p_aout );
65     }
66 }
67
68 /* UpdateInputAndAOut: updates p_input and p_aout, returns true if the
69    interface needs to be updated */
70 bool VlcWrapper::UpdateInputAndAOut()
71 {
72     if( p_input == NULL )
73     {
74         p_input = (input_thread_t *)vlc_object_find( p_intf, VLC_OBJECT_INPUT,
75                                                      FIND_ANYWHERE );
76     }
77     if( p_aout == NULL )
78     {
79         p_aout = (aout_instance_t*)vlc_object_find( p_intf, VLC_OBJECT_AOUT,
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             if( p_aout )
91             {
92                 vlc_object_release( p_aout );
93                 p_aout = NULL;
94             }
95         }
96         return true;
97     }
98     return false;
99 }
100
101
102 /***************************
103  * input infos and control *
104  ***************************/
105
106 bool VlcWrapper::HasInput()
107 {
108     return ( p_input != NULL );
109 //    return ( PlaylistSize() > 0 );
110 }
111
112 /* status (UNDEF_S, PLAYING_S, PAUSE_S, FORWARD_S, BACKWARD_S,
113    REWIND_S, NOT_STARTED_S, START_S) */
114 int VlcWrapper::InputStatus()
115 {
116     if( !p_input )
117     {
118         return UNDEF_S;
119     }
120     return p_input->stream.control.i_status;
121 }
122
123 int VlcWrapper::InputRate()
124 {
125     if( !p_input )
126     {
127         return DEFAULT_RATE;
128     }
129     return p_input->stream.control.i_rate;
130 }
131
132 /* tell: location in the current stream (in arbitrary units) */
133 int VlcWrapper::InputTell()
134 {
135     if( !p_input )
136     {
137         return -1;
138     }
139     return p_input->stream.p_selected_area->i_tell;
140 }
141
142 /* size: total size of the current stream (in arbitrary units) */
143 int VlcWrapper::InputSize()
144 {
145     if( !p_input )
146     {
147         return -1;
148     }
149     return p_input->stream.p_selected_area->i_size;
150 }
151
152 void VlcWrapper::InputSlower()
153 {
154     if( p_input != NULL )
155     {
156         input_SetStatus( p_input, INPUT_STATUS_SLOWER );
157     }
158 }
159
160 void VlcWrapper::InputFaster()
161 {
162     if( p_input != NULL )
163     {
164         input_SetStatus( p_input, INPUT_STATUS_FASTER );
165     }
166 }
167
168 BList * VlcWrapper::InputGetChannels( int i_cat )
169 {
170     if( p_input )
171     {
172         unsigned int i;
173         uint32 what;
174         const char* fieldName;
175
176         switch( i_cat )
177         {
178             case AUDIO_ES:
179             {
180                 what = SELECT_CHANNEL;
181                 fieldName = "channel";
182                 break;
183             }
184             case SPU_ES:
185             {
186                 what = SELECT_SUBTITLE;
187                 fieldName = "subtitle";
188                 break;
189             }
190             default:
191             return NULL;
192        }
193
194         vlc_mutex_lock( &p_input->stream.stream_lock );
195       
196         /* find which track is currently playing */
197         es_descriptor_t *p_es = NULL;
198         for( i = 0; i < p_input->stream.i_selected_es_number; i++ )
199         {
200             if( p_input->stream.pp_selected_es[i]->i_cat == i_cat )
201                 p_es = p_input->stream.pp_selected_es[i];
202         }
203         
204         /* build a list of all tracks */
205         BList *list = new BList( p_input->stream.i_es_number );
206         BMenuItem *menuItem;
207         BMessage *message;
208         char *trackName;
209         
210         /* "None" */
211         message = new BMessage( what );
212         message->AddInt32( fieldName, -1 );
213         menuItem = new BMenuItem( "None", message );
214         if( !p_es )
215             menuItem->SetMarked( true );
216         list->AddItem( menuItem );
217         
218         for( i = 0; i < p_input->stream.i_es_number; i++ )
219         {
220             if( p_input->stream.pp_es[i]->i_cat == i_cat )
221             {
222                 message = new BMessage( what );
223                 message->AddInt32( fieldName, i );
224                 if( strlen( p_input->stream.pp_es[i]->psz_desc ) )
225                     trackName = strdup( p_input->stream.pp_es[i]->psz_desc );
226                 else
227                     trackName = "<unknown>";
228                 menuItem = new BMenuItem( trackName, message );
229                 if( p_input->stream.pp_es[i] == p_es )
230                     menuItem->SetMarked( true );
231                 list->AddItem( menuItem );
232             }
233         }
234         
235         vlc_mutex_unlock( &p_input->stream.stream_lock );
236
237         return list;
238     }
239     return NULL;
240 }
241
242 void VlcWrapper::openFiles( BList* o_files, bool replace )
243 {
244     BString *o_file;
245
246     while( ( o_file = (BString *)o_files->LastItem() ) )
247     {
248         o_files->RemoveItem(o_files->CountItems() - 1);
249         playlist_Add( p_playlist, o_file->String(),
250                   PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
251         delete o_file;
252     }
253 }
254
255 void VlcWrapper::openDisc(BString o_type, BString o_device, int i_title, int i_chapter)
256 {
257     BString o_source("");
258     o_source << o_type << ":" << o_device ;
259
260     playlist_Add( p_playlist, o_source.String(),
261                   PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
262 }
263
264
265
266 void VlcWrapper::ToggleLanguage( int i_language )
267 {
268     es_descriptor_t * p_es = NULL;
269     es_descriptor_t * p_es_old = NULL;
270
271     vlc_mutex_lock( &p_input->stream.stream_lock );
272     for( unsigned int i = 0; i < p_input->stream.i_selected_es_number ; i++ )
273     {
274         if( p_input->stream.pp_selected_es[i]->i_cat == AUDIO_ES )
275         {
276             p_es_old = p_input->stream.pp_selected_es[i];
277             break;
278         }
279     }
280     vlc_mutex_unlock( &p_input->stream.stream_lock );
281     
282     if( i_language != -1 )
283     {
284         p_es = p_input->stream.pp_es[i_language];
285     }
286     if( p_es == p_es_old )
287     {
288         return;
289     }
290     if( p_es_old )
291     {
292         input_ToggleES( p_input, p_es_old, VLC_FALSE );
293     }
294     if( p_es )
295     {
296         input_ToggleES( p_input, p_es, VLC_TRUE );
297     }
298 }
299
300 void VlcWrapper::ToggleSubtitle( int i_subtitle )
301 {
302     es_descriptor_t * p_es = NULL;
303     es_descriptor_t * p_es_old = NULL;
304
305     vlc_mutex_lock( &p_input->stream.stream_lock );
306     for( unsigned int i = 0; i < p_input->stream.i_selected_es_number ; i++ )
307     {
308         if( p_input->stream.pp_selected_es[i]->i_cat == SPU_ES )
309         {
310             p_es_old = p_input->stream.pp_selected_es[i];
311             break;
312         }
313     }
314     vlc_mutex_unlock( &p_input->stream.stream_lock );
315     
316     if( i_subtitle != -1 )
317     {
318         p_es = p_input->stream.pp_es[i_subtitle];
319     }
320     if( p_es == p_es_old )
321     {
322         return;
323     }
324     if( p_es_old )
325     {
326         input_ToggleES( p_input, p_es_old, VLC_FALSE );
327     }
328     if( p_es )
329     {
330         input_ToggleES( p_input, p_es, VLC_TRUE );
331     }
332 }
333
334 const char*  VlcWrapper::getTimeAsString()
335 {
336     static char psz_currenttime[ OFFSETTOTIME_MAX_SIZE ];
337         
338     if( p_input == NULL )
339     {
340         return ("-:--:--");
341     }     
342    
343     input_OffsetToTime( p_input, 
344                         psz_currenttime, 
345                         p_input->stream.p_selected_area->i_tell );        
346
347     return(psz_currenttime);
348 }
349
350 float  VlcWrapper::getTimeAsFloat()
351 {
352     float f_time = 0.0;
353
354     if( p_input != NULL )
355     {
356         f_time = (float)p_input->stream.p_selected_area->i_tell / 
357                  (float)p_input->stream.p_selected_area->i_size;
358     }    
359     else
360     {
361         f_time = 0.0;
362     }
363     return( f_time );
364 }
365
366 void VlcWrapper::setTimeAsFloat(float f_position)
367 {
368     if( p_input != NULL )
369     {
370         input_Seek( p_input, 
371                    (long long int)(p_input->stream.p_selected_area->i_size
372                        * f_position / SEEKSLIDER_RANGE ), 
373                    INPUT_SEEK_SET);
374     }
375 }
376
377 bool VlcWrapper::IsPlaying()
378 {
379
380         bool playing = false;
381         if ( p_input )
382         {
383                 switch ( p_input->stream.control.i_status )
384                 {
385                         case PLAYING_S:
386                         case FORWARD_S:
387                         case BACKWARD_S:
388                         case START_S:
389                                 playing = true;
390                     break;
391                         case PAUSE_S:
392                         case UNDEF_S:
393                         case NOT_STARTED_S:
394                         default:
395                                 break;
396                 }
397         }
398         return playing;
399
400 }
401
402 /******************************
403  * playlist infos and control *
404  ******************************/
405 int VlcWrapper::PlaylistSize()
406 {
407     vlc_mutex_lock( &p_playlist->object_lock );
408     int i_size = p_playlist->i_size;
409     vlc_mutex_unlock( &p_playlist->object_lock );
410     return i_size;
411 }
412
413 char *VlcWrapper::PlaylistItemName( int i )
414 {
415    return p_playlist->pp_items[i]->psz_name;
416 }
417
418 int VlcWrapper::PlaylistCurrent()
419 {
420     return p_playlist->i_index;
421 }
422
423 int  VlcWrapper::PlaylistStatus()
424 {
425     return p_playlist->i_status;
426 }
427
428 bool VlcWrapper::PlaylistPlay()
429 {
430     if( PlaylistSize() )
431     {
432         playlist_Play( p_playlist );
433     }
434     return( true );
435 }
436
437 void VlcWrapper::PlaylistPause()
438 {
439     if( p_input )
440     {
441         input_SetStatus( p_input, INPUT_STATUS_PAUSE );
442     }
443 }
444
445 void VlcWrapper::PlaylistStop()
446 {
447     playlist_Stop( p_playlist );
448 }
449
450 void VlcWrapper::PlaylistNext()
451 {
452     playlist_Next( p_playlist );
453 }
454
455 void VlcWrapper::PlaylistPrev()
456 {
457     playlist_Prev( p_playlist );
458 }
459
460 void VlcWrapper::PlaylistSkip( int i )
461 {
462     playlist_Skip( p_playlist, i );
463 }
464
465 void VlcWrapper::PlaylistGoto( int i )
466 {
467     playlist_Goto( p_playlist, i );
468 }
469
470 void VlcWrapper::PlaylistLoop()
471 {
472     if ( p_intf->p_sys->b_loop )
473     {
474         playlist_Delete( p_playlist, p_playlist->i_size - 1 );
475     }
476     else
477     {
478         playlist_Add( p_playlist, "vlc:loop",
479                       PLAYLIST_APPEND | PLAYLIST_GO,
480                       PLAYLIST_END );
481     }
482     p_intf->p_sys->b_loop = !p_intf->p_sys->b_loop;
483 }
484
485 BList * VlcWrapper::PlaylistAsArray()
486
487     int i;
488     BList* p_list = new BList(p_playlist->i_size);
489     
490     vlc_mutex_lock( &p_playlist->object_lock );
491
492     for( i = 0; i < p_playlist->i_size; i++ )
493     {
494         p_list->AddItem(new BString(p_playlist->pp_items[i]->psz_name));
495     }
496
497     vlc_mutex_unlock( &p_playlist->object_lock );
498     return( p_list );
499 }
500
501 void VlcWrapper::getPlaylistInfo( int32& currentIndex, int32& maxIndex )
502 {
503         currentIndex = -1;
504         maxIndex = -1;
505         if ( p_playlist )
506         {
507                 maxIndex = p_playlist->i_size;
508                 if ( maxIndex > 0 )
509                         currentIndex = p_playlist->i_index + 1;
510                 else
511                         maxIndex = -1;
512         }
513 }
514
515
516 void VlcWrapper::PlaylistJumpTo( int pos )
517 {
518 #if 0
519         // sanity checks
520         if ( pos < 0 )
521                 pos = 0;
522         int size = playlistSize();
523         if (pos >= size)
524                 pos = size - 1;
525         // weird hack
526     if( p_input_bank->pp_input[0] != NULL )
527                 pos--;
528         // stop current stream
529         playlistStop();
530         // modify current position in playlist
531         playlistLock();
532         p_main->p_playlist->i_index = pos;
533         playlistUnlock();
534         // start playing
535         playlistPlay();
536 #endif
537 }
538
539 void VlcWrapper::getNavCapabilities( bool *canSkipPrev, bool *canSkipNext )
540 {
541         if ( canSkipPrev && canSkipNext )
542         {
543                 // init the parameters
544                 *canSkipPrev = false;
545                 *canSkipNext = false;
546                 // get playlist info
547                 int pos = PlaylistCurrent();
548                 int size = PlaylistSize();
549
550                 // see if we have got a stream going            
551                 if ( p_input )
552                 {
553                         vlc_mutex_lock( &p_input->stream.stream_lock );
554
555                         bool hasTitles = p_input->stream.i_area_nb > 1;
556                         int numChapters = p_input->stream.p_selected_area->i_part_nb;
557                         bool hasChapters = numChapters > 1;
558                         // first, look for chapters
559                         if ( hasChapters )
560                         {
561                                 *canSkipPrev = p_input->stream.p_selected_area->i_part > 0;
562                                 *canSkipNext = p_input->stream.p_selected_area->i_part <
563                                                                          p_input->stream.p_selected_area->i_part_nb - 1;
564                         }
565                         // if one of the skip capabilities is false,
566                         // make it depend on titles instead
567                         if ( !*canSkipPrev && hasTitles )
568                                 *canSkipPrev = p_input->stream.p_selected_area->i_id > 1;
569                         if ( !*canSkipNext && hasTitles )
570                                 *canSkipNext = p_input->stream.p_selected_area->i_id <
571                                                    p_input->stream.i_area_nb - 1;
572
573                         vlc_mutex_unlock( &p_input->stream.stream_lock );
574                 }
575                 // last but not least, make capabilities depend on playlist
576                 if ( !*canSkipPrev )
577                         *canSkipPrev = pos > 0;
578                 if ( !*canSkipNext )
579                         *canSkipNext = pos < size - 1;
580         }
581 }
582
583 void VlcWrapper::navigatePrev()
584 {
585         bool hasSkiped = false;
586
587         // see if we have got a stream going            
588         if ( p_input )
589         {
590                 // get information from stream (lock it while looking at it)
591                 vlc_mutex_lock( &p_input->stream.stream_lock );
592
593                 int currentTitle = p_input->stream.p_selected_area->i_id;
594                 int currentChapter = p_input->stream.p_selected_area->i_part;
595                 int numTitles = p_input->stream.i_area_nb;
596                 bool hasTitles = numTitles > 1;
597                 int numChapters = p_input->stream.p_selected_area->i_part_nb;
598                 bool hasChapters = numChapters > 1;
599
600                 vlc_mutex_unlock( &p_input->stream.stream_lock );
601
602                 // first, look for chapters
603                 if ( hasChapters )
604                 {
605                         // skip to the previous chapter
606                         currentChapter--;
607
608                         if ( currentChapter >= 0 )
609                         {
610                                 toggleChapter( currentChapter );
611                                 hasSkiped = true;
612                         }
613                 }
614                 // if we couldn't skip chapters, try titles instead
615                 if ( !hasSkiped && hasTitles )
616                 {
617                         // skip to the previous title
618                         currentTitle--;
619                         // disallow area 0 since it is used for video_ts.vob
620                         if( currentTitle > 0 )
621                         {
622                                 toggleTitle(currentTitle);
623                                 hasSkiped = true;
624                         }
625                 }
626
627         }
628         // last but not least, skip to previous file
629         if ( !hasSkiped )
630                 PlaylistPrev();
631 }
632
633 void VlcWrapper::navigateNext()
634 {
635         bool hasSkiped = false;
636
637         // see if we have got a stream going            
638         if ( p_input )
639         {
640                 // get information from stream (lock it while looking at it)
641                 vlc_mutex_lock( &p_input->stream.stream_lock );
642
643                 int currentTitle = p_input->stream.p_selected_area->i_id;
644                 int currentChapter = p_input->stream.p_selected_area->i_part;
645                 int numTitles = p_input->stream.i_area_nb;
646                 bool hasTitles = numTitles > 1;
647                 int numChapters = p_input->stream.p_selected_area->i_part_nb;
648                 bool hasChapters = numChapters > 1;
649
650                 vlc_mutex_unlock( &p_input->stream.stream_lock );
651
652                 // first, look for chapters
653                 if ( hasChapters )
654                 {
655                         // skip to the next chapter
656                         currentChapter++;
657                         if ( currentChapter < numChapters )
658                         {
659                                 toggleChapter( currentChapter );
660                                 hasSkiped = true;
661                         }
662                 }
663                 // if we couldn't skip chapters, try titles instead
664                 if ( !hasSkiped && hasTitles )
665                 {
666                         // skip to the next title
667                         currentTitle++;
668                         // disallow area 0 since it is used for video_ts.vob
669                         if ( currentTitle < numTitles - 1 )
670                         {
671                                 toggleTitle(currentTitle);
672                                 hasSkiped = true;
673                         }
674                 }
675
676         }
677         // last but not least, skip to next file
678         if ( !hasSkiped )
679                 PlaylistNext();
680 }
681
682
683 /***************************
684  * audio infos and control *
685  ***************************/
686
687 unsigned short VlcWrapper::GetVolume()
688 {
689     if( p_aout != NULL )
690     {
691         unsigned short i_volume;
692         aout_VolumeGet( p_aout, (audio_volume_t*)&i_volume );
693         return i_volume;
694     }
695     return 0;
696 }
697
698 void VlcWrapper::SetVolume(int value)
699 {
700     if( p_aout != NULL )
701     {
702                 if ( p_intf->p_sys->b_mute )
703                 {
704                         p_intf->p_sys->b_mute = 0;
705                 }
706         aout_VolumeSet( p_aout, value );
707     }
708 }
709
710 void VlcWrapper::VolumeMute()
711 {
712     if( p_aout != NULL )
713         {
714             aout_VolumeGet( p_aout, &p_intf->p_sys->i_saved_volume );
715             aout_VolumeMute( p_aout, NULL );
716             p_intf->p_sys->b_mute = 1;
717         }
718 }
719
720 void VlcWrapper::VolumeRestore()
721 {
722     if( p_aout != NULL )
723         {
724         aout_VolumeSet( p_aout, p_intf->p_sys->i_saved_volume );
725         p_intf->p_sys->b_mute = 0;
726         }
727 }
728
729 bool VlcWrapper::IsMuted()
730 {
731     return p_intf->p_sys->b_mute;
732 }
733
734 bool VlcWrapper::HasAudio()
735 {
736     return( p_aout != NULL );
737 }
738
739 /*******
740  * DVD *
741  *******/
742 bool VlcWrapper::HasTitles()
743 {
744     if( !p_input )
745     {
746         return false;
747     }
748     return ( p_input->stream.i_area_nb > 1 );
749 }
750
751 void VlcWrapper::PrevTitle()
752 {
753     int i_id;
754     i_id = p_input->stream.p_selected_area->i_id - 1;
755     if( i_id > 0 )
756     {
757         toggleTitle(i_id);
758     }
759 }
760
761 void VlcWrapper::NextTitle()
762 {
763     unsigned int i_id;
764     i_id = p_input->stream.p_selected_area->i_id + 1;
765     if( i_id < p_input->stream.i_area_nb )
766     {
767         toggleTitle(i_id);
768     }
769 }
770
771 bool VlcWrapper::HasChapters()
772 {
773     if( !p_input )
774     {
775         return false;
776     }
777     return ( p_input->stream.p_selected_area->i_part_nb > 1 );
778 }
779
780 void VlcWrapper::PrevChapter()
781 {
782     int i_id;
783     i_id = p_input->stream.p_selected_area->i_part - 1;
784     if( i_id >= 0 )
785     {
786         toggleChapter(i_id);
787     }
788 }
789
790 void VlcWrapper::NextChapter()
791 {
792     int i_id;
793     i_id = p_input->stream.p_selected_area->i_part + 1;
794     if( i_id >= 0 )
795     {
796         toggleChapter(i_id);
797     }
798 }
799
800 void VlcWrapper::TitleInfo( int32 &currentIndex, int32 &maxIndex )
801 {
802         currentIndex = -1;
803         maxIndex = -1;
804         if ( p_input )
805         {
806                 vlc_mutex_lock( &p_input->stream.stream_lock );
807
808                 maxIndex = p_input->stream.i_area_nb - 1;
809                 if ( maxIndex > 0)
810                         currentIndex = p_input->stream.p_selected_area->i_id;
811                 else
812                         maxIndex = -1;
813
814                 vlc_mutex_unlock( &p_input->stream.stream_lock );
815         }
816 }
817
818 void VlcWrapper::ChapterInfo( int32 &currentIndex, int32 &maxIndex )
819 {
820         currentIndex = -1;
821         maxIndex = -1;
822         if ( p_input )
823         {
824                 vlc_mutex_lock( &p_input->stream.stream_lock );
825
826                 maxIndex = p_input->stream.p_selected_area->i_part_nb - 1;
827                 if ( maxIndex > 0)
828                         currentIndex = p_input->stream.p_selected_area->i_part;
829                 else
830                         maxIndex = -1;
831
832                 vlc_mutex_unlock( &p_input->stream.stream_lock );
833         }
834 }
835
836 void VlcWrapper::toggleTitle(int i_title)
837 {
838     if( p_input != NULL )
839     {
840         input_ChangeArea( p_input,
841                           p_input->stream.pp_areas[i_title] );
842
843         vlc_mutex_lock( &p_input->stream.stream_lock );
844
845         vlc_mutex_unlock( &p_input->stream.stream_lock );
846     }
847 }
848
849 void VlcWrapper::toggleChapter(int i_chapter)
850 {
851     if( p_input != NULL )
852     {
853         p_input->stream.p_selected_area->i_part = i_chapter;
854         input_ChangeArea( p_input,
855                           p_input->stream.p_selected_area );
856
857         vlc_mutex_lock( &p_input->stream.stream_lock );
858         vlc_mutex_unlock( &p_input->stream.stream_lock );
859     }
860 }