Mercurial > mplayer.hg
changeset 35086:8848682f4035
Split out an objective-C common OS X layer, to be reused by -vo gl.
author | reimar |
---|---|
date | Thu, 13 Sep 2012 19:20:47 +0000 |
parents | 5a9728bbb51e |
children | 078a00af881c |
files | Makefile libvo/osx_objc_common.h libvo/osx_objc_common.m libvo/vo_corevideo.h libvo/vo_corevideo.m |
diffstat | 5 files changed, 705 insertions(+), 552 deletions(-) [+] |
line wrap: on
line diff
--- a/Makefile Thu Sep 13 19:15:37 2012 +0000 +++ b/Makefile Thu Sep 13 19:20:47 2012 +0000 @@ -503,7 +503,7 @@ SRCS_MPLAYER-$(BL) += libvo/vo_bl.c SRCS_MPLAYER-$(CACA) += libvo/vo_caca.c SRCS_MPLAYER-$(COREAUDIO) += libao2/ao_coreaudio.c -SRCS_MPLAYER-$(COREVIDEO) += libvo/vo_corevideo.m libvo/osx_common.c +SRCS_MPLAYER-$(COREVIDEO) += libvo/vo_corevideo.m libvo/osx_common.c libvo/osx_objc_common.m SRCS_MPLAYER-$(DART) += libao2/ao_dart.c SRCS_MPLAYER-$(DGA) += libvo/vo_dga.c SRCS_MPLAYER-$(DIRECT3D) += libvo/vo_direct3d.c libvo/w32_common.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libvo/osx_objc_common.h Thu Sep 13 19:20:47 2012 +0000 @@ -0,0 +1,89 @@ +/* + * CoreVideo video output driver + * + * Copyright (c) 2005 Nicolas Plourde <nicolasplourde@gmail.com> + * + * This file is part of MPlayer. + * + * MPlayer 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. + * + * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef MPLAYER_OSX_OBJC_COMMON_H +#define MPLAYER_OSX_OBJC_COMMON_H + +#import <Cocoa/Cocoa.h> + +@interface MPCommonOpenGLView : NSOpenGLView +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1060 +<NSWindowDelegate> +#endif +{ + //Cocoa + NSWindow *window; + + BOOL mouseHide; + + //menu command id + NSMenuItem *kHalfScreenCmd; + NSMenuItem *kNormalScreenCmd; + NSMenuItem *kDoubleScreenCmd; + NSMenuItem *kFullScreenCmd; + NSMenuItem *kKeepAspectCmd; + NSMenuItem *kAspectOrgCmd; + NSMenuItem *kAspectFullCmd; + NSMenuItem *kAspectWideCmd; + NSMenuItem *kPanScanCmd; + + //timestamps for disabling screensaver and mouse hiding + int lastMouseHide; + int lastScreensaverUpdate; +@public + float winSizeMult; +} + +- (BOOL) acceptsFirstResponder; +- (BOOL) becomeFirstResponder; +- (BOOL) resignFirstResponder; + +//window & rendering +- (void) preinit; +- (void) config:(uint32_t)width:(uint32_t)height:(uint32_t)flags; + +//vo control +- (void) fullscreen: (BOOL) animate; +- (void) ontop; +- (void) rootwin; + +//menu +- (void) initMenu; +- (void) menuAction:(id)sender; + +//event +- (void) keyDown: (NSEvent *) theEvent; +- (void) mouseMoved: (NSEvent *) theEvent; +- (void) mouseDown: (NSEvent *) theEvent; +- (void) mouseUp: (NSEvent *) theEvent; +- (void) rightMouseDown: (NSEvent *) theEvent; +- (void) rightMouseUp: (NSEvent *) theEvent; +- (void) otherMouseDown: (NSEvent *) theEvent; +- (void) otherMouseUp: (NSEvent *) theEvent; +- (void) scrollWheel: (NSEvent *) theEvent; +- (void) mouseEvent: (NSEvent *) theEvent; +- (void) check_events; + +- (void) update_screen_info; +@end + +#endif /* MPLAYER_OSX_OBJC_COMMON_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libvo/osx_objc_common.m Thu Sep 13 19:20:47 2012 +0000 @@ -0,0 +1,609 @@ +/* + * CoreVideo video output driver + * Copyright (c) 2005 Nicolas Plourde <nicolasplourde@gmail.com> + * + * This file is part of MPlayer. + * + * MPlayer 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. + * + * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#import "osx_objc_common.h" +#include <Carbon/Carbon.h> +#include <CoreServices/CoreServices.h> +//special workaround for Apple bug #6267445 +//(OSServices Power API disabled in OSServices.h for 64bit systems) +#ifndef __POWER__ +#include <CoreServices/../Frameworks/OSServices.framework/Headers/Power.h> +#endif + +//MPLAYER +#include "config.h" +#include "video_out.h" +#include "aspect.h" +#include "mp_msg.h" +#include "mp_fifo.h" + +#include "input/input.h" +#include "input/mouse.h" + +#include "osdep/keycodes.h" +#include "osx_common.h" + +static float winAlpha = 1; + +static BOOL isLeopardOrLater; + +static NSAutoreleasePool *autoreleasepool; +static MPCommonOpenGLView *oglv; + +int vo_osx_init(void) +{ + autoreleasepool = [[NSAutoreleasePool alloc] init]; + oglv = [[MPCommonOpenGLView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100) pixelFormat:[MPCommonOpenGLView defaultPixelFormat]]; + [oglv autorelease]; + [oglv display]; + [oglv preinit]; + return 1; +} + +void vo_osx_uninit(void) +{ + NSAutoreleasePool *finalPool; + oglv = nil; + [autoreleasepool release]; + finalPool = [[NSAutoreleasePool alloc] init]; + [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:nil inMode:NSDefaultRunLoopMode dequeue:YES]; + [finalPool release]; +} + +int vo_osx_config(uint32_t width, uint32_t height, uint32_t flags) +{ + [oglv config:width:height:flags]; + return 1; +} + +void vo_osx_ontop(void) +{ + vo_ontop = !vo_ontop; + [oglv ontop]; +} + +void vo_osx_fullscreen(void) +{ + vo_fs = !vo_fs; + [oglv fullscreen:YES]; +} + +int vo_osx_check_events(void) +{ + [oglv check_events]; + return 0; +} + +void vo_osx_update_xinerama_info(void) +{ + [oglv update_screen_info]; +} + +@implementation MPCommonOpenGLView +- (void) update_screen_info +{ + int screen_id = xinerama_screen; + NSArray *screen_array = [NSScreen screens]; + NSScreen *screen_handle; + NSRect screen_frame; + + if(screen_id >= (int)[screen_array count]) + { + mp_msg(MSGT_VO, MSGL_INFO, "[vo_corevideo] Device ID %d does not exist, falling back to main device\n", screen_id); + screen_id = -1; + } + if (screen_id < 0 && [self window]) + screen_handle = [[self window] screen]; + else + screen_handle = [screen_array objectAtIndex:(screen_id < 0 ? 0 : screen_id)]; + + screen_frame = [screen_handle frame]; + vo_screenwidth = screen_frame.size.width; + vo_screenheight = screen_frame.size.height; + xinerama_x = screen_frame.origin.x; + xinerama_y = screen_frame.origin.y; + aspect_save_screenres(vo_screenwidth, vo_screenheight); +} + +- (void) preinit +{ + NSOpenGLContext *glContext; + GLint swapInterval = 1; + + NSApplicationLoad(); + NSApp = [NSApplication sharedApplication]; + isLeopardOrLater = floor(NSAppKitVersionNumber) > 824; + + osx_foreground_hack(); + + // Install an event handler so the Quit menu entry works + // The proper way using NSApp setDelegate: and + // applicationShouldTerminate: does not work, + // probably NSApplication never installs its handler. + [[NSAppleEventManager sharedAppleEventManager] + setEventHandler:self + andSelector:@selector(handleQuitEvent:withReplyEvent:) + forEventClass:kCoreEventClass + andEventID:kAEQuitApplication]; + + //init menu + [self initMenu]; + + //create window + window = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 100, 100) + styleMask:NSTitledWindowMask|NSTexturedBackgroundWindowMask|NSClosableWindowMask|NSMiniaturizableWindowMask|NSResizableWindowMask + backing:NSBackingStoreBuffered defer:NO]; + + [window autorelease]; + [window setDelegate:self]; + [window setContentView:self]; + [window setInitialFirstResponder:self]; + [window setAcceptsMouseMovedEvents:YES]; + [window setTitle:@"MPlayer - The Movie Player"]; + + winSizeMult = 1; + + //create OpenGL Context + glContext = [[NSOpenGLContext alloc] initWithFormat:[NSOpenGLView defaultPixelFormat] shareContext:nil]; + + [self setOpenGLContext:glContext]; + [glContext setValues:&swapInterval forParameter:NSOpenGLCPSwapInterval]; + [glContext setView:self]; + [glContext makeCurrentContext]; + [glContext release]; +} + +- (void) dealloc +{ + [self setOpenGLContext:nil]; + [super dealloc]; +} + +- (void) config:(uint32_t)width:(uint32_t)height:(uint32_t)flags +{ + config_movie_aspect((float)width/height); + + vo_dwidth = width *= self->winSizeMult; + vo_dheight = height *= self->winSizeMult; + + //config window + [window setContentSize:NSMakeSize(vo_dwidth, vo_dheight)]; + + // Do not use visibleFrame - taking the menu bar and dock into account + // would be nicer in principle, but currently only results in the window + // being placed strangely off-center since vo_dx/vo_dy calculation is + // not aware of it. + // Also flip vo_dy since the screen origin is in the bottom left on OSX. + [self update_screen_info]; + [window setFrameTopLeftPoint:NSMakePoint( + vo_dx, + 2*xinerama_y + vo_screenheight - vo_dy)]; + + vo_fs = flags & VOFLAG_FULLSCREEN; + + [self rootwin]; + + if(vo_fs) + [self fullscreen: NO]; + + [self ontop]; + + if (!(flags & VOFLAG_HIDDEN)) + //show window + [window makeKeyAndOrderFront:self]; +} + +/* + Init Menu +*/ +- (void)initMenu +{ + NSMenu *mainMenu = [[NSMenu alloc] init]; + NSMenu *menu, *aspectMenu; + NSMenuItem *menuItem; + + menu = [[NSMenu alloc] init]; + menuItem = [[NSMenuItem alloc] init]; + [menuItem setSubmenu:menu]; + [mainMenu addItem:menuItem]; + // Note: setAppleMenu seems to be unnecessary from 10.6 on, + // but is needed for all earlier versions or the menu is + // messed up. + // Round-about way with performSelector used to avoid compiler + // warnings. + [NSApp performSelector:@selector(setAppleMenu:) withObject:menu]; + +//Create Movie Menu + menu = [[NSMenu alloc] initWithTitle:@"Movie"]; + menuItem = [[NSMenuItem alloc] initWithTitle:@"Half Size" action:@selector(menuAction:) keyEquivalent:@"0"]; [menu addItem:menuItem]; + kHalfScreenCmd = menuItem; + menuItem = [[NSMenuItem alloc] initWithTitle:@"Normal Size" action:@selector(menuAction:) keyEquivalent:@"1"]; [menu addItem:menuItem]; + kNormalScreenCmd = menuItem; + menuItem = [[NSMenuItem alloc] initWithTitle:@"Double Size" action:@selector(menuAction:) keyEquivalent:@"2"]; [menu addItem:menuItem]; + kDoubleScreenCmd = menuItem; + menuItem = [[NSMenuItem alloc] initWithTitle:@"Full Size" action:@selector(menuAction:) keyEquivalent:@"f"]; [menu addItem:menuItem]; + kFullScreenCmd = menuItem; + menuItem = [NSMenuItem separatorItem]; [menu addItem:menuItem]; + + aspectMenu = [[NSMenu alloc] initWithTitle:@"Aspect Ratio"]; + menuItem = [[NSMenuItem alloc] initWithTitle:@"Keep" action:@selector(menuAction:) keyEquivalent:@""]; [aspectMenu addItem:menuItem]; + if(vo_keepaspect) [menuItem setState:NSOnState]; + kKeepAspectCmd = menuItem; + menuItem = [[NSMenuItem alloc] initWithTitle:@"Pan-Scan" action:@selector(menuAction:) keyEquivalent:@""]; [aspectMenu addItem:menuItem]; + if(vo_panscan) [menuItem setState:NSOnState]; + kPanScanCmd = menuItem; + menuItem = [NSMenuItem separatorItem]; [aspectMenu addItem:menuItem]; + menuItem = [[NSMenuItem alloc] initWithTitle:@"Original" action:@selector(menuAction:) keyEquivalent:@""]; [aspectMenu addItem:menuItem]; + kAspectOrgCmd = menuItem; + menuItem = [[NSMenuItem alloc] initWithTitle:@"4:3" action:@selector(menuAction:) keyEquivalent:@""]; [aspectMenu addItem:menuItem]; + kAspectFullCmd = menuItem; + menuItem = [[NSMenuItem alloc] initWithTitle:@"16:9" action:@selector(menuAction:) keyEquivalent:@""]; [aspectMenu addItem:menuItem]; + kAspectWideCmd = menuItem; + menuItem = [[NSMenuItem alloc] initWithTitle:@"Aspect Ratio" action:nil keyEquivalent:@""]; + [menuItem setSubmenu:aspectMenu]; + [menu addItem:menuItem]; + [aspectMenu release]; + + //Add to menubar + menuItem = [[NSMenuItem alloc] initWithTitle:@"Movie" action:nil keyEquivalent:@""]; + [menuItem setSubmenu:menu]; + [mainMenu addItem:menuItem]; + +//Create Window Menu + menu = [[NSMenu alloc] initWithTitle:@"Window"]; + + menuItem = [[NSMenuItem alloc] initWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"]; [menu addItem:menuItem]; + menuItem = [[NSMenuItem alloc] initWithTitle:@"Zoom" action:@selector(performZoom:) keyEquivalent:@""]; [menu addItem:menuItem]; + + //Add to menubar + menuItem = [[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""]; + [menuItem setSubmenu:menu]; + [mainMenu addItem:menuItem]; + [NSApp setWindowsMenu:menu]; + [NSApp setMainMenu:mainMenu]; + + [menu release]; + [menuItem release]; +} + +- (void)set_winSizeMult:(float)mult +{ + NSRect frame; + int d_width, d_height; + aspect(&d_width, &d_height, A_NOZOOM); + + if (vo_fs) { + vo_fs = !vo_fs; + [self fullscreen:NO]; + } + + winSizeMult = mult; + frame.size.width = d_width * mult; + frame.size.height = d_height * mult; + [window setContentSize: frame.size]; + [self reshape]; +} + +/* + Menu Action + */ +- (void)menuAction:(id)sender +{ + if(sender == kHalfScreenCmd) + [self set_winSizeMult: 0.5]; + if(sender == kNormalScreenCmd) + [self set_winSizeMult: 1]; + if(sender == kDoubleScreenCmd) + [self set_winSizeMult: 2]; + if(sender == kFullScreenCmd) + { + vo_fs = !vo_fs; + [self fullscreen:NO]; + } + + if(sender == kKeepAspectCmd) + { + vo_keepaspect = !vo_keepaspect; + if(vo_keepaspect) + [kKeepAspectCmd setState:NSOnState]; + else + [kKeepAspectCmd setState:NSOffState]; + + [self reshape]; + } + + if(sender == kPanScanCmd) + { + vo_panscan = !vo_panscan; + if(vo_panscan) + [kPanScanCmd setState:NSOnState]; + else + [kPanScanCmd setState:NSOffState]; + + panscan_calc(); + } + + if(sender == kAspectOrgCmd) + change_movie_aspect(-1); + + if(sender == kAspectFullCmd) + change_movie_aspect(4.0f/3.0f); + + if(sender == kAspectWideCmd) + change_movie_aspect(16.0f/9.0f); +} + +/* + Toggle Fullscreen +*/ +- (void) fullscreen: (BOOL) animate +{ + static NSRect old_frame; + static NSRect old_view_frame; + + panscan_calc(); + + //go fullscreen + if(vo_fs) + { + if(!vo_rootwin) + { + SetSystemUIMode( kUIModeAllHidden, kUIOptionAutoShowMenuBar); + CGDisplayHideCursor(kCGDirectMainDisplay); + mouseHide = YES; + } + + old_frame = [window frame]; //save main window size & position + [self update_screen_info]; + + [window setFrame:NSMakeRect(xinerama_x, xinerama_y, vo_screenwidth, vo_screenheight) display:YES animate:animate]; //zoom-in window with nice useless sfx + old_view_frame = [self bounds]; + + [self setFrame:NSMakeRect(0, 0, vo_screenwidth, vo_screenheight)]; + [self setNeedsDisplay:YES]; + [window setHasShadow:NO]; + } + else + { + SetSystemUIMode( kUIModeNormal, 0); + + CGDisplayShowCursor(kCGDirectMainDisplay); + mouseHide = NO; + + //revert window to previous setting + [self setFrame:old_view_frame]; + [self setNeedsDisplay:YES]; + [window setHasShadow:YES]; + [window setFrame:old_frame display:YES animate:animate];//zoom-out window with nice useless sfx + } +} + +/* + Toggle ontop +*/ +- (void) ontop +{ + if(vo_ontop) + { + [window setLevel:NSScreenSaverWindowLevel]; + } + else + { + [window setLevel:NSNormalWindowLevel]; + } +} + +/* + Toggle rootwin + */ +- (void) rootwin +{ + if(vo_rootwin) + { + [window setLevel:CGWindowLevelForKey(kCGDesktopWindowLevelKey)]; + [window orderBack:self]; + } + else + { + [window setLevel:NSNormalWindowLevel]; + } +} + +/* + Check event for new event +*/ +- (void) check_events +{ + NSEvent *event; + int curTime = TickCount()/60; + + //automatically hide mouse cursor (and future on-screen control?) + if(vo_fs && !mouseHide && !vo_rootwin) + { + if(curTime - lastMouseHide >= 5 || lastMouseHide == 0) + { + CGDisplayHideCursor(kCGDirectMainDisplay); + mouseHide = TRUE; + lastMouseHide = curTime; + } + } + + //update activity every 30 seconds to prevent + //screensaver from starting up. + if(curTime - lastScreensaverUpdate >= 30 || lastScreensaverUpdate == 0) + { + UpdateSystemActivity(UsrActivity); + lastScreensaverUpdate = curTime; + } + + event = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:nil inMode:NSEventTrackingRunLoopMode dequeue:YES]; + if (event == nil) + return; + [NSApp sendEvent:event]; + // Without SDL's bootstrap code (include SDL.h in mplayer.c), + // on Leopard, we have trouble to get the play window automatically focused + // when the app is actived. The Following code fix this problem. +#ifndef CONFIG_SDL + if (isLeopardOrLater && [event type] == NSAppKitDefined + && [event subtype] == NSApplicationActivatedEventType) { + [window makeMainWindow]; + [window makeKeyAndOrderFront:self]; + } +#endif +} + +/* + From NSView, respond to key equivalents. +*/ +- (BOOL)performKeyEquivalent:(NSEvent *)theEvent +{ + switch([theEvent keyCode]) + { + case 0x21: [window setAlphaValue: winAlpha-=0.05]; return YES; + case 0x1e: [window setAlphaValue: winAlpha+=0.05]; return YES; + } + return NO; +} + +/* + Process key event +*/ +- (void) keyDown: (NSEvent *) theEvent +{ + int key = convert_key([theEvent keyCode], *[[theEvent characters] UTF8String]); + if (key != -1) + mplayer_put_key(key); +} + +/* + Process mouse button event +*/ +- (void) mouseMoved: (NSEvent *) theEvent +{ + if(vo_fs && !vo_rootwin) + { + CGDisplayShowCursor(kCGDirectMainDisplay); + mouseHide = NO; + } + if (enable_mouse_movements && !vo_rootwin) { + NSPoint p =[self convertPoint:[theEvent locationInWindow] fromView:nil]; + if ([self mouse:p inRect:[self frame]]) { + vo_mouse_movement(p.x, [self frame].size.height - p.y); + } + } +} + +- (void) mouseDown: (NSEvent *) theEvent +{ + [self mouseEvent: theEvent]; +} + +- (void) mouseUp: (NSEvent *) theEvent +{ + [self mouseEvent: theEvent]; +} + +- (void) rightMouseDown: (NSEvent *) theEvent +{ + [self mouseEvent: theEvent]; +} + +- (void) rightMouseUp: (NSEvent *) theEvent +{ + [self mouseEvent: theEvent]; +} + +- (void) otherMouseDown: (NSEvent *) theEvent +{ + [self mouseEvent: theEvent]; +} + +- (void) otherMouseUp: (NSEvent *) theEvent +{ + [self mouseEvent: theEvent]; +} + +- (void) scrollWheel: (NSEvent *) theEvent +{ + if([theEvent deltaY] > 0) + mplayer_put_key(MOUSE_BTN3); + else + mplayer_put_key(MOUSE_BTN4); +} + +- (void) mouseEvent: (NSEvent *) theEvent +{ + if ( [theEvent buttonNumber] >= 0 && [theEvent buttonNumber] <= 9 ) + { + int buttonNumber = [theEvent buttonNumber]; + // Fix to mplayer defined button order: left, middle, right + if (buttonNumber == 1) + buttonNumber = 2; + else if (buttonNumber == 2) + buttonNumber = 1; + switch([theEvent type]) + { + case NSLeftMouseDown: + case NSRightMouseDown: + case NSOtherMouseDown: + mplayer_put_key((MOUSE_BTN0 + buttonNumber) | MP_KEY_DOWN); + break; + case NSLeftMouseUp: + case NSRightMouseUp: + case NSOtherMouseUp: + mplayer_put_key(MOUSE_BTN0 + buttonNumber); + break; + } + } +} + +/* + NSResponder +*/ +- (BOOL) acceptsFirstResponder +{ + return YES; +} + +- (BOOL) becomeFirstResponder +{ + return YES; +} + +- (BOOL) resignFirstResponder +{ + return YES; +} + +- (BOOL)windowShouldClose:(id)sender +{ + mplayer_put_key(KEY_CLOSE_WIN); + // We have to wait for MPlayer to handle this, + // otherwise we are in trouble if the + // KEY_CLOSE_WIN handler is disabled + return NO; +} + +- (void)handleQuitEvent:(NSAppleEventDescriptor*)e withReplyEvent:(NSAppleEventDescriptor*)r +{ + mplayer_put_key(KEY_CLOSE_WIN); +} +@end
--- a/libvo/vo_corevideo.h Thu Sep 13 19:15:37 2012 +0000 +++ b/libvo/vo_corevideo.h Thu Sep 13 19:20:47 2012 +0000 @@ -26,6 +26,7 @@ #import <Cocoa/Cocoa.h> #import <QuartzCore/QuartzCore.h> #import <Carbon/Carbon.h> +#import "osx_objc_common.h" // MPlayer OS X VO Protocol @protocol MPlayerOSXVOProto @@ -39,14 +40,8 @@ - (void) ontop; @end -@interface MPlayerOpenGLView : NSOpenGLView -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1060 -<NSWindowDelegate> -#endif +@interface MPlayerOpenGLView : MPCommonOpenGLView { - //Cocoa - NSWindow *window; - //CoreVideo CVPixelBufferRef frameBuffers[2]; CVOpenGLTextureCacheRef textureCache; @@ -57,31 +52,8 @@ GLfloat lowerRight[2]; GLfloat upperRight[2]; GLfloat upperLeft[2]; - - BOOL mouseHide; - - //menu command id - NSMenuItem *kHalfScreenCmd; - NSMenuItem *kNormalScreenCmd; - NSMenuItem *kDoubleScreenCmd; - NSMenuItem *kFullScreenCmd; - NSMenuItem *kKeepAspectCmd; - NSMenuItem *kAspectOrgCmd; - NSMenuItem *kAspectFullCmd; - NSMenuItem *kAspectWideCmd; - NSMenuItem *kPanScanCmd; - - //timestamps for disabling screensaver and mouse hiding - int lastMouseHide; - int lastScreensaverUpdate; -@public - float winSizeMult; } -- (BOOL) acceptsFirstResponder; -- (BOOL) becomeFirstResponder; -- (BOOL) resignFirstResponder; - //window & rendering - (void) preinit; - (void) config:(uint32_t)width:(uint32_t)height:(uint32_t)flags; @@ -91,27 +63,6 @@ - (void) setCurrentTexture; - (void) drawRect: (NSRect *) bounds; -//vo control -- (void) fullscreen: (BOOL) animate; -- (void) ontop; -- (void) rootwin; - -//menu -- (void) initMenu; -- (void) menuAction:(id)sender; - -//event -- (void) keyDown: (NSEvent *) theEvent; -- (void) mouseMoved: (NSEvent *) theEvent; -- (void) mouseDown: (NSEvent *) theEvent; -- (void) mouseUp: (NSEvent *) theEvent; -- (void) rightMouseDown: (NSEvent *) theEvent; -- (void) rightMouseUp: (NSEvent *) theEvent; -- (void) otherMouseDown: (NSEvent *) theEvent; -- (void) otherMouseUp: (NSEvent *) theEvent; -- (void) scrollWheel: (NSEvent *) theEvent; -- (void) mouseEvent: (NSEvent *) theEvent; -- (void) check_events; @end #endif /* MPLAYER_VO_COREVIDEO_H */
--- a/libvo/vo_corevideo.m Thu Sep 13 19:15:37 2012 +0000 +++ b/libvo/vo_corevideo.m Thu Sep 13 19:20:47 2012 +0000 @@ -76,10 +76,6 @@ static uint32_t image_stride; static uint32_t image_format; -static float winAlpha = 1; - -static BOOL isLeopardOrLater; - static vo_info_t info = { "Mac OS X Core Video", @@ -111,31 +107,6 @@ } } -static void update_screen_info(void) -{ - int screen_id = xinerama_screen; - NSArray *screen_array = [NSScreen screens]; - NSScreen *screen_handle; - NSRect screen_frame; - - if(screen_id >= (int)[screen_array count]) - { - mp_msg(MSGT_VO, MSGL_INFO, "[vo_corevideo] Device ID %d does not exist, falling back to main device\n", screen_id); - screen_id = -1; - } - if (screen_id < 0 && [mpGLView window]) - screen_handle = [[mpGLView window] screen]; - else - screen_handle = [screen_array objectAtIndex:(screen_id < 0 ? 0 : screen_id)]; - - screen_frame = [screen_handle frame]; - vo_screenwidth = screen_frame.size.width; - vo_screenheight = screen_frame.size.height; - xinerama_x = screen_frame.origin.x; - xinerama_y = screen_frame.origin.y; - aspect_save_screenres(vo_screenwidth, vo_screenheight); -} - static void free_file_specific(void) { if(shared_buffer) @@ -432,7 +403,7 @@ case VOCTRL_FULLSCREEN: vo_fs = !vo_fs; if(!shared_buffer){ [mpGLView fullscreen: NO]; } else { [mplayerosxProto toggleFullscreen]; } return VO_TRUE; case VOCTRL_GET_PANSCAN: return VO_TRUE; case VOCTRL_SET_PANSCAN: panscan_calc(); return VO_TRUE; - case VOCTRL_UPDATE_SCREENINFO: update_screen_info(); return VO_TRUE; + case VOCTRL_UPDATE_SCREENINFO: [mpGLView update_screen_info]; return VO_TRUE; } return VO_NOTIMPL; } @@ -443,53 +414,11 @@ @implementation MPlayerOpenGLView - (void) preinit { - NSOpenGLContext *glContext; - GLint swapInterval = 1; CVReturn error; - NSApplicationLoad(); - NSApp = [NSApplication sharedApplication]; - isLeopardOrLater = floor(NSAppKitVersionNumber) > 824; - - osx_foreground_hack(); - - // Install an event handler so the Quit menu entry works - // The proper way using NSApp setDelegate: and - // applicationShouldTerminate: does not work, - // probably NSApplication never installs its handler. - [[NSAppleEventManager sharedAppleEventManager] - setEventHandler:self - andSelector:@selector(handleQuitEvent:withReplyEvent:) - forEventClass:kCoreEventClass - andEventID:kAEQuitApplication]; - - //init menu - [self initMenu]; + [super preinit]; - //create window - window = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 100, 100) - styleMask:NSTitledWindowMask|NSTexturedBackgroundWindowMask|NSClosableWindowMask|NSMiniaturizableWindowMask|NSResizableWindowMask - backing:NSBackingStoreBuffered defer:NO]; - - [window autorelease]; - [window setDelegate:self]; - [window setContentView:self]; - [window setInitialFirstResponder:self]; - [window setAcceptsMouseMovedEvents:YES]; - [window setTitle:@"MPlayer - The Movie Player"]; - - winSizeMult = 1; - - //create OpenGL Context - glContext = [[NSOpenGLContext alloc] initWithFormat:[NSOpenGLView defaultPixelFormat] shareContext:nil]; - - [self setOpenGLContext:glContext]; - [glContext setValues:&swapInterval forParameter:NSOpenGLCPSwapInterval]; - [glContext setView:self]; - [glContext makeCurrentContext]; - [glContext release]; - - error = CVOpenGLTextureCacheCreate(NULL, 0, [glContext CGLContextObj], [[self pixelFormat] CGLPixelFormatObj], 0, &textureCache); + error = CVOpenGLTextureCacheCreate(NULL, 0, [[self openGLContext] CGLContextObj], [[self pixelFormat] CGLPixelFormatObj], 0, &textureCache); if(error != kCVReturnSuccess) mp_msg(MSGT_VO, MSGL_ERR,"[vo_corevideo] Failed to create OpenGL texture Cache(%d)\n", error); } @@ -509,7 +438,6 @@ [self releaseVideoSpecific]; CVOpenGLTextureCacheRelease(textureCache); textureCache = NULL; - [self setOpenGLContext:nil]; [super dealloc]; } @@ -517,23 +445,7 @@ { CVReturn error = kCVReturnSuccess; - config_movie_aspect((float)width/height); - - vo_dwidth = width *= self->winSizeMult; - vo_dheight = height *= self->winSizeMult; - - //config window - [window setContentSize:NSMakeSize(vo_dwidth, vo_dheight)]; - - // Do not use visibleFrame - taking the menu bar and dock into account - // would be nicer in principle, but currently only results in the window - // being placed strangely off-center since vo_dx/vo_dy calculation is - // not aware of it. - // Also flip vo_dy since the screen origin is in the bottom left on OSX. - update_screen_info(); - [window setFrameTopLeftPoint:NSMakePoint( - vo_dx, - 2*xinerama_y + vo_screenheight - vo_dy)]; + [super config:width:height:flags]; [self releaseVideoSpecific]; error = CVPixelBufferCreateWithBytes(NULL, image_width, image_height, pixelFormat, image_datas[0], image_stride, NULL, NULL, NULL, &frameBuffers[0]); @@ -548,158 +460,6 @@ error = CVOpenGLTextureCacheCreateTextureFromImage(NULL, textureCache, frameBuffers[image_page], 0, &texture); if(error != kCVReturnSuccess) mp_msg(MSGT_VO, MSGL_ERR,"[vo_corevideo] Failed to create OpenGL texture(%d)\n", error); - - vo_fs = flags & VOFLAG_FULLSCREEN; - - [self rootwin]; - - if(vo_fs) - [self fullscreen: NO]; - - [self ontop]; - - //show window - [window makeKeyAndOrderFront:self]; -} - -/* - Init Menu -*/ -- (void)initMenu -{ - NSMenu *mainMenu = [[NSMenu alloc] init]; - NSMenu *menu, *aspectMenu; - NSMenuItem *menuItem; - - menu = [[NSMenu alloc] init]; - menuItem = [[NSMenuItem alloc] init]; - [menuItem setSubmenu:menu]; - [mainMenu addItem:menuItem]; - // Note: setAppleMenu seems to be unnecessary from 10.6 on, - // but is needed for all earlier versions or the menu is - // messed up. - // Round-about way with performSelector used to avoid compiler - // warnings. - [NSApp performSelector:@selector(setAppleMenu:) withObject:menu]; - -//Create Movie Menu - menu = [[NSMenu alloc] initWithTitle:@"Movie"]; - menuItem = [[NSMenuItem alloc] initWithTitle:@"Half Size" action:@selector(menuAction:) keyEquivalent:@"0"]; [menu addItem:menuItem]; - kHalfScreenCmd = menuItem; - menuItem = [[NSMenuItem alloc] initWithTitle:@"Normal Size" action:@selector(menuAction:) keyEquivalent:@"1"]; [menu addItem:menuItem]; - kNormalScreenCmd = menuItem; - menuItem = [[NSMenuItem alloc] initWithTitle:@"Double Size" action:@selector(menuAction:) keyEquivalent:@"2"]; [menu addItem:menuItem]; - kDoubleScreenCmd = menuItem; - menuItem = [[NSMenuItem alloc] initWithTitle:@"Full Size" action:@selector(menuAction:) keyEquivalent:@"f"]; [menu addItem:menuItem]; - kFullScreenCmd = menuItem; - menuItem = [NSMenuItem separatorItem]; [menu addItem:menuItem]; - - aspectMenu = [[NSMenu alloc] initWithTitle:@"Aspect Ratio"]; - menuItem = [[NSMenuItem alloc] initWithTitle:@"Keep" action:@selector(menuAction:) keyEquivalent:@""]; [aspectMenu addItem:menuItem]; - if(vo_keepaspect) [menuItem setState:NSOnState]; - kKeepAspectCmd = menuItem; - menuItem = [[NSMenuItem alloc] initWithTitle:@"Pan-Scan" action:@selector(menuAction:) keyEquivalent:@""]; [aspectMenu addItem:menuItem]; - if(vo_panscan) [menuItem setState:NSOnState]; - kPanScanCmd = menuItem; - menuItem = [NSMenuItem separatorItem]; [aspectMenu addItem:menuItem]; - menuItem = [[NSMenuItem alloc] initWithTitle:@"Original" action:@selector(menuAction:) keyEquivalent:@""]; [aspectMenu addItem:menuItem]; - kAspectOrgCmd = menuItem; - menuItem = [[NSMenuItem alloc] initWithTitle:@"4:3" action:@selector(menuAction:) keyEquivalent:@""]; [aspectMenu addItem:menuItem]; - kAspectFullCmd = menuItem; - menuItem = [[NSMenuItem alloc] initWithTitle:@"16:9" action:@selector(menuAction:) keyEquivalent:@""]; [aspectMenu addItem:menuItem]; - kAspectWideCmd = menuItem; - menuItem = [[NSMenuItem alloc] initWithTitle:@"Aspect Ratio" action:nil keyEquivalent:@""]; - [menuItem setSubmenu:aspectMenu]; - [menu addItem:menuItem]; - [aspectMenu release]; - - //Add to menubar - menuItem = [[NSMenuItem alloc] initWithTitle:@"Movie" action:nil keyEquivalent:@""]; - [menuItem setSubmenu:menu]; - [mainMenu addItem:menuItem]; - -//Create Window Menu - menu = [[NSMenu alloc] initWithTitle:@"Window"]; - - menuItem = [[NSMenuItem alloc] initWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"]; [menu addItem:menuItem]; - menuItem = [[NSMenuItem alloc] initWithTitle:@"Zoom" action:@selector(performZoom:) keyEquivalent:@""]; [menu addItem:menuItem]; - - //Add to menubar - menuItem = [[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""]; - [menuItem setSubmenu:menu]; - [mainMenu addItem:menuItem]; - [NSApp setWindowsMenu:menu]; - [NSApp setMainMenu:mainMenu]; - - [menu release]; - [menuItem release]; -} - -- (void)set_winSizeMult:(float)mult -{ - NSRect frame; - int d_width, d_height; - aspect(&d_width, &d_height, A_NOZOOM); - - if (vo_fs) { - vo_fs = !vo_fs; - [self fullscreen:NO]; - } - - winSizeMult = mult; - frame.size.width = d_width * mult; - frame.size.height = d_height * mult; - [window setContentSize: frame.size]; - [self reshape]; -} - -/* - Menu Action - */ -- (void)menuAction:(id)sender -{ - if(sender == kHalfScreenCmd) - [self set_winSizeMult: 0.5]; - if(sender == kNormalScreenCmd) - [self set_winSizeMult: 1]; - if(sender == kDoubleScreenCmd) - [self set_winSizeMult: 2]; - if(sender == kFullScreenCmd) - { - vo_fs = !vo_fs; - [self fullscreen:NO]; - } - - if(sender == kKeepAspectCmd) - { - vo_keepaspect = !vo_keepaspect; - if(vo_keepaspect) - [kKeepAspectCmd setState:NSOnState]; - else - [kKeepAspectCmd setState:NSOffState]; - - [self reshape]; - } - - if(sender == kPanScanCmd) - { - vo_panscan = !vo_panscan; - if(vo_panscan) - [kPanScanCmd setState:NSOnState]; - else - [kPanScanCmd setState:NSOffState]; - - panscan_calc(); - } - - if(sender == kAspectOrgCmd) - change_movie_aspect(-1); - - if(sender == kAspectFullCmd) - change_movie_aspect(4.0f/3.0f); - - if(sender == kAspectWideCmd) - change_movie_aspect(16.0f/9.0f); } /* @@ -812,260 +572,4 @@ { [self render]; } - -/* - Toggle Fullscreen -*/ -- (void) fullscreen: (BOOL) animate -{ - static NSRect old_frame; - static NSRect old_view_frame; - - panscan_calc(); - - //go fullscreen - if(vo_fs) - { - if(!vo_rootwin) - { - SetSystemUIMode( kUIModeAllHidden, kUIOptionAutoShowMenuBar); - CGDisplayHideCursor(kCGDirectMainDisplay); - mouseHide = YES; - } - - old_frame = [window frame]; //save main window size & position - update_screen_info(); - - [window setFrame:NSMakeRect(xinerama_x, xinerama_y, vo_screenwidth, vo_screenheight) display:YES animate:animate]; //zoom-in window with nice useless sfx - old_view_frame = [self bounds]; - - [self setFrame:NSMakeRect(0, 0, vo_screenwidth, vo_screenheight)]; - [self setNeedsDisplay:YES]; - [window setHasShadow:NO]; - } - else - { - SetSystemUIMode( kUIModeNormal, 0); - - CGDisplayShowCursor(kCGDirectMainDisplay); - mouseHide = NO; - - //revert window to previous setting - [self setFrame:old_view_frame]; - [self setNeedsDisplay:YES]; - [window setHasShadow:YES]; - [window setFrame:old_frame display:YES animate:animate];//zoom-out window with nice useless sfx - } -} - -/* - Toggle ontop -*/ -- (void) ontop -{ - if(vo_ontop) - { - [window setLevel:NSScreenSaverWindowLevel]; - } - else - { - [window setLevel:NSNormalWindowLevel]; - } -} - -/* - Toggle rootwin - */ -- (void) rootwin -{ - if(vo_rootwin) - { - [window setLevel:CGWindowLevelForKey(kCGDesktopWindowLevelKey)]; - [window orderBack:self]; - } - else - { - [window setLevel:NSNormalWindowLevel]; - } -} - -/* - Check event for new event -*/ -- (void) check_events -{ - NSEvent *event; - int curTime = TickCount()/60; - - //automatically hide mouse cursor (and future on-screen control?) - if(vo_fs && !mouseHide && !vo_rootwin) - { - if(curTime - lastMouseHide >= 5 || lastMouseHide == 0) - { - CGDisplayHideCursor(kCGDirectMainDisplay); - mouseHide = TRUE; - lastMouseHide = curTime; - } - } - - //update activity every 30 seconds to prevent - //screensaver from starting up. - if(curTime - lastScreensaverUpdate >= 30 || lastScreensaverUpdate == 0) - { - UpdateSystemActivity(UsrActivity); - lastScreensaverUpdate = curTime; - } - - event = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:nil inMode:NSEventTrackingRunLoopMode dequeue:YES]; - if (event == nil) - return; - [NSApp sendEvent:event]; - // Without SDL's bootstrap code (include SDL.h in mplayer.c), - // on Leopard, we have trouble to get the play window automatically focused - // when the app is actived. The Following code fix this problem. -#ifndef CONFIG_SDL - if (isLeopardOrLater && [event type] == NSAppKitDefined - && [event subtype] == NSApplicationActivatedEventType) { - [window makeMainWindow]; - [window makeKeyAndOrderFront:self]; - } -#endif -} - -/* - From NSView, respond to key equivalents. -*/ -- (BOOL)performKeyEquivalent:(NSEvent *)theEvent -{ - switch([theEvent keyCode]) - { - case 0x21: [window setAlphaValue: winAlpha-=0.05]; return YES; - case 0x1e: [window setAlphaValue: winAlpha+=0.05]; return YES; - } - return NO; -} - -/* - Process key event -*/ -- (void) keyDown: (NSEvent *) theEvent -{ - int key = convert_key([theEvent keyCode], *[[theEvent characters] UTF8String]); - if (key != -1) - mplayer_put_key(key); -} - -/* - Process mouse button event -*/ -- (void) mouseMoved: (NSEvent *) theEvent -{ - if(vo_fs && !vo_rootwin) - { - CGDisplayShowCursor(kCGDirectMainDisplay); - mouseHide = NO; - } - if (enable_mouse_movements && !vo_rootwin) { - NSPoint p =[self convertPoint:[theEvent locationInWindow] fromView:nil]; - if ([self mouse:p inRect:[self frame]]) { - vo_mouse_movement(p.x, [self frame].size.height - p.y); - } - } -} - -- (void) mouseDown: (NSEvent *) theEvent -{ - [self mouseEvent: theEvent]; -} - -- (void) mouseUp: (NSEvent *) theEvent -{ - [self mouseEvent: theEvent]; -} - -- (void) rightMouseDown: (NSEvent *) theEvent -{ - [self mouseEvent: theEvent]; -} - -- (void) rightMouseUp: (NSEvent *) theEvent -{ - [self mouseEvent: theEvent]; -} - -- (void) otherMouseDown: (NSEvent *) theEvent -{ - [self mouseEvent: theEvent]; -} - -- (void) otherMouseUp: (NSEvent *) theEvent -{ - [self mouseEvent: theEvent]; -} - -- (void) scrollWheel: (NSEvent *) theEvent -{ - if([theEvent deltaY] > 0) - mplayer_put_key(MOUSE_BTN3); - else - mplayer_put_key(MOUSE_BTN4); -} - -- (void) mouseEvent: (NSEvent *) theEvent -{ - if ( [theEvent buttonNumber] >= 0 && [theEvent buttonNumber] <= 9 ) - { - int buttonNumber = [theEvent buttonNumber]; - // Fix to mplayer defined button order: left, middle, right - if (buttonNumber == 1) - buttonNumber = 2; - else if (buttonNumber == 2) - buttonNumber = 1; - switch([theEvent type]) - { - case NSLeftMouseDown: - case NSRightMouseDown: - case NSOtherMouseDown: - mplayer_put_key((MOUSE_BTN0 + buttonNumber) | MP_KEY_DOWN); - break; - case NSLeftMouseUp: - case NSRightMouseUp: - case NSOtherMouseUp: - mplayer_put_key(MOUSE_BTN0 + buttonNumber); - break; - } - } -} - -/* - NSResponder -*/ -- (BOOL) acceptsFirstResponder -{ - return YES; -} - -- (BOOL) becomeFirstResponder -{ - return YES; -} - -- (BOOL) resignFirstResponder -{ - return YES; -} - -- (BOOL)windowShouldClose:(id)sender -{ - mplayer_put_key(KEY_CLOSE_WIN); - // We have to wait for MPlayer to handle this, - // otherwise we are in trouble if the - // KEY_CLOSE_WIN handler is disabled - return NO; -} - -- (void)handleQuitEvent:(NSAppleEventDescriptor*)e withReplyEvent:(NSAppleEventDescriptor*)r -{ - mplayer_put_key(KEY_CLOSE_WIN); -} @end