summaryrefslogtreecommitdiff
path: root/src/video_out/macosx
diff options
context:
space:
mode:
authorAndre Pang <athp@users.sourceforge.net>2004-10-22 06:29:45 +0000
committerAndre Pang <athp@users.sourceforge.net>2004-10-22 06:29:45 +0000
commitc82596c62aa4b61795106ec56e29925829c54a4c (patch)
tree8e36a8e581c0c744bb978b9c31bc6dd64fccd63d /src/video_out/macosx
parent9c6378122e9bffab0f2d1b4daf71f5ba2889e15e (diff)
downloadxine-lib-c82596c62aa4b61795106ec56e29925829c54a4c.tar.gz
xine-lib-c82596c62aa4b61795106ec56e29925829c54a4c.tar.bz2
Split Mac OS X video_window.[mh] files into XineOpenGLView.h and XineOpenGLView.m: we still keep a video_window.h file for backward compatibility
CVS patchset: 7064 CVS date: 2004/10/22 06:29:45
Diffstat (limited to 'src/video_out/macosx')
-rw-r--r--src/video_out/macosx/Makefile.am12
-rw-r--r--src/video_out/macosx/XineOpenGLView.h99
-rw-r--r--src/video_out/macosx/XineOpenGLView.m (renamed from src/video_out/macosx/video_window.m)611
-rw-r--r--src/video_out/macosx/XineVideoWindow.h58
-rw-r--r--src/video_out/macosx/XineVideoWindow.m186
-rw-r--r--src/video_out/macosx/video_window.h105
6 files changed, 614 insertions, 457 deletions
diff --git a/src/video_out/macosx/Makefile.am b/src/video_out/macosx/Makefile.am
index 2a3bfa308..028c52eeb 100644
--- a/src/video_out/macosx/Makefile.am
+++ b/src/video_out/macosx/Makefile.am
@@ -1,12 +1,17 @@
include $(top_srcdir)/misc/Makefile.common
-EXTRA_DIST = video_window.m video_window.h
+EXTRA_DIST = \
+ video_window.h \
+ XineOpenGLView.m \
+ XineOpenGLView.h \
+ XineVideoWindow.m \
+ XineVideoWindow.h
if HAVE_MACOSX_VIDEO
lib_LTLIBRARIES = libxine_macosx_video.la
-libxine_macosx_video_la_SOURCES = video_window.m
+libxine_macosx_video_la_SOURCES = XineOpenGLView.m XineVideoWindow.m
# The "-Wl,-framework -Wl,..." is needed for libtool versions before
# 1.5.x (1.257): the default version that ships with Mac OS X is 1.5 (1.1220)
libxine_macosx_video_la_LDFLAGS = -version-info \
@@ -15,6 +20,7 @@ libxine_macosx_video_la_LDFLAGS = -version-info \
-Wl,-framework -Wl,OpenGL -framework OpenGL
libxine_macosx_video_la_OBJCFLAGS = $(OBJCFLAGS)
-include_HEADERS = video_window.h
+include_HEADERS = video_window.h XineOpenGLView.h XineVideoWindow.h
endif
+
diff --git a/src/video_out/macosx/XineOpenGLView.h b/src/video_out/macosx/XineOpenGLView.h
new file mode 100644
index 000000000..9e53a6c69
--- /dev/null
+++ b/src/video_out/macosx/XineOpenGLView.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2004 the xine project
+ *
+ * This file is part of xine, a free video player.
+ *
+ * xine is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * xine is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ */
+
+#ifndef __HAVE_XINE_OPENGL_VIEW_H__
+#define __HAVE_XINE_OPENGL_VIEW_H__
+
+#import <Cocoa/Cocoa.h>
+
+#import "XineVideoWindow.h"
+
+@protocol XineOpenGLViewDelegate;
+
+extern NSString *XineViewDidResizeNotification;
+
+@interface XineOpenGLView : NSOpenGLView
+{
+ 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;
+}
+
+- (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) setVideoSize:(NSSize)size;
+- (void) setViewSizeInMainThread:(NSSize)size;
+// TODO: replace set...Size below with setSize:(double)videoSizeMultiplier
+- (void) setNormalSize;
+- (void) setHalfSize;
+- (void) setDoubleSize;
+- (NSSize) videoSize;
+- (void) setKeepsVideoAspectRatio:(BOOL)flag;
+- (BOOL) keepsVideoAspectRatio;
+- (void) setResizeViewOnVideoSizeChange:(BOOL)flag;
+- (BOOL) resizeViewOnVideoSizeChange;
+- (void) setCurrentCursor:(NSCursor *)cursor;
+- (NSCursor *) currentCursor;
+- (void) resetCursorRectsInMainThread;
+- (void) setXineController:(id)controller;
+- (id) xineController;
+
+// Delegate Methods
+- (id) delegate;
+- (void) setDelegate:(id)aDelegate;
+
+@end
+
+/* XineOpenGLView delegate methods */
+
+@interface NSObject (XineOpenGLViewDelegate)
+
+- (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;
+
+@end
+
+#endif /* __HAVE_XINE_OPENGL_VIEW_H__ */
diff --git a/src/video_out/macosx/video_window.m b/src/video_out/macosx/XineOpenGLView.m
index 4d9f84ebe..d8155dd55 100644
--- a/src/video_out/macosx/video_window.m
+++ b/src/video_out/macosx/XineOpenGLView.m
@@ -17,10 +17,11 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * Written by Daniel Mack <xine@zonque.org>
- *
- * Most parts of this code were taken from VLC, http://www.videolan.org
- * Thanks for the good research!
+ */
+
+
+/*
+#define LOG
*/
#import <Cocoa/Cocoa.h>
@@ -28,16 +29,13 @@
#import <OpenGL/gl.h>
#import <OpenGL/glext.h>
-#import "video_window.h"
+#import "XineOpenGLView.h"
+
NSString *XineViewDidResizeNotification = @"XineViewDidResizeNotification";
-#define DEFAULT_VIDEO_WINDOW_SIZE (NSMakeSize(320, 200))
-/*
-#define LOG
-*/
-#undef LOG_MOUSE
+/* XineOpenGLView delegate methods */
@protocol XineOpenGLViewDelegate
@@ -50,128 +48,6 @@ NSString *XineViewDidResizeNotification = @"XineViewDidResizeNotification";
@end
-@implementation XineVideoWindow
-
-- (void) setContentSize: (NSSize) size {
-#ifdef LOG
- NSLog(@"setContent called with new size w:%d h:%d", size.width, size.height);
-#endif
- [xineView setViewSizeInMainThread:size];
-
- [super setContentSize: size];
-}
-
-- (id) init
-{
- return [self initWithContentSize:DEFAULT_VIDEO_WINDOW_SIZE];
-}
-
-- (id) initWithContentSize:(NSSize)size
-{
- NSScreen *screen = [NSScreen mainScreen];
- NSSize screen_size = [screen frame].size;
-
- /* make a centered window */
- NSRect frame;
- frame.size = size;
- frame.origin.x = (screen_size.width - frame.size.width) / 2;
- frame.origin.y = (screen_size.height - frame.size.height) / 2;
-
- unsigned int style_mask = NSTitledWindowMask | NSMiniaturizableWindowMask |
- NSClosableWindowMask | NSResizableWindowMask;
-
- return ([self initWithContentRect:frame styleMask:style_mask
- backing:NSBackingStoreBuffered defer:NO
- screen:screen]);
-}
-
-- (id) initWithContentRect: (NSRect)rect
- styleMask:(unsigned int)styleMask
- backing:(NSBackingStoreType)bufferingType
- defer:(BOOL)flag
- screen:(NSScreen *)aScreen {
- self = [super initWithContentRect: rect
- styleMask: styleMask
- backing: bufferingType
- defer: flag
- screen: aScreen];
-
-#ifdef LOG
- NSLog(@"initWithContentRect called with rect x:%d y:%d w:%d h:%d",
- rect.origin.x, rect.origin.y, rect.size.width, rect.size.height);
-#endif
-
- xineView = [[XineOpenGLView alloc] initWithFrame:rect];
- [xineView setResizeViewOnVideoSizeChange:YES];
-
- /* receive notifications about window resizing from the xine view */
- NSNotificationCenter *noticeBoard = [NSNotificationCenter defaultCenter];
- [noticeBoard addObserver:self
- selector:@selector(xineViewDidResize:)
- name:XineViewDidResizeNotification
- object:xineView];
-
- [self setContentView: xineView];
- [self setTitle: @"xine video output"];
-
- return self;
-}
-
-- (void) dealloc
-{
- [xineView release];
- xineView = nil;
-
- [super dealloc];
-}
-
-
-- (XineOpenGLView *) xineView {
- return xineView;
-}
-
-- (NSRect)windowWillUseStandardFrame:(NSWindow *)sender
- defaultFrame:(NSRect)defaultFrame
-{
- NSSize screen_size, video_size;
- NSRect standard_frame;
-
- if ([xineView isFullScreen])
- return defaultFrame;
-
- screen_size = defaultFrame.size;
- video_size = [xineView videoSize];
-
- if (screen_size.width / screen_size.height >
- video_size.width / video_size.height) {
- standard_frame.size.width = video_size.width *
- (screen_size.height / video_size.height);
- standard_frame.size.height = screen_size.height;
- } else {
- standard_frame.size.width = screen_size.width;
- standard_frame.size.height = video_size.height *
- (screen_size.width / video_size.width);
- }
-
- standard_frame.origin.x =
- (screen_size.width - standard_frame.size.width) / 2;
- standard_frame.origin.y =
- (screen_size.height - standard_frame.size.height) / 2;
-
- return standard_frame;
-}
-
-/* Notifications */
-
-- (void) xineViewDidResize:(NSNotification *)note {
- NSRect frame = [self frame];
- frame.size = [[self contentView] frame].size;
-
- [self setFrame:[self frameRectForContentRect:frame] display:YES];
-}
-
-@end /* XineVideoWindow */
-
@implementation XineOpenGLView
@@ -195,7 +71,8 @@ NSString *XineViewDidResizeNotification = @"XineViewDidResizeNotification";
return resizeViewOnVideoSizeChange;
}
-- (BOOL)mouseDownCanMoveWindow {
+- (BOOL)mouseDownCanMoveWindow
+{
return YES;
}
@@ -203,17 +80,19 @@ NSString *XineViewDidResizeNotification = @"XineViewDidResizeNotification";
{
NSPoint point = [self convertPoint:[theEvent locationInWindow]
fromView:nil];
-
+
if (!NSMouseInRect(point, [self bounds], [self isFlipped])) return;
-
- if ([delegate respondsToSelector:selector]) {
+
+ if ([delegate respondsToSelector:selector])
+ {
[delegate performSelector:selector
withObject:theEvent
withObject:self];
return;
}
-
- if ([_xineController respondsToSelector:selector]) {
+
+ if ([_xineController respondsToSelector:selector])
+ {
[_xineController performSelector:selector
withObject:theEvent
withObject:self];
@@ -225,7 +104,7 @@ NSString *XineViewDidResizeNotification = @"XineViewDidResizeNotification";
{
[self passEventToDelegate:theEvent
withSelector:@selector(mouseMoved:inXineView:)];
-
+
[super mouseMoved:theEvent];
}
@@ -233,7 +112,7 @@ NSString *XineViewDidResizeNotification = @"XineViewDidResizeNotification";
{
[self passEventToDelegate:theEvent
withSelector:@selector(mouseDown:inXineView:)];
-
+
[super mouseDown:theEvent];
}
@@ -241,7 +120,7 @@ NSString *XineViewDidResizeNotification = @"XineViewDidResizeNotification";
{
[self passEventToDelegate:theEvent
withSelector:@selector(rightMouseDown:inXineView:)];
-
+
[super rightMouseDown:theEvent];
}
@@ -249,24 +128,26 @@ NSString *XineViewDidResizeNotification = @"XineViewDidResizeNotification";
{
[self passEventToDelegate:theEvent
withSelector:@selector(otherMouseDown:inXineView:)];
-
+
[super otherMouseDown:theEvent];
}
-- (NSSize)videoSize {
+- (NSSize)videoSize
+{
return NSMakeSize(video_width, video_height);
}
- (void) displayTexture {
- if ([self lockFocusIfCanDraw]) {
+ if ([self lockFocusIfCanDraw])
+ {
[self drawRect: [self bounds]];
[self reloadTexture];
[self unlockFocus];
}
}
-- (id) initWithFrame: (NSRect) frame {
-
+- (id) initWithFrame: (NSRect) frame
+{
NSOpenGLPixelFormatAttribute attribs[] = {
NSOpenGLPFAAccelerated,
NSOpenGLPFANoRecovery,
@@ -277,23 +158,24 @@ NSString *XineViewDidResizeNotification = @"XineViewDidResizeNotification";
NSOpenGLPFAWindow,
0
};
-
+
NSOpenGLPixelFormat * fmt = [[NSOpenGLPixelFormat alloc]
initWithAttributes: attribs];
-
- if (!fmt) {
- printf ("Cannot create NSOpenGLPixelFormat\n");
+
+ 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;
@@ -303,16 +185,16 @@ NSString *XineViewDidResizeNotification = @"XineViewDidResizeNotification";
mutex = [[NSLock alloc] init];
currentCursor = [NSCursor arrowCursor];
_xineController = nil;
-
+
[self initTextures];
-
+
/* Black background */
glClearColor (0.0, 0.0, 0.0, 0.0);
-
+
#ifdef LOG
NSLog(@"XineOpenGLView: initWithFrame called");
#endif
-
+
return self;
}
@@ -321,44 +203,51 @@ NSString *XineViewDidResizeNotification = @"XineViewDidResizeNotification";
#ifdef LOG
NSLog(@"XineOpenGLView: initWithCoder called");
#endif
-
+
self = [super initWithCoder:coder];
-
+
self = [self initWithFrame:[self frame]];
-
- if ([coder allowsKeyedCoding]) {
+
+ if ([coder allowsKeyedCoding])
+ {
keepsVideoAspectRatio = [coder decodeBoolForKey:@"keepsVideoAspectRatio"];
resizeViewOnVideoSizeChange = [coder decodeBoolForKey:
@"resizeViewOnVideoSizeChange"];
- } else {
+ }
+ else
+ {
/* Must decode values in the same order as encodeWithCoder: */
[coder decodeValueOfObjCType:@encode(BOOL) at:&keepsVideoAspectRatio];
[coder decodeValueOfObjCType:@encode(BOOL) at:&resizeViewOnVideoSizeChange];
}
-
+
return self;
}
- (void) encodeWithCoder:(NSCoder *)coder
{
[super encodeWithCoder:coder];
-
- if ([coder allowsKeyedCoding]) {
+
+ if ([coder allowsKeyedCoding])
+ {
[coder encodeBool:keepsVideoAspectRatio forKey:@"keepsVideoAspectRatio"];
[coder encodeBool:resizeViewOnVideoSizeChange
forKey:@"resizeViewOnVideoSizeChange"];
- } else {
+ }
+ else
+ {
[coder encodeValueOfObjCType:@encode(BOOL) at:&keepsVideoAspectRatio];
[coder encodeValueOfObjCType:@encode(BOOL) at:&resizeViewOnVideoSizeChange];
}
-
+
}
- (void) dealloc {
if (texture_buffer)
free (texture_buffer);
-
- if (fullScreenContext) {
+
+ if (fullScreenContext)
+ {
[NSOpenGLContext clearCurrentContext];
[mutex lock];
[fullScreenContext clearDrawable];
@@ -367,8 +256,9 @@ NSString *XineViewDidResizeNotification = @"XineViewDidResizeNotification";
if (currentContext == fullScreenContext) currentContext = nil;
fullScreenContext = nil;
}
-
- if (currentContext) {
+
+ if (currentContext)
+ {
[NSOpenGLContext clearCurrentContext];
[mutex lock];
[currentContext clearDrawable];
@@ -376,9 +266,9 @@ NSString *XineViewDidResizeNotification = @"XineViewDidResizeNotification";
[mutex unlock];
currentContext = nil;
}
-
+
[mutex dealloc];
-
+
// Enabling the [super dealloc] below (which should be correct behaviour)
// crashes -- not sure why ...
//
@@ -387,23 +277,26 @@ NSString *XineViewDidResizeNotification = @"XineViewDidResizeNotification";
// Maybe dealloc in main thread?
}
-- (void) reshape {
+- (void) reshape
+{
[mutex lock];
-
- if (!initDone) {
+
+ if (!initDone)
+ {
[mutex unlock];
return;
}
-
+
[currentContext makeCurrentContext];
-
+
NSRect bounds = [self bounds];
glViewport (0, 0, bounds.size.width, bounds.size.height);
-
+
[mutex unlock];
}
-- (void) setNormalSize {
+- (void) setNormalSize
+{
NSSize size;
if (isFullScreen)
@@ -411,11 +304,12 @@ NSString *XineViewDidResizeNotification = @"XineViewDidResizeNotification";
size.width = video_width;
size.height = video_height;
-
+
[self setViewSizeInMainThread:size];
}
-- (void) setHalfSize {
+- (void) setHalfSize
+{
NSSize size;
if (isFullScreen)
@@ -423,11 +317,12 @@ NSString *XineViewDidResizeNotification = @"XineViewDidResizeNotification";
size.width = video_width / 2;
size.height = video_height / 2;
-
+
[self setViewSizeInMainThread:size];
}
-- (void) setDoubleSize {
+- (void) setDoubleSize
+{
NSSize size;
if (isFullScreen)
@@ -435,140 +330,155 @@ NSString *XineViewDidResizeNotification = @"XineViewDidResizeNotification";
size.width = video_width * 2;
size.height = video_height * 2;
-
+
[self setViewSizeInMainThread:size];
}
-- (void) initTextures {
+- (void) initTextures
+{
[mutex lock];
-
+
[currentContext makeCurrentContext];
-
+
/* Free previous texture if any */
if (i_texture)
glDeleteTextures (1, &i_texture);
-
+
if (texture_buffer)
+ {
texture_buffer = realloc (texture_buffer, sizeof (char) *
video_width * video_height * 3);
+ }
else
+ {
texture_buffer = malloc (sizeof (char) *
video_width * video_height * 3);
-
+ }
+
/* Create textures */
glGenTextures (1, &i_texture);
-
+
glEnable (GL_TEXTURE_RECTANGLE_EXT);
glEnable (GL_UNPACK_CLIENT_STORAGE_APPLE);
-
+
glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
glPixelStorei (GL_UNPACK_ROW_LENGTH, video_width);
-
+
glBindTexture (GL_TEXTURE_RECTANGLE_EXT, i_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);
-
+ 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 */
+ our buffer */
glPixelStorei (GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE);
-
+
/* Linear interpolation */
glTexParameteri (GL_TEXTURE_RECTANGLE_EXT,
- GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_RECTANGLE_EXT,
- GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-
+ GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
/* I have no idea what this exactly does, but it seems to be
- necessary for scaling */
+ necessary for scaling */
glTexParameteri (GL_TEXTURE_RECTANGLE_EXT,
- GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri (GL_TEXTURE_RECTANGLE_EXT,
- GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-
+ 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);
-
+ video_width, video_height, 0,
+ GL_YCBCR_422_APPLE, GL_UNSIGNED_SHORT_8_8_APPLE,
+ texture_buffer);
+
initDone = YES;
[mutex unlock];
}
-- (void) reloadTexture {
- if (!initDone) {
+- (void) reloadTexture
+{
+ if (!initDone)
+ {
return;
}
[mutex lock];
-
+
[currentContext makeCurrentContext];
-
+
glBindTexture (GL_TEXTURE_RECTANGLE_EXT, i_texture);
glPixelStorei (GL_UNPACK_ROW_LENGTH, video_width);
-
- /* glTexSubImage2D is faster than glTexImage2D
- * http://developer.apple.com/samplecode/Sample_Code/Graphics_3D/TextureRange/MainOpenGLView.m.htm
- */
+
+ // 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);
-
+ video_width, video_height,
+ GL_YCBCR_422_APPLE, GL_UNSIGNED_SHORT_8_8_APPLE,
+ texture_buffer);
+
[mutex unlock];
}
-- (void) calcFullScreenAspect {
+- (void) calcFullScreenAspect
+{
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;
+ 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;
}
-
- printf ("MacOSX fullscreen mode: %dx%d => %dx%d @ %d,%d\n",
- video_width, video_height, w, h, x, y);
-
+
+ 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);
[mutex unlock];
}
-- (void) goFullScreen: (XineVideoWindowFullScreenMode) mode {
+- (void) goFullScreen: (XineVideoWindowFullScreenMode) mode
+{
[mutex lock];
/* Create the new pixel format */
- NSOpenGLPixelFormatAttribute attribs[] = {
+ NSOpenGLPixelFormatAttribute attribs[] =
+ {
NSOpenGLPFAAccelerated,
NSOpenGLPFANoRecovery,
NSOpenGLPFADoubleBuffer,
@@ -582,42 +492,49 @@ NSString *XineViewDidResizeNotification = @"XineViewDidResizeNotification";
};
NSOpenGLPixelFormat * fmt = [[NSOpenGLPixelFormat alloc]
- initWithAttributes: attribs];
- if (!fmt) {
- printf ("Cannot create NSOpenGLPixelFormat\n");
+ initWithAttributes: attribs];
+
+ if (!fmt)
+ {
+ NSLog (@"Cannot create NSOpenGLPixelFormat\n");
return;
}
-
+
/* Create the new OpenGL context */
fullScreenContext = [[NSOpenGLContext alloc]
initWithFormat: fmt shareContext: nil];
- if (!fullScreenContext) {
- printf ("Failed to create new NSOpenGLContext\n");
+
+ if (!fullScreenContext)
+ {
+ NSLog(@"Failed to create new NSOpenGLContext\n");
return;
}
currentContext = fullScreenContext;
-
+
/* Capture display, switch to fullscreen */
- if (CGCaptureAllDisplays() != CGDisplayNoErr) {
- printf ("CGCaptureAllDisplays() failed\n");
+ 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) exitFullScreen
+{
initDone = NO;
currentContext = [self openGLContext];
@@ -630,65 +547,67 @@ NSString *XineViewDidResizeNotification = @"XineViewDidResizeNotification";
[fullScreenContext release];
fullScreenContext = nil;
CGReleaseAllDisplays();
-
+
[self reshape];
[self initTextures];
-
+
/* Redraw the last picture */
[self setNeedsDisplay: YES];
-
+
isFullScreen = NO;
initDone = YES;
}
-- (void) drawQuad {
+- (void) drawQuad
+{
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);
+ /* 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 {
+- (void) drawRect: (NSRect) rect
+{
[currentContext makeCurrentContext];
- if (!initDone) {
+ if (!initDone)
return;
- }
-
+
[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 */
-
+
+ // 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);
-
+
/* Draw */
glBindTexture (GL_TEXTURE_RECTANGLE_EXT, i_texture);
[self drawQuad];
-
+
/* Wait for the job to be done */
[currentContext flushBuffer];
-
+
[mutex unlock];
}
-- (char *) getTextureBuffer {
+- (char *) getTextureBuffer
+{
return texture_buffer;
}
@@ -696,94 +615,97 @@ NSString *XineViewDidResizeNotification = @"XineViewDidResizeNotification";
{
video_width = size.width;
video_height = size.height;
-
+
if (resizeViewOnVideoSizeChange)
- [self setViewSizeInMainThread:size];
-
+ [self setViewSizeInMainThread:size];
+
#ifdef LOG
NSLog(@"setVideoSize called");
#endif
-
+
[self initTextures];
}
- (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 */
+ // 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];
-
+ waitUntilDone:NO];
+
#ifdef LOG
NSLog(@"setViewSizeInMainThread called");
#endif
-
+
[pool release];
}
- (void) setViewSize:(NSValue *)sizeWrapper
{
NSSize proposedSize, newSize, currentSize;
-
+
[sizeWrapper getValue:&proposedSize];
newSize = proposedSize;
-
+
currentSize = [self frame].size;
if (proposedSize.width == currentSize.width &&
- proposedSize.height == currentSize.height) {
+ proposedSize.height == currentSize.height)
+ {
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:)]) {
+ * 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:)])
+ {
NSSize oldSize = [self frame].size;
newSize = [_xineController 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:)]) {
+ * message to him; otherwise, just resize ourselves */
+ if ([delegate respondsToSelector:@selector(xineViewWillResize:toSize:)])
+ {
NSSize oldSize = [self frame].size;
newSize = [delegate xineViewWillResize:oldSize toSize:proposedSize];
}
-
+
[self setFrameSize:newSize];
[self setBoundsSize:newSize];
-
+
/* Post a notification that we resized and also notify our controller */
/* and delegate */
NSNotification *note =
[NSNotification notificationWithName:XineViewDidResizeNotification
object:self];
[[NSNotificationCenter defaultCenter] postNotification:note];
-
- if ([_xineController respondsToSelector:@selector(xineViewDidResize:)]) {
+
+ if ([_xineController respondsToSelector:@selector(xineViewDidResize:)])
[_xineController xineViewDidResize:note];
- }
-
- if ([delegate respondsToSelector:@selector(xineViewDidResize:)]) {
+
+ if ([delegate respondsToSelector:@selector(xineViewDidResize:)])
[delegate xineViewDidResize:note];
- }
-
+
if (isFullScreen)
[self calcFullScreenAspect];
-
+
[self initTextures];
}
-- (BOOL) isFullScreen {
+- (BOOL) isFullScreen
+{
return isFullScreen;
}
-- (id) delegate {
+- (id) delegate
+{
return delegate;
}
@@ -831,28 +753,3 @@ NSString *XineViewDidResizeNotification = @"XineViewDidResizeNotification";
}
@end /* XineOpenGLView */
-
-
-@implementation NSWindow (AspectRatioAdditions)
-
-- (void) setKeepsAspectRatio: (BOOL) flag {
- if (flag) {
- NSSize size = [self frame].size;
- [self setAspectRatio:size];
- }
- else {
- [self setResizeIncrements:NSMakeSize(1.0, 1.0)];
- }
-}
-
-/* XXX: This is 100% untested ... */
-- (BOOL) keepsAspectRatio {
- NSSize size = [self aspectRatio];
- if (size.width == 0 && size.height == 0)
- return false;
- else
- return true;
-}
-
-@end /* NSWindow (AspectRatioAdditions) */
-
diff --git a/src/video_out/macosx/XineVideoWindow.h b/src/video_out/macosx/XineVideoWindow.h
new file mode 100644
index 000000000..2ff617242
--- /dev/null
+++ b/src/video_out/macosx/XineVideoWindow.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2004 the xine project
+ *
+ * This file is part of xine, a free video player.
+ *
+ * xine is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * xine is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ */
+
+#ifndef __HAVE_XINE_VIDEO_WINDOW_H__
+#define __HAVE_XINE_VIDEO_WINDOW_H__
+
+
+#import <Cocoa/Cocoa.h>
+
+
+typedef enum
+{
+ XINE_FULLSCREEN_OVERSCAN,
+ XINE_FULLSCREEN_CROP
+} XineVideoWindowFullScreenMode;
+
+
+@interface XineVideoWindow : NSWindow
+{
+ int width, height;
+ id /* XineOpenGLView * */ xineView;
+}
+
+- (id) initWithContentSize:(NSSize)size;
+- (id /* XineOpenGLView * */) xineView;
+
+@end
+
+
+/* NSWindow aspect ratio convenience methods */
+
+@interface NSWindow (AspectRatioAdditions)
+
+- (void) setKeepsAspectRatio:(BOOL)flag;
+- (BOOL) keepsAspectRatio;
+
+@end
+
+
+#endif /* __HAVE_XINE_VIDEO_WINDOW_H__ */
diff --git a/src/video_out/macosx/XineVideoWindow.m b/src/video_out/macosx/XineVideoWindow.m
new file mode 100644
index 000000000..b61a5b418
--- /dev/null
+++ b/src/video_out/macosx/XineVideoWindow.m
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2004 the xine project
+ *
+ * This file is part of xine, a free video player.
+ *
+ * xine is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * xine is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Written by Daniel Mack <xine@zonque.org>
+ *
+ * Most parts of this code were taken from VLC, http://www.videolan.org
+ * Thanks for the good research!
+ */
+
+
+#import "XineOpenGLView.h"
+#import "XineVideoWindow.h"
+
+
+#define DEFAULT_VIDEO_WINDOW_SIZE (NSMakeSize(320, 200))
+
+@implementation XineVideoWindow
+
+- (void) setContentSize: (NSSize) size
+{
+#ifdef LOG
+ NSLog(@"setContent called with new size w:%d h:%d", size.width, size.height);
+#endif
+ [xineView setViewSizeInMainThread:size];
+
+ [super setContentSize: size];
+}
+
+- (id) init
+{
+ return [self initWithContentSize:DEFAULT_VIDEO_WINDOW_SIZE];
+}
+
+- (id) initWithContentSize:(NSSize)size
+{
+ NSScreen *screen = [NSScreen mainScreen];
+ NSSize screen_size = [screen frame].size;
+
+ /* make a centered window */
+ NSRect frame;
+ frame.size = size;
+ frame.origin.x = (screen_size.width - frame.size.width) / 2;
+ frame.origin.y = (screen_size.height - frame.size.height) / 2;
+
+ unsigned int style_mask = NSTitledWindowMask | NSMiniaturizableWindowMask |
+ NSClosableWindowMask | NSResizableWindowMask;
+
+ return ([self initWithContentRect:frame styleMask:style_mask
+ backing:NSBackingStoreBuffered defer:NO
+ screen:screen]);
+}
+
+- (id) initWithContentRect: (NSRect)rect
+ styleMask:(unsigned int)styleMask
+ backing:(NSBackingStoreType)bufferingType
+ defer:(BOOL)flag
+ screen:(NSScreen *)aScreen
+{
+ self = [super initWithContentRect: rect
+ styleMask: styleMask
+ backing: bufferingType
+ defer: flag
+ screen: aScreen];
+
+#ifdef LOG
+ NSLog(@"initWithContentRect called with rect x:%d y:%d w:%d h:%d",
+ rect.origin.x, rect.origin.y, rect.size.width, rect.size.height);
+#endif
+
+ xineView = [[XineOpenGLView alloc] initWithFrame:rect];
+ [xineView setResizeViewOnVideoSizeChange:YES];
+
+ /* receive notifications about window resizing from the xine view */
+ NSNotificationCenter *noticeBoard = [NSNotificationCenter defaultCenter];
+ [noticeBoard addObserver:self
+ selector:@selector(xineViewDidResize:)
+ name:XineViewDidResizeNotification
+ object:xineView];
+
+ [self setContentView: xineView];
+ [self setTitle: @"xine video output"];
+
+ return self;
+}
+
+- (void) dealloc
+{
+ [xineView release];
+ xineView = nil;
+
+ [super dealloc];
+}
+
+
+- (XineOpenGLView *) xineView
+{
+ return xineView;
+}
+
+- (NSRect)windowWillUseStandardFrame:(NSWindow *)sender
+ defaultFrame:(NSRect)defaultFrame
+{
+ NSSize screen_size, video_size;
+ NSRect standard_frame;
+
+ if ([xineView isFullScreen])
+ return defaultFrame;
+
+ screen_size = defaultFrame.size;
+ video_size = [xineView videoSize];
+
+ if (screen_size.width / screen_size.height >
+ video_size.width / video_size.height)
+ {
+ standard_frame.size.width = video_size.width *
+ (screen_size.height / video_size.height);
+ standard_frame.size.height = screen_size.height;
+ }
+ else
+ {
+ standard_frame.size.width = screen_size.width;
+ standard_frame.size.height = video_size.height *
+ (screen_size.width / video_size.width);
+ }
+
+ standard_frame.origin.x =
+ (screen_size.width - standard_frame.size.width) / 2;
+ standard_frame.origin.y =
+ (screen_size.height - standard_frame.size.height) / 2;
+
+ return standard_frame;
+}
+
+
+/* Notifications */
+
+- (void) xineViewDidResize:(NSNotification *)note
+{
+ NSRect frame = [self frame];
+ frame.size = [[self contentView] frame].size;
+
+ [self setFrame:[self frameRectForContentRect:frame] display:YES];
+}
+
+@end /* XineVideoWindow */
+
+
+@implementation NSWindow (AspectRatioAdditions)
+
+- (void) setKeepsAspectRatio: (BOOL) flag {
+ if (flag) {
+ NSSize size = [self frame].size;
+ [self setAspectRatio:size];
+ }
+ else {
+ [self setResizeIncrements:NSMakeSize(1.0, 1.0)];
+ }
+}
+
+/* XXX: This is 100% untested ... */
+- (BOOL) keepsAspectRatio {
+ NSSize size = [self aspectRatio];
+ if (size.width == 0 && size.height == 0)
+ return false;
+ else
+ return true;
+}
+
+@end /* NSWindow (AspectRatioAdditions) */
+
diff --git a/src/video_out/macosx/video_window.h b/src/video_out/macosx/video_window.h
index b1874672a..07405b8fe 100644
--- a/src/video_out/macosx/video_window.h
+++ b/src/video_out/macosx/video_window.h
@@ -17,106 +17,17 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
+ * Written by Daniel Mack <xine@zonque.org>
+ *
+ * Most parts of this code were taken from VLC, http://www.videolan.org
+ * Thanks for the good research!
*/
+
#ifndef HAVE_VIDEO_WINDOW_H
#define HAVE_VIDEO_WINDOW_H
-#import <Cocoa/Cocoa.h>
-
-@protocol XineOpenGLViewDelegate;
-
-typedef enum {
- XINE_FULLSCREEN_OVERSCAN,
- XINE_FULLSCREEN_CROP
-} XineVideoWindowFullScreenMode;
-
-@interface XineOpenGLView : NSOpenGLView {
- 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;
-}
-
-- (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) setVideoSize:(NSSize)size;
-- (void) setViewSizeInMainThread:(NSSize)size;
-/* TODO: replace set...Size below with setSize:(double)videoSizeMultiplier */
-- (void) setNormalSize;
-- (void) setHalfSize;
-- (void) setDoubleSize;
-- (NSSize) videoSize;
-- (void) setKeepsVideoAspectRatio:(BOOL)flag;
-- (BOOL) keepsVideoAspectRatio;
-- (void) setResizeViewOnVideoSizeChange:(BOOL)flag;
-- (BOOL) resizeViewOnVideoSizeChange;
-- (void) setCurrentCursor:(NSCursor *)cursor;
-- (NSCursor *) currentCursor;
-- (void) resetCursorRectsInMainThread;
-- (void) setXineController:(id)controller;
-- (id) xineController;
-
-/* Delegate methods */
-- (id) delegate;
-- (void) setDelegate:(id)aDelegate;
-
-@end
-
-
-@interface XineVideoWindow : NSWindow {
- int width, height;
- XineOpenGLView * xineView;
-}
-
-- (id) initWithContentSize:(NSSize)size;
-- (XineOpenGLView *) xineView;
-@end
-
-
-/* XineOpenGLView delegate methods */
-
-@interface NSObject (XineOpenGLViewDelegate)
-
-- (NSSize)xineViewWillResize:(NSSize)previousSize
- toSize:(NSSize)proposedFrameSize;
-- (void)xineViewDidResize:(NSNotification *)aNotification;
-
-@end
-
-
-/* XineOpenGLView notifications */
-
-extern NSString *XineViewDidResizeNotification;
-
-
-/* NSWindow aspect ratio convenience methods */
-
-@interface NSWindow (AspectRatioAdditions)
-
-- (void) setKeepsAspectRatio:(BOOL)flag;
-- (BOOL) keepsAspectRatio;
-
-@end
-
-
-#endif /* HAVE_VIDEO_WINDOW_H */
+#include "XineOpenGLView.h"
+#include "XineVideoWindow.h"
+#endif