defining first Display and Registry structs. Added Callback support for Registry.

This commit is contained in:
neo
2026-08-27 17:52:14 +02:00
parent ef2051c07f
commit 9ece322dc7
5 changed files with 267 additions and 14 deletions
+97
View File
@@ -0,0 +1,97 @@
// SPDX-License-Identifier: GPL-2.0-only
use std::{env, fmt, io::{Error, ErrorKind}, ptr::NonNull};
use crate::{display::ffi::{wl_display_dispatch, wl_proxy, wl_proxy_get_version, wl_proxy_marshal_flags, wl_registry_interface}, registry::Registry};
mod ffi {
use std::ffi::{c_char, c_int,c_void};
// relevant type definitions
#[repr(C)]
#[allow(non_camel_case_types)]
pub(super) struct wl_display;
#[repr(C)]
#[allow(non_camel_case_types)]
pub(super) struct wl_proxy;
#[repr(C)]
#[allow(non_camel_case_types)]
pub(super) struct wl_interface;
#[link(name = "wayland-client")]
unsafe extern "C" {
// relevant public static
pub(crate) unsafe static wl_registry_interface: wl_interface;
// relevant function definitions
pub(super) unsafe fn wl_display_connect(name: *const c_char) -> *mut c_void;
pub(super) unsafe fn wl_display_disconnect(disp: *mut wl_display);
pub(super) unsafe fn wl_display_dispatch(disp: *mut wl_display) -> c_int;
pub(super) unsafe fn wl_display_roundtrip(disp: *mut wl_display) -> c_int;
pub(super) unsafe fn wl_proxy_marshal_flags(proxy: *mut wl_proxy, opcode: u32, interface: *const wl_interface, version: u32, flags: u32, ptr: *mut c_void) -> *mut c_void;
pub(super) unsafe fn wl_proxy_get_version(proxy: *mut wl_proxy) -> u32;
}
}
use ffi::wl_display;
// core wayland elemenent: Display
pub struct Display {
raw: NonNull<wl_display>,
}
impl Display {
pub fn new(name: Option<String>) -> Result<Self, std::io::Error> {
let sock_name: String = if name.is_some() {
name.unwrap()
} else {
let env_name = env::var("WAYLAND_DISPLAY");
if env_name.is_ok() {
env_name.unwrap()
} else {
"wayland-0".into()
}
};
let binding = std::ffi::CString::new(sock_name).unwrap();
let str = binding.as_c_str();
let raw = unsafe { ffi::wl_display_connect(str.as_ptr()) };
let raw = NonNull::<wl_display>::new(raw as *mut wl_display)
.expect("Failed to connect to Wayland display.");
Ok(Self{raw})
}
pub fn get_registry(&self) -> Registry {
let registry = unsafe {
wl_proxy_marshal_flags(self.raw.as_ptr() as *mut wl_proxy,
1,
&wl_registry_interface,
wl_proxy_get_version(self.raw.as_ptr() as *mut wl_proxy),
0,
std::ptr::null_mut()
)};
return Registry::from(registry);
}
pub fn dispatch(&self) -> Option<i32> {
let events = unsafe {wl_display_dispatch(self.raw.as_ptr()) };
if events == -1 {
None
} else {
Some(events)
}
}
pub fn roundtrip(&self) -> std::io::Result<i32> {
let r = unsafe { ffi::wl_display_roundtrip(self.raw.as_ptr()) };
if r >= 0 {
Ok(r)
} else {
Err(Error::new(ErrorKind::Other, "unable to process server messages"))
}
}
}
impl Drop for Display {
fn drop(&mut self) {
unsafe { ffi::wl_display_disconnect(self.raw.as_ptr()) };
}
}