intf.m 56.2 KB
Newer Older
1
/*****************************************************************************
2
 * intf.m: MacOS X interface module
3
 *****************************************************************************
4
 * Copyright (C) 2002-2005 the VideoLAN team
5
 * $Id$
6
7
8
 *
 * Authors: Jon Lech Johansen <jon-vl@nanocrew.net>
 *          Christophe Massiot <massiot@via.ecp.fr>
9
 *          Derk-Jan Hartman <hartman at videolan.org>
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
 *
 * 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., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
 *****************************************************************************/

/*****************************************************************************
 * Preamble
 *****************************************************************************/
#include <stdlib.h>                                      /* malloc(), free() */
#include <sys/param.h>                                    /* for MAXPATHLEN */
#include <string.h>
32
#include <vlc_keys.h>
33
34
35

#include "intf.h"
#include "vout.h"
36
#include "prefs.h"
37
#include "playlist.h"
38
#include "controls.h"
39
#include "about.h"
40
#include "open.h"
41
#include "wizard.h"
42
43
44
45

/*****************************************************************************
 * Local prototypes.
 *****************************************************************************/
46
static void Run ( intf_thread_t *p_intf );
47
48
49
50
51

/*****************************************************************************
 * OpenIntf: initialize interface
 *****************************************************************************/
int E_(OpenIntf) ( vlc_object_t *p_this )
Jérome Decoodt's avatar
Jérome Decoodt committed
52
{
53
54
55
56
57
58
59
60
61
    intf_thread_t *p_intf = (intf_thread_t*) p_this;

    p_intf->p_sys = malloc( sizeof( intf_sys_t ) );
    if( p_intf->p_sys == NULL )
    {
        return( 1 );
    }

    memset( p_intf->p_sys, 0, sizeof( *p_intf->p_sys ) );
Jérome Decoodt's avatar
Jérome Decoodt committed
62

63
    p_intf->p_sys->o_pool = [[NSAutoreleasePool alloc] init];
hartman's avatar
hartman committed
64

65
66
67
68
69
    /* Put Cocoa into multithread mode as soon as possible.
     * http://developer.apple.com/techpubs/macosx/Cocoa/
     * TasksAndConcepts/ProgrammingTopics/Multithreading/index.html
     * This thread does absolutely nothing at all. */
    [NSThread detachNewThreadSelector:@selector(self) toTarget:[NSString string] withObject:nil];
Jérome Decoodt's avatar
Jérome Decoodt committed
70

71
72
    p_intf->p_sys->o_sendport = [[NSPort port] retain];
    p_intf->p_sys->p_sub = msg_Subscribe( p_intf );
hartman's avatar
hartman committed
73
    p_intf->b_play = VLC_TRUE;
74
75
76
77
78
79
80
81
82
83
84
    p_intf->pf_run = Run;

    return( 0 );
}

/*****************************************************************************
 * CloseIntf: destroy interface
 *****************************************************************************/
void E_(CloseIntf) ( vlc_object_t *p_this )
{
    intf_thread_t *p_intf = (intf_thread_t*) p_this;
Jérome Decoodt's avatar
Jérome Decoodt committed
85

86
    msg_Unsubscribe( p_intf, p_intf->p_sys->p_sub );
Jérome Decoodt's avatar
Jérome Decoodt committed
87

88
89
    [p_intf->p_sys->o_sendport release];
    [p_intf->p_sys->o_pool release];
Jérome Decoodt's avatar
Jérome Decoodt committed
90

91
92
93
94
95
96
97
98
    free( p_intf->p_sys );
}

/*****************************************************************************
 * Run: main loop
 *****************************************************************************/
static void Run( intf_thread_t *p_intf )
{
99
100
101
102
    /* Do it again - for some unknown reason, vlc_thread_create() often
     * fails to go to real-time priority with the first launched thread
     * (???) --Meuuh */
    vlc_thread_set_priority( p_intf, VLC_THREAD_PRIORITY_LOW );
hartman's avatar
-    
hartman committed
103
    [[VLCMain sharedInstance] setIntf: p_intf];
hartman's avatar
hartman committed
104
    [NSBundle loadNibNamed: @"MainMenu" owner: NSApp];
hartman's avatar
-    
hartman committed
105
106
    [NSApp run];
    [[VLCMain sharedInstance] terminate];
107
108
}

109
int ExecuteOnMainThread( id target, SEL sel, void * p_arg )
110
{
111
    int i_ret = 0;
112

hartman's avatar
-    
hartman committed
113
    //NSAutoreleasePool * o_pool = [[NSAutoreleasePool alloc] init];
114
115
116

    if( [target respondsToSelector: @selector(performSelectorOnMainThread:
                                             withObject:waitUntilDone:)] )
117
    {
118
119
        [target performSelectorOnMainThread: sel
                withObject: [NSValue valueWithPointer: p_arg]
hartman's avatar
-    
hartman committed
120
                waitUntilDone: NO];
121
    }
Jérome Decoodt's avatar
Jérome Decoodt committed
122
    else if( NSApp != nil && [[VLCMain sharedInstance] respondsToSelector: @selector(getIntf)] )
123
124
125
126
127
128
129
130
131
132
133
134
135
    {
        NSValue * o_v1;
        NSValue * o_v2;
        NSArray * o_array;
        NSPort * o_recv_port;
        NSInvocation * o_inv;
        NSPortMessage * o_msg;
        intf_thread_t * p_intf;
        NSConditionLock * o_lock;
        NSMethodSignature * o_sig;

        id * val[] = { &o_lock, &o_v2 };

hartman's avatar
hartman committed
136
        p_intf = (intf_thread_t *)VLCIntf;
137
138

        o_recv_port = [[NSPort port] retain];
Jérome Decoodt's avatar
Jérome Decoodt committed
139
        o_v1 = [NSValue valueWithPointer: val];
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
        o_v2 = [NSValue valueWithPointer: p_arg];

        o_sig = [target methodSignatureForSelector: sel];
        o_inv = [NSInvocation invocationWithMethodSignature: o_sig];
        [o_inv setArgument: &o_v1 atIndex: 2];
        [o_inv setTarget: target];
        [o_inv setSelector: sel];

        o_array = [NSArray arrayWithObject:
            [NSData dataWithBytes: &o_inv length: sizeof(o_inv)]];
        o_msg = [[NSPortMessage alloc]
            initWithSendPort: p_intf->p_sys->o_sendport
            receivePort: o_recv_port components: o_array];

        o_lock = [[NSConditionLock alloc] initWithCondition: 0];
        [o_msg sendBeforeDate: [NSDate distantPast]];
        [o_lock lockWhenCondition: 1];
        [o_lock unlock];
        [o_lock release];

        [o_msg release];
        [o_recv_port release];
Jérome Decoodt's avatar
Jérome Decoodt committed
162
    }
163
164
165
166
167
    else
    {
        i_ret = 1;
    }

hartman's avatar
-    
hartman committed
168
    //[o_pool release];
169

170
    return( i_ret );
171
172
}

