Compare commits
4 Commits
614b9881d2
...
3da8e4d1a5
Author | SHA1 | Date |
---|---|---|
expectocode | 3da8e4d1a5 | |
expectocode | 3d4ac326d4 | |
expectocode | c4650e8158 | |
expectocode | 24e977748e |
|
@ -4,4 +4,4 @@ version = "0.1.0"
|
||||||
authors = ["expectocode <expectocode@gmail.com>"]
|
authors = ["expectocode <expectocode@gmail.com>"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
xcb = {version = "0.8.2", features = ["xkb"]}
|
xcb = {version = "0.8.2", features = ["xkb", "shape"]}
|
||||||
|
|
129
src/main.rs
129
src/main.rs
|
@ -1,4 +1,58 @@
|
||||||
extern crate xcb;
|
extern crate xcb;
|
||||||
|
use std::cmp::{max, min};
|
||||||
|
use xcb::shape;
|
||||||
|
|
||||||
|
const LINE_WIDTH: u16 = 3;
|
||||||
|
|
||||||
|
fn set_shape(conn: &xcb::Connection, window: xcb::Window, rects: &[xcb::Rectangle]) {
|
||||||
|
shape::rectangles(
|
||||||
|
&conn,
|
||||||
|
shape::SO_SET as u8,
|
||||||
|
shape::SK_BOUNDING as u8,
|
||||||
|
0,
|
||||||
|
window,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
&rects,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_title(conn: &xcb::Connection, window: xcb::Window, title: &str) {
|
||||||
|
xcb::change_property(
|
||||||
|
&conn,
|
||||||
|
xcb::PROP_MODE_REPLACE as u8,
|
||||||
|
window,
|
||||||
|
xcb::ATOM_WM_NAME,
|
||||||
|
xcb::ATOM_STRING,
|
||||||
|
8,
|
||||||
|
title.as_bytes(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn grab_pointer_set_cursor(conn: &xcb::Connection, window: xcb::Window, screen: xcb::Screen) {
|
||||||
|
let font = conn.generate_id();
|
||||||
|
xcb::open_font(&conn, font, "cursor");
|
||||||
|
|
||||||
|
// TODO: create cursor with a Pixmap
|
||||||
|
// https://stackoverflow.com/questions/40578969/how-to-create-a-cursor-in-x11-from-raw-data-c
|
||||||
|
let cursor = conn.generate_id();
|
||||||
|
xcb::create_glyph_cursor(&conn, cursor, font, font, 0, 30, 0, 0, 0, 0, 0, 0);
|
||||||
|
|
||||||
|
xcb::grab_pointer(
|
||||||
|
&conn,
|
||||||
|
true,
|
||||||
|
screen.root(),
|
||||||
|
(xcb::EVENT_MASK_BUTTON_RELEASE
|
||||||
|
| xcb::EVENT_MASK_BUTTON_PRESS
|
||||||
|
| xcb::EVENT_MASK_BUTTON_MOTION) as u16,
|
||||||
|
xcb::GRAB_MODE_ASYNC as u8,
|
||||||
|
xcb::GRAB_MODE_ASYNC as u8,
|
||||||
|
xcb::NONE,
|
||||||
|
cursor,
|
||||||
|
xcb::CURRENT_TIME,
|
||||||
|
).get_reply()
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let (conn, screen_num) = xcb::Connection::connect(None).unwrap();
|
let (conn, screen_num) = xcb::Connection::connect(None).unwrap();
|
||||||
|
@ -23,53 +77,23 @@ fn main() {
|
||||||
xcb::COPY_FROM_PARENT as u8,
|
xcb::COPY_FROM_PARENT as u8,
|
||||||
window,
|
window,
|
||||||
screen.root(),
|
screen.root(),
|
||||||
0, // x
|
0, // x
|
||||||
0, // y
|
0, // y
|
||||||
0, // width
|
screen.width_in_pixels(), // width
|
||||||
0, // height
|
screen.height_in_pixels(), // height
|
||||||
0,
|
0,
|
||||||
xcb::WINDOW_CLASS_INPUT_OUTPUT as u16,
|
xcb::WINDOW_CLASS_INPUT_OUTPUT as u16,
|
||||||
screen.root_visual(),
|
screen.root_visual(),
|
||||||
&values,
|
&values,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
set_title(&conn, window, "hacksaw");
|
||||||
|
grab_pointer_set_cursor(&conn, window, screen);
|
||||||
|
|
||||||
|
set_shape(&conn, window, &[xcb::Rectangle::new(0, 0, 0, 0)]);
|
||||||
|
|
||||||
xcb::map_window(&conn, window);
|
xcb::map_window(&conn, window);
|
||||||
|
|
||||||
let title = "hacksaw";
|
|
||||||
// setting title
|
|
||||||
xcb::change_property(
|
|
||||||
&conn,
|
|
||||||
xcb::PROP_MODE_REPLACE as u8,
|
|
||||||
window,
|
|
||||||
xcb::ATOM_WM_NAME,
|
|
||||||
xcb::ATOM_STRING,
|
|
||||||
8,
|
|
||||||
title.as_bytes(),
|
|
||||||
);
|
|
||||||
|
|
||||||
let font = conn.generate_id();
|
|
||||||
xcb::open_font(&conn, font, "cursor");
|
|
||||||
|
|
||||||
// TODO: create cursor with a Pixmap
|
|
||||||
// https://stackoverflow.com/questions/40578969/how-to-create-a-cursor-in-x11-from-raw-data-c
|
|
||||||
let cursor = conn.generate_id();
|
|
||||||
xcb::create_glyph_cursor(&conn, cursor, font, font, 0, 30, 0, 0, 0, 0, 0, 0);
|
|
||||||
|
|
||||||
xcb::grab_pointer(
|
|
||||||
&conn,
|
|
||||||
true,
|
|
||||||
screen.root(),
|
|
||||||
(xcb::EVENT_MASK_BUTTON_RELEASE
|
|
||||||
| xcb::EVENT_MASK_BUTTON_PRESS
|
|
||||||
| xcb::EVENT_MASK_BUTTON_MOTION) as u16,
|
|
||||||
xcb::GRAB_MODE_ASYNC as u8,
|
|
||||||
xcb::GRAB_MODE_ASYNC as u8,
|
|
||||||
xcb::NONE,
|
|
||||||
cursor,
|
|
||||||
xcb::CURRENT_TIME,
|
|
||||||
).get_reply()
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
conn.flush();
|
conn.flush();
|
||||||
|
|
||||||
// TODO formalise the fact that motion comes after press?
|
// TODO formalise the fact that motion comes after press?
|
||||||
|
@ -79,6 +103,9 @@ fn main() {
|
||||||
let mut x = 0;
|
let mut x = 0;
|
||||||
let mut y = 0;
|
let mut y = 0;
|
||||||
|
|
||||||
|
let mut width = 0;
|
||||||
|
let mut height = 0;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let ev = conn.wait_for_event().unwrap();
|
let ev = conn.wait_for_event().unwrap();
|
||||||
match ev.response_type() {
|
match ev.response_type() {
|
||||||
|
@ -105,7 +132,24 @@ fn main() {
|
||||||
let motion: &xcb::MotionNotifyEvent = unsafe { xcb::cast_event(&ev) };
|
let motion: &xcb::MotionNotifyEvent = unsafe { xcb::cast_event(&ev) };
|
||||||
x = motion.event_x();
|
x = motion.event_x();
|
||||||
y = motion.event_y();
|
y = motion.event_y();
|
||||||
// TODO draw rectangles (and guides)
|
|
||||||
|
// TODO investigate efficiency of let mut outside loop vs let inside
|
||||||
|
let top_x = min(x, start_x);
|
||||||
|
let top_y = min(y, start_y);
|
||||||
|
let bot_x = max(x, start_x);
|
||||||
|
let bot_y = max(y, start_y);
|
||||||
|
|
||||||
|
width = (x - start_x).abs() as u16;
|
||||||
|
height = (y - start_y).abs() as u16;
|
||||||
|
|
||||||
|
let rects = [
|
||||||
|
xcb::Rectangle::new(top_x, top_y, LINE_WIDTH, height),
|
||||||
|
xcb::Rectangle::new(top_x, top_y, width, LINE_WIDTH),
|
||||||
|
xcb::Rectangle::new(bot_x, top_y, LINE_WIDTH, height),
|
||||||
|
xcb::Rectangle::new(top_x, bot_y, width, LINE_WIDTH),
|
||||||
|
];
|
||||||
|
set_shape(&conn, window, &rects);
|
||||||
|
conn.flush();
|
||||||
}
|
}
|
||||||
xcb::BUTTON_RELEASE => {
|
xcb::BUTTON_RELEASE => {
|
||||||
let motion: &xcb::ButtonReleaseEvent = unsafe { xcb::cast_event(&ev) };
|
let motion: &xcb::ButtonReleaseEvent = unsafe { xcb::cast_event(&ev) };
|
||||||
|
@ -115,15 +159,10 @@ fn main() {
|
||||||
_ => break, // Move on after mouse released
|
_ => break, // Move on after mouse released
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
xcb::EXPOSE => {
|
|
||||||
println!("expose!");
|
|
||||||
}
|
|
||||||
_ => continue,
|
_ => continue,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now we have taken coordinates, we use them
|
// Now we have taken coordinates, we use them
|
||||||
let width = (x - start_x).abs();
|
|
||||||
let height = (y - start_y).abs();
|
|
||||||
println!("{}x{}+{}+{}", width, height, start_x, start_y);
|
println!("{}x{}+{}+{}", width, height, start_x, start_y);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue