mirror of
				https://codeberg.org/hako/Rosenthal.git
				synced 2025-11-04 03:34:37 +00:00 
			
		
		
		
	rosenthal: Add niri.
* rosenthal/packages/patches/niri.patch: New file. * rosenthal/packages/patches/rust-libspa-sys.patch: New file. * rosenthal/packages/patches/rust-libspa.patch: New file. * rosenthal/packages/patches/rust-pipewire.patch: New file. * rosenthal/packages/patches/rust-smithay.patch: New file. * rosenthal/packages/rust-crates.scm (niri-cargo-inputs): New variable. * rosenthal/packages/rust-apps.scm (niri): New variable. * README.org (Packages): Add it. * etc/manifest: Add it.
This commit is contained in:
		
							parent
							
								
									891eb84b38
								
							
						
					
					
						commit
						f8c9cd9dcc
					
				@ -91,6 +91,7 @@ Rosenthal 頻道定義如下,將其加入 =~/.config/guix/channels.scm= 以由
 | 
			
		||||
+ emacs-wakatime-mode
 | 
			
		||||
+ forgejo
 | 
			
		||||
+ grub-efi-luks2
 | 
			
		||||
+ niri
 | 
			
		||||
+ pam-dumb-runtime-dir
 | 
			
		||||
+ socks2http
 | 
			
		||||
+ tree-sitter-yaml
 | 
			
		||||
 | 
			
		||||
@ -12,6 +12,7 @@
 | 
			
		||||
   "hugo-bin"
 | 
			
		||||
   "komga-bin"
 | 
			
		||||
   "mihomo-bin"
 | 
			
		||||
   "niri"
 | 
			
		||||
   "shadow-tls-bin"
 | 
			
		||||
   "sing-box-bin"
 | 
			
		||||
   "tailscale-bin"
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										31
									
								
								rosenthal/packages/patches/niri.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								rosenthal/packages/patches/niri.patch
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,31 @@
 | 
			
		||||
diff --git a/Cargo.toml b/Cargo.toml
 | 
			
		||||
index 6469c4e5..08d97316 100644
 | 
			
		||||
--- a/Cargo.toml
 | 
			
		||||
+++ b/Cargo.toml
 | 
			
		||||
@@ -26,15 +26,11 @@ tracing-subscriber = { version = "0.3.19", features = ["env-filter"] }
 | 
			
		||||
 tracy-client = { version = "0.18.0", default-features = false }
 | 
			
		||||
 
 | 
			
		||||
 [workspace.dependencies.smithay]
 | 
			
		||||
-# version = "0.4.1"
 | 
			
		||||
-git = "https://github.com/Smithay/smithay.git"
 | 
			
		||||
-# path = "../smithay"
 | 
			
		||||
+version = "0.4.1"
 | 
			
		||||
 default-features = false
 | 
			
		||||
 
 | 
			
		||||
 [workspace.dependencies.smithay-drm-extras]
 | 
			
		||||
-# version = "0.1.0"
 | 
			
		||||
-git = "https://github.com/Smithay/smithay.git"
 | 
			
		||||
-# path = "../smithay/smithay-drm-extras"
 | 
			
		||||
+version = "0.1.0"
 | 
			
		||||
 
 | 
			
		||||
 [package]
 | 
			
		||||
 name = "niri"
 | 
			
		||||
@@ -75,7 +71,7 @@ niri-ipc = { version = "25.2.0", path = "niri-ipc", features = ["clap"] }
 | 
			
		||||
 ordered-float = "5.0.0"
 | 
			
		||||
 pango = { version = "0.20.9", features = ["v1_44"] }
 | 
			
		||||
 pangocairo = "0.20.7"
 | 
			
		||||
-pipewire = { git = "https://gitlab.freedesktop.org/pipewire/pipewire-rs.git", optional = true, features = ["v0_3_33"] }
 | 
			
		||||
+pipewire = { version = "0.8.0", optional = true, features = ["v0_3_33"] }
 | 
			
		||||
 png = "0.17.16"
 | 
			
		||||
 portable-atomic = { version = "1.10.0", default-features = false, features = ["float"] }
 | 
			
		||||
 profiling = "1.0.16"
 | 
			
		||||
							
								
								
									
										54
									
								
								rosenthal/packages/patches/rust-libspa-sys.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								rosenthal/packages/patches/rust-libspa-sys.patch
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,54 @@
 | 
			
		||||
diff --git a/build.rs b/build.rs
 | 
			
		||||
index ea34c22..4bffe86 100644
 | 
			
		||||
--- a/build.rs
 | 
			
		||||
+++ b/build.rs
 | 
			
		||||
@@ -32,7 +32,7 @@ fn main() {
 | 
			
		||||
         // can be called via FFI
 | 
			
		||||
         .wrap_static_fns(true)
 | 
			
		||||
         .wrap_static_fns_suffix("_libspa_rs")
 | 
			
		||||
-        .wrap_static_fns_path(&out_path.join("static_fns"));
 | 
			
		||||
+        .wrap_static_fns_path(out_path.join("static_fns"));
 | 
			
		||||
 
 | 
			
		||||
     let builder = libs
 | 
			
		||||
         .iter()
 | 
			
		||||
diff --git a/src/type_info.rs b/src/type_info.rs
 | 
			
		||||
index 016c971..e1e60e9 100644
 | 
			
		||||
--- a/src/type_info.rs
 | 
			
		||||
+++ b/src/type_info.rs
 | 
			
		||||
@@ -101,9 +101,7 @@ mod test {
 | 
			
		||||
             let type_info = super::spa_debug_type_find(spa_type_media_type, SPA_MEDIA_TYPE_audio);
 | 
			
		||||
             assert_eq!(
 | 
			
		||||
                 ffi::CStr::from_ptr((*type_info).name),
 | 
			
		||||
-                ffi::CString::new("Spa:Enum:MediaType:audio")
 | 
			
		||||
-                    .unwrap()
 | 
			
		||||
-                    .as_ref()
 | 
			
		||||
+                c"Spa:Enum:MediaType:audio"
 | 
			
		||||
             );
 | 
			
		||||
         }
 | 
			
		||||
     }
 | 
			
		||||
@@ -112,12 +110,7 @@ mod test {
 | 
			
		||||
     fn test_libspa_rs_debug_type_find_name() {
 | 
			
		||||
         unsafe {
 | 
			
		||||
             let name = super::spa_debug_type_find_name(spa_type_media_type, SPA_MEDIA_TYPE_audio);
 | 
			
		||||
-            assert_eq!(
 | 
			
		||||
-                ffi::CStr::from_ptr(name),
 | 
			
		||||
-                ffi::CString::new("Spa:Enum:MediaType:audio")
 | 
			
		||||
-                    .unwrap()
 | 
			
		||||
-                    .as_ref()
 | 
			
		||||
-            );
 | 
			
		||||
+            assert_eq!(ffi::CStr::from_ptr(name), c"Spa:Enum:MediaType:audio");
 | 
			
		||||
         }
 | 
			
		||||
     }
 | 
			
		||||
 
 | 
			
		||||
@@ -126,10 +119,7 @@ mod test {
 | 
			
		||||
         unsafe {
 | 
			
		||||
             let name =
 | 
			
		||||
                 super::spa_debug_type_find_short_name(spa_type_media_type, SPA_MEDIA_TYPE_audio);
 | 
			
		||||
-            assert_eq!(
 | 
			
		||||
-                ffi::CStr::from_ptr(name),
 | 
			
		||||
-                ffi::CString::new("audio").unwrap().as_ref()
 | 
			
		||||
-            );
 | 
			
		||||
+            assert_eq!(ffi::CStr::from_ptr(name), c"audio");
 | 
			
		||||
         }
 | 
			
		||||
     }
 | 
			
		||||
 }
 | 
			
		||||
							
								
								
									
										960
									
								
								rosenthal/packages/patches/rust-libspa.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										960
									
								
								rosenthal/packages/patches/rust-libspa.patch
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,960 @@
 | 
			
		||||
diff --git a/Cargo.toml b/Cargo.toml
 | 
			
		||||
index 1f2cc3e..df2d682 100644
 | 
			
		||||
--- a/Cargo.toml
 | 
			
		||||
+++ b/Cargo.toml
 | 
			
		||||
@@ -49,7 +49,7 @@ version = "0.3.2"
 | 
			
		||||
 version = "0.2"
 | 
			
		||||
 
 | 
			
		||||
 [dependencies.nix]
 | 
			
		||||
-version = "0.27"
 | 
			
		||||
+version = "0.29"
 | 
			
		||||
 
 | 
			
		||||
 [dependencies.nom]
 | 
			
		||||
 version = "7"
 | 
			
		||||
diff --git a/src/lib.rs b/src/lib.rs
 | 
			
		||||
index 398658b..6b7c995 100644
 | 
			
		||||
--- a/src/lib.rs
 | 
			
		||||
+++ b/src/lib.rs
 | 
			
		||||
@@ -2,7 +2,9 @@
 | 
			
		||||
 // SPDX-License-Identifier: MIT
 | 
			
		||||
 
 | 
			
		||||
 //! The `libspa` crate provides a high-level API to interact with
 | 
			
		||||
-//! [libspa](https://gitlab.freedesktop.org/pipewire/pipewire/-/tree/master/doc/spa).
 | 
			
		||||
+//! [libspa].
 | 
			
		||||
+//!
 | 
			
		||||
+//! [libspa]: https://docs.pipewire.org/page_spa.html
 | 
			
		||||
 
 | 
			
		||||
 pub mod buffer;
 | 
			
		||||
 pub mod param;
 | 
			
		||||
@@ -11,6 +13,3 @@ pub mod support;
 | 
			
		||||
 pub mod utils;
 | 
			
		||||
 
 | 
			
		||||
 pub use spa_sys as sys;
 | 
			
		||||
-
 | 
			
		||||
-/// prelude module re-exporing all the traits providing public API.
 | 
			
		||||
-pub mod prelude {}
 | 
			
		||||
diff --git a/src/param/audio/mod.rs b/src/param/audio/mod.rs
 | 
			
		||||
index 017fc09..f6d731d 100644
 | 
			
		||||
--- a/src/param/audio/mod.rs
 | 
			
		||||
+++ b/src/param/audio/mod.rs
 | 
			
		||||
