summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile4
-rw-r--r--audio/out/ao_coreaudio.c5
-rwxr-xr-xconfigure17
-rw-r--r--core/mplayer.c45
-rw-r--r--core/parser-mpcmd.c5
-rw-r--r--osdep/macosx_application.h57
-rw-r--r--osdep/macosx_application.m349
-rw-r--r--osdep/macosx_application_objc.h40
-rw-r--r--osdep/macosx_finder_args.h29
-rw-r--r--osdep/macosx_finder_args.m97
-rw-r--r--video/out/cocoa_common.m153
11 files changed, 506 insertions, 295 deletions
diff --git a/Makefile b/Makefile
index 9e565c829d..314bbb4fb7 100644
--- a/Makefile
+++ b/Makefile
@@ -45,10 +45,10 @@ SOURCES-$(LIBBS2B) += audio/filter/af_bs2b.c
SOURCES-$(LIBPOSTPROC) += video/filter/vf_pp.c
SOURCES-$(LIBSMBCLIENT) += stream/stream_smb.c
-SOURCES-$(MACOSX_FINDER) += osdep/macosx_finder_args.m
SOURCES-$(MACOSX_BUNDLE) += osdep/macosx_bundle.m
SOURCES-$(COCOA) += video/out/osx_common.m \
- video/out/cocoa_common.m
+ video/out/cocoa_common.m \
+ osdep/macosx_application.m
SOURCES-$(MNG) += demux/demux_mng.c
SOURCES-$(MPG123) += audio/decode/ad_mpg123.c
diff --git a/audio/out/ao_coreaudio.c b/audio/out/ao_coreaudio.c
index 7993eac910..ba8f517c75 100644
--- a/audio/out/ao_coreaudio.c
+++ b/audio/out/ao_coreaudio.c
@@ -1073,7 +1073,6 @@ static OSStatus RenderCallbackSPDIF( AudioDeviceID inDevice,
static int play(void* output_samples,int num_bytes,int flags)
{
int wrote, b_digital;
- SInt32 exit_reason;
// Check whether we need to reset the digital output stream.
if (ao->b_digital && ao->b_stream_format_changed)
@@ -1103,10 +1102,6 @@ static int play(void* output_samples,int num_bytes,int flags)
wrote=write_buffer(output_samples, num_bytes);
audio_resume();
- do {
- exit_reason = CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, true);
- } while (exit_reason == kCFRunLoopRunHandledSource);
-
return wrote;
}
diff --git a/configure b/configure
index a9edaab93b..83db6cc188 100755
--- a/configure
+++ b/configure
@@ -316,8 +316,6 @@ Optional features:
--disable-dvdread disable libdvdread [autodetect]
--disable-cddb disable cddb [autodetect]
--disable-enca disable ENCA charset oracle library [autodetect]
- --enable-macosx-finder enable Mac OS X Finder invocation parameter
- parsing [disabled]
--enable-macosx-bundle enable Mac OS X bundle file locations [autodetect]
--disable-inet6 disable IPv6 support [autodetect]
--disable-gethostbyname2 gethostbyname2 part of the C library [autodetect]
@@ -476,7 +474,6 @@ _cddb=auto
_coreaudio=auto
_corevideo=auto
_cocoa=auto
-_macosx_finder=no
_macosx_bundle=auto
_enca=auto
_inet6=auto
@@ -722,8 +719,6 @@ for ac_option do
--disable-corevideo) _corevideo=no ;;
--enable-cocoa) _cocoa=yes ;;
--disable-cocoa) _cocoa=no ;;
- --enable-macosx-finder) _macosx_finder=yes ;;
- --disable-macosx-finder) _macosx_finder=no ;;
--enable-macosx-bundle) _macosx_bundle=yes ;;
--disable-macosx-bundle) _macosx_bundle=no ;;
@@ -1665,17 +1660,9 @@ echores "$_sys_sysinfo"
if darwin; then
-echocheck "Mac OS X Finder Support"
-def_macosx_finder='#undef CONFIG_MACOSX_FINDER'
-if test "$_macosx_finder" = yes ; then
- def_macosx_finder='#define CONFIG_MACOSX_FINDER 1'
- libs_mplayer="$libs_mplayer -framework Cocoa"
-fi
-echores "$_macosx_finder"
-
echocheck "Mac OS X Bundle file locations"
def_macosx_bundle='#undef CONFIG_MACOSX_BUNDLE'
-test "$_macosx_bundle" = auto && _macosx_bundle=$_macosx_finder
+test "$_macosx_bundle" = auto
if test "$_macosx_bundle" = yes ; then
extra_ldflags="$extra_ldflags -headerpad_max_install_names"
def_macosx_bundle='#define CONFIG_MACOSX_BUNDLE 1'
@@ -3087,7 +3074,6 @@ LIBSMBCLIENT = $_smb
LIBQUVI = $_libquvi
LIBTHEORA = $_theora
LIRC = $_lirc
-MACOSX_FINDER = $_macosx_finder
MACOSX_BUNDLE = $_macosx_bundle
MNG = $_mng
MPG123 = $_mpg123
@@ -3190,7 +3176,6 @@ $def_dl
$def_dos_paths
$def_iconv
$def_macosx_bundle
-$def_macosx_finder
$def_priority
diff --git a/core/mplayer.c b/core/mplayer.c
index 72871bd0f0..2e79e80c14 100644
--- a/core/mplayer.c
+++ b/core/mplayer.c
@@ -86,6 +86,10 @@
#include "video/out/x11_common.h"
#endif
+#ifdef CONFIG_COCOA
+#include "osdep/macosx_application.h"
+#endif
+
#include "audio/out/ao.h"
#include "core/codecs.h"
@@ -607,7 +611,14 @@ static MP_NORETURN void exit_player(struct MPContext *mpctx,
talloc_free(mpctx);
+#ifdef CONFIG_COCOA
+ terminate_cocoa_application();
+ // never reach here:
+ // terminate calls exit itself, just silence compiler warning
+ exit(0);
+#else
exit(rc);
+#endif
}
static void mk_config_dir(char *subdir)
@@ -3792,6 +3803,32 @@ static void run_playloop(struct MPContext *mpctx)
execute_queued_seek(mpctx);
}
+static void run_playloop_opaque_callback(void *context)
+{
+ run_playloop((struct MPContext *)context);
+}
+
+static int check_stop_play(void *context)
+{
+ struct MPContext *mpctx = context;
+ return mpctx->stop_play;
+}
+
+static void schedule_run_playloop(struct MPContext *mpctx)
+{
+
+ #ifdef CONFIG_COCOA
+ cocoa_run_loop_schedule(run_playloop_opaque_callback,
+ check_stop_play,
+ mpctx, // passed in as opaque type
+ mpctx->input,
+ mpctx->key_fifo);
+ cocoa_run_runloop();
+ #else
+ while (!check_stop_play(mpctx))
+ run_playloop(mpctx);
+ #endif
+}
static int read_keys(void *ctx, int fd)
{
@@ -4395,8 +4432,7 @@ goto_enable_cache: ;
if (mpctx->opts.pause)
pause_player(mpctx);
- while (!mpctx->stop_play)
- run_playloop(mpctx);
+ schedule_run_playloop(mpctx);
mp_msg(MSGT_GLOBAL, MSGL_V, "EOF code: %d \n", mpctx->stop_play);
@@ -4585,6 +4621,11 @@ static void osdep_preinit(int *p_argc, char ***p_argv)
GetCpuCaps(&gCpuCaps);
+#ifdef CONFIG_COCOA
+ init_cocoa_application();
+ macosx_finder_args_preinit(p_argc, p_argv);
+#endif
+
#ifdef __MINGW32__
mp_get_converted_argv(p_argc, p_argv);
#endif
diff --git a/core/parser-mpcmd.c b/core/parser-mpcmd.c
index 156b32e783..25535582a2 100644
--- a/core/parser-mpcmd.c
+++ b/core/parser-mpcmd.c
@@ -31,7 +31,6 @@
#include "playlist.h"
#include "playlist_parser.h"
#include "parser-mpcmd.h"
-#include "osdep/macosx_finder_args.h"
#define GLOBAL 0
#define LOCAL 1
@@ -133,10 +132,6 @@ bool m_config_parse_mp_command_line(m_config_t *config, struct playlist *files,
assert(!config->file_local_mode);
mode = GLOBAL;
-#ifdef CONFIG_MACOSX_FINDER
- if (macosx_finder_args(config, files, argc, argv))
- return true;
-#endif
struct parse_state p = {config, argc, argv};
while (split_opt(&p)) {
diff --git a/osdep/macosx_application.h b/osdep/macosx_application.h
new file mode 100644
index 0000000000..c2227ae05d
--- /dev/null
+++ b/osdep/macosx_application.h
@@ -0,0 +1,57 @@
+/*
+ * 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, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef MPV_MACOSX_APPLICATION
+#define MPV_MACOSX_APPLICATION
+
+struct input_ctx;
+struct mp_fifo;
+
+// Playloop callback function pointer
+typedef void(*play_loop_callback)(void *);
+typedef int(*should_stop_callback)(void *);
+
+// Menu Keys identifing menu items
+typedef enum {
+ MPM_H_SIZE,
+ MPM_N_SIZE,
+ MPM_D_SIZE,
+ MPM_MINIMIZE,
+ MPM_ZOOM,
+} MPMenuKey;
+
+void cocoa_register_menu_item_action(MPMenuKey key, void* action);
+
+// initializes Cocoa application
+void init_cocoa_application(void);
+void terminate_cocoa_application(void);
+
+// Runs the Cocoa Main Event Loop
+void cocoa_run_runloop(void);
+void cocoa_post_fake_event(void);
+
+// Adds play_loop as a timer of the Main Cocoa Event Loop
+void cocoa_run_loop_schedule(play_loop_callback callback,
+ should_stop_callback playback_stopped,
+ void *context,
+ struct input_ctx *input_context,
+ struct mp_fifo *key_fifo);
+
+void macosx_finder_args_preinit(int *argc, char ***argv);
+
+#endif /* MPV_MACOSX_APPLICATION */
diff --git a/osdep/macosx_application.m b/osdep/macosx_application.m
new file mode 100644
index 0000000000..39439e9fde
--- /dev/null
+++ b/osdep/macosx_application.m
@@ -0,0 +1,349 @@
+/*
+ * 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, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "talloc.h"
+
+#include "core/mp_fifo.h"
+#include "core/input/input.h"
+#include "core/input/keycodes.h"
+
+#include "osdep/macosx_application_objc.h"
+#include "video/out/osx_common.h"
+
+// 0.0001 seems too much and 0.01 too low, no idea why this works so well
+#define COCOA_MAGIC_TIMER_DELAY 0.001
+
+static Application *app;
+
+@interface Application (PrivateMethods)
+- (NSMenuItem *)menuItemWithParent:(NSMenu *)parent
+ title:(NSString *)title
+ action:(SEL)selector
+ keyEquivalent:(NSString*)key;
+
+- (NSMenuItem *)mainMenuItemWithParent:(NSMenu *)parent
+ child:(NSMenu *)child;
+- (void)registerMenuItem:(NSMenuItem*)menuItem forKey:(MPMenuKey)key;
+- (NSMenu *)appleMenuWithMainMenu:(NSMenu *)mainMenu;
+- (NSMenu *)movieMenu;
+- (NSMenu *)windowMenu;
+- (void)handleFiles;
+@end
+
+@interface NSApplication (NiblessAdditions)
+- (void)setAppleMenu:(NSMenu *)aMenu;
+@end
+
+@implementation Application
+@synthesize files = _files;
+@synthesize argumentsList = _arguments_list;
+@synthesize willStopOnOpenEvent = _will_stop_on_open_event;
+
+@synthesize callback = _callback;
+@synthesize shouldStopPlayback = _should_stop_playback;
+@synthesize context = _context;
+@synthesize inputContext = _input_context;
+@synthesize keyFIFO = _key_fifo;
+@synthesize callbackTimer = _callback_timer;
+@synthesize menuItems = _menu_items;
+
+- (id)init
+{
+ if (self = [super init]) {
+ self.menuItems = [[[NSMutableDictionary alloc] init] autorelease];
+ self.files = nil;
+ self.argumentsList = [[[NSMutableArray alloc] init] autorelease];
+ self.willStopOnOpenEvent = NO;
+ }
+
+ return self;
+}
+
+#define _R(P, T, E, K) \
+ { \
+ NSMenuItem *tmp = [self menuItemWithParent:(P) title:(T) \
+ action:nil keyEquivalent:(E)]; \
+ [self registerMenuItem:tmp forKey:(K)]; \
+ }
+
+- (NSMenu *)appleMenuWithMainMenu:(NSMenu *)mainMenu
+{
+ NSMenu *menu = [[NSMenu alloc] initWithTitle:@"Apple Menu"];
+ [self mainMenuItemWithParent:mainMenu child:menu];
+ [self menuItemWithParent:menu title:@"Quit mpv"
+ action:@selector(stopPlayback) keyEquivalent: @"q"];
+ return [menu autorelease];
+}
+
+- (NSMenu *)movieMenu
+{
+ NSMenu *menu = [[NSMenu alloc] initWithTitle:@"Movie"];
+ _R(menu, @"Half Size", @"0", MPM_H_SIZE)
+ _R(menu, @"Normal Size", @"1", MPM_N_SIZE)
+ _R(menu, @"Double Size", @"2", MPM_D_SIZE)
+ return [menu autorelease];
+}
+
+- (NSMenu *)windowMenu
+{
+ NSMenu *menu = [[NSMenu alloc] initWithTitle:@"Window"];
+ _R(menu, @"Minimize", @"m", MPM_MINIMIZE)
+ _R(menu, @"Zoom", @"z", MPM_ZOOM)
+ return [menu autorelease];
+}
+
+- (void)initialize_menu
+{
+ NSMenu *main_menu = [[NSMenu new] autorelease];
+ [NSApp setMainMenu:main_menu];
+ [NSApp setAppleMenu:[self appleMenuWithMainMenu:main_menu]];
+
+ [app mainMenuItemWithParent:main_menu child:[self movieMenu]];
+ [app mainMenuItemWithParent:main_menu child:[self windowMenu]];
+}
+
+#undef _R
+
+- (void)call_callback
+{
+ if (self.shouldStopPlayback(self.context)) {
+ [NSApp stop:nil];
+ cocoa_post_fake_event();
+ } else {
+ self.callback(self.context);
+ }
+}
+
+- (void)schedule_timer
+{
+ self.callbackTimer =
+ [NSTimer timerWithTimeInterval:COCOA_MAGIC_TIMER_DELAY
+ target:self
+ selector:@selector(call_callback)
+ userInfo:nil
+ repeats:YES];
+
+ [[NSRunLoop currentRunLoop] addTimer:self.callbackTimer
+ forMode:NSDefaultRunLoopMode];
+
+ [[NSRunLoop currentRunLoop] addTimer:self.callbackTimer
+ forMode:NSEventTrackingRunLoopMode];
+}
+
+- (void)stopPlayback
+{
+ mplayer_put_key(app.keyFIFO, MP_KEY_CLOSE_WIN);
+}
+
+- (void)registerMenuItem:(NSMenuItem*)menuItem forKey:(MPMenuKey)key
+{
+ [self.menuItems setObject:menuItem forKey:[NSNumber numberWithInt:key]];
+}
+
+- (void)registerSelector:(SEL)action forKey:(MPMenuKey)key
+{
+ NSNumber *boxedKey = [NSNumber numberWithInt:key];
+ NSMenuItem *item = [self.menuItems objectForKey:boxedKey];
+ if (item) {
+ [item setAction:action];
+ }
+}
+
+- (NSMenuItem *)menuItemWithParent:(NSMenu *)parent
+ title:(NSString *)title
+ action:(SEL)action
+ keyEquivalent:(NSString*)key
+{
+
+ NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:title
+ action:action
+ keyEquivalent:key];
+ [parent addItem:item];
+ return [item autorelease];
+}
+
+- (NSMenuItem *)mainMenuItemWithParent:(NSMenu *)parent
+ child:(NSMenu *)child
+{
+ NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:@""
+ action:nil
+ keyEquivalent:@""];
+ [item setSubmenu:child];
+ [parent addItem:item];
+ return [item autorelease];
+}
+
+- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)theApp {
+ return NSTerminateNow;
+}
+
+- (void)handleQuitEvent:(NSAppleEventDescriptor*)e
+ withReplyEvent:(NSAppleEventDescriptor*)r
+{
+ [self stopPlayback];
+}
+
+- (void)application:(NSApplication *)sender openFiles:(NSArray *)filenames
+{
+ NSMutableArray *filesToOpen = [[[NSMutableArray alloc] init] autorelease];
+
+ [filenames enumerateObjectsUsingBlock:^(id obj, NSUInteger i, BOOL *_) {
+ NSInteger place = [app.argumentsList indexOfObject:obj];
+ if (place == NSNotFound) {
+ // Proper new event ^_^
+ [filesToOpen addObject:obj];
+ } else {
+ // This file was already opened from the CLI. Cocoa is trying to
+ // open it again using events. Ignore it!
+ [app.argumentsList removeObjectAtIndex:place];
+ }
+ }];
+
+ self.files = [filesToOpen sortedArrayUsingSelector:@selector(compare:)];
+ if (self.willStopOnOpenEvent) {
+ [NSApp stop:nil];
+ } else {
+ [self handleFiles];
+ }
+}
+
+- (void)handleFiles
+{
+ void *ctx = talloc_new(NULL);
+ [self.files enumerateObjectsUsingBlock:^(id obj, NSUInteger i, BOOL *_){
+ const char *file = [escape_loadfile_name(obj) UTF8String];
+ const char *append = (i == 0) ? "" : " append";
+ char *cmd = talloc_asprintf(ctx, "loadfile \"%s\"%s", file, append);
+ mp_cmd_t *cmdt = mp_input_parse_cmd(bstr0(cmd), "");
+ mp_input_queue_cmd(self.inputContext, cmdt);
+ }];
+ talloc_free(ctx);
+}
+@end
+
+void cocoa_register_menu_item_action(MPMenuKey key, void* action)
+{
+ [app registerSelector:(SEL)action forKey:key];
+}
+
+void init_cocoa_application(void)
+{
+ NSApp = [NSApplication sharedApplication];
+ app = [[Application alloc] init];
+ [NSApp setDelegate:app];
+ [app initialize_menu];
+ [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
+}
+
+void terminate_cocoa_application(void)
+{
+ [NSApp hide:app];
+ [NSApp terminate:app];
+}
+
+void cocoa_run_runloop(void)
+{
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ [NSApp run];
+ [pool drain];
+}
+
+void cocoa_run_loop_schedule(play_loop_callback callback,
+ should_stop_callback stop_query,
+ void *context,
+ struct input_ctx *input_context,
+ struct mp_fifo *key_fifo)
+{
+ [NSApp setDelegate:app];
+ app.callback = callback;
+ app.context = context;
+ app.shouldStopPlayback = stop_query;
+ app.inputContext = input_context;
+ app.keyFIFO = key_fifo;
+ [app schedule_timer];
+}
+
+void cocoa_post_fake_event(void)
+{
+ NSEvent* event = [NSEvent otherEventWithType:NSApplicationDefined
+ location:NSMakePoint(0,0)
+ modifierFlags:0
+ timestamp:0.0
+ windowNumber:0
+ context:nil
+ subtype:0
+ data1:0
+ data2:0];
+ [NSApp postEvent:event atStart:NO];
+}
+
+static void macosx_wait_fileopen_events()
+{
+ app.willStopOnOpenEvent = YES;
+ cocoa_run_runloop(); // block until done
+}
+
+static void macosx_redirect_output_to_logfile(const char *filename)
+{
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ NSString *log_path = [NSHomeDirectory() stringByAppendingPathComponent:
+ [@"Library/Logs/" stringByAppendingFormat:@"%s.log", filename]];
+ freopen([log_path fileSystemRepresentation], "a", stdout);
+ freopen([log_path fileSystemRepresentation], "a", stderr);
+ [pool release];
+}
+
+static bool psn_matches_current_process(char *psn_arg_to_check)
+{
+ ProcessSerialNumber psn;
+ size_t psn_length = 5+10+1+10;
+ char psn_arg[psn_length+1];
+
+ GetCurrentProcess(&psn);
+ snprintf(psn_arg, 5+10+1+10+1, "-psn_%u_%u",
+ psn.highLongOfPSN, psn.lowLongOfPSN);
+ psn_arg[psn_length]=0;
+
+ return strcmp(psn_arg, psn_arg_to_check) == 0;
+}
+
+void macosx_finder_args_preinit(int *argc, char ***argv)
+{
+ if (*argc==2 && psn_matches_current_process((*argv)[1])) {
+ macosx_redirect_output_to_logfile("mpv");
+ macosx_wait_fileopen_events();
+
+ char **cocoa_argv = talloc_zero_array(NULL, char*, [app.files count] + 2);
+ cocoa_argv[0] = "mpv";
+ cocoa_argv[1] = "--quiet";
+ int cocoa_argc = 2;
+
+ for (NSString *filename in app.files) {
+ cocoa_argv[cocoa_argc] = (char*)[filename UTF8String];
+ cocoa_argc++;
+ }
+
+ *argc = cocoa_argc;
+ *argv = cocoa_argv;
+ } else {
+ for (int i = 0; i < *argc; i++ ) {
+ NSString *arg = [NSString stringWithUTF8String:(*argv)[i]];
+ [app.argumentsList addObject:arg];
+ }
+ }
+}
diff --git a/osdep/macosx_application_objc.h b/osdep/macosx_application_objc.h
new file mode 100644
index 0000000000..340b2a9b1c
--- /dev/null
+++ b/osdep/macosx_application_objc.h
@@ -0,0 +1,40 @@
+/*
+ * 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, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#import <Cocoa/Cocoa.h>
+#include "osdep/macosx_application.h"
+
+@interface Application : NSObject<NSApplicationDelegate>
+- (void)initialize_menu;
+- (void)registerSelector:(SEL)selector forKey:(MPMenuKey)key;
+- (void)call_callback;
+- (void)schedule_timer;
+- (void)stopPlayback;
+
+@property(nonatomic, assign) play_loop_callback callback;
+@property(nonatomic, assign) should_stop_callback shouldStopPlayback;
+@property(nonatomic, assign) void *context;
+@property(nonatomic, assign) struct input_ctx *inputContext;
+@property(nonatomic, assign) struct mp_fifo *keyFIFO;
+@property(nonatomic, retain) NSTimer *callbackTimer;
+@property(nonatomic, retain) NSMutableDictionary *menuItems;
+@property(nonatomic, retain) NSArray *files;
+@property(nonatomic, retain) NSMutableArray *argumentsList;
+@property(nonatomic, assign) BOOL willStopOnOpenEvent;
+@end
+
diff --git a/osdep/macosx_finder_args.h b/osdep/macosx_finder_args.h
deleted file mode 100644
index 33a2936f05..0000000000
--- a/osdep/macosx_finder_args.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * This file is part of mplayer2.
- *
- * mplayer2 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,
- * 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, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef MPLAYER_MACOSX_FINDER_ARGS_H
-#define MPLAYER_MACOSX_FINDER_ARGS_H
-
-#include <stdbool.h>
-#include "core/m_config.h"
-
-struct playlist;
-bool macosx_finder_args(m_config_t *config, struct playlist *files,
- int argc, char **argv);
-
-#endif /* MPLAYER_MACOSX_FINDER_ARGS_H */
diff --git a/osdep/macosx_finder_args.m b/osdep/macosx_finder_args.m
deleted file mode 100644
index e9038deaed..0000000000
--- a/osdep/macosx_finder_args.m
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * This file is part of mplayer2.
- *
- * mplayer2 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,
- * 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, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#import <Cocoa/Cocoa.h>
-#import <ApplicationServices/ApplicationServices.h>
-#include <stdio.h>
-#include "talloc.h"
-#include "core/playlist.h"
-#include "macosx_finder_args.h"
-
-static struct playlist *files = NULL;
-
-void macosx_wait_fileopen_events(void);
-void macosx_redirect_output_to_logfile(const char *filename);
-bool psn_matches_current_process(char *psn_arg_to_check);
-
-@interface FileOpenDelegate : NSObject
-- (void)application:(NSApplication *)sender openFiles:(NSArray *)filenames;
-@end
-
-@implementation FileOpenDelegate
-- (void)application:(NSApplication *)sender openFiles:(NSArray *)filenames
-{
- NSArray *sorted_filenames = [filenames
- sortedArrayUsingSelector:@selector(compare:)];
- files = talloc_zero(NULL, struct playlist);
- for (NSString *filename in sorted_filenames)
- playlist_add_file(files, [filename UTF8String]);
- [NSApp stop:nil]; // stop the runloop (give back control to mplayer2 code)
-}
-@end
-
-void macosx_wait_fileopen_events()
-{
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- NSApp = [NSApplication sharedApplication];
- [NSApp setDelegate: [[[FileOpenDelegate alloc] init] autorelease]];
- [NSApp run]; // block until we recive the fileopen events
- [pool release];
-}
-
-void macosx_redirect_output_to_logfile(const char *filename)
-{
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- NSString *log_path = [NSHomeDirectory() stringByAppendingPathComponent:
- [@"Library/Logs/" stringByAppendingFormat:@"%s.log", filename]];
- freopen([log_path fileSystemRepresentation], "a", stdout);
- freopen([log_path fileSystemRepresentation], "a", stderr);
- [pool release];
-}
-
-bool psn_matches_current_process(char *psn_arg_to_check)
-{
- ProcessSerialNumber psn;
- char psn_arg[5+10+1+10+1];
-
- GetCurrentProcess(&psn);
- snprintf(psn_arg, 5+10+1+10+1, "-psn_%u_%u",
- psn.highLongOfPSN, psn.lowLongOfPSN);
- psn_arg[5+10+1+10]=0;
-
- return strcmp(psn_arg, psn_arg_to_check) == 0;
-}
-
-bool macosx_finder_args(m_config_t *config, struct playlist *pl_files,
- int argc, char **argv)
-{
- if (argc==1 && psn_matches_current_process(argv[0])) {
- macosx_redirect_output_to_logfile("mpv");
- m_config_set_option0(config, "quiet", NULL);
- macosx_wait_fileopen_events();
- }
-
- if (files) {
- playlist_transfer_entries(pl_files, files);
- talloc_free(files);
- files = NULL;
- return true;
- } else {
- return false;
- }
-}
diff --git a/video/out/cocoa_common.m b/video/out/cocoa_common.m
index 8e06e637a4..fba906c9b2 100644
--- a/video/out/cocoa_common.m
+++ b/video/out/cocoa_common.m
@@ -39,6 +39,8 @@
#include "osx_common.h"
#include "core/mp_msg.h"
+#include "osdep/macosx_application.h"
+
#ifndef NSOpenGLPFAOpenGLProfile
#define NSOpenGLPFAOpenGLProfile 99
#endif
@@ -101,7 +103,6 @@ static bool RightAltPressed(NSEvent *event)
@end
struct vo_cocoa_state {
- NSAutoreleasePool *pool;
GLMPlayerWindow *window;
NSOpenGLContext *glContext;
NSOpenGLPixelFormat *pixelFormat;
@@ -136,13 +137,10 @@ struct vo_cocoa_state {
static int _instances = 0;
-static void create_menu(void);
-
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){
- .pool = [[NSAutoreleasePool alloc] init],
.did_resize = NO,
.current_video_size = {0,0},
.previous_video_size = {0,0},
@@ -211,10 +209,6 @@ int vo_cocoa_init(struct vo *vo)
vo->cocoa = vo_cocoa_init_state(vo);
vo->wakeup_period = 0.02;
_instances++;
-
- NSApplicationLoad();
- NSApp = [NSApplication sharedApplication];
- [NSApp setActivationPolicy: NSApplicationActivationPolicyRegular];
disable_power_management(vo);
return 1;
@@ -231,8 +225,6 @@ void vo_cocoa_uninit(struct vo *vo)
s->window = nil;
[s->glContext release];
s->glContext = nil;
- [s->pool release];
- s->pool = nil;
_instances--;
}
@@ -399,8 +391,13 @@ static int create_window(struct vo *vo, uint32_t d_width, uint32_t d_height,
[[NSOpenGLContext alloc] initWithFormat:s->pixelFormat
shareContext:nil];
- create_menu();
+ cocoa_register_menu_item_action(MPM_H_SIZE, @selector(halfSize));
+ cocoa_register_menu_item_action(MPM_N_SIZE, @selector(normalSize));
+ cocoa_register_menu_item_action(MPM_D_SIZE, @selector(doubleSize));
+ cocoa_register_menu_item_action(MPM_MINIMIZE, @selector(performMiniaturize:));
+ cocoa_register_menu_item_action(MPM_ZOOM, @selector(performZoom:));
+ [s->window setRestorable:NO];
[s->window setContentView:glView];
[glView release];
[s->window setAcceptsMouseMovedEvents:YES];
@@ -408,8 +405,8 @@ static int create_window(struct vo *vo, uint32_t d_width, uint32_t d_height,
[s->glContext makeCurrentContext];
[s->window setVideoOutput:vo];
- [NSApp setDelegate:s->window];
[s->window setDelegate:s->window];
+ [s->window makeMainWindow];
[s->window setContentSize:s->current_video_size keepCentered:YES];
[s->window setContentAspectRatio:s->current_video_size];
@@ -519,31 +516,13 @@ int vo_cocoa_check_events(struct vo *vo)
s->cursor_timer = ms_time;
}
- int result = 0;
-
- for (;;) {
- NSEvent* event = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:nil
- inMode:NSEventTrackingRunLoopMode dequeue:YES];
- if (event == nil)
- break;
- [NSApp sendEvent:event];
-
- if (s->did_resize) {
- s->did_resize = NO;
- resize_window(vo);
- result |= VO_EVENT_RESIZE;
- }
- // 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.
- if ([event type] == NSAppKitDefined
- && [event subtype] == NSApplicationActivatedEventType) {
- [s->window makeMainWindow];
- [s->window makeKeyAndOrderFront:nil];
- }
+ if (s->did_resize) {
+ s->did_resize = NO;
+ resize_window(vo);
+ return VO_EVENT_RESIZE;
}
- return result;
+ return 0;
}
void vo_cocoa_fullscreen(struct vo *vo)
@@ -587,53 +566,6 @@ int vo_cocoa_cgl_color_size(struct vo *vo)
return 8;
}
-static NSMenuItem *new_menu_item(NSMenu *parent_menu, NSString *title,
- SEL action, NSString *key_equivalent)
-{
- NSMenuItem *new_item =
- [[NSMenuItem alloc] initWithTitle:title action:action
- keyEquivalent:key_equivalent];
- [parent_menu addItem:new_item];
- return [new_item autorelease];
-}
-
-static NSMenuItem *new_main_menu_item(NSMenu *parent_menu, NSMenu *child_menu,
- NSString *title)
-{
- NSMenuItem *new_item =
- [[NSMenuItem alloc] initWithTitle:title action:nil
- keyEquivalent:@""];
- [new_item setSubmenu:child_menu];
- [parent_menu addItem:new_item];
- return [new_item autorelease];
-}
-
-void create_menu()
-{
- NSAutoreleasePool *pool = [NSAutoreleasePool new];
- NSMenu *main_menu, *m_menu, *w_menu;
- NSMenuItem *app_menu_item;
-
- main_menu = [[NSMenu new] autorelease];
- app_menu_item = [[NSMenuItem new] autorelease];
- [main_menu addItem:app_menu_item];
- [NSApp setMainMenu: main_menu];
-
- m_menu = [[[NSMenu alloc] initWithTitle:@"Movie"] autorelease];
- new_menu_item(m_menu, @"Half Size", @selector(halfSize), @"0");
- new_menu_item(m_menu, @"Normal Size", @selector(normalSize), @"1");
- new_menu_item(m_menu, @"Double Size", @selector(doubleSize), @"2");
-
- new_main_menu_item(main_menu, m_menu, @"Movie");
-
- w_menu = [[[NSMenu alloc] initWithTitle:@"Window"] autorelease];
- new_menu_item(w_menu, @"Minimize", @selector(performMiniaturize:), @"m");
- new_menu_item(w_menu, @"Zoom", @selector(performZoom:), @"z");
-
- new_main_menu_item(main_menu, w_menu, @"Window");
- [pool release];
-}
-
@implementation GLMPlayerWindow
- (void)setVideoOutput:(struct vo *)vo
{</