defining first Display and Registry structs. Added Callback support for Registry.
This commit is contained in:
@@ -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()) };
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user