Skip to content

Commit

Permalink
Use xcursor-rs for cursor file parsing
Browse files Browse the repository at this point in the history
Instead of reinventing the wheel, let's use an existing wheel for the
same job: Parsing cursor files.

This is a first step towards #934. Besides cursor file parsing,
xcursor-rs also provides parsing of cursor theme files. For now, this is
still left with our own implementation, so this commit does not yet
close #934.

Step-towards: #934
Signed-off-by: Uli Schlachter <[email protected]>
  • Loading branch information
psychon committed Aug 15, 2024
1 parent 3e6b5ea commit d0ed9db
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 504 deletions.
3 changes: 2 additions & 1 deletion x11rb/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ once_cell = { version = "1.19", optional = true }
as-raw-xcb-connection = { version = "1.0", optional = true }
tracing = { version = "0.1", optional = true, default-features = false }
rustix = { version = "0.38", default-features = false, features = ["std", "event", "fs", "net", "system"] }
xcursor = { version = "0.3.7", optional = true }

[target.'cfg(not(unix))'.dependencies]
gethostname = "0.4"
Expand All @@ -37,7 +38,7 @@ tracing-subscriber = "0.3"
allow-unsafe-code = ["libc", "as-raw-xcb-connection"]

# Enable utility functions in `x11rb::cursor` for loading mouse cursors.
cursor = ["render", "resource_manager"]
cursor = ["render", "resource_manager", "xcursor"]

# Enable utility functions in `x11rb::image` for working with image data.
image = []
Expand Down
32 changes: 22 additions & 10 deletions x11rb/src/cursor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use crate::protocol::render::{self, Pictformat};
use crate::protocol::xproto::{self, Font, Window};
use crate::resource_manager::Database;
use crate::NONE;
use xcursor::parser::Image;

use std::fs::File;

Expand Down Expand Up @@ -217,13 +218,20 @@ fn create_core_cursor<C: Connection>(
fn create_render_cursor<C: Connection>(
conn: &C,
handle: &Handle,
image: &parse_cursor::Image,
image: &Image,
storage: &mut Option<(xproto::Pixmap, xproto::Gcontext, u16, u16)>,
) -> Result<render::Animcursorelt, ReplyOrIdError> {
let to_u16 = |input: u32| {
u16::try_from(input).expect(
"xcursor-rs has a 16 bit limit on cursor size, but some number does not fit into u16?!",
)
};

let (cursor, picture) = (conn.generate_id()?, conn.generate_id()?);
let (width, height) = (to_u16(image.width), to_u16(image.height));

// Get a pixmap of the right size and a gc for it
let (pixmap, gc) = if storage.map(|(_, _, w, h)| (w, h)) == Some((image.width, image.height)) {
let (pixmap, gc) = if storage.map(|(_, _, w, h)| (w, h)) == Some((width, height)) {
storage.map(|(pixmap, gc, _, _)| (pixmap, gc)).unwrap()
} else {
let (pixmap, gc) = if let Some((pixmap, gc, _, _)) = storage {
Expand All @@ -233,27 +241,25 @@ fn create_render_cursor<C: Connection>(
} else {
(conn.generate_id()?, conn.generate_id()?)
};
let _ = xproto::create_pixmap(conn, 32, pixmap, handle.root, image.width, image.height)?;
let _ = xproto::create_pixmap(conn, 32, pixmap, handle.root, width, height)?;
let _ = xproto::create_gc(conn, gc, pixmap, &Default::default())?;

*storage = Some((pixmap, gc, image.width, image.height));
*storage = Some((pixmap, gc, width, height));
(pixmap, gc)
};

// Sigh. We need the pixel data as a bunch of bytes.
let pixels = crate::x11_utils::Serialize::serialize(&image.pixels[..]);
let _ = xproto::put_image(
conn,
xproto::ImageFormat::Z_PIXMAP,
pixmap,
gc,
image.width,
image.height,
width,
height,
0,
0,
0,
32,
&pixels,
&image.pixels_rgba,
)?;

let _ = render::create_picture(
Expand All @@ -263,7 +269,13 @@ fn create_render_cursor<C: Connection>(
handle.picture_format,
&Default::default(),
)?;
let _ = render::create_cursor(conn, cursor, picture, image.x_hot, image.y_hot)?;
let _ = render::create_cursor(
conn,
cursor,
picture,
to_u16(image.xhot),
to_u16(image.yhot),
)?;
let _ = render::free_picture(conn, picture)?;

Ok(render::Animcursorelt {
Expand Down
Loading

0 comments on commit d0ed9db

Please sign in to comment.