open.m 26.9 KB
Newer Older
1
2
3
4
/*****************************************************************************
 * open.m: MacOS X plugin for vlc
 *****************************************************************************
 * Copyright (C) 2002 VideoLAN
5
 * $Id: open.m,v 1.11 2003/01/20 03:45:06 hartman Exp $
6
7
 *
 * Authors: Jon Lech Johansen <jon-vl@nanocrew.net> 
8
 *          Christophe Massiot <massiot@via.ecp.fr>
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
 *
 * 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>

#include <paths.h>
#include <IOKit/IOKitLib.h>
#include <IOKit/IOBSD.h>
#include <IOKit/storage/IOMedia.h>
#include <IOKit/storage/IOCDMedia.h>
#include <IOKit/storage/IODVDMedia.h>

#import <Cocoa/Cocoa.h>

#include <vlc/vlc.h>
#include <vlc/intf.h>

#include "netutils.h"

#import "intf.h"
#import "playlist.h"
48
#import "open.h"
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137

/*****************************************************************************
 * GetEjectableMediaOfClass 
 *****************************************************************************/
NSArray *GetEjectableMediaOfClass( const char *psz_class )
{
    io_object_t next_media;
    mach_port_t master_port;
    kern_return_t kern_result;
    NSArray *o_devices = nil;
    NSMutableArray *p_list = nil;
    io_iterator_t media_iterator;
    CFMutableDictionaryRef classes_to_match;

    kern_result = IOMasterPort( MACH_PORT_NULL, &master_port );
    if( kern_result != KERN_SUCCESS )
    {
        return( nil );
    }
    
    classes_to_match = IOServiceMatching( psz_class );
    if( classes_to_match == NULL )
    {
        return( nil );
    }
    
    CFDictionarySetValue( classes_to_match, CFSTR( kIOMediaEjectable ), 
                          kCFBooleanTrue );
    
    kern_result = IOServiceGetMatchingServices( master_port, classes_to_match, 
                                                &media_iterator );
    if( kern_result != KERN_SUCCESS )
    {
        return( nil );
    }

    p_list = [NSMutableArray arrayWithCapacity: 1];
    
    next_media = IOIteratorNext( media_iterator );
    if( next_media != NULL )
    {
        char psz_buf[0x32];
        size_t dev_path_length;
        CFTypeRef str_bsd_path;
    
        do
        {
            str_bsd_path = IORegistryEntryCreateCFProperty( next_media,
                                                            CFSTR( kIOBSDName ),
                                                            kCFAllocatorDefault,
                                                            0 );
            if( str_bsd_path == NULL )
            {
                IOObjectRelease( next_media );
                continue;
            }
            
            snprintf( psz_buf, sizeof(psz_buf), "%s%c", _PATH_DEV, 'r' );
            dev_path_length = strlen( psz_buf );
            
            if( CFStringGetCString( str_bsd_path,
                                    (char*)&psz_buf + dev_path_length,
                                    sizeof(psz_buf) - dev_path_length,
                                    kCFStringEncodingASCII ) )
            {
                [p_list addObject: [NSString stringWithCString: psz_buf]];
            }
            
            CFRelease( str_bsd_path );
            
            IOObjectRelease( next_media );
        
        } while( ( next_media = IOIteratorNext( media_iterator ) ) != NULL );
    }
    
    IOObjectRelease( media_iterator );

    o_devices = [NSArray arrayWithArray: p_list];

    return( o_devices );
}

/*****************************************************************************
 * VLCOpen implementation 
 *****************************************************************************/
@implementation VLCOpen

