From e7639921efd644b4312ebca2bc83282b96cbc6b7 Mon Sep 17 00:00:00 2001 From: ShootingStarDragons Date: Thu, 7 Dec 2023 22:13:36 +0800 Subject: [PATCH] feat: load cursor from data I want to add a function to load cursor from data --- wayland-cursor/src/lib.rs | 45 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/wayland-cursor/src/lib.rs b/wayland-cursor/src/lib.rs index ff6ae747273..17c9e3c959a 100644 --- a/wayland-cursor/src/lib.rs +++ b/wayland-cursor/src/lib.rs @@ -45,7 +45,9 @@ //! # } //! ``` +use std::borrow::Cow; use std::env; +use std::fmt::Debug; use std::fs::File; use std::io::{Error as IoError, Read, Result as IoResult, Seek, SeekFrom, Write}; use std::ops::{Deref, Index}; @@ -81,6 +83,24 @@ pub struct CursorTheme { pool_size: i32, file: File, backend: WeakBackend, + fallback: Option, +} + +struct FallBack(Box Cow<'static, [u8]>>); + +impl FallBack { + fn new(fallback: F) -> Self + where + F: Fn(&str) -> Cow<'static, [u8]> + 'static, + { + Self(Box::new(fallback)) + } +} + +impl Debug for FallBack { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str("fallback function") + } } impl CursorTheme { @@ -160,23 +180,46 @@ impl CursorTheme { pool_size: INITIAL_POOL_SIZE, cursors: Vec::new(), backend: conn.backend().downgrade(), + fallback: None, }) } /// Retrieve a cursor from the theme. /// /// This method returns [`None`] if this cursor is not provided either by the theme, or by one of its parents. + /// + /// If a fallback is set, it will use the data from fallback pub fn get_cursor(&mut self, name: &str) -> Option<&Cursor> { match self.cursors.iter().position(|cursor| cursor.name == name) { Some(i) => Some(&self.cursors[i]), None => { - let cursor = self.load_cursor(name, self.size)?; + let cursor = match self.load_cursor(name, self.size) { + None => { + let Some(ref fallback) = self.fallback else { + return None; + }; + let data = fallback.0(name); + let images = xparser::parse_xcursor(&data)?; + let conn = Connection::from_backend(self.backend.upgrade()?); + Cursor::new(&conn, name, self, &images, self.size) + } + Some(cursor) => cursor, + }; self.cursors.push(cursor); self.cursors.iter().last() } } } + /// Set the set_callback, the return value of the fallback function should be the source of + /// xcursor + pub fn set_callback(&mut self, fallback: F) + where + F: Fn(&str) -> Cow<'static, [u8]> + 'static, + { + self.fallback = Some(FallBack::new(fallback)) + } + /// This function loads a cursor, parses it and pushes the images onto the shm pool. /// /// Keep in mind that if the cursor is already loaded, the function will make a duplicate.