use super::*;
use crate::*;
use crate::d3d9::*;
use winapi::shared::d3d9::*;
use winapi::shared::d3d9types::D3DPRESENT_PARAMETERS;
use winapi::shared::minwindef::UINT;
use winapi::um::unknwnbase::IUnknown;
use winapi::um::wingdi::{RDH_RECTANGLES, RGNDATA, RGNDATAHEADER};
use std::convert::TryInto;
use std::ptr::*;
#[derive(Clone)] #[repr(transparent)]
pub struct SwapChain(pub(crate) mcom::Rc<IDirect3DSwapChain9>);
unsafe impl AsSafe<IUnknown > for SwapChain { fn as_safe(&self) -> &IUnknown { &**self.0 } }
unsafe impl AsSafe<IDirect3DSwapChain9 > for SwapChain { fn as_safe(&self) -> &IDirect3DSwapChain9 { &*self.0 } }
pub trait IDirect3DSwapChain9Ext : AsSafe<IDirect3DSwapChain9> {
type Device : From<Device>;
type Surface : From<Surface>;
fn get_back_buffer(&self, i_back_buffer: impl TryInto<UINT>, ty: impl Into<BackBufferType>) -> Result<Self::Surface, MethodError> {
let i_back_buffer = i_back_buffer.try_into().map_err(|_| MethodError("IDirect3DSwapChain9::GetBackBuffer", THINERR::SLICE_OVERFLOW))?;
let ty = ty.into().into();
let mut back_buffer = null_mut();
let hr = unsafe { self.as_winapi().GetBackBuffer(i_back_buffer, ty, &mut back_buffer) };
MethodError::check("IDirect3DSwapChain9::GetBackBuffer", hr)?;
Ok(Self::Surface::from(unsafe { Surface::from_raw(back_buffer) }))
}
fn get_device(&self) -> Result<Self::Device, MethodError> {
let mut device = null_mut();
let hr = unsafe { self.as_winapi().GetDevice(&mut device) };
MethodError::check("IDirect3DSwapChain9::GetDevice", hr)?;
Ok(Self::Device::from(unsafe { Device::from_raw(device) }))
}
fn get_display_mode(&self) -> Result<DisplayMode, MethodError> {
let mut dm = unsafe { std::mem::zeroed() };
let hr = unsafe { self.as_winapi().GetDisplayMode(&mut dm) };
MethodError::check("IDirect3DSwapChain9::GetDisplayMode", hr)?;
Ok(DisplayMode::from(dm))
}
unsafe fn get_front_buffer_data(&self, dest_surface: &impl IDirect3DSurface9Ext) -> Result<(), MethodError> {
let hr = self.as_winapi().GetFrontBufferData(dest_surface.as_winapi() as *const _ as *mut _);
MethodError::check("IDirect3DSwapChain9::GetFrontBufferData", hr)
}
fn get_present_parameters(&self) -> Result<D3DPRESENT_PARAMETERS, MethodError> {
let mut pp = unsafe { std::mem::zeroed() };
let hr = unsafe { self.as_winapi().GetPresentParameters(&mut pp) };
MethodError::check("IDirect3DSwapChain9::GetPresentParameters", hr)?;
Ok(pp)
}
fn get_raster_status(&self) -> Result<RasterStatus, MethodError> {
let mut rs = unsafe { std::mem::zeroed() };
let hr = unsafe { self.as_winapi().GetRasterStatus(&mut rs) };
MethodError::check("IDirect3DSwapChain9::GetRasterStatus", hr)?;
Ok(RasterStatus::from(rs))
}
fn present<'r>(&self, source_rect: impl IntoRectOrFull, dest_rect: impl IntoRectOrFull, dest_window_override: impl AsHWND, dirty_region: impl Into<Option<&'r RgnData>>, flags: impl Into<Present>) -> Result<(), MethodError> {
let source_rect = source_rect.into_rect();
let dest_rect = dest_rect.into_rect();
let hwnd = dest_window_override.as_hwnd();
let dirty_region = dirty_region.into();
let flags = flags.into().into();
let source_rect = source_rect .map_or(null(), |r| &*r).cast();
let dest_rect = dest_rect .map_or(null(), |r| &*r).cast();
let dirty_region = match dirty_region {
None => null::<RGNDATA>(),
Some(dr) => {
if dr.rdh.dwSize as usize != std::mem::size_of::<RGNDATAHEADER>() { return Err(MethodError("IDirect3DSwapChain9Ext::present", THINERR::INVALID_STRUCT_FIELD)); }
if dr.rdh.iType != RDH_RECTANGLES { return Err(MethodError("IDirect3DSwapChain9Ext::present", THINERR::INVALID_STRUCT_FIELD)); }
if dr.rdh.nCount as usize > dr.buffer.len() { return Err(MethodError("IDirect3DSwapChain9Ext::present", THINERR::INVALID_STRUCT_FIELD)); }
if dr.rdh.nRgnSize as usize > std::mem::size_of_val(dr) { return Err(MethodError("IDirect3DSwapChain9Ext::present", THINERR::INVALID_STRUCT_FIELD)); }
let dr : *const RgnData = dr;
dr.cast()
},
};
let hr = unsafe { self.as_winapi().Present(source_rect, dest_rect, hwnd, dirty_region, flags) };
MethodError::check("IDirect3DSwapChain9::Present", hr)
}
}
impl IDirect3DSwapChain9Ext for mcom::Rc<IDirect3DSwapChain9> { type Device = mcom::Rc<IDirect3DDevice9>; type Surface = mcom::Rc<IDirect3DSurface9>; }
impl IDirect3DSwapChain9Ext for super::SwapChain { type Device = super::Device; type Surface = super::Surface; }