From 4b4af731ccd3738492aa4f785733f9af207e0623 Mon Sep 17 00:00:00 2001 From: Stefano Incardone <93933197+StefanoIncardone@users.noreply.github.com> Date: Thu, 11 Jan 2024 15:17:06 +0100 Subject: [PATCH] Upgraded raw_window_handle dependency to 0.6 (#333) * Moved runtime color bounds checks to compile time - made set_background_color take u8 rgb values instead of usize - removed clamp function (u8 variables cannot be greater than 255) * Cleanup * Improved code consistency and formatting - added inline directives where it made sense (and based on previous usage) - moved freestanding functions inside impl blocks, thus deleting files with a single function definition - possibly found bug/typo in os/posix/wayland.rs is_key_released function * Improved code consistency and formatting - added inline directives where it made sense (and based on previous usage) - moved freestanding functions inside impl blocks, thus deleting files with a single function definition - possibly found bug/typo in os/posix/wayland.rs is_key_released function * Upgraded raw_window_handle to 0.6 - edited deprecated fn_args_layout cargo fmt option to fn_params_layout - tidy preludes --- Cargo.toml | 2 +- rustfmt.toml | 2 +- src/buffer_helper.rs | 23 -------- src/error.rs | 4 +- src/icon.rs | 3 - src/key_handler.rs | 5 +- src/lib.rs | 65 ++++++++++++++------- src/os/macos/mod.rs | 67 +++++++++++---------- src/os/posix/common.rs | 3 +- src/os/posix/mod.rs | 29 +++++----- src/os/posix/wayland.rs | 112 ++++++++++++++++++++---------------- src/os/posix/x11.rs | 75 ++++++++++++------------ src/os/posix/xkb_ffi.rs | 1 + src/os/posix/xkb_keysyms.rs | 2 +- src/os/redox/mod.rs | 54 ++++++++++------- src/os/wasm/keycodes.rs | 1 + src/os/wasm/mod.rs | 83 +++++++++++++------------- src/os/windows/mod.rs | 97 ++++++++++++++++++------------- 18 files changed, 338 insertions(+), 290 deletions(-) delete mode 100644 src/buffer_helper.rs diff --git a/Cargo.toml b/Cargo.toml index eec949d0..b46bca67 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,7 @@ png = "0.17" cc = "1.0" [dependencies] -raw-window-handle = "0.5" +raw-window-handle = "0.6" [target.'cfg(windows)'.dependencies.winapi] version = "0.3" diff --git a/rustfmt.toml b/rustfmt.toml index fd8c8187..6bf96e6c 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -35,7 +35,7 @@ struct_field_align_threshold = 0 enum_discrim_align_threshold = 0 match_arm_blocks = true force_multiline_blocks = false -fn_args_layout = "Tall" +fn_params_layout = "Tall" brace_style = "SameLineWhere" control_brace_style = "AlwaysSameLine" trailing_semicolon = true diff --git a/src/buffer_helper.rs b/src/buffer_helper.rs deleted file mode 100644 index 1b565307..00000000 --- a/src/buffer_helper.rs +++ /dev/null @@ -1,23 +0,0 @@ -use crate::error::Error; -use crate::Result; - -pub fn check_buffer_size( - buffer: &[u32], - buffer_width: usize, - buffer_height: usize, - buffer_stride: usize, -) -> Result<()> { - let width = usize::max(buffer_width, buffer_stride); - let buffer_size = buffer.len() * std::mem::size_of::(); - let required_buffer_size = width * buffer_height * std::mem::size_of::(); // * 4 (size of u32) for 32-bit buffer - - if buffer_size < required_buffer_size { - let err = format!( - "Update failed because input buffer is too small. Required size for {} ({} stride) x {} buffer is {} - bytes but the size of the input buffer has the size {} bytes", - buffer_width, buffer_stride, buffer_height, required_buffer_size, buffer_size); - Err(Error::UpdateFailed(err)) - } else { - Ok(()) - } -} diff --git a/src/error.rs b/src/error.rs index 73f5afbf..63edac5d 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,8 +1,6 @@ -use std::error::Error as StdError; -use std::fmt; +use std::{error::Error as StdError, fmt}; /// Errors that can be returned from various operations -/// pub enum Error { /// Returned if menu Menu function isn't supported MenusNotSupported, diff --git a/src/icon.rs b/src/icon.rs index 534e7ad4..f36fa99c 100644 --- a/src/icon.rs +++ b/src/icon.rs @@ -3,7 +3,6 @@ use std::convert::TryFrom; #[cfg(target_os = "windows")] use std::{ffi::OsStr, os::windows::prelude::OsStrExt, str::FromStr}; -/// /// Represents a window icon /// /// Different under Windows, Linux and MacOS @@ -11,8 +10,6 @@ use std::{ffi::OsStr, os::windows::prelude::OsStrExt, str::FromStr}; /// **Windows**: Icon can be created from a relative path string /// /// **Linux / X11:** Icon can be created from an ARGB buffer -/// -/// #[derive(Clone, Copy, Debug)] pub enum Icon { Path(*const u16), diff --git a/src/key_handler.rs b/src/key_handler.rs index 65b93dca..83007da3 100644 --- a/src/key_handler.rs +++ b/src/key_handler.rs @@ -1,13 +1,14 @@ #[cfg(feature = "web")] extern crate instant; -use crate::{InputCallback, Key, KeyRepeat}; #[cfg(feature = "web")] use instant::{Duration, Instant}; -use std::mem; #[cfg(not(feature = "web"))] use std::time::{Duration, Instant}; +use crate::{InputCallback, Key, KeyRepeat}; +use std::mem; + pub struct KeyHandler { pub key_callback: Option>, prev_time: Instant, diff --git a/src/lib.rs b/src/lib.rs index c2c3ef98..a70d98fd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,25 +10,18 @@ #[macro_use] extern crate dlib; -use std::fmt; -use std::os::raw; - mod error; -pub use self::error::Error; -pub type Result = std::result::Result; -pub use icon::Icon; -pub use raw_window_handle::HasRawWindowHandle; - -mod key; -pub use key::Key; -mod buffer_helper; mod icon; +mod key; mod key_handler; mod os; mod rate; +use raw_window_handle::{DisplayHandle, HandleError, HasDisplayHandle, WindowHandle}; +use std::{fmt, os::raw}; + #[cfg(target_os = "macos")] -use self::os::macos as imp; +use os::macos as imp; #[cfg(any( target_os = "linux", target_os = "freebsd", @@ -36,13 +29,20 @@ use self::os::macos as imp; target_os = "netbsd", target_os = "openbsd" ))] -use self::os::posix as imp; +use os::posix as imp; #[cfg(target_os = "redox")] -use self::os::redox as imp; +use os::redox as imp; #[cfg(target_arch = "wasm32")] -use self::os::wasm as imp; +use os::wasm as imp; #[cfg(target_os = "windows")] -use self::os::windows as imp; +use os::windows as imp; + +pub use error::Error; +pub use icon::Icon; +pub use key::Key; +pub use raw_window_handle::HasWindowHandle; + +pub type Result = std::result::Result; /// Scale will scale the frame buffer and the window that is being sent in when calling the update /// function. This is useful if you for example want to display a 320 x 256 window on a screen with @@ -174,15 +174,15 @@ impl fmt::Debug for Window { } } -unsafe impl raw_window_handle::HasRawWindowHandle for Window { - fn raw_window_handle(&self) -> raw_window_handle::RawWindowHandle { - self.0.raw_window_handle() +impl HasWindowHandle for Window { + fn window_handle(&self) -> std::result::Result { + self.0.window_handle() } } -unsafe impl raw_window_handle::HasRawDisplayHandle for Window { - fn raw_display_handle(&self) -> raw_window_handle::RawDisplayHandle { - self.0.raw_display_handle() +impl HasDisplayHandle for Window { + fn display_handle(&self) -> std::result::Result { + self.0.display_handle() } } @@ -1097,3 +1097,24 @@ impl Default for WindowOptions { } } } + +pub(crate) fn check_buffer_size( + buffer: &[u32], + buffer_width: usize, + buffer_height: usize, + buffer_stride: usize, +) -> Result<()> { + let width = usize::max(buffer_width, buffer_stride); + let buffer_size = buffer.len() * std::mem::size_of::(); + let required_buffer_size = width * buffer_height * std::mem::size_of::(); // * 4 (size of u32) for 32-bit buffer + + if buffer_size < required_buffer_size { + let err = format!( + "Update failed because input buffer is too small. Required size for {} ({} stride) x {} buffer is {} + bytes but the size of the input buffer has the size {} bytes", + buffer_width, buffer_stride, buffer_height, required_buffer_size, buffer_size); + Err(Error::UpdateFailed(err)) + } else { + Ok(()) + } +} diff --git a/src/os/macos/mod.rs b/src/os/macos/mod.rs index 8339b834..2c30c458 100644 --- a/src/os/macos/mod.rs +++ b/src/os/macos/mod.rs @@ -1,25 +1,22 @@ #![cfg(target_os = "macos")] -use crate::error::Error; -use crate::key_handler::KeyHandler; -use crate::rate::UpdateRate; -use crate::Result; -use crate::{Key, KeyRepeat, MouseButton, MouseMode, Scale, WindowOptions}; -// use MenuItem; -use crate::buffer_helper; -use crate::icon::Icon; -use crate::InputCallback; -use crate::{CursorStyle, MenuHandle, MenuItem, MenuItemHandle}; -// use menu::Menu; - -use std::ffi::CString; -use std::mem; -use std::os::raw; -use std::os::raw::{c_char, c_uchar, c_void}; -use std::ptr; - -// Table taken from GLFW and slightly modified - +use crate::{ + check_buffer_size, error::Error, icon::Icon, key_handler::KeyHandler, rate::UpdateRate, + CursorStyle, InputCallback, Key, KeyRepeat, MenuHandle, MenuItem, MenuItemHandle, MouseButton, + MouseMode, Result, Scale, WindowOptions, +}; +use raw_window_handle::{ + AppKitDisplayHandle, AppKitWindowHandle, DisplayHandle, HandleError, HasDisplayHandle, + HasWindowHandle, RawDisplayHandle, RawWindowHandle, WindowHandle, +}; +use std::{ + ffi::CString, + mem, + os::raw::{self, c_char, c_uchar, c_void}, + ptr::{self, NonNull}, +}; + +/// Table taken from GLFW and slightly modified static KEY_MAPPINGS: [Key; 128] = [ /* 00 */ Key::A, /* 01 */ Key::S, @@ -259,19 +256,25 @@ unsafe extern "C" fn char_callback(window: *mut c_void, code_point: u32) { } } -unsafe impl raw_window_handle::HasRawWindowHandle for Window { - fn raw_window_handle(&self) -> raw_window_handle::RawWindowHandle { - let mut handle = raw_window_handle::AppKitWindowHandle::empty(); - handle.ns_window = self.window_handle as *mut _; - handle.ns_view = self.view_handle as *mut _; - raw_window_handle::RawWindowHandle::AppKit(handle) +impl HasWindowHandle for Window { + fn window_handle(&self) -> std::result::Result { + let raw_ns_view = self.view_handle as *mut _; + let ns_view = match NonNull::new(raw_ns_view) { + Some(ns_view) => ns_view, + None => unimplemented!("null view"), + }; + + let handle = AppKitWindowHandle::new(ns_view); + let raw_handle = RawWindowHandle::AppKit(handle); + unsafe { Ok(WindowHandle::borrow_raw(raw_handle)) } } } -unsafe impl raw_window_handle::HasRawDisplayHandle for Window { - fn raw_display_handle(&self) -> raw_window_handle::RawDisplayHandle { - let handle = raw_window_handle::AppKitDisplayHandle::empty(); - raw_window_handle::RawDisplayHandle::AppKit(handle) +impl HasDisplayHandle for Window { + fn display_handle(&self) -> std::result::Result { + let handle = AppKitDisplayHandle::new(); + let raw_handle = RawDisplayHandle::AppKit(handle); + unsafe { Ok(DisplayHandle::borrow_raw(raw_handle)) } } } @@ -378,7 +381,7 @@ impl Window { ) -> Result<()> { self.key_handler.update(); - buffer_helper::check_buffer_size(buffer, buf_width, buf_height, buf_stride)?; + check_buffer_size(buffer, buf_width, buf_height, buf_stride)?; unsafe { mfb_update_with_buffer( @@ -442,6 +445,7 @@ impl Window { ) } + #[inline] pub fn get_scroll_wheel(&self) -> Option<(f32, f32)> { let sx = self.shared_data.scroll_x; let sy = self.shared_data.scroll_y; @@ -742,6 +746,7 @@ impl Menu { } } + #[inline] pub fn add_menu_item(&mut self, item: &MenuItem) -> MenuItemHandle { unsafe { let item_name = CString::new(item.label.as_str()).unwrap(); diff --git a/src/os/posix/common.rs b/src/os/posix/common.rs index dea9a4e0..641242a7 100644 --- a/src/os/posix/common.rs +++ b/src/os/posix/common.rs @@ -1,5 +1,4 @@ -use crate::Result; -use crate::{Key, MenuHandle, MenuItem, MenuItemHandle, UnixMenu, UnixMenuItem}; +use crate::{Key, MenuHandle, MenuItem, MenuItemHandle, Result, UnixMenu, UnixMenuItem}; pub struct Menu { pub internal: UnixMenu, diff --git a/src/os/posix/mod.rs b/src/os/posix/mod.rs index 248c08e0..225146af 100644 --- a/src/os/posix/mod.rs +++ b/src/os/posix/mod.rs @@ -9,6 +9,7 @@ #![allow(non_upper_case_globals)] mod common; + #[cfg(feature = "wayland")] mod wayland; #[cfg(feature = "x11")] @@ -18,12 +19,14 @@ mod xkb_ffi; #[cfg(feature = "wayland")] mod xkb_keysyms; -use crate::icon::Icon; -use crate::Result; -use crate::{CursorStyle, MenuHandle, UnixMenu}; -use crate::{InputCallback, Key, KeyRepeat, MouseButton, MouseMode, WindowOptions}; +use crate::{ + icon::Icon, CursorStyle, InputCallback, Key, KeyRepeat, MenuHandle, MouseButton, MouseMode, + Result, UnixMenu, WindowOptions, +}; pub use common::Menu; - +use raw_window_handle::{ + DisplayHandle, HandleError, HasDisplayHandle, HasWindowHandle, WindowHandle, +}; use std::os::raw; // Differentiate between Wayland and X11 at run-time @@ -367,24 +370,24 @@ impl Window { } } -unsafe impl raw_window_handle::HasRawWindowHandle for Window { - fn raw_window_handle(&self) -> raw_window_handle::RawWindowHandle { +impl HasWindowHandle for Window { + fn window_handle(&self) -> std::result::Result { match self { #[cfg(feature = "x11")] - Window::X11(w) => w.raw_window_handle(), + Window::X11(w) => w.window_handle(), #[cfg(feature = "wayland")] - Window::Wayland(w) => w.raw_window_handle(), + Window::Wayland(w) => w.window_handle(), } } } -unsafe impl raw_window_handle::HasRawDisplayHandle for Window { - fn raw_display_handle(&self) -> raw_window_handle::RawDisplayHandle { +impl HasDisplayHandle for Window { + fn display_handle(&self) -> std::result::Result { match self { #[cfg(feature = "x11")] - Window::X11(w) => w.raw_display_handle(), + Window::X11(w) => w.display_handle(), #[cfg(feature = "wayland")] - Window::Wayland(w) => w.raw_display_handle(), + Window::Wayland(w) => w.display_handle(), } } } diff --git a/src/os/posix/wayland.rs b/src/os/posix/wayland.rs index d35becb5..0789ef84 100644 --- a/src/os/posix/wayland.rs +++ b/src/os/posix/wayland.rs @@ -1,49 +1,56 @@ -use crate::buffer_helper; -use crate::key_handler::KeyHandler; -use crate::rate::UpdateRate; -use crate::{CursorStyle, MenuHandle, UnixMenu}; -use crate::{Error, Result}; -use crate::{ - InputCallback, Key, KeyRepeat, MouseButton, MouseMode, Scale, ScaleMode, WindowOptions, +use std::{ + cell::RefCell, + ffi::c_void, + fs::File, + io::{self, Seek, SeekFrom, Write}, + mem, + os::unix::io::{AsRawFd, RawFd}, + ptr::{self, NonNull}, + rc::Rc, + slice, + sync::mpsc, + time::Duration, }; use super::common::{ Image_center, Image_resize_linear_aspect_fill_c, Image_resize_linear_c, Image_upper_left, Menu, }; +use crate::{ + check_buffer_size, key_handler::KeyHandler, rate::UpdateRate, CursorStyle, Error, + InputCallback, Key, KeyRepeat, MenuHandle, MouseButton, MouseMode, Result, Scale, ScaleMode, + UnixMenu, WindowOptions, +}; +use raw_window_handle::{ + DisplayHandle, HandleError, HasDisplayHandle, HasWindowHandle, RawDisplayHandle, + RawWindowHandle, WaylandDisplayHandle, WaylandWindowHandle, WindowHandle, +}; +use wayland_client::{ + protocol::{ + wl_buffer::WlBuffer, + wl_compositor::WlCompositor, + wl_display::WlDisplay, + wl_keyboard::{self, KeymapFormat, WlKeyboard}, + wl_pointer::{self, WlPointer}, + wl_seat::WlSeat, + wl_shm::{Format, WlShm}, + wl_shm_pool::WlShmPool, + wl_surface::WlSurface, + }, + Attached, Display, EventQueue, GlobalManager, Main, +}; +use wayland_protocols::{ + unstable::xdg_decoration::v1::client::zxdg_decoration_manager_v1::ZxdgDecorationManagerV1, + xdg_shell::client::{ + xdg_surface::XdgSurface, xdg_toplevel::XdgToplevel, xdg_wm_base::XdgWmBase, + }, +}; + use super::xkb_ffi; #[cfg(feature = "dlopen")] use super::xkb_ffi::XKBCOMMON_HANDLE as XKBH; #[cfg(not(feature = "dlopen"))] use super::xkb_ffi::*; -use wayland_client::protocol::wl_buffer::WlBuffer; -use wayland_client::protocol::wl_compositor::WlCompositor; -use wayland_client::protocol::wl_display::WlDisplay; -use wayland_client::protocol::wl_keyboard::{KeymapFormat, WlKeyboard}; -use wayland_client::protocol::wl_pointer::WlPointer; -use wayland_client::protocol::wl_seat::WlSeat; -use wayland_client::protocol::wl_shm::{Format, WlShm}; -use wayland_client::protocol::wl_shm_pool::WlShmPool; -use wayland_client::protocol::wl_surface::WlSurface; -use wayland_client::protocol::{wl_keyboard, wl_pointer}; -use wayland_client::{Attached, Display, EventQueue, GlobalManager, Main}; -use wayland_protocols::unstable::xdg_decoration::v1::client::zxdg_decoration_manager_v1::ZxdgDecorationManagerV1; -use wayland_protocols::xdg_shell::client::xdg_surface::XdgSurface; -use wayland_protocols::xdg_shell::client::xdg_toplevel::XdgToplevel; -use wayland_protocols::xdg_shell::client::xdg_wm_base::XdgWmBase; - -use std::cell::RefCell; -use std::ffi::c_void; -use std::fs::File; -use std::io::{self, Seek, SeekFrom, Write}; -use std::mem; -use std::os::unix::io::{AsRawFd, RawFd}; -use std::ptr; -use std::rc::Rc; -use std::slice; -use std::sync::mpsc; -use std::time::Duration; - const KEY_XKB_OFFSET: u32 = 8; const KEY_MOUSE_BTN1: u32 = 272; const KEY_MOUSE_BTN2: u32 = 273; @@ -1177,7 +1184,7 @@ impl Window { buf_height: usize, buf_stride: usize, ) -> Result<()> { - buffer_helper::check_buffer_size(buffer, buf_width, buf_height, buf_width)?; + check_buffer_size(buffer, buf_width, buf_height, buf_stride)?; unsafe { self.scale_buffer(buffer, buf_width, buf_height, buf_stride) }; @@ -1253,27 +1260,36 @@ impl Window { } } -unsafe impl raw_window_handle::HasRawWindowHandle for Window { - fn raw_window_handle(&self) -> raw_window_handle::RawWindowHandle { - let mut handle = raw_window_handle::WaylandWindowHandle::empty(); - handle.surface = self.display.surface.as_ref().c_ptr() as *mut _ as *mut c_void; +impl HasWindowHandle for Window { + fn window_handle(&self) -> std::result::Result { + let raw_display_surface = self.display.surface.as_ref().c_ptr() as *mut c_void; + let display_surface = match NonNull::new(raw_display_surface) { + Some(display_surface) => display_surface, + None => unimplemented!("null display surface"), + }; - raw_window_handle::RawWindowHandle::Wayland(handle) + let handle = WaylandWindowHandle::new(display_surface); + let raw_handle = RawWindowHandle::Wayland(handle); + unsafe { Ok(WindowHandle::borrow_raw(raw_handle)) } } } -unsafe impl raw_window_handle::HasRawDisplayHandle for Window { - fn raw_display_handle(&self) -> raw_window_handle::RawDisplayHandle { - let mut handle = raw_window_handle::WaylandDisplayHandle::empty(); - handle.display = self +impl HasDisplayHandle for Window { + fn display_handle(&self) -> std::result::Result { + let raw_display = self .display .attached_display .clone() .detach() .as_ref() - .c_ptr() as *mut _ as *mut c_void; - - raw_window_handle::RawDisplayHandle::Wayland(handle) + .c_ptr() as *mut c_void; + let display = match NonNull::new(raw_display) { + Some(display) => display, + None => unimplemented!("null display"), + }; + let handle = WaylandDisplayHandle::new(display); + let raw_handle = RawDisplayHandle::Wayland(handle); + unsafe { Ok(DisplayHandle::borrow_raw(raw_handle)) } } } diff --git a/src/os/posix/x11.rs b/src/os/posix/x11.rs index b82304cd..36b5a6eb 100644 --- a/src/os/posix/x11.rs +++ b/src/os/posix/x11.rs @@ -1,33 +1,30 @@ -use crate::key_handler::KeyHandler; -use crate::rate::UpdateRate; -use crate::{ - InputCallback, Key, KeyRepeat, MouseButton, MouseMode, Scale, ScaleMode, WindowOptions, -}; -use x11_dl::keysym::*; -use x11_dl::xcursor; -use x11_dl::xlib; - -use crate::error::Error; -use crate::Result; -use crate::{CursorStyle, MenuHandle, UnixMenu}; - -use std::convert::TryFrom; -use std::ffi::{c_void, CStr, CString}; -use std::mem; -use std::os::raw; -use std::os::raw::{c_char, c_int, c_long, c_uchar, c_uint, c_ulong}; -use std::ptr; - -use crate::buffer_helper; -use crate::icon::Icon; - use super::common::{ Image_center, Image_resize_linear_aspect_fill_c, Image_resize_linear_c, Image_upper_left, Menu, }; -use x11_dl::xlib::{ - KeyPressMask, KeyReleaseMask, KeySym, Status, XEvent, XIMPreeditNothing, XIMStatusNothing, - XKeyEvent, XNClientWindow, XNFocusWindow, XNInputStyle, XWindowAttributes, XrmDatabase, XIC, - XIM, +use crate::{ + check_buffer_size, error::Error, icon::Icon, key_handler::KeyHandler, rate::UpdateRate, + CursorStyle, InputCallback, Key, KeyRepeat, MenuHandle, MouseButton, MouseMode, Result, Scale, + ScaleMode, UnixMenu, WindowOptions, +}; +use raw_window_handle::{ + DisplayHandle, HandleError, HasDisplayHandle, HasWindowHandle, RawDisplayHandle, + RawWindowHandle, WindowHandle, XlibDisplayHandle, XlibWindowHandle, +}; +use std::{ + convert::TryFrom, + ffi::{c_void, CStr, CString}, + mem, + os::raw::{self, c_char, c_int, c_long, c_uchar, c_uint, c_ulong}, + ptr::{self, NonNull}, +}; +use x11_dl::{ + keysym::*, + xcursor, + xlib::{ + self, KeyPressMask, KeyReleaseMask, KeySym, Status, XEvent, XIMPreeditNothing, + XIMStatusNothing, XKeyEvent, XNClientWindow, XNFocusWindow, XNInputStyle, + XWindowAttributes, XrmDatabase, XIC, XIM, + }, }; // NOTE: the x11-dl crate does not define Button6 or Button7 @@ -284,19 +281,21 @@ pub struct Window { menus: Vec, } -unsafe impl raw_window_handle::HasRawWindowHandle for Window { - fn raw_window_handle(&self) -> raw_window_handle::RawWindowHandle { - let mut handle = raw_window_handle::XlibWindowHandle::empty(); - handle.window = self.handle; - raw_window_handle::RawWindowHandle::Xlib(handle) +impl HasWindowHandle for Window { + fn window_handle(&self) -> std::result::Result { + let handle = XlibWindowHandle::new(self.handle); + let raw_handle = RawWindowHandle::Xlib(handle); + unsafe { Ok(WindowHandle::borrow_raw(raw_handle)) } } } -unsafe impl raw_window_handle::HasRawDisplayHandle for Window { - fn raw_display_handle(&self) -> raw_window_handle::RawDisplayHandle { - let mut handle = raw_window_handle::XlibDisplayHandle::empty(); - handle.display = self.d.display as *mut core::ffi::c_void; - raw_window_handle::RawDisplayHandle::Xlib(handle) +impl HasDisplayHandle for Window { + fn display_handle(&self) -> std::result::Result { + let raw_display = self.d.display as *mut core::ffi::c_void; + let display = NonNull::new(raw_display); + let handle = XlibDisplayHandle::new(display, self.d.screen); + let raw_handle = RawDisplayHandle::Xlib(handle); + unsafe { Ok(DisplayHandle::borrow_raw(raw_handle)) } } } @@ -581,7 +580,7 @@ impl Window { buf_height: usize, buf_stride: usize, ) -> Result<()> { - buffer_helper::check_buffer_size(buffer, buf_width, buf_height, buf_stride)?; + check_buffer_size(buffer, buf_width, buf_height, buf_stride)?; unsafe { self.raw_blit_buffer(buffer, buf_width, buf_height, buf_stride) }; diff --git a/src/os/posix/xkb_ffi.rs b/src/os/posix/xkb_ffi.rs index f1fb39a9..0caaebfa 100644 --- a/src/os/posix/xkb_ffi.rs +++ b/src/os/posix/xkb_ffi.rs @@ -1,4 +1,5 @@ #![allow(non_camel_case_types, clippy::identity_op)] + /** Minimal xkb_common ffi wrapper, based on sctk's. */ use std::os::raw::c_char; diff --git a/src/os/posix/xkb_keysyms.rs b/src/os/posix/xkb_keysyms.rs index 9a20d520..d287ae53 100644 --- a/src/os/posix/xkb_keysyms.rs +++ b/src/os/posix/xkb_keysyms.rs @@ -1,6 +1,6 @@ #![allow(missing_docs, non_upper_case_globals, unused_parens, clippy::all)] -/** The subset of XKB_* key symbols that are used in minifb. */ +/** The subset of XKB_* key symbols that are used in minifb. */ pub const XKB_KEY_0: u32 = 0x0030; pub const XKB_KEY_1: u32 = 0x0031; pub const XKB_KEY_2: u32 = 0x0032; diff --git a/src/os/redox/mod.rs b/src/os/redox/mod.rs index eb299e2a..1eba6d8c 100644 --- a/src/os/redox/mod.rs +++ b/src/os/redox/mod.rs @@ -1,22 +1,17 @@ #![cfg(target_os = "redox")] -use crate::os::redox::orbclient::Renderer; - -use crate::buffer_helper; -use crate::error::Error; -use crate::icon::Icon; -use crate::key_handler::KeyHandler; -use crate::mouse_handler; -use crate::InputCallback; -use crate::Result; -use crate::{CursorStyle, MouseButton, MouseMode}; -use crate::{Key, KeyRepeat}; -use crate::{MenuHandle, MenuItem, MenuItemHandle, UnixMenu, UnixMenuItem}; -use crate::{Scale, WindowOptions}; - +use crate::{ + check_buffer_size, error::Error, icon::Icon, key_handler::KeyHandler, + os::redox::orbclient::Renderer, CursorStyle, InputCallback, Key, KeyRepeat, MenuHandle, + MenuItem, MenuItemHandle, MouseButton, MouseMode, Result, Scale, UnixMenu, UnixMenuItem, + WindowOptions, +}; use orbclient::Renderer; -use std::cmp; -use std::os::raw; +use raw_window_handle::{ + DisplayHandle, HandleError, HasDisplayHandle, HasWindowHandle, OrbitalDisplayHandle, + OrbitalWindowHandle, RawDisplayHandle, RawWindowHandle, WindowHandle, +}; +use std::{cmp, os::raw}; pub struct Window { is_open: bool, @@ -113,11 +108,11 @@ impl Window { self.process_events(); self.key_handler.update(); - let check_res = buffer_helper::check_buffer_size( + let check_res = check_buffer_size( + buffer, self.buffer_width, self.buffer_height, self.window_scale, - buffer, ); if check_res.is_err() { return check_res; @@ -167,8 +162,7 @@ impl Window { #[inline] pub fn get_mouse_pos(&self, mode: MouseMode) -> Option<(f32, f32)> { if let Some((mouse_x, mouse_y)) = self.mouse_pos { - mouse_handler::get_pos( - mode, + mode.get_pos( mouse_x as f32, mouse_y as f32, self.window_scale as f32, @@ -183,8 +177,7 @@ impl Window { #[inline] pub fn get_unscaled_mouse_pos(&self, mode: MouseMode) -> Option<(f32, f32)> { if let Some((mouse_x, mouse_y)) = self.mouse_pos { - mouse_handler::get_pos( - mode, + mode.get_pos( mouse_x as f32, mouse_y as f32, 1.0 as f32, @@ -440,6 +433,23 @@ impl Window { } } +impl HasWindowHandle for Window { + fn window_handle(&self) -> std::result::Result { + let raw_window = &self.window as *const orbclient::Window as *const std::ffi::c_void; + let handle = OrbitalWindowHandle::new(raw_window); + let raw_handle = RawWindowHandle::Orbital(handle); + unsafe { Ok(WindowHandle::borrow_raw(raw_handle)) } + } +} + +impl HasDisplayHandle for Window { + fn display_handle(&self) -> std::result::Result { + let handle = OrbitalDisplayHandle::new(); + let raw_handle = RawDisplayHandle::Orbital(handle); + unsafe { Ok(DisplayHandle::borrow_raw(raw_handle)) } + } +} + pub struct Menu { pub internal: UnixMenu, } diff --git a/src/os/wasm/keycodes.rs b/src/os/wasm/keycodes.rs index bf7eeebc..00b6ed79 100644 --- a/src/os/wasm/keycodes.rs +++ b/src/os/wasm/keycodes.rs @@ -1,4 +1,5 @@ use crate::key::Key; + pub const BACKSPACE: &'static str = "Backspace"; pub const TAB: &'static str = "Tab"; pub const ENTER: &'static str = "Enter"; diff --git a/src/os/wasm/mod.rs b/src/os/wasm/mod.rs index 22ba0009..f549fa35 100644 --- a/src/os/wasm/mod.rs +++ b/src/os/wasm/mod.rs @@ -1,30 +1,35 @@ +// NOTE(stefano): add missing implementations of methods where possible +#![cfg(target_os = "wasm32")] + mod keycodes; -use wasm_bindgen::prelude::*; -use wasm_bindgen::Clamped; -use wasm_bindgen::JsCast; -use web_sys::ImageData; -use web_sys::{window, CanvasRenderingContext2d, HtmlCanvasElement}; - -use crate::buffer_helper; -use crate::key_handler::KeyHandler; -use crate::Icon; -use crate::InputCallback; -use crate::Result; -use crate::{CursorStyle, MouseButton, MouseMode}; -use crate::{Key, KeyRepeat}; -use crate::{MenuHandle, MenuItem, MenuItemHandle, UnixMenu, UnixMenuItem}; -use crate::{Scale, WindowOptions}; -use core; + +use crate::{ + check_buffer_size, key_handler::KeyHandler, CursorStyle, Icon, InputCallback, Key, KeyRepeat, + MenuHandle, MenuItem, MenuItemHandle, MouseButton, MouseMode, Result, Scale, UnixMenu, + UnixMenuItem, WindowOptions, +}; use keycodes::event_to_key; -use std::cell::{Cell, RefCell}; -use std::os::raw; -use std::rc::Rc; +use raw_window_handle::{ + DisplayHandle, HandleError, HasDisplayHandle, HasWindowHandle, RawDisplayHandle, + RawWindowHandle, WebDisplayHandle, WebWindowHandle, WindowHandle, +}; +use std::{ + cell::{Cell, RefCell}, + os::raw, + rc::Rc, +}; +use wasm_bindgen::{prelude::*, Clamped, JsCast}; +use web_sys::{window, CanvasRenderingContext2d, HtmlCanvasElement, ImageData}; #[inline(always)] #[allow(dead_code)] // Only used on 32-bit builds currently -#[inline] pub fn u32_as_u8<'a>(src: &'a [u32]) -> &'a [u8] { - unsafe { core::slice::from_raw_parts(src.as_ptr() as *mut u8, std::mem::size_of::()) } + unsafe { + std::slice::from_raw_parts( + src.as_ptr() as *mut u8, + src.len() * std::mem::size_of::(), + ) + } } struct MouseState { @@ -35,6 +40,7 @@ struct MouseState { middle_button: Cell, } +// IDEA(stefano): possibly have this contain a "document" field, so not to recompute it every time pub struct Window { width: u32, height: u32, @@ -220,7 +226,7 @@ impl Window { buf_height: usize, buf_stride: usize, ) -> Result<()> { - buffer_helper::check_buffer_size(buf_width, buf_height, buf_width, buffer)?; + check_buffer_size(buffer, buf_width, buf_height, buf_stride)?; // scaling not implemented. It's faster to just update the buffer //unsafe { self.scale_buffer(buffer, buf_width, buf_height, buf_stride) }; self.update_with_buffer(&buffer).unwrap(); @@ -229,11 +235,11 @@ impl Window { } pub fn update_with_buffer(&mut self, buffer: &[u32]) -> Result<()> { - buffer_helper::check_buffer_size( + check_buffer_size( + buffer, self.width as usize, self.height as usize, self.window_scale, - buffer, )?; let mut data = u32_as_u8(buffer); @@ -265,8 +271,7 @@ impl Window { #[inline] pub fn get_position(&self) -> (isize, isize) { - let (x, y) = (0, 0); - (x as isize, y as isize) + (0isize, 0isize) } #[inline] @@ -277,8 +282,7 @@ impl Window { #[inline] pub fn get_mouse_pos(&self, mode: MouseMode) -> Option<(f32, f32)> { if let Some((mouse_x, mouse_y)) = self.mouse_state.pos.get() { - mouse_handler::get_pos( - mode, + mode.get_pos( mouse_x as f32, mouse_y as f32, self.window_scale as f32, @@ -293,8 +297,7 @@ impl Window { #[inline] pub fn get_unscaled_mouse_pos(&self, mode: MouseMode) -> Option<(f32, f32)> { if let Some((mouse_x, mouse_y)) = self.mouse_state.pos.get() { - mouse_handler::get_pos( - mode, + mode.get_pos( mouse_x as f32, mouse_y as f32, 1.0 as f32, @@ -450,17 +453,19 @@ impl Menu { pub fn remove_item(&mut self, handle: &MenuItemHandle) {} } -unsafe impl raw_window_handle::HasRawWindowHandle for Window { - fn raw_window_handle(&self) -> raw_window_handle::RawWindowHandle { - //TODO: assign a different ID to each window - let handle = raw_window_handle::WebWindowHandle::empty(); - raw_window_handle::RawWindowHandle::Web(handle) +impl HasWindowHandle for Window { + fn window_handle(&self) -> std::result::Result { + // TODO assign a different ID to each window + let handle = WebWindowHandle::new(0); + let raw_handle = RawWindowHandle::Web(handle); + unsafe { Ok(WindowHandle::borrow_raw(raw_handle)) } } } -unsafe impl raw_window_handle::HasRawDisplayHandle for Window { - fn raw_display_handle(&self) -> raw_window_handle::RawDisplayHandle { - let handle = raw_window_handle::WebDisplayHandle::empty(); - raw_window_handle::RawDisplayHandle::Web(handle) +impl HasDisplayHandle for Window { + fn display_handle(&self) -> std::result::Result { + let handle = WebDisplayHandle::new(); + let raw_handle = RawDisplayHandle::Web(handle); + unsafe { Ok(DisplayHandle::borrow_raw(raw_handle)) } } } diff --git a/src/os/windows/mod.rs b/src/os/windows/mod.rs index cf2ac288..701a19ad 100644 --- a/src/os/windows/mod.rs +++ b/src/os/windows/mod.rs @@ -1,36 +1,40 @@ #![cfg(target_os = "windows")] -const INVALID_ACCEL: usize = 0xffffffff; - -use crate::error::Error; -use crate::icon::Icon; -use crate::key_handler::KeyHandler; -use crate::rate::UpdateRate; -use crate::Result; -use crate::{CursorStyle, MenuHandle, MenuItem, MenuItemHandle}; use crate::{ - InputCallback, Key, KeyRepeat, MouseButton, MouseMode, Scale, ScaleMode, WindowOptions, + check_buffer_size, error::Error, icon::Icon, key_handler::KeyHandler, rate::UpdateRate, + CursorStyle, InputCallback, Key, KeyRepeat, MenuHandle, MenuItem, MenuItemHandle, MouseButton, + MouseMode, Result, Scale, ScaleMode, WindowOptions, MENU_KEY_ALT, MENU_KEY_CTRL, + MENU_KEY_SHIFT, MENU_KEY_WIN, +}; +use raw_window_handle::{ + DisplayHandle, HandleError, HasDisplayHandle, HasWindowHandle, RawDisplayHandle, + RawWindowHandle, Win32WindowHandle, WindowHandle, WindowsDisplayHandle, }; -use crate::{MENU_KEY_ALT, MENU_KEY_CTRL, MENU_KEY_SHIFT, MENU_KEY_WIN}; - -use crate::buffer_helper; -use std::ffi::OsStr; -use std::mem; -use std::os::raw; -use std::os::windows::ffi::OsStrExt; -use std::ptr; - -use winapi::shared::basetsd; -use winapi::shared::minwindef::{self, LPARAM, WPARAM}; -use winapi::shared::ntdef; -use winapi::shared::windef; -use winapi::um::errhandlingapi; -use winapi::um::fileapi::GetFullPathNameW; -use winapi::um::libloaderapi; -use winapi::um::wingdi; -use winapi::um::winuser::{ - self, ICON_BIG, ICON_SMALL, IMAGE_ICON, LR_DEFAULTSIZE, LR_LOADFROMFILE, WM_SETICON, +use std::{ + ffi::OsStr, + mem, + num::NonZeroIsize, + os::{raw, windows::ffi::OsStrExt}, + ptr, }; +use winapi::{ + shared::{ + basetsd, + minwindef::{self, LPARAM, WPARAM}, + ntdef, windef, + }, + um::{ + errhandlingapi, + fileapi::GetFullPathNameW, + libloaderapi, wingdi, + winuser::{ + self, GetWindowLongPtrW, GWLP_HINSTANCE, ICON_BIG, ICON_SMALL, IMAGE_ICON, + LR_DEFAULTSIZE, LR_LOADFROMFILE, WM_SETICON, + }, + }, +}; + +const INVALID_ACCEL: usize = 0xffffffff; // Wrap this so we can have a proper numbef of bmiColors to write in #[repr(C)] @@ -213,7 +217,7 @@ unsafe extern "system" fn wnd_proc( return winuser::DefWindowProcW(window, msg, wparam, lparam); } - let mut wnd: &mut Window = mem::transmute(user_data); + let wnd: &mut Window = mem::transmute(user_data); match msg { winuser::WM_SYSCOMMAND => { @@ -516,20 +520,31 @@ pub struct Window { draw_params: DrawParameters, } -unsafe impl raw_window_handle::HasRawWindowHandle for Window { - fn raw_window_handle(&self) -> raw_window_handle::RawWindowHandle { - let mut handle = raw_window_handle::Win32WindowHandle::empty(); - handle.hwnd = self.window.unwrap() as *mut raw::c_void; - handle.hinstance = - unsafe { libloaderapi::GetModuleHandleA(ptr::null()) } as *mut raw::c_void; - raw_window_handle::RawWindowHandle::Win32(handle) +impl HasWindowHandle for Window { + fn window_handle(&self) -> std::result::Result { + let raw_hwnd = self.window.unwrap(); + let hwnd = match NonZeroIsize::new(unsafe { *(raw_hwnd as *const isize) }) { + Some(hwnd) => hwnd, + None => unimplemented!("invalid hwnd"), + }; + + let raw_hinstance = + unsafe { *(GetWindowLongPtrW(raw_hwnd, GWLP_HINSTANCE) as *const isize) }; + let hinstance = NonZeroIsize::new(raw_hinstance); + + let mut handle = Win32WindowHandle::new(hwnd); + handle.hinstance = hinstance; + + let raw_handle = RawWindowHandle::Win32(handle); + unsafe { Ok(WindowHandle::borrow_raw(raw_handle)) } } } -unsafe impl raw_window_handle::HasRawDisplayHandle for Window { - fn raw_display_handle(&self) -> raw_window_handle::RawDisplayHandle { - let handle = raw_window_handle::WindowsDisplayHandle::empty(); - raw_window_handle::RawDisplayHandle::Windows(handle) +impl HasDisplayHandle for Window { + fn display_handle(&self) -> std::result::Result { + let handle = WindowsDisplayHandle::new(); + let raw_handle = RawDisplayHandle::Windows(handle); + unsafe { Ok(DisplayHandle::borrow_raw(raw_handle)) } } } @@ -980,7 +995,7 @@ impl Window { self.generic_update(window); - buffer_helper::check_buffer_size(buffer, buf_width, buf_height, buf_stride)?; + check_buffer_size(buffer, buf_width, buf_height, buf_stride)?; self.draw_params.buffer = buffer.as_ptr(); self.draw_params.buffer_width = buf_width as u32;