From 1e960af5f27039bc39dba44eeb0149e45dc0fcf4 Mon Sep 17 00:00:00 2001 From: Victor Berger Date: Sun, 4 Jun 2017 22:12:22 +0200 Subject: [PATCH] Add subhandler for wl_surface.{commit,frame} --- src/compositor/global.rs | 18 +++--- src/compositor/handlers.rs | 116 ++++++++++++++++++++++--------------- src/compositor/mod.rs | 80 +++++++++++++++---------- src/compositor/region.rs | 2 +- 4 files changed, 129 insertions(+), 87 deletions(-) diff --git a/src/compositor/global.rs b/src/compositor/global.rs index 788e12e..a5cd9c9 100644 --- a/src/compositor/global.rs +++ b/src/compositor/global.rs @@ -1,20 +1,22 @@ -use super::CompositorHandler; +use super::{CompositorHandler, Handler as UserHandler}; -use wayland_server::{Client, EventLoopHandle, GlobalHandler, Init}; +use wayland_server::{Client, EventLoopHandle, GlobalHandler}; use wayland_server::protocol::{wl_compositor, wl_subcompositor}; -impl GlobalHandler for CompositorHandler - where U: Send + Sync + 'static +impl GlobalHandler for CompositorHandler + where U: Send + 'static, + H: Send + 'static { fn bind(&mut self, evlh: &mut EventLoopHandle, _: &Client, global: wl_compositor::WlCompositor) { - evlh.register::<_, CompositorHandler>(&global, self.my_id); + evlh.register::<_, CompositorHandler>(&global, self.my_id); } } -impl GlobalHandler for CompositorHandler - where U: Send + Sync + 'static +impl GlobalHandler for CompositorHandler + where U: Send + 'static, + H: Send + 'static { fn bind(&mut self, evlh: &mut EventLoopHandle, _: &Client, global: wl_subcompositor::WlSubcompositor) { - evlh.register::<_, CompositorHandler>(&global, self.my_id); + evlh.register::<_, CompositorHandler>(&global, self.my_id); } } diff --git a/src/compositor/handlers.rs b/src/compositor/handlers.rs index b52d76f..73b210e 100644 --- a/src/compositor/handlers.rs +++ b/src/compositor/handlers.rs @@ -1,8 +1,8 @@ -use super::{Rectangle, RectangleKind, SubsurfaceAttributes, Damage, CompositorHandler}; +use super::{CompositorHandler, Damage, Handler as UserHandler, Rectangle, RectangleKind, + SubsurfaceAttributes}; use super::region::RegionData; use super::tree::SurfaceData; -use super::CompositorToken; -use wayland_server::{Client, Destroy, EventLoopHandle, Init, Resource}; +use wayland_server::{Client, Destroy, EventLoopHandle, Resource}; use wayland_server::protocol::{wl_buffer, wl_callback, wl_compositor, wl_output, wl_region, wl_subcompositor, wl_subsurface, wl_surface}; @@ -14,26 +14,31 @@ struct CompositorDestructor { * wl_compositor */ -impl wl_compositor::Handler for CompositorHandler { - fn create_surface(&mut self, evqh: &mut EventLoopHandle, _: &Client, - _: &wl_compositor::WlCompositor, id: wl_surface::WlSurface) { +impl wl_compositor::Handler for CompositorHandler + where U: Default + Send + 'static, + H: UserHandler + Send + 'static +{ + fn create_surface(&mut self, evqh: &mut EventLoopHandle, _: &Client, _: &wl_compositor::WlCompositor, + id: wl_surface::WlSurface) { unsafe { SurfaceData::::init(&id) }; - evqh.register_with_destructor::<_, CompositorHandler, CompositorDestructor>(&id, self.my_id); + evqh.register_with_destructor::<_, CompositorHandler, CompositorDestructor>(&id, self.my_id); } - fn create_region(&mut self, evqh: &mut EventLoopHandle, _: &Client, - _: &wl_compositor::WlCompositor, id: wl_region::WlRegion) { + fn create_region(&mut self, evqh: &mut EventLoopHandle, _: &Client, _: &wl_compositor::WlCompositor, + id: wl_region::WlRegion) { unsafe { RegionData::init(&id) }; - evqh.register_with_destructor::<_, CompositorHandler, CompositorDestructor>(&id, self.my_id); + evqh.register_with_destructor::<_, CompositorHandler, CompositorDestructor>(&id, self.my_id); } } -unsafe impl ::wayland_server::Handler - for CompositorHandler { +unsafe impl ::wayland_server::Handler for CompositorHandler + where U: Default + Send + 'static, + H: UserHandler + Send + 'static +{ unsafe fn message(&mut self, evq: &mut EventLoopHandle, client: &Client, resource: &wl_compositor::WlCompositor, opcode: u32, args: *const ::wayland_server::sys::wl_argument) -> Result<(), ()> { - as ::wayland_server::protocol::wl_compositor::Handler>::__message(self, evq, client, resource, opcode, args) + as ::wayland_server::protocol::wl_compositor::Handler>::__message(self, evq, client, resource, opcode, args) } } @@ -41,7 +46,7 @@ unsafe impl ::wayland_server::Handler wl_surface::Handler for CompositorHandler { +impl wl_surface::Handler for CompositorHandler { fn attach(&mut self, _: &mut EventLoopHandle, _: &Client, surface: &wl_surface::WlSurface, buffer: Option<&wl_buffer::WlBuffer>, x: i32, y: i32) { unsafe { @@ -52,13 +57,19 @@ impl wl_surface::Handler for CompositorHandler { fn damage(&mut self, _: &mut EventLoopHandle, _: &Client, surface: &wl_surface::WlSurface, x: i32, y: i32, width: i32, height: i32) { unsafe { - SurfaceData::::with_data(surface, - |d| d.damage = Damage::Surface(Rectangle { x, y, width, height })); + SurfaceData::::with_data(surface, |d| { + d.damage = Damage::Surface(Rectangle { + x, + y, + width, + height, + }) + }); } } - fn frame(&mut self, _: &mut EventLoopHandle, _: &Client, surface: &wl_surface::WlSurface, + fn frame(&mut self, evlh: &mut EventLoopHandle, client: &Client, surface: &wl_surface::WlSurface, callback: wl_callback::WlCallback) { - unimplemented!() + UserHandler::frame(&mut self.handler, evlh, client, surface, callback); } fn set_opaque_region(&mut self, _: &mut EventLoopHandle, _: &Client, surface: &wl_surface::WlSurface, region: Option<&wl_region::WlRegion>) { @@ -74,8 +85,8 @@ impl wl_surface::Handler for CompositorHandler { SurfaceData::::with_data(surface, |d| d.input_region = attributes); } } - fn commit(&mut self, _: &mut EventLoopHandle, _: &Client, surface: &wl_surface::WlSurface) { - unimplemented!() + fn commit(&mut self, evlh: &mut EventLoopHandle, client: &Client, surface: &wl_surface::WlSurface) { + UserHandler::commit(&mut self.handler, evlh, client, surface); } fn set_buffer_transform(&mut self, _: &mut EventLoopHandle, _: &Client, surface: &wl_surface::WlSurface, transform: wl_output::Transform) { @@ -92,18 +103,24 @@ impl wl_surface::Handler for CompositorHandler { fn damage_buffer(&mut self, _: &mut EventLoopHandle, _: &Client, surface: &wl_surface::WlSurface, x: i32, y: i32, width: i32, height: i32) { unsafe { - SurfaceData::::with_data(surface, - |d| d.damage = Damage::Buffer(Rectangle { x, y, width, height })); + SurfaceData::::with_data(surface, |d| { + d.damage = Damage::Buffer(Rectangle { + x, + y, + width, + height, + }) + }); } } } -unsafe impl ::wayland_server::Handler for CompositorHandler { +unsafe impl ::wayland_server::Handler for CompositorHandler { unsafe fn message(&mut self, evq: &mut EventLoopHandle, client: &Client, resource: &wl_surface::WlSurface, opcode: u32, args: *const ::wayland_server::sys::wl_argument) -> Result<(), ()> { - as ::wayland_server::protocol::wl_surface::Handler>::__message(self, evq, client, resource, opcode, args) + as ::wayland_server::protocol::wl_surface::Handler>::__message(self, evq, client, resource, opcode, args) } } @@ -117,11 +134,12 @@ impl Destroy for CompositorDestructor { * wl_region */ -impl wl_region::Handler for CompositorHandler { +impl wl_region::Handler for CompositorHandler { fn add(&mut self, _: &mut EventLoopHandle, _: &Client, region: &wl_region::WlRegion, x: i32, y: i32, width: i32, height: i32) { unsafe { - RegionData::add_rectangle(region, RectangleKind::Add, + RegionData::add_rectangle(region, + RectangleKind::Add, Rectangle { x, y, @@ -133,7 +151,8 @@ impl wl_region::Handler for CompositorHandler { fn subtract(&mut self, _: &mut EventLoopHandle, _: &Client, region: &wl_region::WlRegion, x: i32, y: i32, width: i32, height: i32) { unsafe { - RegionData::add_rectangle(region, RectangleKind::Subtract, + RegionData::add_rectangle(region, + RectangleKind::Subtract, Rectangle { x, y, @@ -144,12 +163,12 @@ impl wl_region::Handler for CompositorHandler { } } -unsafe impl ::wayland_server::Handler for CompositorHandler { +unsafe impl ::wayland_server::Handler for CompositorHandler { unsafe fn message(&mut self, evq: &mut EventLoopHandle, client: &Client, resource: &wl_region::WlRegion, opcode: u32, args: *const ::wayland_server::sys::wl_argument) -> Result<(), ()> { - as ::wayland_server::protocol::wl_region::Handler>::__message(self, evq, client, resource, opcode, args) + as ::wayland_server::protocol::wl_region::Handler>::__message(self, evq, client, resource, opcode, args) } } @@ -163,7 +182,10 @@ impl Destroy for CompositorDestructor { * wl_subcompositor */ -impl wl_subcompositor::Handler for CompositorHandler { +impl wl_subcompositor::Handler for CompositorHandler + where U: Send + 'static, + H: Send + 'static +{ fn get_subsurface(&mut self, evqh: &mut EventLoopHandle, _: &Client, resource: &wl_subcompositor::WlSubcompositor, id: wl_subsurface::WlSubsurface, surface: &wl_surface::WlSurface, parent: &wl_surface::WlSurface) { @@ -176,17 +198,19 @@ impl wl_subcompositor::Handler for CompositorHandler { SurfaceData::::with_data(surface, |d| d.subsurface_attributes = Some(Default::default())); } - evqh.register_with_destructor::<_, CompositorHandler, CompositorDestructor>(&id, self.my_id); + evqh.register_with_destructor::<_, CompositorHandler, CompositorDestructor>(&id, self.my_id); } } -unsafe impl ::wayland_server::Handler - for CompositorHandler { +unsafe impl ::wayland_server::Handler for CompositorHandler + where U: Send + 'static, + H: Send + 'static +{ unsafe fn message(&mut self, evq: &mut EventLoopHandle, client: &Client, resource: &wl_subcompositor::WlSubcompositor, opcode: u32, args: *const ::wayland_server::sys::wl_argument) -> Result<(), ()> { - as ::wayland_server::protocol::wl_subcompositor::Handler>::__message(self, evq, client, resource, opcode, args) + as ::wayland_server::protocol::wl_subcompositor::Handler>::__message(self, evq, client, resource, opcode, args) } } @@ -202,9 +226,9 @@ unsafe fn with_subsurface_attributes(subsurface: &wl_subsurface::WlSubsurf SurfaceData::::with_data(surface, |d| f(d.subsurface_attributes.as_mut().unwrap())); } -impl wl_subsurface::Handler for CompositorHandler { - fn set_position(&mut self, _: &mut EventLoopHandle, _: &Client, - resource: &wl_subsurface::WlSubsurface, x: i32, y: i32) { +impl wl_subsurface::Handler for CompositorHandler { + fn set_position(&mut self, _: &mut EventLoopHandle, _: &Client, resource: &wl_subsurface::WlSubsurface, + x: i32, y: i32) { unsafe { with_subsurface_attributes::(resource, |attrs| { attrs.x = x; @@ -212,34 +236,32 @@ impl wl_subsurface::Handler for CompositorHandler { }); } } - fn place_above(&mut self, _: &mut EventLoopHandle, _: &Client, - resource: &wl_subsurface::WlSubsurface, sibling: &wl_surface::WlSurface) { + fn place_above(&mut self, _: &mut EventLoopHandle, _: &Client, resource: &wl_subsurface::WlSubsurface, + sibling: &wl_surface::WlSurface) { unimplemented!() } - fn place_below(&mut self, _: &mut EventLoopHandle, _: &Client, - resource: &wl_subsurface::WlSubsurface, sibling: &wl_surface::WlSurface) { + fn place_below(&mut self, _: &mut EventLoopHandle, _: &Client, resource: &wl_subsurface::WlSubsurface, + sibling: &wl_surface::WlSurface) { unimplemented!() } - fn set_sync(&mut self, _: &mut EventLoopHandle, _: &Client, - resource: &wl_subsurface::WlSubsurface) { + fn set_sync(&mut self, _: &mut EventLoopHandle, _: &Client, resource: &wl_subsurface::WlSubsurface) { unsafe { with_subsurface_attributes::(resource, |attrs| { attrs.sync = true; }); } } - fn set_desync(&mut self, _: &mut EventLoopHandle, _: &Client, - resource: &wl_subsurface::WlSubsurface) { + fn set_desync(&mut self, _: &mut EventLoopHandle, _: &Client, resource: &wl_subsurface::WlSubsurface) { unsafe { with_subsurface_attributes::(resource, |attrs| { attrs.sync = false; }); } } } -unsafe impl ::wayland_server::Handler for CompositorHandler { +unsafe impl ::wayland_server::Handler for CompositorHandler { unsafe fn message(&mut self, evq: &mut EventLoopHandle, client: &Client, resource: &wl_subsurface::WlSubsurface, opcode: u32, args: *const ::wayland_server::sys::wl_argument) -> Result<(), ()> { - as ::wayland_server::protocol::wl_subsurface::Handler>::__message(self, evq, client, resource, opcode, args) + as ::wayland_server::protocol::wl_subsurface::Handler>::__message(self, evq, client, resource, opcode, args) } } diff --git a/src/compositor/mod.rs b/src/compositor/mod.rs index bd245e6..2af9f44 100644 --- a/src/compositor/mod.rs +++ b/src/compositor/mod.rs @@ -5,9 +5,9 @@ mod region; pub use self::tree::RoleStatus; use self::tree::SurfaceData; +use wayland_server::{Client, EventLoopHandle, Init, resource_is_registered}; -use wayland_server::protocol::{wl_buffer, wl_output, wl_surface}; -use wayland_server::{EventLoopHandle, resource_is_registered, Init}; +use wayland_server::protocol::{wl_buffer, wl_callback, wl_output, wl_surface}; /// Description of which part of a surface /// should be considered damaged and needs to be redrawn @@ -19,7 +19,7 @@ pub enum Damage { /// A rectangle containing the smaazed zone, in buffer coordinates /// /// Note: Buffer scaling must be taken into consideration - Buffer(Rectangle) + Buffer(Rectangle), } /// Data associated with a surface, aggreged by the handlers @@ -166,12 +166,13 @@ impl Default for RegionAttributes { /// access data associated with the wl_surface and wl_region managed /// by the `CompositorGlobal` that provided it. #[derive(Copy,Clone)] -pub struct CompositorToken { +pub struct CompositorToken { hid: usize, _data: ::std::marker::PhantomData<*mut U>, + _handler: ::std::marker::PhantomData<*mut H>, } -impl CompositorToken { +impl CompositorToken { /// Access the data of a surface /// /// The closure will be called with the contents of the data associated with this surface. @@ -181,7 +182,7 @@ impl CompositorToken { pub fn with_surface_data(&self, surface: &wl_surface::WlSurface, f: F) where F: FnOnce(&mut SurfaceAttributes) { - assert!(resource_is_registered::<_, CompositorHandler>(surface, self.hid), + assert!(resource_is_registered::<_, CompositorHandler>(surface, self.hid), "Accessing the data of foreign surfaces is not supported."); unsafe { SurfaceData::::with_data(surface, f); @@ -198,7 +199,7 @@ impl CompositorToken { pub fn with_surface_tree(&self, surface: &wl_surface::WlSurface, f: F) -> Result<(), ()> where F: FnMut(&wl_surface::WlSurface, &mut SurfaceAttributes) -> bool { - assert!(resource_is_registered::<_, CompositorHandler>(surface, self.hid), + assert!(resource_is_registered::<_, CompositorHandler>(surface, self.hid), "Accessing the data of foreign surfaces is not supported."); unsafe { SurfaceData::::map_tree(surface, f); @@ -213,23 +214,19 @@ impl CompositorToken { /// If the surface is not managed by the CompositorGlobal that provided this token, this /// will panic (having more than one compositor is not supported). pub fn get_parent(&self, surface: &wl_surface::WlSurface) -> Option { - assert!(resource_is_registered::<_, CompositorHandler>(surface, self.hid), + assert!(resource_is_registered::<_, CompositorHandler>(surface, self.hid), "Accessing the data of foreign surfaces is not supported."); - unsafe { - SurfaceData::::get_parent(surface) - } + unsafe { SurfaceData::::get_parent(surface) } } - + /// Retrieve the role status this surface /// /// If the surface is not managed by the CompositorGlobal that provided this token, this /// will panic (having more than one compositor is not supported). pub fn role_status(&self, surface: &wl_surface::WlSurface) -> RoleStatus { - assert!(resource_is_registered::<_, CompositorHandler>(surface, self.hid), + assert!(resource_is_registered::<_, CompositorHandler>(surface, self.hid), "Accessing the data of foreign surfaces is not supported."); - unsafe { - SurfaceData::::role_status(surface) - } + unsafe { SurfaceData::::role_status(surface) } } /// Register that this surface has a role @@ -241,12 +238,10 @@ impl CompositorToken { /// /// If the surface is not managed by the CompositorGlobal that provided this token, this /// will panic (having more than one compositor is not supported). - pub fn give_role(&self, surface: &wl_surface::WlSurface) -> Result<(),()> { - assert!(resource_is_registered::<_, CompositorHandler>(surface, self.hid), + pub fn give_role(&self, surface: &wl_surface::WlSurface) -> Result<(), ()> { + assert!(resource_is_registered::<_, CompositorHandler>(surface, self.hid), "Accessing the data of foreign surfaces is not supported."); - unsafe { - SurfaceData::::give_role(surface) - } + unsafe { SurfaceData::::give_role(surface) } } /// Register that this surface has no role @@ -257,44 +252,67 @@ impl CompositorToken { /// /// If the surface is not managed by the CompositorGlobal that provided this token, this /// will panic (having more than one compositor is not supported). - pub fn remove_role(&self, surface: &wl_surface::WlSurface) -> Result<(),()> { - assert!(resource_is_registered::<_, CompositorHandler>(surface, self.hid), + pub fn remove_role(&self, surface: &wl_surface::WlSurface) -> Result<(), ()> { + assert!(resource_is_registered::<_, CompositorHandler>(surface, self.hid), "Accessing the data of foreign surfaces is not supported."); - unsafe { - SurfaceData::::remove_role(surface) - } + unsafe { SurfaceData::::remove_role(surface) } } } -pub struct CompositorHandler { +pub struct CompositorHandler { my_id: usize, log: ::slog::Logger, + handler: H, _data: ::std::marker::PhantomData, } -impl Init for CompositorHandler { +impl Init for CompositorHandler { fn init(&mut self, _evqh: &mut EventLoopHandle, index: usize) { self.my_id = index; debug!(self.log, "Init finished") } } -impl CompositorHandler { - pub fn new(logger: L) -> CompositorHandler +impl CompositorHandler { + /// Create a new CompositorHandler + pub fn new(handler: H, logger: L) -> CompositorHandler where L: Into> { let log = ::slog_or_stdlog(logger); CompositorHandler { my_id: ::std::usize::MAX, log: log.new(o!("smithay_module" => "compositor_handler")), + handler: handler, _data: ::std::marker::PhantomData, } } - pub fn get_token(&self) -> CompositorToken { + /// Create a token to access the data associated to the objects managed by this handler. + pub fn get_token(&self) -> CompositorToken { + assert!(self.my_id != ::std::usize::MAX, + "CompositorHandler is not initialized yet."); CompositorToken { hid: self.my_id, _data: ::std::marker::PhantomData, + _handler: ::std::marker::PhantomData, } } + + /// Access the underlying sub-handler + pub fn get_handler(&mut self) -> &mut H { + &mut self.handler + } +} + +/// Sub-handler trait for surface event handling +/// +/// The global provided by Smithay cannot process these events for you, so they +/// are forwarded directly to a handler implementing this trait that you must provide +/// at creation of the `CompositorHandler`. +pub trait Handler { + /// See `wayland_server::protocol::wl_surface::Handler::commit` + fn commit(&mut self, evlh: &mut EventLoopHandle, client: &Client, surface: &wl_surface::WlSurface); + /// See `wayland_server::protocol::wl_surface::Handler::frame` + fn frame(&mut self, evlh: &mut EventLoopHandle, client: &Client, surface: &wl_surface::WlSurface, + callback: wl_callback::WlCallback); } diff --git a/src/compositor/region.rs b/src/compositor/region.rs index ff9ebd7..eb09e95 100644 --- a/src/compositor/region.rs +++ b/src/compositor/region.rs @@ -1,4 +1,4 @@ -use super::{Rectangle, RegionAttributes, RectangleKind}; +use super::{Rectangle, RectangleKind, RegionAttributes}; use std::sync::Mutex; use wayland_server::Resource;