@@ -51,6 +51,17 @@ impl AudioFormat {
 | 
			
		||||
     pub const ULAW: Self = Self(spa_sys::SPA_AUDIO_FORMAT_ULAW);
 | 
			
		||||
     pub const ALAW: Self = Self(spa_sys::SPA_AUDIO_FORMAT_ALAW);
 | 
			
		||||
 
 | 
			
		||||
+    pub const S16: Self = Self(spa_sys::SPA_AUDIO_FORMAT_S16);
 | 
			
		||||
+    pub const U16: Self = Self(spa_sys::SPA_AUDIO_FORMAT_U16);
 | 
			
		||||
+    pub const S18: Self = Self(spa_sys::SPA_AUDIO_FORMAT_S18);
 | 
			
		||||
+    pub const U18: Self = Self(spa_sys::SPA_AUDIO_FORMAT_U18);
 | 
			
		||||
+    pub const S20: Self = Self(spa_sys::SPA_AUDIO_FORMAT_S20);
 | 
			
		||||
+    pub const U20: Self = Self(spa_sys::SPA_AUDIO_FORMAT_U20);
 | 
			
		||||
+    pub const S24: Self = Self(spa_sys::SPA_AUDIO_FORMAT_S24);
 | 
			
		||||
+    pub const U24: Self = Self(spa_sys::SPA_AUDIO_FORMAT_U24);
 | 
			
		||||
+    pub const S32: Self = Self(spa_sys::SPA_AUDIO_FORMAT_S32);
 | 
			
		||||
+    pub const U32: Self = Self(spa_sys::SPA_AUDIO_FORMAT_U32);
 | 
			
		||||
+
 | 
			
		||||
     pub const U8P: Self = Self(spa_sys::SPA_AUDIO_FORMAT_U8P);
 | 
			
		||||
     pub const S16P: Self = Self(spa_sys::SPA_AUDIO_FORMAT_S16P);
 | 
			
		||||
     pub const S24_32P: Self = Self(spa_sys::SPA_AUDIO_FORMAT_S24_32P);
 | 
			
		||||
diff --git a/src/pod/builder.rs b/src/pod/builder.rs
 | 
			
		||||
index 138caec..d0209af 100644
 | 
			
		||||
--- a/src/pod/builder.rs
 | 
			
		||||
+++ b/src/pod/builder.rs
 | 
			
		||||
@@ -141,7 +141,7 @@ impl<'d> Builder<'d> {
 | 
			
		||||
         if res >= 0 {
 | 
			
		||||
             Ok(())
 | 
			
		||||
         } else {
 | 
			
		||||
-            Err(Errno::from_i32(-res))
 | 
			
		||||
+            Err(Errno::from_raw(-res))
 | 
			
		||||
         }
 | 
			
		||||
     }
 | 
			
		||||
 
 | 
			
		||||
@@ -163,7 +163,7 @@ impl<'d> Builder<'d> {
 | 
			
		||||
             if res >= 0 {
 | 
			
		||||
                 Ok(())
 | 
			
		||||
             } else {
 | 
			
		||||
-                Err(Errno::from_i32(-res))
 | 
			
		||||
+                Err(Errno::from_raw(-res))
 | 
			
		||||
             }
 | 
			
		||||
         }
 | 
			
		||||
     }
 | 
			
		||||
@@ -177,7 +177,7 @@ impl<'d> Builder<'d> {
 | 
			
		||||
             if res >= 0 {
 | 
			
		||||
                 Ok(())
 | 
			
		||||
             } else {
 | 
			
		||||
-                Err(Errno::from_i32(-res))
 | 
			
		||||
+                Err(Errno::from_raw(-res))
 | 
			
		||||
             }
 | 
			
		||||
         }
 | 
			
		||||
     }
 | 
			
		||||
@@ -189,7 +189,7 @@ impl<'d> Builder<'d> {
 | 
			
		||||
             if res >= 0 {
 | 
			
		||||
                 Ok(())
 | 
			
		||||
             } else {
 | 
			
		||||
-                Err(Errno::from_i32(-res))
 | 
			
		||||
+                Err(Errno::from_raw(-res))
 | 
			
		||||
             }
 | 
			
		||||
         }
 | 
			
		||||
     }
 | 
			
		||||
@@ -201,7 +201,7 @@ impl<'d> Builder<'d> {
 | 
			
		||||
             if res >= 0 {
 | 
			
		||||
                 Ok(())
 | 
			
		||||
             } else {
 | 
			
		||||
-                Err(Errno::from_i32(-res))
 | 
			
		||||
+                Err(Errno::from_raw(-res))
 | 
			
		||||
             }
 | 
			
		||||
         }
 | 
			
		||||
     }
 | 
			
		||||
@@ -213,7 +213,7 @@ impl<'d> Builder<'d> {
 | 
			
		||||
             if res >= 0 {
 | 
			
		||||
                 Ok(())
 | 
			
		||||
             } else {
 | 
			
		||||
-                Err(Errno::from_i32(-res))
 | 
			
		||||
+                Err(Errno::from_raw(-res))
 | 
			
		||||
             }
 | 
			
		||||
         }
 | 
			
		||||
     }
 | 
			
		||||
@@ -225,7 +225,7 @@ impl<'d> Builder<'d> {
 | 
			
		||||
             if res >= 0 {
 | 
			
		||||
                 Ok(())
 | 
			
		||||
             } else {
 | 
			
		||||
-                Err(Errno::from_i32(-res))
 | 
			
		||||
+                Err(Errno::from_raw(-res))
 | 
			
		||||
             }
 | 
			
		||||
         }
 | 
			
		||||
     }
 | 
			
		||||
@@ -237,7 +237,7 @@ impl<'d> Builder<'d> {
 | 
			
		||||
             if res >= 0 {
 | 
			
		||||
                 Ok(())
 | 
			
		||||
             } else {
 | 
			
		||||
-                Err(Errno::from_i32(-res))
 | 
			
		||||
+                Err(Errno::from_raw(-res))
 | 
			
		||||
             }
 | 
			
		||||
         }
 | 
			
		||||
     }
 | 
			
		||||
@@ -256,7 +256,7 @@ impl<'d> Builder<'d> {
 | 
			
		||||
         if res >= 0 {
 | 
			
		||||
             Ok(())
 | 
			
		||||
         } else {
 | 
			
		||||
-            Err(Errno::from_i32(-res))
 | 
			
		||||
+            Err(Errno::from_raw(-res))
 | 
			
		||||
         }
 | 
			
		||||
     }
 | 
			
		||||
 
 | 
			
		||||
@@ -274,7 +274,7 @@ impl<'d> Builder<'d> {
 | 
			
		||||
         if res >= 0 {
 | 
			
		||||
             Ok(())
 | 
			
		||||
         } else {
 | 
			
		||||
-            Err(Errno::from_i32(-res))
 | 
			
		||||
+            Err(Errno::from_raw(-res))
 | 
			
		||||
         }
 | 
			
		||||
     }
 | 
			
		||||
 
 | 
			
		||||
@@ -290,7 +290,7 @@ impl<'d> Builder<'d> {
 | 
			
		||||
             if res >= 0 {
 | 
			
		||||
                 Ok(())
 | 
			
		||||
             } else {
 | 
			
		||||
-                Err(Errno::from_i32(-res))
 | 
			
		||||
+                Err(Errno::from_raw(-res))
 | 
			
		||||
             }
 | 
			
		||||
         }
 | 
			
		||||
     }
 | 
			
		||||
@@ -302,7 +302,7 @@ impl<'d> Builder<'d> {
 | 
			
		||||
             if res >= 0 {
 | 
			
		||||
                 Ok(())
 | 
			
		||||
             } else {
 | 
			
		||||
-                Err(Errno::from_i32(-res))
 | 
			
		||||
+                Err(Errno::from_raw(-res))
 | 
			
		||||
             }
 | 
			
		||||
         }
 | 
			
		||||
     }
 | 
			
		||||
@@ -314,7 +314,7 @@ impl<'d> Builder<'d> {
 | 
			
		||||
             if res >= 0 {
 | 
			
		||||
                 Ok(())
 | 
			
		||||
             } else {
 | 
			
		||||
-                Err(Errno::from_i32(-res))
 | 
			
		||||
+                Err(Errno::from_raw(-res))
 | 
			
		||||
             }
 | 
			
		||||
         }
 | 
			
		||||
     }
 | 
			
		||||
@@ -326,7 +326,7 @@ impl<'d> Builder<'d> {
 | 
			
		||||
             if res >= 0 {
 | 
			
		||||
                 Ok(())
 | 
			
		||||
             } else {
 | 
			
		||||
-                Err(Errno::from_i32(-res))
 | 
			
		||||
+                Err(Errno::from_raw(-res))
 | 
			
		||||
             }
 | 
			
		||||
         }
 | 
			
		||||
     }
 | 
			
		||||
@@ -344,7 +344,7 @@ impl<'d> Builder<'d> {
 | 
			
		||||
         if res >= 0 {
 | 
			
		||||
             Ok(())
 | 
			
		||||
         } else {
 | 
			
		||||
-            Err(Errno::from_i32(-res))
 | 
			
		||||
+            Err(Errno::from_raw(-res))
 | 
			
		||||
         }
 | 
			
		||||
     }
 | 
			
		||||
 
 | 
			
		||||
@@ -370,7 +370,7 @@ impl<'d> Builder<'d> {
 | 
			
		||||
         if res >= 0 {
 | 
			
		||||
             Ok(())
 | 
			
		||||
         } else {
 | 
			
		||||
-            Err(Errno::from_i32(-res))
 | 
			
		||||
+            Err(Errno::from_raw(-res))
 | 
			
		||||
         }
 | 
			
		||||
     }
 | 
			
		||||
 
 | 
			
		||||
@@ -394,7 +394,7 @@ impl<'d> Builder<'d> {
 | 
			
		||||
         if res >= 0 {
 | 
			
		||||
             Ok(())
 | 
			
		||||
         } else {
 | 
			
		||||
-            Err(Errno::from_i32(-res))
 | 
			
		||||
+            Err(Errno::from_raw(-res))
 | 
			
		||||
         }
 | 
			
		||||
     }
 | 
			
		||||
 
 | 
			
		||||
@@ -412,7 +412,7 @@ impl<'d> Builder<'d> {
 | 
			
		||||
             if res >= 0 {
 | 
			
		||||
                 Ok(())
 | 
			
		||||
             } else {
 | 
			
		||||
-                Err(Errno::from_i32(-res))
 | 
			
		||||
+                Err(Errno::from_raw(-res))
 | 
			
		||||
             }
 | 
			
		||||
         }
 | 
			
		||||
     }
 | 
			
		||||
@@ -438,7 +438,7 @@ impl<'d> Builder<'d> {
 | 
			
		||||
             if res >= 0 {
 | 
			
		||||
                 Ok(())
 | 
			
		||||
             } else {
 | 
			
		||||
-                Err(Errno::from_i32(-res))
 | 
			
		||||
+                Err(Errno::from_raw(-res))
 | 
			
		||||
             }
 | 
			
		||||
         }
 | 
			
		||||
     }
 | 
			
		||||