- (void)awakeFromNib
{
138
    intf_thread_t * p_intf = [NSApp getIntf];
Christophe Massiot's avatar
Christophe Massiot committed
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
    char * psz_sout = config_GetPsz( p_intf, "sout" );

    if ( psz_sout != NULL && *psz_sout )
    {
        [o_sout_cbox setState: YES];

        NSRect s_rect = [o_panel frame];
        s_rect.size.height = OPEN_PANEL_FULL_HEIGHT + WINDOW_TITLE_HEIGHT;
        [o_panel setFrame: s_rect display: NO];

        NSPoint s_point;
        s_point.x = 0;
        s_point.y = 0;
        [[o_panel contentView] setBoundsOrigin: s_point];
    }
    else
    {
        [o_sout_cbox setState: NO];

        NSRect s_rect = [o_panel frame];
        s_rect.size.height = OPEN_PANEL_SHORT_HEIGHT + WINDOW_TITLE_HEIGHT;
        [o_panel setFrame: s_rect display: NO];

        NSPoint s_point;
        s_point.x = 0;
        s_point.y = OPEN_PANEL_FULL_HEIGHT - OPEN_PANEL_SHORT_HEIGHT;
        [[o_panel contentView] setBoundsOrigin: s_point];
    }
hartman's avatar
hartman committed
167
    free(psz_sout);
168

169
    [o_panel setTitle: _NS("Open Source")];
170
    [o_mrl_lbl setTitle: _NS("Media Resource Locator (MRL)")];
171
    [o_ckbox_enqueue setTitle: _NS("Only enqueue in playlist. Do not play.")];
172
173
174
175
176
177
178
179
180

    [o_btn_ok setTitle: _NS("OK")];
    [o_btn_cancel setTitle: _NS("Cancel")];

    [[o_tabview tabViewItemAtIndex: 0] setLabel: _NS("File")];
    [[o_tabview tabViewItemAtIndex: 1] setLabel: _NS("Disc")];
    [[o_tabview tabViewItemAtIndex: 2] setLabel: _NS("Network")];

    [o_file_btn_browse setTitle: _NS("Browse...")];
181
    [o_file_stream setTitle: _NS("Treat as a pipe rather than as a file")];
182

183
184
185
    [o_file_sub_btn_browse setTitle: _NS("Browse...")];
    [o_file_sub_ckbox setTitle: _NS("Load subtitles")];

186
187
188
    [o_disc_device_lbl setStringValue: _NS("Device name")];
    [o_disc_title_lbl setStringValue: _NS("Title")];
    [o_disc_chapter_lbl setStringValue: _NS("Chapter")];
189
    [o_disc_videots_btn_browse setStringValue: _NS("Browse...")];
190
    [o_disc_dvd_menus setTitle: _NS("Use DVD menus")];
191

192
193
    [[o_disc_type cellAtRow:0 column:0] setTitle: _NS("VIDEO_TS folder")];
    [[o_disc_type cellAtRow:1 column:0] setTitle: _NS("DVD")];
194
    [[o_disc_type cellAtRow:2 column:0] setTitle: _NS("VCD")];
195
196
197
198
199
200
201
202

    [o_net_udp_port_lbl setStringValue: _NS("Port")];
    [o_net_udpm_addr_lbl setStringValue: _NS("Address")];
    [o_net_udpm_port_lbl setStringValue: _NS("Port")];
    [o_net_cs_addr_lbl setStringValue: _NS("Address")];
    [o_net_cs_port_lbl setStringValue: _NS("Port")];
    [o_net_http_url_lbl setStringValue: _NS("URL")];

203
204
205
206
207
208
209
210
211
212
    [[o_net_mode cellAtRow:0 column:0] setTitle: _NS("UDP/RTP")];
    [[o_net_mode cellAtRow:1 column:0] setTitle: _NS("UDP/RTP Multicast")];
    [[o_net_mode cellAtRow:2 column:0] setTitle: _NS("Channel server")];
    [[o_net_mode cellAtRow:3 column:0] setTitle: _NS("HTTP/FTP/MMS")];

    [o_net_udp_port setIntValue: config_GetInt( p_intf, "server-port" )];
    [o_net_udp_port_stp setIntValue: config_GetInt( p_intf, "server-port" )];
    [o_net_cs_port setIntValue: config_GetInt( p_intf, "channel-port" )];
    [o_net_cs_port_stp setIntValue: config_GetInt( p_intf, "channel-port" )];

Christophe Massiot's avatar
Christophe Massiot committed
213
214
215
216
217
218
219
220
221
222
223
224
225
    [o_sout_cbox setTitle: _NS("Stream output")];
    [o_sout_mrl_lbl setTitle: _NS("Stream output MRL")];
    [[o_sout_access cellAtRow:0 column:0] setTitle: _NS("File")];
    [[o_sout_access cellAtRow:1 column:0] setTitle: _NS("UDP")];
    [[o_sout_access cellAtRow:2 column:0] setTitle: _NS("RTP")];

    [o_sout_file_btn_browse setStringValue: _NS("Browse...")];
    [o_sout_udp_addr_lbl setStringValue: _NS("Address")];
    [o_sout_udp_port_lbl setStringValue: _NS("Port")];

    [[o_sout_mux cellAtRow:0 column:0] setTitle: _NS("PS")];
    [[o_sout_mux cellAtRow:0 column:1] setTitle: _NS("TS")];

226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
    [[NSNotificationCenter defaultCenter] addObserver: self
        selector: @selector(openFilePathChanged:)
        name: NSControlTextDidChangeNotification
        object: o_file_path];

    [[NSNotificationCenter defaultCenter] addObserver: self
        selector: @selector(openDiscInfoChanged:)
        name: NSControlTextDidChangeNotification
        object: o_disc_device];
    [[NSNotificationCenter defaultCenter] addObserver: self
        selector: @selector(openDiscInfoChanged:)
        name: NSControlTextDidChangeNotification
        object: o_disc_title];
    [[NSNotificationCenter defaultCenter] addObserver: self
        selector: @selector(openDiscInfoChanged:)
        name: NSControlTextDidChangeNotification
        object: o_disc_chapter];
243
244
245
246
    [[NSNotificationCenter defaultCenter] addObserver: self
        selector: @selector(openDiscInfoChanged:)
        name: NSControlTextDidChangeNotification
        object: o_disc_videots_folder];
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271

    [[NSNotificationCenter defaultCenter] addObserver: self
        selector: @selector(openNetInfoChanged:)
        name: NSControlTextDidChangeNotification
        object: o_net_udp_port];
    [[NSNotificationCenter defaultCenter] addObserver: self
        selector: @selector(openNetInfoChanged:)
        name: NSControlTextDidChangeNotification
        object: o_net_udpm_addr];
    [[NSNotificationCenter defaultCenter] addObserver: self
        selector: @selector(openNetInfoChanged:)
        name: NSControlTextDidChangeNotification
        object: o_net_udpm_port];
    [[NSNotificationCenter defaultCenter] addObserver: self
        selector: @selector(openNetInfoChanged:)
        name: NSControlTextDidChangeNotification
        object: o_net_cs_addr];
    [[NSNotificationCenter defaultCenter] addObserver: self
        selector: @selector(openNetInfoChanged:)
        name: NSControlTextDidChangeNotification
        object: o_net_cs_port];
    [[NSNotificationCenter defaultCenter] addObserver: self
        selector: @selector(openNetInfoChanged:)
        name: NSControlTextDidChangeNotification
        object: o_net_http_url];
Christophe Massiot's avatar
Christophe Massiot committed
272
273
274
275
276
277
278
279
280
281
282
283
284

    [[NSNotificationCenter defaultCenter] addObserver: self
        selector: @selector(soutInfoChanged:)
        name: NSControlTextDidChangeNotification
        object: o_sout_file_path];
    [[NSNotificationCenter defaultCenter] addObserver: self
        selector: @selector(soutInfoChanged:)
        name: NSControlTextDidChangeNotification
        object: o_sout_udp_addr];
    [[NSNotificationCenter defaultCenter] addObserver: self
        selector: @selector(soutInfoChanged:)
        name: NSControlTextDidChangeNotification
        object: o_sout_udp_port];
285
286
}

