controls.m 24.8 KB
Newer Older
1
/*****************************************************************************
2
 * controls.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>
hartman's avatar
hartman committed
9
 *          Derk-Jan Hartman <hartman at videolan dot org>
10
 *          Benjamin Pracht <bigben at videolan doit org>
11
12
13
14
15
16
17
18
19
20
21
22
23
 *
 * 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
dionoea's avatar
dionoea committed
24
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
25
26
27
28
29
30
31
32
33
34
35
 *****************************************************************************/

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

#include "intf.h"
#include "vout.h"
hartman's avatar
hartman committed
36
#include "open.h"
hartman's avatar
hartman committed
37
#include "controls.h"
38
#include <vlc_osd.h>
39
40
41
42
43
44

/*****************************************************************************
 * VLCControls implementation 
 *****************************************************************************/
@implementation VLCControls

45
46
- (void)awakeFromNib
{
47
    [o_specificTime_mi setTitle: _NS("Jump To Time")];
48
49
50
    [o_specificTime_cancel_btn setTitle: _NS("Cancel")];
    [o_specificTime_ok_btn setTitle: _NS("OK")];
    [o_specificTime_sec_lbl setStringValue: _NS("sec.")];
51
    [o_specificTime_goTo_lbl setStringValue: _NS("Jump to time")];
52
53
}

54
55
- (IBAction)play:(id)sender
{
hartman's avatar
hartman committed
56
    vlc_value_t val;
hartman's avatar
hartman committed
57
    intf_thread_t * p_intf = VLCIntf;
58
    playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
hartman's avatar
hartman committed
59
                                        FIND_ANYWHERE );
60
61
62
63
    if( p_playlist )
    {
        vlc_mutex_lock( &p_playlist->object_lock );
        if( p_playlist->i_size <= 0 )
hartman's avatar
hartman committed
64
        {
65
66
            vlc_mutex_unlock( &p_playlist->object_lock );
            vlc_object_release( p_playlist );
67
            [o_main intfOpenFileGeneric: (id)sender];
hartman's avatar
hartman committed
68
        }
69
70
71
72
73
74
        else
        {
            vlc_mutex_unlock( &p_playlist->object_lock );
            vlc_object_release( p_playlist );
        }

75
    }
76
77
    val.i_int = config_GetInt( p_intf, "key-play-pause" );
    var_Set( p_intf->p_vlc, "key-pressed", val );
78
79
80
81
}

- (IBAction)stop:(id)sender
{
82
    vlc_value_t val;
hartman's avatar
hartman committed
83
    intf_thread_t * p_intf = VLCIntf;
84
85
    val.i_int = config_GetInt( p_intf, "key-stop" );
    var_Set( p_intf->p_vlc, "key-pressed", val );
86
87
88
89
}

- (IBAction)faster:(id)sender
{
90
    vlc_value_t val;
hartman's avatar
hartman committed
91
    intf_thread_t * p_intf = VLCIntf;
92
93
    val.i_int = config_GetInt( p_intf, "key-faster" );
    var_Set( p_intf->p_vlc, "key-pressed", val );
94
95
96
97
}

- (IBAction)slower:(id)sender
{
98
    vlc_value_t val;
hartman's avatar
hartman committed
99
    intf_thread_t * p_intf = VLCIntf;
100
101
    val.i_int = config_GetInt( p_intf, "key-slower" );
    var_Set( p_intf->p_vlc, "key-pressed", val );
hartman's avatar
hartman committed
102
103
}

104
105
- (IBAction)prev:(id)sender
{
106
    vlc_value_t val;
hartman's avatar
hartman committed
107
    intf_thread_t * p_intf = VLCIntf;
108
109
    val.i_int = config_GetInt( p_intf, "key-prev" );
    var_Set( p_intf->p_vlc, "key-pressed", val );
110
111
112
113
}

- (IBAction)next:(id)sender
{
114
    vlc_value_t val;
hartman's avatar
hartman committed
115
    intf_thread_t * p_intf = VLCIntf;
116
117
    val.i_int = config_GetInt( p_intf, "key-next" );
    var_Set( p_intf->p_vlc, "key-pressed", val );
118
119
}

