#import "wizard.h"
#import "extended.h"
#import "bookmarks.h"
-#import "sfilters.h"
#import "interaction.h"
#import "embeddedwindow.h"
#import "update.h"
p_intf->p_sys->o_pool = [[NSAutoreleasePool alloc] init];
- p_intf->p_sys->o_sendport = [[NSPort port] retain];
p_intf->p_sys->p_sub = msg_Subscribe( p_intf );
p_intf->pf_run = Run;
p_intf->b_should_run_on_first_thread = true;
msg_Unsubscribe( p_intf, p_intf->p_sys->p_sub );
- [p_intf->p_sys->o_sendport release];
[p_intf->p_sys->o_pool release];
free( p_intf->p_sys );
}
-/*****************************************************************************
- * KillerThread: Thread that kill the application
- *****************************************************************************/
-static void * KillerThread( void *user_data )
-{
- NSAutoreleasePool * o_pool = [[NSAutoreleasePool alloc] init];
-
- intf_thread_t *p_intf = user_data;
-
- vlc_object_lock ( p_intf );
- while( vlc_object_alive( p_intf ) )
- vlc_object_wait( p_intf );
- vlc_object_unlock( p_intf );
-
- msg_Dbg( p_intf, "Killing the Mac OS X module" );
-
- /* We are dead, terminate */
- [NSApp terminate: nil];
- [o_pool release];
- return NULL;
-}
-
/*****************************************************************************
* Run: main loop
*****************************************************************************/
[[VLCMain sharedInstance] setIntf: p_intf];
[NSBundle loadNibNamed: @"MainMenu" owner: NSApp];
- /* Setup a thread that will monitor the module killing */
- pthread_t killer_thread;
- pthread_create( &killer_thread, NULL, KillerThread, p_intf );
-
/* Install a jmpbuffer to where we can go back before the NSApp exit
* see applicationWillTerminate: */
if(setjmp(jmpbuffer) == 0)
[NSApp run];
- pthread_join( killer_thread, NULL );
-
[o_pool release];
}
-int ExecuteOnMainThread( id target, SEL sel, void * p_arg )
+/*****************************************************************************
+ * ManageThread: An ugly thread that polls
+ *****************************************************************************/
+static void * ManageThread( void *user_data )
{
- int i_ret = 0;
-
- //NSAutoreleasePool * o_pool = [[NSAutoreleasePool alloc] init];
-
- if( [target respondsToSelector: @selector(performSelectorOnMainThread:
- withObject:waitUntilDone:)] )
- {
- [target performSelectorOnMainThread: sel
- withObject: [NSValue valueWithPointer: p_arg]
- waitUntilDone: NO];
- }
- else if( NSApp != nil && [[VLCMain sharedInstance] respondsToSelector: @selector(getIntf)] )
- {
- NSValue * o_v1;
- NSValue * o_v2;
- NSArray * o_array;
- NSPort * o_recv_port;
- NSInvocation * o_inv;
- NSPortMessage * o_msg;
- intf_thread_t * p_intf;
- NSConditionLock * o_lock;
- NSMethodSignature * o_sig;
-
- id * val[] = { &o_lock, &o_v2 };
-
- p_intf = (intf_thread_t *)VLCIntf;
-
- o_recv_port = [[NSPort port] retain];
- o_v1 = [NSValue valueWithPointer: val];
- o_v2 = [NSValue valueWithPointer: p_arg];
-
- o_sig = [target methodSignatureForSelector: sel];
- o_inv = [NSInvocation invocationWithMethodSignature: o_sig];
- [o_inv setArgument: &o_v1 atIndex: 2];
- [o_inv setTarget: target];
- [o_inv setSelector: sel];
-
- o_array = [NSArray arrayWithObject:
- [NSData dataWithBytes: &o_inv length: sizeof(o_inv)]];
- o_msg = [[NSPortMessage alloc]
- initWithSendPort: p_intf->p_sys->o_sendport
- receivePort: o_recv_port components: o_array];
-
- o_lock = [[NSConditionLock alloc] initWithCondition: 0];
- [o_msg sendBeforeDate: [NSDate distantPast]];
- [o_lock lockWhenCondition: 1];
- [o_lock unlock];
- [o_lock release];
-
- [o_msg release];
- [o_recv_port release];
- }
- else
- {
- i_ret = 1;
- }
+ id self = user_data;
- //[o_pool release];
+ [self manage];
- return( i_ret );
+ return NULL;
}
/*****************************************************************************
o_embedded_list = [[VLCEmbeddedList alloc] init];
o_interaction_list = [[VLCInteractionList alloc] init];
o_info = [[VLCInfo alloc] init];
- o_sfilters = nil;
#ifdef UPDATE_CHECK
o_update = [[VLCUpdate alloc] init];
#endif
else
{
b_small_window = NO;
- [o_playlist_view setFrame: NSMakeRect( 10, 10, [o_window frame].size.width - 20, [o_window frame].size.height - 105 )];
+ [o_playlist_view setFrame: NSMakeRect( 0, 0, [o_window frame].size.width, [o_window frame].size.height - 95 )];
[o_playlist_view setNeedsDisplay:YES];
[o_playlist_view setAutoresizesSubviews: YES];
[[o_window contentView] addSubview: o_playlist_view];
o_msg_lock = [[NSLock alloc] init];
o_msg_arr = [[NSMutableArray arrayWithCapacity: 200] retain];
- [p_intf->p_sys->o_sendport setDelegate: self];
- [[NSRunLoop currentRunLoop]
- addPort: p_intf->p_sys->o_sendport
- forMode: NSDefaultRunLoopMode];
-
/* FIXME: don't poll */
- [NSTimer scheduledTimerWithTimeInterval: 0.5
+ interfaceTimer = [[NSTimer scheduledTimerWithTimeInterval: 0.5
target: self selector: @selector(manageIntf:)
- userInfo: nil repeats: FALSE];
+ userInfo: nil repeats: FALSE] retain];
- /* FIXME: don't poll */
- [NSThread detachNewThreadSelector: @selector(manage)
- toTarget: self withObject: nil];
+ /* Note: we use the pthread API to support pre-10.5 */
+ pthread_create( &manage_thread, NULL, ManageThread, self );
[o_controls setupVarMenuItem: o_mi_add_intf target: (vlc_object_t *)p_intf
var: "intf-add" selector: @selector(toggleVar:)];
- (void)manage
{
playlist_t * p_playlist;
+ input_thread_t * p_input = NULL;
/* new thread requires a new pool */
NSAutoreleasePool * o_pool = [[NSAutoreleasePool alloc] init];
{
vlc_mutex_lock( &p_intf->change_lock );
- if( p_intf->p_sys->p_input == NULL )
+ if( !p_input )
{
- p_intf->p_sys->p_input = p_playlist->p_input;
+ p_input = playlist_CurrentInput( p_playlist );
/* Refresh the interface */
- if( p_intf->p_sys->p_input )
+ if( p_input )
{
msg_Dbg( p_intf, "input has changed, refreshing interface" );
p_intf->p_sys->b_input_update = true;
}
}
- else if( p_intf->p_sys->p_input->b_die || p_intf->p_sys->p_input->b_dead )
+ else if( !vlc_object_alive (p_input) || p_input->b_dead )
{
/* input stopped */
p_intf->p_sys->b_intf_update = true;
p_intf->p_sys->i_play_status = END_S;
msg_Dbg( p_intf, "input has stopped, refreshing interface" );
- p_intf->p_sys->p_input = NULL;
+ vlc_object_release( p_input );
+ p_input = NULL;
}
/* Manage volume status */
[self manageVolumeSlider];
vlc_mutex_unlock( &p_intf->change_lock );
- vlc_object_unlock( p_intf );
- msleep( 100000 );
- vlc_object_lock( p_intf );
+
+ vlc_object_timedwait( p_intf, 100000 + mdate());
}
vlc_object_unlock( p_intf );
[o_pool release];
+
+ if( p_input ) vlc_object_release( p_input );
+
+ var_DelCallback( p_playlist, "playlist-current", PlaylistChanged, self );
+ var_DelCallback( p_playlist, "intf-change", PlaylistChanged, self );
+ var_DelCallback( p_playlist, "item-change", PlaylistChanged, self );
+ var_DelCallback( p_playlist, "item-append", PlaylistChanged, self );
+ var_DelCallback( p_playlist, "item-deleted", PlaylistChanged, self );
+
+ pthread_testcancel(); /* If we were cancelled stop here */
+
+ msg_Dbg( p_intf, "Killing the Mac OS X module" );
+
+ /* We are dead, terminate */
+ [NSApp performSelectorOnMainThread: @selector(terminate:) withObject:nil waitUntilDone:NO];
}
- (void)manageIntf:(NSTimer *)o_timer
playlist_t * p_playlist;
input_thread_t * p_input;
- vlc_object_lock( p_intf );
-
- if( !vlc_object_alive( p_intf ) )
- {
- vlc_object_unlock( p_intf );
- [o_timer invalidate];
- return;
- }
-
if( p_intf->p_sys->b_input_update )
{
/* Called when new input is opened */
p_input = vlc_object_find( p_playlist, VLC_OBJECT_INPUT,
FIND_CHILD );
- if( p_input && !p_input->b_die )
+ if( p_input && vlc_object_alive (p_input) )
{
vlc_value_t val;
if( p_playlist->status.p_item == NULL )
{
vlc_object_release( p_input );
- vlc_object_release( p_playlist );
- return;
+ pl_Release( p_intf );
+ goto end;
}
if( input_item_GetNowPlaying ( p_playlist->status.p_item->p_input ) )
o_temp = [NSString stringWithUTF8String:
else
{
p_intf->p_sys->i_play_status = END_S;
- p_intf->p_sys->b_playlist_update = true;
[self playStatusUpdated: p_intf->p_sys->i_play_status];
[o_embedded_window playStatusUpdated: p_intf->p_sys->i_play_status];
[self setSubmenusEnabled: FALSE];
}
- vlc_object_release( p_playlist );
+ pl_Release( p_intf );
+end:
[self updateMessageArray];
if( ((i_end_scroll != -1) && (mdate() > i_end_scroll)) || !p_input )
[self resetScrollField];
- [NSTimer scheduledTimerWithTimeInterval: 0.3
+ [interfaceTimer autorelease];
+
+ interfaceTimer = [[NSTimer scheduledTimerWithTimeInterval: 0.3
target: self selector: @selector(manageIntf:)
- userInfo: nil repeats: FALSE];
- vlc_object_unlock( p_intf );
+ userInfo: nil repeats: FALSE] retain];
}
- (void)setupMenus
input_thread_t * p_input = p_playlist->p_input;
i_end_scroll = -1;
- if( p_input && !p_input->b_die )
+ if( p_input && vlc_object_alive (p_input) )
{
NSString *o_temp;
vlc_object_yield( p_input );
msg_Dbg( p_intf, "Terminating" );
+ /* Make sure the manage_thread won't call -terminate: again */
+ pthread_cancel( manage_thread );
+
+ /* Make sure the intf object is getting killed */
+ vlc_object_kill( p_intf );
+
+ /* Make sure our manage_thread ends */
+ pthread_join( manage_thread, NULL );
+
+ /* Make sure the interfaceTimer is destroyed */
+ [interfaceTimer invalidate];
+ [interfaceTimer release];
+ interfaceTimer = nil;
+
/* make sure that the current volume is saved */
config_PutInt( p_intf->p_libvlc, "volume", i_lastShownVolume );
returnedValue = config_SaveConfigFile( p_intf->p_libvlc, "main" );
[o_extended showPanel];
}
-- (IBAction)showSFilters:(id)sender
-{
- if( o_sfilters == nil )
- {
- o_sfilters = [[VLCsFilters alloc] init];
- }
- if( !nib_sfilters_loaded )
- {
- nib_sfilters_loaded = [NSBundle loadNibNamed:@"SFilters" owner:self];
- [o_sfilters initStrings];
- [o_sfilters showAsPanel];
- } else {
- [o_sfilters showAsPanel];
- }
-}
-
- (IBAction)showBookmarks:(id)sender
{
/* we need the wizard-nib for the bookmarks's extract functionality */
{
/* If large and coming from small then show */
[o_playlist_view setAutoresizesSubviews: YES];
- [o_playlist_view setFrame: NSMakeRect( 10, 10, [o_window frame].size.width - 20, [o_window frame].size.height - [o_window minSize].height - 10 )];
+ [o_playlist_view setFrame: NSMakeRect( 0, 0, [o_window frame].size.width, [o_window frame].size.height - [o_window minSize].height )];
[o_playlist_view setNeedsDisplay:YES];
[[o_window contentView] addSubview: o_playlist_view];
b_small_window = NO;