287
- (void)openTarget:(int)i_type
288
289
290
{
    int i_result;

291
    [o_tabview selectTabViewItemAtIndex: i_type];
292
293
294
295
296
297
    [o_ckbox_enqueue setState: NSOffState];
    [o_file_sub_path setStringValue: @""];
    [o_file_sub_ckbox setState: NSOffState];
    [o_file_sub_path setEnabled: NO];
    [o_file_sub_btn_browse setEnabled: NO];
    
298
299
    i_result = [NSApp runModalForWindow: o_panel];
    [o_panel close];
300
301
302

    if( i_result )
    {
Christophe Massiot's avatar
Christophe Massiot committed
303
        NSString *o_sout = [o_sout_mrl stringValue];
304
305
        intf_thread_t * p_intf = [NSApp getIntf];
        
Christophe Massiot's avatar
Christophe Massiot committed
306
307
308
309
310
        if ( [o_sout_cbox state] )
        {
            config_PutPsz( p_intf, "sout", [o_sout lossyCString] );
        }

311
        NSString *o_source = [o_mrl stringValue];
312
313
314
        BOOL b_enq = [o_ckbox_enqueue state] == NSOnState ? YES : NO;
        NSString *subPath = [o_file_sub_path stringValue];
        
315
        [o_playlist appendArray: 
316
317
318
319
            [NSArray arrayWithObject: o_source] atPos: -1 enqueue:b_enq];
        
        if (([o_file_sub_ckbox state] == NSOnState) && !([subPath isEqualTo: @""]))
            config_PutPsz( p_intf, "sub-file", strdup( [subPath cString] ) );
320
    }
Christophe Massiot's avatar
Christophe Massiot committed
321
322

    [self soutModeChanged: nil];
323
324
}

