declared interfaces and more wrappers

This commit is contained in:
neo
2026-08-25 17:55:57 +02:00
parent aeab2375c8
commit 61cfcf283f
9 changed files with 235 additions and 23 deletions
+15 -6
View File
@@ -3,26 +3,35 @@ use std::io;
use wayland_server::client::Client; use wayland_server::client::Client;
use wayland_server::display::Display; use wayland_server::display::Display;
use wayland_server::global::{Global, GlobalState}; use wayland_server::global::{Global, GlobalState};
use wayland_server::interface::{Interface, Output};
use wayland_server::resource::Resource;
struct State { struct State {
output_interface: Interface<Output>,
}
impl State {
pub fn new() -> Self {
Self { output_interface: Interface::<Output>::new() }
}
} }
impl GlobalState for State { impl GlobalState for State {
fn handle_output_bind(&self, client: Client, version: u32, id: u32) { fn handle_output_bind(&self, client: &Client, _version: u32, id: u32) -> io::Result<()>{
todo!() let resource = Resource::new(&client, id, &self.output_interface)?;
Ok(())
} }
} }
fn main() -> io::Result<()> { fn main() -> io::Result<()> {
// Creating a compositor State // Creating a compositor State
let state = State {}; let state = State::new();
// create a wayland display // create a wayland display
let display = Display::new()?; let display = Display::new()?;
// get the global registry // get the global registry
let global = Global::new(&display, state)?; let _global = Global::new(&display, state)?;
println!("Running wayland_display on {}", display.get_name()); println!("Running wayland_display on {}", display.get_name());
+7
View File
@@ -3,6 +3,7 @@
use std::io; use std::io;
use std::ptr::NonNull; use std::ptr::NonNull;
use crate::Wrapper;
use crate::ffi::wl_client; use crate::ffi::wl_client;
pub struct Client { pub struct Client {
@@ -13,3 +14,9 @@ impl Client {
NonNull::new(raw).map(| raw| Self { raw }) NonNull::new(raw).map(| raw| Self { raw })
} }
} }
impl Wrapper for Client {
type T = wl_client;
fn get_raw(&self) -> std::ptr::NonNull<Self::T> {
self.raw
}
}
+7 -4
View File
@@ -3,6 +3,7 @@
use std::{io::Error, ptr::NonNull}; use std::{io::Error, ptr::NonNull};
use std::io::{ErrorKind, Result}; use std::io::{ErrorKind, Result};
use crate::Wrapper;
// pull in the ffi-bindings // pull in the ffi-bindings
use crate::ffi::{wl_display, use crate::ffi::{wl_display,
wl_display_create, wl_display_destroy, wl_display_destroy_clients, wl_display_add_client_created_listener, wl_display_create, wl_display_destroy, wl_display_destroy_clients, wl_display_add_client_created_listener,
@@ -39,10 +40,6 @@ impl<'disp> Display<'disp> {
pub fn get_name(&self) -> &str { pub fn get_name(&self) -> &str {
self.name self.name
} }
pub(crate) fn get_raw_ptr(&self) -> *mut wl_display {
self.raw.as_ptr()
}
pub fn run(&self) -> Result<()> { pub fn run(&self) -> Result<()> {
unsafe { wl_display_run(self.raw.as_ptr()) }; unsafe { wl_display_run(self.raw.as_ptr()) };
Ok(()) Ok(())
@@ -56,3 +53,9 @@ impl<'disp> Drop for Display<'disp> {
} }
} }
} }
impl<'disp> Wrapper for Display<'disp> {
type T = wl_display;
fn get_raw(&self) -> std::ptr::NonNull<Self::T> {
self.raw
}
}
+26 -4
View File
@@ -30,7 +30,7 @@ pub(crate) type wl_protocol_logger_func_t = unsafe extern "C" fn(user_data: *mut
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
pub(crate) type wl_dispatcher_func_t = unsafe extern "C" fn(user_data: *const libc::c_void, target: *mut libc::c_void, opcode: u32, msg: *const wl_message, args: *mut wl_argument) -> i32; pub(crate) type wl_dispatcher_func_t = unsafe extern "C" fn(user_data: *const libc::c_void, target: *mut libc::c_void, opcode: u32, msg: *const wl_message, args: *mut wl_argument) -> i32;
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
pub(crate) type wl_log_func_t = unsafe extern "C" fn(fmt: *const libc::c_char, args: std::ffi::VaList); pub(crate) type wl_log_func_t = unsafe extern "C" fn(fmt: *const libc::c_char, ...);
// ffi data types and struct // ffi data types and struct
const UNIX_PATH_MAX: usize = 108; const UNIX_PATH_MAX: usize = 108;
@@ -189,7 +189,7 @@ pub(crate) struct wl_message {
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
pub(crate) struct wl_interface { pub(crate) struct wl_interface {
name: *const libc::c_char, name: *const libc::c_char,
version: i32, pub version: i32,
method_count: i32, method_count: i32,
method: *const wl_message, method: *const wl_message,
event_count: i32, event_count: i32,
@@ -342,7 +342,29 @@ pub(crate) struct wl_shm_pool {
// public static interfaces // public static interfaces
unsafe extern "C" { unsafe extern "C" {
pub(crate) unsafe static wl_buffer_interface: wl_interface;
pub(crate) unsafe static wl_callback_interface: wl_interface;
pub(crate) unsafe static wl_compositor_interface: wl_interface;
pub(crate) unsafe static wl_data_device_interface: wl_interface;
pub(crate) unsafe static wl_data_device_manager_interface: wl_interface;
pub(crate) unsafe static wl_data_offer_interface: wl_interface;
pub(crate) unsafe static wl_data_source_interface: wl_interface;
pub(crate) unsafe static wl_display_interface: wl_interface;
pub(crate) unsafe static wl_global_interface: wl_interface;
pub(crate) unsafe static wl_keyboard_interface: wl_interface;
pub(crate) unsafe static wl_output_interface: wl_interface; pub(crate) unsafe static wl_output_interface: wl_interface;
pub(crate) unsafe static wl_pointer_interface: wl_interface;
pub(crate) unsafe static wl_region_interface: wl_interface;
pub(crate) unsafe static wl_registry_interface: wl_interface;
pub(crate) unsafe static wl_seat_interface: wl_interface;
pub(crate) unsafe static wl_shell_interface: wl_interface;
pub(crate) unsafe static wl_shell_surface_interface: wl_interface;
pub(crate) unsafe static wl_shm_interface: wl_interface;
pub(crate) unsafe static wl_shm_pool_interface: wl_interface;
pub(crate) unsafe static wl_subcompositor_interface: wl_interface;
pub(crate) unsafe static wl_subsurface_interface: wl_interface;
pub(crate) unsafe static wl_surface_interface: wl_interface;
pub(crate) unsafe static wl_touch_interface: wl_interface;
} }
#[link(name = "wayland-server")] #[link(name = "wayland-server")]
@@ -423,11 +445,11 @@ unsafe extern "C" {
pub(crate) unsafe fn wl_global_remove(global: *mut wl_global); pub(crate) unsafe fn wl_global_remove(global: *mut wl_global);
pub(crate) unsafe fn wl_global_set_user_data(global: *mut wl_global, data: *mut libc::c_void); pub(crate) unsafe fn wl_global_set_user_data(global: *mut wl_global, data: *mut libc::c_void);
pub(crate) unsafe fn wl_list_empty(list: *const wl_list); pub(crate) unsafe fn wl_list_empty(list: *const wl_list)->bool;
pub(crate) unsafe fn wl_list_init(list: *mut wl_list); pub(crate) unsafe fn wl_list_init(list: *mut wl_list);
pub(crate) unsafe fn wl_list_insert(list: *mut wl_list, elm: *mut wl_list); pub(crate) unsafe fn wl_list_insert(list: *mut wl_list, elm: *mut wl_list);
pub(crate) unsafe fn wl_list_insert_list(list: *mut wl_list, other: *mut wl_list); pub(crate) unsafe fn wl_list_insert_list(list: *mut wl_list, other: *mut wl_list);
pub(crate) unsafe fn wl_list_length(list: *const wl_list); pub(crate) unsafe fn wl_list_length(list: *const wl_list) -> usize;
pub(crate) unsafe fn wl_list_remove(elm: *mut wl_list); pub(crate) unsafe fn wl_list_remove(elm: *mut wl_list);
pub(crate) unsafe fn wl_log_set_handler_server(handler: wl_log_func_t); pub(crate) unsafe fn wl_log_set_handler_server(handler: wl_log_func_t);
+15 -6
View File
@@ -2,21 +2,23 @@
use std::io; use std::io;
use std::ptr::NonNull; use std::ptr::NonNull;
use crate::Wrapper;
use crate::client::Client; use crate::client::Client;
use crate::display::Display; use crate::display::Display;
use crate::ffi::{wl_client, wl_display, wl_global, wl_output_interface}; use crate::interface::{Interface,Global as GlobalInterface};
use crate::ffi::{wl_client, wl_global,};
use crate::ffi::wl_global_create; use crate::ffi::wl_global_create;
pub trait GlobalState { pub trait GlobalState {
fn handle_output_bind(&self, client: Client, version: u32, id: u32); fn handle_output_bind(&self, client: &Client, version: u32, id: u32) -> std::io::Result<()>;
} }
unsafe extern "C" fn trampoline_handle_output_bind(client: *mut wl_client, data: *mut libc::c_void, version: u32, id: u32) { unsafe extern "C" fn trampoline_handle_output_bind(client: *mut wl_client, data: *mut libc::c_void, version: u32, id: u32) {
let Some(client) = Client::from_raw(client) else { let Some(client) = Client::from_raw(client) else {
return; return;
}; };
let holder = &*(data as *const GlobalStateHolder); let holder = unsafe { &*(data as *const GlobalStateHolder) };
holder.state.handle_output_bind(client, version, id); let _ = holder.state.handle_output_bind(&client, version, id);
} }
struct GlobalStateHolder { struct GlobalStateHolder {
@@ -35,10 +37,11 @@ impl Global
{ {
let state = Box::new(GlobalStateHolder { state: Box::new(state) }); let state = Box::new(GlobalStateHolder { state: Box::new(state) });
let data = state.as_ref() as *const GlobalStateHolder as *mut libc::c_void; let data = state.as_ref() as *const GlobalStateHolder as *mut libc::c_void;
let interface = Interface::<GlobalInterface>::new();
let ptr = unsafe { let ptr = unsafe {
wl_global_create(disp.get_raw_ptr(), wl_global_create(disp.as_raw_ptr(),
&wl_output_interface, interface.get_raw().as_ptr(),
1, 1,
data, data,
trampoline_handle_output_bind trampoline_handle_output_bind
@@ -50,3 +53,9 @@ impl Global
Ok(Self{raw,state}) Ok(Self{raw,state})
} }
} }
impl Wrapper for Global {
type T = wl_global;
fn get_raw(&self) -> std::ptr::NonNull<Self::T> {
self.raw
}
}
+64
View File
@@ -0,0 +1,64 @@
// SPDX: GPL-2.0-only
use std::io;
use std::marker::PhantomData;
use std::ptr::{addr_of,NonNull};
use crate::Wrapper;
use crate::ffi::{wl_buffer_interface, wl_callback_interface, wl_compositor_interface, wl_data_device_interface, wl_data_device_manager_interface, wl_data_offer_interface, wl_data_source_interface, wl_display_interface, wl_global_interface, wl_interface, wl_keyboard_interface, wl_output_interface, wl_pointer_interface, wl_region_interface, wl_registry_interface, wl_seat_interface, wl_shell_interface, wl_shell_surface_interface, wl_shm_interface, wl_shm_pool_interface, wl_subcompositor_interface, wl_subsurface_interface, wl_surface_interface, wl_touch_interface};
pub trait WaylandInterface {
fn raw_interface() -> NonNull<wl_interface>;
}
macro_rules! define_interface {
($name:ident, $raw:ident) => {
pub struct $name;
impl WaylandInterface for $name {
#[inline]
fn raw_interface() -> NonNull<wl_interface> {
unsafe { NonNull::from(&$raw) }
}
}
};
}
// defining wayland interfaces
define_interface!(Buffer, wl_buffer_interface);
define_interface!(Calback, wl_callback_interface);
define_interface!(Compositor, wl_compositor_interface);
define_interface!(DataDevice, wl_data_device_interface);
define_interface!(DataDeviceManager, wl_data_device_manager_interface);
define_interface!(DataOffer, wl_data_offer_interface);
define_interface!(DataSource, wl_data_source_interface);
define_interface!(Display, wl_display_interface);
define_interface!(Global, wl_global_interface);
define_interface!(Keyboard, wl_keyboard_interface);
define_interface!(Output, wl_output_interface);
define_interface!(Pointer, wl_pointer_interface);
define_interface!(Region, wl_region_interface);
define_interface!(Registry, wl_registry_interface);
define_interface!(Seat, wl_seat_interface);
define_interface!(Shell, wl_shell_interface);
define_interface!(ShellSurface, wl_shell_surface_interface);
define_interface!(Shm, wl_shm_interface);
define_interface!(ShmPool, wl_shm_pool_interface);
define_interface!(Subcompositor, wl_subcompositor_interface);
define_interface!(Subsurface, wl_subsurface_interface);
define_interface!(Surface, wl_surface_interface);
define_interface!(Touch, wl_touch_interface);
pub struct Interface<T: WaylandInterface> {
_marker: PhantomData<T>
}
impl<T: WaylandInterface> Interface<T> {
pub const fn new() -> Self {
Self {
_marker: PhantomData
}
}
pub(crate) fn get_raw(&self) -> NonNull<wl_interface> {
T::raw_interface()
}
}
+12 -2
View File
@@ -1,7 +1,5 @@
// SPDX: GPL-2.0-only // SPDX: GPL-2.0-only
#![feature(c_variadic)]
pub(crate) mod ffi; pub(crate) mod ffi;
// public api // public api
@@ -9,3 +7,15 @@ pub mod array;
pub mod client; pub mod client;
pub mod display; pub mod display;
pub mod global; pub mod global;
pub mod interface;
pub mod list;
pub mod resource;
pub(crate) trait Wrapper {
type T;
fn get_raw(&self) -> std::ptr::NonNull<Self::T>;
fn as_raw_ptr(&self) -> *mut Self::T {
self.get_raw().as_ptr()
}
}
+49
View File
@@ -0,0 +1,49 @@
// SPDX: GPL-2.0-only
use std::io;
use std::ptr::NonNull;
use crate::Wrapper;
use crate::ffi::wl_list;
use crate::ffi::{
wl_list_init, wl_list_insert, wl_list_insert_list,
wl_list_empty, wl_list_length, wl_list_remove,
};
pub struct List {
raw: NonNull<wl_list>,
}
impl List {
pub fn new() -> io::Result<Self> {
let list = std::ptr::null_mut();
unsafe { wl_list_init(list) };
let Some(raw) = NonNull::new(list) else {
return Err(io::Error::last_os_error());
};
Ok(Self { raw })
}
pub fn insert(&self, elm: &List) {
unsafe { wl_list_insert(self.as_raw_ptr(), elm.as_raw_ptr()) };
}
pub fn insert_list(&self, other: &List) {
unsafe { wl_list_insert_list(self.as_raw_ptr(), other.as_raw_ptr()) };
}
pub fn length(&self) -> usize {
let length = unsafe { wl_list_length(self.as_raw_ptr())};
length
}
pub fn empty(&self) -> bool {
let ret: bool = unsafe { wl_list_empty(self.as_raw_ptr()) };
ret
}
pub fn remove(&self, elm: &List) {
unsafe { wl_list_remove(elm.as_raw_ptr()) };
}
}
impl Wrapper for List {
type T = wl_list;
fn get_raw(&self) -> std::ptr::NonNull<Self::T> {
self.raw
}
}
+39
View File
@@ -0,0 +1,39 @@
//SPDX: GPL-2.0-only
use std::io;
use std::ptr::NonNull;
use crate::Wrapper;
use crate::client::Client;
use crate::ffi::{wl_resource, wl_resource_create,wl_interface};
use crate::interface::{WaylandInterface,Interface};
pub struct Resource {
raw: NonNull<wl_resource>,
}
impl Resource {
pub(crate) fn from_raw(raw: *mut wl_resource) -> Option<Self> {
NonNull::new(raw).map(| raw| Self { raw })
}
pub fn new<I: WaylandInterface>(client: &Client, id: u32, interface: &Interface<I>) -> io::Result<Self> {
let ptr = unsafe { wl_resource_create(
client.as_raw_ptr(),
interface.get_raw().as_ptr(),
interface.get_raw().read().version,
id
)};
let Some(raw) = NonNull::new(ptr) else {
return Err(io::Error::last_os_error());
};
Ok(Self { raw })
}
}
impl Wrapper for Resource {
type T = wl_resource;
fn get_raw(&self) -> std::ptr::NonNull<Self::T> {
self.raw
}
}