]> git.sesse.net Git - vlc/blobdiff - modules/gui/macosx/intf.m
macosx: added an option to disable the native fullscreen mode on Lion
[vlc] / modules / gui / macosx / intf.m
index 2202f4df7f57fa2e69ee1042f21b97ca99c9a124..64265cb3d547c5796a55c1a0cd8b4cfef073ebcf 100644 (file)
@@ -39,9 +39,9 @@
 #include <vlc_vout_window.h>
 #include <unistd.h> /* execl() */
 
+#import "CompatibilityFixes.h"
 #import "intf.h"
 #import "MainMenu.h"
-#import "fspanel.h"
 #import "vout.h"
 #import "prefs.h"
 #import "playlist.h"
@@ -56,6 +56,7 @@
 #import "eyetv.h"
 #import "simple_prefs.h"
 #import "CoreInteraction.h"
+#import "TrackSynchronization.h"
 
 #import <AddressBook/AddressBook.h>         /* for crashlog send mechanism */
 #import <Sparkle/Sparkle.h>                 /* we're the update delegate */
  *****************************************************************************/
 static void Run ( intf_thread_t *p_intf );
 
-static void * ManageThread( void *user_data );
-
 static void updateProgressPanel (void *, const char *, float);
 static bool checkProgressPanel (void *);
 static void destroyProgressPanel (void *);
 
-static void MsgCallback( msg_cb_data_t *, const msg_item_t * );
+static void MsgCallback( void *data, int type, const msg_item_t *item, const char *format, va_list ap );
+
+static int InputEvent( vlc_object_t *, const char *,
+                      vlc_value_t, vlc_value_t, void * );
+static int PLItemChanged( vlc_object_t *, const char *,
+                         vlc_value_t, vlc_value_t, void * );
+static int PlaylistUpdated( vlc_object_t *, const char *,
+                           vlc_value_t, vlc_value_t, void * );
+static int PlaybackModeUpdated( vlc_object_t *, const char *,
+                               vlc_value_t, vlc_value_t, void * );
+static int VolumeUpdated( vlc_object_t *, const char *,
+                         vlc_value_t, vlc_value_t, void * );
 
 #pragma mark -
 #pragma mark VLC Interface Object Callbacks
@@ -81,6 +91,8 @@ static void MsgCallback( msg_cb_data_t *, const msg_item_t * );
  *****************************************************************************/
 int OpenIntf ( vlc_object_t *p_this )
 {
+    NSAutoreleasePool *o_pool = [[NSAutoreleasePool alloc] init];
+    [VLCApplication sharedApplication];
     intf_thread_t *p_intf = (intf_thread_t*) p_this;
 
     p_intf->p_sys = malloc( sizeof( intf_sys_t ) );
@@ -90,10 +102,11 @@ int OpenIntf ( vlc_object_t *p_this )
     memset( p_intf->p_sys, 0, sizeof( *p_intf->p_sys ) );
 
     /* subscribe to LibVLCCore's messages */
-    p_intf->p_sys->p_sub = msg_Subscribe( p_intf->p_libvlc, MsgCallback, NULL );
+    p_intf->p_sys->p_sub = vlc_Subscribe( MsgCallback, NULL );
     p_intf->pf_run = Run;
     p_intf->b_should_run_on_first_thread = true;
 
+    [o_pool release];
     return VLC_SUCCESS;
 }
 
@@ -111,13 +124,13 @@ static int WindowControl( vout_window_t *, int i_query, va_list );
 
 int WindowOpen( vout_window_t *p_wnd, const vout_window_cfg_t *cfg )
 {
+    NSAutoreleasePool *o_pool = [[NSAutoreleasePool alloc] init];
     intf_thread_t *p_intf = VLCIntf;
     if (!p_intf) {
         msg_Err( p_wnd, "Mac OS X interface not found" );
         return VLC_EGENERIC;
     }
 
-    msg_Dbg( p_wnd, "looking for video view" );
     int i_x = cfg->x;
     int i_y = cfg->y;
     unsigned i_width = cfg->width;
@@ -126,11 +139,15 @@ int WindowOpen( vout_window_t *p_wnd, const vout_window_cfg_t *cfg )
 
     if ( !p_wnd->handle.nsobject ) {
         msg_Err( p_wnd, "got no video view from the interface" );
+        [o_pool release];
         return VLC_EGENERIC;
     }
 
+    [[VLCMain sharedInstance] setNativeVideoSize:NSMakeSize( cfg->width, cfg->height )];
+    [[VLCMain sharedInstance] setActiveVideoPlayback: YES];
     p_wnd->control = WindowControl;
     p_wnd->sys = (vout_window_sys_t *)VLCIntf;
+    [o_pool release];
     return VLC_SUCCESS;
 }
 
@@ -140,7 +157,12 @@ static int WindowControl( vout_window_t *p_wnd, int i_query, va_list args )
     if( i_query == VOUT_WINDOW_SET_STATE )
         NSLog( @"WindowControl:VOUT_WINDOW_SET_STATE" );
     else if( i_query == VOUT_WINDOW_SET_SIZE )
+    {
         NSLog( @"WindowControl:VOUT_WINDOW_SET_SIZE" );
+        unsigned int i_width  = va_arg( args, unsigned int );
+        unsigned int i_height = va_arg( args, unsigned int );
+        [[VLCMain sharedInstance] setNativeVideoSize:NSMakeSize( i_width, i_height )];
+    }
     else if( i_query == VOUT_WINDOW_SET_FULLSCREEN )
         NSLog( @"WindowControl:VOUT_WINDOW_SET_FULLSCREEN" );
     else
@@ -150,8 +172,11 @@ static int WindowControl( vout_window_t *p_wnd, int i_query, va_list args )
 
 void WindowClose( vout_window_t *p_wnd )
 {
+    NSAutoreleasePool *o_pool = [[NSAutoreleasePool alloc] init];
+    [[VLCMain sharedInstance] setActiveVideoPlayback:NO];
     NSLog( @"Window Close" );
     // tell the interface to get rid of the video, TODO
+    [o_pool release];
 }
 
 /*****************************************************************************
@@ -166,18 +191,17 @@ static void Run( intf_thread_t *p_intf )
 
     /* Make sure the "force quit" menu item does quit instantly.
      * VLC overrides SIGTERM which is sent by the "force quit"
-     * menu item to make sure deamon mode quits gracefully, so
+     * menu item to make sure daemon mode quits gracefully, so
      * we un-override SIGTERM here. */
     sigemptyset( &set );
     sigaddset( &set, SIGTERM );
     pthread_sigmask( SIG_UNBLOCK, &set, NULL );
 
     NSAutoreleasePool * o_pool = [[NSAutoreleasePool alloc] init];
+    [VLCApplication sharedApplication];
 
     o_appLock = [[NSLock alloc] init];
 
-    [VLCApplication sharedApplication];
-
     [[VLCMain sharedInstance] setIntf: p_intf];
     [NSBundle loadNibNamed: @"MainMenu" owner: NSApp];
 
@@ -193,45 +217,144 @@ static void Run( intf_thread_t *p_intf )
 /*****************************************************************************
  * MsgCallback: Callback triggered by the core once a new debug message is
  * ready to be displayed. We store everything in a NSArray in our Cocoa part
- * of this file, so we are forwarding everything through notifications.
+ * of this file.
  *****************************************************************************/