hartman's avatar
hartman committed
120
- (IBAction)random:(id)sender
121
{
hartman's avatar
hartman committed
122
    vlc_value_t val;
123
    intf_thread_t * p_intf = VLCIntf;
hartman's avatar
hartman committed
124
125
126
127
128
129
130
131
132
133
    playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
                                                       FIND_ANYWHERE );
    if( p_playlist == NULL )
    {
        return;
    }

    var_Get( p_playlist, "random", &val );
    val.b_bool = !val.b_bool;
    var_Set( p_playlist, "random", val );
134
135
    if( val.b_bool )
    {
136
        vout_OSDMessage( p_intf, DEFAULT_CHAN, _( "Random On" ) );
137
138
139
    }
    else
    {
140
        vout_OSDMessage( p_intf, DEFAULT_CHAN, _( "Random Off" ) );
141
    }
hartman's avatar
hartman committed
142

143
    p_intf->p_sys->b_playmode_update = VLC_TRUE;
bigben's avatar
bigben committed
144
    p_intf->p_sys->b_intf_update = VLC_TRUE;
hartman's avatar
hartman committed
145
146
    vlc_object_release( p_playlist );
}
147

hartman's avatar
hartman committed
148
149
150
- (IBAction)repeat:(id)sender
{
    vlc_value_t val;
151
    intf_thread_t * p_intf = VLCIntf;
152
153
154
155
156
157
158
    playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
                                                       FIND_ANYWHERE );
    if( p_playlist == NULL )
    {
        return;
    }

hartman's avatar
hartman committed
159
    var_Get( p_playlist, "repeat", &val );
160
    if (!val.b_bool)
161
    {
162
        var_Set( p_playlist, "loop", val );
163
    }
hartman's avatar
hartman committed
164
165
    val.b_bool = !val.b_bool;
    var_Set( p_playlist, "repeat", val );
166
167
    if( val.b_bool )
    {
168
        vout_OSDMessage( p_intf, DEFAULT_CHAN, _( "Repeat One" ) );
169
170
171
    }
    else
    {
172
        vout_OSDMessage( p_intf, DEFAULT_CHAN, _( "Repeat Off" ) );
bigben's avatar
bigben committed
173
    }
hartman's avatar
hartman committed
174

175
    p_intf->p_sys->b_playmode_update = VLC_TRUE;
bigben's avatar
bigben committed
176
    p_intf->p_sys->b_intf_update = VLC_TRUE;
hartman's avatar
hartman committed
177
178
179
180
181
182
    vlc_object_release( p_playlist );
}

- (IBAction)loop:(id)sender
{
    vlc_value_t val;
183
    intf_thread_t * p_intf = VLCIntf;
hartman's avatar
hartman committed
184
185
186
187
188
189
190
191
    playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
                                                       FIND_ANYWHERE );
    if( p_playlist == NULL )
    {
        return;
    }

    var_Get( p_playlist, "loop", &val );
192
193
194
195
    if (!val.b_bool)
    {
        var_Set( p_playlist, "repeat", val );
    }
hartman's avatar
hartman committed
196
197
    val.b_bool = !val.b_bool;
    var_Set( p_playlist, "loop", val );
198
199
    if( val.b_bool )
    {
200
        vout_OSDMessage( p_intf, DEFAULT_CHAN, _( "Repeat All" ) );
201
202
203
    }
    else
    {
204
        vout_OSDMessage( p_intf, DEFAULT_CHAN, _( "Repeat Off" ) );
205
    }
206

207
    p_intf->p_sys->b_playmode_update = VLC_TRUE;
bigben's avatar
bigben committed
208
    p_intf->p_sys->b_intf_update = VLC_TRUE;
209
210
211
    vlc_object_release( p_playlist );
}

212
213
- (IBAction)forward:(id)sender
{
214
    vlc_value_t val;
hartman's avatar
hartman committed
215
    intf_thread_t * p_intf = VLCIntf;
216
    val.i_int = config_GetInt( p_intf, "key-jump+short" );
217
    var_Set( p_intf->p_vlc, "key-pressed", val );
218
219
}