173
174
175
176
177
178
179
/*****************************************************************************
 * playlistChanged: Callback triggered by the intf-change playlist
 * variable, to let the intf update the playlist.
 *****************************************************************************/
int PlaylistChanged( vlc_object_t *p_this, const char *psz_variable,
                     vlc_value_t old_val, vlc_value_t new_val, void *param )
{
hartman's avatar
hartman committed
180
    intf_thread_t * p_intf = VLCIntf;
hartman's avatar
hartman committed
181
182
    p_intf->p_sys->b_playlist_update = TRUE;
    p_intf->p_sys->b_intf_update = TRUE;
183
    p_intf->p_sys->b_playmode_update = TRUE;
184
185
186
    return VLC_SUCCESS;
}

bigben's avatar
bigben committed
187
188
189
190
191
192
193
194
195
196
197
198
199
/*****************************************************************************
 * FullscreenChanged: Callback triggered by the fullscreen-change playlist
 * variable, to let the intf update the controller.
 *****************************************************************************/
int FullscreenChanged( vlc_object_t *p_this, const char *psz_variable,
                     vlc_value_t old_val, vlc_value_t new_val, void *param )
{
    intf_thread_t * p_intf = VLCIntf;
    p_intf->p_sys->b_fullscreen_update = TRUE;
    return VLC_SUCCESS;
}


200
201
202
static struct
{
    unichar i_nskey;
203
    unsigned int i_vlckey;
Jérome Decoodt's avatar
Jérome Decoodt committed
204
} nskeys_to_vlckeys[] =
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
{
    { NSUpArrowFunctionKey, KEY_UP },
    { NSDownArrowFunctionKey, KEY_DOWN },
    { NSLeftArrowFunctionKey, KEY_LEFT },
    { NSRightArrowFunctionKey, KEY_RIGHT },
    { NSF1FunctionKey, KEY_F1 },
    { NSF2FunctionKey, KEY_F2 },
    { NSF3FunctionKey, KEY_F3 },
    { NSF4FunctionKey, KEY_F4 },
    { NSF5FunctionKey, KEY_F5 },
    { NSF6FunctionKey, KEY_F6 },
    { NSF7FunctionKey, KEY_F7 },
    { NSF8FunctionKey, KEY_F8 },
    { NSF9FunctionKey, KEY_F9 },
    { NSF10FunctionKey, KEY_F10 },
    { NSF11FunctionKey, KEY_F11 },
    { NSF12FunctionKey, KEY_F12 },
    { NSHomeFunctionKey, KEY_HOME },
    { NSEndFunctionKey, KEY_END },
    { NSPageUpFunctionKey, KEY_PAGEUP },
    { NSPageDownFunctionKey, KEY_PAGEDOWN },
    { NSTabCharacter, KEY_TAB },
    { NSCarriageReturnCharacter, KEY_ENTER },
    { NSEnterCharacter, KEY_ENTER },
    { NSBackspaceCharacter, KEY_BACKSPACE },
    { (unichar) ' ', KEY_SPACE },
    { (unichar) 0x1b, KEY_ESC },
    {0,0}
};

235
unichar VLCKeyToCocoa( unsigned int i_key )
236
{
237
    unsigned int i;
Jérome Decoodt's avatar
Jérome Decoodt committed
238

239
240
241
242
243
244
245
246
247
248
249
250
251
    for( i = 0; nskeys_to_vlckeys[i].i_vlckey != 0; i++ )
    {
        if( nskeys_to_vlckeys[i].i_vlckey == (i_key & ~KEY_MODIFIER) )
        {
            return nskeys_to_vlckeys[i].i_nskey;
        }
    }
    return (unichar)(i_key & ~KEY_MODIFIER);
}

unsigned int CocoaKeyToVLC( unichar i_key )
{
    unsigned int i;
Jérome Decoodt's avatar
Jérome Decoodt committed
252

253
254
255
256
257
258
259
    for( i = 0; nskeys_to_vlckeys[i].i_nskey != 0; i++ )
    {
        if( nskeys_to_vlckeys[i].i_nskey == i_key )
        {
            return nskeys_to_vlckeys[i].i_vlckey;
        }
    }
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
    return (unsigned int)i_key;
}

unsigned int VLCModifiersToCocoa( unsigned int i_key )
{
    unsigned int new = 0;
    if( i_key & KEY_MODIFIER_COMMAND )
        new |= NSCommandKeyMask;
    if( i_key & KEY_MODIFIER_ALT )
        new |= NSAlternateKeyMask;
    if( i_key & KEY_MODIFIER_SHIFT )
        new |= NSShiftKeyMask;
    if( i_key & KEY_MODIFIER_CTRL )
        new |= NSControlKeyMask;
    return new;
275
276
}

277
/*****************************************************************************
Jérome Decoodt's avatar
Jérome Decoodt committed
278
 * VLCMain implementation
279
280
281
 *****************************************************************************/
@implementation VLCMain

hartman's avatar
hartman committed
282
283
284
285
286
287
288
static VLCMain *_o_sharedMainInstance = nil;

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

Jérome Decoodt's avatar
Jérome Decoodt committed
289
- (id)init
hartman's avatar
hartman committed
290
{
291
    if( _o_sharedMainInstance) {
hartman's avatar
hartman committed
292
293
294
295
        [self dealloc];
    } else {
        _o_sharedMainInstance = [super init];
    }
296
297
    
    o_about = [[VLAboutBox alloc] init];
298
    o_prefs = nil;
299
    o_open = [[VLCOpen alloc] init];
300
    o_wizard = [[VLCWizard alloc] init];
301
302

    i_lastShownVolume = -1;
hartman's avatar
hartman committed
303
304
305
306
307
308
309
310
311
312
313
    return _o_sharedMainInstance;
}

- (void)setIntf: (intf_thread_t *)p_mainintf {
    p_intf = p_mainintf;
}

- (intf_thread_t *)getIntf {
    return p_intf;
}

