/*****************************************************************************
* CoreInteraction.m: MacOS X interface module
*****************************************************************************
- * Copyright (C) 2011 Felix Paul Kühne
+ * Copyright (C) 2011-2012 Felix Paul Kühne
* $Id$
*
* Authors: Felix Paul Kühne <fkuehne -at- videolan -dot- org>
#import "CoreInteraction.h"
#import "intf.h"
#import "open.h"
+#import "playlist.h"
+#import <math.h>
#import <vlc_playlist.h>
#import <vlc_input.h>
#import <vlc_keys.h>
#import <vlc_osd.h>
#import <vlc_aout_intf.h>
+#import <vlc/vlc.h>
+#import <vlc_strings.h>
+#import <vlc_url.h>
@implementation VLCCoreInteraction
static VLCCoreInteraction *_o_sharedInstance = nil;
- (id)init
{
- if( _o_sharedInstance)
+ if( _o_sharedInstance )
{
[self dealloc];
return _o_sharedInstance;
else
{
_o_sharedInstance = [super init];
- b_lockAspectRatio = YES;
}
-
+
return _o_sharedInstance;
}
- (void)awakeFromNib
{
- [[NSNotificationCenter defaultCenter] addObserver: self
+ [[NSNotificationCenter defaultCenter] addObserver: self
selector: @selector(applicationWillFinishLaunching:)
name: NSApplicationWillFinishLaunchingNotification
object: nil];
{
playlist_t * p_playlist = pl_Get( VLCIntf );
bool empty;
-
+
PL_LOCK;
empty = playlist_IsEmpty( p_playlist );
PL_UNLOCK;
-
+
if( empty )
[[[VLCMain sharedInstance] open] openFileGeneric];
-
+
var_SetInteger( VLCIntf->p_libvlc, "key-action", ACTIONID_PLAY_PAUSE );
}
+- (void)pause
+{
+ var_SetInteger( VLCIntf->p_libvlc, "key-action", ACTIONID_PAUSE );
+}
+
- (void)stop
{
var_SetInteger( VLCIntf->p_libvlc, "key-action", ACTIONID_STOP );
var_SetInteger( VLCIntf->p_libvlc, "key-action", ACTIONID_RATE_NORMAL );
}
+- (void)toggleRecord
+{
+ intf_thread_t *p_intf = VLCIntf;
+ if( !p_intf )
+ return;
+
+ input_thread_t * p_input;
+ p_input = pl_CurrentInput( p_intf );
+ if( p_input )
+ {
+ var_ToggleBool( p_input, "record" );
+ vlc_object_release( p_input );
+ }
+}
+
- (void)setPlaybackRate:(int)i_value
{
playlist_t * p_playlist = pl_Get( VLCIntf );
- (int)playbackRate
{
- playlist_t * p_playlist = pl_Get( VLCIntf );
+ float f_rate;
- float rate = var_GetFloat( p_playlist, "rate" );
- double value = 17 * log( rate ) / log( 2. );
+ intf_thread_t *p_intf = VLCIntf;
+ if( !p_intf )
+ return 0;
+
+ input_thread_t * p_input;
+ p_input = pl_CurrentInput( p_intf );
+ if( p_input )
+ {
+ f_rate = var_GetFloat( p_input, "rate" );
+ vlc_object_release( p_input );
+ }
+ else
+ {
+ playlist_t * p_playlist = pl_Get( VLCIntf );
+ f_rate = var_GetFloat( p_playlist, "rate" );
+ }
+
+ double value = 17 * log( f_rate ) / log( 2. );
int returnValue = (int) ( ( value > 0 ) ? value + .5 : value - .5 );
if( returnValue < -34 )
var_SetInteger( VLCIntf->p_libvlc, "key-action", ACTIONID_NEXT );
}
+- (BOOL)isPlaying
+{
+ intf_thread_t *p_intf = VLCIntf;
+ if( !p_intf )
+ return NO;
+
+ input_thread_t * p_input = pl_CurrentInput( p_intf );
+ if( !p_input )
+ return NO;
+
+ input_state_e i_state = ERROR_S;
+ input_Control( p_input, INPUT_GET_STATE, &i_state );
+ vlc_object_release( p_input );
+
+ return ( ( i_state == OPENING_S ) || ( i_state == PLAYING_S ) );
+}
+
+- (int)currentTime
+{
+ input_thread_t * p_input = pl_CurrentInput( VLCIntf );
+ int64_t i_currentTime = -1;
+
+ if( !p_input )
+ return i_currentTime;
+
+ input_Control( p_input, INPUT_GET_TIME, &i_currentTime );
+ vlc_object_release( p_input );
+
+ return (int)( i_currentTime / 1000000 );
+}
+
+- (void)setCurrentTime:(int)i_value
+{
+ int64_t i64_value = (int64_t)i_value;
+ input_thread_t * p_input = pl_CurrentInput( VLCIntf );
+
+ if ( !p_input )
+ return;
+
+ input_Control( p_input, INPUT_SET_TIME, (int64_t)(i64_value * 1000000) );
+ vlc_object_release( p_input );
+}
+
+- (int)durationOfCurrentPlaylistItem
+{
+ intf_thread_t *p_intf = VLCIntf;
+ if( !p_intf )
+ return 0;
+
+ input_thread_t * p_input = pl_CurrentInput( p_intf );
+ int64_t i_duration = -1;
+ if( !p_input )
+ return i_duration;
+
+ input_Control( p_input, INPUT_GET_LENGTH, &i_duration );
+ vlc_object_release( p_input );
+
+ return (int)( i_duration / 1000000 );
+}
+
+- (NSURL*)URLOfCurrentPlaylistItem
+{
+ intf_thread_t *p_intf = VLCIntf;
+ if( !p_intf )
+ return nil;
+
+ input_thread_t *p_input = pl_CurrentInput( p_intf );
+ if( !p_input )
+ return nil;
+
+ input_item_t *p_item = input_GetItem( p_input );
+ if( !p_item )
+ {
+ vlc_object_release( p_input );
+ return nil;
+ }
+
+ char *psz_uri = input_item_GetURI( p_item );
+ if( !psz_uri )
+ {
+ vlc_object_release( p_input );
+ return nil;
+ }
+
+ NSURL *o_url;
+ o_url = [NSURL URLWithString:[NSString stringWithUTF8String:psz_uri]];
+ vlc_object_release( p_input );
+
+ return o_url;
+}
+
+- (NSString*)nameOfCurrentPlaylistItem
+{
+ intf_thread_t *p_intf = VLCIntf;
+ if( !p_intf )
+ return nil;
+
+ input_thread_t *p_input = pl_CurrentInput( p_intf );
+ if( !p_input )
+ return nil;
+
+ input_item_t *p_item = input_GetItem( p_input );
+ if( !p_item )
+ {
+ vlc_object_release( p_input );
+ return nil;
+ }
+
+ char *psz_uri = input_item_GetURI( p_item );
+ if( !psz_uri )
+ {
+ vlc_object_release( p_input );
+ return nil;
+ }
+
+ NSString *o_name;
+ char *format = var_InheritString( VLCIntf, "input-title-format" );
+ char *formated = str_format_meta( p_input, format );
+ free( format );
+ o_name = [NSString stringWithUTF8String:formated];
+ free( formated );
+
+ NSURL * o_url = [NSURL URLWithString: [NSString stringWithUTF8String: psz_uri]];
+ free( psz_uri );
+
+ if( [o_name isEqualToString:@""] )
+ {
+ if( [o_url isFileURL] )
+ o_name = [[NSFileManager defaultManager] displayNameAtPath: [o_url path]];
+ else
+ o_name = [o_url absoluteString];
+ }
+ vlc_object_release( p_input );
+ return o_name;
+}
+
- (void)forward
{
- var_SetInteger( VLCIntf->p_libvlc, "key-action", ACTIONID_JUMP_FORWARD_SHORT );
+ //LEGACY SUPPORT
+ [self forwardShort];
}
- (void)backward
+{
+ //LEGACY SUPPORT
+ [self backwardShort];
+}
+
+- (void)forwardExtraShort
+{
+ var_SetInteger( VLCIntf->p_libvlc, "key-action", ACTIONID_JUMP_FORWARD_EXTRASHORT );
+}
+
+- (void)backwardExtraShort
+{
+ var_SetInteger( VLCIntf->p_libvlc, "key-action", ACTIONID_JUMP_BACKWARD_EXTRASHORT );
+}
+
+- (void)forwardShort
+{
+ var_SetInteger( VLCIntf->p_libvlc, "key-action", ACTIONID_JUMP_FORWARD_SHORT );
+}
+
+- (void)backwardShort
{
var_SetInteger( VLCIntf->p_libvlc, "key-action", ACTIONID_JUMP_BACKWARD_SHORT );
}
+- (void)forwardMedium
+{
+ var_SetInteger( VLCIntf->p_libvlc, "key-action", ACTIONID_JUMP_FORWARD_MEDIUM );
+}
+
+- (void)backwardMedium
+{
+ var_SetInteger( VLCIntf->p_libvlc, "key-action", ACTIONID_JUMP_BACKWARD_MEDIUM );
+}
+
+- (void)forwardLong
+{
+ var_SetInteger( VLCIntf->p_libvlc, "key-action", ACTIONID_JUMP_FORWARD_LONG );
+}
+
+- (void)backwardLong
+{
+ var_SetInteger( VLCIntf->p_libvlc, "key-action", ACTIONID_JUMP_BACKWARD_LONG );
+}
+
- (void)shuffle
{
+ intf_thread_t *p_intf = VLCIntf;
+ if( !p_intf )
+ return;
+
vlc_value_t val;
- playlist_t * p_playlist = pl_Get( VLCIntf );
-
+ playlist_t * p_playlist = pl_Get( p_intf );
+ vout_thread_t *p_vout = getVout();
+
var_Get( p_playlist, "random", &val );
val.b_bool = !val.b_bool;
var_Set( p_playlist, "random", val );
if( val.b_bool )
{
- //vout_OSDMessage( VLCIntf, SPU_DEFAULT_CHANNEL, "%s", _( "Random On" ) );
+ if( p_vout )
+ {
+ vout_OSDMessage( p_vout, SPU_DEFAULT_CHANNEL, "%s", _( "Random On" ) );
+ vlc_object_release( p_vout );
+ }
config_PutInt( p_playlist, "random", 1 );
}
else
{
- //vout_OSDMessage( VLCIntf, SPU_DEFAULT_CHANNEL, "%s", _( "Random Off" ) );
+ if( p_vout )
+ {
+ vout_OSDMessage( p_vout, SPU_DEFAULT_CHANNEL, "%s", _( "Random Off" ) );
+ vlc_object_release( p_vout );
+ }
config_PutInt( p_playlist, "random", 0 );
}
}
- (void)repeatAll
{
- playlist_t * p_playlist = pl_Get( VLCIntf );
+ intf_thread_t *p_intf = VLCIntf;
+ if( !p_intf )
+ return;
+
+ playlist_t * p_playlist = pl_Get( p_intf );
var_SetBool( p_playlist, "repeat", NO );
var_SetBool( p_playlist, "loop", YES );
config_PutInt( p_playlist, "repeat", NO );
config_PutInt( p_playlist, "loop", YES );
- //vout_OSDMessage( VLCIntf, SPU_DEFAULT_CHANNEL, "%s", _( "Repeat All" ) );
+ vout_thread_t *p_vout = getVout();
+ if( p_vout )
+ {
+ vout_OSDMessage( p_vout, SPU_DEFAULT_CHANNEL, "%s", _( "Repeat All" ) );
+ vlc_object_release( p_vout );
+ }
}
- (void)repeatOne
{
- playlist_t * p_playlist = pl_Get( VLCIntf );
+ intf_thread_t *p_intf = VLCIntf;
+ if( !p_intf )
+ return;
+
+ playlist_t * p_playlist = pl_Get( p_intf );
var_SetBool( p_playlist, "repeat", YES );
var_SetBool( p_playlist, "loop", NO );
config_PutInt( p_playlist, "repeat", YES );
config_PutInt( p_playlist, "loop", NO );
- //vout_OSDMessage( VLCIntf, SPU_DEFAULT_CHANNEL, "%s", _( "Repeat One" ) );
+ vout_thread_t *p_vout = getVout();
+ if( p_vout )
+ {
+ vout_OSDMessage( p_vout, SPU_DEFAULT_CHANNEL, "%s", _( "Repeat One" ) );
+ vlc_object_release( p_vout );
+ }
}
- (void)repeatOff
{
- playlist_t * p_playlist = pl_Get( VLCIntf );
+ intf_thread_t *p_intf = VLCIntf;
+ if( !p_intf )
+ return;
+
+ playlist_t * p_playlist = pl_Get( p_intf );
var_SetBool( p_playlist, "repeat", NO );
var_SetBool( p_playlist, "loop", NO );
config_PutInt( p_playlist, "repeat", NO );
config_PutInt( p_playlist, "loop", NO );
- //vout_OSDMessage( VLCIntf, SPU_DEFAULT_CHANNEL, "%s", _( "Repeat Off" ) );
+ vout_thread_t *p_vout = getVout();
+ if( p_vout )
+ {
+ vout_OSDMessage( p_vout, SPU_DEFAULT_CHANNEL, "%s", _( "Repeat Off" ) );
+ vlc_object_release( p_vout );
+ }
}
-// CAVE: [o_main manageVolumeSlider]
-
- (void)volumeUp
{
- var_SetInteger( VLCIntf->p_libvlc, "key-action", ACTIONID_VOL_UP );
+ intf_thread_t *p_intf = VLCIntf;
+ if( !p_intf )
+ return;
+
+ aout_VolumeUp( pl_Get( p_intf ), 1, NULL );
}
- (void)volumeDown
{
- var_SetInteger( VLCIntf->p_libvlc, "key-action", ACTIONID_VOL_DOWN );
+ intf_thread_t *p_intf = VLCIntf;
+ if( !p_intf )
+ return;
+
+ aout_VolumeDown( pl_Get( p_intf ), 1, NULL );
}
- (void)mute
{
- var_SetInteger( VLCIntf->p_libvlc, "key-action", ACTIONID_VOL_MUTE );
+ intf_thread_t *p_intf = VLCIntf;
+ if( !p_intf )
+ return;
+
+ aout_MuteToggle( pl_Get( p_intf ) );
+}
+
+- (BOOL)isMuted
+{
+ intf_thread_t *p_intf = VLCIntf;
+ if( !p_intf )
+ return NO;
+
+ BOOL b_is_muted = NO;
+ b_is_muted = aout_MuteGet( pl_Get( p_intf ) ) > 0;
+
+ return b_is_muted;
+}
+
+- (int)volume
+{
+ intf_thread_t *p_intf = VLCIntf;
+ if( !p_intf )
+ return 0;
+
+ float volume = aout_VolumeGet( pl_Get( p_intf ) );
+
+ return lroundf(volume * AOUT_VOLUME_DEFAULT);
}
- (void)setVolume: (int)i_value
{
- intf_thread_t * p_intf = VLCIntf;
- playlist_t * p_playlist = pl_Get( VLCIntf );
- audio_volume_t i_volume = (audio_volume_t)i_value;
- int i_volume_step;
+ intf_thread_t *p_intf = VLCIntf;
+ if( !p_intf )
+ return;
+
+ aout_VolumeSet( pl_Get( p_intf ), i_value / (float)AOUT_VOLUME_DEFAULT );
+}
+
+#pragma mark -
+#pragma mark drag and drop support for VLCVoutView, VLBrushedMetalImageView and VLCThreePartDropView
+- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
+{
+ NSPasteboard *o_paste = [sender draggingPasteboard];
+ NSArray *o_types = [NSArray arrayWithObject: NSFilenamesPboardType];
+ NSString *o_desired_type = [o_paste availableTypeFromArray:o_types];
+ NSData *o_carried_data = [o_paste dataForType:o_desired_type];
+ BOOL b_autoplay = config_GetInt( VLCIntf, "macosx-autoplay" );
- i_volume_step = config_GetInt( VLCIntf->p_libvlc, "volume-step" );
- aout_VolumeSet( p_playlist, i_volume * i_volume_step );
+ if( o_carried_data )
+ {
+ if( [o_desired_type isEqualToString:NSFilenamesPboardType] )
+ {
+ NSArray *o_array = [NSArray array];
+ NSArray *o_values = [[o_paste propertyListForType: NSFilenamesPboardType] sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
+ NSUInteger count = [o_values count];
+
+ input_thread_t * p_input = pl_CurrentInput( VLCIntf );
+ BOOL b_returned = NO;
+
+ if( count == 1 && p_input )
+ {
+ b_returned = input_AddSubtitle( p_input, make_URI([[o_values objectAtIndex:0] UTF8String], NULL), true );
+ vlc_object_release( p_input );
+ if( !b_returned )
+ return YES;
+ }
+ else if( p_input )
+ vlc_object_release( p_input );
+
+ for( NSUInteger i = 0; i < count; i++)
+ {
+ NSDictionary *o_dic;
+ char *psz_uri = make_URI([[o_values objectAtIndex:i] UTF8String], NULL);
+ if( !psz_uri )
+ continue;
+
+ o_dic = [NSDictionary dictionaryWithObject:[NSString stringWithCString:psz_uri encoding:NSUTF8StringEncoding] forKey:@"ITEM_URL"];
+ free( psz_uri );
+
+ o_array = [o_array arrayByAddingObject: o_dic];
+ }
+ if( b_autoplay )
+ [[[VLCMain sharedInstance] playlist] appendArray: o_array atPos: -1 enqueue:NO];
+ else
+ [[[VLCMain sharedInstance] playlist] appendArray: o_array atPos: -1 enqueue:YES];
+
+ return YES;
+ }
+ }
+ return NO;
}
#pragma mark -
- (void)setAspectRatioLocked:(BOOL)b_value
{
- b_lockAspectRatio = b_value;
+ config_PutInt( VLCIntf, "macosx-lock-aspect-ratio", b_value );
}
- (BOOL)aspectRatioIsLocked
{
- return b_lockAspectRatio;
+ return config_GetInt( VLCIntf, "macosx-lock-aspect-ratio" );
}
- (void)toggleFullscreen
{
- input_thread_t * p_input = pl_CurrentInput( VLCIntf );
+ intf_thread_t *p_intf = VLCIntf;
+ if( !p_intf )
+ return;
- if( p_input != NULL )
- {
- playlist_t * p_playlist = pl_Get( VLCIntf );
- var_ToggleBool( p_playlist, "fullscreen" );
+ BOOL b_fs = var_ToggleBool( pl_Get( p_intf ), "fullscreen" );
- vlc_object_release( p_input );
+ vout_thread_t *p_vout = getVout();
+ if( p_vout )
+ {
+ var_SetBool( p_vout, "fullscreen", b_fs );
+ vlc_object_release( p_vout );
}
}
+
+#pragma mark -
+#pragma mark uncommon stuff
+
+- (BOOL)fixPreferences
+{
+ NSMutableString * o_workString;
+ NSRange returnedRange;
+ NSRange fullRange;
+ BOOL b_needsRestart = NO;
+
+ #define fixpref( pref ) \
+ o_workString = [[NSMutableString alloc] initWithFormat:@"%s", config_GetPsz( VLCIntf, pref )]; \
+ if ([o_workString length] > 0) \
+ { \
+ returnedRange = [o_workString rangeOfString:@"macosx" options: NSCaseInsensitiveSearch]; \
+ if (returnedRange.location != NSNotFound) \
+ { \
+ if ([o_workString isEqualToString:@"macosx"]) \
+ [o_workString setString:@""]; \
+ fullRange = NSMakeRange( 0, [o_workString length] ); \
+ [o_workString replaceOccurrencesOfString:@":macosx" withString:@"" options: NSCaseInsensitiveSearch range: fullRange]; \
+ fullRange = NSMakeRange( 0, [o_workString length] ); \
+ [o_workString replaceOccurrencesOfString:@"macosx:" withString:@"" options: NSCaseInsensitiveSearch range: fullRange]; \
+ \
+ config_PutPsz( VLCIntf, pref, [o_workString UTF8String] ); \
+ b_needsRestart = YES; \
+ } \
+ } \
+ [o_workString release]
+
+ fixpref( "control" );
+ fixpref( "extraintf" );
+ #undef fixpref
+
+ return b_needsRestart;
+}
+
@end