Changes to ensure BeOS plugins compile and function
[vlc.git] / plugins / beos / InterfaceWindow.cpp
1 /*****************************************************************************
2  * InterfaceWindow.cpp: beos interface
3  *****************************************************************************
4  * Copyright (C) 1999, 2000, 2001 VideoLAN
5  * $Id: InterfaceWindow.cpp,v 1.21 2002/07/23 12:42:17 tcastley Exp $
6  *
7  * Authors: Jean-Marc Dressler <polux@via.ecp.fr>
8  *          Samuel Hocevar <sam@zoy.org>
9  *          Tony Castley <tony@castley.net>
10  *          Richard Shepherd <richard@rshepherd.demon.co.uk>
11  *
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation; either version 2 of the License, or
15  * (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
25  *****************************************************************************/
26
27 /* System headers */
28 #include <kernel/OS.h>
29 #include <InterfaceKit.h>
30 #include <AppKit.h>
31 #include <StorageKit.h>
32 #include <SupportKit.h>
33 #include <malloc.h>
34 #include <scsi.h>
35 #include <scsiprobe_driver.h>
36 #include <fs_info.h>
37 #include <string.h>
38
39
40 /* VLC headers */
41 #include <vlc/vlc.h>
42 #include <vlc/aout.h>
43 #include <vlc/intf.h>
44
45 /* BeOS interface headers */
46 #include "MsgVals.h"
47 #include "MediaControlView.h"
48 #include "PlayListWindow.h"
49 #include "intf_vlc_wrapper.h"
50 #include "InterfaceWindow.h"
51
52
53 /*****************************************************************************
54  * InterfaceWindow
55  *****************************************************************************/
56
57 InterfaceWindow::InterfaceWindow( BRect frame, const char *name,
58                                   intf_thread_t  *p_interface )
59     : BWindow( frame, name, B_FLOATING_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL,
60                B_NOT_RESIZABLE | B_NOT_ZOOMABLE | B_WILL_ACCEPT_FIRST_CLICK
61                 | B_ASYNCHRONOUS_CONTROLS )
62 {
63     file_panel = NULL;
64     playlist_window = NULL;
65     p_intf = p_interface;
66     p_vlc_wrapper = Intf_VLCWrapper::getVLCWrapper(p_intf);
67     BRect controlRect(0,0,0,0);
68     
69     playlist_t *p_playlist = (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
70                                                        FIND_ANYWHERE );
71     b_empty_playlist = (p_playlist->i_size < 0);
72     b_mute = false;
73
74     /* set the title bar */
75     SetName( "interface" );
76     SetTitle(VOUT_TITLE);
77
78     /* set up the main menu */
79     BMenuBar *menu_bar;
80     menu_bar = new BMenuBar(controlRect, "main menu");
81     AddChild( menu_bar );
82
83     BMenu *mFile;
84     BMenu *mAudio;
85     CDMenu *cd_menu;
86     BMenu *mNavigation;
87     
88     /* Add the file Menu */
89     BMenuItem *mItem;
90     menu_bar->AddItem( mFile = new BMenu( "File" ) );
91     menu_bar->ResizeToPreferred();
92     mFile->AddItem( mItem = new BMenuItem( "Open File" B_UTF8_ELLIPSIS,
93                                            new BMessage(OPEN_FILE), 'O') );
94     
95     cd_menu = new CDMenu( "Open Disc" );
96     mFile->AddItem( cd_menu );
97     
98     mFile->AddSeparatorItem();
99     mFile->AddItem( mItem = new BMenuItem( "Play List" B_UTF8_ELLIPSIS,
100                                            new BMessage(OPEN_PLAYLIST), 'P') );
101     
102     mFile->AddSeparatorItem();
103     mFile->AddItem( mItem = new BMenuItem( "About" B_UTF8_ELLIPSIS,
104                                        new BMessage(B_ABOUT_REQUESTED), 'A') );
105     mItem->SetTarget( be_app );
106     mFile->AddItem(mItem = new BMenuItem( "Quit",
107                                         new BMessage(B_QUIT_REQUESTED), 'Q') );
108
109     /* Add the Audio menu */
110     menu_bar->AddItem ( mAudio = new BMenu( "Audio" ) );
111     menu_bar->ResizeToPreferred();
112     mAudio->AddItem( new LanguageMenu( "Language", AUDIO_ES, p_intf ) );
113     mAudio->AddItem( new LanguageMenu( "Subtitles", SPU_ES, p_intf ) );
114
115     /* Add the Navigation menu */
116     menu_bar->AddItem( mNavigation = new BMenu( "Navigation" ) );
117     menu_bar->ResizeToPreferred();
118     mNavigation->AddItem( new BMenuItem( "Prev Title",
119                                         new BMessage(PREV_TITLE)) );
120     mNavigation->AddItem( new BMenuItem( "Next Title",
121                                         new BMessage(NEXT_TITLE)) );
122     mNavigation->AddItem( new BMenuItem( "Prev Chapter",
123                                         new BMessage(PREV_CHAPTER)) );
124     mNavigation->AddItem( new BMenuItem( "Next Chapter",
125                                         new BMessage(NEXT_CHAPTER)) );
126                                         
127     ResizeTo(260,50 + menu_bar->Bounds().IntegerHeight()+1);
128     controlRect = Bounds();
129     controlRect.top += menu_bar->Bounds().IntegerHeight() + 1;
130
131     p_mediaControl = new MediaControlView( controlRect );
132     p_mediaControl->SetViewColor( ui_color(B_PANEL_BACKGROUND_COLOR) );
133     b_empty_playlist = true;
134     p_mediaControl->SetEnabled( !b_empty_playlist );
135
136     /* Show */
137     AddChild( p_mediaControl );
138     Show();
139     
140 }
141
142 InterfaceWindow::~InterfaceWindow()
143 {
144     if (playlist_window) playlist_window->ReallyQuit();
145 }
146
147 /*****************************************************************************
148  * InterfaceWindow::MessageReceived
149  *****************************************************************************/
150 void InterfaceWindow::MessageReceived( BMessage * p_message )
151 {
152     int vol_val = p_mediaControl->GetVolume();    // remember the current volume
153     int playback_status;      // remember playback state
154     int     i_index;
155     BAlert *alert;
156
157     Activate();
158     playback_status = p_vlc_wrapper->inputGetStatus();
159
160     switch( p_message->what )
161     {
162     case B_ABOUT_REQUESTED:
163         alert = new BAlert(VOUT_TITLE, "BeOS " VOUT_TITLE "\n\n<www.videolan.org>", "Ok");
164         alert->Go();
165         break;
166
167     case TOGGLE_ON_TOP:
168         break;
169         
170     case OPEN_FILE:
171         if( file_panel )
172         {
173             file_panel->Show();
174             break;
175         }
176         file_panel = new BFilePanel();
177         file_panel->SetTarget( this );
178         file_panel->Show();
179         b_empty_playlist = false;
180         p_mediaControl->SetEnabled( !b_empty_playlist );
181         break;
182
183         case OPEN_PLAYLIST:
184                 {
185                     BRect rect(20,20,320,420);
186             playlist_t *p_playlist = (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
187                                                        FIND_ANYWHERE );
188
189             playlist_window = PlayListWindow::getPlayList(rect,
190                                 "Playlist", p_playlist);
191             playlist_window->Show();                    
192         }
193                 break;
194     case OPEN_DVD:
195         {
196             const char *psz_device;
197             BString type("dvd");
198             if( p_message->FindString("device", &psz_device) != B_ERROR )
199             {
200                 BString device(psz_device);
201                 p_vlc_wrapper->openDisc(type, device, 0,0);
202             }
203         }
204         break;
205
206     case STOP_PLAYBACK:
207         // this currently stops playback not nicely
208         //p_vlc_wrapper->volume_mute();
209         //snooze( 400000 );
210         p_vlc_wrapper->playlistStop();
211         p_mediaControl->SetStatus(NOT_STARTED_S,DEFAULT_RATE);
212         break;
213
214     case START_PLAYBACK:
215         /*  starts playing in normal mode */
216
217     case PAUSE_PLAYBACK:
218         /* toggle between pause and play */
219         if( p_intf->p_sys->p_input != NULL )
220         {
221             /* pause if currently playing */
222             if ( playback_status == PLAYING_S )
223             {
224                 //p_vlc_wrapper->volume_mute();
225                 //snooze( 400000 );
226                 p_vlc_wrapper->playlistPause();
227             }
228             else
229             {
230                 //p_vlc_wrapper->volume_restore();
231                 p_vlc_wrapper->playlistPlay();
232             }
233         }
234         else
235         {
236             /* Play a new file */
237             p_vlc_wrapper->playlistPlay();
238         }    
239         break;
240
241     case FASTER_PLAY:
242         /* cycle the fast playback modes */
243         //p_vlc_wrapper->volume_mute();
244         //snooze( 400000 );
245         p_vlc_wrapper->playFaster();
246         break;
247
248     case SLOWER_PLAY:
249         /*  cycle the slow playback modes */
250         //p_vlc_wrapper->volume_mute();
251         //snooze( 400000 );
252         p_vlc_wrapper->playSlower();
253         break;
254
255     case SEEK_PLAYBACK:
256         /* handled by semaphores */
257         break;
258
259     case VOLUME_CHG:
260         /* adjust the volume */
261 //        vlc_mutex_lock( &p_intf->p_sys->p_input->lock );
262 //        for( i_index = 0 ; i_index < p_aout_bank->i_count ; i_index++ )
263 //        {
264 //            if( p_aout_bank->pp_aout[i_index]->i_savedvolume )
265 //            {
266 //                p_aout_bank->pp_aout[i_index]->i_savedvolume = vol_val;
267 //            }
268 //            else
269 //            {
270 //                p_aout_bank->pp_aout[i_index]->i_volume = vol_val;
271 //            }
272 //        }
273 //        vlc_mutex_unlock( &p_aout_bank->lock );
274         break;
275
276     case VOLUME_MUTE:
277         /* toggle muting */
278         b_mute != b_mute;
279         p_vlc_wrapper->volumeMute( b_mute );
280         break;
281
282     case SELECT_AUDIO:
283         {
284             int32 i = p_message->FindInt32( "audio" );
285             p_vlc_wrapper->toggleLanguage( i );
286         }
287         break;
288
289     case SELECT_SUBTITLE:
290         {
291             int32 i = p_message->FindInt32( "subtitle" );
292             p_vlc_wrapper->toggleSubtitle( i );
293         }
294         break;
295     case PREV_TITLE:
296         {
297             int             i_id;
298             i_id = p_intf->p_sys->p_input->stream.p_selected_area->i_id - 1;
299
300             /* Disallow area 0 since it is used for video_ts.vob */
301             if( i_id > 0 )
302             {
303                 p_vlc_wrapper->toggleTitle(i_id);
304             }
305             break;
306         }
307     case NEXT_TITLE:
308         {
309             int             i_id;
310
311             i_id = p_intf->p_sys->p_input->stream.p_selected_area->i_id + 1;
312
313             if( i_id < p_intf->p_sys->p_input->stream.i_area_nb )
314             {
315                 p_vlc_wrapper->toggleTitle(i_id);
316             }
317         }
318         break;
319     case PREV_CHAPTER:
320         {
321             int             i_id;
322
323             i_id = p_intf->p_sys->p_input->stream.p_selected_area->i_part - 1;
324
325             if( i_id >= 0 )
326             {
327                 p_vlc_wrapper->toggleChapter(i_id);
328             }
329         }
330         break;
331     case NEXT_CHAPTER:
332         {
333             int             i_id;
334
335             i_id = p_intf->p_sys->p_input->stream.p_selected_area->i_part + 1;
336
337             if( i_id >= 0 )
338             {
339                 p_vlc_wrapper->toggleChapter(i_id);
340             }
341         }
342         break;
343     case B_REFS_RECEIVED:
344     case B_SIMPLE_DATA:
345         {
346             entry_ref ref;
347             BList* files = new BList();
348
349             int i = 0;
350             while( p_message->FindRef( "refs", i, &ref ) == B_OK )
351             {
352                 BPath path( &ref );
353
354                 files->AddItem(new BString((char*)path.Path()) );
355                 i++;
356             }
357             p_vlc_wrapper->openFiles(files);
358             delete files;
359         }
360         break;
361
362     default:
363         BWindow::MessageReceived( p_message );
364         break;
365     }
366
367 }
368
369 /*****************************************************************************
370  * InterfaceWindow::updateInterface
371  *****************************************************************************/
372 void InterfaceWindow::updateInterface()
373 {
374
375         if ( p_intf->p_sys->p_input != NULL )
376         {
377         if ( acquire_sem(p_mediaControl->fScrubSem) == B_OK )
378         {
379             p_vlc_wrapper->setTimeAsFloat(p_mediaControl->GetSeekTo());
380         }
381         else if( Lock() )
382         {
383             p_mediaControl->SetStatus(p_intf->p_sys->p_input->stream.control.i_status, 
384                                       p_intf->p_sys->p_input->stream.control.i_rate);
385             p_mediaControl->SetProgress(p_intf->p_sys->p_input->stream.p_selected_area->i_tell,
386                                         p_intf->p_sys->p_input->stream.p_selected_area->i_size);
387             Unlock();
388         }
389     }
390     
391     playlist_t *p_playlist = (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
392                                                        FIND_ANYWHERE );
393
394     if ( b_empty_playlist != (p_playlist->i_size < 1) )
395     {
396         if (Lock())
397         {
398             b_empty_playlist = !b_empty_playlist;
399             p_mediaControl->SetEnabled( !b_empty_playlist );
400             Unlock();
401         }
402     }
403 }
404
405 /*****************************************************************************
406  * InterfaceWindow::QuitRequested
407  *****************************************************************************/
408 bool InterfaceWindow::QuitRequested()
409 {
410     p_intf->p_vlc->b_die = VLC_TRUE;
411
412     return( true );
413 }
414
415 /*****************************************************************************
416  * CDMenu::CDMenu
417  *****************************************************************************/
418 CDMenu::CDMenu(const char *name)
419       : BMenu(name)
420 {
421 }
422
423 /*****************************************************************************
424  * CDMenu::~CDMenu
425  *****************************************************************************/
426 CDMenu::~CDMenu()
427 {
428 }
429
430 /*****************************************************************************
431  * CDMenu::AttachedToWindow
432  *****************************************************************************/
433 void CDMenu::AttachedToWindow(void)
434 {
435     while (RemoveItem((long int)0) != NULL);  // remove all items
436     GetCD("/dev/disk");
437     BMenu::AttachedToWindow();
438 }
439
440 /*****************************************************************************
441  * CDMenu::GetCD
442  *****************************************************************************/
443 int CDMenu::GetCD( const char *directory )
444 {
445         BVolumeRoster *volRoster;
446         BVolume       *vol;
447         BDirectory    *dir;
448         int           status;
449         int           mounted;   
450         char          name[B_FILE_NAME_LENGTH]; 
451     fs_info       info;
452         dev_t         dev;
453         
454         volRoster = new BVolumeRoster();
455         vol = new BVolume();
456         dir = new BDirectory();
457         status = volRoster->GetNextVolume(vol);
458         status = vol->GetRootDirectory(dir);
459         while (status ==  B_NO_ERROR)
460         {
461             mounted = vol->GetName(name);       
462             if ((mounted == B_OK) && /* Disk is currently Mounted */
463                 (vol->IsReadOnly()) ) /* Disk is read-only */
464             {
465                 dev = vol->Device();
466             fs_stat_dev(dev, &info);
467             
468             device_geometry g;
469             int i_dev;
470             i_dev = open( info.device_name, O_RDONLY );
471            
472             if( i_dev >= 0 )
473             {
474                 if( ioctl(i_dev, B_GET_GEOMETRY, &g, sizeof(g)) >= 0 )
475                 {
476                     if( g.device_type == B_CD ) //ensure the drive is a CD-ROM
477                     {
478                         BMessage *msg;
479                         msg = new BMessage( OPEN_DVD );
480                         msg->AddString( "device", info.device_name );
481                         BMenuItem *menu_item;
482                         menu_item = new BMenuItem( name, msg );
483                         AddItem( menu_item );
484                     }
485                     close(i_dev);
486                 }
487             }
488             }
489             vol->Unset();
490             status = volRoster->GetNextVolume(vol);
491         }
492 }
493
494 /*****************************************************************************
495  * LanguageMenu::LanguageMenu
496  *****************************************************************************/
497 LanguageMenu::LanguageMenu(const char *name, int menu_kind, 
498                             intf_thread_t  *p_interface)
499     :BMenu(name)
500 {
501     kind = menu_kind;
502     p_intf = p_interface;
503 }
504
505 /*****************************************************************************
506  * LanguageMenu::~LanguageMenu
507  *****************************************************************************/
508 LanguageMenu::~LanguageMenu()
509 {
510 }
511
512 /*****************************************************************************
513  * LanguageMenu::AttachedToWindow
514  *****************************************************************************/
515 void LanguageMenu::AttachedToWindow(void)
516 {
517     while( RemoveItem((long int)0) != NULL )
518     {
519         ; // remove all items
520     }
521
522     SetRadioMode(true);
523     GetChannels();
524     BMenu::AttachedToWindow();
525 }
526
527 /*****************************************************************************
528  * LanguageMenu::GetChannels
529  *****************************************************************************/
530 int LanguageMenu::GetChannels()
531 {
532     char  *psz_name;
533     bool   b_active;
534     BMessage *msg;
535     int    i;
536     es_descriptor_t *p_es  = NULL;
537
538     /* Insert the null */
539     if( kind == SPU_ES ) //audio
540     {
541         msg = new BMessage(SELECT_SUBTITLE);
542         msg->AddInt32("subtitle", -1);
543         BMenuItem *menu_item;
544         menu_item = new BMenuItem("None", msg);
545         AddItem(menu_item);
546         menu_item->SetMarked(TRUE);
547
548     }
549
550     if( p_intf->p_sys->p_input == NULL )
551     {
552         return 1;
553     }
554
555
556     vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
557     for( i = 0; i < p_intf->p_sys->p_input->stream.i_selected_es_number; i++ )
558     {
559         if( kind == p_intf->p_sys->p_input->stream.pp_selected_es[i]->i_cat )
560         {
561             p_es = p_intf->p_sys->p_input->stream.pp_selected_es[i];
562         }
563     }
564
565     for( i = 0; i < p_intf->p_sys->p_input->stream.i_es_number; i++ )
566     {
567         if( kind == p_intf->p_sys->p_input->stream.pp_es[i]->i_cat )
568         {
569             psz_name = p_intf->p_sys->p_input->stream.pp_es[i]->psz_desc;
570             if ( strlen(psz_name) == 0 )
571             {
572                 // change to default etc
573             }
574             if( kind == AUDIO_ES ) //audio
575             {
576                 msg = new BMessage(SELECT_AUDIO);
577                 msg->AddInt32("channel", i);
578             }
579             else
580             {
581                 msg = new BMessage(SELECT_SUBTITLE);
582                 msg->AddInt32("subtitle", i);
583             }
584             BMenuItem *menu_item;
585             menu_item = new BMenuItem(psz_name, msg);
586             AddItem(menu_item);
587             b_active = (p_es == p_intf->p_sys->p_input->stream.pp_es[i]);
588             menu_item->SetMarked(b_active);
589         }
590     }
591     vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
592
593 }
594
595
596