/*****************************************************************************
- * vout.m: MacOS X video output module
+ * voutgl.m: MacOS X OpenGL provider
*****************************************************************************
- * Copyright (C) 2001-2003 VideoLAN
+ * Copyright (C) 2001-2004 the VideoLAN team
* $Id: vout.m 8351 2004-08-02 13:06:38Z hartman $
*
* Authors: Colin Delacroix <colin@zoy.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>
*
* 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
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
/*****************************************************************************
#include <OpenGL/OpenGL.h>
#include <OpenGL/gl.h>
+#include <AGL/agl.h>
+
/*****************************************************************************
* VLCView interface
*****************************************************************************/
vout_thread_t * p_vout;
}
-- (id)initWithFrame: (NSRect) frame vout: (vout_thread_t*) p_vout;
-
+- (id) initWithVout: (vout_thread_t *) p_vout;
@end
-
struct vout_sys_t
{
- NSAutoreleasePool *o_pool;
- VLCWindow * o_window;
- VLCGLView * o_glview;
- vlc_bool_t b_saved_frame;
- NSRect s_frame;
+ NSAutoreleasePool * o_pool;
+ VLCGLView * o_glview;
+ VLCVoutView * o_vout_view;
+ vlc_bool_t b_saved_frame;
+ NSRect s_frame;
+ vlc_bool_t b_got_frame;
+ vlc_mutex_t lock;
+ /* Mozilla plugin-related variables */
+ vlc_bool_t b_embedded;
+ AGLContext agl_ctx;
+ AGLDrawable agl_drawable;
+ int i_offx, i_offy;
+ int i_width, i_height;
};
/*****************************************************************************
static int Manage ( vout_thread_t * p_vout );
static int Control( vout_thread_t *, int, va_list );
static void Swap ( vout_thread_t * p_vout );
+static int Lock ( vout_thread_t * p_vout );
+static void Unlock ( vout_thread_t * p_vout );
+
+static int aglInit ( vout_thread_t * p_vout );
+static void aglEnd ( vout_thread_t * p_vout );
+static int aglManage ( vout_thread_t * p_vout );
+static void aglSwap ( vout_thread_t * p_vout );
+
+static int DrawableRedraw( vlc_object_t *p_this, const char *psz_name,
+ vlc_value_t oval, vlc_value_t nval, void *param);
int E_(OpenVideoGL) ( vlc_object_t * p_this )
{
vout_thread_t * p_vout = (vout_thread_t *) p_this;
- int i_timeout;
- vlc_value_t val;
-
+ vlc_value_t value_drawable;
-/* OpenGL interface disabled until
- * - the video on top var is properly working
- * - the escape key is working in fullscreen
- * - the green line is gone
- * - other problems?????
- */
-return( 1 );
if( !CGDisplayUsesOpenGLAcceleration( kCGDirectMainDisplay ) )
{
- msg_Warn( p_vout, "no hardware acceleration" );
+ msg_Warn( p_vout, "no OpenGL hardware acceleration found. "
+ "Video display will be slow" );
return( 1 );
}
msg_Dbg( p_vout, "display is Quartz Extreme accelerated" );
memset( p_vout->p_sys, 0, sizeof( vout_sys_t ) );
- /* Wait for a MacOS X interface to appear. Timeout is 2 seconds. */
- for( i_timeout = 20 ; i_timeout-- ; )
+ vlc_mutex_init( p_vout, &p_vout->p_sys->lock );
+
+ var_Get( p_vout->p_vlc, "drawable", &value_drawable );
+ if( value_drawable.i_int != 0 )
{
- if( NSApp == NULL )
+ static const GLint ATTRIBUTES[] = {
+ AGL_WINDOW,
+ AGL_RGBA,
+ AGL_NO_RECOVERY,
+ AGL_ACCELERATED,
+ AGL_DOUBLEBUFFER,
+ AGL_RED_SIZE, 8,
+ AGL_GREEN_SIZE, 8,
+ AGL_BLUE_SIZE, 8,
+ AGL_ALPHA_SIZE, 8,
+ AGL_DEPTH_SIZE, 24,
+ AGL_NONE };
+
+ AGLDevice screen;
+ AGLPixelFormat pixFormat;
+
+ p_vout->p_sys->b_embedded = VLC_TRUE;
+
+ screen = GetGWorldDevice((CGrafPtr)value_drawable.i_int);
+ if( NULL == screen )
{
- msleep( INTF_IDLE_SLEEP );
+ msg_Err( p_vout, "can't find screen device for drawable" );
+ return VLC_EGENERIC;
+ }
+
+ pixFormat = aglChoosePixelFormat(&screen, 1, ATTRIBUTES);
+ if( NULL == pixFormat )
+ {
+ msg_Err( p_vout, "no screen renderer available for required attributes." );
+ return VLC_EGENERIC;
+ }
+
+ p_vout->p_sys->agl_ctx = aglCreateContext(pixFormat, NULL);
+ aglDestroyPixelFormat(pixFormat);
+ if( NULL == p_vout->p_sys->agl_ctx )
+ {
+ msg_Err( p_vout, "cannot create AGL context." );
+ return VLC_EGENERIC;
+ }
+ else {
+ // tell opengl to sync buffer swap with vertical retrace
+ GLint param = 1;
+ aglSetInteger(p_vout->p_sys->agl_ctx, AGL_SWAP_INTERVAL, ¶m);
+ aglEnable(p_vout->p_sys->agl_ctx, AGL_SWAP_INTERVAL);
}
- }
- if( NSApp == NULL )
- {
- /* No MacOS X intf, unable to communicate with MT */
- msg_Err( p_vout, "no MacOS X interface present" );
- return VLC_EGENERIC;
+ p_vout->pf_init = aglInit;
+ p_vout->pf_end = aglEnd;
+ p_vout->pf_manage = aglManage;
+ p_vout->pf_control = NULL;
+ p_vout->pf_swap = aglSwap;
+ p_vout->pf_lock = Lock;
+ p_vout->pf_unlock = Unlock;
}
-
- p_vout->pf_init = Init;
- p_vout->pf_end = End;
- p_vout->pf_manage = Manage;
- p_vout->pf_control= Control;
- p_vout->pf_swap = Swap;
-
-
- p_vout->p_sys->o_pool = [[NSAutoreleasePool alloc] init];
-
- 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 );
-
- /* Setup the menuitem for the multiple displays. Read the vlc preference (macosx-vdev) for the primary display */
- NSArray * o_screens = [NSScreen screens];
- if( [o_screens count] > 0 && var_Type( p_vout, "video-device" ) == 0 )
+ else
{
- int i = 1;
- vlc_value_t val2, text;
- NSScreen * o_screen;
+ p_vout->p_sys->b_embedded = VLC_FALSE;
- var_Get( p_vout, "macosx-vdev", &val );
+ p_vout->p_sys->o_pool = [[NSAutoreleasePool alloc] init];
- var_Create( p_vout, "video-device", VLC_VAR_INTEGER |
- VLC_VAR_HASCHOICE );
- text.psz_string = _("Video device");
- var_Change( p_vout, "video-device", VLC_VAR_SETTEXT, &text, NULL );
-
- NSEnumerator * o_enumerator = [o_screens objectEnumerator];
+ /* Create the GL view */
+ p_vout->p_sys->o_glview = [[VLCGLView alloc] initWithVout: p_vout];
+ [p_vout->p_sys->o_glview autorelease];
+
+ /* Spawn the window */
- while( (o_screen = [o_enumerator nextObject]) != NULL )
+ if( !(p_vout->p_sys->o_vout_view = [VLCVoutView getVoutView: p_vout
+ subView: p_vout->p_sys->o_glview frame: nil]) )
{
- char psz_temp[255];
- NSRect s_rect = [o_screen frame];
-
- snprintf( psz_temp, sizeof(psz_temp)/sizeof(psz_temp[0])-1,
- "%s %d (%dx%d)", _("Screen"), i,
- (int)s_rect.size.width, (int)s_rect.size.height );
-
- text.psz_string = psz_temp;
- val2.i_int = i;
- var_Change( p_vout, "video-device",
- VLC_VAR_ADDCHOICE, &val2, &text );
-
- if( ( i - 1 ) == val.i_int )
- {
- var_Set( p_vout, "video-device", val2 );
- }
- i++;
+ return VLC_EGENERIC;
}
-
- var_AddCallback( p_vout, "video-device", vout_VarCallback,
- NULL );
-
- val2.b_bool = VLC_TRUE;
- var_Set( p_vout, "intf-change", val2 );
+ p_vout->pf_init = Init;
+ p_vout->pf_end = End;
+ p_vout->pf_manage = Manage;
+ p_vout->pf_control= Control;
+ p_vout->pf_swap = Swap;
+ p_vout->pf_lock = Lock;
+ p_vout->pf_unlock = Unlock;
}
-
- /* Spawn window */
- p_vout->p_sys->o_window = [[VLCWindow alloc] initWithVout: p_vout
- frame: nil];
-
- /* Add OpenGL view */
-#define o_glview p_vout->p_sys->o_glview
- o_glview = [[VLCGLView alloc] initWithFrame:
- [p_vout->p_sys->o_window frame] vout: p_vout];
- [p_vout->p_sys->o_window setContentView: o_glview];
- [o_glview autorelease];
-#undef o_glview
+ p_vout->p_sys->b_got_frame = VLC_FALSE;
return VLC_SUCCESS;
}
-int E_(CloseVideoGL) ( vlc_object_t * p_this )
+void E_(CloseVideoGL) ( vlc_object_t * p_this )
{
vout_thread_t * p_vout = (vout_thread_t *) p_this;
- NSAutoreleasePool *o_pool = [[NSAutoreleasePool alloc] init];
+ if( p_vout->p_sys->b_embedded )
+ {
+ var_DelCallback(p_vout->p_vlc, "drawableredraw", DrawableRedraw, p_vout);
+ aglDestroyContext(p_vout->p_sys->agl_ctx);
+ }
+ else
+ {
+ NSAutoreleasePool *o_pool = [[NSAutoreleasePool alloc] init];
- [p_vout->p_sys->o_window close];
+ /* Close the window */
+ [p_vout->p_sys->o_vout_view closeVout];
- [o_pool release];
- return VLC_SUCCESS;
+ [o_pool release];
+ }
+ /* Clean up */
+ vlc_mutex_destroy( &p_vout->p_sys->lock );
+ free( p_vout->p_sys );
}
static int Init( vout_thread_t * p_vout )
static int Manage( 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];
-
+
if( !p_vout->b_fullscreen )
{
/* Save window size and position */
p_vout->p_sys->s_frame.size =
- [[p_vout->p_sys->o_window contentView] frame].size;
+ [p_vout->p_sys->o_vout_view frame].size;
p_vout->p_sys->s_frame.origin =
- [p_vout->p_sys->o_window frame].origin;
+ [[p_vout->p_sys->o_vout_view getWindow ]frame].origin;
p_vout->p_sys->b_saved_frame = VLC_TRUE;
}
- [p_vout->p_sys->o_window close];
+ [p_vout->p_sys->o_vout_view closeVout];
p_vout->b_fullscreen = !p_vout->b_fullscreen;
+#define o_glview p_vout->p_sys->o_glview
+ o_glview = [[VLCGLView alloc] initWithVout: p_vout];
+ [o_glview autorelease];
+
if( p_vout->p_sys->b_saved_frame )
{
- p_vout->p_sys->o_window = [[VLCWindow alloc]
- initWithVout: p_vout frame: &p_vout->p_sys->s_frame];
+ p_vout->p_sys->o_vout_view = [VLCVoutView getVoutView: p_vout
+ subView: o_glview
+ frame: &p_vout->p_sys->s_frame];
}
else
{
- p_vout->p_sys->o_window = [[VLCWindow alloc]
- initWithVout: p_vout frame: nil];
+ p_vout->p_sys->o_vout_view = [VLCVoutView getVoutView: p_vout
+ subView: o_glview frame: nil];
+
}
-#define o_glview p_vout->p_sys->o_glview
- o_glview = [[VLCGLView alloc] initWithFrame: [p_vout->p_sys->o_window frame] vout: p_vout];
- [p_vout->p_sys->o_window setContentView: o_glview];
- [o_glview autorelease];
[[o_glview openGLContext] makeCurrentContext];
#undef o_glview
+
[o_pool release];
p_vout->i_changes &= ~VOUT_FULLSCREEN_CHANGE;
}
- [p_vout->p_sys->o_window manage];
+
+ [p_vout->p_sys->o_vout_view manage];
return VLC_SUCCESS;
}
{
case VOUT_SET_STAY_ON_TOP:
b_arg = va_arg( args, vlc_bool_t );
- [p_vout->p_sys->o_window setOnTop: b_arg];
+ [p_vout->p_sys->o_vout_view setOnTop: b_arg];
return VLC_SUCCESS;
case VOUT_CLOSE:
static void Swap( vout_thread_t * p_vout )
{
+ p_vout->p_sys->b_got_frame = VLC_TRUE;
[[p_vout->p_sys->o_glview openGLContext] makeCurrentContext];
- if( [p_vout->p_sys->o_glview lockFocusIfCanDraw] )
- {
- glFlush();
- [p_vout->p_sys->o_glview unlockFocus];
- }
+ glFlush();
+}
+
+static int Lock( vout_thread_t * p_vout )
+{
+ vlc_mutex_lock( &p_vout->p_sys->lock );
+ return 0;
+}
+
+static void Unlock( vout_thread_t * p_vout )
+{
+ vlc_mutex_unlock( &p_vout->p_sys->lock );
}
/*****************************************************************************
*****************************************************************************/
@implementation VLCGLView
-- (id) initWithFrame: (NSRect) frame vout: (vout_thread_t*) _p_vout
+- (id) initWithVout: (vout_thread_t *) vout
{
- p_vout = _p_vout;
-
+ p_vout = vout;
+
NSOpenGLPixelFormatAttribute attribs[] =
{
NSOpenGLPFAAccelerated,
if( !fmt )
{
- msg_Warn( p_vout, "Cannot create NSOpenGLPixelFormat" );
+ msg_Warn( p_vout, "could not create OpenGL video output" );
return nil;
}
- self = [super initWithFrame:frame pixelFormat: fmt];
+ self = [super initWithFrame: NSMakeRect(0,0,10,10) pixelFormat: fmt];
[fmt release];
[[self openGLContext] makeCurrentContext];
return self;
}
-- (void)reshape
+- (void) reshape
{
int x, y;
+ vlc_value_t val;
+
+ Lock( p_vout );
NSRect bounds = [self bounds];
+
[[self openGLContext] makeCurrentContext];
- if( bounds.size.height * p_vout->render.i_aspect <
- bounds.size.width * VOUT_ASPECT_FACTOR )
+
+ var_Get( p_vout, "macosx-stretch", &val );
+ if( val.b_bool )
{
- x = bounds.size.height * p_vout->render.i_aspect / VOUT_ASPECT_FACTOR;
+ 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 * VOUT_ASPECT_FACTOR / p_vout->render.i_aspect;
+ 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 );
- glClear( GL_COLOR_BUFFER_BIT );
+
+ 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;
+ Unlock( p_vout );
+ if( p_parent && p_parent->pf_display )
+ {
+ p_parent->pf_display( p_parent, NULL );
+ }
+ }
+ else
+ {
+ glClear( GL_COLOR_BUFFER_BIT );
+ Unlock( p_vout );
+ }
+ [super reshape];
+}
+
+- (void) update
+{
+ Lock( p_vout );
+ [super update];
+ Unlock( p_vout );
}
- (void) drawRect: (NSRect) rect
{
+ Lock( p_vout );
[[self openGLContext] makeCurrentContext];
glFlush();
+ [super drawRect:rect];
+ Unlock( p_vout );
}
@end
+/*****************************************************************************
+ * embedded AGL context implementation
+ *****************************************************************************/
+
+static void UpdateEmbeddedGeometry( vout_thread_t *p_vout );
+static void aglReshape( vout_thread_t * p_vout );
+
+static int aglInit( vout_thread_t * p_vout )
+{
+ UpdateEmbeddedGeometry(p_vout);
+ var_AddCallback(p_vout->p_vlc, "drawableredraw", DrawableRedraw, p_vout);
+
+ aglSetCurrentContext(p_vout->p_sys->agl_ctx);
+ return VLC_SUCCESS;
+}
+
+static void aglEnd( vout_thread_t * p_vout )
+{
+ aglSetCurrentContext(NULL);
+}
+
+static void aglReshape( vout_thread_t * p_vout )
+{
+ int x, y;
+ vlc_value_t val;
+ int i_offx = p_vout->p_sys->i_offx;
+ int i_offy = p_vout->p_sys->i_offy;
+ int i_height = p_vout->p_sys->i_height;
+ int i_width = p_vout->p_sys->i_width;
+
+ Lock( p_vout );
+
+ aglSetCurrentContext(p_vout->p_sys->agl_ctx);
+
+ var_Get( p_vout, "macosx-stretch", &val );
+ if( val.b_bool )
+ {
+ x = i_width;
+ y = i_height;
+ }
+ else if( i_height * p_vout->fmt_in.i_visible_width *
+ p_vout->fmt_in.i_sar_num <
+ i_width * p_vout->fmt_in.i_visible_height *
+ p_vout->fmt_in.i_sar_den )
+ {
+ x = ( i_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 = i_height;
+ }
+ else
+ {
+ x = i_width;
+ y = ( i_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( i_offx+( i_width - x ) / 2,
+ i_offy+( i_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;
+ Unlock( p_vout );
+ if( p_parent && p_parent->pf_display )
+ {
+ p_parent->pf_display( p_parent, NULL );
+ }
+ }
+ else
+ {
+ glClear( GL_COLOR_BUFFER_BIT );
+ Unlock( p_vout );
+ }
+}
+
+static int aglManage( vout_thread_t * p_vout )
+{
+ if( p_vout->i_changes & VOUT_ASPECT_CHANGE )
+ {
+ aglReshape(p_vout);
+ p_vout->i_changes &= ~VOUT_ASPECT_CHANGE;
+ }
+ if( p_vout->i_changes & VOUT_CROP_CHANGE )
+ {
+ aglReshape(p_vout);
+ p_vout->i_changes &= ~VOUT_CROP_CHANGE;
+ }
+ return VLC_SUCCESS;
+}
+
+static void aglSwap( vout_thread_t * p_vout )
+{
+ p_vout->p_sys->b_got_frame = VLC_TRUE;
+ aglSwapBuffers(p_vout->p_sys->agl_ctx);
+}
+
+static void UpdateEmbeddedGeometry( vout_thread_t *p_vout )
+{
+ vlc_value_t val;
+ vlc_value_t valt, vall, valb, valr, valx, valy, valw, valh,
+ valportx, valporty;
+
+ Rect winBounds;
+ Rect clientBounds;
+
+ GLint rect[4];
+
+ var_Get( p_vout->p_vlc, "drawable", &val );
+ var_Get( p_vout->p_vlc, "drawablet", &valt );
+ var_Get( p_vout->p_vlc, "drawablel", &vall );
+ var_Get( p_vout->p_vlc, "drawableb", &valb );
+ var_Get( p_vout->p_vlc, "drawabler", &valr );
+ var_Get( p_vout->p_vlc, "drawablex", &valx );
+ var_Get( p_vout->p_vlc, "drawabley", &valy );
+ var_Get( p_vout->p_vlc, "drawablew", &valw );
+ var_Get( p_vout->p_vlc, "drawableh", &valh );
+ var_Get( p_vout->p_vlc, "drawableportx", &valportx );
+ var_Get( p_vout->p_vlc, "drawableporty", &valporty );
+
+ // mozilla plugin provides coordinates based on port bounds
+ // however AGL coordinates are based on window structure region
+ // and are vertically flipped
+
+ GetWindowBounds(GetWindowFromPort((CGrafPtr)val.i_int),
+ kWindowStructureRgn, &winBounds);
+ GetWindowBounds(GetWindowFromPort((CGrafPtr)val.i_int),
+ kWindowContentRgn, &clientBounds);
+
+ /* update video clipping bounds in drawable */
+ rect[0] = (clientBounds.left-winBounds.left)
+ + vall.i_int; // from window left edge
+ rect[1] = (winBounds.bottom-winBounds.top)
+ - (clientBounds.top-winBounds.top)
+ - valb.i_int; // from window bottom edge
+ rect[2] = valr.i_int-vall.i_int; // width
+ rect[3] = valb.i_int-valt.i_int; // height
+ aglSetInteger(p_vout->p_sys->agl_ctx, AGL_BUFFER_RECT, rect);
+ aglEnable(p_vout->p_sys->agl_ctx, AGL_BUFFER_RECT);
+
+ /* update video internal bounds in drawable */
+ p_vout->p_sys->i_offx = -vall.i_int - valportx.i_int;
+ p_vout->p_sys->i_offy = valb.i_int + valporty.i_int - valh.i_int;
+ p_vout->p_sys->i_width = valw.i_int;
+ p_vout->p_sys->i_height = valh.i_int;
+
+ if( p_vout->p_sys->agl_drawable == (AGLDrawable)val.i_int )
+ {
+ aglUpdateContext(p_vout->p_sys->agl_ctx);
+ }
+ else
+ {
+ p_vout->p_sys->agl_drawable = (AGLDrawable)val.i_int;
+ aglSetDrawable(p_vout->p_sys->agl_ctx, p_vout->p_sys->agl_drawable);
+ }
+ aglReshape( p_vout );
+}
+
+/* If we're embedded, the application is expected to indicate a
+ * window change (move/resize/etc) via the "drawableredraw" value.
+ */
+
+static int DrawableRedraw( vlc_object_t *p_this, const char *psz_name,
+ vlc_value_t oval, vlc_value_t nval, void *param)
+{
+ vout_thread_t *p_vout = (vout_thread_t *)param;
+
+ UpdateEmbeddedGeometry( p_vout );
+
+ return VLC_SUCCESS;
+}