1use super::device::{Adapter, Device, NativeDevice};
4use super::surface::NativeWidget;
5use crate::connection::Connection as ConnectionInterface;
6use crate::device::Device as DeviceInterface;
7use crate::Error;
8use crate::GLApi;
9
10use euclid::default::Size2D;
11
12use std::os::raw::c_void;
13
14pub enum Connection<Def, Alt>
16where
17 Def: DeviceInterface,
18 Alt: DeviceInterface,
19 Def::Connection: ConnectionInterface,
20 Alt::Connection: ConnectionInterface,
21{
22 Default(Def::Connection),
24 Alternate(Alt::Connection),
26}
27
28impl<Def, Alt> Clone for Connection<Def, Alt>
29where
30 Def: DeviceInterface,
31 Alt: DeviceInterface,
32 Def::Connection: Clone,
33 Alt::Connection: Clone,
34{
35 fn clone(&self) -> Self {
36 match self {
37 Connection::Default(ref connection) => Connection::Default(connection.clone()),
38 Connection::Alternate(ref connection) => Connection::Alternate(connection.clone()),
39 }
40 }
41}
42
43pub enum NativeConnection<Def, Alt>
45where
46 Def: DeviceInterface,
47 Alt: DeviceInterface,
48 Def::Connection: ConnectionInterface,
49 Alt::Connection: ConnectionInterface,
50{
51 Default(<Def::Connection as ConnectionInterface>::NativeConnection),
53 Alternate(<Alt::Connection as ConnectionInterface>::NativeConnection),
55}
56
57impl<Def, Alt> Connection<Def, Alt>
58where
59 Def: DeviceInterface,
60 Alt: DeviceInterface,
61 Def::Connection: ConnectionInterface<Device = Def>,
62 Alt::Connection: ConnectionInterface<Device = Alt>,
63{
64 #[inline]
66 pub fn new() -> Result<Connection<Def, Alt>, Error> {
67 match <Def::Connection>::new() {
68 Ok(connection) => Ok(Connection::Default(connection)),
69 Err(_) => <Alt::Connection>::new().map(Connection::Alternate),
70 }
71 }
72
73 pub fn native_connection(&self) -> NativeConnection<Def, Alt> {
75 match *self {
76 Connection::Default(ref connection) => {
77 NativeConnection::Default(connection.native_connection())
78 }
79 Connection::Alternate(ref connection) => {
80 NativeConnection::Alternate(connection.native_connection())
81 }
82 }
83 }
84
85 pub fn gl_api(&self) -> GLApi {
87 match *self {
88 Connection::Default(ref connection) => connection.gl_api(),
89 Connection::Alternate(ref connection) => connection.gl_api(),
90 }
91 }
92
93 pub fn create_adapter(&self) -> Result<Adapter<Def, Alt>, Error> {
97 match *self {
98 Connection::Default(ref connection) => {
99 connection.create_adapter().map(Adapter::Default)
100 }
101 Connection::Alternate(ref connection) => {
102 connection.create_adapter().map(Adapter::Alternate)
103 }
104 }
105 }
106
107 pub fn create_hardware_adapter(&self) -> Result<Adapter<Def, Alt>, Error> {
109 match *self {
110 Connection::Default(ref connection) => {
111 connection.create_hardware_adapter().map(Adapter::Default)
112 }
113 Connection::Alternate(ref connection) => {
114 connection.create_hardware_adapter().map(Adapter::Alternate)
115 }
116 }
117 }
118
119 pub fn create_low_power_adapter(&self) -> Result<Adapter<Def, Alt>, Error> {
121 match *self {
122 Connection::Default(ref connection) => {
123 connection.create_low_power_adapter().map(Adapter::Default)
124 }
125 Connection::Alternate(ref connection) => connection
126 .create_low_power_adapter()
127 .map(Adapter::Alternate),
128 }
129 }
130
131 pub fn create_software_adapter(&self) -> Result<Adapter<Def, Alt>, Error> {
133 match *self {
134 Connection::Default(ref connection) => {
135 connection.create_software_adapter().map(Adapter::Default)
136 }
137 Connection::Alternate(ref connection) => {
138 connection.create_software_adapter().map(Adapter::Alternate)
139 }
140 }
141 }
142
143 pub fn create_device(&self, adapter: &Adapter<Def, Alt>) -> Result<Device<Def, Alt>, Error> {
147 match (self, adapter) {
148 (Connection::Default(connection), Adapter::Default(adapter)) => {
149 connection.create_device(adapter).map(Device::Default)
150 }
151 (Connection::Alternate(connection), Adapter::Alternate(adapter)) => {
152 connection.create_device(adapter).map(Device::Alternate)
153 }
154 _ => Err(Error::IncompatibleAdapter),
155 }
156 }
157
158 #[inline]
160 pub unsafe fn create_device_from_native_device(
161 &self,
162 native_device: NativeDevice<Def, Alt>,
163 ) -> Result<Device<Def, Alt>, Error> {
164 match self {
165 Connection::Default(connection) => match native_device {
166 NativeDevice::Default(native_device) => connection
167 .create_device_from_native_device(native_device)
168 .map(Device::Default),
169 _ => Err(Error::IncompatibleNativeDevice),
170 },
171 Connection::Alternate(connection) => match native_device {
172 NativeDevice::Alternate(native_device) => connection
173 .create_device_from_native_device(native_device)
174 .map(Device::Alternate),
175 _ => Err(Error::IncompatibleNativeDevice),
176 },
177 }
178 }
179
180 #[cfg(feature = "sm-raw-window-handle-05")]
182 pub fn from_raw_display_handle(
183 raw_handle: rwh_05::RawDisplayHandle,
184 ) -> Result<Connection<Def, Alt>, Error> {
185 match <Def::Connection>::from_raw_display_handle(raw_handle) {
186 Ok(connection) => Ok(Connection::Default(connection)),
187 Err(_) => {
188 <Alt::Connection>::from_raw_display_handle(raw_handle).map(Connection::Alternate)
189 }
190 }
191 }
192
193 #[cfg(feature = "sm-raw-window-handle-06")]
195 pub fn from_display_handle(
196 handle: rwh_06::DisplayHandle,
197 ) -> Result<Connection<Def, Alt>, Error> {
198 match <Def::Connection>::from_display_handle(handle) {
199 Ok(connection) => Ok(Connection::Default(connection)),
200 Err(_) => <Alt::Connection>::from_display_handle(handle).map(Connection::Alternate),
201 }
202 }
203
204 pub unsafe fn create_native_widget_from_ptr(
206 &self,
207 raw: *mut c_void,
208 size: Size2D<i32>,
209 ) -> NativeWidget<Def, Alt> {
210 match *self {
211 Connection::Default(ref connection) => {
212 NativeWidget::Default(connection.create_native_widget_from_ptr(raw, size))
213 }
214 Connection::Alternate(ref connection) => {
215 NativeWidget::Alternate(connection.create_native_widget_from_ptr(raw, size))
216 }
217 }
218 }
219
220 #[cfg(feature = "sm-raw-window-handle-05")]
222 pub fn create_native_widget_from_raw_window_handle(
223 &self,
224 raw_handle: rwh_05::RawWindowHandle,
225 size: Size2D<i32>,
226 ) -> Result<NativeWidget<Def, Alt>, Error> {
227 match *self {
228 Connection::Default(ref connection) => connection
229 .create_native_widget_from_raw_window_handle(raw_handle, size)
230 .map(NativeWidget::Default),
231 Connection::Alternate(ref connection) => connection
232 .create_native_widget_from_raw_window_handle(raw_handle, size)
233 .map(NativeWidget::Alternate),
234 }
235 }
236
237 #[cfg(feature = "sm-raw-window-handle-06")]
239 pub fn create_native_widget_from_window_handle(
240 &self,
241 handle: rwh_06::WindowHandle,
242 size: Size2D<i32>,
243 ) -> Result<NativeWidget<Def, Alt>, Error> {
244 match *self {
245 Connection::Default(ref connection) => connection
246 .create_native_widget_from_window_handle(handle, size)
247 .map(NativeWidget::Default),
248 Connection::Alternate(ref connection) => connection
249 .create_native_widget_from_window_handle(handle, size)
250 .map(NativeWidget::Alternate),
251 }
252 }
253}
254
255impl<Def, Alt> ConnectionInterface for Connection<Def, Alt>
256where
257 Def: DeviceInterface,
258 Alt: DeviceInterface,
259 Def::Connection: ConnectionInterface<Device = Def>,
260 Alt::Connection: ConnectionInterface<Device = Alt>,
261{
262 type Adapter = Adapter<Def, Alt>;
263 type Device = Device<Def, Alt>;
264 type NativeConnection = NativeConnection<Def, Alt>;
265 type NativeDevice = NativeDevice<Def, Alt>;
266 type NativeWidget = NativeWidget<Def, Alt>;
267
268 #[inline]
269 fn new() -> Result<Connection<Def, Alt>, Error> {
270 Connection::new()
271 }
272
273 #[inline]
274 fn native_connection(&self) -> NativeConnection<Def, Alt> {
275 Connection::native_connection(self)
276 }
277
278 #[inline]
279 fn gl_api(&self) -> GLApi {
280 Connection::gl_api(self)
281 }
282
283 #[inline]
284 fn create_adapter(&self) -> Result<Adapter<Def, Alt>, Error> {
285 Connection::create_adapter(self)
286 }
287
288 #[inline]
289 fn create_hardware_adapter(&self) -> Result<Adapter<Def, Alt>, Error> {
290 Connection::create_hardware_adapter(self)
291 }
292
293 #[inline]
294 fn create_low_power_adapter(&self) -> Result<Adapter<Def, Alt>, Error> {
295 Connection::create_low_power_adapter(self)
296 }
297
298 #[inline]
299 fn create_software_adapter(&self) -> Result<Adapter<Def, Alt>, Error> {
300 Connection::create_software_adapter(self)
301 }
302
303 #[inline]
304 fn create_device(&self, adapter: &Adapter<Def, Alt>) -> Result<Device<Def, Alt>, Error> {
305 Connection::create_device(self, adapter)
306 }
307
308 #[inline]
309 unsafe fn create_device_from_native_device(
310 &self,
311 native_device: NativeDevice<Def, Alt>,
312 ) -> Result<Device<Def, Alt>, Error> {
313 Connection::create_device_from_native_device(self, native_device)
314 }
315
316 #[cfg(feature = "sm-raw-window-handle-05")]
317 fn from_raw_display_handle(
318 raw_handle: rwh_05::RawDisplayHandle,
319 ) -> Result<Connection<Def, Alt>, Error> {
320 Connection::from_raw_display_handle(raw_handle)
321 }
322
323 #[cfg(feature = "sm-raw-window-handle-06")]
324 fn from_display_handle(handle: rwh_06::DisplayHandle) -> Result<Connection<Def, Alt>, Error> {
325 Connection::from_display_handle(handle)
326 }
327
328 #[inline]
329 unsafe fn create_native_widget_from_ptr(
330 &self,
331 raw: *mut c_void,
332 size: Size2D<i32>,
333 ) -> NativeWidget<Def, Alt> {
334 Connection::create_native_widget_from_ptr(self, raw, size)
335 }
336
337 #[cfg(feature = "sm-raw-window-handle-05")]
338 fn create_native_widget_from_raw_window_handle(
339 &self,
340 raw_handle: rwh_05::RawWindowHandle,
341 size: Size2D<i32>,
342 ) -> Result<Self::NativeWidget, Error> {
343 Connection::create_native_widget_from_raw_window_handle(self, raw_handle, size)
344 }
345
346 #[cfg(feature = "sm-raw-window-handle-06")]
347 fn create_native_widget_from_window_handle(
348 &self,
349 handle: rwh_06::WindowHandle,
350 size: Size2D<i32>,
351 ) -> Result<Self::NativeWidget, Error> {
352 Connection::create_native_widget_from_window_handle(self, handle, size)
353 }
354}