]> git.sesse.net Git - vlc/blobdiff - modules/gui/macosx/intf.m
Adding posterize filter to effects dialog
[vlc] / modules / gui / macosx / intf.m
index be38032b216ab86a01a0a20ef6cf322bcd5d028c..21098e9c370a0183a735a55bf77feffe6e77fd78 100644 (file)
@@ -33,6 +33,7 @@
 #include <vlc_common.h>
 #include <vlc_keys.h>
 #include <vlc_dialog.h>
+#include <vlc_url.h>
 #include <unistd.h> /* execl() */
 
 #import "intf.h"
@@ -52,7 +53,6 @@
 #import "AppleRemote.h"
 #import "eyetv.h"
 #import "simple_prefs.h"
-#import "vlm.h"
 
 #import <AddressBook/AddressBook.h>         /* for crashlog send mechanism */
 #import <IOKit/hidsystem/ev_keymap.h>         /* for the media key support */
@@ -111,7 +111,8 @@ void CloseIntf ( vlc_object_t *p_this )
 /*****************************************************************************
  * Run: main loop
  *****************************************************************************/
-jmp_buf jmpbuffer;
+static NSLock * o_appLock = nil;    // controls access to f_appExit
+static int f_appExit = 0;           // set to 1 when application termination signaled
 
 static void Run( intf_thread_t *p_intf )
 {
@@ -132,18 +133,16 @@ static void Run( intf_thread_t *p_intf )
 
     NSAutoreleasePool * o_pool = [[NSAutoreleasePool alloc] init];
 
-    /* Install a jmpbuffer to where we can go back before the NSApp exit
-     * see applicationWillTerminate: */
+    o_appLock = [[NSLock alloc] init];
+
     [VLCApplication sharedApplication];
 
     [[VLCMain sharedInstance] setIntf: p_intf];
     [NSBundle loadNibNamed: @"MainMenu" owner: NSApp];
 
-    /* Install a jmpbuffer to where we can go back before the NSApp exit
-     * see applicationWillTerminate: */
-    if(setjmp(jmpbuffer) == 0)
-        [NSApp run];
-    
+    [NSApp run];
+    [[VLCMain sharedInstance] applicationWillTerminate:nil];
+
     [o_pool release];
 }
 
@@ -160,7 +159,7 @@ static void MsgCallback( msg_cb_data_t *data, msg_item_t *item, unsigned int i )
     int canc = vlc_savecancel();
     NSAutoreleasePool * o_pool = [[NSAutoreleasePool alloc] init];
 
-    /* this may happen from time to time, let's bail out as info would be useless anyway */ 
+    /* this may happen from time to time, let's bail out as info would be useless anyway */
     if( !item->psz_module || !item->psz_msg )
         return;
 
@@ -169,8 +168,8 @@ static void MsgCallback( msg_cb_data_t *data, msg_item_t *item, unsigned int i )
                                 [NSString stringWithUTF8String: item->psz_msg], @"Message",
                                 [NSNumber numberWithInt: item->i_type], @"Type", nil];
 