-static void MsgCallback( msg_cb_data_t *data, const msg_item_t *item )
+static void MsgCallback( void *data, int type, const msg_item_t *item, const char *format, va_list ap )
 {
     int canc = vlc_savecancel();
-    NSAutoreleasePool * o_pool = [[NSAutoreleasePool alloc] init];
+    char *str;
 
-    /* this may happen from time to time, let's bail out as info would be useless anyway */
-    if( !item->psz_module || !item->psz_msg )
+    if (vasprintf( &str, format, ap ) == -1)
+    {
+        vlc_restorecancel( canc );
         return;
+    }
 
-    NSDictionary *o_dict = [NSDictionary dictionaryWithObjectsAndKeys:
-                                [NSString stringWithUTF8String: item->psz_module], @"Module",
-                                [NSString stringWithUTF8String: item->psz_msg], @"Message",
-                                [NSNumber numberWithInt: item->i_type], @"Type", nil];
-
-    [[NSNotificationCenter defaultCenter] postNotificationName: @"VLCCoreMessageReceived"
-                                                        object: nil
-                                                      userInfo: o_dict];
-
+    NSAutoreleasePool *o_pool = [[NSAutoreleasePool alloc] init];
+    [[VLCMain sharedInstance] processReceivedlibvlcMessage: item ofType: type withStr: str];
     [o_pool release];
+
     vlc_restorecancel( canc );
+    free( str );
 }
 
