Skip to content

Commit

Permalink
Merge pull request #40 from neXromancers/x11rb
Browse files Browse the repository at this point in the history
Port to x11rb
  • Loading branch information
9ary authored Jun 13, 2023
2 parents f023e9a + d2c35e2 commit e7cdd55
Show file tree
Hide file tree
Showing 8 changed files with 381 additions and 310 deletions.
1 change: 0 additions & 1 deletion .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ jobs:
- uses: actions/checkout@v3
- name: Setup environment
run: |
sudo apt-get install libx11-dev libxrandr-dev
echo "RUSTFLAGS=-D warnings" >> $GITHUB_ENV
- name: rustfmt
run: cargo fmt -- --check
Expand Down
116 changes: 104 additions & 12 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 4 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,13 @@ edition = "2018"
[dependencies]
getopts = "0.2"
num-traits = "0.2"
nom = "7.1.3"

[dependencies.image]
default-features = false
version = "0.24.6"
features = ["png", "pnm"]

[dependencies.x11]
version = "2.21.0"
features = ["xlib", "xrandr"]
[dependencies.x11rb]
version = "0.11.1"
features = ["randr"]
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,7 @@ Summary
## Installation

- From source:
- install a recent Rust toolchain, libx11 and libxrandr (depending on your
distribution, you may need to install development headers separately)
- install a recent Rust toolchain
- clone this repository and run `cargo install --path .`
- or install from [crates.io](https://crates.io/crates/shotgun):
`cargo install shotgun`
Expand Down
4 changes: 0 additions & 4 deletions shell.nix
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,5 @@ in pkgs.mkShell {
p.rustc
p.rustfmt
p.clippy

p.xorg.libX11
p.xorg.libXrandr
p.pkgconfig
];
}
25 changes: 14 additions & 11 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

use std::env;
use std::ffi::CString;
use std::fs::File;
use std::io;
use std::path::Path;
Expand All @@ -17,7 +16,7 @@ use image::GenericImageView;
use image::ImageOutputFormat;
use image::Rgba;
use image::RgbaImage;
use x11::xlib;
use x11rb::protocol::xproto;

mod util;
mod xwrap;
Expand Down Expand Up @@ -79,10 +78,10 @@ fn run() -> i32 {
return 1;
}
};
let root = display.get_default_root();
let root = display.root();

let window = match matches.opt_str("i") {
Some(s) => match util::parse_int::<xlib::Window>(&s) {
Some(s) => match util::parse_int::<xproto::Window>(&s) {
Ok(r) => r,
Err(_) => {
eprintln!("Window ID is not a valid integer");
Expand All @@ -106,7 +105,13 @@ fn run() -> i32 {
}
};

let window_rect = display.get_window_rect(window);
let window_rect = match display.get_window_geometry(window) {
Some(r) => r,
None => {
eprintln!("Failed to get window geometry");
return 1;
}
};

if matches.opt_present("s") {
if matches.opt_present("g") {
Expand All @@ -120,9 +125,7 @@ fn run() -> i32 {
}

let mut sel = match matches.opt_str("g") {
Some(s) => match xwrap::parse_geometry(CString::new(s).expect("Failed to convert CString"))
.intersection(window_rect)
{
Some(s) => match util::parse_geometry(&s).and_then(|g| g.intersection(window_rect)) {
Some(sel) => util::Rect {
// Selection is relative to the root window (whole screen)
x: sel.x - window_rect.x,
Expand All @@ -143,16 +146,16 @@ fn run() -> i32 {
},
};

let screen_rects: Vec<util::Rect> = match display.get_screen_rects(root) {
Some(r) => r.collect(),
let screen_rects = match display.get_screen_rects() {
Some(r) => r,
None => {
eprintln!("Failed to get screen rects");
return 1;
}
};

if matches.opt_present("s") {
let cursor = match display.get_cursor_position(root) {
let cursor = match display.get_cursor_position() {
Some(c) => c,
None => {
eprintln!("Failed to get cursor position");
Expand Down
74 changes: 73 additions & 1 deletion src/util.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::cmp;

#[derive(Copy, Clone, Debug)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct Rect {
pub x: i32,
pub y: i32,
Expand Down Expand Up @@ -67,3 +67,75 @@ where
P::COLOR_TYPE,
)
}

mod parse_geometry {
use crate::util;

use nom::bytes::complete as bytes;
use nom::character::complete as chr;
use nom::combinator as comb;
use nom::sequence as seq;

fn equal_sign(i: &str) -> nom::IResult<&str, char> {
chr::char('=')(i)
}

fn x_sign(i: &str) -> nom::IResult<&str, char> {
chr::one_of("xX")(i)
}

fn integer(i: &str) -> nom::IResult<&str, i32> {
comb::map_res(
// Limit to 5 digits - X11 uses i16 and u16 for position and size,
// and this fits comfortably into our i32 Rects.
bytes::take_while_m_n(1, 5, |c: char| c.is_ascii_digit()),
str::parse,
)(i)
}

fn sign(i: &str) -> nom::IResult<&str, i32> {
comb::map(chr::one_of("-+"), |s| if s == '-' { -1 } else { 1 })(i)
}

fn signed_integer(i: &str) -> nom::IResult<&str, i32> {
comb::map(seq::pair(sign, integer), |(s, m)| s * m)(i)
}

/// Parse a string of the form `=<width>x<height>{+-}<xoffset>{+-}<yoffset>` into a [`util::Rect`].
pub fn parse_geometry(g: &str) -> Option<util::Rect> {
let (remainder, (_, w, _, h, x, y)) = seq::tuple((
comb::opt(equal_sign),
integer,
x_sign,
integer,
signed_integer,
signed_integer,
))(g)
.ok()?;

if !remainder.is_empty() {
return None;
}

Some(util::Rect { w, h, x, y })
}

#[cfg(test)]
mod test {
use super::*;

#[test]
fn test_parse_geometry() {
let res = Some(util::Rect {
w: 80,
h: 24,
x: 300,
y: -49,
});
assert_eq!(parse_geometry("=80x24+300-49"), res);
assert_eq!(parse_geometry("80x24+300-49"), res);
}
}
}

pub use parse_geometry::parse_geometry;
Loading

0 comments on commit e7cdd55

Please sign in to comment.