220
221
- (IBAction)backward:(id)sender
{
222
    vlc_value_t val;
hartman's avatar
hartman committed
223
    intf_thread_t * p_intf = VLCIntf;
224
    val.i_int = config_GetInt( p_intf, "key-jump-short" );
225
    var_Set( p_intf->p_vlc, "key-pressed", val );
226
227
}

228

229
230
- (IBAction)volumeUp:(id)sender
{
231
    vlc_value_t val;
hartman's avatar
hartman committed
232
    intf_thread_t * p_intf = VLCIntf;
233
234
    val.i_int = config_GetInt( p_intf, "key-vol-up" );
    var_Set( p_intf->p_vlc, "key-pressed", val );
235
236
    /* Manage volume status */
    [o_main manageVolumeSlider];
237
238
239
240
}

- (IBAction)volumeDown:(id)sender
{
241
    vlc_value_t val;
hartman's avatar
hartman committed
242
    intf_thread_t * p_intf = VLCIntf;
243
244
    val.i_int = config_GetInt( p_intf, "key-vol-down" );
    var_Set( p_intf->p_vlc, "key-pressed", val );
245
246
    /* Manage volume status */
    [o_main manageVolumeSlider];
247
248
249
250
}

- (IBAction)mute:(id)sender
{
251
    vlc_value_t val;
hartman's avatar
hartman committed
252
    intf_thread_t * p_intf = VLCIntf;
253
254
    val.i_int = config_GetInt( p_intf, "key-vol-mute" );
    var_Set( p_intf->p_vlc, "key-pressed", val );
255
256
    /* Manage volume status */
    [o_main manageVolumeSlider];
hartman's avatar
hartman committed
257
258
}

259
- (IBAction)volumeSliderUpdated:(id)sender
hartman's avatar
hartman committed
260
{
hartman's avatar
hartman committed
261
    intf_thread_t * p_intf = VLCIntf;
262
    audio_volume_t i_volume = (audio_volume_t)[sender intValue];
263
264
265
    int i_volume_step = 0;
    i_volume_step = config_GetInt( p_intf->p_vlc, "volume-step" );
    aout_VolumeSet( p_intf, i_volume * i_volume_step );
266
267
    /* Manage volume status */
    [o_main manageVolumeSlider];
268
269
}

270
- (IBAction)windowAction:(id)sender
271
272
{
    id o_window = [NSApp keyWindow];
273
    NSString *o_title = [sender title];
274
    NSArray *o_windows = [NSApp orderedWindows];
275
    NSEnumerator *o_enumerator = [o_windows objectEnumerator];
276
    vout_thread_t *p_vout = vlc_object_find( VLCIntf, VLC_OBJECT_VOUT,
277
                                              FIND_ANYWHERE );
278

279
    if( p_vout != NULL )
280
    {
281
        id o_embedded_vout_list = [[VLCMain sharedInstance] getEmbeddedList];
282
        while ((o_window = [o_enumerator nextObject]))
hartman's avatar
hartman committed
283
        {
284
285
286
287
288
289
290
291
292
            id o_vout_view = nil;
            /* We have an embedded vout */
            if( [o_embedded_vout_list windowContainsEmbedded: o_window] )
            {
                o_vout_view = [o_embedded_vout_list getViewForWindow: o_window];
            }
            /* We have a detached Vout */
            else if( [[o_window className] isEqualToString: @"VLCWindow"] )
            {
293
                msg_Dbg( VLCIntf, "detached vout controls.m call getVoutView" );
294
295
296
297
                o_vout_view = [o_window getVoutView];
            }

            if( o_vout_view )
298
            {
hartman's avatar
hartman committed
299
                if( [o_title isEqualToString: _NS("Half Size") ] )
300
                    [o_vout_view scaleWindowWithFactor: 0.5];
301
                else if( [o_title isEqualToString: _NS("Normal Size") ] )
302
                    [o_vout_view scaleWindowWithFactor: 1.0];
303
                else if( [o_title isEqualToString: _NS("Double Size") ] )
304
                    [o_vout_view scaleWindowWithFactor: 2.0];
305
                else if( [o_title isEqualToString: _NS("Float on Top") ] )
306
                    [o_vout_view toggleFloatOnTop];
307
                else if( [o_title isEqualToString: _NS("Fit to Screen") ] )
308
309
310
311
                {
                    if( ![o_window isZoomed] )
                        [o_window performZoom:self];
                }
312
313
                else if( [o_title isEqualToString: _NS("Snapshot") ] )
                {
314
                    [o_vout_view snapshot];
315
                }
hartman's avatar
hartman committed
316
                else
317
                {
318
                    [o_vout_view toggleFullscreen];
319
                }
320
                break;
321
            }
hartman's avatar
hartman committed
322
        }
323
        vlc_object_release( (vlc_object_t *)p_vout );
hartman's avatar
hartman committed
324
    }
325
    else
bigben's avatar
bigben committed
326
    {
327
328
329
330
331
        playlist_t * p_playlist = vlc_object_find( VLCIntf, VLC_OBJECT_PLAYLIST,
                                              FIND_ANYWHERE );

        if( p_playlist && ( [o_title isEqualToString: _NS("Fullscreen")] ||
            [sender isKindOfClass:[NSButton class]] ) )
bigben's avatar
bigben committed
332
333
334
335
336
        {
            vlc_value_t val;
            var_Get( p_playlist, "fullscreen", &val );
            var_Set( p_playlist, "fullscreen", (vlc_value_t)!val.b_bool );
        }
337
        if( p_playlist ) vlc_object_release( (vlc_object_t *)p_playlist );
bigben's avatar
bigben committed
338
339
    }

hartman's avatar
hartman committed
340
341
}

