summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefano Pigozzi <stefano.pigozzi@gmail.com>2013-09-03 21:18:28 +0200
committerStefano Pigozzi <stefano.pigozzi@gmail.com>2013-09-28 11:20:00 +0200
commit0ab9634eb3f3005c37a0346d9035dbc4d4abd144 (patch)
tree2bd5dbd469772067a4549fb1afafa04d223624f9
parent0e68ff4fad174d73c6e7ab82ead36f9209fb66a2 (diff)
downloadmpv-0ab9634eb3f3005c37a0346d9035dbc4d4abd144.tar.bz2
mpv-0ab9634eb3f3005c37a0346d9035dbc4d4abd144.tar.xz
cocoa_common: split the code, refactoring and cleanups
Split the code to several files. The GUI elements now each have they own files and private state. The original code was a mess to respect the retarded mplayer convention of having everything in a single file. This commit also seems to fix the long running bug of artifacts showing randomly when going fullscreen using nVidia GPUs.
-rw-r--r--Makefile10
-rw-r--r--video/out/cocoa/additions.h27
-rw-r--r--video/out/cocoa/additions.m51
-rw-r--r--video/out/cocoa/mpvadapter.h32
-rw-r--r--video/out/cocoa/view.h30
-rw-r--r--video/out/cocoa/view.m213
-rw-r--r--video/out/cocoa/window.h34
-rw-r--r--video/out/cocoa/window.m161
-rw-r--r--video/out/cocoa_common.h14
-rw-r--r--video/out/cocoa_common.m665
10 files changed, 722 insertions, 515 deletions
diff --git a/Makefile b/Makefile
index 2e93e1f7d5..0c9eabc806 100644
--- a/Makefile
+++ b/Makefile
@@ -44,11 +44,15 @@ SOURCES-$(LIBBS2B) += audio/filter/af_bs2b.c
SOURCES-$(LIBPOSTPROC) += video/filter/vf_pp.c
SOURCES-$(LIBSMBCLIENT) += stream/stream_smb.c
-SOURCES-$(COCOA) += video/out/cocoa_common.m \
- osdep/path-macosx.m \
+SOURCES-$(COCOA) += video/out/cocoa/view.m \
+ video/out/cocoa/window.m \
+ video/out/cocoa/additions.m \
+ video/out/cocoa_common.m \
osdep/macosx_application.m \
osdep/macosx_events.m \
- osdep/ar/HIDRemote.m
+ osdep/ar/HIDRemote.m \
+ osdep/path-macosx.m
+
SOURCES-$(MNG) += demux/demux_mng.c
SOURCES-$(MPG123) += audio/decode/ad_mpg123.c
diff --git a/video/out/cocoa/additions.h b/video/out/cocoa/additions.h
new file mode 100644
index 0000000000..8c237c9a40
--- /dev/null
+++ b/video/out/cocoa/additions.h
@@ -0,0 +1,27 @@
+/*
+ * This file is part of mpv.
+ *
+ * mpv 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.
+ *
+ * mpv 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 mpv. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#import <Cocoa/Cocoa.h>
+
+@interface NSScreen (mpvadditions)
+- (BOOL)hasDock;
+- (BOOL)hasMenubar;
+@end
+
+@interface NSEvent (mpvadditions)
+- (int)mpvButtonNumber;
+@end
diff --git a/video/out/cocoa/additions.m b/video/out/cocoa/additions.m
new file mode 100644
index 0000000000..3caabef956
--- /dev/null
+++ b/video/out/cocoa/additions.m
@@ -0,0 +1,51 @@
+/*
+ * This file is part of mpv.
+ *
+ * mpv 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.
+ *
+ * mpv 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 mpv. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#import "additions.h"
+
+@implementation NSScreen (mpvadditions)
+- (BOOL)hasDock
+{
+ NSRect vF = [self visibleFrame];
+ NSRect f = [self frame];
+ return
+ // The visible frame's width is smaller: dock is on left or right end
+ // of this method's receiver.
+ vF.size.width < f.size.width ||
+ // The visible frame's veritical origin is bigger: dock is
+ // on the bottom of this method's receiver.
+ vF.origin.y > f.origin.y;
+
+}
+
+- (BOOL)hasMenubar
+{
+ return [self isEqual: [NSScreen screens][0]];
+}
+@end
+
+@implementation NSEvent (mpvadditions)
+- (int)mpvButtonNumber
+{
+ int buttonNumber = [self buttonNumber];
+ switch (buttonNumber) {
+ case 1: return 2;
+ case 2: return 1;
+ default: return buttonNumber;
+ }
+}
+@end
diff --git a/video/out/cocoa/mpvadapter.h b/video/out/cocoa/mpvadapter.h
new file mode 100644
index 0000000000..eafeefce9f
--- /dev/null
+++ b/video/out/cocoa/mpvadapter.h
@@ -0,0 +1,32 @@
+/*
+ * This file is part of mpv.
+ *
+ * mpv 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.
+ *
+ * mpv 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 mpv. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#import <Cocoa/Cocoa.h>
+#include "video/out/vo.h"
+
+@interface MpvCocoaAdapter : NSObject
+- (void)setNeedsResize;
+- (void)signalMouseMovement:(NSPoint)point;
+- (void)putKey:(int)mpkey withModifiers:(int)modifiers;
+- (void)putAxis:(int)mpkey delta:(float)delta;
+- (void)performAsyncResize:(NSSize)size;
+
+- (BOOL)isInFullScreenMode;
+- (NSSize)videoSize;
+- (NSScreen *)fsScreen;
+@property(nonatomic, assign) struct vo *vout;
+@end
diff --git a/video/out/cocoa/view.h b/video/out/cocoa/view.h
new file mode 100644
index 0000000000..71d58a3348
--- /dev/null
+++ b/video/out/cocoa/view.h
@@ -0,0 +1,30 @@
+/*
+ * This file is part of mpv.
+ *
+ * mpv 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.
+ *
+ * mpv 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 mpv. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#import <Cocoa/Cocoa.h>
+#import "video/out/cocoa/mpvadapter.h"
+
+@interface MpvVideoView : NSView {
+ BOOL hasMouseDown;
+}
+@property(nonatomic, retain) MpvCocoaAdapter *adapter;
+@property(nonatomic, retain) NSTrackingArea *tracker;
+- (void)setFullScreen:(BOOL)willBeFullscreen;
+- (NSRect)frameInPixels;
+- (BOOL)canHideCursor;
+- (void)signalMousePosition;
+@end
diff --git a/video/out/cocoa/view.m b/video/out/cocoa/view.m
new file mode 100644
index 0000000000..bac485b225
--- /dev/null
+++ b/video/out/cocoa/view.m
@@ -0,0 +1,213 @@
+/*
+ * This file is part of mpv.
+ *
+ * mpv 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.
+ *
+ * mpv 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 mpv. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <libavutil/common.h>
+
+#include "mpvcore/input/input.h"
+#include "mpvcore/input/keycodes.h"
+
+#include "osdep/macosx_compat.h"
+#include "video/out/cocoa_common.h"
+#import "video/out/cocoa/additions.h"
+
+#include "view.h"
+
+@implementation MpvVideoView
+@synthesize adapter = _adapter;
+@synthesize tracker = _tracker;
+
+- (void)setFullScreen:(BOOL)willBeFullscreen
+{
+ if (willBeFullscreen && ![self isInFullScreenMode]) {
+ NSApplicationPresentationOptions popts =
+ NSApplicationPresentationDefault;
+
+ if ([[self.adapter fsScreen] hasMenubar])
+ // Cocoa raises an exception when autohiding the menubar but
+ // not the dock. They probably got bored while programming the
+ // multi screen support and took some shortcuts (tested on 10.8).
+ popts |= NSApplicationPresentationAutoHideMenuBar |
+ NSApplicationPresentationAutoHideDock;
+
+ if ([[self.adapter fsScreen] hasDock])
+ popts |= NSApplicationPresentationAutoHideDock;
+
+ NSDictionary *fsopts = @{
+ NSFullScreenModeAllScreens : @NO,
+ NSFullScreenModeApplicationPresentationOptions : @(popts)
+ };
+
+ // The original "windowed" window will stay around since sending a
+ // view fullscreen wraps it in another window. This is noticeable when
+ // sending the View fullscreen to another screen. Make it go away
+ // manually.
+ [self.window orderOut:self];
+
+ [self enterFullScreenMode:[self.adapter fsScreen]
+ withOptions:fsopts];
+ }
+
+ if (!willBeFullscreen && [self isInFullScreenMode]) {
+ [self exitFullScreenModeWithOptions:nil];
+
+ // Show the "windowed" window again.
+ [self.window makeKeyAndOrderFront:self];
+ [self.window makeFirstResponder:self];
+ }
+}
+
+// mpv uses flipped coordinates, because X11 uses those. So let's just use them
+// as well without having to do any coordinate conversion of mouse positions.
+- (BOOL)isFlipped { return YES; }
+
+- (void)updateTrackingAreas
+{
+ if (self.tracker) [self removeTrackingArea:self.tracker];
+
+ NSTrackingAreaOptions trackingOptions =
+ NSTrackingEnabledDuringMouseDrag |
+ NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved |
+ NSTrackingActiveAlways;
+
+ self.tracker =
+ [[[NSTrackingArea alloc] initWithRect:[self bounds]
+ options:trackingOptions
+ owner:self
+ userInfo:nil] autorelease];
+
+ [self addTrackingArea:self.tracker];
+}
+
+- (NSPoint)mouseLocation
+{
+ NSPoint wLoc = [self.window mouseLocationOutsideOfEventStream];
+ return [self convertPoint:wLoc fromView:nil];
+}
+
+- (BOOL)containsMouseLocation
+{
+ NSRect vF = [[self.window screen] visibleFrame];
+ NSRect vFW = [self.window convertRectFromScreen:vF];
+ NSRect vFV = [self convertRect:vFW fromView:nil];
+
+ // clip bounds to current visibleFrame
+ NSRect clippedBounds = CGRectIntersection([self bounds], vFV);
+ return CGRectContainsPoint(clippedBounds, [self mouseLocation]);
+}
+
+- (BOOL)acceptsFirstMouse:(NSEvent *)theEvent { return YES; }
+- (BOOL)acceptsFirstResponder { return YES; }
+- (BOOL)becomeFirstResponder { return YES; }
+- (BOOL)resignFirstResponder { return YES; }
+
+- (NSRect)frameInPixels
+{
+ return [self convertRectToBacking:[self frame]];
+}
+
+- (BOOL)canHideCursor
+{
+ return !self->hasMouseDown && [self containsMouseLocation];
+}
+
+- (void)mouseEntered:(NSEvent *)event
+{
+ // do nothing!
+}
+
+- (void)mouseExited:(NSEvent *)event
+{
+ [self.adapter putKey:MP_KEY_MOUSE_LEAVE withModifiers:0];
+}
+
+- (void)setFrameSize:(NSSize)size
+{
+ [super setFrameSize:size];
+ [self signalMousePosition];
+}
+
+- (void)signalMousePosition
+{
+ NSPoint p = [self convertPoint:[self mouseLocation] fromView:nil];
+ [self.adapter signalMouseMovement:p];
+}
+
+- (void)signalMouseMovement:(NSEvent *)event
+{
+ NSPoint p = [self convertPoint:[event locationInWindow] fromView:nil];
+ [self.adapter signalMouseMovement:p];
+}
+
+- (void)mouseMoved:(NSEvent *)event { [self signalMouseMovement:event]; }
+- (void)mouseDragged:(NSEvent *)event { [self signalMouseMovement:event]; }
+- (void)mouseDown:(NSEvent *)evt { [self mouseDownEvent:evt]; }
+- (void)mouseUp:(NSEvent *)evt { [self mouseUpEvent:evt]; }
+- (void)rightMouseDown:(NSEvent *)evt { [self mouseDownEvent:evt]; }
+- (void)rightMouseUp:(NSEvent *)evt { [self mouseUpEvent:evt]; }
+- (void)otherMouseDown:(NSEvent *)evt { [self mouseDownEvent:evt]; }
+- (void)otherMouseUp:(NSEvent *)evt { [self mouseUpEvent:evt]; }
+
+- (void)scrollWheel:(NSEvent *)event
+{
+ CGFloat delta;
+ int cmd;
+
+ if (FFABS([event deltaY]) >= FFABS([event deltaX])) {
+ delta = [event deltaY] * 0.1;
+ cmd = delta > 0 ? MP_AXIS_UP : MP_AXIS_DOWN;
+ delta = FFABS(delta);
+ } else {
+ delta = [event deltaX] * 0.1;
+ cmd = delta > 0 ? MP_AXIS_RIGHT : MP_AXIS_LEFT;
+ delta = FFABS(delta);
+ }
+
+ if ([event hasPreciseScrollingDeltas]) {
+ [self.adapter putAxis:cmd delta:delta];
+ } else {
+ const int modifiers = [event modifierFlags];
+ const int mpkey = delta > 0 ? MP_MOUSE_BTN3 : MP_MOUSE_BTN4;
+ [self.adapter putKey:mpkey withModifiers:modifiers];
+ }
+}
+
+- (void)mouseDownEvent:(NSEvent *)event
+{
+ [self putMouseEvent:event withState:MP_KEY_STATE_DOWN];
+
+ if ([event clickCount] > 1)
+ [self putMouseEvent:event withState:MP_KEY_STATE_UP];
+}
+
+- (void)mouseUpEvent:(NSEvent *)event
+{
+ [self putMouseEvent:event withState:MP_KEY_STATE_UP];
+}
+
+- (void)putMouseEvent:(NSEvent *)event withState:(int)state
+{
+ self->hasMouseDown = (state == MP_KEY_STATE_DOWN);
+ int mpkey = (MP_MOUSE_BTN0 + [event mpvButtonNumber]);
+ [self.adapter putKey:(mpkey | state) withModifiers:[event modifierFlags]];
+}
+
+- (void)drawRect:(NSRect)rect
+{
+ [self.adapter performAsyncResize:[self frameInPixels].size];
+ [self.adapter setNeedsResize];
+}
+@end
diff --git a/video/out/cocoa/window.h b/video/out/cocoa/window.h
new file mode 100644
index 0000000000..d6c753cc1b
--- /dev/null
+++ b/video/out/cocoa/window.h
@@ -0,0 +1,34 @@
+/*
+ * This file is part of mpv.
+ *
+ * mpv 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.
+ *
+ * mpv 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 mpv. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#import <Cocoa/Cocoa.h>
+#import "video/out/cocoa/mpvadapter.h"
+
+@interface MpvVideoWindow : NSWindow <NSWindowDelegate>
+@property(nonatomic, retain) MpvCocoaAdapter *adapter;
+- (void)setFullScreen:(BOOL)willBeFullscreen;
+- (BOOL)canBecomeKeyWindow;
+- (BOOL)canBecomeMainWindow;
+- (void)mulSize:(float)multiplier;
+- (void)setCenteredContentSize:(NSSize)newSize;
+
+- (void)queueNewVideoSize:(NSSize)newSize;
+- (void)dispatchNewVideoSize;
+
+// This really needs to use KVO
+- (void)didChangeFullScreenState;
+@end
diff --git a/video/out/cocoa/window.m b/video/out/cocoa/window.m
new file mode 100644
index 0000000000..fa51b8d82a
--- /dev/null
+++ b/video/out/cocoa/window.m
@@ -0,0 +1,161 @@
+/*
+ * This file is part of mpv.
+ *
+ * mpv 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.
+ *
+ * mpv 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 mpv. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "mpvcore/input/keycodes.h"
+
+#include "osdep/macosx_application.h"
+#include "osdep/macosx_events.h"
+#include "osdep/macosx_compat.h"
+
+#include "video/out/cocoa/additions.h"
+#include "video/out/cocoa_common.h"
+
+#include "window.h"
+
+@implementation MpvVideoWindow {
+ NSSize _queued_video_size;
+ bool _fs_resize_scheduled;
+}
+
+@synthesize adapter = _adapter;
+- (id)initWithContentRect:(NSRect)content_rect
+ styleMask:(NSUInteger)style_mask
+ backing:(NSBackingStoreType)buffering_type
+ defer:(BOOL)flag
+{
+ if (self = [super initWithContentRect:content_rect
+ styleMask:style_mask
+ backing:buffering_type
+ defer:flag]) {
+ [self setBackgroundColor:[NSColor blackColor]];
+ }
+ return self;
+}
+
+- (void)windowDidResize:(NSNotification *) notification
+{
+ [self.adapter setNeedsResize];
+}
+
+- (void)windowDidChangeBackingProperties:(NSNotification *)notification {
+ [self.adapter setNeedsResize];
+}
+
+- (BOOL)isInFullScreenMode
+{
+ return (([self styleMask] & NSFullScreenWindowMask) ==
+ NSFullScreenWindowMask);
+}
+
+- (void)setFullScreen:(BOOL)willBeFullscreen
+{
+ if (willBeFullscreen && ![self isInFullScreenMode]) {
+ [self setContentResizeIncrements:NSMakeSize(1, 1)];
+ [self toggleFullScreen:nil];
+ }
+
+ if (!willBeFullscreen && [self isInFullScreenMode]) {
+ [self setContentAspectRatio:self->_queued_video_size];
+ [self toggleFullScreen:nil];
+ }
+
+}
+
+- (BOOL)canBecomeMainWindow { return YES; }
+- (BOOL)canBecomeKeyWindow { return YES; }
+- (BOOL)windowShouldClose:(id)sender
+{
+ cocoa_put_key(MP_KEY_CLOSE_WIN);
+ // We have to wait for MPlayer to handle this,
+ // otherwise we are in trouble if the
+ // MP_KEY_CLOSE_WIN handler is disabled
+ return NO;
+}
+
+- (void)normalSize { [self mulSize:1.0f]; }
+
+- (void)halfSize { [self mulSize:0.5f];}
+
+- (void)doubleSize { [self mulSize:2.0f];}
+
+- (void)mulSize:(float)multiplier
+{
+ if (![self.adapter isInFullScreenMode]) {
+ NSSize size = [self.adapter videoSize];
+ size.width *= multiplier;
+ size.height *= multiplier;
+ [self setCenteredContentSize:size];
+ }
+}
+
+- (int)titleHeight
+{
+ NSRect of = [self frame];
+ NSRect cb = [[self contentView] bounds];
+ return of.size.height - cb.size.height;
+}
+
+- (void)setCenteredContentSize:(NSSize)ns
+{
+ NSRect f = [self frame];
+ CGFloat dx = (f.size.width - ns.width) / 2;
+ CGFloat dy = (f.size.height - ns.height - [self titleHeight]) / 2;
+ NSRect nf = NSRectFromCGRect(CGRectInset(NSRectToCGRect(f), dx, dy));
+ [self setFrame:nf display:NO animate:NO];
+}
+
+- (NSRect)constrainFrameRect:(NSRect)nf toScreen:(NSScreen *)screen
+{
+ NSRect s = [[self screen] visibleFrame];
+ if (nf.origin.y + nf.size.height > s.origin.y + s.size.height)
+ nf.origin.y = s.origin.y + s.size.height - nf.size.height;
+ return nf;
+}
+
+- (void)queueNewVideoSize:(NSSize)new_size
+{
+ NSSize prev_size = self->_queued_video_size;
+ self->_queued_video_size = new_size;
+
+ if (!CGSizeEqualToSize(prev_size, new_size))
+ [self dispatchNewVideoSize];
+}
+
+- (void)dispatchNewVideoSize
+{
+ if ([self.adapter isInFullScreenMode]) {
+ self->_fs_resize_scheduled = true;
+ } else {
+ [self applyNewVideoSize];
+ }
+}
+
+- (void)applyNewVideoSize
+{
+ [self setCenteredContentSize:self->_queued_video_size];
+ [self setContentAspectRatio:self->_queued_video_size];
+}
+
+- (void)didChangeFullScreenState
+{
+ if (![self.adapter isInFullScreenMode] && self->_fs_resize_scheduled) {
+ self->_fs_resize_scheduled = false;
+ [self applyNewVideoSize];
+ }
+}
+@end
+
diff --git a/video/out/cocoa_common.h b/video/out/cocoa_common.h
index 081c43d2ce..5584ae6b05 100644
--- a/video/out/cocoa_common.h
+++ b/video/out/cocoa_common.h
@@ -1,20 +1,20 @@
/*
* Cocoa OpenGL Backend
*
- * This file is part of mplayer2.
+ * This file is part of mpv.
*
- * mplayer2 is free software; you can redistribute it and/or modify
+ * mpv 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.
*
- * mplayer2 is distributed in the hope that it will be useful,
+ * mpv 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
+ * 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 mplayer2. If not, see <http://www.gnu.org/licenses/>.
+ * with mpv. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef MPLAYER_COCOA_COMMON_H
@@ -29,7 +29,6 @@ void *vo_cocoa_glgetaddr(const char *s);
int vo_cocoa_init(struct vo *vo);
void vo_cocoa_uninit(struct vo *vo);
-int vo_cocoa_change_attributes(struct vo *vo);
int vo_cocoa_config_window(struct vo *vo, uint32_t d_width,
uint32_t d_height, uint32_t flags,
int gl3profile);
@@ -37,8 +36,6 @@ int vo_cocoa_config_window(struct vo *vo, uint32_t d_width,
void vo_cocoa_set_current_context(struct vo *vo, bool current);
void vo_cocoa_swap_buffers(struct vo *vo);
int vo_cocoa_check_events(struct vo *vo);
-void vo_cocoa_fullscreen(struct vo *vo);
-void vo_cocoa_ontop(struct vo *vo);
int vo_cocoa_control(struct vo *vo, int *events, int request, void *arg);
void vo_cocoa_register_resize_callback(struct vo *vo,
@@ -49,7 +46,6 @@ int vo_cocoa_swap_interval(int enabled);
void *vo_cocoa_cgl_context(struct vo *vo);
void *vo_cocoa_cgl_pixel_format(struct vo *vo);
-
int vo_cocoa_cgl_color_size(struct vo *vo);
#endif /* MPLAYER_COCOA_COMMON_H */
diff --git a/video/out/cocoa_common.m b/video/out/cocoa_common.m
index 9a5945d82d..612ea27c73 100644
--- a/video/out/cocoa_common.m
+++ b/video/out/cocoa_common.m
@@ -1,82 +1,54 @@
/*
* Cocoa OpenGL Backend
*
- * This file is part of mplayer2.
+ * This file is part of mpv.
*
- * mplayer2 is free software; you can redistribute it and/or modify
+ * mpv 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.
*
- * mplayer2 is distributed in the hope that it will be useful,
+ * mpv 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 mplayer2. If not, see <http://www.gnu.org/licenses/>.
+ * with mpv. If not, see <http://www.gnu.org/licenses/>.
*/
#import <Cocoa/Cocoa.h>
#import <CoreServices/CoreServices.h> // for CGDisplayHideCursor
#import <IOKit/pwr_mgt/IOPMLib.h>
#include <dlfcn.h>
-#include <libavutil/common.h>
#include "cocoa_common.h"
+#include "video/out/cocoa/window.h"
+#include "video/out/cocoa/view.h"
+#import "video/out/cocoa/mpvadapter.h"
+
+#include "osdep/macosx_application.h"
+#include "osdep/macosx_events.h"
#include "config.h"
#include "mpvcore/options.h"
-#include "vo.h"
-#include "aspect.h"
+#include "video/out/vo.h"
+#include "video/out/aspect.h"
#include "mpvcore/input/input.h"
#include "talloc.h"
#include "mpvcore/mp_msg.h"
-#include "osdep/macosx_application.h"
-#include "osdep/macosx_events.h"
-#include "osdep/macosx_compat.h"
-
-@interface GLMPlayerWindow : NSWindow <NSWindowDelegate>
-- (BOOL)canBecomeKeyWindow;
-- (BOOL)canBecomeMainWindow;
-- (void)fullscreen;
-- (void)mulSize:(float)multiplier;
-- (int)titleHeight;
-- (void)setCenteredContentSize:(NSSize)newSize;
-@property(nonatomic, assign) struct vo *videoOutput;
-@end
-
-@interface GLMPlayerOpenGLView : NSView {
- BOOL hasMouseDown;
-}
-@property(nonatomic, retain) NSTrackingArea *tracker;
-@property(nonatomic, assign) struct vo *videoOutput;
-- (BOOL)canHideCursor;
-- (void)recalcDraggableState;
-- (void)signalMousePosition;
-@end
-
-@interface NSScreen (mpvadditions)
-- (BOOL)hasDock;
-- (BOOL)hasMenubar;
-@end
-
-@interface NSEvent (mpvadditions)
-- (int)mpvButtonNumber;
-@end
+static void vo_cocoa_fullscreen(struct vo *vo);
+static void vo_cocoa_ontop(struct vo *vo);
struct vo_cocoa_state {
- GLMPlayerWindow *window;
- GLMPlayerOpenGLView *view;
- NSOpenGLContext *glContext;
- NSOpenGLPixelFormat *pixelFormat;
-
- NSSize current_video_size;
- NSSize previous_video_size;
+ MpvVideoWindow *window;
+ MpvVideoView *view;
+ NSOpenGLContext *gl_ctx;
+ NSOpenGLPixelFormat *gl_pixfmt;
NSScreen *current_screen;
NSScreen *fs_screen;
@@ -86,14 +58,11 @@ struct vo_cocoa_state {
struct aspect_data aspdat;
bool did_resize;
- bool did_async_resize;
- bool out_fs_resize;
- bool want_redraw;
+ bool skip_next_swap_buffer;
+ bool inside_sync_section;
IOPMAssertionID power_mgmt_assertion;
- CGFloat accumulated_scroll;
-
NSLock *lock;
bool enable_resize_redraw;
void (*resize_redraw)(struct vo *vo, int w, int h);
@@ -101,31 +70,6 @@ struct vo_cocoa_state {
struct mp_log *log;
};
-static struct vo_cocoa_state *vo_cocoa_init_state(struct vo *vo)
-{
- struct vo_cocoa_state *s = talloc_ptrtype(vo, s);
- *s = (struct vo_cocoa_state){
- .did_resize = NO,
- .did_async_resize = NO,
- .want_redraw = NO,
- .current_video_size = {0,0},
- .previous_video_size = {0,0},
- .out_fs_resize = NO,
- .power_mgmt_assertion = kIOPMNullAssertionID,
- .accumulated_scroll = 0,
- .lock = [[NSLock alloc] init],
- .enable_resize_redraw = NO,
- .log = mp_log_new(s, vo->log, "cocoa"),
- };
- return s;
-}
-
-static NSRect to_pixels(struct vo *vo, NSRect frame)
-{
- struct vo_cocoa_state *s = vo->cocoa;
- return [s->view convertRectToBacking: frame];
-}
-
void *vo_cocoa_glgetaddr(const char *s)
{
void *ret = NULL;
@@ -160,8 +104,17 @@ static void disable_power_management(struct vo *vo)
int vo_cocoa_init(struct vo *vo)
{
- vo->cocoa = vo_cocoa_init_state(vo);
-
+ struct vo_cocoa_state *s = talloc_zero(vo, struct vo_cocoa_state);
+ *s = (struct vo_cocoa_state){
+ .did_resize = false,
+ .skip_next_swap_buffer = false,
+ .inside_sync_section = false,
+ .power_mgmt_assertion = kIOPMNullAssertionID,
+ .lock = [[NSLock alloc] init],
+ .enable_resize_redraw = NO,
+ .log = mp_log_new(s, vo->log, "cocoa"),
+ };
+ vo->cocoa = s;
return 1;
}
@@ -185,13 +138,21 @@ void vo_cocoa_uninit(struct vo *vo)
enable_power_management(vo);
[NSApp setPresentationOptions:NSApplicationPresentationDefault];
- if (vo->opts->fullscreen)
+ // XXX: It looks like there are some circular retain cycles for the
+ // video view / video window that cause them to not be deallocated,
+ // This is a workaround to make the fullscreen window be released,
+ // but the retain cycle problems should be investigated.
+ if ([s->view isInFullScreenMode])
[[s->view window] release];
[s->window release];
s->window = nil;
- [s->glContext release];
- s->glContext = nil;
+
+ [s->gl_ctx release];
+ s->gl_ctx = nil;
+
+ [s->lock release];
+ s->lock = nil;
});
}
@@ -226,7 +187,7 @@ static int get_screen_handle(struct vo *vo, int identifier, NSWindow *window,
}
}
-static void update_screen_info(struct vo *vo)
+static void vo_cocoa_update_screens_pointers(struct vo *vo)
{
struct vo_cocoa_state *s = vo->cocoa;
struct mp_vo_opts *opts = vo->opts;
@@ -239,7 +200,7 @@ static void vo_cocoa_update_screen_info(struct vo *vo)
struct vo_cocoa_state *s = vo->cocoa;
struct mp_vo_opts *opts = vo->opts;
- update_screen_info(vo);
+ vo_cocoa_update_screens_pointers(vo);
NSRect r = [s->current_screen frame];
@@ -253,10 +214,10 @@ static void vo_cocoa_update_screen_info(struct vo *vo)
static void resize_window(struct vo *vo)
{
struct vo_cocoa_state *s = vo->cocoa;
- NSRect frame = to_pixels(vo, [s->view frame]);
+ NSRect frame = [s->view frameInPixels];
vo->dwidth = frame.size.width;
vo->dheight = frame.size.height;
- [s->glContext update];
+ [s->gl_ctx update];
}
static void vo_set_level(struct vo *vo, int ontop)
@@ -272,28 +233,13 @@ static void vo_set_level(struct vo *vo, int ontop)
[s->window setLevel:s->window_level];
}
-void vo_cocoa_ontop(struct vo *vo)
+static void vo_cocoa_ontop(struct vo *vo)
{
struct mp_vo_opts *opts = vo->opts;
opts->ontop = !opts->ontop;
vo_set_level(vo, opts->ontop);
}
-static void update_state_sizes(struct vo_cocoa_state *s,
- uint32_t d_width, uint32_t d_height)
-{
- if (s->current_video_size.width > 0 || s->current_video_size.height > 0)
- s->previous_video_size = s->current_video_size;
- s->current_video_size = NSMakeSize(d_width, d_height);
-}
-
-static void resize_window_from_stored_size(struct vo *vo)
-{
- struct vo_cocoa_state *s = vo->cocoa;
- [s->window setCenteredContentSize:s->current_video_size];
- [s->window setContentAspectRatio:s->current_video_size];
-}
-
static void create_window(struct vo *vo, uint32_t d_width, uint32_t d_height,
uint32_t flags)
{
@@ -311,12 +257,12 @@ static void create_window(struct vo *vo, uint32_t d_width, uint32_t d_height,
}
s->window =
- [[GLMPlayerWindow alloc] initWithContentRect:contentRect
- styleMask:window_mask
- backing:NSBackingStoreBuffered
- defer:NO];
+ [[MpvVideoWindow alloc] initWithContentRect:contentRect
+ styleMask:window_mask
+ backing:NSBackingStoreBuffered
+ defer:NO];
+ s->view = [[[MpvVideoView alloc] initWithFrame:contentRect] autorelease];
- s->view = [[GLMPlayerOpenGLView alloc] initWithFrame:contentRect];
[s->view setWantsBestResolutionOpenGLSurface:YES];
cocoa_register_menu_item_action(MPM_H_SIZE, @selector(halfSize));
@@ -327,10 +273,12 @@ static void create_window(struct vo *vo, uint32_t d_width, uint32_t d_height,
[s->window setRestorable:NO];
[s->window setContentView:s->view];
- [s->view release];
- [s->glContext setView:s->view];
- s->window.videoOutput = vo;
- s->view.videoOutput = vo;
+ [s->gl_ctx setView:s->view];
+
+ MpvCocoaAdapter *adapter = [[[MpvCocoaAdapter alloc] init] autorelease];
+ adapter.vout = vo;
+ s->view.adapter = adapter;
+ s->