diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index d5a4e08ec1d6..a39636ae6bcf 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -7,6 +7,7 @@ on: - "examples/**" - "gdk4/**" - "gdk4-wayland/**" + - "gdk4-win32/**" - "gdk4-x11/**" - "gsk4/**" - "gtk4/**" @@ -17,6 +18,7 @@ on: - "examples/**" - "gdk4/**" - "gdk4-wayland/**" + - "gdk4-win32/**" - "gdk4-x11/**" - "gsk4/**" - "gtk4/**" @@ -148,6 +150,7 @@ jobs: - { name: "gsk4", is_macros_crate: false } - { name: "gdk4-x11", is_macros_crate: false } - { name: "gdk4-wayland", is_macros_crate: false } + - { name: "gdk4-win32", is_macros_crate: false } - { name: "gtk4-macros", is_macros_crate: true } steps: - uses: actions/checkout@v2 diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index af2d0f83a6e9..d44162b69ed8 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -7,6 +7,7 @@ on: - ".github/workflows/docs.yml" - "gdk4/**" - "gdk4-wayland/**" + - "gdk4-win32/**" - "gdk4-x11/**" - "gsk4/**" - "gtk4/**" @@ -17,6 +18,7 @@ on: - ".github/workflows/docs.yml" - "gdk4/**" - "gdk4-wayland/**" + - "gdk4-win32/**" - "gdk4-x11/**" - "gsk4/**" - "gtk4/**" @@ -67,7 +69,15 @@ jobs: - uses: actions-rs/cargo@v1 with: command: doc - args: -p gdk4 -p gdk4-sys -p gdk4-wayland -p gdk4-wayland-sys -p gdk4-x11 -p gdk4-x11-sys -p gsk4 -p gsk4-sys -p gtk4 -p gtk4-sys -p gtk4-macros --features "dox" --no-deps + args: > + -p gdk4 -p gdk4-sys + -p gdk4-wayland -p gdk4-wayland-sys + -p gdk4-win32 -p gdk4-win32-sys + -p gdk4-x11 -p gdk4-x11-sys + -p gsk4 -p gsk4-sys + -p gtk4 -p gtk4-sys + -p gtk4-macros + --features "dox" --no-deps - name: Fix broken URLs run: | diff --git a/.github/workflows/windows-msvc.yml b/.github/workflows/windows-msvc.yml index 9f09dc8873d0..300ba23c2d0f 100644 --- a/.github/workflows/windows-msvc.yml +++ b/.github/workflows/windows-msvc.yml @@ -6,6 +6,7 @@ on: paths: - ".github/workflows/windows-msvc.yml" - "gdk4/**" + - "gdk4-win32/**" - "gsk4/**" - "gtk4/**" - "gtk4-macros/**" @@ -13,6 +14,7 @@ on: paths: - ".github/workflows/windows-msvc.yml" - "gdk4/**" + - "gdk4-win32/**" - "gsk4/**" - "gtk4/**" - "gtk4-macros/**" @@ -103,3 +105,22 @@ jobs: with: command: test args: --features v4_10,xml_validation + + - name: Build gdk-win32 + working-directory: /gdk4-win32 + uses: actions-rs/cargo@v1 + with: + command: build + args: --features egl,win32 + - name: Clippy gdk-win32 + working-directory: /gdk4-win32 + uses: actions-rs/cargo@v1 + with: + command: clippy + args: --features egl,win32 + - name: Tests gdk-win32 + working-directory: /gdk4-win32 + uses: actions-rs/cargo@v1 + with: + command: test + args: --features egl,win32 diff --git a/Cargo.toml b/Cargo.toml index 5078b9399821..37bcd39959ec 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,6 +20,8 @@ members = [ "gdk4-x11/sys", "gdk4-wayland", "gdk4-wayland/sys", + "gdk4-win32", + "gdk4-win32/sys", "gsk4", "gsk4/sys", "gtk4", diff --git a/README.md b/README.md index 7d142fd899da..a250dcfb012e 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,7 @@ A group of crates that aims to provide complete [GTK](https://gtk.org/) 4 bindin - [GTK](./gtk4) - [GDK](./gdk4): An intermediate layer which isolates GTK from the details of the windowing system. - [GDK Wayland](./gdk4-wayland): Wayland backend specific functions. + - [GDK Win32](./gdk4-win32): Windows backend specific functions. - [GDK X11](./gdk4-x11): X backend specific functions. - [GSK](./gsk4): An intermediate layer which isolates GTK from the details of the OpenGL or Vulkan implementation. diff --git a/gdk4-win32/COPYRIGHT b/gdk4-win32/COPYRIGHT new file mode 120000 index 000000000000..dc5f40a221a3 --- /dev/null +++ b/gdk4-win32/COPYRIGHT @@ -0,0 +1 @@ +../COPYRIGHT \ No newline at end of file diff --git a/gdk4-win32/Cargo.toml b/gdk4-win32/Cargo.toml new file mode 100644 index 000000000000..3e98db93b809 --- /dev/null +++ b/gdk4-win32/Cargo.toml @@ -0,0 +1,63 @@ +[package] +authors = ["The gtk-rs Project Developers"] +description = "Rust bindings of the GDK4 Win32 library" +documentation = "https://gtk-rs.org/gtk4-rs/stable/latest/docs/gdk4_win32/" +edition = "2021" +homepage = "https://gtk-rs.org/" +keywords = ["gdk4", "gdk4-win32", "gtk-rs", "gnome", "GUI"] +license = "MIT" +name = "gdk4-win32" +readme = "README.md" +repository = "https://github.com/gtk-rs/gtk4-rs" +version = "0.6.0" +rust-version = "1.63" +build = "build.rs" + +[package.metadata.docs.rs] +features = ["dox"] + +[package.metadata.system-deps.gtk4_win32] +name = "gtk4-win32" +version = "4" + +[features] +v4_4 = ["ffi/v4_4"] +dox = ["ffi/dox", "gdk/dox", "gio/dox", "glib/dox", "egl", "win32"] +egl = ["khronos-egl"] +win32 = ["windows"] + +[dependencies] +libc = "0.2" +khronos-egl = {version = "4.1.0", optional = true} +windows = { version = "0.41.0", features = [ + "Win32_Foundation", + "Win32_UI_WindowsAndMessaging", +], optional = true } + +[dependencies.ffi] +path = "./sys" +package = "gdk4-win32-sys" +version = "0.6.0" + +[dependencies.gdk] +path = "../gdk4" +package = "gdk4" +version = "0.6.0" + +[dependencies.gio] +git = "https://github.com/gtk-rs/gtk-rs-core" +version = "0.17" +features = ["v2_66"] + +[dependencies.glib] +git = "https://github.com/gtk-rs/gtk-rs-core" +version = "0.17" +features = ["v2_66"] + +[dev-dependencies] +gir-format-check = "^0.1" +shell-words = "1.0.0" +tempfile = "3" + +[build-dependencies] +system-deps = "6" diff --git a/gdk4-win32/Gir.toml b/gdk4-win32/Gir.toml new file mode 100644 index 000000000000..b2713f9973a7 --- /dev/null +++ b/gdk4-win32/Gir.toml @@ -0,0 +1,123 @@ +[options] +girs_directories = ["../gir-files"] +library = "GdkWin32" +version = "4.0" +min_cfg_version = "4.0.0" +target_path = "." +work_mode = "normal" +use_gi_docgen = true +single_version_file = true +generate_safety_asserts = true +deprecate_by_min_version = true +trust_return_value_nullability = true + +generate = [ + "GdkWin32.Win32DisplayManager", + "GdkWin32.Win32Drag", + "GdkWin32.Win32GLContext", + "GdkWin32.Win32MessageFilterReturn", + "GdkWin32.Win32Monitor", + "GdkWin32.Win32Screen", +] + +manual = [ + "Gdk.Cursor", + "Gdk.DisplayManager", + "Gdk.DrawContext", + "Gdk.Rectangle", + "GdkPixbuf.Pixbuf", + "win32.HCURSOR", + "win32.HICON", + "win32.HWND", +] + +[[object]] +name = "Gdk.Device" +status = "manual" +final_type = false + [[object.function]] + name = "get_vendor_id" + ignore = true # docs only, otherwise it gets picked as ExtManual + [[object.function]] + name = "get_product_id" + ignore = true # docs only, otherwise it gets picked as ExtManual + +[[object]] +name = "Gdk.Display" +status = "manual" +final_type = false + [[object.function]] + name = "notify_startup_complete" + ignore = true # docs only, otherwise it gets picked as ExtManual + [[object.function]] + name = "get_product_id" + ignore = true # docs only, otherwise it gets picked as ExtManual + +[[object]] +name = "Gdk.Drag" +status = "manual" +final_type = false + +[[object]] +name = "Gdk.Event" # docs only +status = "manual" +final_type = false + +[[object]] +name = "Gdk.GLContext" +status = "manual" +final_type = false + +[[object]] +name = "Gdk.Monitor" +status = "manual" +final_type = false + [[object.function]] + name = "get_scale_factor" + ignore = true # docs only, otherwise it gets picked as ExtManual + +[[object]] +name = "Gdk.Surface" +status = "manual" +final_type = false + +[[object]] +name = "GdkWin32.*" +status = "generate" + +[[object.function]] +name = "win32_handle_table_lookup" +ignore = true # to be deprecated upstream, and not clean to bind + +[[object]] +name = "GdkWin32.Win32Display" +status = "generate" + [[object.function]] + name = "get_egl_display" + manual = true + +[[object]] +name = "GdkWin32.Win32HCursor" +status = "generate" +# doesn't work with HANDLE +# generate_builder = true + [[object.function]] + name = "new" + manual = true + [[object.property]] + name = "handle" + manual = true + +[[object]] +name = "GdkWin32.Win32Surface" +status = "generate" +# doesn't work with HANDLE + [[object.function]] + name = "lookup_for_display" + manual = true + [[object.function]] + name = "get_handle" + manual = true + [[object.function]] + name = "get_impl_hwnd" + manual = true diff --git a/gdk4-win32/LICENSE b/gdk4-win32/LICENSE new file mode 120000 index 000000000000..ea5b60640b01 --- /dev/null +++ b/gdk4-win32/LICENSE @@ -0,0 +1 @@ +../LICENSE \ No newline at end of file diff --git a/gdk4-win32/README.md b/gdk4-win32/README.md new file mode 100644 index 000000000000..a572faed2f5d --- /dev/null +++ b/gdk4-win32/README.md @@ -0,0 +1,60 @@ +# Rust GDK 4 Win32 bindings + +The project website is [here](https://gtk-rs.org/). + +Rust bindings of [GDK 4's Win32 backend](https://docs.gtk.org/gdk4-win32/), +part of [gtk4-rs](https://github.com/gtk-rs/gtk4-rs/). + +GDK is an intermediate layer that isolates GTK from the details of the windowing system. +GDK Win32 contains functions specific to the Win32 backend. + +## Minimum supported Rust version + +Currently, the minimum supported Rust version is `1.63.0`. + +## Documentation + +- The Rust API [Stable](https://gtk-rs.org/gtk4-rs/stable/latest/docs/gdk4_win32)/[Development](https://gtk-rs.org/gtk4-rs/git/docs/gdk4_win32/) +- [The C API](https://docs.gtk.org/gdk4-win32/) +- [GTK Installation instructions](https://www.gtk.org/docs/installations/) + +## Using + +We recommend using [crates from crates.io](https://crates.io/keywords/gtk-rs), +as [demonstrated here](https://gtk-rs.org/gtk4-rs/stable/latest/docs/gtk4/index.html#library-versions). + +If you want to track the bleeding edge, use the git dependency instead: + +```toml +[dependencies] +gdk-win32= { git = "https://github.com/gtk-rs/gtk4-rs.git", package = "gdk4-win32" } +``` + +Avoid mixing versioned and git crates like this: + +```toml +# This will not compile +[dependencies] +gdk-x11 = {version = "0.1", package = "gdk4-x11"} +gdk-win32 = { git = "https://github.com/gtk-rs/gtk4-rs.git", package = "gdk4-win32" } +``` + +### Features + +| Feature | Description | +| --- | ----------- | +| `v4_4` | Enable the new APIs part of GTK 4.4 | +| `egl` | Integration with the [khronos-egl](https://crates.io/crates/khronos-egl) crate | +| `win32` | Integration with the [windows](https://crates.io/crates/windows) crate | + +### See Also + +- [glib](https://crates.io/crates/glib) +- [gio](https://crates.io/crates/gio) +- [gsk4](https://crates.io/crates/gsk4) +- [gdk4](https://crates.io/crates/gdk4) +- [gtk4](https://crates.io/crates/gtk4) + +## License + +The Rust bindings of __gdk4-win32__ are available under the MIT License, please refer to it. diff --git a/gdk4-win32/build.rs b/gdk4-win32/build.rs new file mode 100644 index 000000000000..e7b297a532b8 --- /dev/null +++ b/gdk4-win32/build.rs @@ -0,0 +1,17 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from ../gir-files +// DO NOT EDIT + +#[cfg(not(feature = "dox"))] +use std::process; + +#[cfg(feature = "dox")] +fn main() {} // prevent linking libraries to avoid documentation failure + +#[cfg(not(feature = "dox"))] +fn main() { + if let Err(s) = system_deps::Config::new().probe() { + println!("cargo:warning={}", s); + process::exit(1); + } +} diff --git a/gdk4-win32/src/auto/enums.rs b/gdk4-win32/src/auto/enums.rs new file mode 100644 index 000000000000..0530a8e7c67a --- /dev/null +++ b/gdk4-win32/src/auto/enums.rs @@ -0,0 +1,57 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from gir-files (https://github.com/gtk-rs/gir-files) +// DO NOT EDIT + +use glib::translate::*; +use std::fmt; + +#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Clone, Copy)] +#[non_exhaustive] +#[doc(alias = "GdkWin32MessageFilterReturn")] +pub enum Win32MessageFilterReturn { + #[doc(alias = "GDK_WIN32_MESSAGE_FILTER_CONTINUE")] + Continue, + #[doc(alias = "GDK_WIN32_MESSAGE_FILTER_REMOVE")] + Remove, + #[doc(hidden)] + __Unknown(i32), +} + +impl fmt::Display for Win32MessageFilterReturn { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!( + f, + "Win32MessageFilterReturn::{}", + match *self { + Self::Continue => "Continue", + Self::Remove => "Remove", + _ => "Unknown", + } + ) + } +} + +#[doc(hidden)] +impl IntoGlib for Win32MessageFilterReturn { + type GlibType = ffi::GdkWin32MessageFilterReturn; + + fn into_glib(self) -> ffi::GdkWin32MessageFilterReturn { + match self { + Self::Continue => ffi::GDK_WIN32_MESSAGE_FILTER_CONTINUE, + Self::Remove => ffi::GDK_WIN32_MESSAGE_FILTER_REMOVE, + Self::__Unknown(value) => value, + } + } +} + +#[doc(hidden)] +impl FromGlib for Win32MessageFilterReturn { + unsafe fn from_glib(value: ffi::GdkWin32MessageFilterReturn) -> Self { + skip_assert_initialized!(); + match value { + ffi::GDK_WIN32_MESSAGE_FILTER_CONTINUE => Self::Continue, + ffi::GDK_WIN32_MESSAGE_FILTER_REMOVE => Self::Remove, + value => Self::__Unknown(value), + } + } +} diff --git a/gdk4-win32/src/auto/mod.rs b/gdk4-win32/src/auto/mod.rs new file mode 100644 index 000000000000..9028d3ec7ede --- /dev/null +++ b/gdk4-win32/src/auto/mod.rs @@ -0,0 +1,30 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from gir-files (https://github.com/gtk-rs/gir-files) +// DO NOT EDIT + +mod win32_display; +pub use self::win32_display::Win32Display; + +mod win32_display_manager; +pub use self::win32_display_manager::Win32DisplayManager; + +mod win32_drag; +pub use self::win32_drag::Win32Drag; + +mod win32_gl_context; +pub use self::win32_gl_context::Win32GLContext; + +mod win32_hcursor; +pub use self::win32_hcursor::Win32HCursor; + +mod win32_monitor; +pub use self::win32_monitor::Win32Monitor; + +mod win32_screen; +pub use self::win32_screen::Win32Screen; + +mod win32_surface; +pub use self::win32_surface::Win32Surface; + +mod enums; +pub use self::enums::Win32MessageFilterReturn; diff --git a/gdk4-win32/src/auto/versions.txt b/gdk4-win32/src/auto/versions.txt new file mode 100644 index 000000000000..1442407c1939 --- /dev/null +++ b/gdk4-win32/src/auto/versions.txt @@ -0,0 +1,2 @@ +Generated by gir (https://github.com/gtk-rs/gir @ 818f714dc796) +from gir-files (https://github.com/gtk-rs/gir-files @ 3b6fe0a33676) diff --git a/gdk4-win32/src/auto/win32_display.rs b/gdk4-win32/src/auto/win32_display.rs new file mode 100644 index 000000000000..3e131c7a814d --- /dev/null +++ b/gdk4-win32/src/auto/win32_display.rs @@ -0,0 +1,89 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from gir-files (https://github.com/gtk-rs/gir-files) +// DO NOT EDIT + +use crate::Win32HCursor; +use glib::object::IsA; +use glib::translate::*; +use std::fmt; +use std::mem; + +glib::wrapper! { + #[doc(alias = "GdkWin32Display")] + pub struct Win32Display(Object) @extends gdk::Display; + + match fn { + type_ => || ffi::gdk_win32_display_get_type(), + } +} + +impl Win32Display { + //#[doc(alias = "gdk_win32_display_add_filter")] + //pub fn add_filter(&self, function: /*Unimplemented*/Fn(&Win32Display, /*Ignored*/win32::MSG, i32) -> Win32MessageFilterReturn, data: /*Unimplemented*/Option) { + // unsafe { TODO: call ffi:gdk_win32_display_add_filter() } + //} + + #[doc(alias = "gdk_win32_display_get_win32hcursor")] + #[doc(alias = "get_win32hcursor")] + pub fn win32hcursor(&self, cursor: &gdk::Cursor) -> Win32HCursor { + unsafe { + from_glib_none(ffi::gdk_win32_display_get_win32hcursor( + self.to_glib_none().0, + cursor.to_glib_none().0, + )) + } + } + + //#[doc(alias = "gdk_win32_display_remove_filter")] + //pub fn remove_filter(&self, function: /*Unimplemented*/Fn(&Win32Display, /*Ignored*/win32::MSG, i32) -> Win32MessageFilterReturn, data: /*Unimplemented*/Option) { + // unsafe { TODO: call ffi:gdk_win32_display_remove_filter() } + //} + + #[doc(alias = "gdk_win32_display_set_cursor_theme")] + pub fn set_cursor_theme(&self, name: Option<&str>, size: i32) { + unsafe { + ffi::gdk_win32_display_set_cursor_theme( + self.to_glib_none().0, + name.to_glib_none().0, + size, + ); + } + } + + #[doc(alias = "gdk_win32_display_get_primary_monitor")] + #[doc(alias = "get_primary_monitor")] + pub fn primary_monitor(display: &impl IsA) -> gdk::Monitor { + assert_initialized_main_thread!(); + unsafe { + from_glib_none(ffi::gdk_win32_display_get_primary_monitor( + display.as_ref().to_glib_none().0, + )) + } + } + + #[doc(alias = "gdk_win32_display_get_wgl_version")] + #[doc(alias = "get_wgl_version")] + pub fn wgl_version(display: &impl IsA) -> Option<(i32, i32)> { + assert_initialized_main_thread!(); + unsafe { + let mut major = mem::MaybeUninit::uninit(); + let mut minor = mem::MaybeUninit::uninit(); + let ret = from_glib(ffi::gdk_win32_display_get_wgl_version( + display.as_ref().to_glib_none().0, + major.as_mut_ptr(), + minor.as_mut_ptr(), + )); + if ret { + Some((major.assume_init(), minor.assume_init())) + } else { + None + } + } + } +} + +impl fmt::Display for Win32Display { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("Win32Display") + } +} diff --git a/gdk4-win32/src/auto/win32_display_manager.rs b/gdk4-win32/src/auto/win32_display_manager.rs new file mode 100644 index 000000000000..8ea46fa41da4 --- /dev/null +++ b/gdk4-win32/src/auto/win32_display_manager.rs @@ -0,0 +1,22 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from gir-files (https://github.com/gtk-rs/gir-files) +// DO NOT EDIT + +use std::fmt; + +glib::wrapper! { + #[doc(alias = "GdkWin32DisplayManager")] + pub struct Win32DisplayManager(Object) @extends gdk::DisplayManager; + + match fn { + type_ => || ffi::gdk_win32_display_manager_get_type(), + } +} + +impl Win32DisplayManager {} + +impl fmt::Display for Win32DisplayManager { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("Win32DisplayManager") + } +} diff --git a/gdk4-win32/src/auto/win32_drag.rs b/gdk4-win32/src/auto/win32_drag.rs new file mode 100644 index 000000000000..0dada192f5cf --- /dev/null +++ b/gdk4-win32/src/auto/win32_drag.rs @@ -0,0 +1,22 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from gir-files (https://github.com/gtk-rs/gir-files) +// DO NOT EDIT + +use std::fmt; + +glib::wrapper! { + #[doc(alias = "GdkWin32Drag")] + pub struct Win32Drag(Object) @extends gdk::Drag; + + match fn { + type_ => || ffi::gdk_win32_drag_get_type(), + } +} + +impl Win32Drag {} + +impl fmt::Display for Win32Drag { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("Win32Drag") + } +} diff --git a/gdk4-win32/src/auto/win32_gl_context.rs b/gdk4-win32/src/auto/win32_gl_context.rs new file mode 100644 index 000000000000..126b3ea39c45 --- /dev/null +++ b/gdk4-win32/src/auto/win32_gl_context.rs @@ -0,0 +1,22 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from gir-files (https://github.com/gtk-rs/gir-files) +// DO NOT EDIT + +use std::fmt; + +glib::wrapper! { + #[doc(alias = "GdkWin32GLContext")] + pub struct Win32GLContext(Object) @extends gdk::GLContext, gdk::DrawContext; + + match fn { + type_ => || ffi::gdk_win32_gl_context_get_type(), + } +} + +impl Win32GLContext {} + +impl fmt::Display for Win32GLContext { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("Win32GLContext") + } +} diff --git a/gdk4-win32/src/auto/win32_hcursor.rs b/gdk4-win32/src/auto/win32_hcursor.rs new file mode 100644 index 000000000000..4e02c595b4e7 --- /dev/null +++ b/gdk4-win32/src/auto/win32_hcursor.rs @@ -0,0 +1,33 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from gir-files (https://github.com/gtk-rs/gir-files) +// DO NOT EDIT + +use glib::object::ObjectType as ObjectType_; +use glib::translate::*; +use glib::StaticType; +use std::fmt; + +glib::wrapper! { + #[doc(alias = "GdkWin32HCursor")] + pub struct Win32HCursor(Object); + + match fn { + type_ => || ffi::gdk_win32_hcursor_get_type(), + } +} + +impl Win32HCursor { + pub fn is_destroyable(&self) -> bool { + glib::ObjectExt::property(self, "destroyable") + } + + pub fn display(&self) -> Option { + glib::ObjectExt::property(self, "display") + } +} + +impl fmt::Display for Win32HCursor { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("Win32HCursor") + } +} diff --git a/gdk4-win32/src/auto/win32_monitor.rs b/gdk4-win32/src/auto/win32_monitor.rs new file mode 100644 index 000000000000..f5e1a91796dc --- /dev/null +++ b/gdk4-win32/src/auto/win32_monitor.rs @@ -0,0 +1,38 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from gir-files (https://github.com/gtk-rs/gir-files) +// DO NOT EDIT + +use glib::object::IsA; +use glib::translate::*; +use std::fmt; + +glib::wrapper! { + #[doc(alias = "GdkWin32Monitor")] + pub struct Win32Monitor(Object) @extends gdk::Monitor; + + match fn { + type_ => || ffi::gdk_win32_monitor_get_type(), + } +} + +impl Win32Monitor { + #[doc(alias = "gdk_win32_monitor_get_workarea")] + #[doc(alias = "get_workarea")] + pub fn workarea(monitor: &impl IsA) -> gdk::Rectangle { + assert_initialized_main_thread!(); + unsafe { + let mut workarea = gdk::Rectangle::uninitialized(); + ffi::gdk_win32_monitor_get_workarea( + monitor.as_ref().to_glib_none().0, + workarea.to_glib_none_mut().0, + ); + workarea + } + } +} + +impl fmt::Display for Win32Monitor { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("Win32Monitor") + } +} diff --git a/gdk4-win32/src/auto/win32_screen.rs b/gdk4-win32/src/auto/win32_screen.rs new file mode 100644 index 000000000000..a01744c676f0 --- /dev/null +++ b/gdk4-win32/src/auto/win32_screen.rs @@ -0,0 +1,22 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from gir-files (https://github.com/gtk-rs/gir-files) +// DO NOT EDIT + +use std::fmt; + +glib::wrapper! { + #[doc(alias = "GdkWin32Screen")] + pub struct Win32Screen(Object); + + match fn { + type_ => || ffi::gdk_win32_screen_get_type(), + } +} + +impl Win32Screen {} + +impl fmt::Display for Win32Screen { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("Win32Screen") + } +} diff --git a/gdk4-win32/src/auto/win32_surface.rs b/gdk4-win32/src/auto/win32_surface.rs new file mode 100644 index 000000000000..5fa68c68d1f6 --- /dev/null +++ b/gdk4-win32/src/auto/win32_surface.rs @@ -0,0 +1,42 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from gir-files (https://github.com/gtk-rs/gir-files) +// DO NOT EDIT + +use glib::object::IsA; +use glib::translate::*; +use std::fmt; + +glib::wrapper! { + #[doc(alias = "GdkWin32Surface")] + pub struct Win32Surface(Object) @extends gdk::Surface; + + match fn { + type_ => || ffi::gdk_win32_surface_get_type(), + } +} + +impl Win32Surface { + #[doc(alias = "gdk_win32_surface_set_urgency_hint")] + pub fn set_urgency_hint(&self, urgent: bool) { + unsafe { + ffi::gdk_win32_surface_set_urgency_hint(self.to_glib_none().0, urgent.into_glib()); + } + } + + #[cfg_attr(feature = "v4_8", deprecated = "Since 4.8")] + #[doc(alias = "gdk_win32_surface_is_win32")] + pub fn is_win32(surface: &impl IsA) -> bool { + assert_initialized_main_thread!(); + unsafe { + from_glib(ffi::gdk_win32_surface_is_win32( + surface.as_ref().to_glib_none().0, + )) + } + } +} + +impl fmt::Display for Win32Surface { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("Win32Surface") + } +} diff --git a/gdk4-win32/src/builders.rs b/gdk4-win32/src/builders.rs new file mode 100644 index 000000000000..1de66c2c724b --- /dev/null +++ b/gdk4-win32/src/builders.rs @@ -0,0 +1,6 @@ +// Take a look at the license at the top of the repository in the LICENSE file. + +// rustdoc-stripper-ignore-next +//! Builder pattern types. + +//pub use crate::auto::builders::*; diff --git a/gdk4-win32/src/lib.rs b/gdk4-win32/src/lib.rs new file mode 100644 index 000000000000..4f84b313ec3e --- /dev/null +++ b/gdk4-win32/src/lib.rs @@ -0,0 +1,41 @@ +// Take a look at the license at the top of the repository in the LICENSE file. + +#![doc = include_str!("../README.md")] +#![cfg_attr(feature = "dox", feature(doc_cfg))] + +pub use ffi; +pub use gdk; +pub use gio; +pub use glib; +#[cfg(any(feature = "win32", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "win32")))] +pub use windows; + +#[macro_use] +mod rt; + +#[allow(clippy::upper_case_acronyms)] +#[allow(unused_imports)] +mod auto; + +pub mod builders; + +pub use auto::*; + +mod win32_display; +mod win32_hcursor; +mod win32_surface; + +#[cfg(not(feature = "win32"))] +pub struct HANDLE(pub isize); +#[cfg(not(feature = "win32"))] +pub struct HCURSOR(pub isize); +#[cfg(not(feature = "win32"))] +pub struct HICON(pub isize); +#[cfg(not(feature = "win32"))] +pub struct HWND(pub isize); + +#[cfg(feature = "win32")] +pub use windows::Win32::Foundation::{HANDLE, HWND}; +#[cfg(feature = "win32")] +pub use windows::Win32::UI::WindowsAndMessaging::{HCURSOR, HICON}; diff --git a/gdk4-win32/src/rt.rs b/gdk4-win32/src/rt.rs new file mode 100644 index 000000000000..917563e7bff9 --- /dev/null +++ b/gdk4-win32/src/rt.rs @@ -0,0 +1,10 @@ +// Take a look at the license at the top of the repository in the LICENSE file. + +macro_rules! assert_initialized_main_thread { + () => {}; +} + +/// No-op. +macro_rules! skip_assert_initialized { + () => {}; +} diff --git a/gdk4-win32/src/win32_display.rs b/gdk4-win32/src/win32_display.rs new file mode 100644 index 000000000000..b87e20f6d5ef --- /dev/null +++ b/gdk4-win32/src/win32_display.rs @@ -0,0 +1,27 @@ +// Take a look at the license at the top of the repository in the LICENSE file. + +use crate::Win32Display; + +#[cfg(any(all(feature = "v4_4", feature = "egl"), feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(all(feature = "v4_4", feature = "egl"))))] +use glib::translate::ToGlibPtr; +#[cfg(any(all(feature = "v4_4", feature = "egl"), feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(all(feature = "v4_4", feature = "egl"))))] +use khronos_egl as egl; + +impl Win32Display { + #[cfg(any(all(feature = "v4_4", feature = "egl"), feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(all(feature = "v4_4", feature = "egl"))))] + #[doc(alias = "gdk_win32_display_get_egl_display")] + #[doc(alias = "get_egl_display")] + pub fn egl_display(&self) -> Option { + unsafe { + let ptr = ffi::gdk_win32_display_get_egl_display(self.to_glib_none().0); + if ptr.is_null() { + None + } else { + Some(egl::Display::from_ptr(ptr)) + } + } + } +} diff --git a/gdk4-win32/src/win32_hcursor.rs b/gdk4-win32/src/win32_hcursor.rs new file mode 100644 index 000000000000..8b37c89782a9 --- /dev/null +++ b/gdk4-win32/src/win32_hcursor.rs @@ -0,0 +1,29 @@ +// Take a look at the license at the top of the repository in the LICENSE file. + +use crate::{Win32HCursor, HCURSOR}; +use glib::object::IsA; +use glib::{translate::*, types::Pointee}; +use std::ptr::NonNull; + +impl Win32HCursor { + #[doc(alias = "gdk_win32_hcursor_new")] + pub fn new( + display: &impl IsA, + handle: HCURSOR, + destroyable: bool, + ) -> Self { + assert_initialized_main_thread!(); + unsafe { + from_glib_full(ffi::gdk_win32_hcursor_new( + display.as_ref().to_glib_none().0, + handle.0, + destroyable.into_glib(), + )) + } + } + + pub fn handle(&self) -> HCURSOR { + let ptr: NonNull = glib::ObjectExt::property(self, "handle"); + HCURSOR(ptr.as_ptr() as _) + } +} diff --git a/gdk4-win32/src/win32_surface.rs b/gdk4-win32/src/win32_surface.rs new file mode 100644 index 000000000000..ae35ed726bbf --- /dev/null +++ b/gdk4-win32/src/win32_surface.rs @@ -0,0 +1,36 @@ +// Take a look at the license at the top of the repository in the LICENSE file. + +use crate::{Win32Surface, HWND}; + +use glib::object::IsA; +use glib::translate::*; + +impl Win32Surface { + #[doc(alias = "gdk_win32_surface_lookup_for_display")] + pub fn lookup_for_display( + display: &impl IsA, + anid: HWND, + ) -> Option { + assert_initialized_main_thread!(); + unsafe { + from_glib_none(ffi::gdk_win32_surface_lookup_for_display( + display.as_ref().to_glib_none().0, + anid.0, + )) + } + } + + #[doc(alias = "gdk_win32_surface_get_handle")] + #[doc(alias = "get_handle")] + pub fn handle(&self) -> HWND { + HWND(unsafe { ffi::gdk_win32_surface_get_handle(self.to_glib_none().0) }) + } + + #[cfg_attr(feature = "v4_8", deprecated = "Since 4.8")] + #[doc(alias = "gdk_win32_surface_get_impl_hwnd")] + #[doc(alias = "get_impl_hwnd")] + pub fn impl_hwnd(surface: &impl IsA) -> HWND { + assert_initialized_main_thread!(); + HWND(unsafe { ffi::gdk_win32_surface_get_impl_hwnd(surface.as_ref().to_glib_none().0) }) + } +} diff --git a/gdk4-win32/sys/Cargo.toml b/gdk4-win32/sys/Cargo.toml new file mode 100644 index 000000000000..c1f4206111c8 --- /dev/null +++ b/gdk4-win32/sys/Cargo.toml @@ -0,0 +1,57 @@ +[package] +authors = ["The gtk-rs Project Developers"] +build = "build.rs" +description = "FFI bindings of GDK4 Win32" +documentation = "https://gtk-rs.org/gtk4-rs/git/docs/gdk4_win32_sys/" +edition = "2021" +homepage = "http://gtk-rs.org/" +keywords = ["gdk4", "gdk4-win32", "ffi", "gtk-rs", "gnome"] +license = "MIT" +name = "gdk4-win32-sys" +repository = "https://github.com/gtk-rs/gtk4-rs" +version = "0.6.0" +rust-version = "1.57" +[package.metadata.system-deps.gtk4_win32] +name = "gtk4-win32" +version = "4.0.0" + +[package.metadata.system-deps.gtk4_win32.v4_4] +version = "4.4" + +[package.metadata.system-deps.gtk4_win32.v4_8] +version = "4.8" +[package.metadata.docs.rs] +features = ["dox"] + +[lib] +name = "gdk4_win32_sys" + +[features] +dox = ["glib/dox", "gdk/dox"] +v4_4 = [] +v4_8 = ["v4_4"] + +[dependencies] +libc = "0.2" + +[dependencies.gdk] +package = "gdk4-sys" +path = "../../gdk4/sys" +version = "0.6.0" + +[dependencies.glib] +package = "glib-sys" +git = "https://github.com/gtk-rs/gtk-rs-core.git" +version = "0.17" + +[dependencies.gdk-pixbuf] +package = "gdk-pixbuf-sys" +git = "https://github.com/gtk-rs/gtk-rs-core" +version = "0.17" + +[build-dependencies] +system-deps = "6" + +[dev-dependencies] +shell-words = "1.0.0" +tempfile = "3" diff --git a/gdk4-win32/sys/Gir.toml b/gdk4-win32/sys/Gir.toml new file mode 100644 index 000000000000..bdfeb31084f1 --- /dev/null +++ b/gdk4-win32/sys/Gir.toml @@ -0,0 +1,14 @@ +[options] +work_mode = "sys" +library = "GdkWin32" +version = "4.0" +min_cfg_version = "4.0.0" +single_version_file = "." +girs_directories = ["../../gir-files"] + +external_libraries = [ + "GLib", +] + +[external_libraries] +gdk4 = "Gdk" diff --git a/gdk4-win32/sys/LICENSE b/gdk4-win32/sys/LICENSE new file mode 120000 index 000000000000..30cff7403da0 --- /dev/null +++ b/gdk4-win32/sys/LICENSE @@ -0,0 +1 @@ +../../LICENSE \ No newline at end of file diff --git a/gdk4-win32/sys/build.rs b/gdk4-win32/sys/build.rs new file mode 100644 index 000000000000..8d181dad8caa --- /dev/null +++ b/gdk4-win32/sys/build.rs @@ -0,0 +1,17 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from gir-files (https://github.com/gtk-rs/gir-files) +// DO NOT EDIT + +#[cfg(not(feature = "dox"))] +use std::process; + +#[cfg(feature = "dox")] +fn main() {} // prevent linking libraries to avoid documentation failure + +#[cfg(not(feature = "dox"))] +fn main() { + if let Err(s) = system_deps::Config::new().probe() { + println!("cargo:warning={s}"); + process::exit(1); + } +} diff --git a/gdk4-win32/sys/src/lib.rs b/gdk4-win32/sys/src/lib.rs new file mode 100644 index 000000000000..c46d5d0762c1 --- /dev/null +++ b/gdk4-win32/sys/src/lib.rs @@ -0,0 +1,302 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from gir-files (https://github.com/gtk-rs/gir-files) +// DO NOT EDIT + +#![allow(non_camel_case_types, non_upper_case_globals, non_snake_case)] +#![allow( + clippy::approx_constant, + clippy::type_complexity, + clippy::unreadable_literal, + clippy::upper_case_acronyms +)] +#![cfg_attr(feature = "dox", feature(doc_cfg))] + +#[allow(unused_imports)] +use libc::{ + c_char, c_double, c_float, c_int, c_long, c_short, c_uchar, c_uint, c_ulong, c_ushort, c_void, + intptr_t, size_t, ssize_t, uintptr_t, FILE, +}; + +#[allow(unused_imports)] +use glib::{gboolean, gconstpointer, gpointer, GType}; + +// Enums +pub type GdkWin32MessageFilterReturn = c_int; +pub const GDK_WIN32_MESSAGE_FILTER_CONTINUE: GdkWin32MessageFilterReturn = 0; +pub const GDK_WIN32_MESSAGE_FILTER_REMOVE: GdkWin32MessageFilterReturn = 1; + +// Callbacks +pub type GdkWin32MessageFilterFunc = Option< + unsafe extern "C" fn( + *mut GdkWin32Display, + gpointer, + *mut c_int, + gpointer, + ) -> GdkWin32MessageFilterReturn, +>; + +// Records +#[repr(C)] +pub struct _GdkWin32DisplayClass { + _data: [u8; 0], + _marker: core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>, +} + +pub type GdkWin32DisplayClass = *mut _GdkWin32DisplayClass; + +#[repr(C)] +pub struct _GdkWin32DisplayManagerClass { + _data: [u8; 0], + _marker: core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>, +} + +pub type GdkWin32DisplayManagerClass = *mut _GdkWin32DisplayManagerClass; + +#[repr(C)] +pub struct _GdkWin32DragClass { + _data: [u8; 0], + _marker: core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>, +} + +pub type GdkWin32DragClass = *mut _GdkWin32DragClass; + +#[repr(C)] +pub struct _GdkWin32GLContextClass { + _data: [u8; 0], + _marker: core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>, +} + +pub type GdkWin32GLContextClass = *mut _GdkWin32GLContextClass; + +#[repr(C)] +pub struct _GdkWin32HCursorClass { + _data: [u8; 0], + _marker: core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>, +} + +pub type GdkWin32HCursorClass = *mut _GdkWin32HCursorClass; + +#[repr(C)] +pub struct _GdkWin32MonitorClass { + _data: [u8; 0], + _marker: core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>, +} + +pub type GdkWin32MonitorClass = *mut _GdkWin32MonitorClass; + +#[repr(C)] +pub struct _GdkWin32ScreenClass { + _data: [u8; 0], + _marker: core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>, +} + +pub type GdkWin32ScreenClass = *mut _GdkWin32ScreenClass; + +#[repr(C)] +pub struct _GdkWin32SurfaceClass { + _data: [u8; 0], + _marker: core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>, +} + +pub type GdkWin32SurfaceClass = *mut _GdkWin32SurfaceClass; + +// Classes +#[repr(C)] +pub struct GdkWin32Display { + _data: [u8; 0], + _marker: core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>, +} + +impl ::std::fmt::Debug for GdkWin32Display { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + f.debug_struct(&format!("GdkWin32Display @ {self:p}")) + .finish() + } +} + +#[repr(C)] +pub struct GdkWin32DisplayManager { + _data: [u8; 0], + _marker: core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>, +} + +impl ::std::fmt::Debug for GdkWin32DisplayManager { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + f.debug_struct(&format!("GdkWin32DisplayManager @ {self:p}")) + .finish() + } +} + +#[repr(C)] +pub struct GdkWin32Drag { + _data: [u8; 0], + _marker: core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>, +} + +impl ::std::fmt::Debug for GdkWin32Drag { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + f.debug_struct(&format!("GdkWin32Drag @ {self:p}")).finish() + } +} + +#[repr(C)] +pub struct GdkWin32GLContext { + _data: [u8; 0], + _marker: core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>, +} + +impl ::std::fmt::Debug for GdkWin32GLContext { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + f.debug_struct(&format!("GdkWin32GLContext @ {self:p}")) + .finish() + } +} + +#[repr(C)] +pub struct GdkWin32HCursor { + _data: [u8; 0], + _marker: core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>, +} + +impl ::std::fmt::Debug for GdkWin32HCursor { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + f.debug_struct(&format!("GdkWin32HCursor @ {self:p}")) + .finish() + } +} + +#[repr(C)] +pub struct GdkWin32Monitor { + _data: [u8; 0], + _marker: core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>, +} + +impl ::std::fmt::Debug for GdkWin32Monitor { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + f.debug_struct(&format!("GdkWin32Monitor @ {self:p}")) + .finish() + } +} + +#[repr(C)] +pub struct GdkWin32Screen { + _data: [u8; 0], + _marker: core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>, +} + +impl ::std::fmt::Debug for GdkWin32Screen { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + f.debug_struct(&format!("GdkWin32Screen @ {self:p}")) + .finish() + } +} + +#[repr(C)] +pub struct GdkWin32Surface { + _data: [u8; 0], + _marker: core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>, +} + +impl ::std::fmt::Debug for GdkWin32Surface { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + f.debug_struct(&format!("GdkWin32Surface @ {self:p}")) + .finish() + } +} + +#[link(name = "gtk-4")] +extern "C" { + + //========================================================================= + // GdkWin32Display + //========================================================================= + pub fn gdk_win32_display_get_type() -> GType; + pub fn gdk_win32_display_get_primary_monitor( + display: *mut gdk::GdkDisplay, + ) -> *mut gdk::GdkMonitor; + pub fn gdk_win32_display_get_wgl_version( + display: *mut gdk::GdkDisplay, + major: *mut c_int, + minor: *mut c_int, + ) -> gboolean; + pub fn gdk_win32_display_add_filter( + display: *mut GdkWin32Display, + function: GdkWin32MessageFilterFunc, + data: gpointer, + ); + #[cfg(any(feature = "v4_4", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v4_4")))] + pub fn gdk_win32_display_get_egl_display(display: *mut GdkWin32Display) -> gpointer; + pub fn gdk_win32_display_get_win32hcursor( + display: *mut GdkWin32Display, + cursor: *mut gdk::GdkCursor, + ) -> *mut GdkWin32HCursor; + pub fn gdk_win32_display_remove_filter( + display: *mut GdkWin32Display, + function: GdkWin32MessageFilterFunc, + data: gpointer, + ); + pub fn gdk_win32_display_set_cursor_theme( + display: *mut GdkWin32Display, + name: *const c_char, + size: c_int, + ); + + //========================================================================= + // GdkWin32DisplayManager + //========================================================================= + pub fn gdk_win32_display_manager_get_type() -> GType; + + //========================================================================= + // GdkWin32Drag + //========================================================================= + pub fn gdk_win32_drag_get_type() -> GType; + + //========================================================================= + // GdkWin32GLContext + //========================================================================= + pub fn gdk_win32_gl_context_get_type() -> GType; + + //========================================================================= + // GdkWin32HCursor + //========================================================================= + pub fn gdk_win32_hcursor_get_type() -> GType; + pub fn gdk_win32_hcursor_new( + display: *mut GdkWin32Display, + handle: ssize_t, + destroyable: gboolean, + ) -> *mut GdkWin32HCursor; + + //========================================================================= + // GdkWin32Monitor + //========================================================================= + pub fn gdk_win32_monitor_get_type() -> GType; + pub fn gdk_win32_monitor_get_workarea( + monitor: *mut gdk::GdkMonitor, + workarea: *mut gdk::GdkRectangle, + ); + + //========================================================================= + // GdkWin32Screen + //========================================================================= + pub fn gdk_win32_screen_get_type() -> GType; + + //========================================================================= + // GdkWin32Surface + //========================================================================= + pub fn gdk_win32_surface_get_type() -> GType; + pub fn gdk_win32_surface_get_impl_hwnd(surface: *mut gdk::GdkSurface) -> ssize_t; + pub fn gdk_win32_surface_is_win32(surface: *mut gdk::GdkSurface) -> gboolean; + pub fn gdk_win32_surface_lookup_for_display( + display: *mut gdk::GdkDisplay, + anid: ssize_t, + ) -> *mut gdk::GdkSurface; + pub fn gdk_win32_surface_get_handle(surface: *mut GdkWin32Surface) -> ssize_t; + pub fn gdk_win32_surface_set_urgency_hint(surface: *mut GdkWin32Surface, urgent: gboolean); + + //========================================================================= + // Other functions + //========================================================================= + pub fn gdk_win32_handle_table_lookup(handle: ssize_t) -> gpointer; + +} diff --git a/gdk4-win32/sys/tests/abi.rs b/gdk4-win32/sys/tests/abi.rs new file mode 100644 index 000000000000..2fda3eb84ed5 --- /dev/null +++ b/gdk4-win32/sys/tests/abi.rs @@ -0,0 +1,214 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from gir-files (https://github.com/gtk-rs/gir-files) +// DO NOT EDIT + +use gdk4_win32_sys::*; +use std::env; +use std::error::Error; +use std::ffi::OsString; +use std::mem::{align_of, size_of}; +use std::path::Path; +use std::process::Command; +use std::str; +use tempfile::Builder; + +static PACKAGES: &[&str] = &["gtk4-win32"]; + +#[derive(Clone, Debug)] +struct Compiler { + pub args: Vec, +} + +impl Compiler { + pub fn new() -> Result> { + let mut args = get_var("CC", "cc")?; + args.push("-Wno-deprecated-declarations".to_owned()); + // For _Generic + args.push("-std=c11".to_owned()); + // For %z support in printf when using MinGW. + args.push("-D__USE_MINGW_ANSI_STDIO".to_owned()); + args.extend(get_var("CFLAGS", "")?); + args.extend(get_var("CPPFLAGS", "")?); + args.extend(pkg_config_cflags(PACKAGES)?); + Ok(Self { args }) + } + + pub fn compile(&self, src: &Path, out: &Path) -> Result<(), Box> { + let mut cmd = self.to_command(); + cmd.arg(src); + cmd.arg("-o"); + cmd.arg(out); + let status = cmd.spawn()?.wait()?; + if !status.success() { + return Err(format!("compilation command {:?} failed, {}", &cmd, status).into()); + } + Ok(()) + } + + fn to_command(&self) -> Command { + let mut cmd = Command::new(&self.args[0]); + cmd.args(&self.args[1..]); + cmd + } +} + +fn get_var(name: &str, default: &str) -> Result, Box> { + match env::var(name) { + Ok(value) => Ok(shell_words::split(&value)?), + Err(env::VarError::NotPresent) => Ok(shell_words::split(default)?), + Err(err) => Err(format!("{} {}", name, err).into()), + } +} + +fn pkg_config_cflags(packages: &[&str]) -> Result, Box> { + if packages.is_empty() { + return Ok(Vec::new()); + } + let pkg_config = env::var_os("PKG_CONFIG").unwrap_or_else(|| OsString::from("pkg-config")); + let mut cmd = Command::new(pkg_config); + cmd.arg("--cflags"); + cmd.args(packages); + let out = cmd.output()?; + if !out.status.success() { + return Err(format!("command {:?} returned {}", &cmd, out.status).into()); + } + let stdout = str::from_utf8(&out.stdout)?; + Ok(shell_words::split(stdout.trim())?) +} + +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +struct Layout { + size: usize, + alignment: usize, +} + +#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)] +struct Results { + /// Number of successfully completed tests. + passed: usize, + /// Total number of failed tests (including those that failed to compile). + failed: usize, +} + +impl Results { + fn record_passed(&mut self) { + self.passed += 1; + } + fn record_failed(&mut self) { + self.failed += 1; + } + fn summary(&self) -> String { + format!("{} passed; {} failed", self.passed, self.failed) + } + fn expect_total_success(&self) { + if self.failed == 0 { + println!("OK: {}", self.summary()); + } else { + panic!("FAILED: {}", self.summary()); + }; + } +} + +#[test] +#[cfg(target_os = "linux")] +fn cross_validate_constants_with_c() { + let mut c_constants: Vec<(String, String)> = Vec::new(); + + for l in get_c_output("constant").unwrap().lines() { + let (name, value) = l.split_once(';').expect("Missing ';' separator"); + c_constants.push((name.to_owned(), value.to_owned())); + } + + let mut results = Results::default(); + + for ((rust_name, rust_value), (c_name, c_value)) in + RUST_CONSTANTS.iter().zip(c_constants.iter()) + { + if rust_name != c_name { + results.record_failed(); + eprintln!("Name mismatch:\nRust: {:?}\nC: {:?}", rust_name, c_name,); + continue; + } + + if rust_value != c_value { + results.record_failed(); + eprintln!( + "Constant value mismatch for {}\nRust: {:?}\nC: {:?}", + rust_name, rust_value, &c_value + ); + continue; + } + + results.record_passed(); + } + + results.expect_total_success(); +} + +#[test] +#[cfg(target_os = "linux")] +fn cross_validate_layout_with_c() { + let mut c_layouts = Vec::new(); + + for l in get_c_output("layout").unwrap().lines() { + let (name, value) = l.split_once(';').expect("Missing first ';' separator"); + let (size, alignment) = value.split_once(';').expect("Missing second ';' separator"); + let size = size.parse().expect("Failed to parse size"); + let alignment = alignment.parse().expect("Failed to parse alignment"); + c_layouts.push((name.to_owned(), Layout { size, alignment })); + } + + let mut results = Results::default(); + + for ((rust_name, rust_layout), (c_name, c_layout)) in RUST_LAYOUTS.iter().zip(c_layouts.iter()) + { + if rust_name != c_name { + results.record_failed(); + eprintln!("Name mismatch:\nRust: {:?}\nC: {:?}", rust_name, c_name,); + continue; + } + + if rust_layout != c_layout { + results.record_failed(); + eprintln!( + "Layout mismatch for {}\nRust: {:?}\nC: {:?}", + rust_name, rust_layout, &c_layout + ); + continue; + } + + results.record_passed(); + } + + results.expect_total_success(); +} + +fn get_c_output(name: &str) -> Result> { + let tmpdir = Builder::new().prefix("abi").tempdir()?; + let exe = tmpdir.path().join(name); + let c_file = Path::new("tests").join(name).with_extension("c"); + + let cc = Compiler::new().expect("configured compiler"); + cc.compile(&c_file, &exe)?; + + let mut abi_cmd = Command::new(exe); + let output = abi_cmd.output()?; + if !output.status.success() { + return Err(format!("command {:?} failed, {:?}", &abi_cmd, &output).into()); + } + + Ok(String::from_utf8(output.stdout)?) +} + +const RUST_LAYOUTS: &[(&str, Layout)] = &[( + "GdkWin32MessageFilterReturn", + Layout { + size: size_of::(), + alignment: align_of::(), + }, +)]; + +const RUST_CONSTANTS: &[(&str, &str)] = &[ + ("(gint) GDK_WIN32_MESSAGE_FILTER_CONTINUE", "0"), + ("(gint) GDK_WIN32_MESSAGE_FILTER_REMOVE", "1"), +]; diff --git a/gdk4-win32/sys/tests/constant.c b/gdk4-win32/sys/tests/constant.c new file mode 100644 index 000000000000..7494fd294c63 --- /dev/null +++ b/gdk4-win32/sys/tests/constant.c @@ -0,0 +1,34 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from gir-files (https://github.com/gtk-rs/gir-files) +// DO NOT EDIT + +#include "manual.h" +#include + +#define PRINT_CONSTANT(CONSTANT_NAME) \ + printf("%s;", #CONSTANT_NAME); \ + printf(_Generic((CONSTANT_NAME), \ + char *: "%s", \ + const char *: "%s", \ + char: "%c", \ + signed char: "%hhd", \ + unsigned char: "%hhu", \ + short int: "%hd", \ + unsigned short int: "%hu", \ + int: "%d", \ + unsigned int: "%u", \ + long: "%ld", \ + unsigned long: "%lu", \ + long long: "%lld", \ + unsigned long long: "%llu", \ + float: "%f", \ + double: "%f", \ + long double: "%ld"), \ + CONSTANT_NAME); \ + printf("\n"); + +int main() { + PRINT_CONSTANT((gint) GDK_WIN32_MESSAGE_FILTER_CONTINUE); + PRINT_CONSTANT((gint) GDK_WIN32_MESSAGE_FILTER_REMOVE); + return 0; +} diff --git a/gdk4-win32/sys/tests/layout.c b/gdk4-win32/sys/tests/layout.c new file mode 100644 index 000000000000..00eb6ddec38e --- /dev/null +++ b/gdk4-win32/sys/tests/layout.c @@ -0,0 +1,12 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from gir-files (https://github.com/gtk-rs/gir-files) +// DO NOT EDIT + +#include "manual.h" +#include +#include + +int main() { + printf("%s;%zu;%zu\n", "GdkWin32MessageFilterReturn", sizeof(GdkWin32MessageFilterReturn), alignof(GdkWin32MessageFilterReturn)); + return 0; +} diff --git a/gdk4-win32/sys/tests/manual.h b/gdk4-win32/sys/tests/manual.h new file mode 100644 index 000000000000..bc741f36d387 --- /dev/null +++ b/gdk4-win32/sys/tests/manual.h @@ -0,0 +1,3 @@ +// Feel free to edit this file, it won't be regenerated by gir generator unless removed. + +#include diff --git a/gdk4-win32/sys/versions.txt b/gdk4-win32/sys/versions.txt new file mode 100644 index 000000000000..1442407c1939 --- /dev/null +++ b/gdk4-win32/sys/versions.txt @@ -0,0 +1,2 @@ +Generated by gir (https://github.com/gtk-rs/gir @ 818f714dc796) +from gir-files (https://github.com/gtk-rs/gir-files @ 3b6fe0a33676) diff --git a/gdk4-win32/tests/check_gir.rs b/gdk4-win32/tests/check_gir.rs new file mode 100644 index 000000000000..b095c0444d49 --- /dev/null +++ b/gdk4-win32/tests/check_gir.rs @@ -0,0 +1,8 @@ +// Take a look at the license at the top of the repository in the LICENSE file. + +#[test] +fn check_gir_file() { + let res = gir_format_check::check_gir_file("Gir.toml"); + println!("{}", res); + assert_eq!(res.nb_errors, 0); +}