-    [[NSNotificationCenter defaultCenter] postNotificationName: @"VLCCoreMessageReceived" 
-                                                        object: nil 
+    [[NSNotificationCenter defaultCenter] postNotificationName: @"VLCCoreMessageReceived"
+                                                        object: nil
                                                       userInfo: o_dict];
 
     [o_pool release];
@@ -223,7 +222,7 @@ static int FullscreenChanged( vlc_object_t *p_this, const char *psz_variable,
 }
 
 /*****************************************************************************
- * DialogCallback: Callback triggered by the "dialog-*" variables 
+ * DialogCallback: Callback triggered by the "dialog-*" variables
  * to let the intf display error and interaction dialogs
  *****************************************************************************/
 static int DialogCallback( vlc_object_t *p_this, const char *type, vlc_value_t previous, vlc_value_t value, void *data )
@@ -333,11 +332,11 @@ static VLCMain *_o_sharedMainInstance = nil;
 
 - (id)init
 {
-    if( _o_sharedMainInstance) 
+    if( _o_sharedMainInstance)
     {
         [self dealloc];
         return _o_sharedMainInstance;
-    } 
+    }
     else
         _o_sharedMainInstance = [super init];
 
@@ -347,24 +346,19 @@ static VLCMain *_o_sharedMainInstance = nil;
     o_msg_arr = [[NSMutableArray arrayWithCapacity: 600] retain];
     /* subscribe to LibVLC's debug messages as early as possible (for us) */
     [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(libvlcMessageReceived:) name: @"VLCCoreMessageReceived" object: nil];
-    
+
     o_about = [[VLAboutBox alloc] init];
     o_prefs = nil;
     o_open = [[VLCOpen alloc] init];
     o_wizard = [[VLCWizard alloc] init];
-    o_vlm = [[VLCVLMController alloc] init];
     o_extended = nil;
     o_bookmarks = [[VLCBookmarks alloc] init];
-    o_embedded_list = [[VLCEmbeddedList alloc] init];
+    o_embedded_list = NULL; // [[VLCEmbeddedList alloc] init];
     o_coredialogs = [[VLCCoreDialogProvider alloc] init];
     o_info = [[VLCInfo alloc] init];
 
     i_lastShownVolume = -1;
 
-    o_remote = [[AppleRemote alloc] init];
-    [o_remote setClickCountEnabledButtons: kRemoteButtonPlay];
-    [o_remote setDelegate: _o_sharedMainInstance];
-
     o_eyetv = [[VLCEyeTVController alloc] init];
 
     /* announce our launch to a potential eyetv plugin */
@@ -426,6 +420,9 @@ static VLCMain *_o_sharedMainInstance = nil;
     i_key = config_GetInt( p_intf, "key-slower" );
     [o_mi_slower setKeyEquivalent: [NSString stringWithFormat:@"%C", VLCKeyToCocoa( i_key )]];
     [o_mi_slower setKeyEquivalentModifierMask: VLCModifiersToCocoa(i_key)];
+    i_key = config_GetInt( p_intf, "key-rate-normal" );
+    [o_mi_normalSpeed setKeyEquivalent: [NSString stringWithFormat:@"%C", VLCKeyToCocoa( i_key )]];
+    [o_mi_normalSpeed setKeyEquivalentModifierMask: VLCModifiersToCocoa(i_key)];
     i_key = config_GetInt( p_intf, "key-prev" );
     [o_mi_previous setKeyEquivalent: [NSString stringWithFormat:@"%C", VLCKeyToCocoa( i_key )]];
     [o_mi_previous setKeyEquivalentModifierMask: VLCModifiersToCocoa(i_key)];
@@ -459,7 +456,7 @@ static VLCMain *_o_sharedMainInstance = nil;
     i_key = config_GetInt( p_intf, "key-vol-mute" );
     [o_mi_mute setKeyEquivalent: [NSString stringWithFormat:@"%C", VLCKeyToCocoa( i_key )]];
     [o_mi_mute setKeyEquivalentModifierMask: VLCModifiersToCocoa(i_key)];
-    i_key = config_GetInt( p_intf, "key-fullscreen" );
+    i_key = config_GetInt( p_intf, "key-toggle-fullscreen" );
     [o_mi_fullscreen setKeyEquivalent: [NSString stringWithFormat:@"%C", VLCKeyToCocoa( i_key )]];
     [o_mi_fullscreen setKeyEquivalentModifierMask: VLCModifiersToCocoa(i_key)];
     i_key = config_GetInt( p_intf, "key-snapshot" );
@@ -484,7 +481,7 @@ static VLCMain *_o_sharedMainInstance = nil;
     [o_volumeslider setEnabled: YES];
     [self manageVolumeSlider];
     [o_window setDelegate: self];
+
     b_restore_size = false;
 
     // Set that here as IB seems to be buggy
@@ -512,19 +509,16 @@ static VLCMain *_o_sharedMainInstance = nil;
 
     o_size_with_playlist = [o_window contentRectForFrameRect:[o_window frame]].size;
 
-    p_playlist = pl_Hold( p_intf );
+    p_playlist = pl_Get( p_intf );
 
-    var_Create( p_playlist, "fullscreen", VLC_VAR_BOOL | VLC_VAR_DOINHERIT);
     val.b_bool = false;
 
     var_AddCallback( p_playlist, "fullscreen", FullscreenChanged, self);
     var_AddCallback( p_intf->p_libvlc, "intf-show", ShowController, self);
 
-    pl_Release( p_intf );
-
     /* load our Core Dialogs nib */
     nib_coredialogs_loaded = [NSBundle loadNibNamed:@"CoreDialogs" owner: NSApp];
-    
+
     /* subscribe to various interactive dialogues */
     var_Create( p_intf, "dialog-error", VLC_VAR_ADDRESS );
     var_AddCallback( p_intf, "dialog-error", DialogCallback, self );
@@ -548,13 +542,18 @@ static VLCMain *_o_sharedMainInstance = nil;
 
     /* take care of tint changes during runtime */
     o_img_play = [NSImage imageNamed: @"play"];
-    o_img_pause = [NSImage imageNamed: @"pause"];    
+    o_img_pause = [NSImage imageNamed: @"pause"];
     [self controlTintChanged];
     [[NSNotificationCenter defaultCenter] addObserver: self
                                              selector: @selector( controlTintChanged )
                                                  name: NSControlTintDidChangeNotification
                                                object: nil];
 
+    /* init Apple Remote support */
+    o_remote = [[AppleRemote alloc] init];
+    [o_remote setClickCountEnabledButtons: kRemoteButtonPlay];
+    [o_remote setDelegate: _o_sharedMainInstance];
+
     /* yeah, we are done */
     nib_main_loaded = TRUE;
 }