-/*****************************************************************************
- * playlistChanged: Callback triggered by the intf-change playlist
- * variable, to let the intf update the playlist.
- *****************************************************************************/
-static int PlaylistChanged( vlc_object_t *p_this, const char *psz_variable,
-                     vlc_value_t old_val, vlc_value_t new_val, void *param )
+static int InputEvent( vlc_object_t *p_this, const char *psz_var,
+                       vlc_value_t oldval, vlc_value_t new_val, void *param )
 {
-    intf_thread_t * p_intf = VLCIntf;
-    if( p_intf && p_intf->p_sys )
-    {
-        p_intf->p_sys->b_intf_update = true;
-        p_intf->p_sys->b_playlist_update = true;
-        p_intf->p_sys->b_playmode_update = true;
-        p_intf->p_sys->b_current_title_update = true;
+    NSAutoreleasePool *o_pool = [[NSAutoreleasePool alloc] init];
+    switch (new_val.i_int) {
+        case INPUT_EVENT_STATE:
+            [[VLCMain sharedInstance] playbackStatusUpdated];
+            break;
+        case INPUT_EVENT_RATE:
+            [[VLCMainMenu sharedInstance] performSelectorOnMainThread:@selector(updatePlaybackRate) withObject: nil waitUntilDone:NO];
+            break;
+        case INPUT_EVENT_POSITION:
+            [[VLCMain sharedInstance] updatePlaybackPosition];
+            break;
+        case INPUT_EVENT_TITLE:
+        case INPUT_EVENT_CHAPTER:
+            [[VLCMain sharedInstance] updateMainMenu];
+            break;
+        case INPUT_EVENT_CACHE:
+            [[VLCMain sharedInstance] updateMainWindow];
+            break;
+        case INPUT_EVENT_STATISTICS:
+            [[[VLCMain sharedInstance] info] performSelectorOnMainThread:@selector(updateStatistics) withObject: nil waitUntilDone: NO];
+            break;
+        case INPUT_EVENT_ES:
+            break;
+        case INPUT_EVENT_TELETEXT:
+            break;
+        case INPUT_EVENT_AOUT:
+            break;
+        case INPUT_EVENT_VOUT:
+            break;
+        case INPUT_EVENT_ITEM_META:
+        case INPUT_EVENT_ITEM_INFO:
+            [[VLCMain sharedInstance] updateMainMenu];
+            [[VLCMain sharedInstance] updateName];
+            [[VLCMain sharedInstance] updateInfoandMetaPanel];
+            break;
+        case INPUT_EVENT_BOOKMARK:
+            break;
+        case INPUT_EVENT_RECORD:
+            [[VLCMain sharedInstance] updateRecordState: var_GetBool( p_this, "record" )];
+            break;
+        case INPUT_EVENT_PROGRAM:
+            [[VLCMain sharedInstance] updateMainMenu];
+            break;
+        case INPUT_EVENT_ITEM_EPG:
+            break;
+        case INPUT_EVENT_SIGNAL:
+            break;
+
+        case INPUT_EVENT_ITEM_NAME:
+            [[VLCMain sharedInstance] updateName];
+            [[VLCMain sharedInstance] playlistUpdated];
+            break;
+
+        case INPUT_EVENT_AUDIO_DELAY:
+        case INPUT_EVENT_SUBTITLE_DELAY:
+            [[VLCMain sharedInstance] updateDelays];
+            break;
+
+        case INPUT_EVENT_DEAD:
+            [[VLCMain sharedInstance] updateName];
+            [[VLCMain sharedInstance] updatePlaybackPosition];
+            break;
+
+        case INPUT_EVENT_ABORT:
+            [[VLCMain sharedInstance] updateName];
+            [[VLCMain sharedInstance] updatePlaybackPosition];
+            break;
+
+        default:
+            //msg_Warn( p_this, "unhandled input event (%lld)", new_val.i_int );
+            break;
     }
+
+    [o_pool release];
+    return VLC_SUCCESS;
+}
+
+static int PLItemChanged( vlc_object_t *p_this, const char *psz_var,
+                         vlc_value_t oldval, vlc_value_t new_val, void *param )
+{
+    NSAutoreleasePool * o_pool = [[NSAutoreleasePool alloc] init];
+    [[VLCMain sharedInstance] performSelectorOnMainThread:@selector(PlaylistItemChanged) withObject:nil waitUntilDone:NO];
+
+    [o_pool release];
+    return VLC_SUCCESS;
+}
+
+static int PlaylistUpdated( vlc_object_t *p_this, const char *psz_var,
+                         vlc_value_t oldval, vlc_value_t new_val, void *param )
+{
+    NSAutoreleasePool * o_pool = [[NSAutoreleasePool alloc] init];
+    [[VLCMain sharedInstance] performSelectorOnMainThread:@selector(playlistUpdated) withObject:nil waitUntilDone:NO];
+
+    [o_pool release];
+    return VLC_SUCCESS;
+}
+
+static int PlaybackModeUpdated( vlc_object_t *p_this, const char *psz_var,
+                         vlc_value_t oldval, vlc_value_t new_val, void *param )
+{
+    NSAutoreleasePool * o_pool = [[NSAutoreleasePool alloc] init];
+    [[VLCMain sharedInstance] playbackModeUpdated];
+
+    [o_pool release];
+    return VLC_SUCCESS;
+}
+
+static int VolumeUpdated( vlc_object_t *p_this, const char *psz_var,
+                         vlc_value_t oldval, vlc_value_t new_val, void *param )
+{
+    NSAutoreleasePool * o_pool = [[NSAutoreleasePool alloc] init];
+    [[VLCMain sharedInstance] performSelectorOnMainThread:@selector(updateVolume) withObject:nil waitUntilDone:NO];
+
+    [o_pool release];
     return VLC_SUCCESS;
 }
 
@@ -245,7 +368,9 @@ static int ShowController( vlc_object_t *p_this, const char *psz_variable,
 {
     intf_thread_t * p_intf = VLCIntf;
     if( p_intf && p_intf->p_sys )
-        p_intf->p_sys->b_intf_show = true;
+    {
+//        [[[VLCMain sharedInstance] fspanel] makeKeyAndOrderFront: nil];
+    }
     return VLC_SUCCESS;
 }
 
@@ -257,8 +382,12 @@ static int FullscreenChanged( vlc_object_t *p_this, const char *psz_variable,
                      vlc_value_t old_val, vlc_value_t new_val, void *param )
 {
     intf_thread_t * p_intf = VLCIntf;
-    if( p_intf && p_intf->p_sys )
-        p_intf->p_sys->b_fullscreen_update = true;
+    if (p_intf)
+    {
+        NSAutoreleasePool *o_pool = [[NSAutoreleasePool alloc] init];
+        [[VLCMain sharedInstance] fullscreenChanged];
+        [o_pool release];
+    }
     return VLC_SUCCESS;
 }
 
@@ -283,7 +412,7 @@ static int DialogCallback( vlc_object_t *p_this, const char *type, vlc_value_t p
     }
 
     NSValue *o_value = [NSValue valueWithPointer:value.p_address];
-    [[NSNotificationCenter defaultCenter] postNotificationName: @"VLCNewCoreDialogEventNotification" object:[interface coreDialogProvider] userInfo:[NSDictionary dictionaryWithObjectsAndKeys: o_value, @"VLCDialogPointer", [NSString stringWithUTF8String: type], @"VLCDialogType", nil]];
+    [[VLCCoreDialogProvider sharedInstance] performEventWithObject: o_value ofType: type];
 
     [o_pool release];
     return VLC_SUCCESS;
@@ -339,12 +468,12 @@ vout_thread_t *getVout(void)
     return p_vout;
 }
 
-aout_instance_t *getAout(void)
+audio_output_t *getAout(void)
 {
     input_thread_t *p_input = getInput();
     if (!p_input)
         return NULL;
-    aout_instance_t *p_aout = input_GetAout(p_input);
+    audio_output_t *p_aout = input_GetAout(p_input);
     vlc_object_release(p_input);
     return p_aout;
 }
@@ -385,8 +514,6 @@ static VLCMain *_o_sharedMainInstance = nil;
 
     o_msg_lock = [[NSLock alloc] init];
     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_open = [[VLCOpen alloc] init];
     //o_embedded_list = [[VLCEmbeddedList alloc] init];
@@ -394,10 +521,8 @@ static VLCMain *_o_sharedMainInstance = nil;
     o_info = [[VLCInfo alloc] init];
     o_mainmenu = [[VLCMainMenu alloc] init];
     o_coreinteraction = [[VLCCoreInteraction alloc] init];
-
-    i_lastShownVolume = -1;
-
     o_eyetv = [[VLCEyeTVController alloc] init];
+    o_mainwindow = [[VLCMainWindow alloc] init];
 
     /* announce our launch to a potential eyetv plugin */
     [[NSDistributedNotificationCenter defaultCenter] postNotificationName: @"VLCOSXGUIInit"
@@ -419,24 +544,36 @@ static VLCMain *_o_sharedMainInstance = nil;
 {
     playlist_t *p_playlist;
     vlc_value_t val;
+    if( !p_intf ) return;
     var_Create( p_intf, "intf-change", VLC_VAR_BOOL );
 
-    [o_volumeslider setEnabled: YES];
-    [self manageVolumeSlider];
-    [o_window setDelegate: self];
-    [o_window setExcludedFromWindowsMenu: YES];
+    /* Check if we already did this once. Opening the other nibs calls it too,
+     because VLCMain is the owner */
+    if( nib_main_loaded ) return;
+
     [o_msgs_panel setExcludedFromWindowsMenu: YES];
     [o_msgs_panel setDelegate: self];
 
-    // Set that here as IB seems to be buggy
-    [o_window setContentMinSize:NSMakeSize(500., 200.)];
-
     p_playlist = pl_Get( p_intf );
 
     val.b_bool = false;
 
     var_AddCallback( p_playlist, "fullscreen", FullscreenChanged, self);
     var_AddCallback( p_intf->p_libvlc, "intf-show", ShowController, self);
+//    var_AddCallback(p_playlist, "item-change", PLItemChanged, self);
+    var_AddCallback(p_playlist, "item-current", PLItemChanged, self);
+    var_AddCallback(p_playlist, "activity", PLItemChanged, self);
+    var_AddCallback(p_playlist, "leaf-to-parent", PlaylistUpdated, self);
+    var_AddCallback(p_playlist, "playlist-item-append", PlaylistUpdated, self);
+    var_AddCallback(p_playlist, "playlist-item-deleted", PlaylistUpdated, self);
+    var_AddCallback(p_playlist, "random", PlaybackModeUpdated, self);
+    var_AddCallback(p_playlist, "repeat", PlaybackModeUpdated, self);
+    var_AddCallback(p_playlist, "loop", PlaybackModeUpdated, self);
+    var_AddCallback(p_playlist, "volume", VolumeUpdated, self);
+    var_AddCallback(p_playlist, "mute", VolumeUpdated, self);
+
+    if ([NSApp currentSystemPresentationOptions] == NSApplicationPresentationFullScreen)
+        var_SetBool( p_playlist, "fullscreen", YES );
 
     /* load our Core Dialogs nib */
     nib_coredialogs_loaded = [NSBundle loadNibNamed:@"CoreDialogs" owner: NSApp];
@@ -454,12 +591,7 @@ static VLCMain *_o_sharedMainInstance = nil;
     var_AddCallback( p_intf, "dialog-progress-bar", DialogCallback, self );
     dialog_Register( p_intf );
 
-    /* update the playmode stuff */
-    p_intf->p_sys->b_playmode_update = true;
-
-    /* take care of tint changes during runtime */
-    o_img_play = [NSImage imageNamed: @"play"];
-    o_img_pause = [NSImage imageNamed: @"pause"];
+    [self playbackModeUpdated];
 
     /* init Apple Remote support */
     o_remote = [[AppleRemote alloc] init];
@@ -467,22 +599,10 @@ static VLCMain *_o_sharedMainInstance = nil;
     [o_remote setDelegate: _o_sharedMainInstance];
 
     /* yeah, we are done */
+    b_nativeFullscreenMode = config_GetInt( p_intf, "macosx-nativefullscreenmode" );
     nib_main_loaded = TRUE;
 }
 
-- (void)applicationWillFinishLaunching:(NSNotification *)o_notification
-{
-    if( !p_intf ) return;
-
-    /* FIXME: don't poll */
-    interfaceTimer = [[NSTimer scheduledTimerWithTimeInterval: 0.5
-                                     target: self selector: @selector(manageIntf:)
-                                   userInfo: nil repeats: FALSE] retain];
-
-    /* Note: we use the pthread API to support pre-10.5 */
-    pthread_create( &manage_thread, NULL, ManageThread, self );
-}
-
 - (void)applicationDidFinishLaunching:(NSNotification *)aNotification
 {
     if( !p_intf ) return;
@@ -501,6 +621,11 @@ static VLCMain *_o_sharedMainInstance = nil;
 
     [self _removeOldPreferences];
 
+    [o_mainwindow updateWindow];
+    [o_mainwindow updateTimeSlider];
+    [o_mainwindow updateVolumeSlider];
+    [o_mainwindow makeKeyAndOrderFront: self];
+
     /* Handle sleep notification */
     [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector:@selector(computerWillSleep:)
            name:NSWorkspaceWillSleepNotification object:nil];
@@ -512,21 +637,6 @@ static VLCMain *_o_sharedMainInstance = nil;
 {
     if( !p_intf ) return;
 
-    [o_window setTitle: _NS("VLC media player")];
-    [self setScrollField:_NS("VLC media player") stopAfter:-1];
-
-    /* button controls */
-    [o_btn_prev setToolTip: _NS("Previous")];
-    [o_btn_rewind setToolTip: _NS("Rewind")];
-    [o_btn_play setToolTip: _NS("Play")];
-    [o_btn_stop setToolTip: _NS("Stop")];
-    [o_btn_ff setToolTip: _NS("Fast Forward")];
-    [o_btn_next setToolTip: _NS("Next")];
-    [o_btn_fullscreen setToolTip: _NS("Fullscreen")];
-    [o_volumeslider setToolTip: _NS("Volume")];
-    [o_timeslider setToolTip: _NS("Position")];
-    [o_btn_playlist setToolTip: _NS("Playlist")];
-
     /* messages panel */
     [o_msgs_panel setTitle: _NS("Messages")];
     [o_msgs_crashlog_btn setTitle: _NS("Open CrashLog...")];
@@ -567,18 +677,9 @@ static VLCMain *_o_sharedMainInstance = nil;
 
     msg_Dbg( p_intf, "Terminating" );
 
-    pthread_join( manage_thread, NULL );
-
     /* Make sure the intf object is getting killed */
     vlc_object_kill( p_intf );
-
-    /* Make sure the interfaceTimer is destroyed */
-    [interfaceTimer invalidate];
-    [interfaceTimer release];
-    interfaceTimer = nil;
-
-    /* make sure that the current volume is saved */
-    config_PutInt( p_intf->p_libvlc, "volume", i_lastShownVolume );
+    p_playlist = pl_Get( p_intf );
 
     /* unsubscribe from the interactive dialogues */
     dialog_Unregister( p_intf );
@@ -587,6 +688,17 @@ static VLCMain *_o_sharedMainInstance = nil;
     var_DelCallback( p_intf, "dialog-login", DialogCallback, self );
     var_DelCallback( p_intf, "dialog-question", DialogCallback, self );
     var_DelCallback( p_intf, "dialog-progress-bar", DialogCallback, self );
+    //var_DelCallback(p_playlist, "item-change", PLItemChanged, self);
+    var_DelCallback(p_playlist, "item-current", PLItemChanged, self);
+    var_DelCallback(p_playlist, "activity", PLItemChanged, self);
+    var_DelCallback(p_playlist, "leaf-to-parent", PlaylistUpdated, self);
+    var_DelCallback(p_playlist, "playlist-item-append", PlaylistUpdated, self);
+    var_DelCallback(p_playlist, "playlist-item-deleted", PlaylistUpdated, self);
+    var_DelCallback(p_playlist, "random", PlaybackModeUpdated, self);
+    var_DelCallback(p_playlist, "repeat", PlaybackModeUpdated, self);
+    var_DelCallback(p_playlist, "loop", PlaybackModeUpdated, self);
+    var_DelCallback(p_playlist, "volume", VolumeUpdated, self);
+    var_DelCallback(p_playlist, "mute", VolumeUpdated, self);
 
     /* remove global observer watching for vout device changes correctly */
     [[NSNotificationCenter defaultCenter] removeObserver: self];
@@ -602,10 +714,7 @@ static VLCMain *_o_sharedMainInstance = nil;
     [o_open release];
 
     if( o_info )
-    {
-        [o_info stopTimers];
         [o_info release];
-    }
 
     if( o_wizard )
         [o_wizard release];
@@ -616,14 +725,10 @@ static VLCMain *_o_sharedMainInstance = nil;
     [o_embedded_list release];
     [o_coredialogs release];
     [o_eyetv release];
-
-    [o_img_pause_pressed release];
-    [o_img_play_pressed release];
-    [o_img_pause release];
-    [o_img_play release];
+    [o_mainwindow release];
 
     /* unsubscribe from libvlc's debug messages */
-    msg_Unsubscribe( p_intf->p_sys->p_sub );
+    vlc_Unsubscribe( p_intf->p_sys->p_sub );
 
     [o_msg_arr removeAllObjects];
     [o_msg_arr release];
@@ -640,7 +745,6 @@ 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_Get( p_intf );
     vlc_object_kill( p_playlist );
     libvlc_Quit( p_intf->p_libvlc );
 
@@ -652,12 +756,9 @@ static VLCMain *_o_sharedMainInstance = nil;
 /* received directly before the update gets installed, so let's shut down a bit */
 - (void)updater:(SUUpdater *)updater willInstallUpdate:(SUAppcastItem *)update
 {
+    [NSApp activateIgnoringOtherApps:YES];
     [o_remote stopListening: self];
     var_SetInteger( p_intf->p_libvlc, "key-action", ACTIONID_STOP );
-
-    /* Close the window directly, because we do know that there
-     * won't be anymore video. It's currently waiting a bit. */
-    [[[o_coreinteraction voutView] window] orderOut:self];
 }
 
 #pragma mark -
@@ -727,10 +828,15 @@ static VLCMain *_o_sharedMainInstance = nil;
 /* Triggered when the computer goes to sleep */
 - (void)computerWillSleep: (NSNotification *)notification
 {
-    /* Pause */
-    if( p_intf && p_intf->p_sys->i_play_status == PLAYING_S )
+    input_thread_t * p_input;
+
+    p_input = pl_CurrentInput( p_intf );
+    if( p_input )
     {
-        var_SetInteger( p_intf->p_libvlc, "key-action", ACTIONID_PLAY_PAUSE );
+        int state = var_GetInteger( p_input, "state" );
+        if( state == PLAYING_S )
+            var_SetInteger( p_intf->p_libvlc, "key-action", ACTIONID_PLAY_PAUSE );
+        vlc_object_release( p_input );
     }
 }
 
@@ -760,7 +866,7 @@ static VLCMain *_o_sharedMainInstance = nil;
 - (BOOL)applicationShouldHandleReopen:(NSApplication *)theApplication hasVisibleWindows:(BOOL)hasVisibleWindows
 {
     if(!hasVisibleWindows)
-        [o_window makeKeyAndOrderFront:self];
+        [o_mainwindow makeKeyAndOrderFront:self];
 
     return YES;
 }
@@ -777,16 +883,16 @@ static VLCMain *_o_sharedMainInstance = nil;
         switch([buttonIdentifierNumber intValue])
         {
             case kRemoteButtonRight_Hold:
-                  [o_controls forward: self];
+                [[VLCCoreInteraction sharedInstance] forward];
             break;
             case kRemoteButtonLeft_Hold:
-                  [o_controls backward: self];
+                [[VLCCoreInteraction sharedInstance] backward];
             break;
             case kRemoteButtonVolume_Plus_Hold:
-                [o_controls volumeUp: self];
+                [[VLCCoreInteraction sharedInstance] volumeUp];
             break;
             case kRemoteButtonVolume_Minus_Hold:
-                [o_controls volumeDown: self];
+                [[VLCCoreInteraction sharedInstance] volumeDown];
             break;
         }
         if(b_remote_button_hold)
@@ -807,29 +913,29 @@ static VLCMain *_o_sharedMainInstance = nil;
     switch( buttonIdentifier )
     {
         case k2009RemoteButtonFullscreen:
-            [o_controls toogleFullscreen:self];
+            [[VLCCoreInteraction sharedInstance] toggleFullscreen];
             break;
         case k2009RemoteButtonPlay:
-            [o_controls play:self];
+            [[VLCCoreInteraction sharedInstance] play];
             break;
         case kRemoteButtonPlay:
             if(count >= 2) {
-                [o_controls toogleFullscreen:self];
+                [[VLCCoreInteraction sharedInstance] toggleFullscreen];
             } else {
-                [o_controls play: self];
+                [[VLCCoreInteraction sharedInstance] play];
             }
             break;
         case kRemoteButtonVolume_Plus:
-            [o_controls volumeUp: self];
+            [[VLCCoreInteraction sharedInstance] volumeUp];
             break;
         case kRemoteButtonVolume_Minus:
-            [o_controls volumeDown: self];
+            [[VLCCoreInteraction sharedInstance] volumeDown];
             break;
         case kRemoteButtonRight:
-            [o_controls next: self];
+            [[VLCCoreInteraction sharedInstance] next];
             break;
         case kRemoteButtonLeft:
-            [o_controls prev: self];
+            [[VLCCoreInteraction sharedInstance] previous];
             break;
         case kRemoteButtonRight_Hold:
         case kRemoteButtonLeft_Hold:
@@ -845,7 +951,7 @@ static VLCMain *_o_sharedMainInstance = nil;
             }
             break;
         case kRemoteButtonMenu:
-            [o_controls showPosition: self];
+            [o_controls showPosition: self]; //FIXME
             break;
         default:
             /* Add here whatever you want other buttons to do */
@@ -1129,10 +1235,166 @@ unsigned int CocoaKeyToVLC( unichar i_key )
         }
     }
     module_config_free (p_config);
-    module_release (p_main);
     o_usedHotkeys = [[NSArray alloc] initWithArray: o_usedHotkeys copyItems: YES];
 }
 
+#pragma mark -
+#pragma mark Interface updaters
+- (void)fullscreenChanged
+{
+    playlist_t * p_playlist = pl_Get( VLCIntf );
+    BOOL b_fullscreen = var_GetBool( p_playlist, "fullscreen" );
+
+    if (OSX_LION && b_nativeFullscreenMode)
+    {
+        [o_mainwindow toggleFullScreen: self];
+        if(b_fullscreen)
+            [NSApp setPresentationOptions:(NSApplicationPresentationFullScreen)];
+        else
+            [NSApp setPresentationOptions:(NSApplicationPresentationDefault)];
+    }
+    else
+    {
+        input_thread_t * p_input = pl_CurrentInput( VLCIntf );
+
+        if( p_input != NULL )
+        {
+            if(b_fullscreen)
+                [o_mainwindow performSelectorOnMainThread:@selector(enterFullscreen) withObject:nil waitUntilDone:NO];
+            else
+                [o_mainwindow performSelectorOnMainThread:@selector(leaveFullscreen) withObject:nil waitUntilDone:NO];
+            vlc_object_release( p_input );
+        }
+    }
+}
+
+- (void)PlaylistItemChanged
+{
+    input_thread_t * p_input;
+
+    p_input = playlist_CurrentInput( pl_Get(VLCIntf) );
+    if( p_input && !( p_input->b_dead || !vlc_object_alive(p_input) ) )
+    {
+        var_AddCallback( p_input, "intf-event", InputEvent, [VLCMain sharedInstance] );
+        [o_mainmenu setRateControlsEnabled: YES];
+        vlc_object_release( p_input );
+    }
+    else
+        [o_mainmenu setRateControlsEnabled: NO];
+
+    [o_playlist updateRowSelection];
+    [o_mainwindow updateWindow];
+    [self updateMainMenu];
+}
+
+- (void)updateMainMenu
+{
+    [o_mainmenu setupMenus];
+    [o_mainmenu updatePlaybackRate];
+}
+
+- (void)updateMainWindow
+{
+    [o_mainwindow updateWindow];
+}
+
+- (void)showFullscreenController
+{
+    [o_mainwindow showFullscreenController];
+}
+
+- (void)updateDelays
+{
+    [[VLCTrackSynchronization sharedInstance] performSelectorOnMainThread: @selector(updateValues) withObject: nil waitUntilDone:NO];
+}
+
+- (void)updateName
+{
+    [o_mainwindow updateName];
+}
+
+- (void)updatePlaybackPosition
+{
+    [o_mainwindow updateTimeSlider];
+
+    input_thread_t * p_input;
+    p_input = pl_CurrentInput( p_intf );
+    if( p_input )
+    {
+        if( var_GetInteger( p_input, "state" ) == PLAYING_S )
+            UpdateSystemActivity( UsrActivity );
+        vlc_object_release( p_input );
+    }
+}
+
+- (void)updateVolume
+{
+    [o_mainwindow updateVolumeSlider];
+}
+
+- (void)playlistUpdated
+{
+    [self playbackStatusUpdated];
+    [o_playlist playlistUpdated];
+    [o_mainwindow updateWindow];
+    [o_mainwindow updateName];
+}
+
+- (void)updateRecordState: (BOOL)b_value
+{
+    [o_mainmenu updateRecordState:b_value];
+}
+
+- (void)updateInfoandMetaPanel
+{
+    [o_playlist outlineViewSelectionDidChange:nil];
+}
+
+- (void)playbackStatusUpdated
+{
+    input_thread_t * p_input;
+
+    p_input = pl_CurrentInput( p_intf );
+    if( p_input )
+    {
+        int state = var_GetInteger( p_input, "state" );
+        if( state == PLAYING_S )
+        {
+            [[self mainMenu] setPause];
+            [o_mainwindow setPause];
+        }
+        else
+        {
+            if (state == END_S)
+                [o_mainmenu setSubmenusEnabled: FALSE];
+            [[self mainMenu] setPlay];
+            [o_mainwindow setPlay];
+        }
+        vlc_object_release( p_input );
+    }
+}
+
+- (void)playbackModeUpdated
+{
+    vlc_value_t looping,repeating;
+    playlist_t * p_playlist = pl_Get( VLCIntf );
+
+    bool loop = var_GetBool( p_playlist, "loop" );
+    bool repeat = var_GetBool( p_playlist, "repeat" );
+    if( repeat ) {
+        [o_mainwindow setRepeatOne];
+        [o_mainmenu setRepeatOne];
+    } else if( loop ) {
+        [o_mainwindow setRepeatAll];
+        [o_mainmenu setRepeatAll];
+    } else {
+        [o_mainwindow setRepeatOff];
+        [o_mainmenu setRepeatOff];
+    }
+
+    [o_mainwindow setShuffle];
+    [o_mainmenu setShuffle];
+}
 
 #pragma mark -
 #pragma mark Other objects getters
@@ -1202,11 +1464,6 @@ unsigned int CocoaKeyToVLC( unichar i_key )
     return nil;
 }
 
