- val.i_int = ( ((int)ml.y) - i_y ) *
- p_vout->render.i_height / i_height;
- var_Set( p_vout, "mouse-y", val );
-
- val.b_bool = VLC_TRUE;
- var_Set( p_vout, "mouse-moved", val );
- p_vout->p_sys->i_time_mouse_last_moved = mdate();
- p_vout->p_sys->b_mouse_moved = YES;
- }
-
- [super mouseMoved: o_event];
-}
-
-@end
-
-/*****************************************************************************
- * VLCGLView implementation
- *****************************************************************************/
-@implementation VLCGLView
-
-
-- (id) initWithFrame: (NSRect) frame vout: (vout_thread_t*) _p_vout
-{
- char * psz_effect;
- p_vout = _p_vout;
-
- NSOpenGLPixelFormatAttribute attribs[] =
- {
- NSOpenGLPFAAccelerated,
- NSOpenGLPFANoRecovery,
- NSOpenGLPFADoubleBuffer,
- NSOpenGLPFAColorSize, 24,
- NSOpenGLPFAAlphaSize, 8,
- NSOpenGLPFADepthSize, 24,
- NSOpenGLPFAWindow,
- 0
- };
-
- NSOpenGLPixelFormat * fmt = [[NSOpenGLPixelFormat alloc]
- initWithAttributes: attribs];
-
- if( !fmt )
- {
- msg_Warn( p_vout, "Cannot create NSOpenGLPixelFormat" );
- return nil;
- }
-
- self = [super initWithFrame:frame pixelFormat: fmt];
-
- currentContext = [self openGLContext];
- [currentContext makeCurrentContext];
- [currentContext update];
-
- /* Black background */
- glClearColor( 0.0, 0.0, 0.0, 0.0 );
-
- /* Check if the user asked for useless visual effects */
- psz_effect = config_GetPsz( p_vout, "macosx-opengl-effect" );
- if( !psz_effect || !strcmp( psz_effect, "none" ))
- {
- i_effect = OPENGL_EFFECT_NONE;
- }
- else if( !strcmp( psz_effect, "cube" ) )
- {
- i_effect = OPENGL_EFFECT_CUBE;
-
- glEnable( GL_DEPTH_TEST );
- }
- else if( !strcmp( psz_effect, "transparent-cube" ) )
- {
- i_effect = OPENGL_EFFECT_TRANSPARENT_CUBE;
-
- glDisable( GL_DEPTH_TEST );
- glEnable( GL_BLEND );
- glBlendFunc( GL_SRC_ALPHA, GL_ONE );
- }
- else
- {
- msg_Warn( p_vout, "no valid opengl effect provided, using "
- "\"none\"" );
- i_effect = OPENGL_EFFECT_NONE;
- }
-
- if( i_effect & ( OPENGL_EFFECT_CUBE |
- OPENGL_EFFECT_TRANSPARENT_CUBE ) )
- {
- /* Set the perpective */
- glMatrixMode( GL_PROJECTION );
- glLoadIdentity();
- glFrustum( -1.0, 1.0, -1.0, 1.0, 3.0, 20.0 );
- glMatrixMode( GL_MODELVIEW );
- glLoadIdentity();
- glTranslatef( 0.0, 0.0, - 5.0 );
- }
-
- i_texture = 0;
- initDone = 0;
- isFullScreen = 0;
-
- return self;
-}
-
-- (void) reshape
-{
- if( !initDone )
- {
- return;
- }
-
- [currentContext makeCurrentContext];
-
- NSRect bounds = [self bounds];
- glViewport( 0, 0, (GLint) bounds.size.width,
- (GLint) bounds.size.height );
-
- /* Quad size is set in order to preserve the aspect ratio */
- if( config_GetInt( p_vout, "macosx-stretch" ) )
- {
- f_x = 1.0;
- f_y = 1.0;
- }
- else if( bounds.size.height * p_vout->output.i_aspect <
- bounds.size.width * VOUT_ASPECT_FACTOR )
- {
- f_x = bounds.size.height * p_vout->output.i_aspect /
- VOUT_ASPECT_FACTOR / bounds.size.width;
- f_y = 1.0;
- }
- else
- {
- f_x = 1.0;
- f_y = bounds.size.width * VOUT_ASPECT_FACTOR /
- p_vout->output.i_aspect / bounds.size.height;
- }
-}
-
-- (void) initTextures
-{
- [currentContext makeCurrentContext];
-
- /* Free previous texture if any */
- if( i_texture )
- {
- glDeleteTextures( 1, &i_texture );
- }
-
- /* Create textures */
- glGenTextures( 1, &i_texture );
-
- glEnable( GL_TEXTURE_RECTANGLE_EXT );
- glEnable( GL_UNPACK_CLIENT_STORAGE_APPLE );
-
- glBindTexture( GL_TEXTURE_RECTANGLE_EXT, i_texture );
-
- /* Use VRAM texturing */
- glTexParameteri( GL_TEXTURE_RECTANGLE_EXT,
- GL_TEXTURE_STORAGE_HINT_APPLE, GL_STORAGE_CACHED_APPLE );
-
- /* Tell the driver not to make a copy of the texture but to use
- our buffer */
- glPixelStorei( GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE );
-
- /* Linear interpolation */
- glTexParameteri( GL_TEXTURE_RECTANGLE_EXT,
- GL_TEXTURE_MIN_FILTER, GL_LINEAR );
- glTexParameteri( GL_TEXTURE_RECTANGLE_EXT,
- GL_TEXTURE_MAG_FILTER, GL_LINEAR );
-
- /* I have no idea what this exactly does, but it seems to be
- necessary for scaling */
- glTexParameteri( GL_TEXTURE_RECTANGLE_EXT,
- GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
- glTexParameteri( GL_TEXTURE_RECTANGLE_EXT,
- GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glPixelStorei( GL_UNPACK_ROW_LENGTH, 0 );
-
- glTexImage2D( GL_TEXTURE_RECTANGLE_EXT, 0, GL_RGBA,
- p_vout->output.i_width, p_vout->output.i_height, 0,
- GL_YCBCR_422_APPLE, GL_UNSIGNED_SHORT_8_8_APPLE,
- PP_OUTPUTPICTURE[0]->p_data );
-
- initDone = 1;
-}
-
-- (void) reloadTexture
-{
- if( !initDone )
- {
- return;
- }
-
- [currentContext makeCurrentContext];
-
- glBindTexture( GL_TEXTURE_RECTANGLE_EXT, i_texture );
-
- /* glTexSubImage2D is faster than glTexImage2D
- http://developer.apple.com/samplecode/Sample_Code/Graphics_3D/
- TextureRange/MainOpenGLView.m.htm */
- glTexSubImage2D( GL_TEXTURE_RECTANGLE_EXT, 0, 0, 0,
- p_vout->output.i_width, p_vout->output.i_height,
- GL_YCBCR_422_APPLE, GL_UNSIGNED_SHORT_8_8_APPLE,
- PP_OUTPUTPICTURE[0]->p_data );
-}
-
-- (void) goFullScreen
-{
- /* Create the new pixel format */
- NSOpenGLPixelFormatAttribute attribs[] =
- {
- NSOpenGLPFAAccelerated,
- NSOpenGLPFANoRecovery,
- NSOpenGLPFADoubleBuffer,
- NSOpenGLPFAColorSize, 24,
- NSOpenGLPFAAlphaSize, 8,
- NSOpenGLPFADepthSize, 24,
- NSOpenGLPFAFullScreen,
- NSOpenGLPFAScreenMask,
- /* TODO handle macosx-vdev */
- CGDisplayIDToOpenGLDisplayMask( kCGDirectMainDisplay ),
- 0
- };
- NSOpenGLPixelFormat * fmt = [[NSOpenGLPixelFormat alloc]
- initWithAttributes: attribs];
- if( !fmt )
- {
- msg_Warn( p_vout, "Cannot create NSOpenGLPixelFormat" );
- return;
- }
-
- /* Create the new OpenGL context */
- fullScreenContext = [[NSOpenGLContext alloc]
- initWithFormat: fmt shareContext: nil];
- if( !fullScreenContext )
- {
- msg_Warn( p_vout, "Failed to create new NSOpenGLContext" );
- return;
- }
- currentContext = fullScreenContext;
-
- /* Capture display, switch to fullscreen */
- if( CGCaptureAllDisplays() != CGDisplayNoErr )
- {
- msg_Warn( p_vout, "CGCaptureAllDisplays() failed" );
- return;
- }
- [fullScreenContext setFullScreen];
- [fullScreenContext makeCurrentContext];
-
- /* Ratio */
- unsigned width = CGDisplayPixelsWide( kCGDirectMainDisplay );
- unsigned height = CGDisplayPixelsHigh( kCGDirectMainDisplay );
- int stretch = config_GetInt( p_vout, "macosx-stretch" );
- int fill = config_GetInt( p_vout, "macosx-fill" );
- int bigRatio = ( height * p_vout->output.i_aspect <
- width * VOUT_ASPECT_FACTOR );
- if( stretch )
- {
- f_x = 1.0;
- f_y = 1.0;
- }
- else if( ( bigRatio && !fill ) || ( !bigRatio && fill ) )
- {
- f_x = (float) height * p_vout->output.i_aspect /
- width / VOUT_ASPECT_FACTOR;
- f_y = 1.0;
- }
- else
- {
- f_x = 1.0;
- f_y = (float) width * VOUT_ASPECT_FACTOR /
- p_vout->output.i_aspect / height;
- }
-
- /* Update viewport, re-init textures */
- glViewport( 0, 0, width, height );
- [self initTextures];
-
- /* Redraw the last picture */
- [self setNeedsDisplay: YES];
-
- isFullScreen = 1;
-}
-
-- (void) exitFullScreen
-{
- /* Free current OpenGL context */
- [NSOpenGLContext clearCurrentContext];
- [fullScreenContext clearDrawable];
- [fullScreenContext release];
- CGReleaseAllDisplays();
-
- currentContext = [self openGLContext];
- [self initTextures];
- [self reshape];
-
- /* Redraw the last picture */
- [self setNeedsDisplay: YES];
-
- isFullScreen = 0;
-}
-
-- (void) cleanUp
-{
- if( isFullScreen )
- {
- [self exitFullScreen];
- }
- initDone = 0;
-}
-
-- (void) drawQuad
-{
- glBegin( GL_QUADS );
- /* Top left */
- glTexCoord2f( 0.0, 0.0 );
- glVertex2f( - f_x, f_y );
- /* Bottom left */
- glTexCoord2f( 0.0, (float) p_vout->output.i_height );
- glVertex2f( - f_x, - f_y );
- /* Bottom right */
- glTexCoord2f( (float) p_vout->output.i_width,
- (float) p_vout->output.i_height );
- glVertex2f( f_x, - f_y );
- /* Top right */
- glTexCoord2f( (float) p_vout->output.i_width, 0.0 );
- glVertex2f( f_x, f_y );
- glEnd();
-}
-
-- (void) drawCube
-{
- glBegin( GL_QUADS );
- /* Front */
- glTexCoord2f( 0.0, 0.0 );
- glVertex3f( - 1.0, 1.0, 1.0 );
- glTexCoord2f( 0.0, (float) p_vout->output.i_height );
- glVertex3f( - 1.0, - 1.0, 1.0 );
- glTexCoord2f( (float) p_vout->output.i_width,
- (float) p_vout->output.i_height );
- glVertex3f( 1.0, - 1.0, 1.0 );
- glTexCoord2f( (float) p_vout->output.i_width, 0.0 );
- glVertex3f( 1.0, 1.0, 1.0 );
-
- /* Left */
- glTexCoord2f( 0.0, 0.0 );
- glVertex3f( - 1.0, 1.0, - 1.0 );
- glTexCoord2f( 0.0, (float) p_vout->output.i_height );
- glVertex3f( - 1.0, - 1.0, - 1.0 );
- glTexCoord2f( (float) p_vout->output.i_width,
- (float) p_vout->output.i_height );
- glVertex3f( - 1.0, - 1.0, 1.0 );
- glTexCoord2f( (float) p_vout->output.i_width, 0.0 );
- glVertex3f( - 1.0, 1.0, 1.0 );
-
- /* Back */
- glTexCoord2f( 0.0, 0.0 );
- glVertex3f( 1.0, 1.0, - 1.0 );
- glTexCoord2f( 0.0, (float) p_vout->output.i_height );
- glVertex3f( 1.0, - 1.0, - 1.0 );
- glTexCoord2f( (float) p_vout->output.i_width,
- (float) p_vout->output.i_height );
- glVertex3f( - 1.0, - 1.0, - 1.0 );
- glTexCoord2f( (float) p_vout->output.i_width, 0.0 );
- glVertex3f( - 1.0, 1.0, - 1.0 );
-
- /* Right */
- glTexCoord2f( 0.0, 0.0 );
- glVertex3f( 1.0, 1.0, 1.0 );
- glTexCoord2f( 0.0, (float) p_vout->output.i_height );
- glVertex3f( 1.0, - 1.0, 1.0 );
- glTexCoord2f( (float) p_vout->output.i_width,
- (float) p_vout->output.i_height );
- glVertex3f( 1.0, - 1.0, - 1.0 );
- glTexCoord2f( (float) p_vout->output.i_width, 0.0 );
- glVertex3f( 1.0, 1.0, - 1.0 );
-
- /* Top */
- glTexCoord2f( 0.0, 0.0 );
- glVertex3f( - 1.0, 1.0, - 1.0 );
- glTexCoord2f( 0.0, (float) p_vout->output.i_height );
- glVertex3f( - 1.0, 1.0, 1.0 );
- glTexCoord2f( (float) p_vout->output.i_width,
- (float) p_vout->output.i_height );
- glVertex3f( 1.0, 1.0, 1.0 );
- glTexCoord2f( (float) p_vout->output.i_width, 0.0 );
- glVertex3f( 1.0, 1.0, - 1.0 );
-
- /* Bottom */
- glTexCoord2f( 0.0, 0.0 );
- glVertex3f( - 1.0, - 1.0, 1.0 );
- glTexCoord2f( 0.0, (float) p_vout->output.i_height );
- glVertex3f( - 1.0, - 1.0, - 1.0 );
- glTexCoord2f( (float) p_vout->output.i_width,
- (float) p_vout->output.i_height );
- glVertex3f( 1.0, - 1.0, - 1.0 );
- glTexCoord2f( (float) p_vout->output.i_width, 0.0 );
- glVertex3f( 1.0, - 1.0, 1.0 );
- glEnd();
-}
-
-- (void) drawRect: (NSRect) rect
-{
- [currentContext makeCurrentContext];
-
- /* 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 );
-
- /* Black background */
- glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
-
- if( !initDone )
- {
- [currentContext flushBuffer];
- return;
- }
-
- /* Draw */
- glBindTexture( GL_TEXTURE_RECTANGLE_EXT, i_texture );
- if( i_effect & ( OPENGL_EFFECT_CUBE |
- OPENGL_EFFECT_TRANSPARENT_CUBE ) )
- {
- glRotatef( 1.0, 0.3, 0.5, 0.7 );
- [self drawCube];
- }
- else
- {
- [self drawQuad];
- }
-
- /* Wait for the job to be done */
- [currentContext flushBuffer];
-}
-
-@end
-
-/*****************************************************************************
- * VLCVout implementation
- *****************************************************************************/
-@implementation VLCVout
-
-- (void)createWindow:(NSValue *)o_value
-{
- vlc_value_t val;
- VLCQTView * o_view;
- NSScreen * o_screen;
- vout_thread_t * p_vout;
- vlc_bool_t b_main_screen;
-
- p_vout = (vout_thread_t *)[o_value pointerValue];
-
- p_vout->p_sys->o_window = [VLCWindow alloc];
- [p_vout->p_sys->o_window setVout: p_vout];
- [p_vout->p_sys->o_window setReleasedWhenClosed: YES];
-
- if( var_Get( p_vout, "video-device", &val ) < 0 )
- {
- o_screen = [NSScreen mainScreen];
- b_main_screen = 1;
- }
- else
- {
- NSArray *o_screens = [NSScreen screens];
- unsigned int i_index = val.i_int;
-
- if( [o_screens count] < i_index )