@@ -649,6 +648,7 @@ static VLCMain *_o_sharedMainInstance = nil;
     [o_mi_stop setTitle: _NS("Stop")];
     [o_mi_faster setTitle: _NS("Faster")];
     [o_mi_slower setTitle: _NS("Slower")];
+    [o_mi_normalSpeed setTitle: _NS("Normal rate")];
     [o_mi_previous setTitle: _NS("Previous")];
     [o_mi_next setTitle: _NS("Next")];
     [o_mi_random setTitle: _NS("Random")];
@@ -699,6 +699,8 @@ static VLCMain *_o_sharedMainInstance = nil;
     [o_mi_addSub setTitle: _NS("Open File...")];
     [o_mi_deinterlace setTitle: _NS("Deinterlace")];
     [o_mu_deinterlace setTitle: _NS("Deinterlace")];
+    [o_mi_deinterlace_mode setTitle: _NS("Deinterlace mode")];
+    [o_mu_deinterlace_mode setTitle: _NS("Deinterlace mode")];
     [o_mi_ffmpeg_pp setTitle: _NS("Post processing")];
     [o_mu_ffmpeg_pp setTitle: _NS("Post processing")];
     [o_mi_teletext setTitle: _NS("Teletext")];
@@ -739,7 +741,7 @@ static VLCMain *_o_sharedMainInstance = nil;
     [o_dmi_next setTitle: _NS("Next")];
     [o_dmi_previous setTitle: _NS("Previous")];
     [o_dmi_mute setTitle: _NS("Mute")];
+
     /* vout menu */
     [o_vmi_play setTitle: _NS("Play")];
     [o_vmi_stop setTitle: _NS("Stop")];
@@ -784,20 +786,28 @@ static VLCMain *_o_sharedMainInstance = nil;
     playlist_t * p_playlist;
     vout_thread_t * p_vout;
     int returnedValue = 0;
-    if( !p_intf ) return;
+
+    if( !p_intf )
+        return;
+
+    // don't allow a double termination call. If the user has
+    // already invoked the quit then simply return this time.
+    int isTerminating = false;
+
+    [o_appLock lock];
+    isTerminating = (f_appExit++ > 0 ? 1 : 0);
+    [o_appLock unlock];
+
+    if (isTerminating)
+        return;
 
     msg_Dbg( p_intf, "Terminating" );
 
-    /* Make sure the manage_thread won't call -terminate: again */
-    pthread_cancel( manage_thread );
+    pthread_join( manage_thread, NULL );
 
     /* Make sure the intf object is getting killed */
     vlc_object_kill( p_intf );
 
-    /* Make sure our manage_thread ends */
-    pthread_join( manage_thread, NULL );
-
     /* Make sure the interfaceTimer is destroyed */
     [interfaceTimer invalidate];
     [interfaceTimer release];
@@ -856,7 +866,7 @@ static VLCMain *_o_sharedMainInstance = nil;
 
     [crashLogURLConnection cancel];
     [crashLogURLConnection release];
+
     [o_embedded_list release];
     [o_coredialogs release];
     [o_eyetv release];
