diff --git a/Cargo.toml b/Cargo.toml index 9775c54..025a388 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,7 @@ exclude = ["examples"] [dependencies] thiserror = "1.0.30" -raw-window-handle = "0.4.2" +raw-window-handle = "0.5.0" [target.'cfg(target_os = "linux")'.dependencies] tempfile = "3.3.0" @@ -41,7 +41,7 @@ features = ["CanvasRenderingContext2d", "Document", "Element", "HtmlCanvasElemen [dev-dependencies] instant = "0.1.12" -winit = "0.26.1" +winit = "0.27.2" [dev-dependencies.image] version = "0.23.14" diff --git a/src/cg.rs b/src/cg.rs index 77e4dff..a64aa2e 100644 --- a/src/cg.rs +++ b/src/cg.rs @@ -1,5 +1,5 @@ use crate::{GraphicsContextImpl, SoftBufferError}; -use raw_window_handle::{HasRawWindowHandle, AppKitHandle}; +use raw_window_handle::{HasRawWindowHandle, AppKitWindowHandle}; use core_graphics::base::{kCGBitmapByteOrder32Little, kCGImageAlphaNoneSkipFirst, kCGRenderingIntentDefault}; use core_graphics::color_space::CGColorSpace; use core_graphics::data_provider::CGDataProvider; @@ -17,7 +17,7 @@ pub struct CGImpl { } impl CGImpl { - pub unsafe fn new(handle: AppKitHandle) -> Result> { + pub unsafe fn new(handle: AppKitWindowHandle) -> Result> { let view = handle.ns_view as id; let layer = CALayer::new(); let subview: id = NSView::alloc(nil).initWithFrame_(view.frame()); diff --git a/src/error.rs b/src/error.rs index e7656ca..e692f4d 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,16 +1,18 @@ use std::error::Error; -use raw_window_handle::{HasRawWindowHandle, RawWindowHandle}; +use raw_window_handle::{HasRawWindowHandle, RawDisplayHandle, RawWindowHandle}; use thiserror::Error; #[derive(Error, Debug)] pub enum SoftBufferError { #[error( - "The provided window returned an unsupported platform: {human_readable_platform_name}." + "The provided window returned an unsupported platform: {human_readable_window_platform_name}, {human_readable_display_platform_name}." )] UnsupportedPlatform { window: W, - human_readable_platform_name: &'static str, - handle: RawWindowHandle, + human_readable_window_platform_name: &'static str, + human_readable_display_platform_name: &'static str, + window_handle: RawWindowHandle, + display_handle: RawDisplayHandle }, #[error("Platform error")] PlatformError(Option, Option>) diff --git a/src/lib.rs b/src/lib.rs index b67785b..8730629 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,6 +3,7 @@ #[cfg(target_os = "macos")] #[macro_use] extern crate objc; +extern crate core; #[cfg(target_os = "windows")] mod win32; @@ -19,40 +20,44 @@ mod error; pub use error::SoftBufferError; -use raw_window_handle::{HasRawWindowHandle, RawWindowHandle}; +use raw_window_handle::{HasRawDisplayHandle, HasRawWindowHandle, RawDisplayHandle, RawWindowHandle}; /// An instance of this struct contains the platform-specific data that must be managed in order to /// write to a window on that platform. This struct owns the window that this data corresponds to /// to ensure safety, as that data must be destroyed before the window itself is destroyed. You may /// access the underlying window via [`window`](Self::window) and [`window_mut`](Self::window_mut). -pub struct GraphicsContext { +pub struct GraphicsContext { window: W, graphics_context_impl: Box, } -impl GraphicsContext { +impl GraphicsContext { /// Creates a new instance of this struct, consuming the given window. /// /// # Safety /// /// - Ensure that the passed object is valid to draw a 2D buffer to pub unsafe fn new(window: W) -> Result> { - let raw_handle = window.raw_window_handle(); - let imple: Box = match raw_handle { + let raw_window_handle = window.raw_window_handle(); + let raw_display_handle = window.raw_display_handle(); + + let imple: Box = match (raw_window_handle, raw_display_handle) { #[cfg(target_os = "linux")] - RawWindowHandle::Xlib(xlib_handle) => Box::new(x11::X11Impl::new(xlib_handle)?), + (RawWindowHandle::Xlib(xlib_window_handle), RawDisplayHandle::Xlib(xlib_display_handle)) => Box::new(x11::X11Impl::new(xlib_window_handle, xlib_display_handle)?), #[cfg(target_os = "linux")] - RawWindowHandle::Wayland(wayland_handle) => Box::new(wayland::WaylandImpl::new(wayland_handle)?), + (RawWindowHandle::Wayland(wayland_window_handle), RawDisplayHandle::Wayland(wayland_display_handle)) => Box::new(wayland::WaylandImpl::new(wayland_window_handle, wayland_display_handle)?), #[cfg(target_os = "windows")] - RawWindowHandle::Win32(win32_handle) => Box::new(win32::Win32Impl::new(&win32_handle)?), + (RawWindowHandle::Win32(win32_handle), _) => Box::new(win32::Win32Impl::new(&win32_handle)?), #[cfg(target_os = "macos")] - RawWindowHandle::AppKit(appkit_handle) => Box::new(cg::CGImpl::new(appkit_handle)?), + (RawWindowHandle::AppKit(appkit_handle), _) => Box::new(cg::CGImpl::new(appkit_handle)?), #[cfg(target_arch = "wasm32")] - RawWindowHandle::Web(web_handle) => Box::new(web::WebImpl::new(web_handle)?), - unimplemented_handle_type => return Err(SoftBufferError::UnsupportedPlatform { + (RawWindowHandle::Web(web_handle), _) => Box::new(web::WebImpl::new(web_handle)?), + (unimplemented_window_handle, unimplemented_display_handle) => return Err(SoftBufferError::UnsupportedPlatform { window, - human_readable_platform_name: window_handle_type_name(&unimplemented_handle_type), - handle: unimplemented_handle_type, + human_readable_window_platform_name: window_handle_type_name(&unimplemented_window_handle), + human_readable_display_platform_name: display_handle_type_name(&unimplemented_display_handle), + window_handle: unimplemented_window_handle, + display_handle: unimplemented_display_handle }), }; @@ -122,7 +127,7 @@ impl GraphicsContext { } } -impl AsRef for GraphicsContext { +impl AsRef for GraphicsContext { /// Equivalent to [`self.window()`](Self::window()). #[inline] fn as_ref(&self) -> &W { @@ -145,6 +150,28 @@ fn window_handle_type_name(handle: &RawWindowHandle) -> &'static str { RawWindowHandle::AppKit(_) => "AppKit", RawWindowHandle::Orbital(_) => "Orbital", RawWindowHandle::UiKit(_) => "UiKit", + RawWindowHandle::Xcb(_) => "XCB", + RawWindowHandle::Drm(_) => "DRM", + RawWindowHandle::Gbm(_) => "GBM", + RawWindowHandle::Haiku(_) => "Haiku", + _ => "Unknown Name", //don't completely fail to compile if there is a new raw window handle type that's added at some point + } +} + +fn display_handle_type_name(handle: &RawDisplayHandle) -> &'static str { + match handle { + RawDisplayHandle::Xlib(_) => "Xlib", + RawDisplayHandle::Web(_) => "Web", + RawDisplayHandle::Wayland(_) => "Wayland", + RawDisplayHandle::AppKit(_) => "AppKit", + RawDisplayHandle::Orbital(_) => "Orbital", + RawDisplayHandle::UiKit(_) => "UiKit", + RawDisplayHandle::Xcb(_) => "XCB", + RawDisplayHandle::Drm(_) => "DRM", + RawDisplayHandle::Gbm(_) => "GBM", + RawDisplayHandle::Haiku(_) => "Haiku", + RawDisplayHandle::Windows(_) => "Windows", + RawDisplayHandle::Android(_) => "Android", _ => "Unknown Name", //don't completely fail to compile if there is a new raw window handle type that's added at some point } } diff --git a/src/wayland.rs b/src/wayland.rs index 99b96cd..db78275 100644 --- a/src/wayland.rs +++ b/src/wayland.rs @@ -1,4 +1,4 @@ -use raw_window_handle::{HasRawWindowHandle, WaylandHandle}; +use raw_window_handle::{HasRawWindowHandle, WaylandDisplayHandle, WaylandWindowHandle}; use tempfile::tempfile; use wayland_client::{Display, sys::client::wl_display, GlobalManager, protocol::{wl_shm::WlShm, wl_buffer::WlBuffer, wl_surface::WlSurface}, Main, Proxy, EventQueue}; use crate::{GraphicsContextImpl, SoftBufferError, error::unwrap}; @@ -20,15 +20,15 @@ struct WaylandBuffer{ impl WaylandImpl { - pub unsafe fn new(handle: WaylandHandle) -> Result> { - let display = Display::from_external_display(handle.display as *mut wl_display); + pub unsafe fn new(window_handle: WaylandWindowHandle, display_handle: WaylandDisplayHandle) -> Result> { + let display = Display::from_external_display(display_handle.display as *mut wl_display); let mut event_queue = display.create_event_queue(); let attached_display = (*display).clone().attach(event_queue.token()); let globals = GlobalManager::new(&attached_display); unwrap(event_queue.sync_roundtrip(&mut (), |_, _, _| unreachable!()), "Failed to make round trip to server")?; let shm = unwrap(globals.instantiate_exact::(1), "Failed to instantiate Wayland Shm")?; let tempfile = unwrap(tempfile(), "Failed to create temporary file to store buffer.")?; - let surface = Proxy::from_c_ptr(handle.surface as _).into(); + let surface = Proxy::from_c_ptr(window_handle.surface as _).into(); Ok(Self{ _event_queue: event_queue, surface, shm, tempfile, diff --git a/src/web.rs b/src/web.rs index bda5cfb..e20fa5e 100644 --- a/src/web.rs +++ b/src/web.rs @@ -1,5 +1,5 @@ use raw_window_handle::HasRawWindowHandle; -use raw_window_handle::WebHandle; +use raw_window_handle::WebWindowHandle; use wasm_bindgen::Clamped; use wasm_bindgen::JsCast; use web_sys::CanvasRenderingContext2d; @@ -15,7 +15,7 @@ pub struct WebImpl { } impl WebImpl { - pub fn new(handle: WebHandle) -> Result> { + pub fn new(handle: WebWindowHandle) -> Result> { let canvas: HtmlCanvasElement = web_sys::window() .ok_or_else(|| { SoftBufferError::PlatformError( diff --git a/src/win32.rs b/src/win32.rs index f2691fb..f117624 100644 --- a/src/win32.rs +++ b/src/win32.rs @@ -1,5 +1,5 @@ use crate::{GraphicsContextImpl, SoftBufferError}; -use raw_window_handle::{HasRawWindowHandle, Win32Handle}; +use raw_window_handle::{HasRawWindowHandle, Win32WindowHandle}; use std::os::raw::c_int; use winapi::shared::windef::{HDC, HWND}; use winapi::um::wingdi::{StretchDIBits, BITMAPINFOHEADER, BI_BITFIELDS, RGBQUAD}; @@ -19,7 +19,7 @@ struct BitmapInfo { } impl Win32Impl { - pub unsafe fn new(handle: &Win32Handle) -> Result> { + pub unsafe fn new(handle: &Win32WindowHandle) -> Result> { let dc = GetDC(handle.hwnd as HWND); if dc.is_null(){ diff --git a/src/x11.rs b/src/x11.rs index cf371ee..6515cf2 100644 --- a/src/x11.rs +++ b/src/x11.rs @@ -1,10 +1,11 @@ use crate::{GraphicsContextImpl, SoftBufferError}; -use raw_window_handle::{HasRawWindowHandle, XlibHandle}; +use raw_window_handle::{HasRawDisplayHandle, HasRawWindowHandle, XlibDisplayHandle, XlibWindowHandle}; use std::os::raw::{c_char, c_uint}; use x11_dl::xlib::{Display, Visual, Xlib, ZPixmap, GC}; pub struct X11Impl { - handle: XlibHandle, + window_handle: XlibWindowHandle, + display_handle: XlibDisplayHandle, lib: Xlib, gc: GC, visual: *mut Visual, @@ -12,19 +13,20 @@ pub struct X11Impl { } impl X11Impl { - pub unsafe fn new(handle: XlibHandle) -> Result> { + pub unsafe fn new(window_handle: XlibWindowHandle, display_handle: XlibDisplayHandle) -> Result> { let lib = match Xlib::open() { Ok(lib) => lib, Err(e) => return Err(SoftBufferError::PlatformError(Some("Failed to open Xlib".into()), Some(Box::new(e)))) }; - let screen = (lib.XDefaultScreen)(handle.display as *mut Display); - let gc = (lib.XDefaultGC)(handle.display as *mut Display, screen); - let visual = (lib.XDefaultVisual)(handle.display as *mut Display, screen); - let depth = (lib.XDefaultDepth)(handle.display as *mut Display, screen); + let screen = (lib.XDefaultScreen)(display_handle.display as *mut Display); + let gc = (lib.XDefaultGC)(display_handle.display as *mut Display, screen); + let visual = (lib.XDefaultVisual)(display_handle.display as *mut Display, screen); + let depth = (lib.XDefaultDepth)(display_handle.display as *mut Display, screen); Ok( Self { - handle, + window_handle, + display_handle, lib, gc, visual, @@ -38,7 +40,7 @@ impl GraphicsContextImpl for X11Impl { unsafe fn set_buffer(&mut self, buffer: &[u32], width: u16, height: u16) { //create image let image = (self.lib.XCreateImage)( - self.handle.display as *mut Display, + self.display_handle.display as *mut Display, self.visual, self.depth as u32, ZPixmap, @@ -52,8 +54,8 @@ impl GraphicsContextImpl for X11Impl { //push image to window (self.lib.XPutImage)( - self.handle.display as *mut Display, - self.handle.window, + self.display_handle.display as *mut Display, + self.window_handle.window, self.gc, image, 0,