Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change how handles are constructed, so that we can ensure non-null handles #136

Merged
merged 5 commits into from
Aug 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

## Unreleased

* **Breaking:** Raw pointer handles now use `NonNull` where appropriate, to avoid null pointer dereferences.
* **Breaking:** Renamed `empty` methods to `new`, and take parameters in most of those, to better match normal Rust semantics.
* **Breaking:** `HasRaw(Display/Window)Handle::raw_(display/window)_handle` returns a result indicating if fetching the window handle failed (#122).
* **Breaking:** Remove the `Active/ActiveHandle` types from the public API (#126).
* **Breaking:** Remove `AppKitWindowHandle::ns_window` and `UiKitWindowHandle::ui_window` since they can be retrived from the view (#129).
Expand Down
51 changes: 29 additions & 22 deletions src/android.rs
Original file line number Diff line number Diff line change
@@ -1,43 +1,50 @@
use core::ffi::c_void;
use core::ptr;
use core::ptr::NonNull;

/// Raw display handle for Android.
///
/// ## Construction
/// ```
/// # use raw_window_handle::AndroidDisplayHandle;
/// let mut display_handle = AndroidDisplayHandle::empty();
/// /* set fields */
/// ```
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct AndroidDisplayHandle;
pub struct AndroidDisplayHandle {}

impl AndroidDisplayHandle {
pub fn empty() -> Self {
/// Create a new empty display handle.
///
///
/// # Example
///
/// ```
/// # use raw_window_handle::AndroidDisplayHandle;
/// let handle = AndroidDisplayHandle::new();
/// ```
pub fn new() -> Self {
Self {}
}
}

/// Raw window handle for Android NDK.
///
/// ## Construction
/// ```
/// # use raw_window_handle::AndroidNdkWindowHandle;
/// let mut window_handle = AndroidNdkWindowHandle::empty();
/// /* set fields */
/// ```
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct AndroidNdkWindowHandle {
/// A pointer to an `ANativeWindow`.
pub a_native_window: *mut c_void,
pub a_native_window: NonNull<c_void>,
}

impl AndroidNdkWindowHandle {
pub fn empty() -> Self {
Self {
a_native_window: ptr::null_mut(),
}
/// Create a new handle to an `ANativeWindow`.
///
///
/// # Example
///
/// ```
/// # use core::ptr::NonNull;
/// # use raw_window_handle::AndroidNdkWindowHandle;
/// # type ANativeWindow = ();
/// #
/// let ptr: NonNull<ANativeWindow>;
/// # ptr = NonNull::from(&());
/// let handle = AndroidNdkWindowHandle::new(ptr.cast());
/// ```
pub fn new(a_native_window: NonNull<c_void>) -> Self {
Self { a_native_window }
}
}
51 changes: 29 additions & 22 deletions src/appkit.rs
Original file line number Diff line number Diff line change
@@ -1,43 +1,50 @@
use core::ffi::c_void;
use core::ptr;
use core::ptr::NonNull;

/// Raw display handle for AppKit.
///
/// ## Construction
/// ```
/// # use raw_window_handle::AppKitDisplayHandle;
/// let mut display_handle = AppKitDisplayHandle::empty();
/// /* set fields */
/// ```
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct AppKitDisplayHandle;
pub struct AppKitDisplayHandle {}

impl AppKitDisplayHandle {
pub fn empty() -> Self {
/// Create a new empty display handle.
///
///
/// # Example
///
/// ```
/// # use raw_window_handle::AppKitDisplayHandle;
/// let handle = AppKitDisplayHandle::new();
/// ```
pub fn new() -> Self {
Self {}
}
}

/// Raw window handle for AppKit.
///
/// ## Construction
/// ```
/// # use raw_window_handle::AppKitWindowHandle;
/// let mut window_handle = AppKitWindowHandle::empty();
/// /* set fields */
/// ```
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct AppKitWindowHandle {
/// A pointer to an `NSView` object.
pub ns_view: *mut c_void,
pub ns_view: NonNull<c_void>,
}

impl AppKitWindowHandle {
pub fn empty() -> Self {
Self {
ns_view: ptr::null_mut(),
}
/// Create a new handle to a view.
///
///
/// # Example
///
/// ```
/// # use core::ptr::NonNull;
/// # use raw_window_handle::AppKitWindowHandle;
/// # type NSView = ();
/// #
/// let view: &NSView;
/// # view = &();
/// let handle = AppKitWindowHandle::new(NonNull::from(view).cast());
/// ```
pub fn new(ns_view: NonNull<c_void>) -> Self {
Self { ns_view }
}
}
55 changes: 33 additions & 22 deletions src/haiku.rs
Original file line number Diff line number Diff line change
@@ -1,46 +1,57 @@
use core::ffi::c_void;
use core::ptr;
use core::ptr::NonNull;

/// Raw display handle for Haiku.
///
/// ## Construction
/// ```
/// # use raw_window_handle::HaikuDisplayHandle;
/// let mut display_handle = HaikuDisplayHandle::empty();
/// /* set fields */
/// ```
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct HaikuDisplayHandle;
pub struct HaikuDisplayHandle {}

impl HaikuDisplayHandle {
pub fn empty() -> Self {
/// Create a new empty display handle.
///
///
/// # Example
///
/// ```
/// # use raw_window_handle::HaikuDisplayHandle;
/// let handle = HaikuDisplayHandle::new();
/// ```
pub fn new() -> Self {
Self {}
}
}

/// Raw window handle for Haiku.
///
/// ## Construction
/// ```
/// # use raw_window_handle::HaikuWindowHandle;
/// let mut window_handle = HaikuWindowHandle::empty();
/// /* set fields */
/// ```
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct HaikuWindowHandle {
/// A pointer to a BWindow object
pub b_window: *mut c_void,
pub b_window: NonNull<c_void>,
/// A pointer to a BDirectWindow object that might be null
pub b_direct_window: *mut c_void,
pub b_direct_window: Option<NonNull<c_void>>,
}
madsmtm marked this conversation as resolved.
Show resolved Hide resolved

impl HaikuWindowHandle {
pub fn empty() -> Self {
/// Create a new handle to a window.
///
///
/// # Example
///
/// ```
/// # use core::ptr::NonNull;
/// # use raw_window_handle::HaikuWindowHandle;
/// # type BWindow = ();
/// #
/// let b_window: NonNull<BWindow>;
/// # b_window = NonNull::from(&());
/// let mut handle = HaikuWindowHandle::new(b_window.cast());
/// // Optionally set `b_direct_window`.
/// handle.b_direct_window = None;
/// ```
pub fn new(b_window: NonNull<c_void>) -> Self {
Self {
b_window: ptr::null_mut(),
b_direct_window: ptr::null_mut(),
b_window,
b_direct_window: None,
}
}
}
4 changes: 2 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ use core::fmt;
///
/// # Safety
///
/// Users can safely assume that non-`null`/`0` fields are valid handles, and it is up to the
/// Users can safely assume that pointers and non-zero fields are valid, and it is up to the
/// implementer of this trait to ensure that condition is upheld.
///
/// Despite that qualification, implementers should still make a best-effort attempt to fill in all
Expand Down Expand Up @@ -205,7 +205,7 @@ pub enum RawWindowHandle {
///
/// # Safety
///
/// Users can safely assume that non-`null`/`0` fields are valid handles, and it is up to the
/// Users can safely assume that pointers and non-zero fields are valid, and it is up to the
/// implementer of this trait to ensure that condition is upheld.
///
/// Despite that qualification, implementers should still make a best-effort attempt to fill in all
Expand Down
53 changes: 31 additions & 22 deletions src/redox.rs
Original file line number Diff line number Diff line change
@@ -1,43 +1,52 @@
use core::ffi::c_void;
use core::ptr;
use core::ptr::NonNull;

/// Raw display handle for the Redox operating system.
///
/// ## Construction
/// ```
/// # use raw_window_handle::OrbitalDisplayHandle;
/// let mut display_handle = OrbitalDisplayHandle::empty();
/// /* set fields */
/// ```
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct OrbitalDisplayHandle;
pub struct OrbitalDisplayHandle {}

impl OrbitalDisplayHandle {
pub fn empty() -> Self {
/// Create a new empty display handle.
///
///
/// # Example
///
/// ```
/// # use raw_window_handle::OrbitalDisplayHandle;
/// let handle = OrbitalDisplayHandle::new();
/// ```
pub fn new() -> Self {
Self {}
}
}

/// Raw window handle for the Redox operating system.
///
/// ## Construction
/// ```
/// # use raw_window_handle::OrbitalWindowHandle;
/// let mut window_handle = OrbitalWindowHandle::empty();
/// /* set fields */
/// ```
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct OrbitalWindowHandle {
/// A pointer to an orbclient window.
pub window: *mut c_void,
// TODO(madsmtm): I think this is a file descriptor, so perhaps it should
// actually use `std::os::fd::RawFd`, or some sort of integer instead?
pub window: NonNull<c_void>,
}

impl OrbitalWindowHandle {
pub fn empty() -> Self {
Self {
window: ptr::null_mut(),
}
/// Create a new handle to a window.
///
///
/// # Example
///
/// ```
/// # use core::ptr::NonNull;
/// # use raw_window_handle::OrbitalWindowHandle;
/// # type Window = ();
/// #
/// let window: NonNull<Window>;
/// # window = NonNull::from(&());
/// let mut handle = OrbitalWindowHandle::new(window.cast());
/// ```
pub fn new(window: NonNull<c_void>) -> Self {
Self { window }
}
}
Loading