summaryrefslogtreecommitdiffstats
path: root/osdep/macosx_application.m
diff options
context:
space:
mode:
Diffstat (limited to 'osdep/macosx_application.m')
-rw-r--r--osdep/macosx_application.m375
1 files changed, 0 insertions, 375 deletions
diff --git a/osdep/macosx_application.m b/osdep/macosx_application.m
deleted file mode 100644
index 73503ad..0000000
--- a/osdep/macosx_application.m
+++ /dev/null
@@ -1,375 +0,0 @@
-/*
- * This file is part of mpv.
- *
- * mpv is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with mpv. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <stdio.h>
-#include "config.h"
-#include "mpv_talloc.h"
-
-#include "common/msg.h"
-#include "input/input.h"
-#include "player/client.h"
-#include "options/m_config.h"
-#include "options/options.h"
-
-#import "osdep/macosx_application_objc.h"
-#import "osdep/macosx_events_objc.h"
-#include "osdep/threads.h"
-#include "osdep/main-fn.h"
-
-#if HAVE_MACOS_TOUCHBAR
-#import "osdep/macosx_touchbar.h"
-#endif
-#if HAVE_MACOS_COCOA_CB
-#include "osdep/macOS_swift.h"
-#endif
-
-#define MPV_PROTOCOL @"mpv://"
-
-#define OPT_BASE_STRUCT struct macos_opts
-const struct m_sub_options macos_conf = {
- .opts = (const struct m_option[]) {
- {"macos-title-bar-appearance", OPT_CHOICE(macos_title_bar_appearance,
- {"auto", 0}, {"aqua", 1}, {"darkAqua", 2},
- {"vibrantLight", 3}, {"vibrantDark", 4},
- {"aquaHighContrast", 5}, {"darkAquaHighContrast", 6},
- {"vibrantLightHighContrast", 7},
- {"vibrantDarkHighContrast", 8})},
- {"macos-title-bar-material", OPT_CHOICE(macos_title_bar_material,
- {"titlebar", 0}, {"selection", 1}, {"menu", 2},
- {"popover", 3}, {"sidebar", 4}, {"headerView", 5},
- {"sheet", 6}, {"windowBackground", 7}, {"hudWindow", 8},
- {"fullScreen", 9}, {"toolTip", 10}, {"contentBackground", 11},
- {"underWindowBackground", 12}, {"underPageBackground", 13},
- {"dark", 14}, {"light", 15}, {"mediumLight", 16},
- {"ultraDark", 17})},
- {"macos-title-bar-color", OPT_COLOR(macos_title_bar_color)},
- {"macos-fs-animation-duration",
- OPT_CHOICE(macos_fs_animation_duration, {"default", -1}),
- M_RANGE(0, 1000)},
- {"macos-force-dedicated-gpu", OPT_BOOL(macos_force_dedicated_gpu)},
- {"macos-app-activation-policy", OPT_CHOICE(macos_app_activation_policy,
- {"regular", 0}, {"accessory", 1}, {"prohibited", 2})},
- {"macos-geometry-calculation", OPT_CHOICE(macos_geometry_calculation,
- {"visible", FRAME_VISIBLE}, {"whole", FRAME_WHOLE})},
- {"macos-render-timer", OPT_CHOICE(macos_render_timer,
- {"callback", RENDER_TIMER_CALLBACK}, {"precise", RENDER_TIMER_PRECISE},
- {"system", RENDER_TIMER_SYSTEM})},
- {"cocoa-cb-sw-renderer", OPT_CHOICE(cocoa_cb_sw_renderer,
- {"auto", -1}, {"no", 0}, {"yes", 1})},
- {"cocoa-cb-10bit-context", OPT_BOOL(cocoa_cb_10bit_context)},
- {0}
- },
- .size = sizeof(struct macos_opts),
- .defaults = &(const struct macos_opts){
- .macos_title_bar_color = {0, 0, 0, 0},
- .macos_fs_animation_duration = -1,
- .cocoa_cb_sw_renderer = -1,
- .cocoa_cb_10bit_context = true
- },
-};
-
-// Whether the NSApplication singleton was created. If this is false, we are
-// running in libmpv mode, and cocoa_main() was never called.
-static bool application_instantiated;
-
-static mp_thread playback_thread_id;
-
-@interface Application ()
-{
- EventsResponder *_eventsResponder;
-}
-
-@end
-
-static Application *mpv_shared_app(void)
-{
- return (Application *)[Application sharedApplication];
-}
-
-static void terminate_cocoa_application(void)
-{
- dispatch_async(dispatch_get_main_queue(), ^{
- [NSApp hide:NSApp];
- [NSApp terminate:NSApp];
- });
-}
-
-@implementation Application
-@synthesize menuBar = _menu_bar;
-@synthesize openCount = _open_count;
-@synthesize cocoaCB = _cocoa_cb;
-
-- (void)sendEvent:(NSEvent *)event
-{
- if ([self modalWindow] || ![_eventsResponder processKeyEvent:event])
- [super sendEvent:event];
- [_eventsResponder wakeup];
-}
-
-- (id)init
-{
- if (self = [super init]) {
- _eventsResponder = [EventsResponder sharedInstance];
-
- NSAppleEventManager *em = [NSAppleEventManager sharedAppleEventManager];
- [em setEventHandler:self
- andSelector:@selector(getUrl:withReplyEvent:)
- forEventClass:kInternetEventClass
- andEventID:kAEGetURL];
- }
-
- return self;
-}
-
-- (void)dealloc
-{
- NSAppleEventManager *em = [NSAppleEventManager sharedAppleEventManager];
- [em removeEventHandlerForEventClass:kInternetEventClass
- andEventID:kAEGetURL];
- [em removeEventHandlerForEventClass:kCoreEventClass
- andEventID:kAEQuitApplication];
- [super dealloc];
-}
-
-static const char macosx_icon[] =
-#include "TOOLS/osxbundle/icon.icns.inc"
-;
-
-- (NSImage *)getMPVIcon
-{
- // The C string contains a trailing null, so we strip it away
- NSData *icon_data = [NSData dataWithBytesNoCopy:(void *)macosx_icon
- length:sizeof(macosx_icon) - 1
- freeWhenDone:NO];
- return [[NSImage alloc] initWithData:icon_data];
-}
-
-#if HAVE_MACOS_TOUCHBAR
-- (NSTouchBar *)makeTouchBar
-{
- TouchBar *tBar = [[TouchBar alloc] init];
- [tBar setApp:self];
- tBar.delegate = tBar;
- tBar.customizationIdentifier = customID;
- tBar.defaultItemIdentifiers = @[play, previousItem, nextItem, seekBar];
- tBar.customizationAllowedItemIdentifiers = @[play, seekBar, previousItem,
- nextItem, previousChapter, nextChapter, cycleAudio, cycleSubtitle,
- currentPosition, timeLeft];
- return tBar;
-}
-#endif
-
-- (void)processEvent:(struct mpv_event *)event
-{
-#if HAVE_MACOS_TOUCHBAR
- [(TouchBar *)self.touchBar processEvent:event];
-#endif
- if (_cocoa_cb) {
- [_cocoa_cb processEvent:event];
- }
-}
-
-- (void)setMpvHandle:(struct mpv_handle *)ctx
-{
-#if HAVE_MACOS_COCOA_CB
- [NSApp setCocoaCB:[[CocoaCB alloc] init:ctx]];
-#endif
-}
-
-- (const struct m_sub_options *)getMacOSConf
-{
- return &macos_conf;
-}
-
-- (const struct m_sub_options *)getVoSubConf
-{
- return &vo_sub_opts;
-}
-
-- (void)queueCommand:(char *)cmd
-{
- [_eventsResponder queueCommand:cmd];
-}
-
-- (void)stopMPV:(char *)cmd
-{
- if (![_eventsResponder queueCommand:cmd])
- terminate_cocoa_application();
-}
-
-- (void)applicationWillFinishLaunching:(NSNotification *)notification
-{
- NSAppleEventManager *em = [NSAppleEventManager sharedAppleEventManager];
- [em setEventHandler:self
- andSelector:@selector(handleQuitEvent:withReplyEvent:)
- forEventClass:kCoreEventClass
- andEventID:kAEQuitApplication];
-}
-
-- (void)handleQuitEvent:(NSAppleEventDescriptor *)event
- withReplyEvent:(NSAppleEventDescriptor *)replyEvent
-{
- [self stopMPV:"quit"];
-}
-
-- (void)getUrl:(NSAppleEventDescriptor *)event
- withReplyEvent:(NSAppleEventDescriptor *)replyEvent
-{
- NSString *url =
- [[event paramDescriptorForKeyword:keyDirectObject] stringValue];
-
- url = [url stringByReplacingOccurrencesOfString:MPV_PROTOCOL
- withString:@""
- options:NSAnchoredSearch
- range:NSMakeRange(0, [MPV_PROTOCOL length])];
-
- url = [url stringByRemovingPercentEncoding];
- [_eventsResponder handleFilesArray:@[url]];
-}
-
-- (void)application:(NSApplication *)sender openFiles:(NSArray *)filenames
-{
- if (mpv_shared_app().openCount > 0) {
- mpv_shared_app().openCount--;
- return;
- }
- [self openFiles:filenames];
-}
-
-- (void)openFiles:(NSArray *)filenames
-{
- SEL cmpsel = @selector(localizedStandardCompare:);
- NSArray *files = [filenames sortedArrayUsingSelector:cmpsel];
- [_eventsResponder handleFilesArray:files];
-}
-@end
-
-struct playback_thread_ctx {
- int *argc;
- char ***argv;
-};
-
-static void cocoa_run_runloop(void)
-{
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- [NSApp run];
- [pool drain];
-}
-
-static MP_THREAD_VOID playback_thread(void *ctx_obj)
-{
- mp_thread_set_name("core/playback");
- @autoreleasepool {
- struct playback_thread_ctx *ctx = (struct playback_thread_ctx*) ctx_obj;
- int r = mpv_main(*ctx->argc, *ctx->argv);
- terminate_cocoa_application();
- // normally never reached - unless the cocoa mainloop hasn't started yet
- exit(r);
- }
-}
-
-void cocoa_register_menu_item_action(MPMenuKey key, void* action)
-{
- if (application_instantiated)
- [[NSApp menuBar] registerSelector:(SEL)action forKey:key];
-}
-
-static void init_cocoa_application(bool regular)
-{
- NSApp = mpv_shared_app();
- [NSApp setDelegate:NSApp];
- [NSApp setMenuBar:[[MenuBar alloc] init]];
-
- // Will be set to Regular from cocoa_common during UI creation so that we
- // don't create an icon when playing audio only files.
- [NSApp setActivationPolicy: regular ?
- NSApplicationActivationPolicyRegular :
- NSApplicationActivationPolicyAccessory];
-
- atexit_b(^{
- // Because activation policy has just been set to behave like a real
- // application, that policy must be reset on exit to prevent, among
- // other things, the menubar created here from remaining on screen.
- dispatch_async(dispatch_get_main_queue(), ^{
- [NSApp setActivationPolicy:NSApplicationActivationPolicyProhibited];
- });
- });
-}
-
-static bool bundle_started_from_finder()
-{
- NSString* bundle = [[[NSProcessInfo processInfo] environment] objectForKey:@"MPVBUNDLE"];
- return [bundle isEqual:@"true"];
-}
-
-static bool is_psn_argument(char *arg_to_check)
-{
- NSString *arg = [NSString stringWithUTF8String:arg_to_check];
- return [arg hasPrefix:@"-psn_"];
-}
-
-static void setup_bundle(int *argc, char *argv[])
-{
- if (*argc > 1 && is_psn_argument(argv[1])) {
- *argc = 1;
- argv[1] = NULL;
- }
-
- NSDictionary *env = [[NSProcessInfo processInfo] environment];
- NSString *path_bundle = [env objectForKey:@"PATH"];
- NSString *path_new = [NSString stringWithFormat:@"%@:%@:%@:%@:%@",
- path_bundle,
- @"/usr/local/bin",
- @"/usr/local/sbin",
- @"/opt/local/bin",
- @"/opt/local/sbin"];
- setenv("PATH", [path_new UTF8String], 1);
-}
-
-int cocoa_main(int argc, char *argv[])
-{
- @autoreleasepool {
- application_instantiated = true;
- [[EventsResponder sharedInstance] setIsApplication:YES];
-
- struct playback_thread_ctx ctx = {0};
- ctx.argc = &argc;
- ctx.argv = &argv;
-
- if (bundle_started_from_finder()) {
- setup_bundle(&argc, argv);
- init_cocoa_application(true);
- } else {
- for (int i = 1; i < argc; i++)
- if (argv[i][0] != '-')
- mpv_shared_app().openCount++;
- init_cocoa_application(false);
- }
-
- mp_thread_create(&playback_thread_id, playback_thread, &ctx);
- [[EventsResponder sharedInstance] waitForInputContext];
- cocoa_run_runloop();
-
- // This should never be reached: cocoa_run_runloop blocks until the
- // process is quit
- fprintf(stderr, "There was either a problem "
- "initializing Cocoa or the Runloop was stopped unexpectedly. "
- "Please report this issues to a developer.\n");
- mp_thread_join(playback_thread_id);
- return 1;
- }
-}