hartman's avatar
* ALL:    
hartman committed
342
343
344
345
- (void)setupVarMenuItem:(NSMenuItem *)o_mi
                    target:(vlc_object_t *)p_object
                    var:(const char *)psz_variable
                    selector:(SEL)pf_callback
346
{
hartman's avatar
* ALL:    
hartman committed
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
    vlc_value_t val, text;
    int i_type = var_Type( p_object, psz_variable );

    switch( i_type & VLC_VAR_TYPE )
    {
    case VLC_VAR_VOID:
    case VLC_VAR_BOOL:
    case VLC_VAR_VARIABLE:
    case VLC_VAR_STRING:
    case VLC_VAR_INTEGER:
        break;
    default:
        /* Variable doesn't exist or isn't handled */
        return;
    }
    
    /* Make sure we want to display the variable */
    if( i_type & VLC_VAR_HASCHOICE )
    {
        var_Change( p_object, psz_variable, VLC_VAR_CHOICESCOUNT, &val, NULL );
        if( val.i_int == 0 ) return;
        if( (i_type & VLC_VAR_TYPE) != VLC_VAR_VARIABLE && val.i_int == 1 )
            return;
    }
    
    /* Get the descriptive name of the variable */
    var_Change( p_object, psz_variable, VLC_VAR_GETTEXT, &text, NULL );
hartman's avatar
hartman committed
374
    [o_mi setTitle: [[VLCMain sharedInstance] localizedString: text.psz_string ?
hartman's avatar
* ALL:    
hartman committed
375
                                        text.psz_string : strdup( psz_variable ) ]];
376

hartman's avatar
* ALL:    
hartman committed
377
378
    var_Get( p_object, psz_variable, &val );
    if( i_type & VLC_VAR_HASCHOICE )
379
    {
hartman's avatar
* ALL:    
hartman committed
380
381
382
383
384
385
386
        NSMenu *o_menu = [o_mi submenu];

        [self setupVarMenu: o_menu forMenuItem: o_mi target:p_object
                        var:psz_variable selector:pf_callback];
        
        if( text.psz_string ) free( text.psz_string );
        return;
387
    }
hartman's avatar
* ALL:    
hartman committed
388
389
390

    VLCMenuExt *o_data;
    switch( i_type & VLC_VAR_TYPE )
391
    {
hartman's avatar
* ALL:    
hartman committed
392
393
394
395
396
397
398
399
400
401
    case VLC_VAR_VOID:
        o_data = [[VLCMenuExt alloc] initWithVar: psz_variable Object: p_object->i_object_id
                Value: val ofType: i_type];
        [o_mi setRepresentedObject: [NSValue valueWithPointer:[o_data retain]]];
        break;

    case VLC_VAR_BOOL:
        o_data = [[VLCMenuExt alloc] initWithVar: psz_variable Object: p_object->i_object_id
                Value: val ofType: i_type];
        [o_mi setRepresentedObject: [NSValue valueWithPointer:[o_data retain]]];
402
403
        if( !( i_type & VLC_VAR_ISCOMMAND ) )
            [o_mi setState: val.b_bool ? TRUE : FALSE ];
hartman's avatar
* ALL:    
hartman committed
404
405
406
407
408
        break;

    default:
        if( text.psz_string ) free( text.psz_string );
        return;
409
    }
hartman's avatar
* ALL:    
hartman committed
410

411
    if( ( i_type & VLC_VAR_TYPE ) == VLC_VAR_STRING ) free( val.psz_string );
hartman's avatar
* ALL:    
hartman committed
412
    if( text.psz_string ) free( text.psz_string );
413
}
414