325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
- (void)tabView:(NSTabView *)o_tv didSelectTabViewItem:(NSTabViewItem *)o_tvi
{
    NSString *o_label = [o_tvi label];

    if( [o_label isEqualToString: _NS("File")] )
    {
        [self openFilePathChanged: nil];
    }
    else if( [o_label isEqualToString: _NS("Disc")] )
    {
        [self openDiscTypeChanged: nil];
    }
    else if( [o_label isEqualToString: _NS("Network")] )
    {
        [self openNetModeChanged: nil];
    }  
}

343
- (IBAction)openFileGeneric:(id)sender
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
{
    [self openFilePathChanged: nil];
    [self openTarget: 0];
}

- (IBAction)openDisc:(id)sender
{
    [self openDiscTypeChanged: nil];
    [self openTarget: 1];
}

- (IBAction)openNet:(id)sender
{
    [self openNetModeChanged: nil];
    [self openTarget: 2];
}

- (void)openFilePathChanged:(NSNotification *)o_notification
{
    NSString *o_mrl_string;
    NSString *o_filename = [o_file_path stringValue];
hartman's avatar
hartman committed
365
    NSString *o_ext = [o_filename pathExtension];
366
    vlc_bool_t b_stream = [o_file_stream state];
367

hartman's avatar
hartman committed
368
369
370
371
372
373
374
375
376
377
378
379
380
    if ([o_ext isEqualToString: @"bin"] ||
        [o_ext isEqualToString: @"cue"] ||
        [o_ext isEqualToString: @"vob"] ||
        [o_ext isEqualToString: @"iso"])
    {
        o_mrl_string = o_filename;
    }
    else
    {
        o_mrl_string = [NSString stringWithFormat: @"%s://%@",
                        b_stream ? "stream" : "file",
                        o_filename];
    }
381
382
383
    [o_mrl setStringValue: o_mrl_string]; 
}

Christophe Massiot's avatar
Christophe Massiot committed
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
- (IBAction)openFileBrowse:(id)sender
{
    NSOpenPanel *o_open_panel = [NSOpenPanel openPanel];
    
    [o_open_panel setAllowsMultipleSelection: NO];
    [o_open_panel setTitle: _NS("Open File")];
    [o_open_panel setPrompt: _NS("Open")];

    if( [o_open_panel runModalForDirectory: nil 
            file: nil types: nil] == NSOKButton )
    {
        NSString *o_filename = [[o_open_panel filenames] objectAtIndex: 0];
        [o_file_path setStringValue: o_filename];
        [self openFilePathChanged: nil];
    }
}

401
402
403
404
405
- (IBAction)openFileStreamChanged:(id)sender
{
    [self openFilePathChanged: nil];
}

406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
- (IBAction)loadSubsChanged:(id)sender
{
    if ([o_file_sub_ckbox state] == NSOnState)
    {
        [o_file_sub_path setEnabled:YES];
        [o_file_sub_btn_browse setEnabled:YES];
    }
    else
    {
        [o_file_sub_path setEnabled:NO];
        [o_file_sub_btn_browse setEnabled:NO];
    }
}

- (IBAction)openSubBrowse:(id)sender
{
    NSOpenPanel *o_open_panel = [NSOpenPanel openPanel];
    
    [o_open_panel setAllowsMultipleSelection: NO];
    [o_open_panel setTitle: _NS("Open File")];
    [o_open_panel setPrompt: _NS("Open")];

    if( [o_open_panel runModalForDirectory: nil 
            file: nil types: nil] == NSOKButton )
    {
        NSString *o_filename = [[o_open_panel filenames] objectAtIndex: 0];
        [o_file_sub_path setStringValue: o_filename];
    }
}

