Commit f3ccaec1 authored by bigben's avatar bigben

* Apply changed made to the 0.8.5 branch to trunk.

* Embedded Vout should work now
* To create an embedded vout, just create a custom view of type VLCEmbeddedVoutView in interface builder
* Just make sure you define the view as resizeable
* Hotkeys and mose events should work
* Tests with the mozilla plugin are welcome

parent 3371c10f
......@@ -34,6 +34,7 @@
OUTLETS = {"o_btn_fullscreen" = id; "o_main" = id; "o_volumeslider" = id; };
SUPERCLASS = NSObject;
},
{CLASS = VLCEmbeddedVoutView; LANGUAGE = ObjC; SUPERCLASS = VLCVoutView; },
{
ACTIONS = {
bandSliderUpdated = id;
......@@ -287,7 +288,8 @@
};
SUPERCLASS = NSObject;
},
{CLASS = VLCPlaylistView; LANGUAGE = ObjC; SUPERCLASS = NSOutlineView; }
{CLASS = VLCPlaylistView; LANGUAGE = ObjC; SUPERCLASS = NSOutlineView; },
{CLASS = VLCVoutView; LANGUAGE = ObjC; SUPERCLASS = NSView; }
);
IBVersion = 1;
}
\ No newline at end of file
}
......@@ -7,6 +7,7 @@
* Authors: Jon Lech Johansen <jon-vl@nanocrew.net>
* Christophe Massiot <massiot@via.ecp.fr>
* Derk-Jan Hartman <hartman at videolan dot org>
* Benjamin Pracht <bigben at videolan doit org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -268,18 +269,31 @@
if( p_vout != NULL )
{
id o_embedded_vout_list = [[VLCMain sharedInstance] getEmbeddedList];
while ((o_window = [o_enumerator nextObject]))
{
if( [[o_window className] isEqualToString: @"VLCWindow"] )
id o_vout_view = nil;
/* We have an embedded vout */
if( [o_embedded_vout_list windowContainsEmbedded: o_window] )
{
o_vout_view = [o_embedded_vout_list getViewForWindow: o_window];
}
/* We have a detached Vout */
else if( [[o_window className] isEqualToString: @"VLCWindow"] )
{
o_vout_view = [o_window getVoutView];
}
if( o_vout_view )
{
if( [o_title isEqualToString: _NS("Half Size") ] )
[o_window scaleWindowWithFactor: 0.5];
[o_vout_view scaleWindowWithFactor: 0.5];
else if( [o_title isEqualToString: _NS("Normal Size") ] )
[o_window scaleWindowWithFactor: 1.0];
[o_vout_view scaleWindowWithFactor: 1.0];
else if( [o_title isEqualToString: _NS("Double Size") ] )
[o_window scaleWindowWithFactor: 2.0];
[o_vout_view scaleWindowWithFactor: 2.0];
else if( [o_title isEqualToString: _NS("Float on Top") ] )
[o_window toggleFloatOnTop];
[o_vout_view toggleFloatOnTop];
else if( [o_title isEqualToString: _NS("Fit to Screen") ] )
{
if( ![o_window isZoomed] )
......@@ -287,11 +301,11 @@
}
else if( [o_title isEqualToString: _NS("Snapshot") ] )
{
[o_window snapshot];
[o_vout_view snapshot];
}
else
{
[o_window toggleFullscreen];
[o_vout_view toggleFullscreen];
}
break;
}
......@@ -470,7 +484,7 @@
Value: another_val ofType: i_type];
[o_lmi setRepresentedObject: [NSValue valueWithPointer:[o_data retain]]];
[o_lmi setTarget: self];
if( !strcmp( val.psz_string, val_list.p_list->p_values[i].psz_string ) && !( i_type & VLC_VAR_ISCOMMAND ) )
[o_lmi setState: TRUE ];
......@@ -497,7 +511,7 @@
break;
}
}
/* clean up everything */
if( (i_type & VLC_VAR_TYPE) == VLC_VAR_STRING ) free( val.psz_string );
var_Change( p_object, psz_variable, VLC_VAR_FREELIST, &val_list, &text_list );
......@@ -640,7 +654,9 @@
while( (o_window = [o_enumerator nextObject]))
{
if( [[o_window className] isEqualToString: @"VLCWindow"] )
if( [[o_window className] isEqualToString: @"VLCWindow"] ||
[[[VLCMain sharedInstance] getEmbeddedList]
windowContainsEmbedded: o_window])
{
bEnabled = TRUE;
break;
......
......@@ -79,6 +79,7 @@ struct intf_sys_t
/* The messages window */
msg_subscription_t * p_sub;
};
/*****************************************************************************
......@@ -93,6 +94,7 @@ struct intf_sys_t
id o_wizard; /* VLCWizard */
id o_extended; /* VLCExtended */
id o_bookmarks; /* VLCBookmarks */
id o_embedded_list; /* VLCEmbeddedList*/
id o_sfilters; /* VLCsFilters */
/*id o_update; VLCUpdate */
BOOL nib_main_loaded; /* reference to the main-nib */
......@@ -278,6 +280,7 @@ struct intf_sys_t
- (id)getInfo;
- (id)getWizard;
- (id)getBookmarks;
- (id)getEmbeddedList;
- (void)terminate;
- (NSString *)localizedString:(char *)psz;
- (char *)delocalizeString:(NSString *)psz;
......
......@@ -304,6 +304,7 @@ static VLCMain *_o_sharedMainInstance = nil;
o_wizard = [[VLCWizard alloc] init];
o_extended = nil;
o_bookmarks = [[VLCBookmarks alloc] init];
o_embedded_list = [[VLCEmbeddedList alloc] init];
o_sfilters = nil;
/*o_update = [[VLCUpdate alloc] init];*/
......@@ -804,6 +805,15 @@ static VLCMain *_o_sharedMainInstance = nil;
return nil;
}
- (id)getEmbeddedList
{
if( o_embedded_list )
{
return o_embedded_list;
}
return nil;
}
- (void)manage
{
playlist_t * p_playlist;
......
......@@ -8,6 +8,7 @@
* Florian G. Pflug <fgp@phlo.org>
* Jon Lech Johansen <jon-vl@nanocrew.net>
* Eric Petit <titer@m0k.org>
* Benjamin Pracht <bigben at videolan dot org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -25,35 +26,99 @@
*****************************************************************************/
/*****************************************************************************
* VLCWindow interface
* VLCEmbeddedList interface
*****************************************************************************/
@interface VLCWindow : NSWindow
@interface VLCEmbeddedList : NSObject
{
NSMutableArray * o_embedded_array;
}
- (id)getEmbeddedVout;
- (void)releaseEmbeddedVout: (id)o_vout_view;
- (void)addEmbeddedVout: (id)o_vout_view;
- (BOOL)windowContainsEmbedded: (id)o_window;
- (id)getViewForWindow: (id)o_window;
@end
/*****************************************************************************
* VLCVoutView interface
*****************************************************************************/
@interface VLCVoutView : NSView
{
vout_thread_t * p_vout;
NSView * o_view;
NSRect * s_frame;
vout_thread_t * p_real_vout;
Ptr p_fullscreen_state;
mtime_t i_time_mouse_last_moved;
vlc_bool_t b_init_ok;
id o_window;
}
- (id) initWithVout: (vout_thread_t *) p_vout view: (NSView *) view
frame: (NSRect *) s_frame;
- (id) initReal: (id) sender;
- (void) close;
- (id) closeReal: (id) sender;
- (void)setOnTop:(BOOL)b_on_top;
- (void)hideMouse:(BOOL)b_hide;
- (BOOL)setVout: (vout_thread_t *) p_arg_vout subView: (NSView *) view
frame: (NSRect *) s_arg_frame;
- (void)closeVout;
- (void)manage;
- (void)scaleWindowWithFactor: (float)factor;
- (void)setOnTop:(BOOL)b_on_top;
- (void)toggleFloatOnTop;
- (void)toggleFullscreen;
- (BOOL)isFullscreen;
- (void)snapshot;
- (id)getWindow;
+ (id)getVoutView: (vout_thread_t *)p_vout subView: (NSView *) view
frame: (NSRect *) s_frame;
+ (vout_thread_t *)getRealVout: (vout_thread_t *)p_vout;
@end
/*****************************************************************************
* VLCVoutDetachedView interface
*****************************************************************************/
@interface VLCDetachedVoutView : VLCVoutView
{
mtime_t i_time_mouse_last_moved;
}
- (void)hideMouse: (BOOL)b_hide;
@end
/*****************************************************************************
* VLCEmbeddedView interface
*****************************************************************************/
@interface VLCEmbeddedVoutView : VLCVoutView
{
BOOL b_used;
}
- (void)setUsed: (BOOL)b_new_used;
- (BOOL)isUsed;
@end
/*****************************************************************************
* VLCWindow interface
*****************************************************************************/
@interface VLCWindow : NSWindow
{
vout_thread_t * p_vout;
VLCVoutView * o_view;
NSRect * s_frame;
vout_thread_t * p_real_vout;
Ptr p_fullscreen_state;
vlc_bool_t b_init_ok;
}
- (id) initWithVout: (vout_thread_t *) p_vout view: (VLCVoutView *) view
frame: (NSRect *) s_frame;
- (id)initReal: (id) sender;
- (void)close;
- (void)closeWindow;
- (id)closeReal: (id) sender;
- (id)getVoutView;
- (void)updateTitle;
- (BOOL)windowShouldClose:(id)sender;
......
......@@ -9,12 +9,13 @@
* Jon Lech Johansen <jon-vl@nanocrew.net>
* Derk-Jan Hartman <hartman at videolan dot org>
* Eric Petit <titer@m0k.org>
* Benjamin Pracht <bigben at videolan dot org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
......@@ -49,11 +50,11 @@ int DeviceCallback( vlc_object_t *p_this, const char *psz_variable,
{
vlc_value_t val;
vout_thread_t *p_vout = (vout_thread_t *)p_this;
msg_Dbg( p_vout, "set %d", new_val.i_int );
var_Create( p_vout->p_vlc, "video-device", VLC_VAR_INTEGER );
var_Set( p_vout->p_vlc, "video-device", new_val );
val.b_bool = VLC_TRUE;
var_Set( p_vout, "intf-change", val );
return VLC_SUCCESS;
......@@ -61,90 +62,110 @@ int DeviceCallback( vlc_object_t *p_this, const char *psz_variable,
/*****************************************************************************
* VLCWindow implementation
* VLCEmbeddedList implementation
*****************************************************************************/
@implementation VLCWindow
@implementation VLCEmbeddedList
- (id) initWithVout: (vout_thread_t *) vout view: (NSView *) view
frame: (NSRect *) frame
- (id)init
{
p_vout = vout;
o_view = view;
s_frame = frame;
[self performSelectorOnMainThread: @selector(initReal:)
withObject: NULL waitUntilDone: YES];
if( !b_init_ok )
{
return NULL;
}
[super init];
o_embedded_array = [NSMutableArray array];
return self;
}
- (id) initReal: (id) sender
- (id)getEmbeddedVout
{
NSAutoreleasePool *o_pool = [[NSAutoreleasePool alloc] init];
NSArray *o_screens = [NSScreen screens];
NSScreen *o_screen;
vlc_bool_t b_menubar_screen = VLC_FALSE;
int i_timeout, i_device;
vlc_value_t value_drawable;
b_init_ok = VLC_FALSE;
var_Get( p_vout->p_vlc, "drawable", &value_drawable );
unsigned int i;
/* We only wait for NSApp to initialise if we're not embedded (as in the
* case of the Mozilla plugin). We can tell whether we're embedded or not
* by examining the "drawable" value: if it's zero, we're running in the
* main Mac intf; if it's non-zero, we're embedded. */
if( value_drawable.i_int == 0 )
for( i = 0; i < [o_embedded_array count]; i++ )
{
/* Wait for a MacOS X interface to appear. Timeout is 2 seconds. */
for( i_timeout = 20 ; i_timeout-- ; )
id o_vout_view = [o_embedded_array objectAtIndex: i];
if( ![o_vout_view isUsed] )
{
if( NSApp == NULL )
{
msleep( INTF_IDLE_SLEEP );
}
[o_vout_view setUsed: YES];
return o_vout_view;
}
}
return nil;
}
if( NSApp == NULL )
{
/* No MacOS X intf, unable to communicate with MT */
msg_Err( p_vout, "no MacOS X interface present" );
return NULL;
}
- (void)releaseEmbeddedVout: (id)o_vout_view
{
if( [o_embedded_array containsObject: o_vout_view] )
{
[o_vout_view setUsed: NO];
}
if( [o_screens count] <= 0 )
else
{
msg_Err( p_vout, "no OSX screens available" );
return NULL;
msg_Warn( VLCIntf, "Cannot find Video Output");
}
}
/* p_real_vout: the vout we have to use to check for video-on-top
and a few other things. If we are the QuickTime output, it's us.
It we are the OpenGL provider, it is our parent. */
if( p_vout->i_object_type == VLC_OBJECT_OPENGL )
- (void)addEmbeddedVout: (id)o_vout_view
{
if( ![o_embedded_array containsObject: o_vout_view] )
{
p_real_vout = (vout_thread_t *) p_vout->p_parent;
[o_embedded_array addObject: o_vout_view];
}
else
}
- (BOOL)windowContainsEmbedded: (id)o_window
{
return ([self getViewForWindow: o_window] == nil ? NO : YES);
}
- (id)getViewForWindow: (id)o_window
{
id o_enumerator = [o_embedded_array objectEnumerator];
id o_current_embedded;
while( (o_current_embedded = [o_enumerator nextObject]) )
{
p_real_vout = p_vout;
if( [o_current_embedded getWindow] == o_window )
{
return o_current_embedded;
}
}
return nil;
}
p_fullscreen_state = NULL;
i_time_mouse_last_moved = mdate();
@end
var_Create( p_vout, "macosx-vdev", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
var_Create( p_vout, "macosx-fill", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
var_Create( p_vout, "macosx-stretch", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
var_Create( p_vout, "macosx-opaqueness", VLC_VAR_FLOAT | VLC_VAR_DOINHERIT );
var_Create( p_vout, "macosx-background", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
/*****************************************************************************
* VLCVoutView implementation
*****************************************************************************/
@implementation VLCVoutView
- (id)initWithFrame:(NSRect)frameRect
{
[super initWithFrame: frameRect];
p_vout = NULL;
o_view = nil;
s_frame = &frameRect;
p_real_vout = NULL;
o_window = nil;
return self;
}
- (BOOL)setVout: (vout_thread_t *) vout subView: (NSView *) view
frame: (NSRect *) frame
{
int i_device;
NSAutoreleasePool *o_pool = [[NSAutoreleasePool alloc] init];
NSArray *o_screens = [NSScreen screens];
p_vout = vout;
o_view = view;
s_frame = frame;
if( [o_screens count] <= 0 )
{
msg_Err( p_vout, "no OSX screens available" );
return NO;
}
p_real_vout = [VLCVoutView getRealVout: p_vout];
/* Get the pref value when this is the first time, otherwise retrieve the device from the top level video-device var */
if( var_Type( p_real_vout->p_vlc, "video-device" ) == 0 )
......@@ -203,172 +224,40 @@ int DeviceCallback( vlc_object_t *p_this, const char *psz_variable,
var_Set( p_real_vout, "intf-change", val2 );
}
/* Find out on which screen to open the window */
if( i_device <= 0 || i_device > (int)[o_screens count] )
{
/* No preference specified. Use the main screen */
o_screen = [NSScreen mainScreen];
if( o_screen == [o_screens objectAtIndex: 0] )
b_menubar_screen = VLC_TRUE;
}
else
{
i_device--;
o_screen = [o_screens objectAtIndex: i_device];
b_menubar_screen = ( i_device == 0 );
}
if( p_vout->b_fullscreen )
{
NSRect screen_rect = [o_screen frame];
screen_rect.origin.x = screen_rect.origin.y = 0;
/* Creates a window with size: screen_rect on o_screen */
[self initWithContentRect: screen_rect
styleMask: NSBorderlessWindowMask
backing: NSBackingStoreBuffered
defer: YES screen: o_screen];
if( b_menubar_screen )
{
BeginFullScreen( &p_fullscreen_state, NULL, 0, 0,
NULL, NULL, fullScreenAllowEvents );
}
}
else if( var_GetBool( p_real_vout, "macosx-background" ) )
{
NSRect screen_rect = [o_screen frame];
screen_rect.origin.x = screen_rect.origin.y = 0;
/* Creates a window with size: screen_rect on o_screen */
[self initWithContentRect: screen_rect
styleMask: NSBorderlessWindowMask
backing: NSBackingStoreBuffered
defer: YES screen: o_screen];
[self setLevel: CGWindowLevelForKey(kCGDesktopWindowLevelKey)];
}
else
{
unsigned int i_stylemask = NSTitledWindowMask |
NSMiniaturizableWindowMask |
NSClosableWindowMask |
NSResizableWindowMask;
NSRect s_rect;
if( !s_frame )
{
s_rect.size.width = p_vout->i_window_width;
s_rect.size.height = p_vout->i_window_height;
}
else
{
s_rect = *s_frame;
}
[self initWithContentRect: s_rect
styleMask: i_stylemask
backing: NSBackingStoreBuffered
defer: YES screen: o_screen];
[self setAlphaValue: var_GetFloat( p_vout, "macosx-opaqueness" )];
if( var_GetBool( p_real_vout, "video-on-top" ) )
{
[self setLevel: NSStatusWindowLevel];
}
if( !s_frame )
{
[self center];
}
}
[self updateTitle];
[self makeKeyAndOrderFront: nil];
[self setReleasedWhenClosed: YES];
/* We'll catch mouse events */
[self setAcceptsMouseMovedEvents: YES];
[self makeFirstResponder: self];
/* Add the view. It's automatically resized to fit the window */
[self setContentView: o_view];
[self addSubview: o_view];
[self setAutoresizesSubviews: YES];
[o_pool release];
b_init_ok = VLC_TRUE;
return self;
return YES;
}
- (void) close
- (void)resizeSubviewsWithOldSize:(NSSize)oldBoundsSize
{
/* XXX waitUntilDone = NO to avoid a possible deadlock when hitting
Command-Q */
[self setAcceptsMouseMovedEvents: NO];
[self setContentView: NULL];
[self performSelectorOnMainThread: @selector(closeReal:)
withObject: NULL waitUntilDone: NO];
[super resizeSubviewsWithOldSize: oldBoundsSize];
[o_view setFrameSize: [self frame].size];
}
- (id) closeReal: (id) sender
- (void)closeVout
{
[super close];
if( p_fullscreen_state )
{
EndFullScreen( p_fullscreen_state, 0 );
}
return NULL;
[o_view removeFromSuperview];
o_view = nil;
p_vout = NULL;
s_frame = nil;
o_window = nil;
p_real_vout = NULL;
}
- (void)setOnTop:(BOOL)b_on_top
{
if( b_on_top )
{
[self setLevel: NSStatusWindowLevel];
}
else
{