hartman's avatar
* ALL:    
hartman committed
415
416
417
418
419
420

- (void)setupVarMenu:(NSMenu *)o_menu
                    forMenuItem: (NSMenuItem *)o_parent
                    target:(vlc_object_t *)p_object
                    var:(const char *)psz_variable
                    selector:(SEL)pf_callback
421
{
hartman's avatar
* ALL:    
hartman committed
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
    vlc_value_t val, val_list, text_list;
    int i_type, i, i_nb_items;

    /* remove previous items */
    i_nb_items = [o_menu numberOfItems];
    for( i = 0; i < i_nb_items; i++ )
    {
        [o_menu removeItemAtIndex: 0];
    }

    /* Check the type of the object variable */
    i_type = var_Type( p_object, psz_variable );

    /* Make sure we want to display the variable */
    if( i_type & VLC_VAR_HASCHOICE )
    {
        var_Change( p_object, psz_variable, VLC_VAR_CHOICESCOUNT, &val, NULL );
        if( val.i_int == 0 ) return;
        if( (i_type & VLC_VAR_TYPE) != VLC_VAR_VARIABLE && val.i_int == 1 )
            return;
    }
    else
    {
        return;
    }

    switch( i_type & VLC_VAR_TYPE )
449
    {
hartman's avatar
* ALL:    
hartman committed
450
451
452
453
454
455
456
457
458
459
    case VLC_VAR_VOID:
    case VLC_VAR_BOOL:
    case VLC_VAR_VARIABLE:
    case VLC_VAR_STRING:
    case VLC_VAR_INTEGER:
        break;
    default:
        /* Variable doesn't exist or isn't handled */
        return;
    }
460

hartman's avatar
* ALL:    
hartman committed
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
    if( var_Get( p_object, psz_variable, &val ) < 0 )
    {
        return;
    }

    if( var_Change( p_object, psz_variable, VLC_VAR_GETLIST,
                    &val_list, &text_list ) < 0 )
    {
        if( (i_type & VLC_VAR_TYPE) == VLC_VAR_STRING ) free( val.psz_string );
        return;
    }

    /* make (un)sensitive */
    [o_parent setEnabled: ( val_list.p_list->i_count > 1 )];

    for( i = 0; i < val_list.p_list->i_count; i++ )
    {
        vlc_value_t another_val;
        NSMenuItem * o_lmi;
        NSString *o_title = @"";
        VLCMenuExt *o_data;

        switch( i_type & VLC_VAR_TYPE )
484
        {
hartman's avatar
* ALL:    
hartman committed
485
486
487
488
        case VLC_VAR_STRING:
            another_val.psz_string =
                strdup(val_list.p_list->p_values[i].psz_string);

hartman's avatar
hartman committed
489
            o_title = [[VLCMain sharedInstance] localizedString: text_list.p_list->p_values[i].psz_string ?
hartman's avatar
* ALL:    
hartman committed
490
491
492
493
494
495
496
                text_list.p_list->p_values[i].psz_string : val_list.p_list->p_values[i].psz_string ];

            o_lmi = [o_menu addItemWithTitle: o_title action: pf_callback keyEquivalent: @""];
            o_data = [[VLCMenuExt alloc] initWithVar: strdup(psz_variable) Object: p_object->i_object_id
                    Value: another_val ofType: i_type];
            [o_lmi setRepresentedObject: [NSValue valueWithPointer:[o_data retain]]];
            [o_lmi setTarget: self];
497

498
            if( !strcmp( val.psz_string, val_list.p_list->p_values[i].psz_string ) && !( i_type & VLC_VAR_ISCOMMAND ) )
hartman's avatar
* ALL:    
hartman committed
499
500
501
502
503
504
505
                [o_lmi setState: TRUE ];

            break;

        case VLC_VAR_INTEGER:

             o_title = text_list.p_list->p_values[i].psz_string ?
hartman's avatar
hartman committed
506
                                 [[VLCMain sharedInstance] localizedString: strdup( text_list.p_list->p_values[i].psz_string )] :
hartman's avatar
* ALL:    
hartman committed
507
508
509
510
511
512
513
514
515
                                 [NSString stringWithFormat: @"%d",
                                 val_list.p_list->p_values[i].i_int];

            o_lmi = [[o_menu addItemWithTitle: o_title action: pf_callback keyEquivalent: @""] retain ];
            o_data = [[VLCMenuExt alloc] initWithVar: strdup(psz_variable) Object: p_object->i_object_id
                    Value: val_list.p_list->p_values[i] ofType: i_type];
            [o_lmi setRepresentedObject: [NSValue valueWithPointer:[ o_data retain]]];
            [o_lmi setTarget: self];

516
            if( val_list.p_list->p_values[i].i_int == val.i_int && !( i_type & VLC_VAR_ISCOMMAND ) )
hartman's avatar
* ALL:    
hartman committed
517
518
519
520
521
                [o_lmi setState: TRUE ];
            break;

        default:
          break;
522
523
        }
    }
524

hartman's avatar
* ALL:    
hartman committed
525
    /* clean up everything */
526
    if( (i_type & VLC_VAR_TYPE) == VLC_VAR_STRING ) free( val.psz_string );
hartman's avatar
* ALL:    
hartman committed
527
528
529
530
531
532
533
    var_Change( p_object, psz_variable, VLC_VAR_FREELIST, &val_list, &text_list );
}