436
437
438
- (IBAction)openDiscTypeChanged:(id)sender
{
    NSString *o_type;
439
    vlc_bool_t b_device, b_menus, b_title_chapter;
440
441
    
    [o_disc_device removeAllItems];
442
    b_title_chapter = ![o_disc_dvd_menus state];
443
444
445
    
    o_type = [[o_disc_type selectedCell] title];

446
    if ( [o_type isEqualToString: _NS("VIDEO_TS folder")] )
447
    {
448
        b_device = 0; b_menus = 1;
449
450
451
    }
    else
    {
452
453
454
        NSArray *o_devices;
        NSString *o_disc;
        const char *psz_class = NULL;
455
        b_device = 1;
456
457
458
459
460

        if ( [o_type isEqualToString: _NS("VCD")] )
        {
            psz_class = kIOCDMediaClass;
            o_disc = o_type;
461
462
            b_menus = 0; b_title_chapter = 1;
            [o_disc_dvd_menus setState: FALSE];
463
        }
464
        else
465
466
467
        {
            psz_class = kIODVDMediaClass;
            o_disc = o_type;
468
            b_menus = 1;
469
        }
470
    
471
472
        o_devices = GetEjectableMediaOfClass( psz_class );
        if ( o_devices != nil )
473
        {
474
            int i_devices = [o_devices count];
475
        
476
            if ( i_devices )
477
            {
478
479
480
481
482
483
484
485
486
487
488
489
490
491
                int i;
        
                for( i = 0; i < i_devices; i++ )
                {
                    [o_disc_device 
                        addItemWithObjectValue: [o_devices objectAtIndex: i]];
                }

                [o_disc_device selectItemAtIndex: 0];
            }
            else
            {
                [o_disc_device setStringValue: 
                    [NSString stringWithFormat: _NS("No %@s found"), o_disc]];
492
493
494
            }
        }
    }
495

496
497
498
499
500
    [o_disc_device setEnabled: b_device];
    [o_disc_title setEnabled: b_title_chapter];
    [o_disc_title_stp setEnabled: b_title_chapter];
    [o_disc_chapter setEnabled: b_title_chapter];
    [o_disc_chapter_stp setEnabled: b_title_chapter];
501
502
503
    [o_disc_videots_folder setEnabled: !b_device];
    [o_disc_videots_btn_browse setEnabled: !b_device];
    [o_disc_dvd_menus setEnabled: b_menus];
504

505
    [self openDiscInfoChanged: nil];
506
507
}

508
- (IBAction)openDiscStepperChanged:(id)sender
509
{
510
    int i_tag = [sender tag];
511

512
    if( i_tag == 0 )
513
    {
514
        [o_disc_title setIntValue: [o_disc_title_stp intValue]];
515
    }
516
    else if( i_tag == 1 )
517
    {
518
519
        [o_disc_chapter setIntValue: [o_disc_chapter_stp intValue]];
    }
520

521
522
    [self openDiscInfoChanged: nil];
}
523

524
525
526
527
- (void)openDiscInfoChanged:(NSNotification *)o_notification
{
    NSString *o_type;
    NSString *o_device;
528
    NSString *o_videots;
529
530
    NSString *o_mrl_string;
    int i_title, i_chapter;
531
    vlc_bool_t b_menus;
532

533
534
535
536
    o_type = [[o_disc_type selectedCell] title];
    o_device = [o_disc_device stringValue];
    i_title = [o_disc_title intValue];
    i_chapter = [o_disc_chapter intValue];
537
    o_videots = [o_disc_videots_folder stringValue];
538
    b_menus = [o_disc_dvd_menus state];
539
540

    if ( [o_type isEqualToString: _NS("VCD")] )
541
    {
542
543
544
545
546
        if ( [o_device isEqualToString:
                [NSString stringWithFormat: _NS("No %@s found"), o_type]] )
            o_device = @"";
        o_mrl_string = [NSString stringWithFormat: @"vcd://%@@%i,%i",
                        o_device, i_title, i_chapter]; 
547
    }
548
    else if ( [o_type isEqualToString: _NS("DVD")] )
549
    {
550
551
552
        if ( [o_device isEqualToString:
                [NSString stringWithFormat: _NS("No %@s found"), o_type]] )
            o_device = @"";
553
554
555
556
557
558
        if ( b_menus )
            o_mrl_string = [NSString stringWithFormat: @"dvdplay://%@",
                            o_device]; 
        else
            o_mrl_string = [NSString stringWithFormat: @"dvdold://%@@%i,%i",
                            o_device, i_title, i_chapter]; 
559
560
561
    }
    else /* VIDEO_TS folder */
    {
562
563
564
565
566
567
        if ( b_menus )
            o_mrl_string = [NSString stringWithFormat: @"dvdplay://%@",
                            o_videots]; 
        else
            o_mrl_string = [NSString stringWithFormat: @"dvdread://%@@%i,%i",
                            o_videots, i_title, i_chapter]; 
568
    }
569

570
    [o_mrl setStringValue: o_mrl_string]; 
571
572
}

