Commit 437d8150 authored by Pierre d'Herbemont's avatar Pierre d'Herbemont

modules/gui/minimal_macosx: Add a minimal_macosx interface and vout that is used by the framework.

parent 2994ae9e
# Automake forgets to add a proper tag to libtool with Objective-C files.
# Moreocer Libtool should default tag to CC when none is specified but
# obviously does not. Here is a fix for that.
LIBTOOL=@LIBTOOL@ --tag=CC
SOURCES_minimal_macosx = \
intf.m \
macosx.c \
VLCMinimalVoutWindow.m \
VLCOpenGLVoutView.m \
voutgl.m \
voutagl.m \
$(NULL)
/*****************************************************************************
* VLCMinimalVoutWindow.h: MacOS X Minimal window for a vout
*****************************************************************************
* Copyright (C) 2001-2004 the VideoLAN team
* $Id$
*
* Authors: Pierre d'Herbemont <pdherbemont # videolan.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
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#import <Cocoa/Cocoa.h>
#include <vlc/vlc.h>
@interface VLCMinimalVoutWindow : NSWindow
{
NSRect rect;
}
- (id)initWithContentRect:(NSRect)contentRect;
/* @protocol VLCOpenGLVoutEmbedding */
- (void)addVoutSubview:(NSView *)view;
- (void)removeVoutSubview:(NSView *)view;
- (void)enterFullscreen;
- (void)leaveFullscreen;
- (BOOL)stretchesVideo;
- (void)setOnTop: (BOOL)ontop;
@end
/*****************************************************************************
* VLCMinimalVoutWindow.m: MacOS X Minimal interface window
*****************************************************************************
* Copyright (C) 2001-2004 the VideoLAN team
* $Id$
*
* Authors: Pierre d'Herbemont <pdherbemont # videolan.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
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#include "intf.h"
#include "voutgl.h"
#include "VLCOpenGLVoutView.h"
#include "VLCMinimalVoutWindow.h"
/* SetSystemUIMode, ... */
#import <QuickTime/QuickTime.h>
#import <Cocoa/Cocoa.h>
@implementation VLCMinimalVoutWindow
- (id)initWithContentRect:(NSRect)contentRect
{
if( self = [super initWithContentRect:contentRect styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO])
{
rect = contentRect;
[self setBackgroundColor:[NSColor blackColor]];
[self setMovableByWindowBackground: YES];
}
return self;
}
- (void)addVoutSubview:(NSView *)view
{
[[self contentView] addSubview:view];
[view setFrame:[[self contentView] bounds]];
}
- (void)removeVoutSubview:(NSView *)view
{
[self close];
[self release];
}
- (void)enterFullscreen
{
SetSystemUIMode( kUIModeAllHidden, kUIOptionAutoShowMenuBar);
[self setFrame:[[self screen] frame] display: YES];
}
- (void)leaveFullscreen
{
SetSystemUIMode( kUIModeNormal, kUIOptionAutoShowMenuBar);
[self setFrame:rect display: YES];
}
- (BOOL)stretchesVideo
{
return NO;
}
- (void)setOnTop: (BOOL)ontop
{
}
@end
/*****************************************************************************
* VLCOpenGLVoutView.h: MacOS X OpenGL provider
*****************************************************************************
* Copyright (C) 2001-2004 the VideoLAN team
* $Id$
*
* Authors: Colin Delacroix <colin@zoy.org>
* Florian G. Pflug <fgp@phlo.org>
* 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>
* Damien Fouilleul <damienf 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
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#import <Cocoa/Cocoa.h>
#include <OpenGL/OpenGL.h>
#include <OpenGL/gl.h>
#include <vlc/vlc.h>
/* Entry point */
int cocoaglvoutviewInit( vout_thread_t * p_vout );
void cocoaglvoutviewEnd( vout_thread_t * p_vout );
int cocoaglvoutviewManage( vout_thread_t * p_vout );
int cocoaglvoutviewControl( vout_thread_t *p_vout, int i_query, va_list args );
void cocoaglvoutviewSwap( vout_thread_t * p_vout );
int cocoaglvoutviewLock( vout_thread_t * p_vout );
void cocoaglvoutviewUnlock( vout_thread_t * p_vout );
/* To commmunicate with the VLC.framework */
@protocol VLCOpenGLVoutEmbedding
- (void)addVoutSubview:(NSView *)view;
- (void)removeVoutSubview:(NSView *)view;
- (void)enterFullscreen;
- (void)leaveFullscreen;
- (BOOL)stretchesVideo;
- (void)setOnTop: (BOOL)ontop; /* Do we really want that in protocol? */
@end
/* VLCOpenGLVoutView */
@interface VLCOpenGLVoutView : NSOpenGLView
{
id <VLCOpenGLVoutEmbedding> container;
vout_thread_t * p_vout;
NSLock * objectLock;
}
/* Init a new gl view and register it to both the framework and the
* vout_thread_t. Must be called from main thread */
+ (void) autoinitOpenGLVoutViewIntVoutWithContainer: (NSData *) args;
- (id) initWithVout: (vout_thread_t *) vout container: (id <VLCOpenGLVoutEmbedding>) container;
- (void) detachFromVout;
- (id <VLCOpenGLVoutEmbedding>) container;
- (void) reshape;
- (void) update;
- (void) drawRect: (NSRect) rect;
@end
/*****************************************************************************
* VLCOpenGLVoutView.m: MacOS X OpenGL provider
*****************************************************************************
* Copyright (C) 2001-2004 the VideoLAN team
* $Id$
*
* Authors: Colin Delacroix <colin@zoy.org>
* Florian G. Pflug <fgp@phlo.org>
* 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>
* Damien Fouilleul <damienf at videolan dot org>
* Pierr d'Herbemont <pdherbemont 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
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#include "intf.h"
#include "voutgl.h"
#include "VLCOpenGLVoutView.h"
#include "VLCMinimalVoutWindow.h"
#include <OpenGL/OpenGL.h>
#include <OpenGL/gl.h>
/*****************************************************************************
* cocoaglvoutviewInit
*****************************************************************************/
int cocoaglvoutviewInit( vout_thread_t * p_vout )
{
vlc_value_t value_drawable;
id <VLCOpenGLVoutEmbedding> o_cocoaglview_container;
msg_Dbg( p_vout, "Mac OS X Vout is opening" );
var_Create( p_vout, "drawable", VLC_VAR_DOINHERIT );
var_Get( p_vout, "drawable", &value_drawable );
o_cocoaglview_container = (id) value_drawable.i_int;
if (!o_cocoaglview_container)
{
msg_Warn( p_vout, "No drawable!, spawing a window" );
o_cocoaglview_container = [[VLCMinimalVoutWindow alloc] initWithContentRect: NSMakeRect( 0, 0, 200, 200 )];
}
p_vout->p_sys->b_embedded = VLC_FALSE;
p_vout->p_sys->o_pool = [[NSAutoreleasePool alloc] init];
/* Create the GL view */
struct args { vout_thread_t * p_vout; id <VLCOpenGLVoutEmbedding> container; } args = { p_vout, o_cocoaglview_container };
[VLCOpenGLVoutView performSelectorOnMainThread:@selector(autoinitOpenGLVoutViewIntVoutWithContainer:)
withObject:[NSData dataWithBytes: &args length: sizeof(struct args)] waitUntilDone:YES];
[[p_vout->p_sys->o_glview openGLContext] makeCurrentContext];
return VLC_SUCCESS;
}
/*****************************************************************************
* cocoaglvoutviewEnd
*****************************************************************************/
void cocoaglvoutviewEnd( vout_thread_t * p_vout )
{
id <VLCOpenGLVoutEmbedding> o_cocoaglview_container;
msg_Dbg( p_vout, "Mac OS X Vout is closing" );
var_Destroy( p_vout, "drawable" );
o_cocoaglview_container = [p_vout->p_sys->o_glview container];
/* Make sure our view won't request the vout now */
[p_vout->p_sys->o_glview detachFromVout];
msg_Dbg( p_vout, "Mac OS X Vout is closing" );
/* Let the view go, _without_blocking_ */
[p_vout->p_sys->o_glview performSelectorOnMainThread:@selector(removeFromSuperview) withObject:NULL waitUntilDone:NO];
if( [(id)o_cocoaglview_container respondsToSelector:@selector(removeVoutSubview:)] )
[o_cocoaglview_container removeVoutSubview: p_vout->p_sys->o_glview];
[p_vout->p_sys->o_pool release];
}
/*****************************************************************************
* cocoaglvoutviewManage
*****************************************************************************/
int cocoaglvoutviewManage( vout_thread_t * p_vout )
{
if( p_vout->i_changes & VOUT_ASPECT_CHANGE )
{
[p_vout->p_sys->o_glview reshape];
p_vout->i_changes &= ~VOUT_ASPECT_CHANGE;
}
if( p_vout->i_changes & VOUT_CROP_CHANGE )
{
[p_vout->p_sys->o_glview reshape];
p_vout->i_changes &= ~VOUT_CROP_CHANGE;
}
if( p_vout->i_changes & VOUT_FULLSCREEN_CHANGE )
{
NSAutoreleasePool *o_pool = [[NSAutoreleasePool alloc] init];
p_vout->b_fullscreen = !p_vout->b_fullscreen;
if( p_vout->b_fullscreen )
[[p_vout->p_sys->o_glview container] enterFullscreen];
else
[[p_vout->p_sys->o_glview container] leaveFullscreen];
[o_pool release];
p_vout->i_changes &= ~VOUT_FULLSCREEN_CHANGE;
}
//[[p_vout->p_sys->o_glview container] manage];
return VLC_SUCCESS;
}
/*****************************************************************************
* cocoaglvoutviewControl: control facility for the vout
*****************************************************************************/
int cocoaglvoutviewControl( vout_thread_t *p_vout, int i_query, va_list args )
{
vlc_bool_t b_arg;
switch( i_query )
{
case VOUT_SET_STAY_ON_TOP:
b_arg = va_arg( args, vlc_bool_t );
[[p_vout->p_sys->o_glview container] setOnTop: b_arg];
return VLC_SUCCESS;
case VOUT_CLOSE:
case VOUT_REPARENT:
default:
return vout_vaControlDefault( p_vout, i_query, args );
}
}
/*****************************************************************************
* cocoaglvoutviewSwap
*****************************************************************************/
void cocoaglvoutviewSwap( vout_thread_t * p_vout )
{
p_vout->p_sys->b_got_frame = VLC_TRUE;
[[p_vout->p_sys->o_glview openGLContext] flushBuffer];
}
/*****************************************************************************
* cocoaglvoutviewLock
*****************************************************************************/
int cocoaglvoutviewLock( vout_thread_t * p_vout )
{
if( kCGLNoError == CGLLockContext([[p_vout->p_sys->o_glview openGLContext] CGLContextObj]) )
{
[[p_vout->p_sys->o_glview openGLContext] makeCurrentContext];
return 0;
}
return 1;
}
/*****************************************************************************
* cocoaglvoutviewUnlock
*****************************************************************************/
void cocoaglvoutviewUnlock( vout_thread_t * p_vout )
{
CGLUnlockContext([[p_vout->p_sys->o_glview openGLContext] CGLContextObj]);
}
/*****************************************************************************
* VLCOpenGLVoutView implementation
*****************************************************************************/
@implementation VLCOpenGLVoutView
/* Init a new gl view and register it to both the framework and the
* vout_thread_t. Must be called from main thread. */
+ (void) autoinitOpenGLVoutViewIntVoutWithContainer: (NSData *) argsAsData
{
struct args { vout_thread_t * p_vout; id <VLCOpenGLVoutEmbedding> container; } *
args = (struct args *)[argsAsData bytes];
VLCOpenGLVoutView * oglview;
oglview = [[VLCOpenGLVoutView alloc] initWithVout: args->p_vout container: args->container];
args->p_vout->p_sys->o_glview = [oglview autorelease];
[args->container addVoutSubview: oglview];
}
- (void)dealloc
{
[objectLock dealloc];
[super dealloc];
}
- (void)removeFromSuperview
{
[super removeFromSuperview];
}
- (id) initWithVout: (vout_thread_t *) vout container: (id <VLCOpenGLVoutEmbedding>) aContainer
{
NSOpenGLPixelFormatAttribute attribs[] =
{
NSOpenGLPFADoubleBuffer,
NSOpenGLPFAAccelerated,
NSOpenGLPFANoRecovery,
NSOpenGLPFAColorSize, 24,
NSOpenGLPFAAlphaSize, 8,
NSOpenGLPFADepthSize, 24,
NSOpenGLPFAWindow,
0
};
NSOpenGLPixelFormat * fmt = [[NSOpenGLPixelFormat alloc]
initWithAttributes: attribs];
if( !fmt )
{
msg_Warn( p_vout, "could not create OpenGL video output" );
return nil;
}
if( self = [super initWithFrame: NSMakeRect(0,0,10,10) pixelFormat: fmt] )
{
p_vout = vout;
container = aContainer;
objectLock = [[NSLock alloc] init];
[fmt release];
[[self openGLContext] makeCurrentContext];
[[self openGLContext] update];
/* Swap buffers only during the vertical retrace of the monitor.
http://developer.apple.com/documentation/GraphicsImaging/
Conceptual/OpenGL/chap5/chapter_5_section_44.html */
long params[] = { 1 };
CGLSetParameter( CGLGetCurrentContext(), kCGLCPSwapInterval,
params );
}
return self;
}
- (void) detachFromVout
{
[objectLock lock];
p_vout = NULL;
[objectLock unlock];
}
- (id <VLCOpenGLVoutEmbedding>) container
{
return container;
}
- (void) destroyVout
{
[objectLock lock];
if( p_vout )
{
vlc_object_detach( p_vout );
vlc_object_release( p_vout );
vout_Destroy( (vout_thread_t *)p_vout );
}
[objectLock unlock];
}
- (void) reshape
{
int x, y;
vlc_value_t val;
[objectLock lock];
if( !p_vout )
{
[objectLock unlock];
return;
}
cocoaglvoutviewLock( p_vout );
NSRect bounds = [self bounds];
if( [[self container] stretchesVideo] )
{
x = bounds.size.width;
y = bounds.size.height;
}
else if( bounds.size.height * p_vout->fmt_in.i_visible_width *
p_vout->fmt_in.i_sar_num <
bounds.size.width * p_vout->fmt_in.i_visible_height *
p_vout->fmt_in.i_sar_den )
{
x = ( bounds.size.height * p_vout->fmt_in.i_visible_width *
p_vout->fmt_in.i_sar_num ) /
( p_vout->fmt_in.i_visible_height * p_vout->fmt_in.i_sar_den);
y = bounds.size.height;
}
else
{
x = bounds.size.width;
y = ( bounds.size.width * p_vout->fmt_in.i_visible_height *
p_vout->fmt_in.i_sar_den) /
( p_vout->fmt_in.i_visible_width * p_vout->fmt_in.i_sar_num );
}
glViewport( ( bounds.size.width - x ) / 2,
( bounds.size.height - y ) / 2, x, y );
if( p_vout->p_sys->b_got_frame )
{
/* Ask the opengl module to redraw */
vout_thread_t * p_parent;
p_parent = (vout_thread_t *) p_vout->p_parent;
cocoaglvoutviewUnlock( p_vout );
if( p_parent && p_parent->pf_display )
{
p_parent->pf_display( p_parent, NULL );
}
}
else
{
glClear( GL_COLOR_BUFFER_BIT );
cocoaglvoutviewUnlock( p_vout );
}
[objectLock unlock];
[super reshape];
}
- (void) update
{
if( kCGLNoError != CGLLockContext([[self openGLContext] CGLContextObj]) )
return;
[super update];
CGLUnlockContext([[p_vout->p_sys->o_glview openGLContext] CGLContextObj]);
}
- (void) drawRect: (NSRect) rect
{
if( kCGLNoError != CGLLockContext([[self openGLContext] CGLContextObj]) )
return;
[[self openGLContext] flushBuffer];
[super drawRect:rect];
CGLUnlockContext([[p_vout->p_sys->o_glview openGLContext] CGLContextObj]);
}
@end
/*****************************************************************************
* intf.h: MacOS X interface module
*****************************************************************************
* Copyright (C) 2002-2006 the VideoLAN team
* $Id$
*
* Authors: Jon Lech Johansen <jon-vl@nanocrew.net>
* Christophe Massiot <massiot@via.ecp.fr>
* Derk-Jan Hartman <hartman at videolan dot org>
* Felix KŸhne <fkuehne 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
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#include <vlc/vlc.h>
#include <vlc_interface.h>
#include <vlc_playlist.h>
#include <vlc_vout.h>
#include <vlc_aout.h>
#include <vlc_input.h>
#include <Cocoa/Cocoa.h>
/*****************************************************************************
* Local prototypes.
*****************************************************************************/
/* switch this to 1, if you want to use Obj-C with GC */
#define GC_ENABLED 0
/*****************************************************************************
* intf_sys_t: description and status of the interface
*****************************************************************************/
struct intf_sys_t
{
NSAutoreleasePool * o_pool;
};
/*****************************************************************************
* intf.m: MacOS X interface module
*****************************************************************************
* Copyright (C) 2002-2007 the VideoLAN team
* $Id$
*
* Authors: Jon Lech Johansen <jon-vl@nanocrew.net>
* Christophe Massiot <massiot@via.ecp.fr>
* Derk-Jan Hartman <hartman at videolan.org>
* Felix Khne <fkuehne 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
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#include <stdlib.h> /* malloc(), free() */
#include <sys/param.h> /* for MAXPATHLEN */
#include <string.h>
#include <vlc/vlc.h>
#include <vlc_keys.h>
#include <vlc_input.h>
#import <intf.h>
/*****************************************************************************
* Local prototypes.
*****************************************************************************/
static void Run ( intf_thread_t *p_intf );
/*****************************************************************************
* OpenIntf: initialize interface
*****************************************************************************/
int E_(OpenIntf) ( vlc_object_t *p_this )
{
intf_thread_t *p_intf = (intf_thread_t*) p_this;
p_intf->p_sys = malloc( sizeof( intf_sys_t ) );
if( p_intf->p_sys == NULL )
{
return( 1 );
}
memset( p_intf->p_sys, 0, sizeof( *p_intf->p_sys ) );
p_intf->p_sys->o_pool = [[NSAutoreleasePool alloc] init];
p_intf->b_play = VLC_TRUE;
p_intf->pf_run = Run;
return( 0 );
}
/*****************************************************************************
* CloseIntf: destroy interface
*****************************************************************************/
void E_(CloseIntf) ( vlc_object_t *p_this )
{
intf_thread_t *p_intf = (intf_thread_t*) p_this;
free( p_intf->p_sys );
}
/*****************************************************************************
* Run: main loop
*****************************************************************************/