summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDiego 'Flameeyes' Pettenò <flameeyes@gmail.com>2007-04-11 17:36:11 +0200
committerDiego 'Flameeyes' Pettenò <flameeyes@gmail.com>2007-04-11 17:36:11 +0200
commite54b6425e71d6b8f25ffc90b71e9fff5eb7743d3 (patch)
treea4a39db203785999c201026d2c37b640967feea7
parentb6d41cbd12e116b9e37e1f8afb37927e4944bc95 (diff)
parentf589d9c3ed2315a91057963583327f870e56f86b (diff)
downloadxine-lib-e54b6425e71d6b8f25ffc90b71e9fff5eb7743d3.tar.gz
xine-lib-e54b6425e71d6b8f25ffc90b71e9fff5eb7743d3.tar.bz2
Merge Matt Messier video output for Mac OS X.
-rw-r--r--src/video_out/macosx/XineOpenGLView.h155
-rw-r--r--src/video_out/macosx/XineOpenGLView.m1124
-rw-r--r--src/video_out/macosx/XineVideoWindow.m2
-rw-r--r--src/video_out/video_out_macosx.m55
4 files changed, 635 insertions, 701 deletions
diff --git a/src/video_out/macosx/XineOpenGLView.h b/src/video_out/macosx/XineOpenGLView.h
index 063a33eb2..b63738047 100644
--- a/src/video_out/macosx/XineOpenGLView.h
+++ b/src/video_out/macosx/XineOpenGLView.h
@@ -23,6 +23,7 @@
#define __HAVE_XINE_OPENGL_VIEW_H__
#import <Cocoa/Cocoa.h>
+#import <OpenGL/gl.h>
#import "XineVideoWindow.h"
@@ -32,74 +33,106 @@ extern NSString *XineViewDidResizeNotification;
@interface XineOpenGLView : NSOpenGLView
{
+ @private
IBOutlet id <NSObject, XineOpenGLViewDelegate> delegate;
- int video_width, video_height;
- char *texture_buffer;
- unsigned long i_texture;
- BOOL initDone;
- BOOL isFullScreen;
- XineVideoWindowFullScreenMode fullscreen_mode;
- NSOpenGLContext *fullScreenContext;
- NSOpenGLContext *currentContext;
- NSLock *mutex;
- BOOL keepsVideoAspectRatio;
- BOOL resizeViewOnVideoSizeChange;
- NSCursor *currentCursor;
- id <NSObject, XineOpenGLViewDelegate> _xineController;
- NSColor *initialColor;
- unsigned int initialColorYUV;
- BOOL initialColorYUVIsSet;
+ IBOutlet id <NSObject, XineOpenGLViewDelegate> controller;
+
+ NSRecursiveLock * mutex;
+ BOOL initDone;
+
+ NSSize videoSize;
+ char * textureBuffer;
+ GLuint texture;
+
+ BOOL keepsVideoAspectRatio;
+ BOOL resizeViewOnVideoSizeChange;
+ NSCursor * currentCursor;
+
+ NSColor * initialColor;
+ unsigned int initialColorYUV;
+ BOOL initialColorYUVIsSet;
+
+ BOOL isFullScreen;
+ BOOL isFullScreenPrepared;
+ XineVideoWindowFullScreenMode fullScreenMode;
+ NSOpenGLContext * fullScreenContext;
}
-- (void) displayTexture;
-- (void) drawQuad;
-- (void) drawRect: (NSRect) rect;
-- (void) goFullScreen: (XineVideoWindowFullScreenMode) mode;
-- (void) exitFullScreen;
-- (BOOL) isFullScreen;
-- (void) reshape;
-- (void) initTextures;
-- (void) reloadTexture;
-- (char *) getTextureBuffer;
-- (void) setViewSizeInMainThread:(NSSize)size;
-// TODO: replace set...Size below with setSize:(double)videoSizeMultiplier
-- (void) setNormalSize;
-- (void) setHalfSize;
-- (void) setDoubleSize;
-- (void) setResizeViewOnVideoSizeChange:(BOOL)flag;
-- (BOOL) resizeViewOnVideoSizeChange;
-- (void) resetCursorRectsInMainThread;
-
-// Accessors
-- (void) setVideoSize:(NSSize)size;
-- (NSSize) videoSize;
-- (void) setKeepsVideoAspectRatio:(BOOL)flag;
-- (BOOL) keepsVideoAspectRatio;
-- (void) setCurrentCursor:(NSCursor *)cursor;
-- (NSCursor *) currentCursor;
-- (void) setXineController:(id)controller;
-- (id) xineController;
-- (void) setInitialColor:(NSColor *)color;
-- (NSColor *) initialColor;
-
-// Delegate Methods
-- (id) delegate;
-- (void) setDelegate:(id)aDelegate;
++ (NSOpenGLPixelFormat *)defaultPixelFormat;
++ (NSOpenGLPixelFormat *)fullScreenPixelFormat;
-@end
+- (id)initWithCoder:(NSCoder *)coder;
+- (id)initWithFrame:(NSRect)frame;
+- (id)initWithFrame:(NSRect)frame pixelFormat:(NSOpenGLPixelFormat *)pixelFormat;
-/* XineOpenGLView delegate methods */
+- (void)dealloc;
+
+- (void)encodeWithCoder:(NSCoder *)coder;
+
+- (NSOpenGLContext *)openGLContext;
+- (void)prepareOpenGL;
+- (void)reshape;
+- (void)update;
+
+- (void)initTextures;
+- (void)updateTexture;
+- (void)drawRect:(NSRect)rect;
+
+- (NSColor *)initialColor;
+- (void)setInitialColor:(NSColor *)color;
+
+- (void)setNormalSize;
+- (void)setHalfSize;
+- (void)setDoubleSize;
-@interface NSObject (XineOpenGLViewDelegate)
+- (NSSize)videoSize;
-- (NSSize) xineViewWillResize:(NSSize)oldSize toSize:(NSSize)proposedSize;
-- (void) xineViewDidResize:(NSNotification *)aNotification;
-- (void) mouseDown:(NSEvent *)theEvent inXineView:(XineOpenGLView *)theView;
-- (void) mouseMoved:(NSEvent *)theEvent inXineView:(XineOpenGLView *)theView;
-- (void) otherMouseDown:(NSEvent *)theEvent
- inXineView:(XineOpenGLView *)theView;
-- (void) rightMouseDown:(NSEvent *)theEvent
- inXineView:(XineOpenGLView *)theView;
+- (BOOL)keepsVideoAspectRatio;
+- (void)setKeepsVideoAspectRatio:(BOOL)flag;
+- (BOOL)resizeViewOnVideoSizeChange;
+- (void)setResizeViewOnVideoSizeChange:(BOOL)flag;
+
+- (void)setViewSize:(NSValue *)sizeWrapper;
+- (void)setViewSizeInMainThread:(NSSize)size;
+
+- (NSCursor *)currentCursor;
+- (void)setCurrentCursor:(NSCursor *)cursor;
+
+- (BOOL)isFullScreen;
+- (void)goFullScreen:(XineVideoWindowFullScreenMode)mode;
+- (void)exitFullScreen;
+
+- (id)delegate;
+- (void)setDelegate:(id)aDelegate;
+- (id)xineController;
+- (void)setXineController:(id)aController;
+
+- (BOOL)acceptsFirstResponder;
+- (BOOL)mouseDownCanMoveWindow;
+
+// Not intended for public use:
+- (char *)textureBuffer;
+- (void)setVideoSize:(NSSize)size;
+- (void)resetCursorRects;
+- (void)resetCursorRectsInMainThread;
+- (void)calcFullScreenAspect;
+- (void)releaseInMainThread;
+- (void)passEventToDelegate:(NSEvent *)theEvent withSelector:(SEL)selector;
+
+- (BOOL)acceptsFirstResponder;
+- (BOOL)mouseDownCanMoveWindow;
+
+@end
+
+/* XineOpenGLView delegate methods */
+@protocol XineOpenGLViewDelegate
+
+- (void)mouseDown:(NSEvent *)theEvent inXineView:(XineOpenGLView *)theView;
+- (void)mouseMoved:(NSEvent *)theEvent inXineView:(XineOpenGLView *)theView;
+- (void)otherMouseDown:(NSEvent *)theEvent inXineView:(XineOpenGLView *)theView;
+- (void)rightMouseDown:(NSEvent *)theEvent inXineView:(XineOpenGLView *)theView;
+- (NSSize)xineViewWillResize:(NSSize)oldSize toSize:(NSSize)proposedSize;
+- (void)xineViewDidResize:(NSNotification *)note;
@end
diff --git a/src/video_out/macosx/XineOpenGLView.m b/src/video_out/macosx/XineOpenGLView.m
index e939575a0..c29f95dc7 100644
--- a/src/video_out/macosx/XineOpenGLView.m
+++ b/src/video_out/macosx/XineOpenGLView.m
@@ -19,7 +19,6 @@
*
*/
-
/*
#define LOG
*/
@@ -37,700 +36,411 @@
# include <xine/xineutils.h>
#endif
+NSString *XineViewDidResizeNotification EXPORTED = @"XineViewDidResizeNotification";
-NSString *XineViewDidResizeNotification = @"XineViewDidResizeNotification";
-
-
-/* XineOpenGLView delegate methods */
-
-@protocol XineOpenGLViewDelegate
-
-- (void) mouseDown:(NSEvent *)theEvent inXineView:(XineOpenGLView *)theView;
-- (void) mouseMoved:(NSEvent *)theEvent inXineView:(XineOpenGLView *)theView;
-- (void) otherMouseDown:(NSEvent *)theEvent inXineView:(XineOpenGLView *)theView;
-- (void) rightMouseDown:(NSEvent *)theEvent inXineView:(XineOpenGLView *)theView;
-- (NSSize) xineViewWillResize:(NSSize)oldSize toSize:(NSSize)proposedSize;
-- (void) xineViewDidResize:(NSNotification *)note;
-
-@end
-
+static uint32_t
+NSColorToYUV(NSColor *color)
+{
+ float red, green, blue, alpha;
+ uint32_t yuv;
+ unsigned char r, g, b;
+ unsigned char y, u, v;
-static uint32_t NSColorToYUV (NSColor *color);
+ NSColor *calibratedColor = [color colorUsingColorSpaceName:NSCalibratedRGBColorSpace];
+ [calibratedColor getRed:&red green:&green blue:&blue alpha:&alpha];
+ r = red * 255;
+ g = green * 255;
+ b = blue * 255;
-@implementation XineOpenGLView
+ init_yuv_conversion();
-- (void) setKeepsVideoAspectRatio:(BOOL)flag
-{
- keepsVideoAspectRatio = flag;
-}
+ y = COMPUTE_Y(r, g, b);
+ u = COMPUTE_U(r, g, b);
+ v = COMPUTE_V(r, g, b);
-- (BOOL) keepsVideoAspectRatio
-{
- return keepsVideoAspectRatio;
+ yuv = (y << 24) | (u << 16) | (y << 8) | v;
+ return yuv;
}
-- (void) setResizeViewOnVideoSizeChange:(BOOL)flag
-{
- resizeViewOnVideoSizeChange = flag;
-}
+@implementation XineOpenGLView
-- (BOOL) resizeViewOnVideoSizeChange
++ (NSOpenGLPixelFormat *)defaultPixelFormat
{
- return resizeViewOnVideoSizeChange;
-}
+ NSOpenGLPixelFormatAttribute attributes[] = {
+ NSOpenGLPFAAccelerated,
+ NSOpenGLPFANoRecovery,
+ NSOpenGLPFADoubleBuffer,
+ NSOpenGLPFAColorSize, 24,
+ NSOpenGLPFAAlphaSize, 8,
+ NSOpenGLPFADepthSize, 24,
+ NSOpenGLPFAWindow,
+ 0
+ };
-- (BOOL)mouseDownCanMoveWindow
-{
- return YES;
+ return [[[NSOpenGLPixelFormat alloc] initWithAttributes:attributes] autorelease];
}
-- (void)passEventToDelegate:(NSEvent *)theEvent withSelector:(SEL)selector
++ (NSOpenGLPixelFormat *)fullScreenPixelFormat
{
- NSPoint point = [self convertPoint:[theEvent locationInWindow]
- fromView:nil];
-
- if (!NSMouseInRect(point, [self bounds], [self isFlipped])) return;
-
- if ([delegate respondsToSelector:selector])
- {
- [delegate performSelector:selector
- withObject:theEvent
- withObject:self];
- return;
- }
+ NSOpenGLPixelFormatAttribute attributes[] = {
+ NSOpenGLPFAAccelerated,
+ NSOpenGLPFANoRecovery,
+ NSOpenGLPFADoubleBuffer,
+ NSOpenGLPFAColorSize, 24,
+ NSOpenGLPFAAlphaSize, 8,
+ NSOpenGLPFADepthSize, 24,
+ NSOpenGLPFAFullScreen,
+ NSOpenGLPFAScreenMask, CGDisplayIDToOpenGLDisplayMask(kCGDirectMainDisplay),
+ 0
+ };
- if ([_xineController respondsToSelector:selector])
- {
- [_xineController performSelector:selector
- withObject:theEvent
- withObject:self];
- return;
- }
+ return [[[NSOpenGLPixelFormat alloc] initWithAttributes:attributes] autorelease];
}
-- (void)mouseMoved:(NSEvent *)theEvent
+- (id)initWithCoder:(NSCoder *)coder
{
- [self passEventToDelegate:theEvent
- withSelector:@selector(mouseMoved:inXineView:)];
-
- [super mouseMoved:theEvent];
-}
+ NSColor *color;
-- (void)mouseDown:(NSEvent *)theEvent
-{
- [self passEventToDelegate:theEvent
- withSelector:@selector(mouseDown:inXineView:)];
-
- [super mouseDown:theEvent];
-}
+ if ((self = [super initWithCoder:coder]) != nil) {
+ videoSize = [self frame].size;
+ mutex = [[NSRecursiveLock alloc] init];
+ currentCursor = [[NSCursor arrowCursor] retain];
-- (void)rightMouseDown:(NSEvent *)theEvent
-{
- [self passEventToDelegate:theEvent
- withSelector:@selector(rightMouseDown:inXineView:)];
-
- [super rightMouseDown:theEvent];
-}
+ if ([coder allowsKeyedCoding]) {
+ keepsVideoAspectRatio = [coder decodeBoolForKey:@"keepsVideoAspectRatio"];
+ resizeViewOnVideoSizeChange = [coder decodeBoolForKey:@"resizeViewOnVideoSizeChange"];
+ color = [coder decodeObjectForKey:@"initialColor"];
+ }
+ else { /* Must decode values in the same order as encodeWithCoder: */
+ [coder decodeValueOfObjCType:@encode(BOOL) at:&keepsVideoAspectRatio];
+ [coder decodeValueOfObjCType:@encode(BOOL) at:&resizeViewOnVideoSizeChange];
+ color = [coder decodeObject];
+ }
+ [self setInitialColor:color];
-- (void)otherMouseDown:(NSEvent *)theEvent
-{
- [self passEventToDelegate:theEvent
- withSelector:@selector(otherMouseDown:inXineView:)];
-
- [super otherMouseDown:theEvent];
+#ifdef LOG
+ NSLog(@"XineOpenGLView: initWithCoder called");
+#endif
+ }
+ return self;
}
-- (NSSize)videoSize
+- (id)initWithFrame:(NSRect)frame
{
- return NSMakeSize(video_width, video_height);
-}
-
-- (void) displayTexture {
- if ([self lockFocusIfCanDraw])
- {
- [self drawRect: [self bounds]];
- [self reloadTexture];
- [self unlockFocus];
- }
+ return [self initWithFrame:frame pixelFormat:[[self class] defaultPixelFormat]];
}
-- (id) initWithFrame: (NSRect) frame
+- (id)initWithFrame:(NSRect)frame pixelFormat:(NSOpenGLPixelFormat *)format
{
- NSOpenGLPixelFormatAttribute attribs[] = {
- NSOpenGLPFAAccelerated,
- NSOpenGLPFANoRecovery,
- NSOpenGLPFADoubleBuffer,
- NSOpenGLPFAColorSize, 24,
- NSOpenGLPFAAlphaSize, 8,
- NSOpenGLPFADepthSize, 24,
- NSOpenGLPFAWindow,
- 0
- };
-
- NSOpenGLPixelFormat * fmt = [[NSOpenGLPixelFormat alloc]
- initWithAttributes: attribs];
-
- if (!fmt)
- {
- NSLog (@"Cannot create NSOpenGLPixelFormat\n");
- return nil;
- }
-
- self = [super initWithFrame:frame pixelFormat:fmt];
-
- currentContext = [self openGLContext];
- [currentContext makeCurrentContext];
- [mutex lock];
- [currentContext update];
- [mutex unlock];
-
- i_texture = 0;
- initDone = NO;
- isFullScreen = NO;
- video_width = frame.size.width;
- video_height = frame.size.height;
- texture_buffer = nil;
- mutex = [[NSLock alloc] init];
- currentCursor = [[NSCursor arrowCursor] retain];
- initialColor = nil;
- initialColorYUV = 0;
- initialColorYUVIsSet = NO;
- _xineController = nil;
-
- [self initTextures];
-
- /* Set GL_COLOR_BUFFER_BIT to black */
- glClearColor (0.0, 0.0, 0.0, 0.0);
+ format = (format ? : [[self class] defaultPixelFormat]);
+ if ((self = [super initWithFrame:frame pixelFormat:format]) != nil) {
+ videoSize = frame.size;
+ mutex = [[NSRecursiveLock alloc] init];
+ currentCursor = [[NSCursor arrowCursor] retain];
+ [self setInitialColor:nil];
#ifdef LOG
- NSLog(@"XineOpenGLView: initWithFrame called");
+ NSLog(@"XineOpenGLView: initWithFrame called");
#endif
-
+ }
return self;
}
-- (void) awakeFromNib
-{
-#ifdef LOG
- NSLog(@"XineOpenGLView: awakeFromNib called");
-#endif
-}
-
-- (id) initWithCoder:(NSCoder *)coder
+- (void)dealloc
{
- self = [super initWithCoder:coder];
-
- self = [self initWithFrame:[self frame]];
-
- if ([coder allowsKeyedCoding])
- {
- keepsVideoAspectRatio = [coder decodeBoolForKey:@"keepsVideoAspectRatio"];
- resizeViewOnVideoSizeChange = [coder decodeBoolForKey:
- @"resizeViewOnVideoSizeChange"];
-
- NSColor *color = [coder decodeObjectForKey:@"initialColor"];
- if (color)
- initialColor = [color copy];
+ if (isFullScreen) {
+ [self exitFullScreen];
}
- else
- {
- /* Must decode values in the same order as encodeWithCoder: */
- [coder decodeValueOfObjCType:@encode(BOOL) at:&keepsVideoAspectRatio];
- [coder decodeValueOfObjCType:@encode(BOOL) at:&resizeViewOnVideoSizeChange];
- NSColor *color = [coder decodeObject];
- if (color)
- initialColor = [color copy];
+ if (texture) {
+ [[self openGLContext] makeCurrentContext];
+ glDeleteTextures(1, &texture);
+ texture = 0;
}
+ free(textureBuffer);
- [self initTextures];
+ [currentCursor release], currentCursor = nil;
+ [initialColor release], initialColor = nil;
+ [delegate release], delegate = nil;
+ [controller release], controller = nil;
+ [mutex release], mutex = nil;
-#ifdef LOG
- NSLog(@"XineOpenGLView: initWithCoder called");
-#endif
-
- return self;
+ [super dealloc];
}
-- (void) encodeWithCoder:(NSCoder *)coder
+- (void)encodeWithCoder:(NSCoder *)coder
{
[super encodeWithCoder:coder];
- if ([coder allowsKeyedCoding])
- {
+ if ([coder allowsKeyedCoding]) {
[coder encodeBool:keepsVideoAspectRatio forKey:@"keepsVideoAspectRatio"];
- [coder encodeBool:resizeViewOnVideoSizeChange
- forKey:@"resizeViewOnVideoSizeChange"];
+ [coder encodeBool:resizeViewOnVideoSizeChange forKey:@"resizeViewOnVideoSizeChange"];
[coder encodeObject:initialColor forKey:@"initialColor"];
}
- else
- {
+ else {
[coder encodeValueOfObjCType:@encode(BOOL) at:&keepsVideoAspectRatio];
[coder encodeValueOfObjCType:@encode(BOOL) at:&resizeViewOnVideoSizeChange];
[coder encodeObject:initialColor];
}
}
-- (void) dealloc {
- if (texture_buffer)
- free (texture_buffer);
-
- if (fullScreenContext)
- {
- [NSOpenGLContext clearCurrentContext];
- [mutex lock];
- [fullScreenContext clearDrawable];
- [fullScreenContext release];
- [mutex unlock];
- if (currentContext == fullScreenContext) currentContext = nil;
- fullScreenContext = nil;
- }
-
- if (currentContext)
- {
- [NSOpenGLContext clearCurrentContext];
- [mutex lock];
- [currentContext clearDrawable];
- [currentContext release];
- [mutex unlock];
- currentContext = nil;
- }
-
- [mutex dealloc];
+- (NSOpenGLContext *)openGLContext
+{
+ NSOpenGLContext *context;
- if (currentCursor)
- {
- [currentCursor release];
- currentCursor = NULL;
+ [mutex lock];
+ if (!(context = [[fullScreenContext retain] autorelease])) {
+ context = [[[super openGLContext] retain] autorelease];
}
-
- if (initialColor)
- {
- [initialColor release];
- initialColor = NULL;
+ else if (!isFullScreenPrepared) {
+ [self prepareOpenGL];
+ isFullScreenPrepared = YES;
}
+ [mutex unlock];
- // Enabling the [super dealloc] below (which should be correct behaviour)
- // crashes -- not sure why ...
- //
- // [super dealloc];
- //
- // Maybe dealloc in main thread?
+ return context;
}
-- (void) reshape
+// NOTE: This does not exist prior to Panther (10.3)
+- (void)prepareOpenGL
{
+ long swapInterval = 1;
+
[mutex lock];
-
- if (!initDone)
- {
- [mutex unlock];
- return;
- }
-
- [currentContext makeCurrentContext];
-
- NSRect bounds = [self bounds];
- glViewport (0, 0, bounds.size.width, bounds.size.height);
-
-#ifdef LOG
- NSLog(@"XineOpenGLView: Reshape: %x%x%x%x%x%x%x%x",
- texture_buffer[0],
- texture_buffer[1],
- texture_buffer[2],
- texture_buffer[3],
- texture_buffer[4],
- texture_buffer[5],
- texture_buffer[6],
- texture_buffer[7]
- );
-#endif
+ [super prepareOpenGL];
+
+ [[self openGLContext] setValues:&swapInterval forParameter:NSOpenGLCPSwapInterval];
+
+ [self initTextures];
+
+ /* Set GL_COLOR_BUFFER_BIT to black */
+ glClearColor (0.0, 0.0, 0.0, 0.0);
[mutex unlock];
}
-- (void) setNormalSize
+- (void)reshape
{
- NSSize size;
-
- if (isFullScreen)
- return;
-
- size.width = video_width;
- size.height = video_height;
-
- [self setViewSizeInMainThread:size];
+ [mutex lock];
+ [super reshape];
+ if (initDone) {
+ [[self openGLContext] makeCurrentContext];
+
+ NSRect bounds = [self bounds];
+ glViewport(0, 0, bounds.size.width, bounds.size.height);
+
+#ifdef LOG
+ NSLog(@"XineOpenGLView: Reshape: %x%x%x%x%x%x%x%x",
+ textureBuffer[0], textureBuffer[1], textureBuffer[2], textureBuffer[3],
+ textureBuffer[4], textureBuffer[5], textureBuffer[6], textureBuffer[7]);
+#endif
+ }
+ [mutex unlock];
}
-- (void) setHalfSize
+- (void)update
{
- NSSize size;
-
- if (isFullScreen)
- return;
-
- size.width = video_width / 2;
- size.height = video_height / 2;
-
- [self setViewSizeInMainThread:size];
+ [mutex lock];
+ [super update];
+ [mutex unlock];
}
-- (void) setDoubleSize
+- (void)initTextures
{
- NSSize size;
-
- if (isFullScreen)
- return;
-
- size.width = video_width * 2;
- size.height = video_height * 2;
-
- [self setViewSizeInMainThread:size];
-}
+ uint32_t *p, *q, yuv;
-- (void) initTextures
-{
[mutex lock];
- [currentContext makeCurrentContext];
-
/* Free previous texture if any */
- if (i_texture)
- glDeleteTextures (1, &i_texture);
+ if (texture) {
+ glDeleteTextures(1, &texture);
+ texture = 0;
+ }
- if (texture_buffer)
- {
- texture_buffer = realloc (texture_buffer, sizeof (char) *
- video_width * video_height * 3);
+ if (!initialColorYUVIsSet && initialColor) {
+ initialColorYUV = NSColorToYUV(initialColor);
+ initialColorYUVIsSet = YES;
}
- else
- {
- texture_buffer = malloc (sizeof (char) *
- video_width * video_height * 3);
-
- {
- // There _has_ to be a better way of doing this ...
-
- uint32_t *p, *q;
- p = (uint32_t *) texture_buffer;
- q = (uint32_t *) (char *) (texture_buffer + (sizeof(char) * video_width * video_height * 3));
-
- for (; p < q; p++) *p = initialColorYUV;
- }
+ if (textureBuffer) {
+ textureBuffer = (char *)realloc(textureBuffer, videoSize.width * videoSize.height * 4);
}
+ else {
+ textureBuffer = (char *)malloc(videoSize.width * videoSize.height * 4);
- if (!initialColorYUVIsSet && initialColor)
- {
- initialColorYUV = NSColorToYUV(initialColor);
- initialColorYUVIsSet = YES;
+ // There _has_ to be a better way of doing this ...
+
+ yuv = OSSwapHostToBigInt32(initialColorYUV);
+ q = (uint32_t *)(char *)(textureBuffer + (int)(videoSize.width * videoSize.height * 4));
+ for (p = (uint32_t *)textureBuffer; p < q; *p++ = yuv);
}
/* Create textures */
- glGenTextures (1, &i_texture);
+ glGenTextures(1, &texture);
- glEnable (GL_TEXTURE_RECTANGLE_EXT);
- glEnable (GL_UNPACK_CLIENT_STORAGE_APPLE);
+ glEnable(GL_TEXTURE_RECTANGLE_EXT);
+ glEnable(GL_UNPACK_CLIENT_STORAGE_APPLE);
- glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
- glPixelStorei (GL_UNPACK_ROW_LENGTH, video_width);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, videoSize.width);
- glBindTexture (GL_TEXTURE_RECTANGLE_EXT, i_texture);
- glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+ glBindTexture(GL_TEXTURE_RECTANGLE_EXT, texture);
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
/* Use VRAM texturing */
- glTexParameteri (GL_TEXTURE_RECTANGLE_EXT,
- GL_TEXTURE_STORAGE_HINT_APPLE, GL_STORAGE_CACHED_APPLE);
+ 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);
+ 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);
+ 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);
-
- glTexImage2D (GL_TEXTURE_RECTANGLE_EXT, 0, GL_RGBA,
- video_width, video_height, 0,
- GL_YCBCR_422_APPLE, GL_UNSIGNED_SHORT_8_8_APPLE,
- texture_buffer);
+ 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);
+
+ glTexImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, GL_RGBA,
+ videoSize.width, videoSize.height, 0, GL_YCBCR_422_APPLE,
+#if WORDS_BIGENDIAN
+ GL_UNSIGNED_SHORT_8_8_APPLE,
+#else
+ GL_UNSIGNED_SHORT_8_8_REV_APPLE,
+#endif
+ textureBuffer);
initDone = YES;
[mutex unlock];
#ifdef LOG
NSLog(@"XineOpenGLView: initTextures called: %hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx",
- texture_buffer[0],
- texture_buffer[1],
- texture_buffer[2],
- texture_buffer[3],
- texture_buffer[4],
- texture_buffer[5],
- texture_buffer[6],
- texture_buffer[7]
- );
+ textureBuffer[0], textureBuffer[1], textureBuffer[2], textureBuffer[3],
+ textureBuffer[4], textureBuffer[5], textureBuffer[6], textureBuffer[7]);
#endif
}
-- (void) reloadTexture
+- (void)updateTexture
{
- if (!initDone)
- {
- return;
- }
-
[mutex lock];
-
- [currentContext makeCurrentContext];
-
- glBindTexture (GL_TEXTURE_RECTANGLE_EXT, i_texture);
- glPixelStorei (GL_UNPACK_ROW_LENGTH, video_width);
-
+ [[self openGLContext] makeCurrentContext];
+
+ glBindTexture(GL_TEXTURE_RECTANGLE_EXT, texture);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, videoSize.width);
+
// 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,
- video_width, video_height,
- GL_YCBCR_422_APPLE, GL_UNSIGNED_SHORT_8_8_APPLE,
- texture_buffer);
-
- [mutex unlock];
-
-#ifdef LOG
- NSLog(@"reloadTexture called");
+ glTexSubImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, 0, 0,
+ videoSize.width, videoSize.height, GL_YCBCR_422_APPLE,
+#if WORDS_BIG_ENDIAN
+ GL_UNSIGNED_SHORT_8_8_APPLE,
+#else
+ GL_UNSIGNED_SHORT_8_8_REV_APPLE,
#endif
+ textureBuffer);
+
+ [self setNeedsDisplay:YES];
+ [mutex unlock];
}
-- (void) calcFullScreenAspect
+- (void)drawRect:(NSRect)rect
{
- int fs_width, fs_height, x = 0, y = 0, w = 0, h = 0;
-
- fs_width = CGDisplayPixelsWide (kCGDirectMainDisplay);
- fs_height = CGDisplayPixelsHigh (kCGDirectMainDisplay);
-
- switch (fullscreen_mode) {
- case XINE_FULLSCREEN_OVERSCAN:
- if (((float) fs_width / (float) fs_height) > ((float) video_width / (float) video_height))
- {
- w = (float) video_width * ((float) fs_height / (float) video_height);
- h = fs_height;
- x = (fs_width - w) / 2;
- y = 0;
- }
- else
- {
- w = fs_width;
- h = (float) video_height * ((float) fs_width / (float) video_width);
- x = 0;
- y = (fs_height - h) / 2;
- }
- break;
-
- case XINE_FULLSCREEN_CROP:
- if (((float) fs_width / (float) fs_height) > ((float) video_width / (float) video_height))
- {
- w = fs_width;
- h = (float) video_height * ((float) fs_width / (float) video_width);
- x = 0;
- y = (fs_height - h) / 2;
- }
- else
- {
- w = (float) video_width * ((float) fs_height / (float) video_height);
- h = fs_height;
- x = (fs_width - w) / 2;
- y = 0;
- }
- break;
- }
-
- NSLog(@"MacOSX fullscreen mode: %dx%d => %dx%d @ %d,%d\n",
- video_width, video_height, w, h, x, y);
-
[mutex lock];
- glViewport (x, y, w, h);
+ if (initDone && texture) {
+ glBindTexture(GL_TEXTURE_RECTANGLE_EXT, texture);
+ glBegin(GL_QUADS);
+ glTexCoord2f(0.0, 0.0); glVertex2f(-1.0, 1.0); // top left
+ glTexCoord2f(0.0, videoSize.height); glVertex2f(-1.0, -1.0); // bottom left
+ glTexCoord2f(videoSize.width, videoSize.height); glVertex2f( 1.0, -1.0); // bottom right
+ glTexCoord2f(videoSize.width, 0.0); glVertex2f( 1.0, 1.0); // top right
+ glEnd();
+ [[self openGLContext] flushBuffer];
+ }
[mutex unlock];
}
-- (void) goFullScreen: (XineVideoWindowFullScreenMode) mode
+- (NSColor *)initialColor
+{
+ return initialColor;
+}
+
+- (void) setInitialColor:(NSColor *)color
+{
+ [initialColor autorelease];
+ initialColor = (color ? [color copy] : [[NSColor blackColor] retain]);
+}
+
+- (void)setNormalSize
{
[mutex lock];
-
- /* Create the new pixel format */
- NSOpenGLPixelFormatAttribute attribs[] =
- {
- NSOpenGLPFAAccelerated,
- NSOpenGLPFANoRecovery,
- NSOpenGLPFADoubleBuffer,
- NSOpenGLPFAColorSize, 24,
- NSOpenGLPFAAlphaSize, 8,
- NSOpenGLPFADepthSize, 24,
- NSOpenGLPFAFullScreen,
- NSOpenGLPFAScreenMask,
- CGDisplayIDToOpenGLDisplayMask (kCGDirectMainDisplay),
- 0
- };
-
- NSOpenGLPixelFormat * fmt = [[NSOpenGLPixelFormat alloc]
- initWithAttributes: attribs];
-
- if (!fmt)
- {
- NSLog (@"Cannot create NSOpenGLPixelFormat\n");
- return;
- }
-
- /* Create the new OpenGL context */
- fullScreenContext = [[NSOpenGLContext alloc]
- initWithFormat: fmt shareContext: nil];
-
- if (!fullScreenContext)
- {
- NSLog(@"Failed to create new NSOpenGLContext\n");
- return;
+ if (!isFullScreen) {
+ [self setViewSizeInMainThread:videoSize];
}
- currentContext = fullScreenContext;
-
- /* Capture display, switch to fullscreen */
- if (CGCaptureAllDisplays() != CGDisplayNoErr)
- {
- NSLog(@"CGCaptureAllDisplays() failed\n");
- return;
- }
-
- [fullScreenContext setFullScreen];
- [fullScreenContext makeCurrentContext];
[mutex unlock];
-
- fullscreen_mode = mode;
-
- [self initTextures];
- [self calcFullScreenAspect];
-
- /* Redraw the last picture */
- [self setNeedsDisplay: YES];
-
- isFullScreen = YES;
}
-- (void) exitFullScreen
+- (void)setHalfSize
{
- initDone = NO;
-
- currentContext = [self openGLContext];
-
- /* Free current OpenGL context */
- [NSOpenGLContext clearCurrentContext];
+ NSSize size;
+
[mutex lock];
- [fullScreenContext clearDrawable];
+ if (!isFullScreen) {
+ size.width = trunc(videoSize.width / 2);
+ size.height = trunc(videoSize.height / 2);
+ [self setViewSizeInMainThread:size];
+ }
[mutex unlock];
- [fullScreenContext release];
- fullScreenContext = nil;
- CGReleaseAllDisplays();
-
- [self reshape];
- [self initTextures];
-
- /* Redraw the last picture */
- [self setNeedsDisplay: YES];
-
- isFullScreen = NO;
- initDone = YES;
}
-- (void) drawQuad
+- (void)setDoubleSize
{
- float f_x = 1.0, f_y = 1.0;
-
- glBegin (GL_QUADS);
- /* Top left */
- glTexCoord2f (0.0, 0.0);
- glVertex2f (-f_x, f_y);
- /* Bottom left */
- glTexCoord2f (0.0, (float) video_height);
- glVertex2f (-f_x, -f_y);
- /* Bottom right */
- glTexCoord2f ((float) video_width, (float) video_height);
- glVertex2f (f_x, -f_y);
- /* Top right */
- glTexCoord2f ((float) video_width, 0.0);
- glVertex2f (f_x, f_y);
- glEnd();
-}
-
-- (void) drawRect: (NSRect) rect
-{
- [currentContext makeCurrentContext];
-
- if (!initDone)
- return;
-
+ NSSize size;
+
[mutex lock];
-
- // 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);
-
- /* Draw */
- glBindTexture (GL_TEXTURE_RECTANGLE_EXT, i_texture);
- [self drawQuad];
-
- /* Wait for the job to be done */
- [currentContext flushBuffer];
-
+ if (!isFullScreen) {
+ size.width = videoSize.width * 2;
+ size.height = videoSize.height * 2;
+ [self setViewSizeInMainThread:size];
+ }
[mutex unlock];
}
-- (char *) getTextureBuffer
+- (NSSize)videoSize
{
- return texture_buffer;
+ return videoSize;
}
-- (void) setVideoSize:(NSSize)size
+- (BOOL)keepsVideoAspectRatio
{
- video_width = size.width;
- video_height = size.height;
-
- if (resizeViewOnVideoSizeChange)
- [self setViewSizeInMainThread:size];
-
- [self initTextures];
+ return keepsVideoAspectRatio;
}
-- (void) setViewSizeInMainThread:(NSSize)size
+- (void)setKeepsVideoAspectRatio:(BOOL)flag
{
- // Create an autorelease pool, since we're running in a xine thread that
- // may not have a pool of its own */
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-
- NSValue *sizeWrapper = [NSValue valueWithBytes:&size
- objCType:@encode(NSSize)];
-
- [self performSelectorOnMainThread:@selector(setViewSize:)
- withObject:sizeWrapper
- waitUntilDone:NO];
-
-#ifdef LOG
- NSLog(@"setViewSizeInMainThread called");
-#endif
-
- [pool release];
+ keepsVideoAspectRatio = flag;
+}
+
+- (BOOL)resizeViewOnVideoSizeChange
+{
+ return resizeViewOnVideoSizeChange;
+}
+
+- (void)setResizeViewOnVideoSizeChange:(BOOL)flag
+{
+ resizeViewOnVideoSizeChange = flag;
}
-- (void) setViewSize:(NSValue *)sizeWrapper
+- (void)setViewSize:(NSValue *)sizeWrapper
{
- NSSize proposedSize, newSize, currentSize;
+ NSSize currentSize, newSize, proposedSize;
[sizeWrapper getValue:&proposedSize];
newSize = proposedSize;
@@ -742,19 +452,17 @@ static uint32_t NSColorToYUV (NSColor *color);
return;
}
- /* If our controller handles xineViewWillResize:toSize:, send the
- * message to him first. Note that the delegate still has a chance
- * to override the controller's resize preference ... */
- if ([_xineController respondsToSelector:@selector(xineViewWillResize:toSize:)])
- {
+ // If our controller handles xineViewWillResize:toSize:, send the
+ // message to him first. Note that the delegate still has a chance
+ // to override the controller's resize preference ...
+ if ([controller respondsToSelector:@selector(xineViewWillResize:toSize:)]) {
NSSize oldSize = [self frame].size;
- newSize = [_xineController xineViewWillResize:oldSize toSize:proposedSize];
+ newSize = [controller xineViewWillResize:oldSize toSize:proposedSize];
}
- /* If our delegate handles xineViewWillResize:toSize:, send the
- * message to him; otherwise, just resize ourselves */
- if ([delegate respondsToSelector:@selector(xineViewWillResize:toSize:)])
- {
+ // If our delegate handles xineViewWillResize:toSize:, send the
+ // message to him; otherwise, just resize ourselves
+ if ([delegate respondsToSelector:@selector(xineViewWillResize:toSize:)]) {
NSSize oldSize = [self frame].size;
newSize = [delegate xineViewWillResize:oldSize toSize:proposedSize];
}
@@ -769,110 +477,294 @@ static uint32_t NSColorToYUV (NSColor *color);
object:self];
[[NSNotificationCenter defaultCenter] postNotification:note];
- if ([_xineController respondsToSelector:@selector(xineViewDidResize:)])
- [_xineController xineViewDidResize:note];
+ if ([controller respondsToSelector:@selector(xineViewDidResize:)]) {
+ [controller xineViewDidResize:note];
+ }
- if ([delegate respondsToSelector:@selector(xineViewDidResize:)])
+ if ([delegate respondsToSelector:@selector(xineViewDidResize:)]) {
[delegate xineViewDidResize:note];
-
- if (isFullScreen)
+ }
+
+ [mutex lock];
+ [[self openGLContext] makeCurrentContext];
+ if (isFullScreen) {
[self calcFullScreenAspect];
-
+ }
[self initTextures];
+ [mutex unlock];
+}
+
+- (void)setViewSizeInMainThread:(NSSize)size
+{
+ // Create an autorelease pool, since we're running in a xine thread that
+ // may not have a pool of its own
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+
+ NSValue *sizeWrapper = [NSValue valueWithBytes:&size
+ objCType:@encode(NSSize)];
+
+ [self performSelectorOnMainThread:@selector(setViewSize:)
+ withObject:sizeWrapper
+ waitUntilDone:NO];
+
+#ifdef LOG
+ NSLog(@"setViewSizeInMainThread called");
+#endif
+
+ [pool release];
+}
+
+- (NSCursor *)currentCursor
+{
+ return currentCursor;
+}
+
+- (void)setCurrentCursor:(NSCursor *)cursor
+{
+ [currentCursor autorelease];
+ currentCursor = [cursor retain];
+ [self resetCursorRectsInMainThread];
}
-- (BOOL) isFullScreen
+- (BOOL)isFullScreen
{
return isFullScreen;
}
-- (id) delegate
+- (void)goFullScreen:(XineVideoWindowFullScreenMode)mode
{
- return delegate;
+ NSOpenGLPixelFormat *pixelFormat;
+
+ if (!(pixelFormat = [[self class] fullScreenPixelFormat])) {
+ NSLog(@"Cannot create NSOpenGLPixelFormat for full screen mode");
+ return;
+ }
+
+ if (!(fullScreenContext = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:nil])) {
+ NSLog(@"Cannot create NSOpenGLContext for full screen mode");
+ return;
+ }
+
+ if (CGCaptureAllDisplays() != CGDisplayNoErr) {
+ [fullScreenContext release], fullScreenContext = nil;
+ NSLog(@"CGCaptureAllDisplays() failed");
+ return;
+ }
+
+ [mutex lock];
+ fullScreenMode = mode;
+ isFullScreenPrepared = NO;
+
+ [fullScreenContext setFullScreen];
+ [[self openGLContext] makeCurrentContext];
+
+ // Redraw the last picture
+ [self setNeedsDisplay:YES];
+
+ isFullScreen = YES;
+ [mutex unlock];
}
-- (void) setDelegate:(id)aDelegate {
- delegate = aDelegate;
+- (void)exitFullScreen
+{
+ NSOpenGLContext *context;
+
+ [mutex lock];
+ if (isFullScreen) {
+ context = fullScreenContext;
+ fullScreenContext = nil;
+ [[self openGLContext] makeCurrentContext];
+
+ [context clearDrawable];
+ [context release];
+
+ [self reshape];
+ [self initTextures];
+
+ CGReleaseAllDisplays();
+ [self setNeedsDisplay:YES];
+ isFullScreen = NO;
+ }
+ [mutex unlock];
}
-- (BOOL)acceptsFirstResponder {
- return YES;
+- (id)delegate
+{
+ return [[delegate retain] autorelease];
}
-- (void) setCurrentCursor:(NSCursor *)cursor
+- (void)setDelegate:(id)aDelegate
{
- currentCursor = cursor;
- [currentCursor retain];
- [self resetCursorRectsInMainThread];
+ [delegate autorelease];
+ delegate = [aDelegate retain];
}
-- (NSCursor *) currentCursor
+- (id)xineController
{
- return currentCursor;
+ return controller;
}
-- (void) resetCursorRectsInMainThread
+- (void)setXineController:(id)aController
{
- [self discardCursorRects];
- [self performSelectorOnMainThread:@selector(resetCursorRects)
- withObject:nil
- waitUntilDone:NO];
+ [controller autorelease];
+ controller = [aController retain];
}
-- (void) resetCursorRects
+- (char *)textureBuffer
{
- [self addCursorRect:[self visibleRect] cursor:currentCursor];
- [currentCursor set];
+ return textureBuffer;
}
-- (void) setXineController:(id)controller
+- (void)setVideoSize:(NSSize)size
{
- [_xineController autorelease];
- _xineController = controller;
- [_xineController retain];
+ [mutex lock];
+ videoSize = size;
+ if (resizeViewOnVideoSizeChange) {
+ [self setViewSizeInMainThread:size];
+ }
+
+ if (initDone) {
+ [[self openGLContext] makeCurrentContext];
+ [self initTextures];
+ }
+ [mutex unlock];
}
-- (id) xineController
+- (void)resetCursorRects
{
- return _xineController;
+ [mutex lock];
+ [self discardCursorRects];
+ [self addCursorRect:[self visibleRect] cursor:currentCursor];
+ [currentCursor set];
+ [mutex unlock];
}
-- (void) setInitialColor:(NSColor *)color
+- (void)resetCursorRectsInMainThread
{
- [initialColor autorelease];
- initialColor = [color copy];
+ [self performSelectorOnMainThread:@selector(resetCursorRects)
+ withObject:nil
+ waitUntilDone:NO];
}
-- (NSColor *) initialColor
+- (void)releaseInMainThread
{
- return initialColor;
+ [self performSelectorOnMainThread:@selector(release)
+ withObject:nil
+ waitUntilDone:NO];
}
-@end /* XineOpenGLView */
+- (void)calcFullScreenAspect
+{
+ float fs_height, fs_width, h, w, x, y;
+
+ // Feh, should go to main or should go to current display of window?
+ fs_width = CGDisplayPixelsWide(kCGDirectMainDisplay);
+ fs_height = CGDisplayPixelsHigh(kCGDirectMainDisplay);
+
+ switch (fullScreenMode) {
+ case XINE_FULLSCREEN_OVERSCAN:
+ if ((fs_width / fs_height) > (videoSize.width / videoSize.height)) {
+ w = videoSize.width * (fs_height / videoSize.height);
+ h = fs_height;
+ x = (fs_width - w) / 2;
+ y = 0;
+ }
+ else {
+ w = fs_width;
+ h = videoSize.height * (fs_width / videoSize.width);
+ x = 0;
+ y = (fs_height - h) / 2;
+ }
+ break;
+
+ case XINE_FULLSCREEN_CROP:
+ if ((fs_width / fs_height) > (videoSize.width / videoSize.height)) {
+ w = fs_width;
+ h = videoSize.height * (fs_width / videoSize.width);
+ x = 0;
+ y = (fs_height - h) / 2;
+ }
+ else {
+ w = videoSize.width * (fs_height / videoSize.height);
+ h = fs_height;
+ x = (fs_width - w) / 2;
+ y = 0;
+ }
+ break;
+
+ default:
+ NSLog(@"Mac OS X fullscreen mode unrecognized: %d", fullScreenMode);
+ return;
+ }
+
+#ifdef LOG
+ NSLog(@"Mac OS X fullscreen mode: %fx%f => %fx%f @ %f,%f\n",
+ videoSize.width, videoSize.height, w, h, x, y);
+#endif
+ // Assumes locked and current context set
+ glViewport(x, y, w, h);
+}
-static uint32_t NSColorToYUV (NSColor *color)
+- (void)passEventToDelegate:(NSEvent *)theEvent withSelector:(SEL)selector
{
- float red, green, blue, alpha;
- unsigned char r, g, b;
- unsigned char y, u, v;
- uint32_t yuv;
+ NSPoint point = [self convertPoint:[theEvent locationInWindow]
+ fromView:nil];
+
+ if (NSMouseInRect(point, [self bounds], [self isFlipped])) {
+ if ([delegate respondsToSelector:selector]) {
+ [delegate performSelector:selector
+ withObject:theEvent
+ withObject:self];
+ }
+ else if ([controller respondsToSelector:selector]) {
+ [controller performSelector:selector
+ withObject:theEvent
+ withObject:self];
+ }
+ }
+}
- NSColor *calibratedColor = [color colorUsingColorSpaceName:NSCalibratedRGBColorSpace];
- [calibratedColor getRed:&red green:&green blue:&blue alpha:&alpha];
+- (void)mouseMoved:(NSEvent *)theEvent
+{
+ [self passEventToDelegate:theEvent
+ withSelector:@selector(mouseMoved:inXineView:)];
+
+ [super mouseMoved:theEvent];
+}
- r = red * 255;
- g = green * 255;
- b = blue * 255;
+- (void)mouseDown:(NSEvent *)theEvent
+{
+ [self passEventToDelegate:theEvent
+ withSelector:@selector(mouseDown:inXineView:)];
+
+ [super mouseDown:theEvent];
+}
- init_yuv_conversion();
+- (void)rightMouseDown:(NSEvent *)theEvent
+{
+ [self passEventToDelegate:theEvent
+ withSelector:@selector(rightMouseDown:inXineView:)];
+
+ [super rightMouseDown:theEvent];
+}
- y = COMPUTE_Y(r, g, b);
- u = COMPUTE_U(r, g, b);
- v = COMPUTE_V(r, g, b);
+- (void)otherMouseDown:(NSEvent *)theEvent
+{
+ [self passEventToDelegate:theEvent
+ withSelector:@selector(otherMouseDown:inXineView:)];
+
+ [super otherMouseDown:theEvent];
+}
- yuv = y << 24 | u << 16 | y << 8 | v;
+- (BOOL)acceptsFirstResponder
+{
+ return YES;
+}
- return yuv;
+- (BOOL)mouseDownCanMoveWindow
+{
+ return YES;
}
+@end
diff --git a/src/video_out/macosx/XineVideoWindow.m b/src/video_out/macosx/XineVideoWindow.m
index b61a5b418..0dd2caa28 100644
--- a/src/video_out/macosx/XineVideoWindow.m
+++ b/src/video_out/macosx/XineVideoWindow.m
@@ -108,7 +108,7 @@
}
-- (XineOpenGLView *) xineView
+- (id) xineView
{
return xineView;
}
diff --git a/src/video_out/video_out_macosx.m b/src/video_out/video_out_macosx.m
index 1a8fb821d..845bd9b94 100644
--- a/src/video_out/video_out_macosx.m
+++ b/src/video_out/video_out_macosx.m
@@ -170,7 +170,9 @@ static void macosx_update_frame_format(vo_driver_t *vo_driver, vo_frame_t *vo_fr
}
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[this->view setVideoSize:video_size];
+ [pool release];
if((format == XINE_IMGFMT_YV12
&& (frame->vo_frame.base[0] == NULL
@@ -189,29 +191,35 @@ static void macosx_update_frame_format(vo_driver_t *vo_driver, vo_frame_t *vo_fr
static void macosx_display_frame(vo_driver_t *vo_driver, vo_frame_t *vo_frame) {
macosx_driver_t *driver = (macosx_driver_t *)vo_driver;
macosx_frame_t *frame = (macosx_frame_t *)vo_frame;
- char *texture_buffer = [driver->view getTextureBuffer];
-
- switch (vo_frame->format) {
- case XINE_IMGFMT_YV12:
- yv12_to_yuy2 (vo_frame->base[0], vo_frame->pitches[0],
- vo_frame->base[1], vo_frame->pitches[1],
- vo_frame->base[2], vo_frame->pitches[2],
- texture_buffer, vo_frame->width * 2,
- vo_frame->width, vo_frame->height, 0);
+ char *texture_buffer;
- [driver->view displayTexture];
- break;
- case XINE_IMGFMT_YUY2:
- xine_fast_memcpy (texture_buffer, vo_frame->base[0],
- vo_frame->pitches[0] * vo_frame->height * 2);
- [driver->view displayTexture];
- break;
- default:
- /* unsupported frame format, do nothing. */
- break;
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+
+ if ((texture_buffer = [driver->view textureBuffer]) != NULL) {
+ switch (vo_frame->format) {
+ case XINE_IMGFMT_YV12:
+ yv12_to_yuy2 (vo_frame->base[0], vo_frame->pitches[0],
+ vo_frame->base[1], vo_frame->pitches[1],
+ vo_frame->base[2], vo_frame->pitches[2],
+ (unsigned char *)texture_buffer,
+ vo_frame->width * 2,
+ vo_frame->width, vo_frame->height, 0);
+
+ [driver->view updateTexture];
+ break;
+ case XINE_IMGFMT_YUY2:
+ xine_fast_memcpy (texture_buffer, vo_frame->base[0],
+ vo_frame->pitches[0] * vo_frame->height * 2);
+ [driver->view updateTexture];
+ break;
+ default:
+ /* unsupported frame format, do nothing. */
+ break;
+ }
}
frame->vo_frame.free(&frame->vo_frame);
+ [pool release];
}
static void macosx_overlay_blend (vo_driver_t *this_gen, vo_frame_t *frame_gen,
@@ -228,11 +236,11 @@ static void macosx_overlay_blend (vo_driver_t *this_gen, vo_frame_t *frame_gen,
if (frame->format == XINE_IMGFMT_YV12)
/* TODO: It may be possible to accelerate the blending via Quartz
* Extreme ... */
- blend_yuv(frame->vo_frame.base, overlay,
+ _x_blend_yuv(frame->vo_frame.base, overlay,
frame->width, frame->height, frame->vo_frame.pitches,
&this->alphablend_extra_data);
else
- blend_yuy2(frame->vo_frame.base[0], overlay,
+ _x_blend_yuy2(frame->vo_frame.base[0], overlay,
frame->width, frame->height, frame->vo_frame.pitches[0],
&this->alphablend_extra_data);
}
@@ -299,6 +307,7 @@ static void macosx_dispose(vo_driver_t *vo_driver) {
macosx_driver_t *this = (macosx_driver_t *) vo_driver;
_x_alphablend_free(&this->alphablend_extra_data);
+ [this->view releaseInMainThread];
free(this);
}
@@ -318,7 +327,7 @@ static vo_driver_t *open_plugin(video_driver_class_t *driver_class, const void *
driver->config = class->config;
driver->xine = class->xine;
driver->ratio = XINE_VO_ASPECT_AUTO;
- driver->view = view;
+ driver->view = [view retain];
driver->vo_driver.get_capabilities = macosx_get_capabilities;
driver->vo_driver.alloc_frame = macosx_alloc_frame;
@@ -377,7 +386,7 @@ static const vo_info_t vo_info_macosx = {
XINE_VISUAL_TYPE_MACOSX /* Visual type */
};
-plugin_info_t xine_plugin_info[] = {
+plugin_info_t xine_plugin_info[] EXPORTED = {
/* type, API, "name", version, special_info, init_function */
/* work around the problem that dlclose() is not allowed to
* get rid of an image module which contains objective C code and simply