Compare commits
5
Commits
0cb4086729
..
trunk
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0a73abdbc6 | ||
|
|
61cfcf283f | ||
|
|
aeab2375c8 | ||
|
|
215362f1bb | ||
|
|
e692e4837d |
@@ -2,6 +2,12 @@
|
|||||||
name = "wayland_server"
|
name = "wayland_server"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
license = "GPL-2.0-only"
|
||||||
|
keywords = ["ffi", "wayland"]
|
||||||
|
|
||||||
|
[[example]]
|
||||||
|
name = "simple_compd"
|
||||||
|
path = "examples/simple_compd.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
libc = "*"
|
libc = "*"
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
// SPDX: GPL-2.0-only
|
||||||
|
use std::io;
|
||||||
|
use wayland_server::client::Client;
|
||||||
|
use wayland_server::display::Display;
|
||||||
|
use wayland_server::global::{Global, GlobalState};
|
||||||
|
use wayland_server::interface::{Interface, Output};
|
||||||
|
use wayland_server::resource::Resource;
|
||||||
|
|
||||||
|
struct State {
|
||||||
|
output_interface: Interface<Output>,
|
||||||
|
}
|
||||||
|
impl State {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self { output_interface: Interface::<Output>::new() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl GlobalState for State {
|
||||||
|
fn handle_output_bind(&self, client: &Client, _version: u32, id: u32) -> io::Result<()>{
|
||||||
|
let resource = Resource::new(&client, id, &self.output_interface)?;
|
||||||
|
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() -> io::Result<()> {
|
||||||
|
// Creating a compositor State
|
||||||
|
let state = State::new();
|
||||||
|
|
||||||
|
// create a wayland display
|
||||||
|
let display = Display::new()?;
|
||||||
|
|
||||||
|
// get the global registry
|
||||||
|
let _global = Global::new(&display, state)?;
|
||||||
|
|
||||||
|
println!("Running wayland_display on {}", display.get_name());
|
||||||
|
|
||||||
|
display.run()?;
|
||||||
|
|
||||||
|
// clean-up
|
||||||
|
drop(display);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
|
||||||
use std::io::{Error, ErrorKind, Result};
|
use std::io::{Error, ErrorKind, Result};
|
||||||
use std::ptr::NonNull;
|
use std::ptr::NonNull;
|
||||||
use crate::ffi::wl_array;
|
use crate::ffi::wl_array;
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
|
||||||
|
use std::io;
|
||||||
|
use std::ptr::NonNull;
|
||||||
|
|
||||||
|
use crate::Wrapper;
|
||||||
|
use crate::ffi::wl_client;
|
||||||
|
|
||||||
|
pub struct Client {
|
||||||
|
raw: NonNull<wl_client>
|
||||||
|
}
|
||||||
|
impl Client {
|
||||||
|
pub(crate) fn from_raw(raw: *mut wl_client) -> Option<Self> {
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
|
||||||
|
use std::{io::Error, ptr::NonNull};
|
||||||
|
use std::io::{ErrorKind, Result};
|
||||||
|
|
||||||
|
use crate::Wrapper;
|
||||||
|
// pull in the ffi-bindings
|
||||||
|
use crate::ffi::{wl_display,
|
||||||
|
wl_display_create, wl_display_destroy, wl_display_destroy_clients, wl_display_add_client_created_listener,
|
||||||
|
wl_display_add_destroy_listener, wl_display_add_global, wl_display_add_protocol_logger, wl_display_add_shm_format,
|
||||||
|
wl_display_add_socket, wl_display_add_socket_auto, wl_display_add_socket_fd, wl_display_flush_clients, wl_display_run,
|
||||||
|
wl_display_get_client_list, wl_display_get_destroy_listener, wl_display_get_event_loop, wl_display_get_serial,
|
||||||
|
wl_display_init_shm, wl_display_next_serial, wl_display_remove_global, wl_display_set_global_filter, wl_display_terminate
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct Display<'disp> {
|
||||||
|
raw: NonNull<wl_display>,
|
||||||
|
name: &'disp str,
|
||||||
|
}
|
||||||
|
impl<'disp> Display<'disp> {
|
||||||
|
pub fn new() -> Result<Self> {
|
||||||
|
let ptr = unsafe { wl_display_create() };
|
||||||
|
if ptr.is_null() {
|
||||||
|
return Err(Error::new(ErrorKind::Other, "cannot create wayland display"))
|
||||||
|
}
|
||||||
|
let raw = match NonNull::<wl_display>::new(ptr) {
|
||||||
|
Some(raw) => raw,
|
||||||
|
None => return Err(Error::new(ErrorKind::AddrNotAvailable, "cannot create display")),
|
||||||
|
};
|
||||||
|
|
||||||
|
let name = unsafe { wl_display_add_socket_auto(ptr) };
|
||||||
|
let name = unsafe {
|
||||||
|
let name = std::ffi::CStr::from_ptr(name as *mut i8);
|
||||||
|
name.to_str().expect("cannot get a socket name")
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(Self { raw, name })
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_name(&self) -> &str {
|
||||||
|
self.name
|
||||||
|
}
|
||||||
|
pub fn run(&self) -> Result<()> {
|
||||||
|
unsafe { wl_display_run(self.raw.as_ptr()) };
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<'disp> Drop for Display<'disp> {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
unsafe {
|
||||||
|
wl_display_destroy_clients(self.raw.as_ptr());
|
||||||
|
wl_display_destroy(self.raw.as_ptr());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<'disp> Wrapper for Display<'disp> {
|
||||||
|
type T = wl_display;
|
||||||
|
fn get_raw(&self) -> std::ptr::NonNull<Self::T> {
|
||||||
|
self.raw
|
||||||
|
}
|
||||||
|
}
|
||||||
+47
-18
@@ -1,34 +1,36 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
|
||||||
use std::{ffi::CStr, os::fd::RawFd};
|
use std::{ffi::CStr, os::fd::RawFd};
|
||||||
|
|
||||||
use libc::epoll_event;
|
use libc::epoll_event;
|
||||||
|
|
||||||
// ffi function types
|
// ffi function types
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
pub(crate) type wl_event_loop_fd_func_t = fn(fd: i32, mask: u32, data: *mut libc::c_void) -> i32;
|
pub(crate) type wl_event_loop_fd_func_t = unsafe extern "C" fn(fd: i32, mask: u32, data: *mut libc::c_void) -> i32;
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
pub(crate) type wl_event_loop_timer_func_t = fn(data: *mut libc::c_void) -> i32;
|
pub(crate) type wl_event_loop_timer_func_t = unsafe extern "C" fn(data: *mut libc::c_void) -> i32;
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
pub(crate) type wl_event_loop_signal_func_t = fn(signal_number: i32, data: *mut libc::c_void) -> i32;
|
pub(crate) type wl_event_loop_signal_func_t = unsafe extern "C" fn(signal_number: i32, data: *mut libc::c_void) -> i32;
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
pub(crate) type wl_event_loop_idle_func_t = fn(data: *mut libc::c_void);
|
pub(crate) type wl_event_loop_idle_func_t = unsafe extern "C" fn(data: *mut libc::c_void);
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
pub(crate) type wl_notify_func_t = fn(listener: *mut wl_listener, data: *mut libc::c_void);
|
pub(crate) type wl_notify_func_t = unsafe extern "C" fn(listener: *mut wl_listener, data: *mut libc::c_void);
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
pub(crate) type wl_global_bind_func_t = fn(client: *mut wl_client, data: *mut libc::c_void, version: u32, id: u32);
|
pub(crate) type wl_global_bind_func_t = unsafe extern "C" fn(client: *mut wl_client, data: *mut libc::c_void, version: u32, id: u32);
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
pub(crate) type wl_display_global_filter_func_t = fn(client: *const wl_client, global: *const wl_global, data: *mut libc::c_void) -> bool;
|
pub(crate) type wl_display_global_filter_func_t = unsafe extern "C" fn(client: *const wl_client, global: *const wl_global, data: *mut libc::c_void) -> bool;
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
pub(crate) type wl_client_for_each_resource_iterator_func_t = fn(resource: *mut wl_resource, user_data: *mut libc::c_void) -> wl_iterator_result;
|
pub(crate) type wl_client_for_each_resource_iterator_func_t = unsafe extern "C" fn(resource: *mut wl_resource, user_data: *mut libc::c_void) -> wl_iterator_result;
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
pub(crate) type wl_user_data_destroy_func_t = fn(data: *mut libc::c_void);
|
pub(crate) type wl_user_data_destroy_func_t = unsafe extern "C" fn(data: *mut libc::c_void);
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
pub(crate) type wl_resource_destroy_func_t = fn(resource: *mut wl_resource);
|
pub(crate) type wl_resource_destroy_func_t = unsafe extern "C" fn(resource: *mut wl_resource);
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
pub(crate) type wl_protocol_logger_func_t = fn(user_data: *mut libc::c_void, direction: wl_protocol_logger_type, message: *const wl_protocol_logger_message);
|
pub(crate) type wl_protocol_logger_func_t = unsafe extern "C" fn(user_data: *mut libc::c_void, direction: wl_protocol_logger_type, message: *const wl_protocol_logger_message);
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
pub(crate) type wl_dispatcher_func_t = 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 = 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;
|
||||||
@@ -187,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,
|
||||||
@@ -338,6 +340,33 @@ pub(crate) struct wl_shm_pool {
|
|||||||
sigbus_is_impossible: bool
|
sigbus_is_impossible: bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// public static interfaces
|
||||||
|
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_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")]
|
||||||
unsafe extern "C" {
|
unsafe extern "C" {
|
||||||
pub(crate) unsafe fn wl_array_add(array: *mut wl_array, size: usize) -> *mut libc::c_void;
|
pub(crate) unsafe fn wl_array_add(array: *mut wl_array, size: usize) -> *mut libc::c_void;
|
||||||
@@ -371,7 +400,7 @@ unsafe extern "C" {
|
|||||||
pub(crate) unsafe fn wl_display_add_global();
|
pub(crate) unsafe fn wl_display_add_global();
|
||||||
pub(crate) unsafe fn wl_display_add_protocol_logger(disp: *mut wl_display, func: wl_protocol_logger_func_t, user_data: *mut libc::c_void) -> *mut wl_protocol_logger;
|
pub(crate) unsafe fn wl_display_add_protocol_logger(disp: *mut wl_display, func: wl_protocol_logger_func_t, user_data: *mut libc::c_void) -> *mut wl_protocol_logger;
|
||||||
pub(crate) unsafe fn wl_display_add_shm_format(disp: *mut wl_display, format: u32) -> u32;
|
pub(crate) unsafe fn wl_display_add_shm_format(disp: *mut wl_display, format: u32) -> u32;
|
||||||
pub(crate) unsafe fn wl_display_add_socket_auto(disp: *mut wl_display) -> std::ffi::CStr;
|
pub(crate) unsafe fn wl_display_add_socket_auto(disp: *mut wl_display) -> *mut u8;
|
||||||
pub(crate) unsafe fn wl_display_add_socket(disp: *mut wl_display, name: *const libc::c_char);
|
pub(crate) unsafe fn wl_display_add_socket(disp: *mut wl_display, name: *const libc::c_char);
|
||||||
pub(crate) unsafe fn wl_display_add_socket_fd(disp: *mut wl_display, sock_fd: RawFd) -> i32;
|
pub(crate) unsafe fn wl_display_add_socket_fd(disp: *mut wl_display, sock_fd: RawFd) -> i32;
|
||||||
pub(crate) unsafe fn wl_display_create() -> *mut wl_display;
|
pub(crate) unsafe fn wl_display_create() -> *mut wl_display;
|
||||||
@@ -406,7 +435,7 @@ unsafe extern "C" {
|
|||||||
pub(crate) unsafe fn wl_event_source_remove(source: *mut wl_event_source) -> i32;
|
pub(crate) unsafe fn wl_event_source_remove(source: *mut wl_event_source) -> i32;
|
||||||
pub(crate) unsafe fn wl_event_source_timer_update(source: *mut wl_event_source, ms_delay: i32) -> i32;
|
pub(crate) unsafe fn wl_event_source_timer_update(source: *mut wl_event_source, ms_delay: i32) -> i32;
|
||||||
|
|
||||||
pub(crate) unsafe fn wl_global_create(disp: *mut wl_display, interface: *const wl_interface) -> *mut wl_global;
|
pub(crate) unsafe fn wl_global_create(disp: *mut wl_display, interface: *const wl_interface, version: i32, data: *mut libc::c_void, bind: wl_global_bind_func_t) -> *mut wl_global;
|
||||||
pub(crate) unsafe fn wl_global_destroy(global: *mut wl_global);
|
pub(crate) unsafe fn wl_global_destroy(global: *mut wl_global);
|
||||||
pub(crate) unsafe fn wl_global_get_display(global: *const wl_global) -> *mut wl_display;
|
pub(crate) unsafe fn wl_global_get_display(global: *const wl_global) -> *mut wl_display;
|
||||||
pub(crate) unsafe fn wl_global_get_interface(global: *const wl_global) -> *const wl_interface;
|
pub(crate) unsafe fn wl_global_get_interface(global: *const wl_global) -> *const wl_interface;
|
||||||
@@ -416,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);
|
||||||
|
|||||||
@@ -0,0 +1,61 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
|
||||||
|
use std::io;
|
||||||
|
use std::ptr::NonNull;
|
||||||
|
use crate::Wrapper;
|
||||||
|
use crate::client::Client;
|
||||||
|
use crate::display::Display;
|
||||||
|
use crate::interface::{Interface,Global as GlobalInterface};
|
||||||
|
use crate::ffi::{wl_client, wl_global,};
|
||||||
|
use crate::ffi::wl_global_create;
|
||||||
|
|
||||||
|
pub trait GlobalState {
|
||||||
|
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) {
|
||||||
|
let Some(client) = Client::from_raw(client) else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
let holder = unsafe { &*(data as *const GlobalStateHolder) };
|
||||||
|
let _ = holder.state.handle_output_bind(&client, version, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct GlobalStateHolder {
|
||||||
|
state: Box<dyn GlobalState>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Global {
|
||||||
|
raw: NonNull<wl_global>,
|
||||||
|
state: Box<GlobalStateHolder>,
|
||||||
|
}
|
||||||
|
impl Global
|
||||||
|
{
|
||||||
|
pub fn new<S>(disp: &Display, state: S) -> io::Result<Self>
|
||||||
|
where
|
||||||
|
S: GlobalState + 'static,
|
||||||
|
{
|
||||||
|
let state = Box::new(GlobalStateHolder { state: Box::new(state) });
|
||||||
|
let data = state.as_ref() as *const GlobalStateHolder as *mut libc::c_void;
|
||||||
|
let interface = Interface::<GlobalInterface>::new();
|
||||||
|
|
||||||
|
let ptr = unsafe {
|
||||||
|
wl_global_create(disp.as_raw_ptr(),
|
||||||
|
interface.get_raw().as_ptr(),
|
||||||
|
1,
|
||||||
|
data,
|
||||||
|
trampoline_handle_output_bind
|
||||||
|
)
|
||||||
|
};
|
||||||
|
let raw = NonNull::new(ptr)
|
||||||
|
.ok_or_else(||io::Error::last_os_error())?;
|
||||||
|
|
||||||
|
Ok(Self{raw,state})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Wrapper for Global {
|
||||||
|
type T = wl_global;
|
||||||
|
fn get_raw(&self) -> std::ptr::NonNull<Self::T> {
|
||||||
|
self.raw
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
// SPDX-License-Identifier: 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()
|
||||||
|
}
|
||||||
|
}
|
||||||
+16
-1
@@ -1,6 +1,21 @@
|
|||||||
#![feature(c_variadic)]
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
|
||||||
pub(crate) mod ffi;
|
pub(crate) mod ffi;
|
||||||
|
|
||||||
// public api
|
// public api
|
||||||
pub mod array;
|
pub mod array;
|
||||||
|
pub mod client;
|
||||||
|
pub mod display;
|
||||||
|
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
@@ -0,0 +1,49 @@
|
|||||||
|
// SPDX-License-Identifier: 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
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
// SPDX-License-Identifier: 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
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user