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