summaryrefslogtreecommitdiff
path: root/src/safe_x11/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/safe_x11/mod.rs')
-rw-r--r--src/safe_x11/mod.rs201
1 files changed, 201 insertions, 0 deletions
diff --git a/src/safe_x11/mod.rs b/src/safe_x11/mod.rs
new file mode 100644
index 0000000..199c402
--- /dev/null
+++ b/src/safe_x11/mod.rs
@@ -0,0 +1,201 @@
+//! Safe wrapper around the `x11-rs` crate. This should be as much safe as possible.
+
+#![allow(dead_code)]
+use x11::xlib;
+use x11::xlib::{
+ Display,
+ Screen,
+ Cursor,
+ XDefaultRootWindow,
+ XQueryTree,
+
+ // Windows
+ Window,
+
+ // Events
+ XEvent,
+};
+use x11::xlib::XKeyEvent;
+
+use std::ffi::CString;
+use std::ffi::NulError;
+use std::ptr;
+use std::error;
+use std::mem::uninitialized;
+use std::slice;
+use std::fmt;
+
+pub mod window;
+
+#[derive(Debug)]
+pub struct XSafeError<'a> {
+ _description: &'a str,
+}
+
+impl<'a> XSafeError<'a> {
+ fn new(desc: &'static str) -> XSafeError<'a> {
+ XSafeError { _description: desc }
+ }
+}
+
+impl<'a> From<NulError> for XSafeError<'a> {
+ fn from(_: NulError) -> XSafeError<'a> {
+ XSafeError::new("Null ponter error!")
+ }
+}
+
+impl<'a> error::Error for XSafeError<'a> {
+ fn description(&self) -> &str {
+ self._description
+ }
+
+ fn cause(&self) -> Option<&error::Error> {
+ None
+ }
+}
+
+impl<'a> fmt::Display for XSafeError<'a> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
+ write!(f, "{}", self._description)
+ }
+}
+
+/// Open a display. If the string passed by parameter is `""`, it will open the
+/// default display.
+///
+/// # Failures
+///
+/// This function can raise a NulError when the bytes yielded contains an internal
+/// 0 byte.
+///
+pub fn open_display(display: &str) -> Result<*mut Display, XSafeError> {
+ let d = if display == "" {
+ println!("Opening default display");
+ unsafe { xlib::XOpenDisplay(0x0 as *const i8) }
+ } else {
+ println!("Opening {}", display);
+ let cstr = try!(CString::new(display));
+ unsafe { xlib::XOpenDisplay(cstr.as_ptr()) }
+ };
+
+ if d.is_null() {
+ Err(XSafeError::new("Cannot open display!"))
+ } else {
+ Ok(d)
+ }
+}
+
+pub fn close_display(display: *mut Display) {
+ unsafe { xlib::XCloseDisplay(display); }
+}
+
+/// Grab pointer buttons.
+///
+/// # Example
+///
+/// ```
+/// grab_button(
+/// // Display
+/// display,
+/// // Button to press
+/// xlib::Button1 as i32,
+/// // Modifiers (can be an or of modifiers).
+/// xlib::Mod1Mask,
+/// // owner events.
+/// true,
+/// // Which motions we'll handle
+/// ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
+/// // Keyboard and pointer sync moddes
+/// GrabModeAsync, GrabModeAsync,
+/// // Confine to and cursor. (Can be 0 :) )
+/// 0, 0
+/// );
+/// ```
+pub fn grab_button(display: *mut Display, button: u32, modifiers: u32,
+ owner_events: bool, event_mask: i64, pointer_mode: i32,
+ keyboard_mode: i32, confine_to: Window,
+ cursor: Cursor) {
+ unsafe {
+ let default_win = xlib::XDefaultRootWindow(display);
+ xlib::XGrabButton(display, button, modifiers , default_win,
+ owner_events as i32, event_mask as u32, pointer_mode,
+ keyboard_mode, confine_to, cursor);
+ }
+}
+
+/// Register a combination of keys that will send a `XEvent`
+///
+pub fn grab_key(display: *mut Display, key: u32, modifiers: u32, owner_events: bool,
+ pointer_mode: i32, keyboard_mode: i32) {
+ unsafe {
+ let default_win = xlib::XDefaultRootWindow(display);
+ let keycode: i32 = xlib::XKeysymToKeycode(display, key as u64) as i32;
+ xlib::XGrabKey(display, keycode, modifiers, default_win,
+ owner_events as i32, pointer_mode, keyboard_mode);
+ }
+}
+
+/// Get the next event from the xserver. This call will block until a
+/// event spawns.
+pub fn next_xevent(display: *mut Display) -> XEvent {
+ unsafe {
+ let mut last_event: XEvent = uninitialized();
+ println!("xevent: getting next event!");
+ xlib::XNextEvent(display, &mut last_event);
+ last_event
+ }
+}
+
+// Window code.
+
+/// Get a list from the active windows. This doesn't generate a hierarchical
+/// struture, so it may change on the future.
+pub fn window_list(display: *mut Display) -> &'static [Window] {
+ let mut root: Window = 0;
+ let mut parent: Window = 0;
+ let mut children_count: u32 = 0;
+ unsafe {
+ let root_window = XDefaultRootWindow(display);
+ let mut children: *mut Window = uninitialized();
+ XQueryTree(display, root_window,
+ &mut root, &mut parent,
+ &mut children, &mut children_count);
+ slice::from_raw_parts(children as *const Window, children_count as usize)
+ }
+}
+
+fn screen_ratio(d: *mut Display) -> f32 {
+ let screen: xlib::Screen = unsafe {
+ let scrptr = xlib::XDefaultScreenOfDisplay(d);
+ ptr::read(scrptr)
+ };
+
+ screen.height as f32 / screen.width as f32
+}
+
+/// Get certain color from the display.
+///
+/// # Example.
+///
+/// This function can be called with a &str
+///
+/// ```
+/// get_color(display, "red");
+/// ```
+fn get_color<T: Into<Vec<u8>>>(display: *mut Display, color: T) -> u64{
+ let screen_num = unsafe { xlib::XDefaultScreen(display) };
+ let colormap = unsafe { xlib::XDefaultColormap(display, screen_num) };
+ unsafe {
+ let mut xcolor: xlib::XColor = uninitialized();
+ let cstr = CString::new(color).unwrap();
+ xlib::XAllocNamedColor(display, colormap, cstr.as_ptr(),
+ &mut xcolor, &mut xcolor);
+
+ xcolor.pixel
+ }
+}
+
+/// Get the keysym for the given event.
+pub fn lookup_keysym(ev: &mut XKeyEvent) -> xlib::KeySym {
+ unsafe { xlib::XLookupKeysym(ev, 0) }
+}