-- (BOOL)isPlaylistCollapsed
-{
-    return ![o_btn_playlist state];
-}
-
 - (id)info
 {
     if(! nib_info_loaded )
@@ -1233,7 +1490,7 @@ unsigned int CocoaKeyToVLC( unichar i_key )
 
 - (id)getVideoViewAtPositionX: (int *)pi_x Y: (int *)pi_y withWidth: (unsigned int*)pi_width andHeight: (unsigned int*)pi_height
 {
-    id videoView = [o_embedded_window videoView];
+    id videoView = [o_mainwindow videoView];
     NSRect videoRect = [videoView frame];
     int i_x = (int)videoRect.origin.x;
     int i_y = (int)videoRect.origin.y;
@@ -1247,6 +1504,11 @@ unsigned int CocoaKeyToVLC( unichar i_key )
     return videoView;
 }
 
+- (void)setNativeVideoSize:(NSSize)size
+{
+    [o_mainwindow setNativeVideoSize:size];
+}
+
 - (id)embeddedList
 {
     if( o_embedded_list )
@@ -1263,21 +1525,6 @@ unsigned int CocoaKeyToVLC( unichar i_key )
     return nil;
 }
 
-- (id)mainIntfPgbar
-{
-    if( o_main_pgbar )
-        return o_main_pgbar;
-
-    return nil;
-}
-
-- (id)controllerWindow
-{
-    if( o_window )
-        return o_window;
-    return nil;
-}
-
 - (id)eyeTVController
 {
     if( o_eyetv )
@@ -1291,470 +1538,16 @@ unsigned int CocoaKeyToVLC( unichar i_key )
        return o_remote;
 }
 
-#pragma mark -
-#pragma mark Polling
-
-/*****************************************************************************
- * ManageThread: An ugly thread that polls
- *****************************************************************************/
-static void * ManageThread( void *user_data )
-{
-    id self = user_data;
-
-    [self manage];
-
-    return NULL;
-}
-
-struct manage_cleanup_stack {
-    intf_thread_t * p_intf;
-    input_thread_t ** p_input;
-    playlist_t * p_playlist;
-    id self;
-};
-
-static void manage_cleanup( void * args )
-{
-    struct manage_cleanup_stack * manage_cleanup_stack = args;
-    intf_thread_t * p_intf = manage_cleanup_stack->p_intf;
-    input_thread_t * p_input = *manage_cleanup_stack->p_input;
-    id self = manage_cleanup_stack->self;
-    playlist_t * p_playlist = manage_cleanup_stack->p_playlist;
-
-    var_DelCallback( p_playlist, "item-current", PlaylistChanged, self );
-    var_DelCallback( p_playlist, "intf-change", PlaylistChanged, self );
-    var_DelCallback( p_playlist, "item-change", PlaylistChanged, self );
-    var_DelCallback( p_playlist, "playlist-item-append", PlaylistChanged, self );
-    var_DelCallback( p_playlist, "playlist-item-deleted", PlaylistChanged, self );
-
-    if( p_input ) vlc_object_release( p_input );
-}
-
-- (void)manage
-{
-    playlist_t * p_playlist;
-    input_thread_t * p_input = NULL;
-
-    /* new thread requires a new pool */
-
-    p_playlist = pl_Get( p_intf );
-
-    var_AddCallback( p_playlist, "item-current", PlaylistChanged, self );
-    var_AddCallback( p_playlist, "intf-change", PlaylistChanged, self );
-    var_AddCallback( p_playlist, "item-change", PlaylistChanged, self );
-    var_AddCallback( p_playlist, "playlist-item-append", PlaylistChanged, self );
-    var_AddCallback( p_playlist, "playlist-item-deleted", PlaylistChanged, self );
-
-    struct manage_cleanup_stack stack = { p_intf, &p_input, p_playlist, self };
-    pthread_cleanup_push(manage_cleanup, &stack);
-
-    bool exitLoop = false;
-    while( !exitLoop )
-    {
-        NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
-
-        if( !p_input )
-        {
-            p_input = playlist_CurrentInput( p_playlist );
-
-            /* Refresh the interface */
-            if( p_input )
-            {
-                msg_Dbg( p_intf, "input has changed, refreshing interface" );
-                p_intf->p_sys->b_input_update = true;
-            }
-        }
-        else if( !vlc_object_alive (p_input) || p_input->b_dead )
-        {
-            /* input stopped */
-            p_intf->p_sys->b_intf_update = true;
-            p_intf->p_sys->i_play_status = END_S;
-            msg_Dbg( p_intf, "input has stopped, refreshing interface" );
-            vlc_object_release( p_input );
-            p_input = NULL;
-        }
-        else if( cachedInputState != input_GetState( p_input ) )
-        {
-            p_intf->p_sys->b_intf_update = true;
-        }
-
-        /* Manage volume status */
-        [self manageVolumeSlider];
-
-        msleep( INTF_IDLE_SLEEP );
-
-        [pool release];
-
-        [o_appLock lock];
-        exitLoop = (f_appExit != 0 ? true : false);
-        [o_appLock unlock];
-    }
-
-    pthread_cleanup_pop(1);
-}
-
-- (void)manageVolumeSlider
-{
-    audio_volume_t i_volume;
-    playlist_t * p_playlist = pl_Get( p_intf );
-
-    i_volume = aout_VolumeGet( p_playlist );
-
-    if( i_volume != i_lastShownVolume )
-    {
-        i_lastShownVolume = i_volume;
-        p_intf->p_sys->b_volume_update = TRUE;
-    }
-}
-
-- (void)manageIntf:(NSTimer *)o_timer
-{
-    vlc_value_t val;
-    playlist_t * p_playlist;
-    input_thread_t * p_input;
-
-    if( p_intf->p_sys->b_input_update )
-    {
-        /* Called when new input is opened */
-        p_intf->p_sys->b_current_title_update = true;
-        p_intf->p_sys->b_intf_update = true;
-        p_intf->p_sys->b_input_update = false;
-        [o_mainmenu setupMenus]; /* Make sure input menu is up to date */
-
-        /* update our info-panel to reflect the new item, if we don't show
-         * the playlist or the selection is empty */
-        if( [self isPlaylistCollapsed] == YES )
-        {
-            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];
-        }
-    }
-    if( p_intf->p_sys->b_intf_update )
-    {
-        bool b_input = false;
-        bool b_plmul = false;
-        bool b_control = false;
-        bool b_seekable = false;
-        bool b_chapters = false;
-
-        playlist_t * p_playlist = pl_Get( p_intf );
-
-        PL_LOCK;
-        b_plmul = playlist_CurrentSize( p_playlist ) > 1;
-        PL_UNLOCK;
-
-        p_input = playlist_CurrentInput( p_playlist );
-
-        bool b_buffering = NO;
-
-        if( ( b_input = ( p_input != NULL ) ) )
-        {
-            /* seekable streams */
-            cachedInputState = input_GetState( p_input );
-            if ( cachedInputState == INIT_S ||
-                 cachedInputState == OPENING_S )
-            {
-                b_buffering = YES;
-            }
-
-            /* seekable streams */
-            b_seekable = var_GetBool( p_input, "can-seek" );
-
-            /* check whether slow/fast motion is possible */
-            b_control = var_GetBool( p_input, "can-rate" );
-
-            /* chapters & titles */
-            //b_chapters = p_input->stream.i_area_nb > 1;
-            vlc_object_release( p_input );
-        }
-
-        if( b_buffering )
-        {
-            [o_main_pgbar startAnimation:self];
-            [o_main_pgbar setIndeterminate:YES];
-            [o_main_pgbar setHidden:NO];
-        }
-        else
-        {
-            [o_main_pgbar stopAnimation:self];
-            [o_main_pgbar setHidden:YES];
-        }
-
-        [o_btn_stop setEnabled: b_input];
-        [o_embedded_window setStop: b_input];
-        [o_btn_ff setEnabled: b_seekable];
-        [o_btn_rewind setEnabled: b_seekable];
-        [o_btn_prev setEnabled: (b_plmul || b_chapters)];
-        [o_embedded_window setPrev: (b_plmul || b_chapters)];
-        [o_btn_next setEnabled: (b_plmul || b_chapters)];
-        [o_embedded_window setNext: (b_plmul || b_chapters)];
-        [o_mainmenu setRateControlsEnabled: b_control];
-
-        [o_timeslider setFloatValue: 0.0];
-        [o_timeslider setEnabled: b_seekable];
-        [o_timefield setStringValue: @"00:00"];
-        [[[self controls] fspanel] setStreamPos: 0 andTime: @"00:00"];
-        [[[self controls] fspanel] setSeekable: b_seekable];
-
-        [o_embedded_window setSeekable: b_seekable];
-        [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;
-    }
-
-    if( p_intf->p_sys->b_playmode_update )
-    {
-        [o_playlist playModeUpdated];
-        p_intf->p_sys->b_playmode_update = false;
-    }
-    if( p_intf->p_sys->b_playlist_update )
-    {
-        [o_playlist playlistUpdated];
-        p_intf->p_sys->b_playlist_update = false;
-    }
-
-    if( p_intf->p_sys->b_fullscreen_update )
-    {
-        p_intf->p_sys->b_fullscreen_update = false;
-    }
-
-    if( p_intf->p_sys->b_intf_show )
-    {
-        if( [[o_coreinteraction voutView] isFullscreen] && config_GetInt( VLCIntf, "macosx-fspanel" ) )
-            [[o_controls fspanel] fadeIn];
-        else
-            [o_window makeKeyAndOrderFront: self];
-
-        p_intf->p_sys->b_intf_show = false;
-    }
-
-    p_input = pl_CurrentInput( p_intf );
-    if( p_input && vlc_object_alive (p_input) )
-    {
-        vlc_value_t val;
-
-        if( p_intf->p_sys->b_current_title_update )
-        {
-            NSString *aString;
-            input_item_t * p_item = input_GetItem( p_input );
-            char * name = input_item_GetNowPlaying( p_item );
-
-            if( !name )
-                name = input_item_GetName( p_item );
-
-            aString = [NSString stringWithUTF8String:name];
-
-            free(name);
-
-            [self setScrollField: aString stopAfter:-1];
-            [[[self controls] fspanel] setStreamTitle: aString];
-
-            [[o_coreinteraction voutView] updateTitle];
-
-            [o_playlist updateRowSelection];
-
-            p_intf->p_sys->b_current_title_update = FALSE;
-        }
-
-        if( [o_timeslider isEnabled] )
-        {
-            /* Update the slider */
-            vlc_value_t time;
-            NSString * o_time;
-            vlc_value_t pos;
-            char psz_time[MSTRTIME_MAX_SIZE];
-            float f_updated;
-
-            var_Get( p_input, "position", &pos );
-            f_updated = 10000. * pos.f_float;
-            [o_timeslider setFloatValue: f_updated];
-
-            var_Get( p_input, "time", &time );
-
-            mtime_t dur = input_item_GetDuration( input_GetItem( p_input ) );
-            if( b_time_remaining && dur != -1 )
-            {
-                o_time = [NSString stringWithFormat: @"-%s", secstotimestr( psz_time, ((dur - time.i_time) / 1000000))];
-            }
-            else
-                o_time = [NSString stringWithUTF8String: secstotimestr( psz_time, (time.i_time / 1000000) )];
-
-            [o_timefield setStringValue: o_time];
-            [[[self controls] fspanel] setStreamPos: f_updated andTime: o_time];
-            [o_embedded_window setTime: o_time position: f_updated];
-        }
-
-        /* Manage Playing status */
-        var_Get( p_input, "state", &val );
-        if( p_intf->p_sys->i_play_status != val.i_int )
-        {
-            p_intf->p_sys->i_play_status = val.i_int;
-            [self playStatusUpdated: p_intf->p_sys->i_play_status];
-            [o_embedded_window playStatusUpdated: p_intf->p_sys->i_play_status];
-        }
-        vlc_object_release( p_input );
-    }
-    else if( p_input )
-    {
-        vlc_object_release( p_input );
-    }
-    else
-    {
-        p_intf->p_sys->i_play_status = END_S;
-        [self playStatusUpdated: p_intf->p_sys->i_play_status];
-        [o_embedded_window playStatusUpdated: p_intf->p_sys->i_play_status];
-        [o_mainmenu setSubmenusEnabled: FALSE];
-    }
-
-    if( p_intf->p_sys->b_volume_update )
-    {
-        NSString *o_text;
-        int i_volume_step = 0;
-        o_text = [NSString stringWithFormat: _NS("Volume: %d%%"), i_lastShownVolume * 400 / AOUT_VOLUME_MAX];
-        if( i_lastShownVolume != -1 )
-        [self setScrollField:o_text stopAfter:1000000];
-        i_volume_step = config_GetInt( p_intf->p_libvlc, "volume-step" );
-        [o_volumeslider setFloatValue: (float)i_lastShownVolume / i_volume_step];
-        [o_volumeslider setEnabled: TRUE];
-        [o_embedded_window setVolumeSlider: (float)i_lastShownVolume / i_volume_step];
-        [o_embedded_window setVolumeEnabled: TRUE];
-        [[[self controls] fspanel] setVolumeLevel: (float)i_lastShownVolume / i_volume_step];
-        p_intf->p_sys->b_mute = ( i_lastShownVolume == 0 );
-        p_intf->p_sys->b_volume_update = FALSE;
-    }
-
-end:
-    [self updateMessageDisplay];
-
-    if( ((i_end_scroll != -1) && (mdate() > i_end_scroll)) || !p_input )
-        [self resetScrollField];
-
-    [interfaceTimer autorelease];
-
-    interfaceTimer = [[NSTimer scheduledTimerWithTimeInterval: 0.3
-        target: self selector: @selector(manageIntf:)
-        userInfo: nil repeats: FALSE] retain];
-}
-
-#pragma mark -
-#pragma mark Interface update
-
-- (void)setScrollField:(NSString *)o_string stopAfter:(int)timeout
+- (void)setActiveVideoPlayback:(BOOL)b_value
 {
-    if( timeout != -1 )
-        i_end_scroll = mdate() + timeout;
-    else
-        i_end_scroll = -1;
-    [o_scrollfield setStringValue: o_string];
-    [o_embedded_window setScrollString: o_string];
+    b_active_videoplayback = b_value;
+    [o_mainwindow setVideoplayEnabled];
+    [o_mainwindow togglePlaylist:nil];
 }
 
-- (void)resetScrollField
+- (BOOL)activeVideoPlayback
 {
-    playlist_t * p_playlist = pl_Get( p_intf );
-    input_thread_t * p_input = playlist_CurrentInput( p_playlist );
-
-    i_end_scroll = -1;
-    if( p_input && vlc_object_alive (p_input) )
-    {
-        NSString *o_temp;
-        PL_LOCK;
-        playlist_item_t * p_item = playlist_CurrentPlayingItem( p_playlist );
-        if( input_item_GetNowPlaying( p_item->p_input ) )
-            o_temp = [NSString stringWithUTF8String:input_item_GetNowPlaying( p_item->p_input )];
-        else
-            o_temp = [NSString stringWithUTF8String:p_item->p_input->psz_name];
-        PL_UNLOCK;
-        [self setScrollField: o_temp stopAfter:-1];
-        [[[self controls] fspanel] setStreamTitle: o_temp];
-        vlc_object_release( p_input );
-        return;
-    }
-    [self setScrollField: _NS("VLC media player") stopAfter:-1];
-}
-
-- (void)playStatusUpdated:(int)i_status
-{
-    if( i_status == PLAYING_S )
-    {
-        [[[self controls] fspanel] setPause];
-        [[self mainMenu] setPause];
-        [o_btn_play setImage: o_img_pause];
-        [o_btn_play setAlternateImage: o_img_pause_pressed];
-        [o_btn_play setToolTip: _NS("Pause")];
-    }
-    else
-    {
-        [[[self controls] fspanel] setPlay];
-        [[self mainMenu] setPlay];
-        [o_btn_play setImage: o_img_play];
-        [o_btn_play setAlternateImage: o_img_play_pressed];
-        [o_btn_play setToolTip: _NS("Play")];
-    }
-}
-
-- (IBAction)timesliderUpdate:(id)sender
-{
-    float f_updated;
-    playlist_t * p_playlist;
-    input_thread_t * p_input;
-
-    switch( [[NSApp currentEvent] type] )
-    {
-        case NSLeftMouseUp:
-        case NSLeftMouseDown:
-        case NSLeftMouseDragged:
-            f_updated = [sender floatValue];
-            break;
-
-        default:
-            return;
-    }
-    p_playlist = pl_Get( p_intf );
-    p_input = playlist_CurrentInput( p_playlist );
-    if( p_input != NULL )
-    {
-        vlc_value_t time;
-        vlc_value_t pos;
-        NSString * o_time;
-        char psz_time[MSTRTIME_MAX_SIZE];
-
-        pos.f_float = f_updated / 10000.;
-        var_Set( p_input, "position", pos );
-        [o_timeslider setFloatValue: f_updated];
-
-        var_Get( p_input, "time", &time );
-
-        mtime_t dur = input_item_GetDuration( input_GetItem( p_input ) );
-        if( b_time_remaining && dur != -1 )
-        {
-            o_time = [NSString stringWithFormat: @"-%s", secstotimestr( psz_time, ((dur - time.i_time) / 1000000) )];
-        }
-        else
-            o_time = [NSString stringWithUTF8String: secstotimestr( psz_time, (time.i_time / 1000000) )];
-
-        [o_timefield setStringValue: o_time];
-        [[[self controls] fspanel] setStreamPos: f_updated andTime: o_time];
-        [o_embedded_window setTime: o_time position: f_updated];
-        vlc_object_release( p_input );
-    }
-}
-
-- (IBAction)timeFieldWasClicked:(id)sender
-{
-    b_time_remaining = !b_time_remaining;
-}
-
-- (IBAction)showController:(id)sender
-{
-    //FIXME: temporary hack until we have VLCMainWindow
-    [o_window makeKeyAndOrderFront:sender];
+    return b_active_videoplayback;
 }
 
 #pragma mark -
@@ -1984,7 +1777,7 @@ end:
     }
 }
 