314
315
- (void)awakeFromNib
{
hartman's avatar
hartman committed
316
    unsigned int i_key = 0;
317
    playlist_t *p_playlist;
318
    vlc_value_t val;
hartman's avatar
hartman committed
319

320
    [self initStrings];
hartman's avatar
hartman committed
321
    [o_window setExcludedFromWindowsMenu: TRUE];
322
323
    [o_msgs_panel setExcludedFromWindowsMenu: TRUE];
    [o_msgs_panel setDelegate: self];
Jérome Decoodt's avatar
Jérome Decoodt committed
324

325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
    i_key = config_GetInt( p_intf, "key-quit" );
    [o_mi_quit setKeyEquivalent: [NSString stringWithFormat:@"%C", VLCKeyToCocoa( i_key )]];
    [o_mi_quit setKeyEquivalentModifierMask: VLCModifiersToCocoa(i_key)];
    i_key = config_GetInt( p_intf, "key-play-pause" );
    [o_mi_play setKeyEquivalent: [NSString stringWithFormat:@"%C", VLCKeyToCocoa( i_key )]];
    [o_mi_play setKeyEquivalentModifierMask: VLCModifiersToCocoa(i_key)];
    i_key = config_GetInt( p_intf, "key-stop" );
    [o_mi_stop setKeyEquivalent: [NSString stringWithFormat:@"%C", VLCKeyToCocoa( i_key )]];
    [o_mi_stop setKeyEquivalentModifierMask: VLCModifiersToCocoa(i_key)];
    i_key = config_GetInt( p_intf, "key-faster" );
    [o_mi_faster setKeyEquivalent: [NSString stringWithFormat:@"%C", VLCKeyToCocoa( i_key )]];
    [o_mi_faster setKeyEquivalentModifierMask: VLCModifiersToCocoa(i_key)];
    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-prev" );
    [o_mi_previous setKeyEquivalent: [NSString stringWithFormat:@"%C", VLCKeyToCocoa( i_key )]];
    [o_mi_previous setKeyEquivalentModifierMask: VLCModifiersToCocoa(i_key)];
    i_key = config_GetInt( p_intf, "key-next" );
    [o_mi_next setKeyEquivalent: [NSString stringWithFormat:@"%C", VLCKeyToCocoa( i_key )]];
    [o_mi_next setKeyEquivalentModifierMask: VLCModifiersToCocoa(i_key)];
    i_key = config_GetInt( p_intf, "key-jump+10sec" );
    [o_mi_fwd setKeyEquivalent: [NSString stringWithFormat:@"%C", VLCKeyToCocoa( i_key )]];
    [o_mi_fwd setKeyEquivalentModifierMask: VLCModifiersToCocoa(i_key)];
    i_key = config_GetInt( p_intf, "key-jump-10sec" );
    [o_mi_bwd setKeyEquivalent: [NSString stringWithFormat:@"%C", VLCKeyToCocoa( i_key )]];
    [o_mi_bwd setKeyEquivalentModifierMask: VLCModifiersToCocoa(i_key)];
352
353
354
355
356
357
358
359
360
361
362
363
    i_key = config_GetInt( p_intf, "key-jump+1min" );
    [o_mi_fwd1m setKeyEquivalent: [NSString stringWithFormat:@"%C", VLCKeyToCocoa( i_key )]];
    [o_mi_fwd1m setKeyEquivalentModifierMask: VLCModifiersToCocoa(i_key)];
    i_key = config_GetInt( p_intf, "key-jump-1min" );
    [o_mi_bwd1m setKeyEquivalent: [NSString stringWithFormat:@"%C", VLCKeyToCocoa( i_key )]];
    [o_mi_bwd1m setKeyEquivalentModifierMask: VLCModifiersToCocoa(i_key)];
    i_key = config_GetInt( p_intf, "key-jump+5min" );
    [o_mi_fwd5m setKeyEquivalent: [NSString stringWithFormat:@"%C", VLCKeyToCocoa( i_key )]];
    [o_mi_fwd5m setKeyEquivalentModifierMask: VLCModifiersToCocoa(i_key)];
    i_key = config_GetInt( p_intf, "key-jump-5min" );
    [o_mi_bwd5m setKeyEquivalent: [NSString stringWithFormat:@"%C", VLCKeyToCocoa( i_key )]];
    [o_mi_bwd5m setKeyEquivalentModifierMask: VLCModifiersToCocoa(i_key)];
364
365
366
367
368
369
    i_key = config_GetInt( p_intf, "key-vol-up" );
    [o_mi_vol_up setKeyEquivalent: [NSString stringWithFormat:@"%C", VLCKeyToCocoa( i_key )]];
    [o_mi_vol_up setKeyEquivalentModifierMask: VLCModifiersToCocoa(i_key)];
    i_key = config_GetInt( p_intf, "key-vol-down" );
    [o_mi_vol_down setKeyEquivalent: [NSString stringWithFormat:@"%C", VLCKeyToCocoa( i_key )]];
    [o_mi_vol_down setKeyEquivalentModifierMask: VLCModifiersToCocoa(i_key)];
hartman's avatar
hartman committed
370
371
372
    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)];
373
374
375
    i_key = config_GetInt( p_intf, "key-fullscreen" );
    [o_mi_fullscreen setKeyEquivalent: [NSString stringWithFormat:@"%C", VLCKeyToCocoa( i_key )]];
    [o_mi_fullscreen setKeyEquivalentModifierMask: VLCModifiersToCocoa(i_key)];
376
377
378
    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)];
379

380
    var_Create( p_intf, "intf-change", VLC_VAR_BOOL );
381

382
383
    [self setSubmenusEnabled: FALSE];
    [self manageVolumeSlider];
hartman's avatar
hartman committed
384
    [o_window setDelegate: self];
385
386
387
388
    
    if( [o_window frame].size.height <= 200 )
    {
        b_small_window = YES;
389
390
391
        [o_window setFrame: NSMakeRect( [o_window frame].origin.x,
            [o_window frame].origin.y, [o_window frame].size.width,
            [o_window minSize].height ) display: YES animate:YES];
392
393
394
395
396
397
398
399
400
401
402
        [o_playlist_view setAutoresizesSubviews: NO];
    }
    else
    {
        b_small_window = NO;
        [o_playlist_view setFrame: NSMakeRect( 10, 10, [o_window frame].size.width - 20, [o_window frame].size.height - 105 )];
        [o_playlist_view setNeedsDisplay:YES];
        [o_playlist_view setAutoresizesSubviews: YES];
        [[o_window contentView] addSubview: o_playlist_view];
    }
    [self updateTogglePlaylistState];
Jérome Decoodt's avatar
Jérome Decoodt committed
403

404
405
    o_size_with_playlist = [o_window frame].size;

406
    p_playlist = (playlist_t *) vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
hartman's avatar
hartman committed
407

408
409
410
411
    if( p_playlist )
    {
        /* Check if we need to start playing */
        if( p_intf->b_play )
hartman's avatar
hartman committed
412
413
414
        {
            playlist_Play( p_playlist );
        }
bigben's avatar
bigben committed
415
416
417
418
419
        var_Create( p_playlist, "fullscreen", VLC_VAR_BOOL | VLC_VAR_DOINHERIT);
        val.b_bool = VLC_FALSE;

        var_AddCallback( p_playlist, "fullscreen", FullscreenChanged, self);

420
421
        [o_btn_fullscreen setState: ( var_Get( p_playlist, "fullscreen", &val )>=0 && val.b_bool )];
        vlc_object_release( p_playlist );
hartman's avatar
hartman committed
422
    }
423
424
}

