]> git.sesse.net Git - vlc/blob - plugins/beos/InterfaceWindow.cpp
Some heavy changes today:
[vlc] / plugins / beos / InterfaceWindow.cpp
1 /*****************************************************************************
2  * InterfaceWindow.cpp: beos interface
3  *****************************************************************************
4  * Copyright (C) 1999, 2000, 2001 VideoLAN
5  * $Id: InterfaceWindow.cpp,v 1.11 2001/12/30 07:09:54 sam 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 <malloc.h>
33 #include <scsi.h>
34 #include <scsiprobe_driver.h>
35 #include <fs_info.h>
36 #include <string.h>
37
38
39 /* VLC headers */
40 extern "C"
41 {
42 #include <videolan/vlc.h>
43
44 #include "stream_control.h"
45 #include "input_ext-intf.h"
46
47 #include "interface.h"
48 #include "intf_playlist.h"
49
50 #include "audio_output.h"
51 }
52
53 /* BeOS interface headers */
54 #include "MsgVals.h"
55 #include "MediaControlView.h"
56 #include "InterfaceWindow.h"
57 #include "PlayListWindow.h"
58
59 /*****************************************************************************
60  * InterfaceWindow
61  *****************************************************************************/
62
63 InterfaceWindow::InterfaceWindow( BRect frame, const char *name,
64                                   intf_thread_t  *p_interface )
65     : BWindow( frame, name, B_FLOATING_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL,
66                B_NOT_RESIZABLE | B_NOT_ZOOMABLE | B_WILL_ACCEPT_FIRST_CLICK
67                 | B_ASYNCHRONOUS_CONTROLS )
68 {
69     file_panel = NULL;
70     p_intf = p_interface;
71     BRect controlRect(0,0,0,0);
72     b_empty_playlist = (p_main->p_playlist->i_size < 0);
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
128     ResizeTo(260,50 + menu_bar->Bounds().IntegerHeight()+1);
129     controlRect = Bounds();
130     controlRect.top += menu_bar->Bounds().IntegerHeight() + 1;
131
132     p_mediaControl = new MediaControlView( controlRect );
133     p_mediaControl->SetViewColor( ui_color(B_PANEL_BACKGROUND_COLOR) );
134
135     /* Show */
136     AddChild( p_mediaControl );
137     Show();
138     
139 }
140
141 InterfaceWindow::~InterfaceWindow()
142 {
143 }
144
145 /*****************************************************************************
146  * InterfaceWindow::MessageReceived
147  *****************************************************************************/
148 void InterfaceWindow::MessageReceived( BMessage * p_message )
149 {
150     int vol_val = p_mediaControl->GetVolume();    // remember the current volume
151     int playback_status;      // remember playback state
152     int     i_index;
153     BAlert *alert;
154
155     Activate();
156     if (p_intf->p_input)
157     {
158             playback_status = p_intf->p_input->stream.control.i_status;
159         }
160         else
161         {
162             playback_status = UNDEF_S;
163         }
164
165     switch( p_message->what )
166     {
167     case B_ABOUT_REQUESTED:
168         alert = new BAlert(VOUT_TITLE, "BeOS " VOUT_TITLE "\n\n<www.videolan.org>", "Ok");
169         alert->Go();
170         break;
171
172     case OPEN_FILE:
173         if( file_panel )
174         {
175             file_panel->Show();
176             break;
177         }
178         file_panel = new BFilePanel();
179         file_panel->SetTarget( this );
180         file_panel->Show();
181         break;
182
183         case OPEN_PLAYLIST:
184                 {
185                     BRect rect(20,20,320,420);
186             PlayListWindow* playlist_window = new PlayListWindow(rect,
187                          "Playlist", (playlist_t *)p_main->p_playlist);
188             playlist_window->Show();
189         }
190                 break;
191     case OPEN_DVD:
192         const char *psz_device;
193         char psz_source[ B_FILE_NAME_LENGTH + 4 ];
194         if( p_message->FindString("device", &psz_device) != B_ERROR )
195         {
196             snprintf( psz_source, B_FILE_NAME_LENGTH + 4,
197                       "dvd:%s", psz_device );
198             psz_source[ strlen(psz_source) ] = '\0';
199             intf_PlaylistAdd( p_main->p_playlist, PLAYLIST_END, (char*)psz_source );
200             if( p_intf->p_input != NULL )
201             {
202                 p_intf->p_input->b_eof = 1;
203             }
204             intf_PlaylistJumpto( p_main->p_playlist, 
205                                  p_main->p_playlist->i_size - 1 );
206         }
207         break;
208
209     case STOP_PLAYBACK:
210         // this currently stops playback not nicely
211         if( p_intf->p_input != NULL )
212         {
213             // silence the sound, otherwise very horrible
214             vlc_mutex_lock( &p_aout_bank->lock );
215             for( i_index = 0 ; i_index < p_aout_bank->i_count ; i_index++ )
216             {
217                 p_aout_bank->pp_aout[i_index]->i_savedvolume = p_aout_bank->pp_aout[i_index]->i_volume;
218                 p_aout_bank->pp_aout[i_index]->i_volume = 0;
219             }
220             vlc_mutex_unlock( &p_aout_bank->lock );
221             snooze( 400000 );
222
223             /* end playing item */
224             p_intf->p_input->b_eof = 1;
225             
226             /* update playlist */
227             vlc_mutex_lock( &p_main->p_playlist->change_lock );
228             p_main->p_playlist->i_index--;
229             p_main->p_playlist->b_stopped = 1;
230             vlc_mutex_unlock( &p_main->p_playlist->change_lock );
231         }
232         p_mediaControl->SetStatus(NOT_STARTED_S,DEFAULT_RATE);
233         break;
234
235     case START_PLAYBACK:
236         /*  starts playing in normal mode */
237
238     case PAUSE_PLAYBACK:
239         /* toggle between pause and play */
240         if( p_intf->p_input != NULL )
241         {
242             /* pause if currently playing */
243             if( playback_status == PLAYING_S )
244             {
245                 /* mute the sound */
246                 vlc_mutex_lock( &p_aout_bank->lock );
247                 for( i_index = 0 ; i_index < p_aout_bank->i_count ; i_index++ )
248                 {
249                     p_aout_bank->pp_aout[i_index]->i_savedvolume =
250                                        p_aout_bank->pp_aout[i_index]->i_volume;
251                     p_aout_bank->pp_aout[i_index]->i_volume = 0;
252                 }
253                 vlc_mutex_unlock( &p_aout_bank->lock );
254                 snooze( 400000 );
255                 
256                 /* pause the movie */
257                 input_SetStatus( p_intf->p_input, INPUT_STATUS_PAUSE );
258                 vlc_mutex_lock( &p_main->p_playlist->change_lock );
259                 p_main->p_playlist->b_stopped = 0;
260                 vlc_mutex_unlock( &p_main->p_playlist->change_lock );
261             }
262             else
263             {
264                 /* Play after pausing */
265                 /* Restore the volume */
266                 vlc_mutex_lock( &p_aout_bank->lock );
267                 for( i_index = 0 ; i_index < p_aout_bank->i_count ; i_index++ )
268                 {
269                     p_aout_bank->pp_aout[i_index]->i_volume =
270                                   p_aout_bank->pp_aout[i_index]->i_savedvolume;
271                     p_aout_bank->pp_aout[i_index]->i_savedvolume = 0;
272                 }
273                 vlc_mutex_unlock( &p_aout_bank->lock );
274                 snooze( 400000 );
275                 
276                 /* Start playing */
277                 input_SetStatus( p_intf->p_input, INPUT_STATUS_PLAY );
278                 p_main->p_playlist->b_stopped = 0;
279             }
280         }
281         else
282         {
283             /* Play a new file */
284             vlc_mutex_lock( &p_main->p_playlist->change_lock );
285             if( p_main->p_playlist->b_stopped )
286             {
287                 if( p_main->p_playlist->i_size )
288                 {
289                     vlc_mutex_unlock( &p_main->p_playlist->change_lock );
290                     intf_PlaylistJumpto( p_main->p_playlist, 
291                                          p_main->p_playlist->i_index );
292                     p_main->p_playlist->b_stopped = 0;
293                 }
294                 else
295                 {
296                     vlc_mutex_unlock( &p_main->p_playlist->change_lock );
297                 }
298             }
299         }    
300         break;
301
302     case FASTER_PLAY:
303         /* cycle the fast playback modes */
304         if( p_intf->p_input != NULL )
305         {
306             /* mute the sound */
307             vlc_mutex_lock( &p_aout_bank->lock );
308             for( i_index = 0 ; i_index < p_aout_bank->i_count ; i_index++ )
309             {
310                 p_aout_bank->pp_aout[i_index]->i_savedvolume =
311                                        p_aout_bank->pp_aout[i_index]->i_volume;
312                 p_aout_bank->pp_aout[i_index]->i_volume = 0;
313             }
314             vlc_mutex_unlock( &p_aout_bank->lock );
315             snooze( 400000 );
316
317             /* change the fast play mode */
318             input_SetStatus( p_intf->p_input, INPUT_STATUS_FASTER );
319             vlc_mutex_lock( &p_main->p_playlist->change_lock );
320             p_main->p_playlist->b_stopped = 0;
321             vlc_mutex_unlock( &p_main->p_playlist->change_lock );
322         }
323         break;
324
325     case SLOWER_PLAY:
326         /*  cycle the slow playback modes */
327         if (p_intf->p_input != NULL )
328         {
329             /* mute the sound */
330             vlc_mutex_lock( &p_aout_bank->lock );
331             for( i_index = 0 ; i_index < p_aout_bank->i_count ; i_index++ )
332             {
333                 p_aout_bank->pp_aout[i_index]->i_savedvolume =
334                                        p_aout_bank->pp_aout[i_index]->i_volume;
335                 p_aout_bank->pp_aout[i_index]->i_volume = 0;
336             }
337             vlc_mutex_unlock( &p_aout_bank->lock );
338             snooze( 400000 );
339
340             /* change the slower play */
341             input_SetStatus( p_intf->p_input, INPUT_STATUS_SLOWER );
342             vlc_mutex_lock( &p_main->p_playlist->change_lock );
343             p_main->p_playlist->b_stopped = 0;
344             vlc_mutex_unlock( &p_main->p_playlist->change_lock );
345         }
346         break;
347
348     case SEEK_PLAYBACK:
349         /* handled by semaphores */
350         break;
351
352     case VOLUME_CHG:
353         /* adjust the volume */
354         vlc_mutex_lock( &p_aout_bank->lock );
355         for( i_index = 0 ; i_index < p_aout_bank->i_count ; i_index++ )
356         {
357             if( p_aout_bank->pp_aout[i_index]->i_savedvolume )
358             {
359                 p_aout_bank->pp_aout[i_index]->i_savedvolume = vol_val;
360             }
361             else
362             {
363                 p_aout_bank->pp_aout[i_index]->i_volume = vol_val;
364             }
365         }
366         vlc_mutex_unlock( &p_aout_bank->lock );
367         break;
368
369     case VOLUME_MUTE:
370         /* toggle muting */
371         vlc_mutex_lock( &p_aout_bank->lock );
372         for( i_index = 0 ; i_index < p_aout_bank->i_count ; i_index++ )
373         {
374             if( p_aout_bank->pp_aout[i_index]->i_savedvolume )
375             {
376                 p_aout_bank->pp_aout[i_index]->i_volume =
377                                   p_aout_bank->pp_aout[i_index]->i_savedvolume;
378                 p_aout_bank->pp_aout[i_index]->i_savedvolume = 0;
379             }
380             else
381             {
382                 p_aout_bank->pp_aout[i_index]->i_savedvolume =
383                                        p_aout_bank->pp_aout[i_index]->i_volume;
384                 p_aout_bank->pp_aout[i_index]->i_volume = 0;
385             }
386         }
387         vlc_mutex_unlock( &p_aout_bank->lock );
388         break;
389
390     case SELECT_CHANNEL:
391         {
392             int32 i = p_message->FindInt32( "channel" );
393             if ( i == -1 )
394             {
395                 input_ChangeES( p_intf->p_input, NULL, AUDIO_ES );
396             }
397             else
398             {
399                 input_ChangeES( p_intf->p_input,
400                         p_intf->p_input->stream.pp_es[i], AUDIO_ES );
401             }
402         }
403         break;
404
405     case SELECT_SUBTITLE:
406         {
407             int32 i = p_message->FindInt32( "subtitle" );
408             if ( i == -1 )
409             {
410                 input_ChangeES( p_intf->p_input, NULL, SPU_ES);
411             }
412             else
413             {
414                 input_ChangeES( p_intf->p_input,
415                         p_intf->p_input->stream.pp_es[i], SPU_ES );
416             }
417         }
418         break;
419     case PREV_TITLE:
420         {
421             input_area_t *  p_area;
422             int             i_id;
423
424             i_id = p_intf->p_input->stream.p_selected_area->i_id - 1;
425
426             /* Disallow area 0 since it is used for video_ts.vob */
427             if( i_id > 0 )
428             {
429                 p_area = p_intf->p_input->stream.pp_areas[i_id];
430                 input_ChangeArea( p_intf->p_input, (input_area_t*)p_area );
431                 input_SetStatus( p_intf->p_input, INPUT_STATUS_PLAY );
432             }
433             break;
434         }
435     case NEXT_TITLE:
436         {
437             input_area_t *  p_area;
438             int             i_id;
439
440             i_id = p_intf->p_input->stream.p_selected_area->i_id + 1;
441
442             if( i_id < p_intf->p_input->stream.i_area_nb )
443             {
444                 p_area = p_intf->p_input->stream.pp_areas[i_id];
445                 input_ChangeArea( p_intf->p_input, (input_area_t*)p_area );
446                 input_SetStatus( p_intf->p_input, INPUT_STATUS_PLAY );
447             }
448         }
449         break;
450     case PREV_CHAPTER:
451         {
452             input_area_t *  p_area;
453
454             p_area = p_intf->p_input->stream.p_selected_area;
455
456             if( p_area->i_part > 0 )
457             {
458                 p_area->i_part--;
459                 input_ChangeArea( p_intf->p_input, (input_area_t*)p_area );
460                 input_SetStatus( p_intf->p_input, INPUT_STATUS_PLAY );
461             }
462         }
463         break;
464     case NEXT_CHAPTER:
465         {
466             input_area_t *  p_area;
467
468             p_area = p_intf->p_input->stream.p_selected_area;
469
470             if( p_area->i_part > 0 )
471             {
472                 p_area->i_part++;
473                 input_ChangeArea( p_intf->p_input, (input_area_t*)p_area );
474                 input_SetStatus( p_intf->p_input, INPUT_STATUS_PLAY );
475             }
476         }
477         break;
478     case B_REFS_RECEIVED:
479     case B_SIMPLE_DATA:
480         {
481             entry_ref ref;
482             if( p_message->FindRef( "refs", &ref ) == B_OK )
483             {
484                 BPath path( &ref );
485                 intf_PlaylistAdd( p_main->p_playlist,
486                                   PLAYLIST_END, (char*)path.Path() );
487                 if( p_intf->p_input != NULL )
488                 {
489                     p_intf->p_input->b_eof = 1;
490                 }
491                 intf_PlaylistJumpto( p_main->p_playlist, 
492                                      p_main->p_playlist->i_size - 1 );
493                                   
494              }
495         }
496         break;
497
498     default:
499         BWindow::MessageReceived( p_message );
500         break;
501     }
502
503 }
504
505 /*****************************************************************************
506  * InterfaceWindow::updateInterface
507  *****************************************************************************/
508 void InterfaceWindow::updateInterface()
509 {
510         if ( p_intf->p_input )
511         {
512         if ( acquire_sem(p_mediaControl->fScrubSem) == B_OK )
513         {
514             uint64 seekTo = (p_mediaControl->GetSeekTo() *
515                         p_intf->p_input->stream.p_selected_area->i_size) / 100;
516             input_Seek( p_intf->p_input, seekTo);
517         }
518         else if( Lock() )
519         {
520             p_mediaControl->SetStatus(p_intf->p_input->stream.control.i_status, 
521                                       p_intf->p_input->stream.control.i_rate);
522             p_mediaControl->SetProgress(p_intf->p_input->stream.p_selected_area->i_tell,
523                                         p_intf->p_input->stream.p_selected_area->i_size);
524             Unlock();
525         }
526     }
527     if ( b_empty_playlist != (p_main->p_playlist->i_size < 1) )
528     {
529         if (Lock())
530         {
531             b_empty_playlist = !b_empty_playlist;
532             p_mediaControl->SetEnabled( !b_empty_playlist );
533             Unlock();
534         }
535     }
536 }
537
538 /*****************************************************************************
539  * InterfaceWindow::QuitRequested
540  *****************************************************************************/
541 bool InterfaceWindow::QuitRequested()
542 {
543     p_intf->b_die = 1;
544
545     return( false );
546 }
547
548 /*****************************************************************************
549  * CDMenu::CDMenu
550  *****************************************************************************/
551 CDMenu::CDMenu(const char *name)
552       : BMenu(name)
553 {
554 }
555
556 /*****************************************************************************
557  * CDMenu::~CDMenu
558  *****************************************************************************/
559 CDMenu::~CDMenu()
560 {
561 }
562
563 /*****************************************************************************
564  * CDMenu::AttachedToWindow
565  *****************************************************************************/
566 void CDMenu::AttachedToWindow(void)
567 {
568     while (RemoveItem((long int)0) != NULL);  // remove all items
569     GetCD("/dev/disk");
570     BMenu::AttachedToWindow();
571 }
572
573 /*****************************************************************************
574  * CDMenu::GetCD
575  *****************************************************************************/
576 int CDMenu::GetCD( const char *directory )
577 {
578         BVolumeRoster *volRoster;
579         BVolume       *vol;
580         BDirectory    *dir;
581         int           status;
582         int           mounted;   
583         char          name[B_FILE_NAME_LENGTH]; 
584     fs_info       info;
585         dev_t         dev;
586         
587         volRoster = new BVolumeRoster();
588         vol = new BVolume();
589         dir = new BDirectory();
590         status = volRoster->GetNextVolume(vol);
591         status = vol->GetRootDirectory(dir);
592         while (status ==  B_NO_ERROR)
593         {
594             mounted = vol->GetName(name);       
595             if ((mounted == B_OK) && /* Disk is currently Mounted */
596                 (vol->IsReadOnly()) ) /* Disk is read-only */
597             {
598                 dev = vol->Device();
599             fs_stat_dev(dev, &info);
600             
601             device_geometry g;
602             int i_dev;
603             i_dev = open( info.device_name, O_RDONLY );
604            
605             if( i_dev >= 0 )
606             {
607                 if( ioctl(i_dev, B_GET_GEOMETRY, &g, sizeof(g)) >= 0 )
608                 {
609                     if( g.device_type == B_CD ) //ensure the drive is a CD-ROM
610                     {
611                         BMessage *msg;
612                         msg = new BMessage( OPEN_DVD );
613                         msg->AddString( "device", info.device_name );
614                         BMenuItem *menu_item;
615                         menu_item = new BMenuItem( name, msg );
616                         AddItem( menu_item );
617                     }
618                     close(i_dev);
619                 }
620             }
621             }
622             vol->Unset();
623             status = volRoster->GetNextVolume(vol);
624         }
625 }
626
627 /*****************************************************************************
628  * LanguageMenu::LanguageMenu
629  *****************************************************************************/
630 LanguageMenu::LanguageMenu(const char *name, int menu_kind, 
631                             intf_thread_t  *p_interface)
632     :BMenu(name)
633 {
634     kind = menu_kind;
635     p_intf = p_interface;
636 }
637
638 /*****************************************************************************
639  * LanguageMenu::~LanguageMenu
640  *****************************************************************************/
641 LanguageMenu::~LanguageMenu()
642 {
643 }
644
645 /*****************************************************************************
646  * LanguageMenu::AttachedToWindow
647  *****************************************************************************/
648 void LanguageMenu::AttachedToWindow(void)
649 {
650     while( RemoveItem((long int)0) != NULL )
651     {
652         ; // remove all items
653     }
654
655     SetRadioMode(true);
656     GetChannels();
657     BMenu::AttachedToWindow();
658 }
659
660 /*****************************************************************************
661  * LanguageMenu::GetChannels
662  *****************************************************************************/
663 int LanguageMenu::GetChannels()
664 {
665     char  *psz_name;
666     bool   b_active;
667     BMessage *msg;
668     int    i;
669     es_descriptor_t *p_es  = NULL;
670
671     /* Insert the null */
672     if( kind == AUDIO_ES ) //audio
673     {
674         msg = new BMessage(SELECT_CHANNEL);
675         msg->AddInt32("channel", -1);
676     }
677     else
678     {
679         msg = new BMessage(SELECT_SUBTITLE);
680         msg->AddInt32("subtitle", -1);
681     }
682     BMenuItem *menu_item;
683     menu_item = new BMenuItem("None", msg);
684     AddItem(menu_item);
685     menu_item->SetMarked(TRUE);
686
687     if( p_intf->p_input == NULL )
688     {
689         return 1;
690     }
691
692
693     vlc_mutex_lock( &p_intf->p_input->stream.stream_lock );
694     for( i = 0; i < p_intf->p_input->stream.i_selected_es_number; i++ )
695     {
696         if( kind == p_intf->p_input->stream.pp_selected_es[i]->i_cat )
697         {
698             p_es = p_intf->p_input->stream.pp_selected_es[i];
699         }
700     }
701
702     for( i = 0; i < p_intf->p_input->stream.i_es_number; i++ )
703     {
704         if( kind == p_intf->p_input->stream.pp_es[i]->i_cat )
705         {
706             psz_name = p_intf->p_input->stream.pp_es[i]->psz_desc;
707             if( kind == AUDIO_ES ) //audio
708             {
709                 msg = new BMessage(SELECT_CHANNEL);
710                 msg->AddInt32("channel", i);
711             }
712             else
713             {
714                 msg = new BMessage(SELECT_SUBTITLE);
715                 msg->AddInt32("subtitle", i);
716             }
717             BMenuItem *menu_item;
718             menu_item = new BMenuItem(psz_name, msg);
719             AddItem(menu_item);
720             b_active = (p_es == p_intf->p_input->stream.pp_es[i]);
721             menu_item->SetMarked(b_active);
722         }
723     }
724     vlc_mutex_unlock( &p_intf->p_input->stream.stream_lock );
725
726 }
727
728
729