@@ -449,7 +449,7 @@ impl<'d> Builder<'d> {
 | 
			
		||||
         if res >= 0 {
 | 
			
		||||
             Ok(())
 | 
			
		||||
         } else {
 | 
			
		||||
-            Err(Errno::from_i32(-res))
 | 
			
		||||
+            Err(Errno::from_raw(-res))
 | 
			
		||||
         }
 | 
			
		||||
     }
 | 
			
		||||
 
 | 
			
		||||
@@ -468,13 +468,14 @@ impl<'d> Builder<'d> {
 | 
			
		||||
         if res >= 0 {
 | 
			
		||||
             Ok(())
 | 
			
		||||
         } else {
 | 
			
		||||
-            Err(Errno::from_i32(-res))
 | 
			
		||||
+            Err(Errno::from_raw(-res))
 | 
			
		||||
         }
 | 
			
		||||
     }
 | 
			
		||||
 
 | 
			
		||||
     pub fn add_control(&mut self, offset: u32, type_: u32) -> c_int {
 | 
			
		||||
         // Older versions of pipewire mistakenly had the return type as uint32_t,
 | 
			
		||||
         // so we need to use try_into().unwrap() to ensure those versions also work
 | 
			
		||||
+        #[allow(clippy::useless_conversion)]
 | 
			
		||||
         unsafe {
 | 
			
		||||
             spa_sys::spa_pod_builder_control(self.as_raw_ptr(), offset, type_)
 | 
			
		||||
                 .try_into()
 | 
			
		||||
@@ -511,7 +512,7 @@ impl<'d> Builder<'d> {
 | 
			
		||||
 ///         Bytes(<&[u8]>),
 | 
			
		||||
 ///     }
 | 
			
		||||
 /// );
 | 
			
		||||
-/// builder_add(<&mut libspa::pod::builder::Builder>,
 | 
			
		||||
+/// builder_add!(<&mut libspa::pod::builder::Builder>,
 | 
			
		||||
 ///     Object(
 | 
			
		||||
 ///         <type as u32>,
 | 
			
		||||
 ///         <id as u32>
 | 
			
		||||
diff --git a/src/pod/mod.rs b/src/pod/mod.rs
 | 
			
		||||
index 98c21ee..9f51ded 100644
 | 
			
		||||
--- a/src/pod/mod.rs
 | 
			
		||||
+++ b/src/pod/mod.rs
 | 
			
		||||
@@ -17,6 +17,7 @@ use std::{
 | 
			
		||||
     io::{Seek, Write},
 | 
			
		||||
     mem::MaybeUninit,
 | 
			
		||||
     os::fd::RawFd,
 | 
			
		||||
+    ptr::addr_of,
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
 use bitflags::bitflags;
 | 
			
		||||
@@ -89,7 +90,18 @@ impl Pod {
 | 
			
		||||
     }
 | 
			
		||||
 
 | 
			
		||||
     pub fn as_raw_ptr(&self) -> *mut spa_sys::spa_pod {
 | 
			
		||||
-        std::ptr::addr_of!(self.0).cast_mut()
 | 
			
		||||
+        addr_of!(self.0).cast_mut()
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
+    /// Returns a pointer to the pods body.
 | 
			
		||||
+    ///
 | 
			
		||||
+    /// If the pod has an empty body, this can be outside the pods allocation.
 | 
			
		||||
+    pub fn body(&self) -> *mut c_void {
 | 
			
		||||
+        unsafe {
 | 
			
		||||
+            self.as_raw_ptr()
 | 
			
		||||
+                .byte_add(std::mem::size_of::<spa_sys::spa_pod>())
 | 
			
		||||
+                .cast()
 | 
			
		||||
+        }
 | 
			
		||||
     }
 | 
			
		||||
 
 | 
			
		||||
     /// Construct a pod from raw bytes.
 | 
			
		||||
@@ -158,7 +170,7 @@ impl Pod {
 | 
			
		||||
             if res >= 0 {
 | 
			
		||||
                 Ok(b.assume_init())
 | 
			
		||||
             } else {
 | 
			
		||||
-                Err(Errno::from_i32(-res))
 | 
			
		||||
+                Err(Errno::from_raw(-res))
 | 
			
		||||
             }
 | 
			
		||||
         }
 | 
			
		||||
     }
 | 
			
		||||
@@ -176,7 +188,7 @@ impl Pod {
 | 
			
		||||
             if res >= 0 {
 | 
			
		||||
                 Ok(Id(id.assume_init()))
 | 
			
		||||
             } else {
 | 
			
		||||
-                Err(Errno::from_i32(-res))
 | 
			
		||||
+                Err(Errno::from_raw(-res))
 | 
			
		||||
             }
 | 
			
		||||
         }
 | 
			
		||||
     }
 | 
			
		||||
@@ -194,7 +206,7 @@ impl Pod {
 | 
			
		||||
             if res >= 0 {
 | 
			
		||||
                 Ok(int.assume_init())
 | 
			
		||||
             } else {
 | 
			
		||||
-                Err(Errno::from_i32(-res))
 | 
			
		||||
+                Err(Errno::from_raw(-res))
 | 
			
		||||
             }
 | 
			
		||||
         }
 | 
			
		||||
     }
 | 
			
		||||
@@ -212,7 +224,7 @@ impl Pod {
 | 
			
		||||
             if res >= 0 {
 | 
			
		||||
                 Ok(long.assume_init())
 | 
			
		||||
             } else {
 | 
			
		||||
-                Err(Errno::from_i32(-res))
 | 
			
		||||
+                Err(Errno::from_raw(-res))
 | 
			
		||||
             }
 | 
			
		||||
         }
 | 
			
		||||
     }
 | 
			
		||||
@@ -230,7 +242,7 @@ impl Pod {
 | 
			
		||||
             if res >= 0 {
 | 
			
		||||
                 Ok(float.assume_init())
 | 
			
		||||
             } else {
 | 
			
		||||
-                Err(Errno::from_i32(-res))
 | 
			
		||||
+                Err(Errno::from_raw(-res))
 | 
			
		||||
             }
 | 
			
		||||
         }
 | 
			
		||||
     }
 | 
			
		||||
@@ -248,7 +260,7 @@ impl Pod {
 | 
			
		||||
             if res >= 0 {
 | 
			
		||||
                 Ok(double.assume_init())
 | 
			
		||||
             } else {
 | 
			
		||||
-                Err(Errno::from_i32(-res))
 | 
			
		||||
+                Err(Errno::from_raw(-res))
 | 
			
		||||
             }
 | 
			
		||||
         }
 | 
			
		||||
     }
 | 
			
		||||
@@ -278,7 +290,7 @@ impl Pod {
 | 
			
		||||
                 let bytes = std::slice::from_raw_parts(bytes.cast(), len.try_into().unwrap());
 | 
			
		||||
                 Ok(bytes)
 | 
			
		||||
             } else {
 | 
			
		||||
-                Err(Errno::from_i32(-res))
 | 
			
		||||
+                Err(Errno::from_raw(-res))
 | 
			
		||||
             }
 | 
			
		||||
         }
 | 
			
		||||
     }
 | 
			
		||||
@@ -303,7 +315,7 @@ impl Pod {
 | 
			
		||||
                 let pointer = pointer.assume_init();
 | 
			
		||||
                 Ok((pointer, _type))
 | 
			
		||||
             } else {
 | 
			
		||||
-                Err(Errno::from_i32(-res))
 | 
			
		||||
+                Err(Errno::from_raw(-res))
 | 
			
		||||
             }
 | 
			
		||||
         }
 | 
			
		||||
     }
 | 
			
		||||
@@ -323,7 +335,7 @@ impl Pod {
 | 
			
		||||
                 let fd: RawFd = fd.try_into().unwrap();
 | 
			
		||||
                 Ok(fd)
 | 
			
		||||
             } else {
 | 
			
		||||
-                Err(Errno::from_i32(-res))
 | 
			
		||||
+                Err(Errno::from_raw(-res))
 | 
			
		||||
             }
 | 
			
		||||
         }
 | 
			
		||||
     }
 | 
			
		||||
@@ -341,7 +353,7 @@ impl Pod {
 | 
			
		||||
             if res >= 0 {
 | 
			
		||||
                 Ok(rectangle.assume_init())
 | 
			
		||||
             } else {
 | 
			
		||||
-                Err(Errno::from_i32(-res))
 | 
			
		||||
+                Err(Errno::from_raw(-res))
 | 
			
		||||
             }
 | 
			
		||||
         }
 | 
			
		||||
     }
 | 
			
		||||
@@ -359,7 +371,7 @@ impl Pod {
 | 
			
		||||
             if res >= 0 {
 | 
			
		||||
                 Ok(fraction.assume_init())
 | 
			
		||||
             } else {
 | 
			
		||||
-                Err(Errno::from_i32(-res))
 | 
			
		||||
+                Err(Errno::from_raw(-res))
 | 
			
		||||
             }
 | 
			
		||||
         }
 | 
			
		||||
     }
 | 
			
		||||
@@ -384,17 +396,324 @@ impl Pod {
 | 
			
		||||
         res != 0
 | 
			
		||||
     }
 | 
			
		||||
 
 | 
			
		||||
