From acb391335b04534d155ab24bdbd527f0085c0ece Mon Sep 17 00:00:00 2001 From: Julian Orth Date: Mon, 8 Apr 2024 17:37:35 +0200 Subject: [PATCH] wire: generate trait for request handling --- build/wire.rs | 138 +++++++-- src/client.rs | 2 +- src/client/error.rs | 32 +- src/client/tasks.rs | 2 +- src/ifs/ext_foreign_toplevel_handle_v1.rs | 23 +- src/ifs/ext_foreign_toplevel_list_v1.rs | 25 +- src/ifs/ext_idle_notification_v1.rs | 23 +- src/ifs/ext_idle_notifier_v1.rs | 31 +- src/ifs/ext_session_lock_manager_v1.rs | 23 +- src/ifs/ext_session_lock_v1.rs | 30 +- src/ifs/ipc/wl_data_device.rs | 22 +- src/ifs/ipc/wl_data_device_manager.rs | 24 +- src/ifs/ipc/wl_data_offer.rs | 34 +-- src/ifs/ipc/wl_data_source.rs | 28 +- src/ifs/ipc/zwlr_data_control_device_v1.rs | 25 +- src/ifs/ipc/zwlr_data_control_manager_v1.rs | 28 +- src/ifs/ipc/zwlr_data_control_offer_v1.rs | 18 +- src/ifs/ipc/zwlr_data_control_source_v1.rs | 18 +- ...zwp_primary_selection_device_manager_v1.rs | 37 +-- .../ipc/zwp_primary_selection_device_v1.rs | 22 +- src/ifs/ipc/zwp_primary_selection_offer_v1.rs | 21 +- .../ipc/zwp_primary_selection_source_v1.rs | 24 +- src/ifs/jay_compositor.rs | 165 ++++------ src/ifs/jay_idle.rs | 20 +- src/ifs/jay_input.rs | 286 ++++++++---------- src/ifs/jay_log_file.rs | 24 +- src/ifs/jay_output.rs | 30 +- src/ifs/jay_pointer.rs | 20 +- src/ifs/jay_randr.rs | 95 +++--- src/ifs/jay_render_ctx.rs | 30 +- src/ifs/jay_screencast.rs | 76 ++--- src/ifs/jay_screenshot.rs | 9 +- src/ifs/jay_seat_events.rs | 9 +- src/ifs/jay_workspace.rs | 30 +- src/ifs/jay_workspace_watcher.rs | 30 +- src/ifs/org_kde_kwin_server_decoration.rs | 29 +- .../org_kde_kwin_server_decoration_manager.rs | 24 +- src/ifs/wl_buffer.rs | 29 +- src/ifs/wl_callback.rs | 9 +- src/ifs/wl_compositor.rs | 22 +- src/ifs/wl_display.rs | 26 +- src/ifs/wl_drm.rs | 40 +-- src/ifs/wl_output.rs | 21 +- src/ifs/wl_region.rs | 32 +- src/ifs/wl_registry.rs | 14 +- src/ifs/wl_seat.rs | 86 +++--- src/ifs/wl_seat/wl_keyboard.rs | 18 +- src/ifs/wl_seat/wl_pointer.rs | 18 +- src/ifs/wl_seat/wl_touch.rs | 14 +- src/ifs/wl_seat/zwp_pointer_constraints_v1.rs | 40 ++- .../zwp_confined_pointer_v1.rs | 21 +- .../zwp_locked_pointer_v1.rs | 28 +- .../zwp_relative_pointer_manager_v1.rs | 26 +- src/ifs/wl_seat/zwp_relative_pointer_v1.rs | 17 +- src/ifs/wl_shm.rs | 19 +- src/ifs/wl_shm_pool.rs | 31 +- src/ifs/wl_subcompositor.rs | 24 +- src/ifs/wl_surface.rs | 144 ++++----- .../wl_surface/ext_session_lock_surface_v1.rs | 27 +- src/ifs/wl_surface/wl_subsurface.rs | 132 ++++---- src/ifs/wl_surface/wp_fractional_scale_v1.rs | 20 +- .../wp_linux_drm_syncobj_surface_v1.rs | 33 +- src/ifs/wl_surface/wp_tearing_control_v1.rs | 24 +- src/ifs/wl_surface/wp_viewport.rs | 28 +- .../x_surface/xwayland_surface_v1.rs | 25 +- src/ifs/wl_surface/xdg_surface.rs | 61 ++-- src/ifs/wl_surface/xdg_surface/xdg_popup.rs | 29 +- .../wl_surface/xdg_surface/xdg_toplevel.rs | 82 ++--- src/ifs/wl_surface/xwayland_shell_v1.rs | 23 +- src/ifs/wl_surface/zwlr_layer_surface_v1.rs | 60 ++-- src/ifs/wl_surface/zwp_idle_inhibitor_v1.rs | 19 +- src/ifs/wp_content_type_manager_v1.rs | 22 +- src/ifs/wp_content_type_v1.rs | 21 +- src/ifs/wp_cursor_shape_device_v1.rs | 21 +- src/ifs/wp_cursor_shape_manager_v1.rs | 26 +- src/ifs/wp_fractional_scale_manager_v1.rs | 27 +- src/ifs/wp_linux_drm_syncobj_manager_v1.rs | 31 +- src/ifs/wp_linux_drm_syncobj_timeline_v1.rs | 19 +- src/ifs/wp_presentation.rs | 23 +- src/ifs/wp_presentation_feedback.rs | 10 +- src/ifs/wp_single_pixel_buffer_manager_v1.rs | 30 +- src/ifs/wp_tearing_control_manager_v1.rs | 41 ++- src/ifs/wp_viewporter.rs | 24 +- src/ifs/xdg_activation_token_v1.rs | 42 ++- src/ifs/xdg_activation_v1.rs | 37 ++- src/ifs/xdg_positioner.rs | 57 ++-- src/ifs/xdg_toplevel_drag_manager_v1.rs | 23 +- src/ifs/xdg_toplevel_drag_v1.rs | 34 +-- src/ifs/xdg_wm_base.rs | 34 +-- src/ifs/zwlr_layer_shell_v1.rs | 29 +- src/ifs/zwlr_screencopy_frame_v1.rs | 29 +- src/ifs/zwlr_screencopy_manager_v1.rs | 38 +-- src/ifs/zwp_idle_inhibit_manager_v1.rs | 26 +- src/ifs/zwp_linux_buffer_params_v1.rs | 81 +++-- src/ifs/zwp_linux_dmabuf_feedback_v1.rs | 21 +- src/ifs/zwp_linux_dmabuf_v1.rs | 68 ++--- src/ifs/zxdg_decoration_manager_v1.rs | 32 +- src/ifs/zxdg_output_manager_v1.rs | 21 +- src/ifs/zxdg_output_v1.rs | 14 +- src/ifs/zxdg_toplevel_decoration_v1.rs | 33 +- src/macros.rs | 25 +- src/object.rs | 8 +- 102 files changed, 1621 insertions(+), 2075 deletions(-) diff --git a/build/wire.rs b/build/wire.rs index 49118699..f6d1979e 100644 --- a/build/wire.rs +++ b/build/wire.rs @@ -230,10 +230,11 @@ struct Field { struct Message { name: String, camel_name: String, + safe_name: String, id: u32, fields: Vec>, - #[allow(dead_code)] attribs: MessageAttribs, + has_reference_type: bool, } #[derive(Debug, Default)] @@ -246,22 +247,25 @@ struct Parser<'a> { tokens: &'a [Token<'a>], } +struct ParseResult { + requests: Vec>, + events: Vec>, +} + impl<'a> Parser<'a> { - fn parse(&mut self) -> Result>> { - let mut res = vec![]; - let mut requests = 0; - let mut events = 0; + fn parse(&mut self) -> Result { + let mut requests = vec![]; + let mut events = vec![]; while !self.eof() { let (line, ty) = self.expect_ident()?; - let num = match ty.as_bytes() { + let res = match ty.as_bytes() { b"request" => &mut requests, b"event" => &mut events, _ => bail!("In line {}: Unexpected entry {:?}", line, ty), }; - res.push(self.parse_message(*num)?); - *num += 1; + res.push(self.parse_message(res.len() as _)?); } - Ok(res) + Ok(ParseResult { requests, events }) } fn eof(&self) -> bool { @@ -320,14 +324,24 @@ impl<'a> Parser<'a> { while !parser.eof() { fields.push(parser.parse_field()?); } + let has_reference_type = fields.iter().any(|f| match &f.val.ty.val { + Type::OptStr | Type::Str | Type::BStr | Type::Array(..) => true, + _ => false, + }); + let safe_name = match name { + "move" => "move_", + _ => name, + }; Ok(Lined { line, val: Message { name: name.to_owned(), camel_name: to_camel(name), + safe_name: safe_name.to_string(), id, fields, attribs, + has_reference_type, }, }) })(); @@ -513,7 +527,7 @@ impl<'a> Parser<'a> { } } -fn parse_messages(s: &[u8]) -> Result>> { +fn parse_messages(s: &[u8]) -> Result { let tokens = tokenize(s)?; let mut parser = Parser { pos: 0, @@ -610,10 +624,7 @@ fn write_message_type( } fn write_message(f: &mut W, obj: &str, message: &Message) -> Result<()> { - let has_reference_type = message.fields.iter().any(|f| match &f.val.ty.val { - Type::OptStr | Type::Str | Type::BStr | Type::Array(..) => true, - _ => false, - }); + let has_reference_type = message.has_reference_type; let uppercase = message.name.to_ascii_uppercase(); writeln!(f)?; writeln!(f, " pub const {}: u32 = {};", uppercase, message.id)?; @@ -706,6 +717,99 @@ fn write_message(f: &mut W, obj: &str, message: &Message) -> Result<() Ok(()) } +fn write_request_handler( + f: &mut W, + camel_obj_name: &str, + messages: &ParseResult, +) -> Result<()> { + writeln!(f)?; + writeln!( + f, + " pub trait {camel_obj_name}RequestHandler: crate::object::Object + Sized {{" + )?; + writeln!(f, " type Error: std::error::Error;")?; + for message in &messages.requests { + let msg = &message.val; + let lt = match msg.has_reference_type { + true => "<'_>", + false => "", + }; + writeln!(f)?; + writeln!( + f, + " fn {}(&self, req: {}{lt}, _slf: &Rc) -> Result<(), Self::Error>;", + msg.safe_name, msg.camel_name + )?; + } + writeln!(f)?; + writeln!(f, " #[inline(always)]")?; + writeln!(f, " fn handle_request_impl(")?; + writeln!(f, " self: Rc,")?; + writeln!(f, " client: &crate::client::Client,")?; + writeln!(f, " req: u32,")?; + writeln!( + f, + " parser: crate::utils::buffd::MsgParser<'_, '_>," + )?; + writeln!(f, " ) -> Result<(), crate::client::ClientError> {{")?; + if messages.requests.is_empty() { + writeln!(f, " #![allow(unused_variables)]")?; + writeln!( + f, + " Err(crate::client::ClientError::InvalidMethod)" + )?; + } else { + writeln!(f, " let method;")?; + writeln!( + f, + " let error: Box = match req {{" + )?; + for message in &messages.requests { + let msg = &message.val; + write!(f, " {} ", msg.id)?; + if let Some(since) = msg.attribs.since { + write!(f, "if self.version() >= {since} ")?; + } + writeln!(f, "=> {{")?; + writeln!(f, " method = \"{}\";", msg.name)?; + writeln!( + f, + " match client.parse(&*self, parser) {{" + )?; + writeln!( + f, + " Ok(req) => match self.{}(req, &self) {{", + msg.safe_name + )?; + writeln!(f, " Ok(()) => return Ok(()),")?; + writeln!(f, " Err(e) => Box::new(e),")?; + writeln!(f, " }},")?; + writeln!( + f, + " Err(e) => Box::new(crate::client::ParserError(e))," + )?; + writeln!(f, " }}")?; + writeln!(f, " }},")?; + } + writeln!( + f, + " _ => return Err(crate::client::ClientError::InvalidMethod)," + )?; + writeln!(f, " }};")?; + writeln!( + f, + " Err(crate::client::ClientError::MethodError {{" + )?; + writeln!(f, " interface: {camel_obj_name},")?; + writeln!(f, " method,")?; + writeln!(f, " error,")?; + writeln!(f, " }})")?; + } + writeln!(f, " }}")?; + writeln!(f, " }}")?; + Ok(()) +} + fn write_file(f: &mut W, file: &DirEntry) -> Result<()> { let file_name = file.file_name(); let file_name = std::str::from_utf8(file_name.as_bytes())?; @@ -722,15 +826,13 @@ fn write_file(f: &mut W, file: &DirEntry) -> Result<()> { )?; let contents = std::fs::read(file.path())?; let messages = parse_messages(&contents)?; - if messages.is_empty() { - return Ok(()); - } writeln!(f)?; writeln!(f, "pub mod {} {{", obj_name)?; writeln!(f, " use super::*;")?; - for message in &messages { + for message in messages.requests.iter().chain(messages.events.iter()) { write_message(f, &camel_obj_name, &message.val)?; } + write_request_handler(f, &camel_obj_name, &messages)?; writeln!(f, "}}")?; Ok(()) } diff --git a/src/client.rs b/src/client.rs index 1030fa69..e0f2da25 100644 --- a/src/client.rs +++ b/src/client.rs @@ -35,7 +35,7 @@ use { uapi::{c, OwnedFd}, }; pub use { - error::{ClientError, MethodError, ObjectError}, + error::{ClientError, ParserError}, objects::MIN_SERVER_ID, }; diff --git a/src/client/error.rs b/src/client/error.rs index feaff0ac..08e592ed 100644 --- a/src/client/error.rs +++ b/src/client/error.rs @@ -25,8 +25,6 @@ pub enum ClientError { UnalignedMessage, #[error("The requested client {0} does not exist")] ClientDoesNotExist(ClientId), - #[error("Cannot parse the message")] - ParserError(#[source] Box), #[error("Server tried to allocate more than 0x1_00_00_00 ids")] TooManyIds, #[error("The server object id is out of bounds")] @@ -39,14 +37,22 @@ pub enum ClientError { ClientIdOutOfBounds, #[error("Object {0} is not a display")] NotADisplay(WlDisplayId), - #[error(transparent)] - ObjectError(ObjectError), + #[error("Could not process a `{}.{}` request", .interface.name(), .method)] + MethodError { + interface: Interface, + method: &'static str, + #[source] + error: Box, + }, #[error(transparent)] LookupError(LookupError), #[error("Could not add object {0} to the client")] AddObjectError(ObjectId, #[source] Box), } -efrom!(ClientError, ParserError, MsgParserError); + +#[derive(Debug, Error)] +#[error("Parsing failed")] +pub struct ParserError(#[source] pub MsgParserError); impl ClientError { pub fn peer_closed(&self) -> bool { @@ -54,22 +60,6 @@ impl ClientError { } } -#[derive(Debug, Error)] -#[error("Could not process a `{method}` request")] -pub struct MethodError { - pub method: &'static str, - #[source] - pub error: Box, -} - -#[derive(Debug, Error)] -#[error("An error occurred in a `{}`", .interface.name())] -pub struct ObjectError { - pub interface: Interface, - #[source] - pub error: Box, -} - #[derive(Debug, Error)] #[error("There is no `{}` with id {}", .interface.name(), .id)] pub struct LookupError { diff --git a/src/client/tasks.rs b/src/client/tasks.rs index 74ed4f3a..5e754bf5 100644 --- a/src/client/tasks.rs +++ b/src/client/tasks.rs @@ -71,7 +71,7 @@ async fn receive(data: Rc) { } // log::trace!("{:x?}", data_buf); let parser = MsgParser::new(&mut buf, &data_buf[..]); - if let Err(e) = obj.handle_request(request, parser) { + if let Err(e) = obj.handle_request(&data, request, parser) { if let ClientError::InvalidMethod = e { if let Ok(obj) = data.objects.get_obj(obj_id) { data.invalid_request(&*obj, request); diff --git a/src/ifs/ext_foreign_toplevel_handle_v1.rs b/src/ifs/ext_foreign_toplevel_handle_v1.rs index a679bcb1..4ce7fc10 100644 --- a/src/ifs/ext_foreign_toplevel_handle_v1.rs +++ b/src/ifs/ext_foreign_toplevel_handle_v1.rs @@ -2,9 +2,8 @@ use { crate::{ client::{Client, ClientError}, leaks::Tracker, - object::Object, + object::{Object, Version}, tree::ToplevelNode, - utils::buffd::{MsgParser, MsgParserError}, wire::{ext_foreign_toplevel_handle_v1::*, ExtForeignToplevelHandleV1Id}, }, std::rc::Rc, @@ -16,6 +15,7 @@ pub struct ExtForeignToplevelHandleV1 { pub client: Rc, pub tracker: Tracker, pub toplevel: Rc, + pub version: Version, } impl ExtForeignToplevelHandleV1 { @@ -25,14 +25,19 @@ impl ExtForeignToplevelHandleV1 { .handles .remove(&(self.client.id, self.id)); } +} + +impl ExtForeignToplevelHandleV1RequestHandler for ExtForeignToplevelHandleV1 { + type Error = ExtForeignToplevelHandleV1Error; - fn destroy(&self, msg: MsgParser<'_, '_>) -> Result<(), ExtSessionLockV1Error> { - let _req: Destroy = self.client.parse(self, msg)?; + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { self.detach(); self.client.remove_obj(self)?; Ok(()) } +} +impl ExtForeignToplevelHandleV1 { pub fn send_closed(&self) { self.client.event(Closed { self_id: self.id }); } @@ -65,8 +70,7 @@ impl ExtForeignToplevelHandleV1 { object_base! { self = ExtForeignToplevelHandleV1; - - DESTROY => destroy, + version = self.version; } impl Object for ExtForeignToplevelHandleV1 { @@ -78,11 +82,8 @@ impl Object for ExtForeignToplevelHandleV1 { simple_add_obj!(ExtForeignToplevelHandleV1); #[derive(Debug, Error)] -pub enum ExtSessionLockV1Error { - #[error("Parsing failed")] - MsgParserError(#[source] Box), +pub enum ExtForeignToplevelHandleV1Error { #[error(transparent)] ClientError(Box), } -efrom!(ExtSessionLockV1Error, MsgParserError); -efrom!(ExtSessionLockV1Error, ClientError); +efrom!(ExtForeignToplevelHandleV1Error, ClientError); diff --git a/src/ifs/ext_foreign_toplevel_list_v1.rs b/src/ifs/ext_foreign_toplevel_list_v1.rs index 93f383ad..8e21c486 100644 --- a/src/ifs/ext_foreign_toplevel_list_v1.rs +++ b/src/ifs/ext_foreign_toplevel_list_v1.rs @@ -9,7 +9,6 @@ use { leaks::Tracker, object::{Object, Version}, tree::{NodeVisitorBase, ToplevelNode}, - utils::buffd::{MsgParser, MsgParserError}, wire::{ ext_foreign_toplevel_list_v1::*, ExtForeignToplevelHandleV1Id, ExtForeignToplevelListV1Id, @@ -32,12 +31,13 @@ impl ExtForeignToplevelListV1Global { self: Rc, id: ExtForeignToplevelListV1Id, client: &Rc, - _version: Version, + version: Version, ) -> Result<(), ExtForeignToplevelListV1Error> { let obj = Rc::new(ExtForeignToplevelListV1 { id, client: client.clone(), tracker: Default::default(), + version, }); track!(client, obj); client.add_client_obj(&obj)?; @@ -65,6 +65,7 @@ pub struct ExtForeignToplevelListV1 { pub id: ExtForeignToplevelListV1Id, pub client: Rc, pub tracker: Tracker, + pub version: Version, } impl ExtForeignToplevelListV1 { @@ -74,21 +75,25 @@ impl ExtForeignToplevelListV1 { .toplevel_lists .remove(&(self.client.id, self.id)); } +} + +impl ExtForeignToplevelListV1RequestHandler for ExtForeignToplevelListV1 { + type Error = ExtForeignToplevelListV1Error; - fn stop(&self, msg: MsgParser<'_, '_>) -> Result<(), ExtForeignToplevelListV1Error> { - let _req: Stop = self.client.parse(self, msg)?; + fn stop(&self, _req: Stop, _slf: &Rc) -> Result<(), Self::Error> { self.detach(); self.send_finished(); Ok(()) } - fn destroy(&self, msg: MsgParser<'_, '_>) -> Result<(), ExtForeignToplevelListV1Error> { - let _req: Destroy = self.client.parse(self, msg)?; + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { self.detach(); self.client.remove_obj(self)?; Ok(()) } +} +impl ExtForeignToplevelListV1 { fn send_finished(&self) { self.client.event(Finished { self_id: self.id }) } @@ -116,6 +121,7 @@ impl ExtForeignToplevelListV1 { client: self.client.clone(), tracker: Default::default(), toplevel: tl.clone(), + version: self.version, }); track!(self.client, handle); self.client.add_server_obj(&handle); @@ -148,9 +154,7 @@ simple_add_global!(ExtForeignToplevelListV1Global); object_base! { self = ExtForeignToplevelListV1; - - STOP => stop, - DESTROY => destroy, + version = self.version; } impl Object for ExtForeignToplevelListV1 { @@ -163,10 +167,7 @@ simple_add_obj!(ExtForeignToplevelListV1); #[derive(Debug, Error)] pub enum ExtForeignToplevelListV1Error { - #[error("Parsing failed")] - MsgParserError(#[source] Box), #[error(transparent)] ClientError(Box), } -efrom!(ExtForeignToplevelListV1Error, MsgParserError); efrom!(ExtForeignToplevelListV1Error, ClientError); diff --git a/src/ifs/ext_idle_notification_v1.rs b/src/ifs/ext_idle_notification_v1.rs index ac985a7d..935ddfbb 100644 --- a/src/ifs/ext_idle_notification_v1.rs +++ b/src/ifs/ext_idle_notification_v1.rs @@ -4,11 +4,8 @@ use { client::{Client, ClientError}, ifs::wl_seat::WlSeatGlobal, leaks::Tracker, - object::Object, - utils::{ - asyncevent::AsyncEvent, - buffd::{MsgParser, MsgParserError}, - }, + object::{Object, Version}, + utils::asyncevent::AsyncEvent, wire::{ext_idle_notification_v1::*, ExtIdleNotificationV1Id}, }, std::{cell::Cell, rc::Rc}, @@ -23,6 +20,7 @@ pub struct ExtIdleNotificationV1 { pub task: Cell>>, pub seat: Rc, pub duration_usec: u64, + pub version: Version, } impl ExtIdleNotificationV1 { @@ -30,14 +28,19 @@ impl ExtIdleNotificationV1 { self.seat.remove_idle_notification(self); self.task.take(); } +} + +impl ExtIdleNotificationV1RequestHandler for ExtIdleNotificationV1 { + type Error = ExtIdleNotificationV1Error; - fn destroy(&self, msg: MsgParser<'_, '_>) -> Result<(), ExtIdleNotificationV1Error> { - let _req: Destroy = self.client.parse(self, msg)?; + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { self.detach(); self.client.remove_obj(self)?; Ok(()) } +} +impl ExtIdleNotificationV1 { pub fn send_idled(&self) { self.client.event(Idled { self_id: self.id }); } @@ -49,8 +52,7 @@ impl ExtIdleNotificationV1 { object_base! { self = ExtIdleNotificationV1; - - DESTROY => destroy, + version = self.version; } impl Object for ExtIdleNotificationV1 { @@ -63,10 +65,7 @@ simple_add_obj!(ExtIdleNotificationV1); #[derive(Debug, Error)] pub enum ExtIdleNotificationV1Error { - #[error("Parsing failed")] - MsgParserError(#[source] Box), #[error(transparent)] ClientError(Box), } -efrom!(ExtIdleNotificationV1Error, MsgParserError); efrom!(ExtIdleNotificationV1Error, ClientError); diff --git a/src/ifs/ext_idle_notifier_v1.rs b/src/ifs/ext_idle_notifier_v1.rs index 7e08b9c2..6cbade69 100644 --- a/src/ifs/ext_idle_notifier_v1.rs +++ b/src/ifs/ext_idle_notifier_v1.rs @@ -6,10 +6,7 @@ use { leaks::Tracker, object::{Object, Version}, time::now_usec, - utils::{ - buffd::{MsgParser, MsgParserError}, - errorfmt::ErrorFmt, - }, + utils::errorfmt::ErrorFmt, wire::{ext_idle_notifier_v1::*, ExtIdleNotifierV1Id}, }, std::{cell::Cell, rc::Rc}, @@ -29,12 +26,13 @@ impl ExtIdleNotifierV1Global { self: Rc, id: ExtIdleNotifierV1Id, client: &Rc, - _version: Version, + version: Version, ) -> Result<(), ExtIdleNotifierV1Error> { let obj = Rc::new(ExtIdleNotifierV1 { id, client: client.clone(), tracker: Default::default(), + version, }); track!(client, obj); client.add_client_obj(&obj)?; @@ -46,17 +44,22 @@ pub struct ExtIdleNotifierV1 { pub id: ExtIdleNotifierV1Id, pub client: Rc, pub tracker: Tracker, + pub version: Version, } -impl ExtIdleNotifierV1 { - fn destroy(&self, msg: MsgParser<'_, '_>) -> Result<(), ExtIdleNotifierV1Error> { - let _req: Destroy = self.client.parse(self, msg)?; +impl ExtIdleNotifierV1RequestHandler for ExtIdleNotifierV1 { + type Error = ExtIdleNotifierV1Error; + + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { self.client.remove_obj(self)?; Ok(()) } - fn get_idle_notification(&self, msg: MsgParser<'_, '_>) -> Result<(), ExtIdleNotifierV1Error> { - let req: GetIdleNotification = self.client.parse(self, msg)?; + fn get_idle_notification( + &self, + req: GetIdleNotification, + _slf: &Rc, + ) -> Result<(), Self::Error> { let seat = self.client.lookup(req.seat)?; let notification = Rc::new(ExtIdleNotificationV1 { id: req.id, @@ -66,6 +69,7 @@ impl ExtIdleNotifierV1 { task: Cell::new(None), seat: seat.global.clone(), duration_usec: (req.timeout as u64).max(1000).saturating_mul(1000), + version: self.version, }); self.client.add_client_obj(¬ification)?; let future = self.client.state.eng.spawn(run(notification.clone())); @@ -122,9 +126,7 @@ simple_add_global!(ExtIdleNotifierV1Global); object_base! { self = ExtIdleNotifierV1; - - DESTROY => destroy, - GET_IDLE_NOTIFICATION => get_idle_notification, + version = self.version; } impl Object for ExtIdleNotifierV1 {} @@ -133,10 +135,7 @@ simple_add_obj!(ExtIdleNotifierV1); #[derive(Debug, Error)] pub enum ExtIdleNotifierV1Error { - #[error("Parsing failed")] - MsgParserError(#[source] Box), #[error(transparent)] ClientError(Box), } -efrom!(ExtIdleNotifierV1Error, MsgParserError); efrom!(ExtIdleNotifierV1Error, ClientError); diff --git a/src/ifs/ext_session_lock_manager_v1.rs b/src/ifs/ext_session_lock_manager_v1.rs index 19e6b9c1..85b14a8c 100644 --- a/src/ifs/ext_session_lock_manager_v1.rs +++ b/src/ifs/ext_session_lock_manager_v1.rs @@ -5,7 +5,6 @@ use { ifs::ext_session_lock_v1::ExtSessionLockV1, leaks::Tracker, object::{Object, Version}, - utils::buffd::{MsgParser, MsgParserError}, wire::{ext_session_lock_manager_v1::*, ExtSessionLockManagerV1Id}, }, std::{cell::Cell, rc::Rc}, @@ -25,12 +24,13 @@ impl ExtSessionLockManagerV1Global { self: Rc, id: ExtSessionLockManagerV1Id, client: &Rc, - _version: Version, + version: Version, ) -> Result<(), ExtSessionLockManagerV1Error> { let obj = Rc::new(ExtSessionLockManagerV1 { id, client: client.clone(), tracker: Default::default(), + version, }); track!(client, obj); client.add_client_obj(&obj)?; @@ -42,17 +42,18 @@ pub struct ExtSessionLockManagerV1 { pub id: ExtSessionLockManagerV1Id, pub client: Rc, pub tracker: Tracker, + pub version: Version, } -impl ExtSessionLockManagerV1 { - fn destroy(&self, msg: MsgParser<'_, '_>) -> Result<(), ExtSessionLockManagerV1Error> { - let _req: Destroy = self.client.parse(self, msg)?; +impl ExtSessionLockManagerV1RequestHandler for ExtSessionLockManagerV1 { + type Error = ExtSessionLockManagerV1Error; + + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { self.client.remove_obj(self)?; Ok(()) } - fn lock(&self, msg: MsgParser<'_, '_>) -> Result<(), ExtSessionLockManagerV1Error> { - let req: Lock = self.client.parse(self, msg)?; + fn lock(&self, req: Lock, _slf: &Rc) -> Result<(), Self::Error> { let did_lock = self.client.state.lock.locked.get() == false; let new = Rc::new(ExtSessionLockV1 { id: req.id, @@ -60,6 +61,7 @@ impl ExtSessionLockManagerV1 { tracker: Default::default(), did_lock, finished: Cell::new(false), + version: self.version, }); track!(new.client, new); self.client.add_client_obj(&new)?; @@ -105,9 +107,7 @@ simple_add_global!(ExtSessionLockManagerV1Global); object_base! { self = ExtSessionLockManagerV1; - - DESTROY => destroy, - LOCK => lock, + version = self.version; } impl Object for ExtSessionLockManagerV1 {} @@ -116,10 +116,7 @@ simple_add_obj!(ExtSessionLockManagerV1); #[derive(Debug, Error)] pub enum ExtSessionLockManagerV1Error { - #[error("Parsing failed")] - MsgParserError(#[source] Box), #[error(transparent)] ClientError(Box), } -efrom!(ExtSessionLockManagerV1Error, MsgParserError); efrom!(ExtSessionLockManagerV1Error, ClientError); diff --git a/src/ifs/ext_session_lock_v1.rs b/src/ifs/ext_session_lock_v1.rs index dd518d8a..ca2db3af 100644 --- a/src/ifs/ext_session_lock_v1.rs +++ b/src/ifs/ext_session_lock_v1.rs @@ -5,8 +5,7 @@ use { ExtSessionLockSurfaceV1, ExtSessionLockSurfaceV1Error, }, leaks::Tracker, - object::Object, - utils::buffd::{MsgParser, MsgParserError}, + object::{Object, Version}, wire::{ext_session_lock_v1::*, ExtSessionLockV1Id}, }, std::{cell::Cell, rc::Rc}, @@ -19,6 +18,7 @@ pub struct ExtSessionLockV1 { pub tracker: Tracker, pub did_lock: bool, pub finished: Cell, + pub version: Version, } impl ExtSessionLockV1 { @@ -34,9 +34,12 @@ impl ExtSessionLockV1 { self.send_finished(); self.finished.set(true); } +} + +impl ExtSessionLockV1RequestHandler for ExtSessionLockV1 { + type Error = ExtSessionLockV1Error; - fn destroy(&self, msg: MsgParser<'_, '_>) -> Result<(), ExtSessionLockV1Error> { - let _req: Destroy = self.client.parse(self, msg)?; + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { if !self.finished.get() { self.client.state.lock.lock.take(); } @@ -44,8 +47,7 @@ impl ExtSessionLockV1 { Ok(()) } - fn get_lock_surface(&self, msg: MsgParser<'_, '_>) -> Result<(), ExtSessionLockV1Error> { - let req: GetLockSurface = self.client.parse(self, msg)?; + fn get_lock_surface(&self, req: GetLockSurface, _slf: &Rc) -> Result<(), Self::Error> { let output = self.client.lookup(req.output)?; let surface = self.client.lookup(req.surface)?; let new = Rc::new(ExtSessionLockSurfaceV1 { @@ -57,6 +59,7 @@ impl ExtSessionLockV1 { serial: Default::default(), output: output.global.node.get(), seat_state: Default::default(), + version: self.version, }); track!(new.client, new); new.install()?; @@ -75,8 +78,11 @@ impl ExtSessionLockV1 { Ok(()) } - fn unlock_and_destroy(&self, msg: MsgParser<'_, '_>) -> Result<(), ExtSessionLockV1Error> { - let _req: UnlockAndDestroy = self.client.parse(self, msg)?; + fn unlock_and_destroy( + &self, + _req: UnlockAndDestroy, + _slf: &Rc, + ) -> Result<(), Self::Error> { if !self.did_lock { return Err(ExtSessionLockV1Error::NeverLocked); } @@ -99,10 +105,7 @@ impl ExtSessionLockV1 { object_base! { self = ExtSessionLockV1; - - DESTROY => destroy, - GET_LOCK_SURFACE => get_lock_surface, - UNLOCK_AND_DESTROY => unlock_and_destroy, + version = self.version; } impl Object for ExtSessionLockV1 { @@ -117,8 +120,6 @@ simple_add_obj!(ExtSessionLockV1); #[derive(Debug, Error)] pub enum ExtSessionLockV1Error { - #[error("Parsing failed")] - MsgParserError(#[source] Box), #[error(transparent)] ClientError(Box), #[error("The lock was not accepted")] @@ -128,5 +129,4 @@ pub enum ExtSessionLockV1Error { #[error(transparent)] ExtSessionLockSurfaceV1Error(#[from] ExtSessionLockSurfaceV1Error), } -efrom!(ExtSessionLockV1Error, MsgParserError); efrom!(ExtSessionLockV1Error, ClientError); diff --git a/src/ifs/ipc/wl_data_device.rs b/src/ifs/ipc/wl_data_device.rs index 0ac8b78f..772438bd 100644 --- a/src/ifs/ipc/wl_data_device.rs +++ b/src/ifs/ipc/wl_data_device.rs @@ -13,7 +13,6 @@ use { }, leaks::Tracker, object::{Object, Version}, - utils::buffd::{MsgParser, MsgParserError}, wire::{wl_data_device::*, WlDataDeviceId, WlDataOfferId, WlSurfaceId}, }, std::rc::Rc, @@ -98,9 +97,12 @@ impl WlDataDevice { pub fn send_drop(&self) { self.client.event(Drop { self_id: self.id }) } +} + +impl WlDataDeviceRequestHandler for WlDataDevice { + type Error = WlDataDeviceError; - fn start_drag(&self, parser: MsgParser<'_, '_>) -> Result<(), WlDataDeviceError> { - let req: StartDrag = self.client.parse(self, parser)?; + fn start_drag(&self, req: StartDrag, _slf: &Rc) -> Result<(), Self::Error> { if !self.client.valid_serial(req.serial) { log::warn!("Client tried to start_drag with an invalid serial"); return Ok(()); @@ -122,8 +124,7 @@ impl WlDataDevice { Ok(()) } - fn set_selection(&self, parser: MsgParser<'_, '_>) -> Result<(), WlDataDeviceError> { - let req: SetSelection = self.client.parse(self, parser)?; + fn set_selection(&self, req: SetSelection, _slf: &Rc) -> Result<(), Self::Error> { if !self.client.valid_serial(req.serial) { log::warn!("Client tried to set_selection with an invalid serial"); return Ok(()); @@ -142,8 +143,7 @@ impl WlDataDevice { Ok(()) } - fn release(&self, parser: MsgParser<'_, '_>) -> Result<(), WlDataDeviceError> { - let _req: Release = self.client.parse(self, parser)?; + fn release(&self, _req: Release, _slf: &Rc) -> Result<(), Self::Error> { destroy_data_device::(self); self.seat.remove_data_device(self); self.client.remove_obj(self)?; @@ -224,10 +224,7 @@ impl IpcVtable for ClipboardIpc { object_base! { self = WlDataDevice; - - START_DRAG => start_drag, - SET_SELECTION => set_selection, - RELEASE => release if self.version >= 2, + version = self.version; } impl Object for WlDataDevice { @@ -241,8 +238,6 @@ simple_add_obj!(WlDataDevice); #[derive(Debug, Error)] pub enum WlDataDeviceError { - #[error("Parsing failed")] - MsgParserError(#[source] Box), #[error(transparent)] ClientError(Box), #[error(transparent)] @@ -250,7 +245,6 @@ pub enum WlDataDeviceError { #[error(transparent)] WlSurfaceError(Box), } -efrom!(WlDataDeviceError, MsgParserError); efrom!(WlDataDeviceError, ClientError); efrom!(WlDataDeviceError, WlSeatError); efrom!(WlDataDeviceError, WlSurfaceError); diff --git a/src/ifs/ipc/wl_data_device_manager.rs b/src/ifs/ipc/wl_data_device_manager.rs index 7e961fb4..73b6c199 100644 --- a/src/ifs/ipc/wl_data_device_manager.rs +++ b/src/ifs/ipc/wl_data_device_manager.rs @@ -5,7 +5,6 @@ use { ifs::ipc::{wl_data_device::WlDataDevice, wl_data_source::WlDataSource}, leaks::Tracker, object::{Object, Version}, - utils::buffd::{MsgParser, MsgParserError}, wire::{wl_data_device_manager::*, WlDataDeviceManagerId}, }, std::rc::Rc, @@ -55,23 +54,21 @@ impl WlDataDeviceManagerGlobal { } } -impl WlDataDeviceManager { +impl WlDataDeviceManagerRequestHandler for WlDataDeviceManager { + type Error = WlDataDeviceManagerError; + fn create_data_source( &self, - parser: MsgParser<'_, '_>, - ) -> Result<(), WlDataDeviceManagerError> { - let req: CreateDataSource = self.client.parse(self, parser)?; + req: CreateDataSource, + _slf: &Rc, + ) -> Result<(), Self::Error> { let res = Rc::new(WlDataSource::new(req.id, &self.client, self.version)); track!(self.client, res); self.client.add_client_obj(&res)?; Ok(()) } - fn get_data_device( - self: &Rc, - parser: MsgParser<'_, '_>, - ) -> Result<(), WlDataDeviceManagerError> { - let req: GetDataDevice = self.client.parse(&**self, parser)?; + fn get_data_device(&self, req: GetDataDevice, _slf: &Rc) -> Result<(), Self::Error> { let seat = self.client.lookup(req.seat)?; let dev = Rc::new(WlDataDevice::new( req.id, @@ -106,9 +103,7 @@ simple_add_global!(WlDataDeviceManagerGlobal); object_base! { self = WlDataDeviceManager; - - CREATE_DATA_SOURCE => create_data_source, - GET_DATA_DEVICE => get_data_device, + version = self.version; } impl Object for WlDataDeviceManager {} @@ -119,8 +114,5 @@ simple_add_obj!(WlDataDeviceManager); pub enum WlDataDeviceManagerError { #[error(transparent)] ClientError(Box), - #[error("Parsing failed")] - MsgParserError(#[source] Box), } efrom!(WlDataDeviceManagerError, ClientError); -efrom!(WlDataDeviceManagerError, MsgParserError); diff --git a/src/ifs/ipc/wl_data_offer.rs b/src/ifs/ipc/wl_data_offer.rs index 17078882..20c14796 100644 --- a/src/ifs/ipc/wl_data_offer.rs +++ b/src/ifs/ipc/wl_data_offer.rs @@ -14,10 +14,7 @@ use { }, leaks::Tracker, object::Object, - utils::{ - bitflags::BitflagsExt, - buffd::{MsgParser, MsgParserError}, - }, + utils::bitflags::BitflagsExt, wire::{wl_data_offer::*, WlDataOfferId, WlSurfaceId}, }, std::rc::Rc, @@ -113,9 +110,12 @@ impl WlDataOffer { dnd_action, }) } +} - fn accept(&self, parser: MsgParser<'_, '_>) -> Result<(), WlDataOfferError> { - let req: Accept = self.client.parse(self, parser)?; +impl WlDataOfferRequestHandler for WlDataOffer { + type Error = WlDataOfferError; + + fn accept(&self, req: Accept, _slf: &Rc) -> Result<(), Self::Error> { let _ = req.serial; // unused let mut state = self.data.shared.state.get(); if state.contains(OFFER_STATE_FINISHED) { @@ -133,8 +133,7 @@ impl WlDataOffer { Ok(()) } - fn receive(&self, parser: MsgParser<'_, '_>) -> Result<(), WlDataOfferError> { - let req: Receive = self.client.parse(self, parser)?; + fn receive(&self, req: Receive, _slf: &Rc) -> Result<(), Self::Error> { if self.data.shared.state.get().contains(OFFER_STATE_FINISHED) { return Err(WlDataOfferError::AlreadyFinished); } @@ -142,15 +141,13 @@ impl WlDataOffer { Ok(()) } - fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), WlDataOfferError> { - let _req: Destroy = self.client.parse(self, parser)?; + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { destroy_data_offer::(self); self.client.remove_obj(self)?; Ok(()) } - fn finish(&self, parser: MsgParser<'_, '_>) -> Result<(), WlDataOfferError> { - let _req: Finish = self.client.parse(self, parser)?; + fn finish(&self, _req: Finish, _slf: &Rc) -> Result<(), Self::Error> { if self.data.shared.role.get() != Role::Dnd { return Err(WlDataOfferError::NotDnd); } @@ -175,8 +172,7 @@ impl WlDataOffer { Ok(()) } - fn set_actions(&self, parser: MsgParser<'_, '_>) -> Result<(), WlDataOfferError> { - let req: SetActions = self.client.parse(self, parser)?; + fn set_actions(&self, req: SetActions, _slf: &Rc) -> Result<(), Self::Error> { let state = self.data.shared.state.get(); if state.contains(OFFER_STATE_FINISHED) { return Err(WlDataOfferError::AlreadyFinished); @@ -201,12 +197,7 @@ impl WlDataOffer { object_base! { self = WlDataOffer; - - ACCEPT => accept, - RECEIVE => receive, - DESTROY => destroy, - FINISH => finish if self.device.version >= 3, - SET_ACTIONS => set_actions if self.device.version >= 3, + version = self.device.version; } impl Object for WlDataOffer { @@ -221,8 +212,6 @@ simple_add_obj!(WlDataOffer); pub enum WlDataOfferError { #[error(transparent)] ClientError(Box), - #[error("Parsing failed")] - MsgParserError(#[source] Box), #[error("`finish` was already called")] AlreadyFinished, #[error("The drag operation is still ongoing")] @@ -237,4 +226,3 @@ pub enum WlDataOfferError { MultiplePreferred, } efrom!(WlDataOfferError, ClientError); -efrom!(WlDataOfferError, MsgParserError); diff --git a/src/ifs/ipc/wl_data_source.rs b/src/ifs/ipc/wl_data_source.rs index 18281feb..3aefe5fa 100644 --- a/src/ifs/ipc/wl_data_source.rs +++ b/src/ifs/ipc/wl_data_source.rs @@ -19,12 +19,7 @@ use { }, leaks::Tracker, object::{Object, Version}, - utils::{ - bitflags::BitflagsExt, - buffd::{MsgParser, MsgParserError}, - cell_ext::CellExt, - clonecell::CloneCell, - }, + utils::{bitflags::BitflagsExt, cell_ext::CellExt, clonecell::CloneCell}, wire::{wl_data_source::*, WlDataSourceId}, }, std::rc::Rc, @@ -208,22 +203,23 @@ impl WlDataSource { .client .event(DndDropPerformed { self_id: self.id }) } +} - fn offer(&self, parser: MsgParser<'_, '_>) -> Result<(), WlDataSourceError> { - let req: Offer = self.data.client.parse(self, parser)?; +impl WlDataSourceRequestHandler for WlDataSource { + type Error = WlDataSourceError; + + fn offer(&self, req: Offer, _slf: &Rc) -> Result<(), Self::Error> { add_data_source_mime_type::(self, req.mime_type); Ok(()) } - fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), WlDataSourceError> { - let _req: Destroy = self.data.client.parse(self, parser)?; + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { destroy_data_source::(self); self.data.client.remove_obj(self)?; Ok(()) } - fn set_actions(&self, parser: MsgParser<'_, '_>) -> Result<(), WlDataSourceError> { - let req: SetActions = self.data.client.parse(self, parser)?; + fn set_actions(&self, req: SetActions, _slf: &Rc) -> Result<(), Self::Error> { if self.data.actions.is_some() { return Err(WlDataSourceError::AlreadySet); } @@ -237,10 +233,7 @@ impl WlDataSource { object_base! { self = WlDataSource; - - OFFER => offer, - DESTROY => destroy, - SET_ACTIONS => set_actions if self.version >= 3, + version = self.version; } impl Object for WlDataSource { @@ -254,8 +247,6 @@ dedicated_add_obj!(WlDataSource, WlDataSourceId, wl_data_source); #[derive(Debug, Error)] pub enum WlDataSourceError { - #[error("Parsing failed")] - MsgParserError(#[source] Box), #[error(transparent)] ClientError(Box), #[error("The set of actions is invalid")] @@ -264,4 +255,3 @@ pub enum WlDataSourceError { AlreadySet, } efrom!(WlDataSourceError, ClientError); -efrom!(WlDataSourceError, MsgParserError); diff --git a/src/ifs/ipc/zwlr_data_control_device_v1.rs b/src/ifs/ipc/zwlr_data_control_device_v1.rs index a8efe85d..f5d1e207 100644 --- a/src/ifs/ipc/zwlr_data_control_device_v1.rs +++ b/src/ifs/ipc/zwlr_data_control_device_v1.rs @@ -15,7 +15,6 @@ use { }, leaks::Tracker, object::{Object, Version}, - utils::buffd::{MsgParser, MsgParserError}, wire::{ zwlr_data_control_device_v1::*, ZwlrDataControlDeviceV1Id, ZwlrDataControlOfferV1Id, ZwlrDataControlSourceV1Id, @@ -98,16 +97,18 @@ impl ZwlrDataControlDeviceV1 { Ok(Some(src)) } } +} + +impl ZwlrDataControlDeviceV1RequestHandler for ZwlrDataControlDeviceV1 { + type Error = ZwlrDataControlDeviceV1Error; - fn set_selection(&self, parser: MsgParser<'_, '_>) -> Result<(), ZwlrDataControlDeviceV1Error> { - let req: SetSelection = self.client.parse(self, parser)?; + fn set_selection(&self, req: SetSelection, _slf: &Rc) -> Result<(), Self::Error> { let src = self.use_source(req.source, IpcLocation::Clipboard)?; self.seat.set_selection(src)?; Ok(()) } - fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), ZwlrDataControlDeviceV1Error> { - let _req: Destroy = self.client.parse(self, parser)?; + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { destroy_data_device::(self); destroy_data_device::(self); self.seat.remove_wlr_device(self); @@ -117,9 +118,9 @@ impl ZwlrDataControlDeviceV1 { fn set_primary_selection( &self, - parser: MsgParser<'_, '_>, - ) -> Result<(), ZwlrDataControlDeviceV1Error> { - let req: SetPrimarySelection = self.client.parse(self, parser)?; + req: SetPrimarySelection, + _slf: &Rc, + ) -> Result<(), Self::Error> { let src = self.use_source(req.source, IpcLocation::PrimarySelection)?; self.seat.set_primary_selection(src)?; Ok(()) @@ -276,10 +277,7 @@ impl IpcVtable for WlrIpcImpl { object_base! { self = ZwlrDataControlDeviceV1; - - SET_SELECTION => set_selection, - DESTROY => destroy, - SET_PRIMARY_SELECTION => set_primary_selection if self.version >= 2, + version = self.version; } impl Object for ZwlrDataControlDeviceV1 { @@ -292,8 +290,6 @@ simple_add_obj!(ZwlrDataControlDeviceV1); #[derive(Debug, Error)] pub enum ZwlrDataControlDeviceV1Error { - #[error("Parsing failed")] - MsgParserError(#[source] Box), #[error(transparent)] ClientError(Box), #[error(transparent)] @@ -301,6 +297,5 @@ pub enum ZwlrDataControlDeviceV1Error { #[error("The source has already been used")] AlreadyUsed, } -efrom!(ZwlrDataControlDeviceV1Error, MsgParserError); efrom!(ZwlrDataControlDeviceV1Error, ClientError); efrom!(ZwlrDataControlDeviceV1Error, WlSeatError); diff --git a/src/ifs/ipc/zwlr_data_control_manager_v1.rs b/src/ifs/ipc/zwlr_data_control_manager_v1.rs index 0f77cfa4..87aa1f5f 100644 --- a/src/ifs/ipc/zwlr_data_control_manager_v1.rs +++ b/src/ifs/ipc/zwlr_data_control_manager_v1.rs @@ -8,7 +8,6 @@ use { }, leaks::Tracker, object::{Object, Version}, - utils::buffd::{MsgParser, MsgParserError}, wire::{zwlr_data_control_manager_v1::*, ZwlrDataControlManagerV1Id}, }, std::rc::Rc, @@ -49,12 +48,14 @@ impl ZwlrDataControlManagerV1Global { } } -impl ZwlrDataControlManagerV1 { +impl ZwlrDataControlManagerV1RequestHandler for ZwlrDataControlManagerV1 { + type Error = ZwlrDataControlManagerV1Error; + fn create_data_source( &self, - parser: MsgParser<'_, '_>, - ) -> Result<(), ZwlrDataControlManagerV1Error> { - let req: CreateDataSource = self.client.parse(self, parser)?; + req: CreateDataSource, + _slf: &Rc, + ) -> Result<(), Self::Error> { let res = Rc::new(ZwlrDataControlSourceV1::new( req.id, &self.client, @@ -65,11 +66,7 @@ impl ZwlrDataControlManagerV1 { Ok(()) } - fn get_data_device( - self: &Rc, - parser: MsgParser<'_, '_>, - ) -> Result<(), ZwlrDataControlManagerV1Error> { - let req: GetDataDevice = self.client.parse(&**self, parser)?; + fn get_data_device(&self, req: GetDataDevice, _slf: &Rc) -> Result<(), Self::Error> { let seat = self.client.lookup(req.seat)?; let dev = Rc::new(ZwlrDataControlDeviceV1::new( req.id, @@ -93,8 +90,7 @@ impl ZwlrDataControlManagerV1 { Ok(()) } - fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), ZwlrDataControlManagerV1Error> { - let _req: Destroy = self.client.parse(self, parser)?; + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { self.client.remove_obj(self)?; Ok(()) } @@ -124,10 +120,7 @@ simple_add_global!(ZwlrDataControlManagerV1Global); object_base! { self = ZwlrDataControlManagerV1; - - CREATE_DATA_SOURCE => create_data_source, - GET_DATA_DEVICE => get_data_device, - DESTROY => destroy, + version = self.version; } impl Object for ZwlrDataControlManagerV1 {} @@ -138,8 +131,5 @@ simple_add_obj!(ZwlrDataControlManagerV1); pub enum ZwlrDataControlManagerV1Error { #[error(transparent)] ClientError(Box), - #[error("Parsing failed")] - MsgParserError(#[source] Box), } efrom!(ZwlrDataControlManagerV1Error, ClientError); -efrom!(ZwlrDataControlManagerV1Error, MsgParserError); diff --git a/src/ifs/ipc/zwlr_data_control_offer_v1.rs b/src/ifs/ipc/zwlr_data_control_offer_v1.rs index a9eb427c..1b8a5358 100644 --- a/src/ifs/ipc/zwlr_data_control_offer_v1.rs +++ b/src/ifs/ipc/zwlr_data_control_offer_v1.rs @@ -13,7 +13,6 @@ use { }, leaks::Tracker, object::Object, - utils::buffd::{MsgParser, MsgParserError}, wire::{zwlr_data_control_offer_v1::*, ZwlrDataControlOfferV1Id}, }, std::rc::Rc, @@ -81,9 +80,12 @@ impl ZwlrDataControlOfferV1 { mime_type, }) } +} + +impl ZwlrDataControlOfferV1RequestHandler for ZwlrDataControlOfferV1 { + type Error = ZwlrDataControlOfferV1Error; - fn receive(&self, parser: MsgParser<'_, '_>) -> Result<(), ZwlrDataControlOfferV1Error> { - let req: Receive = self.client.parse(self, parser)?; + fn receive(&self, req: Receive, _slf: &Rc) -> Result<(), Self::Error> { match self.location { IpcLocation::Clipboard => { receive_data_offer::(self, req.mime_type, req.fd) @@ -95,8 +97,7 @@ impl ZwlrDataControlOfferV1 { Ok(()) } - fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), ZwlrDataControlOfferV1Error> { - let _req: Destroy = self.client.parse(self, parser)?; + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { match self.location { IpcLocation::Clipboard => destroy_data_offer::(self), IpcLocation::PrimarySelection => destroy_data_offer::(self), @@ -108,9 +109,7 @@ impl ZwlrDataControlOfferV1 { object_base! { self = ZwlrDataControlOfferV1; - - RECEIVE => receive, - DESTROY => destroy, + version = self.device.version; } impl Object for ZwlrDataControlOfferV1 { @@ -128,8 +127,5 @@ simple_add_obj!(ZwlrDataControlOfferV1); pub enum ZwlrDataControlOfferV1Error { #[error(transparent)] ClientError(Box), - #[error("Parsing failed")] - MsgParserError(#[source] Box), } efrom!(ZwlrDataControlOfferV1Error, ClientError); -efrom!(ZwlrDataControlOfferV1Error, MsgParserError); diff --git a/src/ifs/ipc/zwlr_data_control_source_v1.rs b/src/ifs/ipc/zwlr_data_control_source_v1.rs index 5e6760fa..16fadf5e 100644 --- a/src/ifs/ipc/zwlr_data_control_source_v1.rs +++ b/src/ifs/ipc/zwlr_data_control_source_v1.rs @@ -18,7 +18,6 @@ use { }, leaks::Tracker, object::{Object, Version}, - utils::buffd::{MsgParser, MsgParserError}, wire::{zwlr_data_control_source_v1::*, ZwlrDataControlSourceV1Id}, }, std::{cell::Cell, rc::Rc}, @@ -113,9 +112,12 @@ impl ZwlrDataControlSourceV1 { pub fn send_cancelled(&self) { self.data.client.event(Cancelled { self_id: self.id }) } +} + +impl ZwlrDataControlSourceV1RequestHandler for ZwlrDataControlSourceV1 { + type Error = ZwlrDataControlSourceV1Error; - fn offer(&self, parser: MsgParser<'_, '_>) -> Result<(), ZwlrDataControlSourceV1Error> { - let req: Offer = self.data.client.parse(self, parser)?; + fn offer(&self, req: Offer, _slf: &Rc) -> Result<(), Self::Error> { if self.used.get() { return Err(ZwlrDataControlSourceV1Error::AlreadyUsed); } @@ -123,8 +125,7 @@ impl ZwlrDataControlSourceV1 { Ok(()) } - fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), ZwlrDataControlSourceV1Error> { - let _req: Destroy = self.data.client.parse(self, parser)?; + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { match self.location.get() { IpcLocation::Clipboard => destroy_data_source::(self), IpcLocation::PrimarySelection => destroy_data_source::(self), @@ -136,9 +137,7 @@ impl ZwlrDataControlSourceV1 { object_base! { self = ZwlrDataControlSourceV1; - - OFFER => offer, - DESTROY => destroy, + version = self.version; } impl Object for ZwlrDataControlSourceV1 { @@ -158,12 +157,9 @@ dedicated_add_obj!( #[derive(Debug, Error)] pub enum ZwlrDataControlSourceV1Error { - #[error("Parsing failed")] - MsgParserError(#[source] Box), #[error(transparent)] ClientError(Box), #[error("The source has already been used")] AlreadyUsed, } efrom!(ZwlrDataControlSourceV1Error, ClientError); -efrom!(ZwlrDataControlSourceV1Error, MsgParserError); diff --git a/src/ifs/ipc/zwp_primary_selection_device_manager_v1.rs b/src/ifs/ipc/zwp_primary_selection_device_manager_v1.rs index 95051b77..32eb80b0 100644 --- a/src/ifs/ipc/zwp_primary_selection_device_manager_v1.rs +++ b/src/ifs/ipc/zwp_primary_selection_device_manager_v1.rs @@ -8,7 +8,6 @@ use { }, leaks::Tracker, object::{Object, Version}, - utils::buffd::{MsgParser, MsgParserError}, wire::{zwp_primary_selection_device_manager_v1::*, ZwpPrimarySelectionDeviceManagerV1Id}, }, std::rc::Rc, @@ -49,23 +48,21 @@ impl ZwpPrimarySelectionDeviceManagerV1Global { } } -impl ZwpPrimarySelectionDeviceManagerV1 { - fn create_source( - &self, - parser: MsgParser<'_, '_>, - ) -> Result<(), ZwpPrimarySelectionDeviceManagerV1Error> { - let req: CreateSource = self.client.parse(self, parser)?; - let res = Rc::new(ZwpPrimarySelectionSourceV1::new(req.id, &self.client)); +impl ZwpPrimarySelectionDeviceManagerV1RequestHandler for ZwpPrimarySelectionDeviceManagerV1 { + type Error = ZwpPrimarySelectionDeviceManagerV1Error; + + fn create_source(&self, req: CreateSource, _slf: &Rc) -> Result<(), Self::Error> { + let res = Rc::new(ZwpPrimarySelectionSourceV1::new( + req.id, + &self.client, + self.version, + )); track!(self.client, res); self.client.add_client_obj(&res)?; Ok(()) } - fn get_data_device( - self: &Rc, - parser: MsgParser<'_, '_>, - ) -> Result<(), ZwpPrimarySelectionDeviceManagerV1Error> { - let req: GetDevice = self.client.parse(&**self, parser)?; + fn get_device(&self, req: GetDevice, _slf: &Rc) -> Result<(), Self::Error> { let seat = self.client.lookup(req.seat)?; let dev = Rc::new(ZwpPrimarySelectionDeviceV1::new( req.id, @@ -79,11 +76,7 @@ impl ZwpPrimarySelectionDeviceManagerV1 { Ok(()) } - fn destroy( - &self, - parser: MsgParser<'_, '_>, - ) -> Result<(), ZwpPrimarySelectionDeviceManagerV1Error> { - let _req: Destroy = self.client.parse(self, parser)?; + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { self.client.remove_obj(self)?; Ok(()) } @@ -109,10 +102,7 @@ simple_add_global!(ZwpPrimarySelectionDeviceManagerV1Global); object_base! { self = ZwpPrimarySelectionDeviceManagerV1; - - CREATE_SOURCE => create_source, - GET_DEVICE => get_data_device, - DESTROY => destroy, + version = self.version; } impl Object for ZwpPrimarySelectionDeviceManagerV1 {} @@ -121,10 +111,7 @@ simple_add_obj!(ZwpPrimarySelectionDeviceManagerV1); #[derive(Debug, Error)] pub enum ZwpPrimarySelectionDeviceManagerV1Error { - #[error("Parsing failed")] - MsgParserError(#[source] Box), #[error(transparent)] ClientError(Box), } efrom!(ZwpPrimarySelectionDeviceManagerV1Error, ClientError); -efrom!(ZwpPrimarySelectionDeviceManagerV1Error, MsgParserError); diff --git a/src/ifs/ipc/zwp_primary_selection_device_v1.rs b/src/ifs/ipc/zwp_primary_selection_device_v1.rs index 5cdb32c2..43041885 100644 --- a/src/ifs/ipc/zwp_primary_selection_device_v1.rs +++ b/src/ifs/ipc/zwp_primary_selection_device_v1.rs @@ -12,7 +12,6 @@ use { }, leaks::Tracker, object::{Object, Version}, - utils::buffd::{MsgParser, MsgParserError}, wire::{ zwp_primary_selection_device_v1::*, ZwpPrimarySelectionDeviceV1Id, ZwpPrimarySelectionOfferV1Id, @@ -64,12 +63,12 @@ impl ZwpPrimarySelectionDeviceV1 { id, }) } +} + +impl ZwpPrimarySelectionDeviceV1RequestHandler for ZwpPrimarySelectionDeviceV1 { + type Error = ZwpPrimarySelectionDeviceV1Error; - fn set_selection( - &self, - parser: MsgParser<'_, '_>, - ) -> Result<(), ZwpPrimarySelectionDeviceV1Error> { - let req: SetSelection = self.client.parse(self, parser)?; + fn set_selection(&self, req: SetSelection, _slf: &Rc) -> Result<(), Self::Error> { if !self.client.valid_serial(req.serial) { log::warn!("Client tried to set_selection with an invalid serial"); return Ok(()); @@ -90,8 +89,7 @@ impl ZwpPrimarySelectionDeviceV1 { Ok(()) } - fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), ZwpPrimarySelectionDeviceV1Error> { - let _req: Destroy = self.client.parse(self, parser)?; + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { destroy_data_device::(self); self.seat.remove_primary_selection_device(self); self.client.remove_obj(self)?; @@ -144,6 +142,7 @@ impl IpcVtable for PrimarySelectionIpc { client: device.client.clone(), data: offer_data, tracker: Default::default(), + version: device.version, }); track!(device.client, rc); device.client.add_server_obj(&rc); @@ -169,9 +168,7 @@ impl IpcVtable for PrimarySelectionIpc { object_base! { self = ZwpPrimarySelectionDeviceV1; - - SET_SELECTION => set_selection, - DESTROY => destroy, + version = self.version; } impl Object for ZwpPrimarySelectionDeviceV1 { @@ -187,11 +184,8 @@ simple_add_obj!(ZwpPrimarySelectionDeviceV1); pub enum ZwpPrimarySelectionDeviceV1Error { #[error(transparent)] ClientError(Box), - #[error("Parsing failed")] - MsgParserError(#[source] Box), #[error(transparent)] WlSeatError(Box), } efrom!(ZwpPrimarySelectionDeviceV1Error, ClientError); -efrom!(ZwpPrimarySelectionDeviceV1Error, MsgParserError); efrom!(ZwpPrimarySelectionDeviceV1Error, WlSeatError); diff --git a/src/ifs/ipc/zwp_primary_selection_offer_v1.rs b/src/ifs/ipc/zwp_primary_selection_offer_v1.rs index d6a7caa3..7690b4fe 100644 --- a/src/ifs/ipc/zwp_primary_selection_offer_v1.rs +++ b/src/ifs/ipc/zwp_primary_selection_offer_v1.rs @@ -12,8 +12,7 @@ use { wl_seat::WlSeatGlobal, }, leaks::Tracker, - object::Object, - utils::buffd::{MsgParser, MsgParserError}, + object::{Object, Version}, wire::{zwp_primary_selection_offer_v1::*, ZwpPrimarySelectionOfferV1Id}, }, std::rc::Rc, @@ -27,6 +26,7 @@ pub struct ZwpPrimarySelectionOfferV1 { pub client: Rc, pub data: OfferData, pub tracker: Tracker, + pub version: Version, } impl DataOffer for ZwpPrimarySelectionOfferV1 { @@ -70,15 +70,17 @@ impl ZwpPrimarySelectionOfferV1 { mime_type, }) } +} + +impl ZwpPrimarySelectionOfferV1RequestHandler for ZwpPrimarySelectionOfferV1 { + type Error = ZwpPrimarySelectionOfferV1Error; - fn receive(&self, parser: MsgParser<'_, '_>) -> Result<(), ZwpPrimarySelectionOfferV1Error> { - let req: Receive = self.client.parse(self, parser)?; + fn receive(&self, req: Receive, _slf: &Rc) -> Result<(), Self::Error> { receive_data_offer::(self, req.mime_type, req.fd); Ok(()) } - fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), ZwpPrimarySelectionOfferV1Error> { - let _req: Destroy = self.client.parse(self, parser)?; + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { destroy_data_offer::(self); self.client.remove_obj(self)?; Ok(()) @@ -87,9 +89,7 @@ impl ZwpPrimarySelectionOfferV1 { object_base! { self = ZwpPrimarySelectionOfferV1; - - RECEIVE => receive, - DESTROY => destroy, + version = self.version; } impl Object for ZwpPrimarySelectionOfferV1 { @@ -102,10 +102,7 @@ simple_add_obj!(ZwpPrimarySelectionOfferV1); #[derive(Debug, Error)] pub enum ZwpPrimarySelectionOfferV1Error { - #[error("Parsing failed")] - MsgParserError(#[source] Box), #[error(transparent)] ClientError(Box), } efrom!(ZwpPrimarySelectionOfferV1Error, ClientError); -efrom!(ZwpPrimarySelectionOfferV1Error, MsgParserError); diff --git a/src/ifs/ipc/zwp_primary_selection_source_v1.rs b/src/ifs/ipc/zwp_primary_selection_source_v1.rs index d6d50683..9cf1f735 100644 --- a/src/ifs/ipc/zwp_primary_selection_source_v1.rs +++ b/src/ifs/ipc/zwp_primary_selection_source_v1.rs @@ -14,8 +14,7 @@ use { wl_seat::WlSeatGlobal, }, leaks::Tracker, - object::Object, - utils::buffd::{MsgParser, MsgParserError}, + object::{Object, Version}, wire::{zwp_primary_selection_source_v1::*, ZwpPrimarySelectionSourceV1Id}, }, std::rc::Rc, @@ -27,6 +26,7 @@ pub struct ZwpPrimarySelectionSourceV1 { pub id: ZwpPrimarySelectionSourceV1Id, pub data: SourceData, pub tracker: Tracker, + pub version: Version, } impl DataSource for ZwpPrimarySelectionSourceV1 { @@ -66,11 +66,12 @@ impl DynDataSource for ZwpPrimarySelectionSourceV1 { } impl ZwpPrimarySelectionSourceV1 { - pub fn new(id: ZwpPrimarySelectionSourceV1Id, client: &Rc) -> Self { + pub fn new(id: ZwpPrimarySelectionSourceV1Id, client: &Rc, version: Version) -> Self { Self { id, data: SourceData::new(client), tracker: Default::default(), + version, } } @@ -85,15 +86,17 @@ impl ZwpPrimarySelectionSourceV1 { fd, }) } +} + +impl ZwpPrimarySelectionSourceV1RequestHandler for ZwpPrimarySelectionSourceV1 { + type Error = ZwpPrimarySelectionSourceV1Error; - fn offer(&self, parser: MsgParser<'_, '_>) -> Result<(), ZwpPrimarySelectionSourceV1Error> { - let req: Offer = self.data.client.parse(self, parser)?; + fn offer(&self, req: Offer, _slf: &Rc) -> Result<(), Self::Error> { add_data_source_mime_type::(self, req.mime_type); Ok(()) } - fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), ZwpPrimarySelectionSourceV1Error> { - let _req: Destroy = self.data.client.parse(self, parser)?; + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { destroy_data_source::(self); self.data.client.remove_obj(self)?; Ok(()) @@ -102,9 +105,7 @@ impl ZwpPrimarySelectionSourceV1 { object_base! { self = ZwpPrimarySelectionSourceV1; - - OFFER => offer, - DESTROY => destroy, + version = self.version; } impl Object for ZwpPrimarySelectionSourceV1 { @@ -123,8 +124,5 @@ dedicated_add_obj!( pub enum ZwpPrimarySelectionSourceV1Error { #[error(transparent)] ClientError(Box), - #[error("Parsing failed")] - MsgParserError(#[source] Box), } efrom!(ZwpPrimarySelectionSourceV1Error, ClientError); -efrom!(ZwpPrimarySelectionSourceV1Error, MsgParserError); diff --git a/src/ifs/jay_compositor.rs b/src/ifs/jay_compositor.rs index 134dc700..eb714db3 100644 --- a/src/ifs/jay_compositor.rs +++ b/src/ifs/jay_compositor.rs @@ -13,11 +13,7 @@ use { leaks::Tracker, object::{Object, Version}, screenshoter::take_screenshot, - utils::{ - buffd::{MsgParser, MsgParserError}, - clonecell::CloneCell, - errorfmt::ErrorFmt, - }, + utils::{clonecell::CloneCell, errorfmt::ErrorFmt}, wire::{jay_compositor::*, JayCompositorId, JayScreenshotId}, }, bstr::ByteSlice, @@ -77,14 +73,51 @@ pub struct JayCompositor { } impl JayCompositor { - fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), JayCompositorError> { - let _req: Destroy = self.client.parse(self, parser)?; + fn take_screenshot_impl( + &self, + id: JayScreenshotId, + include_cursor: bool, + ) -> Result<(), JayCompositorError> { + let ss = Rc::new(JayScreenshot { + id, + client: self.client.clone(), + tracker: Default::default(), + }); + track!(self.client, ss); + self.client.add_client_obj(&ss)?; + match take_screenshot(&self.client.state, include_cursor) { + Ok(s) => { + let dmabuf = s.bo.dmabuf(); + let plane = &dmabuf.planes[0]; + ss.send_dmabuf( + &s.drm, + &plane.fd, + dmabuf.width, + dmabuf.height, + plane.offset, + plane.stride, + dmabuf.modifier, + ); + } + Err(e) => { + let msg = ErrorFmt(e).to_string(); + ss.send_error(&msg); + } + } + self.client.remove_obj(ss.deref())?; + Ok(()) + } +} + +impl JayCompositorRequestHandler for JayCompositor { + type Error = JayCompositorError; + + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { self.client.remove_obj(self)?; Ok(()) } - fn get_log_file(&self, parser: MsgParser<'_, '_>) -> Result<(), JayCompositorError> { - let req: GetLogFile = self.client.parse(self, parser)?; + fn get_log_file(&self, req: GetLogFile, _slf: &Rc) -> Result<(), Self::Error> { let log_file = Rc::new(JayLogFile::new(req.id, &self.client)); track!(self.client, log_file); self.client.add_client_obj(&log_file)?; @@ -95,15 +128,13 @@ impl JayCompositor { Ok(()) } - fn quit(&self, parser: MsgParser<'_, '_>) -> Result<(), JayCompositorError> { - let _req: Quit = self.client.parse(self, parser)?; + fn quit(&self, _req: Quit, _slf: &Rc) -> Result<(), Self::Error> { log::info!("Quitting"); self.client.state.ring.stop(); Ok(()) } - fn set_log_level(&self, parser: MsgParser<'_, '_>) -> Result<(), JayCompositorError> { - let req: SetLogLevel = self.client.parse(self, parser)?; + fn set_log_level(&self, req: SetLogLevel, _slf: &Rc) -> Result<(), Self::Error> { const ERROR: u32 = CliLogLevel::Error as u32; const WARN: u32 = CliLogLevel::Warn as u32; const INFO: u32 = CliLogLevel::Info as u32; @@ -123,53 +154,15 @@ impl JayCompositor { Ok(()) } - fn take_screenshot(&self, parser: MsgParser<'_, '_>) -> Result<(), JayCompositorError> { - let req: TakeScreenshot = self.client.parse(self, parser)?; + fn take_screenshot(&self, req: TakeScreenshot, _slf: &Rc) -> Result<(), Self::Error> { self.take_screenshot_impl(req.id, false) } - fn take_screenshot2(&self, parser: MsgParser<'_, '_>) -> Result<(), JayCompositorError> { - let req: TakeScreenshot2 = self.client.parse(self, parser)?; + fn take_screenshot2(&self, req: TakeScreenshot2, _slf: &Rc) -> Result<(), Self::Error> { self.take_screenshot_impl(req.id, req.include_cursor != 0) } - fn take_screenshot_impl( - &self, - id: JayScreenshotId, - include_cursor: bool, - ) -> Result<(), JayCompositorError> { - let ss = Rc::new(JayScreenshot { - id, - client: self.client.clone(), - tracker: Default::default(), - }); - track!(self.client, ss); - self.client.add_client_obj(&ss)?; - match take_screenshot(&self.client.state, include_cursor) { - Ok(s) => { - let dmabuf = s.bo.dmabuf(); - let plane = &dmabuf.planes[0]; - ss.send_dmabuf( - &s.drm, - &plane.fd, - dmabuf.width, - dmabuf.height, - plane.offset, - plane.stride, - dmabuf.modifier, - ); - } - Err(e) => { - let msg = ErrorFmt(e).to_string(); - ss.send_error(&msg); - } - } - self.client.remove_obj(ss.deref())?; - Ok(()) - } - - fn get_idle(&self, parser: MsgParser<'_, '_>) -> Result<(), JayCompositorError> { - let req: GetIdle = self.client.parse(self, parser)?; + fn get_idle(&self, req: GetIdle, _slf: &Rc) -> Result<(), Self::Error> { let idle = Rc::new(JayIdle { id: req.id, client: self.client.clone(), @@ -180,8 +173,7 @@ impl JayCompositor { Ok(()) } - fn get_client_id(&self, parser: MsgParser<'_, '_>) -> Result<(), JayCompositorError> { - let _req: GetClientId = self.client.parse(self, parser)?; + fn get_client_id(&self, _req: GetClientId, _slf: &Rc) -> Result<(), Self::Error> { self.client.event(ClientId { self_id: self.id, client_id: self.client.id.raw(), @@ -189,14 +181,16 @@ impl JayCompositor { Ok(()) } - fn enable_symmetric_delete(&self, parser: MsgParser<'_, '_>) -> Result<(), JayCompositorError> { - let _req: EnableSymmetricDelete = self.client.parse(self, parser)?; + fn enable_symmetric_delete( + &self, + _req: EnableSymmetricDelete, + _slf: &Rc, + ) -> Result<(), Self::Error> { self.client.symmetric_delete.set(true); Ok(()) } - fn unlock(&self, parser: MsgParser<'_, '_>) -> Result<(), JayCompositorError> { - let _req: Unlock = self.client.parse(self, parser)?; + fn unlock(&self, _req: Unlock, _slf: &Rc) -> Result<(), Self::Error> { let state = &self.client.state; if state.lock.locked.replace(false) { if let Some(lock) = state.lock.lock.take() { @@ -214,8 +208,7 @@ impl JayCompositor { Ok(()) } - fn get_seats(&self, parser: MsgParser<'_, '_>) -> Result<(), JayCompositorError> { - let _req: GetSeats = self.client.parse(self, parser)?; + fn get_seats(&self, _req: GetSeats, _slf: &Rc) -> Result<(), Self::Error> { for seat in self.client.state.globals.seats.lock().values() { self.client.event(Seat { self_id: self.id, @@ -226,8 +219,7 @@ impl JayCompositor { Ok(()) } - fn seat_events(&self, parser: MsgParser<'_, '_>) -> Result<(), JayCompositorError> { - let req: SeatEvents = self.client.parse(self, parser)?; + fn seat_events(&self, req: SeatEvents, _slf: &Rc) -> Result<(), Self::Error> { let se = Rc::new(JaySeatEvents { id: req.id, client: self.client.clone(), @@ -243,8 +235,7 @@ impl JayCompositor { Ok(()) } - fn get_output(&self, parser: MsgParser<'_, '_>) -> Result<(), JayCompositorError> { - let req: GetOutput = self.client.parse(self, parser)?; + fn get_output(&self, req: GetOutput, _slf: &Rc) -> Result<(), Self::Error> { let output = self.client.lookup(req.output)?; let jo = Rc::new(JayOutput { id: req.id, @@ -263,8 +254,7 @@ impl JayCompositor { Ok(()) } - fn get_pointer(&self, parser: MsgParser<'_, '_>) -> Result<(), JayCompositorError> { - let req: GetPointer = self.client.parse(self, parser)?; + fn get_pointer(&self, req: GetPointer, _slf: &Rc) -> Result<(), Self::Error> { let seat = self.client.lookup(req.seat)?; let ctx = Rc::new(JayPointer { id: req.id, @@ -277,8 +267,7 @@ impl JayCompositor { Ok(()) } - fn get_render_ctx(&self, parser: MsgParser<'_, '_>) -> Result<(), JayCompositorError> { - let req: GetRenderCtx = self.client.parse(self, parser)?; + fn get_render_ctx(&self, req: GetRenderCtx, _slf: &Rc) -> Result<(), Self::Error> { let ctx = Rc::new(JayRenderCtx { id: req.id, client: self.client.clone(), @@ -295,8 +284,7 @@ impl JayCompositor { Ok(()) } - fn watch_workspaces(&self, parser: MsgParser<'_, '_>) -> Result<(), JayCompositorError> { - let req: WatchWorkspaces = self.client.parse(self, parser)?; + fn watch_workspaces(&self, req: WatchWorkspaces, _slf: &Rc) -> Result<(), Self::Error> { let watcher = Rc::new(JayWorkspaceWatcher { id: req.id, client: self.client.clone(), @@ -314,24 +302,21 @@ impl JayCompositor { Ok(()) } - fn create_screencast(&self, parser: MsgParser<'_, '_>) -> Result<(), JayCompositorError> { - let req: CreateScreencast = self.client.parse(self, parser)?; + fn create_screencast(&self, req: CreateScreencast, _slf: &Rc) -> Result<(), Self::Error> { let sc = Rc::new(JayScreencast::new(req.id, &self.client)); track!(self.client, sc); self.client.add_client_obj(&sc)?; Ok(()) } - fn get_randr(&self, parser: MsgParser<'_, '_>) -> Result<(), JayCompositorError> { - let req: GetRandr = self.client.parse(self, parser)?; + fn get_randr(&self, req: GetRandr, _slf: &Rc) -> Result<(), Self::Error> { let sc = Rc::new(JayRandr::new(req.id, &self.client)); track!(self.client, sc); self.client.add_client_obj(&sc)?; Ok(()) } - fn get_input(&self, parser: MsgParser<'_, '_>) -> Result<(), JayCompositorError> { - let req: GetInput = self.client.parse(self, parser)?; + fn get_input(&self, req: GetInput, _slf: &Rc) -> Result<(), Self::Error> { let sc = Rc::new(JayInput::new(req.id, &self.client)); track!(self.client, sc); self.client.add_client_obj(&sc)?; @@ -341,26 +326,7 @@ impl JayCompositor { object_base! { self = JayCompositor; - - DESTROY => destroy, - GET_LOG_FILE => get_log_file, - QUIT => quit, - SET_LOG_LEVEL => set_log_level, - TAKE_SCREENSHOT => take_screenshot, - GET_IDLE => get_idle, - GET_CLIENT_ID => get_client_id, - ENABLE_SYMMETRIC_DELETE => enable_symmetric_delete, - UNLOCK => unlock, - GET_SEATS => get_seats, - SEAT_EVENTS => seat_events, - GET_OUTPUT => get_output, - GET_POINTER => get_pointer, - GET_RENDER_CTX => get_render_ctx, - WATCH_WORKSPACES => watch_workspaces, - CREATE_SCREENCAST => create_screencast, - GET_RANDR => get_randr, - GET_INPUT => get_input, - TAKE_SCREENSHOT2 => take_screenshot2, + version = Version(1); } impl Object for JayCompositor {} @@ -369,12 +335,9 @@ simple_add_obj!(JayCompositor); #[derive(Debug, Error)] pub enum JayCompositorError { - #[error("Parsing failed")] - MsgParserError(#[source] Box), #[error(transparent)] ClientError(Box), #[error("Unknown log level {0}")] UnknownLogLevel(u32), } efrom!(JayCompositorError, ClientError); -efrom!(JayCompositorError, MsgParserError); diff --git a/src/ifs/jay_idle.rs b/src/ifs/jay_idle.rs index b36bbbd8..21dfa6db 100644 --- a/src/ifs/jay_idle.rs +++ b/src/ifs/jay_idle.rs @@ -3,8 +3,7 @@ use { client::{Client, ClientError}, ifs::wl_surface::zwp_idle_inhibitor_v1::ZwpIdleInhibitorV1, leaks::Tracker, - object::Object, - utils::buffd::{MsgParser, MsgParserError}, + object::{Object, Version}, wire::{jay_idle::*, JayIdleId}, }, std::{rc::Rc, time::Duration}, @@ -36,9 +35,12 @@ impl JayIdle { comm: &surface.client.pid_info.comm, }); } +} + +impl JayIdleRequestHandler for JayIdle { + type Error = JayIdleError; - fn get_status(&self, parser: MsgParser<'_, '_>) -> Result<(), JayIdleError> { - let _req: GetStatus = self.client.parse(self, parser)?; + fn get_status(&self, _req: GetStatus, _slf: &Rc) -> Result<(), Self::Error> { self.send_interval(); { let inhibitors = self.client.state.idle.inhibitors.lock(); @@ -49,8 +51,7 @@ impl JayIdle { Ok(()) } - fn set_interval(&self, parser: MsgParser<'_, '_>) -> Result<(), JayIdleError> { - let req: SetInterval = self.client.parse(self, parser)?; + fn set_interval(&self, req: SetInterval, _slf: &Rc) -> Result<(), Self::Error> { let interval = Duration::from_secs(req.interval); self.client.state.idle.set_timeout(interval); Ok(()) @@ -59,9 +60,7 @@ impl JayIdle { object_base! { self = JayIdle; - - GET_STATUS => get_status, - SET_INTERVAL => set_interval, + version = Version(1); } impl Object for JayIdle {} @@ -70,10 +69,7 @@ simple_add_obj!(JayIdle); #[derive(Debug, Error)] pub enum JayIdleError { - #[error("Parsing failed")] - MsgParserError(#[source] Box), #[error(transparent)] ClientError(Box), } efrom!(JayIdleError, ClientError); -efrom!(JayIdleError, MsgParserError); diff --git a/src/ifs/jay_input.rs b/src/ifs/jay_input.rs index 765a25ef..0f483617 100644 --- a/src/ifs/jay_input.rs +++ b/src/ifs/jay_input.rs @@ -9,12 +9,9 @@ use { AccelProfile, LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE, LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT, }, - object::Object, + object::{Object, Version}, state::{DeviceHandlerData, InputDeviceData}, - utils::{ - buffd::{MsgParser, MsgParserError}, - errorfmt::ErrorFmt, - }, + utils::errorfmt::ErrorFmt, wire::{jay_input::*, JayInputId}, xkbcommon::XkbCommonError, }, @@ -37,59 +34,6 @@ impl JayInput { } } - fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), JayInputError> { - let _req: Destroy = self.client.parse(self, parser)?; - self.client.remove_obj(self)?; - Ok(()) - } - - fn get_all(&self, parser: MsgParser<'_, '_>) -> Result<(), JayInputError> { - let _req: GetAll = self.client.parse(self, parser)?; - let state = &self.client.state; - for seat in state.globals.seats.lock().values() { - self.send_seat(seat); - } - for dev in state.input_device_handlers.borrow().values() { - self.send_input_device(dev); - } - Ok(()) - } - - fn get_seat(&self, parser: MsgParser<'_, '_>) -> Result<(), JayInputError> { - let req: GetSeat = self.client.parse(self, parser)?; - self.or_error(|| { - let seat = self.seat(req.name)?; - self.send_seat(&seat); - for dev in self.client.state.input_device_handlers.borrow().values() { - if let Some(attached) = dev.data.seat.get() { - if attached.id() == seat.id() { - self.send_input_device(dev); - } - } - } - Ok(()) - }) - } - - fn get_device(&self, parser: MsgParser<'_, '_>) -> Result<(), JayInputError> { - let req: GetDevice = self.client.parse(self, parser)?; - self.or_error(|| { - match self - .client - .state - .input_device_handlers - .borrow() - .get(&InputDeviceId::from_raw(req.id)) - { - None => Err(JayInputError::DeviceDoesNotExist(req.id)), - Some(d) => { - self.send_input_device(d); - Ok(()) - } - } - }) - } - fn seat(&self, name: &str) -> Result, JayInputError> { for seat in self.client.state.globals.seats.lock().values() { if seat.seat_name() == name { @@ -106,52 +50,6 @@ impl JayInput { Ok(()) } - fn set_repeat_rate(&self, parser: MsgParser<'_, '_>) -> Result<(), JayInputError> { - let req: SetRepeatRate = self.client.parse(self, parser)?; - self.or_error(|| { - if req.repeat_rate < 0 { - return Err(JayInputError::NegativeRepeatRate); - } - if req.repeat_delay < 0 { - return Err(JayInputError::NegativeRepeatDelay); - } - let seat = self.seat(req.seat)?; - seat.set_rate(req.repeat_rate, req.repeat_delay); - Ok(()) - }) - } - - fn set_keymap(&self, parser: MsgParser<'_, '_>) -> Result<(), JayInputError> { - let req: SetKeymap = self.client.parse(self, parser)?; - let cm = Rc::new(ClientMem::new(req.keymap.raw(), req.keymap_len as _, true)?).offset(0); - let mut map = vec![]; - cm.read(&mut map)?; - self.or_error(|| { - let map = self.client.state.xkb_ctx.keymap_from_str(&map)?; - let seat = self.seat(req.seat)?; - seat.set_keymap(&map); - Ok(()) - }) - } - - fn get_keymap(&self, parser: MsgParser<'_, '_>) -> Result<(), JayInputError> { - let req: GetKeymap = self.client.parse(self, parser)?; - self.or_error(|| { - let seat = self.seat(req.seat)?; - self.send_keymap(&seat); - Ok(()) - }) - } - - fn use_hardware_cursor(&self, parser: MsgParser<'_, '_>) -> Result<(), JayInputError> { - let req: UseHardwareCursor = self.client.parse(self, parser)?; - self.or_error(|| { - let seat = self.seat(req.seat)?; - seat.set_hardware_cursor(req.use_hardware_cursor != 0); - Ok(()) - }) - } - fn send_seat(&self, data: &WlSeatGlobal) { self.client.event(Seat { self_id: self.id, @@ -240,9 +138,74 @@ impl JayInput { Some(d) => Ok(d.data.clone()), } } +} + +impl JayInputRequestHandler for JayInput { + type Error = JayInputError; + + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { + self.client.remove_obj(self)?; + Ok(()) + } + + fn get_all(&self, _req: GetAll, _slf: &Rc) -> Result<(), Self::Error> { + let state = &self.client.state; + for seat in state.globals.seats.lock().values() { + self.send_seat(seat); + } + for dev in state.input_device_handlers.borrow().values() { + self.send_input_device(dev); + } + Ok(()) + } - fn set_accel_profile(&self, parser: MsgParser<'_, '_>) -> Result<(), JayInputError> { - let req: SetAccelProfile = self.client.parse(self, parser)?; + fn set_repeat_rate(&self, req: SetRepeatRate, _slf: &Rc) -> Result<(), Self::Error> { + self.or_error(|| { + if req.repeat_rate < 0 { + return Err(JayInputError::NegativeRepeatRate); + } + if req.repeat_delay < 0 { + return Err(JayInputError::NegativeRepeatDelay); + } + let seat = self.seat(req.seat)?; + seat.set_rate(req.repeat_rate, req.repeat_delay); + Ok(()) + }) + } + + fn set_keymap(&self, req: SetKeymap, _slf: &Rc) -> Result<(), Self::Error> { + let cm = Rc::new(ClientMem::new(req.keymap.raw(), req.keymap_len as _, true)?).offset(0); + let mut map = vec![]; + cm.read(&mut map)?; + self.or_error(|| { + let map = self.client.state.xkb_ctx.keymap_from_str(&map)?; + let seat = self.seat(req.seat)?; + seat.set_keymap(&map); + Ok(()) + }) + } + + fn use_hardware_cursor( + &self, + req: UseHardwareCursor, + _slf: &Rc, + ) -> Result<(), Self::Error> { + self.or_error(|| { + let seat = self.seat(req.seat)?; + seat.set_hardware_cursor(req.use_hardware_cursor != 0); + Ok(()) + }) + } + + fn get_keymap(&self, req: GetKeymap, _slf: &Rc) -> Result<(), Self::Error> { + self.or_error(|| { + let seat = self.seat(req.seat)?; + self.send_keymap(&seat); + Ok(()) + }) + } + + fn set_accel_profile(&self, req: SetAccelProfile, _slf: &Rc) -> Result<(), Self::Error> { self.or_error(|| { let dev = self.device(req.id)?; let profile = match AccelProfile(req.profile) { @@ -255,8 +218,7 @@ impl JayInput { }) } - fn set_accel_speed(&self, parser: MsgParser<'_, '_>) -> Result<(), JayInputError> { - let req: SetAccelSpeed = self.client.parse(self, parser)?; + fn set_accel_speed(&self, req: SetAccelSpeed, _slf: &Rc) -> Result<(), Self::Error> { self.or_error(|| { let dev = self.device(req.id)?; dev.device.set_accel_speed(req.speed); @@ -264,8 +226,7 @@ impl JayInput { }) } - fn set_tap_enabled(&self, parser: MsgParser<'_, '_>) -> Result<(), JayInputError> { - let req: SetTapEnabled = self.client.parse(self, parser)?; + fn set_tap_enabled(&self, req: SetTapEnabled, _slf: &Rc) -> Result<(), Self::Error> { self.or_error(|| { let dev = self.device(req.id)?; dev.device.set_tap_enabled(req.enabled != 0); @@ -273,8 +234,11 @@ impl JayInput { }) } - fn set_tap_drag_enabled(&self, parser: MsgParser<'_, '_>) -> Result<(), JayInputError> { - let req: SetTapDragEnabled = self.client.parse(self, parser)?; + fn set_tap_drag_enabled( + &self, + req: SetTapDragEnabled, + _slf: &Rc, + ) -> Result<(), Self::Error> { self.or_error(|| { let dev = self.device(req.id)?; dev.device.set_drag_enabled(req.enabled != 0); @@ -282,8 +246,11 @@ impl JayInput { }) } - fn set_tap_drag_lock_enabled(&self, parser: MsgParser<'_, '_>) -> Result<(), JayInputError> { - let req: SetTapDragEnabled = self.client.parse(self, parser)?; + fn set_tap_drag_lock_enabled( + &self, + req: SetTapDragLockEnabled, + _slf: &Rc, + ) -> Result<(), Self::Error> { self.or_error(|| { let dev = self.device(req.id)?; dev.device.set_drag_lock_enabled(req.enabled != 0); @@ -291,8 +258,7 @@ impl JayInput { }) } - fn set_left_handed(&self, parser: MsgParser<'_, '_>) -> Result<(), JayInputError> { - let req: SetLeftHanded = self.client.parse(self, parser)?; + fn set_left_handed(&self, req: SetLeftHanded, _slf: &Rc) -> Result<(), Self::Error> { self.or_error(|| { let dev = self.device(req.id)?; dev.device.set_left_handed(req.enabled != 0); @@ -300,8 +266,11 @@ impl JayInput { }) } - fn set_natural_scrolling(&self, parser: MsgParser<'_, '_>) -> Result<(), JayInputError> { - let req: SetNaturalScrolling = self.client.parse(self, parser)?; + fn set_natural_scrolling( + &self, + req: SetNaturalScrolling, + _slf: &Rc, + ) -> Result<(), Self::Error> { self.or_error(|| { let dev = self.device(req.id)?; dev.device.set_natural_scrolling_enabled(req.enabled != 0); @@ -309,8 +278,11 @@ impl JayInput { }) } - fn set_px_per_wheel_scroll(&self, parser: MsgParser<'_, '_>) -> Result<(), JayInputError> { - let req: SetPxPerWheelScroll = self.client.parse(self, parser)?; + fn set_px_per_wheel_scroll( + &self, + req: SetPxPerWheelScroll, + _slf: &Rc, + ) -> Result<(), Self::Error> { self.or_error(|| { let dev = self.device(req.id)?; dev.px_per_scroll_wheel.set(req.px); @@ -318,8 +290,11 @@ impl JayInput { }) } - fn set_transform_matrix(&self, parser: MsgParser<'_, '_>) -> Result<(), JayInputError> { - let req: SetTransformMatrix = self.client.parse(self, parser)?; + fn set_transform_matrix( + &self, + req: SetTransformMatrix, + _slf: &Rc, + ) -> Result<(), Self::Error> { self.or_error(|| { let dev = self.device(req.id)?; dev.device @@ -328,8 +303,7 @@ impl JayInput { }) } - fn set_cursor_size(&self, parser: MsgParser<'_, '_>) -> Result<(), JayInputError> { - let req: SetCursorSize = self.client.parse(self, parser)?; + fn set_cursor_size(&self, req: SetCursorSize, _slf: &Rc) -> Result<(), Self::Error> { self.or_error(|| { let seat = self.seat(req.seat)?; seat.set_cursor_size(req.size); @@ -337,8 +311,7 @@ impl JayInput { }) } - fn attach(&self, parser: MsgParser<'_, '_>) -> Result<(), JayInputError> { - let req: Attach = self.client.parse(self, parser)?; + fn attach(&self, req: Attach, _slf: &Rc) -> Result<(), Self::Error> { self.or_error(|| { let seat = self.seat(req.seat)?; let dev = self.device(req.id)?; @@ -347,39 +320,51 @@ impl JayInput { }) } - fn detach(&self, parser: MsgParser<'_, '_>) -> Result<(), JayInputError> { - let req: Detach = self.client.parse(self, parser)?; + fn detach(&self, req: Detach, _slf: &Rc) -> Result<(), Self::Error> { self.or_error(|| { let dev = self.device(req.id)?; dev.seat.set(None); Ok(()) }) } + + fn get_seat(&self, req: GetSeat, _slf: &Rc) -> Result<(), Self::Error> { + self.or_error(|| { + let seat = self.seat(req.name)?; + self.send_seat(&seat); + for dev in self.client.state.input_device_handlers.borrow().values() { + if let Some(attached) = dev.data.seat.get() { + if attached.id() == seat.id() { + self.send_input_device(dev); + } + } + } + Ok(()) + }) + } + + fn get_device(&self, req: GetDevice, _slf: &Rc) -> Result<(), Self::Error> { + self.or_error(|| { + match self + .client + .state + .input_device_handlers + .borrow() + .get(&InputDeviceId::from_raw(req.id)) + { + None => Err(JayInputError::DeviceDoesNotExist(req.id)), + Some(d) => { + self.send_input_device(d); + Ok(()) + } + } + }) + } } object_base! { self = JayInput; - - DESTROY => destroy, - GET_ALL => get_all, - SET_REPEAT_RATE => set_repeat_rate, - SET_KEYMAP => set_keymap, - USE_HARDWARE_CURSOR => use_hardware_cursor, - GET_KEYMAP => get_keymap, - SET_ACCEL_PROFILE => set_accel_profile, - SET_ACCEL_SPEED => set_accel_speed, - SET_TAP_ENABLED => set_tap_enabled, - SET_TAP_DRAG_ENABLED => set_tap_drag_enabled, - SET_TAP_DRAG_LOCK_ENABLED => set_tap_drag_lock_enabled, - SET_LEFT_HANDED => set_left_handed, - SET_NATURAL_SCROLLING => set_natural_scrolling, - SET_PX_PER_WHEEL_SCROLL => set_px_per_wheel_scroll, - SET_TRANSFORM_MATRIX => set_transform_matrix, - SET_CURSOR_SIZE => set_cursor_size, - ATTACH => attach, - DETACH => detach, - GET_SEAT => get_seat, - GET_DEVICE => get_device, + version = Version(1); } impl Object for JayInput {} @@ -388,8 +373,6 @@ simple_add_obj!(JayInput); #[derive(Debug, Error)] pub enum JayInputError { - #[error("Parsing failed")] - MsgParserError(Box), #[error(transparent)] ClientError(Box), #[error("There is no seat called {0}")] @@ -407,5 +390,4 @@ pub enum JayInputError { #[error("Could not parse keymap")] XkbCommonError(#[from] XkbCommonError), } -efrom!(JayInputError, MsgParserError); efrom!(JayInputError, ClientError); diff --git a/src/ifs/jay_log_file.rs b/src/ifs/jay_log_file.rs index 3c75e23e..72957ea6 100644 --- a/src/ifs/jay_log_file.rs +++ b/src/ifs/jay_log_file.rs @@ -2,8 +2,7 @@ use { crate::{ client::{Client, ClientError}, leaks::Tracker, - object::Object, - utils::buffd::{MsgParser, MsgParserError}, + object::{Object, Version}, wire::{jay_log_file::*, JayLogFileId}, }, bstr::BStr, @@ -26,12 +25,6 @@ impl JayLogFile { } } - fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), JayLogFileError> { - let _req: Destroy = self.client.parse(self, parser)?; - self.client.remove_obj(self)?; - Ok(()) - } - pub fn send_path(&self, path: &BStr) { self.client.event(Path { self_id: self.id, @@ -40,10 +33,18 @@ impl JayLogFile { } } +impl JayLogFileRequestHandler for JayLogFile { + type Error = JayLogFileError; + + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { + self.client.remove_obj(self)?; + Ok(()) + } +} + object_base! { self = JayLogFile; - - DESTROY => destroy, + version = Version(1); } impl Object for JayLogFile {} @@ -52,10 +53,7 @@ simple_add_obj!(JayLogFile); #[derive(Debug, Error)] pub enum JayLogFileError { - #[error("Parsing failed")] - MsgParserError(#[source] Box), #[error(transparent)] ClientError(Box), } efrom!(JayLogFileError, ClientError); -efrom!(JayLogFileError, MsgParserError); diff --git a/src/ifs/jay_output.rs b/src/ifs/jay_output.rs index 6dde371c..b56ec159 100644 --- a/src/ifs/jay_output.rs +++ b/src/ifs/jay_output.rs @@ -2,12 +2,9 @@ use { crate::{ client::{Client, ClientError}, leaks::Tracker, - object::Object, + object::{Object, Version}, tree::OutputNode, - utils::{ - buffd::{MsgParser, MsgParserError}, - clonecell::CloneCell, - }, + utils::clonecell::CloneCell, wire::{jay_output::*, JayOutputId}, }, std::rc::Rc, @@ -35,13 +32,6 @@ impl JayOutput { } } - fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), JayOutputError> { - let _req: Destroy = self.client.parse(self, parser)?; - self.remove_from_node(); - self.client.remove_obj(self)?; - Ok(()) - } - fn remove_from_node(&self) { if let Some(output) = self.output.get() { output.jay_outputs.remove(&(self.client.id, self.id)); @@ -49,10 +39,19 @@ impl JayOutput { } } +impl JayOutputRequestHandler for JayOutput { + type Error = JayOutputError; + + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { + self.remove_from_node(); + self.client.remove_obj(self)?; + Ok(()) + } +} + object_base! { self = JayOutput; - - DESTROY => destroy, + version = Version(1); } impl Object for JayOutput { @@ -65,10 +64,7 @@ dedicated_add_obj!(JayOutput, JayOutputId, jay_outputs); #[derive(Debug, Error)] pub enum JayOutputError { - #[error("Parsing failed")] - MsgParserError(Box), #[error(transparent)] ClientError(Box), } -efrom!(JayOutputError, MsgParserError); efrom!(JayOutputError, ClientError); diff --git a/src/ifs/jay_pointer.rs b/src/ifs/jay_pointer.rs index 6f9c219e..35170189 100644 --- a/src/ifs/jay_pointer.rs +++ b/src/ifs/jay_pointer.rs @@ -4,8 +4,7 @@ use { cursor::KnownCursor, ifs::wl_seat::WlSeatGlobal, leaks::Tracker, - object::Object, - utils::buffd::{MsgParser, MsgParserError}, + object::{Object, Version}, wire::{jay_pointer::*, JayPointerId}, }, num_traits::FromPrimitive, @@ -20,15 +19,15 @@ pub struct JayPointer { pub tracker: Tracker, } -impl JayPointer { - fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), JayPointerError> { - let _req: Destroy = self.client.parse(self, parser)?; +impl JayPointerRequestHandler for JayPointer { + type Error = JayPointerError; + + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { self.client.remove_obj(self)?; Ok(()) } - fn set_known_cursor(&self, parser: MsgParser<'_, '_>) -> Result<(), JayPointerError> { - let req: SetKnownCursor = self.client.parse(self, parser)?; + fn set_known_cursor(&self, req: SetKnownCursor, _slf: &Rc) -> Result<(), Self::Error> { let cursor = match KnownCursor::from_u32(req.idx) { Some(c) => c, _ => return Err(JayPointerError::OutOfBounds), @@ -50,9 +49,7 @@ impl JayPointer { object_base! { self = JayPointer; - - DESTROY => destroy, - SET_KNOWN_CURSOR => set_known_cursor, + version = Version(1); } impl Object for JayPointer {} @@ -61,12 +58,9 @@ 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/jay_randr.rs b/src/ifs/jay_randr.rs index 735f65a8..923e70cc 100644 --- a/src/ifs/jay_randr.rs +++ b/src/ifs/jay_randr.rs @@ -4,14 +4,10 @@ use { client::{Client, ClientError}, compositor::MAX_EXTENTS, leaks::Tracker, - object::Object, + object::{Object, Version}, scale::Scale, state::{ConnectorData, DrmDevData, OutputData}, - utils::{ - buffd::{MsgParser, MsgParserError}, - gfx_api_ext::GfxApiExt, - transform_ext::TransformExt, - }, + utils::{gfx_api_ext::GfxApiExt, transform_ext::TransformExt}, wire::{jay_randr::*, JayRandrId}, }, jay_config::video::{GfxApi, Transform}, @@ -34,25 +30,6 @@ impl JayRandr { } } - fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), JayRandrError> { - let _req: Destroy = self.client.parse(self, parser)?; - self.client.remove_obj(self)?; - Ok(()) - } - - fn get(&self, parser: MsgParser<'_, '_>) -> Result<(), JayRandrError> { - let _req: Get = self.client.parse(self, parser)?; - let state = &self.client.state; - self.send_global(); - for dev in state.drm_devs.lock().values() { - self.send_drm_device(dev); - } - for connector in state.connectors.lock().values() { - self.send_connector(connector); - } - Ok(()) - } - fn send_global(&self) { self.client.event(Global { self_id: self.id, @@ -167,9 +144,29 @@ impl JayRandr { } None } +} + +impl JayRandrRequestHandler for JayRandr { + type Error = JayRandrError; - fn set_api(&self, parser: MsgParser<'_, '_>) -> Result<(), JayRandrError> { - let req: SetApi = self.client.parse(self, parser)?; + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { + self.client.remove_obj(self)?; + Ok(()) + } + + fn get(&self, _req: Get, _slf: &Rc) -> Result<(), Self::Error> { + let state = &self.client.state; + self.send_global(); + for dev in state.drm_devs.lock().values() { + self.send_drm_device(dev); + } + for connector in state.connectors.lock().values() { + self.send_connector(connector); + } + Ok(()) + } + + fn set_api(&self, req: SetApi, _slf: &Rc) -> Result<(), Self::Error> { let Some(dev) = self.get_device(req.dev) else { return Ok(()); }; @@ -181,8 +178,11 @@ impl JayRandr { Ok(()) } - fn make_render_device(&self, parser: MsgParser<'_, '_>) -> Result<(), JayRandrError> { - let req: MakeRenderDevice = self.client.parse(self, parser)?; + fn make_render_device( + &self, + req: MakeRenderDevice, + _slf: &Rc, + ) -> Result<(), Self::Error> { let Some(dev) = self.get_device(req.dev) else { return Ok(()); }; @@ -190,8 +190,11 @@ impl JayRandr { Ok(()) } - fn set_direct_scanout(&self, parser: MsgParser<'_, '_>) -> Result<(), JayRandrError> { - let req: SetDirectScanout = self.client.parse(self, parser)?; + fn set_direct_scanout( + &self, + req: SetDirectScanout, + _slf: &Rc, + ) -> Result<(), Self::Error> { let Some(dev) = self.get_device(req.dev) else { return Ok(()); }; @@ -199,8 +202,7 @@ impl JayRandr { Ok(()) } - fn set_transform(&self, parser: MsgParser<'_, '_>) -> Result<(), JayRandrError> { - let req: SetTransform = self.client.parse(self, parser)?; + fn set_transform(&self, req: SetTransform, _slf: &Rc) -> Result<(), Self::Error> { let Some(c) = self.get_output(req.output) else { return Ok(()); }; @@ -212,8 +214,7 @@ impl JayRandr { Ok(()) } - fn set_scale(&self, parser: MsgParser<'_, '_>) -> Result<(), JayRandrError> { - let req: SetScale = self.client.parse(self, parser)?; + fn set_scale(&self, req: SetScale, _slf: &Rc) -> Result<(), Self::Error> { let Some(c) = self.get_output(req.output) else { return Ok(()); }; @@ -221,8 +222,7 @@ impl JayRandr { Ok(()) } - fn set_mode(&self, parser: MsgParser<'_, '_>) -> Result<(), JayRandrError> { - let req: SetMode = self.client.parse(self, parser)?; + fn set_mode(&self, req: SetMode, _slf: &Rc) -> Result<(), Self::Error> { let Some(c) = self.get_output(req.output) else { return Ok(()); }; @@ -234,8 +234,7 @@ impl JayRandr { Ok(()) } - fn set_position(&self, parser: MsgParser<'_, '_>) -> Result<(), JayRandrError> { - let req: SetPosition = self.client.parse(self, parser)?; + fn set_position(&self, req: SetPosition, _slf: &Rc) -> Result<(), Self::Error> { let Some(c) = self.get_output(req.output) else { return Ok(()); }; @@ -251,8 +250,7 @@ impl JayRandr { Ok(()) } - fn set_enabled(&self, parser: MsgParser<'_, '_>) -> Result<(), JayRandrError> { - let req: SetEnabled = self.client.parse(self, parser)?; + fn set_enabled(&self, req: SetEnabled, _slf: &Rc) -> Result<(), Self::Error> { let Some(c) = self.get_connector(req.output) else { return Ok(()); }; @@ -263,17 +261,7 @@ impl JayRandr { object_base! { self = JayRandr; - - DESTROY => destroy, - GET => get, - SET_API => set_api, - MAKE_RENDER_DEVICE => make_render_device, - SET_DIRECT_SCANOUT => set_direct_scanout, - SET_TRANSFORM => set_transform, - SET_SCALE => set_scale, - SET_MODE => set_mode, - SET_POSITION => set_position, - SET_ENABLED => set_enabled, + version = Version(1); } impl Object for JayRandr {} @@ -282,10 +270,7 @@ simple_add_obj!(JayRandr); #[derive(Debug, Error)] pub enum JayRandrError { - #[error("Parsing failed")] - MsgParserError(Box), #[error(transparent)] ClientError(Box), } -efrom!(JayRandrError, MsgParserError); efrom!(JayRandrError, ClientError); diff --git a/src/ifs/jay_render_ctx.rs b/src/ifs/jay_render_ctx.rs index 17b16166..724e0967 100644 --- a/src/ifs/jay_render_ctx.rs +++ b/src/ifs/jay_render_ctx.rs @@ -3,11 +3,8 @@ use { client::{Client, ClientError}, gfx_api::GfxContext, leaks::Tracker, - object::Object, - utils::{ - buffd::{MsgParser, MsgParserError}, - errorfmt::ErrorFmt, - }, + object::{Object, Version}, + utils::errorfmt::ErrorFmt, wire::{jay_render_ctx::*, JayRenderCtxId}, }, std::rc::Rc, @@ -42,13 +39,6 @@ impl JayRenderCtx { } } - fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), JayRenderCtxError> { - let _req: Destroy = self.client.parse(self, parser)?; - self.remove_from_state(); - self.client.remove_obj(self)?; - Ok(()) - } - fn remove_from_state(&self) { self.client .state @@ -57,10 +47,19 @@ impl JayRenderCtx { } } +impl JayRenderCtxRequestHandler for JayRenderCtx { + type Error = JayRenderCtxError; + + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { + self.remove_from_state(); + self.client.remove_obj(self)?; + Ok(()) + } +} + object_base! { self = JayRenderCtx; - - DESTROY => destroy, + version = Version(1); } impl Object for JayRenderCtx { @@ -73,10 +72,7 @@ simple_add_obj!(JayRenderCtx); #[derive(Debug, Error)] pub enum JayRenderCtxError { - #[error("Parsing failed")] - MsgParserError(Box), #[error(transparent)] ClientError(Box), } -efrom!(JayRenderCtxError, MsgParserError); efrom!(JayRenderCtxError, ClientError); diff --git a/src/ifs/jay_screencast.rs b/src/ifs/jay_screencast.rs index 4e655d83..89da2708 100644 --- a/src/ifs/jay_screencast.rs +++ b/src/ifs/jay_screencast.rs @@ -5,14 +5,10 @@ use { gfx_api::{GfxContext, GfxError, GfxFramebuffer, GfxTexture}, ifs::jay_output::JayOutput, leaks::Tracker, - object::Object, + object::{Object, Version}, tree::{OutputNode, WorkspaceNodeId}, utils::{ - buffd::{MsgParser, MsgParserError}, - clonecell::CloneCell, - errorfmt::ErrorFmt, - numcell::NumCell, - option_ext::OptionExt, + clonecell::CloneCell, errorfmt::ErrorFmt, numcell::NumCell, option_ext::OptionExt, }, video::{ dmabuf::DmaBuf, @@ -26,7 +22,7 @@ use { once_cell::sync::Lazy, std::{ cell::{Cell, RefCell}, - ops::{Deref, DerefMut}, + ops::DerefMut, rc::Rc, }, thiserror::Error, @@ -277,16 +273,16 @@ impl JayScreencast { } } -impl JayScreencast { - fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), JayScreencastError> { - let _req: Destroy = self.client.parse(self, parser)?; +impl JayScreencastRequestHandler for JayScreencast { + type Error = JayScreencastError; + + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { self.detach(); self.client.remove_obj(self)?; Ok(()) } - fn set_output(&self, parser: MsgParser<'_, '_>) -> Result<(), JayScreencastError> { - let req: SetOutput = self.client.parse(self, parser)?; + fn set_output(&self, req: SetOutput, _slf: &Rc) -> Result<(), Self::Error> { let output = if req.output.is_some() { Some(self.client.lookup(req.output)?) } else { @@ -301,9 +297,9 @@ impl JayScreencast { fn set_allow_all_workspaces( &self, - parser: MsgParser<'_, '_>, - ) -> Result<(), JayScreencastError> { - let req: SetAllowAllWorkspaces = self.client.parse(self, parser)?; + req: SetAllowAllWorkspaces, + _slf: &Rc, + ) -> Result<(), Self::Error> { if self.destroyed.get() || !self.config_acked.get() { return Ok(()); } @@ -311,8 +307,7 @@ impl JayScreencast { Ok(()) } - fn allow_workspace(&self, parser: MsgParser<'_, '_>) -> Result<(), JayScreencastError> { - let req: AllowWorkspace = self.client.parse(self, parser)?; + fn allow_workspace(&self, req: AllowWorkspace, _slf: &Rc) -> Result<(), Self::Error> { let ws = self.client.lookup(req.workspace)?; if self.destroyed.get() || !self.config_acked.get() { return Ok(()); @@ -327,9 +322,9 @@ impl JayScreencast { fn touch_allowed_workspaces( &self, - parser: MsgParser<'_, '_>, - ) -> Result<(), JayScreencastError> { - let _req: TouchAllowedWorkspaces = self.client.parse(self, parser)?; + _req: TouchAllowedWorkspaces, + _slf: &Rc, + ) -> Result<(), Self::Error> { if self.destroyed.get() || !self.config_acked.get() { return Ok(()); } @@ -340,8 +335,11 @@ impl JayScreencast { Ok(()) } - fn set_use_linear_buffers(&self, parser: MsgParser<'_, '_>) -> Result<(), JayScreencastError> { - let req: SetUseLinearBuffers = self.client.parse(self, parser)?; + fn set_use_linear_buffers( + &self, + req: SetUseLinearBuffers, + _slf: &Rc, + ) -> Result<(), Self::Error> { if self.destroyed.get() || !self.config_acked.get() { return Ok(()); } @@ -349,8 +347,7 @@ impl JayScreencast { Ok(()) } - fn set_running(&self, parser: MsgParser<'_, '_>) -> Result<(), JayScreencastError> { - let req: SetRunning = self.client.parse(self, parser)?; + fn set_running(&self, req: SetRunning, _slf: &Rc) -> Result<(), Self::Error> { if self.destroyed.get() || !self.config_acked.get() { return Ok(()); } @@ -358,9 +355,7 @@ impl JayScreencast { Ok(()) } - fn configure(self: &Rc, parser: MsgParser<'_, '_>) -> Result<(), JayScreencastError> { - let _req: Configure = self.client.parse(self.deref(), parser)?; - + fn configure(&self, _req: Configure, slf: &Rc) -> Result<(), Self::Error> { if self.destroyed.get() || !self.config_acked.get() { return Ok(()); } @@ -377,7 +372,7 @@ impl JayScreencast { if new.screencasts.is_empty() { new.state.damage(); } - new.screencasts.set((self.client.id, self.id), self.clone()); + new.screencasts.set((self.client.id, self.id), slf.clone()); } self.output.set(output); } @@ -414,8 +409,7 @@ impl JayScreencast { Ok(()) } - fn ack_buffers(&self, parser: MsgParser<'_, '_>) -> Result<(), JayScreencastError> { - let req: AckBuffers = self.client.parse(self, parser)?; + fn ack_buffers(&self, req: AckBuffers, _slf: &Rc) -> Result<(), Self::Error> { if self.destroyed.get() { return Ok(()); } @@ -425,8 +419,7 @@ impl JayScreencast { Ok(()) } - fn ack_config(&self, parser: MsgParser<'_, '_>) -> Result<(), JayScreencastError> { - let req: AckConfig = self.client.parse(self, parser)?; + fn ack_config(&self, req: AckConfig, _slf: &Rc) -> Result<(), Self::Error> { if self.destroyed.get() { return Ok(()); } @@ -436,8 +429,7 @@ impl JayScreencast { Ok(()) } - fn release_buffer(&self, parser: MsgParser<'_, '_>) -> Result<(), JayScreencastError> { - let req: ReleaseBuffer = self.client.parse(self, parser)?; + fn release_buffer(&self, req: ReleaseBuffer, _slf: &Rc) -> Result<(), Self::Error> { if self.destroyed.get() || !self.buffers_acked.get() { return Ok(()); } @@ -455,18 +447,7 @@ impl JayScreencast { object_base! { self = JayScreencast; - - DESTROY => destroy, - SET_OUTPUT => set_output, - SET_ALLOW_ALL_WORKSPACES => set_allow_all_workspaces, - ALLOW_WORKSPACE => allow_workspace, - TOUCH_ALLOWED_WORKSPACES => touch_allowed_workspaces, - SET_USE_LINEAR_BUFFERS => set_use_linear_buffers, - SET_RUNNING => set_running, - CONFIGURE => configure, - ACK_CONFIG => ack_config, - ACK_BUFFERS => ack_buffers, - RELEASE_BUFFER => release_buffer, + version = Version(1); } impl Object for JayScreencast { @@ -479,8 +460,6 @@ dedicated_add_obj!(JayScreencast, JayScreencastId, screencasts); #[derive(Debug, Error)] pub enum JayScreencastError { - #[error("Parsing failed")] - MsgParserError(Box), #[error(transparent)] ClientError(Box), #[error("Buffer index {0} is out-of-bounds")] @@ -496,7 +475,6 @@ pub enum JayScreencastError { #[error("Render context supports neither linear or invalid modifier")] Modifier, } -efrom!(JayScreencastError, MsgParserError); efrom!(JayScreencastError, ClientError); fn output_size(output: &Option>) -> (i32, i32) { diff --git a/src/ifs/jay_screenshot.rs b/src/ifs/jay_screenshot.rs index aff61452..5695067f 100644 --- a/src/ifs/jay_screenshot.rs +++ b/src/ifs/jay_screenshot.rs @@ -2,10 +2,10 @@ use { crate::{ client::Client, leaks::Tracker, - object::Object, + object::{Object, Version}, wire::{jay_screenshot::*, JayScreenshotId}, }, - std::rc::Rc, + std::{convert::Infallible, rc::Rc}, uapi::OwnedFd, }; @@ -47,8 +47,13 @@ impl JayScreenshot { } } +impl JayScreenshotRequestHandler for JayScreenshot { + type Error = Infallible; +} + object_base! { self = JayScreenshot; + version = Version(1); } impl Object for JayScreenshot {} diff --git a/src/ifs/jay_seat_events.rs b/src/ifs/jay_seat_events.rs index e77c948e..36a1ae62 100644 --- a/src/ifs/jay_seat_events.rs +++ b/src/ifs/jay_seat_events.rs @@ -5,11 +5,11 @@ use { fixed::Fixed, ifs::wl_seat::{wl_pointer::PendingScroll, SeatId}, leaks::Tracker, - object::Object, + object::{Object, Version}, wire::{jay_seat_events::*, JaySeatEventsId}, xkbcommon::ModifierState, }, - std::rc::Rc, + std::{convert::Infallible, rc::Rc}, }; pub struct JaySeatEvents { @@ -124,8 +124,13 @@ impl JaySeatEvents { } } +impl JaySeatEventsRequestHandler for JaySeatEvents { + type Error = Infallible; +} + object_base! { self = JaySeatEvents; + version = Version(1); } impl Object for JaySeatEvents { diff --git a/src/ifs/jay_workspace.rs b/src/ifs/jay_workspace.rs index 55009f28..1c430f1f 100644 --- a/src/ifs/jay_workspace.rs +++ b/src/ifs/jay_workspace.rs @@ -2,12 +2,9 @@ use { crate::{ client::{Client, ClientError}, leaks::Tracker, - object::Object, + object::{Object, Version}, tree::{OutputNode, WorkspaceNode}, - utils::{ - buffd::{MsgParser, MsgParserError}, - clonecell::CloneCell, - }, + utils::clonecell::CloneCell, wire::{jay_workspace::*, JayWorkspaceId}, }, std::rc::Rc, @@ -58,13 +55,6 @@ impl JayWorkspace { }); } - fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), JayWorkspaceError> { - let _req: Destroy = self.client.parse(self, parser)?; - self.remove_from_node(); - self.client.remove_obj(self)?; - Ok(()) - } - fn remove_from_node(&self) { if let Some(ws) = self.workspace.take() { ws.jay_workspaces.remove(&(self.client.id, self.id)); @@ -72,10 +62,19 @@ impl JayWorkspace { } } +impl JayWorkspaceRequestHandler for JayWorkspace { + type Error = JayWorkspaceError; + + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { + self.remove_from_node(); + self.client.remove_obj(self)?; + Ok(()) + } +} + object_base! { self = JayWorkspace; - - DESTROY => destroy, + version = Version(1); } impl Object for JayWorkspace { @@ -88,10 +87,7 @@ dedicated_add_obj!(JayWorkspace, JayWorkspaceId, jay_workspaces); #[derive(Debug, Error)] pub enum JayWorkspaceError { - #[error("Parsing failed")] - MsgParserError(Box), #[error(transparent)] ClientError(Box), } -efrom!(JayWorkspaceError, MsgParserError); efrom!(JayWorkspaceError, ClientError); diff --git a/src/ifs/jay_workspace_watcher.rs b/src/ifs/jay_workspace_watcher.rs index 430f8ab3..0e6ab76d 100644 --- a/src/ifs/jay_workspace_watcher.rs +++ b/src/ifs/jay_workspace_watcher.rs @@ -3,12 +3,9 @@ use { client::{Client, ClientError}, ifs::jay_workspace::JayWorkspace, leaks::Tracker, - object::Object, + object::{Object, Version}, tree::WorkspaceNode, - utils::{ - buffd::{MsgParser, MsgParserError}, - clonecell::CloneCell, - }, + utils::clonecell::CloneCell, wire::{jay_workspace_watcher::*, JayWorkspaceWatcherId}, }, std::rc::Rc, @@ -47,13 +44,6 @@ impl JayWorkspaceWatcher { Ok(()) } - fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), JayWorkspaceWatcherError> { - let _req: Destroy = self.client.parse(self, parser)?; - self.remove_from_state(); - self.client.remove_obj(self)?; - Ok(()) - } - fn remove_from_state(&self) { self.client .state @@ -62,10 +52,19 @@ impl JayWorkspaceWatcher { } } +impl JayWorkspaceWatcherRequestHandler for JayWorkspaceWatcher { + type Error = JayWorkspaceWatcherError; + + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { + self.remove_from_state(); + self.client.remove_obj(self)?; + Ok(()) + } +} + object_base! { self = JayWorkspaceWatcher; - - DESTROY => destroy, + version = Version(1); } impl Object for JayWorkspaceWatcher { @@ -78,10 +77,7 @@ simple_add_obj!(JayWorkspaceWatcher); #[derive(Debug, Error)] pub enum JayWorkspaceWatcherError { - #[error("Parsing failed")] - MsgParserError(Box), #[error(transparent)] ClientError(Box), } -efrom!(JayWorkspaceWatcherError, MsgParserError); efrom!(JayWorkspaceWatcherError, ClientError); diff --git a/src/ifs/org_kde_kwin_server_decoration.rs b/src/ifs/org_kde_kwin_server_decoration.rs index e02bb893..1b5ce1c5 100644 --- a/src/ifs/org_kde_kwin_server_decoration.rs +++ b/src/ifs/org_kde_kwin_server_decoration.rs @@ -2,8 +2,7 @@ use { crate::{ client::{Client, ClientError}, leaks::Tracker, - object::Object, - utils::buffd::{MsgParser, MsgParserError}, + object::{Object, Version}, wire::{org_kde_kwin_server_decoration::*, OrgKdeKwinServerDecorationId}, }, std::{cell::Cell, rc::Rc}, @@ -21,36 +20,37 @@ pub struct OrgKdeKwinServerDecoration { client: Rc, requested: Cell, pub tracker: Tracker, + pub version: Version, } impl OrgKdeKwinServerDecoration { - pub fn new(id: OrgKdeKwinServerDecorationId, client: &Rc) -> Self { + pub fn new(id: OrgKdeKwinServerDecorationId, client: &Rc, version: Version) -> Self { Self { id, client: client.clone(), requested: Cell::new(false), tracker: Default::default(), + version, } } - pub fn send_mode(self: &Rc, mode: u32) { + pub fn send_mode(&self, mode: u32) { self.client.event(Mode { self_id: self.id, mode, }) } +} + +impl OrgKdeKwinServerDecorationRequestHandler for OrgKdeKwinServerDecoration { + type Error = OrgKdeKwinServerDecorationError; - fn release(&self, parser: MsgParser<'_, '_>) -> Result<(), OrgKdeKwinServerDecorationError> { - let _req: Release = self.client.parse(self, parser)?; + fn release(&self, _req: Release, _slf: &Rc) -> Result<(), Self::Error> { self.client.remove_obj(self)?; Ok(()) } - fn request_mode( - self: &Rc, - parser: MsgParser<'_, '_>, - ) -> Result<(), OrgKdeKwinServerDecorationError> { - let req: RequestMode = self.client.parse(&**self, parser)?; + fn request_mode(&self, req: RequestMode, _slf: &Rc) -> Result<(), Self::Error> { if req.mode > SERVER { return Err(OrgKdeKwinServerDecorationError::InvalidMode(req.mode)); } @@ -66,9 +66,7 @@ impl OrgKdeKwinServerDecoration { object_base! { self = OrgKdeKwinServerDecoration; - - RELEASE => release, - REQUEST_MODE => request_mode, + version = self.version; } impl Object for OrgKdeKwinServerDecoration {} @@ -81,8 +79,5 @@ pub enum OrgKdeKwinServerDecorationError { ClientError(Box), #[error("Mode {0} does not exist")] InvalidMode(u32), - #[error("Parsing failed")] - MsgParserError(#[source] Box), } efrom!(OrgKdeKwinServerDecorationError, ClientError); -efrom!(OrgKdeKwinServerDecorationError, MsgParserError); diff --git a/src/ifs/org_kde_kwin_server_decoration_manager.rs b/src/ifs/org_kde_kwin_server_decoration_manager.rs index 55eeb026..f4eb9a0b 100644 --- a/src/ifs/org_kde_kwin_server_decoration_manager.rs +++ b/src/ifs/org_kde_kwin_server_decoration_manager.rs @@ -7,7 +7,6 @@ use { }, leaks::Tracker, object::{Object, Version}, - utils::buffd::{MsgParser, MsgParserError}, wire::{org_kde_kwin_server_decoration_manager::*, OrgKdeKwinServerDecorationManagerId}, }, std::rc::Rc, @@ -37,7 +36,7 @@ impl OrgKdeKwinServerDecorationManagerGlobal { let obj = Rc::new(OrgKdeKwinServerDecorationManager { id, client: client.clone(), - _version: version, + version, tracker: Default::default(), }); track!(client, obj); @@ -68,7 +67,7 @@ simple_add_global!(OrgKdeKwinServerDecorationManagerGlobal); pub struct OrgKdeKwinServerDecorationManager { id: OrgKdeKwinServerDecorationManagerId, client: Rc, - _version: Version, + version: Version, pub tracker: Tracker, } @@ -79,11 +78,18 @@ impl OrgKdeKwinServerDecorationManager { mode, }) } +} + +impl OrgKdeKwinServerDecorationManagerRequestHandler for OrgKdeKwinServerDecorationManager { + type Error = OrgKdeKwinServerDecorationError; - fn create(&self, parser: MsgParser<'_, '_>) -> Result<(), OrgKdeKwinServerDecorationError> { - let req: Create = self.client.parse(self, parser)?; + fn create(&self, req: Create, _slf: &Rc) -> Result<(), Self::Error> { let _ = self.client.lookup(req.surface)?; - let obj = Rc::new(OrgKdeKwinServerDecoration::new(req.id, &self.client)); + let obj = Rc::new(OrgKdeKwinServerDecoration::new( + req.id, + &self.client, + self.version, + )); track!(self.client, obj); self.client.add_client_obj(&obj)?; obj.send_mode(SERVER); @@ -93,8 +99,7 @@ impl OrgKdeKwinServerDecorationManager { object_base! { self = OrgKdeKwinServerDecorationManager; - - CREATE => create, + version = self.version; } impl Object for OrgKdeKwinServerDecorationManager {} @@ -105,8 +110,5 @@ simple_add_obj!(OrgKdeKwinServerDecorationManager); pub enum OrgKdeKwinServerDecorationManagerError { #[error(transparent)] ClientError(Box), - #[error("Parsing failed")] - MsgParserError(#[source] Box), } efrom!(OrgKdeKwinServerDecorationManagerError, ClientError); -efrom!(OrgKdeKwinServerDecorationManagerError, MsgParserError); diff --git a/src/ifs/wl_buffer.rs b/src/ifs/wl_buffer.rs index e28f72f1..51feccc6 100644 --- a/src/ifs/wl_buffer.rs +++ b/src/ifs/wl_buffer.rs @@ -5,14 +5,10 @@ use { format::{Format, ARGB8888}, gfx_api::{GfxError, GfxFramebuffer, GfxImage, GfxTexture}, leaks::Tracker, - object::Object, + object::{Object, Version}, rect::Rect, theme::Color, - utils::{ - buffd::{MsgParser, MsgParserError}, - clonecell::CloneCell, - errorfmt::ErrorFmt, - }, + utils::{clonecell::CloneCell, errorfmt::ErrorFmt}, video::dmabuf::DmaBuf, wire::{wl_buffer::*, WlBufferId}, }, @@ -237,22 +233,24 @@ impl WlBuffer { Ok(()) } - fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), WlBufferError> { - let _req: Destroy = self.client.parse(self, parser)?; + pub fn send_release(&self) { + self.client.event(Release { self_id: self.id }) + } +} + +impl WlBufferRequestHandler for WlBuffer { + type Error = WlBufferError; + + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { self.client.remove_obj(self)?; self.destroyed.set(true); Ok(()) } - - pub fn send_release(&self) { - self.client.event(Release { self_id: self.id }) - } } object_base! { self = WlBuffer; - - DESTROY => destroy, + version = Version(1); } impl Object for WlBuffer {} @@ -269,13 +267,10 @@ pub enum WlBufferError { ClientMemError(#[source] Box), #[error("The graphics library could not import the client image")] GfxError(#[from] GfxError), - #[error("Parsing failed")] - MsgParserError(#[source] Box), #[error(transparent)] ClientError(Box), #[error("Buffer format {0} is not supported for shm buffers")] UnsupportedShmFormat(&'static str), } efrom!(WlBufferError, ClientMemError); -efrom!(WlBufferError, MsgParserError); efrom!(WlBufferError, ClientError); diff --git a/src/ifs/wl_callback.rs b/src/ifs/wl_callback.rs index 470feef0..c4f16ed1 100644 --- a/src/ifs/wl_callback.rs +++ b/src/ifs/wl_callback.rs @@ -2,10 +2,10 @@ use { crate::{ client::Client, leaks::Tracker, - object::Object, + object::{Object, Version}, wire::{wl_callback::*, WlCallbackId}, }, - std::rc::Rc, + std::{convert::Infallible, rc::Rc}, thiserror::Error, }; @@ -32,8 +32,13 @@ impl WlCallback { } } +impl WlCallbackRequestHandler for WlCallback { + type Error = Infallible; +} + object_base! { self = WlCallback; + version = Version(1); } impl Object for WlCallback {} diff --git a/src/ifs/wl_compositor.rs b/src/ifs/wl_compositor.rs index e545fc7b..c7575663 100644 --- a/src/ifs/wl_compositor.rs +++ b/src/ifs/wl_compositor.rs @@ -5,7 +5,6 @@ use { ifs::{wl_region::WlRegion, wl_surface::WlSurface}, leaks::Tracker, object::{Object, Version}, - utils::buffd::{MsgParser, MsgParserError}, wire::{wl_compositor::*, WlCompositorId}, xwayland::XWaylandEvent, }, @@ -47,10 +46,11 @@ impl WlCompositorGlobal { } } -impl WlCompositor { - fn create_surface(&self, parser: MsgParser<'_, '_>) -> Result<(), WlCompositorError> { - let surface: CreateSurface = self.client.parse(self, parser)?; - let surface = Rc::new(WlSurface::new(surface.id, &self.client, self.version)); +impl WlCompositorRequestHandler for WlCompositor { + type Error = WlCompositorError; + + fn create_surface(&self, req: CreateSurface, _slf: &Rc) -> Result<(), Self::Error> { + let surface = Rc::new(WlSurface::new(req.id, &self.client, self.version)); track!(self.client, surface); self.client.add_client_obj(&surface)?; if self.client.is_xwayland { @@ -63,9 +63,8 @@ impl WlCompositor { Ok(()) } - fn create_region(&self, parser: MsgParser<'_, '_>) -> Result<(), WlCompositorError> { - let region: CreateRegion = self.client.parse(self, parser)?; - let region = Rc::new(WlRegion::new(region.id, &self.client)); + fn create_region(&self, req: CreateRegion, _slf: &Rc) -> Result<(), Self::Error> { + let region = Rc::new(WlRegion::new(req.id, &self.client, self.version)); track!(self.client, region); self.client.add_client_obj(®ion)?; Ok(()) @@ -88,9 +87,7 @@ simple_add_global!(WlCompositorGlobal); object_base! { self = WlCompositor; - - CREATE_SURFACE => create_surface, - CREATE_REGION => create_region, + version = self.version; } impl Object for WlCompositor {} @@ -101,9 +98,6 @@ simple_add_obj!(WlCompositor); pub enum WlCompositorError { #[error(transparent)] ClientError(Box), - #[error("Parsing failed")] - MsgParserError(#[source] Box), } efrom!(WlCompositorError, ClientError); -efrom!(WlCompositorError, MsgParserError); diff --git a/src/ifs/wl_display.rs b/src/ifs/wl_display.rs index b228c3bc..47153044 100644 --- a/src/ifs/wl_display.rs +++ b/src/ifs/wl_display.rs @@ -3,8 +3,7 @@ use { client::{Client, ClientError}, ifs::{wl_callback::WlCallback, wl_registry::WlRegistry}, leaks::Tracker, - object::{Object, ObjectId, WL_DISPLAY_ID}, - utils::buffd::{MsgParser, MsgParserError}, + object::{Object, ObjectId, Version, WL_DISPLAY_ID}, wire::{wl_display::*, WlDisplayId}, }, std::rc::Rc, @@ -31,10 +30,13 @@ impl WlDisplay { tracker: Default::default(), } } +} + +impl WlDisplayRequestHandler for WlDisplay { + type Error = WlDisplayError; - fn sync(&self, parser: MsgParser<'_, '_>) -> Result<(), WlDisplayError> { - let sync: Sync = self.client.parse(self, parser)?; - let cb = Rc::new(WlCallback::new(sync.callback, &self.client)); + fn sync(&self, req: Sync, _slf: &Rc) -> Result<(), Self::Error> { + let cb = Rc::new(WlCallback::new(req.callback, &self.client)); track!(self.client, cb); self.client.add_client_obj(&cb)?; cb.send_done(); @@ -42,15 +44,16 @@ impl WlDisplay { Ok(()) } - fn get_registry(&self, parser: MsgParser<'_, '_>) -> Result<(), WlDisplayError> { - let gr: GetRegistry = self.client.parse(self, parser)?; - let registry = Rc::new(WlRegistry::new(gr.registry, &self.client)); + fn get_registry(&self, req: GetRegistry, _slf: &Rc) -> Result<(), Self::Error> { + let registry = Rc::new(WlRegistry::new(req.registry, &self.client)); track!(self.client, registry); self.client.add_client_obj(®istry)?; self.client.state.globals.notify_all(®istry); Ok(()) } +} +impl WlDisplay { pub fn send_error>(&self, object_id: O, code: u32, message: &str) { self.client.event(Error { self_id: self.id, @@ -90,19 +93,14 @@ impl WlDisplay { object_base! { self = WlDisplay; - - SYNC => sync, - GET_REGISTRY => get_registry, + version = Version(1); } impl Object for WlDisplay {} #[derive(Debug, Error)] pub enum WlDisplayError { - #[error("Parsing failed")] - MsgParserError(#[source] Box), #[error(transparent)] ClientError(Box), } -efrom!(WlDisplayError, MsgParserError); efrom!(WlDisplayError, ClientError); diff --git a/src/ifs/wl_drm.rs b/src/ifs/wl_drm.rs index 9b364491..3f6c453f 100644 --- a/src/ifs/wl_drm.rs +++ b/src/ifs/wl_drm.rs @@ -6,7 +6,6 @@ use { ifs::wl_buffer::WlBuffer, leaks::Tracker, object::{Object, Version}, - utils::buffd::{MsgParser, MsgParserError}, video::{ dmabuf::{DmaBuf, DmaBufPlane, PlaneVec}, INVALID_MODIFIER, @@ -73,42 +72,50 @@ pub struct WlDrm { } impl WlDrm { - fn send_device(self: &Rc, device: &Rc) { + fn send_device(&self, device: &Rc) { self.client.event(Device { self_id: self.id, name: device.as_bytes().as_bstr(), }) } - fn send_authenticated(self: &Rc) { + fn send_authenticated(&self) { self.client.event(Authenticated { self_id: self.id }) } - fn send_capabilities(self: &Rc, value: u32) { + fn send_capabilities(&self, value: u32) { self.client.event(Capabilities { self_id: self.id, value, }) } +} + +impl WlDrmRequestHandler for WlDrm { + type Error = WlDrmError; - fn authenticate(self: &Rc, parser: MsgParser<'_, '_>) -> Result<(), WlDrmError> { - let _req: Authenticate = self.client.parse(&**self, parser)?; + fn authenticate(&self, _req: Authenticate, _slf: &Rc) -> Result<(), Self::Error> { self.send_authenticated(); Ok(()) } - fn create_buffer(self: &Rc, parser: MsgParser<'_, '_>) -> Result<(), WlDrmError> { - let _req: CreateBuffer = self.client.parse(&**self, parser)?; + fn create_buffer(&self, _req: CreateBuffer, _slf: &Rc) -> Result<(), Self::Error> { Err(WlDrmError::Unsupported) } - fn create_planar_buffer(self: &Rc, parser: MsgParser<'_, '_>) -> Result<(), WlDrmError> { - let _req: CreatePlanarBuffer = self.client.parse(&**self, parser)?; + fn create_planar_buffer( + &self, + _req: CreatePlanarBuffer, + _slf: &Rc, + ) -> Result<(), Self::Error> { Err(WlDrmError::Unsupported) } - fn create_prime_buffer(self: &Rc, parser: MsgParser<'_, '_>) -> Result<(), WlDrmError> { - let req: CreatePrimeBuffer = self.client.parse(&**self, parser)?; + fn create_prime_buffer( + &self, + req: CreatePrimeBuffer, + _slf: &Rc, + ) -> Result<(), Self::Error> { let ctx = match self.client.state.render_ctx.get() { Some(ctx) => ctx, None => return Err(WlDrmError::NoRenderContext), @@ -163,11 +170,7 @@ impl WlDrm { object_base! { self = WlDrm; - - AUTHENTICATE => authenticate, - CREATE_BUFFER => create_buffer, - CREATE_PLANAR_BUFFER => create_planar_buffer, - CREATE_PRIME_BUFFER => create_prime_buffer if self.version >= 2, + version = self.version; } impl Object for WlDrm {} @@ -176,8 +179,6 @@ simple_add_obj!(WlDrm); #[derive(Debug, Error)] pub enum WlDrmError { - #[error("Parsing failed")] - MsgParserError(#[source] Box), #[error(transparent)] ClientError(Box), #[error("This api is not supported")] @@ -190,4 +191,3 @@ pub enum WlDrmError { ImportError(#[from] GfxError), } efrom!(WlDrmError, ClientError); -efrom!(WlDrmError, MsgParserError); diff --git a/src/ifs/wl_output.rs b/src/ifs/wl_output.rs index 8de498f1..39255533 100644 --- a/src/ifs/wl_output.rs +++ b/src/ifs/wl_output.rs @@ -15,12 +15,8 @@ use { time::Time, tree::{calculate_logical_size, OutputNode}, utils::{ - buffd::{MsgParser, MsgParserError}, - clonecell::CloneCell, - copyhashmap::CopyHashMap, - errorfmt::ErrorFmt, - linkedlist::LinkedList, - transform_ext::TransformExt, + clonecell::CloneCell, copyhashmap::CopyHashMap, errorfmt::ErrorFmt, + linkedlist::LinkedList, transform_ext::TransformExt, }, wire::{wl_output::*, WlOutputId, ZxdgOutputV1Id}, }, @@ -393,9 +389,12 @@ impl WlOutput { } } } +} + +impl WlOutputRequestHandler for WlOutput { + type Error = WlOutputError; - fn release(&self, parser: MsgParser<'_, '_>) -> Result<(), WlOutputError> { - let _req: Release = self.client.parse(self, parser)?; + fn release(&self, _req: Release, _slf: &Rc) -> Result<(), Self::Error> { self.xdg_outputs.clear(); self.remove_binding(); self.client.remove_obj(self)?; @@ -405,8 +404,7 @@ impl WlOutput { object_base! { self = WlOutput; - - RELEASE => release if self.version >= 3, + version = self.version; } impl Object for WlOutput { @@ -422,8 +420,5 @@ dedicated_add_obj!(WlOutput, WlOutputId, outputs); pub enum WlOutputError { #[error(transparent)] ClientError(Box), - #[error("Parsing failed")] - MsgParserError(#[source] Box), } efrom!(WlOutputError, ClientError); -efrom!(WlOutputError, MsgParserError); diff --git a/src/ifs/wl_region.rs b/src/ifs/wl_region.rs index 06a8c3ad..47e054c9 100644 --- a/src/ifs/wl_region.rs +++ b/src/ifs/wl_region.rs @@ -2,9 +2,8 @@ use { crate::{ client::{Client, ClientError}, leaks::Tracker, - object::Object, + object::{Object, Version}, rect::{Rect, Region, RegionBuilder}, - utils::buffd::{MsgParser, MsgParserError}, wire::{wl_region::*, WlRegionId}, }, std::{cell::RefCell, rc::Rc}, @@ -16,40 +15,43 @@ pub struct WlRegion { client: Rc, region: RefCell, pub tracker: Tracker, + version: Version, } impl WlRegion { - pub fn new(id: WlRegionId, client: &Rc) -> Self { + pub fn new(id: WlRegionId, client: &Rc, version: Version) -> Self { Self { id, client: client.clone(), region: Default::default(), tracker: Default::default(), + version, } } pub fn region(&self) -> Rc { self.region.borrow_mut().get() } +} + +impl WlRegionRequestHandler for WlRegion { + type Error = WlRegionError; - fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), WlRegionError> { - let _destroy: Destroy = self.client.parse(self, parser)?; + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { self.client.remove_obj(self)?; Ok(()) } - fn add(&self, parser: MsgParser<'_, '_>) -> Result<(), WlRegionError> { - let add: Add = self.client.parse(self, parser)?; - if add.width < 0 || add.height < 0 { + fn add(&self, req: Add, _slf: &Rc) -> Result<(), Self::Error> { + if req.width < 0 || req.height < 0 { return Err(WlRegionError::NegativeExtents); } let mut region = self.region.borrow_mut(); - region.add(Rect::new_sized(add.x, add.y, add.width, add.height).unwrap()); + region.add(Rect::new_sized(req.x, req.y, req.width, req.height).unwrap()); Ok(()) } - fn subtract(&self, parser: MsgParser<'_, '_>) -> Result<(), WlRegionError> { - let req: Subtract = self.client.parse(self, parser)?; + fn subtract(&self, req: Subtract, _slf: &Rc) -> Result<(), Self::Error> { if req.width < 0 || req.height < 0 { return Err(WlRegionError::NegativeExtents); } @@ -61,10 +63,7 @@ impl WlRegion { object_base! { self = WlRegion; - - DESTROY => destroy, - ADD => add, - SUBTRACT => subtract, + version = self.version; } impl Object for WlRegion {} @@ -73,12 +72,9 @@ dedicated_add_obj!(WlRegion, WlRegionId, regions); #[derive(Debug, Error)] pub enum WlRegionError { - #[error("Parsing failed")] - MsgParserError(#[source] Box), #[error(transparent)] ClientError(Box), #[error("width and/or height are negative")] NegativeExtents, } -efrom!(WlRegionError, MsgParserError); efrom!(WlRegionError, ClientError); diff --git a/src/ifs/wl_registry.rs b/src/ifs/wl_registry.rs index de420cd3..7c91713c 100644 --- a/src/ifs/wl_registry.rs +++ b/src/ifs/wl_registry.rs @@ -4,7 +4,6 @@ use { globals::{Global, GlobalName, GlobalsError}, leaks::Tracker, object::{Interface, Object, Version}, - utils::buffd::{MsgParser, MsgParserError}, wire::{wl_registry::*, WlRegistryId}, }, std::rc::Rc, @@ -41,9 +40,12 @@ impl WlRegistry { name: name.raw(), }) } +} + +impl WlRegistryRequestHandler for WlRegistry { + type Error = WlRegistryError; - fn bind(&self, parser: MsgParser<'_, '_>) -> Result<(), WlRegistryError> { - let bind: Bind = self.client.parse(self, parser)?; + fn bind(&self, bind: Bind, _slf: &Rc) -> Result<(), Self::Error> { let name = GlobalName::from_raw(bind.name); let globals = &self.client.state.globals; let global = globals.get(name, self.client.secure, self.client.is_xwayland)?; @@ -69,8 +71,7 @@ impl WlRegistry { object_base! { self = WlRegistry; - - BIND => bind, + version = Version(1); } impl Object for WlRegistry {} @@ -79,8 +80,6 @@ dedicated_add_obj!(WlRegistry, WlRegistryId, registries); #[derive(Debug, Error)] pub enum WlRegistryError { - #[error("Parsing failed")] - MsgParserError(#[source] Box), #[error(transparent)] GlobalsError(Box), #[error("Tried to bind to global {} of type {} using interface {}", .0.name, .0.interface.name(), .0.actual)] @@ -88,7 +87,6 @@ pub enum WlRegistryError { #[error("Tried to bind to global {} of type {} and version {} using version {}", .0.name, .0.interface.name(), .0.version, .0.actual)] InvalidVersion(VersionError), } -efrom!(WlRegistryError, MsgParserError); efrom!(WlRegistryError, GlobalsError); #[derive(Debug)] diff --git a/src/ifs/wl_seat.rs b/src/ifs/wl_seat.rs index 6a57be2f..0cfb87a7 100644 --- a/src/ifs/wl_seat.rs +++ b/src/ifs/wl_seat.rs @@ -54,16 +54,9 @@ use { Node, OutputNode, ToplevelNode, WorkspaceNode, }, utils::{ - asyncevent::AsyncEvent, - buffd::{MsgParser, MsgParserError}, - clonecell::CloneCell, - copyhashmap::CopyHashMap, - errorfmt::ErrorFmt, - linkedlist::LinkedNode, - numcell::NumCell, - rc_eq::rc_eq, - smallmap::SmallMap, - transform_ext::TransformExt, + asyncevent::AsyncEvent, clonecell::CloneCell, copyhashmap::CopyHashMap, + errorfmt::ErrorFmt, linkedlist::LinkedNode, numcell::NumCell, rc_eq::rc_eq, + smallmap::SmallMap, transform_ext::TransformExt, }, wire::{ wl_seat::*, ExtIdleNotificationV1Id, WlDataDeviceId, WlKeyboardId, WlPointerId, @@ -1149,18 +1142,41 @@ impl WlSeat { self.global.move_(node); } - fn get_pointer(self: &Rc, parser: MsgParser<'_, '_>) -> Result<(), WlSeatError> { - let req: GetPointer = self.client.parse(&**self, parser)?; - let p = Rc::new(WlPointer::new(req.id, self)); + pub fn keymap_fd(&self, keymap: &XkbKeymap) -> Result, WlKeyboardError> { + if self.version >= READ_ONLY_KEYMAP_SINCE { + return Ok(keymap.map.clone()); + } + let fd = match uapi::memfd_create("shared-keymap", c::MFD_CLOEXEC) { + Ok(fd) => fd, + Err(e) => return Err(WlKeyboardError::KeymapMemfd(e.into())), + }; + let target = keymap.map_len as c::off_t; + let mut pos = 0; + while pos < target { + let rem = target - pos; + let res = uapi::sendfile(fd.raw(), keymap.map.raw(), Some(&mut pos), rem as usize); + match res { + Ok(_) | Err(Errno(c::EINTR)) => {} + Err(e) => return Err(WlKeyboardError::KeymapCopy(e.into())), + } + } + Ok(Rc::new(fd)) + } +} + +impl WlSeatRequestHandler for WlSeat { + type Error = WlSeatError; + + fn get_pointer(&self, req: GetPointer, slf: &Rc) -> Result<(), Self::Error> { + let p = Rc::new(WlPointer::new(req.id, slf)); track!(self.client, p); self.client.add_client_obj(&p)?; self.pointers.set(req.id, p); Ok(()) } - fn get_keyboard(self: &Rc, parser: MsgParser<'_, '_>) -> Result<(), WlSeatError> { - let req: GetKeyboard = self.client.parse(&**self, parser)?; - let p = Rc::new(WlKeyboard::new(req.id, self)); + fn get_keyboard(&self, req: GetKeyboard, slf: &Rc) -> Result<(), Self::Error> { + let p = Rc::new(WlKeyboard::new(req.id, slf)); track!(self.client, p); self.client.add_client_obj(&p)?; self.keyboards.set(req.id, p.clone()); @@ -1177,37 +1193,14 @@ impl WlSeat { Ok(()) } - pub fn keymap_fd(&self, keymap: &XkbKeymap) -> Result, WlKeyboardError> { - if self.version >= READ_ONLY_KEYMAP_SINCE { - return Ok(keymap.map.clone()); - } - let fd = match uapi::memfd_create("shared-keymap", c::MFD_CLOEXEC) { - Ok(fd) => fd, - Err(e) => return Err(WlKeyboardError::KeymapMemfd(e.into())), - }; - let target = keymap.map_len as c::off_t; - let mut pos = 0; - while pos < target { - let rem = target - pos; - let res = uapi::sendfile(fd.raw(), keymap.map.raw(), Some(&mut pos), rem as usize); - match res { - Ok(_) | Err(Errno(c::EINTR)) => {} - Err(e) => return Err(WlKeyboardError::KeymapCopy(e.into())), - } - } - Ok(Rc::new(fd)) - } - - fn get_touch(self: &Rc, parser: MsgParser<'_, '_>) -> Result<(), WlSeatError> { - let req: GetTouch = self.client.parse(&**self, parser)?; - let p = Rc::new(WlTouch::new(req.id, self)); + fn get_touch(&self, req: GetTouch, slf: &Rc) -> Result<(), Self::Error> { + let p = Rc::new(WlTouch::new(req.id, slf)); track!(self.client, p); self.client.add_client_obj(&p)?; Ok(()) } - fn release(&self, parser: MsgParser<'_, '_>) -> Result<(), WlSeatError> { - let _req: Release = self.client.parse(self, parser)?; + fn release(&self, _req: Release, _slf: &Rc) -> Result<(), Self::Error> { { let mut bindings = self.global.bindings.borrow_mut(); if let Entry::Occupied(mut hm) = bindings.entry(self.client.id) { @@ -1224,11 +1217,7 @@ impl WlSeat { object_base! { self = WlSeat; - - GET_POINTER => get_pointer, - GET_KEYBOARD => get_keyboard, - GET_TOUCH => get_touch, - RELEASE => release if self.version >= 5, + version = self.version; } impl Object for WlSeat { @@ -1256,15 +1245,12 @@ pub enum WlSeatError { ClientError(Box), #[error(transparent)] IpcError(#[from] IpcError), - #[error("Parsing failed")] - MsgParserError(#[source] Box), #[error(transparent)] WlKeyboardError(Box), #[error("Data source has a toplevel attached")] OfferHasDrag, } efrom!(WlSeatError, ClientError); -efrom!(WlSeatError, MsgParserError); efrom!(WlSeatError, WlKeyboardError); pub fn collect_kb_foci2(node: Rc, seats: &mut SmallVec<[Rc; 3]>) { diff --git a/src/ifs/wl_seat/wl_keyboard.rs b/src/ifs/wl_seat/wl_keyboard.rs index 2ad5da7c..f5089eaf 100644 --- a/src/ifs/wl_seat/wl_keyboard.rs +++ b/src/ifs/wl_seat/wl_keyboard.rs @@ -4,10 +4,7 @@ use { ifs::wl_seat::WlSeat, leaks::Tracker, object::{Object, Version}, - utils::{ - buffd::{MsgParser, MsgParserError}, - oserror::OsError, - }, + utils::oserror::OsError, wire::{wl_keyboard::*, WlKeyboardId, WlSurfaceId}, }, std::rc::Rc, @@ -100,9 +97,12 @@ impl WlKeyboard { delay, }) } +} + +impl WlKeyboardRequestHandler for WlKeyboard { + type Error = WlKeyboardError; - fn release(&self, parser: MsgParser<'_, '_>) -> Result<(), WlKeyboardError> { - let _req: Release = self.seat.client.parse(self, parser)?; + fn release(&self, _req: Release, _slf: &Rc) -> Result<(), Self::Error> { self.seat.keyboards.remove(&self.id); self.seat.client.remove_obj(self)?; Ok(()) @@ -111,8 +111,7 @@ impl WlKeyboard { object_base! { self = WlKeyboard; - - RELEASE => release if self.seat.version >= 3, + version = self.seat.version; } impl Object for WlKeyboard {} @@ -127,8 +126,5 @@ pub enum WlKeyboardError { KeymapMemfd(#[source] OsError), #[error("Could not copy the keymap")] KeymapCopy(#[source] OsError), - #[error("Parsing failed")] - MsgParserError(#[source] Box), } efrom!(WlKeyboardError, ClientError); -efrom!(WlKeyboardError, MsgParserError); diff --git a/src/ifs/wl_seat/wl_pointer.rs b/src/ifs/wl_seat/wl_pointer.rs index ba070244..cfd16383 100644 --- a/src/ifs/wl_seat/wl_pointer.rs +++ b/src/ifs/wl_seat/wl_pointer.rs @@ -6,7 +6,6 @@ use { ifs::{wl_seat::WlSeat, wl_surface::WlSurfaceError}, leaks::Tracker, object::{Object, Version}, - utils::buffd::{MsgParser, MsgParserError}, wire::{wl_pointer::*, WlPointerId, WlSurfaceId}, }, std::{cell::Cell, rc::Rc}, @@ -174,9 +173,12 @@ impl WlPointer { value120, }) } +} + +impl WlPointerRequestHandler for WlPointer { + type Error = WlPointerError; - fn set_cursor(&self, parser: MsgParser<'_, '_>) -> Result<(), WlPointerError> { - let req: SetCursor = self.seat.client.parse(self, parser)?; + fn set_cursor(&self, req: SetCursor, _slf: &Rc) -> Result<(), Self::Error> { if !self.seat.client.valid_serial(req.serial) { log::warn!("Client tried to set_cursor with an invalid serial"); return Ok(()); @@ -213,8 +215,7 @@ impl WlPointer { Ok(()) } - fn release(&self, parser: MsgParser<'_, '_>) -> Result<(), WlPointerError> { - let _req: Release = self.seat.client.parse(self, parser)?; + fn release(&self, _req: Release, _slf: &Rc) -> Result<(), Self::Error> { self.seat.pointers.remove(&self.id); self.seat.client.remove_obj(self)?; Ok(()) @@ -223,9 +224,7 @@ impl WlPointer { object_base! { self = WlPointer; - - SET_CURSOR => set_cursor, - RELEASE => release if self.seat.version >= 3, + version = self.seat.version; } impl Object for WlPointer {} @@ -236,11 +235,8 @@ dedicated_add_obj!(WlPointer, WlPointerId, pointers); pub enum WlPointerError { #[error(transparent)] ClientError(Box), - #[error("Parsing failed")] - MsgParserError(#[source] Box), #[error(transparent)] WlSurfaceError(Box), } efrom!(WlPointerError, ClientError); -efrom!(WlPointerError, MsgParserError); efrom!(WlPointerError, WlSurfaceError); diff --git a/src/ifs/wl_seat/wl_touch.rs b/src/ifs/wl_seat/wl_touch.rs index 502c7257..6a7a5a8d 100644 --- a/src/ifs/wl_seat/wl_touch.rs +++ b/src/ifs/wl_seat/wl_touch.rs @@ -4,7 +4,6 @@ use { ifs::wl_seat::WlSeat, leaks::Tracker, object::Object, - utils::buffd::{MsgParser, MsgParserError}, wire::{wl_touch::*, WlTouchId}, }, std::rc::Rc, @@ -40,9 +39,12 @@ impl WlTouch { tracker: Default::default(), } } +} + +impl WlTouchRequestHandler for WlTouch { + type Error = WlTouchError; - fn release(&self, parser: MsgParser<'_, '_>) -> Result<(), WlTouchError> { - let _req: Release = self.seat.client.parse(self, parser)?; + fn release(&self, _req: Release, _slf: &Rc) -> Result<(), Self::Error> { self.seat.client.remove_obj(self)?; Ok(()) } @@ -50,8 +52,7 @@ impl WlTouch { object_base! { self = WlTouch; - - RELEASE => release if self.seat.version >= 3, + version = self.seat.version; } impl Object for WlTouch {} @@ -62,8 +63,5 @@ simple_add_obj!(WlTouch); pub enum WlTouchError { #[error(transparent)] ClientError(Box), - #[error("Parsing failed")] - MsgParserError(#[source] Box), } efrom!(WlTouchError, ClientError); -efrom!(WlTouchError, MsgParserError); diff --git a/src/ifs/wl_seat/zwp_pointer_constraints_v1.rs b/src/ifs/wl_seat/zwp_pointer_constraints_v1.rs index e0fd8401..2230408d 100644 --- a/src/ifs/wl_seat/zwp_pointer_constraints_v1.rs +++ b/src/ifs/wl_seat/zwp_pointer_constraints_v1.rs @@ -13,10 +13,7 @@ use { leaks::Tracker, object::{Object, Version}, rect::Region, - utils::{ - buffd::{MsgParser, MsgParserError}, - clonecell::CloneCell, - }, + utils::clonecell::CloneCell, wire::{ zwp_pointer_constraints_v1::*, WlPointerId, WlRegionId, WlSurfaceId, ZwpPointerConstraintsV1Id, @@ -38,6 +35,7 @@ pub struct ZwpPointerConstraintsV1 { pub id: ZwpPointerConstraintsV1Id, pub client: Rc, pub tracker: Tracker, + pub version: Version, } #[derive(Copy, Clone, Eq, PartialEq)] @@ -154,12 +152,13 @@ impl ZwpPointerConstraintsV1Global { self: Rc, id: ZwpPointerConstraintsV1Id, client: &Rc, - _version: Version, + version: Version, ) -> Result<(), ZwpPointerConstraintsV1Error> { let cs = Rc::new(ZwpPointerConstraintsV1 { id, client: client.clone(), tracker: Default::default(), + version, }); track!(client, cs); client.add_client_obj(&cs)?; @@ -168,12 +167,6 @@ impl ZwpPointerConstraintsV1Global { } impl ZwpPointerConstraintsV1 { - fn destroy(&self, msg: MsgParser<'_, '_>) -> Result<(), ZwpPointerConstraintsV1Error> { - let _req: Destroy = self.client.parse(self, msg)?; - self.client.remove_obj(self)?; - Ok(()) - } - fn create_constraint( &self, ty: ConstraintType, @@ -209,9 +202,17 @@ impl ZwpPointerConstraintsV1 { ty, })) } +} + +impl ZwpPointerConstraintsV1RequestHandler for ZwpPointerConstraintsV1 { + type Error = ZwpPointerConstraintsV1Error; + + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { + self.client.remove_obj(self)?; + Ok(()) + } - fn lock_pointer(&self, msg: MsgParser<'_, '_>) -> Result<(), ZwpPointerConstraintsV1Error> { - let req: LockPointer = self.client.parse(self, msg)?; + fn lock_pointer(&self, req: LockPointer, _slf: &Rc) -> Result<(), Self::Error> { let constraint = self.create_constraint( ConstraintType::Lock, req.pointer, @@ -223,6 +224,7 @@ impl ZwpPointerConstraintsV1 { id: req.id, tracker: Default::default(), constraint, + version: self.version, }); self.client.add_client_obj(&lp)?; lp.constraint.owner.set(Some(lp.clone())); @@ -234,8 +236,7 @@ impl ZwpPointerConstraintsV1 { Ok(()) } - fn confine_pointer(&self, msg: MsgParser<'_, '_>) -> Result<(), ZwpPointerConstraintsV1Error> { - let req: ConfinePointer = self.client.parse(self, msg)?; + fn confine_pointer(&self, req: ConfinePointer, _slf: &Rc) -> Result<(), Self::Error> { let constraint = self.create_constraint( ConstraintType::Confine, req.pointer, @@ -247,6 +248,7 @@ impl ZwpPointerConstraintsV1 { id: req.id, tracker: Default::default(), constraint, + version: self.version, }); self.client.add_client_obj(&lp)?; lp.constraint.owner.set(Some(lp.clone())); @@ -279,10 +281,7 @@ simple_add_global!(ZwpPointerConstraintsV1Global); object_base! { self = ZwpPointerConstraintsV1; - - DESTROY => destroy, - LOCK_POINTER => lock_pointer, - CONFINE_POINTER => confine_pointer, + version = self.version; } impl Object for ZwpPointerConstraintsV1 {} @@ -293,12 +292,9 @@ simple_add_obj!(ZwpPointerConstraintsV1); pub enum ZwpPointerConstraintsV1Error { #[error(transparent)] ClientError(Box), - #[error("Parsing failed")] - MsgParserError(#[source] Box), #[error("The surface already has a constraint attached for the seat")] AlreadyConstrained, #[error("The constraint lifetime {0} is unknown")] UnknownLifetime(u32), } efrom!(ZwpPointerConstraintsV1Error, ClientError); -efrom!(ZwpPointerConstraintsV1Error, MsgParserError); diff --git a/src/ifs/wl_seat/zwp_pointer_constraints_v1/zwp_confined_pointer_v1.rs b/src/ifs/wl_seat/zwp_pointer_constraints_v1/zwp_confined_pointer_v1.rs index e01a0001..418a2669 100644 --- a/src/ifs/wl_seat/zwp_pointer_constraints_v1/zwp_confined_pointer_v1.rs +++ b/src/ifs/wl_seat/zwp_pointer_constraints_v1/zwp_confined_pointer_v1.rs @@ -5,8 +5,7 @@ use { ConstraintOwner, SeatConstraint, ZwpPointerConstraintsV1Error, }, leaks::Tracker, - object::Object, - utils::buffd::{MsgParser, MsgParserError}, + object::{Object, Version}, wire::{zwp_confined_pointer_v1::*, ZwpConfinedPointerV1Id}, }, std::rc::Rc, @@ -17,18 +16,19 @@ pub struct ZwpConfinedPointerV1 { pub id: ZwpConfinedPointerV1Id, pub tracker: Tracker, pub constraint: Rc, + pub version: Version, } -impl ZwpConfinedPointerV1 { - fn destroy(&self, msg: MsgParser<'_, '_>) -> Result<(), ZwpConfinedPointerV1Error> { - let _req: Destroy = self.constraint.client.parse(self, msg)?; +impl ZwpConfinedPointerV1RequestHandler for ZwpConfinedPointerV1 { + type Error = ZwpConfinedPointerV1Error; + + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { self.constraint.detach(); self.constraint.client.remove_obj(self)?; Ok(()) } - fn set_region(&self, msg: MsgParser<'_, '_>) -> Result<(), ZwpConfinedPointerV1Error> { - let req: SetRegion = self.constraint.client.parse(self, msg)?; + fn set_region(&self, req: SetRegion, _slf: &Rc) -> Result<(), Self::Error> { self.constraint.set_region(req.region)?; Ok(()) } @@ -48,9 +48,7 @@ impl ConstraintOwner for ZwpConfinedPointerV1 { object_base! { self = ZwpConfinedPointerV1; - - DESTROY => destroy, - SET_REGION => set_region, + version = self.version; } impl Object for ZwpConfinedPointerV1 { @@ -65,10 +63,7 @@ simple_add_obj!(ZwpConfinedPointerV1); pub enum ZwpConfinedPointerV1Error { #[error(transparent)] ClientError(Box), - #[error("Parsing failed")] - MsgParserError(#[source] Box), #[error(transparent)] ZwpPointerConstraintsV1Error(#[from] ZwpPointerConstraintsV1Error), } efrom!(ZwpConfinedPointerV1Error, ClientError); -efrom!(ZwpConfinedPointerV1Error, MsgParserError); diff --git a/src/ifs/wl_seat/zwp_pointer_constraints_v1/zwp_locked_pointer_v1.rs b/src/ifs/wl_seat/zwp_pointer_constraints_v1/zwp_locked_pointer_v1.rs index 3c5207b4..581df25c 100644 --- a/src/ifs/wl_seat/zwp_pointer_constraints_v1/zwp_locked_pointer_v1.rs +++ b/src/ifs/wl_seat/zwp_pointer_constraints_v1/zwp_locked_pointer_v1.rs @@ -5,8 +5,7 @@ use { ConstraintOwner, SeatConstraint, ZwpPointerConstraintsV1Error, }, leaks::Tracker, - object::Object, - utils::buffd::{MsgParser, MsgParserError}, + object::{Object, Version}, wire::{zwp_locked_pointer_v1::*, ZwpLockedPointerV1Id}, }, std::rc::Rc, @@ -17,11 +16,13 @@ pub struct ZwpLockedPointerV1 { pub id: ZwpLockedPointerV1Id, pub tracker: Tracker, pub constraint: Rc, + pub version: Version, } -impl ZwpLockedPointerV1 { - fn destroy(&self, msg: MsgParser<'_, '_>) -> Result<(), ZwpLockedPointerV1Error> { - let _req: Destroy = self.constraint.client.parse(self, msg)?; +impl ZwpLockedPointerV1RequestHandler for ZwpLockedPointerV1 { + type Error = ZwpLockedPointerV1Error; + + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { self.constraint.detach(); self.constraint.client.remove_obj(self)?; Ok(()) @@ -29,14 +30,13 @@ impl ZwpLockedPointerV1 { fn set_cursor_position_hint( &self, - msg: MsgParser<'_, '_>, - ) -> Result<(), ZwpLockedPointerV1Error> { - let _req: SetCursorPositionHint = self.constraint.client.parse(self, msg)?; + _req: SetCursorPositionHint, + _slf: &Rc, + ) -> Result<(), Self::Error> { Ok(()) } - fn set_region(&self, msg: MsgParser<'_, '_>) -> Result<(), ZwpLockedPointerV1Error> { - let req: SetRegion = self.constraint.client.parse(self, msg)?; + fn set_region(&self, req: SetRegion, _slf: &Rc) -> Result<(), Self::Error> { self.constraint.set_region(req.region)?; Ok(()) } @@ -54,10 +54,7 @@ impl ConstraintOwner for ZwpLockedPointerV1 { object_base! { self = ZwpLockedPointerV1; - - DESTROY => destroy, - SET_CURSOR_POSITION_HINT => set_cursor_position_hint, - SET_REGION => set_region, + version = self.version; } impl Object for ZwpLockedPointerV1 { @@ -72,10 +69,7 @@ simple_add_obj!(ZwpLockedPointerV1); pub enum ZwpLockedPointerV1Error { #[error(transparent)] ClientError(Box), - #[error("Parsing failed")] - MsgParserError(#[source] Box), #[error(transparent)] ZwpPointerConstraintsV1Error(#[from] ZwpPointerConstraintsV1Error), } efrom!(ZwpLockedPointerV1Error, ClientError); -efrom!(ZwpLockedPointerV1Error, MsgParserError); diff --git a/src/ifs/wl_seat/zwp_relative_pointer_manager_v1.rs b/src/ifs/wl_seat/zwp_relative_pointer_manager_v1.rs index bb262bc0..f04e80eb 100644 --- a/src/ifs/wl_seat/zwp_relative_pointer_manager_v1.rs +++ b/src/ifs/wl_seat/zwp_relative_pointer_manager_v1.rs @@ -5,7 +5,6 @@ use { ifs::wl_seat::zwp_relative_pointer_v1::ZwpRelativePointerV1, leaks::Tracker, object::{Object, Version}, - utils::buffd::{MsgParser, MsgParserError}, wire::{zwp_relative_pointer_manager_v1::*, ZwpRelativePointerManagerV1Id}, }, std::rc::Rc, @@ -20,6 +19,7 @@ pub struct ZwpRelativePointerManagerV1 { pub id: ZwpRelativePointerManagerV1Id, pub client: Rc, pub tracker: Tracker, + pub version: Version, } impl ZwpRelativePointerManagerV1Global { @@ -31,12 +31,13 @@ impl ZwpRelativePointerManagerV1Global { self: Rc, id: ZwpRelativePointerManagerV1Id, client: &Rc, - _version: Version, + version: Version, ) -> Result<(), ZwpRelativePointerManagerV1Error> { let obj = Rc::new(ZwpRelativePointerManagerV1 { id, client: client.clone(), tracker: Default::default(), + version, }); track!(client, obj); client.add_client_obj(&obj)?; @@ -62,24 +63,26 @@ impl Global for ZwpRelativePointerManagerV1Global { simple_add_global!(ZwpRelativePointerManagerV1Global); -impl ZwpRelativePointerManagerV1 { - fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), ZwpRelativePointerManagerV1Error> { - let _req: Destroy = self.client.parse(self, parser)?; +impl ZwpRelativePointerManagerV1RequestHandler for ZwpRelativePointerManagerV1 { + type Error = ZwpRelativePointerManagerV1Error; + + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { self.client.remove_obj(self)?; Ok(()) } fn get_relative_pointer( &self, - parser: MsgParser<'_, '_>, - ) -> Result<(), ZwpRelativePointerManagerV1Error> { - let req: GetRelativePointer = self.client.parse(self, parser)?; + req: GetRelativePointer, + _slf: &Rc, + ) -> Result<(), Self::Error> { let pointer = self.client.lookup(req.pointer)?; let rp = Rc::new(ZwpRelativePointerV1 { id: req.id, client: self.client.clone(), seat: pointer.seat.clone(), tracker: Default::default(), + version: self.version, }); track!(self.client, rp); self.client.add_client_obj(&rp)?; @@ -90,9 +93,7 @@ impl ZwpRelativePointerManagerV1 { object_base! { self = ZwpRelativePointerManagerV1; - - DESTROY => destroy, - GET_RELATIVE_POINTER => get_relative_pointer, + version = self.version; } impl Object for ZwpRelativePointerManagerV1 {} @@ -101,10 +102,7 @@ simple_add_obj!(ZwpRelativePointerManagerV1); #[derive(Debug, Error)] pub enum ZwpRelativePointerManagerV1Error { - #[error("Parsing failed")] - MsgParserError(#[source] Box), #[error(transparent)] ClientError(Box), } -efrom!(ZwpRelativePointerManagerV1Error, MsgParserError); efrom!(ZwpRelativePointerManagerV1Error, ClientError); diff --git a/src/ifs/wl_seat/zwp_relative_pointer_v1.rs b/src/ifs/wl_seat/zwp_relative_pointer_v1.rs index 277e201a..a24cd8e9 100644 --- a/src/ifs/wl_seat/zwp_relative_pointer_v1.rs +++ b/src/ifs/wl_seat/zwp_relative_pointer_v1.rs @@ -4,8 +4,7 @@ use { fixed::Fixed, ifs::wl_seat::WlSeat, leaks::Tracker, - object::Object, - utils::buffd::{MsgParser, MsgParserError}, + object::{Object, Version}, wire::{zwp_relative_pointer_v1::*, ZwpRelativePointerV1Id}, }, std::rc::Rc, @@ -17,6 +16,7 @@ pub struct ZwpRelativePointerV1 { pub client: Rc, pub seat: Rc, pub tracker: Tracker, + pub version: Version, } impl ZwpRelativePointerV1 { @@ -38,9 +38,12 @@ impl ZwpRelativePointerV1 { dy_unaccelerated, }); } +} + +impl ZwpRelativePointerV1RequestHandler for ZwpRelativePointerV1 { + type Error = ZwpRelativePointerV1Error; - fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), ZwpRelativePointerV1Error> { - let _req: Destroy = self.client.parse(self, parser)?; + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { self.seat.relative_pointers.remove(&self.id); self.client.remove_obj(self)?; Ok(()) @@ -49,8 +52,7 @@ impl ZwpRelativePointerV1 { object_base! { self = ZwpRelativePointerV1; - - DESTROY => destroy, + version = self.version; } impl Object for ZwpRelativePointerV1 {} @@ -61,8 +63,5 @@ simple_add_obj!(ZwpRelativePointerV1); pub enum ZwpRelativePointerV1Error { #[error(transparent)] ClientError(Box), - #[error("Parsing failed")] - MsgParserError(Box), } efrom!(ZwpRelativePointerV1Error, ClientError); -efrom!(ZwpRelativePointerV1Error, MsgParserError); diff --git a/src/ifs/wl_shm.rs b/src/ifs/wl_shm.rs index cdcf5206..3748a6d0 100644 --- a/src/ifs/wl_shm.rs +++ b/src/ifs/wl_shm.rs @@ -6,7 +6,6 @@ use { ifs::wl_shm_pool::{WlShmPool, WlShmPoolError}, leaks::Tracker, object::{Object, Version}, - utils::buffd::{MsgParser, MsgParserError}, wire::{wl_shm::*, WlShmId}, }, std::rc::Rc, @@ -57,9 +56,10 @@ impl WlShmGlobal { } } -impl WlShm { - fn create_pool(&self, parser: MsgParser<'_, '_>) -> Result<(), WlShmError> { - let create: CreatePool = self.client.parse(self, parser)?; +impl WlShmRequestHandler for WlShm { + type Error = WlShmError; + + fn create_pool(&self, create: CreatePool, _slf: &Rc) -> Result<(), Self::Error> { if create.size < 0 { return Err(WlShmError::NegativeSize); } @@ -68,14 +68,14 @@ impl WlShm { &self.client, create.fd, create.size as usize, + self.version, )?); track!(self.client, pool); self.client.add_client_obj(&pool)?; Ok(()) } - fn release(&self, parser: MsgParser<'_, '_>) -> Result<(), WlShmError> { - let _req: Release = self.client.parse(self, parser)?; + fn release(&self, _req: Release, _slf: &Rc) -> Result<(), Self::Error> { self.client.remove_obj(self)?; Ok(()) } @@ -97,9 +97,7 @@ simple_add_global!(WlShmGlobal); object_base! { self = WlShm; - - CREATE_POOL => create_pool, - RELEASE => release if self.version >= 2, + version = self.version; } impl Object for WlShm {} @@ -110,13 +108,10 @@ simple_add_obj!(WlShm); pub enum WlShmError { #[error(transparent)] ClientError(Box), - #[error("Parsing failed")] - MsgParserError(#[source] Box), #[error("The passed size is negative")] NegativeSize, #[error(transparent)] WlShmPoolError(Box), } efrom!(WlShmError, ClientError); -efrom!(WlShmError, MsgParserError); efrom!(WlShmError, WlShmPoolError); diff --git a/src/ifs/wl_shm_pool.rs b/src/ifs/wl_shm_pool.rs index cef57fdf..30687f6c 100644 --- a/src/ifs/wl_shm_pool.rs +++ b/src/ifs/wl_shm_pool.rs @@ -5,11 +5,8 @@ use { format::{formats, map_wayland_format_id}, ifs::wl_buffer::{WlBuffer, WlBufferError}, leaks::Tracker, - object::Object, - utils::{ - buffd::{MsgParser, MsgParserError}, - clonecell::CloneCell, - }, + object::{Object, Version}, + utils::clonecell::CloneCell, wire::{wl_shm_pool::*, WlShmPoolId}, }, std::rc::Rc, @@ -23,6 +20,7 @@ pub struct WlShmPool { fd: Rc, mem: CloneCell>, pub tracker: Tracker, + version: Version, } impl WlShmPool { @@ -31,6 +29,7 @@ impl WlShmPool { client: &Rc, fd: Rc, len: usize, + version: Version, ) -> Result { Ok(Self { id, @@ -38,11 +37,15 @@ impl WlShmPool { mem: CloneCell::new(Rc::new(ClientMem::new(fd.raw(), len, false)?)), fd, tracker: Default::default(), + version, }) } +} + +impl WlShmPoolRequestHandler for WlShmPool { + type Error = WlShmPoolError; - fn create_buffer(&self, parser: MsgParser<'_, '_>) -> Result<(), WlShmPoolError> { - let req: CreateBuffer = self.client.parse(self, parser)?; + fn create_buffer(&self, req: CreateBuffer, _slf: &Rc) -> Result<(), Self::Error> { let drm_format = map_wayland_format_id(req.format); let format = match formats().get(&drm_format) { Some(f) if f.shm_info.is_some() => *f, @@ -66,14 +69,12 @@ impl WlShmPool { Ok(()) } - fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), WlShmPoolError> { - let _req: Destroy = self.client.parse(self, parser)?; + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { self.client.remove_obj(self)?; Ok(()) } - fn resize(&self, parser: MsgParser<'_, '_>) -> Result<(), WlShmPoolError> { - let req: Resize = self.client.parse(self, parser)?; + fn resize(&self, req: Resize, _slf: &Rc) -> Result<(), Self::Error> { if req.size < 0 { return Err(WlShmPoolError::NegativeSize); } @@ -91,10 +92,7 @@ impl WlShmPool { object_base! { self = WlShmPool; - - CREATE_BUFFER => create_buffer, - DESTROY => destroy, - RESIZE => resize, + version = self.version; } impl Object for WlShmPool {} @@ -107,8 +105,6 @@ pub enum WlShmPoolError { ClientError(Box), #[error(transparent)] ClientMemError(Box), - #[error("Parsing failed")] - MsgParserError(#[source] Box), #[error("Tried to shrink the pool")] CannotShrink, #[error("Requested size is negative")] @@ -123,4 +119,3 @@ pub enum WlShmPoolError { efrom!(WlShmPoolError, ClientError); efrom!(WlShmPoolError, ClientMemError); efrom!(WlShmPoolError, WlBufferError); -efrom!(WlShmPoolError, MsgParserError); diff --git a/src/ifs/wl_subcompositor.rs b/src/ifs/wl_subcompositor.rs index 01e477d6..bc3ea8af 100644 --- a/src/ifs/wl_subcompositor.rs +++ b/src/ifs/wl_subcompositor.rs @@ -5,7 +5,6 @@ use { ifs::wl_surface::wl_subsurface::{WlSubsurface, WlSubsurfaceError}, leaks::Tracker, object::{Object, Version}, - utils::buffd::{MsgParser, MsgParserError}, wire::{wl_subcompositor::*, WlSubcompositorId}, }, std::rc::Rc, @@ -23,6 +22,7 @@ pub struct WlSubcompositor { id: WlSubcompositorId, client: Rc, pub tracker: Tracker, + version: Version, } impl WlSubcompositorGlobal { @@ -34,12 +34,13 @@ impl WlSubcompositorGlobal { self: Rc, id: WlSubcompositorId, client: &Rc, - _version: Version, + version: Version, ) -> Result<(), WlSubcompositorError> { let obj = Rc::new(WlSubcompositor { id, client: client.clone(), tracker: Default::default(), + version, }); track!(client, obj); client.add_client_obj(&obj)?; @@ -47,18 +48,18 @@ impl WlSubcompositorGlobal { } } -impl WlSubcompositor { - fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), WlSubcompositorError> { - let _req: Destroy = self.client.parse(self, parser)?; +impl WlSubcompositorRequestHandler for WlSubcompositor { + type Error = WlSubcompositorError; + + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { self.client.remove_obj(self)?; Ok(()) } - fn get_subsurface(&self, parser: MsgParser<'_, '_>) -> Result<(), WlSubcompositorError> { - let req: GetSubsurface = self.client.parse(self, parser)?; + fn get_subsurface(&self, req: GetSubsurface, _slf: &Rc) -> Result<(), Self::Error> { let surface = self.client.lookup(req.surface)?; let parent = self.client.lookup(req.parent)?; - let subsurface = Rc::new(WlSubsurface::new(req.id, &surface, &parent)); + let subsurface = Rc::new(WlSubsurface::new(req.id, &surface, &parent, self.version)); track!(self.client, subsurface); self.client.add_client_obj(&subsurface)?; subsurface.install()?; @@ -82,9 +83,7 @@ simple_add_global!(WlSubcompositorGlobal); object_base! { self = WlSubcompositor; - - DESTROY => destroy, - GET_SUBSURFACE => get_subsurface, + version = self.version; } impl Object for WlSubcompositor {} @@ -95,11 +94,8 @@ simple_add_obj!(WlSubcompositor); pub enum WlSubcompositorError { #[error(transparent)] ClientError(Box), - #[error("Parsing failed")] - MsgParserError(#[source] Box), #[error(transparent)] WlSubsurfaceError(Box), } efrom!(WlSubcompositorError, ClientError); -efrom!(WlSubcompositorError, MsgParserError); efrom!(WlSubcompositorError, WlSubsurfaceError); diff --git a/src/ifs/wl_surface.rs b/src/ifs/wl_surface.rs index 32191bbf..707a37fe 100644 --- a/src/ifs/wl_surface.rs +++ b/src/ifs/wl_surface.rs @@ -15,7 +15,7 @@ pub mod zwp_idle_inhibitor_v1; use { crate::{ backend::KeyState, - client::{Client, ClientError, RequestParser}, + client::{Client, ClientError}, drm_feedback::DrmFeedback, fixed::Fixed, gfx_api::{AcquireSync, BufferResv, BufferResvUser, ReleaseSync, SampleRect, SyncFile}, @@ -51,14 +51,8 @@ use { ToplevelNode, }, utils::{ - buffd::{MsgParser, MsgParserError}, - cell_ext::CellExt, - clonecell::CloneCell, - copyhashmap::CopyHashMap, - errorfmt::ErrorFmt, - linkedlist::LinkedList, - numcell::NumCell, - smallmap::SmallMap, + cell_ext::CellExt, clonecell::CloneCell, copyhashmap::CopyHashMap, errorfmt::ErrorFmt, + linkedlist::LinkedList, numcell::NumCell, smallmap::SmallMap, transform_ext::TransformExt, }, video::{ @@ -742,13 +736,6 @@ impl WlSurface { root } - fn parse<'a, T: RequestParser<'a>>( - &self, - parser: MsgParser<'_, 'a>, - ) -> Result { - self.client.parse(self, parser) - } - fn unset_cursors(&self) { while let Some((_, cursor)) = self.cursors.pop() { cursor.handle_surface_destroy(); @@ -760,9 +747,12 @@ impl WlSurface { seat.remove_dnd_icon() } } +} + +impl WlSurfaceRequestHandler for WlSurface { + type Error = WlSurfaceError; - fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), WlSurfaceError> { - let _req: Destroy = self.parse(parser)?; + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { self.commit_timeline.clear(ClearReason::Destroy); self.unset_dnd_icons(); self.unset_cursors(); @@ -792,8 +782,7 @@ impl WlSurface { Ok(()) } - fn attach(self: &Rc, parser: MsgParser<'_, '_>) -> Result<(), WlSurfaceError> { - let req: Attach = self.parse(parser)?; + fn attach(&self, req: Attach, _slf: &Rc) -> Result<(), Self::Error> { let pending = &mut *self.pending.borrow_mut(); if self.version >= OFFSET_SINCE { if req.x != 0 || req.y != 0 { @@ -811,14 +800,12 @@ impl WlSurface { Ok(()) } - fn damage(&self, parser: MsgParser<'_, '_>) -> Result<(), WlSurfaceError> { - let _req: Damage = self.parse(parser)?; + fn damage(&self, _req: Damage, _slf: &Rc) -> Result<(), Self::Error> { self.pending.borrow_mut().damage = true; Ok(()) } - fn frame(&self, parser: MsgParser<'_, '_>) -> Result<(), WlSurfaceError> { - let req: Frame = self.parse(parser)?; + fn frame(&self, req: Frame, _slf: &Rc) -> Result<(), Self::Error> { let cb = Rc::new(WlCallback::new(req.callback, &self.client)); track!(self.client, cb); self.client.add_client_obj(&cb)?; @@ -826,8 +813,11 @@ impl WlSurface { Ok(()) } - fn set_opaque_region(&self, parser: MsgParser<'_, '_>) -> Result<(), WlSurfaceError> { - let region: SetOpaqueRegion = self.parse(parser)?; + fn set_opaque_region( + &self, + region: SetOpaqueRegion, + _slf: &Rc, + ) -> Result<(), Self::Error> { let region = if region.region.is_some() { Some(self.client.lookup(region.region)?.region()) } else { @@ -837,8 +827,7 @@ impl WlSurface { Ok(()) } - fn set_input_region(&self, parser: MsgParser<'_, '_>) -> Result<(), WlSurfaceError> { - let req: SetInputRegion = self.parse(parser)?; + fn set_input_region(&self, req: SetInputRegion, _slf: &Rc) -> Result<(), Self::Error> { let region = if req.region.is_some() { Some(self.client.lookup(req.region)?.region()) } else { @@ -848,6 +837,48 @@ impl WlSurface { Ok(()) } + fn commit(&self, _req: Commit, slf: &Rc) -> Result<(), Self::Error> { + let ext = self.ext.get(); + let pending = &mut *self.pending.borrow_mut(); + self.verify_explicit_sync(pending)?; + if ext.commit_requested(pending) == CommitAction::ContinueCommit { + self.commit_timeline.commit(slf, pending)?; + } + Ok(()) + } + + fn set_buffer_transform( + &self, + req: SetBufferTransform, + _slf: &Rc, + ) -> Result<(), Self::Error> { + let Some(tf) = Transform::from_wl(req.transform) else { + return Err(WlSurfaceError::UnknownBufferTransform(req.transform)); + }; + self.pending.borrow_mut().transform = Some(tf); + Ok(()) + } + + fn set_buffer_scale(&self, req: SetBufferScale, _slf: &Rc) -> Result<(), Self::Error> { + if req.scale < 1 { + return Err(WlSurfaceError::NonPositiveBufferScale); + } + self.pending.borrow_mut().scale = Some(req.scale); + Ok(()) + } + + fn damage_buffer(&self, _req: DamageBuffer, _slf: &Rc) -> Result<(), Self::Error> { + self.pending.borrow_mut().damage = true; + Ok(()) + } + + fn offset(&self, req: Offset, _slf: &Rc) -> Result<(), Self::Error> { + self.pending.borrow_mut().offset = (req.x, req.y); + Ok(()) + } +} + +impl WlSurface { fn apply_state(self: &Rc, pending: &mut PendingState) -> Result<(), WlSurfaceError> { for (_, pending) in &mut pending.subsurfaces { pending.subsurface.apply_state(&mut pending.pending)?; @@ -1056,17 +1087,6 @@ impl WlSurface { Ok(()) } - fn commit(self: &Rc, parser: MsgParser<'_, '_>) -> Result<(), WlSurfaceError> { - let _req: Commit = self.parse(parser)?; - let ext = self.ext.get(); - let pending = &mut *self.pending.borrow_mut(); - self.verify_explicit_sync(pending)?; - if ext.commit_requested(pending) == CommitAction::ContinueCommit { - self.commit_timeline.commit(self, pending)?; - } - Ok(()) - } - fn verify_explicit_sync(&self, pending: &mut PendingState) -> Result<(), WlSurfaceError> { pending.explicit_sync = self.sync_obj_surface.is_some(); if !pending.explicit_sync { @@ -1088,36 +1108,6 @@ impl WlSurface { } } - fn set_buffer_transform(&self, parser: MsgParser<'_, '_>) -> Result<(), WlSurfaceError> { - let req: SetBufferTransform = self.parse(parser)?; - let Some(tf) = Transform::from_wl(req.transform) else { - return Err(WlSurfaceError::UnknownBufferTransform(req.transform)); - }; - self.pending.borrow_mut().transform = Some(tf); - Ok(()) - } - - fn set_buffer_scale(&self, parser: MsgParser<'_, '_>) -> Result<(), WlSurfaceError> { - let req: SetBufferScale = self.parse(parser)?; - if req.scale < 1 { - return Err(WlSurfaceError::NonPositiveBufferScale); - } - self.pending.borrow_mut().scale = Some(req.scale); - Ok(()) - } - - fn damage_buffer(&self, parser: MsgParser<'_, '_>) -> Result<(), WlSurfaceError> { - let _req: DamageBuffer = self.parse(parser)?; - self.pending.borrow_mut().damage = true; - Ok(()) - } - - fn offset(&self, parser: MsgParser<'_, '_>) -> Result<(), WlSurfaceError> { - let req: Offset = self.parse(parser)?; - self.pending.borrow_mut().offset = (req.x, req.y); - Ok(()) - } - fn accepts_input_at(&self, x: i32, y: i32) -> bool { let rect = self.buffer_abs_pos.get().at_point(0, 0); if !rect.contains(x, y) { @@ -1292,18 +1282,7 @@ impl WlSurface { object_base! { self = WlSurface; - - DESTROY => destroy, - ATTACH => attach, - DAMAGE => damage, - FRAME => frame, - SET_OPAQUE_REGION => set_opaque_region, - SET_INPUT_REGION => set_input_region, - COMMIT => commit, - SET_BUFFER_TRANSFORM => set_buffer_transform if self.version >= 2, - SET_BUFFER_SCALE => set_buffer_scale if self.version >= 3, - DAMAGE_BUFFER => damage_buffer if self.version >= 4, - OFFSET => offset if self.version >= 5, + version = self.version; } impl Object for WlSurface { @@ -1479,8 +1458,6 @@ pub enum WlSurfaceError { }, #[error("Cannot destroy a `wl_surface` before its role object")] ReloObjectStillExists, - #[error("Parsing failed")] - MsgParserError(#[source] Box), #[error("Buffer scale is not positive")] NonPositiveBufferScale, #[error("Unknown buffer transform {0}")] @@ -1501,5 +1478,4 @@ pub enum WlSurfaceError { efrom!(WlSurfaceError, ClientError); efrom!(WlSurfaceError, XdgSurfaceError); efrom!(WlSurfaceError, ZwlrLayerSurfaceV1Error); -efrom!(WlSurfaceError, MsgParserError); efrom!(WlSurfaceError, CommitTimelineError); diff --git a/src/ifs/wl_surface/ext_session_lock_surface_v1.rs b/src/ifs/wl_surface/ext_session_lock_surface_v1.rs index cc713ea8..b708b0db 100644 --- a/src/ifs/wl_surface/ext_session_lock_surface_v1.rs +++ b/src/ifs/wl_surface/ext_session_lock_surface_v1.rs @@ -7,13 +7,10 @@ use { wl_surface::{SurfaceExt, SurfaceRole, WlSurface, WlSurfaceError}, }, leaks::Tracker, - object::Object, + object::{Object, Version}, rect::Rect, tree::{FindTreeResult, FoundNode, Node, NodeId, NodeVisitor, OutputNode}, - utils::{ - buffd::{MsgParser, MsgParserError}, - numcell::NumCell, - }, + utils::numcell::NumCell, wire::{ext_session_lock_surface_v1::*, ExtSessionLockSurfaceV1Id, WlSurfaceId}, }, std::rc::Rc, @@ -29,6 +26,7 @@ pub struct ExtSessionLockSurfaceV1 { pub serial: NumCell, pub output: Option>, pub seat_state: NodeSeatState, + pub version: Version, } impl ExtSessionLockSurfaceV1 { @@ -56,20 +54,24 @@ impl ExtSessionLockSurfaceV1 { height: height as _, }); } +} + +impl ExtSessionLockSurfaceV1RequestHandler for ExtSessionLockSurfaceV1 { + type Error = ExtSessionLockSurfaceV1Error; - fn destroy(&self, msg: MsgParser<'_, '_>) -> Result<(), ExtSessionLockSurfaceV1Error> { - let _req: Destroy = self.client.parse(self, msg)?; + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { self.destroy_node(); self.surface.unset_ext(); self.client.remove_obj(self)?; Ok(()) } - fn ack_configure(&self, msg: MsgParser<'_, '_>) -> Result<(), ExtSessionLockSurfaceV1Error> { - let _req: AckConfigure = self.client.parse(self, msg)?; + fn ack_configure(&self, _req: AckConfigure, _slf: &Rc) -> Result<(), Self::Error> { Ok(()) } +} +impl ExtSessionLockSurfaceV1 { pub fn destroy_node(&self) { if let Some(output) = &self.output { if let Some(ls) = output.lock_surface.get() { @@ -131,9 +133,7 @@ impl Node for ExtSessionLockSurfaceV1 { object_base! { self = ExtSessionLockSurfaceV1; - - DESTROY => destroy, - ACK_CONFIGURE => ack_configure, + version = self.version; } impl Object for ExtSessionLockSurfaceV1 { @@ -146,8 +146,6 @@ simple_add_obj!(ExtSessionLockSurfaceV1); #[derive(Debug, Error)] pub enum ExtSessionLockSurfaceV1Error { - #[error("Parsing failed")] - MsgParserError(#[source] Box), #[error(transparent)] ClientError(Box), #[error(transparent)] @@ -155,5 +153,4 @@ pub enum ExtSessionLockSurfaceV1Error { #[error("Surface {0} cannot be turned into an ext_session_lock_surface because it already has an attached ext_session_lock_surface")] AlreadyAttached(WlSurfaceId), } -efrom!(ExtSessionLockSurfaceV1Error, MsgParserError); efrom!(ExtSessionLockSurfaceV1Error, ClientError); diff --git a/src/ifs/wl_surface/wl_subsurface.rs b/src/ifs/wl_surface/wl_subsurface.rs index ea1fb0df..377226f0 100644 --- a/src/ifs/wl_surface/wl_subsurface.rs +++ b/src/ifs/wl_surface/wl_subsurface.rs @@ -6,10 +6,9 @@ use { SurfaceRole, WlSurface, WlSurfaceError, WlSurfaceId, }, leaks::Tracker, - object::Object, + object::{Object, Version}, rect::Rect, utils::{ - buffd::{MsgParser, MsgParserError}, clonecell::CloneCell, linkedlist::{LinkedNode, NodeRef}, numcell::NumCell, @@ -20,7 +19,6 @@ use { cell::{Cell, RefCell, RefMut}, collections::hash_map::OccupiedEntry, mem, - ops::Deref, rc::Rc, }, thiserror::Error, @@ -46,6 +44,7 @@ pub struct WlSubsurface { depth: NumCell, pub tracker: Tracker, had_buffer: Cell, + version: Version, } #[derive(Default)] @@ -92,7 +91,12 @@ fn update_children_attach(surface: &WlSubsurface) -> Result<(), WlSubsurfaceErro } impl WlSubsurface { - pub fn new(id: WlSubsurfaceId, surface: &Rc, parent: &Rc) -> Self { + pub fn new( + id: WlSubsurfaceId, + surface: &Rc, + parent: &Rc, + version: Version, + ) -> Self { Self { id, unique_id: surface.client.state.subsurface_ids.next(), @@ -106,6 +110,7 @@ impl WlSubsurface { depth: NumCell::new(1), tracker: Default::default(), had_buffer: Cell::new(false), + version, } } @@ -170,45 +175,6 @@ impl WlSubsurface { Ok(()) } - fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), WlSubsurfaceError> { - let _req: Destroy = self.surface.client.parse(self, parser)?; - self.surface.unset_ext(); - self.parent.consume_pending_child(self.unique_id, |oe| { - let oe = oe.remove(); - if let Some(mut state) = oe.pending.state { - self.surface.apply_state(&mut state)?; - } - Ok(()) - })?; - *self.node.borrow_mut() = None; - self.latest_node.take(); - { - let mut children = self.parent.children.borrow_mut(); - if let Some(children) = &mut *children { - children.subsurfaces.remove(&self.surface.id); - } - } - if !self.surface.extents.get().is_empty() { - let mut parent_opt = Some(self.parent.clone()); - while let Some(parent) = parent_opt.take() { - if !parent.need_extents_update.get() { - break; - } - parent.calculate_extents(); - parent_opt = parent.ext.get().subsurface_parent(); - } - } - self.surface.client.remove_obj(self)?; - self.surface.destroy_node(); - Ok(()) - } - - fn set_position(self: &Rc, parser: MsgParser<'_, '_>) -> Result<(), WlSubsurfaceError> { - let req: SetPosition = self.surface.client.parse(&**self, parser)?; - self.pending().position = Some((req.x, req.y)); - Ok(()) - } - fn place(self: &Rc, sibling: WlSurfaceId, above: bool) -> Result<(), WlSubsurfaceError> { if sibling == self.surface.id { return Err(WlSubsurfaceError::AboveSelf(sibling)); @@ -244,18 +210,6 @@ impl WlSubsurface { Ok(()) } - fn place_above(self: &Rc, parser: MsgParser<'_, '_>) -> Result<(), WlSubsurfaceError> { - let req: PlaceAbove = self.surface.client.parse(self.deref(), parser)?; - self.place(req.sibling, true)?; - Ok(()) - } - - fn place_below(self: &Rc, parser: MsgParser<'_, '_>) -> Result<(), WlSubsurfaceError> { - let req: PlaceBelow = self.surface.client.parse(self.deref(), parser)?; - self.place(req.sibling, false)?; - Ok(()) - } - pub fn sync(&self) -> bool { self.sync_requested.get() || self.sync_ancestor.get() } @@ -298,15 +252,64 @@ impl WlSubsurface { } Ok(()) } +} + +impl WlSubsurfaceRequestHandler for WlSubsurface { + type Error = WlSubsurfaceError; - fn set_sync(&self, parser: MsgParser<'_, '_>) -> Result<(), WlSubsurfaceError> { - let _req: SetSync = self.surface.client.parse(self, parser)?; + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { + self.surface.unset_ext(); + self.parent.consume_pending_child(self.unique_id, |oe| { + let oe = oe.remove(); + if let Some(mut state) = oe.pending.state { + self.surface.apply_state(&mut state)?; + } + Ok(()) + })?; + *self.node.borrow_mut() = None; + self.latest_node.take(); + { + let mut children = self.parent.children.borrow_mut(); + if let Some(children) = &mut *children { + children.subsurfaces.remove(&self.surface.id); + } + } + if !self.surface.extents.get().is_empty() { + let mut parent_opt = Some(self.parent.clone()); + while let Some(parent) = parent_opt.take() { + if !parent.need_extents_update.get() { + break; + } + parent.calculate_extents(); + parent_opt = parent.ext.get().subsurface_parent(); + } + } + self.surface.client.remove_obj(self)?; + self.surface.destroy_node(); + Ok(()) + } + + fn set_position(&self, req: SetPosition, slf: &Rc) -> Result<(), Self::Error> { + slf.pending().position = Some((req.x, req.y)); + Ok(()) + } + + fn place_above(&self, req: PlaceAbove, slf: &Rc) -> Result<(), Self::Error> { + slf.place(req.sibling, true)?; + Ok(()) + } + + fn place_below(&self, req: PlaceBelow, slf: &Rc) -> Result<(), Self::Error> { + slf.place(req.sibling, false)?; + Ok(()) + } + + fn set_sync(&self, _req: SetSync, _slf: &Rc) -> Result<(), Self::Error> { self.update_sync(true)?; Ok(()) } - fn set_desync(&self, parser: MsgParser<'_, '_>) -> Result<(), WlSubsurfaceError> { - let _req: SetDesync = self.surface.client.parse(self, parser)?; + fn set_desync(&self, _req: SetDesync, _slf: &Rc) -> Result<(), Self::Error> { self.update_sync(false)?; Ok(()) } @@ -314,13 +317,7 @@ impl WlSubsurface { object_base! { self = WlSubsurface; - - DESTROY => destroy, - SET_POSITION => set_position, - PLACE_ABOVE => place_above, - PLACE_BELOW => place_below, - SET_SYNC => set_sync, - SET_DESYNC => set_desync, + version = self.version; } impl Object for WlSubsurface { @@ -404,13 +401,10 @@ pub enum WlSubsurfaceError { WlSurfaceError(Box), #[error(transparent)] ClientError(Box), - #[error("Parsing failed")] - MsgParserError(#[source] Box), #[error("Cannot place {0} above/below itself")] AboveSelf(WlSurfaceId), #[error("{0} is not a sibling of {1}")] NotASibling(WlSurfaceId, WlSurfaceId), } efrom!(WlSubsurfaceError, WlSurfaceError); -efrom!(WlSubsurfaceError, MsgParserError); efrom!(WlSubsurfaceError, ClientError); diff --git a/src/ifs/wl_surface/wp_fractional_scale_v1.rs b/src/ifs/wl_surface/wp_fractional_scale_v1.rs index 6f86fdcc..e3c841b0 100644 --- a/src/ifs/wl_surface/wp_fractional_scale_v1.rs +++ b/src/ifs/wl_surface/wp_fractional_scale_v1.rs @@ -3,8 +3,7 @@ use { client::{Client, ClientError}, ifs::wl_surface::WlSurface, leaks::Tracker, - object::Object, - utils::buffd::{MsgParser, MsgParserError}, + object::{Object, Version}, wire::{wp_fractional_scale_v1::*, WpFractionalScaleV1Id}, }, std::rc::Rc, @@ -16,15 +15,17 @@ pub struct WpFractionalScaleV1 { pub client: Rc, pub surface: Rc, pub tracker: Tracker, + pub version: Version, } impl WpFractionalScaleV1 { - pub fn new(id: WpFractionalScaleV1Id, surface: &Rc) -> Self { + pub fn new(id: WpFractionalScaleV1Id, surface: &Rc, version: Version) -> Self { Self { id, client: surface.client.clone(), surface: surface.clone(), tracker: Default::default(), + version, } } @@ -50,9 +51,12 @@ impl WpFractionalScaleV1 { .to_wl(), }); } +} + +impl WpFractionalScaleV1RequestHandler for WpFractionalScaleV1 { + type Error = WpFractionalScaleError; - fn destroy(&self, msg: MsgParser<'_, '_>) -> Result<(), WpFractionalScaleError> { - let _req: Destroy = self.client.parse(self, msg)?; + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { self.surface.fractional_scale.take(); self.client.remove_obj(self)?; Ok(()) @@ -61,8 +65,7 @@ impl WpFractionalScaleV1 { object_base! { self = WpFractionalScaleV1; - - DESTROY => destroy, + version = self.version; } impl Object for WpFractionalScaleV1 {} @@ -71,12 +74,9 @@ simple_add_obj!(WpFractionalScaleV1); #[derive(Debug, Error)] pub enum WpFractionalScaleError { - #[error("Parsing failed")] - MsgParserError(#[source] Box), #[error(transparent)] ClientError(Box), #[error("The surface already has a fractional scale extension attached")] Exists, } -efrom!(WpFractionalScaleError, MsgParserError); efrom!(WpFractionalScaleError, ClientError); diff --git a/src/ifs/wl_surface/wp_linux_drm_syncobj_surface_v1.rs b/src/ifs/wl_surface/wp_linux_drm_syncobj_surface_v1.rs index 9df410ab..4c755699 100644 --- a/src/ifs/wl_surface/wp_linux_drm_syncobj_surface_v1.rs +++ b/src/ifs/wl_surface/wp_linux_drm_syncobj_surface_v1.rs @@ -3,8 +3,7 @@ use { client::{Client, ClientError}, ifs::wl_surface::WlSurface, leaks::Tracker, - object::Object, - utils::buffd::{MsgParser, MsgParserError}, + object::{Object, Version}, video::drm::sync_obj::SyncObjPoint, wire::{wp_linux_drm_syncobj_surface_v1::*, WpLinuxDrmSyncobjSurfaceV1Id}, }, @@ -17,6 +16,7 @@ pub struct WpLinuxDrmSyncobjSurfaceV1 { client: Rc, surface: Rc, pub tracker: Tracker, + version: Version, } impl WpLinuxDrmSyncobjSurfaceV1 { @@ -24,12 +24,14 @@ impl WpLinuxDrmSyncobjSurfaceV1 { id: WpLinuxDrmSyncobjSurfaceV1Id, client: &Rc, surface: &Rc, + version: Version, ) -> Self { Self { id, client: client.clone(), tracker: Default::default(), surface: surface.clone(), + version, } } @@ -40,9 +42,12 @@ impl WpLinuxDrmSyncobjSurfaceV1 { self.surface.sync_obj_surface.set(Some(self.clone())); Ok(()) } +} + +impl WpLinuxDrmSyncobjSurfaceV1RequestHandler for WpLinuxDrmSyncobjSurfaceV1 { + type Error = WpLinuxDrmSyncobjSurfaceV1Error; - fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), WpLinuxDrmSyncobjSurfaceV1Error> { - let _req: Destroy = self.client.parse(self, parser)?; + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { self.surface.sync_obj_surface.take(); let pending = &mut *self.surface.pending.borrow_mut(); pending.release_point.take(); @@ -51,22 +56,14 @@ impl WpLinuxDrmSyncobjSurfaceV1 { Ok(()) } - fn set_acquire_point( - &self, - parser: MsgParser<'_, '_>, - ) -> Result<(), WpLinuxDrmSyncobjSurfaceV1Error> { - let req: SetAcquirePoint = self.client.parse(self, parser)?; + fn set_acquire_point(&self, req: SetAcquirePoint, _slf: &Rc) -> Result<(), Self::Error> { let point = point(req.point_hi, req.point_lo); let timeline = self.client.lookup(req.timeline)?; self.surface.pending.borrow_mut().acquire_point = Some((timeline.sync_obj.clone(), point)); Ok(()) } - fn set_release_point( - &self, - parser: MsgParser<'_, '_>, - ) -> Result<(), WpLinuxDrmSyncobjSurfaceV1Error> { - let req: SetReleasePoint = self.client.parse(self, parser)?; + fn set_release_point(&self, req: SetReleasePoint, _slf: &Rc) -> Result<(), Self::Error> { let point = point(req.point_hi, req.point_lo); let timeline = self.client.lookup(req.timeline)?; self.surface.pending.borrow_mut().release_point = Some((timeline.sync_obj.clone(), point)); @@ -80,10 +77,7 @@ fn point(hi: u32, lo: u32) -> SyncObjPoint { object_base! { self = WpLinuxDrmSyncobjSurfaceV1; - - DESTROY => destroy, - SET_ACQUIRE_POINT => set_acquire_point, - SET_RELEASE_POINT => set_release_point, + version = self.version; } impl Object for WpLinuxDrmSyncobjSurfaceV1 {} @@ -92,12 +86,9 @@ simple_add_obj!(WpLinuxDrmSyncobjSurfaceV1); #[derive(Debug, Error)] pub enum WpLinuxDrmSyncobjSurfaceV1Error { - #[error("Parsing failed")] - MsgParserError(#[source] Box), #[error(transparent)] ClientError(Box), #[error("The surface already has a syncobj extension attached")] Exists, } -efrom!(WpLinuxDrmSyncobjSurfaceV1Error, MsgParserError); efrom!(WpLinuxDrmSyncobjSurfaceV1Error, ClientError); diff --git a/src/ifs/wl_surface/wp_tearing_control_v1.rs b/src/ifs/wl_surface/wp_tearing_control_v1.rs index 7e90f388..57316e7c 100644 --- a/src/ifs/wl_surface/wp_tearing_control_v1.rs +++ b/src/ifs/wl_surface/wp_tearing_control_v1.rs @@ -3,8 +3,7 @@ use { client::ClientError, ifs::wl_surface::WlSurface, leaks::Tracker, - object::Object, - utils::buffd::{MsgParser, MsgParserError}, + object::{Object, Version}, wire::{wp_tearing_control_v1::*, WlSurfaceId, WpTearingControlV1Id}, }, std::{fmt::Debug, rc::Rc}, @@ -18,6 +17,7 @@ pub struct WpTearingControlV1 { pub id: WpTearingControlV1Id, pub surface: Rc, pub tracker: Tracker, + pub version: Version, } impl WpTearingControlV1 { @@ -28,12 +28,16 @@ impl WpTearingControlV1 { self.surface.tearing_control.set(Some(self.clone())); Ok(()) } +} + +impl WpTearingControlV1RequestHandler for WpTearingControlV1 { + type Error = WpTearingControlV1Error; fn set_presentation_hint( &self, - parser: MsgParser<'_, '_>, - ) -> Result<(), WpTearingControlV1Error> { - let req: SetPresentationHint = self.surface.client.parse(self, parser)?; + req: SetPresentationHint, + _slf: &Rc, + ) -> Result<(), Self::Error> { let tearing = match req.hint { VSYNC => false, ASYNC => true, @@ -43,8 +47,7 @@ impl WpTearingControlV1 { Ok(()) } - fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), WpTearingControlV1Error> { - let _req: Destroy = self.surface.client.parse(self, parser)?; + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { self.surface.pending.borrow_mut().tearing = Some(false); self.surface.tearing_control.take(); self.surface.client.remove_obj(self)?; @@ -54,9 +57,7 @@ impl WpTearingControlV1 { object_base! { self = WpTearingControlV1; - - SET_PRESENTATION_HINT => set_presentation_hint, - DESTROY => destroy, + version = self.version; } impl Object for WpTearingControlV1 {} @@ -71,8 +72,5 @@ pub enum WpTearingControlV1Error { UnknownPresentationHint(u32), #[error(transparent)] ClientError(Box), - #[error("Parsing failed")] - MsgParserError(#[source] Box), } efrom!(WpTearingControlV1Error, ClientError); -efrom!(WpTearingControlV1Error, MsgParserError); diff --git a/src/ifs/wl_surface/wp_viewport.rs b/src/ifs/wl_surface/wp_viewport.rs index f7945fcf..1c03ff47 100644 --- a/src/ifs/wl_surface/wp_viewport.rs +++ b/src/ifs/wl_surface/wp_viewport.rs @@ -3,8 +3,7 @@ use { client::{Client, ClientError}, ifs::wl_surface::WlSurface, leaks::Tracker, - object::Object, - utils::buffd::{MsgParser, MsgParserError}, + object::{Object, Version}, wire::{wp_viewport::*, WpViewportId}, }, std::rc::Rc, @@ -16,15 +15,17 @@ pub struct WpViewport { pub client: Rc, pub surface: Rc, pub tracker: Tracker, + pub version: Version, } impl WpViewport { - pub fn new(id: WpViewportId, surface: &Rc) -> Self { + pub fn new(id: WpViewportId, surface: &Rc, version: Version) -> Self { Self { id, client: surface.client.clone(), surface: surface.clone(), tracker: Default::default(), + version, } } @@ -35,9 +36,12 @@ impl WpViewport { self.surface.viewporter.set(Some(self.clone())); Ok(()) } +} + +impl WpViewportRequestHandler for WpViewport { + type Error = WpViewportError; - fn destroy(&self, msg: MsgParser<'_, '_>) -> Result<(), WpViewportError> { - let _req: Destroy = self.client.parse(self, msg)?; + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { let pending = &mut *self.surface.pending.borrow_mut(); pending.src_rect = Some(None); pending.dst_size = Some(None); @@ -46,8 +50,7 @@ impl WpViewport { Ok(()) } - fn set_source(&self, msg: MsgParser<'_, '_>) -> Result<(), WpViewportError> { - let req: SetSource = self.client.parse(self, msg)?; + fn set_source(&self, req: SetSource, _slf: &Rc) -> Result<(), Self::Error> { let rect = if req.x == -1 && req.y == -1 && req.width == -1 && req.height == -1 { None } else { @@ -61,8 +64,7 @@ impl WpViewport { Ok(()) } - fn set_destination(&self, msg: MsgParser<'_, '_>) -> Result<(), WpViewportError> { - let req: SetDestination = self.client.parse(self, msg)?; + fn set_destination(&self, req: SetDestination, _slf: &Rc) -> Result<(), Self::Error> { let size = if req.width == -1 && req.height == -1 { None } else if req.width <= 0 || req.height <= 0 { @@ -77,10 +79,7 @@ impl WpViewport { object_base! { self = WpViewport; - - DESTROY => destroy, - SET_SOURCE => set_source, - SET_DESTINATION => set_destination, + version = self.version; } impl Object for WpViewport {} @@ -89,8 +88,6 @@ simple_add_obj!(WpViewport); #[derive(Debug, Error)] pub enum WpViewportError { - #[error("Parsing failed")] - MsgParserError(#[source] Box), #[error(transparent)] ClientError(Box), #[error("The surface already has a viewport")] @@ -100,5 +97,4 @@ pub enum WpViewportError { #[error("Rectangle is empty")] InvalidDestRect, } -efrom!(WpViewportError, MsgParserError); efrom!(WpViewportError, ClientError); diff --git a/src/ifs/wl_surface/x_surface/xwayland_surface_v1.rs b/src/ifs/wl_surface/x_surface/xwayland_surface_v1.rs index 70a391b3..aac1fb54 100644 --- a/src/ifs/wl_surface/x_surface/xwayland_surface_v1.rs +++ b/src/ifs/wl_surface/x_surface/xwayland_surface_v1.rs @@ -3,11 +3,8 @@ use { client::{Client, ClientError}, ifs::wl_surface::{x_surface::XSurface, WlSurfaceError}, leaks::Tracker, - object::Object, - utils::{ - buffd::{MsgParser, MsgParserError}, - cell_ext::CellExt, - }, + object::{Object, Version}, + utils::cell_ext::CellExt, wire::{xwayland_surface_v1::*, XwaylandSurfaceV1Id}, }, std::rc::Rc, @@ -19,11 +16,13 @@ pub struct XwaylandSurfaceV1 { pub client: Rc, pub x: Rc, pub tracker: Tracker, + pub version: Version, } -impl XwaylandSurfaceV1 { - fn set_serial(&self, parser: MsgParser<'_, '_>) -> Result<(), XwaylandSurfaceV1Error> { - let req: SetSerial = self.client.parse(self, parser)?; +impl XwaylandSurfaceV1RequestHandler for XwaylandSurfaceV1 { + type Error = XwaylandSurfaceV1Error; + + fn set_serial(&self, req: SetSerial, _slf: &Rc) -> Result<(), Self::Error> { if self.x.surface.xwayland_serial.is_some() { return Err(XwaylandSurfaceV1Error::SerialAlreadySet); } @@ -36,8 +35,7 @@ impl XwaylandSurfaceV1 { Ok(()) } - fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), XwaylandSurfaceV1Error> { - let _req: Destroy = self.client.parse(self, parser)?; + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { self.x.xwayland_surface.set(None); self.client.remove_obj(self)?; Ok(()) @@ -46,9 +44,7 @@ impl XwaylandSurfaceV1 { object_base! { self = XwaylandSurfaceV1; - - SET_SERIAL => set_serial, - DESTROY => destroy, + version = self.version; } impl Object for XwaylandSurfaceV1 { @@ -67,10 +63,7 @@ pub enum XwaylandSurfaceV1Error { NonMonotonicSerial, #[error(transparent)] WlSurfaceError(#[from] WlSurfaceError), - #[error("Parsing failed")] - MsgParserError(#[source] Box), #[error(transparent)] ClientError(Box), } -efrom!(XwaylandSurfaceV1Error, MsgParserError); efrom!(XwaylandSurfaceV1Error, ClientError); diff --git a/src/ifs/wl_surface/xdg_surface.rs b/src/ifs/wl_surface/xdg_surface.rs index 5bb581b7..6b1d7b01 100644 --- a/src/ifs/wl_surface/xdg_surface.rs +++ b/src/ifs/wl_surface/xdg_surface.rs @@ -19,11 +19,7 @@ use { rect::Rect, tree::{FindTreeResult, FoundNode, OutputNode, WorkspaceNode}, utils::{ - buffd::{MsgParser, MsgParserError}, - clonecell::CloneCell, - copyhashmap::CopyHashMap, - numcell::NumCell, - option_ext::OptionExt, + clonecell::CloneCell, copyhashmap::CopyHashMap, numcell::NumCell, option_ext::OptionExt, }, wire::{xdg_surface::*, WlSurfaceId, XdgPopupId, XdgSurfaceId}, }, @@ -215,8 +211,17 @@ impl XdgSurface { Ok(()) } - fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), XdgSurfaceError> { - let _req: Destroy = self.surface.client.parse(self, parser)?; + fn pending(&self) -> RefMut> { + RefMut::map(self.surface.pending.borrow_mut(), |p| { + p.xdg_surface.get_or_insert_default_ext() + }) + } +} + +impl XdgSurfaceRequestHandler for XdgSurface { + type Error = XdgSurfaceError; + + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { if self.ext.is_some() { return Err(XdgSurfaceError::RoleNotYetDestroyed(self.id)); } @@ -232,12 +237,11 @@ impl XdgSurface { Ok(()) } - fn get_toplevel(self: &Rc, parser: MsgParser<'_, '_>) -> Result<(), XdgSurfaceError> { - let req: GetToplevel = self.surface.client.parse(&**self, parser)?; + fn get_toplevel(&self, req: GetToplevel, slf: &Rc) -> Result<(), Self::Error> { self.set_role(XdgSurfaceRole::XdgToplevel)?; if self.ext.is_some() { self.surface.client.protocol_error( - &**self, + self, ALREADY_CONSTRUCTED, &format!( "wl_surface {} already has an assigned xdg_toplevel", @@ -246,7 +250,7 @@ impl XdgSurface { ); return Err(XdgSurfaceError::AlreadyConstructed); } - let toplevel = Rc::new(XdgToplevel::new(req.id, self)); + let toplevel = Rc::new(XdgToplevel::new(req.id, slf)); track!(self.surface.client, toplevel); self.surface.client.add_client_obj(&toplevel)?; self.ext.set(Some(toplevel.clone())); @@ -257,8 +261,7 @@ impl XdgSurface { Ok(()) } - fn get_popup(self: &Rc, parser: MsgParser<'_, '_>) -> Result<(), XdgSurfaceError> { - let req: GetPopup = self.surface.client.parse(&**self, parser)?; + fn get_popup(&self, req: GetPopup, slf: &Rc) -> Result<(), Self::Error> { self.set_role(XdgSurfaceRole::XdgPopup)?; let mut parent = None; if req.parent.is_some() { @@ -267,7 +270,7 @@ impl XdgSurface { let positioner = self.surface.client.lookup(req.positioner)?; if self.ext.is_some() { self.surface.client.protocol_error( - &**self, + self, ALREADY_CONSTRUCTED, &format!( "wl_surface {} already has an assigned xdg_popup", @@ -276,7 +279,7 @@ impl XdgSurface { ); return Err(XdgSurfaceError::AlreadyConstructed); } - let popup = Rc::new(XdgPopup::new(req.id, self, parent.as_ref(), &positioner)?); + let popup = Rc::new(XdgPopup::new(req.id, slf, parent.as_ref(), &positioner)?); track!(self.surface.client, popup); self.surface.client.add_client_obj(&popup)?; if let Some(parent) = &parent { @@ -286,14 +289,11 @@ impl XdgSurface { Ok(()) } - fn pending(&self) -> RefMut> { - RefMut::map(self.surface.pending.borrow_mut(), |p| { - p.xdg_surface.get_or_insert_default_ext() - }) - } - - fn set_window_geometry(&self, parser: MsgParser<'_, '_>) -> Result<(), XdgSurfaceError> { - let req: SetWindowGeometry = self.surface.client.parse(self, parser)?; + fn set_window_geometry( + &self, + req: SetWindowGeometry, + _slf: &Rc, + ) -> Result<(), Self::Error> { if req.height == 0 && req.width == 0 { // TODO: https://crbug.com/1329214 return Ok(()); @@ -306,14 +306,15 @@ impl XdgSurface { Ok(()) } - fn ack_configure(&self, parser: MsgParser<'_, '_>) -> Result<(), XdgSurfaceError> { - let req: AckConfigure = self.surface.client.parse(self, parser)?; + fn ack_configure(&self, req: AckConfigure, _slf: &Rc) -> Result<(), Self::Error> { if self.requested_serial.get() == req.serial { self.acked_serial.set(Some(req.serial)); } Ok(()) } +} +impl XdgSurface { fn update_extents(&self) { let old_extents = self.extents.get(); let mut new_extents = self.surface.extents.get(); @@ -360,12 +361,7 @@ impl XdgSurface { object_base! { self = XdgSurface; - - DESTROY => destroy, - GET_TOPLEVEL => get_toplevel, - GET_POPUP => get_popup, - SET_WINDOW_GEOMETRY => set_window_geometry, - ACK_CONFIGURE => ack_configure, + version = self.base.version; } impl Object for XdgSurface { @@ -429,8 +425,6 @@ pub enum XdgSurfaceError { }, #[error(transparent)] ClientError(Box), - #[error("Parsing failed")] - MsgParserError(#[source] Box), #[error("Tried no set a non-positive width/height")] NonPositiveWidthHeight, #[error("Cannot destroy xdg_surface {0} because it's associated xdg_toplevel/popup is not yet destroyed")] @@ -444,4 +438,3 @@ pub enum XdgSurfaceError { } efrom!(XdgSurfaceError, WlSurfaceError); efrom!(XdgSurfaceError, ClientError); -efrom!(XdgSurfaceError, MsgParserError); diff --git a/src/ifs/wl_surface/xdg_surface/xdg_popup.rs b/src/ifs/wl_surface/xdg_surface/xdg_popup.rs index a6df1ff8..56dac416 100644 --- a/src/ifs/wl_surface/xdg_surface/xdg_popup.rs +++ b/src/ifs/wl_surface/xdg_surface/xdg_popup.rs @@ -16,11 +16,7 @@ use { rect::Rect, renderer::Renderer, tree::{FindTreeResult, FoundNode, Node, NodeId, NodeVisitor, StackedNode, WorkspaceNode}, - utils::{ - buffd::{MsgParser, MsgParserError}, - clonecell::CloneCell, - linkedlist::LinkedNode, - }, + utils::{clonecell::CloneCell, linkedlist::LinkedNode}, wire::{xdg_popup::*, XdgPopupId}, }, std::{ @@ -205,9 +201,12 @@ impl XdgPopup { .set_absolute_desired_extents(&rel.move_(parent.x1(), parent.y1())); } } +} + +impl XdgPopupRequestHandler for XdgPopup { + type Error = XdgPopupError; - fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), XdgPopupError> { - let _req: Destroy = self.xdg.surface.client.parse(self, parser)?; + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { self.destroy_node(); { if let Some(parent) = self.parent.take() { @@ -221,13 +220,11 @@ impl XdgPopup { Ok(()) } - fn grab(&self, parser: MsgParser<'_, '_>) -> Result<(), XdgPopupError> { - let _req: Grab = self.xdg.surface.client.parse(self, parser)?; + fn grab(&self, _req: Grab, _slf: &Rc) -> Result<(), Self::Error> { Ok(()) } - fn reposition(self: &Rc, parser: MsgParser<'_, '_>) -> Result<(), XdgPopupError> { - let req: Reposition = self.xdg.surface.client.parse(&**self, parser)?; + fn reposition(&self, req: Reposition, _slf: &Rc) -> Result<(), Self::Error> { *self.pos.borrow_mut() = self.xdg.surface.client.lookup(req.positioner)?.value(); if let Some(parent) = self.parent.get() { self.update_position(&parent)?; @@ -238,7 +235,9 @@ impl XdgPopup { } Ok(()) } +} +impl XdgPopup { fn get_parent_workspace(&self) -> Option> { self.parent.get()?.workspace.get() } @@ -276,10 +275,7 @@ impl XdgPopup { object_base! { self = XdgPopup; - - DESTROY => destroy, - GRAB => grab, - REPOSITION => reposition if self.xdg.base.version >= 3, + version = self.xdg.base.version; } impl Object for XdgPopup { @@ -419,10 +415,7 @@ impl XdgSurfaceExt for XdgPopup { pub enum XdgPopupError { #[error("The `xdg_positioner` is incomplete")] Incomplete, - #[error("Parsing failed")] - MsgParserError(#[source] Box), #[error(transparent)] ClientError(Box), } -efrom!(XdgPopupError, MsgParserError); efrom!(XdgPopupError, ClientError); diff --git a/src/ifs/wl_surface/xdg_surface/xdg_toplevel.rs b/src/ifs/wl_surface/xdg_surface/xdg_toplevel.rs index 7feafa51..54bc9815 100644 --- a/src/ifs/wl_surface/xdg_surface/xdg_toplevel.rs +++ b/src/ifs/wl_surface/xdg_surface/xdg_toplevel.rs @@ -23,10 +23,7 @@ use { Direction, FindTreeResult, FoundNode, Node, NodeId, NodeVisitor, OutputNode, ToplevelData, ToplevelNode, ToplevelNodeBase, ToplevelNodeId, WorkspaceNode, }, - utils::{ - buffd::{MsgParser, MsgParserError}, - clonecell::CloneCell, - }, + utils::clonecell::CloneCell, wire::{xdg_toplevel::*, XdgToplevelId}, }, ahash::{AHashMap, AHashSet}, @@ -35,7 +32,6 @@ use { cell::{Cell, RefCell}, fmt::{Debug, Formatter}, mem, - ops::Deref, rc::Rc, }, thiserror::Error, @@ -199,9 +195,12 @@ impl XdgToplevel { capabilities: &[CAP_FULLSCREEN], }) } +} + +impl XdgToplevelRequestHandler for XdgToplevel { + type Error = XdgToplevelError; - fn destroy(self: &Rc, parser: MsgParser<'_, '_>) -> Result<(), XdgToplevelError> { - let _req: Destroy = self.xdg.surface.client.parse(self.deref(), parser)?; + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { self.tl_destroy(); self.xdg.ext.set(None); { @@ -223,13 +222,12 @@ impl XdgToplevel { parent.children.borrow_mut().remove(&self.id); } } - self.xdg.surface.client.remove_obj(self.deref())?; + self.xdg.surface.client.remove_obj(self)?; self.xdg.surface.set_toplevel(None); Ok(()) } - fn set_parent(&self, parser: MsgParser<'_, '_>) -> Result<(), XdgToplevelError> { - let req: SetParent = self.xdg.surface.client.parse(self, parser)?; + fn set_parent(&self, req: SetParent, _slf: &Rc) -> Result<(), Self::Error> { let mut parent = None; if req.parent.is_some() { parent = Some(self.xdg.surface.client.lookup(req.parent)?); @@ -238,27 +236,23 @@ impl XdgToplevel { Ok(()) } - fn set_title(&self, parser: MsgParser<'_, '_>) -> Result<(), XdgToplevelError> { - let req: SetTitle = self.xdg.surface.client.parse(self, parser)?; + fn set_title(&self, req: SetTitle, _slf: &Rc) -> Result<(), Self::Error> { self.toplevel_data.set_title(req.title); self.tl_title_changed(); Ok(()) } - fn set_app_id(&self, parser: MsgParser<'_, '_>) -> Result<(), XdgToplevelError> { - let req: SetAppId = self.xdg.surface.client.parse(self, parser)?; + fn set_app_id(&self, req: SetAppId, _slf: &Rc) -> Result<(), Self::Error> { self.toplevel_data.set_app_id(req.app_id); self.bugs.set(bugs::get(req.app_id)); Ok(()) } - fn show_window_menu(&self, parser: MsgParser<'_, '_>) -> Result<(), XdgToplevelError> { - let _req: ShowWindowMenu = self.xdg.surface.client.parse(self, parser)?; + fn show_window_menu(&self, _req: ShowWindowMenu, _slf: &Rc) -> Result<(), Self::Error> { Ok(()) } - fn move_(&self, parser: MsgParser<'_, '_>) -> Result<(), XdgToplevelError> { - let req: Move = self.xdg.surface.client.parse(self, parser)?; + fn move_(&self, req: Move, _slf: &Rc) -> Result<(), Self::Error> { let seat = self.xdg.surface.client.lookup(req.seat)?; if let Some(parent) = self.toplevel_data.parent.get() { if let Some(float) = parent.node_into_float() { @@ -268,13 +262,11 @@ impl XdgToplevel { Ok(()) } - fn resize(&self, parser: MsgParser<'_, '_>) -> Result<(), XdgToplevelError> { - let _req: Resize = self.xdg.surface.client.parse(self, parser)?; + fn resize(&self, _req: Resize, _slf: &Rc) -> Result<(), Self::Error> { Ok(()) } - fn set_max_size(&self, parser: MsgParser<'_, '_>) -> Result<(), XdgToplevelError> { - let req: SetMaxSize = self.xdg.surface.client.parse(self, parser)?; + fn set_max_size(&self, req: SetMaxSize, _slf: &Rc) -> Result<(), Self::Error> { if req.height < 0 || req.width < 0 { return Err(XdgToplevelError::NonNegative); } @@ -291,8 +283,7 @@ impl XdgToplevel { Ok(()) } - fn set_min_size(&self, parser: MsgParser<'_, '_>) -> Result<(), XdgToplevelError> { - let req: SetMinSize = self.xdg.surface.client.parse(self, parser)?; + fn set_min_size(&self, req: SetMinSize, _slf: &Rc) -> Result<(), Self::Error> { if req.height < 0 || req.width < 0 { return Err(XdgToplevelError::NonNegative); } @@ -309,19 +300,16 @@ impl XdgToplevel { Ok(()) } - fn set_maximized(&self, parser: MsgParser<'_, '_>) -> Result<(), XdgToplevelError> { - let _req: SetMaximized = self.xdg.surface.client.parse(self, parser)?; + fn set_maximized(&self, _req: SetMaximized, _slf: &Rc) -> Result<(), Self::Error> { Ok(()) } - fn unset_maximized(&self, parser: MsgParser<'_, '_>) -> Result<(), XdgToplevelError> { - let _req: UnsetMaximized = self.xdg.surface.client.parse(self, parser)?; + fn unset_maximized(&self, _req: UnsetMaximized, _slf: &Rc) -> Result<(), Self::Error> { Ok(()) } - fn set_fullscreen(self: &Rc, parser: MsgParser<'_, '_>) -> Result<(), XdgToplevelError> { + fn set_fullscreen(&self, req: SetFullscreen, slf: &Rc) -> Result<(), Self::Error> { let client = &self.xdg.surface.client; - let req: SetFullscreen = client.parse(self.deref(), parser)?; self.states.borrow_mut().insert(STATE_FULLSCREEN); 'set_fullscreen: { let output = if req.output.is_some() { @@ -338,29 +326,26 @@ impl XdgToplevel { break 'set_fullscreen; }; self.toplevel_data - .set_fullscreen(&client.state, self.clone(), &output); + .set_fullscreen(&client.state, slf.clone(), &output); } self.send_current_configure(); Ok(()) } - fn unset_fullscreen( - self: &Rc, - parser: MsgParser<'_, '_>, - ) -> Result<(), XdgToplevelError> { - let _req: UnsetFullscreen = self.xdg.surface.client.parse(self.deref(), parser)?; + fn unset_fullscreen(&self, _req: UnsetFullscreen, slf: &Rc) -> Result<(), Self::Error> { self.states.borrow_mut().remove(&STATE_FULLSCREEN); self.toplevel_data - .unset_fullscreen(&self.state, self.clone()); + .unset_fullscreen(&self.state, slf.clone()); self.send_current_configure(); Ok(()) } - fn set_minimized(&self, parser: MsgParser<'_, '_>) -> Result<(), XdgToplevelError> { - let _req: SetMinimized = self.xdg.surface.client.parse(self, parser)?; + fn set_minimized(&self, _req: SetMinimized, _slf: &Rc) -> Result<(), Self::Error> { Ok(()) } +} +impl XdgToplevel { fn map_floating(self: &Rc, workspace: &Rc, abs_pos: Option<(i32, i32)>) { let (width, height) = self.toplevel_data.float_size(workspace); self.state @@ -461,21 +446,7 @@ impl XdgToplevel { object_base! { self = XdgToplevel; - - DESTROY => destroy, - SET_PARENT => set_parent, - SET_TITLE => set_title, - SET_APP_ID => set_app_id, - SHOW_WINDOW_MENU => show_window_menu, - MOVE => move_, - RESIZE => resize, - SET_MAX_SIZE => set_max_size, - SET_MIN_SIZE => set_min_size, - SET_MAXIMIZED => set_maximized, - UNSET_MAXIMIZED => unset_maximized, - SET_FULLSCREEN => set_fullscreen, - UNSET_FULLSCREEN => unset_fullscreen, - SET_MINIMIZED => set_minimized, + version = self.xdg.base.version; } impl Object for XdgToplevel { @@ -673,12 +644,9 @@ impl XdgSurfaceExt for XdgToplevel { #[derive(Debug, Error)] pub enum XdgToplevelError { - #[error("Parsing failed")] - MsgParserError(#[source] Box), #[error(transparent)] ClientError(Box), #[error("width/height must be non-negative")] NonNegative, } -efrom!(XdgToplevelError, MsgParserError); efrom!(XdgToplevelError, ClientError); diff --git a/src/ifs/wl_surface/xwayland_shell_v1.rs b/src/ifs/wl_surface/xwayland_shell_v1.rs index a749d816..d865f174 100644 --- a/src/ifs/wl_surface/xwayland_shell_v1.rs +++ b/src/ifs/wl_surface/xwayland_shell_v1.rs @@ -5,7 +5,6 @@ use { ifs::wl_surface::{x_surface::xwayland_surface_v1::XwaylandSurfaceV1, WlSurfaceError}, leaks::Tracker, object::{Object, Version}, - utils::buffd::{MsgParser, MsgParserError}, wire::{xwayland_shell_v1::*, WlSurfaceId, XwaylandShellV1Id}, }, std::rc::Rc, @@ -45,15 +44,19 @@ impl XwaylandShellV1Global { Ok(()) } } -impl XwaylandShellV1 { - fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), XwaylandShellV1Error> { - let _req: Destroy = self.client.parse(self, parser)?; +impl XwaylandShellV1RequestHandler for XwaylandShellV1 { + type Error = XwaylandShellV1Error; + + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { self.client.remove_obj(self)?; Ok(()) } - fn get_xwayland_surface(&self, parser: MsgParser<'_, '_>) -> Result<(), XwaylandShellV1Error> { - let req: GetXwaylandSurface = self.client.parse(self, parser)?; + fn get_xwayland_surface( + &self, + req: GetXwaylandSurface, + _slf: &Rc, + ) -> Result<(), Self::Error> { let surface = self.client.lookup(req.surface)?; let xsurface = surface.get_xsurface()?; if xsurface.xwayland_surface.is_some() { @@ -64,6 +67,7 @@ impl XwaylandShellV1 { client: self.client.clone(), x: xsurface, tracker: Default::default(), + version: self.version, }); track!(self.client, xws); xws.x.xwayland_surface.set(Some(xws.clone())); @@ -92,9 +96,7 @@ simple_add_global!(XwaylandShellV1Global); object_base! { self = XwaylandShellV1; - - DESTROY => destroy, - GET_XWAYLAND_SURFACE => get_xwayland_surface, + version = self.version; } impl Object for XwaylandShellV1 {} @@ -105,12 +107,9 @@ simple_add_obj!(XwaylandShellV1); pub enum XwaylandShellV1Error { #[error(transparent)] ClientError(Box), - #[error("Parsing failed")] - MsgParserError(#[source] Box), #[error("The `wl_surface` {0} already has an extension object")] AlreadyAttached(WlSurfaceId), #[error(transparent)] WlSurfaceError(#[from] WlSurfaceError), } efrom!(XwaylandShellV1Error, ClientError); -efrom!(XwaylandShellV1Error, MsgParserError); diff --git a/src/ifs/wl_surface/zwlr_layer_surface_v1.rs b/src/ifs/wl_surface/zwlr_layer_surface_v1.rs index f70d0147..17d0aa4c 100644 --- a/src/ifs/wl_surface/zwlr_layer_surface_v1.rs +++ b/src/ifs/wl_surface/zwlr_layer_surface_v1.rs @@ -12,11 +12,7 @@ use { renderer::Renderer, tree::{FindTreeResult, FoundNode, Node, NodeId, NodeVisitor, OutputNode}, utils::{ - bitflags::BitflagsExt, - buffd::{MsgParser, MsgParserError}, - cell_ext::CellExt, - linkedlist::LinkedNode, - numcell::NumCell, + bitflags::BitflagsExt, cell_ext::CellExt, linkedlist::LinkedNode, numcell::NumCell, option_ext::OptionExt, }, wire::{zwlr_layer_surface_v1::*, WlSurfaceId, ZwlrLayerSurfaceV1Id}, @@ -157,9 +153,12 @@ impl ZwlrLayerSurfaceV1 { m.layer_surface.get_or_insert_default_ext() }) } +} + +impl ZwlrLayerSurfaceV1RequestHandler for ZwlrLayerSurfaceV1 { + type Error = ZwlrLayerSurfaceV1Error; - fn set_size(&self, parser: MsgParser<'_, '_>) -> Result<(), ZwlrLayerSurfaceV1Error> { - let req: SetSize = self.client.parse(self, parser)?; + fn set_size(&self, req: SetSize, _slf: &Rc) -> Result<(), Self::Error> { if req.width > u16::MAX as u32 || req.height > u16::MAX as u32 { return Err(ZwlrLayerSurfaceV1Error::ExcessiveSize); } @@ -169,8 +168,7 @@ impl ZwlrLayerSurfaceV1 { Ok(()) } - fn set_anchor(&self, parser: MsgParser<'_, '_>) -> Result<(), ZwlrLayerSurfaceV1Error> { - let req: SetAnchor = self.client.parse(self, parser)?; + fn set_anchor(&self, req: SetAnchor, _slf: &Rc) -> Result<(), Self::Error> { if req.anchor & !(LEFT | RIGHT | TOP | BOTTOM) != 0 { return Err(ZwlrLayerSurfaceV1Error::UnknownAnchor(req.anchor)); } @@ -180,16 +178,18 @@ impl ZwlrLayerSurfaceV1 { Ok(()) } - fn set_exclusive_zone(&self, parser: MsgParser<'_, '_>) -> Result<(), ZwlrLayerSurfaceV1Error> { - let req: SetExclusiveZone = self.client.parse(self, parser)?; + fn set_exclusive_zone( + &self, + req: SetExclusiveZone, + _slf: &Rc, + ) -> Result<(), Self::Error> { let mut pending = self.pending(); pending.exclusive_zone = Some(req.zone); pending.any = true; Ok(()) } - fn set_margin(&self, parser: MsgParser<'_, '_>) -> Result<(), ZwlrLayerSurfaceV1Error> { - let req: SetMargin = self.client.parse(self, parser)?; + fn set_margin(&self, req: SetMargin, _slf: &Rc) -> Result<(), Self::Error> { let mut pending = self.pending(); pending.margin = Some((req.top, req.right, req.bottom, req.left)); pending.any = true; @@ -198,9 +198,9 @@ impl ZwlrLayerSurfaceV1 { fn set_keyboard_interactivity( &self, - parser: MsgParser<'_, '_>, - ) -> Result<(), ZwlrLayerSurfaceV1Error> { - let req: SetKeyboardInteractivity = self.client.parse(self, parser)?; + req: SetKeyboardInteractivity, + _slf: &Rc, + ) -> Result<(), Self::Error> { if req.keyboard_interactivity > KI_ON_DEMAND { return Err(ZwlrLayerSurfaceV1Error::UnknownKi( req.keyboard_interactivity, @@ -212,27 +212,23 @@ impl ZwlrLayerSurfaceV1 { Ok(()) } - fn get_popup(&self, parser: MsgParser<'_, '_>) -> Result<(), ZwlrLayerSurfaceV1Error> { - let _req: GetPopup = self.client.parse(self, parser)?; + fn get_popup(&self, _req: GetPopup, _slf: &Rc) -> Result<(), Self::Error> { Ok(()) } - fn ack_configure(&self, parser: MsgParser<'_, '_>) -> Result<(), ZwlrLayerSurfaceV1Error> { - let req: AckConfigure = self.client.parse(self, parser)?; + fn ack_configure(&self, req: AckConfigure, _slf: &Rc) -> Result<(), Self::Error> { self.acked_serial.set(Some(req.serial)); Ok(()) } - fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), ZwlrLayerSurfaceV1Error> { - let _req: Destroy = self.client.parse(self, parser)?; + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { self.destroy_node(); self.client.remove_obj(self)?; self.surface.unset_ext(); Ok(()) } - fn set_layer(&self, parser: MsgParser<'_, '_>) -> Result<(), ZwlrLayerSurfaceV1Error> { - let req: SetLayer = self.client.parse(self, parser)?; + fn set_layer(&self, req: SetLayer, _slf: &Rc) -> Result<(), Self::Error> { if req.layer > OVERLAY { return Err(ZwlrLayerSurfaceV1Error::UnknownLayer(req.layer)); } @@ -241,7 +237,9 @@ impl ZwlrLayerSurfaceV1 { pending.any = true; Ok(()) } +} +impl ZwlrLayerSurfaceV1 { fn pre_commit(&self, pending: &mut PendingState) -> Result<(), ZwlrLayerSurfaceV1Error> { let pending = pending.layer_surface.get_or_insert_default_ext(); let mut send_configure = mem::replace(&mut pending.any, false); @@ -437,16 +435,7 @@ impl Node for ZwlrLayerSurfaceV1 { object_base! { self = ZwlrLayerSurfaceV1; - - SET_SIZE => set_size, - SET_ANCHOR => set_anchor, - SET_EXCLUSIVE_ZONE => set_exclusive_zone, - SET_MARGIN => set_margin, - SET_KEYBOARD_INTERACTIVITY => set_keyboard_interactivity, - GET_POPUP => get_popup, - ACK_CONFIGURE => ack_configure, - DESTROY => destroy, - SET_LAYER => set_layer if self.shell.version >= 2, + version = self.shell.version; } impl Object for ZwlrLayerSurfaceV1 { @@ -468,8 +457,6 @@ pub enum ZwlrLayerSurfaceV1Error { HeightZero, #[error(transparent)] WlSurfaceError(Box), - #[error("Parsing failed")] - MsgParserError(#[source] Box), #[error(transparent)] ClientError(Box), #[error("Unknown layer {0}")] @@ -482,5 +469,4 @@ pub enum ZwlrLayerSurfaceV1Error { UnknownKi(u32), } efrom!(ZwlrLayerSurfaceV1Error, WlSurfaceError); -efrom!(ZwlrLayerSurfaceV1Error, MsgParserError); efrom!(ZwlrLayerSurfaceV1Error, ClientError); diff --git a/src/ifs/wl_surface/zwp_idle_inhibitor_v1.rs b/src/ifs/wl_surface/zwp_idle_inhibitor_v1.rs index 12f1f003..3bbc9fe1 100644 --- a/src/ifs/wl_surface/zwp_idle_inhibitor_v1.rs +++ b/src/ifs/wl_surface/zwp_idle_inhibitor_v1.rs @@ -3,8 +3,7 @@ use { client::{Client, ClientError}, ifs::wl_surface::WlSurface, leaks::Tracker, - object::Object, - utils::buffd::{MsgParser, MsgParserError}, + object::{Object, Version}, wire::{zwp_idle_inhibitor_v1::*, ZwpIdleInhibitorV1Id}, }, std::rc::Rc, @@ -19,18 +18,22 @@ pub struct ZwpIdleInhibitorV1 { pub client: Rc, pub surface: Rc, pub tracker: Tracker, + pub version: Version, } -impl ZwpIdleInhibitorV1 { - fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), ZwpIdleInhibitorV1Error> { - let _req: Destroy = self.client.parse(self, parser)?; +impl ZwpIdleInhibitorV1RequestHandler for ZwpIdleInhibitorV1 { + type Error = ZwpIdleInhibitorV1Error; + + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { self.client.remove_obj(self)?; if self.surface.idle_inhibitors.remove(&self.id).is_some() { self.deactivate(); } Ok(()) } +} +impl ZwpIdleInhibitorV1 { pub fn install(self: &Rc) -> Result<(), ZwpIdleInhibitorV1Error> { self.surface.idle_inhibitors.insert(self.id, self.clone()); if self.surface.visible.get() { @@ -50,8 +53,7 @@ impl ZwpIdleInhibitorV1 { object_base! { self = ZwpIdleInhibitorV1; - - DESTROY => destroy, + version = self.version; } impl Object for ZwpIdleInhibitorV1 { @@ -64,10 +66,7 @@ simple_add_obj!(ZwpIdleInhibitorV1); #[derive(Debug, Error)] pub enum ZwpIdleInhibitorV1Error { - #[error("Parsing failed")] - MsgParserError(#[source] Box), #[error(transparent)] ClientError(Box), } efrom!(ZwpIdleInhibitorV1Error, ClientError); -efrom!(ZwpIdleInhibitorV1Error, MsgParserError); diff --git a/src/ifs/wp_content_type_manager_v1.rs b/src/ifs/wp_content_type_manager_v1.rs index 54516b23..1ce0a538 100644 --- a/src/ifs/wp_content_type_manager_v1.rs +++ b/src/ifs/wp_content_type_manager_v1.rs @@ -5,7 +5,6 @@ use { ifs::wp_content_type_v1::WpContentTypeV1, leaks::Tracker, object::{Object, Version}, - utils::buffd::{MsgParser, MsgParserError}, wire::{wp_content_type_manager_v1::*, WpContentTypeManagerV1Id}, }, std::rc::Rc, @@ -64,18 +63,19 @@ pub struct WpContentTypeManagerV1 { pub version: Version, } -impl WpContentTypeManagerV1 { - fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), WpContentTypeManagerV1Error> { - let _req: Destroy = self.client.parse(self, parser)?; +impl WpContentTypeManagerV1RequestHandler for WpContentTypeManagerV1 { + type Error = WpContentTypeManagerV1Error; + + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { self.client.remove_obj(self)?; Ok(()) } fn get_surface_content_type( &self, - parser: MsgParser<'_, '_>, - ) -> Result<(), WpContentTypeManagerV1Error> { - let req: GetSurfaceContentType = self.client.parse(self, parser)?; + req: GetSurfaceContentType, + _slf: &Rc, + ) -> Result<(), Self::Error> { let surface = self.client.lookup(req.surface)?; if surface.has_content_type_manager.replace(true) { return Err(WpContentTypeManagerV1Error::DuplicateContentType); @@ -85,6 +85,7 @@ impl WpContentTypeManagerV1 { client: self.client.clone(), surface, tracker: Default::default(), + version: self.version, }); track!(self.client, device); self.client.add_client_obj(&device)?; @@ -94,9 +95,7 @@ impl WpContentTypeManagerV1 { object_base! { self = WpContentTypeManagerV1; - - DESTROY => destroy, - GET_SURFACE_CONTENT_TYPE => get_surface_content_type, + version = self.version; } impl Object for WpContentTypeManagerV1 {} @@ -107,10 +106,7 @@ simple_add_obj!(WpContentTypeManagerV1); pub enum WpContentTypeManagerV1Error { #[error(transparent)] ClientError(Box), - #[error("Parsing failed")] - MsgParserError(#[source] Box), #[error("Surface already has a content type object")] DuplicateContentType, } efrom!(WpContentTypeManagerV1Error, ClientError); -efrom!(WpContentTypeManagerV1Error, MsgParserError); diff --git a/src/ifs/wp_content_type_v1.rs b/src/ifs/wp_content_type_v1.rs index 2b2da660..f0821f9a 100644 --- a/src/ifs/wp_content_type_v1.rs +++ b/src/ifs/wp_content_type_v1.rs @@ -3,8 +3,7 @@ use { client::{Client, ClientError}, ifs::wl_surface::WlSurface, leaks::Tracker, - object::Object, - utils::buffd::{MsgParser, MsgParserError}, + object::{Object, Version}, wire::{wp_content_type_v1::*, WpContentTypeV1Id}, }, std::rc::Rc, @@ -28,18 +27,19 @@ pub struct WpContentTypeV1 { pub client: Rc, pub surface: Rc, pub tracker: Tracker, + pub version: Version, } -impl WpContentTypeV1 { - fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), WpContentTypeV1Error> { - let _req: Destroy = self.client.parse(self, parser)?; +impl WpContentTypeV1RequestHandler for WpContentTypeV1 { + type Error = WpContentTypeV1Error; + + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { self.surface.has_content_type_manager.set(false); self.client.remove_obj(self)?; Ok(()) } - fn set_content_type(&self, parser: MsgParser<'_, '_>) -> Result<(), WpContentTypeV1Error> { - let req: SetContentType = self.client.parse(self, parser)?; + fn set_content_type(&self, req: SetContentType, _slf: &Rc) -> Result<(), Self::Error> { if req.content_type == NONE { self.surface.set_content_type(None); return Ok(()); @@ -57,9 +57,7 @@ impl WpContentTypeV1 { object_base! { self = WpContentTypeV1; - - DESTROY => destroy, - SET_CONTENT_TYPE => set_content_type, + version = self.version; } impl Object for WpContentTypeV1 {} @@ -70,10 +68,7 @@ simple_add_obj!(WpContentTypeV1); pub enum WpContentTypeV1Error { #[error(transparent)] ClientError(Box), - #[error("Parsing failed")] - MsgParserError(#[source] Box), #[error("Content type {0} is unknown")] UnknownContentType(u32), } efrom!(WpContentTypeV1Error, ClientError); -efrom!(WpContentTypeV1Error, MsgParserError); diff --git a/src/ifs/wp_cursor_shape_device_v1.rs b/src/ifs/wp_cursor_shape_device_v1.rs index 84a2b480..ede3c710 100644 --- a/src/ifs/wp_cursor_shape_device_v1.rs +++ b/src/ifs/wp_cursor_shape_device_v1.rs @@ -4,8 +4,7 @@ use { cursor::KnownCursor, ifs::wl_seat::WlSeatGlobal, leaks::Tracker, - object::Object, - utils::buffd::{MsgParser, MsgParserError}, + object::{Object, Version}, wire::{wp_cursor_shape_device_v1::*, WpCursorShapeDeviceV1Id}, }, std::rc::Rc, @@ -52,17 +51,18 @@ pub struct WpCursorShapeDeviceV1 { pub client: Rc, pub seat: Rc, pub tracker: Tracker, + pub version: Version, } -impl WpCursorShapeDeviceV1 { - fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), WpCursorShapeDeviceV1Error> { - let _req: Destroy = self.client.parse(self, parser)?; +impl WpCursorShapeDeviceV1RequestHandler for WpCursorShapeDeviceV1 { + type Error = WpCursorShapeDeviceV1Error; + + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { self.client.remove_obj(self)?; Ok(()) } - fn set_shape(&self, parser: MsgParser<'_, '_>) -> Result<(), WpCursorShapeDeviceV1Error> { - let req: SetShape = self.client.parse(self, parser)?; + fn set_shape(&self, req: SetShape, _slf: &Rc) -> Result<(), Self::Error> { let cursor = match req.shape { DEFAULT => KnownCursor::Default, CONTEXT_MENU => KnownCursor::ContextMenu, @@ -114,9 +114,7 @@ impl WpCursorShapeDeviceV1 { object_base! { self = WpCursorShapeDeviceV1; - - DESTROY => destroy, - SET_SHAPE => set_shape, + version = self.version; } impl Object for WpCursorShapeDeviceV1 {} @@ -127,10 +125,7 @@ simple_add_obj!(WpCursorShapeDeviceV1); pub enum WpCursorShapeDeviceV1Error { #[error(transparent)] ClientError(Box), - #[error("Parsing failed")] - MsgParserError(#[source] Box), #[error("Shape {0} is unknown")] UnknownShape(u32), } efrom!(WpCursorShapeDeviceV1Error, ClientError); -efrom!(WpCursorShapeDeviceV1Error, MsgParserError); diff --git a/src/ifs/wp_cursor_shape_manager_v1.rs b/src/ifs/wp_cursor_shape_manager_v1.rs index 4a0d9be1..301a939b 100644 --- a/src/ifs/wp_cursor_shape_manager_v1.rs +++ b/src/ifs/wp_cursor_shape_manager_v1.rs @@ -5,7 +5,6 @@ use { ifs::wp_cursor_shape_device_v1::WpCursorShapeDeviceV1, leaks::Tracker, object::{Object, Version}, - utils::buffd::{MsgParser, MsgParserError}, wire::{wp_cursor_shape_manager_v1::*, WpCursorShapeManagerV1Id}, }, std::rc::Rc, @@ -64,21 +63,22 @@ pub struct WpCursorShapeManagerV1 { pub version: Version, } -impl WpCursorShapeManagerV1 { - fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), WpCursorShapeManagerV1Error> { - let _req: Destroy = self.client.parse(self, parser)?; +impl WpCursorShapeManagerV1RequestHandler for WpCursorShapeManagerV1 { + type Error = WpCursorShapeManagerV1Error; + + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { self.client.remove_obj(self)?; Ok(()) } - fn get_pointer(&self, parser: MsgParser<'_, '_>) -> Result<(), WpCursorShapeManagerV1Error> { - let req: GetPointer = self.client.parse(self, parser)?; + fn get_pointer(&self, req: GetPointer, _slf: &Rc) -> Result<(), Self::Error> { let pointer = self.client.lookup(req.pointer)?; let device = Rc::new(WpCursorShapeDeviceV1 { id: req.cursor_shape_device, client: self.client.clone(), seat: pointer.seat.global.clone(), tracker: Default::default(), + version: self.version, }); track!(self.client, device); self.client.add_client_obj(&device)?; @@ -87,19 +87,16 @@ impl WpCursorShapeManagerV1 { fn get_tablet_tool_v2( &self, - parser: MsgParser<'_, '_>, - ) -> Result<(), WpCursorShapeManagerV1Error> { - let _req: GetTabletToolV2 = self.client.parse(self, parser)?; + _req: GetTabletToolV2, + _slf: &Rc, + ) -> Result<(), Self::Error> { Err(WpCursorShapeManagerV1Error::TabletToolNotSupported) } } object_base! { self = WpCursorShapeManagerV1; - - DESTROY => destroy, - GET_POINTER => get_pointer, - GET_TABLET_TOOL_V2 => get_tablet_tool_v2, + version = self.version; } impl Object for WpCursorShapeManagerV1 {} @@ -110,10 +107,7 @@ simple_add_obj!(WpCursorShapeManagerV1); pub enum WpCursorShapeManagerV1Error { #[error(transparent)] ClientError(Box), - #[error("Parsing failed")] - MsgParserError(#[source] Box), #[error("This compositor does not support tablet tools")] TabletToolNotSupported, } efrom!(WpCursorShapeManagerV1Error, ClientError); -efrom!(WpCursorShapeManagerV1Error, MsgParserError); diff --git a/src/ifs/wp_fractional_scale_manager_v1.rs b/src/ifs/wp_fractional_scale_manager_v1.rs index f8a533d9..22a4672f 100644 --- a/src/ifs/wp_fractional_scale_manager_v1.rs +++ b/src/ifs/wp_fractional_scale_manager_v1.rs @@ -5,7 +5,6 @@ use { ifs::wl_surface::wp_fractional_scale_v1::{WpFractionalScaleError, WpFractionalScaleV1}, leaks::Tracker, object::{Object, Version}, - utils::buffd::{MsgParser, MsgParserError}, wire::{wp_fractional_scale_manager_v1::*, WpFractionalScaleManagerV1Id}, }, std::rc::Rc, @@ -20,6 +19,7 @@ pub struct WpFractionalScaleManagerV1 { pub id: WpFractionalScaleManagerV1Id, pub client: Rc, pub tracker: Tracker, + pub version: Version, } impl WpFractionalScaleManagerV1Global { @@ -31,12 +31,13 @@ impl WpFractionalScaleManagerV1Global { self: Rc, id: WpFractionalScaleManagerV1Id, client: &Rc, - _version: Version, + version: Version, ) -> Result<(), WpFractionalScaleManagerError> { let obj = Rc::new(WpFractionalScaleManagerV1 { id, client: client.clone(), tracker: Default::default(), + version, }); track!(client, obj); client.add_client_obj(&obj)?; @@ -62,20 +63,21 @@ impl Global for WpFractionalScaleManagerV1Global { simple_add_global!(WpFractionalScaleManagerV1Global); -impl WpFractionalScaleManagerV1 { - fn destroy(&self, msg: MsgParser<'_, '_>) -> Result<(), WpFractionalScaleManagerError> { - let _req: Destroy = self.client.parse(self, msg)?; +impl WpFractionalScaleManagerV1RequestHandler for WpFractionalScaleManagerV1 { + type Error = WpFractionalScaleManagerError; + + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { self.client.remove_obj(self)?; Ok(()) } fn get_fractional_scale( &self, - msg: MsgParser<'_, '_>, - ) -> Result<(), WpFractionalScaleManagerError> { - let req: GetFractionalScale = self.client.parse(self, msg)?; + req: GetFractionalScale, + _slf: &Rc, + ) -> Result<(), Self::Error> { let surface = self.client.lookup(req.surface)?; - let fs = Rc::new(WpFractionalScaleV1::new(req.id, &surface)); + let fs = Rc::new(WpFractionalScaleV1::new(req.id, &surface, self.version)); track!(self.client, fs); fs.install()?; self.client.add_client_obj(&fs)?; @@ -86,9 +88,7 @@ impl WpFractionalScaleManagerV1 { object_base! { self = WpFractionalScaleManagerV1; - - DESTROY => destroy, - GET_FRACTIONAL_SCALE => get_fractional_scale, + version = self.version; } impl Object for WpFractionalScaleManagerV1 {} @@ -97,12 +97,9 @@ simple_add_obj!(WpFractionalScaleManagerV1); #[derive(Debug, Error)] pub enum WpFractionalScaleManagerError { - #[error("Parsing failed")] - MsgParserError(#[source] Box), #[error(transparent)] ClientError(Box), #[error(transparent)] WpFractionalScaleError(#[from] WpFractionalScaleError), } -efrom!(WpFractionalScaleManagerError, MsgParserError); efrom!(WpFractionalScaleManagerError, ClientError); diff --git a/src/ifs/wp_linux_drm_syncobj_manager_v1.rs b/src/ifs/wp_linux_drm_syncobj_manager_v1.rs index 9a40dce2..5b08571f 100644 --- a/src/ifs/wp_linux_drm_syncobj_manager_v1.rs +++ b/src/ifs/wp_linux_drm_syncobj_manager_v1.rs @@ -10,7 +10,6 @@ use { }, leaks::Tracker, object::{Object, Version}, - utils::buffd::{MsgParser, MsgParserError}, video::drm::sync_obj::SyncObj, wire::{wp_linux_drm_syncobj_manager_v1::*, WpLinuxDrmSyncobjManagerV1Id}, }, @@ -26,6 +25,7 @@ pub struct WpLinuxDrmSyncobjManagerV1 { pub id: WpLinuxDrmSyncobjManagerV1Id, pub client: Rc, pub tracker: Tracker, + pub version: Version, } impl WpLinuxDrmSyncobjManagerV1Global { @@ -37,12 +37,13 @@ impl WpLinuxDrmSyncobjManagerV1Global { self: Rc, id: WpLinuxDrmSyncobjManagerV1Id, client: &Rc, - _version: Version, + version: Version, ) -> Result<(), WpLinuxDrmSyncobjManagerV1Error> { let obj = Rc::new(WpLinuxDrmSyncobjManagerV1 { id, client: client.clone(), tracker: Default::default(), + version, }); track!(client, obj); client.add_client_obj(&obj)?; @@ -68,20 +69,21 @@ impl Global for WpLinuxDrmSyncobjManagerV1Global { simple_add_global!(WpLinuxDrmSyncobjManagerV1Global); -impl WpLinuxDrmSyncobjManagerV1 { - fn destroy(&self, msg: MsgParser<'_, '_>) -> Result<(), WpLinuxDrmSyncobjManagerV1Error> { - let _req: Destroy = self.client.parse(self, msg)?; +impl WpLinuxDrmSyncobjManagerV1RequestHandler for WpLinuxDrmSyncobjManagerV1 { + type Error = WpLinuxDrmSyncobjManagerV1Error; + + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { self.client.remove_obj(self)?; Ok(()) } - fn get_surface(&self, msg: MsgParser<'_, '_>) -> Result<(), WpLinuxDrmSyncobjManagerV1Error> { - let req: GetSurface = self.client.parse(self, msg)?; + fn get_surface(&self, req: GetSurface, _slf: &Rc) -> Result<(), Self::Error> { let surface = self.client.lookup(req.surface)?; let sync = Rc::new(WpLinuxDrmSyncobjSurfaceV1::new( req.id, &self.client, &surface, + self.version, )); track!(self.client, sync); sync.install()?; @@ -89,16 +91,13 @@ impl WpLinuxDrmSyncobjManagerV1 { Ok(()) } - fn import_timeline( - &self, - msg: MsgParser<'_, '_>, - ) -> Result<(), WpLinuxDrmSyncobjManagerV1Error> { - let req: ImportTimeline = self.client.parse(self, msg)?; + fn import_timeline(&self, req: ImportTimeline, _slf: &Rc) -> Result<(), Self::Error> { let sync_obj = Rc::new(SyncObj::new(&req.fd)); let sync = Rc::new(WpLinuxDrmSyncobjTimelineV1::new( req.id, &self.client, &sync_obj, + self.version, )); self.client.add_client_obj(&sync)?; Ok(()) @@ -107,10 +106,7 @@ impl WpLinuxDrmSyncobjManagerV1 { object_base! { self = WpLinuxDrmSyncobjManagerV1; - - DESTROY => destroy, - GET_SURFACE => get_surface, - IMPORT_TIMELINE => import_timeline, + version = self.version; } impl Object for WpLinuxDrmSyncobjManagerV1 {} @@ -119,12 +115,9 @@ simple_add_obj!(WpLinuxDrmSyncobjManagerV1); #[derive(Debug, Error)] pub enum WpLinuxDrmSyncobjManagerV1Error { - #[error("Parsing failed")] - MsgParserError(#[source] Box), #[error(transparent)] ClientError(Box), #[error(transparent)] WpLinuxDrmSyncobjSurfaceV1Error(#[from] WpLinuxDrmSyncobjSurfaceV1Error), } -efrom!(WpLinuxDrmSyncobjManagerV1Error, MsgParserError); efrom!(WpLinuxDrmSyncobjManagerV1Error, ClientError); diff --git a/src/ifs/wp_linux_drm_syncobj_timeline_v1.rs b/src/ifs/wp_linux_drm_syncobj_timeline_v1.rs index e97e68e9..d3f35765 100644 --- a/src/ifs/wp_linux_drm_syncobj_timeline_v1.rs +++ b/src/ifs/wp_linux_drm_syncobj_timeline_v1.rs @@ -2,8 +2,7 @@ use { crate::{ client::{Client, ClientError}, leaks::Tracker, - object::Object, - utils::buffd::{MsgParser, MsgParserError}, + object::{Object, Version}, video::drm::sync_obj::SyncObj, wire::{wp_linux_drm_syncobj_timeline_v1::*, WpLinuxDrmSyncobjTimelineV1Id}, }, @@ -16,6 +15,7 @@ pub struct WpLinuxDrmSyncobjTimelineV1 { client: Rc, pub sync_obj: Rc, pub tracker: Tracker, + version: Version, } impl WpLinuxDrmSyncobjTimelineV1 { @@ -23,17 +23,22 @@ impl WpLinuxDrmSyncobjTimelineV1 { id: WpLinuxDrmSyncobjTimelineV1Id, client: &Rc, sync_obj: &Rc, + version: Version, ) -> Self { Self { id, client: client.clone(), tracker: Default::default(), sync_obj: sync_obj.clone(), + version, } } +} + +impl WpLinuxDrmSyncobjTimelineV1RequestHandler for WpLinuxDrmSyncobjTimelineV1 { + type Error = WpLinuxDrmSyncobjTimelineV1Error; - fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), WpLinuxDrmSyncobjTimelineV1Error> { - let _destroy: Destroy = self.client.parse(self, parser)?; + fn destroy(&self, _destroy: Destroy, _slf: &Rc) -> Result<(), Self::Error> { self.client.remove_obj(self)?; Ok(()) } @@ -41,8 +46,7 @@ impl WpLinuxDrmSyncobjTimelineV1 { object_base! { self = WpLinuxDrmSyncobjTimelineV1; - - DESTROY => destroy, + version = self.version; } impl Object for WpLinuxDrmSyncobjTimelineV1 {} @@ -55,10 +59,7 @@ dedicated_add_obj!( #[derive(Debug, Error)] pub enum WpLinuxDrmSyncobjTimelineV1Error { - #[error("Parsing failed")] - MsgParserError(#[source] Box), #[error(transparent)] ClientError(Box), } -efrom!(WpLinuxDrmSyncobjTimelineV1Error, MsgParserError); efrom!(WpLinuxDrmSyncobjTimelineV1Error, ClientError); diff --git a/src/ifs/wp_presentation.rs b/src/ifs/wp_presentation.rs index 684bc018..5299b64e 100644 --- a/src/ifs/wp_presentation.rs +++ b/src/ifs/wp_presentation.rs @@ -6,7 +6,6 @@ use { ifs::wp_presentation_feedback::WpPresentationFeedback, leaks::Tracker, object::{Object, Version}, - utils::buffd::{MsgParser, MsgParserError}, }, std::rc::Rc, thiserror::Error, @@ -26,12 +25,13 @@ impl WpPresentationGlobal { self: Rc, id: WpPresentationId, client: &Rc, - _version: Version, + version: Version, ) -> Result<(), WpPresentationError> { let obj = Rc::new(WpPresentation { id, client: client.clone(), tracker: Default::default(), + version, }); track!(client, obj); client.add_client_obj(&obj)?; @@ -58,6 +58,7 @@ pub struct WpPresentation { pub id: WpPresentationId, pub client: Rc, pub tracker: Tracker, + pub version: Version, } impl WpPresentation { @@ -67,21 +68,24 @@ impl WpPresentation { clk_id: c::CLOCK_MONOTONIC as _, }); } +} + +impl WpPresentationRequestHandler for WpPresentation { + type Error = WpPresentationError; - pub fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), WpPresentationError> { - let _req: Destroy = self.client.parse(self, parser)?; + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { self.client.remove_obj(self)?; Ok(()) } - pub fn feedback(&self, parser: MsgParser<'_, '_>) -> Result<(), WpPresentationError> { - let req: Feedback = self.client.parse(self, parser)?; + fn feedback(&self, req: Feedback, _slf: &Rc) -> Result<(), Self::Error> { let surface = self.client.lookup(req.surface)?; let fb = Rc::new(WpPresentationFeedback { id: req.callback, client: self.client.clone(), surface: surface.clone(), tracker: Default::default(), + version: self.version, }); track!(self.client, fb); self.client.add_client_obj(&fb)?; @@ -92,9 +96,7 @@ impl WpPresentation { object_base! { self = WpPresentation; - - DESTROY => destroy, - FEEDBACK => feedback, + version = self.version; } impl Object for WpPresentation {} @@ -103,10 +105,7 @@ simple_add_obj!(WpPresentation); #[derive(Debug, Error)] pub enum WpPresentationError { - #[error("Parsing failed")] - MsgParserError(#[source] Box), #[error(transparent)] ClientError(Box), } -efrom!(WpPresentationError, MsgParserError); efrom!(WpPresentationError, ClientError); diff --git a/src/ifs/wp_presentation_feedback.rs b/src/ifs/wp_presentation_feedback.rs index a1bc3438..8b1682bb 100644 --- a/src/ifs/wp_presentation_feedback.rs +++ b/src/ifs/wp_presentation_feedback.rs @@ -3,10 +3,10 @@ use { client::Client, ifs::{wl_output::WlOutput, wl_surface::WlSurface}, leaks::Tracker, - object::Object, + object::{Object, Version}, wire::{wp_presentation_feedback::*, WpPresentationFeedbackId}, }, - std::rc::Rc, + std::{convert::Infallible, rc::Rc}, thiserror::Error, }; @@ -15,6 +15,7 @@ pub struct WpPresentationFeedback { pub client: Rc, pub surface: Rc, pub tracker: Tracker, + pub version: Version, } pub const KIND_VSYNC: u32 = 0x1; @@ -50,8 +51,13 @@ impl WpPresentationFeedback { } } +impl WpPresentationFeedbackRequestHandler for WpPresentationFeedback { + type Error = Infallible; +} + object_base! { self = WpPresentationFeedback; + version = self.version; } impl Object for WpPresentationFeedback {} diff --git a/src/ifs/wp_single_pixel_buffer_manager_v1.rs b/src/ifs/wp_single_pixel_buffer_manager_v1.rs index 38827bc1..6a3ba876 100644 --- a/src/ifs/wp_single_pixel_buffer_manager_v1.rs +++ b/src/ifs/wp_single_pixel_buffer_manager_v1.rs @@ -5,7 +5,6 @@ use { ifs::wl_buffer::WlBuffer, leaks::Tracker, object::{Object, Version}, - utils::buffd::{MsgParser, MsgParserError}, wire::{wp_single_pixel_buffer_manager_v1::*, WpSinglePixelBufferManagerV1Id}, }, std::rc::Rc, @@ -25,12 +24,13 @@ impl WpSinglePixelBufferManagerV1Global { self: Rc, id: WpSinglePixelBufferManagerV1Id, client: &Rc, - _version: Version, + version: Version, ) -> Result<(), WpSinglePixelBufferManagerV1Error> { let obj = Rc::new(WpSinglePixelBufferManagerV1 { id, client: client.clone(), tracker: Default::default(), + version, }); track!(client, obj); client.add_client_obj(&obj)?; @@ -60,23 +60,22 @@ pub struct WpSinglePixelBufferManagerV1 { pub id: WpSinglePixelBufferManagerV1Id, pub client: Rc, pub tracker: Tracker, + pub version: Version, } -impl WpSinglePixelBufferManagerV1 { - pub fn destroy( - &self, - parser: MsgParser<'_, '_>, - ) -> Result<(), WpSinglePixelBufferManagerV1Error> { - let _req: Destroy = self.client.parse(self, parser)?; +impl WpSinglePixelBufferManagerV1RequestHandler for WpSinglePixelBufferManagerV1 { + type Error = WpSinglePixelBufferManagerV1Error; + + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { self.client.remove_obj(self)?; Ok(()) } - pub fn create_u32_rgba_buffer( + fn create_u32_rgba_buffer( &self, - parser: MsgParser<'_, '_>, - ) -> Result<(), WpSinglePixelBufferManagerV1Error> { - let req: CreateU32RgbaBuffer = self.client.parse(self, parser)?; + req: CreateU32RgbaBuffer, + _slf: &Rc, + ) -> Result<(), Self::Error> { let buffer = Rc::new(WlBuffer::new_single_pixel( req.id, &self.client, @@ -93,9 +92,7 @@ impl WpSinglePixelBufferManagerV1 { object_base! { self = WpSinglePixelBufferManagerV1; - - DESTROY => destroy, - CREATE_U32_RGBA_BUFFER => create_u32_rgba_buffer, + version = self.version; } impl Object for WpSinglePixelBufferManagerV1 {} @@ -104,10 +101,7 @@ simple_add_obj!(WpSinglePixelBufferManagerV1); #[derive(Debug, Error)] pub enum WpSinglePixelBufferManagerV1Error { - #[error("Parsing failed")] - MsgParserError(#[source] Box), #[error(transparent)] ClientError(Box), } efrom!(WpSinglePixelBufferManagerV1Error, ClientError); -efrom!(WpSinglePixelBufferManagerV1Error, MsgParserError); diff --git a/src/ifs/wp_tearing_control_manager_v1.rs b/src/ifs/wp_tearing_control_manager_v1.rs index 4ea50aac..f66263a4 100644 --- a/src/ifs/wp_tearing_control_manager_v1.rs +++ b/src/ifs/wp_tearing_control_manager_v1.rs @@ -5,11 +5,7 @@ use { ifs::wl_surface::wp_tearing_control_v1::{WpTearingControlV1, WpTearingControlV1Error}, leaks::Tracker, object::{Object, Version}, - utils::buffd::{MsgParser, MsgParserError}, - wire::{ - wp_tearing_control_manager_v1::{GET_TEARING_CONTROL, *}, - WpTearingControlManagerV1Id, - }, + wire::{wp_tearing_control_manager_v1::*, WpTearingControlManagerV1Id}, }, std::rc::Rc, thiserror::Error, @@ -28,12 +24,13 @@ impl WpTearingControlManagerV1Global { self: Rc, id: WpTearingControlManagerV1Id, client: &Rc, - _version: Version, + version: Version, ) -> Result<(), WpTearingControlManagerV1Error> { let obj = Rc::new(WpTearingControlManagerV1 { id, client: client.clone(), tracker: Default::default(), + version, }); track!(client, obj); client.add_client_obj(&obj)?; @@ -63,25 +60,33 @@ pub struct WpTearingControlManagerV1 { pub id: WpTearingControlManagerV1Id, pub client: Rc, pub tracker: Tracker, + pub version: Version, } -impl WpTearingControlManagerV1 { - pub fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), WpTearingControlManagerV1Error> { - let _req: Destroy = self.client.parse(self, parser)?; +object_base! { + self = WpTearingControlManagerV1; + version = self.version; +} + +impl WpTearingControlManagerV1RequestHandler for WpTearingControlManagerV1 { + type Error = WpTearingControlManagerV1Error; + + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { self.client.remove_obj(self)?; Ok(()) } - pub fn get_tearing_control( + fn get_tearing_control( &self, - parser: MsgParser<'_, '_>, - ) -> Result<(), WpTearingControlManagerV1Error> { - let req: GetTearingControl = self.client.parse(self, parser)?; + req: GetTearingControl, + _slf: &Rc, + ) -> Result<(), Self::Error> { let surface = self.client.lookup(req.surface)?; let control = Rc::new(WpTearingControlV1 { id: req.id, surface, tracker: Default::default(), + version: self.version, }); track!(self.client, control); self.client.add_client_obj(&control)?; @@ -90,25 +95,15 @@ impl WpTearingControlManagerV1 { } } -object_base! { - self = WpTearingControlManagerV1; - - DESTROY => destroy, - GET_TEARING_CONTROL => get_tearing_control, -} - impl Object for WpTearingControlManagerV1 {} simple_add_obj!(WpTearingControlManagerV1); #[derive(Debug, Error)] pub enum WpTearingControlManagerV1Error { - #[error("Parsing failed")] - MsgParserError(#[source] Box), #[error(transparent)] ClientError(Box), #[error(transparent)] WpTearingControlV1Error(#[from] WpTearingControlV1Error), } efrom!(WpTearingControlManagerV1Error, ClientError); -efrom!(WpTearingControlManagerV1Error, MsgParserError); diff --git a/src/ifs/wp_viewporter.rs b/src/ifs/wp_viewporter.rs index f919999b..14eb34ac 100644 --- a/src/ifs/wp_viewporter.rs +++ b/src/ifs/wp_viewporter.rs @@ -5,7 +5,6 @@ use { ifs::wl_surface::wp_viewport::{WpViewport, WpViewportError}, leaks::Tracker, object::{Object, Version}, - utils::buffd::{MsgParser, MsgParserError}, wire::{wp_viewporter::*, WpViewporterId}, }, std::rc::Rc, @@ -25,12 +24,13 @@ impl WpViewporterGlobal { self: Rc, id: WpViewporterId, client: &Rc, - _version: Version, + version: Version, ) -> Result<(), WpViewporterError> { let obj = Rc::new(WpViewporter { id, client: client.clone(), tracker: Default::default(), + version, }); track!(client, obj); client.add_client_obj(&obj)?; @@ -56,19 +56,20 @@ pub struct WpViewporter { pub id: WpViewporterId, pub client: Rc, pub tracker: Tracker, + pub version: Version, } -impl WpViewporter { - fn destroy(&self, msg: MsgParser<'_, '_>) -> Result<(), WpViewporterError> { - let _req: Destroy = self.client.parse(self, msg)?; +impl WpViewporterRequestHandler for WpViewporter { + type Error = WpViewporterError; + + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { self.client.remove_obj(self)?; Ok(()) } - fn get_viewport(&self, msg: MsgParser<'_, '_>) -> Result<(), WpViewporterError> { - let req: GetViewport = self.client.parse(self, msg)?; + fn get_viewport(&self, req: GetViewport, _slf: &Rc) -> Result<(), Self::Error> { let surface = self.client.lookup(req.surface)?; - let viewport = Rc::new(WpViewport::new(req.id, &surface)); + let viewport = Rc::new(WpViewport::new(req.id, &surface, self.version)); track!(self.client, viewport); viewport.install()?; self.client.add_client_obj(&viewport)?; @@ -78,9 +79,7 @@ impl WpViewporter { object_base! { self = WpViewporter; - - DESTROY => destroy, - GET_VIEWPORT => get_viewport, + version = self.version; } impl Object for WpViewporter {} @@ -89,12 +88,9 @@ simple_add_obj!(WpViewporter); #[derive(Debug, Error)] pub enum WpViewporterError { - #[error("Parsing failed")] - MsgParserError(#[source] Box), #[error(transparent)] ClientError(Box), #[error(transparent)] WpViewportError(#[from] WpViewportError), } -efrom!(WpViewporterError, MsgParserError); efrom!(WpViewporterError, ClientError); diff --git a/src/ifs/xdg_activation_token_v1.rs b/src/ifs/xdg_activation_token_v1.rs index d9b7e152..c4ac48fc 100644 --- a/src/ifs/xdg_activation_token_v1.rs +++ b/src/ifs/xdg_activation_token_v1.rs @@ -2,11 +2,8 @@ use { crate::{ client::{Client, ClientError}, leaks::Tracker, - object::Object, - utils::{ - activation_token::{activation_token, ActivationToken}, - buffd::{MsgParser, MsgParserError}, - }, + object::{Object, Version}, + utils::activation_token::{activation_token, ActivationToken}, wire::{xdg_activation_token_v1::*, XdgActivationTokenV1Id}, }, std::{cell::Cell, rc::Rc}, @@ -20,36 +17,38 @@ pub struct XdgActivationTokenV1 { pub client: Rc, pub tracker: Tracker, already_used: Cell, + version: Version, } impl XdgActivationTokenV1 { - pub fn new(id: XdgActivationTokenV1Id, client: &Rc) -> Self { + pub fn new(id: XdgActivationTokenV1Id, client: &Rc, version: Version) -> Self { Self { id, client: client.clone(), tracker: Default::default(), already_used: Cell::new(false), + version, } } +} + +impl XdgActivationTokenV1RequestHandler for XdgActivationTokenV1 { + type Error = XdgActivationTokenV1Error; - fn set_serial(&self, parser: MsgParser<'_, '_>) -> Result<(), XdgActivationTokenV1Error> { - let _req: SetSerial = self.client.parse(self, parser)?; + fn set_serial(&self, _req: SetSerial, _slf: &Rc) -> Result<(), Self::Error> { Ok(()) } - fn set_app_id(&self, parser: MsgParser<'_, '_>) -> Result<(), XdgActivationTokenV1Error> { - let _req: SetAppId = self.client.parse(self, parser)?; + fn set_app_id(&self, _req: SetAppId, _slf: &Rc) -> Result<(), Self::Error> { Ok(()) } - fn set_surface(&self, parser: MsgParser<'_, '_>) -> Result<(), XdgActivationTokenV1Error> { - let req: SetSurface = self.client.parse(self, parser)?; + fn set_surface(&self, req: SetSurface, _slf: &Rc) -> Result<(), Self::Error> { self.client.lookup(req.surface)?; Ok(()) } - fn commit(&self, parser: MsgParser<'_, '_>) -> Result<(), XdgActivationTokenV1Error> { - let _req: Commit = self.client.parse(self, parser)?; + fn commit(&self, _req: Commit, _slf: &Rc) -> Result<(), Self::Error> { if self.already_used.replace(true) { return Err(XdgActivationTokenV1Error::AlreadyUsed); } @@ -66,12 +65,13 @@ impl XdgActivationTokenV1 { Ok(()) } - fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), XdgActivationTokenV1Error> { - let _req: Destroy = self.client.parse(self, parser)?; + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { self.client.remove_obj(self)?; Ok(()) } +} +impl XdgActivationTokenV1 { fn send_done(&self, token: ActivationToken) { let token = token.to_string(); self.client.event(Done { @@ -83,12 +83,7 @@ impl XdgActivationTokenV1 { object_base! { self = XdgActivationTokenV1; - - SET_SERIAL => set_serial, - SET_APP_ID => set_app_id, - SET_SURFACE => set_surface, - COMMIT => commit, - DESTROY => destroy, + version = self.version; } impl Object for XdgActivationTokenV1 {} @@ -99,10 +94,7 @@ simple_add_obj!(XdgActivationTokenV1); pub enum XdgActivationTokenV1Error { #[error(transparent)] ClientError(Box), - #[error("Parsing failed")] - MsgParserError(#[source] Box), #[error("The activation token has already been used")] AlreadyUsed, } efrom!(XdgActivationTokenV1Error, ClientError); -efrom!(XdgActivationTokenV1Error, MsgParserError); diff --git a/src/ifs/xdg_activation_v1.rs b/src/ifs/xdg_activation_v1.rs index 78b44f1c..184cf76d 100644 --- a/src/ifs/xdg_activation_v1.rs +++ b/src/ifs/xdg_activation_v1.rs @@ -5,11 +5,7 @@ use { ifs::xdg_activation_token_v1::XdgActivationTokenV1, leaks::Tracker, object::{Object, Version}, - utils::{ - activation_token::ActivationToken, - buffd::{MsgParser, MsgParserError}, - opaque::OpaqueError, - }, + utils::{activation_token::ActivationToken, opaque::OpaqueError}, wire::{xdg_activation_v1::*, XdgActivationV1Id}, }, std::rc::Rc, @@ -64,23 +60,30 @@ pub struct XdgActivationV1 { pub version: Version, } -impl XdgActivationV1 { - fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), XdgActivationV1Error> { - let _req: Destroy = self.client.parse(self, parser)?; +impl XdgActivationV1RequestHandler for XdgActivationV1 { + type Error = XdgActivationV1Error; + + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { self.client.remove_obj(self)?; Ok(()) } - fn get_activation_token(&self, parser: MsgParser<'_, '_>) -> Result<(), XdgActivationV1Error> { - let req: GetActivationToken = self.client.parse(self, parser)?; - let token = Rc::new(XdgActivationTokenV1::new(req.id, &self.client)); + fn get_activation_token( + &self, + req: GetActivationToken, + _slf: &Rc, + ) -> Result<(), Self::Error> { + let token = Rc::new(XdgActivationTokenV1::new( + req.id, + &self.client, + self.version, + )); track!(self.client, token); self.client.add_client_obj(&token)?; Ok(()) } - fn activate(&self, parser: MsgParser<'_, '_>) -> Result<(), XdgActivationV1Error> { - let req: Activate = self.client.parse(self, parser)?; + fn activate(&self, req: Activate, _slf: &Rc) -> Result<(), Self::Error> { let token: ActivationToken = req.token.parse()?; let surface = self.client.lookup(req.surface)?; if self.client.state.activation_tokens.remove(&token).is_none() { @@ -97,10 +100,7 @@ impl XdgActivationV1 { object_base! { self = XdgActivationV1; - - DESTROY => destroy, - GET_ACTIVATION_TOKEN => get_activation_token, - ACTIVATE => activate, + version = self.version; } impl Object for XdgActivationV1 {} @@ -111,10 +111,7 @@ simple_add_obj!(XdgActivationV1); pub enum XdgActivationV1Error { #[error(transparent)] ClientError(Box), - #[error("Parsing failed")] - MsgParserError(#[source] Box), #[error("Could not parse the activation token")] ParseActivationToken(#[from] OpaqueError), } efrom!(XdgActivationV1Error, ClientError); -efrom!(XdgActivationV1Error, MsgParserError); diff --git a/src/ifs/xdg_positioner.rs b/src/ifs/xdg_positioner.rs index f2538d72..07a6d233 100644 --- a/src/ifs/xdg_positioner.rs +++ b/src/ifs/xdg_positioner.rs @@ -5,7 +5,6 @@ use { leaks::Tracker, object::Object, rect::Rect, - utils::buffd::{MsgParser, MsgParserError}, wire::{xdg_positioner::*, XdgPositionerId}, }, std::{cell::RefCell, rc::Rc}, @@ -151,15 +150,17 @@ impl XdgPositioner { pub fn value(&self) -> XdgPositioned { *self.position.borrow() } +} + +impl XdgPositionerRequestHandler for XdgPositioner { + type Error = XdgPositionerError; - fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), XdgPositionerError> { - let _req: Destroy = self.client.parse(self, parser)?; + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { self.client.remove_obj(self)?; Ok(()) } - fn set_size(&self, parser: MsgParser<'_, '_>) -> Result<(), XdgPositionerError> { - let req: SetSize = self.client.parse(self, parser)?; + fn set_size(&self, req: SetSize, _slf: &Rc) -> Result<(), Self::Error> { if req.width <= 0 || req.height <= 0 { self.client.protocol_error( self, @@ -174,8 +175,7 @@ impl XdgPositioner { Ok(()) } - fn set_anchor_rect(&self, parser: MsgParser<'_, '_>) -> Result<(), XdgPositionerError> { - let req: SetAnchorRect = self.client.parse(self, parser)?; + fn set_anchor_rect(&self, req: SetAnchorRect, _slf: &Rc) -> Result<(), Self::Error> { if req.width < 0 || req.height < 0 { self.client.protocol_error( self, @@ -189,8 +189,7 @@ impl XdgPositioner { Ok(()) } - fn set_anchor(&self, parser: MsgParser<'_, '_>) -> Result<(), XdgPositionerError> { - let req: SetAnchor = self.client.parse(self, parser)?; + fn set_anchor(&self, req: SetAnchor, _slf: &Rc) -> Result<(), Self::Error> { let anchor = match Edge::from_enum(req.anchor) { Some(a) => a, _ => return Err(XdgPositionerError::UnknownAnchor(req.anchor)), @@ -199,8 +198,7 @@ impl XdgPositioner { Ok(()) } - fn set_gravity(&self, parser: MsgParser<'_, '_>) -> Result<(), XdgPositionerError> { - let req: SetGravity = self.client.parse(self, parser)?; + fn set_gravity(&self, req: SetGravity, _slf: &Rc) -> Result<(), Self::Error> { let gravity = match Edge::from_enum(req.gravity) { Some(a) => a, _ => return Err(XdgPositionerError::UnknownGravity(req.gravity)), @@ -211,9 +209,9 @@ impl XdgPositioner { fn set_constraint_adjustment( &self, - parser: MsgParser<'_, '_>, - ) -> Result<(), XdgPositionerError> { - let req: SetConstraintAdjustment = self.client.parse(self, parser)?; + req: SetConstraintAdjustment, + _slf: &Rc, + ) -> Result<(), Self::Error> { let ca = CA(req.constraint_adjustment); if !ca.is_valid() { return Err(XdgPositionerError::UnknownCa(req.constraint_adjustment)); @@ -222,22 +220,19 @@ impl XdgPositioner { Ok(()) } - fn set_offset(&self, parser: MsgParser<'_, '_>) -> Result<(), XdgPositionerError> { - let req: SetOffset = self.client.parse(self, parser)?; + fn set_offset(&self, req: SetOffset, _slf: &Rc) -> Result<(), Self::Error> { let mut position = self.position.borrow_mut(); position.off_x = req.x; position.off_y = req.y; Ok(()) } - fn set_reactive(&self, parser: MsgParser<'_, '_>) -> Result<(), XdgPositionerError> { - let _req: SetReactive = self.client.parse(self, parser)?; + fn set_reactive(&self, _req: SetReactive, _slf: &Rc) -> Result<(), Self::Error> { self.position.borrow_mut().reactive = true; Ok(()) } - fn set_parent_size(&self, parser: MsgParser<'_, '_>) -> Result<(), XdgPositionerError> { - let req: SetParentSize = self.client.parse(self, parser)?; + fn set_parent_size(&self, req: SetParentSize, _slf: &Rc) -> Result<(), Self::Error> { if req.parent_width < 0 || req.parent_height < 0 { self.client.protocol_error( self, @@ -252,8 +247,11 @@ impl XdgPositioner { Ok(()) } - fn set_parent_configure(&self, parser: MsgParser<'_, '_>) -> Result<(), XdgPositionerError> { - let req: SetParentConfigure = self.client.parse(self, parser)?; + fn set_parent_configure( + &self, + req: SetParentConfigure, + _slf: &Rc, + ) -> Result<(), Self::Error> { self.position.borrow_mut().parent_serial = req.serial; Ok(()) } @@ -261,17 +259,7 @@ impl XdgPositioner { object_base! { self = XdgPositioner; - - DESTROY => destroy, - SET_SIZE => set_size, - SET_ANCHOR_RECT => set_anchor_rect, - SET_ANCHOR => set_anchor, - SET_GRAVITY => set_gravity, - SET_CONSTRAINT_ADJUSTMENT => set_constraint_adjustment, - SET_OFFSET => set_offset, - SET_REACTIVE => set_reactive if self.base.version >= 3, - SET_PARENT_SIZE => set_parent_size if self.base.version >= 3, - SET_PARENT_CONFIGURE => set_parent_configure if self.base.version >= 3, + version = self.base.version; } impl Object for XdgPositioner {} @@ -290,12 +278,9 @@ pub enum XdgPositionerError { UnknownGravity(u32), #[error("Unknown constraint adjustment {0}")] UnknownCa(u32), - #[error("Parsing failed")] - MsgParserError(#[source] Box), #[error("Cannot set a negative parent size")] NegativeParentSize, #[error(transparent)] ClientError(Box), } -efrom!(XdgPositionerError, MsgParserError); efrom!(XdgPositionerError, ClientError); diff --git a/src/ifs/xdg_toplevel_drag_manager_v1.rs b/src/ifs/xdg_toplevel_drag_manager_v1.rs index 4a1378ce..94dda82e 100644 --- a/src/ifs/xdg_toplevel_drag_manager_v1.rs +++ b/src/ifs/xdg_toplevel_drag_manager_v1.rs @@ -5,7 +5,6 @@ use { ifs::xdg_toplevel_drag_v1::XdgToplevelDragV1, leaks::Tracker, object::{Object, Version}, - utils::buffd::{MsgParser, MsgParserError}, wire::{xdg_toplevel_drag_manager_v1::*, XdgToplevelDragManagerV1Id}, }, std::rc::Rc, @@ -64,18 +63,19 @@ pub struct XdgToplevelDragManagerV1 { pub version: Version, } -impl XdgToplevelDragManagerV1 { - fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), XdgToplevelDragManagerV1Error> { - let _req: Destroy = self.client.parse(self, parser)?; +impl XdgToplevelDragManagerV1RequestHandler for XdgToplevelDragManagerV1 { + type Error = XdgToplevelDragManagerV1Error; + + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { self.client.remove_obj(self)?; Ok(()) } fn get_xdg_toplevel_drag( &self, - parser: MsgParser<'_, '_>, - ) -> Result<(), XdgToplevelDragManagerV1Error> { - let req: GetXdgToplevelDrag = self.client.parse(self, parser)?; + req: GetXdgToplevelDrag, + _slf: &Rc, + ) -> Result<(), Self::Error> { let source = self.client.lookup(req.data_source)?; if source.data.was_used() { return Err(XdgToplevelDragManagerV1Error::AlreadyUsed); @@ -83,7 +83,7 @@ impl XdgToplevelDragManagerV1 { if source.toplevel_drag.get().is_some() { return Err(XdgToplevelDragManagerV1Error::HasDrag); } - let drag = Rc::new(XdgToplevelDragV1::new(req.id, &source)); + let drag = Rc::new(XdgToplevelDragV1::new(req.id, &source, self.version)); track!(&self.client, drag); self.client.add_client_obj(&drag)?; source.toplevel_drag.set(Some(drag)); @@ -93,9 +93,7 @@ impl XdgToplevelDragManagerV1 { object_base! { self = XdgToplevelDragManagerV1; - - DESTROY => destroy, - GET_XDG_TOPLEVEL_DRAG => get_xdg_toplevel_drag, + version = self.version; } impl Object for XdgToplevelDragManagerV1 {} @@ -106,12 +104,9 @@ simple_add_obj!(XdgToplevelDragManagerV1); pub enum XdgToplevelDragManagerV1Error { #[error(transparent)] ClientError(Box), - #[error("Parsing failed")] - MsgParserError(#[source] Box), #[error("The data source has already been used")] AlreadyUsed, #[error("The source already has a drag object")] HasDrag, } efrom!(XdgToplevelDragManagerV1Error, ClientError); -efrom!(XdgToplevelDragManagerV1Error, MsgParserError); diff --git a/src/ifs/xdg_toplevel_drag_v1.rs b/src/ifs/xdg_toplevel_drag_v1.rs index beadf987..3a8e0eb7 100644 --- a/src/ifs/xdg_toplevel_drag_v1.rs +++ b/src/ifs/xdg_toplevel_drag_v1.rs @@ -6,11 +6,8 @@ use { wl_surface::xdg_surface::xdg_toplevel::XdgToplevel, }, leaks::Tracker, - object::Object, - utils::{ - buffd::{MsgParser, MsgParserError}, - clonecell::CloneCell, - }, + object::{Object, Version}, + utils::clonecell::CloneCell, wire::{xdg_toplevel_drag_v1::*, XdgToplevelDragV1Id}, }, std::{cell::Cell, rc::Rc}, @@ -25,10 +22,11 @@ pub struct XdgToplevelDragV1 { pub toplevel: CloneCell>>, pub x_off: Cell, pub y_off: Cell, + pub version: Version, } impl XdgToplevelDragV1 { - pub fn new(id: XdgToplevelDragV1Id, source: &Rc) -> Self { + pub fn new(id: XdgToplevelDragV1Id, source: &Rc, version: Version) -> Self { Self { id, client: source.data.client.clone(), @@ -37,6 +35,7 @@ impl XdgToplevelDragV1 { toplevel: Default::default(), x_off: Cell::new(0), y_off: Cell::new(0), + version, } } @@ -50,9 +49,12 @@ impl XdgToplevelDragV1 { tl.drag.take(); } } +} + +impl XdgToplevelDragV1RequestHandler for XdgToplevelDragV1 { + type Error = XdgToplevelDragV1Error; - fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), XdgToplevelDragV1Error> { - let _req: Destroy = self.client.parse(self, parser)?; + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { if self.is_ongoing() { return Err(XdgToplevelDragV1Error::ActiveDrag); } @@ -61,13 +63,12 @@ impl XdgToplevelDragV1 { Ok(()) } - fn attach(self: &Rc, parser: MsgParser<'_, '_>) -> Result<(), XdgToplevelDragV1Error> { - let req: Attach = self.client.parse(&**self, parser)?; + fn attach(&self, req: Attach, slf: &Rc) -> Result<(), Self::Error> { if self.source.data.was_dropped_or_cancelled() { return Ok(()); } let toplevel = self.client.lookup(req.toplevel)?; - if toplevel.drag.set(Some(self.clone())).is_some() { + if toplevel.drag.set(Some(slf.clone())).is_some() { return Err(XdgToplevelDragV1Error::AlreadyDragged); } if let Some(prev) = self.toplevel.set(Some(toplevel)) { @@ -83,8 +84,10 @@ impl XdgToplevelDragV1 { self.start_drag(); Ok(()) } +} - pub fn start_drag(self: &Rc) { +impl XdgToplevelDragV1 { + pub fn start_drag(&self) { if !self.is_ongoing() { return; } @@ -114,9 +117,7 @@ impl XdgToplevelDragV1 { object_base! { self = XdgToplevelDragV1; - - DESTROY => destroy, - ATTACH => attach, + version = self.version; } impl Object for XdgToplevelDragV1 { @@ -131,8 +132,6 @@ simple_add_obj!(XdgToplevelDragV1); pub enum XdgToplevelDragV1Error { #[error(transparent)] ClientError(Box), - #[error("Parsing failed")] - MsgParserError(#[source] Box), #[error("The toplevel already has a drag attached")] AlreadyDragged, #[error("There already is a mapped toplevel attached")] @@ -141,4 +140,3 @@ pub enum XdgToplevelDragV1Error { ActiveDrag, } efrom!(XdgToplevelDragV1Error, ClientError); -efrom!(XdgToplevelDragV1Error, MsgParserError); diff --git a/src/ifs/xdg_wm_base.rs b/src/ifs/xdg_wm_base.rs index 4f438b6b..adeec9c0 100644 --- a/src/ifs/xdg_wm_base.rs +++ b/src/ifs/xdg_wm_base.rs @@ -8,10 +8,7 @@ use { }, leaks::Tracker, object::{Object, Version}, - utils::{ - buffd::{MsgParser, MsgParserError}, - copyhashmap::CopyHashMap, - }, + utils::copyhashmap::CopyHashMap, wire::{xdg_wm_base::*, XdgSurfaceId, XdgWmBaseId}, }, std::rc::Rc, @@ -66,9 +63,10 @@ impl XdgWmBaseGlobal { } } -impl XdgWmBase { - fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), XdgWmBaseError> { - let _req: Destroy = self.client.parse(self, parser)?; +impl XdgWmBaseRequestHandler for XdgWmBase { + type Error = XdgWmBaseError; + + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { if !self.surfaces.is_empty() { self.client.protocol_error( self, @@ -84,18 +82,16 @@ impl XdgWmBase { Ok(()) } - fn create_positioner(self: &Rc, parser: MsgParser<'_, '_>) -> Result<(), XdgWmBaseError> { - let req: CreatePositioner = self.client.parse(&**self, parser)?; - let pos = Rc::new(XdgPositioner::new(self, req.id, &self.client)); + fn create_positioner(&self, req: CreatePositioner, slf: &Rc) -> Result<(), Self::Error> { + let pos = Rc::new(XdgPositioner::new(slf, req.id, &self.client)); track!(self.client, pos); self.client.add_client_obj(&pos)?; Ok(()) } - fn get_xdg_surface(self: &Rc, parser: MsgParser<'_, '_>) -> Result<(), XdgWmBaseError> { - let req: GetXdgSurface = self.client.parse(&**self, parser)?; + fn get_xdg_surface(&self, req: GetXdgSurface, slf: &Rc) -> Result<(), Self::Error> { let surface = self.client.lookup(req.surface)?; - let xdg_surface = Rc::new(XdgSurface::new(self, req.id, &surface)); + let xdg_surface = Rc::new(XdgSurface::new(slf, req.id, &surface)); track!(self.client, xdg_surface); self.client.add_client_obj(&xdg_surface)?; xdg_surface.install()?; @@ -103,8 +99,7 @@ impl XdgWmBase { Ok(()) } - fn pong(&self, parser: MsgParser<'_, '_>) -> Result<(), XdgWmBaseError> { - let _req: Pong = self.client.parse(self, parser)?; + fn pong(&self, _req: Pong, _slf: &Rc) -> Result<(), Self::Error> { Ok(()) } } @@ -125,11 +120,7 @@ simple_add_global!(XdgWmBaseGlobal); object_base! { self = XdgWmBase; - - DESTROY => destroy, - CREATE_POSITIONER => create_positioner, - GET_XDG_SURFACE => get_xdg_surface, - PONG => pong, + version = self.version; } dedicated_add_obj!(XdgWmBase, XdgWmBaseId, xdg_wm_bases); @@ -144,13 +135,10 @@ impl Object for XdgWmBase { pub enum XdgWmBaseError { #[error(transparent)] ClientError(Box), - #[error("Parsing failed")] - MsgParserError(#[source] Box), #[error("Tried to destroy xdg_wm_base object before destroying its surfaces")] DefunctSurfaces, #[error(transparent)] XdgSurfaceError(Box), } efrom!(XdgWmBaseError, ClientError); -efrom!(XdgWmBaseError, MsgParserError); efrom!(XdgWmBaseError, XdgSurfaceError); diff --git a/src/ifs/zwlr_layer_shell_v1.rs b/src/ifs/zwlr_layer_shell_v1.rs index c8da33e5..7e8ca7c2 100644 --- a/src/ifs/zwlr_layer_shell_v1.rs +++ b/src/ifs/zwlr_layer_shell_v1.rs @@ -5,7 +5,6 @@ use { ifs::wl_surface::zwlr_layer_surface_v1::{ZwlrLayerSurfaceV1, ZwlrLayerSurfaceV1Error}, leaks::Tracker, object::{Object, Version}, - utils::buffd::{MsgParser, MsgParserError}, wire::{zwlr_layer_shell_v1::*, ZwlrLayerShellV1Id}, }, std::rc::Rc, @@ -51,18 +50,10 @@ impl ZwlrLayerShellV1Global { } } -impl ZwlrLayerShellV1 { - fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), ZwlrLayerSurfaceV1Error> { - let _req: Destroy = self.client.parse(self, parser)?; - self.client.remove_obj(self)?; - Ok(()) - } +impl ZwlrLayerShellV1RequestHandler for ZwlrLayerShellV1 { + type Error = ZwlrLayerShellV1Error; - fn get_layer_surface( - self: &Rc, - parser: MsgParser<'_, '_>, - ) -> Result<(), ZwlrLayerShellV1Error> { - let req: GetLayerSurface = self.client.parse(&**self, parser)?; + fn get_layer_surface(&self, req: GetLayerSurface, slf: &Rc) -> Result<(), Self::Error> { let surface = self.client.lookup(req.surface)?; let output = 'get_output: { if req.output.is_some() { @@ -86,7 +77,7 @@ impl ZwlrLayerShellV1 { } let surface = Rc::new(ZwlrLayerSurfaceV1::new( req.id, - self, + slf, &surface, &output, req.layer, @@ -97,6 +88,11 @@ impl ZwlrLayerShellV1 { surface.install()?; Ok(()) } + + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { + self.client.remove_obj(self)?; + Ok(()) + } } global_base!( @@ -123,9 +119,7 @@ simple_add_global!(ZwlrLayerShellV1Global); object_base! { self = ZwlrLayerShellV1; - - GET_LAYER_SURFACE => get_layer_surface, - DESTROY => destroy if self.version >= 3, + version = self.version; } simple_add_obj!(ZwlrLayerShellV1); @@ -134,8 +128,6 @@ impl Object for ZwlrLayerShellV1 {} #[derive(Debug, Error)] pub enum ZwlrLayerShellV1Error { - #[error("Parsing failed")] - MsgParserError(#[source] Box), #[error(transparent)] ClientError(Box), #[error("Unknown layer {0}")] @@ -146,5 +138,4 @@ pub enum ZwlrLayerShellV1Error { ZwlrLayerSurfaceV1Error(Box), } efrom!(ZwlrLayerShellV1Error, ClientError); -efrom!(ZwlrLayerShellV1Error, MsgParserError); efrom!(ZwlrLayerShellV1Error, ZwlrLayerSurfaceV1Error); diff --git a/src/ifs/zwlr_screencopy_frame_v1.rs b/src/ifs/zwlr_screencopy_frame_v1.rs index 022cdd08..dbd9782a 100644 --- a/src/ifs/zwlr_screencopy_frame_v1.rs +++ b/src/ifs/zwlr_screencopy_frame_v1.rs @@ -9,10 +9,7 @@ use { leaks::Tracker, object::{Object, Version}, rect::Rect, - utils::{ - buffd::{MsgParser, MsgParserError}, - linkedlist::LinkedNode, - }, + utils::linkedlist::LinkedNode, wire::{zwlr_screencopy_frame_v1::*, WlBufferId, ZwlrScreencopyFrameV1Id}, }, std::{cell::Cell, ops::Deref, rc::Rc}, @@ -129,34 +126,29 @@ impl ZwlrScreencopyFrameV1 { self.output_link.set(Some(link)); Ok(()) } +} - fn copy(&self, parser: MsgParser<'_, '_>) -> Result<(), ZwlrScreencopyFrameV1Error> { - let req: Copy = self.client.parse(self, parser)?; +impl ZwlrScreencopyFrameV1RequestHandler for ZwlrScreencopyFrameV1 { + type Error = ZwlrScreencopyFrameV1Error; + + fn copy(&self, req: Copy, _slf: &Rc) -> Result<(), Self::Error> { self.do_copy(req.buffer, false) } - fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), ZwlrScreencopyFrameV1Error> { - let _req: Destroy = self.client.parse(self, parser)?; + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { self.client.remove_obj(self)?; self.output_link.take(); Ok(()) } - fn copy_with_damage( - &self, - parser: MsgParser<'_, '_>, - ) -> Result<(), ZwlrScreencopyFrameV1Error> { - let req: CopyWithDamage = self.client.parse(self, parser)?; + fn copy_with_damage(&self, req: CopyWithDamage, _slf: &Rc) -> Result<(), Self::Error> { self.do_copy(req.buffer, true) } } object_base! { self = ZwlrScreencopyFrameV1; - - COPY => copy, - DESTROY => destroy, - COPY_WITH_DAMAGE => copy_with_damage if self.version >= 2, + version = self.version; } simple_add_obj!(ZwlrScreencopyFrameV1); @@ -181,9 +173,6 @@ pub enum ZwlrScreencopyFrameV1Error { WlBufferError(Box), #[error(transparent)] ClientError(Box), - #[error(transparent)] - MsgParserError(Box), } efrom!(ZwlrScreencopyFrameV1Error, WlBufferError); efrom!(ZwlrScreencopyFrameV1Error, ClientError); -efrom!(ZwlrScreencopyFrameV1Error, MsgParserError); diff --git a/src/ifs/zwlr_screencopy_manager_v1.rs b/src/ifs/zwlr_screencopy_manager_v1.rs index 036bcc18..7acbf3d2 100644 --- a/src/ifs/zwlr_screencopy_manager_v1.rs +++ b/src/ifs/zwlr_screencopy_manager_v1.rs @@ -6,7 +6,6 @@ use { leaks::Tracker, object::{Object, Version}, rect::Rect, - utils::buffd::{MsgParser, MsgParserError}, wire::{ zwlr_screencopy_manager_v1::*, WlOutputId, ZwlrScreencopyFrameV1Id, ZwlrScreencopyManagerV1Id, @@ -72,20 +71,18 @@ pub struct ZwlrScreencopyManagerV1 { pub version: Version, } -impl ZwlrScreencopyManagerV1 { - fn capture_output( - &self, - parser: MsgParser<'_, '_>, - ) -> Result<(), ZwlrScreencopyManagerV1Error> { - let req: CaptureOutput = self.client.parse(self, parser)?; +impl ZwlrScreencopyManagerV1RequestHandler for ZwlrScreencopyManagerV1 { + type Error = ZwlrScreencopyManagerV1Error; + + fn capture_output(&self, req: CaptureOutput, _slf: &Rc) -> Result<(), Self::Error> { self.do_capture_output(req.output, req.overlay_cursor != 0, req.frame, None) } fn capture_output_region( &self, - parser: MsgParser<'_, '_>, - ) -> Result<(), ZwlrScreencopyManagerV1Error> { - let req: CaptureOutputRegion = self.client.parse(self, parser)?; + req: CaptureOutputRegion, + _slf: &Rc, + ) -> Result<(), Self::Error> { let region = match Rect::new_sized(req.x, req.y, req.width, req.height) { Some(r) => r, _ => return Err(ZwlrScreencopyManagerV1Error::InvalidRegion), @@ -93,6 +90,13 @@ impl ZwlrScreencopyManagerV1 { self.do_capture_output(req.output, req.overlay_cursor != 0, req.frame, Some(region)) } + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { + self.client.remove_obj(self)?; + Ok(()) + } +} + +impl ZwlrScreencopyManagerV1 { fn do_capture_output( &self, output: WlOutputId, @@ -137,20 +141,11 @@ impl ZwlrScreencopyManagerV1 { .set(Some(output.global.unused_captures.add_last(frame.clone()))); Ok(()) } - - fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), ZwlrScreencopyManagerV1Error> { - let _req: Destroy = self.client.parse(self, parser)?; - self.client.remove_obj(self)?; - Ok(()) - } } object_base! { self = ZwlrScreencopyManagerV1; - - CAPTURE_OUTPUT => capture_output, - CAPTURE_OUTPUT_REGION => capture_output_region, - DESTROY => destroy, + version = self.version; } impl Object for ZwlrScreencopyManagerV1 {} @@ -161,10 +156,7 @@ simple_add_obj!(ZwlrScreencopyManagerV1); pub enum ZwlrScreencopyManagerV1Error { #[error(transparent)] ClientError(Box), - #[error("Parsing failed")] - MsgParserError(#[source] Box), #[error("The passed region is invalid")] InvalidRegion, } efrom!(ZwlrScreencopyManagerV1Error, ClientError); -efrom!(ZwlrScreencopyManagerV1Error, MsgParserError); diff --git a/src/ifs/zwp_idle_inhibit_manager_v1.rs b/src/ifs/zwp_idle_inhibit_manager_v1.rs index 62801b06..c3bf27ff 100644 --- a/src/ifs/zwp_idle_inhibit_manager_v1.rs +++ b/src/ifs/zwp_idle_inhibit_manager_v1.rs @@ -8,7 +8,6 @@ use { }, leaks::Tracker, object::{Object, Version}, - utils::buffd::{MsgParser, MsgParserError}, wire::{zwp_idle_inhibit_manager_v1::*, ZwpIdleInhibitManagerV1Id}, }, std::rc::Rc, @@ -33,7 +32,7 @@ impl ZwpIdleInhibitManagerV1Global { let obj = Rc::new(ZwpIdleInhibitManagerV1 { id, client: client.clone(), - _version: version, + version, tracker: Default::default(), }); track!(client, obj); @@ -63,22 +62,19 @@ simple_add_global!(ZwpIdleInhibitManagerV1Global); pub struct ZwpIdleInhibitManagerV1 { pub id: ZwpIdleInhibitManagerV1Id, pub client: Rc, - pub _version: Version, + pub version: Version, pub tracker: Tracker, } -impl ZwpIdleInhibitManagerV1 { - pub fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), ZwpIdleInhibitManagerV1Error> { - let _req: Destroy = self.client.parse(self, parser)?; +impl ZwpIdleInhibitManagerV1RequestHandler for ZwpIdleInhibitManagerV1 { + type Error = ZwpIdleInhibitManagerV1Error; + + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { self.client.remove_obj(self)?; Ok(()) } - pub fn create_inhibitor( - &self, - parser: MsgParser<'_, '_>, - ) -> Result<(), ZwpIdleInhibitManagerV1Error> { - let req: CreateInhibitor = self.client.parse(self, parser)?; + fn create_inhibitor(&self, req: CreateInhibitor, _slf: &Rc) -> Result<(), Self::Error> { let surface = self.client.lookup(req.surface)?; let inhibit = Rc::new(ZwpIdleInhibitorV1 { id: req.id, @@ -86,6 +82,7 @@ impl ZwpIdleInhibitManagerV1 { client: self.client.clone(), surface, tracker: Default::default(), + version: self.version, }); track!(self.client, inhibit); self.client.add_client_obj(&inhibit)?; @@ -96,9 +93,7 @@ impl ZwpIdleInhibitManagerV1 { object_base! { self = ZwpIdleInhibitManagerV1; - - DESTROY => destroy, - CREATE_INHIBITOR => create_inhibitor, + version = self.version; } impl Object for ZwpIdleInhibitManagerV1 {} @@ -107,12 +102,9 @@ simple_add_obj!(ZwpIdleInhibitManagerV1); #[derive(Debug, Error)] pub enum ZwpIdleInhibitManagerV1Error { - #[error("Parsing failed")] - MsgParserError(#[source] Box), #[error(transparent)] ClientError(Box), #[error(transparent)] ZwpIdleInhibitorV1Error(#[from] ZwpIdleInhibitorV1Error), } efrom!(ZwpIdleInhibitManagerV1Error, ClientError); -efrom!(ZwpIdleInhibitManagerV1Error, MsgParserError); diff --git a/src/ifs/zwp_linux_buffer_params_v1.rs b/src/ifs/zwp_linux_buffer_params_v1.rs index 4dcebf55..db1914a6 100644 --- a/src/ifs/zwp_linux_buffer_params_v1.rs +++ b/src/ifs/zwp_linux_buffer_params_v1.rs @@ -5,10 +5,7 @@ use { ifs::{wl_buffer::WlBuffer, zwp_linux_dmabuf_v1::ZwpLinuxDmabufV1}, leaks::Tracker, object::Object, - utils::{ - buffd::{MsgParser, MsgParserError}, - errorfmt::ErrorFmt, - }, + utils::errorfmt::ErrorFmt, video::dmabuf::{DmaBuf, DmaBufPlane, PlaneVec, MAX_PLANES}, wire::{zwp_linux_buffer_params_v1::*, WlBufferId, ZwpLinuxBufferParamsV1Id}, }, @@ -61,36 +58,8 @@ impl ZwpLinuxBufferParamsV1 { self.parent.client.event(Failed { self_id: self.id }) } - fn destroy( - self: &Rc, - parser: MsgParser<'_, '_>, - ) -> Result<(), ZwpLinuxBufferParamsV1Error> { - let _req: Destroy = self.parent.client.parse(&**self, parser)?; - self.parent.client.remove_obj(&**self)?; - Ok(()) - } - - fn add(self: &Rc, parser: MsgParser<'_, '_>) -> Result<(), ZwpLinuxBufferParamsV1Error> { - let req: Add = self.parent.client.parse(&**self, parser)?; - let modifier = ((req.modifier_hi as u64) << 32) | req.modifier_lo as u64; - match self.modifier.get() { - Some(m) if m != modifier => { - return Err(ZwpLinuxBufferParamsV1Error::MixedModifiers(modifier, m)) - } - _ => self.modifier.set(Some(modifier)), - } - let plane = req.plane_idx; - if plane > MAX_PLANE { - return Err(ZwpLinuxBufferParamsV1Error::MaxPlane); - } - if self.planes.borrow_mut().insert(plane, req).is_some() { - return Err(ZwpLinuxBufferParamsV1Error::AlreadySet(plane)); - } - Ok(()) - } - fn do_create( - self: &Rc, + &self, buffer_id: Option, width: i32, height: i32, @@ -153,9 +122,35 @@ impl ZwpLinuxBufferParamsV1 { } Ok(buffer_id) } +} + +impl ZwpLinuxBufferParamsV1RequestHandler for ZwpLinuxBufferParamsV1 { + type Error = ZwpLinuxBufferParamsV1Error; - fn create(self: &Rc, parser: MsgParser) -> Result<(), ZwpLinuxBufferParamsV1Error> { - let req: Create = self.parent.client.parse(&**self, parser)?; + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { + self.parent.client.remove_obj(self)?; + Ok(()) + } + + fn add(&self, req: Add, _slf: &Rc) -> Result<(), Self::Error> { + let modifier = ((req.modifier_hi as u64) << 32) | req.modifier_lo as u64; + match self.modifier.get() { + Some(m) if m != modifier => { + return Err(ZwpLinuxBufferParamsV1Error::MixedModifiers(modifier, m)) + } + _ => self.modifier.set(Some(modifier)), + } + let plane = req.plane_idx; + if plane > MAX_PLANE { + return Err(ZwpLinuxBufferParamsV1Error::MaxPlane); + } + if self.planes.borrow_mut().insert(plane, req).is_some() { + return Err(ZwpLinuxBufferParamsV1Error::AlreadySet(plane)); + } + Ok(()) + } + + fn create(&self, req: Create, _slf: &Rc) -> Result<(), Self::Error> { if self.used.replace(true) { return Err(ZwpLinuxBufferParamsV1Error::AlreadyUsed); } @@ -171,8 +166,11 @@ impl ZwpLinuxBufferParamsV1 { Ok(()) } - fn create_immed(self: &Rc, parser: MsgParser) -> Result<(), ZwpLinuxBufferParamsV1Error> { - let req: CreateImmed = self.parent.client.parse(&**self, parser)?; + fn create_immed( + &self, + req: CreateImmed, + _slf: &Rc, + ) -> Result<(), ZwpLinuxBufferParamsV1Error> { if self.used.replace(true) { return Err(ZwpLinuxBufferParamsV1Error::AlreadyUsed); } @@ -189,11 +187,7 @@ impl ZwpLinuxBufferParamsV1 { object_base! { self = ZwpLinuxBufferParamsV1; - - DESTROY => destroy, - ADD => add, - CREATE => create, - CREATE_IMMED => create_immed if self.parent.version >= 2, + version = self.parent.version; } impl Object for ZwpLinuxBufferParamsV1 {} @@ -206,8 +200,6 @@ pub enum ZwpLinuxBufferParamsV1Error { ClientError(Box), #[error("The params object has already been used")] AlreadyUsed, - #[error("Parsing failed")] - MsgParserError(#[source] Box), #[error("A buffer can contain at most 4 planes")] MaxPlane, #[error("Tried to add a plane with modifier {0} that differs from a previous modifier {1}")] @@ -228,4 +220,3 @@ pub enum ZwpLinuxBufferParamsV1Error { ImportError(#[from] GfxError), } efrom!(ZwpLinuxBufferParamsV1Error, ClientError); -efrom!(ZwpLinuxBufferParamsV1Error, MsgParserError); diff --git a/src/ifs/zwp_linux_dmabuf_feedback_v1.rs b/src/ifs/zwp_linux_dmabuf_feedback_v1.rs index f8828ce2..172d6d8c 100644 --- a/src/ifs/zwp_linux_dmabuf_feedback_v1.rs +++ b/src/ifs/zwp_linux_dmabuf_feedback_v1.rs @@ -4,8 +4,7 @@ use { drm_feedback::{DrmFeedback, DrmFeedbackId}, ifs::wl_surface::WlSurface, leaks::Tracker, - object::Object, - utils::buffd::{MsgParser, MsgParserError}, + object::{Object, Version}, wire::{zwp_linux_dmabuf_feedback_v1::*, ZwpLinuxDmabufFeedbackV1Id}, }, std::{cell::Cell, rc::Rc}, @@ -22,6 +21,7 @@ pub struct ZwpLinuxDmabufFeedbackV1 { pub tracker: Tracker, pub last_feedback: Cell>, pub surface: Option>, + pub version: Version, } impl ZwpLinuxDmabufFeedbackV1 { @@ -29,6 +29,7 @@ impl ZwpLinuxDmabufFeedbackV1 { id: ZwpLinuxDmabufFeedbackV1Id, client: &Rc, surface: Option<&Rc>, + version: Version, ) -> Self { Self { id, @@ -36,6 +37,7 @@ impl ZwpLinuxDmabufFeedbackV1 { tracker: Default::default(), last_feedback: Default::default(), surface: surface.cloned(), + version, } } @@ -97,14 +99,19 @@ impl ZwpLinuxDmabufFeedbackV1 { flags, }); } +} + +impl ZwpLinuxDmabufFeedbackV1RequestHandler for ZwpLinuxDmabufFeedbackV1 { + type Error = ZwpLinuxDmabufFeedbackV1Error; - fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), ZwpLinuxDmabufFeedbackV1Error> { - let _req: Destroy = self.client.parse(self, parser)?; + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { self.detach(); self.client.remove_obj(self)?; Ok(()) } +} +impl ZwpLinuxDmabufFeedbackV1 { fn detach(&self) { self.client .state @@ -118,8 +125,7 @@ impl ZwpLinuxDmabufFeedbackV1 { object_base! { self = ZwpLinuxDmabufFeedbackV1; - - DESTROY => destroy, + version = self.version; } impl Object for ZwpLinuxDmabufFeedbackV1 { @@ -134,8 +140,5 @@ simple_add_obj!(ZwpLinuxDmabufFeedbackV1); pub enum ZwpLinuxDmabufFeedbackV1Error { #[error(transparent)] ClientError(Box), - #[error("Parsing failed")] - MsgParserError(#[source] Box), } efrom!(ZwpLinuxDmabufFeedbackV1Error, ClientError); -efrom!(ZwpLinuxDmabufFeedbackV1Error, MsgParserError); diff --git a/src/ifs/zwp_linux_dmabuf_v1.rs b/src/ifs/zwp_linux_dmabuf_v1.rs index a0febff3..5dd63a64 100644 --- a/src/ifs/zwp_linux_dmabuf_v1.rs +++ b/src/ifs/zwp_linux_dmabuf_v1.rs @@ -8,7 +8,6 @@ use { }, leaks::Tracker, object::{Object, Version}, - utils::buffd::{MsgParser, MsgParserError}, wire::{zwp_linux_dmabuf_v1::*, ZwpLinuxDmabufFeedbackV1Id, ZwpLinuxDmabufV1Id}, }, std::rc::Rc, @@ -100,29 +99,17 @@ impl ZwpLinuxDmabufV1 { }) } - fn destroy(self: &Rc, parser: MsgParser<'_, '_>) -> Result<(), ZwpLinuxDmabufV1Error> { - let _req: Destroy = self.client.parse(&**self, parser)?; - self.client.remove_obj(&**self)?; - Ok(()) - } - - fn create_params( - self: &Rc, - parser: MsgParser<'_, '_>, - ) -> Result<(), ZwpLinuxDmabufV1Error> { - let req: CreateParams = self.client.parse(&**self, parser)?; - let params = Rc::new(ZwpLinuxBufferParamsV1::new(req.params_id, self)); - track!(self.client, params); - self.client.add_client_obj(¶ms)?; - Ok(()) - } - fn get_feedback( - self: &Rc, + &self, id: ZwpLinuxDmabufFeedbackV1Id, surface: Option<&Rc>, ) -> Result, ZwpLinuxDmabufV1Error> { - let fb = Rc::new(ZwpLinuxDmabufFeedbackV1::new(id, &self.client, surface)); + let fb = Rc::new(ZwpLinuxDmabufFeedbackV1::new( + id, + &self.client, + surface, + self.version, + )); track!(self.client, fb); self.client.add_client_obj(&fb)?; self.client @@ -134,21 +121,37 @@ impl ZwpLinuxDmabufV1 { } Ok(fb) } +} + +impl ZwpLinuxDmabufV1RequestHandler for ZwpLinuxDmabufV1 { + type Error = ZwpLinuxDmabufV1Error; + + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { + self.client.remove_obj(self)?; + Ok(()) + } + + fn create_params(&self, req: CreateParams, slf: &Rc) -> Result<(), Self::Error> { + let params = Rc::new(ZwpLinuxBufferParamsV1::new(req.params_id, slf)); + track!(self.client, params); + self.client.add_client_obj(¶ms)?; + Ok(()) + } fn get_default_feedback( - self: &Rc, - parser: MsgParser<'_, '_>, - ) -> Result<(), ZwpLinuxDmabufV1Error> { - let req: GetDefaultFeedback = self.client.parse(&**self, parser)?; + &self, + req: GetDefaultFeedback, + _slf: &Rc, + ) -> Result<(), Self::Error> { self.get_feedback(req.id, None)?; Ok(()) } fn get_surface_feedback( - self: &Rc, - parser: MsgParser<'_, '_>, - ) -> Result<(), ZwpLinuxDmabufV1Error> { - let req: GetSurfaceFeedback = self.client.parse(&**self, parser)?; + &self, + req: GetSurfaceFeedback, + _slf: &Rc, + ) -> Result<(), Self::Error> { let surface = self.client.lookup(req.surface)?; let fb = self.get_feedback(req.id, Some(&surface))?; surface.drm_feedback.set(req.id, fb); @@ -158,11 +161,7 @@ impl ZwpLinuxDmabufV1 { object_base! { self = ZwpLinuxDmabufV1; - - DESTROY => destroy, - CREATE_PARAMS => create_params, - GET_DEFAULT_FEEDBACK => get_default_feedback if self.version.0 >= 4, - GET_SURFACE_FEEDBACK => get_surface_feedback if self.version.0 >= 4, + version = self.version; } impl Object for ZwpLinuxDmabufV1 {} @@ -173,8 +172,5 @@ simple_add_obj!(ZwpLinuxDmabufV1); pub enum ZwpLinuxDmabufV1Error { #[error(transparent)] ClientError(Box), - #[error("Parsing failed")] - MsgParserError(#[source] Box), } efrom!(ZwpLinuxDmabufV1Error, ClientError); -efrom!(ZwpLinuxDmabufV1Error, MsgParserError); diff --git a/src/ifs/zxdg_decoration_manager_v1.rs b/src/ifs/zxdg_decoration_manager_v1.rs index fdd4d894..c4ce9c76 100644 --- a/src/ifs/zxdg_decoration_manager_v1.rs +++ b/src/ifs/zxdg_decoration_manager_v1.rs @@ -5,7 +5,6 @@ use { ifs::zxdg_toplevel_decoration_v1::ZxdgToplevelDecorationV1, leaks::Tracker, object::{Object, Version}, - utils::buffd::{MsgParser, MsgParserError}, wire::{zxdg_decoration_manager_v1::*, ZxdgDecorationManagerV1Id}, }, std::rc::Rc, @@ -30,7 +29,7 @@ impl ZxdgDecorationManagerV1Global { let obj = Rc::new(ZxdgDecorationManagerV1 { id, client: client.clone(), - _version: version, + version, tracker: Default::default(), }); track!(client, obj); @@ -60,24 +59,30 @@ simple_add_global!(ZxdgDecorationManagerV1Global); pub struct ZxdgDecorationManagerV1 { id: ZxdgDecorationManagerV1Id, client: Rc, - _version: Version, + version: Version, tracker: Tracker, } -impl ZxdgDecorationManagerV1 { - fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), ZxdgDecorationManagerV1Error> { - let _req: Destroy = self.client.parse(self, parser)?; +impl ZxdgDecorationManagerV1RequestHandler for ZxdgDecorationManagerV1 { + type Error = ZxdgDecorationManagerV1Error; + + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { self.client.remove_obj(self)?; Ok(()) } fn get_toplevel_decoration( &self, - parser: MsgParser<'_, '_>, - ) -> Result<(), ZxdgDecorationManagerV1Error> { - let req: GetToplevelDecoration = self.client.parse(self, parser)?; + req: GetToplevelDecoration, + _slf: &Rc, + ) -> Result<(), Self::Error> { let tl = self.client.lookup(req.toplevel)?; - let obj = Rc::new(ZxdgToplevelDecorationV1::new(req.id, &self.client, &tl)); + let obj = Rc::new(ZxdgToplevelDecorationV1::new( + req.id, + &self.client, + &tl, + self.version, + )); track!(self.client, obj); self.client.add_client_obj(&obj)?; obj.do_send_configure(); @@ -87,9 +92,7 @@ impl ZxdgDecorationManagerV1 { object_base! { self = ZxdgDecorationManagerV1; - - DESTROY => destroy, - GET_TOPLEVEL_DECORATION => get_toplevel_decoration, + version = self.version; } impl Object for ZxdgDecorationManagerV1 {} @@ -100,8 +103,5 @@ simple_add_obj!(ZxdgDecorationManagerV1); pub enum ZxdgDecorationManagerV1Error { #[error(transparent)] ClientError(Box), - #[error("Parsing failed")] - MsgParserError(#[source] Box), } efrom!(ZxdgDecorationManagerV1Error, ClientError); -efrom!(ZxdgDecorationManagerV1Error, MsgParserError); diff --git a/src/ifs/zxdg_output_manager_v1.rs b/src/ifs/zxdg_output_manager_v1.rs index a218d62e..f7225e64 100644 --- a/src/ifs/zxdg_output_manager_v1.rs +++ b/src/ifs/zxdg_output_manager_v1.rs @@ -5,7 +5,6 @@ use { ifs::zxdg_output_v1::ZxdgOutputV1, leaks::Tracker, object::{Object, Version}, - utils::buffd::{MsgParser, MsgParserError}, wire::{zxdg_output_manager_v1::*, ZxdgOutputManagerV1Id}, }, std::rc::Rc, @@ -46,18 +45,15 @@ impl ZxdgOutputManagerV1Global { } } -impl ZxdgOutputManagerV1 { - fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), ZxdgOutputManagerV1Error> { - let _req: Destroy = self.client.parse(self, parser)?; +impl ZxdgOutputManagerV1RequestHandler for ZxdgOutputManagerV1 { + type Error = ZxdgOutputManagerV1Error; + + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { self.client.remove_obj(self)?; Ok(()) } - fn get_xdg_output( - self: &Rc, - parser: MsgParser<'_, '_>, - ) -> Result<(), ZxdgOutputManagerV1Error> { - let req: GetXdgOutput = self.client.parse(&**self, parser)?; + fn get_xdg_output(&self, req: GetXdgOutput, _slf: &Rc) -> Result<(), Self::Error> { let output = self.client.lookup(req.output)?; let xdg_output = Rc::new(ZxdgOutputV1 { id: req.id, @@ -94,9 +90,7 @@ simple_add_global!(ZxdgOutputManagerV1Global); object_base! { self = ZxdgOutputManagerV1; - - DESTROY => destroy, - GET_XDG_OUTPUT => get_xdg_output, + version = self.version; } simple_add_obj!(ZxdgOutputManagerV1); @@ -107,8 +101,5 @@ impl Object for ZxdgOutputManagerV1 {} pub enum ZxdgOutputManagerV1Error { #[error(transparent)] ClientError(Box), - #[error("Parsing failed")] - MsgParserError(#[source] Box), } efrom!(ZxdgOutputManagerV1Error, ClientError); -efrom!(ZxdgOutputManagerV1Error, MsgParserError); diff --git a/src/ifs/zxdg_output_v1.rs b/src/ifs/zxdg_output_v1.rs index 97606c55..8c3377de 100644 --- a/src/ifs/zxdg_output_v1.rs +++ b/src/ifs/zxdg_output_v1.rs @@ -4,7 +4,6 @@ use { ifs::wl_output::{WlOutput, SEND_DONE_SINCE}, leaks::Tracker, object::{Object, Version}, - utils::buffd::{MsgParser, MsgParserError}, wire::{zxdg_output_v1::*, ZxdgOutputV1Id}, }, std::rc::Rc, @@ -75,9 +74,12 @@ impl ZxdgOutputV1 { self.send_done(); } } +} + +impl ZxdgOutputV1RequestHandler for ZxdgOutputV1 { + type Error = ZxdgOutputV1Error; - pub fn destroy(&self, msg: MsgParser) -> Result<(), ZxdgOutputV1Error> { - let _req: Destroy = self.client.parse(self, msg)?; + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { self.output.xdg_outputs.remove(&self.id); self.client.remove_obj(self)?; Ok(()) @@ -86,8 +88,7 @@ impl ZxdgOutputV1 { object_base! { self = ZxdgOutputV1; - - DESTROY => destroy, + version = self.version; } impl Object for ZxdgOutputV1 {} @@ -96,10 +97,7 @@ simple_add_obj!(ZxdgOutputV1); #[derive(Debug, Error)] pub enum ZxdgOutputV1Error { - #[error("Parsing failed")] - MsgParserError(#[source] Box), #[error(transparent)] ClientError(Box), } -efrom!(ZxdgOutputV1Error, MsgParserError); efrom!(ZxdgOutputV1Error, ClientError); diff --git a/src/ifs/zxdg_toplevel_decoration_v1.rs b/src/ifs/zxdg_toplevel_decoration_v1.rs index 65c1d304..21e61246 100644 --- a/src/ifs/zxdg_toplevel_decoration_v1.rs +++ b/src/ifs/zxdg_toplevel_decoration_v1.rs @@ -3,8 +3,7 @@ use { client::{Client, ClientError}, ifs::wl_surface::xdg_surface::xdg_toplevel::{Decoration, XdgToplevel}, leaks::Tracker, - object::Object, - utils::buffd::{MsgParser, MsgParserError}, + object::{Object, Version}, wire::{zxdg_toplevel_decoration_v1::*, ZxdgToplevelDecorationV1Id}, }, std::rc::Rc, @@ -19,6 +18,7 @@ pub struct ZxdgToplevelDecorationV1 { pub client: Rc, pub toplevel: Rc, pub tracker: Tracker, + pub version: Version, } impl ZxdgToplevelDecorationV1 { @@ -26,12 +26,14 @@ impl ZxdgToplevelDecorationV1 { id: ZxdgToplevelDecorationV1Id, client: &Rc, toplevel: &Rc, + version: Version, ) -> Self { Self { id, client: client.clone(), toplevel: toplevel.clone(), tracker: Default::default(), + version, } } @@ -50,27 +52,22 @@ impl ZxdgToplevelDecorationV1 { self.send_configure(mode); self.toplevel.send_current_configure(); } +} + +impl ZxdgToplevelDecorationV1RequestHandler for ZxdgToplevelDecorationV1 { + type Error = ZxdgToplevelDecorationV1Error; - fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), ZxdgToplevelDecorationV1Error> { - let _req: Destroy = self.client.parse(self, parser)?; + fn destroy(&self, _req: Destroy, _slf: &Rc) -> Result<(), Self::Error> { self.client.remove_obj(self)?; Ok(()) } - fn set_mode( - self: &Rc, - parser: MsgParser<'_, '_>, - ) -> Result<(), ZxdgToplevelDecorationV1Error> { - let _req: SetMode = self.client.parse(&**self, parser)?; + fn set_mode(&self, _req: SetMode, _slf: &Rc) -> Result<(), Self::Error> { self.do_send_configure(); Ok(()) } - fn unset_mode( - self: &Rc, - parser: MsgParser<'_, '_>, - ) -> Result<(), ZxdgToplevelDecorationV1Error> { - let _req: UnsetMode = self.client.parse(&**self, parser)?; + fn unset_mode(&self, _req: UnsetMode, _slf: &Rc) -> Result<(), Self::Error> { self.do_send_configure(); Ok(()) } @@ -78,10 +75,7 @@ impl ZxdgToplevelDecorationV1 { object_base! { self = ZxdgToplevelDecorationV1; - - DESTROY => destroy, - SET_MODE => set_mode, - UNSET_MODE => unset_mode, + version = self.version; } impl Object for ZxdgToplevelDecorationV1 {} @@ -90,10 +84,7 @@ simple_add_obj!(ZxdgToplevelDecorationV1); #[derive(Debug, Error)] pub enum ZxdgToplevelDecorationV1Error { - #[error("Parsing failed")] - MsgParserError(#[source] Box), #[error(transparent)] ClientError(Box), } efrom!(ZxdgToplevelDecorationV1Error, ClientError); -efrom!(ZxdgToplevelDecorationV1Error, MsgParserError); diff --git a/src/macros.rs b/src/macros.rs index ebd28cd3..9c79ee1e 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -52,38 +52,27 @@ macro_rules! usr_object_base { } macro_rules! object_base { - ($self:ident = $oname:ident; $($code:ident => $f:ident $(if $cond:expr)?,)*) => { + ($self:ident = $oname:ident; version = $version:expr;) => { impl crate::object::ObjectBase for $oname { fn id(&$self) -> crate::object::ObjectId { $self.id.into() } + fn version(&$self) -> crate::object::Version { + $version + } + fn into_any($self: std::rc::Rc) -> std::rc::Rc { $self } - #[allow(unused_variables, unreachable_code)] fn handle_request( $self: std::rc::Rc, + client: &crate::client::Client, request: u32, parser: crate::utils::buffd::MsgParser<'_, '_>, ) -> Result<(), crate::client::ClientError> { - let res: Result<(), crate::client::MethodError> = match request { - $( - $code $(if $cond)? => $oname::$f(&$self, parser).map_err(|e| crate::client::MethodError { - method: stringify!($f), - error: Box::new(e), - }), - )* - _ => return Err(crate::client::ClientError::InvalidMethod), - }; - if let Err(e) = res { - return Err(crate::client::ClientError::ObjectError(crate::client::ObjectError { - interface: crate::wire::$oname, - error: Box::new(e), - })); - } - Ok(()) + $self.handle_request_impl(client, request, parser) } fn interface(&$self) -> crate::object::Interface { diff --git a/src/object.rs b/src/object.rs index 21a827e3..ee19f454 100644 --- a/src/object.rs +++ b/src/object.rs @@ -1,5 +1,9 @@ use { - crate::{client::ClientError, utils::buffd::MsgParser, wire::WlDisplayId}, + crate::{ + client::{Client, ClientError}, + utils::buffd::MsgParser, + wire::WlDisplayId, + }, std::{ any::Any, cmp::Ordering, @@ -34,9 +38,11 @@ impl Display for ObjectId { pub trait ObjectBase { fn id(&self) -> ObjectId; + fn version(&self) -> Version; fn into_any(self: Rc) -> Rc; fn handle_request( self: Rc, + client: &Client, request: u32, parser: MsgParser<'_, '_>, ) -> Result<(), ClientError>;