diff --git a/gio/Gir.toml b/gio/Gir.toml index 2f2e32cf35c2..e2b922eee982 100644 --- a/gio/Gir.toml +++ b/gio/Gir.toml @@ -1273,3 +1273,16 @@ status = "generate" name = "get" [object.function.return] nullable = false + +[[object]] +name = "Gio.Win32InputStream" +status = "manual" +cfg_condition = "windows" +manual_traits = ["Win32InputStreamExtManual"] + + +[[object]] +name = "Gio.Win32OutputStream" +status = "manual" +cfg_condition = "windows" +manual_traits = ["Win32OutputStreamExtManual"] diff --git a/gio/src/lib.rs b/gio/src/lib.rs index 6f5622b6aa02..2fa5c77a3536 100644 --- a/gio/src/lib.rs +++ b/gio/src/lib.rs @@ -100,3 +100,13 @@ mod tls_connection; pub use crate::tls_connection::TlsConnectionManualExt; pub mod task; + +#[cfg(target_family = "windows")] +mod win32_input_stream; +#[cfg(target_family = "windows")] +pub use self::win32_input_stream::{Win32InputStream, NONE_WIN32_INPUT_STREAM}; + +#[cfg(target_family = "windows")] +mod win32_output_stream; +#[cfg(target_family = "windows")] +pub use self::win32_output_stream::{Win32OutputStream, NONE_WIN32_OUTPUT_STREAM}; diff --git a/gio/src/win32_input_stream.rs b/gio/src/win32_input_stream.rs new file mode 100644 index 000000000000..2f2e30d4ec1a --- /dev/null +++ b/gio/src/win32_input_stream.rs @@ -0,0 +1,82 @@ +// Take a look at the license at the top of the repository in the LICENSE file. + +use crate::InputStream; +use glib::object::{Cast, IsA}; +use glib::translate::*; +use std::fmt; + +use std::os::windows::io::{AsRawHandle, FromRawHandle, IntoRawHandle, RawHandle}; + +glib::wrapper! { + pub struct Win32InputStream(Object) @extends InputStream; + + match fn { + get_type => || ffi::g_win32_input_stream_get_type(), + } +} + +pub const NONE_WIN32_INPUT_STREAM: Option<&Win32InputStream> = None; + +pub trait Win32InputStreamExt: 'static { + #[doc(alias = "g_win32_input_stream_get_close_handle")] + fn get_close_handle(&self) -> bool; +} + +impl> Win32InputStreamExt for O { + fn get_close_handle(&self) -> bool { + unsafe { + from_glib(ffi::g_win32_input_stream_get_close_handle( + self.as_ref().to_glib_none().0, + )) + } + } +} + +impl fmt::Display for Win32InputStream { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("Win32InputStream") + } +} + +impl Win32InputStream { + #[doc(alias = "g_win32_input_stream_new")] + #[allow(clippy::missing_safety_doc)] + pub unsafe fn new(handle: T) -> Win32InputStream { + let handle = handle.into_raw_handle(); + let close_handle = true.to_glib(); + InputStream::from_glib_full(ffi::g_win32_input_stream_new(handle, close_handle)) + .unsafe_cast() + } +} + +impl AsRawHandle for Win32InputStream { + fn as_raw_handle(&self) -> RawHandle { + unsafe { ffi::g_win32_input_stream_get_handle(self.to_glib_none().0) as _ } + } +} + +pub trait Win32InputStreamExtManual: Sized { + #[doc(alias = "g_win32_input_stream_get_handle")] + fn get_handle(&self) -> T; + + #[doc(alias = "g_win32_input_stream_set_close_handle")] + #[allow(clippy::missing_safety_doc)] + unsafe fn set_close_handle(&self, close_handle: bool); +} + +impl> Win32InputStreamExtManual for O { + fn get_handle(&self) -> T { + unsafe { + T::from_raw_handle(ffi::g_win32_input_stream_get_handle( + self.as_ref().to_glib_none().0, + )) + } + } + + unsafe fn set_close_handle(&self, close_handle: bool) { + ffi::g_win32_input_stream_set_close_handle( + self.as_ref().to_glib_none().0, + close_handle.to_glib(), + ); + } +} diff --git a/gio/src/win32_output_stream.rs b/gio/src/win32_output_stream.rs new file mode 100644 index 000000000000..e118fa3d3440 --- /dev/null +++ b/gio/src/win32_output_stream.rs @@ -0,0 +1,82 @@ +// Take a look at the license at the top of the repository in the LICENSE file. + +use crate::OutputStream; +use glib::object::{Cast, IsA}; +use glib::translate::*; +use std::fmt; + +use std::os::windows::io::{AsRawHandle, FromRawHandle, IntoRawHandle, RawHandle}; + +glib::wrapper! { + pub struct Win32OutputStream(Object) @extends OutputStream; + + match fn { + get_type => || ffi::g_win32_output_stream_get_type(), + } +} + +pub const NONE_WIN32_OUTPUT_STREAM: Option<&Win32OutputStream> = None; + +pub trait Win32OutputStreamExt: 'static { + #[doc(alias = "g_win32_output_stream_get_close_handle")] + fn get_close_handle(&self) -> bool; +} + +impl> Win32OutputStreamExt for O { + fn get_close_handle(&self) -> bool { + unsafe { + from_glib(ffi::g_win32_output_stream_get_close_handle( + self.as_ref().to_glib_none().0, + )) + } + } +} + +impl fmt::Display for Win32OutputStream { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("Win32OutputStream") + } +} + +impl Win32OutputStream { + #[doc(alias = "g_win32_output_stream_new")] + #[allow(clippy::missing_safety_doc)] + pub unsafe fn new(handle: T) -> Win32OutputStream { + let handle = handle.into_raw_handle(); + let close_handle = true.to_glib(); + OutputStream::from_glib_full(ffi::g_win32_output_stream_new(handle, close_handle)) + .unsafe_cast() + } +} + +impl AsRawHandle for Win32OutputStream { + fn as_raw_handle(&self) -> RawHandle { + unsafe { ffi::g_win32_output_stream_get_handle(self.to_glib_none().0) as _ } + } +} + +pub trait Win32OutputStreamExtManual: Sized { + #[doc(alias = "g_win32_output_stream_get_handle")] + fn get_handle(&self) -> T; + + #[doc(alias = "g_win32_output_stream_set_close_handle")] + #[allow(clippy::missing_safety_doc)] + unsafe fn set_close_handle(&self, close_handle: bool); +} + +impl> Win32OutputStreamExtManual for O { + fn get_handle(&self) -> T { + unsafe { + T::from_raw_handle(ffi::g_win32_output_stream_get_handle( + self.as_ref().to_glib_none().0, + )) + } + } + + unsafe fn set_close_handle(&self, close_handle: bool) { + ffi::g_win32_output_stream_set_close_handle( + self.as_ref().to_glib_none().0, + close_handle.to_glib(), + ); + } +} diff --git a/gio/sys/Gir.toml b/gio/sys/Gir.toml index 6114112926a5..cd2fd397115f 100644 --- a/gio/sys/Gir.toml +++ b/gio/sys/Gir.toml @@ -46,3 +46,13 @@ status = "manual" [[object]] name = "Gio.SocketMsgFlags" status = "manual" + +[[object]] +name = "Gio.Win32InputStream" +status = "manual" +cfg_condition = "windows" + +[[object]] +name = "Gio.Win32OutputStream" +status = "manual" +cfg_condition = "windows" diff --git a/gio/sys/src/manual.rs b/gio/sys/src/manual.rs index 8e68a0cb6863..45639070e3c7 100644 --- a/gio/sys/src/manual.rs +++ b/gio/sys/src/manual.rs @@ -35,3 +35,135 @@ mod libc_constants { pub const G_SOCKET_MSG_PEEK: super::GSocketMsgFlags = libc::MSG_PEEK; pub const G_SOCKET_MSG_DONTROUTE: super::GSocketMsgFlags = libc::MSG_DONTROUTE; } + +#[cfg(target_family = "windows")] +pub use self::windows_streams::*; + +#[cfg(target_family = "windows")] +mod windows_streams { + use crate::{ + gboolean, GInputStream, GInputStreamClass, GOutputStream, GOutputStreamClass, GType, + }; + use libc::c_void; + + #[link(name = "gio-2.0")] + extern "C" { + //========================================================================= + // GWin32InputStream + //========================================================================= + pub fn g_win32_input_stream_get_type() -> GType; + pub fn g_win32_input_stream_new( + handle: *mut c_void, + close_handle: gboolean, + ) -> *mut GInputStream; + pub fn g_win32_input_stream_get_close_handle(stream: *mut GWin32InputStream) -> gboolean; + pub fn g_win32_input_stream_get_handle(stream: *mut GWin32InputStream) -> *mut c_void; + pub fn g_win32_input_stream_set_close_handle( + stream: *mut GWin32InputStream, + close_handle: gboolean, + ); + + //========================================================================= + // GWin32OutputStream + //========================================================================= + pub fn g_win32_output_stream_get_type() -> GType; + pub fn g_win32_output_stream_new( + handle: *mut c_void, + close_handle: gboolean, + ) -> *mut GOutputStream; + pub fn g_win32_output_stream_get_close_handle(stream: *mut GWin32OutputStream) -> gboolean; + pub fn g_win32_output_stream_get_handle(stream: *mut GWin32OutputStream) -> *mut c_void; + pub fn g_win32_output_stream_set_close_handle( + stream: *mut GWin32OutputStream, + close_handle: gboolean, + ); + } + + #[repr(C)] + #[derive(Copy, Clone)] + pub struct GWin32InputStreamClass { + pub parent_class: GInputStreamClass, + pub _g_reserved1: Option, + pub _g_reserved2: Option, + pub _g_reserved3: Option, + pub _g_reserved4: Option, + pub _g_reserved5: Option, + } + + impl ::std::fmt::Debug for GWin32InputStreamClass { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + f.debug_struct(&format!("GWin32InputStreamClass @ {:?}", self as *const _)) + .field("parent_class", &self.parent_class) + .field("_g_reserved1", &self._g_reserved1) + .field("_g_reserved2", &self._g_reserved2) + .field("_g_reserved3", &self._g_reserved3) + .field("_g_reserved4", &self._g_reserved4) + .field("_g_reserved5", &self._g_reserved5) + .finish() + } + } + + #[repr(C)] + pub struct _GWin32InputStreamPrivate(c_void); + + pub type GWin32InputStreamPrivate = *mut _GWin32InputStreamPrivate; + + #[repr(C)] + #[derive(Copy, Clone)] + pub struct GWin32InputStream { + pub parent_instance: GInputStream, + pub priv_: *mut GWin32InputStreamPrivate, + } + + impl ::std::fmt::Debug for GWin32InputStream { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + f.debug_struct(&format!("GWin32InputStream @ {:?}", self as *const _)) + .field("parent_instance", &self.parent_instance) + .finish() + } + } + + #[repr(C)] + #[derive(Copy, Clone)] + pub struct GWin32OutputStreamClass { + pub parent_class: GOutputStreamClass, + pub _g_reserved1: Option, + pub _g_reserved2: Option, + pub _g_reserved3: Option, + pub _g_reserved4: Option, + pub _g_reserved5: Option, + } + + impl ::std::fmt::Debug for GWin32OutputStreamClass { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + f.debug_struct(&format!("GWin32OutputStreamClass @ {:?}", self as *const _)) + .field("parent_class", &self.parent_class) + .field("_g_reserved1", &self._g_reserved1) + .field("_g_reserved2", &self._g_reserved2) + .field("_g_reserved3", &self._g_reserved3) + .field("_g_reserved4", &self._g_reserved4) + .field("_g_reserved5", &self._g_reserved5) + .finish() + } + } + + #[repr(C)] + pub struct _GWin32OutputStreamPrivate(c_void); + + pub type GWin32OutputStreamPrivate = *mut _GWin32OutputStreamPrivate; + + #[repr(C)] + #[derive(Copy, Clone)] + pub struct GWin32OutputStream { + pub parent_instance: GOutputStream, + pub priv_: *mut GWin32OutputStreamPrivate, + } + + impl ::std::fmt::Debug for GWin32OutputStream { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + f.debug_struct(&format!("GWin32OutputStream @ {:?}", self as *const _)) + .field("parent_instance", &self.parent_instance) + .finish() + } + } +}