diff --git a/examples/simple_compd.rs b/examples/simple_compd.rs new file mode 100644 index 0000000..33a7462 --- /dev/null +++ b/examples/simple_compd.rs @@ -0,0 +1,15 @@ +use std::io; +use wayland_server::display::Display; + +fn main() -> io::Result<()> { + let display = Display::new()?; + + println!("Running wayland_display on {}", display.get_name()); + + display.run()?; + + // clean-up + drop(display); + + Ok(()) +} \ No newline at end of file diff --git a/src/display.rs b/src/display.rs index df3cb63..16afab3 100644 --- a/src/display.rs +++ b/src/display.rs @@ -10,22 +10,44 @@ use crate::ffi::{wl_display, wl_display_init_shm, wl_display_next_serial, wl_display_remove_global, wl_display_set_global_filter, wl_display_terminate }; -pub struct Display { +pub struct Display<'disp> { raw: NonNull, + name: &'disp str, } -impl Display { +impl<'disp> Display<'disp> { pub fn new() -> Result { let ptr = unsafe { wl_display_create() }; + if ptr.is_null() { + return Err(Error::new(ErrorKind::Other, "cannot create wayland display")) + } let raw = match NonNull::::new(ptr) { Some(raw) => raw, None => return Err(Error::new(ErrorKind::AddrNotAvailable, "cannot create display")), }; - Ok(Self { raw }) + 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 Drop for Display { +impl<'disp> Drop for Display<'disp> { fn drop(&mut self) { - unsafe { wl_display_destroy(self.raw.as_ptr()) }; + unsafe { + wl_display_destroy_clients(self.raw.as_ptr()); + wl_display_destroy(self.raw.as_ptr()); + } } } \ No newline at end of file diff --git a/src/ffi.rs b/src/ffi.rs index b1268aa..a4c1ee9 100644 --- a/src/ffi.rs +++ b/src/ffi.rs @@ -4,31 +4,31 @@ use libc::epoll_event; // ffi function 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)] -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)] -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)] -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)] -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)] -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)] -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)] -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)] -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)] -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)] -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)] -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)] -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, args: std::ffi::VaList); // ffi data types and struct const UNIX_PATH_MAX: usize = 108; @@ -371,7 +371,7 @@ unsafe extern "C" { 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_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_fd(disp: *mut wl_display, sock_fd: RawFd) -> i32; pub(crate) unsafe fn wl_display_create() -> *mut wl_display; diff --git a/src/lib.rs b/src/lib.rs index 3b1a4d1..39aaded 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,3 +4,4 @@ pub(crate) mod ffi; // public api pub mod array; +pub mod display; \ No newline at end of file