X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fgui%2Fmacosx%2Fintf.m;h=e29a6b20a0691fc15231028c9043728db41c7873;hb=644bd8439cebee81fbb3aabd3531b99061d2a375;hp=335ada7d9cfa2c06fbae2ed9e23e43a6ed91ac8f;hpb=454ac21d57f224820a9260643c124aeea935fb15;p=vlc diff --git a/modules/gui/macosx/intf.m b/modules/gui/macosx/intf.m index 335ada7d9c..e29a6b20a0 100644 --- a/modules/gui/macosx/intf.m +++ b/modules/gui/macosx/intf.m @@ -34,7 +34,6 @@ #include #include #include /* execl() */ -#import #import "intf.h" #import "fspanel.h" @@ -48,15 +47,15 @@ #import "wizard.h" #import "extended.h" #import "bookmarks.h" -#import "interaction.h" +#import "coredialogs.h" #import "embeddedwindow.h" -#import "update.h" #import "AppleRemote.h" #import "eyetv.h" #import "simple_prefs.h" -#import "vlm.h" -#import +#import /* for crashlog send mechanism */ +#import /* for the media key support */ +#import /* we're the update delegate */ /***************************************************************************** * Local prototypes. @@ -68,6 +67,12 @@ static void * ManageThread( void *user_data ); static unichar VLCKeyToCocoa( unsigned int i_key ); static unsigned int VLCModifiersToCocoa( unsigned int i_key ); +static void updateProgressPanel (void *, const char *, float); +static bool checkProgressPanel (void *); +static void destroyProgressPanel (void *); + +static void MsgCallback( msg_cb_data_t *, msg_item_t *, unsigned ); + #pragma mark - #pragma mark VLC Interface Object Callbacks @@ -84,8 +89,6 @@ int OpenIntf ( vlc_object_t *p_this ) memset( p_intf->p_sys, 0, sizeof( *p_intf->p_sys ) ); - p_intf->p_sys->o_pool = [[NSAutoreleasePool alloc] init]; - /* subscribe to LibVLCCore's messages */ p_intf->p_sys->p_sub = msg_Subscribe( p_intf->p_libvlc, MsgCallback, NULL ); p_intf->pf_run = Run; @@ -101,15 +104,14 @@ void CloseIntf ( vlc_object_t *p_this ) { intf_thread_t *p_intf = (intf_thread_t*) p_this; - [p_intf->p_sys->o_pool release]; - free( p_intf->p_sys ); } /***************************************************************************** * 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 ) { @@ -130,18 +132,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: */ - [NSApplication sharedApplication]; + 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]; } @@ -157,24 +157,24 @@ 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]; - - NSDictionary *o_dict = [NSDictionary dictionaryWithObjects: - [NSArray arrayWithObjects: - [NSString stringWithUTF8String: item->psz_module], - [NSString stringWithUTF8String: item->psz_msg], - [NSNumber numberWithInt: item->i_type], nil] - forKeys: - [NSArray arrayWithObjects: @"Module", @"Message", @"Type", nil]]; - - [[NSNotificationCenter defaultCenter] postNotificationName: @"VLCCoreMessageReceived" - object: nil + + /* 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; + + 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]; - + [o_pool release]; vlc_restorecancel( canc ); } - /***************************************************************************** * playlistChanged: Callback triggered by the intf-change playlist * variable, to let the intf update the playlist. @@ -221,30 +221,92 @@ 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 ) { NSAutoreleasePool * o_pool = [[NSAutoreleasePool alloc] init]; VLCMain *interface = (VLCMain *)data; - - NSLog( @"dialog callback triggered; type of dialogue is '%s'", type ); - if(!strcmp (type, "dialog-fatal")) + + if( [[NSString stringWithUTF8String: type] isEqualToString: @"dialog-progress-bar"] ) { - const dialog_fatal_t *p_dialog = (const dialog_fatal_t *)value.p_address; - NSLog( @"fatal dialogue with title '%s' and message '%s'", p_dialog->title, p_dialog->message ); -#if 0 - NSValue *o_value = [NSValue valueWithPointer:p_dialog]; + /* the progress panel needs to update itself and therefore wants special treatment within this context */ + dialog_progress_bar_t *p_dialog = (dialog_progress_bar_t *)value.p_address; - [[NSNotificationCenter defaultCenter] postNotificationName: @"VLCNewInteractionEventNotification" object:[interface getInteractionList] userInfo:[NSDictionary dictionaryWithObject:o_value forKey:@"VLCDialogPointer"]]; -#endif + p_dialog->pf_update = updateProgressPanel; + p_dialog->pf_check = checkProgressPanel; + p_dialog->pf_destroy = destroyProgressPanel; + p_dialog->p_sys = VLCIntf->p_libvlc; } + 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]]; + [o_pool release]; return VLC_SUCCESS; } +void updateProgressPanel (void *priv, const char *text, float value) +{ + NSAutoreleasePool *o_pool = [[NSAutoreleasePool alloc] init]; + + NSString *o_txt; + if( text != NULL ) + o_txt = [NSString stringWithUTF8String: text]; + else + o_txt = @""; + + [[[VLCMain sharedInstance] coreDialogProvider] updateProgressPanelWithText: o_txt andNumber: (double)(value * 1000.)]; + + [o_pool release]; +} + +void destroyProgressPanel (void *priv) +{ + NSAutoreleasePool *o_pool = [[NSAutoreleasePool alloc] init]; + [[[VLCMain sharedInstance] coreDialogProvider] destroyProgressPanel]; + [o_pool release]; +} + +bool checkProgressPanel (void *priv) +{ + NSAutoreleasePool *o_pool = [[NSAutoreleasePool alloc] init]; + return [[[VLCMain sharedInstance] coreDialogProvider] progressCancelled]; + [o_pool release]; +} + +#pragma mark - +#pragma mark Helpers + +input_thread_t *getInput(void) +{ + intf_thread_t *p_intf = VLCIntf; + if (!p_intf) + return NULL; + return pl_CurrentInput(p_intf); +} + +vout_thread_t *getVout(void) +{ + input_thread_t *p_input = getInput(); + if (!p_input) + return NULL; + vout_thread_t *p_vout = input_GetVout(p_input); + vlc_object_release(p_input); + return p_vout; +} + +aout_instance_t *getAout(void) +{ + input_thread_t *p_input = getInput(); + if (!p_input) + return NULL; + aout_instance_t *p_aout = input_GetAout(p_input); + vlc_object_release(p_input); + return p_aout; +} + #pragma mark - #pragma mark Private @@ -269,39 +331,33 @@ static VLCMain *_o_sharedMainInstance = nil; - (id)init { - if( _o_sharedMainInstance) + if( _o_sharedMainInstance) { [self dealloc]; return _o_sharedMainInstance; - } + } else _o_sharedMainInstance = [super init]; + p_intf = NULL; + o_msg_lock = [[NSLock alloc] init]; - o_msg_arr = [[NSMutableArray arrayWithCapacity: 200] retain]; + 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_interaction_list = [[VLCInteractionList alloc] init]; + o_coredialogs = [[VLCCoreDialogProvider alloc] init]; o_info = [[VLCInfo alloc] init]; -#ifdef UPDATE_CHECK - o_update = [[VLCUpdate alloc] init]; -#endif 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 */ @@ -317,7 +373,7 @@ static VLCMain *_o_sharedMainInstance = nil; p_intf = p_mainintf; } -- (intf_thread_t *)getIntf { +- (intf_thread_t *)intf { return p_intf; } @@ -327,32 +383,11 @@ static VLCMain *_o_sharedMainInstance = nil; playlist_t *p_playlist; vlc_value_t val; - /* Check if we already did this once. Opening the other nibs calls it too, because VLCMain is the owner */ - if( nib_main_loaded ) return; + if( !p_intf ) return; - /* check whether the user runs a valid version of OS X */ - if( MACOS_VERSION < 10.5f ) - { - NSAlert *ourAlert; - int i_returnValue; - NSString *o_blabla; - if( MACOS_VERSION == 10.4f ) - o_blabla = _NS("VLC's last release for your OS is the 0.9 series." ); - else if( MACOS_VERSION == 10.3f ) - o_blabla = _NS("VLC's last release for your OS is VLC 0.8.6i, which is prone to known security issues." ); - else // 10.2 and 10.1, still 3% of the OS X market share - o_blabla = _NS("VLC's last release for your OS is VLC 0.7.2, which is highly out of date and prone to " \ - "known security issues. We recommend you to update your Mac to a modern version of Mac OS X."); - ourAlert = [NSAlert alertWithMessageText: _NS("Your version of Mac OS X is no longer supported") - defaultButton: _NS("Quit") - alternateButton: NULL - otherButton: NULL - informativeTextWithFormat: _NS("VLC media player %s requires Mac OS X 10.5 or higher.\n\n%@"), VLC_Version(), o_blabla]; - [ourAlert setAlertStyle: NSCriticalAlertStyle]; - i_returnValue = [ourAlert runModal]; - [NSApp performSelectorOnMainThread: @selector(terminate:) withObject:nil waitUntilDone:NO]; - return; - } + /* Check if we already did this once. Opening the other nibs calls it too, + because VLCMain is the owner */ + if( nib_main_loaded ) return; [self initStrings]; @@ -384,6 +419,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)]; @@ -417,12 +455,24 @@ 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" ); [o_mi_snapshot setKeyEquivalent: [NSString stringWithFormat:@"%C", VLCKeyToCocoa( i_key )]]; [o_mi_snapshot setKeyEquivalentModifierMask: VLCModifiersToCocoa(i_key)]; + i_key = config_GetInt( p_intf, "key-random" ); + [o_mi_random setKeyEquivalent: [NSString stringWithFormat:@"%C", VLCKeyToCocoa( i_key )]]; + [o_mi_random setKeyEquivalentModifierMask: VLCModifiersToCocoa(i_key)]; + i_key = config_GetInt( p_intf, "key-zoom-half" ); + [o_mi_half_window setKeyEquivalent: [NSString stringWithFormat:@"%C", VLCKeyToCocoa( i_key )]]; + [o_mi_half_window setKeyEquivalentModifierMask: VLCModifiersToCocoa(i_key)]; + i_key = config_GetInt( p_intf, "key-zoom-original" ); + [o_mi_normal_window setKeyEquivalent: [NSString stringWithFormat:@"%C", VLCKeyToCocoa( i_key )]]; + [o_mi_normal_window setKeyEquivalentModifierMask: VLCModifiersToCocoa(i_key)]; + i_key = config_GetInt( p_intf, "key-zoom-double" ); + [o_mi_double_window setKeyEquivalent: [NSString stringWithFormat:@"%C", VLCKeyToCocoa( i_key )]]; + [o_mi_double_window setKeyEquivalentModifierMask: VLCModifiersToCocoa(i_key)]; var_Create( p_intf, "intf-change", VLC_VAR_BOOL ); @@ -430,7 +480,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 @@ -458,19 +508,27 @@ 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-fatal", VLC_VAR_ADDRESS ); - var_AddCallback( p_intf, "dialog-fatal", DialogCallback, self ); + var_Create( p_intf, "dialog-error", VLC_VAR_ADDRESS ); + var_AddCallback( p_intf, "dialog-error", DialogCallback, self ); + var_Create( p_intf, "dialog-critical", VLC_VAR_ADDRESS ); + var_AddCallback( p_intf, "dialog-critical", DialogCallback, self ); + var_Create( p_intf, "dialog-login", VLC_VAR_ADDRESS ); + var_AddCallback( p_intf, "dialog-login", DialogCallback, self ); + var_Create( p_intf, "dialog-question", VLC_VAR_ADDRESS ); + var_AddCallback( p_intf, "dialog-question", DialogCallback, self ); + var_Create( p_intf, "dialog-progress-bar", VLC_VAR_ADDRESS ); + var_AddCallback( p_intf, "dialog-progress-bar", DialogCallback, self ); dialog_Register( p_intf ); /* update the playmode stuff */ @@ -483,19 +541,26 @@ 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; } - (void)applicationWillFinishLaunching:(NSNotification *)o_notification { + if( !p_intf ) return; + /* FIXME: don't poll */ interfaceTimer = [[NSTimer scheduledTimerWithTimeInterval: 0.5 target: self selector: @selector(manageIntf:) @@ -512,16 +577,9 @@ static VLCMain *_o_sharedMainInstance = nil; - (void)applicationDidFinishLaunching:(NSNotification *)aNotification { - [self _removeOldPreferences]; - -#ifdef UPDATE_CHECK - /* Check for update silently on startup */ - if( !nib_update_loaded ) - nib_update_loaded = [NSBundle loadNibNamed:@"Update" owner: NSApp]; + if( !p_intf ) return; - if([o_update shouldCheckForUpdate]) - [NSThread detachNewThreadSelector:@selector(checkForUpdate) toTarget:o_update withObject:nil]; -#endif + [self _removeOldPreferences]; /* Handle sleep notification */ [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector:@selector(computerWillSleep:) @@ -532,6 +590,8 @@ static VLCMain *_o_sharedMainInstance = nil; - (void)initStrings { + if( !p_intf ) return; + [o_window setTitle: _NS("VLC media player")]; [self setScrollField:_NS("VLC media player") stopAfter:-1]; @@ -587,11 +647,13 @@ 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")]; [o_mi_repeat setTitle: _NS("Repeat One")]; [o_mi_loop setTitle: _NS("Repeat All")]; + [o_mi_quitAfterPB setTitle: _NS("Quit after Playback")]; [o_mi_fwd setTitle: _NS("Step Forward")]; [o_mi_bwd setTitle: _NS("Step Backward")]; @@ -649,6 +711,7 @@ static VLCMain *_o_sharedMainInstance = nil; [o_mu_window setTitle: _NS("Window")]; [o_mi_minimize setTitle: _NS("Minimize Window")]; [o_mi_close_window setTitle: _NS("Close Window")]; + [o_mi_player setTitle: _NS("Player...")]; [o_mi_controller setTitle: _NS("Controller...")]; [o_mi_equalizer setTitle: _NS("Equalizer...")]; [o_mi_extended setTitle: _NS("Extended Controls...")]; @@ -675,7 +738,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")]; @@ -700,23 +763,48 @@ static VLCMain *_o_sharedMainInstance = nil; #pragma mark - #pragma mark Termination +- (void)releaseRepresentedObjects:(NSMenu *)the_menu +{ + if( !p_intf ) return; + + NSArray *menuitems_array = [the_menu itemArray]; + for( int i=0; i<[menuitems_array count]; i++ ) + { + NSMenuItem *one_item = [menuitems_array objectAtIndex: i]; + if( [one_item hasSubmenu] ) + [self releaseRepresentedObjects: [one_item submenu]]; + + [one_item setRepresentedObject:NULL]; + } +} + - (void)applicationWillTerminate:(NSNotification *)notification { playlist_t * p_playlist; vout_thread_t * p_vout; int returnedValue = 0; - + + 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]; @@ -726,20 +814,22 @@ static VLCMain *_o_sharedMainInstance = nil; config_PutInt( p_intf->p_libvlc, "volume", i_lastShownVolume ); /* save the prefs if they were changed in the extended panel */ - if(o_extended && [o_extended getConfigChanged]) + if(o_extended && [o_extended configChanged]) { [o_extended savePrefs]; } /* unsubscribe from the interactive dialogues */ dialog_Unregister( p_intf ); - var_DelCallback( p_intf, "dialog-fatal", DialogCallback, self ); + var_DelCallback( p_intf, "dialog-error", DialogCallback, self ); + var_DelCallback( p_intf, "dialog-critical", DialogCallback, self ); + 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 ); /* remove global observer watching for vout device changes correctly */ [[NSNotificationCenter defaultCenter] removeObserver: self]; - [o_update end]; - /* release some other objects here, because it isn't sure whether dealloc * will be called later on */ if( nib_about_loaded ) @@ -773,9 +863,9 @@ static VLCMain *_o_sharedMainInstance = nil; [crashLogURLConnection cancel]; [crashLogURLConnection release]; - + [o_embedded_list release]; - [o_interaction_list release]; + [o_coredialogs release]; [o_eyetv release]; [o_img_pause_pressed release]; @@ -794,20 +884,29 @@ static VLCMain *_o_sharedMainInstance = nil; /* write cached user defaults to disk */ [[NSUserDefaults standardUserDefaults] synchronize]; + /* Make sure the Menu doesn't have any references to vlc objects anymore */ + [self releaseRepresentedObjects:[NSApp mainMenu]]; + /* 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]; +} + +#pragma mark - +#pragma mark Sparkle delegate +/* received directly before the update gets installed, so let's shut down a bit */ +- (void)updater:(SUUpdater *)updater willInstallUpdate:(SUAppcastItem *)update +{ + [o_remote stopListening: self]; + var_SetInteger( p_intf->p_libvlc, "key-action", ACTIONID_STOP ); - /* Go back to Run() and make libvlc exit properly */ - if( jmpbuffer ) - longjmp( jmpbuffer, 1 ); - /* not reached */ + /* Close the window directly, because we do know that there + * won't be anymore video. It's currently waiting a bit. */ + [[[o_controls voutView] window] orderOut:self]; } #pragma mark - @@ -838,7 +937,6 @@ static NSString * VLCToolbarMediaControl = @"VLCToolbarMediaControl"; { NSToolbarItem *toolbarItem = [[[NSToolbarItem alloc] initWithItemIdentifier: itemIdentifier] autorelease]; - if( [itemIdentifier isEqual: VLCToolbarMediaControl] ) { [toolbarItem setLabel:@"Media Controls"]; @@ -877,15 +975,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"]]; @@ -899,7 +997,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"]]; @@ -909,7 +1007,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 @@ -920,10 +1018,13 @@ static NSString * VLCToolbarMediaControl = @"VLCToolbarMediaControl"; application */ - (void)applicationDidBecomeActive:(NSNotification *)aNotification { - [o_remote startListening: self]; + if( !p_intf ) return; + if( config_GetInt( p_intf, "macosx-appleremote" ) == YES ) + [o_remote startListening: self]; } - (void)applicationDidResignActive:(NSNotification *)aNotification { + if( !p_intf ) return; [o_remote stopListening: self]; } @@ -931,11 +1032,9 @@ static NSString * VLCToolbarMediaControl = @"VLCToolbarMediaControl"; - (void)computerWillSleep: (NSNotification *)notification { /* Pause */ - if( p_intf->p_sys->i_play_status == PLAYING_S ) + if( p_intf && p_intf->p_sys->i_play_status == PLAYING_S ) { - vlc_value_t val; - val.i_int = config_GetInt( p_intf, "key-play-pause" ); - var_Set( p_intf->p_libvlc, "key-pressed", val ); + var_SetInteger( p_intf->p_libvlc, "key-action", ACTIONID_PLAY_PAUSE ); } } @@ -956,7 +1055,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]; @@ -1179,8 +1278,6 @@ static struct { NSCarriageReturnCharacter, KEY_ENTER }, { NSEnterCharacter, KEY_ENTER }, { NSBackspaceCharacter, KEY_BACKSPACE }, - { (unichar) ' ', KEY_SPACE }, - { (unichar) 0x1b, KEY_ESC }, {0,0} }; @@ -1236,7 +1333,7 @@ static unsigned int VLCModifiersToCocoa( unsigned int i_key ) unichar key = 0; vlc_value_t val; unsigned int i_pressed_modifiers = 0; - struct hotkey *p_hotkeys; + const struct hotkey *p_hotkeys; int i; val.i_int = 0; @@ -1286,9 +1383,8 @@ static unsigned int VLCModifiersToCocoa( unsigned int i_key ) #pragma mark - #pragma mark Other objects getters -// FIXME: this is ugly and does not respect cocoa naming scheme -- (id)getControls +- (id)controls { if( o_controls ) return o_controls; @@ -1296,7 +1392,7 @@ static unsigned int VLCModifiersToCocoa( unsigned int i_key ) return nil; } -- (id)getSimplePreferences +- (id)simplePreferences { if( !o_sprefs ) return nil; @@ -1307,7 +1403,7 @@ static unsigned int VLCModifiersToCocoa( unsigned int i_key ) return o_sprefs; } -- (id)getPreferences +- (id)preferences { if( !o_prefs ) return nil; @@ -1318,7 +1414,7 @@ static unsigned int VLCModifiersToCocoa( unsigned int i_key ) return o_prefs; } -- (id)getPlaylist +- (id)playlist { if( o_playlist ) return o_playlist; @@ -1331,7 +1427,7 @@ static unsigned int VLCModifiersToCocoa( unsigned int i_key ) return ![o_btn_playlist state]; } -- (id)getInfo +- (id)info { if( o_info ) return o_info; @@ -1339,7 +1435,7 @@ static unsigned int VLCModifiersToCocoa( unsigned int i_key ) return nil; } -- (id)getWizard +- (id)wizard { if( o_wizard ) return o_wizard; @@ -1347,12 +1443,7 @@ static unsigned int VLCModifiersToCocoa( unsigned int i_key ) return nil; } -- (id)getVLM -{ - return o_vlm; -} - -- (id)getBookmarks +- (id)bookmarks { if( o_bookmarks ) return o_bookmarks; @@ -1360,7 +1451,7 @@ static unsigned int VLCModifiersToCocoa( unsigned int i_key ) return nil; } -- (id)getEmbeddedList +- (id)embeddedList { if( o_embedded_list ) return o_embedded_list; @@ -1368,15 +1459,15 @@ static unsigned int VLCModifiersToCocoa( unsigned int i_key ) return nil; } -- (id)getInteractionList +- (id)coreDialogProvider { - if( o_interaction_list ) - return o_interaction_list; + if( o_coredialogs ) + return o_coredialogs; return nil; } -- (id)getMainIntfPgbar +- (id)mainIntfPgbar { if( o_main_pgbar ) return o_main_pgbar; @@ -1384,19 +1475,19 @@ static unsigned int VLCModifiersToCocoa( unsigned int i_key ) return nil; } -- (id)getControllerWindow +- (id)controllerWindow { if( o_window ) return o_window; return nil; } -- (id)getVoutMenu +- (id)voutMenu { return o_vout_menu; } -- (id)getEyeTVController +- (id)eyeTVController { if( o_eyetv ) return o_eyetv; @@ -1404,6 +1495,11 @@ static unsigned int VLCModifiersToCocoa( unsigned int i_key ) return nil; } +- (id)appleRemoteController +{ + return o_remote; +} + #pragma mark - #pragma mark Polling @@ -1434,13 +1530,11 @@ static void manage_cleanup( void * args ) id self = manage_cleanup_stack->self; playlist_t * p_playlist = manage_cleanup_stack->p_playlist; - 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 ); - - pl_Release( p_intf ); + 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 ); } @@ -1454,7 +1548,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 ); @@ -1465,7 +1559,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]; @@ -1500,20 +1595,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; - aout_VolumeGet( p_intf, &i_volume ); + playlist_t * p_playlist = pl_Get( p_intf ); + + aout_VolumeGet( p_playlist, &i_volume ); if( i_volume != i_lastShownVolume ) { @@ -1535,6 +1631,18 @@ static void manage_cleanup( void * args ) p_intf->p_sys->b_intf_update = true; p_intf->p_sys->b_input_update = false; [self 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 ) { @@ -1544,14 +1652,16 @@ 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 ); - /* TODO: fix i_size use */ - b_plmul = p_playlist->items.i_size > 1; + 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 */ @@ -1562,15 +1672,6 @@ static void manage_cleanup( void * args ) b_buffering = YES; } - /* 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 ) - { - PL_LOCK; - [[self getInfo] updatePanelWithItem: playlist_CurrentPlayingItem( p_playlist )->p_input]; - PL_UNLOCK; - } - /* seekable streams */ b_seekable = var_GetBool( p_input, "can-seek" ); @@ -1581,7 +1682,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 ) { @@ -1596,21 +1696,25 @@ static void manage_cleanup( void * args ) } [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_timeslider setFloatValue: 0.0]; [o_timeslider setEnabled: b_seekable]; [o_timefield setStringValue: @"00:00"]; - [[[self getControls] getFSPanel] setStreamPos: 0 andTime: @"00:00"]; - [[[self getControls] getFSPanel] setSeekable: b_seekable]; + [[[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; } @@ -1633,7 +1737,7 @@ static void manage_cleanup( void * args ) if( p_intf->p_sys->b_intf_show ) { if( [[o_controls voutView] isFullscreen] && config_GetInt( VLCIntf, "macosx-fspanel" ) ) - [[o_controls getFSPanel] fadeIn]; + [[o_controls fspanel] fadeIn]; else [o_window makeKeyAndOrderFront: self]; @@ -1659,11 +1763,12 @@ static void manage_cleanup( void * args ) free(name); [self setScrollField: aString stopAfter:-1]; - [[[self getControls] getFSPanel] setStreamTitle: aString]; + [[[self controls] fspanel] setStreamTitle: aString]; [[o_controls voutView] updateTitle]; - + [o_playlist updateRowSelection]; + p_intf->p_sys->b_current_title_update = FALSE; } @@ -1691,7 +1796,7 @@ static void manage_cleanup( void * args ) o_time = [NSString stringWithUTF8String: secstotimestr( psz_time, (time.i_time / 1000000) )]; [o_timefield setStringValue: o_time]; - [[[self getControls] getFSPanel] setStreamPos: f_updated andTime: o_time]; + [[[self controls] fspanel] setStreamPos: f_updated andTime: o_time]; [o_embedded_window setTime: o_time position: f_updated]; } @@ -1727,7 +1832,9 @@ static void manage_cleanup( void * args ) i_volume_step = config_GetInt( p_intf->p_libvlc, "volume-step" ); [o_volumeslider setFloatValue: (float)i_lastShownVolume / i_volume_step]; [o_volumeslider setEnabled: TRUE]; - [[[self getControls] getFSPanel] setVolumeLevel: (float)i_lastShownVolume / i_volume_step]; + [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; } @@ -1750,7 +1857,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 ) { @@ -1806,39 +1913,27 @@ end: var: "video-device" selector: @selector(toggleVar:)]; [o_controls setupVarMenuItem: o_mi_deinterlace target: (vlc_object_t *)p_vout - var: "deinterlace" selector: @selector(toggleVar:)]; - -#if 0 -/* FIXME Post processing. */ - p_dec_obj = (vlc_object_t *)vlc_object_find( - (vlc_object_t *)p_vout, - VLC_OBJECT_DECODER, - FIND_PARENT ); - if( p_dec_obj != NULL ) - { - [o_controls setupVarMenuItem: o_mi_ffmpeg_pp target: - (vlc_object_t *)p_dec_obj var:"ffmpeg-pp-q" selector: + var: "deinterlace-mode" selector: @selector(toggleVar:)]; + +#if 1 + [o_controls setupVarMenuItem: o_mi_ffmpeg_pp target: + (vlc_object_t *)p_vout var:"postprocess" selector: @selector(toggleVar:)]; - vlc_object_release(p_dec_obj); - } #endif vlc_object_release( (vlc_object_t *)p_vout ); } vlc_object_release( p_input ); } - pl_Release( p_intf ); } - (void)refreshVoutDeviceMenu:(NSNotification *)o_notification { - int x,y = 0; - vout_thread_t * p_vout = vlc_object_find( p_intf, VLC_OBJECT_VOUT, - FIND_ANYWHERE ); - - if(! p_vout ) + int x, y = 0; + vout_thread_t * p_vout = getVout(); + if( !p_vout ) return; - + /* clean the menu before adding new entries */ if( [o_mi_screen hasSubmenu] ) { @@ -1864,11 +1959,12 @@ end: else i_end_scroll = -1; [o_scrollfield setStringValue: o_string]; + [o_embedded_window setScrollString: o_string]; } - (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; @@ -1883,12 +1979,10 @@ end: o_temp = [NSString stringWithUTF8String:p_item->p_input->psz_name]; PL_UNLOCK; [self setScrollField: o_temp stopAfter:-1]; - [[[self getControls] getFSPanel] setStreamTitle: o_temp]; + [[[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]; } @@ -1896,7 +1990,7 @@ end: { if( i_status == PLAYING_S ) { - [[[self getControls] getFSPanel] setPause]; + [[[self controls] fspanel] setPause]; [o_btn_play setImage: o_img_pause]; [o_btn_play setAlternateImage: o_img_pause_pressed]; [o_btn_play setToolTip: _NS("Pause")]; @@ -1906,7 +2000,7 @@ end: } else { - [[[self getControls] getFSPanel] setPlay]; + [[[self controls] fspanel] setPlay]; [o_btn_play setImage: o_img_play]; [o_btn_play setAlternateImage: o_img_play_pressed]; [o_btn_play setToolTip: _NS("Play")]; @@ -1952,7 +2046,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 ) { @@ -1976,18 +2070,17 @@ end: o_time = [NSString stringWithUTF8String: secstotimestr( psz_time, (time.i_time / 1000000) )]; [o_timefield setStringValue: o_time]; - [[[self getControls] getFSPanel] setStreamPos: f_updated andTime: 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 ); } - pl_Release( p_intf ); } - (IBAction)timeFieldWasClicked:(id)sender { b_time_remaining = !b_time_remaining; } - + #pragma mark - #pragma mark Recent Items @@ -2080,14 +2173,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 ) @@ -2101,16 +2186,13 @@ end: - (IBAction)showBookmarks:(id)sender { - dialog_Fatal( p_intf, _("Video Settings not saved"), - _("An error occured while saving your settings via SimplePrefs.") ); - /* we need the wizard-nib for the bookmarks's extract functionality */ if( !nib_wizard_loaded ) { nib_wizard_loaded = [NSBundle loadNibNamed:@"Wizard" owner: NSApp]; [o_wizard initStrings]; } - + if( !nib_bookmarks_loaded ) nib_bookmarks_loaded = [NSBundle loadNibNamed:@"Bookmarks" owner: NSApp]; @@ -2129,21 +2211,6 @@ end: [o_sprefs showSimplePrefs]; } -#pragma mark - -#pragma mark Update - -- (IBAction)checkForUpdate:(id)sender -{ -#ifdef UPDATE_CHECK - if( !nib_update_loaded ) - nib_update_loaded = [NSBundle loadNibNamed:@"Update" owner: NSApp]; - [o_update showUpdateWindow]; -#else - msg_Err( VLCIntf, "Update checker wasn't enabled in this build" ); - dialog_Fatal( VLCIntf, _("Update check failed"), _("Checking for updates was not enabled in this build.") ); -#endif -} - #pragma mark - #pragma mark Help and Docs @@ -2162,7 +2229,7 @@ end: [o_about showGPL: sender]; } - + - (IBAction)viewHelp:(id)sender { if( !nib_about_loaded ) @@ -2247,9 +2314,6 @@ end: - (void)connectionDidFinishLoading:(NSURLConnection *)connection { - NSRunInformationalAlertPanel(_NS("Crash Report successfully sent"), - _NS("Thanks for your report!"), - _NS("OK"), nil, nil, nil); [crashLogURLConnection release]; crashLogURLConnection = nil; } @@ -2284,7 +2348,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] || @@ -2361,7 +2425,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"]; @@ -2411,7 +2475,7 @@ end: - (IBAction)viewErrorsAndWarnings:(id)sender { - [[[self getInteractionList] getErrorPanel] showPanel]; + [[[self coreDialogProvider] errorPanel] showPanel]; } - (IBAction)showMessagesPanel:(id)sender @@ -2423,7 +2487,7 @@ end: { if(! nib_info_loaded ) nib_info_loaded = [NSBundle loadNibNamed:@"MediaInfo" owner: NSApp]; - + [o_info initPanel]; } @@ -2475,11 +2539,10 @@ end: [o_msg_lock lock]; - if( [o_msg_arr count] + 2 > 400 ) + if( [o_msg_arr count] + 2 > 600 ) { - unsigned rid[] = { 0, 1 }; - [o_msg_arr removeObjectsFromIndices: (unsigned *)&rid - numIndices: sizeof(rid)/sizeof(rid[0])]; + [o_msg_arr removeObjectAtIndex: 0]; + [o_msg_arr removeObjectAtIndex: 1]; } o_attr = [NSDictionary dictionaryWithObject: o_gray @@ -2505,7 +2568,7 @@ end: - (IBAction)saveDebugLog:(id)sender { NSOpenPanel * saveFolderPanel = [[NSSavePanel alloc] init]; - + [saveFolderPanel setCanChooseDirectories: NO]; [saveFolderPanel setCanChooseFiles: YES]; [saveFolderPanel setCanSelectHiddenExtension: NO]; @@ -2544,7 +2607,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 @@ -2606,7 +2669,7 @@ end: else [o_btn_playlist setState: YES]; - [[self getPlaylist] outlineViewSelectionDidChange: NULL]; + [[self playlist] outlineViewSelectionDidChange: NULL]; } - (NSSize)windowWillResize:(NSWindow *)sender toSize:(NSSize)proposedFrameSize @@ -2747,3 +2810,99 @@ end: } @end + +/***************************************************************************** + * VLCApplication interface + * exclusively used to implement media key support on Al Apple keyboards + * b_justJumped is required as the keyboard send its events faster than + * the user can actually jump through his media + *****************************************************************************/ + +@implementation VLCApplication + +- (void)awakeFromNib +{ + b_active = b_mediaKeySupport = config_GetInt( VLCIntf, "macosx-mediakeys" ); + b_activeInBackground = config_GetInt( VLCIntf, "macosx-mediakeys-background" ); + [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(coreChangedMediaKeySupportSetting:) name: @"VLCMediaKeySupportSettingChanged" object: nil]; + [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(appGotActiveOrInactive:) name: @"NSApplicationDidBecomeActiveNotification" object: nil]; + [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(appGotActiveOrInactive:) name: @"NSApplicationWillResignActiveNotification" object: nil]; +} + +- (void)dealloc +{ + [[NSNotificationCenter defaultCenter] removeObserver: self]; + [super dealloc]; +} + +- (void)appGotActiveOrInactive: (NSNotification *)o_notification +{ + if(( [[o_notification name] isEqualToString: @"NSApplicationWillResignActiveNotification"] && !b_activeInBackground ) || !b_mediaKeySupport) + b_active = NO; + else + b_active = YES; +} + +- (void)coreChangedMediaKeySupportSetting: (NSNotification *)o_notification +{ + b_active = b_mediaKeySupport = config_GetInt( VLCIntf, "macosx-mediakeys" ); + b_activeInBackground = config_GetInt( VLCIntf, "macosx-mediakeys-background" ); +} + + +- (void)sendEvent: (NSEvent*)event +{ + if( b_active ) + { + if( [event type] == NSSystemDefined && [event subtype] == 8 ) + { + int keyCode = (([event data1] & 0xFFFF0000) >> 16); + 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 ) + { + var_SetInteger( VLCIntf->p_libvlc, "key-action", ACTIONID_NEXT ); + } + else if( keyRepeat == 1 ) + { + var_SetInteger( VLCIntf->p_libvlc, "key-action", ACTIONID_JUMP_FORWARD_SHORT ); + b_justJumped = YES; + [self performSelector:@selector(resetJump) + withObject: NULL + afterDelay:0.25]; + } + } + + if( keyCode == NX_KEYTYPE_REWIND && !b_justJumped ) + { + if( keyState == 0 && keyRepeat == 0 ) + { + var_SetInteger( VLCIntf->p_libvlc, "key-action", ACTIONID_PREV ); + } + else if( keyRepeat == 1 ) + { + var_SetInteger( VLCIntf->p_libvlc, "key-action", ACTIONID_JUMP_BACKWARD_SHORT ); + b_justJumped = YES; + [self performSelector:@selector(resetJump) + withObject: NULL + afterDelay:0.25]; + } + } + } + } + [super sendEvent: event]; +} + +- (void)resetJump +{ + b_justJumped = NO; +} + +@end