wayland-sys-0.29.5/.cargo_vcs_info.json0000644000000001510000000000100134010ustar { "git": { "sha1": "8f4127a21d65cf10189ff0e3b78983e9686dd288" }, "path_in_vcs": "wayland-sys" }wayland-sys-0.29.5/Cargo.toml0000644000000027220000000000100114050ustar # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies. # # If you are reading this file be aware that the original Cargo.toml # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. [package] edition = "2018" name = "wayland-sys" version = "0.29.5" authors = ["Victor Berger "] description = "FFI bindings to the various libwayland-*.so libraries. You should only need this crate if you are working on custom wayland protocol extensions. Look at the crate wayland-client for usable bindings." documentation = "https://smithay.github.io/wayland-rs/wayland_sys/" readme = "README.md" categories = ["external-ffi-bindings"] license = "MIT" repository = "https://github.com/smithay/wayland-rs" [package.metadata.docs.rs] all-features = true [dependencies.dlib] version = "0.5" optional = true [dependencies.lazy_static] version = "1.0.2" optional = true [dependencies.libc] version = "0.2" optional = true [dependencies.memoffset] version = "0.6.4" optional = true [build-dependencies.pkg-config] version = "0.3.7" [features] client = ["dlib"] cursor = ["client"] dlopen = [ "dlib", "lazy_static", ] egl = ["client"] server = [ "libc", "dlib", "memoffset", ] wayland-sys-0.29.5/Cargo.toml.orig000064400000000000000000000017111046102023000150630ustar 00000000000000[package] name = "wayland-sys" version = "0.29.5" repository = "https://github.com/smithay/wayland-rs" documentation = "https://smithay.github.io/wayland-rs/wayland_sys/" authors = ["Victor Berger "] description = "FFI bindings to the various libwayland-*.so libraries. You should only need this crate if you are working on custom wayland protocol extensions. Look at the crate wayland-client for usable bindings." license = "MIT" categories = ["external-ffi-bindings"] edition = "2018" readme = "README.md" [dependencies] dlib = { version = "0.5", optional = true } libc = { version = "0.2", optional = true } lazy_static = { version = "1.0.2", optional = true } memoffset = { version = "0.6.4", optional = true } [build-dependencies] pkg-config = "0.3.7" [features] dlopen = ["dlib", "lazy_static"] client = ["dlib"] cursor = ["client"] egl = ["client"] server = ["libc", "dlib", "memoffset"] [package.metadata.docs.rs] all-features = true wayland-sys-0.29.5/LICENSE.txt000064400000000000000000000020401046102023000140130ustar 00000000000000Copyright (c) 2015 Victor Berger Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.wayland-sys-0.29.5/README.md000064400000000000000000000025651046102023000134630ustar 00000000000000[![crates.io](https://img.shields.io/crates/v/wayland-sys.svg)](https://crates.io/crates/wayland-sys) [![docs.rs](https://docs.rs/wayland-sys/badge.svg)](https://docs.rs/wayland-sys) [![Continuous Integration](https://github.com/Smithay/wayland-rs/workflows/Continuous%20Integration/badge.svg)](https://github.com/Smithay/wayland-rs/actions?query=workflow%3A%22Continuous+Integration%22) [![codecov](https://codecov.io/gh/Smithay/wayland-rs/branch/master/graph/badge.svg)](https://codecov.io/gh/Smithay/wayland-rs) # wayland-sys This crate provides raw bindings to the system `libwayland-*.so` libraries. If you are looking for a Rust API over the Wayland protocol, see the `wayland-client` or `wayland-server` crates instead. Bindings to the different libraries are enabled by the different cargo features: - `client` for bindings to `libwayland-client.so` - `server` for bindings to `libwayland-server.so` - `cursor` for bindings to `libwayland-cursor.so` - `egl` for bindings to `libwayland-egl.so` Furthermore, the `dlopen` cargo feature will switch the library to a mode where, instead of directly linking to these system libraries, it'll instead try to open them at runtime. This allows to create binaries that can gracefully handle being run on non-Wayland environments. In that case the crate should be used with its provided `ffi_dispatch!()` macro, to support both modes seamlessly.wayland-sys-0.29.5/build.rs000064400000000000000000000011771046102023000136470ustar 00000000000000use pkg_config::Config; fn main() { if std::env::var_os("CARGO_FEATURE_DLOPEN").is_some() { // Do not link to anything return; } if std::env::var_os("CARGO_FEATURE_CLIENT").is_some() { Config::new().probe("wayland-client").unwrap(); } if std::env::var_os("CARGO_FEATURE_CURSOR").is_some() { Config::new().probe("wayland-cursor").unwrap(); } if std::env::var_os("CARGO_FEATURE_EGL").is_some() { Config::new().probe("wayland-egl").unwrap(); } if std::env::var_os("CARGO_FEATURE_SERVER").is_some() { Config::new().probe("wayland-server").unwrap(); } } wayland-sys-0.29.5/src/client.rs000064400000000000000000000130431046102023000146100ustar 00000000000000//! Bindings to the client library `libwayland-client.so` //! //! The generated handle is named `WAYLAND_CLIENT_HANDLE` #![cfg_attr(rustfmt, rustfmt_skip)] #[cfg(feature = "client")] use super::common::*; #[cfg(feature = "client")] use std::os::raw::{c_char, c_int, c_void}; pub enum wl_proxy {} pub enum wl_display {} pub enum wl_event_queue {} #[cfg(feature = "client")] external_library!(WaylandClient, "wayland-client", functions: // display creation and destruction fn wl_display_connect_to_fd(c_int) -> *mut wl_display, fn wl_display_connect(*const c_char) -> *mut wl_display, fn wl_display_disconnect(*mut wl_display) -> (), fn wl_display_get_fd(*mut wl_display) -> c_int, // display events handling fn wl_display_roundtrip(*mut wl_display) -> c_int, fn wl_display_read_events(*mut wl_display) -> c_int, fn wl_display_prepare_read(*mut wl_display) -> c_int, fn wl_display_cancel_read(*mut wl_display) -> (), fn wl_display_dispatch(*mut wl_display) -> c_int, fn wl_display_dispatch_pending(*mut wl_display) -> c_int, // error handling fn wl_display_get_error(*mut wl_display) -> c_int, fn wl_display_get_protocol_error(*mut wl_display, *mut *mut wl_interface, *mut u32) -> u32, // requests handling fn wl_display_flush(*mut wl_display) -> c_int, // event queues fn wl_event_queue_destroy(*mut wl_event_queue) -> (), fn wl_display_create_queue(*mut wl_display) -> *mut wl_event_queue, fn wl_display_roundtrip_queue(*mut wl_display, *mut wl_event_queue) -> c_int, fn wl_display_prepare_read_queue(*mut wl_display, *mut wl_event_queue) -> c_int, fn wl_display_dispatch_queue(*mut wl_display, *mut wl_event_queue) -> c_int, fn wl_display_dispatch_queue_pending(*mut wl_display, *mut wl_event_queue) -> c_int, // proxys fn wl_proxy_create(*mut wl_proxy, *const wl_interface) -> *mut wl_proxy, fn wl_proxy_destroy(*mut wl_proxy) -> (), fn wl_proxy_add_listener(*mut wl_proxy, *mut extern fn(), *mut c_void) -> c_int, fn wl_proxy_get_listener(*mut wl_proxy) -> *const c_void, fn wl_proxy_add_dispatcher(*mut wl_proxy, wl_dispatcher_func_t, *const c_void, *mut c_void) -> c_int, fn wl_proxy_marshal_array_constructor(*mut wl_proxy, u32, *mut wl_argument, *const wl_interface) -> *mut wl_proxy, fn wl_proxy_marshal_array_constructor_versioned(*mut wl_proxy, u32, *mut wl_argument, *const wl_interface, u32) -> *mut wl_proxy, fn wl_proxy_marshal_array(*mut wl_proxy, u32, *mut wl_argument ) -> (), fn wl_proxy_set_user_data(*mut wl_proxy, *mut c_void) -> (), fn wl_proxy_get_user_data(*mut wl_proxy) -> *mut c_void, fn wl_proxy_get_id(*mut wl_proxy) -> u32, fn wl_proxy_get_class(*mut wl_proxy) -> *const c_char, fn wl_proxy_set_queue(*mut wl_proxy, *mut wl_event_queue) -> (), fn wl_proxy_get_version(*mut wl_proxy) -> u32, fn wl_proxy_create_wrapper(*mut wl_proxy) -> *mut wl_proxy, fn wl_proxy_wrapper_destroy(*mut wl_proxy) -> (), // log fn wl_log_set_handler_client(wl_log_func_t) -> (), // lists fn wl_list_init(*mut wl_list) -> (), fn wl_list_insert(*mut wl_list, *mut wl_list) -> (), fn wl_list_remove(*mut wl_list) -> (), fn wl_list_length(*const wl_list) -> c_int, fn wl_list_empty(*const wl_list) -> c_int, fn wl_list_insert_list(*mut wl_list,*mut wl_list) -> (), // arrays fn wl_array_init(*mut wl_array) -> (), fn wl_array_release(*mut wl_array) -> (), fn wl_array_add(*mut wl_array,usize) -> (), fn wl_array_copy(*mut wl_array, *mut wl_array) -> (), varargs: fn wl_proxy_marshal_constructor(*mut wl_proxy, u32, *const wl_interface) -> *mut wl_proxy, fn wl_proxy_marshal_constructor_versioned(*mut wl_proxy, u32, *const wl_interface, u32) -> *mut wl_proxy, fn wl_proxy_marshal(*mut wl_proxy, u32) -> (), ); #[cfg(all(feature = "client", feature = "dlopen"))] lazy_static::lazy_static!( pub static ref WAYLAND_CLIENT_OPTION: Option = { // This is a workaround for Ubuntu 17.04, which doesn't have a bare symlink // for libwayland-client.so but does have it with the version numbers for // whatever reason. // // We could do some trickery with str slices but that is more trouble // than its worth let versions = ["libwayland-client.so", "libwayland-client.so.0"]; for ver in &versions { match unsafe { WaylandClient::open(ver) } { Ok(h) => return Some(h), Err(::dlib::DlError::CantOpen(_)) => continue, Err(::dlib::DlError::MissingSymbol(s)) => { if ::std::env::var_os("WAYLAND_RS_DEBUG").is_some() { // only print debug messages if WAYLAND_RS_DEBUG is set eprintln!("[wayland-client] Found library {} cannot be used: symbol {} is missing.", ver, s); } return None; } } } None }; pub static ref WAYLAND_CLIENT_HANDLE: &'static WaylandClient = { WAYLAND_CLIENT_OPTION.as_ref().expect("Library libwayland-client.so could not be loaded.") }; ); #[cfg(all(feature = "client", not(feature = "dlopen")))] pub fn is_lib_available() -> bool { true } #[cfg(all(feature = "client", feature = "dlopen"))] pub fn is_lib_available() -> bool { WAYLAND_CLIENT_OPTION.is_some() } wayland-sys-0.29.5/src/common.rs000064400000000000000000000030071046102023000146210ustar 00000000000000//! Various types and functions that are used by both the client and the server //! libraries. use std::os::raw::{c_char, c_int, c_void}; use std::os::unix::io::RawFd; #[repr(C)] pub struct wl_message { pub name: *const c_char, pub signature: *const c_char, pub types: *const *const wl_interface, } #[repr(C)] pub struct wl_interface { pub name: *const c_char, pub version: c_int, pub request_count: c_int, pub requests: *const wl_message, pub event_count: c_int, pub events: *const wl_message, } #[repr(C)] pub struct wl_list { pub prev: *mut wl_list, pub next: *mut wl_list, } #[repr(C)] pub struct wl_array { pub size: usize, pub alloc: usize, pub data: *mut c_void, } pub type wl_fixed_t = i32; pub fn wl_fixed_to_double(f: wl_fixed_t) -> f64 { f64::from(f) / 256. } pub fn wl_fixed_from_double(d: f64) -> wl_fixed_t { (d * 256.) as i32 } pub fn wl_fixed_to_int(f: wl_fixed_t) -> i32 { f / 256 } pub fn wl_fixed_from_int(i: i32) -> wl_fixed_t { i * 256 } // must be the appropriate size // can contain i32, u32 and pointers #[repr(C)] pub union wl_argument { pub i: i32, pub u: u32, pub f: wl_fixed_t, pub s: *const c_char, pub o: *const c_void, pub n: u32, pub a: *const wl_array, pub h: RawFd, } pub type wl_dispatcher_func_t = unsafe extern "C" fn( *const c_void, *mut c_void, u32, *const wl_message, *const wl_argument, ) -> c_int; pub type wl_log_func_t = unsafe extern "C" fn(*const c_char, ...); wayland-sys-0.29.5/src/cursor.rs000064400000000000000000000052561046102023000146560ustar 00000000000000//! Bindings to the `wayland-cursor.so` library //! //! The created handle is named `WAYLAND_CURSOR_HANDLE`. use crate::client::wl_proxy; use std::os::raw::{c_char, c_int, c_uint}; pub enum wl_cursor_theme {} #[repr(C)] pub struct wl_cursor_image { /// actual width pub width: u32, /// actual height pub height: u32, /// hot spot x (must be inside image) pub hotspot_x: u32, /// hot spot y (must be inside image) pub hotspot_y: u32, /// animation delay to next frame pub delay: u32, } #[repr(C)] pub struct wl_cursor { pub image_count: c_uint, pub images: *mut *mut wl_cursor_image, pub name: *mut c_char, } external_library!(WaylandCursor, "wayland-cursor", functions: fn wl_cursor_theme_load(*const c_char, c_int, *mut wl_proxy) -> *mut wl_cursor_theme, fn wl_cursor_theme_destroy(*mut wl_cursor_theme) -> (), fn wl_cursor_theme_get_cursor(*mut wl_cursor_theme, *const c_char) -> *mut wl_cursor, fn wl_cursor_image_get_buffer(*mut wl_cursor_image) -> *mut wl_proxy, fn wl_cursor_frame(*mut wl_cursor, u32) -> c_int, fn wl_cursor_frame_and_duration(*mut wl_cursor, u32, *mut u32) -> c_int, ); #[cfg(feature = "dlopen")] lazy_static::lazy_static!( pub static ref WAYLAND_CURSOR_OPTION: Option = { // This is a workaround for Ubuntu 17.04, which doesn't have a bare symlink // for libwayland-client.so but does have it with the version numbers for // whatever reason. // // We could do some trickery with str slices but that is more trouble // than its worth let versions = ["libwayland-cursor.so", "libwayland-cursor.so.0"]; for ver in &versions { match unsafe { WaylandCursor::open(ver) } { Ok(h) => return Some(h), Err(::dlib::DlError::CantOpen(_)) => continue, Err(::dlib::DlError::MissingSymbol(s)) => { if ::std::env::var_os("WAYLAND_RS_DEBUG").is_some() { // only print debug messages if WAYLAND_RS_DEBUG is set eprintln!("[wayland-client] Found library {} cannot be used: symbol {} is missing.", ver, s); } return None; } } } None }; pub static ref WAYLAND_CURSOR_HANDLE: &'static WaylandCursor = { WAYLAND_CURSOR_OPTION.as_ref().expect("Library libwayland-cursor.so could not be loaded.") }; ); #[cfg(not(feature = "dlopen"))] pub fn is_lib_available() -> bool { true } #[cfg(feature = "dlopen")] pub fn is_lib_available() -> bool { WAYLAND_CURSOR_OPTION.is_some() } wayland-sys-0.29.5/src/egl.rs000064400000000000000000000041521046102023000141020ustar 00000000000000//! Bindings to the EGL library `libwayland-egl.so` //! //! This lib allows to create EGL surfaces out of wayland surfaces. //! //! The created handle is named `WAYLAND_EGl_HANDLE`. use crate::client::wl_proxy; use std::os::raw::c_int; pub enum wl_egl_window {} external_library!(WaylandEgl, "wayland-egl", functions: fn wl_egl_window_create(*mut wl_proxy, c_int, c_int) -> *mut wl_egl_window, fn wl_egl_window_destroy(*mut wl_egl_window) -> (), fn wl_egl_window_resize(*mut wl_egl_window, c_int, c_int, c_int, c_int) -> (), fn wl_egl_window_get_attached_size(*mut wl_egl_window, *mut c_int, *mut c_int) -> (), ); #[cfg(feature = "dlopen")] lazy_static::lazy_static!( pub static ref WAYLAND_EGL_OPTION: Option = { // This is a workaround for Ubuntu 17.04, which doesn't have a bare symlink // for libwayland-client.so but does have it with the version numbers for // whatever reason. // // We could do some trickery with str slices but that is more trouble // than its worth let versions = ["libwayland-egl.so", "libwayland-egl.so.1"]; for ver in &versions { match unsafe { WaylandEgl::open(ver) } { Ok(h) => return Some(h), Err(::dlib::DlError::CantOpen(_)) => continue, Err(::dlib::DlError::MissingSymbol(s)) => { if ::std::env::var_os("WAYLAND_RS_DEBUG").is_some() { // only print debug messages if WAYLAND_RS_DEBUG is set eprintln!("[wayland-client] Found library {} cannot be used: symbol {} is missing.", ver, s); } return None; } } } None }; pub static ref WAYLAND_EGL_HANDLE: &'static WaylandEgl = { WAYLAND_EGL_OPTION.as_ref().expect("Library libwayland-egl.so could not be loaded.") }; ); #[cfg(not(feature = "dlopen"))] pub fn is_lib_available() -> bool { true } #[cfg(feature = "dlopen")] pub fn is_lib_available() -> bool { WAYLAND_EGL_OPTION.is_some() } wayland-sys-0.29.5/src/lib.rs000064400000000000000000000047141046102023000141050ustar 00000000000000//! FFI bindings to the wayland system libraries. //! //! The names exported by this crate should *not* be used directly, but through //! the `ffi_dispatch` macro, like this: //! //! ```ignore //! ffi_dispatch!(HANDLE_NAME, func_name, arg1, arg2, arg3); //! ``` //! //! Where `HANDLE_NAME` is the name of the handle generated if the cargo feature `dlopen` is on. //! //! For this to work, you must ensure every needed symbol is in scope (aka the static handle //! if `dlopen` is on, the extern function if not). The easiest way to do this is to glob import //! the appropriate module. For example: //! //! ```ignore //! #[macro_use] extern crate wayland_sys; //! //! use wayland_sys::client::*; //! //! let display_ptr = unsafe { //! ffi_dispatch!(WAYLAND_CLIENT_HANDLE, wl_display_connect, ::std::ptr::null()) //! }; //! ``` //! //! Each module except `common` corresponds to a system library. They all define a function named //! `is_lib_available()` which returns whether the library could be loaded. They always return true //! if the feature `dlopen` is absent, as we link against the library directly in that case. #![allow(non_camel_case_types)] // If compiling with neither the `client` or `server` feature (non-sensical but // it's what happens when running `cargo test --all` from the workspace root), // dlib isn't actually used. This is not an issue, so don't warn about it. #[allow(unused_imports)] #[cfg(any(feature = "client", feature = "server"))] #[macro_use] extern crate dlib; /// Magic static for wayland objects managed by wayland-client or wayland-server /// /// This static serves no purpose other than existing at a stable address. /// /// It is used internally by wayland-client, wayland-server and wayland-scanner to ensure safety /// regarding wayland objects that are created by other libraries. pub static RUST_MANAGED: u8 = 42; pub mod common; pub mod client; pub mod server; #[cfg(all(feature = "egl", feature = "client"))] pub mod egl; #[cfg(all(feature = "cursor", feature = "client"))] pub mod cursor; #[cfg(feature = "server")] pub use libc::{gid_t, pid_t, uid_t}; // Small hack while #[macro_reexport] is not stable #[cfg(feature = "dlopen")] #[macro_export] macro_rules! ffi_dispatch( ($handle: ident, $func: ident, $($arg: expr),*) => ( ($handle.$func)($($arg),*) ) ); #[cfg(not(feature = "dlopen"))] #[macro_export] macro_rules! ffi_dispatch( ($handle: ident, $func: ident, $($arg: expr),*) => ( $func($($arg),*) ) ); wayland-sys-0.29.5/src/server.rs000064400000000000000000000320231046102023000146370ustar 00000000000000//! Bindings to the client library `libwayland-server.so` //! //! The generated handle is named `WAYLAND_SERVER_HANDLE` #![cfg_attr(rustfmt, rustfmt_skip)] use super::common::*; #[cfg(feature = "server")] use libc::{gid_t, pid_t, uid_t}; #[cfg(feature = "server")] use std::os::raw::c_char; use std::os::raw::{c_int, c_void}; pub enum wl_client {} pub enum wl_display {} pub enum wl_event_loop {} pub enum wl_event_source {} pub enum wl_global {} pub enum wl_resource {} pub enum wl_shm_buffer {} pub type wl_event_loop_fd_func_t = unsafe extern "C" fn(c_int, u32, *mut c_void) -> c_int; pub type wl_event_loop_timer_func_t = unsafe extern "C" fn(*mut c_void) -> c_int; pub type wl_event_loop_signal_func_t = unsafe extern "C" fn(c_int, *mut c_void) -> c_int; pub type wl_event_loop_idle_func_t = unsafe extern "C" fn(*mut c_void) -> (); pub type wl_global_bind_func_t = unsafe extern "C" fn(*mut wl_client, *mut c_void, u32, u32) -> (); pub type wl_notify_func_t = unsafe extern "C" fn(*mut wl_listener, *mut c_void) -> (); pub type wl_resource_destroy_func_t = unsafe extern "C" fn(*mut wl_resource) -> (); pub type wl_display_global_filter_func_t = unsafe extern "C" fn(*const wl_client, *const wl_global, *mut c_void) -> bool; #[repr(C)] pub struct wl_listener { pub link: wl_list, pub notify: wl_notify_func_t, } #[repr(C)] pub struct wl_signal { pub listener_list: wl_list, } #[cfg(feature = "server")] external_library!(WaylandServer, "wayland-server", functions: // wl_client fn wl_client_flush(*mut wl_client) -> (), fn wl_client_destroy(*mut wl_client) -> (), fn wl_client_get_display(*mut wl_client) -> *mut wl_display, fn wl_client_get_credentials(*mut wl_client, *mut pid_t, *mut uid_t, *mut gid_t) -> (), fn wl_client_get_object(*mut wl_client, u32) -> *mut wl_resource, fn wl_client_add_destroy_listener(*mut wl_client, *mut wl_listener) -> (), fn wl_client_get_destroy_listener(*mut wl_client, wl_notify_func_t) -> *mut wl_listener, fn wl_client_post_no_memory(*mut wl_client) -> (), fn wl_resource_create(*mut wl_client, *const wl_interface, c_int, u32) -> *mut wl_resource, // wl_display fn wl_client_create(*mut wl_display, c_int) -> *mut wl_client, fn wl_display_create() -> *mut wl_display, fn wl_display_destroy(*mut wl_display) -> (), fn wl_display_destroy_clients(*mut wl_display) -> (), fn wl_display_get_serial(*mut wl_display) -> u32, fn wl_display_next_serial(*mut wl_display) -> u32, fn wl_display_add_socket(*mut wl_display, *const c_char) -> c_int, fn wl_display_add_socket_auto(*mut wl_display) -> *const c_char, fn wl_display_add_socket_fd(*mut wl_display, c_int) -> c_int, fn wl_display_add_shm_format(*mut wl_display, u32) -> *mut u32, fn wl_display_get_event_loop(*mut wl_display) -> *mut wl_event_loop, fn wl_display_terminate(*mut wl_display) -> (), fn wl_display_run(*mut wl_display) -> (), fn wl_display_flush_clients(*mut wl_display) -> (), fn wl_display_add_destroy_listener(*mut wl_display, *mut wl_listener) -> (), fn wl_display_get_destroy_listener(*mut wl_display, wl_notify_func_t) -> *mut wl_listener, fn wl_global_create(*mut wl_display, *const wl_interface, c_int, *mut c_void, wl_global_bind_func_t) -> *mut wl_global, fn wl_display_init_shm(*mut wl_display) -> c_int, fn wl_display_add_client_created_listener(*mut wl_display, *mut wl_listener) -> (), fn wl_display_set_global_filter(*mut wl_display, wl_display_global_filter_func_t, *mut c_void) -> (), // wl_event_loop fn wl_event_loop_create() -> *mut wl_event_loop, fn wl_event_loop_destroy(*mut wl_event_loop) -> (), fn wl_event_loop_add_fd(*mut wl_event_loop, c_int, u32, wl_event_loop_fd_func_t, *mut c_void) -> *mut wl_event_source, fn wl_event_loop_add_timer(*mut wl_event_loop, wl_event_loop_timer_func_t, *mut c_void) -> *mut wl_event_source, fn wl_event_loop_add_signal(*mut wl_event_loop, c_int, wl_event_loop_signal_func_t, *mut c_void) -> *mut wl_event_source, fn wl_event_loop_dispatch(*mut wl_event_loop, c_int) -> c_int, fn wl_event_loop_dispatch_idle(*mut wl_event_loop) -> (), fn wl_event_loop_add_idle(*mut wl_event_loop, wl_event_loop_idle_func_t, *mut c_void) -> *mut wl_event_source, fn wl_event_loop_get_fd(*mut wl_event_loop) -> c_int, fn wl_event_loop_add_destroy_listener(*mut wl_event_loop, *mut wl_listener) -> (), fn wl_event_loop_get_destroy_listener(*mut wl_event_loop, wl_notify_func_t) -> *mut wl_listener, // wl_event_source fn wl_event_source_fd_update(*mut wl_event_source, u32) -> c_int, fn wl_event_source_timer_update(*mut wl_event_source, c_int) -> c_int, fn wl_event_source_remove(*mut wl_event_source) -> c_int, fn wl_event_source_check(*mut wl_event_source) -> (), // wl_global fn wl_global_destroy(*mut wl_global) -> (), fn wl_global_get_user_data(*const wl_global) -> *mut c_void, // wl_resource fn wl_resource_post_event_array(*mut wl_resource, u32, *mut wl_argument) -> (), fn wl_resource_queue_event_array(*mut wl_resource, u32, *mut wl_argument) -> (), fn wl_resource_post_no_memory(*mut wl_resource) -> (), fn wl_resource_set_implementation(*mut wl_resource, *const c_void, *mut c_void, Option) -> (), fn wl_resource_set_dispatcher(*mut wl_resource, wl_dispatcher_func_t, *const c_void, *mut c_void, Option) -> (), fn wl_resource_destroy(*mut wl_resource) -> (), fn wl_resource_get_client(*mut wl_resource) -> *mut wl_client, fn wl_resource_get_id(*mut wl_resource) -> u32, fn wl_resource_get_link(*mut wl_resource) -> *mut wl_list, fn wl_resource_from_link(*mut wl_list) -> *mut wl_resource, fn wl_resource_find_for_client(*mut wl_list, *mut wl_client) -> (), fn wl_resource_set_user_data(*mut wl_resource, *mut c_void) -> (), fn wl_resource_get_user_data(*mut wl_resource) -> *mut c_void, fn wl_resource_get_version(*mut wl_resource) -> c_int, fn wl_resource_get_class(*mut wl_resource) -> *const c_char, fn wl_resource_set_destructor(*mut wl_resource, Option) -> (), fn wl_resource_instance_of(*mut wl_resource, *const wl_interface, *const c_void) -> c_int, fn wl_resource_add_destroy_listener(*mut wl_resource, wl_notify_func_t) -> (), fn wl_resource_get_destroy_listener(*mut wl_resource,wl_notify_func_t) -> *mut wl_listener, // wl_shm fn wl_shm_buffer_begin_access(*mut wl_shm_buffer) -> (), fn wl_shm_buffer_end_access(*mut wl_shm_buffer) -> (), fn wl_shm_buffer_get(*mut wl_resource) -> *mut wl_shm_buffer, fn wl_shm_buffer_get_data(*mut wl_shm_buffer) -> *mut c_void, fn wl_shm_buffer_get_stride(*mut wl_shm_buffer) -> i32, fn wl_shm_buffer_get_format(*mut wl_shm_buffer) -> u32, fn wl_shm_buffer_get_width(*mut wl_shm_buffer) -> i32, fn wl_shm_buffer_get_height(*mut wl_shm_buffer) -> i32, // wl_log fn wl_log_set_handler_server(wl_log_func_t) -> (), // wl_list fn wl_list_init(*mut wl_list) -> (), fn wl_list_insert(*mut wl_list, *mut wl_list) -> (), fn wl_list_remove(*mut wl_list) -> (), fn wl_list_length(*const wl_list) -> c_int, fn wl_list_empty(*const wl_list) -> c_int, fn wl_list_insert_list(*mut wl_list,*mut wl_list) -> (), // arrays fn wl_array_init(*mut wl_array) -> (), fn wl_array_release(*mut wl_array) -> (), fn wl_array_add(*mut wl_array,usize) -> (), fn wl_array_copy(*mut wl_array, *mut wl_array) -> (), varargs: fn wl_resource_post_event(*mut wl_resource, u32) -> (), fn wl_resource_queue_event(*mut wl_resource, u32) -> (), fn wl_resource_post_error(*mut wl_resource, u32, *const c_char) -> (), ); #[cfg(all(feature = "server", feature = "dlopen"))] lazy_static::lazy_static!( pub static ref WAYLAND_SERVER_OPTION: Option = { // This is a workaround for Ubuntu 17.04, which doesn't have a bare symlink // for libwayland-server.so but does have it with the version numbers for // whatever reason. // // We could do some trickery with str slices but that is more trouble // than its worth let versions = ["libwayland-server.so", "libwayland-server.so.0"]; for ver in &versions { match unsafe { WaylandServer::open(ver) } { Ok(h) => return Some(h), Err(::dlib::DlError::CantOpen(_)) => continue, Err(::dlib::DlError::MissingSymbol(s)) => { if ::std::env::var_os("WAYLAND_RS_DEBUG").is_some() { // only print debug messages if WAYLAND_RS_DEBUG is set eprintln!("[wayland-server] Found library {} cannot be used: symbol {} is missing.", ver, s); } return None; } } } None }; pub static ref WAYLAND_SERVER_HANDLE: &'static WaylandServer = { WAYLAND_SERVER_OPTION.as_ref().expect("Library libwayland-server.so could not be loaded.") }; ); #[cfg(all(feature = "server", not(feature = "dlopen")))] pub fn is_lib_available() -> bool { true } #[cfg(all(feature = "server", feature = "dlopen"))] pub fn is_lib_available() -> bool { WAYLAND_SERVER_OPTION.is_some() } #[cfg(feature = "server")] pub mod signal { #![allow(clippy::cast_ptr_alignment, clippy::missing_safety_doc)] #[cfg(feature = "dlopen")] use super::WAYLAND_SERVER_HANDLE as WSH; #[cfg(not(feature = "dlopen"))] use super::{wl_list_init, wl_list_insert}; use super::{wl_listener, wl_notify_func_t, wl_signal}; use crate::common::wl_list; use std::os::raw::c_void; use std::ptr; macro_rules! container_of( ($ptr: expr, $container: ident, $field: ident) => { ($ptr as *mut u8).offset(-(memoffset::offset_of!($container, $field) as isize)) as *mut $container } ); macro_rules! list_for_each( ($pos: ident, $head:expr, $container: ident, $field: ident, $action: block) => { let mut $pos = container_of!((*$head).next, $container, $field); while &mut (*$pos).$field as *mut _ != $head { $action; $pos = container_of!((*$pos).$field.next, $container, $field); } } ); macro_rules! list_for_each_safe( ($pos: ident, $head: expr, $container: ident, $field: ident, $action: block) => { let mut $pos = container_of!((*$head).next, $container, $field); let mut tmp = container_of!((*$pos).$field.next, $container, $field); while &mut (*$pos).$field as *mut _ != $head { $action; $pos = tmp; tmp = container_of!((*$pos).$field.next, $container, $field); } } ); pub unsafe fn wl_signal_init(signal: *mut wl_signal) { ffi_dispatch!(WSH, wl_list_init, &mut (*signal).listener_list); } pub unsafe fn wl_signal_add(signal: *mut wl_signal, listener: *mut wl_listener) { ffi_dispatch!(WSH, wl_list_insert, (*signal).listener_list.prev, &mut (*listener).link) } pub unsafe fn wl_signal_get( signal: *mut wl_signal, notify: wl_notify_func_t, ) -> *mut wl_listener { list_for_each!(l, &mut (*signal).listener_list as *mut wl_list, wl_listener, link, { if (*l).notify == notify { return l; } }); ptr::null_mut() } pub unsafe fn wl_signal_emit(signal: *mut wl_signal, data: *mut c_void) { list_for_each_safe!(l, &mut (*signal).listener_list as *mut wl_list, wl_listener, link, { ((*l).notify)(l, data); }); } #[repr(C)] struct ListenerWithUserData { listener: wl_listener, user_data: *mut c_void, } pub fn rust_listener_create(notify: wl_notify_func_t) -> *mut wl_listener { let data = Box::into_raw(Box::new(ListenerWithUserData { listener: wl_listener { link: wl_list { prev: ptr::null_mut(), next: ptr::null_mut() }, notify, }, user_data: ptr::null_mut(), })); unsafe { &mut (*data).listener as *mut wl_listener } } pub unsafe fn rust_listener_get_user_data(listener: *mut wl_listener) -> *mut c_void { let data = container_of!(listener, ListenerWithUserData, listener); (*data).user_data } pub unsafe fn rust_listener_set_user_data(listener: *mut wl_listener, user_data: *mut c_void) { let data = container_of!(listener, ListenerWithUserData, listener); (*data).user_data = user_data } pub unsafe fn rust_listener_destroy(listener: *mut wl_listener) { let data = container_of!(listener, ListenerWithUserData, listener); let _ = Box::from_raw(data); } }