hartman's avatar
hartman committed
425
- (void)initStrings
426
427
{
    [o_window setTitle: _NS("VLC - Controller")];
428
    [self setScrollField:_NS("VLC media player") stopAfter:-1];
429

Jon Lech Johansen's avatar
Jon Lech Johansen committed
430
431
    /* button controls */
    [o_btn_prev setToolTip: _NS("Previous")];
hartman's avatar
hartman committed
432
    [o_btn_rewind setToolTip: _NS("Rewind")];
Jon Lech Johansen's avatar
Jon Lech Johansen committed
433
434
    [o_btn_play setToolTip: _NS("Play")];
    [o_btn_stop setToolTip: _NS("Stop")];
hartman's avatar
hartman committed
435
    [o_btn_ff setToolTip: _NS("Fast Forward")];
Jon Lech Johansen's avatar
Jon Lech Johansen committed
436
    [o_btn_next setToolTip: _NS("Next")];
hartman's avatar
hartman committed
437
    [o_btn_fullscreen setToolTip: _NS("Fullscreen")];
hartman's avatar
hartman committed
438
439
    [o_volumeslider setToolTip: _NS("Volume")];
    [o_timeslider setToolTip: _NS("Position")];
440
    [o_btn_playlist setToolTip: _NS("Playlist")];
441

Jérome Decoodt's avatar
Jérome Decoodt committed
442
    /* messages panel */
443
    [o_msgs_panel setTitle: _NS("Messages")];
444
    [o_msgs_btn_crashlog setTitle: _NS("Open CrashLog")];
445

Jon Lech Johansen's avatar
Jon Lech Johansen committed
446
    /* main menu */
Felix Paul Kühne's avatar
Felix Paul Kühne committed
447
    [o_mi_about setTitle: _NS("About VLC media player...")];
448
    [o_mi_prefs setTitle: _NS("Preferences...")];
hartman's avatar
hartman committed
449
450
    [o_mi_add_intf setTitle: _NS("Add Interface")];
    [o_mu_add_intf setTitle: _NS("Add Interface")];
451
    [o_mi_services setTitle: _NS("Services")];
452
    [o_mi_hide setTitle: _NS("Hide VLC")];
453
454
    [o_mi_hide_others setTitle: _NS("Hide Others")];
    [o_mi_show_all setTitle: _NS("Show All")];
455
    [o_mi_quit setTitle: _NS("Quit VLC")];
456

hartman's avatar
ALL:    
hartman committed
457
    [o_mu_file setTitle: _ANS("1:File")];
hartman's avatar
hartman committed
458
459
    [o_mi_open_generic setTitle: _NS("Open File...")];
    [o_mi_open_file setTitle: _NS("Quick Open File...")];
460
461
    [o_mi_open_disc setTitle: _NS("Open Disc...")];
    [o_mi_open_net setTitle: _NS("Open Network...")];
462
463
    [o_mi_open_recent setTitle: _NS("Open Recent")];
    [o_mi_open_recent_cm setTitle: _NS("Clear Menu")];
464
    [o_mi_open_wizard setTitle: _NS("Wizard...")];
465
466
467
468
469
470
471
472
473

    [o_mu_edit setTitle: _NS("Edit")];
    [o_mi_cut setTitle: _NS("Cut")];
    [o_mi_copy setTitle: _NS("Copy")];
    [o_mi_paste setTitle: _NS("Paste")];
    [o_mi_clear setTitle: _NS("Clear")];
    [o_mi_select_all setTitle: _NS("Select All")];

    [o_mu_controls setTitle: _NS("Controls")];
474
    [o_mi_play setTitle: _NS("Play")];
475
476
477
    [o_mi_stop setTitle: _NS("Stop")];
    [o_mi_faster setTitle: _NS("Faster")];
    [o_mi_slower setTitle: _NS("Slower")];
Christophe Massiot's avatar
Christophe Massiot committed
478
    [o_mi_previous setTitle: _NS("Previous")];
479
    [o_mi_next setTitle: _NS("Next")];
480
481
482
    [o_mi_random setTitle: _NS("Random")];
    [o_mi_repeat setTitle: _NS("Repeat One")];
    [o_mi_loop setTitle: _NS("Repeat All")];
483
484
    [o_mi_fwd setTitle: _NS("Step Forward")];
    [o_mi_bwd setTitle: _NS("Step Backward")];
485

hartman's avatar
hartman committed
486
    [o_mi_program setTitle: _NS("Program")];
487
    [o_mu_program setTitle: _NS("Program")];
hartman's avatar
hartman committed
488
    [o_mi_title setTitle: _NS("Title")];
489
    [o_mu_title setTitle: _NS("Title")];
hartman's avatar
hartman committed
490
    [o_mi_chapter setTitle: _NS("Chapter")];
491
    [o_mu_chapter setTitle: _NS("Chapter")];
Jérome Decoodt's avatar
Jérome Decoodt committed
492

hartman's avatar
hartman committed
493
    [o_mu_audio setTitle: _NS("Audio")];
Jon Lech Johansen's avatar
Jon Lech Johansen committed
494
495
    [o_mi_vol_up setTitle: _NS("Volume Up")];
    [o_mi_vol_down setTitle: _NS("Volume Down")];
496
    [o_mi_mute setTitle: _NS("Mute")];
497
498
499
500
501
502
    [o_mi_audiotrack setTitle: _NS("Audio Track")];
    [o_mu_audiotrack setTitle: _NS("Audio Track")];
    [o_mi_channels setTitle: _NS("Audio Channels")];
    [o_mu_channels setTitle: _NS("Audio Channels")];
    [o_mi_device setTitle: _NS("Audio Device")];
    [o_mu_device setTitle: _NS("Audio Device")];
503
504
    [o_mi_visual setTitle: _NS("Visualizations")];
    [o_mu_visual setTitle: _NS("Visualizations")];
Jérome Decoodt's avatar
Jérome Decoodt committed
505

hartman's avatar
hartman committed
506
    [o_mu_video setTitle: _NS("Video")];
507
508
509
    [o_mi_half_window setTitle: _NS("Half Size")];
    [o_mi_normal_window setTitle: _NS("Normal Size")];
    [o_mi_double_window setTitle: _NS("Double Size")];
510
    [o_mi_fittoscreen setTitle: _NS("Fit to Screen")];
511
    [o_mi_fullscreen setTitle: _NS("Fullscreen")];
512
    [o_mi_floatontop setTitle: _NS("Float on Top")];
513
    [o_mi_snapshot setTitle: _NS("Snapshot")];
514
515
516
517
518
519
    [o_mi_videotrack setTitle: _NS("Video Track")];
    [o_mu_videotrack setTitle: _NS("Video Track")];
    [o_mi_screen setTitle: _NS("Video Device")];
    [o_mu_screen setTitle: _NS("Video Device")];
    [o_mi_subtitle setTitle: _NS("Subtitles Track")];
    [o_mu_subtitle setTitle: _NS("Subtitles Track")];
520
    [o_mi_deinterlace setTitle: _NS("Deinterlace")];
521
    [o_mu_deinterlace setTitle: _NS("Deinterlace")];
bigben's avatar
bigben committed
522
523
    [o_mi_ffmpeg_pp setTitle: _NS("Post processing")];
    [o_mu_ffmpeg_pp setTitle: _NS("Post processing")];
524
525

    [o_mu_window setTitle: _NS("Window")];
526
527
    [o_mi_minimize setTitle: _NS("Minimize Window")];
    [o_mi_close_window setTitle: _NS("Close Window")];
hartman's avatar
hartman committed
528
    [o_mi_controller setTitle: _NS("Controller")];
Jérome Decoodt's avatar
Jérome Decoodt committed
529
    [o_mi_equalizer setTitle: _NS("Equalizer")];
hartman's avatar
hartman committed
530
    [o_mi_playlist setTitle: _NS("Playlist")];
531
    [o_mi_info setTitle: _NS("Info")];
hartman's avatar
hartman committed
532
533
    [o_mi_messages setTitle: _NS("Messages")];

534
535
    [o_mi_bring_atf setTitle: _NS("Bring All to Front")];

536
537
    [o_mu_help setTitle: _NS("Help")];
    [o_mi_readme setTitle: _NS("ReadMe...")];
hartman's avatar
hartman committed
538
    [o_mi_documentation setTitle: _NS("Online Documentation")];
539
    [o_mi_reportabug setTitle: _NS("Report a Bug")];
540
541
542
    [o_mi_website setTitle: _NS("VideoLAN Website")];
    [o_mi_license setTitle: _NS("License")];

543
    /* dock menu */
544
    [o_dmi_play setTitle: _NS("Play")];
545
    [o_dmi_stop setTitle: _NS("Stop")];
546
547
    [o_dmi_next setTitle: _NS("Next")];
    [o_dmi_previous setTitle: _NS("Previous")];
548
    [o_dmi_mute setTitle: _NS("Mute")];
549

550
551
    /* error panel */
    [o_error setTitle: _NS("Error")];
552
    [o_err_lbl setStringValue: _NS("An error has occurred which probably prevented the execution of your request:")];
Jérome Decoodt's avatar
Jérome Decoodt committed
553
    [o_err_bug_lbl setStringValue: _NS("If you believe that it is a bug, please follow the instructions at:")];
554
555
    [o_err_btn_msgs setTitle: _NS("Open Messages Window")];
    [o_err_btn_dismiss setTitle: _NS("Dismiss")];
556
    [o_err_ckbk_surpress setTitle: _NS("Suppress further errors")];
557

558
    [o_info_window setTitle: _NS("Info")];
559
560
561
562
}

