diff --git a/tutorials/src/bin/basic-tutorial-1.rs b/tutorials/src/bin/basic-tutorial-1.rs index c2a849096..62980de86 100644 --- a/tutorials/src/bin/basic-tutorial-1.rs +++ b/tutorials/src/bin/basic-tutorial-1.rs @@ -1,7 +1,10 @@ extern crate gstreamer as gst; use gst::prelude::*; -fn main() { +#[path = "../tutorials-common.rs"] +mod tutorials_common; + +fn tutorial_main() { // Initialize GStreamer gst::init().unwrap(); @@ -38,3 +41,9 @@ fn main() { let ret = pipeline.set_state(gst::State::Null); assert_ne!(ret, gst::StateChangeReturn::Failure); } + +fn main() { + // tutorials_common::run is only required to set up the application environment on macOS + // (but not necessary in normal Cocoa applications where this is set up automatically) + tutorials_common::run(tutorial_main); +} diff --git a/tutorials/src/bin/basic-tutorial-2.rs b/tutorials/src/bin/basic-tutorial-2.rs index 653729765..8a0ac9b06 100644 --- a/tutorials/src/bin/basic-tutorial-2.rs +++ b/tutorials/src/bin/basic-tutorial-2.rs @@ -1,8 +1,10 @@ extern crate gstreamer as gst; - use gst::prelude::*; -fn main() { +#[path = "../tutorials-common.rs"] +mod tutorials_common; + +fn tutorial_main() { // Initialize GStreamer gst::init().unwrap(); @@ -56,3 +58,10 @@ fn main() { "Unable to set the pipeline to the Null state." ); } + + +fn main() { + // tutorials_common::run is only required to set up the application environment on macOS + // (but not necessary in normal Cocoa applications where this is set up automatically) + tutorials_common::run(tutorial_main); +} diff --git a/tutorials/src/bin/basic-tutorial-3.rs b/tutorials/src/bin/basic-tutorial-3.rs index a2650e009..aad8ab823 100644 --- a/tutorials/src/bin/basic-tutorial-3.rs +++ b/tutorials/src/bin/basic-tutorial-3.rs @@ -1,8 +1,10 @@ extern crate gstreamer as gst; - use gst::prelude::*; -fn main() { +#[path = "../tutorials-common.rs"] +mod tutorials_common; + +fn tutorial_main() { // Initialize GStreamer gst::init().unwrap(); @@ -116,3 +118,9 @@ fn main() { "Unable to set the pipeline to the Null state." ); } + +fn main() { + // tutorials_common::run is only required to set up the application environment on macOS + // (but not necessary in normal Cocoa applications where this is set up automatically) + tutorials_common::run(tutorial_main); +} diff --git a/tutorials/src/bin/basic-tutorial-4.rs b/tutorials/src/bin/basic-tutorial-4.rs index 0761b9d88..64e4470a9 100644 --- a/tutorials/src/bin/basic-tutorial-4.rs +++ b/tutorials/src/bin/basic-tutorial-4.rs @@ -4,6 +4,9 @@ use std::io::Write; use gst::prelude::*; use gst::MessageView; +#[path = "../tutorials-common.rs"] +mod tutorials_common; + struct CustomData { playbin: gst::Element, // Our one and only element playing: bool, // Are we in the PLAYING state? @@ -13,7 +16,7 @@ struct CustomData { duration: gst::ClockTime, // How long does this media last, in nanoseconds } -fn main() { +fn tutorial_main() { // Initialize GStreamer gst::init().unwrap(); @@ -147,3 +150,9 @@ fn handle_message(custom_data: &mut CustomData, msg: &gst::GstRc (), } } + +fn main() { + // tutorials_common::run is only required to set up the application environment on macOS + // (but not necessary in normal Cocoa applications where this is set up automatically) + tutorials_common::run(tutorial_main); +} diff --git a/tutorials/src/bin/basic-tutorial-6.rs b/tutorials/src/bin/basic-tutorial-6.rs index 7f9ab9fe6..b3ddd1140 100644 --- a/tutorials/src/bin/basic-tutorial-6.rs +++ b/tutorials/src/bin/basic-tutorial-6.rs @@ -2,6 +2,8 @@ extern crate gstreamer as gst; use gst::prelude::*; use gst::MessageView; +#[path = "../tutorials-common.rs"] +mod tutorials_common; fn print_caps(caps: &gst::Caps, prefix: &str) { if caps.is_any() { @@ -76,7 +78,7 @@ fn print_pad_capabilities(element: &gst::Element, pad_name: &str) { } } -fn main() { +fn tutorial_main() { // Initialize GStreamer gst::init().unwrap(); @@ -155,3 +157,9 @@ fn main() { let ret = pipeline.set_state(gst::State::Null); assert_ne!(ret, gst::StateChangeReturn::Failure); } + +fn main() { + // tutorials_common::run is only required to set up the application environment on macOS + // (but not necessary in normal Cocoa applications where this is set up automatically) + tutorials_common::run(tutorial_main); +} diff --git a/tutorials/src/bin/basic-tutorial-7.rs b/tutorials/src/bin/basic-tutorial-7.rs index 0c9a7cca6..0ba3445e5 100644 --- a/tutorials/src/bin/basic-tutorial-7.rs +++ b/tutorials/src/bin/basic-tutorial-7.rs @@ -1,7 +1,10 @@ extern crate gstreamer as gst; use gst::prelude::*; -fn main() { +#[path = "../tutorials-common.rs"] +mod tutorials_common; + +fn tutorial_main() { // Initialize GStreamer if let Err(err) = gst::init() { eprintln!("Failed to initialize Gst: {}", err); @@ -92,3 +95,9 @@ fn main() { .into_result() .expect("Unable to set the pipeline to the Null state."); } + +fn main() { + // tutorials_common::run is only required to set up the application environment on macOS + // (but not necessary in normal Cocoa applications where this is set up automatically) + tutorials_common::run(tutorial_main); +} diff --git a/tutorials/src/tutorials-common.rs b/tutorials/src/tutorials-common.rs new file mode 100644 index 000000000..715cf5151 --- /dev/null +++ b/tutorials/src/tutorials-common.rs @@ -0,0 +1,23 @@ +/// macOS has a specific requirement that there must be a run loop running +/// on the main thread in order to open windows and use OpenGL. + +#[cfg(target_os = "macos")] +#[link(name = "foundation", kind = "framework")] +extern "C" { + fn CFRunLoopRun(); +} + +/// On macOS this launches the callback function on a thread. +/// On other platforms it's just executed immediately. +#[cfg(not(target_os = "macos"))] +pub fn run(main: F) { + main(); +} + +#[cfg(target_os = "macos")] +pub fn run(main: F) { + ::std::thread::spawn(main); + unsafe { + CFRunLoopRun(); + } +}