use super::device::{Adapter, Device};
use crate::platform::macos::system::connection::Connection as SystemConnection;
use crate::platform::macos::system::device::NativeDevice;
use crate::platform::macos::system::surface::NativeWidget;
use crate::Error;
use crate::GLApi;
use euclid::default::Size2D;
use std::os::raw::c_void;
pub use crate::platform::macos::system::connection::NativeConnection;
#[derive(Clone)]
pub struct Connection(pub SystemConnection);
impl Connection {
#[inline]
pub fn new() -> Result<Connection, Error> {
SystemConnection::new().map(Connection)
}
#[inline]
pub unsafe fn from_native_connection(
native_connection: NativeConnection,
) -> Result<Connection, Error> {
SystemConnection::from_native_connection(native_connection).map(Connection)
}
#[inline]
pub fn native_connection(&self) -> NativeConnection {
self.0.native_connection()
}
#[inline]
pub fn gl_api(&self) -> GLApi {
GLApi::GL
}
#[inline]
pub fn create_adapter(&self) -> Result<Adapter, Error> {
self.0.create_adapter().map(Adapter)
}
#[inline]
pub fn create_hardware_adapter(&self) -> Result<Adapter, Error> {
self.0.create_hardware_adapter().map(Adapter)
}
#[inline]
pub fn create_low_power_adapter(&self) -> Result<Adapter, Error> {
self.0.create_low_power_adapter().map(Adapter)
}
#[inline]
pub fn create_software_adapter(&self) -> Result<Adapter, Error> {
self.0.create_software_adapter().map(Adapter)
}
#[inline]
pub fn create_device(&self, adapter: &Adapter) -> Result<Device, Error> {
self.0.create_device(&adapter.0).map(Device)
}
#[inline]
pub unsafe fn create_device_from_native_device(
&self,
native_device: NativeDevice,
) -> Result<Device, Error> {
self.0
.create_device_from_native_device(native_device)
.map(Device)
}
#[cfg(feature = "sm-raw-window-handle-05")]
pub fn from_raw_display_handle(
raw_handle: rwh_05::RawDisplayHandle,
) -> Result<Connection, Error> {
SystemConnection::from_raw_display_handle(raw_handle).map(Connection)
}
#[cfg(feature = "sm-raw-window-handle-06")]
pub fn from_display_handle(handle: rwh_06::DisplayHandle) -> Result<Connection, Error> {
SystemConnection::from_display_handle(handle).map(Connection)
}
pub unsafe fn create_native_widget_from_ptr(
&self,
raw: *mut c_void,
size: Size2D<i32>,
) -> NativeWidget {
self.0.create_native_widget_from_ptr(raw, size)
}
#[cfg(feature = "sm-raw-window-handle-05")]
#[inline]
pub fn create_native_widget_from_raw_window_handle(
&self,
raw_handle: rwh_05::RawWindowHandle,
_size: Size2D<i32>,
) -> Result<NativeWidget, Error> {
use objc2::{MainThreadMarker, Message};
use objc2_app_kit::{NSView, NSWindow};
use rwh_05::RawWindowHandle::AppKit;
match raw_handle {
AppKit(handle) => {
assert!(
MainThreadMarker::new().is_some(),
"NSView is only usable on the main thread"
);
let ns_view = unsafe { handle.ns_view.cast::<NSView>().as_ref().unwrap() };
let ns_window = unsafe { handle.ns_window.cast::<NSWindow>().as_ref().unwrap() };
Ok(NativeWidget {
view: ns_view.retain(),
opaque: ns_window.isOpaque(),
})
}
_ => Err(Error::IncompatibleNativeWidget),
}
}
#[cfg(feature = "sm-raw-window-handle-06")]
#[inline]
pub fn create_native_widget_from_window_handle(
&self,
handle: rwh_06::WindowHandle,
_size: Size2D<i32>,
) -> Result<NativeWidget, Error> {
use objc2::{MainThreadMarker, Message};
use objc2_app_kit::NSView;
use rwh_06::RawWindowHandle::AppKit;
match handle.as_raw() {
AppKit(handle) => {
assert!(
MainThreadMarker::new().is_some(),
"NSView is only usable on the main thread"
);
let ns_view = unsafe { handle.ns_view.cast::<NSView>().as_ref() };
let ns_window = ns_view
.window()
.expect("view must be installed in a window");
Ok(NativeWidget {
view: ns_view.retain(),
opaque: ns_window.isOpaque(),
})
}
_ => Err(Error::IncompatibleNativeWidget),
}
}
}