- (void)applicationWillFinishLaunching:(NSNotification *)o_notification
{
563
564
565
    o_msg_lock = [[NSLock alloc] init];
    o_msg_arr = [[NSMutableArray arrayWithCapacity: 200] retain];

566
    o_img_play = [[NSImage imageNamed: @"play"] retain];
hartman's avatar
hartman committed
567
    o_img_play_pressed = [[NSImage imageNamed: @"play_blue"] retain];
568
    o_img_pause = [[NSImage imageNamed: @"pause"] retain];
hartman's avatar
hartman committed
569
    o_img_pause_pressed = [[NSImage imageNamed: @"pause_blue"] retain];
570
571

    [p_intf->p_sys->o_sendport setDelegate: self];
Jérome Decoodt's avatar
Jérome Decoodt committed
572
    [[NSRunLoop currentRunLoop]
573
574
        addPort: p_intf->p_sys->o_sendport
        forMode: NSDefaultRunLoopMode];
575

576
    [NSTimer scheduledTimerWithTimeInterval: 0.5
577
        target: self selector: @selector(manageIntf:)
578
        userInfo: nil repeats: FALSE];
579
580
581

    [NSThread detachNewThreadSelector: @selector(manage)
        toTarget: self withObject: nil];
Jérome Decoodt's avatar
Jérome Decoodt committed
582

hartman's avatar
hartman committed
583
584
    [o_controls setupVarMenuItem: o_mi_add_intf target: (vlc_object_t *)p_intf
        var: "intf-add" selector: @selector(toggleVar:)];
585
586

    vlc_thread_set_priority( p_intf, VLC_THREAD_PRIORITY_LOW );
587
}
hartman's avatar
-    
hartman committed
588

589
590
- (BOOL)application:(NSApplication *)o_app openFile:(NSString *)o_filename
{
591
    NSDictionary *o_dic = [NSDictionary dictionaryWithObjectsAndKeys: o_filename, @"ITEM_URL", nil];
592
    [o_playlist appendArray:
593
        [NSArray arrayWithObject: o_dic] atPos: -1 enqueue: NO];
Jérome Decoodt's avatar
Jérome Decoodt committed
594

595
596
    return( TRUE );
}
hartman's avatar
-    
hartman committed
597

hartman's avatar
hartman committed
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
- (NSString *)localizedString:(char *)psz
{
    NSString * o_str = nil;

    if( psz != NULL )
    {
        o_str = [[[NSString alloc] initWithUTF8String: psz] autorelease];
    }
    if ( o_str == NULL )
    {
        msg_Err( VLCIntf, "could not translate: %s", psz );
    }

    return( o_str );
}

- (char *)delocalizeString:(NSString *)id
{
    NSData * o_data = [id dataUsingEncoding: NSUTF8StringEncoding
                          allowLossyConversion: NO];
    char * psz_string;

    if ( o_data == nil )
    {
        o_data = [id dataUsingEncoding: NSUTF8StringEncoding
                     allowLossyConversion: YES];
Jérome Decoodt's avatar
Jérome Decoodt committed
624
        psz_string = malloc( [o_data length] + 1 );
hartman's avatar
hartman committed
625
626
627
628
629
630
631
        [o_data getBytes: psz_string];
        psz_string[ [o_data length] ] = '\0';
        msg_Err( VLCIntf, "cannot convert to wanted encoding: %s",
                 psz_string );
    }
    else
    {
Jérome Decoodt's avatar
Jérome Decoodt committed
632
        psz_string = malloc( [o_data length] + 1 );
hartman's avatar
hartman committed
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
        [o_data getBytes: psz_string];
        psz_string[ [o_data length] ] = '\0';
    }

    return psz_string;
}

