diff --git a/src/lib.rs b/src/lib.rs index ff1438e9..8af5d8cb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -304,8 +304,7 @@ pub mod error; mod cursor; pub mod event; pub mod event_loop; -pub mod icon; -pub use winit_core::{keyboard, monitor}; +pub use winit_core::{icon, keyboard, monitor}; mod platform_impl; use winit_core::as_any as utils; pub mod window; diff --git a/src/platform_impl/linux/x11/util/icon.rs b/src/platform_impl/linux/x11/util/icon.rs index 07b5fee6..d8c57616 100644 --- a/src/platform_impl/linux/x11/util/icon.rs +++ b/src/platform_impl/linux/x11/util/icon.rs @@ -1,7 +1,18 @@ #![allow(clippy::assertions_on_constants)] use super::*; -use crate::icon::{Pixel, RgbaIcon, PIXEL_SIZE}; +use crate::icon::RgbaIcon; + +pub(crate) const PIXEL_SIZE: usize = mem::size_of::(); + +#[repr(C)] +#[derive(Debug)] +pub(crate) struct Pixel { + pub(crate) r: u8, + pub(crate) g: u8, + pub(crate) b: u8, + pub(crate) a: u8, +} impl Pixel { pub fn to_packed_argb(&self) -> Cardinal { @@ -18,19 +29,17 @@ impl Pixel { } } -impl RgbaIcon { - pub(crate) fn to_cardinals(&self) -> Vec { - assert_eq!(self.rgba.len() % PIXEL_SIZE, 0); - let pixel_count = self.rgba.len() / PIXEL_SIZE; - assert_eq!(pixel_count, (self.width * self.height) as usize); - let mut data = Vec::with_capacity(pixel_count); - data.push(self.width as Cardinal); - data.push(self.height as Cardinal); - let pixels = self.rgba.as_ptr() as *const Pixel; - for pixel_index in 0..pixel_count { - let pixel = unsafe { &*pixels.add(pixel_index) }; - data.push(pixel.to_packed_argb()); - } - data +pub(crate) fn rgba_to_cardinals(icon: &RgbaIcon) -> Vec { + assert_eq!(icon.buffer().len() % PIXEL_SIZE, 0); + let pixel_count = icon.buffer().len() / PIXEL_SIZE; + assert_eq!(pixel_count, (icon.width() * icon.height()) as usize); + let mut data = Vec::with_capacity(pixel_count); + data.push(icon.width() as Cardinal); + data.push(icon.height() as Cardinal); + let pixels = icon.buffer().as_ptr() as *const Pixel; + for pixel_index in 0..pixel_count { + let pixel = unsafe { &*pixels.add(pixel_index) }; + data.push(pixel.to_packed_argb()); } + data } diff --git a/src/platform_impl/linux/x11/util/mod.rs b/src/platform_impl/linux/x11/util/mod.rs index 9f034aff..1cd7ecf3 100644 --- a/src/platform_impl/linux/x11/util/mod.rs +++ b/src/platform_impl/linux/x11/util/mod.rs @@ -25,6 +25,7 @@ use x11rb::protocol::xproto::{self, ConnectionExt as _}; pub use self::cursor::*; pub use self::geometry::*; pub use self::hint::*; +pub(crate) use self::icon::rgba_to_cardinals; pub use self::input::*; pub use self::mouse::*; pub use self::window_property::*; diff --git a/src/platform_impl/linux/x11/window.rs b/src/platform_impl/linux/x11/window.rs index 14f8a8d9..8c88f01a 100644 --- a/src/platform_impl/linux/x11/window.rs +++ b/src/platform_impl/linux/x11/window.rs @@ -35,6 +35,7 @@ use crate::monitor::{ use crate::platform::x11::WindowType; use crate::platform_impl::common; use crate::platform_impl::x11::atoms::*; +use crate::platform_impl::x11::util::rgba_to_cardinals; use crate::platform_impl::x11::{ xinput_fp1616_to_float, MonitorHandle as X11MonitorHandle, WakeSender, X11Error, }; @@ -205,7 +206,7 @@ impl CoreWindow for Window { fn set_window_icon(&self, window_icon: Option) { let icon = match window_icon.as_ref() { - Some(icon) => icon.0.cast_ref::(), + Some(icon) => icon.cast_ref::(), None => None, }; self.0.set_window_icon(icon) @@ -771,7 +772,7 @@ impl UnownedWindow { // Set window icons if let Some(icon) = - window_attrs.window_icon.as_ref().and_then(|icon| icon.0.cast_ref::()) + window_attrs.window_icon.as_ref().and_then(|icon| icon.cast_ref::()) { leap!(window.set_icon_inner(icon)).ignore_error(); } @@ -1414,7 +1415,7 @@ impl UnownedWindow { fn set_icon_inner(&self, icon: &RgbaIcon) -> Result, X11Error> { let atoms = self.xconn.atoms(); let icon_atom = atoms[_NET_WM_ICON]; - let data = icon.to_cardinals(); + let data = rgba_to_cardinals(icon); self.xconn.change_property( self.xwindow, icon_atom, diff --git a/src/platform_impl/windows/icon.rs b/src/platform_impl/windows/icon.rs index 8670f9c9..e751782a 100644 --- a/src/platform_impl/windows/icon.rs +++ b/src/platform_impl/windows/icon.rs @@ -20,6 +20,8 @@ use crate::error::RequestError; use crate::icon::*; use crate::platform::windows::WinIcon; +pub(crate) const PIXEL_SIZE: usize = mem::size_of::(); + unsafe impl Send for WinIcon {} impl WinIcon { @@ -92,10 +94,10 @@ impl WinIcon { } pub(crate) fn from_rgba(rgba: &RgbaIcon) -> Result { - let pixel_count = rgba.rgba.len() / PIXEL_SIZE; + let pixel_count = rgba.buffer().len() / PIXEL_SIZE; let mut and_mask = Vec::with_capacity(pixel_count); let pixels = unsafe { - std::slice::from_raw_parts_mut(rgba.rgba.as_ptr() as *mut Pixel, pixel_count) + std::slice::from_raw_parts_mut(rgba.buffer().as_ptr() as *mut Pixel, pixel_count) }; for pixel in pixels { and_mask.push(pixel.a.wrapping_sub(u8::MAX)); // invert alpha channel @@ -105,12 +107,12 @@ impl WinIcon { let handle = unsafe { CreateIcon( ptr::null_mut(), - rgba.width as i32, - rgba.height as i32, + rgba.width() as i32, + rgba.height() as i32, 1, (PIXEL_SIZE * 8) as u8, and_mask.as_ptr(), - rgba.rgba.as_ptr(), + rgba.buffer().as_ptr(), ) }; if !handle.is_null() { @@ -250,3 +252,12 @@ impl RaiiCursor { self.handle } } + +#[repr(C)] +#[derive(Debug)] +pub(crate) struct Pixel { + pub(crate) r: u8, + pub(crate) g: u8, + pub(crate) b: u8, + pub(crate) a: u8, +} diff --git a/src/platform_impl/windows/window.rs b/src/platform_impl/windows/window.rs index 894cb605..d715a715 100644 --- a/src/platform_impl/windows/window.rs +++ b/src/platform_impl/windows/window.rs @@ -351,7 +351,7 @@ impl Window { } fn set_icon(&self, mut new_icon: Icon, icon_type: IconType) { - if let Some(icon) = new_icon.0.cast_ref::() { + if let Some(icon) = new_icon.cast_ref::() { let icon = match WinIcon::from_rgba(icon) { Ok(icon) => icon, Err(err) => { @@ -362,7 +362,7 @@ impl Window { new_icon = Icon(Arc::new(icon)); } - if let Some(icon) = new_icon.0.cast_ref::() { + if let Some(icon) = new_icon.cast_ref::() { unsafe { SendMessageW( self.hwnd(), diff --git a/src/icon.rs b/winit-core/src/icon.rs similarity index 90% rename from src/icon.rs rename to winit-core/src/icon.rs index 9aa3ec72..ba5f8caa 100644 --- a/src/icon.rs +++ b/winit-core/src/icon.rs @@ -1,30 +1,29 @@ use std::error::Error; +use std::ops::Deref; use std::sync::Arc; use std::{fmt, io, mem}; -use crate::utils::{impl_dyn_casting, AsAny}; +use crate::as_any::{impl_dyn_casting, AsAny}; -pub(crate) const PIXEL_SIZE: usize = mem::size_of::(); +pub(crate) const PIXEL_SIZE: usize = mem::size_of::(); /// An icon used for the window titlebar, taskbar, etc. -#[allow(dead_code)] #[derive(Debug, Clone)] -pub struct Icon(pub(crate) Arc); +pub struct Icon(pub Arc); // TODO remove that once split. pub trait IconProvider: AsAny + fmt::Debug + Send + Sync {} -impl_dyn_casting!(IconProvider); +impl Deref for Icon { + type Target = dyn IconProvider; -#[repr(C)] -#[derive(Debug)] -pub(crate) struct Pixel { - pub(crate) r: u8, - pub(crate) g: u8, - pub(crate) b: u8, - pub(crate) a: u8, + fn deref(&self) -> &Self::Target { + self.0.as_ref() + } } +impl_dyn_casting!(IconProvider); + #[derive(Debug)] /// An error produced when using [`RgbaIcon::new`] with invalid arguments. pub enum BadIcon { diff --git a/winit-core/src/lib.rs b/winit-core/src/lib.rs index 676399e4..3fa05dc1 100644 --- a/winit-core/src/lib.rs +++ b/winit-core/src/lib.rs @@ -1,4 +1,5 @@ #[macro_use] pub mod as_any; +pub mod icon; pub mod keyboard; pub mod monitor;