// Stream Configuration APIs - SCStreamConfiguration
import CoreGraphics
import CoreMedia
import Foundation
import ScreenCaptureKit
// MARK: - Configuration: SCStreamConfiguration
@_cdecl("sc_stream_configuration_create")
public func createStreamConfiguration() -> OpaquePointer {
retain(SCStreamConfiguration())
}
@_cdecl("sc_stream_configuration_retain")
public func retainStreamConfiguration(_ config: OpaquePointer) -> OpaquePointer {
let c: SCStreamConfiguration = unretained(config)
return retain(c)
}
@_cdecl("sc_stream_configuration_release")
public func releaseStreamConfiguration(_ config: OpaquePointer) {
release(config)
}
@_cdecl("sc_stream_configuration_set_width")
public func setStreamConfigurationWidth(_ config: OpaquePointer, _ width: Int) {
let scConfig: SCStreamConfiguration = unretained(config)
scConfig.width = width
}
@_cdecl("sc_stream_configuration_get_width")
public func getStreamConfigurationWidth(_ config: OpaquePointer) -> Int {
let scConfig: SCStreamConfiguration = unretained(config)
return scConfig.width
}
@_cdecl("sc_stream_configuration_set_height")
public func setStreamConfigurationHeight(_ config: OpaquePointer, _ height: Int) {
let scConfig: SCStreamConfiguration = unretained(config)
scConfig.height = height
}
@_cdecl("sc_stream_configuration_get_height")
public func getStreamConfigurationHeight(_ config: OpaquePointer) -> Int {
let scConfig: SCStreamConfiguration = unretained(config)
return scConfig.height
}
@_cdecl("sc_stream_configuration_set_shows_cursor")
public func setStreamConfigurationShowsCursor(_ config: OpaquePointer, _ showsCursor: Bool) {
let scConfig: SCStreamConfiguration = unretained(config)
scConfig.showsCursor = showsCursor
}
@_cdecl("sc_stream_configuration_get_shows_cursor")
public func getStreamConfigurationShowsCursor(_ config: OpaquePointer) -> Bool {
let scConfig: SCStreamConfiguration = unretained(config)
return scConfig.showsCursor
}
@_cdecl("sc_stream_configuration_set_scales_to_fit")
public func setStreamConfigurationScalesToFit(_ config: OpaquePointer, _ scalesToFit: Bool) {
let scConfig: SCStreamConfiguration = unretained(config)
scConfig.scalesToFit = scalesToFit
}
@_cdecl("sc_stream_configuration_get_scales_to_fit")
public func getStreamConfigurationScalesToFit(_ config: OpaquePointer) -> Bool {
let scConfig: SCStreamConfiguration = unretained(config)
return scConfig.scalesToFit
}
@_cdecl("sc_stream_configuration_set_captures_audio")
public func setStreamConfigurationCapturesAudio(_ config: OpaquePointer, _ capturesAudio: Bool) {
let scConfig: SCStreamConfiguration = unretained(config)
scConfig.capturesAudio = capturesAudio
}
@_cdecl("sc_stream_configuration_get_captures_audio")
public func getStreamConfigurationCapturesAudio(_ config: OpaquePointer) -> Bool {
let scConfig: SCStreamConfiguration = unretained(config)
return scConfig.capturesAudio
}
@_cdecl("sc_stream_configuration_set_sample_rate")
public func setStreamConfigurationSampleRate(_ config: OpaquePointer, _ sampleRate: Int) {
let scConfig: SCStreamConfiguration = unretained(config)
scConfig.sampleRate = sampleRate
}
@_cdecl("sc_stream_configuration_get_sample_rate")
public func getStreamConfigurationSampleRate(_ config: OpaquePointer) -> Int {
let scConfig: SCStreamConfiguration = unretained(config)
return scConfig.sampleRate
}
@_cdecl("sc_stream_configuration_set_channel_count")
public func setStreamConfigurationChannelCount(_ config: OpaquePointer, _ channelCount: Int) {
let scConfig: SCStreamConfiguration = unretained(config)
scConfig.channelCount = channelCount
}
@_cdecl("sc_stream_configuration_get_channel_count")
public func getStreamConfigurationChannelCount(_ config: OpaquePointer) -> Int {
let scConfig: SCStreamConfiguration = unretained(config)
return scConfig.channelCount
}
@_cdecl("sc_stream_configuration_set_minimum_frame_interval")
public func setStreamConfigurationMinimumFrameInterval(_ config: OpaquePointer, _ value: Int64, _ timescale: Int32, _ flags: UInt32, _ epoch: Int64) {
let scConfig: SCStreamConfiguration = unretained(config)
scConfig.minimumFrameInterval = CMTime(value: value, timescale: timescale, flags: CMTimeFlags(rawValue: flags), epoch: epoch)
}
@_cdecl("sc_stream_configuration_get_minimum_frame_interval")
public func getStreamConfigurationMinimumFrameInterval(_ config: OpaquePointer, _ value: UnsafeMutablePointer<Int64>, _ timescale: UnsafeMutablePointer<Int32>, _ flags: UnsafeMutablePointer<UInt32>, _ epoch: UnsafeMutablePointer<Int64>) {
let scConfig: SCStreamConfiguration = unretained(config)
let cmTime = scConfig.minimumFrameInterval
value.pointee = cmTime.value
timescale.pointee = cmTime.timescale
flags.pointee = cmTime.flags.rawValue
epoch.pointee = cmTime.epoch
}
@_cdecl("sc_stream_configuration_set_queue_depth")
public func setStreamConfigurationQueueDepth(_ config: OpaquePointer, _ depth: Int) {
let scConfig: SCStreamConfiguration = unretained(config)
scConfig.queueDepth = depth
}
@_cdecl("sc_stream_configuration_get_queue_depth")
public func getStreamConfigurationQueueDepth(_ config: OpaquePointer) -> Int {
let scConfig: SCStreamConfiguration = unretained(config)
return scConfig.queueDepth
}
@_cdecl("sc_stream_configuration_set_pixel_format")
public func setStreamConfigurationPixelFormat(_ config: OpaquePointer, _ format: UInt32) {
let scConfig: SCStreamConfiguration = unretained(config)
scConfig.pixelFormat = format
}
@_cdecl("sc_stream_configuration_get_pixel_format")
public func getStreamConfigurationPixelFormat(_ config: OpaquePointer) -> UInt32 {
let scConfig: SCStreamConfiguration = unretained(config)
return scConfig.pixelFormat
}
@_cdecl("sc_stream_configuration_set_background_color")
public func setStreamConfigurationBackgroundColor(_ config: OpaquePointer, _ r: Float, _ g: Float, _ b: Float) {
let scConfig: SCStreamConfiguration = unretained(config)
let color = CGColor(red: CGFloat(r), green: CGFloat(g), blue: CGFloat(b), alpha: 1.0)
scConfig.backgroundColor = color
}
@_cdecl("sc_stream_configuration_set_color_space_name")
public func setStreamConfigurationColorSpaceName(_ config: OpaquePointer, _ name: UnsafePointer<CChar>) {
let scConfig: SCStreamConfiguration = unretained(config)
let colorSpaceName = String(cString: name)
scConfig.colorSpaceName = colorSpaceName as CFString
}
@_cdecl("sc_stream_configuration_set_should_be_opaque")
public func setStreamConfigurationShouldBeOpaque(_ config: OpaquePointer, _ shouldBeOpaque: Bool) {
let scConfig: SCStreamConfiguration = unretained(config)
if #available(macOS 14.0, *) {
scConfig.shouldBeOpaque = shouldBeOpaque
}
}
@_cdecl("sc_stream_configuration_get_should_be_opaque")
public func getStreamConfigurationShouldBeOpaque(_ config: OpaquePointer) -> Bool {
let scConfig: SCStreamConfiguration = unretained(config)
if #available(macOS 14.0, *) {
return scConfig.shouldBeOpaque
}
return false
}
// Shadow display configuration
@_cdecl("sc_stream_configuration_set_ignores_shadow_display_configuration")
public func setStreamConfigurationIgnoresShadowDisplayConfiguration(_ config: OpaquePointer, _ ignores: Bool) {
let scConfig: SCStreamConfiguration = unretained(config)
if #available(macOS 14.0, *) {
scConfig.ignoreShadowsDisplay = ignores
}
}
@_cdecl("sc_stream_configuration_get_ignores_shadow_display_configuration")
public func getStreamConfigurationIgnoresShadowDisplayConfiguration(_ config: OpaquePointer) -> Bool {
let scConfig: SCStreamConfiguration = unretained(config)
if #available(macOS 14.0, *) {
return scConfig.ignoreShadowsDisplay
}
return false
}
// MARK: - Source and Destination Rectangles
@_cdecl("sc_stream_configuration_set_source_rect")
public func setStreamConfigurationSourceRect(_ config: OpaquePointer, _ x: Double, _ y: Double, _ width: Double, _ height: Double) {
let scConfig: SCStreamConfiguration = unretained(config)
scConfig.sourceRect = CGRect(x: x, y: y, width: width, height: height)
}
@_cdecl("sc_stream_configuration_get_source_rect")
public func getStreamConfigurationSourceRect(_ config: OpaquePointer, _ x: UnsafeMutablePointer<Double>, _ y: UnsafeMutablePointer<Double>, _ width: UnsafeMutablePointer<Double>, _ height: UnsafeMutablePointer<Double>) {
let scConfig: SCStreamConfiguration = unretained(config)
let rect = scConfig.sourceRect
x.pointee = rect.origin.x
y.pointee = rect.origin.y
width.pointee = rect.size.width
height.pointee = rect.size.height
}
@_cdecl("sc_stream_configuration_set_destination_rect")
public func setStreamConfigurationDestinationRect(_ config: OpaquePointer, _ x: Double, _ y: Double, _ width: Double, _ height: Double) {
let scConfig: SCStreamConfiguration = unretained(config)
scConfig.destinationRect = CGRect(x: x, y: y, width: width, height: height)
}
@_cdecl("sc_stream_configuration_get_destination_rect")
public func getStreamConfigurationDestinationRect(_ config: OpaquePointer, _ x: UnsafeMutablePointer<Double>, _ y: UnsafeMutablePointer<Double>, _ width: UnsafeMutablePointer<Double>, _ height: UnsafeMutablePointer<Double>) {
let scConfig: SCStreamConfiguration = unretained(config)
let rect = scConfig.destinationRect
x.pointee = rect.origin.x
y.pointee = rect.origin.y
width.pointee = rect.size.width
height.pointee = rect.size.height
}
@_cdecl("sc_stream_configuration_set_preserves_aspect_ratio")
public func setStreamConfigurationPreservesAspectRatio(_ config: OpaquePointer, _ preserves: Bool) {
let scConfig: SCStreamConfiguration = unretained(config)
if #available(macOS 14.0, *) {
scConfig.preservesAspectRatio = preserves
}
}
@_cdecl("sc_stream_configuration_get_preserves_aspect_ratio")
public func getStreamConfigurationPreservesAspectRatio(_ config: OpaquePointer) -> Bool {
let scConfig: SCStreamConfiguration = unretained(config)
if #available(macOS 14.0, *) {
return scConfig.preservesAspectRatio
}
return false
}
// MARK: - Other Configuration Properties
@_cdecl("sc_stream_configuration_set_preserve_aspect_ratio")
public func setStreamConfigurationPreserveAspectRatio(_ config: OpaquePointer, _ preserves: Bool) {
// Legacy name - forward to new function
setStreamConfigurationPreservesAspectRatio(config, preserves)
}
@_cdecl("sc_stream_configuration_get_preserve_aspect_ratio")
public func getStreamConfigurationPreserveAspectRatio(_ config: OpaquePointer) -> Bool {
// Legacy name - forward to new function
getStreamConfigurationPreservesAspectRatio(config)
}
@_cdecl("sc_stream_configuration_set_capture_resolution_type")
public func setStreamConfigurationCaptureResolutionType(_ config: OpaquePointer, _ resolution: Int32) {
if #available(macOS 14.0, *) {
let scConfig: SCStreamConfiguration = unretained(config)
switch resolution {
case 0: scConfig.captureResolution = .automatic
case 1: scConfig.captureResolution = .best
case 2: scConfig.captureResolution = .nominal
default: break
}
}
}
@_cdecl("sc_stream_configuration_get_capture_resolution_type")
public func getStreamConfigurationCaptureResolutionType(_ config: OpaquePointer) -> Int32 {
if #available(macOS 14.0, *) {
let scConfig: SCStreamConfiguration = unretained(config)
switch scConfig.captureResolution {
case .automatic: return 0
case .best: return 1
case .nominal: return 2
@unknown default: return 0
}
}
return 0
}
@_cdecl("sc_stream_configuration_set_color_matrix")
public func setStreamConfigurationColorMatrix(_ config: OpaquePointer, _ matrix: UnsafePointer<CChar>) {
let scConfig: SCStreamConfiguration = unretained(config)
let matrixStr = String(cString: matrix)
scConfig.colorMatrix = matrixStr as CFString
}
@_cdecl("sc_stream_configuration_get_color_matrix")
public func getStreamConfigurationColorMatrix(_ config: OpaquePointer, _ buffer: UnsafeMutablePointer<CChar>, _ bufferSize: Int) -> Bool {
let scConfig: SCStreamConfiguration = unretained(config)
let matrix = scConfig.colorMatrix as String
return matrix.withCString { src in
strlcpy(buffer, src, bufferSize)
return true
}
}
@_cdecl("sc_stream_configuration_set_ignores_shadows_single_window")
public func setStreamConfigurationIgnoresShadowsSingleWindow(_ config: OpaquePointer, _ ignoresShadows: Bool) {
let cfg: SCStreamConfiguration = unretained(config)
if #available(macOS 14.0, *) {
cfg.ignoreShadowsSingleWindow = ignoresShadows
}
}
@_cdecl("sc_stream_configuration_get_ignores_shadows_single_window")
public func getStreamConfigurationIgnoresShadowsSingleWindow(_ config: OpaquePointer) -> Bool {
let cfg: SCStreamConfiguration = unretained(config)
if #available(macOS 14.0, *) {
return cfg.ignoreShadowsSingleWindow
}
return false
}
@_cdecl("sc_stream_configuration_set_includes_child_windows")
public func setStreamConfigurationIncludesChildWindows(_ config: OpaquePointer, _ includesChildWindows: Bool) {
let cfg: SCStreamConfiguration = unretained(config)
if #available(macOS 14.2, *) {
cfg.includeChildWindows = includesChildWindows
}
}
@_cdecl("sc_stream_configuration_get_includes_child_windows")
public func getStreamConfigurationIncludesChildWindows(_ config: OpaquePointer) -> Bool {
let cfg: SCStreamConfiguration = unretained(config)
if #available(macOS 14.2, *) {
return cfg.includeChildWindows
}
return false
}
@_cdecl("sc_stream_configuration_set_presenter_overlay_privacy_alert_setting")
public func setStreamConfigurationPresenterOverlayPrivacyAlertSetting(_ config: OpaquePointer, _ setting: Int) {
let cfg: SCStreamConfiguration = unretained(config)
if #available(macOS 14.0, *) {
switch setting {
case 0: cfg.presenterOverlayPrivacyAlertSetting = .system
case 1: cfg.presenterOverlayPrivacyAlertSetting = .never
case 2: cfg.presenterOverlayPrivacyAlertSetting = .always
default: break
}
}
}
@_cdecl("sc_stream_configuration_get_presenter_overlay_privacy_alert_setting")
public func getStreamConfigurationPresenterOverlayPrivacyAlertSetting(_ config: OpaquePointer) -> Int {
let cfg: SCStreamConfiguration = unretained(config)
if #available(macOS 14.0, *) {
switch cfg.presenterOverlayPrivacyAlertSetting {
case .system: return 0
case .never: return 1
case .always: return 2
@unknown default: return 0
}
}
return 0
}
@_cdecl("sc_stream_configuration_set_captures_shadows_only")
public func setStreamConfigurationCapturesShadowsOnly(_ config: OpaquePointer, _ value: Bool) {
let cfg: SCStreamConfiguration = unretained(config)
if #available(macOS 14.0, *) {
cfg.capturesShadowsOnly = value
}
}
@_cdecl("sc_stream_configuration_get_captures_shadows_only")
public func getStreamConfigurationCapturesShadowsOnly(_ config: OpaquePointer) -> Bool {
let cfg: SCStreamConfiguration = unretained(config)
if #available(macOS 14.0, *) {
return cfg.capturesShadowsOnly
}
return false
}
#if SCREENCAPTUREKIT_HAS_MACOS15_SDK
@_cdecl("sc_stream_configuration_set_captures_microphone")
public func setStreamConfigurationCapturesMicrophone(_ config: OpaquePointer, _ value: Bool) {
let cfg: SCStreamConfiguration = unretained(config)
if #available(macOS 15.0, *) {
cfg.captureMicrophone = value
}
}
#else
@_cdecl("sc_stream_configuration_set_captures_microphone")
public func setStreamConfigurationCapturesMicrophone(_: OpaquePointer, _: Bool) {}
#endif
#if SCREENCAPTUREKIT_HAS_MACOS15_SDK
@_cdecl("sc_stream_configuration_get_captures_microphone")
public func getStreamConfigurationCapturesMicrophone(_ config: OpaquePointer) -> Bool {
let cfg: SCStreamConfiguration = unretained(config)
if #available(macOS 15.0, *) {
return cfg.captureMicrophone
}
return false
}
#else
@_cdecl("sc_stream_configuration_get_captures_microphone")
public func getStreamConfigurationCapturesMicrophone(_: OpaquePointer) -> Bool {
false
}
#endif
@_cdecl("sc_stream_configuration_set_excludes_current_process_audio")
public func setStreamConfigurationExcludesCurrentProcessAudio(_ config: OpaquePointer, _ value: Bool) {
let cfg: SCStreamConfiguration = unretained(config)
cfg.excludesCurrentProcessAudio = value
}
@_cdecl("sc_stream_configuration_get_excludes_current_process_audio")
public func getStreamConfigurationExcludesCurrentProcessAudio(_ config: OpaquePointer) -> Bool {
let cfg: SCStreamConfiguration = unretained(config)
return cfg.excludesCurrentProcessAudio
}
#if SCREENCAPTUREKIT_HAS_MACOS15_SDK
@_cdecl("sc_stream_configuration_set_microphone_capture_device_id")
public func setStreamConfigurationMicrophoneCaptureDeviceId(_ config: OpaquePointer, _ deviceId: UnsafePointer<CChar>?) {
let cfg: SCStreamConfiguration = unretained(config)
if #available(macOS 15.0, *) {
if let deviceId {
cfg.microphoneCaptureDeviceID = String(cString: deviceId)
} else {
cfg.microphoneCaptureDeviceID = nil
}
}
}
#else
@_cdecl("sc_stream_configuration_set_microphone_capture_device_id")
public func setStreamConfigurationMicrophoneCaptureDeviceId(_: OpaquePointer, _: UnsafePointer<CChar>?) {}
#endif
#if SCREENCAPTUREKIT_HAS_MACOS15_SDK
@_cdecl("sc_stream_configuration_get_microphone_capture_device_id")
public func getStreamConfigurationMicrophoneCaptureDeviceId(_ config: OpaquePointer, _ buffer: UnsafeMutablePointer<CChar>, _ bufferSize: Int) -> Bool {
let cfg: SCStreamConfiguration = unretained(config)
if #available(macOS 15.0, *) {
if let deviceId = cfg.microphoneCaptureDeviceID {
guard let cString = deviceId.cString(using: .utf8), cString.count < bufferSize else {
return false
}
buffer.initialize(from: cString, count: min(cString.count, bufferSize))
return true
}
}
return false
}
#else
@_cdecl("sc_stream_configuration_get_microphone_capture_device_id")
public func getStreamConfigurationMicrophoneCaptureDeviceId(_: OpaquePointer, _: UnsafeMutablePointer<CChar>, _: Int) -> Bool {
false
}
#endif
@_cdecl("sc_stream_configuration_set_stream_name")
public func setStreamConfigurationStreamName(_ config: OpaquePointer, _ name: UnsafePointer<CChar>?) {
let cfg: SCStreamConfiguration = unretained(config)
if #available(macOS 14.0, *) {
if let name {
cfg.streamName = String(cString: name)
} else {
cfg.streamName = nil
}
}
}
@_cdecl("sc_stream_configuration_get_stream_name")
public func getStreamConfigurationStreamName(_ config: OpaquePointer, _ buffer: UnsafeMutablePointer<CChar>, _ bufferSize: Int) -> Bool {
let cfg: SCStreamConfiguration = unretained(config)
if #available(macOS 14.0, *) {
if let streamName = cfg.streamName {
guard let cString = streamName.cString(using: .utf8), cString.count < bufferSize else {
return false
}
buffer.initialize(from: cString, count: min(cString.count, bufferSize))
return true
}
}
return false
}
#if SCREENCAPTUREKIT_HAS_MACOS15_SDK
@_cdecl("sc_stream_configuration_set_capture_dynamic_range")
public func setStreamConfigurationCaptureDynamicRange(_ config: OpaquePointer, _ value: Int32) {
let cfg: SCStreamConfiguration = unretained(config)
if #available(macOS 15.0, *) {
switch value {
case 0:
cfg.captureDynamicRange = .SDR
case 1:
cfg.captureDynamicRange = .hdrLocalDisplay
case 2:
cfg.captureDynamicRange = .hdrCanonicalDisplay
default:
cfg.captureDynamicRange = .SDR
}
}
}
#else
@_cdecl("sc_stream_configuration_set_capture_dynamic_range")
public func setStreamConfigurationCaptureDynamicRange(_: OpaquePointer, _: Int32) {
// Not available on macOS < 15.0
}
#endif
#if SCREENCAPTUREKIT_HAS_MACOS15_SDK
@_cdecl("sc_stream_configuration_get_capture_dynamic_range")
public func getStreamConfigurationCaptureDynamicRange(_ config: OpaquePointer) -> Int32 {
let cfg: SCStreamConfiguration = unretained(config)
if #available(macOS 15.0, *) {
switch cfg.captureDynamicRange {
case .SDR:
return 0
case .hdrLocalDisplay:
return 1
case .hdrCanonicalDisplay:
return 2
@unknown default:
return 0
}
}
return 0
}
#else
@_cdecl("sc_stream_configuration_get_capture_dynamic_range")
public func getStreamConfigurationCaptureDynamicRange(_: OpaquePointer) -> Int32 {
0 // Not available on macOS < 15.0
}
#endif
// MARK: - macOS 15.0+ Properties
#if SCREENCAPTUREKIT_HAS_MACOS15_SDK
@_cdecl("sc_stream_configuration_set_shows_mouse_clicks")
public func setStreamConfigurationShowsMouseClicks(_ config: OpaquePointer, _ value: Bool) {
let cfg: SCStreamConfiguration = unretained(config)
if #available(macOS 15.0, *) {
cfg.showMouseClicks = value
}
}
#else
@_cdecl("sc_stream_configuration_set_shows_mouse_clicks")
public func setStreamConfigurationShowsMouseClicks(_: OpaquePointer, _: Bool) {}
#endif
#if SCREENCAPTUREKIT_HAS_MACOS15_SDK
@_cdecl("sc_stream_configuration_get_shows_mouse_clicks")
public func getStreamConfigurationShowsMouseClicks(_ config: OpaquePointer) -> Bool {
let cfg: SCStreamConfiguration = unretained(config)
if #available(macOS 15.0, *) {
return cfg.showMouseClicks
}
return false
}
#else
@_cdecl("sc_stream_configuration_get_shows_mouse_clicks")
public func getStreamConfigurationShowsMouseClicks(_: OpaquePointer) -> Bool {
false
}
#endif
// MARK: - macOS 14.0+ Properties
@_cdecl("sc_stream_configuration_set_ignores_shadows_display")
public func setStreamConfigurationIgnoresShadowsDisplay(_ config: OpaquePointer, _ value: Bool) {
let cfg: SCStreamConfiguration = unretained(config)
if #available(macOS 14.0, *) {
cfg.ignoreShadowsDisplay = value
}
}
@_cdecl("sc_stream_configuration_get_ignores_shadows_display")
public func getStreamConfigurationIgnoresShadowsDisplay(_ config: OpaquePointer) -> Bool {
let cfg: SCStreamConfiguration = unretained(config)
if #available(macOS 14.0, *) {
return cfg.ignoreShadowsDisplay
}
return false
}
@_cdecl("sc_stream_configuration_set_ignore_global_clip_display")
public func setStreamConfigurationIgnoreGlobalClipDisplay(_ config: OpaquePointer, _ value: Bool) {
let cfg: SCStreamConfiguration = unretained(config)
if #available(macOS 14.0, *) {
cfg.ignoreGlobalClipDisplay = value
}
}
@_cdecl("sc_stream_configuration_get_ignore_global_clip_display")
public func getStreamConfigurationIgnoreGlobalClipDisplay(_ config: OpaquePointer) -> Bool {
let cfg: SCStreamConfiguration = unretained(config)
if #available(macOS 14.0, *) {
return cfg.ignoreGlobalClipDisplay
}
return false
}
@_cdecl("sc_stream_configuration_set_ignore_global_clip_single_window")
public func setStreamConfigurationIgnoreGlobalClipSingleWindow(_ config: OpaquePointer, _ value: Bool) {
let cfg: SCStreamConfiguration = unretained(config)
if #available(macOS 14.0, *) {
cfg.ignoreGlobalClipSingleWindow = value
}
}
@_cdecl("sc_stream_configuration_get_ignore_global_clip_single_window")
public func getStreamConfigurationIgnoreGlobalClipSingleWindow(_ config: OpaquePointer) -> Bool {
let cfg: SCStreamConfiguration = unretained(config)
if #available(macOS 14.0, *) {
return cfg.ignoreGlobalClipSingleWindow
}
return false
}
// MARK: - Preset-based configuration (macOS 15.0+)
#if SCREENCAPTUREKIT_HAS_MACOS15_SDK
@_cdecl("sc_stream_configuration_create_with_preset")
public func createStreamConfigurationWithPreset(_ preset: Int32) -> OpaquePointer? {
if #available(macOS 15.0, *) {
let scPreset: SCStreamConfiguration.Preset = switch preset {
case 0:
.captureHDRStreamLocalDisplay
case 1:
.captureHDRStreamCanonicalDisplay
case 2:
.captureHDRScreenshotLocalDisplay
case 3:
.captureHDRScreenshotCanonicalDisplay
default:
.captureHDRStreamLocalDisplay
}
return retain(SCStreamConfiguration(preset: scPreset))
}
return retain(SCStreamConfiguration())
}
#else
@_cdecl("sc_stream_configuration_create_with_preset")
public func createStreamConfigurationWithPreset(_: Int32) -> OpaquePointer? {
retain(SCStreamConfiguration())
}
#endif