summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMatt Messier <mmessier@grapetv.org>2007-04-03 21:32:31 -0700
committerMatt Messier <mmessier@grapetv.org>2007-04-03 21:32:31 -0700
commitf589d9c3ed2315a91057963583327f870e56f86b (patch)
treefe899649b940d301918759ccb5430c009db54ca2 /src
parent1563a2e0e9557b293ed71de35f5615637df2823d (diff)
downloadxine-lib-f589d9c3ed2315a91057963583327f870e56f86b.tar.gz
xine-lib-f589d9c3ed2315a91057963583327f870e56f86b.tar.bz2
Overhaul the Mac OS X video output plugin. XineOpenGLView is almost completely
rewritten, and various fixes and changes have been made to the supporting code. It's still not perfect, but it at least works now.
Diffstat (limited to 'src')
-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