@@ -882,18 +892,11 @@ static VLCMain *_o_sharedMainInstance = nil;
 
     /* Kill the playlist, so that it doesn't accept new request
      * such as the play request from vlc.c (we are a blocking interface). */
-    p_playlist = pl_Hold( p_intf );
+    p_playlist = pl_Get( p_intf );
     vlc_object_kill( p_playlist );
-    pl_Release( p_intf );
-
     libvlc_Quit( p_intf->p_libvlc );
 
     [self setIntf:nil];
-
-    /* Go back to Run() and make libvlc exit properly */
-    if( jmpbuffer )
-        longjmp( jmpbuffer, 1 );
-    /* not reached */
 }
 
 #pragma mark -
@@ -975,15 +978,15 @@ static NSString * VLCToolbarMediaControl     = @"VLCToolbarMediaControl";
 - (void)controlTintChanged
 {
     BOOL b_playing = NO;
-    
+
     if( [o_btn_play alternateImage] == o_img_play_pressed )
         b_playing = YES;
-    
+
     if( [NSColor currentControlTint] == NSGraphiteControlTint )
     {
         o_img_play_pressed = [NSImage imageNamed: @"play_graphite"];
         o_img_pause_pressed = [NSImage imageNamed: @"pause_graphite"];
-        
+
         [o_btn_prev setAlternateImage: [NSImage imageNamed: @"previous_graphite"]];
         [o_btn_rewind setAlternateImage: [NSImage imageNamed: @"skip_previous_graphite"]];
         [o_btn_stop setAlternateImage: [NSImage imageNamed: @"stop_graphite"]];
@@ -997,7 +1000,7 @@ static NSString * VLCToolbarMediaControl     = @"VLCToolbarMediaControl";
     {
         o_img_play_pressed = [NSImage imageNamed: @"play_blue"];
         o_img_pause_pressed = [NSImage imageNamed: @"pause_blue"];
-        
+
         [o_btn_prev setAlternateImage: [NSImage imageNamed: @"previous_blue"]];
         [o_btn_rewind setAlternateImage: [NSImage imageNamed: @"skip_previous_blue"]];
         [o_btn_stop setAlternateImage: [NSImage imageNamed: @"stop_blue"]];
@@ -1007,7 +1010,7 @@ static NSString * VLCToolbarMediaControl     = @"VLCToolbarMediaControl";
         [o_btn_playlist setAlternateImage: [NSImage imageNamed: @"playlistdrawer_blue"]];
         [o_btn_equalizer setAlternateImage: [NSImage imageNamed: @"equalizerdrawer_blue"]];
     }
-    
+
     if( b_playing )
         [o_btn_play setAlternateImage: o_img_play_pressed];
     else
@@ -1044,7 +1047,14 @@ static NSString * VLCToolbarMediaControl     = @"VLCToolbarMediaControl";
 - (BOOL)application:(NSApplication *)o_app openFile:(NSString *)o_filename
 {
     BOOL b_autoplay = config_GetInt( VLCIntf, "macosx-autoplay" );
-    NSDictionary *o_dic = [NSDictionary dictionaryWithObjectsAndKeys: o_filename, @"ITEM_URL", nil];
+    char *psz_uri = make_URI([o_filename UTF8String], "file" );
+    if( !psz_uri )
+        return( FALSE );
+
+    NSDictionary *o_dic = [NSDictionary dictionaryWithObject:[NSString stringWithCString:psz_uri encoding:NSUTF8StringEncoding] forKey:@"ITEM_URL"];
+
+    free( psz_uri );
+
     if( b_autoplay )
         [o_playlist appendArray: [NSArray arrayWithObject: o_dic] atPos: -1 enqueue: NO];
     else
@@ -1055,7 +1065,7 @@ static NSString * VLCToolbarMediaControl     = @"VLCToolbarMediaControl";
 
 /* When user click in the Dock icon our double click in the finder */
 - (BOOL)applicationShouldHandleReopen:(NSApplication *)theApplication hasVisibleWindows:(BOOL)hasVisibleWindows
-{    
+{
     if(!hasVisibleWindows)
         [o_window makeKeyAndOrderFront:self];
 
@@ -1103,6 +1113,12 @@ static NSString * VLCToolbarMediaControl     = @"VLCToolbarMediaControl";
 {
     switch( buttonIdentifier )
     {
+        case k2009RemoteButtonFullscreen:
+            [o_controls toogleFullscreen:self];
+            break;
+        case k2009RemoteButtonPlay:
+            [o_controls play:self];
+            break;
         case kRemoteButtonPlay:
             if(count >= 2) {
                 [o_controls toogleFullscreen:self];
@@ -1278,8 +1294,6 @@ static struct
     { NSCarriageReturnCharacter, KEY_ENTER },
     { NSEnterCharacter, KEY_ENTER },
     { NSBackspaceCharacter, KEY_BACKSPACE },
-    { (unichar) ' ', KEY_SPACE },
-    { (unichar) 0x1b, KEY_ESC },
     {0,0}
 };
 
@@ -1445,11 +1459,6 @@ static unsigned int VLCModifiersToCocoa( unsigned int i_key )
     return nil;
 }
 
-- (id)vlm
-{
-    return o_vlm;
-}
-
 - (id)bookmarks
 {
     if( o_bookmarks )
@@ -1543,8 +1552,6 @@ static void manage_cleanup( void * args )
     var_DelCallback( p_playlist, "playlist-item-append", PlaylistChanged, self );
     var_DelCallback( p_playlist, "playlist-item-deleted", PlaylistChanged, self );
 
-    pl_Release( p_intf );
-
     if( p_input ) vlc_object_release( p_input );
 }
 
@@ -1557,7 +1564,7 @@ static void manage_cleanup( void * args )
 
     vlc_thread_set_priority( p_intf, VLC_THREAD_PRIORITY_LOW );
 
-    p_playlist = pl_Hold( p_intf );
+    p_playlist = pl_Get( p_intf );
 
     var_AddCallback( p_playlist, "item-current", PlaylistChanged, self );
     var_AddCallback( p_playlist, "intf-change", PlaylistChanged, self );
@@ -1568,7 +1575,8 @@ static void manage_cleanup( void * args )
     struct manage_cleanup_stack stack = { p_intf, &p_input, p_playlist, self };
     pthread_cleanup_push(manage_cleanup, &stack);
 
-    while( true )
+    bool exitLoop = false;
+    while( !exitLoop )
     {
         NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
 
@@ -1603,23 +1611,21 @@ static void manage_cleanup( void * args )
         msleep( INTF_IDLE_SLEEP );
 
         [pool release];
+
+        [o_appLock lock];
+        exitLoop = (f_appExit != 0 ? true : false);
+        [o_appLock unlock];
     }
 
     pthread_cleanup_pop(1);
-
-    msg_Dbg( p_intf, "Killing the Mac OS X module" );
-
-    /* We are dead, terminate */
-    [NSApp performSelectorOnMainThread: @selector(terminate:) withObject:nil waitUntilDone:NO];
 }
 
 - (void)manageVolumeSlider
 {
     audio_volume_t i_volume;
-    playlist_t * p_playlist = pl_Hold( p_intf );
+    playlist_t * p_playlist = pl_Get( p_intf );
 
     aout_VolumeGet( p_playlist, &i_volume );
-    pl_Release( p_intf );
 
     if( i_volume != i_lastShownVolume )
     {
@@ -1646,13 +1652,12 @@ static void manage_cleanup( void * args )
          * the playlist or the selection is empty */
         if( [self isPlaylistCollapsed] == YES )
         {
-            playlist_t * p_playlist = pl_Hold( p_intf );
+            playlist_t * p_playlist = pl_Get( p_intf );
             PL_LOCK;
             playlist_item_t * p_item = playlist_CurrentPlayingItem( p_playlist );
             PL_UNLOCK;
             if( p_item )
                 [[self info] updatePanelWithItem: p_item->p_input];
-            pl_Release( p_intf );
         }
     }
     if( p_intf->p_sys->b_intf_update )
@@ -1663,7 +1668,7 @@ static void manage_cleanup( void * args )
         bool b_seekable = false;
         bool b_chapters = false;
 
-        playlist_t * p_playlist = pl_Hold( p_intf );
+        playlist_t * p_playlist = pl_Get( p_intf );
 
         PL_LOCK;
         b_plmul = playlist_CurrentSize( p_playlist ) > 1;
@@ -1672,7 +1677,7 @@ static void manage_cleanup( void * args )
         p_input = playlist_CurrentInput( p_playlist );
 
         bool b_buffering = NO;
-    
+
         if( ( b_input = ( p_input != NULL ) ) )
         {
             /* seekable streams */
@@ -1693,7 +1698,6 @@ static void manage_cleanup( void * args )
             //b_chapters = p_input->stream.i_area_nb > 1;
             vlc_object_release( p_input );
         }
-        pl_Release( p_intf );
 
         if( b_buffering )
         {
@@ -1726,7 +1730,7 @@ static void manage_cleanup( void * args )
         [o_embedded_window setTime:@"00:00" position:0.0];
 
         p_intf->p_sys->b_current_title_update = true;
-        
+
         p_intf->p_sys->b_intf_update = false;
     }
 
@@ -1778,7 +1782,7 @@ static void manage_cleanup( void * args )
             [[[self controls] fspanel] setStreamTitle: aString];
 
             [[o_controls voutView] updateTitle];
+
             [o_playlist updateRowSelection];
 
             p_intf->p_sys->b_current_title_update = FALSE;
@@ -1869,7 +1873,7 @@ end:
 
 - (void)setupMenus
 {
-    playlist_t * p_playlist = pl_Hold( p_intf );
+    playlist_t * p_playlist = pl_Get( p_intf );
     input_thread_t * p_input = playlist_CurrentInput( p_playlist );
     if( p_input != NULL )
     {
@@ -1927,6 +1931,9 @@ end:
             [o_controls setupVarMenuItem: o_mi_deinterlace target: (vlc_object_t *)p_vout
                 var: "deinterlace" selector: @selector(toggleVar:)];
 
+            [o_controls setupVarMenuItem: o_mi_deinterlace_mode target: (vlc_object_t *)p_vout
+                var: "deinterlace-mode" selector: @selector(toggleVar:)];
+
 #if 1
            [o_controls setupVarMenuItem: o_mi_ffmpeg_pp target:
                     (vlc_object_t *)p_vout var:"postprocess" selector:
@@ -1937,7 +1944,6 @@ end:
         }
         vlc_object_release( p_input );
     }
-    pl_Release( p_intf );
 }
 
 - (void)refreshVoutDeviceMenu:(NSNotification *)o_notification
@@ -1946,7 +1952,7 @@ end:
     vout_thread_t * p_vout = getVout();
     if( !p_vout )
         return;
+
     /* clean the menu before adding new entries */
     if( [o_mi_screen hasSubmenu] )
     {
@@ -1977,7 +1983,7 @@ end:
 
 - (void)resetScrollField
 {
-    playlist_t * p_playlist = pl_Hold( p_intf );
+    playlist_t * p_playlist = pl_Get( p_intf );
     input_thread_t * p_input = playlist_CurrentInput( p_playlist );
 
     i_end_scroll = -1;
@@ -1994,10 +2000,8 @@ end:
         [self setScrollField: o_temp stopAfter:-1];
         [[[self controls] fspanel] setStreamTitle: o_temp];
         vlc_object_release( p_input );
-        pl_Release( p_intf );
         return;
     }
-    pl_Release( p_intf );
     [self setScrollField: _NS("VLC media player") stopAfter:-1];
 }
 
@@ -2036,6 +2040,7 @@ end:
     [o_mi_subtitle setEnabled: b_enabled];
     [o_mi_channels setEnabled: b_enabled];
     [o_mi_deinterlace setEnabled: b_enabled];
+    [o_mi_deinterlace_mode setEnabled: b_enabled];
     [o_mi_ffmpeg_pp setEnabled: b_enabled];
     [o_mi_device setEnabled: b_enabled];
     [o_mi_screen setEnabled: b_enabled];
@@ -2061,7 +2066,7 @@ end:
         default:
             return;
     }
-    p_playlist = pl_Hold( p_intf );
+    p_playlist = pl_Get( p_intf );
     p_input = playlist_CurrentInput( p_playlist );
     if( p_input != NULL )
     {
@@ -2089,14 +2094,13 @@ end:
         [o_embedded_window setTime: o_time position: f_updated];
         vlc_object_release( p_input );
     }
-    pl_Release( p_intf );
 }
 
 - (IBAction)timeFieldWasClicked:(id)sender
 {
     b_time_remaining = !b_time_remaining;
 }
-    
+
 
 #pragma mark -
 #pragma mark Recent Items
@@ -2189,14 +2193,6 @@ end:
     }
 }
 
-- (IBAction)showVLM:(id)sender
-{
-    if( !nib_vlm_loaded )
-        nib_vlm_loaded = [NSBundle loadNibNamed:@"VLM" owner: NSApp];
-
-    [o_vlm showVLMWindow];
-}
-
 - (IBAction)showExtended:(id)sender
 {
     if( o_extended == nil )
@@ -2216,7 +2212,7 @@ end:
         nib_wizard_loaded = [NSBundle loadNibNamed:@"Wizard" owner: NSApp];
         [o_wizard initStrings];
     }
+
     if( !nib_bookmarks_loaded )
         nib_bookmarks_loaded = [NSBundle loadNibNamed:@"Bookmarks" owner: NSApp];
 
@@ -2253,7 +2249,7 @@ end:
 
     [o_about showGPL: sender];
 }
-    
+
 - (IBAction)viewHelp:(id)sender
 {
     if( !nib_about_loaded )
@@ -2372,7 +2368,7 @@ end:
 
             // Dooh. ugly.
             if( year < [[compo objectAtIndex:0] intValue] ||
-                (year ==[[compo objectAtIndex:0] intValue] && 
+                (year ==[[compo objectAtIndex:0] intValue] &&
                  (month < [[compo objectAtIndex:1] intValue] ||
                   (month ==[[compo objectAtIndex:1] intValue] &&
                    (day   < [[compo objectAtIndex:2] intValue] ||
@@ -2449,7 +2445,7 @@ end:
     int version = [[NSUserDefaults standardUserDefaults] integerForKey:kVLCPreferencesVersion];
     if( version >= kCurrentPreferencesVersion ) return;
 
-    NSArray *libraries = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, 
+    NSArray *libraries = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory,
         NSUserDomainMask, YES);
     if( !libraries || [libraries count] == 0) return;
     NSString * preferences = [[libraries objectAtIndex:0] stringByAppendingPathComponent:@"Preferences"];
@@ -2511,7 +2507,7 @@ end:
 {
     if(! nib_info_loaded )
         nib_info_loaded = [NSBundle loadNibNamed:@"MediaInfo" owner: NSApp];
-    
+
     [o_info initPanel];
 }
 
@@ -2592,7 +2588,7 @@ end:
 - (IBAction)saveDebugLog:(id)sender
 {
     NSOpenPanel * saveFolderPanel = [[NSSavePanel alloc] init];
-    
+
     [saveFolderPanel setCanChooseDirectories: NO];
     [saveFolderPanel setCanChooseFiles: YES];
     [saveFolderPanel setCanSelectHiddenExtension: NO];
@@ -2631,7 +2627,7 @@ end:
             o_rect.size.height = o_size_with_playlist.height;
         else
             o_rect.size.height = 500.;
+
         if( o_size_with_playlist.width >= [o_window contentMinSize].width )
             o_rect.size.width = o_size_with_playlist.width;
         else
@@ -2884,10 +2880,10 @@ end:
             int keyFlags = ([event data1] & 0x0000FFFF);
             int keyState = (((keyFlags & 0xFF00) >> 8)) == 0xA;
             int keyRepeat = (keyFlags & 0x1);
-            
+
             if( keyCode == NX_KEYTYPE_PLAY && keyState == 0 )
                 var_SetInteger( VLCIntf->p_libvlc, "key-action", ACTIONID_PLAY_PAUSE );
-            
+
             if( keyCode == NX_KEYTYPE_FAST && !b_justJumped )
             {
                 if( keyState == 0 && keyRepeat == 0 )
@@ -2903,7 +2899,7 @@ end:
                                afterDelay:0.25];
                 }
             }
-            
+
             if( keyCode == NX_KEYTYPE_REWIND && !b_justJumped )
             {
                 if( keyState == 0 && keyRepeat == 0 )
@@ -2929,4 +2925,14 @@ end:
     b_justJumped = NO;
 }
 
+// when user selects the quit menu from dock it sends a terminate:
+// but we need to send a stop: to properly exits libvlc.
+// However, we are not able to change the action-method sent by this standard menu item.
+// thus we override terminat: to send a stop:
+// see [af97f24d528acab89969d6541d83f17ce1ecd580] that introduced the removal of setjmp() and longjmp() 
+- (void)terminate:(id)sender
+{
+    [self stop:sender];
+}
+
 @end