aboutsummaryrefslogtreecommitdiff
path: root/src/safe_x11
diff options
context:
space:
mode:
Diffstat (limited to 'src/safe_x11')
-rw-r--r--src/safe_x11/mod.rs7
-rw-r--r--src/safe_x11/window.rs97
2 files changed, 94 insertions, 10 deletions
diff --git a/src/safe_x11/mod.rs b/src/safe_x11/mod.rs
index 9e5859a..03c54d8 100644
--- a/src/safe_x11/mod.rs
+++ b/src/safe_x11/mod.rs
@@ -16,9 +16,11 @@ use x11::xlib::{
XEvent,
XNextEvent,
+ XDefaultGC,
// Windows
Window,
+ GC,
Atom, XInternAtom,
};
@@ -226,6 +228,11 @@ fn get_color<T: Into<Vec<u8>>>(display: *mut Display, color: T) -> u64{
}
}
+fn default_gc(display: *mut Display) -> GC {
+ let screen_num = unsafe { xlib::XDefaultScreen(display) };
+ unsafe { XDefaultGC(display, screen_num) }
+}
+
/// Get the keysym for the given event.
pub fn lookup_keysym(ev: &mut XKeyEvent) -> xlib::KeySym {
unsafe { xlib::XLookupKeysym(ev, 0) }
diff --git a/src/safe_x11/window.rs b/src/safe_x11/window.rs
index 78b73f7..c889dfc 100644
--- a/src/safe_x11/window.rs
+++ b/src/safe_x11/window.rs
@@ -23,19 +23,22 @@ use x11::xlib::{
XChangeWindowAttributes, XSetWindowAttributes,
XMapWindow, XUnmapWindow,
+
+ XBlackPixel,XWhitePixel, XDrawString,
};
use std::ptr;
use std::mem::uninitialized;
use std::mem::transmute;
use std::cmp::{max};
+use std::ffi::CString;
use safe_x11::{screen_ratio,get_color};
/// Representation of [`xlib::Window`](../../x11/xlib/type.Window.html)
pub struct XWindow {
display: *mut xlib::Display,
- /// xlib::Window that wraps this struct.
+ // The Application window.
pub inner: Window,
fullscreen: bool,
prev_attribs: XWindowAttributes,
@@ -47,12 +50,21 @@ fn fixed_with_ratio(x: i32, ratio: f32) -> i32 {
fixed as i32
}
+fn window_attribs(display: *mut xlib::Display, w: Window) -> XWindowAttributes {
+ unsafe {
+ let mut attrptr: XWindowAttributes = uninitialized();
+ XGetWindowAttributes(display, w, &mut attrptr);
+ attrptr
+ }
+}
+
impl XWindow {
/// Generate a reference to the window in certain display. This will return
/// `None` if the window is the root window.
pub fn new(d: *mut xlib::Display, w: Window) -> Option<XWindow> {
if w != 0 {
let attrs: XWindowAttributes = unsafe { uninitialized() };
+ println!("Window created!");
Some(XWindow {
display: d,
inner: w,
@@ -73,6 +85,7 @@ impl XWindow {
/// the user selected "delete window" from a hypothetical menu and
/// also perform any confirmation dialog with the user.
pub fn delete(&self) {
+ // First delete the border window and then the main window.
let mut ev: XClientMessageEvent = unsafe { uninitialized() };
ev.type_ = ClientMessage;
ev.window = self.inner;
@@ -95,7 +108,9 @@ impl XWindow {
/// Raises a window.
pub fn raise(&self) {
- unsafe { xlib::XRaiseWindow(self.display, self.inner); }
+ unsafe {
+ xlib::XRaiseWindow(self.display, self.inner);
+ }
}
/// Register input events on some [`xlib::Window`](../../x11/xlib/type.Window.html)
@@ -120,11 +135,7 @@ impl XWindow {
/// Returns the window attributes from certain window.
pub fn attributes(&self) -> XWindowAttributes {
- unsafe {
- let mut attrptr: XWindowAttributes = uninitialized();
- XGetWindowAttributes(self.display, self.inner, &mut attrptr);
- attrptr
- }
+ window_attribs(self.display, self.inner)
}
/// Moves the window given an offset from where it is.
@@ -148,15 +159,64 @@ impl XWindow {
if 0 > x && x <= screen.width || 0 > y && y <= screen.height {
Err("Cannot move the window outside the screen!")
} else {
- unsafe { XMoveWindow(self.display, self.inner, x, y) };
+ unsafe {
+ XMoveWindow(self.display, self.inner, x, y);
+ };
Ok(())
}
}
+ // Some functions for moving within some boundaries.
+
+ /// Move sticky to the left.
+ pub fn move_sticky_left(&self, boundaries: &[i32]) {
+ let attrs = self.attributes();
+ if let Some(v) = boundaries.iter()
+ .skip_while(|&a| *a >= attrs.x)
+ .next() {
+ let _ = self.move_to(*v, attrs.y);
+ }
+ }
+
+ /// Move sticky to the right.
+ pub fn move_sticky_right(&self, boundaries: &[i32]) {
+ let attrs = self.attributes();
+ let win_bound = attrs.x + attrs.width;
+
+ if let Some(v) = boundaries.iter()
+ .skip_while(|&a| *a <= win_bound)
+ .next() {
+ let _ = self.move_to(*v - attrs.width, attrs.y);
+ }
+ }
+
+ /// Move up sticky.
+ pub fn move_sticky_up(&self, boundaries: &[i32]) {
+ let attrs = self.attributes();
+
+ if let Some(v) = boundaries.iter()
+ .skip_while(|&a| *a >= attrs.y)
+ .next() {
+ let _ = self.move_to(attrs.x, *v);
+ }
+ }
+
+ /// Move down sticky.
+ pub fn move_sticky_down(&self, boundaries: &[i32]) {
+ let attrs = self.attributes();
+ let win_bound = attrs.y + attrs.height;
+
+ if let Some(v) = boundaries.iter()
+ .skip_while(|&a| *a <= win_bound)
+ .next() {
+ let _ = self.move_to(attrs.x, *v - attrs.height);
+ }
+ }
+
/// Move and resize the window in one step
pub fn move_resize(&self, x:i32, y: i32, w: u32, h: u32) {
unsafe {
- XMoveResizeWindow(self.display, self.inner, x, y, w, h);
+ XMoveResizeWindow(self.display, self.inner, x, y, w, h as u32);
}
}
@@ -168,7 +228,7 @@ impl XWindow {
let ww: u32 = max(1, (attrs.width + fixed_with_ratio(w, ratio)) as u32);
let wh: u32 = max(1, (attrs.height + fixed_with_ratio(h, ratio)) as u32);
xlib::XResizeWindow(self.display, self.inner,
- ww, wh);
+ ww, wh as u32);
}
}
@@ -245,6 +305,23 @@ impl XWindow {
}
}
+ pub fn draw_string<T: Into<Vec<u8>>>(&self, s: T) {
+ // Title :D
+ println!("Drawing string for {}", self.inner);
+ let cstr = CString::new(s).unwrap();
+ unsafe {
+ let gc = xlib::XCreateGC(self.display, self.inner, 0, ptr::null_mut());
+ xlib::XSetForeground(self.display, gc, XWhitePixel(self.display, 0));
+ xlib::XSetBackground(self.display, gc, XBlackPixel(self.display, 0));
+ println!("Loading fixed");
+ let font: xlib::XFontStruct = ptr::read(xlib::XLoadQueryFont(self.display, CString::new("fixed").unwrap().as_ptr()));
+ xlib::XSetFont(self.display, gc, font.fid);
+ xlib::XClearWindow(self.display, self.inner);
+ XDrawString(self.display, self.inner, gc,
+ 3, 10, cstr.as_ptr(), cstr.to_bytes().len() as i32);
+ }
+ }
+
pub fn map(&self) {
unsafe { XMapWindow(self.display, self.inner); }
}