modules/gui/beos/PreferenceWindow.h/.cpp
[vlc.git] / modules / gui / beos / PreferencesWindow.cpp
1 /*****************************************************************************
2  * PreferencesWindow.cpp: beos interface
3  *****************************************************************************
4  * Copyright (C) 1999, 2000, 2001 VideoLAN
5  * $Id: PreferencesWindow.cpp,v 1.13 2003/02/09 17:10:52 stippi Exp $
6  *
7  * Authors: Eric Petit <titer@videolan.org>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
22  *****************************************************************************/
23
24 /* system headers */
25 #include <malloc.h>
26 #include <string.h>
27
28 /* BeOS headers */
29 #include <InterfaceKit.h>
30 #include <Entry.h>
31 #include <Path.h>
32 #include <TranslatorRoster.h>
33
34 /* VLC headers */
35 #include <vlc/vlc.h>
36 #include <vlc/intf.h>
37
38 /* BeOS module headers */
39 #include "VlcWrapper.h"
40 #include "MsgVals.h"
41 #include "PreferencesWindow.h"
42
43 static const char* kTranslatorField = "be:translator";
44 static const char* kTypeField = "be:type";
45 static const char* kDefaultScreenShotPath = "/boot/home/vlc screenshot";
46 static const uint32 kDefaultScreenShotFormat = 'PNG ';
47
48 // add_translator_items
49 status_t
50 add_translator_items( BMenu* intoMenu, uint32 fromType, uint32 command )
51
52         BTranslatorRoster* roster = BTranslatorRoster::Default();
53         translator_id* ids = NULL;
54         int32 count = 0;
55         
56         status_t err = B_NO_INIT;
57         if ( roster )
58                 err = roster->GetAllTranslators( &ids, &count );
59         if ( err < B_OK )
60                 return err;
61         for ( int32 tix = 0; tix < count; tix++ )
62         { 
63                 const translation_format* formats = NULL;
64                 int32 num_formats = 0;
65                 bool checkOutFormats = false; 
66                 err = roster->GetInputFormats( ids[tix], &formats, &num_formats );
67                 if ( err == B_OK )
68                 {
69                         for ( int iix = 0; iix < num_formats; iix++ )
70                         {
71                                 if ( formats[iix].type == fromType )
72                                 { 
73                                         checkOutFormats = true;
74                                         break;
75                                 }
76                         }
77                 }
78                 if ( !checkOutFormats )
79                         continue;
80                 err = roster->GetOutputFormats(ids[tix], &formats, &num_formats);
81                 if ( err == B_OK )
82                 {
83                         for ( int32 oix = 0; oix < num_formats; oix++ )
84                         {
85                                 if ( formats[oix].type != fromType )
86                                 {
87                                         BMessage* message = new BMessage( command );
88                                         message->AddInt32( kTranslatorField, ids[tix] );
89                                         message->AddInt32( kTypeField, formats[oix].type );
90                                         intoMenu->AddItem( new BMenuItem( formats[oix].name, message ) );
91                                 }
92                         }
93                 } 
94         }
95         delete[] ids;
96         return B_OK; 
97 }
98
99 // get_config_string
100 char*
101 get_config_string( intf_thread_t* intf, const char* field, const char* defaultString )
102 {
103         char* string = config_GetPsz( intf, field );
104         if ( !string )
105         {
106                 string = strdup( defaultString );
107                 config_PutPsz( intf, field, string );
108         }
109         return string;
110 }
111
112 // get_config_int
113 int32
114 get_config_int( intf_thread_t* intf, const char* field, int32 defaultValue )
115 {
116         int32 value = config_GetInt( intf, field );
117         if ( value < 0 )
118         {
119                 value = defaultValue;
120                 config_PutInt( intf, field, value );
121         }
122         return value;
123 }
124
125 // get_config_float
126 float
127 get_config_float( intf_thread_t* intf, const char* field, float defaultValue )
128 {
129         float value = config_GetFloat( intf, field );
130         if ( value < 0 )
131         {
132                 value = defaultValue;
133                 config_PutFloat( intf, field, value );
134         }
135         return value;
136 }
137
138
139 /*****************************************************************************
140  * DirectoryTextControl class
141  *****************************************************************************/
142 class DirectoryTextControl : public BTextControl
143 {
144  public:
145         DirectoryTextControl( BRect frame, const char* name, 
146                                                   const char* label, const char* text,
147                                                   BMessage* message,
148                                                   uint32 resizingMode = B_FOLLOW_LEFT | B_FOLLOW_TOP,
149                                                   uint32 flags = B_WILL_DRAW | B_NAVIGABLE );
150         virtual                         ~DirectoryTextControl();
151
152         virtual void            MessageReceived(BMessage *msg);
153 };
154
155 DirectoryTextControl::DirectoryTextControl( BRect frame, const char* name, 
156                                                                                         const char* label, const char* text,
157                                                                                         BMessage* message,
158                                                                                         uint32 resizingMode, uint32 flags)
159         : BTextControl( frame, name, label, text, message, resizingMode, flags )
160 {
161 }
162
163 DirectoryTextControl::~DirectoryTextControl()
164 {
165 }
166
167 /*****************************************************************************
168  * DirectoryTextControl::MessageReceived
169  *****************************************************************************/
170 void
171 DirectoryTextControl::MessageReceived( BMessage* message )
172 {
173         switch ( message->what )
174         {
175                 case B_SIMPLE_DATA:
176                 {
177                         entry_ref ref;
178                         if ( message->FindRef( "refs", &ref ) == B_OK ) {
179                                 BString directory;
180                                 BEntry entry;
181                                 BPath path;
182                                 if ( entry.SetTo( &ref, true ) == B_OK
183                                          && entry.IsDirectory()
184                                          && path.SetTo( &entry ) == B_OK )
185                                 {
186                                         SetText( path.Path() );
187                                 }
188                         }
189                         break;
190                 }
191                 default:
192                         BTextControl::MessageReceived( message );
193                         break;
194         }
195 }
196
197
198
199 /*****************************************************************************
200  * Preferences::PreferencesWindow
201  *****************************************************************************/
202 PreferencesWindow::PreferencesWindow( intf_thread_t * p_interface,
203                                       BRect frame, const char * name )
204     : BWindow( frame, name, B_FLOATING_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL,
205                B_NOT_ZOOMABLE | B_NOT_RESIZABLE ),
206           fDVDMenusBackup( false ),
207           fPostProcessingBackup( 0 ),
208           fBrightnessBackup( 100.0 ),
209           fContrastBackup( 100.0 ),
210           fHueBackup( 0 ),
211           fSaturationBackup( 100.0 ),
212           fScreenShotPathBackup( kDefaultScreenShotPath ),
213           fScreenShotFormatBackup( kDefaultScreenShotFormat ),
214           p_intf( p_interface )
215 {
216     BRect rect;
217
218     /* "background" view */
219     rgb_color background = ui_color( B_PANEL_BACKGROUND_COLOR );
220     fPrefsView = new BView( Bounds(), NULL, B_FOLLOW_ALL, B_WILL_DRAW );
221     fPrefsView->SetViewColor( background );
222     AddChild( fPrefsView );
223
224     /* add the tabs */
225     rect = Bounds();
226     rect.top += 10.0;
227     rect.bottom -= 45.0;
228     fTabView = new BTabView( rect, "preferences view" );
229     fTabView->SetViewColor( background );
230     
231     fGeneralView = new BView( fTabView->Bounds(), NULL, B_FOLLOW_ALL, B_WILL_DRAW );
232     fGeneralView->SetViewColor( background );
233     fAdjustView = new BView( fTabView->Bounds(), NULL, B_FOLLOW_ALL, B_WILL_DRAW );
234     fAdjustView->SetViewColor( background );
235     
236     fGeneralTab = new BTab();
237     fTabView->AddTab( fGeneralView, fGeneralTab );
238     fGeneralTab->SetLabel( "General" );
239     
240     fAdjustTab = new BTab();
241     fTabView->AddTab( fAdjustView, fAdjustTab );
242     fAdjustTab->SetLabel( "Picture" );
243     
244     /* fills the tabs */
245     /* general tab */
246     rect = fGeneralView->Bounds();
247     rect.InsetBy( 10, 10 );
248     rect.bottom = rect.top + 10;
249     fDvdMenusCheck = new BCheckBox( rect, "dvdmenus", "Use DVD menus",
250                                   new BMessage( DVDMENUS_CHECK ) );
251     fGeneralView->AddChild( fDvdMenusCheck );
252     
253     rect.top = rect.bottom + 20;
254     rect.bottom = rect.top + 30;
255     fPpSlider = new BSlider( rect, "post-processing", "MPEG4 post-processing level",
256                                new BMessage( FFMPEG_UPDATE ),
257                                0, 6, B_TRIANGLE_THUMB,
258                                B_FOLLOW_LEFT, B_WILL_DRAW ); 
259     fPpSlider->SetHashMarks(B_HASH_MARKS_BOTTOM);
260     fPpSlider->SetHashMarkCount( 7 );
261     fPpSlider->SetLimitLabels( "None", "Maximum" );
262     fGeneralView->AddChild( fPpSlider );
263
264
265         rect.top = fPpSlider->Frame().bottom + 5.0;
266         rect.bottom = rect.top + 15.0;
267         fScreenShotPathTC = new DirectoryTextControl( rect, "screenshot path",
268                                                                                                   "Screenshot Path:",
269                                                                                                   fScreenShotPathBackup.String(),
270                                                                                                   new BMessage( SET_FOLDER ) );
271 //      fScreenShotPathTC->ResizeToPreferred();
272
273         rect.top = fScreenShotPathTC->Frame().bottom + 5.0;
274         rect.bottom = rect.top + 15.0;  // TODO: this will be so tricky to get right!
275         BMenu* translatorMenu = new BMenu( "translators" );
276         add_translator_items( translatorMenu, B_TRANSLATOR_BITMAP, SET_TRANSLATOR );
277         fScreenShotFormatMF = new BMenuField( rect, "translators field",
278                                                                                   "Screenshot Format:", translatorMenu );
279         fScreenShotFormatMF->Menu()->SetRadioMode( true );
280         fScreenShotFormatMF->Menu()->SetLabelFromMarked( true );
281         // this will most likely not work for BMenuFields
282 //      fScreenShotFormatMF->ResizeToPreferred();
283
284         fGeneralView->AddChild( fScreenShotPathTC );
285         fGeneralView->AddChild( fScreenShotFormatMF );
286
287         // make sure the controls labels are aligned nicely
288         float labelWidthM = fScreenShotFormatMF->StringWidth( fScreenShotFormatMF->Label() ) + 5.0;
289         float labelWidthP = fScreenShotPathTC->StringWidth( fScreenShotPathTC->Label() ) + 5.0;
290         if ( labelWidthM > labelWidthP )
291         {
292                 fScreenShotPathTC->SetDivider( labelWidthM );
293                 fScreenShotFormatMF->SetDivider( labelWidthM );
294         }
295         else
296         {
297                 fScreenShotPathTC->SetDivider( labelWidthP );
298                 fScreenShotFormatMF->SetDivider( labelWidthP );
299         }
300
301     /* restart message */
302     rect = fGeneralView->Bounds();
303     rect.bottom -= 40.0;
304     font_height fh;
305     be_plain_font->GetHeight( &fh );
306     rect.top = rect.bottom - ceilf( fh.ascent + fh.descent ) - 2.0;
307     fRestartString = new BStringView( rect, NULL,
308         "DVD-menu and MPEG4 settings take effect after playback is restarted." );
309     fRestartString->SetAlignment( B_ALIGN_CENTER );
310     fGeneralView->AddChild( fRestartString );
311
312     
313     /* adjust tab */
314     rect = fAdjustView->Bounds();
315     rect.InsetBy( 10, 10 );
316     rect.bottom = rect.top + 30;
317     fBrightnessSlider = new BSlider( rect, "brightness", "Brightness",
318                                        new BMessage( ADJUST_UPDATE ),
319                                        0, 200, B_TRIANGLE_THUMB,
320                                        B_FOLLOW_LEFT, B_WILL_DRAW );
321     rect.OffsetBy( 0, 40 );
322     fContrastSlider = new BSlider( rect, "contrast", "Contrast",
323                                      new BMessage( ADJUST_UPDATE ),
324                                      0, 200, B_TRIANGLE_THUMB,
325                                      B_FOLLOW_LEFT, B_WILL_DRAW );
326     rect.OffsetBy( 0, 40 );
327     fHueSlider = new BSlider( rect, "hue", "Hue",
328                                 new BMessage( ADJUST_UPDATE ),
329                                 0, 360, B_TRIANGLE_THUMB,
330                                 B_FOLLOW_LEFT, B_WILL_DRAW );
331     rect.OffsetBy( 0, 40 );
332     fSaturationSlider = new BSlider( rect, "saturation", "Saturation",
333                                        new BMessage( ADJUST_UPDATE ),
334                                        0, 200, B_TRIANGLE_THUMB,
335                                        B_FOLLOW_LEFT, B_WILL_DRAW );
336     fAdjustView->AddChild( fBrightnessSlider );
337     fAdjustView->AddChild( fContrastSlider );
338     fAdjustView->AddChild( fHueSlider );
339     fAdjustView->AddChild( fSaturationSlider );
340     
341     fPrefsView->AddChild( fTabView );
342
343     /* buttons */
344     BButton *button;
345     rect = Bounds();
346     rect.InsetBy( 10, 10 );
347     rect.top = rect.bottom - 25;
348     rect.left = rect.right - 80;
349     button = new BButton( rect, NULL, "OK", new BMessage( PREFS_OK ) );
350     fPrefsView->AddChild( button );
351
352         SetDefaultButton( button );
353
354     rect.OffsetBy( -90, 0 );
355     button = new BButton( rect, NULL, "Cancel", new BMessage( PREFS_CANCEL ) );
356     fPrefsView->AddChild( button );
357
358     rect.OffsetBy( -90, 0 );
359     button = new BButton( rect, NULL, "Revert", new BMessage( PREFS_REVERT ) );
360     fPrefsView->AddChild( button );
361
362         rect.left = Bounds().left + 10.0;
363         rect.right = rect.left + 80.0;
364     button = new BButton( rect, NULL, "Defaults", new BMessage( PREFS_DEFAULTS ) );
365     fPrefsView->AddChild( button );
366
367
368         // sync GUI to VLC 
369         _SetToSettings();
370
371     // start window thread in hidden state
372     Hide();
373     Show();
374 }
375
376 /*****************************************************************************
377  * PreferencesWindow::~PreferencesWindow
378  *****************************************************************************/
379 PreferencesWindow::~PreferencesWindow()
380 {
381 }
382
383 /*****************************************************************************
384  * PreferencesWindow::QuitRequested
385  *****************************************************************************/
386 bool
387 PreferencesWindow::QuitRequested()
388 {
389         // work arround problem when window is closed or Ok pressed though
390         // the text control has focus (it will not have commited changes)
391         config_PutPsz( p_intf, "beos-screenshot-path", fScreenShotPathTC->Text() );
392         if ( !IsHidden() )
393                 Hide();
394         return false;
395 }
396
397 /*****************************************************************************
398  * PreferencesWindow::MessageReceived
399  *****************************************************************************/
400 void PreferencesWindow::MessageReceived( BMessage * p_message )
401 {
402     switch ( p_message->what )
403     {
404         case SET_TRANSLATOR:
405         case SET_FOLDER:
406                 _ApplyScreenShotSettings();
407                 break;
408         case DVDMENUS_CHECK:
409                 _ApplyDVDSettings();
410                 break;
411         case ADJUST_UPDATE:
412                 _ApplyPictureSettings();
413                 break;
414         case FFMPEG_UPDATE:
415                 _ApplyFFmpegSettings();
416             break;
417         case PREFS_REVERT:
418                 _RevertChanges();
419                 break;
420         case PREFS_DEFAULTS:
421             _SetDefaults();
422             _ApplyChanges();
423             break;
424         case PREFS_CANCEL:
425                 _RevertChanges();
426                 // fall through
427         case PREFS_OK:
428             PostMessage( B_QUIT_REQUESTED );
429             break;
430         default:
431             BWindow::MessageReceived( p_message );
432             break;
433     }
434 }
435
436 /*****************************************************************************
437  * PreferencesWindow::Show
438  *****************************************************************************/
439 void
440 PreferencesWindow::Show()
441 {
442         // collect settings for backup
443     fDVDMenusBackup = fDvdMenusCheck->Value() == B_CONTROL_ON;
444     fPostProcessingBackup = fPpSlider->Value();
445     fBrightnessBackup = fBrightnessSlider->Value();
446     fContrastBackup = fContrastSlider->Value();
447     fHueBackup = fHueSlider->Value();
448     fSaturationBackup = fSaturationSlider->Value();
449     fScreenShotPathBackup.SetTo( fScreenShotPathTC->Text() );
450         if ( BMenuItem* item = fScreenShotFormatMF->Menu()->FindMarked() )
451         {
452                 BMessage* message = item->Message();
453                 if ( message && message->FindInt32( kTypeField,
454                                                         (int32*)&fScreenShotFormatBackup ) != B_OK )
455                         fScreenShotFormatBackup = kDefaultScreenShotFormat;
456         }
457         else
458             fScreenShotFormatBackup = kDefaultScreenShotFormat;
459
460         BWindow::Show();
461 }
462
463 /*****************************************************************************
464  * PreferencesWindow::ReallyQuit
465  *****************************************************************************/
466 void PreferencesWindow::ReallyQuit()
467 {
468     Lock();
469     Hide();
470     Quit();
471 }
472
473 void
474 PreferencesWindow::_SetGUI( bool dvdMenus, int32 postProcessing,
475                                                    float brightness, float contrast,
476                                                    int32 hue, float saturation,
477                                                    const char* screenShotPath,
478                                                    uint32 screenShotTranslator)
479 {
480         fDvdMenusCheck->SetValue( dvdMenus );
481         fPpSlider->SetValue( postProcessing );
482         fBrightnessSlider->SetValue( brightness );
483         fContrastSlider->SetValue( contrast );
484         fHueSlider->SetValue( hue );
485         fSaturationSlider->SetValue( saturation );
486         // mark appropriate translator item
487         bool found = false;
488         for ( int32 i = 0; BMenuItem* item = fScreenShotFormatMF->Menu()->ItemAt( i ); i++ )
489         {
490                 if ( BMessage* message = item->Message() )
491                 {
492                         uint32 format;
493                         if ( message->FindInt32( kTypeField, (int32*)&format ) == B_OK
494                                  && format == screenShotTranslator )
495                         {
496                                 item->SetMarked( true );
497                                 found = true;
498                                 break;
499                         }
500                 }
501         }
502         if ( !found )
503         {
504                 if ( BMenuItem* item = fScreenShotFormatMF->Menu()->ItemAt( 0 ) )
505                         item->SetMarked( true );
506         }
507         fScreenShotPathTC->SetText( screenShotPath );
508 }
509
510
511 /*****************************************************************************
512  * PreferencesWindow::_SetDefaults
513  *****************************************************************************/
514 void PreferencesWindow::_SetDefaults()
515 {
516         _SetGUI( false, 0, 100.0, 100.0, 0, 100.0,
517                         kDefaultScreenShotPath, kDefaultScreenShotFormat );
518 }
519
520 /*****************************************************************************
521  * PreferencesWindow::_SetToSettings
522  *****************************************************************************/
523 void PreferencesWindow::_SetToSettings()
524 {
525         char* path = get_config_string( p_intf, "beos-screenshot-path", kDefaultScreenShotPath );
526
527         p_intf->p_sys->b_dvdmenus = get_config_int( p_intf, "beos-use-dvd-menus", false );
528
529         _SetGUI( p_intf->p_sys->b_dvdmenus,
530                         get_config_int( p_intf, "ffmpeg-pp-q", 0 ),
531                         100 *  get_config_float( p_intf, "brightness", 1.0 ),
532                         100 * get_config_float( p_intf, "contrast", 1.0 ),
533                         get_config_int( p_intf, "hue", 0 ),
534                         100 * get_config_float( p_intf, "saturation", 1.0 ),
535                         path,
536                         get_config_int( p_intf, "beos-screenshot-format",
537                                                         kDefaultScreenShotFormat ) );
538         free( path );
539 }
540
541 /*****************************************************************************
542  * PreferencesWindow::_RevertChanges
543  *****************************************************************************/
544 void
545 PreferencesWindow::_RevertChanges()
546 {
547         _SetGUI( fDVDMenusBackup,
548                         fPostProcessingBackup,
549                         fBrightnessBackup,
550                         fContrastBackup,
551                         fHueBackup,
552                         fSaturationBackup,
553                         fScreenShotPathBackup.String(),
554                         fScreenShotFormatBackup );
555
556         _ApplyChanges();
557 }
558
559 /*****************************************************************************
560  * PreferencesWindow::_ApplyChanges
561  *****************************************************************************/
562 void PreferencesWindow::_ApplyChanges()
563 {
564         _ApplyScreenShotSettings();
565         _ApplyPictureSettings();
566         _ApplyFFmpegSettings();
567         _ApplyDVDSettings();
568 }
569
570 /*****************************************************************************
571  * PreferencesWindow::_ApplyScreenShotSettings
572  *****************************************************************************/
573 void
574 PreferencesWindow::_ApplyScreenShotSettings()
575 {
576         // screen shot settings
577         uint32 translator = kDefaultScreenShotFormat;
578         if ( BMenuItem* item = fScreenShotFormatMF->Menu()->FindMarked() )
579         {
580                 BMessage* message = item->Message();
581                 if ( message && message->FindInt32( kTypeField, (int32*)&translator ) != B_OK )
582                         translator = kDefaultScreenShotFormat;
583         }
584         config_PutInt( p_intf, "beos-screenshot-format", translator );
585         config_PutPsz( p_intf, "beos-screenshot-path", fScreenShotPathTC->Text() );
586 }
587
588 /*****************************************************************************
589  * PreferencesWindow::_ApplyPictureSettings
590  *****************************************************************************/
591 void
592 PreferencesWindow::_ApplyPictureSettings()
593 {
594         VlcWrapper* p_wrapper = p_intf->p_sys->p_wrapper;
595
596         // picture adjustment settings
597     config_PutFloat( p_intf, "brightness",
598                      (float)fBrightnessSlider->Value() / 100 );
599     config_PutFloat( p_intf, "contrast",
600                      (float)fContrastSlider->Value() / 100 );
601     config_PutInt( p_intf, "hue", fHueSlider->Value() );
602     config_PutFloat( p_intf, "saturation",
603                      (float)fSaturationSlider->Value() / 100 );
604
605         // take care of changing "filters on the fly"
606     if( config_GetFloat( p_intf, "brightness" ) != 1 ||
607         config_GetFloat( p_intf, "contrast" ) != 1 ||
608         config_GetInt( p_intf, "hue" ) != 0 ||
609         config_GetFloat( p_intf, "saturation" ) != 1 )
610     {
611         char* string = config_GetPsz( p_intf, "filter" );
612         if( !string || strcmp( string, "adjust" ) )
613         {
614             config_PutPsz( p_intf, "filter", "adjust" );
615             p_wrapper->FilterChange();
616         }
617         if ( string )
618                 free( string );
619     }
620     else
621     {
622         char* string = config_GetPsz( p_intf, "filter" );
623         if ( string )
624         {
625             config_PutPsz( p_intf, "filter", NULL );
626             p_wrapper->FilterChange();
627                 free( string );
628         }
629     }
630 }
631
632 /*****************************************************************************
633  * PreferencesWindow::_ApplyFFmpegSettings
634  *****************************************************************************/
635 void
636 PreferencesWindow::_ApplyFFmpegSettings()
637 {
638         // ffmpeg post processing
639     config_PutInt( p_intf, "ffmpeg-pp-q", fPpSlider->Value() );
640 }
641
642 /*****************************************************************************
643  * PreferencesWindow::_ApplyDVDSettings
644  *****************************************************************************/
645 void
646 PreferencesWindow::_ApplyDVDSettings()
647 {
648         // dvd menus
649         bool dvdMenus = fDvdMenusCheck->Value() == B_CONTROL_ON;
650         p_intf->p_sys->b_dvdmenus = dvdMenus;
651         config_PutInt( p_intf, "beos-use-dvd-menus", dvdMenus );
652 }
653