-- (void)libvlcMessageReceived: (NSNotification *)o_notification
+- (void)processReceivedlibvlcMessage:(const msg_item_t *) item ofType: (int)i_type withStr: (char *)str
 {
     NSColor *o_white = [NSColor whiteColor];
     NSColor *o_red = [NSColor redColor];
@@ -1992,15 +1785,11 @@ end:
     NSColor *o_gray = [NSColor grayColor];
 
     NSColor * pp_color[4] = { o_white, o_red, o_yellow, o_gray };
-    static const char * ppsz_type[4] = { ": ", " error: ",
-    " warning: ", " debug: " };
+    static const char * ppsz_type[4] = { ": ", " error: ", " warning: ", " debug: " };
 
-    NSString *o_msg;
     NSDictionary *o_attr;
     NSAttributedString *o_msg_color;
 
-    int i_type = [[[o_notification userInfo] objectForKey: @"Type"] intValue];
-
     [o_msg_lock lock];
 
     if( [o_msg_arr count] + 2 > 600 )
@@ -2009,32 +1798,24 @@ end:
         [o_msg_arr removeObjectAtIndex: 1];
     }
 
-    o_attr = [NSDictionary dictionaryWithObject: o_gray
-                                         forKey: NSForegroundColorAttributeName];
-    o_msg = [NSString stringWithFormat: @"%@%s",
-             [[o_notification userInfo] objectForKey: @"Module"],
-             ppsz_type[i_type]];
-    o_msg_color = [[NSAttributedString alloc]
-                   initWithString: o_msg attributes: o_attr];
+    o_attr = [NSDictionary dictionaryWithObject: o_gray forKey: NSForegroundColorAttributeName];
+    o_msg_color = [[NSAttributedString alloc] initWithString: [NSString stringWithFormat: @"%s%s", item->psz_module, ppsz_type[i_type]] attributes: o_attr];
     [o_msg_arr addObject: [o_msg_color autorelease]];
 
