X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fgui%2Fmacosx%2Fintf.m;h=21098e9c370a0183a735a55bf77feffe6e77fd78;hb=1df0fa1323fbb927ae8e869a85e2eca0a03fff0f;hp=e1fc00eb91a2ae71c3673f33d9bb2bcf2202d9c0;hpb=c3a1a712783d3818557ac17de685fa7a0300a0dc;p=vlc diff --git a/modules/gui/macosx/intf.m b/modules/gui/macosx/intf.m index e1fc00eb91..21098e9c37 100644 --- a/modules/gui/macosx/intf.m +++ b/modules/gui/macosx/intf.m @@ -33,8 +33,8 @@ #include #include #include +#include #include /* execl() */ -#import #import "intf.h" #import "fspanel.h" @@ -50,14 +50,13 @@ #import "bookmarks.h" #import "coredialogs.h" #import "embeddedwindow.h" -#import "update.h" #import "AppleRemote.h" #import "eyetv.h" #import "simple_prefs.h" -#import "vlm.h" #import /* for crashlog send mechanism */ #import /* for the media key support */ +#import /* we're the update delegate */ /***************************************************************************** * Local prototypes. @@ -69,6 +68,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 @@ -85,8 +90,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; @@ -102,15 +105,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 ) { @@ -131,18 +133,16 @@ static void Run( intf_thread_t *p_intf ) NSAutoreleasePool * o_pool = [[NSAutoreleasePool alloc] init]; - /* Install a jmpbuffer to where we can go back before the NSApp exit - * see applicationWillTerminate: */ + o_appLock = [[NSLock alloc] init]; + [VLCApplication sharedApplication]; [[VLCMain sharedInstance] setIntf: p_intf]; [NSBundle loadNibNamed: @"MainMenu" owner: NSApp]; - /* Install a jmpbuffer to where we can go back before the NSApp exit - * see applicationWillTerminate: */ - if(setjmp(jmpbuffer) == 0) - [NSApp run]; - + [NSApp run]; + [[VLCMain sharedInstance] applicationWillTerminate:nil]; + [o_pool release]; } @@ -159,7 +159,7 @@ static void MsgCallback( msg_cb_data_t *data, msg_item_t *item, unsigned int i ) int canc = vlc_savecancel(); NSAutoreleasePool * o_pool = [[NSAutoreleasePool alloc] init]; - /* this may happen from time to time, let's bail out as info would be useless anyway */ + /* this may happen from time to time, let's bail out as info would be useless anyway */ if( !item->psz_module || !item->psz_msg ) return; @@ -168,15 +168,14 @@ static void MsgCallback( msg_cb_data_t *data, msg_item_t *item, unsigned int i ) [NSString stringWithUTF8String: item->psz_msg], @"Message", [NSNumber numberWithInt: item->i_type], @"Type", nil]; - [[NSNotificationCenter defaultCenter] postNotificationName: @"VLCCoreMessageReceived" - object: nil + [[NSNotificationCenter defaultCenter] postNotificationName: @"VLCCoreMessageReceived" + object: nil userInfo: o_dict]; [o_pool release]; vlc_restorecancel( canc ); } - /***************************************************************************** * playlistChanged: Callback triggered by the intf-change playlist * variable, to let the intf update the playlist. @@ -223,7 +222,7 @@ static int FullscreenChanged( vlc_object_t *p_this, const char *psz_variable, } /***************************************************************************** - * DialogCallback: Callback triggered by the "dialog-*" variables + * DialogCallback: Callback triggered by the "dialog-*" variables * to let the intf display error and interaction dialogs *****************************************************************************/ static int DialogCallback( vlc_object_t *p_this, const char *type, vlc_value_t previous, vlc_value_t value, void *data ) @@ -231,15 +230,84 @@ static int DialogCallback( vlc_object_t *p_this, const char *type, vlc_value_t p NSAutoreleasePool * o_pool = [[NSAutoreleasePool alloc] init]; VLCMain *interface = (VLCMain *)data; - const dialog_fatal_t *p_dialog = (const dialog_fatal_t *)value.p_address; + if( [[NSString stringWithUTF8String: type] isEqualToString: @"dialog-progress-bar"] ) + { + /* 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; + + 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:p_dialog]; + 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 @@ -264,41 +332,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_embedded_list = NULL; // [[VLCEmbeddedList alloc] init]; o_coredialogs = [[VLCCoreDialogProvider alloc] init]; o_info = [[VLCInfo alloc] init]; -#ifdef UPDATE_CHECK - o_update = [[VLCUpdate alloc] init]; -#endif i_lastShownVolume = -1; -#ifndef __x86_64__ - o_remote = [[AppleRemote alloc] init]; - [o_remote setClickCountEnabledButtons: kRemoteButtonPlay]; - [o_remote setDelegate: _o_sharedMainInstance]; -#endif - o_eyetv = [[VLCEyeTVController alloc] init]; /* announce our launch to a potential eyetv plugin */ @@ -324,32 +384,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]; @@ -381,6 +420,9 @@ static VLCMain *_o_sharedMainInstance = nil; i_key = config_GetInt( p_intf, "key-slower" ); [o_mi_slower setKeyEquivalent: [NSString stringWithFormat:@"%C", VLCKeyToCocoa( i_key )]]; [o_mi_slower setKeyEquivalentModifierMask: VLCModifiersToCocoa(i_key)]; + i_key = config_GetInt( p_intf, "key-rate-normal" ); + [o_mi_normalSpeed setKeyEquivalent: [NSString stringWithFormat:@"%C", VLCKeyToCocoa( i_key )]]; + [o_mi_normalSpeed setKeyEquivalentModifierMask: VLCModifiersToCocoa(i_key)]; i_key = config_GetInt( p_intf, "key-prev" ); [o_mi_previous setKeyEquivalent: [NSString stringWithFormat:@"%C", VLCKeyToCocoa( i_key )]]; [o_mi_previous setKeyEquivalentModifierMask: VLCModifiersToCocoa(i_key)]; @@ -414,12 +456,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 ); @@ -427,7 +481,7 @@ static VLCMain *_o_sharedMainInstance = nil; [o_volumeslider setEnabled: YES]; [self manageVolumeSlider]; [o_window setDelegate: self]; - + b_restore_size = false; // Set that here as IB seems to be buggy @@ -455,22 +509,21 @@ 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 ); @@ -489,19 +542,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:) @@ -518,16 +578,9 @@ static VLCMain *_o_sharedMainInstance = nil; - (void)applicationDidFinishLaunching:(NSNotification *)aNotification { - [self _removeOldPreferences]; + if( !p_intf ) return; -#ifdef UPDATE_CHECK - /* Check for update silently on startup */ - if( !nib_update_loaded ) - nib_update_loaded = [NSBundle loadNibNamed:@"Update" owner: NSApp]; - - 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:) @@ -538,6 +591,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]; @@ -593,11 +648,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")]; @@ -642,6 +699,8 @@ static VLCMain *_o_sharedMainInstance = nil; [o_mi_addSub setTitle: _NS("Open File...")]; [o_mi_deinterlace setTitle: _NS("Deinterlace")]; [o_mu_deinterlace setTitle: _NS("Deinterlace")]; + [o_mi_deinterlace_mode setTitle: _NS("Deinterlace mode")]; + [o_mu_deinterlace_mode setTitle: _NS("Deinterlace mode")]; [o_mi_ffmpeg_pp setTitle: _NS("Post processing")]; [o_mu_ffmpeg_pp setTitle: _NS("Post processing")]; [o_mi_teletext setTitle: _NS("Teletext")]; @@ -655,6 +714,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...")]; @@ -681,7 +741,7 @@ static VLCMain *_o_sharedMainInstance = nil; [o_dmi_next setTitle: _NS("Next")]; [o_dmi_previous setTitle: _NS("Previous")]; [o_dmi_mute setTitle: _NS("Mute")]; - + /* vout menu */ [o_vmi_play setTitle: _NS("Play")]; [o_vmi_stop setTitle: _NS("Stop")]; @@ -708,6 +768,8 @@ static VLCMain *_o_sharedMainInstance = nil; - (void)releaseRepresentedObjects:(NSMenu *)the_menu { + if( !p_intf ) return; + NSArray *menuitems_array = [the_menu itemArray]; for( int i=0; i<[menuitems_array count]; i++ ) { @@ -724,18 +786,28 @@ static VLCMain *_o_sharedMainInstance = nil; 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]; @@ -752,7 +824,8 @@ static VLCMain *_o_sharedMainInstance = nil; /* 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 ); @@ -760,8 +833,6 @@ static VLCMain *_o_sharedMainInstance = nil; /* 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 ) @@ -795,7 +866,7 @@ static VLCMain *_o_sharedMainInstance = nil; [crashLogURLConnection cancel]; [crashLogURLConnection release]; - + [o_embedded_list release]; [o_coredialogs release]; [o_eyetv release]; @@ -821,18 +892,24 @@ static VLCMain *_o_sharedMainInstance = nil; /* Kill the playlist, so that it doesn't accept new request * such as the play request from vlc.c (we are a blocking interface). */ - p_playlist = pl_Hold( p_intf ); + p_playlist = pl_Get( p_intf ); vlc_object_kill( p_playlist ); - pl_Release( p_intf ); - libvlc_Quit( p_intf->p_libvlc ); [self setIntf:nil]; +} - /* Go back to Run() and make libvlc exit properly */ - if( jmpbuffer ) - longjmp( jmpbuffer, 1 ); - /* not reached */ +#pragma mark - +#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 ); + + /* 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 - @@ -863,7 +940,6 @@ static NSString * VLCToolbarMediaControl = @"VLCToolbarMediaControl"; { NSToolbarItem *toolbarItem = [[[NSToolbarItem alloc] initWithItemIdentifier: itemIdentifier] autorelease]; - if( [itemIdentifier isEqual: VLCToolbarMediaControl] ) { [toolbarItem setLabel:@"Media Controls"]; @@ -902,15 +978,15 @@ static NSString * VLCToolbarMediaControl = @"VLCToolbarMediaControl"; - (void)controlTintChanged { BOOL b_playing = NO; - + if( [o_btn_play alternateImage] == o_img_play_pressed ) b_playing = YES; - + if( [NSColor currentControlTint] == NSGraphiteControlTint ) { o_img_play_pressed = [NSImage imageNamed: @"play_graphite"]; o_img_pause_pressed = [NSImage imageNamed: @"pause_graphite"]; - + [o_btn_prev setAlternateImage: [NSImage imageNamed: @"previous_graphite"]]; [o_btn_rewind setAlternateImage: [NSImage imageNamed: @"skip_previous_graphite"]]; [o_btn_stop setAlternateImage: [NSImage imageNamed: @"stop_graphite"]]; @@ -924,7 +1000,7 @@ static NSString * VLCToolbarMediaControl = @"VLCToolbarMediaControl"; { o_img_play_pressed = [NSImage imageNamed: @"play_blue"]; o_img_pause_pressed = [NSImage imageNamed: @"pause_blue"]; - + [o_btn_prev setAlternateImage: [NSImage imageNamed: @"previous_blue"]]; [o_btn_rewind setAlternateImage: [NSImage imageNamed: @"skip_previous_blue"]]; [o_btn_stop setAlternateImage: [NSImage imageNamed: @"stop_blue"]]; @@ -934,7 +1010,7 @@ static NSString * VLCToolbarMediaControl = @"VLCToolbarMediaControl"; [o_btn_playlist setAlternateImage: [NSImage imageNamed: @"playlistdrawer_blue"]]; [o_btn_equalizer setAlternateImage: [NSImage imageNamed: @"equalizerdrawer_blue"]]; } - + if( b_playing ) [o_btn_play setAlternateImage: o_img_play_pressed]; else @@ -945,26 +1021,23 @@ static NSString * VLCToolbarMediaControl = @"VLCToolbarMediaControl"; application */ - (void)applicationDidBecomeActive:(NSNotification *)aNotification { -#ifndef __x86_64__ - [o_remote startListening: self]; -#endif + if( !p_intf ) return; + if( config_GetInt( p_intf, "macosx-appleremote" ) == YES ) + [o_remote startListening: self]; } - (void)applicationDidResignActive:(NSNotification *)aNotification { -#ifndef __x86_64__ + if( !p_intf ) return; [o_remote stopListening: self]; -#endif } /* Triggered when the computer goes to sleep */ - (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 ); } } @@ -974,7 +1047,14 @@ static NSString * VLCToolbarMediaControl = @"VLCToolbarMediaControl"; - (BOOL)application:(NSApplication *)o_app openFile:(NSString *)o_filename { BOOL b_autoplay = config_GetInt( VLCIntf, "macosx-autoplay" ); - NSDictionary *o_dic = [NSDictionary dictionaryWithObjectsAndKeys: o_filename, @"ITEM_URL", nil]; + char *psz_uri = make_URI([o_filename UTF8String], "file" ); + if( !psz_uri ) + return( FALSE ); + + NSDictionary *o_dic = [NSDictionary dictionaryWithObject:[NSString stringWithCString:psz_uri encoding:NSUTF8StringEncoding] forKey:@"ITEM_URL"]; + + free( psz_uri ); + if( b_autoplay ) [o_playlist appendArray: [NSArray arrayWithObject: o_dic] atPos: -1 enqueue: NO]; else @@ -985,7 +1065,7 @@ static NSString * VLCToolbarMediaControl = @"VLCToolbarMediaControl"; /* When user click in the Dock icon our double click in the finder */ - (BOOL)applicationShouldHandleReopen:(NSApplication *)theApplication hasVisibleWindows:(BOOL)hasVisibleWindows -{ +{ if(!hasVisibleWindows) [o_window makeKeyAndOrderFront:self]; @@ -1033,6 +1113,12 @@ static NSString * VLCToolbarMediaControl = @"VLCToolbarMediaControl"; { switch( buttonIdentifier ) { + case k2009RemoteButtonFullscreen: + [o_controls toogleFullscreen:self]; + break; + case k2009RemoteButtonPlay: + [o_controls play:self]; + break; case kRemoteButtonPlay: if(count >= 2) { [o_controls toogleFullscreen:self]; @@ -1208,8 +1294,6 @@ static struct { NSCarriageReturnCharacter, KEY_ENTER }, { NSEnterCharacter, KEY_ENTER }, { NSBackspaceCharacter, KEY_BACKSPACE }, - { (unichar) ' ', KEY_SPACE }, - { (unichar) 0x1b, KEY_ESC }, {0,0} }; @@ -1265,7 +1349,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; @@ -1375,11 +1459,6 @@ static unsigned int VLCModifiersToCocoa( unsigned int i_key ) return nil; } -- (id)vlm -{ - return o_vlm; -} - - (id)bookmarks { if( o_bookmarks ) @@ -1432,6 +1511,11 @@ static unsigned int VLCModifiersToCocoa( unsigned int i_key ) return nil; } +- (id)appleRemoteController +{ + return o_remote; +} + #pragma mark - #pragma mark Polling @@ -1462,13 +1546,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 ); } @@ -1482,7 +1564,7 @@ static void manage_cleanup( void * args ) vlc_thread_set_priority( p_intf, VLC_THREAD_PRIORITY_LOW ); - p_playlist = pl_Hold( p_intf ); + p_playlist = pl_Get( p_intf ); var_AddCallback( p_playlist, "item-current", PlaylistChanged, self ); var_AddCallback( p_playlist, "intf-change", PlaylistChanged, self ); @@ -1493,7 +1575,8 @@ static void manage_cleanup( void * args ) struct manage_cleanup_stack stack = { p_intf, &p_input, p_playlist, self }; pthread_cleanup_push(manage_cleanup, &stack); - while( true ) + bool exitLoop = false; + while( !exitLoop ) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; @@ -1528,20 +1611,21 @@ static void manage_cleanup( void * args ) msleep( INTF_IDLE_SLEEP ); [pool release]; + + [o_appLock lock]; + exitLoop = (f_appExit != 0 ? true : false); + [o_appLock unlock]; } pthread_cleanup_pop(1); - - msg_Dbg( p_intf, "Killing the Mac OS X module" ); - - /* We are dead, terminate */ - [NSApp performSelectorOnMainThread: @selector(terminate:) withObject:nil waitUntilDone:NO]; } - (void)manageVolumeSlider { audio_volume_t i_volume; - 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 ) { @@ -1563,6 +1647,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 ) { @@ -1572,14 +1668,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 */ @@ -1590,15 +1688,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 info] updatePanelWithItem: playlist_CurrentPlayingItem( p_playlist )->p_input]; - PL_UNLOCK; - } - /* seekable streams */ b_seekable = var_GetBool( p_input, "can-seek" ); @@ -1609,7 +1698,6 @@ static void manage_cleanup( void * args ) //b_chapters = p_input->stream.i_area_nb > 1; vlc_object_release( p_input ); } - pl_Release( p_intf ); if( b_buffering ) { @@ -1624,10 +1712,13 @@ 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]; @@ -1636,9 +1727,10 @@ static void manage_cleanup( void * args ) [[[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; } @@ -1690,8 +1782,9 @@ static void manage_cleanup( void * args ) [[[self controls] fspanel] setStreamTitle: aString]; [[o_controls voutView] updateTitle]; - + [o_playlist updateRowSelection]; + p_intf->p_sys->b_current_title_update = FALSE; } @@ -1755,6 +1848,8 @@ 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]; + [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; @@ -1778,7 +1873,7 @@ end: - (void)setupMenus { - playlist_t * p_playlist = pl_Hold( p_intf ); + playlist_t * p_playlist = pl_Get( p_intf ); input_thread_t * p_input = playlist_CurrentInput( p_playlist ); if( p_input != NULL ) { @@ -1836,37 +1931,28 @@ end: [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: + [o_controls setupVarMenuItem: o_mi_deinterlace_mode target: (vlc_object_t *)p_vout + var: "deinterlace-mode" selector: @selector(toggleVar:)]; + +#if 1 + [o_controls setupVarMenuItem: o_mi_ffmpeg_pp target: + (vlc_object_t *)p_vout var:"postprocess" selector: @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] ) { @@ -1892,11 +1978,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; @@ -1913,10 +2000,8 @@ end: [self setScrollField: o_temp stopAfter:-1]; [[[self controls] fspanel] setStreamTitle: o_temp]; vlc_object_release( p_input ); - pl_Release( p_intf ); return; } - pl_Release( p_intf ); [self setScrollField: _NS("VLC media player") stopAfter:-1]; } @@ -1955,6 +2040,7 @@ end: [o_mi_subtitle setEnabled: b_enabled]; [o_mi_channels setEnabled: b_enabled]; [o_mi_deinterlace setEnabled: b_enabled]; + [o_mi_deinterlace_mode setEnabled: b_enabled]; [o_mi_ffmpeg_pp setEnabled: b_enabled]; [o_mi_device setEnabled: b_enabled]; [o_mi_screen setEnabled: b_enabled]; @@ -1980,7 +2066,7 @@ end: default: return; } - p_playlist = pl_Hold( p_intf ); + p_playlist = pl_Get( p_intf ); p_input = playlist_CurrentInput( p_playlist ); if( p_input != NULL ) { @@ -2008,14 +2094,13 @@ end: [o_embedded_window setTime: o_time position: f_updated]; vlc_object_release( p_input ); } - pl_Release( p_intf ); } - (IBAction)timeFieldWasClicked:(id)sender { b_time_remaining = !b_time_remaining; } - + #pragma mark - #pragma mark Recent Items @@ -2108,14 +2193,6 @@ end: } } -- (IBAction)showVLM:(id)sender -{ - if( !nib_vlm_loaded ) - nib_vlm_loaded = [NSBundle loadNibNamed:@"VLM" owner: NSApp]; - - [o_vlm showVLMWindow]; -} - - (IBAction)showExtended:(id)sender { if( o_extended == nil ) @@ -2135,7 +2212,7 @@ end: nib_wizard_loaded = [NSBundle loadNibNamed:@"Wizard" owner: NSApp]; [o_wizard initStrings]; } - + if( !nib_bookmarks_loaded ) nib_bookmarks_loaded = [NSBundle loadNibNamed:@"Bookmarks" owner: NSApp]; @@ -2154,21 +2231,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_FatalWait( VLCIntf, _("Update check failed"), _("Checking for updates was not enabled in this build.") ); -#endif -} - #pragma mark - #pragma mark Help and Docs @@ -2187,7 +2249,7 @@ end: [o_about showGPL: sender]; } - + - (IBAction)viewHelp:(id)sender { if( !nib_about_loaded ) @@ -2272,9 +2334,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; } @@ -2309,7 +2368,7 @@ end: // Dooh. ugly. if( year < [[compo objectAtIndex:0] intValue] || - (year ==[[compo objectAtIndex:0] intValue] && + (year ==[[compo objectAtIndex:0] intValue] && (month < [[compo objectAtIndex:1] intValue] || (month ==[[compo objectAtIndex:1] intValue] && (day < [[compo objectAtIndex:2] intValue] || @@ -2386,7 +2445,7 @@ end: int version = [[NSUserDefaults standardUserDefaults] integerForKey:kVLCPreferencesVersion]; if( version >= kCurrentPreferencesVersion ) return; - NSArray *libraries = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, + NSArray *libraries = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES); if( !libraries || [libraries count] == 0) return; NSString * preferences = [[libraries objectAtIndex:0] stringByAppendingPathComponent:@"Preferences"]; @@ -2448,7 +2507,7 @@ end: { if(! nib_info_loaded ) nib_info_loaded = [NSBundle loadNibNamed:@"MediaInfo" owner: NSApp]; - + [o_info initPanel]; } @@ -2500,12 +2559,10 @@ end: [o_msg_lock lock]; - if( [o_msg_arr count] + 2 > 400 ) + if( [o_msg_arr count] + 2 > 600 ) { - NSUInteger rid[] = { 0, 1 }; - /* FIXME: THIS METHOD WILL BE DEPRECATED */ - [o_msg_arr removeObjectsFromIndices: (NSUInteger *)&rid - numIndices: sizeof(rid)/sizeof(rid[0])]; + [o_msg_arr removeObjectAtIndex: 0]; + [o_msg_arr removeObjectAtIndex: 1]; } o_attr = [NSDictionary dictionaryWithObject: o_gray @@ -2531,7 +2588,7 @@ end: - (IBAction)saveDebugLog:(id)sender { NSOpenPanel * saveFolderPanel = [[NSSavePanel alloc] init]; - + [saveFolderPanel setCanChooseDirectories: NO]; [saveFolderPanel setCanChooseFiles: YES]; [saveFolderPanel setCanSelectHiddenExtension: NO]; @@ -2570,7 +2627,7 @@ end: o_rect.size.height = o_size_with_playlist.height; else o_rect.size.height = 500.; - + if( o_size_with_playlist.width >= [o_window contentMinSize].width ) o_rect.size.width = o_size_with_playlist.width; else @@ -2783,50 +2840,83 @@ end: @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( [event type] == NSSystemDefined && [event subtype] == 8 ) + if( b_active ) { - int keyCode = (([event data1] & 0xFFFF0000) >> 16); - int keyFlags = ([event data1] & 0x0000FFFF); - int keyState = (((keyFlags & 0xFF00) >> 8)) == 0xA; - int keyRepeat = (keyFlags & 0x1); + 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_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 ) + 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]; + } } - 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 ) + if( keyCode == NX_KEYTYPE_REWIND && !b_justJumped ) { - var_SetInteger( VLCIntf->p_libvlc, "key-action", ACTIONID_JUMP_BACKWARD_SHORT ); - b_justJumped = YES; - [self performSelector:@selector(resetJump) - withObject: NULL - afterDelay:0.25]; + 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]; } @@ -2835,4 +2925,14 @@ end: b_justJumped = NO; } +// when user selects the quit menu from dock it sends a terminate: +// but we need to send a stop: to properly exits libvlc. +// However, we are not able to change the action-method sent by this standard menu item. +// thus we override terminat: to send a stop: +// see [af97f24d528acab89969d6541d83f17ce1ecd580] that introduced the removal of setjmp() and longjmp() +- (void)terminate:(id)sender +{ + [self stop:sender]; +} + @end