/* i_width is in pixels */
- (NSString *)wrapString: (NSString *)o_in_string toWidth: (int) i_width
{
    NSMutableString *o_wrapped;
    NSString *o_out_string;
    NSRange glyphRange, effectiveRange, charRange;
    NSRect lineFragmentRect;
    unsigned glyphIndex, breaksInserted = 0;

    NSTextStorage *o_storage = [[NSTextStorage alloc] initWithString: o_in_string
        attributes: [NSDictionary dictionaryWithObjectsAndKeys:
        [NSFont labelFontOfSize: 0.0], NSFontAttributeName, nil]];
    NSLayoutManager *o_layout_manager = [[NSLayoutManager alloc] init];
    NSTextContainer *o_container = [[NSTextContainer alloc]
        initWithContainerSize: NSMakeSize(i_width, 2000)];
Jérome Decoodt's avatar
Jérome Decoodt committed
655

hartman's avatar
hartman committed
656
657
658
659
    [o_layout_manager addTextContainer: o_container];
    [o_container release];
    [o_storage addLayoutManager: o_layout_manager];
    [o_layout_manager release];
Jérome Decoodt's avatar
Jérome Decoodt committed
660

hartman's avatar
hartman committed
661
662
    o_wrapped = [o_in_string mutableCopy];
    glyphRange = [o_layout_manager glyphRangeForTextContainer: o_container];
Jérome Decoodt's avatar
Jérome Decoodt committed
663

hartman's avatar
hartman committed
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
    for( glyphIndex = glyphRange.location ; glyphIndex < NSMaxRange(glyphRange) ;
            glyphIndex += effectiveRange.length) {
        lineFragmentRect = [o_layout_manager lineFragmentRectForGlyphAtIndex: glyphIndex
                                            effectiveRange: &effectiveRange];
        charRange = [o_layout_manager characterRangeForGlyphRange: effectiveRange
                                    actualGlyphRange: &effectiveRange];
        if ([o_wrapped lineRangeForRange:
                NSMakeRange(charRange.location + breaksInserted, charRange.length)].length > charRange.length) {
            [o_wrapped insertString: @"\n" atIndex: NSMaxRange(charRange) + breaksInserted];
            breaksInserted++;
        }
    }
    o_out_string = [NSString stringWithString: o_wrapped];
    [o_wrapped release];
    [o_storage release];
Jérome Decoodt's avatar
Jérome Decoodt committed
679

hartman's avatar
hartman committed
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
    return o_out_string;
}


/*****************************************************************************
 * hasDefinedShortcutKey: Check to see if the key press is a defined VLC
 * shortcut key.  If it is, pass it off to VLC for handling and return YES,
 * otherwise ignore it and return NO (where it will get handled by Cocoa).
 *****************************************************************************/
- (BOOL)hasDefinedShortcutKey:(NSEvent *)o_event
{
    unichar key = 0;
    vlc_value_t val;
    unsigned int i_pressed_modifiers = 0;
    struct hotkey *p_hotkeys;
    int i;

    val.i_int = 0;
hartman's avatar
-    
hartman committed
698
    p_hotkeys = p_intf->p_vlc->p_hotkeys;
hartman's avatar
hartman committed
699
700
701
702
703
704
705
706
707
708
709
710
711
712

    i_pressed_modifiers = [o_event modifierFlags];

    if( i_pressed_modifiers & NSShiftKeyMask )
        val.i_int |= KEY_MODIFIER_SHIFT;
    if( i_pressed_modifiers & NSControlKeyMask )
        val.i_int |= KEY_MODIFIER_CTRL;
    if( i_pressed_modifiers & NSAlternateKeyMask )
        val.i_int |= KEY_MODIFIER_ALT;
    if( i_pressed_modifiers & NSCommandKeyMask )
        val.i_int |= KEY_MODIFIER_COMMAND;

    key = [[o_event charactersIgnoringModifiers] characterAtIndex: 0];

713
714
715
716
717
718
719
    switch( key )
    {
        case NSDeleteCharacter:
        case NSDeleteFunctionKey:
        case NSDeleteCharFunctionKey:
        case NSBackspaceCharacter:
            return YES;
720
721
722
723
724
725
726
        case NSUpArrowFunctionKey:
        case NSDownArrowFunctionKey:
        case NSRightArrowFunctionKey:
        case NSLeftArrowFunctionKey:
        case NSEnterCharacter:
        case NSCarriageReturnCharacter:
            return NO;
727
728
    }

hartman's avatar
hartman committed
729
730
731
732
733
734
    val.i_int |= CocoaKeyToVLC( key );

    for( i = 0; p_hotkeys[i].psz_action != NULL; i++ )
    {
        if( p_hotkeys[i].i_key == val.i_int )
        {
hartman's avatar
-    
hartman committed
735
            var_Set( p_intf->p_vlc, "key-pressed", val );
hartman's avatar
hartman committed
736
737
738
739
740
741
            return YES;
        }
    }

    return NO;
}
742

hartman's avatar
hartman committed
743
744
745
746
747
748
749
750
751
- (id)getControls
{
    if ( o_controls )
    {
        return o_controls;
    }
    return nil;
}

hartman's avatar
hartman committed
752
753
754
755
756
757
758
759
760
- (id)getPlaylist
{
    if ( o_playlist )
    {
        return o_playlist;
    }
    return nil;
}

761
762
763
764
765
766
- (id)getInfo
{
    if ( o_info )
    {
        return o_info;
    }
767
768
769
770
771
772
773
774
775
776
    return nil;
}

- (id)getWizard
{
    if ( o_wizard )
    {
        return o_wizard;
    }
    return nil;
777
778
}

779
780
781
- (void)manage
{
    NSDate * o_sleep_date;
hartman's avatar
hartman committed
782
    playlist_t * p_playlist;
Jérome Decoodt's avatar
Jérome Decoodt committed
783

hartman's avatar
-    
hartman committed
784
    /* new thread requires a new pool */
785
786
    NSAutoreleasePool * o_pool = [[NSAutoreleasePool alloc] init];

787
788
    vlc_thread_set_priority( p_intf, VLC_THREAD_PRIORITY_LOW );

Jérome Decoodt's avatar
Jérome Decoodt committed
789
    p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
hartman's avatar
hartman committed
790
791
792
793
794
795
                                              FIND_ANYWHERE );

    if( p_playlist != NULL )
    {
        var_AddCallback( p_playlist, "intf-change", PlaylistChanged, self );
        var_AddCallback( p_playlist, "item-change", PlaylistChanged, self );
796
797
        var_AddCallback( p_playlist, "item-append", PlaylistChanged, self );
        var_AddCallback( p_playlist, "item-deleted", PlaylistChanged, self );
hartman's avatar
hartman committed
798
        var_AddCallback( p_playlist, "playlist-current", PlaylistChanged, self );
bigben's avatar
bigben committed
799

hartman's avatar
hartman committed
800
801
802
        vlc_object_release( p_playlist );
    }

803
804
805
806
    while( !p_intf->b_die )
    {
        vlc_mutex_lock( &p_intf->change_lock );

hartman's avatar
hartman committed
807
#define p_input p_intf->p_sys->p_input
Jérome Decoodt's avatar
Jérome Decoodt committed
808

hartman's avatar
hartman committed
809
810
811
812
        if( p_input == NULL )
        {
            p_input = (input_thread_t *)vlc_object_find( p_intf, VLC_OBJECT_INPUT,
                                           FIND_ANYWHERE );
Jérome Decoodt's avatar
Jérome Decoodt committed
813

hartman's avatar
hartman committed
814
815
            /* Refresh the interface */
            if( p_input )
816
            {
hartman's avatar
hartman committed
817
                msg_Dbg( p_intf, "input has changed, refreshing interface" );
hartman's avatar
hartman committed
818
                p_intf->p_sys->b_input_update = VLC_TRUE;
819
            }
820
        }
hartman's avatar
hartman committed
821
        else if( p_input->b_die || p_input->b_dead )
hartman's avatar
hartman committed
822
823
        {
            /* input stopped */
hartman's avatar
hartman committed
824
825
            p_intf->p_sys->b_intf_update = VLC_TRUE;
            p_intf->p_sys->i_play_status = END_S;
826
            [self setScrollField: _NS("VLC media player") stopAfter:-1];
hartman's avatar
hartman committed
827
828
829
830
            vlc_object_release( p_input );
            p_input = NULL;
        }
#undef p_input
831

832
833
834
        /* Manage volume status */
        [self manageVolumeSlider];

835
        vlc_mutex_unlock( &p_intf->change_lock );
836

hartman's avatar
hartman committed
837
        o_sleep_date = [NSDate dateWithTimeIntervalSinceNow: .1];
838
839
        [NSThread sleepUntilDate: o_sleep_date];
    }
