diff --git a/Cargo.lock b/Cargo.lock index 10ee37b..ff25da1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,15 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "libc" +version = "0.2.189" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2" + [[package]] name = "wayland_server" version = "0.1.0" +dependencies = [ + "libc", +] diff --git a/Cargo.toml b/Cargo.toml index 82c4542..b7ce215 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,3 +4,4 @@ version = "0.1.0" edition = "2024" [dependencies] +libc = "*" \ No newline at end of file diff --git a/src/ffi.rs b/src/ffi.rs new file mode 100644 index 0000000..b1268aa --- /dev/null +++ b/src/ffi.rs @@ -0,0 +1,468 @@ +use std::{ffi::CStr, os::fd::RawFd}; + +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; +#[allow(non_camel_case_types)] +pub(crate) type wl_event_loop_timer_func_t = 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; +#[allow(non_camel_case_types)] +pub(crate) type wl_event_loop_idle_func_t = 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); +#[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); +#[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; +#[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; +#[allow(non_camel_case_types)] +pub(crate) type wl_user_data_destroy_func_t = fn(data: *mut libc::c_void); +#[allow(non_camel_case_types)] +pub(crate) type wl_resource_destroy_func_t = 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); +#[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; +#[allow(non_camel_case_types)] +pub(crate) type wl_log_func_t = fn(fmt: *const libc::c_char, args: std::ffi::VaList); + +// ffi data types and struct +const UNIX_PATH_MAX: usize = 108; +const LOCK_SUFFIX: &str = ".lock"; +const LOCK_SUFFIXLEN: usize = 5; +#[repr(C)] +#[allow(non_camel_case_types)] +struct wl_socket { + fd: RawFd, + fd_lock: i32, + addr: libc::sockaddr_un, + lock_addr: [libc::c_char; UNIX_PATH_MAX+LOCK_SUFFIXLEN], + link: wl_list, + source: *mut wl_event_source, + display_name: *mut libc::c_char, +} + +#[repr(C)] +#[allow(non_camel_case_types)] +pub(crate) struct wl_client { + connection: *mut wl_connection, + source: *mut wl_event_source, + display: *mut wl_display, + display_resource: *mut wl_resource, + link: wl_list, + objects: wl_map, + destroy_signal: wl_priv_signal, + destroy_late_signal: wl_priv_signal, + pid: libc::pid_t, + uid: libc::uid_t, + gid: libc::gid_t, + error: bool, + resource_created_signal: wl_priv_signal, + data: *mut libc::c_void, + data_dtor: wl_user_data_destroy_func_t, +} + +#[repr(C)] +#[allow(non_camel_case_types)] +pub(crate) struct wl_display { + r#loop: *mut wl_event_loop, + run: bool, + + next_global_name: u32, + serial: u32, + + registry_resource_list: wl_list, + global_list: wl_list, + socket_list: wl_list, + client_list: wl_list, + protocol_loggers: wl_list, + + destroy_signal: wl_priv_signal, + create_client_signal: wl_priv_signal, + + additional_shm_formats: wl_array, + + global_filter: wl_display_global_filter_func_t, + global_filter_data: *mut libc::c_void, + + terminate_efd: i32, + term_source: *mut wl_event_source, + + max_buffer_size: usize, +} + +#[repr(C)] +#[allow(non_camel_case_types)] +pub(crate) struct wl_global{ + display: *mut wl_display, + interface: *const wl_interface, + name: u32, + version: u32, + data: *mut libc::c_void, + bind: wl_global_bind_func_t, + link: wl_list, + removed: bool, +} + +#[repr(C)] +#[allow(non_camel_case_types)] +pub(crate) struct wl_resource { + object: wl_object, + destroy: wl_resource_destroy_func_t, + link: wl_list, + deprecated_destroy_signal: wl_signal, + client: *mut wl_client, + data: *mut libc::c_void, + version: i32, + dispatcher: wl_dispatcher_func_t, + destroy_signal: wl_priv_signal, +} + +#[repr(C)] +#[allow(non_camel_case_types)] +pub(crate) struct wl_protocol_logger { + link: wl_list, + func: wl_protocol_logger_func_t, + user_data: *mut libc::c_void, +} + +#[repr(C)] +#[allow(non_camel_case_types)] +struct wl_object { + interface: *const wl_interface, + implementation: *const libc::c_void, + id: u32, +} + +#[repr(C)] +#[allow(non_camel_case_types)] +struct wl_priv_signal { + listener_list: wl_list, + emit_list: wl_list, +} + +#[repr(C)] +#[allow(non_camel_case_types)] +pub(crate) struct wl_listener { + link: wl_list, + notify: wl_notify_func_t, +} + +#[repr(C)] +#[allow(non_camel_case_types)] +pub(crate) struct wl_signal { + listener_list: wl_list, +} + +#[repr(C)] +#[allow(non_camel_case_types)] +pub(crate) enum wl_protocol_logger_type { + WL_PROTOCOL_LOGGER_REQUEST, + WL_PROTOCOL_LOGGER_EVENT, +} + +#[repr(C)] +#[allow(non_camel_case_types)] +pub(crate) struct wl_protocol_logger_message { + resource: *mut wl_resource, + message_opcode: i32, + message: *const wl_message, + arguments_count: i32, + arguments: *const wl_argument, +} + +#[repr(C)] +#[allow(non_camel_case_types)] +pub(crate) struct wl_message { + name: *const libc::c_char, + signature: *const libc::c_char, + types: *const *const wl_interface, +} + +#[repr(C)] +#[allow(non_camel_case_types)] +pub(crate) struct wl_interface { + name: *const libc::c_char, + version: i32, + method_count: i32, + method: *const wl_message, + event_count: i32, + events: *const wl_message, +} + +#[repr(C)] +#[allow(non_camel_case_types)] +pub(crate) struct wl_list { + prev: *mut wl_list, + next: *mut wl_list, +} + +#[repr(C)] +#[allow(non_camel_case_types)] +pub(crate) struct wl_array { + size: usize, + alloc: usize, + data: *mut libc::c_void, +} + +#[allow(non_camel_case_types)] +type wl_fixed_t = i32; + +#[repr(C)] +#[allow(non_camel_case_types)] +pub(crate) union wl_argument { + i: i32, + u: u32, + f: wl_fixed_t, + s: *const libc::c_char, + o: *mut wl_object, + n: u32, + a: *mut wl_array, + h: i32, +} + +#[repr(C)] +#[allow(non_camel_case_types)] +pub(crate) enum wl_iterator_result { + WL_ITERATOR_STOP, + WL_ITERATOR_CONTINUE, +} + +#[repr(C)] +#[allow(non_camel_case_types)] +struct wl_map { + client_entries: wl_array, + server_entries: wl_array, + side: u32, + free_list: u32, +} + +#[repr(C)] +#[allow(non_camel_case_types)] +struct wl_ring_buffer { + data: *mut libc::c_char, + head: usize, + tail: usize, + size_bits: u32, + max_size_bits: u32, +} + +#[repr(C)] +#[allow(non_camel_case_types)] +struct wl_connection { + r#in: wl_ring_buffer, + out: wl_ring_buffer, + fds_in: wl_ring_buffer, + fds_out: wl_ring_buffer, + fd: RawFd, + want_flush: i32, +} + +#[repr(C)] +#[allow(non_camel_case_types)] +pub(crate) struct wl_event_source { + interface: *mut wl_event_source_interface, + r#loop: *mut wl_event_loop, + link: wl_list, + data: *mut libc::c_void, + fd: RawFd, +} + +#[repr(C)] +#[allow(non_camel_case_types)] +struct wl_timer_heap { + base: wl_event_source, + data: *mut *mut wl_event_source_timer, + space: i32, + active: i32, + count: i32, +} + +#[repr(C)] +#[allow(non_camel_case_types)] +pub(crate) struct wl_event_loop { + epoll_fd: i32, + check_list: wl_list, + idle_list: wl_list, + destroy_list: wl_list, + + destroy_signal: wl_priv_signal, + timers: wl_timer_heap, +} + +#[repr(C)] +#[allow(non_camel_case_types)] +pub(crate) struct wl_event_source_interface { + dispatch: fn(source: *mut wl_event_source, ep: *mut epoll_event) -> i32, +} + +#[repr(C)] +#[allow(non_camel_case_types)] +pub(crate) struct wl_event_source_timer { + base: wl_event_source, + func: wl_event_loop_timer_func_t, + next_due: *mut wl_event_source_timer, + deadline: libc::timespec, + heap_idx: i32, +} + +#[repr(C)] +#[allow(non_camel_case_types)] +pub(crate) struct wl_shm_buffer { + resource: *mut wl_resource, + internal_refcount: i32, + external_refcount: i32, + client: *mut wl_client, + client_destroy_listener: wl_listener, + width: i32, + height: i32, + stride: i32, + format: u32, + offset: i32, + pool: *mut wl_shm_pool, +} + +#[repr(C)] +#[allow(non_camel_case_types)] +pub(crate) struct wl_shm_pool { + resource: *mut wl_resource, + internal_refcount: i32, + external_refcount: i32, + data: *mut libc::c_char, + size: isize, + new_size: isize, + sigbus_is_impossible: bool +} + +#[link(name = "wayland-server")] +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_copy(array: *mut wl_array, source: *mut wl_array) -> i32; + pub(crate) unsafe fn wl_array_init(array: *mut wl_array); + pub(crate) unsafe fn wl_array_release(array: *mut wl_array); + + pub(crate) unsafe fn wl_client_add_destroy_late_listener(client: *mut wl_client, listener: *mut wl_listener); + pub(crate) unsafe fn wl_client_add_destroy_listener(client: *mut wl_client, listener: *mut wl_listener); + pub(crate) unsafe fn wl_client_add_object(); + pub(crate) unsafe fn wl_client_add_resource_created_listener(client: *mut wl_client, listener: *mut wl_listener); + pub(crate) unsafe fn wl_client_add_resource(); + pub(crate) unsafe fn wl_client_create(disp: *mut wl_display, fd: RawFd) -> *mut wl_client; + pub(crate) unsafe fn wl_client_destroy(client: *mut wl_client); + pub(crate) unsafe fn wl_client_flush(client: *mut wl_client); + pub(crate) unsafe fn wl_client_for_each_resource(client: *mut wl_client, iterator: wl_client_for_each_resource_iterator_func_t, user_data: *mut libc::c_void); + pub(crate) unsafe fn wl_client_from_link(link: *mut wl_list) -> *mut wl_client; + pub(crate) unsafe fn wl_client_get_credentials(client: *const wl_client, pid: *mut libc::pid_t, uid: *mut libc::uid_t, gid: *mut libc::gid_t); + pub(crate) unsafe fn wl_client_get_destroy_late_listener(client: *mut wl_client, notify: wl_notify_func_t) -> *mut wl_listener; + pub(crate) unsafe fn wl_client_get_destroy_listener(client: *mut wl_client, notify: wl_notify_func_t) -> *mut wl_listener; + pub(crate) unsafe fn wl_client_get_display(client: *mut wl_client) -> *mut wl_display; + pub(crate) unsafe fn wl_client_get_fd(client: *mut wl_client) -> i32; + pub(crate) unsafe fn wl_client_get_link(client: *mut wl_client) -> *mut wl_list; + pub(crate) unsafe fn wl_client_get_object(client: *mut wl_client, id: u32) -> *mut wl_resource; + pub(crate) unsafe fn wl_client_new_object(); + pub(crate) unsafe fn wl_client_post_implementation_error(client: *mut wl_client, msg: *const std::ffi::CStr, ...); + pub(crate) unsafe fn wl_client_post_no_memory(client: *mut wl_client); + + pub(crate) unsafe fn wl_display_add_client_created_listener(disp: *mut wl_display, listener: *mut wl_listener); + pub(crate) unsafe fn wl_display_add_destroy_listener(disp: *mut wl_display, listener: *mut wl_listener); + 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(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; + pub(crate) unsafe fn wl_display_destroy_clients(disp: *mut wl_display); + pub(crate) unsafe fn wl_display_destroy(disp: *mut wl_display); + pub(crate) unsafe fn wl_display_flush_clients(disp: *mut wl_display); + pub(crate) unsafe fn wl_display_get_client_list(disp: *mut wl_client) -> *mut wl_list; + pub(crate) unsafe fn wl_display_get_destroy_listener(disp: *mut wl_display, interface: *const wl_interface) -> *mut wl_global; + pub(crate) unsafe fn wl_display_get_event_loop(disp: *mut wl_display) -> *mut wl_event_loop; + pub(crate) unsafe fn wl_display_get_serial(disp: *mut wl_display) -> u32; + pub(crate) unsafe fn wl_display_init_shm(disp: *mut wl_display) -> i32; + pub(crate) unsafe fn wl_display_next_serial(disp: *mut wl_display) -> u32; + pub(crate) unsafe fn wl_display_remove_global(); + pub(crate) unsafe fn wl_display_run(disp: *mut wl_display); + pub(crate) unsafe fn wl_display_set_global_filter(disp: *mut wl_display, filter: wl_display_global_filter_func_t, data: *mut libc::c_void); + pub(crate) unsafe fn wl_display_terminate(disp: *mut wl_display); + + pub(crate) unsafe fn wl_event_loop_add_destroy_listener(r#loop: *mut wl_event_loop, listener: *mut wl_listener); + pub(crate) unsafe fn wl_event_loop_add_fd(r#loop: *mut wl_event_loop, fd: RawFd, mask: u32, func: wl_event_loop_fd_func_t, data: *mut libc::c_void) -> *mut wl_event_source; + pub(crate) unsafe fn wl_event_loop_add_idle(r#loop: *mut wl_event_loop, func: wl_event_loop_idle_func_t, data: *mut libc::c_void) -> *mut wl_event_source; + pub(crate) unsafe fn wl_event_loop_add_signal(r#loop: *mut wl_event_loop, signal_number: i32, func: wl_event_loop_signal_func_t, data: *mut libc::c_void) -> *mut wl_event_source; + pub(crate) unsafe fn wl_event_loop_add_timer(r#loop: *mut wl_event_loop, func: wl_event_loop_timer_func_t, data: *mut libc::c_void) -> *mut wl_event_source; + pub(crate) unsafe fn wl_event_loop_create() -> *mut wl_event_loop; + pub(crate) unsafe fn wl_event_loop_destroy(r#loop: *mut wl_event_loop); + pub(crate) unsafe fn wl_event_loop_dispatch(r#loop: *mut wl_event_loop, timeout: i32) -> i32; + pub(crate) unsafe fn wl_event_loop_dispatch_idle(r#loop: *mut wl_event_loop); + pub(crate) unsafe fn wl_event_loop_get_destroy_listener(r#loop: *mut wl_event_loop, notify: wl_notify_func_t) -> *mut wl_listener; + pub(crate) unsafe fn wl_event_loop_get_fd(r#loop: *mut wl_event_loop) -> RawFd; + + pub(crate) unsafe fn wl_event_source_check(source: *mut wl_event_source); + pub(crate) unsafe fn wl_event_source_fd_update(source: *mut wl_event_source, mask: u32) -> 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_global_create(disp: *mut wl_display, interface: *const wl_interface) -> *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_interface(global: *const wl_global) -> *const wl_interface; + pub(crate) unsafe fn wl_global_get_name(global: *const wl_global, client: *const wl_client) -> u32; + pub(crate) unsafe fn wl_global_get_user_data(global: *const wl_global) -> *mut libc::c_void; + pub(crate) unsafe fn wl_global_get_version(global: *const wl_global) -> u32; + 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_list_empty(list: *const 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(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_remove(elm: *mut wl_list); + + pub(crate) unsafe fn wl_log_set_handler_server(handler: wl_log_func_t); + + pub(crate) unsafe fn wl_protocol_logger_destroy(logger: *mut wl_protocol_logger); + + pub(crate) unsafe fn wl_resource_add_destroy_listener(resource: *mut wl_resource, listener: *mut wl_listener); + pub(crate) unsafe fn wl_resource_create(client: *mut wl_client, interface: *const wl_interface, version: i32, id: u32) -> *mut wl_resource; + pub(crate) unsafe fn wl_resource_destroy(resource: *mut wl_resource); + pub(crate) unsafe fn wl_resource_find_for_client(list: *mut wl_list, client: *mut wl_client) -> *mut wl_resource; + pub(crate) unsafe fn wl_resource_from_link(resource: *mut wl_list) -> *mut wl_resource; + pub(crate) unsafe fn wl_resource_get_class(resource: *const wl_resource) -> *const CStr; + pub(crate) unsafe fn wl_resouce_get_destroy_listener(resource: *mut wl_resource, notify: wl_notify_func_t) -> *mut wl_listener; + pub(crate) unsafe fn wl_resource_get_id(resource: *const wl_resource) -> u32; + pub(crate) unsafe fn wl_resource_get_link(resource: *mut wl_resource) -> *mut wl_list; + pub(crate) unsafe fn wl_resource_get_user_data(resource: *mut wl_resource) -> *mut libc::c_void; + pub(crate) unsafe fn wl_resource_get_version(resource: *const wl_resource) -> i32; + pub(crate) unsafe fn wl_resource_instance_of(resource: *mut wl_resource, interface: *const wl_interface, implementation: *const libc::c_void) -> i32; + pub(crate) unsafe fn wl_resource_post_error(resource: *mut wl_resource, code: u32, msg: *const std::ffi::CStr); + pub(crate) unsafe fn wl_resource_post_event_array(resource: *mut wl_resource, opcode: u32, args: *mut wl_argument); + pub(crate) unsafe fn wl_resource_post_event(resource: *mut wl_resource, opcode: u32, ...); + pub(crate) unsafe fn wl_resource_post_no_memory(resource: *mut wl_resource); + pub(crate) unsafe fn wl_resource_queue_event_array(resource: *mut wl_resource, opcode: u32, args: *mut wl_argument); + pub(crate) unsafe fn wl_resource_queue_event(resource: *mut wl_resource, opcode: u32, ...); + pub(crate) unsafe fn wl_resource_set_destructor(resource: *mut wl_resource, destroy: wl_resource_destroy_func_t); + pub(crate) unsafe fn wl_resource_set_dispatcher(resource: *mut wl_resource, dispatcher: wl_dispatcher_func_t, implementation: *const libc::c_void, data: *mut libc::c_void, destroy: wl_resource_destroy_func_t); + pub(crate) unsafe fn wl_resource_set_implementation(resource: *mut wl_resource, dispatcher: wl_dispatcher_func_t, implementation: *const libc::c_void, data: *mut libc::c_void, destroy: wl_resource_destroy_func_t); + pub(crate) unsafe fn wl_resource_set_user_data(resource: *mut wl_resource, data: *mut libc::c_void); + + pub(crate) unsafe fn wl_shm_buffer_begin_access(buffer: *mut wl_shm_buffer); + #[deprecated] + pub(crate) unsafe fn wl_shm_buffer_create(client: *mut wl_client, id: u32, width: i32, height: i32, stride: i32, format: u32) -> *mut wl_shm_buffer; + pub(crate) unsafe fn wl_shm_buffer_end_access(buffer: *mut wl_shm_buffer); + pub(crate) unsafe fn wl_shm_buffer_get_data(buffer: *mut wl_shm_buffer) -> *mut libc::c_void; + pub(crate) unsafe fn wl_shm_buffer_get(resource: *mut wl_resource) -> *mut wl_shm_buffer; + pub(crate) unsafe fn wl_shm_buffer_get_format(buffer: *const wl_shm_buffer) -> i32; + pub(crate) unsafe fn wl_shm_buffer_get_height(buffer: *const wl_shm_buffer) -> i32; + pub(crate) unsafe fn wl_shm_buffer_get_stride(buffer: *const wl_shm_buffer) -> i32; + pub(crate) unsafe fn wl_shm_buffer_get_width(buffer: *const wl_shm_buffer) -> i32; + pub(crate) unsafe fn wl_shm_buffer_ref_pool(buffer: *mut wl_shm_buffer) -> *mut wl_shm_pool; + + pub(crate) unsafe fn wl_shm_pool_unref(pool: *mut wl_shm_pool); + + pub(crate) unsafe fn wl_signal_emit_mutable(signal: *mut wl_signal, data: *mut libc::c_void); +} \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index b93cf3f..23ba080 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,14 +1,3 @@ -pub fn add(left: u64, right: u64) -> u64 { - left + right -} +#![feature(c_variadic)] -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn it_works() { - let result = add(2, 2); - assert_eq!(result, 4); - } -} +pub(crate) mod ffi; \ No newline at end of file