From b3c20c530965cb0971db32b52a8faa2f588c0edb Mon Sep 17 00:00:00 2001 From: Julian Orth Date: Sat, 30 Jul 2022 11:14:16 +0200 Subject: [PATCH] wayland: add jay_pointer --- src/cursor.rs | 6 ++- src/ifs.rs | 1 + src/ifs/jay_compositor.rs | 19 +++++++- src/ifs/jay_pointer.rs | 76 +++++++++++++++++++++++++++++++ src/ifs/wl_seat.rs | 1 + src/ifs/wl_seat/event_handling.rs | 2 +- wire/jay_compositor.txt | 5 ++ wire/jay_pointer.txt | 9 ++++ 8 files changed, 115 insertions(+), 4 deletions(-) create mode 100644 src/ifs/jay_pointer.rs create mode 100644 wire/jay_pointer.txt diff --git a/src/cursor.rs b/src/cursor.rs index eedd0dd7..acaa021a 100644 --- a/src/cursor.rs +++ b/src/cursor.rs @@ -13,6 +13,7 @@ use { bstr::{BStr, BString, ByteSlice, ByteVec}, byteorder::{LittleEndian, ReadBytesExt}, isnt::std_1::primitive::IsntSliceExt, + num_derive::FromPrimitive, std::{ cell::Cell, convert::TryInto, @@ -56,6 +57,7 @@ pub trait Cursor { pub struct ServerCursors { pub default: ServerCursorTemplate, + pub pointer: ServerCursorTemplate, pub resize_right: ServerCursorTemplate, pub resize_left: ServerCursorTemplate, pub resize_top: ServerCursorTemplate, @@ -68,9 +70,10 @@ pub struct ServerCursors { pub resize_bottom_right: ServerCursorTemplate, } -#[derive(Copy, Clone, Debug, Eq, PartialEq)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, FromPrimitive)] pub enum KnownCursor { Default, + Pointer, ResizeLeftRight, ResizeTopBottom, ResizeTopLeft, @@ -92,6 +95,7 @@ impl ServerCursors { |name: &str| ServerCursorTemplate::load(name, None, &scales, &sizes, &paths, ctx); Ok(Some(Self { default: load("left_ptr")?, + pointer: load("hand2")?, // default: load("left_ptr_watch")?, resize_right: load("right_side")?, resize_left: load("left_side")?, diff --git a/src/ifs.rs b/src/ifs.rs index 171a10b8..57a16714 100644 --- a/src/ifs.rs +++ b/src/ifs.rs @@ -5,6 +5,7 @@ pub mod jay_compositor; pub mod jay_idle; pub mod jay_log_file; pub mod jay_output; +pub mod jay_pointer; pub mod jay_screenshot; pub mod jay_seat_events; pub mod org_kde_kwin_server_decoration; diff --git a/src/ifs/jay_compositor.rs b/src/ifs/jay_compositor.rs index 8a3cf001..084c5839 100644 --- a/src/ifs/jay_compositor.rs +++ b/src/ifs/jay_compositor.rs @@ -5,7 +5,7 @@ use { globals::{Global, GlobalName}, ifs::{ jay_idle::JayIdle, jay_log_file::JayLogFile, jay_output::JayOutput, - jay_screenshot::JayScreenshot, jay_seat_events::JaySeatEvents, + jay_pointer::JayPointer, jay_screenshot::JayScreenshot, jay_seat_events::JaySeatEvents, }, leaks::Tracker, object::Object, @@ -246,6 +246,20 @@ impl JayCompositor { } Ok(()) } + + fn get_pointer(&self, parser: MsgParser<'_, '_>) -> Result<(), JayCompositorError> { + let req: GetPointer = self.client.parse(self, parser)?; + let seat = self.client.lookup(req.seat)?; + let ctx = Rc::new(JayPointer { + id: req.id, + client: self.client.clone(), + seat: seat.global.clone(), + tracker: Default::default(), + }); + track!(self.client, ctx); + self.client.add_client_obj(&ctx)?; + Ok(()) + } } object_base! { @@ -263,11 +277,12 @@ object_base! { GET_SEATS => get_seats, SEAT_EVENTS => seat_events, GET_OUTPUT => get_output, + GET_POINTER => get_pointer, } impl Object for JayCompositor { fn num_requests(&self) -> u32 { - GET_OUTPUT + 1 + GET_POINTER + 1 } } diff --git a/src/ifs/jay_pointer.rs b/src/ifs/jay_pointer.rs new file mode 100644 index 00000000..2e31357f --- /dev/null +++ b/src/ifs/jay_pointer.rs @@ -0,0 +1,76 @@ +use { + crate::{ + client::{Client, ClientError}, + cursor::KnownCursor, + ifs::wl_seat::WlSeatGlobal, + leaks::Tracker, + object::Object, + utils::buffd::{MsgParser, MsgParserError}, + wire::{jay_pointer::*, JayPointerId}, + }, + num_traits::FromPrimitive, + std::rc::Rc, + thiserror::Error, +}; + +pub struct JayPointer { + pub id: JayPointerId, + pub client: Rc, + pub seat: Rc, + pub tracker: Tracker, +} + +impl JayPointer { + fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), JayPointerError> { + let _req: Destroy = self.client.parse(self, parser)?; + self.client.remove_obj(self)?; + Ok(()) + } + + fn set_known_cursor(&self, parser: MsgParser<'_, '_>) -> Result<(), JayPointerError> { + let req: SetKnownCursor = self.client.parse(self, parser)?; + let cursor = match KnownCursor::from_u32(req.idx) { + Some(c) => c, + _ => return Err(JayPointerError::OutOfBounds), + }; + let pointer_node = match self.seat.pointer_node() { + Some(n) => n, + _ => { + // cannot happen + return Ok(()); + } + }; + if pointer_node.node_client_id() != Some(self.client.id) { + return Ok(()); + } + self.seat.set_known_cursor(cursor); + Ok(()) + } +} + +object_base! { + JayPointer; + + DESTROY => destroy, + SET_KNOWN_CURSOR => set_known_cursor, +} + +impl Object for JayPointer { + fn num_requests(&self) -> u32 { + SET_KNOWN_CURSOR + 1 + } +} + +simple_add_obj!(JayPointer); + +#[derive(Debug, Error)] +pub enum JayPointerError { + #[error("Parsing failed")] + MsgParserError(Box), + #[error(transparent)] + ClientError(Box), + #[error("Cursor index is out of bounds")] + OutOfBounds, +} +efrom!(JayPointerError, MsgParserError); +efrom!(JayPointerError, ClientError); diff --git a/src/ifs/wl_seat.rs b/src/ifs/wl_seat.rs index 9b07eab6..9f89b8a2 100644 --- a/src/ifs/wl_seat.rs +++ b/src/ifs/wl_seat.rs @@ -775,6 +775,7 @@ impl WlSeatGlobal { }; let tpl = match cursor { KnownCursor::Default => &cursors.default, + KnownCursor::Pointer => &cursors.pointer, KnownCursor::ResizeLeftRight => &cursors.resize_left_right, KnownCursor::ResizeTopBottom => &cursors.resize_top_bottom, KnownCursor::ResizeTopLeft => &cursors.resize_top_left, diff --git a/src/ifs/wl_seat/event_handling.rs b/src/ifs/wl_seat/event_handling.rs index de22e181..c565049e 100644 --- a/src/ifs/wl_seat/event_handling.rs +++ b/src/ifs/wl_seat/event_handling.rs @@ -375,7 +375,7 @@ impl WlSeatGlobal { } impl WlSeatGlobal { - pub(super) fn pointer_node(&self) -> Option> { + pub fn pointer_node(&self) -> Option> { self.pointer_stack.borrow().last().cloned() } diff --git a/wire/jay_compositor.txt b/wire/jay_compositor.txt index 16d7e600..f0f0144e 100644 --- a/wire/jay_compositor.txt +++ b/wire/jay_compositor.txt @@ -48,6 +48,11 @@ msg get_output = 11 { output: id(wl_output), } +msg get_pointer = 12 { + id: id(jay_pointer), + seat: id(wl_seat), +} + # events msg client_id = 0 { diff --git a/wire/jay_pointer.txt b/wire/jay_pointer.txt new file mode 100644 index 00000000..a4d81561 --- /dev/null +++ b/wire/jay_pointer.txt @@ -0,0 +1,9 @@ +# requests + +msg destroy = 0 { + +} + +msg set_known_cursor = 1 { + idx: u32, +}