840

841
842
843
844
845
846
    [self terminate];
    [o_pool release];
}

- (void)manageIntf:(NSTimer *)o_timer
{
hartman's avatar
hartman committed
847
848
    vlc_value_t val;

849
850
851
852
853
    if( p_intf->p_vlc->b_die == VLC_TRUE )
    {
        [o_timer invalidate];
        return;
    }
854

hartman's avatar
hartman committed
855
#define p_input p_intf->p_sys->p_input
hartman's avatar
hartman committed
856
857
858
859
860
861
862
    if( p_intf->p_sys->b_input_update )
    {
        /* Called when new input is opened */
        p_intf->p_sys->b_current_title_update = VLC_TRUE;
        p_intf->p_sys->b_intf_update = VLC_TRUE;
        p_intf->p_sys->b_input_update = VLC_FALSE;
    }
863
864
865
866
867
868
869
870
    if( p_intf->p_sys->b_intf_update )
    {
        vlc_bool_t b_input = VLC_FALSE;
        vlc_bool_t b_plmul = VLC_FALSE;
        vlc_bool_t b_control = VLC_FALSE;
        vlc_bool_t b_seekable = VLC_FALSE;
        vlc_bool_t b_chapters = VLC_FALSE;

hartman's avatar
hartman committed
871
872
        playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
                                                   FIND_ANYWHERE );
873
        b_plmul = p_playlist->i_size > 1;
Jérome Decoodt's avatar
Jérome Decoodt committed
874
875

        vlc_object_release( p_playlist );
876
877

        if( ( b_input = ( p_input != NULL ) ) )
878
        {
879
            /* seekable streams */
hartman's avatar
hartman committed
880
881
            var_Get( p_input, "seekable", &val);
            b_seekable = val.b_bool;
882

883
            /* check wether slow/fast motion is possible*/
Jérome Decoodt's avatar
Jérome Decoodt committed
884
            b_control = p_input->input.b_can_pace_control;
885

hartman's avatar
hartman committed
886
            /* chapters & titles */
Jérome Decoodt's avatar
Jérome Decoodt committed
887
            //b_chapters = p_input->stream.i_area_nb > 1;
888
889
890
        }

        [o_btn_stop setEnabled: b_input];
891
892
        [o_btn_ff setEnabled: b_seekable];
        [o_btn_rewind setEnabled: b_seekable];
893
894
895
896
897
898
899
900
901
        [o_btn_prev setEnabled: (b_plmul || b_chapters)];
        [o_btn_next setEnabled: (b_plmul || b_chapters)];

        [o_timeslider setFloatValue: 0.0];
        [o_timeslider setEnabled: b_seekable];
        [o_timefield setStringValue: @"0:00:00"];

        p_intf->p_sys->b_intf_update = VLC_FALSE;
    }
Jérome Decoodt's avatar
Jérome Decoodt committed
902

903
904
905
906
907
908
    if( p_intf->p_sys->b_playmode_update )
    {
        [o_playlist playModeUpdated];
        p_intf->p_sys->b_playmode_update = VLC_FALSE;
    }
    if( p_intf->p_sys->b_playlist_update )
hartman's avatar
hartman committed
909
    {
910
        [o_playlist playlistUpdated];
hartman's avatar
hartman committed
911
912
        p_intf->p_sys->b_playlist_update = VLC_FALSE;
    }
Jérome Decoodt's avatar
Jérome Decoodt committed
913

914
    if( p_intf->p_sys->b_fullscreen_update )
915
    {
hartman's avatar
hartman committed
916
917
        playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
                                                   FIND_ANYWHERE );
918
919
        var_Get( p_playlist, "fullscreen", &val );
        [o_btn_fullscreen setState: val.b_bool];
hartman's avatar
hartman committed
920
921
        vlc_object_release( p_playlist );

922
        p_intf->p_sys->b_fullscreen_update = VLC_FALSE;
923
924
    }

hartman's avatar
hartman committed
925
    if( p_input && !p_input->b_die )
926
    {
hartman's avatar
hartman committed
927
        vlc_value_t val;
928

hartman's avatar
hartman committed
929
        if( p_intf->p_sys->b_current_title_update )
930
        {
hartman's avatar
hartman committed
931
932
933
934
935
            NSString *o_temp;
            vout_thread_t *p_vout;
            playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
                                                       FIND_ANYWHERE );

936
            if( p_playlist == NULL || p_playlist->status.p_item == NULL )
hartman's avatar
hartman committed
937
938
939
            {
                return;
            }
Jérome Decoodt's avatar
Jérome Decoodt committed
940
            o_temp = [NSString stringWithUTF8String:
941
                p_playlist->status.p_item->input.psz_name];
hartman's avatar
hartman committed
942
943
            if( o_temp == NULL )
                o_temp = [NSString stringWithCString:
944
                    p_playlist->status.p_item->input.psz_name];
945
            [self setScrollField: o_temp stopAfter:-1];
946
947

            p_vout = vlc_object_find( p_intf, VLC_OBJECT_VOUT,
hartman's avatar
hartman committed
948
949
                                                    FIND_ANYWHERE );
            if( p_vout != NULL )
950
            {
hartman's avatar
hartman committed
951
952
                id o_vout_wnd;
                NSEnumerator * o_enum = [[NSApp orderedWindows] objectEnumerator];
Jérome Decoodt's avatar
Jérome Decoodt committed
953

hartman's avatar
hartman committed
954
955
956
957
                while( ( o_vout_wnd = [o_enum nextObject] ) )
                {
                    if( [[o_vout_wnd className] isEqualToString: @"VLCWindow"] )
                    {
958
                        [o_vout_wnd updateTitle];
hartman's avatar
hartman committed
959
960
961
                    }
                }
                vlc_object_release( (vlc_object_t *)p_vout );
962
            }
963
            [o_playlist updateRowSelection];
hartman's avatar
hartman committed
964
965
            vlc_object_release( p_playlist );
            p_intf->p_sys->b_current_title_update = FALSE;
966
        }
967

hartman's avatar
hartman committed
968
        if( p_input && [o_timeslider isEnabled] )
