CoreInteraction.m 15.9 KB
Newer Older
1 2 3
/*****************************************************************************
 * CoreInteraction.m: MacOS X interface module
 *****************************************************************************
4
 * Copyright (C) 2011-2012 Felix Paul Kühne
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
 * $Id$
 *
 * Authors: Felix Paul Kühne <fkuehne -at- videolan -dot- org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

#import "CoreInteraction.h"
#import "intf.h"
#import "open.h"
27
#import "playlist.h"
28 29 30 31
#import <vlc_playlist.h>
#import <vlc_input.h>
#import <vlc_keys.h>
#import <vlc_osd.h>
32
#import <vlc_aout_intf.h>
33 34
#import <vlc/vlc.h>
#import <vlc_strings.h>
35
#import <vlc_url.h>
36 37 38 39 40 41 42 43 44 45 46 47 48 49

@implementation VLCCoreInteraction
static VLCCoreInteraction *_o_sharedInstance = nil;

+ (VLCCoreInteraction *)sharedInstance
{
    return _o_sharedInstance ? _o_sharedInstance : [[self alloc] init];
}

#pragma mark -
#pragma mark Initialization

- (id)init
{
50
    if( _o_sharedInstance )
51 52 53 54 55 56 57 58
    {
        [self dealloc];
        return _o_sharedInstance;
    }
    else
    {
        _o_sharedInstance = [super init];
    }
59

60 61 62 63 64 65 66 67 68 69 70
    return _o_sharedInstance;
}

- (void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver: self];
    [super dealloc];
}

- (void)awakeFromNib
{
71
    [[NSNotificationCenter defaultCenter] addObserver: self
72 73 74 75 76 77 78 79 80 81
                                             selector: @selector(applicationWillFinishLaunching:)
                                                 name: NSApplicationWillFinishLaunchingNotification
                                               object: nil];
}

#pragma mark -
#pragma mark Playback Controls

- (void)play
{
82
    playlist_t * p_playlist = pl_Get( VLCIntf );
83
    bool empty;
84

85 86 87
    PL_LOCK;
    empty = playlist_IsEmpty( p_playlist );
    PL_UNLOCK;
88

89 90
    if( empty )
        [[[VLCMain sharedInstance] open] openFileGeneric];
91

92
    var_SetInteger( VLCIntf->p_libvlc, "key-action", ACTIONID_PLAY_PAUSE );
93 94
}

95 96 97 98 99
- (void)pause
{
    var_SetInteger( VLCIntf->p_libvlc, "key-action", ACTIONID_PAUSE );
}

100 101
- (void)stop
{
102
    var_SetInteger( VLCIntf->p_libvlc, "key-action", ACTIONID_STOP );
103 104 105 106
}

- (void)faster
{
107
    var_SetInteger( VLCIntf->p_libvlc, "key-action", ACTIONID_FASTER );
108 109 110 111
}

- (void)slower
{
112
    var_SetInteger( VLCIntf->p_libvlc, "key-action", ACTIONID_SLOWER );
113 114 115 116
}

- (void)normalSpeed
{
117
    var_SetInteger( VLCIntf->p_libvlc, "key-action", ACTIONID_RATE_NORMAL );
118 119
}

120 121
- (void)toggleRecord
{
122
    intf_thread_t *p_intf = VLCIntf;
123
    if( !p_intf )
124
        return;
125

126
    input_thread_t * p_input;
127
    p_input = pl_CurrentInput( p_intf );
128 129 130 131 132 133 134
    if( p_input )
    {
        var_ToggleBool( p_input, "record" );
        vlc_object_release( p_input );
    }
}

135 136 137
- (void)setPlaybackRate:(int)i_value
{
    playlist_t * p_playlist = pl_Get( VLCIntf );
138

139 140 141 142 143 144 145 146 147
    double speed = pow( 2, (double)i_value / 17 );
    int rate = INPUT_RATE_DEFAULT / speed;
    if( i_currentPlaybackRate != rate )
        var_SetFloat( p_playlist, "rate", (float)INPUT_RATE_DEFAULT / (float)rate );
    i_currentPlaybackRate = rate;
}

- (int)playbackRate
{
148 149
    float f_rate;

150
    intf_thread_t *p_intf = VLCIntf;
151
    if( !p_intf )
152
        return 0;
153

154
    input_thread_t * p_input;
155
    p_input = pl_CurrentInput( p_intf );
156
    if( p_input )
157 158 159 160 161 162 163
    {
        f_rate = var_GetFloat( p_input, "rate" );
        vlc_object_release( p_input );
    }
    else
    {
        playlist_t * p_playlist = pl_Get( VLCIntf );
164
        f_rate = var_GetFloat( p_playlist, "rate" );
165
    }
166

167
    double value = 17 * log( f_rate ) / log( 2. );
168
    int returnValue = (int) ( ( value > 0 ) ? value + .5 : value - .5 );
169

170 171 172 173
    if( returnValue < -34 )
        returnValue = -34;
    else if( returnValue > 34 )
        returnValue = 34;
174

175 176 177 178
    i_currentPlaybackRate = returnValue;
    return returnValue;
}

179 180
- (void)previous
{
181
    var_SetInteger( VLCIntf->p_libvlc, "key-action", ACTIONID_PREV );
182 183 184 185
}

- (void)next
{
186
    var_SetInteger( VLCIntf->p_libvlc, "key-action", ACTIONID_NEXT );
187 188
}

189 190
- (BOOL)isPlaying
{
191
    intf_thread_t *p_intf = VLCIntf;
192
    if( !p_intf )
193
        return NO;
194 195

    input_thread_t * p_input = pl_CurrentInput( p_intf );
196 197
    if( !p_input )
        return NO;
198 199

    input_state_e i_state = ERROR_S;
200
    input_Control( p_input, INPUT_GET_STATE, &i_state );
201 202
    vlc_object_release( p_input );

203
    return ( ( i_state == OPENING_S ) || ( i_state == PLAYING_S ) );
204 205 206 207
}

- (int)currentTime
{
208 209 210
    input_thread_t * p_input = pl_CurrentInput( VLCIntf );
    int64_t i_currentTime = -1;

211 212
    if( !p_input )
        return i_currentTime;
213

214
    input_Control( p_input, INPUT_GET_TIME, &i_currentTime );
215 216 217
    vlc_object_release( p_input );

    return (int)( i_currentTime / 1000000 );
218 219 220 221
}

- (void)setCurrentTime:(int)i_value
{
222 223 224
    int64_t i64_value = (int64_t)i_value;
    input_thread_t * p_input = pl_CurrentInput( VLCIntf );

225 226
    if ( !p_input )
        return;
227

228
    input_Control( p_input, INPUT_SET_TIME, (int64_t)(i64_value * 1000000) );
229
    vlc_object_release( p_input );
230 231 232 233
}

- (int)durationOfCurrentPlaylistItem
{
234
    intf_thread_t *p_intf = VLCIntf;
235
    if( !p_intf )
236
        return 0;
237 238

    input_thread_t * p_input = pl_CurrentInput( p_intf );
239
    int64_t i_duration = -1;
240 241
    if( !p_input )
        return i_duration;
242

243
    input_Control( p_input, INPUT_GET_LENGTH, &i_duration );
244 245
    vlc_object_release( p_input );

246
    return (int)( i_duration / 1000000 );
247 248 249 250
}

- (NSURL*)URLOfCurrentPlaylistItem
{
251
    intf_thread_t *p_intf = VLCIntf;
252
    if( !p_intf )
253
        return nil;
254 255

    input_thread_t *p_input = pl_CurrentInput( p_intf );
256 257
    if( !p_input )
        return nil;
258 259

    input_item_t *p_item = input_GetItem( p_input );
260
    if( !p_item )
261 262 263 264
    {
        vlc_object_release( p_input );
        return nil;
    }
265 266

    char *psz_uri = input_item_GetURI( p_item );
267
    if( !psz_uri )
268 269 270 271
    {
        vlc_object_release( p_input );
        return nil;
    }
272 273 274

    NSURL *o_url;
    o_url = [NSURL URLWithString:[NSString stringWithUTF8String:psz_uri]];
275
    vlc_object_release( p_input );
276 277

    return o_url;
278 279 280 281
}

- (NSString*)nameOfCurrentPlaylistItem
{
282
    intf_thread_t *p_intf = VLCIntf;
283
    if( !p_intf )
284
        return nil;
285 286

    input_thread_t *p_input = pl_CurrentInput( p_intf );
287 288
    if( !p_input )
        return nil;
289 290

    input_item_t *p_item = input_GetItem( p_input );
291
    if( !p_item )
292 293 294 295
    {
        vlc_object_release( p_input );
        return nil;
    }
296 297

    char *psz_uri = input_item_GetURI( p_item );
298
    if( !psz_uri )
299 300 301 302
    {
        vlc_object_release( p_input );
        return nil;
    }
303 304 305 306 307 308 309 310 311 312 313

    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 );

314
    if( [o_name isEqualToString:@""] )
315
    {
316
        if( [o_url isFileURL] )
317 318 319 320
            o_name = [[NSFileManager defaultManager] displayNameAtPath: [o_url path]];
        else
            o_name = [o_url absoluteString];
    }
321
    vlc_object_release( p_input );
322
    return o_name;
323 324
}

325 326
- (void)forward
{
327 328
    //LEGACY SUPPORT
    [self forwardShort];
329 330 331 332
}

- (void)backward
{
333 334
    //LEGACY SUPPORT
    [self backwardShort];
335 336
}

337
- (void)forwardExtraShort
338
{
339
    var_SetInteger( VLCIntf->p_libvlc, "key-action", ACTIONID_JUMP_FORWARD_EXTRASHORT );
340
}
341

342 343
- (void)backwardExtraShort
{
344
    var_SetInteger( VLCIntf->p_libvlc, "key-action", ACTIONID_JUMP_BACKWARD_EXTRASHORT );
345 346 347 348
}

- (void)forwardShort
{
349
    var_SetInteger( VLCIntf->p_libvlc, "key-action", ACTIONID_JUMP_FORWARD_SHORT );
350 351 352 353
}

- (void)backwardShort
{
354
    var_SetInteger( VLCIntf->p_libvlc, "key-action", ACTIONID_JUMP_BACKWARD_SHORT );
355 356 357 358
}

- (void)forwardMedium
{
359
    var_SetInteger( VLCIntf->p_libvlc, "key-action", ACTIONID_JUMP_FORWARD_MEDIUM );
360 361 362 363
}

- (void)backwardMedium
{
364
    var_SetInteger( VLCIntf->p_libvlc, "key-action", ACTIONID_JUMP_BACKWARD_MEDIUM );
365 366 367 368
}

- (void)forwardLong
{
369
    var_SetInteger( VLCIntf->p_libvlc, "key-action", ACTIONID_JUMP_FORWARD_LONG );
370 371 372 373
}

- (void)backwardLong
{
374
    var_SetInteger( VLCIntf->p_libvlc, "key-action", ACTIONID_JUMP_BACKWARD_LONG );
375 376 377 378
}

- (void)shuffle
{
379
    intf_thread_t *p_intf = VLCIntf;
380
    if( !p_intf )
381
        return;
382

383
    vlc_value_t val;
384
    playlist_t * p_playlist = pl_Get( p_intf );
385 386 387 388 389 390 391
    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 )
    {
392
        if( p_vout )
393
        {
394 395
            vout_OSDMessage( p_vout, SPU_DEFAULT_CHANNEL, "%s", _( "Random On" ) );
            vlc_object_release( p_vout );
396
        }
397 398 399 400
        config_PutInt( p_playlist, "random", 1 );
    }
    else
    {
401
        if( p_vout )
402
        {
403 404
            vout_OSDMessage( p_vout, SPU_DEFAULT_CHANNEL, "%s", _( "Random Off" ) );
            vlc_object_release( p_vout );
405
        }
406 407
        config_PutInt( p_playlist, "random", 0 );
    }
408 409 410 411
}

- (void)repeatAll
{
412
    intf_thread_t *p_intf = VLCIntf;
413
    if( !p_intf )
414
        return;
415 416

    playlist_t * p_playlist = pl_Get( p_intf );
417 418 419 420 421 422 423

    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_thread_t *p_vout = getVout();
424
    if( p_vout )
425 426 427 428
    {
        vout_OSDMessage( p_vout, SPU_DEFAULT_CHANNEL, "%s", _( "Repeat All" ) );
        vlc_object_release( p_vout );
    }
429 430 431 432
}

- (void)repeatOne
{
433
    intf_thread_t *p_intf = VLCIntf;
434
    if( !p_intf )
435
        return;
436 437

    playlist_t * p_playlist = pl_Get( p_intf );
438 439 440 441 442 443 444

    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_thread_t *p_vout = getVout();
445
    if( p_vout )
446 447 448 449
    {
        vout_OSDMessage( p_vout, SPU_DEFAULT_CHANNEL, "%s", _( "Repeat One" ) );
        vlc_object_release( p_vout );
    }
450 451 452 453
}

- (void)repeatOff
{
454
    intf_thread_t *p_intf = VLCIntf;
455
    if( !p_intf )
456
        return;
457 458

    playlist_t * p_playlist = pl_Get( p_intf );
459 460 461 462 463 464 465

    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_thread_t *p_vout = getVout();
466
    if( p_vout )
467 468 469 470
    {
        vout_OSDMessage( p_vout, SPU_DEFAULT_CHANNEL, "%s", _( "Repeat Off" ) );
        vlc_object_release( p_vout );
    }
471 472 473 474
}

- (void)volumeUp
{
475
    intf_thread_t *p_intf = VLCIntf;
476
    if( !p_intf )
477
        return;
478 479

    aout_VolumeUp( pl_Get( p_intf ), 1, NULL );
480 481 482 483
}

- (void)volumeDown
{
484
    intf_thread_t *p_intf = VLCIntf;
485
    if( !p_intf )
486
        return;
487 488

    aout_VolumeDown( pl_Get( p_intf ), 1, NULL );
489 490 491 492
}

- (void)mute
{
493
    intf_thread_t *p_intf = VLCIntf;
494
    if( !p_intf )
495
        return;
496 497

    aout_ToggleMute( pl_Get( p_intf ), NULL );
498 499
}

500
- (BOOL)isMuted
501 502
{
    intf_thread_t *p_intf = VLCIntf;
503
    if( !p_intf )
504
        return NO;
505

506
    BOOL b_is_muted = NO;
507
    b_is_muted = aout_IsMuted( VLC_OBJECT(pl_Get( p_intf )) );
508 509

    return b_is_muted;
510 511 512
}

- (int)volume
513
{
514
    intf_thread_t *p_intf = VLCIntf;
515
    if( !p_intf )
516
        return 0;
517 518

    audio_volume_t i_volume = aout_VolumeGet( pl_Get( p_intf ) );
519 520

    return (int)i_volume;
521
}
522

523 524
- (void)setVolume: (int)i_value
{
525
    intf_thread_t *p_intf = VLCIntf;
526
    if( !p_intf )
527
        return;
528

529
    aout_VolumeSet( pl_Get( p_intf ), i_value );
530 531
}

532 533 534 535 536 537 538 539 540 541 542 543
#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" );

    if( o_carried_data )
    {
544
        if( [o_desired_type isEqualToString:NSFilenamesPboardType] )
545 546 547 548 549 550 551 552
        {
            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;

553
            if( count == 1 && p_input )
554 555 556
            {
                b_returned = input_AddSubtitle( p_input, make_URI([[o_values objectAtIndex:0] UTF8String], NULL), true );
                vlc_object_release( p_input );
557
                if( !b_returned )
558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585
                    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;
}

586 587 588 589 590
#pragma mark -
#pragma mark video output stuff

- (void)setAspectRatioLocked:(BOOL)b_value
{
591
    config_PutInt( VLCIntf, "macosx-lock-aspect-ratio", b_value );
592 593 594 595
}

- (BOOL)aspectRatioIsLocked
{
596
    return config_GetInt( VLCIntf, "macosx-lock-aspect-ratio" );
597 598 599 600
}

- (void)toggleFullscreen
{
601
    intf_thread_t *p_intf = VLCIntf;
602
    if( !p_intf )
603
        return;
604

605 606 607 608 609 610 611 612
    BOOL b_fs = var_ToggleBool( pl_Get( p_intf ), "fullscreen" );

    vout_thread_t *p_vout = getVout();
    if( p_vout )
    {
        var_SetBool( p_vout, "fullscreen", b_fs );
        vlc_object_release( p_vout );
    }
613
}
614

615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651
#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;
}

652
@end