use super::*;
use std::marker::PhantomData;
use winit::event_loop::EventLoopWindowTarget;
use winit::window::{Window, WindowBuilder};
pub type WindowedContext<T> = ContextWrapper<T, Window>;
#[cfg_attr(
target_os = "windows",
doc = "\
[`platform::windows::RawContextExt`]: os/windows/enum.RawHandle.html
"
)]
#[cfg_attr(
not(target_os = "windows",),
doc = "\
[`platform::windows::RawContextExt`]: os/index.html
"
)]
#[cfg_attr(
not(any(
target_os = "linux",
target_os = "dragonfly",
target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd",
)),
doc = "\
[`platform::unix::RawContextExt`]: os/index.html
"
)]
#[cfg_attr(
any(
target_os = "linux",
target_os = "dragonfly",
target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd",
),
doc = "\
[`platform::unix::RawContextExt`]: os/unix/enum.RawHandle.html
"
)]
pub type RawContext<T> = ContextWrapper<T, ()>;
#[derive(Debug)]
pub struct ContextWrapper<T: ContextCurrentState, W> {
pub(crate) context: Context<T>,
pub(crate) window: W,
}
impl<T: ContextCurrentState> WindowedContext<T> {
pub fn window(&self) -> &Window {
&self.window
}
pub unsafe fn split(self) -> (RawContext<T>, Window) {
(RawContext { context: self.context, window: () }, self.window)
}
}
impl<W> ContextWrapper<PossiblyCurrent, W> {
pub fn swap_buffers(&self) -> Result<(), ContextError> {
self.context.context.swap_buffers()
}
pub fn swap_buffers_with_damage(&self, rects: &[Rect]) -> Result<(), ContextError> {
self.context.context.swap_buffers_with_damage(rects)
}
pub fn swap_buffers_with_damage_supported(&self) -> bool {
self.context.context.swap_buffers_with_damage_supported()
}
pub fn get_pixel_format(&self) -> PixelFormat {
self.context.context.get_pixel_format()
}
pub fn resize(&self, size: dpi::PhysicalSize<u32>) {
let (width, height) = size.into();
self.context.context.resize(width, height);
}
}
impl<T: ContextCurrentState, W> ContextWrapper<T, W> {
pub fn context(&self) -> &Context<T> {
&self.context
}
pub unsafe fn make_current(
self,
) -> Result<ContextWrapper<PossiblyCurrent, W>, (Self, ContextError)> {
let window = self.window;
match self.context.make_current() {
Ok(context) => Ok(ContextWrapper { window, context }),
Err((context, err)) => Err((ContextWrapper { window, context }, err)),
}
}
pub unsafe fn make_not_current(
self,
) -> Result<ContextWrapper<NotCurrent, W>, (Self, ContextError)> {
let window = self.window;
match self.context.make_not_current() {
Ok(context) => Ok(ContextWrapper { window, context }),
Err((context, err)) => Err((ContextWrapper { window, context }, err)),
}
}
pub unsafe fn treat_as_not_current(self) -> ContextWrapper<NotCurrent, W> {
ContextWrapper { context: self.context.treat_as_not_current(), window: self.window }
}
pub unsafe fn treat_as_current(self) -> ContextWrapper<PossiblyCurrent, W> {
ContextWrapper { context: self.context.treat_as_current(), window: self.window }
}
pub fn is_current(&self) -> bool {
self.context.is_current()
}
pub fn get_api(&self) -> Api {
self.context.get_api()
}
}
impl<W> ContextWrapper<PossiblyCurrent, W> {
#[inline]
pub fn get_proc_address(&self, addr: &str) -> *const core::ffi::c_void {
self.context.get_proc_address(addr)
}
}
impl<T: ContextCurrentState, W> std::ops::Deref for ContextWrapper<T, W> {
type Target = Context<T>;
fn deref(&self) -> &Self::Target {
&self.context
}
}
impl<'a, T: ContextCurrentState> ContextBuilder<'a, T> {
pub fn build_windowed<TE>(
self,
wb: WindowBuilder,
el: &EventLoopWindowTarget<TE>,
) -> Result<WindowedContext<NotCurrent>, CreationError> {
let ContextBuilder { pf_reqs, gl_attr } = self;
let gl_attr = gl_attr.map_sharing(|ctx| &ctx.context);
platform_impl::Context::new_windowed(wb, el, &pf_reqs, &gl_attr).map(|(window, context)| {
WindowedContext { window, context: Context { context, phantom: PhantomData } }
})
}
}