hartman's avatar
hartman committed
969
        {
hartman's avatar
hartman committed
970
971
972
973
974
975
            /* Update the slider */
            vlc_value_t time;
            NSString * o_time;
            mtime_t i_seconds;
            vlc_value_t pos;
            float f_updated;
Jérome Decoodt's avatar
Jérome Decoodt committed
976

hartman's avatar
hartman committed
977
978
979
            var_Get( p_input, "position", &pos );
            f_updated = 10000. * pos.f_float;
            [o_timeslider setFloatValue: f_updated];
Jérome Decoodt's avatar
Jérome Decoodt committed
980

hartman's avatar
hartman committed
981
982
            var_Get( p_input, "time", &time );
            i_seconds = time.i_time / 1000000;
Jérome Decoodt's avatar
Jérome Decoodt committed
983

hartman's avatar
hartman committed
984
985
986
987
988
            o_time = [NSString stringWithFormat: @"%d:%02d:%02d",
                            (int) (i_seconds / (60 * 60)),
                            (int) (i_seconds / 60 % 60),
                            (int) (i_seconds % 60)];
            [o_timefield setStringValue: o_time];
hartman's avatar
hartman committed
989
        }
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
        
        if( p_intf->p_sys->b_volume_update )
        {
            NSString *o_text;
            o_text = [NSString stringWithFormat: _NS("Volume: %d"), i_lastShownVolume * 200 / AOUT_VOLUME_MAX];
            if( i_lastShownVolume != -1 )
            [self setScrollField:o_text stopAfter:1000000];

            [o_volumeslider setFloatValue: (float)i_lastShownVolume / AOUT_VOLUME_STEP];
            [o_volumeslider setEnabled: TRUE];
            p_intf->p_sys->b_mute = ( i_lastShownVolume == 0 );
            p_intf->p_sys->b_volume_update = FALSE;
        }
Jérome Decoodt's avatar
Jérome Decoodt committed
1003

hartman's avatar
hartman committed
1004
1005
1006
        /* Manage Playing status */
        var_Get( p_input, "state", &val );
        if( p_intf->p_sys->i_play_status != val.i_int )
hartman's avatar
hartman committed
1007
        {
hartman's avatar
hartman committed
1008
1009
            p_intf->p_sys->i_play_status = val.i_int;
            [self playStatusUpdated: p_intf->p_sys->i_play_status];
hartman's avatar
hartman committed
1010
1011
        }
    }
hartman's avatar
hartman committed
1012
    else
hartman's avatar
hartman committed
1013
    {
hartman's avatar
hartman committed
1014
        p_intf->p_sys->i_play_status = END_S;
hartman's avatar
hartman committed
1015
1016
        p_intf->p_sys->b_intf_update = VLC_TRUE;
        [self playStatusUpdated: p_intf->p_sys->i_play_status];
hartman's avatar
hartman committed
1017
        [self setSubmenusEnabled: FALSE];
1018
1019
    }

1020
1021
1022
#undef p_input

    [self updateMessageArray];
1023

1024
1025
1026
    if( (i_end_scroll != -1) && (mdate() > i_end_scroll) )
        [self resetScrollField];

1027

hartman's avatar
hartman committed
1028
    [NSTimer scheduledTimerWithTimeInterval: 0.3
1029
1030
        target: self selector: @selector(manageIntf:)
        userInfo: nil repeats: FALSE];
1031
1032
}

hartman's avatar
* ALL:    
hartman committed
1033
1034
- (void)setupMenus
{
hartman's avatar
hartman committed
1035
1036
#define p_input p_intf->p_sys->p_input
    if( p_input != NULL )
hartman's avatar
* ALL:    
hartman committed
1037
    {
hartman's avatar
hartman committed
1038
1039
        [o_controls setupVarMenuItem: o_mi_program target: (vlc_object_t *)p_input
            var: "program" selector: @selector(toggleVar:)];
Jérome Decoodt's avatar
Jérome Decoodt committed
1040

hartman's avatar
hartman committed
1041
1042
        [o_controls setupVarMenuItem: o_mi_title target: (vlc_object_t *)p_input
            var: "title" selector: @selector(toggleVar:)];
Jérome Decoodt's avatar
Jérome Decoodt committed
1043

hartman's avatar
hartman committed
1044
1045
        [o_controls setupVarMenuItem: o_mi_chapter target: (vlc_object_t *)p_input
            var: "chapter" selector: @selector(toggleVar:)];
Jérome Decoodt's avatar
Jérome Decoodt committed
1046

hartman's avatar
hartman committed
1047
1048
        [o_controls setupVarMenuItem: o_mi_audiotrack target: (vlc_object_t *)p_input
            var: "audio-es" selector: @selector(toggleVar:)];
Jérome Decoodt's avatar
Jérome Decoodt committed
1049

hartman's avatar
hartman committed
1050
1051
        [o_controls setupVarMenuItem: o_mi_videotrack target: (vlc_object_t *)p_input
            var: "video-es" selector: @selector(toggleVar:)];
Jérome Decoodt's avatar
Jérome Decoodt committed
1052

hartman's avatar
hartman committed
1053
1054
        [o_controls setupVarMenuItem: o_mi_subtitle target: (vlc_object_t *)p_input
            var: "spu-es" selector: @selector(toggleVar:)];
Jérome Decoodt's avatar
Jérome Decoodt committed
1055

hartman's avatar
hartman committed
1056
1057
1058
1059
1060
1061
        aout_instance_t * p_aout = vlc_object_find( p_intf, VLC_OBJECT_AOUT,
                                                    FIND_ANYWHERE );
        if ( p_aout != NULL )
        {
            [o_controls setupVarMenuItem: o_mi_channels target: (vlc_object_t *)p_aout
                var: "audio-channels" selector: @selector(toggleVar:)];
Jérome Decoodt's avatar
Jérome Decoodt committed
1062

hartman's avatar
hartman committed
1063
1064
            [o_controls setupVarMenuItem: o_mi_device target: (vlc_object_t *)p_aout
                var: "audio-device" selector: @selector(toggleVar:)];
Jérome Decoodt's avatar
Jérome Decoodt committed
1065

hartman's avatar
hartman committed
1066
1067
1068
1069
            [o_controls setupVarMenuItem: o_mi_visual target: (vlc_object_t *)p_aout
                var: "visual" selector: @selector(toggleVar:)];
            vlc_object_release( (vlc_object_t *)p_aout );
        }
Jérome Decoodt's avatar
Jérome Decoodt committed
1070

hartman's avatar
hartman committed
1071
1072
        vout_thread_t * p_vout = vlc_object_find( p_intf, VLC_OBJECT_VOUT,
                                                            FIND_ANYWHERE );
Jérome Decoodt's avatar
Jérome Decoodt committed
1073

hartman's avatar
hartman committed
1074
1075
1076
        if ( p_vout != NULL )
        {
            vlc_object_t * p_dec_obj;
bigben's avatar
bigben committed
1077

hartman's avatar