From 45519cdd271b783193d0fe3449894d6ae5fe901b Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Mon, 29 Aug 2022 18:00:51 +0200 Subject: [PATCH] WIP --- Cargo.lock | 1 + crates/capture/Cargo.toml | 3 ++ crates/capture/build.rs | 7 +++ crates/capture/src/dummy.m | 12 ++++++ crates/capture/src/main.rs | 75 ++++++++++++++++++++++++++++++--- crates/gpui/src/platform/mac.rs | 2 +- styles/package-lock.json | 1 + 7 files changed, 94 insertions(+), 7 deletions(-) create mode 100644 crates/capture/src/dummy.m diff --git a/Cargo.lock b/Cargo.lock index e12e49184d..f001ab934a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -755,6 +755,7 @@ name = "capture" version = "0.1.0" dependencies = [ "block", + "cc", "cocoa", "core-foundation", "core-graphics", diff --git a/crates/capture/Cargo.toml b/crates/capture/Cargo.toml index 4dc975353f..2b483a25ca 100644 --- a/crates/capture/Cargo.toml +++ b/crates/capture/Cargo.toml @@ -19,3 +19,6 @@ foreign-types = "0.3" log = { version = "0.4.16", features = ["kv_unstable_serde"] } objc = "0.2" simplelog = "0.9" + +[build-dependencies] +cc = "1.0" \ No newline at end of file diff --git a/crates/capture/build.rs b/crates/capture/build.rs index 5aa9032376..33baf392bb 100644 --- a/crates/capture/build.rs +++ b/crates/capture/build.rs @@ -1,3 +1,10 @@ fn main() { println!("cargo:rustc-link-lib=framework=ScreenCaptureKit"); + println!("cargo:rustc-link-lib=framework=CoreMedia"); + println!("cargo:rustc-env=MACOSX_DEPLOYMENT_TARGET=12.3"); + + cc::Build::new() + .file("src/dummy.m") + .define("MACOSX_DEPLOYMENT_TARGET", "12.3") + .compile("dummy"); } diff --git a/crates/capture/src/dummy.m b/crates/capture/src/dummy.m new file mode 100644 index 0000000000..8edb379692 --- /dev/null +++ b/crates/capture/src/dummy.m @@ -0,0 +1,12 @@ +#import + +@interface MyClass : NSObject +@end + +@implementation MyClass +- (void)stream:(SCStream *)stream + didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer + ofType:(SCStreamOutputType)type { +} + +@end \ No newline at end of file diff --git a/crates/capture/src/main.rs b/crates/capture/src/main.rs index 6bad5bb7f3..e790d622ee 100644 --- a/crates/capture/src/main.rs +++ b/crates/capture/src/main.rs @@ -1,13 +1,14 @@ -use std::{slice, str}; +use std::{ffi::CStr, slice, str}; use block::ConcreteBlock; use cocoa::{ - base::id, - foundation::{NSString, NSUInteger}, + base::{id, nil}, + foundation::{NSArray, NSString, NSUInteger, NSInteger}, }; -use gpui::{actions, elements::*, keymap::Binding, Menu, MenuItem}; +use core_graphics::display::CGDirectDisplayID; +use gpui::{actions, elements::*, keymap::Binding, Menu, MenuItem, mac::dispatcher::dispatch_get_main_queue}; use log::LevelFilter; -use objc::{class, msg_send, sel, sel_impl}; +use objc::{class, msg_send, sel, sel_impl, declare::ClassDecl, runtime::{Protocol, Object, Sel}}; use simplelog::SimpleLogger; #[allow(non_upper_case_globals)] @@ -32,13 +33,57 @@ fn main() { }]); unsafe { + + let block = ConcreteBlock::new(move |content: id, error: id| { println!( "got response with shareable content {:?} {:?} {:?}", content, error, string_from_objc(msg_send![error, localizedDescription]), - ) + ); + + let displays: id = msg_send![content, displays]; + if let Some(display) = (0..displays.count()) + .map(|ix| displays.objectAtIndex(ix)) + .next() + { + let mut decl = ClassDecl::new("CaptureOutput", class!(NSObject)).unwrap(); + decl.add_protocol(Protocol::get("SCStreamOutput").unwrap()); + decl.add_method(sel!(stream:didOutputSampleBuffer:ofType:), sample_output as extern "C" fn(&Object, Sel, id, id, NSInteger)); + let capture_output_class = decl.register(); + + let output: id = msg_send![capture_output_class, alloc]; + let output: id = msg_send![output, init]; + + let excluded_windows: id = msg_send![class!(NSArray), array]; + let filter: id = msg_send![class!(SCContentFilter), alloc]; + let filter: id = msg_send![filter, initWithDisplay: display excludingWindows: excluded_windows]; + let config: id = msg_send![class!(SCStreamConfiguration), alloc]; + // Configure the display content width and height. + let _: () = msg_send![config, setWidth: 800]; + let _: () = msg_send![config, setHeight: 600]; + let _: () = msg_send![config, setMinimumFrameInterval: CMTimeMake(1, 60)]; + let _: () = msg_send![config, setQueueDepth: 5]; + + let stream: id = msg_send![class!(SCStream), alloc]; + let stream: id = msg_send![stream, initWithFilter: filter configuration: config delegate: nil]; + let error: id = nil; + let _: () = msg_send![stream, addStreamOutput: output type: 0 sampleHandlerQueue: dispatch_get_main_queue() error: &error]; + println!("Added stream output... error? {}", string_from_objc(msg_send![error, localizedDescription])); + + + let start_capture_completion = ConcreteBlock::new(move |error: id| { + println!("Started capturing... error? {}", string_from_objc(msg_send![error, localizedDescription])); + println!("recovery suggestion {}", string_from_objc(msg_send![error, localizedRecoverySuggestion])); + println!("failure reason {}", string_from_objc(msg_send![error, localizedFailureReason])); + + + }); + + assert!(!stream.is_null()); + let _: () = msg_send![stream, startCaptureWithCompletionHandler: start_capture_completion]; + } }); let _: id = msg_send![ @@ -75,6 +120,24 @@ pub unsafe fn string_from_objc(string: id) -> String { .to_string() } +extern "C" fn sample_output(this: &Object, _: Sel, stream: id, buffer: id, kind: NSInteger) { + println!("sample_output"); +} + + +extern "C" { + fn CMTimeMake(value: u64, timescale: i32) -> CMTime; +} + +#[repr(C)] +struct CMTime { + value: i64, + timescale: i32, + flags: u32, + epoch: i64, +} + + fn quit(_: &Quit, cx: &mut gpui::MutableAppContext) { cx.platform().quit(); } diff --git a/crates/gpui/src/platform/mac.rs b/crates/gpui/src/platform/mac.rs index 8cf3f62874..1d2f5fc8ae 100644 --- a/crates/gpui/src/platform/mac.rs +++ b/crates/gpui/src/platform/mac.rs @@ -1,5 +1,5 @@ mod atlas; -mod dispatcher; +pub mod dispatcher; mod event; mod fonts; mod geometry; diff --git a/styles/package-lock.json b/styles/package-lock.json index 5499f1852c..582f1c8496 100644 --- a/styles/package-lock.json +++ b/styles/package-lock.json @@ -5,6 +5,7 @@ "requires": true, "packages": { "": { + "name": "styles", "version": "1.0.0", "license": "ISC", "dependencies": {