use super::device::{Adapter, Device, NativeDevice};
use super::surface::NativeWidget;
use crate::connection::Connection as ConnectionInterface;
use crate::device::Device as DeviceInterface;
use crate::Error;
use crate::GLApi;
use euclid::default::Size2D;
use std::os::raw::c_void;
pub enum Connection<Def, Alt>
where
Def: DeviceInterface,
Alt: DeviceInterface,
Def::Connection: ConnectionInterface,
Alt::Connection: ConnectionInterface,
{
Default(Def::Connection),
Alternate(Alt::Connection),
}
impl<Def, Alt> Clone for Connection<Def, Alt>
where
Def: DeviceInterface,
Alt: DeviceInterface,
Def::Connection: Clone,
Alt::Connection: Clone,
{
fn clone(&self) -> Self {
match self {
Connection::Default(ref connection) => Connection::Default(connection.clone()),
Connection::Alternate(ref connection) => Connection::Alternate(connection.clone()),
}
}
}
pub enum NativeConnection<Def, Alt>
where
Def: DeviceInterface,
Alt: DeviceInterface,
Def::Connection: ConnectionInterface,
Alt::Connection: ConnectionInterface,
{
Default(<Def::Connection as ConnectionInterface>::NativeConnection),
Alternate(<Alt::Connection as ConnectionInterface>::NativeConnection),
}
impl<Def, Alt> Connection<Def, Alt>
where
Def: DeviceInterface,
Alt: DeviceInterface,
Def::Connection: ConnectionInterface<Device = Def>,
Alt::Connection: ConnectionInterface<Device = Alt>,
{
#[inline]
pub fn new() -> Result<Connection<Def, Alt>, Error> {
match <Def::Connection>::new() {
Ok(connection) => Ok(Connection::Default(connection)),
Err(_) => <Alt::Connection>::new().map(Connection::Alternate),
}
}
pub fn native_connection(&self) -> NativeConnection<Def, Alt> {
match *self {
Connection::Default(ref connection) => {
NativeConnection::Default(connection.native_connection())
}
Connection::Alternate(ref connection) => {
NativeConnection::Alternate(connection.native_connection())
}
}
}
pub fn gl_api(&self) -> GLApi {
match *self {
Connection::Default(ref connection) => connection.gl_api(),
Connection::Alternate(ref connection) => connection.gl_api(),
}
}
pub fn create_adapter(&self) -> Result<Adapter<Def, Alt>, Error> {
match *self {
Connection::Default(ref connection) => {
connection.create_adapter().map(Adapter::Default)
}
Connection::Alternate(ref connection) => {
connection.create_adapter().map(Adapter::Alternate)
}
}
}
pub fn create_hardware_adapter(&self) -> Result<Adapter<Def, Alt>, Error> {
match *self {
Connection::Default(ref connection) => {
connection.create_hardware_adapter().map(Adapter::Default)
}
Connection::Alternate(ref connection) => {
connection.create_hardware_adapter().map(Adapter::Alternate)
}
}
}
pub fn create_low_power_adapter(&self) -> Result<Adapter<Def, Alt>, Error> {
match *self {
Connection::Default(ref connection) => {
connection.create_low_power_adapter().map(Adapter::Default)
}
Connection::Alternate(ref connection) => connection
.create_low_power_adapter()
.map(Adapter::Alternate),
}
}
pub fn create_software_adapter(&self) -> Result<Adapter<Def, Alt>, Error> {
match *self {
Connection::Default(ref connection) => {
connection.create_software_adapter().map(Adapter::Default)
}
Connection::Alternate(ref connection) => {
connection.create_software_adapter().map(Adapter::Alternate)
}
}
}
pub fn create_device(&self, adapter: &Adapter<Def, Alt>) -> Result<Device<Def, Alt>, Error> {
match (self, adapter) {
(Connection::Default(connection), Adapter::Default(adapter)) => {
connection.create_device(adapter).map(Device::Default)
}
(Connection::Alternate(connection), Adapter::Alternate(adapter)) => {
connection.create_device(adapter).map(Device::Alternate)
}
_ => Err(Error::IncompatibleAdapter),
}
}
#[inline]
pub unsafe fn create_device_from_native_device(
&self,
native_device: NativeDevice<Def, Alt>,
) -> Result<Device<Def, Alt>, Error> {
match self {
Connection::Default(connection) => match native_device {
NativeDevice::Default(native_device) => connection
.create_device_from_native_device(native_device)
.map(Device::Default),
_ => Err(Error::IncompatibleNativeDevice),
},
Connection::Alternate(connection) => match native_device {
NativeDevice::Alternate(native_device) => connection
.create_device_from_native_device(native_device)
.map(Device::Alternate),
_ => Err(Error::IncompatibleNativeDevice),
},
}
}
#[cfg(feature = "sm-raw-window-handle-05")]
pub fn from_raw_display_handle(
raw_handle: rwh_05::RawDisplayHandle,
) -> Result<Connection<Def, Alt>, Error> {
match <Def::Connection>::from_raw_display_handle(raw_handle) {
Ok(connection) => Ok(Connection::Default(connection)),
Err(_) => {
<Alt::Connection>::from_raw_display_handle(raw_handle).map(Connection::Alternate)
}
}
}
#[cfg(feature = "sm-raw-window-handle-06")]
pub fn from_display_handle(
handle: rwh_06::DisplayHandle,
) -> Result<Connection<Def, Alt>, Error> {
match <Def::Connection>::from_display_handle(handle) {
Ok(connection) => Ok(Connection::Default(connection)),
Err(_) => <Alt::Connection>::from_display_handle(handle).map(Connection::Alternate),
}
}
pub unsafe fn create_native_widget_from_ptr(
&self,
raw: *mut c_void,
size: Size2D<i32>,
) -> NativeWidget<Def, Alt> {
match *self {
Connection::Default(ref connection) => {
NativeWidget::Default(connection.create_native_widget_from_ptr(raw, size))
}
Connection::Alternate(ref connection) => {
NativeWidget::Alternate(connection.create_native_widget_from_ptr(raw, size))
}
}
}
#[cfg(feature = "sm-raw-window-handle-05")]
pub fn create_native_widget_from_raw_window_handle(
&self,
raw_handle: rwh_05::RawWindowHandle,
size: Size2D<i32>,
) -> Result<NativeWidget<Def, Alt>, Error> {
match *self {
Connection::Default(ref connection) => connection
.create_native_widget_from_raw_window_handle(raw_handle, size)
.map(NativeWidget::Default),
Connection::Alternate(ref connection) => connection
.create_native_widget_from_raw_window_handle(raw_handle, size)
.map(NativeWidget::Alternate),
}
}
#[cfg(feature = "sm-raw-window-handle-06")]
pub fn create_native_widget_from_window_handle(
&self,
handle: rwh_06::WindowHandle,
size: Size2D<i32>,
) -> Result<NativeWidget<Def, Alt>, Error> {
match *self {
Connection::Default(ref connection) => connection
.create_native_widget_from_window_handle(handle, size)
.map(NativeWidget::Default),
Connection::Alternate(ref connection) => connection
.create_native_widget_from_window_handle(handle, size)
.map(NativeWidget::Alternate),
}
}
}
impl<Def, Alt> ConnectionInterface for Connection<Def, Alt>
where
Def: DeviceInterface,
Alt: DeviceInterface,
Def::Connection: ConnectionInterface<Device = Def>,
Alt::Connection: ConnectionInterface<Device = Alt>,
{
type Adapter = Adapter<Def, Alt>;
type Device = Device<Def, Alt>;
type NativeConnection = NativeConnection<Def, Alt>;
type NativeDevice = NativeDevice<Def, Alt>;
type NativeWidget = NativeWidget<Def, Alt>;
#[inline]
fn new() -> Result<Connection<Def, Alt>, Error> {
Connection::new()
}
#[inline]
fn native_connection(&self) -> NativeConnection<Def, Alt> {
Connection::native_connection(self)
}
#[inline]
fn gl_api(&self) -> GLApi {
Connection::gl_api(self)
}
#[inline]
fn create_adapter(&self) -> Result<Adapter<Def, Alt>, Error> {
Connection::create_adapter(self)
}
#[inline]
fn create_hardware_adapter(&self) -> Result<Adapter<Def, Alt>, Error> {
Connection::create_hardware_adapter(self)
}
#[inline]
fn create_low_power_adapter(&self) -> Result<Adapter<Def, Alt>, Error> {
Connection::create_low_power_adapter(self)
}
#[inline]
fn create_software_adapter(&self) -> Result<Adapter<Def, Alt>, Error> {
Connection::create_software_adapter(self)
}
#[inline]
fn create_device(&self, adapter: &Adapter<Def, Alt>) -> Result<Device<Def, Alt>, Error> {
Connection::create_device(self, adapter)
}
#[inline]
unsafe fn create_device_from_native_device(
&self,
native_device: NativeDevice<Def, Alt>,
) -> Result<Device<Def, Alt>, Error> {
Connection::create_device_from_native_device(self, native_device)
}
#[cfg(feature = "sm-raw-window-handle-05")]
fn from_raw_display_handle(
raw_handle: rwh_05::RawDisplayHandle,
) -> Result<Connection<Def, Alt>, Error> {
Connection::from_raw_display_handle(raw_handle)
}
#[cfg(feature = "sm-raw-window-handle-06")]
fn from_display_handle(handle: rwh_06::DisplayHandle) -> Result<Connection<Def, Alt>, Error> {
Connection::from_display_handle(handle)
}
#[inline]
unsafe fn create_native_widget_from_ptr(
&self,
raw: *mut c_void,
size: Size2D<i32>,
) -> NativeWidget<Def, Alt> {
Connection::create_native_widget_from_ptr(self, raw, size)
}
#[cfg(feature = "sm-raw-window-handle-05")]
fn create_native_widget_from_raw_window_handle(
&self,
raw_handle: rwh_05::RawWindowHandle,
size: Size2D<i32>,
) -> Result<Self::NativeWidget, Error> {
Connection::create_native_widget_from_raw_window_handle(self, raw_handle, size)
}
#[cfg(feature = "sm-raw-window-handle-06")]
fn create_native_widget_from_window_handle(
&self,
handle: rwh_06::WindowHandle,
size: Size2D<i32>,
) -> Result<Self::NativeWidget, Error> {
Connection::create_native_widget_from_window_handle(self, handle, size)
}
}