-    o_attr = [NSDictionary dictionaryWithObject: pp_color[i_type]
-                                         forKey: NSForegroundColorAttributeName];
-    o_msg = [[[o_notification userInfo] objectForKey: @"Message"] stringByAppendingString: @"\n"];
-    o_msg_color = [[NSAttributedString alloc]
-                   initWithString: o_msg attributes: o_attr];
+    o_attr = [NSDictionary dictionaryWithObject: pp_color[i_type] forKey: NSForegroundColorAttributeName];
+    o_msg_color = [[NSAttributedString alloc] initWithString: [NSString stringWithFormat: @"%s\n", str] attributes: o_attr];
     [o_msg_arr addObject: [o_msg_color autorelease]];
 
     b_msg_arr_changed = YES;
     [o_msg_lock unlock];
+
+    [self updateMessageDisplay];
 }
 
 - (IBAction)saveDebugLog:(id)sender
 {
-    NSOpenPanel * saveFolderPanel = [[NSSavePanel alloc] init];
+    NSSavePanel * saveFolderPanel = [[NSSavePanel alloc] init];
 
-    [saveFolderPanel setCanChooseDirectories: NO];
-    [saveFolderPanel setCanChooseFiles: YES];
     [saveFolderPanel setCanSelectHiddenExtension: NO];
     [saveFolderPanel setCanCreateDirectories: YES];
     [saveFolderPanel setAllowedFileTypes: [NSArray arrayWithObject:@"rtfd"]];
@@ -2055,11 +1836,6 @@ end:
 #pragma mark -
 #pragma mark Playlist toggling
 
-- (IBAction)togglePlaylist:(id)sender
-{
-    NSLog( @"needs to be re-implemented" );
-}
-
 - (void)updateTogglePlaylistState
 {
     [[self playlist] outlineViewSelectionDidChange: NULL];