573
574
575
576
577
578
- (IBAction)openDiscMenusChanged:(id)sender
{
    [self openDiscInfoChanged: nil];
    [self openDiscTypeChanged: nil];
}

Christophe Massiot's avatar
Christophe Massiot committed
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
- (IBAction)openVTSBrowse:(id)sender
{
    NSOpenPanel *o_open_panel = [NSOpenPanel openPanel];

    [o_open_panel setAllowsMultipleSelection: NO];
    [o_open_panel setCanChooseFiles: NO];
    [o_open_panel setCanChooseDirectories: YES];
    [o_open_panel setTitle: _NS("Open VIDEO_TS Directory")];
    [o_open_panel setPrompt: _NS("Open")];

    if( [o_open_panel runModalForDirectory: nil
            file: nil types: nil] == NSOKButton )
    {
        NSString *o_dirname = [[o_open_panel filenames] objectAtIndex: 0];
        [o_disc_videots_folder setStringValue: o_dirname];
        [self openDiscInfoChanged: nil];
    }
}

598
599
- (IBAction)openNetModeChanged:(id)sender
{
600
601
602
603
604
    NSString *o_mode;
    BOOL b_udp = FALSE;
    BOOL b_udpm = FALSE;
    BOOL b_cs = FALSE;
    BOOL b_http = FALSE;
605
606
607

    o_mode = [[o_net_mode selectedCell] title];

Christophe Massiot's avatar
Christophe Massiot committed
608
609
610
611
    if( [o_mode isEqualToString: _NS("UDP/RTP")] ) b_udp = TRUE;   
    else if( [o_mode isEqualToString: _NS("UDP/RTP Multicast")] ) b_udpm = TRUE;
    else if( [o_mode isEqualToString: _NS("Channel server")] ) b_cs = TRUE;
    else if( [o_mode isEqualToString: _NS("HTTP/FTP/MMS")] ) b_http = TRUE;
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630

    [o_net_udp_port setEnabled: b_udp];
    [o_net_udp_port_stp setEnabled: b_udp];
    [o_net_udpm_addr setEnabled: b_udpm];
    [o_net_udpm_port setEnabled: b_udpm];
    [o_net_udpm_port_stp setEnabled: b_udpm];
    [o_net_cs_addr setEnabled: b_cs];
    [o_net_cs_port setEnabled: b_cs]; 
    [o_net_cs_port_stp setEnabled: b_cs]; 
    [o_net_http_url setEnabled: b_http];

    [self openNetInfoChanged: nil];
}

- (IBAction)openNetStepperChanged:(id)sender
{
    int i_tag = [sender tag];

    if( i_tag == 0 )
631
    {
632
        [o_net_udp_port setIntValue: [o_net_udp_port_stp intValue]];
633
    }
634
    else if( i_tag == 1 )
635
    {
636
        [o_net_udpm_port setIntValue: [o_net_udpm_port_stp intValue]];
637
    }
638
    else if( i_tag == 2 )
639
    {
640
        [o_net_cs_port setIntValue: [o_net_cs_port_stp intValue]];
641
642
    }

643
644
645
646
647
648
649
650
651
652
653
654
    [self openNetInfoChanged: nil];
}