- (IBAction)toggleVar:(id)sender
{
    NSMenuItem *o_mi = (NSMenuItem *)sender;
    VLCMenuExt *o_data = [[o_mi representedObject] pointerValue];
534
535
536
537
538
539
540
541
    [NSThread detachNewThreadSelector: @selector(toggleVarThread:)
        toTarget: self withObject: o_data];

    return;
}

- (int)toggleVarThread: (id)_o_data
{
hartman's avatar
* ALL:    
hartman committed
542
    vlc_object_t *p_object;
543
544
545
    NSAutoreleasePool * o_pool = [[NSAutoreleasePool alloc] init];
    VLCMenuExt *o_data = (VLCMenuExt *)_o_data;

hartman's avatar
hartman committed
546
    vlc_thread_set_priority( VLCIntf , VLC_THREAD_PRIORITY_LOW );
hartman's avatar
* ALL:    
hartman committed
547

hartman's avatar
hartman committed
548
    p_object = (vlc_object_t *)vlc_object_get( VLCIntf,
hartman's avatar
* ALL:    
hartman committed
549
550
                                    [o_data objectID] );

551
552
553
554
555
556
557
558
559
    if( p_object != NULL )
    {
        var_Set( p_object, strdup([o_data name]), [o_data value] );
        vlc_object_release( p_object );
        [o_pool release];
        return VLC_TRUE;
    }
    [o_pool release];
    return VLC_EGENERIC;
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
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
- (IBAction)goToSpecificTime:(id)sender
{
    if( sender == o_specificTime_cancel_btn )
    {
        [NSApp endSheet: o_specificTime_win];
        [o_specificTime_win close];
    }
    else if( sender == o_specificTime_ok_btn )
    {
        input_thread_t * p_input = (input_thread_t *)vlc_object_find( VLCIntf, \
            VLC_OBJECT_INPUT, FIND_ANYWHERE );
        if( p_input )
        {
            input_Control( p_input, INPUT_SET_TIME, \
                (int64_t)([o_specificTime_enter_fld intValue] * 1000000));
            vlc_object_release( p_input );
        }
    
        [NSApp endSheet: o_specificTime_win];
        [o_specificTime_win close];
    }
    else
    {
        input_thread_t * p_input = (input_thread_t *)vlc_object_find( VLCIntf, \
            VLC_OBJECT_INPUT, FIND_ANYWHERE );
        if( p_input )
        {
            /* we can obviously only do that if an input is available */
            vlc_value_t pos, length;
            var_Get( p_input, "time", &pos );
            [o_specificTime_enter_fld setIntValue: (pos.i_time / 1000000)];
            var_Get( p_input, "length", &length );
            [o_specificTime_stepper setMaxValue: (length.i_time / 1000000)];

            [NSApp beginSheet: o_specificTime_win modalForWindow: \
                [NSApp mainWindow] modalDelegate: self didEndSelector: nil \
                contextInfo: nil];
            [o_specificTime_win makeKeyWindow];
            vlc_object_release( p_input );
        }
    }
}

605
606
607
@end

@implementation VLCControls (NSMenuValidation)
608

609
610
611
- (BOOL)validateMenuItem:(NSMenuItem *)o_mi
{
    BOOL bEnabled = TRUE;
hartman's avatar
hartman committed
612
    vlc_value_t val;
hartman's avatar
hartman committed
613
    intf_thread_t * p_intf = VLCIntf;
614
615
616
617
618
619
620
    playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
                                                       FIND_ANYWHERE );

    if( p_playlist != NULL )
    {
        vlc_mutex_lock( &p_playlist->object_lock );
    }
621
    else return FALSE;
622

623
624
#define p_input p_playlist->p_input

hartman's avatar
hartman committed
625
    if( [[o_mi title] isEqualToString: _NS("Faster")] ||
626
627
        [[o_mi title] isEqualToString: _NS("Slower")] )
    {
628
        if( p_input != NULL )
629
        {
630
            bEnabled = p_input->input.b_can_pace_control;
631
632
633
634
635
636
637
638
        }
        else
        {
            bEnabled = FALSE;
        }
    }
    else if( [[o_mi title] isEqualToString: _NS("Stop")] )
    {
639
        if( p_input == NULL )
640
641
642
        {
            bEnabled = FALSE;
        }
643
        [o_main setupMenus]; /* Make sure input menu is up to date */
644
    }
Jon Lech Johansen's avatar
Jon Lech Johansen committed
645
    else if( [[o_mi title] isEqualToString: _NS("Previous")] ||
646
647
648
649
             [[o_mi title] isEqualToString: _NS("Next")] )
    {
            bEnabled = p_playlist->i_size > 1;
    }
650
    else if( [[o_mi title] isEqualToString: _NS("Random")] )
651
    {
hartman's avatar
hartman committed
652
653
654
655
656
        int i_state;
        var_Get( p_playlist, "random", &val );
        i_state = val.b_bool ? NSOnState : NSOffState;
        [o_mi setState: i_state];
    }
657
    else if( [[o_mi title] isEqualToString: _NS("Repeat One")] )
hartman's avatar
hartman committed
658
659
660
661
662
663
    {
        int i_state;
        var_Get( p_playlist, "repeat", &val );
        i_state = val.b_bool ? NSOnState : NSOffState;
        [o_mi setState: i_state];
    }
664
    else if( [[o_mi title] isEqualToString: _NS("Repeat All")] )
hartman's avatar
hartman committed
665
666
667
668
    {
        int i_state;
        var_Get( p_playlist, "loop", &val );
        i_state = val.b_bool ? NSOnState : NSOffState;
669
670
        [o_mi setState: i_state];
    }
671
    else if( [[o_mi title] isEqualToString: _NS("Step Forward")] ||
672
673
             [[o_mi title] isEqualToString: _NS("Step Backward")] ||
             [[o_mi title] isEqualToString: _NS("Jump To Time")])
674
    {
675
        if( p_input != NULL )
676
        {
677
            var_Get( p_input, "seekable", &val);
678
            bEnabled = val.b_bool;
679
        }
680
        else bEnabled = FALSE;
681
    }
682
    else if( [[o_mi title] isEqualToString: _NS("Mute")] )
683
684
    {
        [o_mi setState: p_intf->p_sys->b_mute ? NSOnState : NSOffState];
685
        [o_main setupMenus]; /* Make sure audio menu is up to date */
686
    }
bigben's avatar
bigben committed
687
    else if( [[o_mi title] isEqualToString: _NS("Half Size")] ||
688
                [[o_mi title] isEqualToString: _NS("Normal Size")] ||
hartman's avatar
hartman committed
689
                [[o_mi title] isEqualToString: _NS("Double Size")] ||
690
                [[o_mi title] isEqualToString: _NS("Fit to Screen")] ||
691
                [[o_mi title] isEqualToString: _NS("Snapshot")] ||
692
                [[o_mi title] isEqualToString: _NS("Fullscreen")] ||
693
                [[o_mi title] isEqualToString: _NS("Float on Top")] )
694
    {
695
        id o_window;
696
        NSArray *o_windows = [NSApp orderedWindows];
697
698
699
        NSEnumerator *o_enumerator = [o_windows objectEnumerator];
        bEnabled = FALSE;
        
700
701
702
        vout_thread_t   *p_vout = vlc_object_find( p_intf, VLC_OBJECT_VOUT,
                                              FIND_ANYWHERE );
        if( p_vout != NULL )
703
        {
704
            if( [[o_mi title] isEqualToString: _NS("Float on Top")] )
705
706
707
708
709
            {
                var_Get( p_vout, "video-on-top", &val );
                [o_mi setState: val.b_bool ?  NSOnState : NSOffState];
            }

710
            while( (o_window = [o_enumerator nextObject]))
711
            {
712
713
714
                if( [[o_window className] isEqualToString: @"VLCWindow"] ||
                            [[[VLCMain sharedInstance] getEmbeddedList]
                            windowContainsEmbedded: o_window])
715
716
717
718
                {
                    bEnabled = TRUE;
                    break;
                }
719
            }
720
            vlc_object_release( (vlc_object_t *)p_vout );
721
        }
722
        else if( [[o_mi title] isEqualToString: _NS("Fullscreen")] )
bigben's avatar
bigben committed
723
        {
724
            var_Get( p_playlist, "fullscreen", &val );
bigben's avatar
bigben committed
725
726
727
            [o_mi setState: val.b_bool];
            bEnabled = TRUE;
        }
728
		[o_main setupMenus]; /* Make sure video menu is up to date */
bigben's avatar
bigben committed
729
730
    }

731
732
    vlc_mutex_unlock( &p_playlist->object_lock );
    vlc_object_release( p_playlist );
733

734
735
736
737
    return( bEnabled );
}

