1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194
#![warn(missing_docs)] //! Module defining main wlc functions. #![allow(improper_ctypes)] // We get warnings on WlcInterface extern crate libc; #[macro_use] extern crate bitflags; use std::ffi; use std::ptr; use std::ffi::CString; pub mod handle; pub mod interface; pub mod types; pub mod input; pub mod wayland; pub mod xkb; use types::{BackendType, LogType}; use interface::WlcInterface; // External WLC functions #[link(name = "wlc")] extern "C" { fn wlc_exec(bin: *const libc::c_char, args: *const *const libc::c_char); fn wlc_init(interface: *const WlcInterface, argc: i32, argv: *const *mut libc::c_char) -> bool; fn wlc_run(); fn wlc_terminate(); fn wlc_log_set_handler(callback: extern "C" fn(log_type: LogType, text: *const libc::c_char)); fn wlc_get_backend_type() -> BackendType; } /// Query backend wlc is using. /// /// # Results /// * None: Unknown backend type /// * DRM: "Direct Rendering Manager" - running on tty /// * X11: Running inside an X server pub fn get_backend_type() -> BackendType { unsafe { wlc_get_backend_type() } } /// Initialize wlc with a `WlcInterface`. /// /// Create a WlcInterface with the proper callback methods /// and call `rustwlc::init` to initialize wlc (alternatively use init_with_args). /// If it returns true, continue with `rustwlc::run_wlc()` to run wlc's event loop. /// /// # Example /// ```no_run /// use rustwlc; /// /// let interface = rustwlc::interface::WlcInterface::new(); /// // Set a default log callback /// rustwlc::log_set_default_handler(); /// /// if let Some(run_wlc) = rustwlc::init(interface) { /// run_wlc() /// } /// else { /// panic!("Unable to initialize wlc!"); /// } /// ``` pub fn init(interface: WlcInterface) -> Option<fn() -> ()> { unsafe { if wlc_init(&interface, 0, ptr::null()) { Some(run_wlc) } else { None } } } /// Runs wlc's event loop. /// /// The initialize functions will return this function in an Option. /// If and only if they succeed can this function be called wlc with `rustwlc::init` call this method /// to being wlc's main event loop. fn run_wlc() { unsafe { wlc_run(); } } /// Deprecated, do not use. /// /// # Deprecated /// This function does not seem to work across the FFI boundary, and Rust provides a /// much better interface in the `std::command::Command` class to executing programs. pub fn exec(bin: String, args: Vec<String>) { unsafe { let bin_c = CString::new(bin).unwrap().as_ptr() as *const libc::c_char; let argv: Vec<CString> = args.into_iter() .map(|arg| CString::new(arg).unwrap()) .collect(); let args: Vec<*const libc::c_char> = argv.into_iter() .map(|arg: CString| { arg.as_ptr() as *const libc::c_char }) .collect(); wlc_exec(bin_c, args.as_ptr() as *const *const libc::c_char); } } /// Halts execution of wlc. pub fn terminate() { unsafe { wlc_terminate(); } } /// Registers a callback for wlc logging. /// /// Note that `rustwlc::log_set_default_handler()` will register a simple callback /// that will print the type and text to the console. /// /// # Parameters /// The `handler` callback has two parameters: /// * `type`: The `LogType` of the message being printed. /// * `text`: The text to be logged, currently in C form. One may call `rustwlc::pointer_to_string` /// to convert it to a Rust String. /// /// # Safety /// The callback function (like other callbacks in `rustwlc`) must be marked as extern as it is called /// from C code. /// /// In addition, `unsafe` will be required to convert the text into a Rust String. #[allow(dead_code)] pub fn log_set_handler(handler: extern "C" fn(type_: LogType, text: *const libc::c_char)) { unsafe { wlc_log_set_handler(handler); } } #[allow(dead_code)] extern "C" fn default_log_callback(log_type: LogType, text: *const libc::c_char) { let string_text = unsafe { pointer_to_string(text) }; println!("wlc [{:?}] {}", log_type, string_text); } /// Sets the wlc log callback to a simple function that prints to console. /// /// Not calling any `log_set_handler` will have no logging, use this or /// `log_set_handler` with a callback to use wlc logging. /// /// # Example /// ```no_run /// use rustwlc; /// /// let interface = rustwlc::interface::WlcInterface::new(); /// rustwlc::log_set_default_handler(); /// /// if let Some(run_wlc) = rustwlc::init(interface) { /// run_wlc(); /// } /// else { /// panic!("Unable to initialize wlc!"); /// } /// ``` pub fn log_set_default_handler() { log_set_handler(default_log_callback); } /// Unsafe strings conversion function. /// /// Converts a `*const libc::c_char` to an owned `String`. /// Useful for log callbacks. /// /// # Example /// Standard usage may be for the log callbacks. /// ```rust /// extern "C" fn default_log_callback(log_type: LogType, text: *const libc::c_char) { /// let string = unsafe { pointer_to_string(text) }; /// println!("wlc [{:?}]: {}", log_type, string); /// } /// ``` pub unsafe fn pointer_to_string(pointer: *const libc::c_char) -> String { if pointer.is_null() { return "".to_string(); } let slice = ffi::CStr::from_ptr(pointer); slice.to_string_lossy().into_owned() }