- (void)openNetInfoChanged:(NSNotification *)o_notification
{
    NSString *o_mode;
    vlc_bool_t b_channel;
    NSString *o_mrl_string = [NSString string];
    intf_thread_t * p_intf = [NSApp getIntf];

    o_mode = [[o_net_mode selectedCell] title];

655
    b_channel = (vlc_bool_t)[o_mode isEqualToString: _NS("Channel server")]; 
656
657
    config_PutInt( p_intf, "network-channel", b_channel );

658
    if( [o_mode isEqualToString: _NS("UDP/RTP")] )
659
    {
660
661
662
663
        int i_port = [o_net_udp_port intValue];

        o_mrl_string = [NSString stringWithString: @"udp://"]; 

664
        if( i_port != config_GetInt( p_intf, "server-port" ) )
665
666
667
668
        {
            o_mrl_string = 
                [o_mrl_string stringByAppendingFormat: @"@:%i", i_port]; 
        } 
669
    }
670
    else if( [o_mode isEqualToString: _NS("UDP/RTP Multicast")] ) 
671
    {
672
673
674
675
        NSString *o_addr = [o_net_udpm_addr stringValue];
        int i_port = [o_net_udpm_port intValue];

        o_mrl_string = [NSString stringWithFormat: @"udp://@%@", o_addr]; 
676

677
        if( i_port != config_GetInt( p_intf, "server-port" ) )
678
679
680
681
682
        {
            o_mrl_string = 
                [o_mrl_string stringByAppendingFormat: @":%i", i_port]; 
        } 
    }
683
    else if( [o_mode isEqualToString: _NS("Channel server")] )
684
    {
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
        NSString *o_addr = [o_net_cs_addr stringValue];
        int i_port = [o_net_cs_port intValue];

        if( p_intf->p_vlc->p_channel == NULL )
        {
            network_ChannelCreate( p_intf );
        } 

        config_PutPsz( p_intf, "channel-server", [o_addr lossyCString] ); 
        if( i_port < 65536 )
        {
            config_PutInt( p_intf, "channel-port", i_port );
        }

        /* FIXME: we should use a playlist server instead */
        o_mrl_string = [NSString stringWithString: @"udp://"];
701
    }
702
    else if( [o_mode isEqualToString: _NS("HTTP/FTP/MMS")] )
703
    {
704
705
        NSString *o_url = [o_net_http_url stringValue];

706
707
708
709
710
        if ( ![o_url hasPrefix:@"http:"] && ![o_url hasPrefix:@"ftp:"]
              && ![o_url hasPrefix:@"mms"] )
            o_mrl_string = [NSString stringWithFormat: @"http://%@", o_url];
        else
            o_mrl_string = o_url;
711
    }
712
713

    [o_mrl setStringValue: o_mrl_string];
714
715
}

Christophe Massiot's avatar
Christophe Massiot committed
716
- (IBAction)soutChanged:(id)sender;
717
{
Christophe Massiot's avatar
Christophe Massiot committed
718
    [self soutModeChanged: nil];
719

Christophe Massiot's avatar
Christophe Massiot committed
720
    if ( [o_sout_cbox state] )
721
    {
Christophe Massiot's avatar
Christophe Massiot committed
722
723
724
725
726
727
728
729
730
        NSPoint s_point;
        s_point.x = 0;
        s_point.y = 0;
        [[o_panel contentView] setBoundsOrigin: s_point];
        [[o_panel contentView] setNeedsDisplay: YES];

        NSRect s_rect = [o_panel frame];
        s_rect.size.height = OPEN_PANEL_FULL_HEIGHT + WINDOW_TITLE_HEIGHT;
        s_rect.origin.y -= OPEN_PANEL_FULL_HEIGHT - OPEN_PANEL_SHORT_HEIGHT;
hartman's avatar
hartman committed
731
        [o_panel setFrame: s_rect display: YES animate: NO];
Christophe Massiot's avatar
Christophe Massiot committed
732
733
734
735
736
737
738
739
740
741
742
743
    }
    else
    {
        NSPoint s_point;
        s_point.x = 0;
        s_point.y = OPEN_PANEL_FULL_HEIGHT - OPEN_PANEL_SHORT_HEIGHT;
        [[o_panel contentView] setBoundsOrigin: s_point];
        [[o_panel contentView] setNeedsDisplay: YES];

        NSRect s_rect = [o_panel frame];
        s_rect.size.height = OPEN_PANEL_SHORT_HEIGHT + WINDOW_TITLE_HEIGHT;
        s_rect.origin.y += OPEN_PANEL_FULL_HEIGHT - OPEN_PANEL_SHORT_HEIGHT;
hartman's avatar
hartman committed
744
        [o_panel setFrame: s_rect display: YES animate:NO];
745
746
747
    }
}

