use std::ops::{Deref, DerefMut};
use crate::co;
use crate::decl::*;
use crate::gdi::ffi;
use crate::guard::*;
use crate::prelude::*;
handle_guard! { DeleteDCGuard: HDC;
ffi::DeleteDC;
}
pub struct DeleteObjectGuard<T>
where
T: GdiObject,
{
handle: T,
}
impl<T> Drop for DeleteObjectGuard<T>
where
T: GdiObject,
{
fn drop(&mut self) {
if let Some(h) = self.handle.as_opt() {
unsafe {
ffi::DeleteObject(h.ptr());
} }
}
}
impl<T> Deref for DeleteObjectGuard<T>
where
T: GdiObject,
{
type Target = T;
fn deref(&self) -> &Self::Target {
&self.handle
}
}
impl<T> DerefMut for DeleteObjectGuard<T>
where
T: GdiObject,
{
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.handle
}
}
impl<T> DeleteObjectGuard<T>
where
T: GdiObject,
{
#[must_use]
pub const unsafe fn new(handle: T) -> Self {
Self { handle }
}
#[must_use]
pub fn leak(&mut self) -> T {
std::mem::replace(&mut self.handle, T::INVALID)
}
}
handle_guard! { DeleteObjectPaletteGuard: HPALETTE;
ffi::DeleteObject;
}
pub struct LogpaletteGuard {
ptr: GlobalFreeGuard,
}
impl Deref for LogpaletteGuard {
type Target = LOGPALETTE;
fn deref(&self) -> &Self::Target {
unsafe { &*(self.ptr.ptr() as *const _) }
}
}
impl DerefMut for LogpaletteGuard {
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe { &mut *(self.ptr.ptr() as *mut _) }
}
}
impl LogpaletteGuard {
#[must_use]
pub(in crate::gdi) fn new(pal_version: u16, entries: &[PALETTEENTRY]) -> SysResult<Self> {
let sz = std::mem::size_of::<LOGPALETTE>() - std::mem::size_of::<PALETTEENTRY>()
+ (entries.len() * std::mem::size_of::<PALETTEENTRY>());
let mut new_self = Self {
ptr: HGLOBAL::GlobalAlloc(co::GMEM::FIXED | co::GMEM::ZEROINIT, sz)?,
};
new_self.palVersion = pal_version;
new_self.palNumEntries = entries.len() as _;
entries
.iter()
.zip(new_self.palPalEntry_mut())
.for_each(|(src, dest)| *dest = *src); Ok(new_self)
}
}
pub struct SelectObjectGuard<'a, G>
where
G: GdiObject,
{
hdc: &'a HDC,
prev_hgdi: G,
region: Option<co::REGION>,
}
impl<'a, G> Drop for SelectObjectGuard<'a, G>
where
G: GdiObject,
{
fn drop(&mut self) {
if let Some(h) = self.hdc.as_opt() {
if let Some(g) = self.prev_hgdi.as_opt() {
unsafe {
ffi::SelectObject(h.ptr(), g.ptr());
} }
}
}
}
impl<'a, G> SelectObjectGuard<'a, G>
where
G: GdiObject,
{
#[must_use]
pub const unsafe fn new(hdc: &'a HDC, prev_hgdi: G, region: Option<co::REGION>) -> Self {
Self { hdc, prev_hgdi, region }
}
#[must_use]
pub const fn prev_object(&self) -> &G {
&self.prev_hgdi
}
#[must_use]
pub const fn region(&self) -> Option<co::REGION> {
self.region
}
#[must_use]
pub fn leak(&mut self) -> G {
std::mem::replace(&mut self.prev_hgdi, G::INVALID)
}
}