diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 01:13:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 01:13:14 +0000 |
commit | 5a3b54c78ce63d899f76dbb3db72e4894b40bd53 (patch) | |
tree | 50693d13eeefc4d683bdf5417f0861b0ef274a0c /osdep/macos | |
parent | Adding debian version 0.37.0-1. (diff) | |
download | mpv-5a3b54c78ce63d899f76dbb3db72e4894b40bd53.tar.xz mpv-5a3b54c78ce63d899f76dbb3db72e4894b40bd53.zip |
Merging upstream version 0.38.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'osdep/macos')
-rw-r--r-- | osdep/macos/libmpv_helper.swift | 250 | ||||
-rw-r--r-- | osdep/macos/log_helper.swift | 47 | ||||
-rw-r--r-- | osdep/macos/mpv_helper.swift | 156 | ||||
-rw-r--r-- | osdep/macos/precise_timer.swift | 153 | ||||
-rw-r--r-- | osdep/macos/remote_command_center.swift | 191 | ||||
-rw-r--r-- | osdep/macos/swift_compat.swift | 36 | ||||
-rw-r--r-- | osdep/macos/swift_extensions.swift | 58 |
7 files changed, 0 insertions, 891 deletions
diff --git a/osdep/macos/libmpv_helper.swift b/osdep/macos/libmpv_helper.swift deleted file mode 100644 index 8b1c697..0000000 --- a/osdep/macos/libmpv_helper.swift +++ /dev/null @@ -1,250 +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/>. - */ - -import Cocoa -import OpenGL.GL -import OpenGL.GL3 - -let glDummy: @convention(c) () -> Void = {} - -class LibmpvHelper { - var log: LogHelper - var mpvHandle: OpaquePointer? - var mpvRenderContext: OpaquePointer? - var macOptsPtr: UnsafeMutableRawPointer? - var macOpts: macos_opts = macos_opts() - var fbo: GLint = 1 - let deinitLock = NSLock() - - init(_ mpv: OpaquePointer, _ mpLog: OpaquePointer?) { - mpvHandle = mpv - log = LogHelper(mpLog) - - guard let app = NSApp as? Application, - let ptr = mp_get_config_group(nil, - mp_client_get_global(mpvHandle), - app.getMacOSConf()) else - { - log.sendError("macOS config group couldn't be retrieved'") - exit(1) - } - macOptsPtr = ptr - macOpts = UnsafeMutablePointer<macos_opts>(OpaquePointer(ptr)).pointee - } - - func initRender() { - let advanced: CInt = 1 - let api = UnsafeMutableRawPointer(mutating: (MPV_RENDER_API_TYPE_OPENGL as NSString).utf8String) - let pAddress = mpv_opengl_init_params(get_proc_address: getProcAddress, - get_proc_address_ctx: nil) - - MPVHelper.withUnsafeMutableRawPointers([pAddress, advanced]) { (pointers: [UnsafeMutableRawPointer?]) in - var params: [mpv_render_param] = [ - mpv_render_param(type: MPV_RENDER_PARAM_API_TYPE, data: api), - mpv_render_param(type: MPV_RENDER_PARAM_OPENGL_INIT_PARAMS, data: pointers[0]), - mpv_render_param(type: MPV_RENDER_PARAM_ADVANCED_CONTROL, data: pointers[1]), - mpv_render_param() - ] - - if (mpv_render_context_create(&mpvRenderContext, mpvHandle, ¶ms) < 0) { - log.sendError("Render context init has failed.") - exit(1) - } - } - - } - - let getProcAddress: (@convention(c) (UnsafeMutableRawPointer?, UnsafePointer<Int8>?) - -> UnsafeMutableRawPointer?) = - { - (ctx: UnsafeMutableRawPointer?, name: UnsafePointer<Int8>?) - -> UnsafeMutableRawPointer? in - let symbol: CFString = CFStringCreateWithCString( - kCFAllocatorDefault, name, kCFStringEncodingASCII) - let identifier = CFBundleGetBundleWithIdentifier("com.apple.opengl" as CFString) - let addr = CFBundleGetFunctionPointerForName(identifier, symbol) - - if symbol as String == "glFlush" { - return unsafeBitCast(glDummy, to: UnsafeMutableRawPointer.self) - } - - return addr - } - - func setRenderUpdateCallback(_ callback: @escaping mpv_render_update_fn, context object: AnyObject) { - if mpvRenderContext == nil { - log.sendWarning("Init mpv render context first.") - } else { - mpv_render_context_set_update_callback(mpvRenderContext, callback, MPVHelper.bridge(obj: object)) - } - } - - func setRenderControlCallback(_ callback: @escaping mp_render_cb_control_fn, context object: AnyObject) { - if mpvRenderContext == nil { - log.sendWarning("Init mpv render context first.") - } else { - mp_render_context_set_control_callback(mpvRenderContext, callback, MPVHelper.bridge(obj: object)) - } - } - - func reportRenderFlip() { - if mpvRenderContext == nil { return } - mpv_render_context_report_swap(mpvRenderContext) - } - - func isRenderUpdateFrame() -> Bool { - deinitLock.lock() - if mpvRenderContext == nil { - deinitLock.unlock() - return false - } - let flags: UInt64 = mpv_render_context_update(mpvRenderContext) - deinitLock.unlock() - return flags & UInt64(MPV_RENDER_UPDATE_FRAME.rawValue) > 0 - } - - func drawRender(_ surface: NSSize, _ depth: GLint, _ ctx: CGLContextObj, skip: Bool = false) { - deinitLock.lock() - if mpvRenderContext != nil { - var i: GLint = 0 - let flip: CInt = 1 - let skip: CInt = skip ? 1 : 0 - let ditherDepth = depth - glGetIntegerv(GLenum(GL_DRAW_FRAMEBUFFER_BINDING), &i) - // CAOpenGLLayer has ownership of FBO zero yet can return it to us, - // so only utilize a newly received FBO ID if it is nonzero. - fbo = i != 0 ? i : fbo - - let data = mpv_opengl_fbo(fbo: Int32(fbo), - w: Int32(surface.width), - h: Int32(surface.height), - internal_format: 0) - - MPVHelper.withUnsafeMutableRawPointers([data, flip, ditherDepth, skip]) { (pointers: [UnsafeMutableRawPointer?]) in - var params: [mpv_render_param] = [ - mpv_render_param(type: MPV_RENDER_PARAM_OPENGL_FBO, data: pointers[0]), - mpv_render_param(type: MPV_RENDER_PARAM_FLIP_Y, data: pointers[1]), - mpv_render_param(type: MPV_RENDER_PARAM_DEPTH, data: pointers[2]), - mpv_render_param(type: MPV_RENDER_PARAM_SKIP_RENDERING, data: pointers[3]), - mpv_render_param() - ] - mpv_render_context_render(mpvRenderContext, ¶ms); - } - } else { - glClearColor(0, 0, 0, 1) - glClear(GLbitfield(GL_COLOR_BUFFER_BIT)) - } - - if !skip { CGLFlushDrawable(ctx) } - - deinitLock.unlock() - } - - func setRenderICCProfile(_ profile: NSColorSpace) { - if mpvRenderContext == nil { return } - guard var iccData = profile.iccProfileData else { - log.sendWarning("Invalid ICC profile data.") - return - } - iccData.withUnsafeMutableBytes { (ptr: UnsafeMutableRawBufferPointer) in - guard let baseAddress = ptr.baseAddress, ptr.count > 0 else { return } - - let u8Ptr = baseAddress.assumingMemoryBound(to: UInt8.self) - let iccBstr = bstrdup(nil, bstr(start: u8Ptr, len: ptr.count)) - var icc = mpv_byte_array(data: iccBstr.start, size: iccBstr.len) - withUnsafeMutableBytes(of: &icc) { (ptr: UnsafeMutableRawBufferPointer) in - let params = mpv_render_param(type: MPV_RENDER_PARAM_ICC_PROFILE, data: ptr.baseAddress) - mpv_render_context_set_parameter(mpvRenderContext, params) - } - } - } - - func setRenderLux(_ lux: Int) { - if mpvRenderContext == nil { return } - var light = lux - withUnsafeMutableBytes(of: &light) { (ptr: UnsafeMutableRawBufferPointer) in - let params = mpv_render_param(type: MPV_RENDER_PARAM_AMBIENT_LIGHT, data: ptr.baseAddress) - mpv_render_context_set_parameter(mpvRenderContext, params) - } - } - - func commandAsync(_ cmd: [String?], id: UInt64 = 1) { - if mpvHandle == nil { return } - var mCmd = cmd - mCmd.append(nil) - var cargs = mCmd.map { $0.flatMap { UnsafePointer<Int8>(strdup($0)) } } - mpv_command_async(mpvHandle, id, &cargs) - for ptr in cargs { free(UnsafeMutablePointer(mutating: ptr)) } - } - - // Unsafe function when called while using the render API - func command(_ cmd: String) { - if mpvHandle == nil { return } - mpv_command_string(mpvHandle, cmd) - } - - func getBoolProperty(_ name: String) -> Bool { - if mpvHandle == nil { return false } - var value = Int32() - mpv_get_property(mpvHandle, name, MPV_FORMAT_FLAG, &value) - return value > 0 - } - - func getIntProperty(_ name: String) -> Int { - if mpvHandle == nil { return 0 } - var value = Int64() - mpv_get_property(mpvHandle, name, MPV_FORMAT_INT64, &value) - return Int(value) - } - - func getStringProperty(_ name: String) -> String? { - guard let mpv = mpvHandle else { return nil } - guard let value = mpv_get_property_string(mpv, name) else { return nil } - let str = String(cString: value) - mpv_free(value) - return str - } - - func deinitRender() { - mpv_render_context_set_update_callback(mpvRenderContext, nil, nil) - mp_render_context_set_control_callback(mpvRenderContext, nil, nil) - deinitLock.lock() - mpv_render_context_free(mpvRenderContext) - mpvRenderContext = nil - deinitLock.unlock() - } - - func deinitMPV(_ destroy: Bool = false) { - if destroy { - mpv_destroy(mpvHandle) - } - ta_free(macOptsPtr) - macOptsPtr = nil - mpvHandle = nil - } - - // *(char **) MPV_FORMAT_STRING on mpv_event_property - class func mpvStringArrayToString(_ obj: UnsafeMutableRawPointer) -> String? { - let cstr = UnsafeMutablePointer<UnsafeMutablePointer<Int8>>(OpaquePointer(obj)) - return String(cString: cstr[0]) - } - - // MPV_FORMAT_FLAG - class func mpvFlagToBool(_ obj: UnsafeMutableRawPointer) -> Bool? { - return UnsafePointer<Bool>(OpaquePointer(obj))?.pointee - } -} diff --git a/osdep/macos/log_helper.swift b/osdep/macos/log_helper.swift deleted file mode 100644 index 9464075..0000000 --- a/osdep/macos/log_helper.swift +++ /dev/null @@ -1,47 +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/>. - */ - -import Cocoa - -class LogHelper: NSObject { - var log: OpaquePointer? - - init(_ log: OpaquePointer?) { - self.log = log - } - - func sendVerbose(_ msg: String) { - send(message: msg, type: MSGL_V) - } - - func sendInfo(_ msg: String) { - send(message: msg, type: MSGL_INFO) - } - - func sendWarning(_ msg: String) { - send(message: msg, type: MSGL_WARN) - } - - func sendError(_ msg: String) { - send(message: msg, type: MSGL_ERR) - } - - func send(message msg: String, type t: Int) { - let args: [CVarArg] = [ (msg as NSString).utf8String ?? "NO MESSAGE"] - mp_msg_va(log, Int32(t), "%s\n", getVaList(args)) - } -} diff --git a/osdep/macos/mpv_helper.swift b/osdep/macos/mpv_helper.swift deleted file mode 100644 index 3b2a716..0000000 --- a/osdep/macos/mpv_helper.swift +++ /dev/null @@ -1,156 +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/>. - */ - -import Cocoa - -typealias swift_wakeup_cb_fn = (@convention(c) (UnsafeMutableRawPointer?) -> Void)? - -class MPVHelper { - var log: LogHelper - var vo: UnsafeMutablePointer<vo> - var optsCachePtr: UnsafeMutablePointer<m_config_cache> - var optsPtr: UnsafeMutablePointer<mp_vo_opts> - var macOptsCachePtr: UnsafeMutablePointer<m_config_cache> - var macOptsPtr: UnsafeMutablePointer<macos_opts> - - // these computed properties return a local copy of the struct accessed: - // - don't use if you rely on the pointers - // - only for reading - var vout: vo { get { return vo.pointee } } - var optsCache: m_config_cache { get { return optsCachePtr.pointee } } - var opts: mp_vo_opts { get { return optsPtr.pointee } } - var macOptsCache: m_config_cache { get { return macOptsCachePtr.pointee } } - var macOpts: macos_opts { get { return macOptsPtr.pointee } } - - var input: OpaquePointer { get { return vout.input_ctx } } - - init(_ vo: UnsafeMutablePointer<vo>, _ log: LogHelper) { - self.vo = vo - self.log = log - - guard let app = NSApp as? Application, - let cache = m_config_cache_alloc(vo, vo.pointee.global, app.getVoSubConf()) else - { - log.sendError("NSApp couldn't be retrieved") - exit(1) - } - - optsCachePtr = cache - optsPtr = UnsafeMutablePointer<mp_vo_opts>(OpaquePointer(cache.pointee.opts)) - - guard let macCache = m_config_cache_alloc(vo, - vo.pointee.global, - app.getMacOSConf()) else - { - // will never be hit, mp_get_config_group asserts for invalid groups - exit(1) - } - macOptsCachePtr = macCache - macOptsPtr = UnsafeMutablePointer<macos_opts>(OpaquePointer(macCache.pointee.opts)) - } - - func canBeDraggedAt(_ pos: NSPoint) -> Bool { - let canDrag = !mp_input_test_dragging(input, Int32(pos.x), Int32(pos.y)) - return canDrag - } - - func mouseEnabled() -> Bool { - return mp_input_mouse_enabled(input) - } - - func setMousePosition(_ pos: NSPoint) { - mp_input_set_mouse_pos(input, Int32(pos.x), Int32(pos.y)) - } - - func putAxis(_ mpkey: Int32, delta: Double) { - mp_input_put_wheel(input, mpkey, delta) - } - - func nextChangedOption(property: inout UnsafeMutableRawPointer?) -> Bool { - return m_config_cache_get_next_changed(optsCachePtr, &property) - } - - func setOption(fullscreen: Bool) { - optsPtr.pointee.fullscreen = fullscreen - _ = withUnsafeMutableBytes(of: &optsPtr.pointee.fullscreen) { (ptr: UnsafeMutableRawBufferPointer) in - m_config_cache_write_opt(optsCachePtr, ptr.baseAddress) - } - } - - func setOption(minimized: Bool) { - optsPtr.pointee.window_minimized = minimized - _ = withUnsafeMutableBytes(of: &optsPtr.pointee.window_minimized) { (ptr: UnsafeMutableRawBufferPointer) in - m_config_cache_write_opt(optsCachePtr, ptr.baseAddress) - } - } - - func setOption(maximized: Bool) { - optsPtr.pointee.window_maximized = maximized - _ = withUnsafeMutableBytes(of: &optsPtr.pointee.window_maximized) { (ptr: UnsafeMutableRawBufferPointer) in - m_config_cache_write_opt(optsCachePtr, ptr.baseAddress) - } - } - - func setMacOptionCallback(_ callback: swift_wakeup_cb_fn, context object: AnyObject) { - m_config_cache_set_wakeup_cb(macOptsCachePtr, callback, MPVHelper.bridge(obj: object)) - } - - func nextChangedMacOption(property: inout UnsafeMutableRawPointer?) -> Bool { - return m_config_cache_get_next_changed(macOptsCachePtr, &property) - } - - func command(_ cmd: String) { - let cCmd = UnsafePointer<Int8>(strdup(cmd)) - let mpvCmd = mp_input_parse_cmd(input, bstr0(cCmd), "") - mp_input_queue_cmd(input, mpvCmd) - free(UnsafeMutablePointer(mutating: cCmd)) - } - - // (__bridge void*) - class func bridge<T: AnyObject>(obj: T) -> UnsafeMutableRawPointer { - return UnsafeMutableRawPointer(Unmanaged.passUnretained(obj).toOpaque()) - } - - // (__bridge T*) - class func bridge<T: AnyObject>(ptr: UnsafeRawPointer) -> T { - return Unmanaged<T>.fromOpaque(ptr).takeUnretainedValue() - } - - class func withUnsafeMutableRawPointers(_ arguments: [Any], - pointers: [UnsafeMutableRawPointer?] = [], - closure: (_ pointers: [UnsafeMutableRawPointer?]) -> Void) { - if arguments.count > 0 { - let args = Array(arguments.dropFirst(1)) - var newPtrs = pointers - var firstArg = arguments.first - withUnsafeMutableBytes(of: &firstArg) { (ptr: UnsafeMutableRawBufferPointer) in - newPtrs.append(ptr.baseAddress) - withUnsafeMutableRawPointers(args, pointers: newPtrs, closure: closure) - } - - return - } - - closure(pointers) - } - - class func getPointer<T>(_ value: inout T) -> UnsafeMutableRawPointer? { - return withUnsafeMutableBytes(of: &value) { (ptr: UnsafeMutableRawBufferPointer) in - ptr.baseAddress - } - } -} diff --git a/osdep/macos/precise_timer.swift b/osdep/macos/precise_timer.swift deleted file mode 100644 index f4ad3bb..0000000 --- a/osdep/macos/precise_timer.swift +++ /dev/null @@ -1,153 +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/>. - */ - -import Cocoa - -struct Timing { - let time: UInt64 - let closure: () -> () -} - -class PreciseTimer { - unowned var common: Common - var mpv: MPVHelper? { get { return common.mpv } } - - let nanoPerSecond: Double = 1e+9 - let machToNano: Double = { - var timebase: mach_timebase_info = mach_timebase_info() - mach_timebase_info(&timebase) - return Double(timebase.numer) / Double(timebase.denom) - }() - - let condition = NSCondition() - var events: [Timing] = [] - var isRunning: Bool = true - var isHighPrecision: Bool = false - - var thread: pthread_t! - var threadPort: thread_port_t = thread_port_t() - let policyFlavor = thread_policy_flavor_t(THREAD_TIME_CONSTRAINT_POLICY) - let policyCount = MemoryLayout<thread_time_constraint_policy>.size / - MemoryLayout<integer_t>.size - var typeNumber: mach_msg_type_number_t { - return mach_msg_type_number_t(policyCount) - } - var threadAttr: pthread_attr_t = { - var attr = pthread_attr_t() - var param = sched_param() - pthread_attr_init(&attr) - param.sched_priority = sched_get_priority_max(SCHED_FIFO) - pthread_attr_setschedparam(&attr, ¶m) - pthread_attr_setschedpolicy(&attr, SCHED_FIFO) - return attr - }() - - init?(common com: Common) { - common = com - - pthread_create(&thread, &threadAttr, entryC, MPVHelper.bridge(obj: self)) - if thread == nil { - common.log.sendWarning("Couldn't create pthread for high precision timer") - return nil - } - - threadPort = pthread_mach_thread_np(thread) - } - - func updatePolicy(periodSeconds: Double = 1 / 60.0) { - let period = periodSeconds * nanoPerSecond / machToNano - var policy = thread_time_constraint_policy( - period: UInt32(period), - computation: UInt32(0.75 * period), - constraint: UInt32(0.85 * period), - preemptible: 1 - ) - - let success = withUnsafeMutablePointer(to: &policy) { - $0.withMemoryRebound(to: integer_t.self, capacity: policyCount) { - thread_policy_set(threadPort, policyFlavor, $0, typeNumber) - } - } - - isHighPrecision = success == KERN_SUCCESS - if !isHighPrecision { - common.log.sendWarning("Couldn't create a high precision timer") - } - } - - func terminate() { - condition.lock() - isRunning = false - condition.signal() - condition.unlock() - pthread_kill(thread, SIGALRM) - pthread_join(thread, nil) - } - - func scheduleAt(time: UInt64, closure: @escaping () -> ()) { - condition.lock() - let firstEventTime = events.first?.time ?? 0 - let lastEventTime = events.last?.time ?? 0 - events.append(Timing(time: time, closure: closure)) - - if lastEventTime > time { - events.sort{ $0.time < $1.time } - } - - condition.signal() - condition.unlock() - - if firstEventTime > time { - pthread_kill(thread, SIGALRM) - } - } - - let threadSignal: @convention(c) (Int32) -> () = { (sig: Int32) in } - - let entryC: @convention(c) (UnsafeMutableRawPointer) -> UnsafeMutableRawPointer? = { (ptr: UnsafeMutableRawPointer) in - let ptimer: PreciseTimer = MPVHelper.bridge(ptr: ptr) - ptimer.entry() - return nil - } - - func entry() { - signal(SIGALRM, threadSignal) - - while isRunning { - condition.lock() - while events.count == 0 && isRunning { - condition.wait() - } - - if !isRunning { break } - - guard let event = events.first else { - continue - } - condition.unlock() - - mach_wait_until(event.time) - - condition.lock() - if events.first?.time == event.time && isRunning { - event.closure() - events.removeFirst() - } - condition.unlock() - } - } -} diff --git a/osdep/macos/remote_command_center.swift b/osdep/macos/remote_command_center.swift deleted file mode 100644 index 6fb2229..0000000 --- a/osdep/macos/remote_command_center.swift +++ /dev/null @@ -1,191 +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/>. - */ - -import MediaPlayer - -class RemoteCommandCenter: NSObject { - enum KeyType { - case normal - case repeatable - } - - var config: [MPRemoteCommand:[String:Any]] = [ - MPRemoteCommandCenter.shared().pauseCommand: [ - "mpKey": MP_KEY_PAUSEONLY, - "keyType": KeyType.normal - ], - MPRemoteCommandCenter.shared().playCommand: [ - "mpKey": MP_KEY_PLAYONLY, - "keyType": KeyType.normal - ], - MPRemoteCommandCenter.shared().stopCommand: [ - "mpKey": MP_KEY_STOP, - "keyType": KeyType.normal - ], - MPRemoteCommandCenter.shared().nextTrackCommand: [ - "mpKey": MP_KEY_NEXT, - "keyType": KeyType.normal - ], - MPRemoteCommandCenter.shared().previousTrackCommand: [ - "mpKey": MP_KEY_PREV, - "keyType": KeyType.normal - ], - MPRemoteCommandCenter.shared().togglePlayPauseCommand: [ - "mpKey": MP_KEY_PLAY, - "keyType": KeyType.normal - ], - MPRemoteCommandCenter.shared().seekForwardCommand: [ - "mpKey": MP_KEY_FORWARD, - "keyType": KeyType.repeatable, - "state": MP_KEY_STATE_UP - ], - MPRemoteCommandCenter.shared().seekBackwardCommand: [ - "mpKey": MP_KEY_REWIND, - "keyType": KeyType.repeatable, - "state": MP_KEY_STATE_UP - ], - ] - - var nowPlayingInfo: [String: Any] = [ - MPNowPlayingInfoPropertyMediaType: NSNumber(value: MPNowPlayingInfoMediaType.video.rawValue), - MPNowPlayingInfoPropertyDefaultPlaybackRate: NSNumber(value: 1), - MPNowPlayingInfoPropertyPlaybackProgress: NSNumber(value: 0.0), - MPMediaItemPropertyPlaybackDuration: NSNumber(value: 0), - MPMediaItemPropertyTitle: "mpv", - MPMediaItemPropertyAlbumTitle: "mpv", - MPMediaItemPropertyArtist: "mpv", - ] - - let disabledCommands: [MPRemoteCommand] = [ - MPRemoteCommandCenter.shared().changePlaybackRateCommand, - MPRemoteCommandCenter.shared().changeRepeatModeCommand, - MPRemoteCommandCenter.shared().changeShuffleModeCommand, - MPRemoteCommandCenter.shared().skipForwardCommand, - MPRemoteCommandCenter.shared().skipBackwardCommand, - MPRemoteCommandCenter.shared().changePlaybackPositionCommand, - MPRemoteCommandCenter.shared().enableLanguageOptionCommand, - MPRemoteCommandCenter.shared().disableLanguageOptionCommand, - MPRemoteCommandCenter.shared().ratingCommand, - MPRemoteCommandCenter.shared().likeCommand, - MPRemoteCommandCenter.shared().dislikeCommand, - MPRemoteCommandCenter.shared().bookmarkCommand, - ] - - var mpInfoCenter: MPNowPlayingInfoCenter { get { return MPNowPlayingInfoCenter.default() } } - var isPaused: Bool = false { didSet { updatePlaybackState() } } - - @objc override init() { - super.init() - - for cmd in disabledCommands { - cmd.isEnabled = false - } - } - - @objc func start() { - for (cmd, _) in config { - cmd.isEnabled = true - cmd.addTarget { [unowned self] event in - return self.cmdHandler(event) - } - } - - if let app = NSApp as? Application, let icon = app.getMPVIcon() { - let albumArt = MPMediaItemArtwork(boundsSize: icon.size) { _ in - return icon - } - nowPlayingInfo[MPMediaItemPropertyArtwork] = albumArt - } - - mpInfoCenter.nowPlayingInfo = nowPlayingInfo - mpInfoCenter.playbackState = .playing - - NotificationCenter.default.addObserver( - self, - selector: #selector(self.makeCurrent), - name: NSApplication.willBecomeActiveNotification, - object: nil - ) - } - - @objc func stop() { - for (cmd, _) in config { - cmd.isEnabled = false - cmd.removeTarget(nil) - } - - mpInfoCenter.nowPlayingInfo = nil - mpInfoCenter.playbackState = .unknown - } - - @objc func makeCurrent(notification: NSNotification) { - mpInfoCenter.playbackState = .paused - mpInfoCenter.playbackState = .playing - updatePlaybackState() - } - - func updatePlaybackState() { - mpInfoCenter.playbackState = isPaused ? .paused : .playing - } - - func cmdHandler(_ event: MPRemoteCommandEvent) -> MPRemoteCommandHandlerStatus { - guard let cmdConfig = config[event.command], - let mpKey = cmdConfig["mpKey"] as? Int32, - let keyType = cmdConfig["keyType"] as? KeyType else - { - return .commandFailed - } - - var state = cmdConfig["state"] as? UInt32 ?? 0 - - if let currentState = cmdConfig["state"] as? UInt32, keyType == .repeatable { - state = MP_KEY_STATE_DOWN - config[event.command]?["state"] = MP_KEY_STATE_DOWN - if currentState == MP_KEY_STATE_DOWN { - state = MP_KEY_STATE_UP - config[event.command]?["state"] = MP_KEY_STATE_UP - } - } - - EventsResponder.sharedInstance().handleMPKey(mpKey, withMask: Int32(state)) - - return .success - } - - @objc func processEvent(_ event: UnsafeMutablePointer<mpv_event>) { - switch event.pointee.event_id { - case MPV_EVENT_PROPERTY_CHANGE: - handlePropertyChange(event) - default: - break - } - } - - func handlePropertyChange(_ event: UnsafeMutablePointer<mpv_event>) { - let pData = OpaquePointer(event.pointee.data) - guard let property = UnsafePointer<mpv_event_property>(pData)?.pointee else { - return - } - - switch String(cString: property.name) { - case "pause" where property.format == MPV_FORMAT_FLAG: - isPaused = LibmpvHelper.mpvFlagToBool(property.data) ?? false - default: - break - } - } -} diff --git a/osdep/macos/swift_compat.swift b/osdep/macos/swift_compat.swift deleted file mode 100644 index 83059da..0000000 --- a/osdep/macos/swift_compat.swift +++ /dev/null @@ -1,36 +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/>. - */ - - -#if !swift(>=5.0) -extension Data { - mutating func withUnsafeMutableBytes<Type>(_ body: (UnsafeMutableRawBufferPointer) throws -> Type) rethrows -> Type { - let dataCount = count - return try withUnsafeMutableBytes { (ptr: UnsafeMutablePointer<UInt8>) throws -> Type in - try body(UnsafeMutableRawBufferPointer(start: ptr, count: dataCount)) - } - } -} -#endif - -#if !swift(>=4.2) -extension NSDraggingInfo { - var draggingPasteboard: NSPasteboard { - get { return draggingPasteboard() } - } -} -#endif diff --git a/osdep/macos/swift_extensions.swift b/osdep/macos/swift_extensions.swift deleted file mode 100644 index 127c568..0000000 --- a/osdep/macos/swift_extensions.swift +++ /dev/null @@ -1,58 +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/>. - */ - -import Cocoa - -extension NSDeviceDescriptionKey { - static let screenNumber = NSDeviceDescriptionKey("NSScreenNumber") -} - -extension NSScreen { - - public var displayID: CGDirectDisplayID { - get { - return deviceDescription[.screenNumber] as? CGDirectDisplayID ?? 0 - } - } -} - -extension NSColor { - - convenience init(hex: String) { - let int = Int(hex.dropFirst(), radix: 16) ?? 0 - let alpha = CGFloat((int >> 24) & 0x000000FF)/255 - let red = CGFloat((int >> 16) & 0x000000FF)/255 - let green = CGFloat((int >> 8) & 0x000000FF)/255 - let blue = CGFloat((int) & 0x000000FF)/255 - - self.init(calibratedRed: red, green: green, blue: blue, alpha: alpha) - } -} - -extension Bool { - - init(_ int32: Int32) { - self.init(int32 != 0) - } -} - -extension Int32 { - - init(_ bool: Bool) { - self.init(bool ? 1 : 0) - } -} |