Christophe Massiot's avatar
Christophe Massiot committed
748
- (IBAction)soutFileBrowse:(id)sender
749
{
Christophe Massiot's avatar
Christophe Massiot committed
750
751
752
753
754
755
    NSSavePanel *o_save_panel = [NSSavePanel savePanel];
    NSString *o_mux_string;
    if ( [[[o_sout_mux selectedCell] title] isEqualToString: _NS("PS")] )
        o_mux_string = @"vob";
    else
        o_mux_string = @"ts";
756

Christophe Massiot's avatar
Christophe Massiot committed
757
758
    NSString * o_name = [NSString stringWithFormat: @"vlc-output.%@",
                         o_mux_string];
759

Christophe Massiot's avatar
Christophe Massiot committed
760
761
762
763
764
    [o_save_panel setTitle: _NS("Save File")];
    [o_save_panel setPrompt: _NS("Save")];

    if( [o_save_panel runModalForDirectory: nil
            file: o_name] == NSOKButton )
765
    {
Christophe Massiot's avatar
Christophe Massiot committed
766
767
768
        NSString *o_filename = [o_save_panel filename];
        [o_sout_file_path setStringValue: o_filename];
        [self soutInfoChanged: nil];
769
770
771
    }
}

Christophe Massiot's avatar
Christophe Massiot committed
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
- (void)soutModeChanged:(NSNotification *)o_notification
{
    NSString *o_mode;
    BOOL b_file = FALSE;
    BOOL b_udp = FALSE;
    BOOL b_rtp = FALSE;

    o_mode = [[o_sout_access selectedCell] title];

    if( [o_mode isEqualToString: _NS("File")] ) b_file = TRUE;   
    else if( [o_mode isEqualToString: _NS("UDP")] ) b_udp = TRUE;
    else if( [o_mode isEqualToString: _NS("RTP")] ) b_rtp = TRUE;

    [o_sout_file_path setEnabled: b_file];
    [o_sout_file_btn_browse setEnabled: b_file];
    [o_sout_udp_addr setEnabled: b_udp|b_rtp];
    [o_sout_udp_port setEnabled: b_udp|b_rtp];
    [o_sout_udp_port_stp setEnabled: b_udp|b_rtp];
    [[o_sout_mux cellAtRow:0 column: 0] setEnabled: !b_rtp];

    if ( b_rtp )
    {
        [[o_sout_mux cellAtRow: 0 column:1] setState: YES];
    }

    [self soutInfoChanged: nil];
}

- (void)soutInfoChanged:(NSNotification *)o_notification
{
    NSString *o_mode;
    NSString *o_mux;
    NSString *o_mrl_string;
    NSString *o_mux_string;

    o_mode = [[o_sout_access selectedCell] title];
    o_mux = [[o_sout_mux selectedCell] title];

    if ( [o_mux isEqualToString: _NS("PS")] ) o_mux_string = @"ps";
    else o_mux_string = @"ts";

    if ( [o_mode isEqualToString: _NS("File")] )
    {
        o_mrl_string = [NSString stringWithFormat: @"file/%@://%@",
                        o_mux_string, [o_sout_file_path stringValue]];
    }
    else if ( [o_mode isEqualToString: _NS("UDP")] )
    {
        o_mrl_string = [NSString stringWithFormat: @"udp/%@://%@:%i",
                        o_mux_string, [o_sout_udp_addr stringValue],
                        [o_sout_udp_port intValue]];
    }
    else
    {
        o_mrl_string = [NSString stringWithFormat: @"rtp/%@://%@:%i",
                        o_mux_string, [o_sout_udp_addr stringValue],
                        [o_sout_udp_port intValue]];
    }


    [o_sout_mrl setStringValue: o_mrl_string];
}

- (IBAction)soutStepperChanged:(id)sender
{
    [o_sout_udp_port setIntValue: [o_net_udp_port_stp intValue]];

    [self soutInfoChanged: nil];
}

842
843
- (IBAction)openFile:(id)sender
{
844
845
    [self openFilePathChanged: nil];
    [self openTarget: 0];
846
847
}

848
849
850
851
852
853
854
- (IBAction)panelCancel:(id)sender
{
    [NSApp stopModalWithCode: 0];
}

- (IBAction)panelOk:(id)sender
{
855
856
857
858
859
860
861
862
    if( [[o_mrl stringValue] length] )
    {
        [NSApp stopModalWithCode: 1];
    }
    else
    {
        NSBeep();
    }
863
864
865
}

@end