* intf.m: MacOS X interface plugin
*****************************************************************************
* Copyright (C) 2002-2003 VideoLAN
- * $Id: intf.m,v 1.79 2003/05/11 18:40:11 hartman Exp $
+ * $Id: intf.m,v 1.97 2003/10/29 02:13:04 hartman Exp $
*
* Authors: Jon Lech Johansen <jon-vl@nanocrew.net>
* Christophe Massiot <massiot@via.ecp.fr>
#include <stdlib.h> /* malloc(), free() */
#include <sys/param.h> /* for MAXPATHLEN */
#include <string.h>
+#include <vlc_keys.h>
#include "intf.h"
#include "vout.h"
#include "prefs.h"
#include "playlist.h"
#include "info.h"
+#include "controls.h"
/*****************************************************************************
* Local prototypes.
}
memset( p_intf->p_sys, 0, sizeof( *p_intf->p_sys ) );
-
+
p_intf->p_sys->o_pool = [[NSAutoreleasePool alloc] init];
+
+ /* Put Cocoa into multithread mode as soon as possible.
+ * http://developer.apple.com/techpubs/macosx/Cocoa/
+ * TasksAndConcepts/ProgrammingTopics/Multithreading/index.html
+ * This thread does absolutely nothing at all. */
+ [NSThread detachNewThreadSelector:@selector(self) toTarget:[NSString string] withObject:nil];
+
p_intf->p_sys->o_sendport = [[NSPort port] retain];
-
p_intf->p_sys->p_sub = msg_Subscribe( p_intf );
-
p_intf->pf_run = Run;
-
+
[[VLCApplication sharedApplication] autorelease];
- [NSApp initIntlSupport];
[NSApp setIntf: p_intf];
[NSBundle loadNibNamed: @"MainMenu" owner: NSApp];
*****************************************************************************/
@implementation VLCApplication
-- (id)init
-{
- /* default encoding: ISO-8859-1 */
- i_encoding = NSISOLatin1StringEncoding;
-
- return( [super init] );
-}
-
-- (void)initIntlSupport
-{
- char *psz_lang = getenv( "LANG" );
-
- if( psz_lang == NULL )
- {
- return;
- }
-
- if( strncmp( psz_lang, "pl", 2 ) == 0 )
- {
- i_encoding = NSISOLatin2StringEncoding;
- }
- else if( strncmp( psz_lang, "ja", 2 ) == 0 )
- {
- i_encoding = NSJapaneseEUCStringEncoding;
- }
- else if( strncmp( psz_lang, "ru", 2 ) == 0 )
- {
-#define CFSENC2NSSENC(e) CFStringConvertEncodingToNSStringEncoding(e)
- i_encoding = CFSENC2NSSENC( kCFStringEncodingKOI8_R );
-#undef CFSENC2NSSENC
- }
-}
-
- (NSString *)localizedString:(char *)psz
{
NSString * o_str = nil;
if( psz != NULL )
{
- UInt32 uiLength = (UInt32)strlen( psz );
- NSData * o_data = [NSData dataWithBytes: psz length: uiLength];
- o_str = [[[NSString alloc] initWithData: o_data
- encoding: i_encoding] autorelease];
+ o_str = [[[NSString alloc] initWithUTF8String: psz] autorelease];
+ }
+ if ( o_str == NULL )
+ {
+ msg_Err( p_intf, "could not translate: %s", psz );
}
return( o_str );
- (char *)delocalizeString:(NSString *)id
{
- NSData * o_data = [id dataUsingEncoding: i_encoding
+ NSData * o_data = [id dataUsingEncoding: NSUTF8StringEncoding
allowLossyConversion: NO];
char * psz_string;
if ( o_data == nil )
{
- o_data = [id dataUsingEncoding: i_encoding
+ o_data = [id dataUsingEncoding: NSUTF8StringEncoding
allowLossyConversion: YES];
psz_string = malloc( [o_data length] + 1 );
[o_data getBytes: psz_string];
return psz_string;
}
-- (NSStringEncoding)getEncoding
+/* i_width is in pixels */
+- (NSString *)wrapString: (NSString *)o_in_string toWidth: (int) i_width
{
- return i_encoding;
+ NSMutableString *o_wrapped;
+ NSString *o_out_string;
+ NSRange glyphRange, effectiveRange, charRange;
+ NSRect lineFragmentRect;
+ unsigned glyphIndex, breaksInserted = 0;
+
+ NSTextStorage *o_storage = [[NSTextStorage alloc] initWithString: o_in_string
+ attributes: [NSDictionary dictionaryWithObjectsAndKeys:
+ [NSFont labelFontOfSize: 0.0], NSFontAttributeName, nil]];
+ NSLayoutManager *o_layout_manager = [[NSLayoutManager alloc] init];
+ NSTextContainer *o_container = [[NSTextContainer alloc]
+ initWithContainerSize: NSMakeSize(i_width, 2000)];
+
+ [o_layout_manager addTextContainer: o_container];
+ [o_container release];
+ [o_storage addLayoutManager: o_layout_manager];
+ [o_layout_manager release];
+
+ o_wrapped = [o_in_string mutableCopy];
+ glyphRange = [o_layout_manager glyphRangeForTextContainer: o_container];
+
+ for( glyphIndex = glyphRange.location ; glyphIndex < NSMaxRange(glyphRange) ;
+ glyphIndex += effectiveRange.length) {
+ lineFragmentRect = [o_layout_manager lineFragmentRectForGlyphAtIndex: glyphIndex
+ effectiveRange: &effectiveRange];
+ charRange = [o_layout_manager characterRangeForGlyphRange: effectiveRange
+ actualGlyphRange: &effectiveRange];
+ if ([o_wrapped lineRangeForRange:
+ NSMakeRange(charRange.location + breaksInserted, charRange.length)].length > charRange.length) {
+ [o_wrapped insertString: @"\n" atIndex: NSMaxRange(charRange) + breaksInserted];
+ breaksInserted++;
+ }
+ }
+ o_out_string = [NSString stringWithString: o_wrapped];
+ [o_wrapped release];
+ [o_storage release];
+
+ return o_out_string;
}
- (void)setIntf:(intf_thread_t *)_p_intf
return( i_ret );
}
+/*****************************************************************************
+ * playlistChanged: Callback triggered by the intf-change playlist
+ * variable, to let the intf update the playlist.
+ *****************************************************************************/
+int PlaylistChanged( vlc_object_t *p_this, const char *psz_variable,
+ vlc_value_t old_val, vlc_value_t new_val, void *param )
+{
+ intf_thread_t * p_intf = [NSApp getIntf];
+ p_intf->p_sys->b_playlist_update = VLC_TRUE;
+ p_intf->p_sys->b_intf_update = VLC_TRUE;
+ return VLC_SUCCESS;
+}
+
+static struct
+{
+ unichar i_nskey;
+ int i_vlckey;
+} nskeys_to_vlckeys[] =
+{
+ { NSUpArrowFunctionKey, KEY_UP },
+ { NSDownArrowFunctionKey, KEY_DOWN },
+ { NSLeftArrowFunctionKey, KEY_LEFT },
+ { NSRightArrowFunctionKey, KEY_RIGHT },
+ { NSF1FunctionKey, KEY_F1 },
+ { NSF2FunctionKey, KEY_F2 },
+ { NSF3FunctionKey, KEY_F3 },
+ { NSF4FunctionKey, KEY_F4 },
+ { NSF5FunctionKey, KEY_F5 },
+ { NSF6FunctionKey, KEY_F6 },
+ { NSF7FunctionKey, KEY_F7 },
+ { NSF8FunctionKey, KEY_F8 },
+ { NSF9FunctionKey, KEY_F9 },
+ { NSF10FunctionKey, KEY_F10 },
+ { NSF11FunctionKey, KEY_F11 },
+ { NSF12FunctionKey, KEY_F12 },
+ { NSHomeFunctionKey, KEY_HOME },
+ { NSEndFunctionKey, KEY_END },
+ { NSPageUpFunctionKey, KEY_PAGEUP },
+ { NSPageDownFunctionKey, KEY_PAGEDOWN },
+ { NSTabCharacter, KEY_TAB },
+ { NSCarriageReturnCharacter, KEY_ENTER },
+ { NSEnterCharacter, KEY_ENTER },
+ { NSBackspaceCharacter, KEY_BACKSPACE },
+ { (unichar) ' ', KEY_SPACE },
+ { (unichar) 0x1b, KEY_ESC },
+ {0,0}
+};
+
+int CocoaConvertKey( unichar i_key )
+{
+ int i;
+
+ for( i = 0; nskeys_to_vlckeys[i].i_nskey != 0; i++ )
+ {
+ if( nskeys_to_vlckeys[i].i_nskey == i_key )
+ {
+ return nskeys_to_vlckeys[i].i_vlckey;
+ }
+ }
+ return (int)i_key;
+}
+
/*****************************************************************************
* VLCMain implementation
*****************************************************************************/
[o_mi_slower setTitle: _NS("Slower")];
[o_mi_previous setTitle: _NS("Previous")];
[o_mi_next setTitle: _NS("Next")];
- [o_mi_loop setTitle: _NS("Loop")];
+ [o_mi_random setTitle: _NS("Shuffle")];
+ [o_mi_repeat setTitle: _NS("Repeat Item")];
+ [o_mi_loop setTitle: _NS("Repeat Playlist")];
[o_mi_fwd setTitle: _NS("Step Forward")];
[o_mi_bwd setTitle: _NS("Step Backward")];
[o_mi_program setTitle: _NS("Program")];
[o_mi_vol_up setTitle: _NS("Volume Up")];
[o_mi_vol_down setTitle: _NS("Volume Down")];
[o_mi_mute setTitle: _NS("Mute")];
- [o_mi_audiotrack setTitle: _NS("Audio Track")];
- [o_mu_audiotrack setTitle: _NS("Audio Track")];
- [o_mi_channels setTitle: _NS("Channels")];
- [o_mu_channels setTitle: _NS("Channels")];
- [o_mi_device setTitle: _NS("Device")];
- [o_mu_device setTitle: _NS("Device")];
+ [o_mi_audiotrack setTitle: _NS("Audio track")];
+ [o_mu_audiotrack setTitle: _NS("Audio track")];
+ [o_mi_channels setTitle: _NS("Audio channels")];
+ [o_mu_channels setTitle: _NS("Audio channels")];
+ [o_mi_device setTitle: _NS("Audio device")];
+ [o_mu_device setTitle: _NS("Audio device")];
[o_mu_video setTitle: _NS("Video")];
[o_mi_half_window setTitle: _NS("Half Size")];
[o_mi_fittoscreen setTitle: _NS("Fit To Screen")];
[o_mi_fullscreen setTitle: _NS("Fullscreen")];
[o_mi_floatontop setTitle: _NS("Float On Top")];
- [o_mi_videotrack setTitle: _NS("Video Track")];
- [o_mu_videotrack setTitle: _NS("Video Track")];
- [o_mi_screen setTitle: _NS("Screen")];
- [o_mu_screen setTitle: _NS("Screen")];
- [o_mi_subtitle setTitle: _NS("Subtitles")];
- [o_mu_subtitle setTitle: _NS("Subtitles")];
+ [o_mi_videotrack setTitle: _NS("Video track")];
+ [o_mu_videotrack setTitle: _NS("Video track")];
+ [o_mi_screen setTitle: _NS("Video device")];
+ [o_mu_screen setTitle: _NS("Video device")];
+ [o_mi_subtitle setTitle: _NS("Subtitles track")];
+ [o_mu_subtitle setTitle: _NS("Subtitles track")];
[o_mi_deinterlace setTitle: _NS("Deinterlace")];
[o_mu_deinterlace setTitle: _NS("Deinterlace")];
[o_mu_help setTitle: _NS("Help")];
[o_mi_readme setTitle: _NS("ReadMe...")];
+ [o_mi_documentation setTitle: _NS("Online Documentation")];
[o_mi_reportabug setTitle: _NS("Report a Bug")];
[o_mi_website setTitle: _NS("VideoLAN Website")];
[o_mi_license setTitle: _NS("License")];
[o_info_window setTitle: _NS("Info")];
+ [self setSubmenusEnabled: FALSE];
[self manageVolumeSlider];
}
- (BOOL)application:(NSApplication *)o_app openFile:(NSString *)o_filename
{
- intf_thread_t * p_intf = [NSApp getIntf];
-
+ NSDictionary *o_dic = [NSDictionary dictionaryWithObjectsAndKeys: o_filename, @"ITEM_URL", nil];
[o_playlist appendArray:
- [NSArray arrayWithObject: o_filename] atPos: -1 enqueue: NO];
-
- config_PutPsz( [NSApp getIntf], "sub-file", "" );
- config_PutInt( p_intf, "sub-delay", 0 );
- config_PutFloat( p_intf, "sub-fps", 0.0 );
- config_PutPsz( p_intf, "sout", "" );
+ [NSArray arrayWithObject: o_dic] atPos: -1 enqueue: NO];
return( TRUE );
}
if( p_playlist != NULL )
{
- vlc_mutex_lock( &p_playlist->object_lock );
-
- [self manage: p_playlist];
-
- vlc_mutex_unlock( &p_playlist->object_lock );
- vlc_object_release( p_playlist );
- }
-
- vlc_mutex_unlock( &p_intf->change_lock );
-
- o_sleep_date = [NSDate dateWithTimeIntervalSinceNow: .5];
- [NSThread sleepUntilDate: o_sleep_date];
- }
-
- [self terminate];
-
- [o_pool release];
-}
-
-- (void)manage:(playlist_t *)p_playlist
-{
- vlc_value_t val;
-
- intf_thread_t * p_intf = [NSApp getIntf];
-
- if( var_Get( (vlc_object_t *)p_playlist, "intf-change", &val ) >= 0 &&
- val.b_bool )
- {
- p_intf->p_sys->b_playlist_update = VLC_TRUE;
- p_intf->p_sys->b_intf_update = VLC_TRUE;
- }
-
+ var_AddCallback( p_playlist, "intf-change", PlaylistChanged, self );
#define p_input p_playlist->p_input
-
- if( p_input )
- {
- vout_thread_t * p_vout = NULL;
- aout_instance_t * p_aout = NULL;
-
- vlc_mutex_lock( &p_input->stream.stream_lock );
-
- if( !p_input->b_die )
- {
- audio_volume_t i_volume;
-
- /* New input or stream map change */
- if( p_input->stream.b_changed )
- {
- p_intf->p_sys->b_playing = TRUE;
- [self manageMode: p_playlist];
- }
-
- vlc_value_t val;
-
- if( var_Get( (vlc_object_t *)p_input, "intf-change", &val )
- >= 0 && val.b_bool )
- {
- p_intf->p_sys->b_input_update = TRUE;
- }
-
- p_aout = vlc_object_find( p_intf, VLC_OBJECT_AOUT,
- FIND_ANYWHERE );
- if( p_aout != NULL )
+
+ if( p_input )
{
- vlc_value_t val;
-
- if( var_Get( (vlc_object_t *)p_aout, "intf-change", &val )
- >= 0 && val.b_bool )
+ if( !p_input->b_die )
{
- p_intf->p_sys->b_aout_update = TRUE;
+ vlc_value_t val;
+
+ /* New input or stream map change */
+ if( p_input->stream.b_changed )
+ {
+ msg_Dbg( p_intf, "stream has changed, refreshing interface" );
+ p_intf->p_sys->b_playing = TRUE;
+ p_intf->p_sys->b_current_title_update = 1;
+ p_input->stream.b_changed = 0;
+ p_intf->p_sys->b_intf_update = TRUE;
+ }
+
+ if( var_Get( (vlc_object_t *)p_input, "intf-change", &val )
+ >= 0 && val.b_bool )
+ {
+ p_intf->p_sys->b_input_update = TRUE;
+ }
}
-
- vlc_object_release( (vlc_object_t *)p_aout );
}
-
- aout_VolumeGet( p_intf, &i_volume );
- p_intf->p_sys->b_mute = ( i_volume == 0 );
-
- p_vout = vlc_object_find( p_intf, VLC_OBJECT_VOUT,
- FIND_ANYWHERE );
- if( p_vout != NULL )
+ else if( p_intf->p_sys->b_playing && !p_intf->b_die )
{
- vlc_value_t val;
-
- if( var_Get( (vlc_object_t *)p_vout, "intf-change", &val )
- >= 0 && val.b_bool )
- {
- p_intf->p_sys->b_vout_update = TRUE;
- }
-
- vlc_object_release( (vlc_object_t *)p_vout );
+ p_intf->p_sys->b_playing = FALSE;
+ p_intf->p_sys->b_intf_update = TRUE;
}
- [self setupMenus: p_input];
- }
- vlc_mutex_unlock( &p_input->stream.stream_lock );
- }
- else if( p_intf->p_sys->b_playing && !p_intf->b_die )
- {
- p_intf->p_sys->b_playing = FALSE;
- [self manageMode: p_playlist];
- }
-
+
#undef p_input
-}
-
-- (void)manageMode:(playlist_t *)p_playlist
-{
- intf_thread_t * p_intf = [NSApp getIntf];
+ vlc_object_release( p_playlist );
+ }
- if( p_playlist->p_input != NULL )
- {
- p_intf->p_sys->b_current_title_update = 1;
- p_playlist->p_input->stream.b_changed = 0;
-
- msg_Dbg( p_intf, "stream has changed, refreshing interface" );
- }
- else
- {
- vout_thread_t * p_vout = vlc_object_find( p_intf, VLC_OBJECT_VOUT,
- FIND_ANYWHERE );
- if( p_vout != NULL )
- {
- vlc_object_detach( p_vout );
- vlc_object_release( p_vout );
+ vlc_mutex_unlock( &p_intf->change_lock );
- vlc_mutex_unlock( &p_playlist->object_lock );
- vout_Destroy( p_vout );
- vlc_mutex_lock( &p_playlist->object_lock );
- }
+ o_sleep_date = [NSDate dateWithTimeIntervalSinceNow: .5];
+ [NSThread sleepUntilDate: o_sleep_date];
}
- p_intf->p_sys->b_intf_update = VLC_TRUE;
+ [self terminate];
+ [o_pool release];
}
- (void)manageIntf:(NSTimer *)o_timer
if ( p_intf->p_sys->b_playlist_update )
{
- vlc_value_t val;
-
- val.b_bool = FALSE;
- var_Set( (vlc_object_t *)p_playlist, "intf-change", val );
-
[o_playlist playlistUpdated];
-
p_intf->p_sys->b_playlist_update = VLC_FALSE;
}
#define p_input p_playlist->p_input
- if( p_input != NULL )
- {
- vlc_mutex_lock( &p_input->stream.stream_lock );
- }
-
if( p_intf->p_sys->b_intf_update )
{
vlc_bool_t b_input = VLC_FALSE;
vlc_bool_t b_control = VLC_FALSE;
vlc_bool_t b_seekable = VLC_FALSE;
vlc_bool_t b_chapters = VLC_FALSE;
+ vlc_value_t val;
b_plmul = p_playlist->i_size > 1;
if( ( b_input = ( p_input != NULL ) ) )
{
+ vlc_mutex_lock( &p_input->stream.stream_lock );
+
/* seekable streams */
b_seekable = p_input->stream.b_seekable;
/* control buttons for free pace streams */
b_control = p_input->stream.b_pace_control;
- /* chapters */
- b_chapters = p_input->stream.p_selected_area->i_part_nb > 1;
+ /* chapters & titles */
+ b_chapters = p_input->stream.i_area_nb > 1;
+
+ vlc_mutex_unlock( &p_input->stream.stream_lock );
/* play status */
- p_intf->p_sys->b_play_status =
- p_input->stream.control.i_status != PAUSE_S;
+ var_Get( p_input, "state", &val );
+ p_intf->p_sys->b_play_status = val.i_int != PAUSE_S;
}
else
{
/* play status */
- p_intf->p_sys->b_play_status = VLC_FALSE;
+ p_intf->p_sys->b_play_status = FALSE;
+ [self setSubmenusEnabled: FALSE];
}
[self playStatusUpdated: p_intf->p_sys->b_play_status];
p_intf->p_sys->b_intf_update = VLC_FALSE;
}
-#define p_area p_input->stream.p_selected_area
-
if( p_intf->p_sys->b_playing && p_input != NULL )
{
- vlc_bool_t b_field_update = TRUE;
+ vlc_value_t time, val;
+ NSString * o_time;
+ mtime_t i_seconds;
+ var_Get( p_input, "state", &val );
if( !p_input->b_die && ( p_intf->p_sys->b_play_status !=
- ( p_input->stream.control.i_status != PAUSE_S ) ) )
+ ( val.i_int != PAUSE_S ) ) )
{
p_intf->p_sys->b_play_status =
!p_intf->p_sys->b_play_status;
if( p_input->stream.b_seekable )
{
- if( f_slider == f_slider_old )
- {
- float f_updated = ( 10000. * p_area->i_tell ) /
- p_area->i_size;
+ vlc_value_t pos;
+ float f_updated;
+
+ var_Get( p_input, "position", &pos );
+ f_updated = 10000. * pos.f_float;
- if( f_slider != f_updated )
- {
- [o_timeslider setFloatValue: f_updated];
- }
- }
- else
+ if( f_slider != f_updated )
{
- off_t i_seek = ( f_slider * p_area->i_size ) / 10000;
-
- /* release the lock to be able to seek */
- vlc_mutex_unlock( &p_input->stream.stream_lock );
- input_Seek( p_input, i_seek, INPUT_SEEK_SET );
- vlc_mutex_lock( &p_input->stream.stream_lock );
-
- /* update the old value */
- f_slider_old = f_slider;
-
- b_field_update = VLC_FALSE;
+ [o_timeslider setFloatValue: f_updated];
}
}
-
- if( b_field_update )
- {
- NSString * o_time;
- char psz_time[ OFFSETTOTIME_MAX_SIZE ];
-
- input_OffsetToTime( p_input, psz_time, p_area->i_tell );
-
- o_time = [NSString stringWithCString: psz_time];
- [o_timefield setStringValue: o_time];
- }
+
+ var_Get( p_input, "time", &time );
+ i_seconds = time.i_time / 1000000;
+
+ o_time = [NSString stringWithFormat: @"%d:%02d:%02d",
+ (int) (i_seconds / (60 * 60)),
+ (int) (i_seconds / 60 % 60),
+ (int) (i_seconds % 60)];
+ [o_timefield setStringValue: o_time];
/* disable screen saver */
UpdateSystemActivity( UsrActivity );
}
-#undef p_area
-
- if( p_input != NULL )
- {
- vlc_mutex_unlock( &p_input->stream.stream_lock );
- }
-
#undef p_input
vlc_mutex_unlock( &p_playlist->object_lock );
userInfo: nil repeats: FALSE];
}
+- (void)setupMenus
+{
+ intf_thread_t * p_intf = [NSApp getIntf];
+ playlist_t *p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
+ FIND_ANYWHERE );
+
+ if( p_playlist != NULL )
+ {
+#define p_input p_playlist->p_input
+ if( p_input != NULL )
+ {
+ [o_controls setupVarMenuItem: o_mi_program target: (vlc_object_t *)p_input
+ var: "program" selector: @selector(toggleVar:)];
+
+ [o_controls setupVarMenuItem: o_mi_title target: (vlc_object_t *)p_input
+ var: "title" selector: @selector(toggleVar:)];
+
+ [o_controls setupVarMenuItem: o_mi_chapter target: (vlc_object_t *)p_input
+ var: "chapter" selector: @selector(toggleVar:)];
+
+ [o_controls setupVarMenuItem: o_mi_audiotrack target: (vlc_object_t *)p_input
+ var: "audio-es" selector: @selector(toggleVar:)];
+
+ [o_controls setupVarMenuItem: o_mi_videotrack target: (vlc_object_t *)p_input
+ var: "video-es" selector: @selector(toggleVar:)];
+
+ [o_controls setupVarMenuItem: o_mi_subtitle target: (vlc_object_t *)p_input
+ var: "spu-es" selector: @selector(toggleVar:)];
+
+ aout_instance_t * p_aout = vlc_object_find( p_intf, VLC_OBJECT_AOUT,
+ FIND_ANYWHERE );
+ if ( p_aout != NULL )
+ {
+ [o_controls setupVarMenuItem: o_mi_channels target: (vlc_object_t *)p_aout
+ var: "audio-channels" selector: @selector(toggleVar:)];
+
+ [o_controls setupVarMenuItem: o_mi_device target: (vlc_object_t *)p_aout
+ var: "audio-device" selector: @selector(toggleVar:)];
+ vlc_object_release( (vlc_object_t *)p_aout );
+ }
+
+ vout_thread_t * p_vout = vlc_object_find( p_intf, VLC_OBJECT_VOUT,
+ FIND_ANYWHERE );
+
+ if ( p_vout != NULL )
+ {
+ [o_controls setupVarMenuItem: o_mi_screen target: (vlc_object_t *)p_vout
+ var: "video-device" selector: @selector(toggleVar:)];
+
+ [o_controls setupVarMenuItem: o_mi_deinterlace target: (vlc_object_t *)p_vout
+ var: "deinterlace" selector: @selector(toggleVar:)];
+ vlc_object_release( (vlc_object_t *)p_vout );
+ }
+ }
+#undef p_input
+ }
+ vlc_object_release( (vlc_object_t *)p_playlist );
+}
+
- (void)updateMessageArray
{
int i_start, i_stop;
}
}
+- (void)setSubmenusEnabled:(BOOL)b_enabled
+{
+ [o_mi_program setEnabled: b_enabled];
+ [o_mi_title setEnabled: b_enabled];
+ [o_mi_chapter setEnabled: b_enabled];
+ [o_mi_audiotrack setEnabled: b_enabled];
+ [o_mi_videotrack setEnabled: b_enabled];
+ [o_mi_subtitle setEnabled: b_enabled];
+ [o_mi_channels setEnabled: b_enabled];
+ [o_mi_deinterlace setEnabled: b_enabled];
+ [o_mi_device setEnabled: b_enabled];
+ [o_mi_screen setEnabled: b_enabled];
+}
+
- (void)manageVolumeSlider
{
audio_volume_t i_volume;
p_intf->p_sys->b_mute = ( i_volume == 0 );
}
+- (IBAction)timesliderUpdate:(id)sender
+{
+ intf_thread_t * p_intf;
+ input_thread_t * p_input;
+ float f_updated;
+
+ switch( [[NSApp currentEvent] type] )
+ {
+ case NSLeftMouseUp:
+ case NSLeftMouseDown:
+ case NSLeftMouseDragged:
+ f_updated = [sender floatValue];
+ break;
+
+ default:
+ return;
+ }
+
+ p_intf = [NSApp getIntf];
+ p_input = vlc_object_find( p_intf, VLC_OBJECT_INPUT,
+ FIND_ANYWHERE );
+
+ if( p_input != NULL )
+ {
+ vlc_value_t time;
+ mtime_t i_seconds;
+ NSString * o_time;
+
+ if( p_input->stream.b_seekable )
+ {
+ vlc_value_t pos;
+ pos.f_float = f_updated / 10000.;
+ if( f_slider != f_updated )
+ {
+ var_Set( p_input, "position", pos );
+ [o_timeslider setFloatValue: f_updated];
+ }
+ }
+
+ var_Get( p_input, "time", &time );
+ i_seconds = time.i_time / 1000000;
+
+ o_time = [NSString stringWithFormat: @"%d:%02d:%02d",
+ (int) (i_seconds / (60 * 60)),
+ (int) (i_seconds / 60 % 60),
+ (int) (i_seconds % 60)];
+ [o_timefield setStringValue: o_time];
+ vlc_object_release( p_input );
+ }
+}
+
- (void)terminate
{
NSEvent * o_event;
- vout_thread_t * p_vout;
playlist_t * p_playlist;
intf_thread_t * p_intf = [NSApp getIntf];
playlist_Destroy( p_playlist );
}
- /*
- * Free video outputs
- */
- msg_Dbg( p_intf, "removing all video outputs" );
- while( (p_vout = vlc_object_find( p_intf->p_vlc,
- VLC_OBJECT_VOUT, FIND_CHILD )) )
- {
- vlc_object_detach( p_vout );
- vlc_object_release( p_vout );
- vout_Destroy( p_vout );
- }
-
if( o_img_pause != nil )
{
[o_img_pause release];
o_msg_lock = nil;
}
- if( o_prefs != nil )
- {
- [o_prefs release];
- o_prefs = nil;
- }
-
[NSApp stop: nil];
/* write cached user defaults to disk */
[NSApp postEvent: o_event atStart: YES];
}
-- (void)setupMenus:(input_thread_t *)p_input
-{
- intf_thread_t * p_intf = [NSApp getIntf];
- vlc_value_t val;
-
- if( p_intf->p_sys->b_input_update )
- {
- val.b_bool = FALSE;
-
- [self setupVarMenu: o_mi_program target: (vlc_object_t *)p_input
- var: "program" selector: @selector(toggleVar:)];
-
- [self setupVarMenu: o_mi_title target: (vlc_object_t *)p_input
- var: "title" selector: @selector(toggleVar:)];
-
- [self setupVarMenu: o_mi_chapter target: (vlc_object_t *)p_input
- var: "chapter" selector: @selector(toggleVar:)];
-
- [self setupVarMenu: o_mi_audiotrack target: (vlc_object_t *)p_input
- var: "audio-es" selector: @selector(toggleVar:)];
-
- [self setupVarMenu: o_mi_videotrack target: (vlc_object_t *)p_input
- var: "video-es" selector: @selector(toggleVar:)];
-
- [self setupVarMenu: o_mi_subtitle target: (vlc_object_t *)p_input
- var: "spu-es" selector: @selector(toggleVar:)];
-
- p_intf->p_sys->b_input_update = FALSE;
- var_Set( (vlc_object_t *)p_input, "intf-change", val );
- }
-
- if ( p_intf->p_sys->b_aout_update )
- {
- aout_instance_t * p_aout = vlc_object_find( p_intf, VLC_OBJECT_AOUT,
- FIND_ANYWHERE );
-
- if ( p_aout != NULL )
- {
- val.b_bool = FALSE;
-
- [self setupVarMenu: o_mi_channels target: (vlc_object_t *)p_aout
- var: "audio-channels" selector: @selector(toggleVar:)];
-
- [self setupVarMenu: o_mi_device target: (vlc_object_t *)p_aout
- var: "audio-device" selector: @selector(toggleVar:)];
- var_Set( (vlc_object_t *)p_aout, "intf-change", val );
-
- vlc_object_release( (vlc_object_t *)p_aout );
- }
- p_intf->p_sys->b_aout_update = FALSE;
- }
-
- if( p_intf->p_sys->b_vout_update )
- {
- vout_thread_t * p_vout = vlc_object_find( p_intf, VLC_OBJECT_VOUT,
- FIND_ANYWHERE );
-
- if ( p_vout != NULL )
- {
- val.b_bool = FALSE;
-
- [self setupVarMenu: o_mi_screen target: (vlc_object_t *)p_vout
- var: "video-device" selector: @selector(toggleVar:)];
- var_Set( (vlc_object_t *)p_vout, "intf-change", val );
-
- vlc_object_release( (vlc_object_t *)p_vout );
- [o_mi_close_window setEnabled: TRUE];
- }
-
- p_intf->p_sys->b_vout_update = FALSE;
- }
-}
-
-- (void)setupVarMenu:(NSMenuItem *)o_mi
- target:(vlc_object_t *)p_object
- var:(const char *)psz_variable
- selector:(SEL)pf_callback
-{
- int i, i_nb_items, i_value;
- NSMenu * o_menu = [o_mi submenu];
- vlc_value_t val, text;
-
- [o_mi setTag: (int)psz_variable];
-
- /* remove previous items */
- i_nb_items = [o_menu numberOfItems];
- for( i = 0; i < i_nb_items; i++ )
- {
- [o_menu removeItemAtIndex: 0];
- }
-
- if ( var_Get( p_object, psz_variable, &val ) < 0 )
- {
- return;
- }
- i_value = val.i_int;
-
- if ( var_Change( p_object, psz_variable,
- VLC_VAR_GETLIST, &val, &text ) < 0 )
- {
- return;
- }
-
- /* make (un)sensitive */
- [o_mi setEnabled: ( val.p_list->i_count > 1 )];
-
- for ( i = 0; i < val.p_list->i_count; i++ )
- {
- NSMenuItem * o_lmi;
- NSString * o_title;
-NSLog(@"%d, %s", i_value, psz_variable);
-
- if ( text.p_list->p_values[i].psz_string )
- {
- o_title = [NSApp localizedString: text.p_list->p_values[i].psz_string];
- }
- else
- {
- o_title = [NSString stringWithFormat: @"%s - %d",
- strdup(psz_variable), val.p_list->p_values[i].i_int ];
- }
- o_lmi = [o_menu addItemWithTitle: [o_title copy]
- action: pf_callback keyEquivalent: @""];
-
- /* FIXME: this isn't 64-bit clean ! */
- [o_lmi setTag: val.p_list->p_values[i].i_int];
- [o_lmi setRepresentedObject:
- [NSValue valueWithPointer: p_object]];
- [o_lmi setTarget: o_controls];
-
- if ( i_value == val.p_list->p_values[i].i_int )
- [o_lmi setState: NSOnState];
- }
-
- var_Change( p_object, psz_variable, VLC_VAR_FREELIST,
- &val, &text );
-
-}
-
- (IBAction)clearRecentItems:(id)sender
{
[[NSDocumentController sharedDocumentController]
- (IBAction)viewPreferences:(id)sender
{
- if( o_prefs == nil )
- {
- o_prefs = [[VLCPrefs alloc] init];
- }
-
- [o_prefs createPrefPanel: @"main"];
-}
-
-- (IBAction)timesliderUpdate:(id)sender
-{
- float f_updated;
-
- switch( [[NSApp currentEvent] type] )
- {
- case NSLeftMouseUp:
- case NSLeftMouseDown:
- f_slider = [sender floatValue];
- return;
-
- case NSLeftMouseDragged:
- f_updated = [sender floatValue];
- break;
-
- default:
- return;
- }
-
- intf_thread_t * p_intf = [NSApp getIntf];
-
- playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
- FIND_ANYWHERE );
-
- if( p_playlist == NULL )
- {
- return;
- }
-
- vlc_mutex_lock( &p_playlist->object_lock );
-
- if( p_playlist->p_input != NULL )
- {
- off_t i_tell;
- NSString * o_time;
- char psz_time[ OFFSETTOTIME_MAX_SIZE ];
-
-#define p_area p_playlist->p_input->stream.p_selected_area
- vlc_mutex_lock( &p_playlist->p_input->stream.stream_lock );
- i_tell = f_updated / 10000. * p_area->i_size;
- input_OffsetToTime( p_playlist->p_input, psz_time, i_tell );
- vlc_mutex_unlock( &p_playlist->p_input->stream.stream_lock );
-#undef p_area
-
- o_time = [NSString stringWithCString: psz_time];
- [o_timefield setStringValue: o_time];
- }
-
- vlc_mutex_unlock( &p_playlist->object_lock );
- vlc_object_release( p_playlist );
+ [o_prefs showPrefs];
}
- (IBAction)closeError:(id)sender
withApplication: @"TextEdit"];
}
+- (IBAction)openDocumentation:(id)sender
+{
+ NSURL * o_url = [NSURL URLWithString:
+ @"http://www.videolan.org/doc/"];
+
+ [[NSWorkspace sharedWorkspace] openURL: o_url];
+}
+
- (IBAction)reportABug:(id)sender
{
NSURL * o_url = [NSURL URLWithString:
- (BOOL)validateMenuItem:(NSMenuItem *)o_mi
{
+ NSString *o_title = [o_mi title];
BOOL bEnabled = TRUE;
- /* Recent Items Menu */
+ if( [o_title isEqualToString: _NS("License")] )
+ {
+ /* we need to do this only once */
+ [self setupMenus];
+ }
- if( [[o_mi title] isEqualToString: _NS("Clear Menu")] )
+ /* Recent Items Menu */
+ if( [o_title isEqualToString: _NS("Clear Menu")] )
{
NSMenu * o_menu = [o_mi_open_recent submenu];
int i_nb_items = [o_menu numberOfItems];
bEnabled = FALSE;
}
}
-
return( bEnabled );
}