@end
hartman's avatar
* ALL:    
hartman committed
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765

/*****************************************************************************
 * VLCMenuExt implementation 
 *****************************************************************************
 * Object connected to a playlistitem which remembers the data belonging to
 * the variable of the autogenerated menu
 *****************************************************************************/
@implementation VLCMenuExt

- (id)initWithVar: (const char *)_psz_name Object: (int)i_id
        Value: (vlc_value_t)val ofType: (int)_i_type
{
    self = [super init];

    if( self != nil )
    {
        psz_name = strdup( _psz_name );
        i_object_id = i_id;
        value = val;
        i_type = _i_type;
    }

    return( self );
}

- (void)dealloc
{
    free( psz_name );
766
    [super dealloc];
hartman's avatar
* ALL:    
hartman committed
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
}

- (char *)name
{
    return psz_name;
}

- (int)objectID
{
    return i_object_id;
}

- (vlc_value_t)value
{
    return value;
}

- (int)type
{
    return i_type;
}

@end
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804


/*****************************************************************************
 * VLCTimeField implementation 
 *****************************************************************************
 * we need this to catch our click-event in the controller window
 *****************************************************************************/

@implementation VLCTimeField
- (void)mouseDown: (NSEvent *)ourEvent
{
    if( [ourEvent clickCount] > 1 )
        [[[VLCMain sharedInstance] getControls] goToSpecificTime: nil];
}
@end