+    pub fn as_struct(&self) -> Result<&PodStruct, Errno> {
 | 
			
		||||
+        if self.is_struct() {
 | 
			
		||||
+            // Safety: We already know that the pod is valid, and since it is a struct, we can
 | 
			
		||||
+            //         safely create a PodStruct from it
 | 
			
		||||
+            Ok(unsafe { PodStruct::from_raw(self.as_raw_ptr() as *const spa_sys::spa_pod_struct) })
 | 
			
		||||
+        } else {
 | 
			
		||||
+            Err(Errno::EINVAL)
 | 
			
		||||
+        }
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
     pub fn is_object(&self) -> bool {
 | 
			
		||||
         let res = unsafe { spa_sys::spa_pod_is_object(self.as_raw_ptr()) };
 | 
			
		||||
         res != 0
 | 
			
		||||
     }
 | 
			
		||||
 
 | 
			
		||||
+    // TODO: spa_pod_is_object_type, spa_pod_is_object_id
 | 
			
		||||
+
 | 
			
		||||
+    pub fn as_object(&self) -> Result<&PodObject, Errno> {
 | 
			
		||||
+        if self.is_object() {
 | 
			
		||||
+            // Safety: We already know that the pod is valid, and since it is an object, we can
 | 
			
		||||
+            //         safely create a PodObject from it
 | 
			
		||||
+            Ok(unsafe { PodObject::from_raw(self.as_raw_ptr() as *const spa_sys::spa_pod_object) })
 | 
			
		||||
+        } else {
 | 
			
		||||
+            Err(Errno::EINVAL)
 | 
			
		||||
+        }
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
     pub fn is_sequence(&self) -> bool {
 | 
			
		||||
         let res = unsafe { spa_sys::spa_pod_is_sequence(self.as_raw_ptr()) };
 | 
			
		||||
         res != 0
 | 
			
		||||
     }
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+impl<'p> From<&'p PodStruct> for &'p Pod {
 | 
			
		||||
+    fn from(value: &'p PodStruct) -> Self {
 | 
			
		||||
+        value.as_pod()
 | 
			
		||||
+    }
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+impl<'p> From<&'p PodObject> for &'p Pod {
 | 
			
		||||
+    fn from(value: &'p PodObject) -> Self {
 | 
			
		||||
+        value.as_pod()
 | 
			
		||||
+    }
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+/// A transparent wrapper around a `spa_sys::spa_pod_struct`.
 | 
			
		||||
+#[repr(transparent)]
 | 
			
		||||
+pub struct PodStruct(spa_sys::spa_pod_struct);
 | 
			
		||||
+
 | 
			
		||||
+impl PodStruct {
 | 
			
		||||
+    /// # Safety
 | 
			
		||||
+    ///
 | 
			
		||||
+    /// The provided pointer must point to a valid, well-aligned pod of type struct.
 | 
			
		||||
+    ///
 | 
			
		||||
+    /// All restrictions from [`Pod::from_raw`] also apply here.
 | 
			
		||||
+    pub unsafe fn from_raw(pod: *const spa_sys::spa_pod_struct) -> &'static Self {
 | 
			
		||||
+        pod.cast::<Self>().as_ref().unwrap()
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
+    /// # Safety
 | 
			
		||||
+    ///
 | 
			
		||||
+    /// The provided pointer must point to a valid, well-aligned pod of type struct.
 | 
			
		||||
+    ///
 | 
			
		||||
+    /// All restrictions from [`Pod::from_raw_mut`] also apply here.
 | 
			
		||||
+    pub unsafe fn from_raw_mut(pod: *mut spa_sys::spa_pod_struct) -> &'static mut Self {
 | 
			
		||||
+        pod.cast::<Self>().as_mut().unwrap()
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
+    pub fn as_raw_ptr(&self) -> *mut spa_sys::spa_pod_struct {
 | 
			
		||||
+        std::ptr::addr_of!(self.0).cast_mut()
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
+    pub fn as_pod(&self) -> &Pod {
 | 
			
		||||
+        // Safety: Since this is a valid spa_pod_object, it must also be a valid spa_pod
 | 
			
		||||
+        unsafe { Pod::from_raw(addr_of!(self.0.pod)) }
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
+    pub fn fields(&self) -> PodStructIter<'_> {
 | 
			
		||||
+        PodStructIter::new(self)
 | 
			
		||||
+    }
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+impl<'p> TryFrom<&'p Pod> for &'p PodStruct {
 | 
			
		||||
+    type Error = Errno;
 | 
			
		||||
+
 | 
			
		||||
+    fn try_from(value: &'p Pod) -> Result<Self, Self::Error> {
 | 
			
		||||
+        value.as_struct()
 | 
			
		||||
+    }
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+impl AsRef<Pod> for PodStruct {
 | 
			
		||||
+    fn as_ref(&self) -> &Pod {
 | 
			
		||||
+        self.as_pod()
 | 
			
		||||
+    }
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+pub struct PodStructIter<'s> {
 | 
			
		||||
+    struct_pod: &'s PodStruct,
 | 
			
		||||
+    next: *mut c_void,
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+impl<'s> PodStructIter<'s> {
 | 
			
		||||
+    fn new(struct_pod: &'s PodStruct) -> Self {
 | 
			
		||||
+        let first_field = struct_pod.as_pod().body();
 | 
			
		||||
+
 | 
			
		||||
+        Self {
 | 
			
		||||
+            struct_pod,
 | 
			
		||||
+            next: first_field,
 | 
			
		||||
+        }
 | 
			
		||||
+    }
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+impl<'s> Iterator for PodStructIter<'s> {
 | 
			
		||||
+    type Item = &'s Pod;
 | 
			
		||||
+
 | 
			
		||||
+    fn next(&mut self) -> Option<Self::Item> {
 | 
			
		||||
+        // Check if the iterator has at least one element left that we can return
 | 
			
		||||
+        let has_next = unsafe {
 | 
			
		||||
+            spa_sys::spa_pod_is_inside(
 | 
			
		||||
+                self.struct_pod.as_pod().body(),
 | 
			
		||||
+                self.struct_pod.0.pod.size,
 | 
			
		||||
+                self.next,
 | 
			
		||||
+            )
 | 
			
		||||
+        };
 | 
			
		||||
+
 | 
			
		||||
+        if has_next {
 | 
			
		||||
+            let res = unsafe { Pod::from_raw(self.next as *const spa_sys::spa_pod) };
 | 
			
		||||
+
 | 
			
		||||
+            // Advance iter to next property
 | 
			
		||||
+            self.next = unsafe { spa_sys::spa_pod_next(self.next) };
 | 
			
		||||
+
 | 
			
		||||
+            Some(res)
 | 
			
		||||
+        } else {
 | 
			
		||||
+            None
 | 
			
		||||
+        }
 | 
			
		||||
+    }
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+/// A transparent wrapper around a `spa_sys::spa_pod_object`.
 | 
			
		||||
+#[repr(transparent)]
 | 
			
		||||
+pub struct PodObject(spa_sys::spa_pod_object);
 | 
			
		||||
+
 | 
			
		||||
+impl PodObject {
 | 
			
		||||
+    /// # Safety
 | 
			
		||||
+    ///
 | 
			
		||||
+    /// The provided pointer must point to a valid, well-aligned pod of type object.
 | 
			
		||||
+    ///
 | 
			
		||||
+    /// All restrictions from [`Pod::from_raw`] also apply here.
 | 
			
		||||
+    pub unsafe fn from_raw(pod: *const spa_sys::spa_pod_object) -> &'static Self {
 | 
			
		||||
+        pod.cast::<Self>().as_ref().unwrap()
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
+    /// # Safety
 | 
			
		||||
+    ///
 | 
			
		||||
+    /// The provided pointer must point to a valid, well-aligned pod of type object.
 | 
			
		||||
+    ///
 | 
			
		||||
+    /// All restrictions from [`Pod::from_raw_mut`] also apply here.
 | 
			
		||||
+    pub unsafe fn from_raw_mut(pod: *mut spa_sys::spa_pod_object) -> &'static mut Self {
 | 
			
		||||
+        pod.cast::<Self>().as_mut().unwrap()
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
+    pub fn as_raw_ptr(&self) -> *mut spa_sys::spa_pod_object {
 | 
			
		||||
+        std::ptr::addr_of!(self.0).cast_mut()
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
+    pub fn as_pod(&self) -> &Pod {
 | 
			
		||||
+        // Safety: Since this is a valid spa_pod_object, it must also be a valid spa_pod
 | 
			
		||||
+        unsafe { Pod::from_raw(addr_of!(self.0.pod)) }
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
+    pub fn type_(&self) -> SpaTypes {
 | 
			
		||||
+        SpaTypes::from_raw(self.0.body.type_)
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
+    pub fn id(&self) -> Id {
 | 
			
		||||
+        Id(self.0.body.id)
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
+    pub fn props(&self) -> PodObjectIter<'_> {
 | 
			
		||||
+        PodObjectIter::new(self)
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
+    pub fn find_prop(&self, /* TODO: start, */ key: Id) -> Option<&PodProp> {
 | 
			
		||||
+        let prop = unsafe {
 | 
			
		||||
+            spa_sys::spa_pod_object_find_prop(self.as_raw_ptr(), std::ptr::null(), key.0)
 | 
			
		||||
+        };
 | 
			
		||||
+
 | 
			
		||||
+        if !prop.is_null() {
 | 
			
		||||
+            unsafe { Some(PodProp::from_raw(prop)) }
 | 
			
		||||
+        } else {
 | 
			
		||||
+            None
 | 
			
		||||
+        }
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
+    pub fn fixate(&mut self) {
 | 
			
		||||
+        let _res = unsafe { spa_sys::spa_pod_object_fixate(self.as_raw_ptr()) };
 | 
			
		||||
+        // C implementation always returns 0
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
+    #[cfg(feature = "v0_3_40")]
 | 
			
		||||
+    pub fn is_fixated(&self) -> bool {
 | 
			
		||||
+        let res = unsafe { spa_sys::spa_pod_object_is_fixated(self.as_raw_ptr()) };
 | 
			
		||||
+        res != 0
 | 
			
		||||
+    }
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+impl<'p> TryFrom<&'p Pod> for &'p PodObject {
 | 
			
		||||
+    type Error = Errno;
 | 
			
		||||
+
 | 
			
		||||
+    fn try_from(value: &'p Pod) -> Result<Self, Self::Error> {
 | 
			
		||||
+        value.as_object()
 | 
			
		||||
+    }
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+impl AsRef<Pod> for PodObject {
 | 
			
		||||
+    fn as_ref(&self) -> &Pod {
 | 
			
		||||
+        self.as_pod()
 | 
			
		||||
+    }
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+pub struct PodObjectIter<'o> {
 | 
			
		||||
+    object: &'o PodObject,
 | 
			
		||||
+    next: *mut spa_sys::spa_pod_prop,
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+impl<'o> PodObjectIter<'o> {
 | 
			
		||||
+    fn new(object: &'o PodObject) -> Self {
 | 
			
		||||
+        let first_prop = unsafe { spa_sys::spa_pod_prop_first(addr_of!(object.0.body)) };
 | 
			
		||||
+
 | 
			
		||||
+        Self {
 | 
			
		||||
+            object,
 | 
			
		||||
+            next: first_prop,
 | 
			
		||||
+        }
 | 
			
		||||
+    }
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+impl<'o> Iterator for PodObjectIter<'o> {
 | 
			
		||||
+    type Item = &'o PodProp;
 | 
			
		||||
+
 | 
			
		||||
+    fn next(&mut self) -> Option<Self::Item> {
 | 
			
		||||
+        // Check if the iterator has at least one element left that we can return
 | 
			
		||||
+        let has_next = unsafe {
 | 
			
		||||
+            spa_sys::spa_pod_prop_is_inside(
 | 
			
		||||
+                addr_of!(self.object.0.body),
 | 
			
		||||
+                self.object.0.pod.size,
 | 
			
		||||
+                self.next,
 | 
			
		||||
+            )
 | 
			
		||||
+        };
 | 
			
		||||
+
 | 
			
		||||
+        if has_next {
 | 
			
		||||
+            let res = unsafe { PodProp::from_raw(self.next.cast_const()) };
 | 
			
		||||
+
 | 
			
		||||
+            // Advance iter to next property
 | 
			
		||||
+            self.next = unsafe { spa_sys::spa_pod_prop_next(self.next) };
 | 
			
		||||
+
 | 
			
		||||
+            Some(res)
 | 
			
		||||
+        } else {
 | 
			
		||||
+            None
 | 
			
		||||
+        }
 | 
			
		||||
+    }
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+bitflags! {
 | 
			
		||||
+    #[derive(Debug, PartialEq, Eq, Clone, Copy)]
 | 
			
		||||
+    pub struct PodPropFlags: u32 {
 | 
			
		||||
+        const READONLY = spa_sys::SPA_POD_PROP_FLAG_READONLY;
 | 
			
		||||
+        const HARDWARE = spa_sys::SPA_POD_PROP_FLAG_HARDWARE;
 | 
			
		||||
+        const HINT_DICT = spa_sys::SPA_POD_PROP_FLAG_HINT_DICT;
 | 
			
		||||
+        const MANDATORY = spa_sys::SPA_POD_PROP_FLAG_MANDATORY;
 | 
			
		||||
+        const DONT_FIXATE = spa_sys::SPA_POD_PROP_FLAG_DONT_FIXATE;
 | 
			
		||||
+    }
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+/// A transparent wrapper around a `spa_sys::spa_pod_prop`.
 | 
			
		||||
+#[repr(transparent)]
 | 
			
		||||
+pub struct PodProp(spa_sys::spa_pod_prop);
 | 
			
		||||
+
 | 
			
		||||
+impl PodProp {
 | 
			
		||||
+    /// # Safety
 | 
			
		||||
+    ///
 | 
			
		||||
+    /// The provided pointer must point to a valid, well-aligned [`spa_sys::spa_pod_prop`].
 | 
			
		||||
+    ///
 | 
			
		||||
+    /// While this struct doesn't represent a full pod, all restrictions from [`Pod::from_raw`] also apply
 | 
			
		||||
+    /// to this struct and the contained `value` pod.
 | 
			
		||||
+    pub unsafe fn from_raw(prop: *const spa_sys::spa_pod_prop) -> &'static Self {
 | 
			
		||||
+        prop.cast::<Self>().as_ref().unwrap()
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
+    /// # Safety
 | 
			
		||||
+    ///
 | 
			
		||||
+    /// The provided pointer must point to a valid, well-aligned pod of type object.
 | 
			
		||||
+    ///
 | 
			
		||||
+    /// While this struct doesn't represent a full pod, all restrictions from [`Pod::from_raw`] also apply
 | 
			
		||||
+    /// to this struct and the contained `value` pod.
 | 
			
		||||
+    pub unsafe fn from_raw_mut(prop: *mut spa_sys::spa_pod_prop) -> &'static mut Self {
 | 
			
		||||
+        prop.cast::<Self>().as_mut().unwrap()
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
+    pub fn as_raw_ptr(&self) -> *mut spa_sys::spa_pod_prop {
 | 
			
		||||
+        std::ptr::addr_of!(self.0).cast_mut()
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
+    pub fn key(&self) -> Id {
 | 
			
		||||
+        Id(self.0.key)
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
+    pub fn flags(&self) -> PodPropFlags {
 | 
			
		||||
+        PodPropFlags::from_bits_retain(self.0.flags)
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
+    pub fn value(&self) -> &Pod {
 | 
			
		||||
+        // Safety: Since PodProp may only be constructed around valid Pods, the contained value must also be valid.
 | 
			
		||||
+        //         We don't mutate the pod and neither can the returned reference.
 | 
			
		||||
+        //         The returned lifetime is properly shortened by this methods signature.
 | 
			
		||||
+        unsafe { Pod::from_raw(addr_of!(self.0.value)) }
 | 
			
		||||
+    }
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 /// Implementors of this trait are the canonical representation of a specific type of fixed sized SPA pod.
 | 
			
		||||
 ///
 | 
			
		||||
 /// They can be used as an output type for [`FixedSizedPod`] implementors
 | 
			
		||||
diff --git a/src/pod/parser.rs b/src/pod/parser.rs
 | 
			
		||||
index a909d57..7203ce5 100644
 | 
			
		||||
--- a/src/pod/parser.rs
 | 
			
		||||
+++ b/src/pod/parser.rs
 | 
			
		||||
@@ -134,7 +134,7 @@ impl<'d> Parser<'d> {
 | 
			
		||||
         if res >= 0 {
 | 
			
		||||
             Ok(())
 | 
			
		||||
         } else {
 | 
			
		||||
-            Err(Errno::from_i32(-res))
 | 
			
		||||
+            Err(Errno::from_raw(-res))
 | 
			
		||||
         }
 | 
			
		||||
     }
 | 
			
		||||
 
 | 
			
		||||
@@ -145,7 +145,7 @@ impl<'d> Parser<'d> {
 | 
			
		||||
             if res >= 0 {
 | 
			
		||||
                 Ok(b.assume_init())
 | 
			
		||||
             } else {
 | 
			
		||||
-                Err(Errno::from_i32(-res))
 | 
			
		||||
+                Err(Errno::from_raw(-res))
 | 
			
		||||
             }
 | 
			
		||||
         }
 | 
			
		||||
     }
 | 
			
		||||
@@ -157,7 +157,7 @@ impl<'d> Parser<'d> {
 | 
			
		||||
             if res >= 0 {
 | 
			
		||||
                 Ok(Id(id.assume_init()))
 | 
			
		||||
             } else {
 | 
			
		||||
-                Err(Errno::from_i32(-res))
 | 
			
		||||
+                Err(Errno::from_raw(-res))
 | 
			
		||||
             }
 | 
			
		||||
         }
 | 
			
		||||
     }
 | 
			
		||||
@@ -169,7 +169,7 @@ impl<'d> Parser<'d> {
 | 
			
		||||
             if res >= 0 {
 | 
			
		||||
                 Ok(int.assume_init())
 | 
			
		||||
             } else {
 | 
			
		||||
-                Err(Errno::from_i32(-res))
 | 
			
		||||
+                Err(Errno::from_raw(-res))
 | 
			
		||||
             }
 | 
			
		||||
         }
 | 
			
		||||
     }
 | 
			
		||||
@@ -181,7 +181,7 @@ impl<'d> Parser<'d> {
 | 
			
		||||
             if res >= 0 {
 | 
			
		||||
                 Ok(long.assume_init())
 | 
			
		||||
             } else {
 | 
			
		||||
-                Err(Errno::from_i32(-res))
 | 
			
		||||
+                Err(Errno::from_raw(-res))
 | 
			
		||||
             }
 | 
			
		||||
         }
 | 
			
		||||
     }
 | 
			
		||||
@@ -193,7 +193,7 @@ impl<'d> Parser<'d> {
 | 
			
		||||
             if res >= 0 {
 | 
			
		||||
                 Ok(float.assume_init())
 | 
			
		||||
             } else {
 | 
			
		||||
-                Err(Errno::from_i32(-res))
 | 
			
		||||
+                Err(Errno::from_raw(-res))
 | 
			
		||||
             }
 | 
			
		||||
         }
 | 
			
		||||
     }
 | 
			
		||||
@@ -205,7 +205,7 @@ impl<'d> Parser<'d> {
 | 
			
		||||
             if res >= 0 {
 | 
			
		||||
                 Ok(double.assume_init())
 | 
			
		||||
             } else {
 | 
			
		||||
-                Err(Errno::from_i32(-res))
 | 
			
		||||
+                Err(Errno::from_raw(-res))
 | 
			
		||||
             }
 | 
			
		||||
         }
 | 
			
		||||
     }
 | 
			
		||||
@@ -220,7 +220,7 @@ impl<'d> Parser<'d> {
 | 
			
		||||
                 let string = CStr::from_ptr(string);
 | 
			
		||||
                 Ok(string)
 | 
			
		||||
             } else {
 | 
			
		||||
-                Err(Errno::from_i32(-res))
 | 
			
		||||
+                Err(Errno::from_raw(-res))
 | 
			
		||||
             }
 | 
			
		||||
         }
 | 
			
		||||
     }
 | 
			
		||||
@@ -241,7 +241,7 @@ impl<'d> Parser<'d> {
 | 
			
		||||
                 let bytes = std::slice::from_raw_parts(bytes, len.try_into().unwrap());
 | 
			
		||||
                 Ok(bytes)
 | 
			
		||||
             } else {
 | 
			
		||||
-                Err(Errno::from_i32(-res))
 | 
			
		||||
+                Err(Errno::from_raw(-res))
 | 
			
		||||
             }
 | 
			
		||||
         }
 | 
			
		||||
     }
 | 
			
		||||
@@ -258,7 +258,7 @@ impl<'d> Parser<'d> {
 | 
			
		||||
             if res >= 0 {
 | 
			
		||||
                 Ok((ptr.assume_init(), Id(type_.assume_init())))
 | 
			
		||||
             } else {
 | 
			
		||||
-                Err(Errno::from_i32(-res))
 | 
			
		||||
+                Err(Errno::from_raw(-res))
 | 
			
		||||
             }
 | 
			
		||||
         }
 | 
			
		||||
     }
 | 
			
		||||
@@ -270,7 +270,7 @@ impl<'d> Parser<'d> {
 | 
			
		||||
             if res >= 0 {
 | 
			
		||||
                 Ok(fd.assume_init())
 | 
			
		||||
             } else {
 | 
			
		||||
-                Err(Errno::from_i32(-res))
 | 
			
		||||
+                Err(Errno::from_raw(-res))
 | 
			
		||||
             }
 | 
			
		||||
         }
 | 
			
		||||
     }
 | 
			
		||||
@@ -282,7 +282,7 @@ impl<'d> Parser<'d> {
 | 
			
		||||
             if res >= 0 {
 | 
			
		||||
                 Ok(rect.assume_init())
 | 
			
		||||
             } else {
 | 
			
		||||
-                Err(Errno::from_i32(-res))
 | 
			
		||||
+                Err(Errno::from_raw(-res))
 | 
			
		||||
             }
 | 
			
		||||
         }
 | 
			
		||||
     }
 | 
			
		||||
@@ -294,7 +294,7 @@ impl<'d> Parser<'d> {
 | 
			
		||||
             if res >= 0 {
 | 
			
		||||
                 Ok(frac.assume_init())
 | 
			
		||||
             } else {
 | 
			
		||||
-                Err(Errno::from_i32(-res))
 | 
			
		||||
+                Err(Errno::from_raw(-res))
 | 
			
		||||
             }
 | 
			
		||||
         }
 | 
			
		||||
     }
 | 
			
		||||
@@ -311,7 +311,7 @@ impl<'d> Parser<'d> {
 | 
			
		||||
 
 | 
			
		||||
                 Ok(pod)
 | 
			
		||||
             } else {
 | 
			
		||||
-                Err(Errno::from_i32(-res))
 | 
			
		||||
+                Err(Errno::from_raw(-res))
 | 
			
		||||
             }
 | 
			
		||||
         }
 | 
			
		||||
     }
 | 
			
		||||
@@ -329,7 +329,7 @@ impl<'d> Parser<'d> {
 | 
			
		||||
         if res >= 0 {
 | 
			
		||||
             Ok(())
 | 
			
		||||
         } else {
 | 
			
		||||
-            Err(Errno::from_i32(-res))
 | 
			
		||||
+            Err(Errno::from_raw(-res))
 | 
			
		||||
         }
 | 
			
		||||
     }
 | 
			
		||||
 
 | 
			
		||||
@@ -353,7 +353,7 @@ impl<'d> Parser<'d> {
 | 
			
		||||
         if res >= 0 {
 | 
			
		||||
             Ok(Id(id.assume_init()))
 | 
			
		||||
         } else {
 | 
			
		||||
-            Err(Errno::from_i32(-res))
 | 
			
		||||
+            Err(Errno::from_raw(-res))
 | 
			
		||||
         }
 | 
			
		||||
     }
 | 
			
		||||
 }
 | 
			
		||||
diff --git a/src/utils/dict.rs b/src/utils/dict.rs
 | 
			
		||||
index 7c02cff..4e99133 100644
 | 
			
		||||
--- a/src/utils/dict.rs
 | 
			
		||||
+++ b/src/utils/dict.rs
 | 
			
		||||
@@ -102,7 +102,6 @@ impl DictRef {
 | 
			
		||||
     ///
 | 
			
		||||
     /// # Examples
 | 
			
		||||
     /// ```
 | 
			
		||||
-    /// use libspa::prelude::*;
 | 
			
		||||
     /// use libspa::{utils::dict::StaticDict, static_dict};
 | 
			
		||||
     ///
 | 
			
		||||
     /// static DICT: StaticDict = static_dict! {
 | 
			
		||||
@@ -145,9 +144,7 @@ impl std::fmt::Debug for DictRef {
 | 
			
		||||
 
 | 
			
		||||
         impl<'a> fmt::Debug for Entries<'a> {
 | 
			
		||||
             fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 | 
			
		||||
-                f.debug_map()
 | 
			
		||||
-                    .entries(self.0.clone().map(|(k, v)| (k, v)))
 | 
			
		||||
-                    .finish()
 | 
			
		||||
+                f.debug_map().entries(self.0.clone()).finish()
 | 
			
		||||
             }
 | 
			
		||||
         }
 | 
			
		||||
 
 | 
			
		||||
@@ -392,7 +389,7 @@ macro_rules! static_dict {
 | 
			
		||||
         };
 | 
			
		||||
 
 | 
			
		||||
         unsafe {
 | 
			
		||||
-            let ptr = &RAW as *const _ as *mut _;
 | 
			
		||||
+            let ptr = std::ptr::addr_of!(RAW).cast_mut();
 | 
			
		||||
             StaticDict::from_ptr(ptr::NonNull::new_unchecked(ptr))
 | 
			
		||||
         }
 | 
			
		||||
     }};
 | 
			
		||||
@@ -421,7 +418,7 @@ unsafe impl Sync for StaticDict {}
 | 
			
		||||
 mod tests {
 | 
			
		||||
     use super::{DictRef, Flags, StaticDict};
 | 
			
		||||
     use spa_sys::spa_dict;
 | 
			
		||||
-    use std::{ffi::CString, ptr};
 | 
			
		||||
+    use std::ptr;
 | 
			
		||||
 
 | 
			
		||||
     #[test]
 | 
			
		||||
     fn test_empty_dict() {
 | 
			
		||||
@@ -447,20 +444,8 @@ mod tests {
 | 
			
		||||
         };
 | 
			
		||||
 
 | 
			
		||||
         let mut iter = dict.iter_cstr();
 | 
			
		||||
-        assert_eq!(
 | 
			
		||||
-            (
 | 
			
		||||
-                CString::new("K0").unwrap().as_c_str(),
 | 
			
		||||
-                CString::new("V0").unwrap().as_c_str()
 | 
			
		||||
-            ),
 | 
			
		||||
-            iter.next().unwrap()
 | 
			
		||||
-        );
 | 
			
		||||
-        assert_eq!(
 | 
			
		||||
-            (
 | 
			
		||||
-                CString::new("K1").unwrap().as_c_str(),
 | 
			
		||||
-                CString::new("V1").unwrap().as_c_str()
 | 
			
		||||
-            ),
 | 
			
		||||
-            iter.next().unwrap()
 | 
			
		||||
-        );
 | 
			
		||||
+        assert_eq!((c"K0", c"V0"), iter.next().unwrap());
 | 
			
		||||
+        assert_eq!((c"K1", c"V1"), iter.next().unwrap());
 | 
			
		||||
         assert_eq!(None, iter.next());
 | 
			
		||||
     }
 | 
			
		||||
 
 | 
			
		||||
diff --git a/src/utils/mod.rs b/src/utils/mod.rs
 | 
			
		||||
index c0c4051..6aa83f2 100644
 | 
			
		||||
--- a/src/utils/mod.rs
 | 
			
		||||
+++ b/src/utils/mod.rs
 | 
			
		||||
@@ -144,7 +144,7 @@ impl SpaTypes {
 | 
			
		||||
         Self(raw)
 | 
			
		||||
     }
 | 
			
		||||
 
 | 
			
		||||
-    /// Get the raw [`c_uint`](std::os::raw::c_uint) representing this `SpaTypes`.
 | 
			
		||||
+    /// Get the raw [`c_uint`] representing this `SpaTypes`.
 | 
			
		||||
     pub fn as_raw(&self) -> c_uint {
 | 
			
		||||
         self.0
 | 
			
		||||
     }
 | 
			
		||||
diff --git a/src/utils/result.rs b/src/utils/result.rs
 | 
			
		||||
index 83d1e87..8d06636 100644
 | 
			
		||||
--- a/src/utils/result.rs
 | 
			
		||||
+++ b/src/utils/result.rs
 | 
			
		||||
@@ -133,7 +133,7 @@ impl Error {
 | 
			
		||||
     fn new(e: i32) -> Self {
 | 
			
		||||
         assert!(e > 0);
 | 
			
		||||
 
 | 
			
		||||
-        Self(Errno::from_i32(e))
 | 
			
		||||
+        Self(Errno::from_raw(e))
 | 
			
		||||
     }
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										345
									
								
								rosenthal/packages/patches/rust-pipewire.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										345
									
								
								rosenthal/packages/patches/rust-pipewire.patch
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,345 @@
 | 
			
		||||
diff --git a/Cargo.toml b/Cargo.toml
 | 
			
		||||
index bef8079..f795a3e 100644
 | 
			
		||||
--- a/Cargo.toml
 | 
			
		||||
+++ b/Cargo.toml
 | 
			
		||||
@@ -45,7 +45,7 @@ version = "2"
 | 
			
		||||
 version = "0.2"
 | 
			
		||||
 
 | 
			
		||||
 [dependencies.nix]
 | 
			
		||||
-version = "0.27"
 | 
			
		||||
+version = "0.29"
 | 
			
		||||
 features = [
 | 
			
		||||
     "signal",
 | 
			
		||||
     "fs",
 | 
			
		||||
diff --git a/src/channel.rs b/src/channel.rs
 | 
			
		||||
index 3c8c742..672cddc 100644
 | 
			
		||||
--- a/src/channel.rs
 | 
			
		||||
+++ b/src/channel.rs
 | 
			
		||||
@@ -89,7 +89,11 @@ impl<T: 'static> Receiver<T> {
 | 
			
		||||
         F: Fn(T) + 'static,
 | 
			
		||||
     {
 | 
			
		||||
         let channel = self.channel.clone();
 | 
			
		||||
-        let readfd = channel.lock().expect("Channel mutex lock poisoned").readfd;
 | 
			
		||||
+        let readfd = channel
 | 
			
		||||
+            .lock()
 | 
			
		||||
+            .expect("Channel mutex lock poisoned")
 | 
			
		||||
+            .readfd
 | 
			
		||||
+            .as_raw_fd();
 | 
			
		||||
 
 | 
			
		||||
         // Attach the pipe as an IO source to the loop.
 | 
			
		||||
         // Whenever the pipe is written to, call the users callback with each message in the queue.
 | 
			
		||||
@@ -97,7 +101,7 @@ impl<T: 'static> Receiver<T> {
 | 
			
		||||
             let mut channel = channel.lock().expect("Channel mutex lock poisoned");
 | 
			
		||||
 
 | 
			
		||||
             // Read from the pipe to make it block until written to again.
 | 
			
		||||
-            let _ = nix::unistd::read(channel.readfd, &mut [0]);
 | 
			
		||||
+            let _ = nix::unistd::read(channel.readfd.as_raw_fd(), &mut [0]);
 | 
			
		||||
 
 | 
			
		||||
             channel.queue.drain(..).for_each(&callback);
 | 
			
		||||
         });
 | 
			
		||||
@@ -162,7 +166,7 @@ impl<T> Sender<T> {
 | 
			
		||||
         // If no messages are waiting already, signal the receiver to read some.
 | 
			
		||||
         // Because the channel mutex is locked, it is alright to do this before pushing the message.
 | 
			
		||||
         if channel.queue.is_empty() {
 | 
			
		||||
-            match nix::unistd::write(channel.writefd, &[1u8]) {
 | 
			
		||||
+            match nix::unistd::write(&channel.writefd, &[1u8]) {
 | 
			
		||||
                 Ok(_) => (),
 | 
			
		||||
                 Err(_) => return Err(t),
 | 
			
		||||
             }
 | 
			
		||||
@@ -178,21 +182,12 @@ impl<T> Sender<T> {
 | 
			
		||||
 /// Shared state between the [`Sender`]s and the [`Receiver`].
 | 
			
		||||
 struct Channel<T> {
 | 
			
		||||
     /// A pipe used to signal the loop the receiver is attached to that messages are waiting.
 | 
			
		||||
-    readfd: RawFd,
 | 
			
		||||
-    writefd: RawFd,
 | 
			
		||||
+    readfd: OwnedFd,
 | 
			
		||||
+    writefd: OwnedFd,
 | 
			
		||||
     /// Queue of any messages waiting to be received.
 | 
			
		||||
     queue: VecDeque<T>,
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
-impl<T> Drop for Channel<T> {
 | 
			
		||||
-    fn drop(&mut self) {
 | 
			
		||||
-        // We do not error check here, because the pipe does not contain any data that might be lost,
 | 
			
		||||
-        // and because there is no way to handle an error in a `Drop` implementation anyways.
 | 
			
		||||
-        let _ = nix::unistd::close(self.readfd);
 | 
			
		||||
-        let _ = nix::unistd::close(self.writefd);
 | 
			
		||||
-    }
 | 
			
		||||
-}
 | 
			
		||||
-
 | 
			
		||||
 /// Create a Sender-Receiver pair, where the sender can be used to send messages to the receiver.
 | 
			
		||||
 ///
 | 
			
		||||
 /// This functions similar to [`std::sync::mpsc`], but with a receiver that can be attached to any
 | 
			
		||||
diff --git a/src/client.rs b/src/client.rs
 | 
			
		||||
index cd28024..89f71e7 100644
 | 
			
		||||
--- a/src/client.rs
 | 
			
		||||
+++ b/src/client.rs
 | 
			
		||||
@@ -5,7 +5,10 @@ use bitflags::bitflags;
 | 
			
		||||
 use libc::c_void;
 | 
			
		||||
 use std::ops::Deref;
 | 
			
		||||
 use std::pin::Pin;
 | 
			
		||||
-use std::{ffi::CString, ptr};
 | 
			
		||||
+use std::{
 | 
			
		||||
+    ffi::{CStr, CString},
 | 
			
		||||
+    ptr,
 | 
			
		||||
+};
 | 
			
		||||
 use std::{fmt, mem};
 | 
			
		||||
 
 | 
			
		||||
 use crate::{
 | 
			
		||||
@@ -53,7 +56,11 @@ impl Client {
 | 
			
		||||
 
 | 
			
		||||
     pub fn error(&self, id: u32, res: i32, message: &str) {
 | 
			
		||||
         let message = CString::new(message).expect("Null byte in message parameter");
 | 
			
		||||
+        let message_cstr = message.as_c_str();
 | 
			
		||||
+        Client::error_cstr(self, id, res, message_cstr)
 | 
			
		||||
+    }
 | 
			
		||||
 
 | 
			
		||||
+    pub fn error_cstr(&self, id: u32, res: i32, message: &CStr) {
 | 
			
		||||
         unsafe {
 | 
			
		||||
             spa_interface_call_method!(
 | 
			
		||||
                 self.proxy.as_ptr(),
 | 
			
		||||
diff --git a/src/core.rs b/src/core.rs
 | 
			
		||||
index 960c3c2..1feb79f 100644
 | 
			
		||||
--- a/src/core.rs
 | 
			
		||||
+++ b/src/core.rs
 | 
			
		||||
@@ -126,8 +126,17 @@ impl CoreRef {
 | 
			
		||||
         factory_name: &str,
 | 
			
		||||
         properties: &impl AsRef<spa::utils::dict::DictRef>,
 | 
			
		||||
     ) -> Result<P, Error> {
 | 
			
		||||
-        let type_ = P::type_();
 | 
			
		||||
         let factory_name = CString::new(factory_name).expect("Null byte in factory_name parameter");
 | 
			
		||||
+        let factory_name_cstr = factory_name.as_c_str();
 | 
			
		||||
+        CoreRef::create_object_cstr(self, factory_name_cstr, properties)
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
+    pub fn create_object_cstr<P: ProxyT>(
 | 
			
		||||
+        &self,
 | 
			
		||||
+        factory_name: &CStr,
 | 
			
		||||
+        properties: &impl AsRef<spa::utils::dict::DictRef>,
 | 
			
		||||
+    ) -> Result<P, Error> {
 | 
			
		||||
+        let type_ = P::type_();
 | 
			
		||||
         let type_str = CString::new(type_.to_string())
 | 
			
		||||
             .expect("Null byte in string representation of type_ parameter");
 | 
			
		||||
 
 | 
			
		||||
diff --git a/src/lib.rs b/src/lib.rs
 | 
			
		||||
index e63490c..7f100df 100644
 | 
			
		||||
--- a/src/lib.rs
 | 
			
		||||
+++ b/src/lib.rs
 | 
			
		||||
@@ -140,12 +140,6 @@ mod utils;
 | 
			
		||||
 pub use pw_sys as sys;
 | 
			
		||||
 pub use spa;
 | 
			
		||||
 
 | 
			
		||||
-// Re-export all the traits in a prelude module, so that applications
 | 
			
		||||
-// can always "use pipewire::prelude::*" without getting conflicts
 | 
			
		||||
-pub mod prelude {
 | 
			
		||||
-    pub use spa::prelude::*;
 | 
			
		||||
-}
 | 
			
		||||
-
 | 
			
		||||
 use std::ptr;
 | 
			
		||||
 
 | 
			
		||||
 /// Initialize PipeWire
 | 
			
		||||
diff --git a/src/loop_.rs b/src/loop_.rs
 | 
			
		||||
index 01560c4..3dfa8bc 100644
 | 
			
		||||
--- a/src/loop_.rs
 | 
			
		||||
+++ b/src/loop_.rs
 | 
			
		||||
@@ -635,7 +635,14 @@ impl<'l> TimerSource<'l> {
 | 
			
		||||
         fn duration_to_timespec(duration: Duration) -> spa_sys::timespec {
 | 
			
		||||
             spa_sys::timespec {
 | 
			
		||||
                 tv_sec: duration.as_secs().try_into().expect("Duration too long"),
 | 
			
		||||
-                tv_nsec: duration.subsec_nanos().try_into().unwrap(),
 | 
			
		||||
+                // `Into` is only implemented on some platforms for these types,
 | 
			
		||||
+                // so use a fallible conversion.
 | 
			
		||||
+                // As there are a limited amount of nanoseconds in a second, this shouldn't fail
 | 
			
		||||
+                #[allow(clippy::unnecessary_fallible_conversions)]
 | 
			
		||||
+                tv_nsec: duration
 | 
			
		||||
+                    .subsec_nanos()
 | 
			
		||||
+                    .try_into()
 | 
			
		||||
+                    .expect("Nanoseconds should fit into timespec"),
 | 
			
		||||
             }
 | 
			
		||||
         }
 | 
			
		||||
 
 | 
			
		||||
diff --git a/src/metadata.rs b/src/metadata.rs
 | 
			
		||||
index 64a68e1..ebdc3e7 100644
 | 
			
		||||
--- a/src/metadata.rs
 | 
			
		||||
+++ b/src/metadata.rs
 | 
			
		||||
@@ -55,6 +55,18 @@ impl Metadata {
 | 
			
		||||
         let key = CString::new(key).expect("Invalid byte in metadata key");
 | 
			
		||||
         let type_ = type_.map(|t| CString::new(t).expect("Invalid byte in metadata type"));
 | 
			
		||||
         let value = value.map(|v| CString::new(v).expect("Invalid byte in metadata value"));
 | 
			
		||||
+        let key_cstr = key.as_c_str();
 | 
			
		||||
+
 | 
			
		||||
+        Metadata::set_property_cstr(self, subject, key_cstr, type_.as_deref(), value.as_deref())
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
+    pub fn set_property_cstr(
 | 
			
		||||
+        &self,
 | 
			
		||||
+        subject: u32,
 | 
			
		||||
+        key: &CStr,
 | 
			
		||||
+        type_: Option<&CStr>,
 | 
			
		||||
+        value: Option<&CStr>,
 | 
			
		||||
+    ) {
 | 
			
		||||
         unsafe {
 | 
			
		||||
             spa::spa_interface_call_method!(
 | 
			
		||||
                 self.proxy.as_ptr(),
 | 
			
		||||
@@ -62,8 +74,8 @@ impl Metadata {
 | 
			
		||||
                 set_property,
 | 
			
		||||
                 subject,
 | 
			
		||||
                 key.as_ptr() as *const _,
 | 
			
		||||
-                type_.as_deref().map_or_else(ptr::null, CStr::as_ptr) as *const _,
 | 
			
		||||
-                value.as_deref().map_or_else(ptr::null, CStr::as_ptr) as *const _
 | 
			
		||||
+                type_.map_or_else(ptr::null, CStr::as_ptr) as *const _,
 | 
			
		||||
+                value.map_or_else(ptr::null, CStr::as_ptr) as *const _
 | 
			
		||||
             );
 | 
			
		||||
         }
 | 
			
		||||
     }
 | 
			
		||||
diff --git a/src/permissions.rs b/src/permissions.rs
 | 
			
		||||
index bdb011c..7d445ad 100644
 | 
			
		||||
--- a/src/permissions.rs
 | 
			
		||||
+++ b/src/permissions.rs
 | 
			
		||||
@@ -16,17 +16,33 @@ bitflags! {
 | 
			
		||||
     }
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+#[derive(Clone, Copy)]
 | 
			
		||||
 #[repr(transparent)]
 | 
			
		||||
 pub struct Permission(pw_sys::pw_permission);
 | 
			
		||||
 
 | 
			
		||||
 impl Permission {
 | 
			
		||||
+    pub fn new(id: u32, flags: PermissionFlags) -> Self {
 | 
			
		||||
+        Self(pw_sys::pw_permission {
 | 
			
		||||
+            id,
 | 
			
		||||
+            permissions: flags.bits(),
 | 
			
		||||
+        })
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
     pub fn id(&self) -> u32 {
 | 
			
		||||
         self.0.id
 | 
			
		||||
     }
 | 
			
		||||
 
 | 
			
		||||
+    pub fn set_id(&mut self, id: u32) {
 | 
			
		||||
+        self.0.id = id;
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
     pub fn permission_flags(&self) -> PermissionFlags {
 | 
			
		||||
         PermissionFlags::from_bits_retain(self.0.permissions)
 | 
			
		||||
     }
 | 
			
		||||
+
 | 
			
		||||
+    pub fn set_permission_flags(&mut self, flags: PermissionFlags) {
 | 
			
		||||
+        self.0.permissions = flags.bits();
 | 
			
		||||
+    }
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 impl fmt::Debug for Permission {
 | 
			
		||||
diff --git a/src/properties.rs b/src/properties.rs
 | 
			
		||||
index c71cf72..008bed6 100644
 | 
			
		||||
--- a/src/properties.rs
 | 
			
		||||
+++ b/src/properties.rs
 | 
			
		||||
@@ -1,4 +1,10 @@
 | 
			
		||||
-use std::{ffi::CString, fmt, mem::ManuallyDrop, ops::Deref, ptr};
 | 
			
		||||
+use std::{
 | 
			
		||||
+    ffi::{CStr, CString},
 | 
			
		||||
+    fmt,
 | 
			
		||||
+    mem::ManuallyDrop,
 | 
			
		||||
+    ops::Deref,
 | 
			
		||||
+    ptr,
 | 
			
		||||
+};
 | 
			
		||||
 
 | 
			
		||||
 /// A collection of key/value pairs.
 | 
			
		||||
 ///
 | 
			
		||||
@@ -36,7 +42,6 @@ pub struct Properties {
 | 
			
		||||
 ///
 | 
			
		||||
 /// Any expression that evaluates to a `impl Into<Vec<u8>>` can be used for both keys and values.
 | 
			
		||||
 /// ```rust
 | 
			
		||||
-/// use pipewire::prelude::*;
 | 
			
		||||
 /// use pipewire::properties::properties;
 | 
			
		||||
 ///
 | 
			
		||||
 /// let key = String::from("Key");
 | 
			
		||||
@@ -149,6 +154,19 @@ impl Clone for Properties {
 | 
			
		||||
     }
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+impl<K, V> FromIterator<(K, V)> for Properties
 | 
			
		||||
+where
 | 
			
		||||
+    K: Into<Vec<u8>>,
 | 
			
		||||
+    V: Into<Vec<u8>>,
 | 
			
		||||
+{
 | 
			
		||||
+    fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> Self {
 | 
			
		||||
+        let mut props = Self::new();
 | 
			
		||||
+        props.extend(iter);
 | 
			
		||||
+
 | 
			
		||||
+        props
 | 
			
		||||
+    }
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 impl Drop for Properties {
 | 
			
		||||
     fn drop(&mut self) {
 | 
			
		||||
         unsafe { pw_sys::pw_properties_free(self.ptr.as_ptr()) }
 | 
			
		||||
@@ -196,6 +214,11 @@ impl PropertiesRef {
 | 
			
		||||
     pub fn get(&self, key: &str) -> Option<&str> {
 | 
			
		||||
         let key = CString::new(key).expect("key contains null byte");
 | 
			
		||||
 
 | 
			
		||||
+        let key_cstr = key.as_c_str();
 | 
			
		||||
+        PropertiesRef::get_cstr(self, key_cstr)
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
+    pub fn get_cstr(&self, key: &CStr) -> Option<&str> {
 | 
			
		||||
         let res =
 | 
			
		||||
             unsafe { pw_sys::pw_properties_get(self.as_raw_ptr().cast_const(), key.as_ptr()) };
 | 
			
		||||
 
 | 
			
		||||
@@ -245,6 +268,18 @@ impl fmt::Debug for PropertiesRef {
 | 
			
		||||
     }
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+impl<K, V> Extend<(K, V)> for PropertiesRef
 | 
			
		||||
+where
 | 
			
		||||
+    K: Into<Vec<u8>>,
 | 
			
		||||
+    V: Into<Vec<u8>>,
 | 
			
		||||
+{
 | 
			
		||||
+    fn extend<T: IntoIterator<Item = (K, V)>>(&mut self, iter: T) {
 | 
			
		||||
+        for (k, v) in iter {
 | 
			
		||||
+            self.insert(k, v);
 | 
			
		||||
+        }
 | 
			
		||||
+    }
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 #[cfg(test)]
 | 
			
		||||
 mod tests {
 | 
			
		||||
     use super::*;
 | 
			
		||||
diff --git a/src/stream.rs b/src/stream.rs
 | 
			
		||||
index ff28af8..e04ff64 100644
 | 
			
		||||
--- a/src/stream.rs
 | 
			
		||||
+++ b/src/stream.rs
 | 
			
		||||
@@ -64,6 +64,13 @@ impl Stream {
 | 
			
		||||
     /// Initialises a new stream with the given `name` and `properties`.
 | 
			
		||||
     pub fn new(core: &Core, name: &str, properties: Properties) -> Result<Self, Error> {
 | 
			
		||||
         let name = CString::new(name).expect("Invalid byte in stream name");
 | 
			
		||||
+
 | 
			
		||||
+        let c_str = name.as_c_str();
 | 
			
		||||
+        Stream::new_cstr(core, c_str, properties)
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
+    /// Initialises a new stream with the given `name` as Cstr and `properties`.
 | 
			
		||||
+    pub fn new_cstr(core: &Core, name: &CStr, properties: Properties) -> Result<Self, Error> {
 | 
			
		||||
         let stream = unsafe {
 | 
			
		||||
             pw_sys::pw_stream_new(core.as_raw_ptr(), name.as_ptr(), properties.into_raw())
 | 
			
		||||
         };
 | 
			
		||||
@@ -249,8 +256,18 @@ impl StreamRef {
 | 
			
		||||
     ///
 | 
			
		||||
     pub fn set_error(&mut self, res: i32, error: &str) {
 | 
			
		||||
         let error = CString::new(error).expect("failed to convert error to CString");
 | 
			
		||||
+        let error_cstr = error.as_c_str();
 | 
			
		||||
+        StreamRef::set_error_cstr(self, res, error_cstr)
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
+    /// Set the stream in error state with CStr
 | 
			
		||||
+    ///
 | 
			
		||||
+    /// # Panics
 | 
			
		||||
+    /// Will panic if `error` contains a 0 byte.
 | 
			
		||||
+    ///
 | 
			
		||||
+    pub fn set_error_cstr(&mut self, res: i32, error: &CStr) {
 | 
			
		||||
         unsafe {
 | 
			
		||||
-            pw_sys::pw_stream_set_error(self.as_raw_ptr(), res, error.as_c_str().as_ptr());
 | 
			
		||||
+            pw_sys::pw_stream_set_error(self.as_raw_ptr(), res, error.as_ptr());
 | 
			
		||||
         }
 | 
			
		||||
     }
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1901
									
								
								rosenthal/packages/patches/rust-smithay.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1901
									
								
								rosenthal/packages/patches/rust-smithay.patch
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -9,6 +9,17 @@
 | 
			
		||||
  #:use-module (guix download)
 | 
			
		||||
  #:use-module (guix git-download)
 | 
			
		||||
  #:use-module (guix build-system cargo)
 | 
			
		||||
  #:use-module (gnu packages admin)
 | 
			
		||||
  #:use-module (gnu packages freedesktop)
 | 
			
		||||
  #:use-module (gnu packages gl)
 | 
			
		||||
  #:use-module (gnu packages glib)
 | 
			
		||||
  #:use-module (gnu packages gtk)
 | 
			
		||||
  #:use-module (gnu packages linux)
 | 
			
		||||
  #:use-module (gnu packages llvm)
 | 
			
		||||
  #:use-module (gnu packages pkg-config)
 | 
			
		||||
  #:use-module (gnu packages wm)
 | 
			
		||||
  #:use-module (gnu packages xdisorg)
 | 
			
		||||
  #:use-module (rosenthal packages)
 | 
			
		||||
  #:use-module (rosenthal packages rust-crates))
 | 
			
		||||
 | 
			
		||||
(define-public atuin
 | 
			
		||||
@ -56,3 +67,60 @@
 | 
			
		||||
additional context for commands.  Additionally, it provides optional and fully
 | 
			
		||||
encrypted synchronisation of history between machines, via an Atuin server.")
 | 
			
		||||
    (license license:gpl3)))
 | 
			
		||||
 | 
			
		||||
(define-public niri
 | 
			
		||||
  (package
 | 
			
		||||
   (name "niri")
 | 
			
		||||
   (version "25.02")
 | 
			
		||||
   (source (origin
 | 
			
		||||
             (method git-fetch)
 | 
			
		||||
             (uri (git-reference
 | 
			
		||||
                   (url "https://github.com/YaLTeR/niri")
 | 
			
		||||
                   (commit (string-append "v" version))))
 | 
			
		||||
             (file-name (git-file-name name version))
 | 
			
		||||
             (sha256
 | 
			
		||||
              (base32
 | 
			
		||||
               "0vzskaalcz6pcml687n54adjddzgf5r07gggc4fhfsa08h1wfd4r"))
 | 
			
		||||
             (patches (list (local-file "./patches/niri.patch")))))
 | 
			
		||||
   (build-system cargo-build-system)
 | 
			
		||||
   (arguments
 | 
			
		||||
    (list #:install-source? #f
 | 
			
		||||
          #:phases
 | 
			
		||||
          #~(modify-phases %standard-phases
 | 
			
		||||
              (add-after 'configure 'set-rust-flags
 | 
			
		||||
                (lambda _
 | 
			
		||||
                  (setenv "RUSTFLAGS" (string-join
 | 
			
		||||
                                       '("-C" "link-arg=-lEGL"
 | 
			
		||||
                                         "-C" "link-arg=-lwayland-client")
 | 
			
		||||
                                       " "))))
 | 
			
		||||
              (add-before 'check 'prepare-test-environment
 | 
			
		||||
                (lambda _
 | 
			
		||||
                  (setenv "XDG_RUNTIME_DIR" "/tmp")))
 | 
			
		||||
              (add-after 'install 'install-extras
 | 
			
		||||
                (lambda _
 | 
			
		||||
                  (install-file
 | 
			
		||||
                   "resources/niri.desktop"
 | 
			
		||||
                   (in-vicinity #$output "share/wayland-sessions"))
 | 
			
		||||
                  (install-file
 | 
			
		||||
                   "resources/niri-portals.conf"
 | 
			
		||||
                   (in-vicinity #$output "share/xdg-desktop-portal")))))))
 | 
			
		||||
   (native-inputs
 | 
			
		||||
    (list pkg-config))
 | 
			
		||||
   (inputs
 | 
			
		||||
    (cons* clang
 | 
			
		||||
           libdisplay-info
 | 
			
		||||
           libinput-minimal
 | 
			
		||||
           libseat
 | 
			
		||||
           libxkbcommon
 | 
			
		||||
           mesa
 | 
			
		||||
           pango
 | 
			
		||||
           pipewire
 | 
			
		||||
           wayland
 | 
			
		||||
           (force niri-cargo-inputs)))
 | 
			
		||||
   (home-page "https://github.com/YaLTeR/niri")
 | 
			
		||||
   (synopsis "Scrollable-tiling Wayland compositor")
 | 
			
		||||
   (description
 | 
			
		||||
    "Niri is a scrollable-tiling Wayland compositor which arranges windows in a
 | 
			
		||||
scrollable format.  It is considered stable for daily use and performs most
 | 
			
		||||
functions expected of a Wayland compositor.")
 | 
			
		||||
   (license license:gpl3)))
 | 
			
		||||
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Loading…
	
		Reference in New Issue
	
	Block a user