/*****************************************************************************
* intf.m: MacOS X interface module
*****************************************************************************
- * Copyright (C) 2002-2011 the VideoLAN team
+ * Copyright (C) 2002-2012 VLC authors and VideoLAN
* $Id$
*
* Authors: Jon Lech Johansen <jon-vl@nanocrew.net>
/*****************************************************************************
* Preamble
*****************************************************************************/
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
#include <stdlib.h> /* malloc(), free() */
#include <sys/param.h> /* for MAXPATHLEN */
#include <string.h>
#include <vlc_dialog.h>
#include <vlc_url.h>
#include <vlc_modules.h>
+#include <vlc_plugin.h>
#include <vlc_aout_intf.h>
#include <vlc_vout_window.h>
#include <unistd.h> /* execl() */
+#import "CompatibilityFixes.h"
#import "intf.h"
#import "MainMenu.h"
-#import "MainWindow.h"
-#import "vout.h"
+#import "VideoView.h"
#import "prefs.h"
#import "playlist.h"
#import "playlistinfo.h"
#import "wizard.h"
#import "bookmarks.h"
#import "coredialogs.h"
-#import "embeddedwindow.h"
#import "AppleRemote.h"
#import "eyetv.h"
#import "simple_prefs.h"
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 * );
{
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 ) );
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->pf_run = Run;
- p_intf->b_should_run_on_first_thread = true;
+ vlc_Subscribe( &p_intf->p_sys->sub, MsgCallback, NULL );
+
+ Run( p_intf );
[o_pool release];
return VLC_SUCCESS;
{
/* TODO */
if( i_query == VOUT_WINDOW_SET_STATE )
- NSLog( @"WindowControl:VOUT_WINDOW_SET_STATE" );
+ msg_Dbg( p_wnd, "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" );
+ {
+ NSAutoreleasePool *o_pool = [[NSAutoreleasePool alloc] init];
+ // we already have our playlist "fullscreen" callback, do not repeat the same call here
+ //[[VLCMain sharedInstance] performSelectorOnMainThread:@selector(fullscreenChanged) withObject: nil waitUntilDone: NO];
+ [o_pool release];
+ }
else
- NSLog( @"WindowControl: unknown query" );
+ msg_Dbg( p_wnd, "WindowControl: unknown query" );
return VLC_SUCCESS;
}
{
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];
}
* Run: main loop
*****************************************************************************/
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 )
{
- sigset_t set;
-
- /* 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 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];
[[VLCMain sharedInstance] applicationWillTerminate:nil];
[o_appLock release];
[o_pool release];
+
+ raise(SIGTERM);
}
#pragma mark -
* ready to be displayed. We store everything in a NSArray in our Cocoa part
* 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();
+ 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;
+ }
NSAutoreleasePool *o_pool = [[NSAutoreleasePool alloc] init];
- [[VLCMain sharedInstance] processReceivedlibvlcMessage: item];
+ [[VLCMain sharedInstance] processReceivedlibvlcMessage: item ofType: type withStr: str];
[o_pool release];
vlc_restorecancel( canc );
+ free( str );
}
static int InputEvent( vlc_object_t *p_this, const char *psz_var,
NSAutoreleasePool *o_pool = [[NSAutoreleasePool alloc] init];
switch (new_val.i_int) {
case INPUT_EVENT_STATE:
- [[VLCMain sharedInstance] playbackStatusUpdated];
+ [[VLCMain sharedInstance] performSelectorOnMainThread:@selector(playbackStatusUpdated) withObject: nil waitUntilDone:NO];
break;
case INPUT_EVENT_RATE:
- [[VLCMainMenu sharedInstance] performSelectorOnMainThread:@selector(updatePlaybackRate) withObject: nil waitUntilDone:NO];
+ [[[VLCMain sharedInstance] mainMenu] performSelectorOnMainThread:@selector(updatePlaybackRate) withObject: nil waitUntilDone:NO];
break;
case INPUT_EVENT_POSITION:
- [[VLCMain sharedInstance] updatePlaybackPosition];
+ [[VLCMain sharedInstance] performSelectorOnMainThread:@selector(updatePlaybackPosition) withObject: nil waitUntilDone:NO];
break;
case INPUT_EVENT_TITLE:
case INPUT_EVENT_CHAPTER:
+ [[VLCMain sharedInstance] performSelectorOnMainThread:@selector(updateMainMenu) withObject: nil waitUntilDone:NO];
break;
case INPUT_EVENT_CACHE:
- [[VLCMain sharedInstance] updateMainWindow];
+ [[VLCMain sharedInstance] performSelectorOnMainThread:@selector(updateMainWindow) withObject: nil waitUntilDone: NO];
break;
case INPUT_EVENT_STATISTICS:
[[[VLCMain sharedInstance] info] performSelectorOnMainThread:@selector(updateStatistics) withObject: nil waitUntilDone: NO];
case INPUT_EVENT_ES:
break;
case INPUT_EVENT_TELETEXT:
- NSLog( @"teletext" );
break;
case INPUT_EVENT_AOUT:
break;
break;
case INPUT_EVENT_ITEM_META:
case INPUT_EVENT_ITEM_INFO:
- [[VLCMain sharedInstance] updateName];
- [[VLCMain sharedInstance] updateInfoandMetaPanel];
+ [[VLCMain sharedInstance] performSelectorOnMainThread:@selector(updateMainMenu) withObject: nil waitUntilDone:NO];
+ [[VLCMain sharedInstance] performSelectorOnMainThread:@selector(updateName) withObject: nil waitUntilDone:NO];
+ [[VLCMain sharedInstance] performSelectorOnMainThread:@selector(updateInfoandMetaPanel) withObject: nil waitUntilDone:NO];
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] performSelectorOnMainThread:@selector(updateMainMenu) withObject: nil waitUntilDone:NO];
break;
case INPUT_EVENT_ITEM_EPG:
break;
break;
case INPUT_EVENT_ITEM_NAME:
- [[VLCMain sharedInstance] updateName];
- [[VLCMain sharedInstance] playlistUpdated];
+ [[VLCMain sharedInstance] performSelectorOnMainThread:@selector(updateName) withObject: nil waitUntilDone:NO];
+ [[VLCMain sharedInstance] performSelectorOnMainThread:@selector(playlistUpdated) withObject: nil waitUntilDone:NO];
break;
case INPUT_EVENT_AUDIO_DELAY:
case INPUT_EVENT_SUBTITLE_DELAY:
- [[VLCMain sharedInstance] updateDelays];
+ [[VLCMain sharedInstance] performSelectorOnMainThread:@selector(updateDelays) withObject:nil waitUntilDone:NO];
break;
case INPUT_EVENT_DEAD:
- [[VLCMain sharedInstance] updateName];
- [[VLCMain sharedInstance] updatePlaybackPosition];
+ [[VLCMain sharedInstance] performSelectorOnMainThread:@selector(updateName) withObject: nil waitUntilDone:NO];
+ [[VLCMain sharedInstance] performSelectorOnMainThread:@selector(updatePlaybackPosition) withObject:nil waitUntilDone:NO];
break;
case INPUT_EVENT_ABORT:
- //NSLog( @"input stopped by user" );
+ [[VLCMain sharedInstance] performSelectorOnMainThread:@selector(updateName) withObject: nil waitUntilDone:NO];
+ [[VLCMain sharedInstance] performSelectorOnMainThread:@selector(updatePlaybackPosition) withObject:nil waitUntilDone:NO];
break;
default:
vlc_value_t oldval, vlc_value_t new_val, void *param )
{
NSAutoreleasePool * o_pool = [[NSAutoreleasePool alloc] init];
- [[VLCMain sharedInstance] playbackModeUpdated];
+ [[VLCMain sharedInstance] performSelectorOnMainThread:@selector(playbackModeUpdated) withObject:nil waitUntilDone:NO];
[o_pool release];
return VLC_SUCCESS;
intf_thread_t * p_intf = VLCIntf;
if( p_intf && p_intf->p_sys )
{
-// [[[VLCMain sharedInstance] fspanel] makeKeyAndOrderFront: nil];
+ playlist_t * p_playlist = pl_Get( p_intf );
+ BOOL b_fullscreen = var_GetBool( p_playlist, "fullscreen" );
+ if( strcmp(psz_variable, "intf-toggle-fscontrol") || b_fullscreen )
+ {
+ [[VLCMain sharedInstance] performSelectorOnMainThread:@selector(showFullscreenController) withObject:nil waitUntilDone:NO];
+ }
+ else
+ {
+ [[VLCMain sharedInstance] performSelectorOnMainThread:@selector(showMainWindow) withObject:nil waitUntilDone:NO];
+ }
}
return VLC_SUCCESS;
}
if (p_intf)
{
NSAutoreleasePool *o_pool = [[NSAutoreleasePool alloc] init];
- [[VLCMain sharedInstance] fullscreenChanged];
+ [[VLCMain sharedInstance] performSelectorOnMainThread:@selector(fullscreenChanged) withObject:nil waitUntilDone:NO];
[o_pool release];
}
return VLC_SUCCESS;
void destroyProgressPanel (void *priv)
{
NSAutoreleasePool *o_pool = [[NSAutoreleasePool alloc] init];
- [[[VLCMain sharedInstance] coreDialogProvider] destroyProgressPanel];
+ [[[VLCMain sharedInstance] coreDialogProvider] performSelectorOnMainThread:@selector(destroyProgressPanel) withObject:nil waitUntilDone:NO];
[o_pool release];
}
_o_sharedMainInstance = [super init];
p_intf = NULL;
+ p_current_input = NULL;
o_msg_lock = [[NSLock alloc] init];
o_msg_arr = [[NSMutableArray arrayWithCapacity: 600] retain];
object: @"VLCEyeTVSupport"
userInfo: NULL
deliverImmediately: YES];
+
+ NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
+ NSDictionary *appDefaults = [NSDictionary dictionaryWithObject:@"NO" forKey:@"LiveUpdateTheMessagesPanel"];
+ [defaults registerDefaults:appDefaults];
+
return _o_sharedMainInstance;
}
val.b_bool = false;
- var_AddCallback( p_playlist, "fullscreen", FullscreenChanged, self);
+ var_AddCallback(p_playlist, "fullscreen", FullscreenChanged, self);
+ var_AddCallback( p_intf->p_libvlc, "intf-toggle-fscontrol", ShowController, self);
var_AddCallback( p_intf->p_libvlc, "intf-show", ShowController, self);
-// var_AddCallback(p_playlist, "item-change", PLItemChanged, 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, "volume", VolumeUpdated, self);
var_AddCallback(p_playlist, "mute", VolumeUpdated, self);
+ if (OSX_LION)
+ {
+ if ([NSApp currentSystemPresentationOptions] & NSApplicationPresentationFullScreen)
+ var_SetBool( p_playlist, "fullscreen", YES );
+ }
+
/* load our Core Dialogs nib */
nib_coredialogs_loaded = [NSBundle loadNibNamed:@"CoreDialogs" owner: NSApp];
var_AddCallback( p_intf, "dialog-progress-bar", DialogCallback, self );
dialog_Register( p_intf );
- [self playbackModeUpdated];
-
/* init Apple Remote support */
o_remote = [[AppleRemote alloc] init];
[o_remote setClickCountEnabledButtons: kRemoteButtonPlay];
[o_remote setDelegate: _o_sharedMainInstance];
+ [o_msgs_refresh_btn setImage: [NSImage imageNamed: NSImageNameRefreshTemplate]];
+
/* yeah, we are done */
+ b_nativeFullscreenMode = NO;
+#ifdef MAC_OS_X_VERSION_10_7
+ if( OSX_LION )
+ b_nativeFullscreenMode = config_GetInt( p_intf, "macosx-nativefullscreenmode" );
+#endif
+
+ /* recover stored audio device, if set
+ * in case it was unplugged in the meantime, auhal will fall back on the default */
+ int i_value = config_GetInt( p_intf, "macosx-audio-device" );
+ if (i_value > 0)
+ var_SetInteger( pl_Get( VLCIntf ), "audio-device", i_value );
+
+ if (config_GetInt( VLCIntf, "macosx-icon-change"))
+ {
+ /* After day 354 of the year, the usual VLC cone is replaced by another cone
+ * wearing a Father Xmas hat.
+ * Note: this icon doesn't represent an endorsement of The Coca-Cola Company.
+ */
+ NSCalendar *gregorian =
+ [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
+ NSUInteger dayOfYear = [gregorian ordinalityOfUnit:NSDayCalendarUnit inUnit:NSYearCalendarUnit forDate:[NSDate date]];
+ [gregorian release];
+
+ if (dayOfYear >= 354)
+ [[VLCApplication sharedApplication] setApplicationIconImage: [NSImage imageNamed:@"vlc-xmas"]];
+ }
+
nib_main_loaded = TRUE;
}
{
if( !p_intf ) return;
+ [self updateCurrentlyUsedHotkeys];
+
+ [o_mainwindow updateWindow];
+ [o_mainwindow updateTimeSlider];
+ [o_mainwindow updateVolumeSlider];
+ [o_mainwindow makeKeyAndOrderFront: self];
+
/* init media key support */
b_mediaKeySupport = config_GetInt( VLCIntf, "macosx-mediakeys" );
if( b_mediaKeySupport )
[self _removeOldPreferences];
- [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];
- [NSThread detachNewThreadSelector:@selector(lookForCrashLog) toTarget:self withObject:nil];
+ [[VLCMain sharedInstance] performSelectorOnMainThread:@selector(lookForCrashLog) withObject:nil waitUntilDone:NO];
+
+ /* we will need this, so let's load it here so the interface appears to be more responsive */
+ nib_open_loaded = [NSBundle loadNibNamed:@"Open" owner: NSApp];
+ [self initStrings];
}
- (void)initStrings
- (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;
+ /* don't allow a double termination call. If the user has
+ * already invoked the quit then simply return this time. */
+ static bool f_appExit = false;
+ bool isTerminating;
[o_appLock lock];
- isTerminating = (f_appExit++ > 0 ? 1 : 0);
+ isTerminating = f_appExit;
+ f_appExit = true;
[o_appLock unlock];
if (isTerminating)
return;
- msg_Dbg( p_intf, "Terminating" );
+ if (notification == nil)
+ [[NSNotificationCenter defaultCenter] postNotificationName: NSApplicationWillTerminateNotification object: nil];
- /* Make sure the intf object is getting killed */
- vlc_object_kill( p_intf );
- p_playlist = pl_Get( p_intf );
+ playlist_t * p_playlist = pl_Get( p_intf );
+ int returnedValue = 0;
+
+ /* always exit fullscreen on quit, otherwise we get ugly artifacts on the next launch */
+ if (b_nativeFullscreenMode)
+ {
+ [o_mainwindow toggleFullScreen: self];
+ [NSApp setPresentationOptions:(NSApplicationPresentationDefault)];
+ }
+
+ /* Save some interface state in configuration, at module quit */
+ config_PutInt( p_intf, "random", var_GetBool( p_playlist, "random" ) );
+ config_PutInt( p_intf, "loop", var_GetBool( p_playlist, "loop" ) );
+ config_PutInt( p_intf, "repeat", var_GetBool( p_playlist, "repeat" ) );
+
+ msg_Dbg( p_intf, "Terminating" );
/* unsubscribe from the interactive dialogues */
dialog_Unregister( p_intf );
var_DelCallback(p_playlist, "loop", PlaybackModeUpdated, self);
var_DelCallback(p_playlist, "volume", VolumeUpdated, self);
var_DelCallback(p_playlist, "mute", VolumeUpdated, self);
+ var_DelCallback(p_playlist, "fullscreen", FullscreenChanged, self);
+ var_DelCallback(p_intf->p_libvlc, "intf-toggle-fscontrol", ShowController, self);
+ var_DelCallback(p_intf->p_libvlc, "intf-show", ShowController, self);
+
+ if( p_current_input )
+ {
+ var_DelCallback( p_current_input, "intf-event", InputEvent, [VLCMain sharedInstance] );
+ vlc_object_release( p_current_input );
+ p_current_input = NULL;
+ }
/* remove global observer watching for vout device changes correctly */
[[NSNotificationCenter defaultCenter] removeObserver: self];
[o_embedded_list release];
[o_coredialogs release];
[o_eyetv release];
- [o_mainwindow release];
/* unsubscribe from libvlc's debug messages */
- msg_Unsubscribe( p_intf->p_sys->p_sub );
+ vlc_Unsubscribe( &p_intf->p_sys->sub );
[o_msg_arr removeAllObjects];
[o_msg_arr release];
+ o_msg_arr = NULL;
[o_msg_lock release];
[o_mainmenu releaseRepresentedObjects:[NSApp mainMenu]];
[o_mainmenu release];
- /* Kill the playlist, so that it doesn't accept new request
- * such as the play request from vlc.c (we are a blocking interface). */
- vlc_object_kill( p_playlist );
libvlc_Quit( p_intf->p_libvlc );
+ [o_mainwindow release];
+ o_mainwindow = NULL;
+
[self setIntf:nil];
}
{
[NSApp activateIgnoringOtherApps:YES];
[o_remote stopListening: self];
- var_SetInteger( p_intf->p_libvlc, "key-action", ACTIONID_STOP );
+ [[VLCCoreInteraction sharedInstance] stop];
}
#pragma mark -
int keyRepeat = (keyFlags & 0x1);
if( keyCode == NX_KEYTYPE_PLAY && keyState == 0 )
- var_SetInteger( p_intf->p_libvlc, "key-action", ACTIONID_PLAY_PAUSE );
+ [[VLCCoreInteraction sharedInstance] play];
- if( keyCode == NX_KEYTYPE_FAST && !b_mediakeyJustJumped )
+ if( (keyCode == NX_KEYTYPE_FAST || keyCode == NX_KEYTYPE_NEXT) && !b_mediakeyJustJumped )
{
if( keyState == 0 && keyRepeat == 0 )
- var_SetInteger( p_intf->p_libvlc, "key-action", ACTIONID_NEXT );
+ [[VLCCoreInteraction sharedInstance] next];
else if( keyRepeat == 1 )
{
- var_SetInteger( p_intf->p_libvlc, "key-action", ACTIONID_JUMP_FORWARD_SHORT );
+ [[VLCCoreInteraction sharedInstance] forwardShort];
b_mediakeyJustJumped = YES;
[self performSelector:@selector(resetMediaKeyJump)
withObject: NULL
}
}
- if( keyCode == NX_KEYTYPE_REWIND && !b_mediakeyJustJumped )
+ if( (keyCode == NX_KEYTYPE_REWIND || keyCode == NX_KEYTYPE_PREVIOUS) && !b_mediakeyJustJumped )
{
if( keyState == 0 && keyRepeat == 0 )
- var_SetInteger( p_intf->p_libvlc, "key-action", ACTIONID_PREV );
+ [[VLCCoreInteraction sharedInstance] previous];
else if( keyRepeat == 1 )
{
- var_SetInteger( p_intf->p_libvlc, "key-action", ACTIONID_JUMP_BACKWARD_SHORT );
+ [[VLCCoreInteraction sharedInstance] backwardShort];
b_mediakeyJustJumped = YES;
[self performSelector:@selector(resetMediaKeyJump)
withObject: NULL
- (void)applicationDidBecomeActive:(NSNotification *)aNotification
{
if( !p_intf ) return;
- if( config_GetInt( p_intf, "macosx-appleremote" ) == YES )
- [o_remote startListening: self];
+ if( config_GetInt( p_intf, "macosx-appleremote" ) == YES )
+ [o_remote startListening: self];
}
- (void)applicationDidResignActive:(NSNotification *)aNotification
{
/* Triggered when the computer goes to sleep */
- (void)computerWillSleep: (NSNotification *)notification
{
- 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 )
- var_SetInteger( p_intf->p_libvlc, "key-action", ACTIONID_PLAY_PAUSE );
- vlc_object_release( p_input );
- }
+ [[VLCCoreInteraction sharedInstance] pause];
}
#pragma mark -
if( !psz_uri )
return( FALSE );
+ input_thread_t * p_input = pl_CurrentInput( VLCIntf );
+ BOOL b_returned = NO;
+
+ if (p_input)
+ {
+ b_returned = input_AddSubtitle( p_input, psz_uri, true );
+ vlc_object_release( p_input );
+ if(!b_returned)
+ {
+ free( psz_uri );
+ return YES;
+ }
+ }
+ else if( p_input )
+ vlc_object_release( p_input );
+
NSDictionary *o_dic = [NSDictionary dictionaryWithObject:[NSString stringWithCString:psz_uri encoding:NSUTF8StringEncoding] forKey:@"ITEM_URL"];
free( psz_uri );
if( psz != NULL )
{
- o_str = [NSString stringWithCString: psz encoding:NSUTF8StringEncoding];
+ o_str = [NSString stringWithCString: _(psz) encoding:NSUTF8StringEncoding];
if( o_str == NULL )
{
{ NSCarriageReturnCharacter, KEY_ENTER },
{ NSEnterCharacter, KEY_ENTER },
{ NSBackspaceCharacter, KEY_BACKSPACE },
+ { NSDeleteCharacter, KEY_DELETE },
{0,0}
};
- (NSString *)VLCKeyToString:(NSString *)theString
{
if (![theString isEqualToString:@""]) {
+ if ([theString characterAtIndex:([theString length] - 1)] != 0x2b)
+ theString = [theString stringByReplacingOccurrencesOfString:@"+" withString:@""];
+ else
+ {
+ theString = [theString stringByReplacingOccurrencesOfString:@"+" withString:@""];
+ theString = [NSString stringWithFormat:@"%@+", theString];
+ }
+ if ([theString characterAtIndex:([theString length] - 1)] != 0x2d)
+ theString = [theString stringByReplacingOccurrencesOfString:@"-" withString:@""];
+ else
+ {
+ theString = [theString stringByReplacingOccurrencesOfString:@"-" withString:@""];
+ theString = [NSString stringWithFormat:@"%@-", theString];
+ }
theString = [theString stringByReplacingOccurrencesOfString:@"Command" withString:@""];
theString = [theString stringByReplacingOccurrencesOfString:@"Alt" withString:@""];
theString = [theString stringByReplacingOccurrencesOfString:@"Shift" withString:@""];
theString = [theString stringByReplacingOccurrencesOfString:@"Ctrl" withString:@""];
- theString = [theString stringByReplacingOccurrencesOfString:@"+" withString:@""];
- theString = [theString stringByReplacingOccurrencesOfString:@"-" withString:@""];
}
+ if ([theString length] > 1)
+ {
+ if([theString rangeOfString:@"Up"].location != NSNotFound)
+ return [NSString stringWithFormat:@"%C", NSUpArrowFunctionKey];
+ else if([theString rangeOfString:@"Down"].location != NSNotFound)
+ return [NSString stringWithFormat:@"%C", NSDownArrowFunctionKey];
+ else if([theString rangeOfString:@"Right"].location != NSNotFound)
+ return [NSString stringWithFormat:@"%C", NSRightArrowFunctionKey];
+ else if([theString rangeOfString:@"Left"].location != NSNotFound)
+ return [NSString stringWithFormat:@"%C", NSLeftArrowFunctionKey];
+ else if([theString rangeOfString:@"Enter"].location != NSNotFound)
+ return [NSString stringWithFormat:@"%C", NSEnterCharacter]; // we treat NSCarriageReturnCharacter as aquivalent
+ else if([theString rangeOfString:@"Insert"].location != NSNotFound)
+ return [NSString stringWithFormat:@"%C", NSInsertFunctionKey];
+ else if([theString rangeOfString:@"Home"].location != NSNotFound)
+ return [NSString stringWithFormat:@"%C", NSHomeFunctionKey];
+ else if([theString rangeOfString:@"End"].location != NSNotFound)
+ return [NSString stringWithFormat:@"%C", NSEndFunctionKey];
+ else if([theString rangeOfString:@"Pageup"].location != NSNotFound)
+ return [NSString stringWithFormat:@"%C", NSPageUpFunctionKey];
+ else if([theString rangeOfString:@"Pagedown"].location != NSNotFound)
+ return [NSString stringWithFormat:@"%C", NSPageDownFunctionKey];
+ else if([theString rangeOfString:@"Menu"].location != NSNotFound)
+ return [NSString stringWithFormat:@"%C", NSMenuFunctionKey];
+ else if([theString rangeOfString:@"Tab"].location != NSNotFound)
+ return [NSString stringWithFormat:@"%C", NSTabCharacter];
+ else if([theString rangeOfString:@"Backspace"].location != NSNotFound)
+ return [NSString stringWithFormat:@"%C", NSBackspaceCharacter];
+ else if([theString rangeOfString:@"Delete"].location != NSNotFound)
+ return [NSString stringWithFormat:@"%C", NSDeleteCharacter];
+ else if([theString rangeOfString:@"F12"].location != NSNotFound)
+ return [NSString stringWithFormat:@"%C", NSF12FunctionKey];
+ else if([theString rangeOfString:@"F11"].location != NSNotFound)
+ return [NSString stringWithFormat:@"%C", NSF11FunctionKey];
+ else if([theString rangeOfString:@"F10"].location != NSNotFound)
+ return [NSString stringWithFormat:@"%C", NSF10FunctionKey];
+ else if([theString rangeOfString:@"F9"].location != NSNotFound)
+ return [NSString stringWithFormat:@"%C", NSF9FunctionKey];
+ else if([theString rangeOfString:@"F8"].location != NSNotFound)
+ return [NSString stringWithFormat:@"%C", NSF8FunctionKey];
+ else if([theString rangeOfString:@"F7"].location != NSNotFound)
+ return [NSString stringWithFormat:@"%C", NSF7FunctionKey];
+ else if([theString rangeOfString:@"F6"].location != NSNotFound)
+ return [NSString stringWithFormat:@"%C", NSF6FunctionKey];
+ else if([theString rangeOfString:@"F5"].location != NSNotFound)
+ return [NSString stringWithFormat:@"%C", NSF5FunctionKey];
+ else if([theString rangeOfString:@"F4"].location != NSNotFound)
+ return [NSString stringWithFormat:@"%C", NSF4FunctionKey];
+ else if([theString rangeOfString:@"F3"].location != NSNotFound)
+ return [NSString stringWithFormat:@"%C", NSF3FunctionKey];
+ else if([theString rangeOfString:@"F2"].location != NSNotFound)
+ return [NSString stringWithFormat:@"%C", NSF2FunctionKey];
+ else if([theString rangeOfString:@"F1"].location != NSNotFound)
+ return [NSString stringWithFormat:@"%C", NSF1FunctionKey];
+ /* note that we don't support esc here, since it is reserved for leaving fullscreen */
+ }
+
return theString;
}
unsigned int i_pressed_modifiers = 0;
const struct hotkey *p_hotkeys;
int i;
- NSMutableString *tempString = [[[NSMutableString alloc] init] autorelease];
- NSMutableString *tempStringPlus = [[[NSMutableString alloc] init] autorelease];
+ NSMutableString *tempString = [[NSMutableString alloc] init];
+ NSMutableString *tempStringPlus = [[NSMutableString alloc] init];
val.i_int = 0;
p_hotkeys = p_intf->p_libvlc->p_hotkeys;
key = [[o_event charactersIgnoringModifiers] characterAtIndex: 0];
+ /* handle Lion's default key combo for fullscreen-toggle in addition to our own hotkeys */
+ if( key == 'f' && i_pressed_modifiers & NSControlKeyMask && i_pressed_modifiers & NSCommandKeyMask )
+ {
+ [[VLCCoreInteraction sharedInstance] toggleFullscreen];
+ [tempString release];
+ [tempStringPlus release];
+ return YES;
+ }
+
switch( key )
{
case NSDeleteCharacter:
case NSLeftArrowFunctionKey:
case NSEnterCharacter:
case NSCarriageReturnCharacter:
+ [tempString release];
+ [tempStringPlus release];
return NO;
}
+ if( key == 0x0020 ) // space key
+ {
+ [[VLCCoreInteraction sharedInstance] play];
+ [tempString release];
+ [tempStringPlus release];
+ return YES;
+ }
+
val.i_int |= CocoaKeyToVLC( key );
if( [o_usedHotkeys indexOfObject: tempString] != NSNotFound || [o_usedHotkeys indexOfObject: tempStringPlus] != NSNotFound )
{
var_SetInteger( p_intf->p_libvlc, "key-pressed", val.i_int );
+ [tempString release];
+ [tempStringPlus release];
return YES;
}
+ [tempString release];
+ [tempStringPlus release];
return NO;
}
}
}
module_config_free (p_config);
- module_release (p_main);
- o_usedHotkeys = [[NSArray alloc] initWithArray: o_usedHotkeys copyItems: YES];
+ o_usedHotkeys = [[NSArray alloc] initWithArray: o_tempArray copyItems: YES];
+ [o_tempArray release];
}
#pragma mark -
#pragma mark Interface updaters
- (void)fullscreenChanged
{
- if(! [o_mainwindow isFullscreen] )
- [o_mainwindow performSelectorOnMainThread:@selector(enterFullscreen) withObject:nil waitUntilDone:NO];
+ playlist_t * p_playlist = pl_Get( VLCIntf );
+ BOOL b_fullscreen = var_GetBool( p_playlist, "fullscreen" );
+
+ if (b_nativeFullscreenMode)
+ {
+ // this is called twice in certain situations, so only toogle if we really need to
+ if( ( b_fullscreen && !([NSApp currentSystemPresentationOptions] & NSApplicationPresentationFullScreen) ) ||
+ ( !b_fullscreen && ([NSApp currentSystemPresentationOptions] & NSApplicationPresentationFullScreen) ) )
+ [o_mainwindow toggleFullScreen: self];
+
+ if(b_fullscreen)
+ [NSApp setPresentationOptions:(NSApplicationPresentationFullScreen | NSApplicationPresentationAutoHideDock | NSApplicationPresentationAutoHideMenuBar)];
+ else
+ [NSApp setPresentationOptions:(NSApplicationPresentationDefault)];
+ }
else
- [o_mainwindow performSelectorOnMainThread:@selector(leaveFullscreen) withObject:nil waitUntilDone:NO];
+ {
+ if( b_fullscreen )
+ {
+ input_thread_t * p_input = pl_CurrentInput( VLCIntf );
+ if( p_input != NULL && [self activeVideoPlayback] )
+ {
+ [o_mainwindow performSelectorOnMainThread:@selector(enterFullscreen) withObject:nil waitUntilDone:NO];
+ }
+ if (p_input)
+ vlc_object_release( p_input );
+ }
+ else
+ {
+ // leaving fullscreen is always allowed
+ [o_mainwindow performSelectorOnMainThread:@selector(leaveFullscreen) withObject:nil waitUntilDone:NO];
+ }
+ }
}
- (void)PlaylistItemChanged
{
- input_thread_t * p_input;
+ if( p_current_input && ( p_current_input->b_dead || !vlc_object_alive( p_current_input ) ))
+ {
+ var_DelCallback( p_current_input, "intf-event", InputEvent, [VLCMain sharedInstance] );
+ vlc_object_release( p_current_input );
+ p_current_input = NULL;
- p_input = playlist_CurrentInput( pl_Get(VLCIntf) );
- if( p_input && !( p_input->b_dead || !vlc_object_alive(p_input) ) )
+ [o_mainmenu setRateControlsEnabled: NO];
+ }
+ else if( !p_current_input )
{
- var_AddCallback( p_input, "intf-event", InputEvent, [VLCMain sharedInstance] );
- [o_mainmenu setRateControlsEnabled: YES];
- vlc_object_release( p_input );
+ // object is hold here and released then it is dead
+ p_current_input = playlist_CurrentInput( pl_Get( VLCIntf ));
+ if( p_current_input )
+ {
+ var_AddCallback( p_current_input, "intf-event", InputEvent, [VLCMain sharedInstance] );
+ [self playbackStatusUpdated];
+ [o_mainmenu setRateControlsEnabled: YES];
+ if ( [self activeVideoPlayback] && [[o_mainwindow videoView] isHidden] )
+ [o_mainwindow performSelectorOnMainThread:@selector(togglePlaylist:) withObject: nil waitUntilDone:NO];
+ }
}
- else
- [o_mainmenu setRateControlsEnabled: NO];
[o_playlist updateRowSelection];
[o_mainwindow updateWindow];
+ [self updateDelays];
+ [self updateMainMenu];
+}
+
+- (void)updateMainMenu
+{
[o_mainmenu setupMenus];
[o_mainmenu updatePlaybackRate];
}
[o_mainwindow updateWindow];
}
+- (void)showMainWindow
+{
+ [o_mainwindow performSelectorOnMainThread:@selector(makeKeyAndOrderFront:) withObject:nil waitUntilDone:NO];
+}
+
- (void)showFullscreenController
{
- [o_mainwindow showFullscreenController];
+ [o_mainwindow performSelectorOnMainThread:@selector(showFullscreenController) withObject:nil waitUntilDone:NO];
}
- (void)updateDelays
p_input = pl_CurrentInput( p_intf );
if( p_input )
{
- if( var_GetInteger( p_input, "state" ) == PLAYING_S )
+ if( var_GetInteger( p_input, "state" ) == PLAYING_S && [self activeVideoPlayback] )
UpdateSystemActivity( UsrActivity );
vlc_object_release( p_input );
}
[self playbackStatusUpdated];
[o_playlist playlistUpdated];
[o_mainwindow updateWindow];
+ [o_mainwindow updateName];
+}
+
+- (void)updateRecordState: (BOOL)b_value
+{
+ [o_mainmenu updateRecordState:b_value];
}
- (void)updateInfoandMetaPanel
}
vlc_object_release( p_input );
}
+
+ [[VLCMain sharedInstance] performSelectorOnMainThread:@selector(updateMainWindow) withObject: nil waitUntilDone: NO];
+ [self performSelectorOnMainThread:@selector(sendDistributedNotificationWithUpdatedPlaybackStatus) withObject: nil waitUntilDone: NO];
+}
+
+- (void)sendDistributedNotificationWithUpdatedPlaybackStatus
+{
+ [[NSDistributedNotificationCenter defaultCenter] postNotificationName:@"VLCPlayerStateDidChange"
+ object:nil
+ userInfo:nil
+ deliverImmediately:YES];
}
- (void)playbackModeUpdated
return o_mainmenu;
}
+- (id)mainWindow
+{
+ return o_mainwindow;
+}
+
- (id)controls
{
if( o_controls )
- (id)getVideoViewAtPositionX: (int *)pi_x Y: (int *)pi_y withWidth: (unsigned int*)pi_width andHeight: (unsigned int*)pi_height
{
- id videoView = [o_mainwindow videoView];
+ id videoView = [o_mainwindow setupVideoView];
NSRect videoRect = [videoView frame];
int i_x = (int)videoRect.origin.x;
int i_y = (int)videoRect.origin.y;
unsigned int i_width = (int)videoRect.size.width;
unsigned int i_height = (int)videoRect.size.height;
- pi_x = (int *)i_x;
- pi_y = (int *)i_y;
- pi_width = (unsigned int*)i_width;
- pi_height = (unsigned int*)i_height;
+ pi_x = &i_x;
+ pi_y = &i_y;
+ pi_width = &i_width;
+ pi_height = &i_height;
msg_Dbg( VLCIntf, "returning videoview with x=%i, y=%i, width=%i, height=%i", i_x, i_y, i_width, i_height );
return videoView;
}
- (id)appleRemoteController
{
- return o_remote;
+ return o_remote;
}
- (void)setActiveVideoPlayback:(BOOL)b_value
{
b_active_videoplayback = b_value;
- [o_mainwindow setVideoplayEnabled];
- [o_mainwindow togglePlaylist:nil];
+ if( o_mainwindow )
+ {
+ [o_mainwindow performSelectorOnMainThread:@selector(setVideoplayEnabled) withObject:nil waitUntilDone:YES];
+ [o_mainwindow performSelectorOnMainThread:@selector(togglePlaylist:) withObject:nil waitUntilDone:NO];
+ }
}
- (BOOL)activeVideoPlayback
- (void)_removeOldPreferences
{
static NSString * kVLCPreferencesVersion = @"VLCPreferencesVersion";
- static const int kCurrentPreferencesVersion = 1;
+ static const int kCurrentPreferencesVersion = 2;
int version = [[NSUserDefaults standardUserDefaults] integerForKey:kVLCPreferencesVersion];
if( version >= kCurrentPreferencesVersion ) return;
- NSArray *libraries = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory,
- NSUserDomainMask, YES);
- if( !libraries || [libraries count] == 0) return;
- NSString * preferences = [[libraries objectAtIndex:0] stringByAppendingPathComponent:@"Preferences"];
-
- /* File not found, don't attempt anything */
- if(![[NSFileManager defaultManager] fileExistsAtPath:[preferences stringByAppendingPathComponent:@"VLC"]] &&
- ![[NSFileManager defaultManager] fileExistsAtPath:[preferences stringByAppendingPathComponent:@"org.videolan.vlc.plist"]] )
+ if( version == 1 )
{
[[NSUserDefaults standardUserDefaults] setInteger:kCurrentPreferencesVersion forKey:kVLCPreferencesVersion];
- return;
- }
+ [[NSUserDefaults standardUserDefaults] synchronize];
- int res = NSRunInformationalAlertPanel(_NS("Remove old preferences?"),
- _NS("We just found an older version of VLC's preferences files."),
- _NS("Move To Trash and Relaunch VLC"), _NS("Ignore"), nil, nil);
- if( res != NSOKButton )
- {
- [[NSUserDefaults standardUserDefaults] setInteger:kCurrentPreferencesVersion forKey:kVLCPreferencesVersion];
- return;
+ if (![[VLCCoreInteraction sharedInstance] fixPreferences])
+ return;
+ else
+ config_SaveConfigFile( VLCIntf ); // we need to do manually, since we won't quit libvlc cleanly
}
+ else
+ {
+ NSArray *libraries = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory,
+ NSUserDomainMask, YES);
+ if( !libraries || [libraries count] == 0) return;
+ NSString * preferences = [[libraries objectAtIndex:0] stringByAppendingPathComponent:@"Preferences"];
+
+ /* File not found, don't attempt anything */
+ if(![[NSFileManager defaultManager] fileExistsAtPath:[preferences stringByAppendingPathComponent:@"org.videolan.vlc"]] &&
+ ![[NSFileManager defaultManager] fileExistsAtPath:[preferences stringByAppendingPathComponent:@"org.videolan.vlc.plist"]] )
+ {
+ [[NSUserDefaults standardUserDefaults] setInteger:kCurrentPreferencesVersion forKey:kVLCPreferencesVersion];
+ return;
+ }
+
+ int res = NSRunInformationalAlertPanel(_NS("Remove old preferences?"),
+ _NS("We just found an older version of VLC's preferences files."),
+ _NS("Move To Trash and Relaunch VLC"), _NS("Ignore"), nil, nil);
+ if( res != NSOKButton )
+ {
+ [[NSUserDefaults standardUserDefaults] setInteger:kCurrentPreferencesVersion forKey:kVLCPreferencesVersion];
+ return;
+ }
- NSArray * ourPreferences = [NSArray arrayWithObjects:@"org.videolan.vlc.plist", @"VLC", nil];
+ NSArray * ourPreferences = [NSArray arrayWithObjects:@"org.videolan.vlc.plist", @"VLC", @"org.videolan.vlc", nil];
- /* Move the file to trash so that user can find them later */
- [[NSWorkspace sharedWorkspace] performFileOperation:NSWorkspaceRecycleOperation source:preferences destination:nil files:ourPreferences tag:0];
+ /* Move the file to trash so that user can find them later */
+ [[NSWorkspace sharedWorkspace] performFileOperation:NSWorkspaceRecycleOperation source:preferences destination:nil files:ourPreferences tag:0];
- /* really reset the defaults from now on */
- [NSUserDefaults resetStandardUserDefaults];
+ /* really reset the defaults from now on */
+ [NSUserDefaults resetStandardUserDefaults];
- [[NSUserDefaults standardUserDefaults] setInteger:kCurrentPreferencesVersion forKey:kVLCPreferencesVersion];
- [[NSUserDefaults standardUserDefaults] synchronize];
+ [[NSUserDefaults standardUserDefaults] setInteger:kCurrentPreferencesVersion forKey:kVLCPreferencesVersion];
+ [[NSUserDefaults standardUserDefaults] synchronize];
+ }
/* Relaunch now */
const char * path = [[[NSBundle mainBundle] executablePath] UTF8String];
#pragma mark -
#pragma mark Errors, warnings and messages
+- (IBAction)updateMessagesPanel:(id)sender
+{
+ [self windowDidBecomeKey:nil];
+}
+
- (IBAction)showMessagesPanel:(id)sender
{
[o_msgs_panel makeKeyAndOrderFront: sender];
- (void)windowDidBecomeKey:(NSNotification *)o_notification
{
- if( [o_notification object] == o_msgs_panel )
- [self updateMessageDisplay];
+ [o_msgs_table reloadData];
+ [o_msgs_table scrollRowToVisible: [o_msg_arr count] - 1];
}
-- (void)updateMessageDisplay
+- (NSInteger)numberOfRowsInTableView:(NSTableView *)aTableView
{
- if( [o_msgs_panel isVisible] && b_msg_arr_changed )
- {
- id o_msg;
- NSEnumerator * o_enum;
-
- [o_messages setString: @""];
-
- [o_msg_lock lock];
-
- o_enum = [o_msg_arr objectEnumerator];
-
- while( ( o_msg = [o_enum nextObject] ) != nil )
- {
- [o_messages insertText: o_msg];
- }
-
- b_msg_arr_changed = NO;
- [o_msg_lock unlock];
- }
+ if (aTableView == o_msgs_table)
+ return [o_msg_arr count];
+ return 0;
}
-- (void)processReceivedlibvlcMessage:(const msg_item_t *)item
+- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex
{
- NSColor *o_white = [NSColor whiteColor];
- NSColor *o_red = [NSColor redColor];
- NSColor *o_yellow = [NSColor yellowColor];
- NSColor *o_gray = [NSColor grayColor];
+ NSMutableAttributedString *result = NULL;
- NSColor * pp_color[4] = { o_white, o_red, o_yellow, o_gray };
- static const char * ppsz_type[4] = { ": ", " error: ", " warning: ", " debug: " };
+ [o_msg_lock lock];
+ if( rowIndex < [o_msg_arr count] )
+ result = [o_msg_arr objectAtIndex: rowIndex];
+ [o_msg_lock unlock];
- NSDictionary *o_attr;
- NSAttributedString *o_msg_color;
+ if( result != NULL )
+ return result;
+ else
+ return @"";
+}
- int i_type = item->i_type;
+- (void)processReceivedlibvlcMessage:(const msg_item_t *) item ofType: (int)i_type withStr: (char *)str
+{
+ if (o_msg_arr)
+ {
+ NSColor *o_white = [NSColor whiteColor];
+ NSColor *o_red = [NSColor redColor];
+ NSColor *o_yellow = [NSColor yellowColor];
+ NSColor *o_gray = [NSColor grayColor];
+ NSString * firstString, * secondString;
- [o_msg_lock lock];
+ NSColor * pp_color[4] = { o_white, o_red, o_yellow, o_gray };
+ static const char * ppsz_type[4] = { ": ", " error: ", " warning: ", " debug: " };
- if( [o_msg_arr count] + 2 > 600 )
- {
- [o_msg_arr removeObjectAtIndex: 0];
- [o_msg_arr removeObjectAtIndex: 1];
- }
+ NSDictionary *o_attr;
+ NSMutableAttributedString *o_msg_color;
- 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_msg_lock lock];
- o_attr = [NSDictionary dictionaryWithObject: pp_color[i_type] forKey: NSForegroundColorAttributeName];
- o_msg_color = [[NSAttributedString alloc] initWithString: [NSString stringWithFormat: @"%s\n", item->psz_msg] attributes: o_attr];
- [o_msg_arr addObject: [o_msg_color autorelease]];
+ if( [o_msg_arr count] + 2 > 600 )
+ {
+ [o_msg_arr removeObjectAtIndex: 0];
+ [o_msg_arr removeObjectAtIndex: 1];
+ }
+ firstString = [NSString stringWithFormat:@"%s%s", item->psz_module, ppsz_type[i_type]];
+ secondString = [NSString stringWithFormat:@"%@%s\n", firstString, str];
- b_msg_arr_changed = YES;
- [o_msg_lock unlock];
+ o_attr = [NSDictionary dictionaryWithObject: pp_color[i_type] forKey: NSForegroundColorAttributeName];
+ o_msg_color = [[NSMutableAttributedString alloc] initWithString: secondString attributes: o_attr];
+ o_attr = [NSDictionary dictionaryWithObject: pp_color[3] forKey: NSForegroundColorAttributeName];
+ [o_msg_color setAttributes: o_attr range: NSMakeRange( 0, [firstString length] )];
+ [o_msg_arr addObject: [o_msg_color autorelease]];
- [self updateMessageDisplay];
+ b_msg_arr_changed = YES;
+ [o_msg_lock unlock];
+ }
}
- (IBAction)saveDebugLog:(id)sender
BOOL b_returned;
if( returnCode == NSOKButton )
{
- b_returned = [o_messages writeRTFDToFile: [[sheet URL] path] atomically: YES];
+ NSUInteger count = [o_msg_arr count];
+ NSMutableAttributedString * string = [[NSMutableAttributedString alloc] init];
+ for (NSUInteger i = 0; i < count; i++)
+ {
+ [string appendAttributedString: [o_msg_arr objectAtIndex: i]];
+ }
+ b_returned = [[string RTFDFileWrapperFromRange:NSMakeRange( 0, [string length] ) documentAttributes:[NSDictionary dictionaryWithObject: NSRTFDTextDocumentType forKey: NSDocumentTypeDocumentAttribute]] writeToFile:[[sheet URL] path] atomically:YES updateFilenames:NO];
+ [string release];
+
if(! b_returned )
msg_Warn( p_intf, "Error while saving the debug log" );
}
- (void)coreChangedMediaKeySupportSetting: (NSNotification *)o_notification
{
b_mediaKeySupport = config_GetInt( VLCIntf, "macosx-mediakeys" );
- if (b_mediaKeySupport) {
+ if (b_mediaKeySupport)
+ {
if (!o_mediaKeyController)
o_mediaKeyController = [[SPMediaKeyTap alloc] initWithDelegate:self];
[o_mediaKeyController startWatchingMediaKeys];
}
else if (!b_mediaKeySupport && o_mediaKeyController)
- {
- int returnedValue = NSRunInformationalAlertPanel(_NS("Relaunch required"),
- _NS("To make sure that VLC no longer listens to your media key events, it needs to be restarted."),
- _NS("Relaunch VLC"), _NS("Ignore"), nil, nil);
- if( returnedValue == NSOKButton )
- {
- /* Relaunch now */
- const char * path = [[[NSBundle mainBundle] executablePath] UTF8String];
-
- /* For some reason we need to fork(), not just execl(), which reports a ENOTSUP then. */
- if(fork() != 0)
- {
- exit(0);
- return;
- }
- execl(path, path, NULL);
- }
- }
+ [o_mediaKeyController stopWatchingMediaKeys];
}
@end
// 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:
+// thus we override terminate: to send a stop:
// see [af97f24d528acab89969d6541d83f17ce1ecd580] that introduced the removal of setjmp() and longjmp()
- (void)terminate:(id)sender
{