00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include <stdlib.h>
00030 #include <sys/param.h>
00031 #include <string.h>
00032 #include <vlc_keys.h>
00033
00034 #include "intf.h"
00035 #include "vout.h"
00036 #include "prefs.h"
00037 #include "playlist.h"
00038 #include "controls.h"
00039 #include "about.h"
00040 #include "open.h"
00041 #include "wizard.h"
00042 #include "extended.h"
00043 #include "bookmarks.h"
00044
00045
00046
00047
00048
00049 static void Run ( intf_thread_t *p_intf );
00050
00051
00052
00053
00054 int E_(OpenIntf) ( vlc_object_t *p_this )
00055 {
00056 intf_thread_t *p_intf = (intf_thread_t*) p_this;
00057
00058 p_intf->p_sys = malloc( sizeof( intf_sys_t ) );
00059 if( p_intf->p_sys == NULL )
00060 {
00061 return( 1 );
00062 }
00063
00064 memset( p_intf->p_sys, 0, sizeof( *p_intf->p_sys ) );
00065
00066 p_intf->p_sys->o_pool = [[NSAutoreleasePool alloc] init];
00067
00068
00069
00070
00071
00072 [NSThread detachNewThreadSelector:@selector(self) toTarget:[NSString string] withObject:nil];
00073
00074 p_intf->p_sys->o_sendport = [[NSPort port] retain];
00075 p_intf->p_sys->p_sub = msg_Subscribe( p_intf );
00076 p_intf->b_play = VLC_TRUE;
00077 p_intf->pf_run = Run;
00078
00079 return( 0 );
00080 }
00081
00082
00083
00084
00085 void E_(CloseIntf) ( vlc_object_t *p_this )
00086 {
00087 intf_thread_t *p_intf = (intf_thread_t*) p_this;
00088
00089 msg_Unsubscribe( p_intf, p_intf->p_sys->p_sub );
00090
00091 [p_intf->p_sys->o_sendport release];
00092 [p_intf->p_sys->o_pool release];
00093
00094 free( p_intf->p_sys );
00095 }
00096
00097
00098
00099
00100 static void Run( intf_thread_t *p_intf )
00101 {
00102
00103
00104
00105 vlc_thread_set_priority( p_intf, VLC_THREAD_PRIORITY_LOW );
00106 [[VLCMain sharedInstance] setIntf: p_intf];
00107 [NSBundle loadNibNamed: @"MainMenu" owner: NSApp];
00108 [NSApp run];
00109 [[VLCMain sharedInstance] terminate];
00110 }
00111
00112 int ExecuteOnMainThread( id target, SEL sel, void * p_arg )
00113 {
00114 int i_ret = 0;
00115
00116
00117
00118 if( [target respondsToSelector: @selector(performSelectorOnMainThread:
00119 withObject:waitUntilDone:)] )
00120 {
00121 [target performSelectorOnMainThread: sel
00122 withObject: [NSValue valueWithPointer: p_arg]
00123 waitUntilDone: NO];
00124 }
00125 else if( NSApp != nil && [[VLCMain sharedInstance] respondsToSelector: @selector(getIntf)] )
00126 {
00127 NSValue * o_v1;
00128 NSValue * o_v2;
00129 NSArray * o_array;
00130 NSPort * o_recv_port;
00131 NSInvocation * o_inv;
00132 NSPortMessage * o_msg;
00133 intf_thread_t * p_intf;
00134 NSConditionLock * o_lock;
00135 NSMethodSignature * o_sig;
00136
00137 id * val[] = { &o_lock, &o_v2 };
00138
00139 p_intf = (intf_thread_t *)VLCIntf;
00140
00141 o_recv_port = [[NSPort port] retain];
00142 o_v1 = [NSValue valueWithPointer: val];
00143 o_v2 = [NSValue valueWithPointer: p_arg];
00144
00145 o_sig = [target methodSignatureForSelector: sel];
00146 o_inv = [NSInvocation invocationWithMethodSignature: o_sig];
00147 [o_inv setArgument: &o_v1 atIndex: 2];
00148 [o_inv setTarget: target];
00149 [o_inv setSelector: sel];
00150
00151 o_array = [NSArray arrayWithObject:
00152 [NSData dataWithBytes: &o_inv length: sizeof(o_inv)]];
00153 o_msg = [[NSPortMessage alloc]
00154 initWithSendPort: p_intf->p_sys->o_sendport
00155 receivePort: o_recv_port components: o_array];
00156
00157 o_lock = [[NSConditionLock alloc] initWithCondition: 0];
00158 [o_msg sendBeforeDate: [NSDate distantPast]];
00159 [o_lock lockWhenCondition: 1];
00160 [o_lock unlock];
00161 [o_lock release];
00162
00163 [o_msg release];
00164 [o_recv_port release];
00165 }
00166 else
00167 {
00168 i_ret = 1;
00169 }
00170
00171
00172
00173 return( i_ret );
00174 }
00175
00176
00177
00178
00179
00180 int PlaylistChanged( vlc_object_t *p_this, const char *psz_variable,
00181 vlc_value_t old_val, vlc_value_t new_val, void *param )
00182 {
00183 intf_thread_t * p_intf = VLCIntf;
00184 p_intf->p_sys->b_playlist_update = TRUE;
00185 p_intf->p_sys->b_intf_update = TRUE;
00186 p_intf->p_sys->b_playmode_update = TRUE;
00187 return VLC_SUCCESS;
00188 }
00189
00190
00191
00192
00193
00194 int FullscreenChanged( vlc_object_t *p_this, const char *psz_variable,
00195 vlc_value_t old_val, vlc_value_t new_val, void *param )
00196 {
00197 intf_thread_t * p_intf = VLCIntf;
00198 p_intf->p_sys->b_fullscreen_update = TRUE;
00199 return VLC_SUCCESS;
00200 }
00201
00202
00203 static struct
00204 {
00205 unichar i_nskey;
00206 unsigned int i_vlckey;
00207 } nskeys_to_vlckeys[] =
00208 {
00209 { NSUpArrowFunctionKey, KEY_UP },
00210 { NSDownArrowFunctionKey, KEY_DOWN },
00211 { NSLeftArrowFunctionKey, KEY_LEFT },
00212 { NSRightArrowFunctionKey, KEY_RIGHT },
00213 { NSF1FunctionKey, KEY_F1 },
00214 { NSF2FunctionKey, KEY_F2 },
00215 { NSF3FunctionKey, KEY_F3 },
00216 { NSF4FunctionKey, KEY_F4 },
00217 { NSF5FunctionKey, KEY_F5 },
00218 { NSF6FunctionKey, KEY_F6 },
00219 { NSF7FunctionKey, KEY_F7 },
00220 { NSF8FunctionKey, KEY_F8 },
00221 { NSF9FunctionKey, KEY_F9 },
00222 { NSF10FunctionKey, KEY_F10 },
00223 { NSF11FunctionKey, KEY_F11 },
00224 { NSF12FunctionKey, KEY_F12 },
00225 { NSHomeFunctionKey, KEY_HOME },
00226 { NSEndFunctionKey, KEY_END },
00227 { NSPageUpFunctionKey, KEY_PAGEUP },
00228 { NSPageDownFunctionKey, KEY_PAGEDOWN },
00229 { NSTabCharacter, KEY_TAB },
00230 { NSCarriageReturnCharacter, KEY_ENTER },
00231 { NSEnterCharacter, KEY_ENTER },
00232 { NSBackspaceCharacter, KEY_BACKSPACE },
00233 { (unichar) ' ', KEY_SPACE },
00234 { (unichar) 0x1b, KEY_ESC },
00235 {0,0}
00236 };
00237
00238 unichar VLCKeyToCocoa( unsigned int i_key )
00239 {
00240 unsigned int i;
00241
00242 for( i = 0; nskeys_to_vlckeys[i].i_vlckey != 0; i++ )
00243 {
00244 if( nskeys_to_vlckeys[i].i_vlckey == (i_key & ~KEY_MODIFIER) )
00245 {
00246 return nskeys_to_vlckeys[i].i_nskey;
00247 }
00248 }
00249 return (unichar)(i_key & ~KEY_MODIFIER);
00250 }
00251
00252 unsigned int CocoaKeyToVLC( unichar i_key )
00253 {
00254 unsigned int i;
00255
00256 for( i = 0; nskeys_to_vlckeys[i].i_nskey != 0; i++ )
00257 {
00258 if( nskeys_to_vlckeys[i].i_nskey == i_key )
00259 {
00260 return nskeys_to_vlckeys[i].i_vlckey;
00261 }
00262 }
00263 return (unsigned int)i_key;
00264 }
00265
00266 unsigned int VLCModifiersToCocoa( unsigned int i_key )
00267 {
00268 unsigned int new = 0;
00269 if( i_key & KEY_MODIFIER_COMMAND )
00270 new |= NSCommandKeyMask;
00271 if( i_key & KEY_MODIFIER_ALT )
00272 new |= NSAlternateKeyMask;
00273 if( i_key & KEY_MODIFIER_SHIFT )
00274 new |= NSShiftKeyMask;
00275 if( i_key & KEY_MODIFIER_CTRL )
00276 new |= NSControlKeyMask;
00277 return new;
00278 }
00279
00280
00281
00282
00283 @implementation VLCMain
00284
00285 static VLCMain *_o_sharedMainInstance = nil;
00286
00287 + (VLCMain *)sharedInstance
00288 {
00289 return _o_sharedMainInstance ? _o_sharedMainInstance : [[self alloc] init];
00290 }
00291
00292 - (id)init
00293 {
00294 if( _o_sharedMainInstance) {
00295 [self dealloc];
00296 } else {
00297 _o_sharedMainInstance = [super init];
00298 }
00299
00300 o_about = [[VLAboutBox alloc] init];
00301 o_prefs = nil;
00302 o_open = [[VLCOpen alloc] init];
00303 o_wizard = [[VLCWizard alloc] init];
00304 o_extended = nil;
00305 o_bookmarks = [[VLCBookmarks alloc] init];
00306
00307
00308 i_lastShownVolume = -1;
00309 return _o_sharedMainInstance;
00310 }
00311
00312 - (void)setIntf: (intf_thread_t *)p_mainintf {
00313 p_intf = p_mainintf;
00314 }
00315
00316 - (intf_thread_t *)getIntf {
00317 return p_intf;
00318 }
00319
00320 - (void)awakeFromNib
00321 {
00322 unsigned int i_key = 0;
00323 playlist_t *p_playlist;
00324 vlc_value_t val;
00325
00326
00327 if( nib_main_loaded ) return;
00328
00329 [self initStrings];
00330 [o_window setExcludedFromWindowsMenu: TRUE];
00331 [o_msgs_panel setExcludedFromWindowsMenu: TRUE];
00332 [o_msgs_panel setDelegate: self];
00333
00334 i_key = config_GetInt( p_intf, "key-quit" );
00335 [o_mi_quit setKeyEquivalent: [NSString stringWithFormat:@"%C", VLCKeyToCocoa( i_key )]];
00336 [o_mi_quit setKeyEquivalentModifierMask: VLCModifiersToCocoa(i_key)];
00337 i_key = config_GetInt( p_intf, "key-play-pause" );
00338 [o_mi_play setKeyEquivalent: [NSString stringWithFormat:@"%C", VLCKeyToCocoa( i_key )]];
00339 [o_mi_play setKeyEquivalentModifierMask: VLCModifiersToCocoa(i_key)];
00340 i_key = config_GetInt( p_intf, "key-stop" );
00341 [o_mi_stop setKeyEquivalent: [NSString stringWithFormat:@"%C", VLCKeyToCocoa( i_key )]];
00342 [o_mi_stop setKeyEquivalentModifierMask: VLCModifiersToCocoa(i_key)];
00343 i_key = config_GetInt( p_intf, "key-faster" );
00344 [o_mi_faster setKeyEquivalent: [NSString stringWithFormat:@"%C", VLCKeyToCocoa( i_key )]];
00345 [o_mi_faster setKeyEquivalentModifierMask: VLCModifiersToCocoa(i_key)];
00346 i_key = config_GetInt( p_intf, "key-slower" );
00347 [o_mi_slower setKeyEquivalent: [NSString stringWithFormat:@"%C", VLCKeyToCocoa( i_key )]];
00348 [o_mi_slower setKeyEquivalentModifierMask: VLCModifiersToCocoa(i_key)];
00349 i_key = config_GetInt( p_intf, "key-prev" );
00350 [o_mi_previous setKeyEquivalent: [NSString stringWithFormat:@"%C", VLCKeyToCocoa( i_key )]];
00351 [o_mi_previous setKeyEquivalentModifierMask: VLCModifiersToCocoa(i_key)];
00352 i_key = config_GetInt( p_intf, "key-next" );
00353 [o_mi_next setKeyEquivalent: [NSString stringWithFormat:@"%C", VLCKeyToCocoa( i_key )]];
00354 [o_mi_next setKeyEquivalentModifierMask: VLCModifiersToCocoa(i_key)];
00355 i_key = config_GetInt( p_intf, "key-jump+10sec" );
00356 [o_mi_fwd setKeyEquivalent: [NSString stringWithFormat:@"%C", VLCKeyToCocoa( i_key )]];
00357 [o_mi_fwd setKeyEquivalentModifierMask: VLCModifiersToCocoa(i_key)];
00358 i_key = config_GetInt( p_intf, "key-jump-10sec" );
00359 [o_mi_bwd setKeyEquivalent: [NSString stringWithFormat:@"%C", VLCKeyToCocoa( i_key )]];
00360 [o_mi_bwd setKeyEquivalentModifierMask: VLCModifiersToCocoa(i_key)];
00361 i_key = config_GetInt( p_intf, "key-jump+1min" );
00362 [o_mi_fwd1m setKeyEquivalent: [NSString stringWithFormat:@"%C", VLCKeyToCocoa( i_key )]];
00363 [o_mi_fwd1m setKeyEquivalentModifierMask: VLCModifiersToCocoa(i_key)];
00364 i_key = config_GetInt( p_intf, "key-jump-1min" );
00365 [o_mi_bwd1m setKeyEquivalent: [NSString stringWithFormat:@"%C", VLCKeyToCocoa( i_key )]];
00366 [o_mi_bwd1m setKeyEquivalentModifierMask: VLCModifiersToCocoa(i_key)];
00367 i_key = config_GetInt( p_intf, "key-jump+5min" );
00368 [o_mi_fwd5m setKeyEquivalent: [NSString stringWithFormat:@"%C", VLCKeyToCocoa( i_key )]];
00369 [o_mi_fwd5m setKeyEquivalentModifierMask: VLCModifiersToCocoa(i_key)];
00370 i_key = config_GetInt( p_intf, "key-jump-5min" );
00371 [o_mi_bwd5m setKeyEquivalent: [NSString stringWithFormat:@"%C", VLCKeyToCocoa( i_key )]];
00372 [o_mi_bwd5m setKeyEquivalentModifierMask: VLCModifiersToCocoa(i_key)];
00373 i_key = config_GetInt( p_intf, "key-vol-up" );
00374 [o_mi_vol_up setKeyEquivalent: [NSString stringWithFormat:@"%C", VLCKeyToCocoa( i_key )]];
00375 [o_mi_vol_up setKeyEquivalentModifierMask: VLCModifiersToCocoa(i_key)];
00376 i_key = config_GetInt( p_intf, "key-vol-down" );
00377 [o_mi_vol_down setKeyEquivalent: [NSString stringWithFormat:@"%C", VLCKeyToCocoa( i_key )]];
00378 [o_mi_vol_down setKeyEquivalentModifierMask: VLCModifiersToCocoa(i_key)];
00379 i_key = config_GetInt( p_intf, "key-vol-mute" );
00380 [o_mi_mute setKeyEquivalent: [NSString stringWithFormat:@"%C", VLCKeyToCocoa( i_key )]];
00381 [o_mi_mute setKeyEquivalentModifierMask: VLCModifiersToCocoa(i_key)];
00382 i_key = config_GetInt( p_intf, "key-fullscreen" );
00383 [o_mi_fullscreen setKeyEquivalent: [NSString stringWithFormat:@"%C", VLCKeyToCocoa( i_key )]];
00384 [o_mi_fullscreen setKeyEquivalentModifierMask: VLCModifiersToCocoa(i_key)];
00385 i_key = config_GetInt( p_intf, "key-snapshot" );
00386 [o_mi_snapshot setKeyEquivalent: [NSString stringWithFormat:@"%C", VLCKeyToCocoa( i_key )]];
00387 [o_mi_snapshot setKeyEquivalentModifierMask: VLCModifiersToCocoa(i_key)];
00388
00389 var_Create( p_intf, "intf-change", VLC_VAR_BOOL );
00390
00391 [self setSubmenusEnabled: FALSE];
00392 [self manageVolumeSlider];
00393 [o_window setDelegate: self];
00394
00395 if( [o_window frame].size.height <= 200 )
00396 {
00397 b_small_window = YES;
00398 [o_window setFrame: NSMakeRect( [o_window frame].origin.x,
00399 [o_window frame].origin.y, [o_window frame].size.width,
00400 [o_window minSize].height ) display: YES animate:YES];
00401 [o_playlist_view setAutoresizesSubviews: NO];
00402 }
00403 else
00404 {
00405 b_small_window = NO;
00406 [o_playlist_view setFrame: NSMakeRect( 10, 10, [o_window frame].size.width - 20, [o_window frame].size.height - 105 )];
00407 [o_playlist_view setNeedsDisplay:YES];
00408 [o_playlist_view setAutoresizesSubviews: YES];
00409 [[o_window contentView] addSubview: o_playlist_view];
00410 }
00411 [self updateTogglePlaylistState];
00412
00413 o_size_with_playlist = [o_window frame].size;
00414
00415 p_playlist = (playlist_t *) vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
00416
00417 if( p_playlist )
00418 {
00419
00420 if( p_intf->b_play )
00421 {
00422 playlist_LockControl( p_playlist, PLAYLIST_AUTOPLAY );
00423 }
00424 var_Create( p_playlist, "fullscreen", VLC_VAR_BOOL | VLC_VAR_DOINHERIT);
00425 val.b_bool = VLC_FALSE;
00426
00427 var_AddCallback( p_playlist, "fullscreen", FullscreenChanged, self);
00428
00429 [o_btn_fullscreen setState: ( var_Get( p_playlist, "fullscreen", &val )>=0 && val.b_bool )];
00430 vlc_object_release( p_playlist );
00431 }
00432 nib_main_loaded = TRUE;
00433 }
00434
00435 - (void)initStrings
00436 {
00437 [o_window setTitle: _NS("VLC - Controller")];
00438 [self setScrollField:_NS("VLC media player") stopAfter:-1];
00439
00440
00441 [o_btn_prev setToolTip: _NS("Previous")];
00442 [o_btn_rewind setToolTip: _NS("Rewind")];
00443 [o_btn_play setToolTip: _NS("Play")];
00444 [o_btn_stop setToolTip: _NS("Stop")];
00445 [o_btn_ff setToolTip: _NS("Fast Forward")];
00446 [o_btn_next setToolTip: _NS("Next")];
00447 [o_btn_fullscreen setToolTip: _NS("Fullscreen")];
00448 [o_volumeslider setToolTip: _NS("Volume")];
00449 [o_timeslider setToolTip: _NS("Position")];
00450 [o_btn_playlist setToolTip: _NS("Playlist")];
00451
00452
00453 [o_msgs_panel setTitle: _NS("Messages")];
00454 [o_msgs_btn_crashlog setTitle: _NS("Open CrashLog")];
00455
00456
00457 [o_mi_about setTitle: [_NS("About VLC media player") \
00458 stringByAppendingString: @"..."]];
00459
00460 [o_mi_prefs setTitle: _NS("Preferences...")];
00461 [o_mi_add_intf setTitle: _NS("Add Interface")];
00462 [o_mu_add_intf setTitle: _NS("Add Interface")];
00463 [o_mi_services setTitle: _NS("Services")];
00464 [o_mi_hide setTitle: _NS("Hide VLC")];
00465 [o_mi_hide_others setTitle: _NS("Hide Others")];
00466 [o_mi_show_all setTitle: _NS("Show All")];
00467 [o_mi_quit setTitle: _NS("Quit VLC")];
00468
00469 [o_mu_file setTitle: _ANS("1:File")];
00470 [o_mi_open_generic setTitle: _NS("Open File...")];
00471 [o_mi_open_file setTitle: _NS("Quick Open File...")];
00472 [o_mi_open_disc setTitle: _NS("Open Disc...")];
00473 [o_mi_open_net setTitle: _NS("Open Network...")];
00474 [o_mi_open_recent setTitle: _NS("Open Recent")];
00475 [o_mi_open_recent_cm setTitle: _NS("Clear Menu")];
00476 [o_mi_open_wizard setTitle: _NS("Streaming/Exporting Wizard...")];
00477
00478 [o_mu_edit setTitle: _NS("Edit")];
00479 [o_mi_cut setTitle: _NS("Cut")];
00480 [o_mi_copy setTitle: _NS("Copy")];
00481 [o_mi_paste setTitle: _NS("Paste")];
00482 [o_mi_clear setTitle: _NS("Clear")];
00483 [o_mi_select_all setTitle: _NS("Select All")];
00484
00485 [o_mu_controls setTitle: _NS("Playback")];
00486 [o_mi_play setTitle: _NS("Play")];
00487 [o_mi_stop setTitle: _NS("Stop")];
00488 [o_mi_faster setTitle: _NS("Faster")];
00489 [o_mi_slower setTitle: _NS("Slower")];
00490 [o_mi_previous setTitle: _NS("Previous")];
00491 [o_mi_next setTitle: _NS("Next")];
00492 [o_mi_random setTitle: _NS("Random")];
00493 [o_mi_repeat setTitle: _NS("Repeat One")];
00494 [o_mi_loop setTitle: _NS("Repeat All")];
00495 [o_mi_fwd setTitle: _NS("Step Forward")];
00496 [o_mi_bwd setTitle: _NS("Step Backward")];
00497
00498 [o_mi_program setTitle: _NS("Program")];
00499 [o_mu_program setTitle: _NS("Program")];
00500 [o_mi_title setTitle: _NS("Title")];
00501 [o_mu_title setTitle: _NS("Title")];
00502 [o_mi_chapter setTitle: _NS("Chapter")];
00503 [o_mu_chapter setTitle: _NS("Chapter")];
00504
00505 [o_mu_audio setTitle: _NS("Audio")];
00506 [o_mi_vol_up setTitle: _NS("Volume Up")];
00507 [o_mi_vol_down setTitle: _NS("Volume Down")];
00508 [o_mi_mute setTitle: _NS("Mute")];
00509 [o_mi_audiotrack setTitle: _NS("Audio Track")];
00510 [o_mu_audiotrack setTitle: _NS("Audio Track")];
00511 [o_mi_channels setTitle: _NS("Audio Channels")];
00512 [o_mu_channels setTitle: _NS("Audio Channels")];
00513 [o_mi_device setTitle: _NS("Audio Device")];
00514 [o_mu_device setTitle: _NS("Audio Device")];
00515 [o_mi_visual setTitle: _NS("Visualizations")];
00516 [o_mu_visual setTitle: _NS("Visualizations")];
00517
00518 [o_mu_video setTitle: _NS("Video")];
00519 [o_mi_half_window setTitle: _NS("Half Size")];
00520 [o_mi_normal_window setTitle: _NS("Normal Size")];
00521 [o_mi_double_window setTitle: _NS("Double Size")];
00522 [o_mi_fittoscreen setTitle: _NS("Fit to Screen")];
00523 [o_mi_fullscreen setTitle: _NS("Fullscreen")];
00524 [o_mi_floatontop setTitle: _NS("Float on Top")];
00525 [o_mi_snapshot setTitle: _NS("Snapshot")];
00526 [o_mi_videotrack setTitle: _NS("Video Track")];
00527 [o_mu_videotrack setTitle: _NS("Video Track")];
00528 [o_mi_screen setTitle: _NS("Video Device")];
00529 [o_mu_screen setTitle: _NS("Video Device")];
00530 [o_mi_subtitle setTitle: _NS("Subtitles Track")];
00531 [o_mu_subtitle setTitle: _NS("Subtitles Track")];
00532 [o_mi_deinterlace setTitle: _NS("Deinterlace")];
00533 [o_mu_deinterlace setTitle: _NS("Deinterlace")];
00534 [o_mi_ffmpeg_pp setTitle: _NS("Post processing")];
00535 [o_mu_ffmpeg_pp setTitle: _NS("Post processing")];
00536
00537 [o_mu_window setTitle: _NS("Window")];
00538 [o_mi_minimize setTitle: _NS("Minimize Window")];
00539 [o_mi_close_window setTitle: _NS("Close Window")];
00540 [o_mi_controller setTitle: _NS("Controller")];
00541 [o_mi_equalizer setTitle: _NS("Equalizer")];
00542 [o_mi_extended setTitle: _NS("Extended Controls")];
00543 [o_mi_bookmarks setTitle: _NS("Bookmarks")];
00544 [o_mi_playlist setTitle: _NS("Playlist")];
00545 [o_mi_info setTitle: _NS("Info")];
00546 [o_mi_messages setTitle: _NS("Messages")];
00547
00548 [o_mi_bring_atf setTitle: _NS("Bring All to Front")];
00549
00550 [o_mu_help setTitle: _NS("Help")];
00551 [o_mi_readme setTitle: _NS("ReadMe...")];
00552 [o_mi_documentation setTitle: _NS("Online Documentation")];
00553 [o_mi_reportabug setTitle: _NS("Report a Bug")];
00554 [o_mi_website setTitle: _NS("VideoLAN Website")];
00555 [o_mi_license setTitle: _NS("License")];
00556 [o_mi_donation setTitle: _NS("Make a donation")];
00557 [o_mi_forum setTitle: _NS("Online Forum")];
00558
00559
00560 [o_dmi_play setTitle: _NS("Play")];
00561 [o_dmi_stop setTitle: _NS("Stop")];
00562 [o_dmi_next setTitle: _NS("Next")];
00563 [o_dmi_previous setTitle: _NS("Previous")];
00564 [o_dmi_mute setTitle: _NS("Mute")];
00565
00566
00567 [o_error setTitle: _NS("Error")];
00568 [o_err_lbl setStringValue: _NS("An error has occurred which probably " \
00569 "prevented the execution of your request:")];
00570 [o_err_bug_lbl setStringValue: _NS("If you believe that it is a bug, " \
00571 "please follow the instructions at:")];
00572 [o_err_btn_msgs setTitle: _NS("Open Messages Window")];
00573 [o_err_btn_dismiss setTitle: _NS("Dismiss")];
00574 [o_err_ckbk_surpress setTitle: _NS("Suppress further errors")];
00575
00576 [o_info_window setTitle: _NS("Info")];
00577 }
00578
00579 - (void)applicationWillFinishLaunching:(NSNotification *)o_notification
00580 {
00581 o_msg_lock = [[NSLock alloc] init];
00582 o_msg_arr = [[NSMutableArray arrayWithCapacity: 200] retain];
00583
00584 o_img_play = [[NSImage imageNamed: @"play"] retain];
00585 o_img_play_pressed = [[NSImage imageNamed: @"play_blue"] retain];
00586 o_img_pause = [[NSImage imageNamed: @"pause"] retain];
00587 o_img_pause_pressed = [[NSImage imageNamed: @"pause_blue"] retain];
00588
00589 [p_intf->p_sys->o_sendport setDelegate: self];
00590 [[NSRunLoop currentRunLoop]
00591 addPort: p_intf->p_sys->o_sendport
00592 forMode: NSDefaultRunLoopMode];
00593
00594 [NSTimer scheduledTimerWithTimeInterval: 0.5
00595 target: self selector: @selector(manageIntf:)
00596 userInfo: nil repeats: FALSE];
00597
00598 [NSThread detachNewThreadSelector: @selector(manage)
00599 toTarget: self withObject: nil];
00600
00601 [o_controls setupVarMenuItem: o_mi_add_intf target: (vlc_object_t *)p_intf
00602 var: "intf-add" selector: @selector(toggleVar:)];
00603
00604 vlc_thread_set_priority( p_intf, VLC_THREAD_PRIORITY_LOW );
00605 }
00606
00607 - (BOOL)application:(NSApplication *)o_app openFile:(NSString *)o_filename
00608 {
00609 NSDictionary *o_dic = [NSDictionary dictionaryWithObjectsAndKeys: o_filename, @"ITEM_URL", nil];
00610 [o_playlist appendArray:
00611 [NSArray arrayWithObject: o_dic] atPos: -1 enqueue: NO];
00612
00613 return( TRUE );
00614 }
00615
00616 - (NSString *)localizedString:(char *)psz
00617 {
00618 NSString * o_str = nil;
00619
00620 if( psz != NULL )
00621 {
00622 o_str = [[[NSString alloc] initWithUTF8String: psz] autorelease];
00623 }
00624 if ( o_str == NULL )
00625 {
00626 msg_Err( VLCIntf, "could not translate: %s", psz );
00627 }
00628
00629 return( o_str );
00630 }
00631
00632 - (char *)delocalizeString:(NSString *)id
00633 {
00634 NSData * o_data = [id dataUsingEncoding: NSUTF8StringEncoding
00635 allowLossyConversion: NO];
00636 char * psz_string;
00637
00638 if ( o_data == nil )
00639 {
00640 o_data = [id dataUsingEncoding: NSUTF8StringEncoding
00641 allowLossyConversion: YES];
00642 psz_string = malloc( [o_data length] + 1 );
00643 [o_data getBytes: psz_string];
00644 psz_string[ [o_data length] ] = '\0';
00645 msg_Err( VLCIntf, "cannot convert to wanted encoding: %s",
00646 psz_string );
00647 }
00648 else
00649 {
00650 psz_string = malloc( [o_data length] + 1 );
00651 [o_data getBytes: psz_string];
00652 psz_string[ [o_data length] ] = '\0';
00653 }
00654
00655 return psz_string;
00656 }
00657
00658
00659 - (NSString *)wrapString: (NSString *)o_in_string toWidth: (int) i_width
00660 {
00661 NSMutableString *o_wrapped;
00662 NSString *o_out_string;
00663 NSRange glyphRange, effectiveRange, charRange;
00664 NSRect lineFragmentRect;
00665 unsigned glyphIndex, breaksInserted = 0;
00666
00667 NSTextStorage *o_storage = [[NSTextStorage alloc] initWithString: o_in_string
00668 attributes: [NSDictionary dictionaryWithObjectsAndKeys:
00669 [NSFont labelFontOfSize: 0.0], NSFontAttributeName, nil]];
00670 NSLayoutManager *o_layout_manager = [[NSLayoutManager alloc] init];
00671 NSTextContainer *o_container = [[NSTextContainer alloc]
00672 initWithContainerSize: NSMakeSize(i_width, 2000)];
00673
00674 [o_layout_manager addTextContainer: o_container];
00675 [o_container release];
00676 [o_storage addLayoutManager: o_layout_manager];
00677 [o_layout_manager release];
00678
00679 o_wrapped = [o_in_string mutableCopy];
00680 glyphRange = [o_layout_manager glyphRangeForTextContainer: o_container];
00681
00682 for( glyphIndex = glyphRange.location ; glyphIndex < NSMaxRange(glyphRange) ;
00683 glyphIndex += effectiveRange.length) {
00684 lineFragmentRect = [o_layout_manager lineFragmentRectForGlyphAtIndex: glyphIndex
00685 effectiveRange: &effectiveRange];
00686 charRange = [o_layout_manager characterRangeForGlyphRange: effectiveRange
00687 actualGlyphRange: &effectiveRange];
00688 if ([o_wrapped lineRangeForRange:
00689 NSMakeRange(charRange.location + breaksInserted, charRange.length)].length > charRange.length) {
00690 [o_wrapped insertString: @"\n" atIndex: NSMaxRange(charRange) + breaksInserted];
00691 breaksInserted++;
00692 }
00693 }
00694 o_out_string = [NSString stringWithString: o_wrapped];
00695 [o_wrapped release];
00696 [o_storage release];
00697
00698 return o_out_string;
00699 }
00700
00701
00702
00703
00704
00705
00706
00707 - (BOOL)hasDefinedShortcutKey:(NSEvent *)o_event
00708 {
00709 unichar key = 0;
00710 vlc_value_t val;
00711 unsigned int i_pressed_modifiers = 0;
00712 struct hotkey *p_hotkeys;
00713 int i;
00714
00715 val.i_int = 0;
00716 p_hotkeys = p_intf->p_vlc->p_hotkeys;
00717
00718 i_pressed_modifiers = [o_event modifierFlags];
00719
00720 if( i_pressed_modifiers & NSShiftKeyMask )
00721 val.i_int |= KEY_MODIFIER_SHIFT;
00722 if( i_pressed_modifiers & NSControlKeyMask )
00723 val.i_int |= KEY_MODIFIER_CTRL;
00724 if( i_pressed_modifiers & NSAlternateKeyMask )
00725 val.i_int |= KEY_MODIFIER_ALT;
00726 if( i_pressed_modifiers & NSCommandKeyMask )
00727 val.i_int |= KEY_MODIFIER_COMMAND;
00728
00729 key = [[o_event charactersIgnoringModifiers] characterAtIndex: 0];
00730
00731 switch( key )
00732 {
00733 case NSDeleteCharacter:
00734 case NSDeleteFunctionKey:
00735 case NSDeleteCharFunctionKey:
00736 case NSBackspaceCharacter:
00737 case NSUpArrowFunctionKey:
00738 case NSDownArrowFunctionKey:
00739 case NSRightArrowFunctionKey:
00740 case NSLeftArrowFunctionKey:
00741 case NSEnterCharacter:
00742 case NSCarriageReturnCharacter:
00743 return NO;
00744 }
00745
00746 val.i_int |= CocoaKeyToVLC( key );
00747
00748 for( i = 0; p_hotkeys[i].psz_action != NULL; i++ )
00749 {
00750 if( p_hotkeys[i].i_key == val.i_int )
00751 {
00752 var_Set( p_intf->p_vlc, "key-pressed", val );
00753 return YES;
00754 }
00755 }
00756
00757 return NO;
00758 }
00759
00760 - (id)getControls
00761 {
00762 if ( o_controls )
00763 {
00764 return o_controls;
00765 }
00766 return nil;
00767 }
00768
00769 - (id)getPlaylist
00770 {
00771 if ( o_playlist )
00772 {
00773 return o_playlist;
00774 }
00775 return nil;
00776 }
00777
00778 - (id)getInfo
00779 {
00780 if ( o_info )
00781 {
00782 return o_info;
00783 }
00784 return nil;
00785 }
00786
00787 - (id)getWizard
00788 {
00789 if ( o_wizard )
00790 {
00791 return o_wizard;
00792 }
00793 return nil;
00794 }
00795
00796 - (id)getBookmarks
00797 {
00798 if ( o_bookmarks )
00799 {
00800 return o_bookmarks;
00801 }
00802 return nil;
00803 }
00804
00805 - (void)manage
00806 {
00807 NSDate * o_sleep_date;
00808 playlist_t * p_playlist;
00809
00810
00811 NSAutoreleasePool * o_pool = [[NSAutoreleasePool alloc] init];
00812
00813 vlc_thread_set_priority( p_intf, VLC_THREAD_PRIORITY_LOW );
00814
00815 p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
00816 FIND_ANYWHERE );
00817
00818 if( p_playlist != NULL )
00819 {
00820 var_AddCallback( p_playlist, "intf-change", PlaylistChanged, self );
00821 var_AddCallback( p_playlist, "item-change", PlaylistChanged, self );
00822 var_AddCallback( p_playlist, "item-append", PlaylistChanged, self );
00823 var_AddCallback( p_playlist, "item-deleted", PlaylistChanged, self );
00824 var_AddCallback( p_playlist, "playlist-current", PlaylistChanged, self );
00825
00826 vlc_object_release( p_playlist );
00827 }
00828
00829 while( !p_intf->b_die )
00830 {
00831 vlc_mutex_lock( &p_intf->change_lock );
00832
00833 #define p_input p_intf->p_sys->p_input
00834
00835 if( p_input == NULL )
00836 {
00837 p_input = (input_thread_t *)vlc_object_find( p_intf, VLC_OBJECT_INPUT,
00838 FIND_ANYWHERE );
00839
00840
00841 if( p_input )
00842 {
00843 msg_Dbg( p_intf, "input has changed, refreshing interface" );
00844 p_intf->p_sys->b_input_update = VLC_TRUE;
00845 }
00846 }
00847 else if( p_input->b_die || p_input->b_dead )
00848 {
00849
00850 p_intf->p_sys->b_intf_update = VLC_TRUE;
00851 p_intf->p_sys->i_play_status = END_S;
00852 [self setScrollField: _NS("VLC media player") stopAfter:-1];
00853 vlc_object_release( p_input );
00854 p_input = NULL;
00855 }
00856 #undef p_input
00857
00858
00859 [self manageVolumeSlider];
00860
00861 vlc_mutex_unlock( &p_intf->change_lock );
00862
00863 o_sleep_date = [NSDate dateWithTimeIntervalSinceNow: .1];
00864 [NSThread sleepUntilDate: o_sleep_date];
00865 }
00866
00867 [self terminate];
00868 [o_pool release];
00869 }
00870
00871 - (void)manageIntf:(NSTimer *)o_timer
00872 {
00873 vlc_value_t val;
00874
00875 if( p_intf->p_vlc->b_die == VLC_TRUE )
00876 {
00877 [o_timer invalidate];
00878 return;
00879 }
00880
00881 #define p_input p_intf->p_sys->p_input
00882 if( p_intf->p_sys->b_input_update )
00883 {
00884
00885 p_intf->p_sys->b_current_title_update = VLC_TRUE;
00886 p_intf->p_sys->b_intf_update = VLC_TRUE;
00887 p_intf->p_sys->b_input_update = VLC_FALSE;
00888 }
00889 if( p_intf->p_sys->b_intf_update )
00890 {
00891 vlc_bool_t b_input = VLC_FALSE;
00892 vlc_bool_t b_plmul = VLC_FALSE;
00893 vlc_bool_t b_control = VLC_FALSE;
00894 vlc_bool_t b_seekable = VLC_FALSE;
00895 vlc_bool_t b_chapters = VLC_FALSE;
00896
00897 playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
00898 FIND_ANYWHERE );
00899 b_plmul = p_playlist->i_size > 1;
00900
00901 vlc_object_release( p_playlist );
00902
00903 if( ( b_input = ( p_input != NULL ) ) )
00904 {
00905
00906 var_Get( p_input, "seekable", &val);
00907 b_seekable = val.b_bool;
00908
00909
00910 b_control = p_input->input.b_can_pace_control;
00911
00912
00913
00914 }
00915
00916 [o_btn_stop setEnabled: b_input];
00917 [o_btn_ff setEnabled: b_seekable];
00918 [o_btn_rewind setEnabled: b_seekable];
00919 [o_btn_prev setEnabled: (b_plmul || b_chapters)];
00920 [o_btn_next setEnabled: (b_plmul || b_chapters)];
00921
00922 [o_timeslider setFloatValue: 0.0];
00923 [o_timeslider setEnabled: b_seekable];
00924 [o_timefield setStringValue: @"0:00:00"];
00925
00926 p_intf->p_sys->b_intf_update = VLC_FALSE;
00927 }
00928
00929 if( p_intf->p_sys->b_playmode_update )
00930 {
00931 [o_playlist playModeUpdated];
00932 p_intf->p_sys->b_playmode_update = VLC_FALSE;
00933 }
00934 if( p_intf->p_sys->b_playlist_update )
00935 {
00936 [o_playlist playlistUpdated];
00937 p_intf->p_sys->b_playlist_update = VLC_FALSE;
00938 }
00939
00940 if( p_intf->p_sys->b_fullscreen_update )
00941 {
00942 playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
00943 FIND_ANYWHERE );
00944 var_Get( p_playlist, "fullscreen", &val );
00945 [o_btn_fullscreen setState: val.b_bool];
00946 vlc_object_release( p_playlist );
00947
00948 p_intf->p_sys->b_fullscreen_update = VLC_FALSE;
00949 }
00950
00951 if( p_input && !p_input->b_die )
00952 {
00953 vlc_value_t val;
00954
00955 if( p_intf->p_sys->b_current_title_update )
00956 {
00957 NSString *o_temp;
00958 vout_thread_t *p_vout;
00959 playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
00960 FIND_ANYWHERE );
00961
00962 if( p_playlist == NULL || p_playlist->status.p_item == NULL )
00963 {
00964 return;
00965 }
00966 o_temp = [NSString stringWithUTF8String:
00967 p_playlist->status.p_item->input.psz_name];
00968 if( o_temp == NULL )
00969 o_temp = [NSString stringWithCString:
00970 p_playlist->status.p_item->input.psz_name];
00971 [self setScrollField: o_temp stopAfter:-1];
00972
00973 p_vout = vlc_object_find( p_intf, VLC_OBJECT_VOUT,
00974 FIND_ANYWHERE );
00975 if( p_vout != NULL )
00976 {
00977 id o_vout_wnd;
00978 NSEnumerator * o_enum = [[NSApp orderedWindows] objectEnumerator];
00979
00980 while( ( o_vout_wnd = [o_enum nextObject] ) )
00981 {
00982 if( [[o_vout_wnd className] isEqualToString: @"VLCWindow"] )
00983 {
00984 [o_vout_wnd updateTitle];
00985 }
00986 }
00987 vlc_object_release( (vlc_object_t *)p_vout );
00988 }
00989 [o_playlist updateRowSelection];
00990 vlc_object_release( p_playlist );
00991 p_intf->p_sys->b_current_title_update = FALSE;
00992 }
00993
00994 if( p_input && [o_timeslider isEnabled] )
00995 {
00996
00997 vlc_value_t time;
00998 NSString * o_time;
00999 mtime_t i_seconds;
01000 vlc_value_t pos;
01001 float f_updated;
01002
01003 var_Get( p_input, "position", &pos );
01004 f_updated = 10000. * pos.f_float;
01005 [o_timeslider setFloatValue: f_updated];
01006
01007 var_Get( p_input, "time", &time );
01008 i_seconds = time.i_time / 1000000;
01009
01010 o_time = [NSString stringWithFormat: @"%d:%02d:%02d",
01011 (int) (i_seconds / (60 * 60)),
01012 (int) (i_seconds / 60 % 60),
01013 (int) (i_seconds % 60)];
01014 [o_timefield setStringValue: o_time];
01015 }
01016
01017 if( p_intf->p_sys->b_volume_update )
01018 {
01019 NSString *o_text;
01020 int i_volume_step = 0;
01021 o_text = [NSString stringWithFormat: _NS("Volume: %d%%"), i_lastShownVolume * 400 / AOUT_VOLUME_MAX];
01022 if( i_lastShownVolume != -1 )
01023 [self setScrollField:o_text stopAfter:1000000];
01024 i_volume_step = config_GetInt( p_intf->p_vlc, "volume-step" );
01025 [o_volumeslider setFloatValue: (float)i_lastShownVolume / i_volume_step];
01026 [o_volumeslider setEnabled: TRUE];
01027 p_intf->p_sys->b_mute = ( i_lastShownVolume == 0 );
01028 p_intf->p_sys->b_volume_update = FALSE;
01029 }
01030
01031
01032 var_Get( p_input, "state", &val );
01033 if( p_intf->p_sys->i_play_status != val.i_int )
01034 {
01035 p_intf->p_sys->i_play_status = val.i_int;
01036 [self playStatusUpdated: p_intf->p_sys->i_play_status];
01037 }
01038 }
01039 else
01040 {
01041 p_intf->p_sys->i_play_status = END_S;
01042 p_intf->p_sys->b_intf_update = VLC_TRUE;
01043 [self playStatusUpdated: p_intf->p_sys->i_play_status];
01044 [self setSubmenusEnabled: FALSE];
01045 }
01046
01047 #undef p_input
01048
01049 [self updateMessageArray];
01050
01051 if( (i_end_scroll != -1) && (mdate() > i_end_scroll) )
01052 [self resetScrollField];
01053
01054
01055 [NSTimer scheduledTimerWithTimeInterval: 0.3
01056 target: self selector: @selector(manageIntf:)
01057 userInfo: nil repeats: FALSE];
01058 }
01059
01060 - (void)setupMenus
01061 {
01062 #define p_input p_intf->p_sys->p_input
01063 if( p_input != NULL )
01064 {
01065 [o_controls setupVarMenuItem: o_mi_program target: (vlc_object_t *)p_input
01066 var: "program" selector: @selector(toggleVar:)];
01067
01068 [o_controls setupVarMenuItem: o_mi_title target: (vlc_object_t *)p_input
01069 var: "title" selector: @selector(toggleVar:)];
01070
01071 [o_controls setupVarMenuItem: o_mi_chapter target: (vlc_object_t *)p_input
01072 var: "chapter" selector: @selector(toggleVar:)];
01073
01074 [o_controls setupVarMenuItem: o_mi_audiotrack target: (vlc_object_t *)p_input
01075 var: "audio-es" selector: @selector(toggleVar:)];
01076
01077 [o_controls setupVarMenuItem: o_mi_videotrack target: (vlc_object_t *)p_input
01078 var: "video-es" selector: @selector(toggleVar:)];
01079
01080 [o_controls setupVarMenuItem: o_mi_subtitle target: (vlc_object_t *)p_input
01081 var: "spu-es" selector: @selector(toggleVar:)];
01082
01083 aout_instance_t * p_aout = vlc_object_find( p_intf, VLC_OBJECT_AOUT,
01084 FIND_ANYWHERE );
01085 if ( p_aout != NULL )
01086 {
01087 [o_controls setupVarMenuItem: o_mi_channels target: (vlc_object_t *)p_aout
01088 var: "audio-channels" selector: @selector(toggleVar:)];
01089
01090 [o_controls setupVarMenuItem: o_mi_device target: (vlc_object_t *)p_aout
01091 var: "audio-device" selector: @selector(toggleVar:)];
01092
01093 [o_controls setupVarMenuItem: o_mi_visual target: (vlc_object_t *)p_aout
01094 var: "visual" selector: @selector(toggleVar:)];
01095 vlc_object_release( (vlc_object_t *)p_aout );
01096 }
01097
01098 vout_thread_t * p_vout = vlc_object_find( p_intf, VLC_OBJECT_VOUT,
01099 FIND_ANYWHERE );
01100
01101 if ( p_vout != NULL )
01102 {
01103 vlc_object_t * p_dec_obj;
01104
01105 [o_controls setupVarMenuItem: o_mi_screen target: (vlc_object_t *)p_vout
01106 var: "video-device" selector: @selector(toggleVar:)];
01107
01108 [o_controls setupVarMenuItem: o_mi_deinterlace target: (vlc_object_t *)p_vout
01109 var: "deinterlace" selector: @selector(toggleVar:)];
01110
01111 p_dec_obj = (vlc_object_t *)vlc_object_find(
01112 (vlc_object_t *)p_vout,
01113 VLC_OBJECT_DECODER,
01114 FIND_PARENT );
01115 if ( p_dec_obj != NULL )
01116 {
01117 [o_controls setupVarMenuItem: o_mi_ffmpeg_pp target:
01118 (vlc_object_t *)p_dec_obj var:"ffmpeg-pp-q" selector:
01119 @selector(toggleVar:)];
01120
01121 vlc_object_release(p_dec_obj);
01122 }
01123 vlc_object_release( (vlc_object_t *)p_vout );
01124 }
01125 }
01126 #undef p_input
01127 }
01128
01129 - (void)setScrollField:(NSString *)o_string stopAfter:(int)timeout
01130 {
01131 if( timeout != -1 )
01132 i_end_scroll = mdate() + timeout;
01133 else
01134 i_end_scroll = -1;
01135 [o_scrollfield setStringValue: o_string];
01136 }
01137
01138 - (void)resetScrollField
01139 {
01140 i_end_scroll = -1;
01141 #define p_input p_intf->p_sys->p_input
01142 if( p_input && !p_input->b_die )
01143 {
01144 NSString *o_temp;
01145 playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
01146 FIND_ANYWHERE );
01147 if( p_playlist == NULL )
01148 {
01149 return;
01150 }
01151 o_temp = [NSString stringWithUTF8String:
01152 p_playlist->status.p_item->input.psz_name];
01153 if( o_temp == NULL )
01154 o_temp = [NSString stringWithCString:
01155 p_playlist->status.p_item->input.psz_name];
01156 [self setScrollField: o_temp stopAfter:-1];
01157 vlc_object_release( p_playlist );
01158 return;
01159 }
01160 #undef p_input
01161 [self setScrollField: _NS("VLC media player") stopAfter:-1];
01162 }
01163
01164 - (void)updateMessageArray
01165 {
01166 int i_start, i_stop;
01167 vlc_value_t quiet;
01168
01169 vlc_mutex_lock( p_intf->p_sys->p_sub->p_lock );
01170 i_stop = *p_intf->p_sys->p_sub->pi_stop;
01171 vlc_mutex_unlock( p_intf->p_sys->p_sub->p_lock );
01172
01173 if( p_intf->p_sys->p_sub->i_start != i_stop )
01174 {
01175 NSColor *o_white = [NSColor whiteColor];
01176 NSColor *o_red = [NSColor redColor];
01177 NSColor *o_yellow = [NSColor yellowColor];
01178 NSColor *o_gray = [NSColor grayColor];
01179
01180 NSColor * pp_color[4] = { o_white, o_red, o_yellow, o_gray };
01181 static const char * ppsz_type[4] = { ": ", " error: ",
01182 " warning: ", " debug: " };
01183
01184 for( i_start = p_intf->p_sys->p_sub->i_start;
01185 i_start != i_stop;
01186 i_start = (i_start+1) % VLC_MSG_QSIZE )
01187 {
01188 NSString *o_msg;
01189 NSDictionary *o_attr;
01190 NSAttributedString *o_msg_color;
01191
01192 int i_type = p_intf->p_sys->p_sub->p_msg[i_start].i_type;
01193
01194 [o_msg_lock lock];
01195
01196 if( [o_msg_arr count] + 2 > 400 )
01197 {
01198 unsigned rid[] = { 0, 1 };
01199 [o_msg_arr removeObjectsFromIndices: (unsigned *)&rid
01200 numIndices: sizeof(rid)/sizeof(rid[0])];
01201 }
01202
01203 o_attr = [NSDictionary dictionaryWithObject: o_gray
01204 forKey: NSForegroundColorAttributeName];
01205 o_msg = [NSString stringWithFormat: @"%s%s",
01206 p_intf->p_sys->p_sub->p_msg[i_start].psz_module,
01207 ppsz_type[i_type]];
01208 o_msg_color = [[NSAttributedString alloc]
01209 initWithString: o_msg attributes: o_attr];
01210 [o_msg_arr addObject: [o_msg_color autorelease]];
01211
01212 o_attr = [NSDictionary dictionaryWithObject: pp_color[i_type]
01213 forKey: NSForegroundColorAttributeName];
01214 o_msg = [NSString stringWithFormat: @"%s\n",
01215 p_intf->p_sys->p_sub->p_msg[i_start].psz_msg];
01216 o_msg_color = [[NSAttributedString alloc]
01217 initWithString: o_msg attributes: o_attr];
01218 [o_msg_arr addObject: [o_msg_color autorelease]];
01219
01220 [o_msg_lock unlock];
01221
01222 var_Get( p_intf->p_vlc, "verbose", &quiet );
01223
01224 if( i_type == 1 && quiet.i_int > -1 )
01225 {
01226 NSString *o_my_msg = [NSString stringWithFormat: @"%s: %s\n",
01227 p_intf->p_sys->p_sub->p_msg[i_start].psz_module,
01228 p_intf->p_sys->p_sub->p_msg[i_start].psz_msg];
01229
01230 NSRange s_r = NSMakeRange( [[o_err_msg string] length], 0 );
01231 [o_err_msg setEditable: YES];
01232 [o_err_msg setSelectedRange: s_r];
01233 [o_err_msg insertText: o_my_msg];
01234
01235 [o_error makeKeyAndOrderFront: self];
01236 [o_err_msg setEditable: NO];
01237 }
01238 }
01239
01240 vlc_mutex_lock( p_intf->p_sys->p_sub->p_lock );
01241 p_intf->p_sys->p_sub->i_start = i_start;
01242 vlc_mutex_unlock( p_intf->p_sys->p_sub->p_lock );
01243 }
01244 }
01245
01246 - (void)playStatusUpdated:(int)i_status
01247 {
01248 if( i_status == PLAYING_S )
01249 {
01250 [o_btn_play setImage: o_img_pause];
01251 [o_btn_play setAlternateImage: o_img_pause_pressed];
01252 [o_btn_play setToolTip: _NS("Pause")];
01253 [o_mi_play setTitle: _NS("Pause")];
01254 [o_dmi_play setTitle: _NS("Pause")];
01255 }
01256 else
01257 {
01258 [o_btn_play setImage: o_img_play];
01259 [o_btn_play setAlternateImage: o_img_play_pressed];
01260 [o_btn_play setToolTip: _NS("Play")];
01261 [o_mi_play setTitle: _NS("Play")];
01262 [o_dmi_play setTitle: _NS("Play")];
01263 }
01264 }
01265
01266 - (void)setSubmenusEnabled:(BOOL)b_enabled
01267 {
01268 [o_mi_program setEnabled: b_enabled];
01269 [o_mi_title setEnabled: b_enabled];
01270 [o_mi_chapter setEnabled: b_enabled];
01271 [o_mi_audiotrack setEnabled: b_enabled];
01272 [o_mi_visual setEnabled: b_enabled];
01273 [o_mi_videotrack setEnabled: b_enabled];
01274 [o_mi_subtitle setEnabled: b_enabled];
01275 [o_mi_channels setEnabled: b_enabled];
01276 [o_mi_deinterlace setEnabled: b_enabled];
01277 [o_mi_ffmpeg_pp setEnabled: b_enabled];
01278 [o_mi_device setEnabled: b_enabled];
01279 [o_mi_screen setEnabled: b_enabled];
01280 }
01281
01282 - (void)manageVolumeSlider
01283 {
01284 audio_volume_t i_volume;
01285 aout_VolumeGet( p_intf, &i_volume );
01286
01287 if( i_volume != i_lastShownVolume )
01288 {
01289 i_lastShownVolume = i_volume;
01290 p_intf->p_sys->b_volume_update = TRUE;
01291 }
01292 }
01293
01294 - (IBAction)timesliderUpdate:(id)sender
01295 {
01296 #define p_input p_intf->p_sys->p_input
01297 float f_updated;
01298
01299 switch( [[NSApp currentEvent] type] )
01300 {
01301 case NSLeftMouseUp:
01302 case NSLeftMouseDown:
01303 case NSLeftMouseDragged:
01304 f_updated = [sender floatValue];
01305 break;
01306
01307 default:
01308 return;
01309 }
01310
01311 if( p_input != NULL )
01312 {
01313 vlc_value_t time;
01314 vlc_value_t pos;
01315 mtime_t i_seconds;
01316 NSString * o_time;
01317
01318 pos.f_float = f_updated / 10000.;
01319 var_Set( p_input, "position", pos );
01320 [o_timeslider setFloatValue: f_updated];
01321
01322 var_Get( p_input, "time", &time );
01323 i_seconds = time.i_time / 1000000;
01324
01325 o_time = [NSString stringWithFormat: @"%d:%02d:%02d",
01326 (int) (i_seconds / (60 * 60)),
01327 (int) (i_seconds / 60 % 60),
01328 (int) (i_seconds % 60)];
01329 [o_timefield setStringValue: o_time];
01330 }
01331 #undef p_input
01332 }
01333
01334 - (void)terminate
01335 {
01336 playlist_t * p_playlist;
01337 vout_thread_t * p_vout;
01338
01339 #define p_input p_intf->p_sys->p_input
01340 if( p_input )
01341 {
01342 vlc_object_release( p_input );
01343 p_input = NULL;
01344 }
01345 #undef p_input
01346
01347
01348 if( ( p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
01349 FIND_ANYWHERE ) ) )
01350 {
01351 playlist_Stop( p_playlist );
01352 vlc_object_release( p_playlist );
01353 }
01354
01355
01356
01357
01358
01359
01360 while( ( p_vout = vlc_object_find( p_intf, VLC_OBJECT_VOUT,
01361 FIND_ANYWHERE ) ) )
01362 {
01363 vlc_object_release( p_vout );
01364 msleep( 100000 );
01365 }
01366 msleep( 500000 );
01367
01368
01369 if (o_extended && [o_extended getConfigChanged])
01370 {
01371 [o_extended savePrefs];
01372 }
01373
01374
01375
01376 if( nib_about_loaded && o_about )
01377 [o_about release];
01378
01379 if( nib_open_loaded && o_open )
01380 [o_open release];
01381
01382 if( nib_extended_loaded && o_extended )
01383 {
01384 [o_extended collapsAll];
01385 [o_extended release];
01386 }
01387
01388 if( nib_bookmarks_loaded && o_bookmarks )
01389 [o_bookmarks release];
01390
01391 if( nib_wizard_loaded && o_wizard )
01392 [o_wizard release];
01393
01394 if( o_img_pause_pressed != nil )
01395 {
01396 [o_img_pause_pressed release];
01397 o_img_pause_pressed = nil;
01398 }
01399
01400 if( o_img_pause_pressed != nil )
01401 {
01402 [o_img_pause_pressed release];
01403 o_img_pause_pressed = nil;
01404 }
01405
01406 if( o_img_pause != nil )
01407 {
01408 [o_img_pause release];
01409 o_img_pause = nil;
01410 }
01411
01412 if( o_img_play != nil )
01413 {
01414 [o_img_play release];
01415 o_img_play = nil;
01416 }
01417
01418 if( o_msg_arr != nil )
01419 {
01420 [o_msg_arr removeAllObjects];
01421 [o_msg_arr release];
01422 o_msg_arr = nil;
01423 }
01424
01425 if( o_msg_lock != nil )
01426 {
01427 [o_msg_lock release];
01428 o_msg_lock = nil;
01429 }
01430
01431
01432 [[NSUserDefaults standardUserDefaults] synchronize];
01433
01434 p_intf->b_die = VLC_TRUE;
01435 [NSApp stop:NULL];
01436 }
01437
01438 - (IBAction)clearRecentItems:(id)sender
01439 {
01440 [[NSDocumentController sharedDocumentController]
01441 clearRecentDocuments: nil];
01442 }
01443
01444 - (void)openRecentItem:(id)sender
01445 {
01446 [self application: nil openFile: [sender title]];
01447 }
01448
01449 - (IBAction)intfOpenFile:(id)sender
01450 {
01451 if (!nib_open_loaded)
01452 {
01453 nib_open_loaded = [NSBundle loadNibNamed:@"Open" owner:self];
01454 [o_open awakeFromNib];
01455 [o_open openFile];
01456 } else {
01457 [o_open openFile];
01458 }
01459 }
01460
01461 - (IBAction)intfOpenFileGeneric:(id)sender
01462 {
01463 if (!nib_open_loaded)
01464 {
01465 nib_open_loaded = [NSBundle loadNibNamed:@"Open" owner:self];
01466 [o_open awakeFromNib];
01467 [o_open openFileGeneric];
01468 } else {
01469 [o_open openFileGeneric];
01470 }
01471 }
01472
01473 - (IBAction)intfOpenDisc:(id)sender
01474 {
01475 if (!nib_open_loaded)
01476 {
01477 nib_open_loaded = [NSBundle loadNibNamed:@"Open" owner:self];
01478 [o_open awakeFromNib];
01479 [o_open openDisc];
01480 } else {
01481 [o_open openDisc];
01482 }
01483 }
01484
01485 - (IBAction)intfOpenNet:(id)sender
01486 {
01487 if (!nib_open_loaded)
01488 {
01489 nib_open_loaded = [NSBundle loadNibNamed:@"Open" owner:self];
01490 [o_open awakeFromNib];
01491 [o_open openNet];
01492 } else {
01493 [o_open openNet];
01494 }
01495 }
01496
01497 - (IBAction)showWizard:(id)sender
01498 {
01499 if (!nib_wizard_loaded)
01500 {
01501 nib_wizard_loaded = [NSBundle loadNibNamed:@"Wizard" owner:self];
01502 [o_wizard initStrings];
01503 [o_wizard resetWizard];
01504 [o_wizard showWizard];
01505 } else {
01506 [o_wizard resetWizard];
01507 [o_wizard showWizard];
01508 }
01509 }
01510
01511 - (IBAction)showExtended:(id)sender
01512 {
01513 if ( o_extended == nil )
01514 {
01515 o_extended = [[VLCExtended alloc] init];
01516 }
01517 if (!nib_extended_loaded)
01518 {
01519 nib_extended_loaded = [NSBundle loadNibNamed:@"Extended" owner:self];
01520 [o_extended initStrings];
01521 [o_extended showPanel];
01522 } else {
01523 [o_extended showPanel];
01524 }
01525 }
01526
01527 - (IBAction)showBookmarks:(id)sender
01528 {
01529
01530 if (!nib_wizard_loaded)
01531 {
01532 nib_wizard_loaded = [NSBundle loadNibNamed:@"Wizard" owner:self];
01533 [o_wizard initStrings];
01534 }
01535
01536 if (!nib_bookmarks_loaded)
01537 {
01538 nib_bookmarks_loaded = [NSBundle loadNibNamed:@"Bookmarks" owner:self];
01539 [o_bookmarks showBookmarks];
01540 } else {
01541 [o_bookmarks showBookmarks];
01542 }
01543 }
01544
01545 - (IBAction)viewAbout:(id)sender
01546 {
01547 if (!nib_about_loaded)
01548 {
01549 nib_about_loaded = [NSBundle loadNibNamed:@"About" owner:self];
01550 [o_about showPanel];
01551 } else {
01552 [o_about showPanel];
01553 }
01554 }
01555
01556 - (IBAction)viewPreferences:(id)sender
01557 {
01558
01559 if( o_prefs == nil )
01560 o_prefs = [[VLCPrefs alloc] init];
01561 [o_prefs showPrefs];
01562 }
01563
01564
01565
01566
01567
01568
01569
01570
01571
01572
01573
01574
01575 - (IBAction)closeError:(id)sender
01576 {
01577 vlc_value_t val;
01578
01579 if( [o_err_ckbk_surpress state] == NSOnState )
01580 {
01581 val.i_int = -1;
01582 var_Set( p_intf->p_vlc, "verbose", val );
01583 }
01584 [o_err_msg setString: @""];
01585 [o_error performClose: self];
01586 }
01587
01588 - (IBAction)openReadMe:(id)sender
01589 {
01590 NSString * o_path = [[NSBundle mainBundle]
01591 pathForResource: @"README.MacOSX" ofType: @"rtf"];
01592
01593 [[NSWorkspace sharedWorkspace] openFile: o_path
01594 withApplication: @"TextEdit"];
01595 }
01596
01597 - (IBAction)openDocumentation:(id)sender
01598 {
01599 NSURL * o_url = [NSURL URLWithString:
01600 @"http://www.videolan.org/doc/"];
01601
01602 [[NSWorkspace sharedWorkspace] openURL: o_url];
01603 }
01604
01605 - (IBAction)reportABug:(id)sender
01606 {
01607 NSURL * o_url = [NSURL URLWithString:
01608 @"http://www.videolan.org/support/bug-reporting.html"];
01609
01610 [[NSWorkspace sharedWorkspace] openURL: o_url];
01611 }
01612
01613 - (IBAction)openWebsite:(id)sender
01614 {
01615 NSURL * o_url = [NSURL URLWithString: @"http://www.videolan.org/"];
01616
01617 [[NSWorkspace sharedWorkspace] openURL: o_url];
01618 }
01619
01620 - (IBAction)openLicense:(id)sender
01621 {
01622 NSString * o_path = [[NSBundle mainBundle]
01623 pathForResource: @"COPYING" ofType: nil];
01624
01625 [[NSWorkspace sharedWorkspace] openFile: o_path
01626 withApplication: @"TextEdit"];
01627 }
01628
01629 - (IBAction)openForum:(id)sender
01630 {
01631 NSURL * o_url = [NSURL URLWithString: @"http://forum.videolan.org/"];
01632
01633 [[NSWorkspace sharedWorkspace] openURL: o_url];
01634 }
01635
01636 - (IBAction)openDonate:(id)sender
01637 {
01638 NSURL * o_url = [NSURL URLWithString: @"http://www.videolan.org/contribute.html#paypal"];
01639
01640 [[NSWorkspace sharedWorkspace] openURL: o_url];
01641 }
01642
01643 - (IBAction)openCrashLog:(id)sender
01644 {
01645 NSString * o_path = [@"~/Library/Logs/CrashReporter/VLC.crash.log"
01646 stringByExpandingTildeInPath];
01647
01648
01649 if ( [[NSFileManager defaultManager] fileExistsAtPath: o_path ] )
01650 {
01651 [[NSWorkspace sharedWorkspace] openFile: o_path
01652 withApplication: @"Console"];
01653 }
01654 else
01655 {
01656 NSBeginInformationalAlertSheet(_NS("No CrashLog found"), @"Continue", nil, nil, o_msgs_panel, self, NULL, NULL, nil, _NS("You haven't experienced any heavy crashes yet.") );
01657
01658 }
01659 }
01660
01661 - (void)windowDidBecomeKey:(NSNotification *)o_notification
01662 {
01663 if( [o_notification object] == o_msgs_panel )
01664 {
01665 id o_msg;
01666 NSEnumerator * o_enum;
01667
01668 [o_messages setString: @""];
01669
01670 [o_msg_lock lock];
01671
01672 o_enum = [o_msg_arr objectEnumerator];
01673
01674 while( ( o_msg = [o_enum nextObject] ) != nil )
01675 {
01676 [o_messages insertText: o_msg];
01677 }
01678
01679 [o_msg_lock unlock];
01680 }
01681 }
01682
01683 - (IBAction)togglePlaylist:(id)sender
01684 {
01685 NSRect o_rect = [o_window frame];
01686
01687 if( o_rect.size.height <= 200 )
01688 {
01689 b_small_window = YES;
01690
01691 if ( o_size_with_playlist.height > 200 )
01692 {
01693 o_rect.size.height = o_size_with_playlist.height;
01694 } else {
01695 o_rect.size.height = 500;
01696 }
01697
01698 if ( o_size_with_playlist.width > [o_window minSize].width )
01699 {
01700 o_rect.size.width = o_size_with_playlist.width;
01701 } else {
01702 o_rect.size.width = 500;
01703 }
01704
01705 o_rect.size.height = (o_size_with_playlist.height > 200) ?
01706 o_size_with_playlist.height : 500;
01707 o_rect.origin.x = [o_window frame].origin.x;
01708 o_rect.origin.y = [o_window frame].origin.y - o_rect.size.height +
01709 [o_window minSize].height;
01710 [o_btn_playlist setState: YES];
01711 }
01712 else
01713 {
01714
01715 o_rect.size.height = [o_window minSize].height;
01716 o_rect.size.width = [o_window minSize].width;
01717 o_rect.origin.x = [o_window frame].origin.x;
01718
01719 o_rect.origin.y = [o_window frame].origin.y +
01720 [o_window frame].size.height - [o_window minSize].height;
01721
01722 [o_playlist_view setAutoresizesSubviews: NO];
01723 [o_playlist_view removeFromSuperview];
01724 [o_btn_playlist setState: NO];
01725 b_small_window = NO;
01726 }
01727
01728 [o_window setFrame: o_rect display:YES animate: YES];
01729 }
01730
01731 - (void)updateTogglePlaylistState
01732 {
01733 if( [o_window frame].size.height <= 200 )
01734 {
01735 [o_btn_playlist setState: NO];
01736 }
01737 else
01738 {
01739 [o_btn_playlist setState: YES];
01740 }
01741 }
01742
01743 - (NSSize)windowWillResize:(NSWindow *)sender toSize:(NSSize)proposedFrameSize
01744 {
01745
01746
01747
01748
01749 o_size_with_playlist = proposedFrameSize;
01750
01751 if( proposedFrameSize.height <= 200 )
01752 {
01753 if( b_small_window == NO )
01754 {
01755
01756 b_small_window = YES;
01757 [o_playlist_view setAutoresizesSubviews: NO];
01758 [o_playlist_view removeFromSuperview];
01759 }
01760 return NSMakeSize( proposedFrameSize.width, [o_window minSize].height);
01761 }
01762 return proposedFrameSize;
01763 }
01764
01765 - (void)windowDidResize:(NSNotification *)notif
01766 {
01767 if( [o_window frame].size.height > 200 && b_small_window )
01768 {
01769
01770 [o_playlist_view setAutoresizesSubviews: YES];
01771 [o_playlist_view setFrame: NSMakeRect( 10, 10, [o_window frame].size.width - 20, [o_window frame].size.height - [o_window minSize].height - 10 )];
01772 [o_playlist_view setNeedsDisplay:YES];
01773 [[o_window contentView] addSubview: o_playlist_view];
01774 b_small_window = NO;
01775 }
01776 [self updateTogglePlaylistState];
01777 }
01778
01779 @end
01780
01781 @implementation VLCMain (NSMenuValidation)
01782
01783 - (BOOL)validateMenuItem:(NSMenuItem *)o_mi
01784 {
01785 NSString *o_title = [o_mi title];
01786 BOOL bEnabled = TRUE;
01787
01788
01789 if( [o_title isEqualToString: _NS("Clear Menu")] )
01790 {
01791 NSMenu * o_menu = [o_mi_open_recent submenu];
01792 int i_nb_items = [o_menu numberOfItems];
01793 NSArray * o_docs = [[NSDocumentController sharedDocumentController]
01794 recentDocumentURLs];
01795 UInt32 i_nb_docs = [o_docs count];
01796
01797 if( i_nb_items > 1 )
01798 {
01799 while( --i_nb_items )
01800 {
01801 [o_menu removeItemAtIndex: 0];
01802 }
01803 }
01804
01805 if( i_nb_docs > 0 )
01806 {
01807 NSURL * o_url;
01808 NSString * o_doc;
01809
01810 [o_menu insertItem: [NSMenuItem separatorItem] atIndex: 0];
01811
01812 while( TRUE )
01813 {
01814 i_nb_docs--;
01815
01816 o_url = [o_docs objectAtIndex: i_nb_docs];
01817
01818 if( [o_url isFileURL] )
01819 {
01820 o_doc = [o_url path];
01821 }
01822 else
01823 {
01824 o_doc = [o_url absoluteString];
01825 }
01826
01827 [o_menu insertItemWithTitle: o_doc
01828 action: @selector(openRecentItem:)
01829 keyEquivalent: @"" atIndex: 0];
01830
01831 if( i_nb_docs == 0 )
01832 {
01833 break;
01834 }
01835 }
01836 }
01837 else
01838 {
01839 bEnabled = FALSE;
01840 }
01841 }
01842 return( bEnabled );
01843 }
01844
01845 @end
01846
01847 @implementation VLCMain (Internal)
01848
01849 - (void)handlePortMessage:(NSPortMessage *)o_msg
01850 {
01851 id ** val;
01852 NSData * o_data;
01853 NSValue * o_value;
01854 NSInvocation * o_inv;
01855 NSConditionLock * o_lock;
01856
01857 o_data = [[o_msg components] lastObject];
01858 o_inv = *((NSInvocation **)[o_data bytes]);
01859 [o_inv getArgument: &o_value atIndex: 2];
01860 val = (id **)[o_value pointerValue];
01861 [o_inv setArgument: val[1] atIndex: 2];
01862 o_lock = *(val[0]);
01863
01864 [o_lock lock];
01865 [o_inv invoke];
01866 [o_lock unlockWithCondition: 1];
01867 }
01868
01869 @end