compositor: update to new wayland-server
This commit is contained in:
parent
bb86b1c3ed
commit
33f80a622f
|
@ -1,28 +0,0 @@
|
||||||
use super::{CompositorHandler, Handler as UserHandler, Role, RoleType, SubsurfaceRole};
|
|
||||||
|
|
||||||
use wayland_server::{Client, EventLoopHandle, GlobalHandler};
|
|
||||||
use wayland_server::protocol::{wl_compositor, wl_subcompositor};
|
|
||||||
|
|
||||||
impl<U, R, H> GlobalHandler<wl_compositor::WlCompositor> for CompositorHandler<U, R, H>
|
|
||||||
where
|
|
||||||
U: Default + Send + 'static,
|
|
||||||
R: Default + Send + 'static,
|
|
||||||
H: UserHandler<U, R> + Send + 'static,
|
|
||||||
{
|
|
||||||
fn bind(&mut self, evlh: &mut EventLoopHandle, _: &Client, global: wl_compositor::WlCompositor) {
|
|
||||||
debug!(self.log, "New compositor global binded.");
|
|
||||||
evlh.register::<_, CompositorHandler<U, R, H>>(&global, self.my_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<U, R, H> GlobalHandler<wl_subcompositor::WlSubcompositor> for CompositorHandler<U, R, H>
|
|
||||||
where
|
|
||||||
U: Send + 'static,
|
|
||||||
R: RoleType + Role<SubsurfaceRole> + Send + 'static,
|
|
||||||
H: Send + 'static,
|
|
||||||
{
|
|
||||||
fn bind(&mut self, evlh: &mut EventLoopHandle, _: &Client, global: wl_subcompositor::WlSubcompositor) {
|
|
||||||
debug!(self.log, "New subcompositor global binded.");
|
|
||||||
evlh.register::<_, CompositorHandler<U, R, H>>(&global, self.my_id);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,66 +1,101 @@
|
||||||
use super::{CompositorHandler, Damage, Handler as UserHandler, Rectangle, RectangleKind, Role, RoleType,
|
use super::{CompositorToken, Damage, Rectangle, RectangleKind, Role, RoleType, SubsurfaceRole,
|
||||||
SubsurfaceRole};
|
SurfaceUserImplementation};
|
||||||
use super::region::RegionData;
|
use super::region::RegionData;
|
||||||
use super::tree::{Location, SurfaceData};
|
use super::tree::{Location, SurfaceData};
|
||||||
use wayland_server::{Client, Destroy, EventLoopHandle, Liveness, Resource};
|
use std::cell::RefCell;
|
||||||
use wayland_server::protocol::{wl_buffer, wl_callback, wl_compositor, wl_output, wl_region,
|
use std::rc::Rc;
|
||||||
wl_subcompositor, wl_subsurface, wl_surface};
|
use wayland_server::{Client, EventLoopHandle, Liveness, Resource};
|
||||||
|
use wayland_server::protocol::{wl_compositor, wl_region, wl_subcompositor, wl_subsurface, wl_surface};
|
||||||
struct CompositorDestructor<U, R> {
|
|
||||||
_t: ::std::marker::PhantomData<U>,
|
|
||||||
_r: ::std::marker::PhantomData<R>,
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* wl_compositor
|
* wl_compositor
|
||||||
*/
|
*/
|
||||||
|
|
||||||
impl<U, R, H> wl_compositor::Handler for CompositorHandler<U, R, H>
|
pub(crate) fn compositor_bind<U, R, ID>(evlh: &mut EventLoopHandle, idata: &mut SurfaceIData<U, R, ID>,
|
||||||
|
_: &Client, compositor: wl_compositor::WlCompositor)
|
||||||
where
|
where
|
||||||
U: Default + Send + 'static,
|
U: Default + 'static,
|
||||||
R: Default + Send + 'static,
|
R: Default + 'static,
|
||||||
H: UserHandler<U, R> + Send + 'static,
|
ID: 'static,
|
||||||
{
|
{
|
||||||
fn create_surface(&mut self, evqh: &mut EventLoopHandle, _: &Client, _: &wl_compositor::WlCompositor,
|
trace!(idata.log, "Binding a new wl_compositor.");
|
||||||
id: wl_surface::WlSurface) {
|
evlh.register(
|
||||||
trace!(self.log, "New surface created.");
|
&compositor,
|
||||||
unsafe { SurfaceData::<U, R>::init(&id) };
|
compositor_implementation::<U, R, ID>(),
|
||||||
evqh.register_with_destructor::<_, CompositorHandler<U, R, H>, CompositorDestructor<U, R>>(
|
idata.clone(),
|
||||||
&id,
|
None,
|
||||||
self.my_id,
|
);
|
||||||
);
|
|
||||||
}
|
|
||||||
fn create_region(&mut self, evqh: &mut EventLoopHandle, _: &Client, _: &wl_compositor::WlCompositor,
|
|
||||||
id: wl_region::WlRegion) {
|
|
||||||
trace!(self.log, "New region created.");
|
|
||||||
unsafe { RegionData::init(&id) };
|
|
||||||
evqh.register_with_destructor::<_, CompositorHandler<U, R, H>, CompositorDestructor<U, R>>(
|
|
||||||
&id,
|
|
||||||
self.my_id,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
server_declare_handler!(CompositorHandler<U: [Default, Send], R: [Default, Send], H: [UserHandler<U, R>, Send]>, wl_compositor::Handler, wl_compositor::WlCompositor);
|
fn compositor_implementation<U, R, ID>() -> wl_compositor::Implementation<SurfaceIData<U, R, ID>>
|
||||||
|
where
|
||||||
|
U: Default + 'static,
|
||||||
|
R: Default + 'static,
|
||||||
|
ID: 'static,
|
||||||
|
{
|
||||||
|
wl_compositor::Implementation {
|
||||||
|
create_surface: |evlh, idata, _, _, surface| {
|
||||||
|
unsafe { SurfaceData::<U, R>::init(&surface) };
|
||||||
|
evlh.register(
|
||||||
|
&surface,
|
||||||
|
surface_implementation::<U, R, ID>(),
|
||||||
|
idata.clone(),
|
||||||
|
Some(destroy_surface::<U, R>),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
create_region: |evlh, _, _, _, region| {
|
||||||
|
unsafe { RegionData::init(®ion) };
|
||||||
|
evlh.register(®ion, region_implementation(), (), Some(destroy_region));
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* wl_surface
|
* wl_surface
|
||||||
*/
|
*/
|
||||||
|
|
||||||
impl<U, R, H: UserHandler<U, R>> wl_surface::Handler for CompositorHandler<U, R, H> {
|
/// Internal implementation data of surfaces
|
||||||
fn attach(&mut self, _: &mut EventLoopHandle, _: &Client, surface: &wl_surface::WlSurface,
|
///
|
||||||
buffer: Option<&wl_buffer::WlBuffer>, x: i32, y: i32) {
|
/// This type is only visible as type parameter of
|
||||||
trace!(self.log, "Attaching buffer to surface.");
|
/// the `Global` handle you are provided.
|
||||||
unsafe {
|
pub struct SurfaceIData<U, R, ID> {
|
||||||
|
log: ::slog::Logger,
|
||||||
|
implem: SurfaceUserImplementation<U, R, ID>,
|
||||||
|
idata: Rc<RefCell<ID>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<U, R, ID> SurfaceIData<U, R, ID> {
|
||||||
|
pub(crate) fn make(log: ::slog::Logger, implem: SurfaceUserImplementation<U, R, ID>, idata: ID)
|
||||||
|
-> SurfaceIData<U, R, ID> {
|
||||||
|
SurfaceIData {
|
||||||
|
log: log,
|
||||||
|
implem: implem,
|
||||||
|
idata: Rc::new(RefCell::new(idata)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<U, R, ID> Clone for SurfaceIData<U, R, ID> {
|
||||||
|
fn clone(&self) -> SurfaceIData<U, R, ID> {
|
||||||
|
SurfaceIData {
|
||||||
|
log: self.log.clone(),
|
||||||
|
implem: self.implem.clone(),
|
||||||
|
idata: self.idata.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn surface_implementation<U: 'static, R: 'static, ID: 'static>(
|
||||||
|
)
|
||||||
|
-> wl_surface::Implementation<SurfaceIData<U, R, ID>>
|
||||||
|
{
|
||||||
|
wl_surface::Implementation {
|
||||||
|
attach: |_, _, _, surface, buffer, x, y| unsafe {
|
||||||
SurfaceData::<U, R>::with_data(surface, |d| {
|
SurfaceData::<U, R>::with_data(surface, |d| {
|
||||||
d.buffer = Some(buffer.map(|b| (b.clone_unchecked(), (x, y))))
|
d.buffer = Some(buffer.map(|b| (b.clone_unchecked(), (x, y))))
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
}
|
damage: |_, _, _, surface, x, y, width, height| unsafe {
|
||||||
fn damage(&mut self, _: &mut EventLoopHandle, _: &Client, surface: &wl_surface::WlSurface, x: i32,
|
|
||||||
y: i32, width: i32, height: i32) {
|
|
||||||
trace!(self.log, "Registering damage to surface.");
|
|
||||||
unsafe {
|
|
||||||
SurfaceData::<U, R>::with_data(surface, |d| {
|
SurfaceData::<U, R>::with_data(surface, |d| {
|
||||||
d.damage = Damage::Surface(Rectangle {
|
d.damage = Damage::Surface(Rectangle {
|
||||||
x,
|
x,
|
||||||
|
@ -69,56 +104,38 @@ impl<U, R, H: UserHandler<U, R>> wl_surface::Handler for CompositorHandler<U, R,
|
||||||
height,
|
height,
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
}
|
frame: |evlh, idata, _, surface, callback| {
|
||||||
fn frame(&mut self, evlh: &mut EventLoopHandle, client: &Client, surface: &wl_surface::WlSurface,
|
let mut user_idata = idata.idata.borrow_mut();
|
||||||
callback: wl_callback::WlCallback) {
|
trace!(idata.log, "Calling user callback for wl_surface.frame");
|
||||||
trace!(self.log, "Frame surface callback.");
|
(idata.implem.frame)(
|
||||||
let token = self.get_token();
|
evlh,
|
||||||
UserHandler::frame(&mut self.handler, evlh, client, surface, callback, token);
|
&mut *user_idata,
|
||||||
}
|
surface,
|
||||||
fn set_opaque_region(&mut self, _: &mut EventLoopHandle, _: &Client, surface: &wl_surface::WlSurface,
|
callback,
|
||||||
region: Option<&wl_region::WlRegion>) {
|
CompositorToken::make(),
|
||||||
trace!(self.log, "Setting surface opaque region.");
|
)
|
||||||
unsafe {
|
},
|
||||||
|
set_opaque_region: |_, _, _, surface, region| unsafe {
|
||||||
let attributes = region.map(|r| RegionData::get_attributes(r));
|
let attributes = region.map(|r| RegionData::get_attributes(r));
|
||||||
SurfaceData::<U, R>::with_data(surface, |d| d.opaque_region = attributes);
|
SurfaceData::<U, R>::with_data(surface, |d| d.opaque_region = attributes);
|
||||||
}
|
},
|
||||||
}
|
set_input_region: |_, _, _, surface, region| unsafe {
|
||||||
fn set_input_region(&mut self, _: &mut EventLoopHandle, _: &Client, surface: &wl_surface::WlSurface,
|
|
||||||
region: Option<&wl_region::WlRegion>) {
|
|
||||||
trace!(self.log, "Setting surface input region.");
|
|
||||||
unsafe {
|
|
||||||
let attributes = region.map(|r| RegionData::get_attributes(r));
|
let attributes = region.map(|r| RegionData::get_attributes(r));
|
||||||
SurfaceData::<U, R>::with_data(surface, |d| d.input_region = attributes);
|
SurfaceData::<U, R>::with_data(surface, |d| d.input_region = attributes);
|
||||||
}
|
},
|
||||||
}
|
commit: |evlh, idata, _, surface| {
|
||||||
fn commit(&mut self, evlh: &mut EventLoopHandle, client: &Client, surface: &wl_surface::WlSurface) {
|
let mut user_idata = idata.idata.borrow_mut();
|
||||||
trace!(self.log, "Commit surface callback.");
|
trace!(idata.log, "Calling user callback for wl_surface.commit");
|
||||||
let token = self.get_token();
|
(idata.implem.commit)(evlh, &mut *user_idata, surface, CompositorToken::make())
|
||||||
UserHandler::commit(&mut self.handler, evlh, client, surface, token);
|
},
|
||||||
}
|
set_buffer_transform: |_, _, _, surface, transform| unsafe {
|
||||||
fn set_buffer_transform(&mut self, _: &mut EventLoopHandle, _: &Client,
|
|
||||||
surface: &wl_surface::WlSurface, transform: wl_output::Transform) {
|
|
||||||
trace!(self.log, "Setting surface's buffer transform.");
|
|
||||||
unsafe {
|
|
||||||
SurfaceData::<U, R>::with_data(surface, |d| d.buffer_transform = transform);
|
SurfaceData::<U, R>::with_data(surface, |d| d.buffer_transform = transform);
|
||||||
}
|
},
|
||||||
}
|
set_buffer_scale: |_, _, _, surface, scale| unsafe {
|
||||||
fn set_buffer_scale(&mut self, _: &mut EventLoopHandle, _: &Client, surface: &wl_surface::WlSurface,
|
|
||||||
scale: i32) {
|
|
||||||
trace!(self.log, "Setting surface's buffer scale.");
|
|
||||||
unsafe {
|
|
||||||
SurfaceData::<U, R>::with_data(surface, |d| d.buffer_scale = scale);
|
SurfaceData::<U, R>::with_data(surface, |d| d.buffer_scale = scale);
|
||||||
}
|
},
|
||||||
}
|
damage_buffer: |_, _, _, surface, x, y, width, height| unsafe {
|
||||||
fn damage_buffer(&mut self, _: &mut EventLoopHandle, _: &Client, surface: &wl_surface::WlSurface,
|
|
||||||
x: i32, y: i32, width: i32, height: i32) {
|
|
||||||
trace!(
|
|
||||||
self.log,
|
|
||||||
"Registering damage to surface (buffer coordinates)."
|
|
||||||
);
|
|
||||||
unsafe {
|
|
||||||
SurfaceData::<U, R>::with_data(surface, |d| {
|
SurfaceData::<U, R>::with_data(surface, |d| {
|
||||||
d.damage = Damage::Buffer(Rectangle {
|
d.damage = Damage::Buffer(Rectangle {
|
||||||
x,
|
x,
|
||||||
|
@ -127,97 +144,102 @@ impl<U, R, H: UserHandler<U, R>> wl_surface::Handler for CompositorHandler<U, R,
|
||||||
height,
|
height,
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
|
destroy: |_, _, _, _| {},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
server_declare_handler!(CompositorHandler<U:[], R: [], H: [UserHandler<U, R>]>, wl_surface::Handler, wl_surface::WlSurface);
|
fn destroy_surface<U: 'static, R: 'static>(surface: &wl_surface::WlSurface) {
|
||||||
|
unsafe { SurfaceData::<U, R>::cleanup(surface) }
|
||||||
impl<U, R> Destroy<wl_surface::WlSurface> for CompositorDestructor<U, R> {
|
|
||||||
fn destroy(surface: &wl_surface::WlSurface) {
|
|
||||||
unsafe { SurfaceData::<U, R>::cleanup(surface) }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* wl_region
|
* wl_region
|
||||||
*/
|
*/
|
||||||
|
|
||||||
impl<U, R, H> wl_region::Handler for CompositorHandler<U, R, H> {
|
pub(crate) fn region_implementation() -> wl_region::Implementation<()> {
|
||||||
fn add(&mut self, _: &mut EventLoopHandle, _: &Client, region: &wl_region::WlRegion, x: i32, y: i32,
|
wl_region::Implementation {
|
||||||
width: i32, height: i32) {
|
add: |_, _, _, region, x, y, width, height| {
|
||||||
trace!(self.log, "Adding rectangle to a region.");
|
unsafe {
|
||||||
unsafe {
|
RegionData::add_rectangle(
|
||||||
RegionData::add_rectangle(
|
region,
|
||||||
region,
|
RectangleKind::Add,
|
||||||
RectangleKind::Add,
|
Rectangle {
|
||||||
Rectangle {
|
x,
|
||||||
x,
|
y,
|
||||||
y,
|
width,
|
||||||
width,
|
height,
|
||||||
height,
|
},
|
||||||
},
|
)
|
||||||
)
|
};
|
||||||
};
|
},
|
||||||
}
|
subtract: |_, _, _, region, x, y, width, height| {
|
||||||
fn subtract(&mut self, _: &mut EventLoopHandle, _: &Client, region: &wl_region::WlRegion, x: i32,
|
unsafe {
|
||||||
y: i32, width: i32, height: i32) {
|
RegionData::add_rectangle(
|
||||||
trace!(self.log, "Subtracting rectangle to a region.");
|
region,
|
||||||
unsafe {
|
RectangleKind::Subtract,
|
||||||
RegionData::add_rectangle(
|
Rectangle {
|
||||||
region,
|
x,
|
||||||
RectangleKind::Subtract,
|
y,
|
||||||
Rectangle {
|
width,
|
||||||
x,
|
height,
|
||||||
y,
|
},
|
||||||
width,
|
)
|
||||||
height,
|
};
|
||||||
},
|
},
|
||||||
)
|
destroy: |_, _, _, _| {},
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
server_declare_handler!(CompositorHandler<U: [], R: [], H: []>, wl_region::Handler, wl_region::WlRegion);
|
fn destroy_region(region: &wl_region::WlRegion) {
|
||||||
|
unsafe { RegionData::cleanup(region) };
|
||||||
impl<U, R> Destroy<wl_region::WlRegion> for CompositorDestructor<U, R> {
|
|
||||||
fn destroy(region: &wl_region::WlRegion) {
|
|
||||||
unsafe { RegionData::cleanup(region) };
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* wl_subcompositor
|
* wl_subcompositor
|
||||||
*/
|
*/
|
||||||
|
|
||||||
impl<U, R, H> wl_subcompositor::Handler for CompositorHandler<U, R, H>
|
pub(crate) fn subcompositor_bind<U, R>(evlh: &mut EventLoopHandle, _: &mut (), _: &Client,
|
||||||
|
subcompositor: wl_subcompositor::WlSubcompositor)
|
||||||
where
|
where
|
||||||
U: Send + 'static,
|
R: RoleType + Role<SubsurfaceRole> + 'static,
|
||||||
R: RoleType + Role<SubsurfaceRole> + Send + 'static,
|
U: 'static,
|
||||||
H: Send + 'static,
|
|
||||||
{
|
{
|
||||||
fn get_subsurface(&mut self, evqh: &mut EventLoopHandle, _: &Client,
|
evlh.register(
|
||||||
resource: &wl_subcompositor::WlSubcompositor, id: wl_subsurface::WlSubsurface,
|
&subcompositor,
|
||||||
surface: &wl_surface::WlSurface, parent: &wl_surface::WlSurface) {
|
subcompositor_implementation::<U, R>(),
|
||||||
trace!(self.log, "Creating new subsurface.");
|
(),
|
||||||
if let Err(()) = unsafe { SurfaceData::<U, R>::set_parent(surface, parent) } {
|
None,
|
||||||
resource.post_error(
|
);
|
||||||
wl_subcompositor::Error::BadSurface as u32,
|
|
||||||
"Surface already has a role.".into(),
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
id.set_user_data(
|
|
||||||
Box::into_raw(Box::new(unsafe { surface.clone_unchecked() })) as *mut _,
|
|
||||||
);
|
|
||||||
evqh.register_with_destructor::<_, CompositorHandler<U, R, H>, CompositorDestructor<U, R>>(
|
|
||||||
&id,
|
|
||||||
self.my_id,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
server_declare_handler!(CompositorHandler<U: [Send], R: [RoleType, Role<SubsurfaceRole>, Send], H: [Send]>, wl_subcompositor::Handler, wl_subcompositor::WlSubcompositor);
|
fn subcompositor_implementation<U, R>() -> wl_subcompositor::Implementation<()>
|
||||||
|
where
|
||||||
|
R: RoleType + Role<SubsurfaceRole> + 'static,
|
||||||
|
U: 'static,
|
||||||
|
{
|
||||||
|
wl_subcompositor::Implementation {
|
||||||
|
get_subsurface: |evlh, _, _, subcompositor, subsurface, surface, parent| {
|
||||||
|
if let Err(()) = unsafe { SurfaceData::<U, R>::set_parent(surface, parent) } {
|
||||||
|
subcompositor.post_error(
|
||||||
|
wl_subcompositor::Error::BadSurface as u32,
|
||||||
|
"Surface already has a role.".into(),
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
subsurface.set_user_data(
|
||||||
|
Box::into_raw(Box::new(unsafe { surface.clone_unchecked() })) as *mut _,
|
||||||
|
);
|
||||||
|
evlh.register(
|
||||||
|
&subsurface,
|
||||||
|
subsurface_implementation::<U, R>(),
|
||||||
|
(),
|
||||||
|
Some(destroy_subsurface::<U, R>),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
destroy: |_, _, _, _| {},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* wl_subsurface
|
* wl_subsurface
|
||||||
|
@ -226,7 +248,8 @@ server_declare_handler!(CompositorHandler<U: [Send], R: [RoleType, Role<Subsurfa
|
||||||
unsafe fn with_subsurface_attributes<U, R, F>(subsurface: &wl_subsurface::WlSubsurface, f: F)
|
unsafe fn with_subsurface_attributes<U, R, F>(subsurface: &wl_subsurface::WlSubsurface, f: F)
|
||||||
where
|
where
|
||||||
F: FnOnce(&mut SubsurfaceRole),
|
F: FnOnce(&mut SubsurfaceRole),
|
||||||
R: RoleType + Role<SubsurfaceRole>,
|
U: 'static,
|
||||||
|
R: RoleType + Role<SubsurfaceRole> + 'static,
|
||||||
{
|
{
|
||||||
let ptr = subsurface.get_user_data();
|
let ptr = subsurface.get_user_data();
|
||||||
let surface = &*(ptr as *mut wl_surface::WlSurface);
|
let surface = &*(ptr as *mut wl_surface::WlSurface);
|
||||||
|
@ -235,24 +258,19 @@ where
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<U, R, H> wl_subsurface::Handler for CompositorHandler<U, R, H>
|
fn subsurface_implementation<U, R>() -> wl_subsurface::Implementation<()>
|
||||||
where
|
where
|
||||||
R: RoleType + Role<SubsurfaceRole>,
|
R: RoleType + Role<SubsurfaceRole> + 'static,
|
||||||
|
U: 'static,
|
||||||
{
|
{
|
||||||
fn set_position(&mut self, _: &mut EventLoopHandle, _: &Client,
|
wl_subsurface::Implementation {
|
||||||
subsurface: &wl_subsurface::WlSubsurface, x: i32, y: i32) {
|
set_position: |_, _, _, subsurface, x, y| unsafe {
|
||||||
trace!(self.log, "Setting subsurface position.");
|
|
||||||
unsafe {
|
|
||||||
with_subsurface_attributes::<U, R, _>(subsurface, |attrs| {
|
with_subsurface_attributes::<U, R, _>(subsurface, |attrs| {
|
||||||
attrs.x = x;
|
attrs.x = x;
|
||||||
attrs.y = y;
|
attrs.y = y;
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
}
|
place_above: |_, _, _, subsurface, sibling| unsafe {
|
||||||
fn place_above(&mut self, _: &mut EventLoopHandle, _: &Client,
|
|
||||||
subsurface: &wl_subsurface::WlSubsurface, sibling: &wl_surface::WlSurface) {
|
|
||||||
trace!(self.log, "Setting subsurface above an other.");
|
|
||||||
unsafe {
|
|
||||||
let ptr = subsurface.get_user_data();
|
let ptr = subsurface.get_user_data();
|
||||||
let surface = &*(ptr as *mut wl_surface::WlSurface);
|
let surface = &*(ptr as *mut wl_surface::WlSurface);
|
||||||
if let Err(()) = SurfaceData::<U, R>::reorder(surface, Location::After, sibling) {
|
if let Err(()) = SurfaceData::<U, R>::reorder(surface, Location::After, sibling) {
|
||||||
|
@ -261,12 +279,8 @@ where
|
||||||
"Provided surface is not a sibling or parent.".into(),
|
"Provided surface is not a sibling or parent.".into(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
place_below: |_, _, _, subsurface, sibling| unsafe {
|
||||||
fn place_below(&mut self, _: &mut EventLoopHandle, _: &Client,
|
|
||||||
subsurface: &wl_subsurface::WlSubsurface, sibling: &wl_surface::WlSurface) {
|
|
||||||
trace!(self.log, "Setting subsurface below an other.");
|
|
||||||
unsafe {
|
|
||||||
let ptr = subsurface.get_user_data();
|
let ptr = subsurface.get_user_data();
|
||||||
let surface = &*(ptr as *mut wl_surface::WlSurface);
|
let surface = &*(ptr as *mut wl_surface::WlSurface);
|
||||||
if let Err(()) = SurfaceData::<U, R>::reorder(surface, Location::Before, sibling) {
|
if let Err(()) = SurfaceData::<U, R>::reorder(surface, Location::Before, sibling) {
|
||||||
|
@ -275,36 +289,32 @@ where
|
||||||
"Provided surface is not a sibling or parent.".into(),
|
"Provided surface is not a sibling or parent.".into(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
set_sync: |_, _, _, subsurface| unsafe {
|
||||||
fn set_sync(&mut self, _: &mut EventLoopHandle, _: &Client, subsurface: &wl_subsurface::WlSubsurface) {
|
with_subsurface_attributes::<U, R, _>(subsurface, |attrs| {
|
||||||
trace!(self.log, "Setting subsurface sync."; "sync_status" => true);
|
attrs.sync = true;
|
||||||
unsafe {
|
});
|
||||||
with_subsurface_attributes::<U, R, _>(subsurface, |attrs| { attrs.sync = true; });
|
},
|
||||||
}
|
set_desync: |_, _, _, subsurface| unsafe {
|
||||||
}
|
with_subsurface_attributes::<U, R, _>(subsurface, |attrs| {
|
||||||
fn set_desync(&mut self, _: &mut EventLoopHandle, _: &Client, subsurface: &wl_subsurface::WlSubsurface) {
|
attrs.sync = false;
|
||||||
trace!(self.log, "Setting subsurface sync."; "sync_status" => false);
|
});
|
||||||
unsafe {
|
},
|
||||||
with_subsurface_attributes::<U, R, _>(subsurface, |attrs| { attrs.sync = false; });
|
destroy: |_, _, _, _| {},
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
server_declare_handler!(CompositorHandler<U: [], R: [RoleType, Role<SubsurfaceRole>], H: []>, wl_subsurface::Handler, wl_subsurface::WlSubsurface);
|
fn destroy_subsurface<U, R>(subsurface: &wl_subsurface::WlSubsurface)
|
||||||
|
|
||||||
impl<U, R> Destroy<wl_subsurface::WlSubsurface> for CompositorDestructor<U, R>
|
|
||||||
where
|
where
|
||||||
R: RoleType + Role<SubsurfaceRole>,
|
U: 'static,
|
||||||
|
R: RoleType + Role<SubsurfaceRole> + 'static,
|
||||||
{
|
{
|
||||||
fn destroy(subsurface: &wl_subsurface::WlSubsurface) {
|
let ptr = subsurface.get_user_data();
|
||||||
let ptr = subsurface.get_user_data();
|
subsurface.set_user_data(::std::ptr::null_mut());
|
||||||
subsurface.set_user_data(::std::ptr::null_mut());
|
unsafe {
|
||||||
unsafe {
|
let surface = Box::from_raw(ptr as *mut wl_surface::WlSurface);
|
||||||
let surface = Box::from_raw(ptr as *mut wl_surface::WlSurface);
|
if surface.status() == Liveness::Alive {
|
||||||
if surface.status() == Liveness::Alive {
|
SurfaceData::<U, R>::unset_parent(&surface);
|
||||||
SurfaceData::<U, R>::unset_parent(&surface);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
//! Utilities for handling surfaces, subsurfaces and regions
|
//! Utilities for handling surfaces, subsurfaces and regions
|
||||||
//!
|
//!
|
||||||
//! This module provides the `CompositorHandler<U,H>` type, with implements
|
//! This module provides automatic handling of sufaces, subsurfaces
|
||||||
//! automatic handling of sufaces, subsurfaces and region wayland objects,
|
//! and region wayland objects, by registering an implementation for
|
||||||
//! by being registered as a global handler for `wl_compositor` and
|
//! for the `wl_compositor` and `wl_subcompositor` globals.
|
||||||
//! `wl_subcompositor`.
|
|
||||||
//!
|
//!
|
||||||
//! ## Why use this handler
|
//! ## Why use this implementation
|
||||||
//!
|
//!
|
||||||
//! This handler does a simple job: it stores in a coherent way the state of
|
//! This implementation does a simple job: it stores in a coherent way the state of
|
||||||
//! surface trees with subsurfaces, to provide you a direct access to the tree
|
//! surface trees with subsurfaces, to provide you a direct access to the tree
|
||||||
//! structure and all surface metadata.
|
//! structure and all surface metadata.
|
||||||
//!
|
//!
|
||||||
|
@ -15,7 +14,7 @@
|
||||||
//! you can iterate over the whole tree of subsurfaces to recover all the metadata you
|
//! you can iterate over the whole tree of subsurfaces to recover all the metadata you
|
||||||
//! need to display the subsurface tree.
|
//! need to display the subsurface tree.
|
||||||
//!
|
//!
|
||||||
//! This handler will not do anything more than present you the metadata specified by the
|
//! This implementation will not do anything more than present you the metadata specified by the
|
||||||
//! client in a coherent and practical way. All the logic regarding to drawing itself, and
|
//! client in a coherent and practical way. All the logic regarding to drawing itself, and
|
||||||
//! the positionning of windows (surface trees) one relative to another is out of its scope.
|
//! the positionning of windows (surface trees) one relative to another is out of its scope.
|
||||||
//!
|
//!
|
||||||
|
@ -23,15 +22,16 @@
|
||||||
//!
|
//!
|
||||||
//! ### Initialization
|
//! ### Initialization
|
||||||
//!
|
//!
|
||||||
//! To initialize this handler, simply instanciate it and register it to the event loop
|
//! To initialize this implementation, use the `compositor_init` method provided
|
||||||
//! as a global handler for wl_compositor and wl_subcompositor:
|
//! by this module. It'll require you to first define as few things, as shown in
|
||||||
|
//! this example:
|
||||||
//!
|
//!
|
||||||
//! ```
|
//! ```
|
||||||
//! # extern crate wayland_server;
|
//! # extern crate wayland_server;
|
||||||
//! # #[macro_use] extern crate smithay;
|
//! # #[macro_use] extern crate smithay;
|
||||||
//! use wayland_server::protocol::wl_compositor::WlCompositor;
|
//! use wayland_server::protocol::wl_compositor::WlCompositor;
|
||||||
//! use wayland_server::protocol::wl_subcompositor::WlSubcompositor;
|
//! use wayland_server::protocol::wl_subcompositor::WlSubcompositor;
|
||||||
//! use smithay::compositor;
|
//! use smithay::compositor::{compositor_init, SurfaceUserImplementation};
|
||||||
//!
|
//!
|
||||||
//! // Define some user data to be associated with the surfaces.
|
//! // Define some user data to be associated with the surfaces.
|
||||||
//! // It must implement the Default trait, which will represent the state of a surface which
|
//! // It must implement the Default trait, which will represent the state of a surface which
|
||||||
|
@ -44,39 +44,25 @@
|
||||||
//! // Declare the roles enum
|
//! // Declare the roles enum
|
||||||
//! define_roles!(MyRoles);
|
//! define_roles!(MyRoles);
|
||||||
//!
|
//!
|
||||||
//! // Define a sub-handler to take care of the events the CompositorHandler does not rack for you
|
|
||||||
//! struct MyHandler {
|
|
||||||
//! // whatever you need
|
|
||||||
//! }
|
|
||||||
//!
|
|
||||||
//! // Implement the handler trait for this sub-handler
|
|
||||||
//! impl compositor::Handler<MyData, MyRoles> for MyHandler {
|
|
||||||
//! // See the trait documentation for its implementation
|
|
||||||
//! // A default implementation for each method is provided, that does nothing
|
|
||||||
//! }
|
|
||||||
//!
|
|
||||||
//! // A type alias to shorten things:
|
|
||||||
//! type MyCompositorHandler = compositor::CompositorHandler<MyData, MyRoles, MyHandler>;
|
|
||||||
//!
|
|
||||||
//! # fn main() {
|
//! # fn main() {
|
||||||
//! # let (_display, mut event_loop) = wayland_server::create_display();
|
//! # let (_display, mut event_loop) = wayland_server::create_display();
|
||||||
|
//! // define your implementation for surface
|
||||||
|
//! let my_implementation = SurfaceUserImplementation {
|
||||||
|
//! commit: |evlh, idata, surface, token| { /* ... */ },
|
||||||
|
//! frame: |evlh, idata, surface, callback, token| { /* ... */ }
|
||||||
|
//! };
|
||||||
|
//! // define your implementation data
|
||||||
|
//! let my_implementation_data = ();
|
||||||
//!
|
//!
|
||||||
//! // Instanciate the CompositorHandler and give it to the event loop
|
//! // Call the init function:
|
||||||
//! let compositor_hid = event_loop.add_handler_with_init(
|
//! let (token, _, _) = compositor_init::<MyData, MyRoles, _, _>(
|
||||||
//! MyCompositorHandler::new(MyHandler{ /* ... */ }, None /* put a logger here */)
|
//! &mut event_loop,
|
||||||
|
//! my_implementation, // instance of compositor::SurfaceUserImplementation
|
||||||
|
//! my_implementation_data, // whatever implementation data you need
|
||||||
|
//! None // put a logger here
|
||||||
//! );
|
//! );
|
||||||
//!
|
//!
|
||||||
//! // Register it as a handler for wl_compositor
|
//! // this `token` is what you'll use to access the surface associated data
|
||||||
//! event_loop.register_global::<WlCompositor, MyCompositorHandler>(compositor_hid, 4);
|
|
||||||
//!
|
|
||||||
//! // Register it as a handler for wl_subcompositor
|
|
||||||
//! event_loop.register_global::<WlSubcompositor, MyCompositorHandler>(compositor_hid, 1);
|
|
||||||
//!
|
|
||||||
//! // retrieve the token needed to access the surfaces' metadata
|
|
||||||
//! let compositor_token = {
|
|
||||||
//! let state = event_loop.state();
|
|
||||||
//! state.get_handler::<MyCompositorHandler>(compositor_hid).get_token()
|
|
||||||
//! };
|
|
||||||
//!
|
//!
|
||||||
//! // You're now ready to go!
|
//! // You're now ready to go!
|
||||||
//! # }
|
//! # }
|
||||||
|
@ -85,8 +71,9 @@
|
||||||
//! ### Use the surface metadata
|
//! ### Use the surface metadata
|
||||||
//!
|
//!
|
||||||
//! As you can see in the previous example, in the end we are retrieving a token from
|
//! As you can see in the previous example, in the end we are retrieving a token from
|
||||||
//! the `CompositorHandler`. This token is necessary to retrieve the metadata associated with
|
//! the init function. This token is necessary to retrieve the metadata associated with
|
||||||
//! a surface. It can be cloned, and is sendable accross threads. See `CompositorToken` for
|
//! a surface. It can be cloned, and is sendable accross threads (as long as your
|
||||||
|
//! `Mydata` and `MyRoles` are `Send` too). See `CompositorToken` for
|
||||||
//! the details of what it enables you.
|
//! the details of what it enables you.
|
||||||
//!
|
//!
|
||||||
//! The surface metadata is held in the `SurfaceAttributes` struct. In contains double-buffered
|
//! The surface metadata is held in the `SurfaceAttributes` struct. In contains double-buffered
|
||||||
|
@ -97,19 +84,19 @@
|
||||||
//! This `CompositorToken` also provides access to the metadata associated with the role of the
|
//! This `CompositorToken` also provides access to the metadata associated with the role of the
|
||||||
//! surfaces. See the documentation of the `roles` submodule for a detailed explanation.
|
//! surfaces. See the documentation of the `roles` submodule for a detailed explanation.
|
||||||
|
|
||||||
mod global;
|
|
||||||
mod handlers;
|
mod handlers;
|
||||||
mod tree;
|
mod tree;
|
||||||
mod region;
|
mod region;
|
||||||
pub mod roles;
|
pub mod roles;
|
||||||
|
|
||||||
|
pub use self::handlers::SurfaceIData;
|
||||||
use self::region::RegionData;
|
use self::region::RegionData;
|
||||||
use self::roles::{Role, RoleType, WrongRole};
|
use self::roles::{Role, RoleType, WrongRole};
|
||||||
use self::tree::SurfaceData;
|
use self::tree::SurfaceData;
|
||||||
pub use self::tree::TraversalAction;
|
pub use self::tree::TraversalAction;
|
||||||
use wayland_server::{resource_is_registered, Client, EventLoopHandle, Init};
|
use wayland_server::{resource_is_registered, EventLoop, EventLoopHandle, Global};
|
||||||
|
use wayland_server::protocol::{wl_buffer, wl_callback, wl_compositor, wl_output, wl_region,
|
||||||
use wayland_server::protocol::{wl_buffer, wl_callback, wl_output, wl_region, wl_surface};
|
wl_subcompositor, wl_surface};
|
||||||
|
|
||||||
/// Description of which part of a surface
|
/// Description of which part of a surface
|
||||||
/// should be considered damaged and needs to be redrawn
|
/// should be considered damaged and needs to be redrawn
|
||||||
|
@ -124,6 +111,12 @@ pub enum Damage {
|
||||||
Buffer(Rectangle),
|
Buffer(Rectangle),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Default)]
|
||||||
|
struct Marker<U, R> {
|
||||||
|
_u: ::std::marker::PhantomData<U>,
|
||||||
|
_r: ::std::marker::PhantomData<R>,
|
||||||
|
}
|
||||||
|
|
||||||
/// Data associated with a surface, aggreged by the handlers
|
/// Data associated with a surface, aggreged by the handlers
|
||||||
///
|
///
|
||||||
/// Most of the fields of this struct represent a double-buffered state, which
|
/// Most of the fields of this struct represent a double-buffered state, which
|
||||||
|
@ -261,26 +254,35 @@ impl Default for RegionAttributes {
|
||||||
/// This token can be cloned at will, and is the entry-point to
|
/// This token can be cloned at will, and is the entry-point to
|
||||||
/// access data associated with the wl_surface and wl_region managed
|
/// access data associated with the wl_surface and wl_region managed
|
||||||
/// by the `CompositorGlobal` that provided it.
|
/// by the `CompositorGlobal` that provided it.
|
||||||
pub struct CompositorToken<U, R, H> {
|
pub struct CompositorToken<U, R, ID> {
|
||||||
hid: usize,
|
|
||||||
_data: ::std::marker::PhantomData<*mut U>,
|
_data: ::std::marker::PhantomData<*mut U>,
|
||||||
_role: ::std::marker::PhantomData<*mut R>,
|
_role: ::std::marker::PhantomData<*mut R>,
|
||||||
_handler: ::std::marker::PhantomData<*mut H>,
|
_idata: ::std::marker::PhantomData<*mut ID>,
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl<U: Send, R: Send, H: Send> Send for CompositorToken<U, R, H> {}
|
unsafe impl<U: Send, R: Send, ID> Send for CompositorToken<U, R, ID> {}
|
||||||
unsafe impl<U: Send, R: Send, H: Send> Sync for CompositorToken<U, R, H> {}
|
unsafe impl<U: Send, R: Send, ID> Sync for CompositorToken<U, R, ID> {}
|
||||||
|
|
||||||
// we implement them manually because #[derive(..)] would require
|
// we implement them manually because #[derive(..)] would require
|
||||||
// U: Clone and H: Clone ...
|
// U: Clone and R: Clone
|
||||||
impl<U, R, H> Copy for CompositorToken<U, R, H> {}
|
impl<U, R, ID> Copy for CompositorToken<U, R, ID> {}
|
||||||
impl<U, R, H> Clone for CompositorToken<U, R, H> {
|
impl<U, R, ID> Clone for CompositorToken<U, R, ID> {
|
||||||
fn clone(&self) -> CompositorToken<U, R, H> {
|
fn clone(&self) -> CompositorToken<U, R, ID> {
|
||||||
*self
|
*self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<U: Send + 'static, R: Send + 'static, H: Handler<U, R> + Send + 'static> CompositorToken<U, R, H> {
|
impl<U, R, ID> CompositorToken<U, R, ID> {
|
||||||
|
pub(crate) fn make() -> CompositorToken<U, R, ID> {
|
||||||
|
CompositorToken {
|
||||||
|
_data: ::std::marker::PhantomData,
|
||||||
|
_role: ::std::marker::PhantomData,
|
||||||
|
_idata: ::std::marker::PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<U: Send + 'static, R: Send + 'static, ID: 'static> CompositorToken<U, R, ID> {
|
||||||
/// Access the data of a surface
|
/// Access the data of a surface
|
||||||
///
|
///
|
||||||
/// The closure will be called with the contents of the data associated with this surface.
|
/// The closure will be called with the contents of the data associated with this surface.
|
||||||
|
@ -292,18 +294,21 @@ impl<U: Send + 'static, R: Send + 'static, H: Handler<U, R> + Send + 'static> Co
|
||||||
F: FnOnce(&mut SurfaceAttributes<U>) -> T,
|
F: FnOnce(&mut SurfaceAttributes<U>) -> T,
|
||||||
{
|
{
|
||||||
assert!(
|
assert!(
|
||||||
resource_is_registered::<_, CompositorHandler<U, R, H>>(surface, self.hid),
|
resource_is_registered(
|
||||||
|
surface,
|
||||||
|
&self::handlers::surface_implementation::<U, R, ID>()
|
||||||
|
),
|
||||||
"Accessing the data of foreign surfaces is not supported."
|
"Accessing the data of foreign surfaces is not supported."
|
||||||
);
|
);
|
||||||
unsafe { SurfaceData::<U, R>::with_data(surface, f) }
|
unsafe { SurfaceData::<U, R>::with_data(surface, f) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<U, R, H> CompositorToken<U, R, H>
|
impl<U, R, ID> CompositorToken<U, R, ID>
|
||||||
where
|
where
|
||||||
U: Send + 'static,
|
U: 'static,
|
||||||
R: RoleType + Role<SubsurfaceRole> + Send + 'static,
|
R: RoleType + Role<SubsurfaceRole> + 'static,
|
||||||
H: Handler<U, R> + Send + 'static,
|
ID: 'static,
|
||||||
{
|
{
|
||||||
/// Access the data of a surface tree
|
/// Access the data of a surface tree
|
||||||
///
|
///
|
||||||
|
@ -327,7 +332,10 @@ where
|
||||||
-> TraversalAction<T>,
|
-> TraversalAction<T>,
|
||||||
{
|
{
|
||||||
assert!(
|
assert!(
|
||||||
resource_is_registered::<_, CompositorHandler<U, R, H>>(surface, self.hid),
|
resource_is_registered(
|
||||||
|
surface,
|
||||||
|
&self::handlers::surface_implementation::<U, R, ID>()
|
||||||
|
),
|
||||||
"Accessing the data of foreign surfaces is not supported."
|
"Accessing the data of foreign surfaces is not supported."
|
||||||
);
|
);
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -344,7 +352,10 @@ where
|
||||||
/// will panic (having more than one compositor is not supported).
|
/// will panic (having more than one compositor is not supported).
|
||||||
pub fn get_parent(&self, surface: &wl_surface::WlSurface) -> Option<wl_surface::WlSurface> {
|
pub fn get_parent(&self, surface: &wl_surface::WlSurface) -> Option<wl_surface::WlSurface> {
|
||||||
assert!(
|
assert!(
|
||||||
resource_is_registered::<_, CompositorHandler<U, R, H>>(surface, self.hid),
|
resource_is_registered(
|
||||||
|
surface,
|
||||||
|
&self::handlers::surface_implementation::<U, R, ID>()
|
||||||
|
),
|
||||||
"Accessing the data of foreign surfaces is not supported."
|
"Accessing the data of foreign surfaces is not supported."
|
||||||
);
|
);
|
||||||
unsafe { SurfaceData::<U, R>::get_parent(surface) }
|
unsafe { SurfaceData::<U, R>::get_parent(surface) }
|
||||||
|
@ -356,22 +367,27 @@ where
|
||||||
/// will panic (having more than one compositor is not supported).
|
/// will panic (having more than one compositor is not supported).
|
||||||
pub fn get_children(&self, surface: &wl_surface::WlSurface) -> Vec<wl_surface::WlSurface> {
|
pub fn get_children(&self, surface: &wl_surface::WlSurface) -> Vec<wl_surface::WlSurface> {
|
||||||
assert!(
|
assert!(
|
||||||
resource_is_registered::<_, CompositorHandler<U, R, H>>(surface, self.hid),
|
resource_is_registered(
|
||||||
|
surface,
|
||||||
|
&self::handlers::surface_implementation::<U, R, ID>()
|
||||||
|
),
|
||||||
"Accessing the data of foreign surfaces is not supported."
|
"Accessing the data of foreign surfaces is not supported."
|
||||||
);
|
);
|
||||||
unsafe { SurfaceData::<U, R>::get_children(surface) }
|
unsafe { SurfaceData::<U, R>::get_children(surface) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<U: Send + 'static, R: Send + RoleType + 'static, H: Handler<U, R> + Send + 'static>
|
impl<U: 'static, R: RoleType + 'static, ID: 'static> CompositorToken<U, R, ID> {
|
||||||
CompositorToken<U, R, H> {
|
|
||||||
/// Check wether this surface as a role or not
|
/// Check wether this surface as a role or not
|
||||||
///
|
///
|
||||||
/// If the surface is not managed by the CompositorGlobal that provided this token, this
|
/// If the surface is not managed by the CompositorGlobal that provided this token, this
|
||||||
/// will panic (having more than one compositor is not supported).
|
/// will panic (having more than one compositor is not supported).
|
||||||
pub fn has_a_role(&self, surface: &wl_surface::WlSurface) -> bool {
|
pub fn has_a_role(&self, surface: &wl_surface::WlSurface) -> bool {
|
||||||
assert!(
|
assert!(
|
||||||
resource_is_registered::<_, CompositorHandler<U, R, H>>(surface, self.hid),
|
resource_is_registered(
|
||||||
|
surface,
|
||||||
|
&self::handlers::surface_implementation::<U, R, ID>()
|
||||||
|
),
|
||||||
"Accessing the data of foreign surfaces is not supported."
|
"Accessing the data of foreign surfaces is not supported."
|
||||||
);
|
);
|
||||||
unsafe { SurfaceData::<U, R>::has_a_role(surface) }
|
unsafe { SurfaceData::<U, R>::has_a_role(surface) }
|
||||||
|
@ -386,7 +402,10 @@ impl<U: Send + 'static, R: Send + RoleType + 'static, H: Handler<U, R> + Send +
|
||||||
R: Role<RoleData>,
|
R: Role<RoleData>,
|
||||||
{
|
{
|
||||||
assert!(
|
assert!(
|
||||||
resource_is_registered::<_, CompositorHandler<U, R, H>>(surface, self.hid),
|
resource_is_registered(
|
||||||
|
surface,
|
||||||
|
&self::handlers::surface_implementation::<U, R, ID>()
|
||||||
|
),
|
||||||
"Accessing the data of foreign surfaces is not supported."
|
"Accessing the data of foreign surfaces is not supported."
|
||||||
);
|
);
|
||||||
unsafe { SurfaceData::<U, R>::has_role::<RoleData>(surface) }
|
unsafe { SurfaceData::<U, R>::has_role::<RoleData>(surface) }
|
||||||
|
@ -405,7 +424,10 @@ impl<U: Send + 'static, R: Send + RoleType + 'static, H: Handler<U, R> + Send +
|
||||||
RoleData: Default,
|
RoleData: Default,
|
||||||
{
|
{
|
||||||
assert!(
|
assert!(
|
||||||
resource_is_registered::<_, CompositorHandler<U, R, H>>(surface, self.hid),
|
resource_is_registered(
|
||||||
|
surface,
|
||||||
|
&self::handlers::surface_implementation::<U, R, ID>()
|
||||||
|
),
|
||||||
"Accessing the data of foreign surfaces is not supported."
|
"Accessing the data of foreign surfaces is not supported."
|
||||||
);
|
);
|
||||||
unsafe { SurfaceData::<U, R>::give_role::<RoleData>(surface) }
|
unsafe { SurfaceData::<U, R>::give_role::<RoleData>(surface) }
|
||||||
|
@ -423,7 +445,10 @@ impl<U: Send + 'static, R: Send + RoleType + 'static, H: Handler<U, R> + Send +
|
||||||
R: Role<RoleData>,
|
R: Role<RoleData>,
|
||||||
{
|
{
|
||||||
assert!(
|
assert!(
|
||||||
resource_is_registered::<_, CompositorHandler<U, R, H>>(surface, self.hid),
|
resource_is_registered(
|
||||||
|
surface,
|
||||||
|
&self::handlers::surface_implementation::<U, R, ID>()
|
||||||
|
),
|
||||||
"Accessing the data of foreign surfaces is not supported."
|
"Accessing the data of foreign surfaces is not supported."
|
||||||
);
|
);
|
||||||
unsafe { SurfaceData::<U, R>::give_role_with::<RoleData>(surface, data) }
|
unsafe { SurfaceData::<U, R>::give_role_with::<RoleData>(surface, data) }
|
||||||
|
@ -442,7 +467,10 @@ impl<U: Send + 'static, R: Send + RoleType + 'static, H: Handler<U, R> + Send +
|
||||||
F: FnOnce(&mut RoleData) -> T,
|
F: FnOnce(&mut RoleData) -> T,
|
||||||
{
|
{
|
||||||
assert!(
|
assert!(
|
||||||
resource_is_registered::<_, CompositorHandler<U, R, H>>(surface, self.hid),
|
resource_is_registered(
|
||||||
|
surface,
|
||||||
|
&self::handlers::surface_implementation::<U, R, ID>()
|
||||||
|
),
|
||||||
"Accessing the data of foreign surfaces is not supported."
|
"Accessing the data of foreign surfaces is not supported."
|
||||||
);
|
);
|
||||||
unsafe { SurfaceData::<U, R>::with_role_data::<RoleData, _, _>(surface, f) }
|
unsafe { SurfaceData::<U, R>::with_role_data::<RoleData, _, _>(surface, f) }
|
||||||
|
@ -459,7 +487,10 @@ impl<U: Send + 'static, R: Send + RoleType + 'static, H: Handler<U, R> + Send +
|
||||||
R: Role<RoleData>,
|
R: Role<RoleData>,
|
||||||
{
|
{
|
||||||
assert!(
|
assert!(
|
||||||
resource_is_registered::<_, CompositorHandler<U, R, H>>(surface, self.hid),
|
resource_is_registered(
|
||||||
|
surface,
|
||||||
|
&self::handlers::surface_implementation::<U, R, ID>()
|
||||||
|
),
|
||||||
"Accessing the data of foreign surfaces is not supported."
|
"Accessing the data of foreign surfaces is not supported."
|
||||||
);
|
);
|
||||||
unsafe { SurfaceData::<U, R>::remove_role::<RoleData>(surface) }
|
unsafe { SurfaceData::<U, R>::remove_role::<RoleData>(surface) }
|
||||||
|
@ -471,98 +502,93 @@ impl<U: Send + 'static, R: Send + RoleType + 'static, H: Handler<U, R> + Send +
|
||||||
/// will panic (having more than one compositor is not supported).
|
/// will panic (having more than one compositor is not supported).
|
||||||
pub fn get_region_attributes(&self, region: &wl_region::WlRegion) -> RegionAttributes {
|
pub fn get_region_attributes(&self, region: &wl_region::WlRegion) -> RegionAttributes {
|
||||||
assert!(
|
assert!(
|
||||||
resource_is_registered::<_, CompositorHandler<U, R, H>>(region, self.hid),
|
resource_is_registered(region, &self::handlers::region_implementation()),
|
||||||
"Accessing the data of foreign regions is not supported."
|
"Accessing the data of foreign surfaces is not supported."
|
||||||
);
|
);
|
||||||
unsafe { RegionData::get_attributes(region) }
|
unsafe { RegionData::get_attributes(region) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A struct handling the `wl_compositor` and `wl_subcompositor` globals
|
/// Create new wl_compositor and wl_subcompositor globals.
|
||||||
///
|
///
|
||||||
/// It allows you to choose a custom `U` type to store data you want
|
/// The globals are directly registered into the eventloop, and this function
|
||||||
/// associated with the surfaces in their metadata, as well a providing
|
/// returns a `CompositorToken` which you'll need access the data associated to
|
||||||
/// a sub-handler to handle the events defined by the `Handler` trait
|
/// the `wl_surface`s.
|
||||||
/// defined in this module.
|
|
||||||
///
|
///
|
||||||
/// See the module-level documentation for instructions and examples of use.
|
/// It also returns the two global handles, in case you whish to remove these
|
||||||
pub struct CompositorHandler<U, R, H> {
|
/// globals from the event loop in the future.
|
||||||
my_id: usize,
|
pub fn compositor_init<U, R, ID, L>(
|
||||||
log: ::slog::Logger,
|
evl: &mut EventLoop, implem: SurfaceUserImplementation<U, R, ID>, idata: ID, logger: L)
|
||||||
handler: H,
|
-> (
|
||||||
_role: ::std::marker::PhantomData<R>,
|
CompositorToken<U, R, ID>,
|
||||||
_data: ::std::marker::PhantomData<U>,
|
Global<wl_compositor::WlCompositor, self::handlers::SurfaceIData<U, R, ID>>,
|
||||||
|
Global<wl_subcompositor::WlSubcompositor, ()>,
|
||||||
|
)
|
||||||
|
where
|
||||||
|
L: Into<Option<::slog::Logger>>,
|
||||||
|
U: Default + 'static,
|
||||||
|
R: Default + RoleType + Role<SubsurfaceRole> + 'static,
|
||||||
|
ID: 'static,
|
||||||
|
{
|
||||||
|
let log = ::slog_or_stdlog(logger);
|
||||||
|
let idata = self::handlers::SurfaceIData::make(
|
||||||
|
log.new(o!("smithay_module" => "compositor_handler")),
|
||||||
|
implem,
|
||||||
|
idata,
|
||||||
|
);
|
||||||
|
let compositor_global_token =
|
||||||
|
evl.register_global::<wl_compositor::WlCompositor, _>(4, self::handlers::compositor_bind, idata);
|
||||||
|
let subcompositor_global_token = evl.register_global::<wl_subcompositor::WlSubcompositor, _>(
|
||||||
|
1,
|
||||||
|
self::handlers::subcompositor_bind::<U, R>,
|
||||||
|
(),
|
||||||
|
);
|
||||||
|
|
||||||
|
(
|
||||||
|
CompositorToken::make(),
|
||||||
|
compositor_global_token,
|
||||||
|
subcompositor_global_token,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<U, R, H> Init for CompositorHandler<U, R, H> {
|
/// Sub-implementation for surface event handling
|
||||||
fn init(&mut self, _evqh: &mut EventLoopHandle, index: usize) {
|
|
||||||
self.my_id = index;
|
|
||||||
debug!(self.log, "Init finished")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<U, R, H> CompositorHandler<U, R, H> {
|
|
||||||
/// Create a new CompositorHandler
|
|
||||||
pub fn new<L>(handler: H, logger: L) -> CompositorHandler<U, R, H>
|
|
||||||
where
|
|
||||||
L: Into<Option<::slog::Logger>>,
|
|
||||||
{
|
|
||||||
let log = ::slog_or_stdlog(logger);
|
|
||||||
CompositorHandler {
|
|
||||||
my_id: ::std::usize::MAX,
|
|
||||||
log: log.new(o!("smithay_module" => "compositor_handler")),
|
|
||||||
handler: handler,
|
|
||||||
_role: ::std::marker::PhantomData,
|
|
||||||
_data: ::std::marker::PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Create a token to access the data associated to the objects managed by this handler.
|
|
||||||
pub fn get_token(&self) -> CompositorToken<U, R, H> {
|
|
||||||
assert!(
|
|
||||||
self.my_id != ::std::usize::MAX,
|
|
||||||
"CompositorHandler is not initialized yet."
|
|
||||||
);
|
|
||||||
trace!(self.log, "Creating a compositor token.");
|
|
||||||
CompositorToken {
|
|
||||||
hid: self.my_id,
|
|
||||||
_data: ::std::marker::PhantomData,
|
|
||||||
_role: ::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
|
/// 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
|
/// are forwarded directly to this implementation that you must provide
|
||||||
/// at creation of the `CompositorHandler`.
|
/// at creation of the compositor global.
|
||||||
#[allow(unused_variables)]
|
pub struct SurfaceUserImplementation<U, R, ID> {
|
||||||
pub trait Handler<U, R>: Sized {
|
|
||||||
/// The double-buffered state has been validated by the client
|
/// The double-buffered state has been validated by the client
|
||||||
///
|
///
|
||||||
/// At this point, the pending state that has been accumulated in the `SurfaceAttributes` associated
|
/// At this point, the pending state that has been accumulated in the `SurfaceAttributes` associated
|
||||||
/// to this surface should be integrated into the current state of the surface.
|
/// to this surface should be integrated into the current state of the surface.
|
||||||
///
|
///
|
||||||
/// See [`wayland_server::protocol::wl_surface::Handler::commit`](https://docs.rs/wayland-server/*/wayland_server/protocol/wl_surface/trait.Handler.html#method.commit)
|
/// See [`wayland_server::protocol::wl_surface::Implementation::commit`](https://docs.rs/wayland-server/0.10.1/wayland_server/protocol/wl_surface/struct.Implementation.html#structfield.commit)
|
||||||
/// for more details
|
/// for more details
|
||||||
fn commit(&mut self, evlh: &mut EventLoopHandle, client: &Client, surface: &wl_surface::WlSurface,
|
pub commit: fn(
|
||||||
token: CompositorToken<U, R, Self>) {
|
evlh: &mut EventLoopHandle,
|
||||||
}
|
idata: &mut ID,
|
||||||
|
surface: &wl_surface::WlSurface,
|
||||||
|
token: CompositorToken<U, R, ID>,
|
||||||
|
),
|
||||||
/// The client asks to be notified when would be a good time to update the contents of this surface
|
/// The client asks to be notified when would be a good time to update the contents of this surface
|
||||||
///
|
///
|
||||||
/// You must keep the provided `WlCallback` and trigger it at the appropriate time by calling
|
/// You must keep the provided `WlCallback` and trigger it at the appropriate time by calling
|
||||||
/// its `done()` method.
|
/// its `done()` method.
|
||||||
///
|
///
|
||||||
/// See [`wayland_server::protocol::wl_surface::Handler::frame`](https://docs.rs/wayland-server/*/wayland_server/protocol/wl_surface/trait.Handler.html#method.frame)
|
/// See [`wayland_server::protocol::wl_surface::Implementation::frame`](https://docs.rs/wayland-server/0.10.1/wayland_server/protocol/wl_surface/struct.Implementation.html#structfield.frame)
|
||||||
/// for more details
|
/// for more details
|
||||||
fn frame(&mut self, evlh: &mut EventLoopHandle, client: &Client, surface: &wl_surface::WlSurface,
|
pub frame: fn(
|
||||||
callback: wl_callback::WlCallback, token: CompositorToken<U, R, Self>) {
|
evlh: &mut EventLoopHandle,
|
||||||
|
idata: &mut ID,
|
||||||
|
surface: &wl_surface::WlSurface,
|
||||||
|
callback: wl_callback::WlCallback,
|
||||||
|
token: CompositorToken<U, R, ID>,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<U, R, ID> Copy for SurfaceUserImplementation<U, R, ID> {}
|
||||||
|
impl<U, R, ID> Clone for SurfaceUserImplementation<U, R, ID> {
|
||||||
|
fn clone(&self) -> SurfaceUserImplementation<U, R, ID> {
|
||||||
|
*self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
use super::{Rectangle, RectangleKind, RegionAttributes};
|
use super::{Rectangle, RectangleKind, RegionAttributes};
|
||||||
|
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
use wayland_server::Resource;
|
use wayland_server::Resource;
|
||||||
|
|
||||||
use wayland_server::protocol::wl_region;
|
use wayland_server::protocol::wl_region;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
|
@ -13,9 +11,8 @@ pub struct RegionData {
|
||||||
impl RegionData {
|
impl RegionData {
|
||||||
/// Initialize the user_data of a region, must be called right when the surface is created
|
/// Initialize the user_data of a region, must be called right when the surface is created
|
||||||
pub unsafe fn init(region: &wl_region::WlRegion) {
|
pub unsafe fn init(region: &wl_region::WlRegion) {
|
||||||
region.set_user_data(
|
region.set_user_data(Box::into_raw(Box::new(Mutex::new(RegionData::default())))
|
||||||
Box::into_raw(Box::new(Mutex::new(RegionData::default()))) as *mut _,
|
as *mut _)
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Cleans the user_data of that surface, must be called when it is destroyed
|
/// Cleans the user_data of that surface, must be called when it is destroyed
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use super::{SubsurfaceRole, SurfaceAttributes};
|
use super::{SubsurfaceRole, SurfaceAttributes};
|
||||||
use super::roles::*;
|
use super::roles::*;
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
|
|
||||||
use wayland_server::{Liveness, Resource};
|
use wayland_server::{Liveness, Resource};
|
||||||
use wayland_server::protocol::wl_surface;
|
use wayland_server::protocol::wl_surface;
|
||||||
|
|
||||||
|
@ -64,7 +63,11 @@ impl<U: Default, R: Default> SurfaceData<U, R> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<U, R> SurfaceData<U, R> {
|
impl<U, R> SurfaceData<U, R>
|
||||||
|
where
|
||||||
|
U: 'static,
|
||||||
|
R: 'static,
|
||||||
|
{
|
||||||
unsafe fn get_data(surface: &wl_surface::WlSurface) -> &Mutex<SurfaceData<U, R>> {
|
unsafe fn get_data(surface: &wl_surface::WlSurface) -> &Mutex<SurfaceData<U, R>> {
|
||||||
let ptr = surface.get_user_data();
|
let ptr = surface.get_user_data();
|
||||||
&*(ptr as *mut _)
|
&*(ptr as *mut _)
|
||||||
|
@ -97,7 +100,7 @@ impl<U, R> SurfaceData<U, R> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<U, R: RoleType> SurfaceData<U, R> {
|
impl<U: 'static, R: RoleType + 'static> SurfaceData<U, R> {
|
||||||
pub unsafe fn has_a_role(surface: &wl_surface::WlSurface) -> bool {
|
pub unsafe fn has_a_role(surface: &wl_surface::WlSurface) -> bool {
|
||||||
debug_assert!(surface.status() == Liveness::Alive);
|
debug_assert!(surface.status() == Liveness::Alive);
|
||||||
let data_mutex = Self::get_data(surface);
|
let data_mutex = Self::get_data(surface);
|
||||||
|
@ -171,7 +174,7 @@ impl<U, R: RoleType> SurfaceData<U, R> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<U, R: RoleType + Role<SubsurfaceRole>> SurfaceData<U, R> {
|
impl<U: 'static, R: RoleType + Role<SubsurfaceRole> + 'static> SurfaceData<U, R> {
|
||||||
/// Sets the parent of a surface
|
/// Sets the parent of a surface
|
||||||
///
|
///
|
||||||
/// if this surface already has a role, does nothing and fails, otherwise
|
/// if this surface already has a role, does nothing and fails, otherwise
|
||||||
|
@ -291,7 +294,7 @@ impl<U, R: RoleType + Role<SubsurfaceRole>> SurfaceData<U, R> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<U, R> SurfaceData<U, R> {
|
impl<U: 'static, R: 'static> SurfaceData<U, R> {
|
||||||
/// Access the attributes associated with a surface
|
/// Access the attributes associated with a surface
|
||||||
///
|
///
|
||||||
/// Note that an internal lock is taken during access of this data,
|
/// Note that an internal lock is taken during access of this data,
|
||||||
|
@ -319,9 +322,9 @@ impl<U, R> SurfaceData<U, R> {
|
||||||
-> TraversalAction<T>,
|
-> TraversalAction<T>,
|
||||||
{
|
{
|
||||||
// helper function for recursion
|
// helper function for recursion
|
||||||
unsafe fn map<U, R, F, T>(surface: &wl_surface::WlSurface, root: &wl_surface::WlSurface,
|
unsafe fn map<U: 'static, R: 'static, F, T>(surface: &wl_surface::WlSurface,
|
||||||
initial: &T, f: &mut F)
|
root: &wl_surface::WlSurface, initial: &T, f: &mut F)
|
||||||
-> bool
|
-> bool
|
||||||
where
|
where
|
||||||
F: FnMut(&wl_surface::WlSurface, &mut SurfaceAttributes<U>, &mut R, &T)
|
F: FnMut(&wl_surface::WlSurface, &mut SurfaceAttributes<U>, &mut R, &T)
|
||||||
-> TraversalAction<T>,
|
-> TraversalAction<T>,
|
||||||
|
|
|
@ -32,7 +32,7 @@ extern crate slog;
|
||||||
extern crate slog_stdlog;
|
extern crate slog_stdlog;
|
||||||
|
|
||||||
pub mod backend;
|
pub mod backend;
|
||||||
//pub mod compositor;
|
pub mod compositor;
|
||||||
pub mod shm;
|
pub mod shm;
|
||||||
pub mod keyboard;
|
pub mod keyboard;
|
||||||
//pub mod shell;
|
//pub mod shell;
|
||||||
|
|
Loading…
Reference in New Issue