wayland.shm: migrate to wayland_rs-0.20
This commit is contained in:
parent
570cee0987
commit
b9cac1a373
|
@ -49,7 +49,7 @@ extern crate error_chain;
|
||||||
extern crate lazy_static;
|
extern crate lazy_static;
|
||||||
|
|
||||||
//pub mod backend;
|
//pub mod backend;
|
||||||
//pub mod wayland;
|
pub mod wayland;
|
||||||
pub mod utils;
|
pub mod utils;
|
||||||
|
|
||||||
fn slog_or_stdlog<L>(logger: L) -> ::slog::Logger
|
fn slog_or_stdlog<L>(logger: L) -> ::slog::Logger
|
||||||
|
|
|
@ -18,8 +18,8 @@
|
||||||
//! not previously destroyed all the globals using it, otherwise you'll
|
//! not previously destroyed all the globals using it, otherwise you'll
|
||||||
//! quickly encounter a panic.
|
//! quickly encounter a panic.
|
||||||
|
|
||||||
pub mod compositor;
|
//pub mod compositor;
|
||||||
pub mod output;
|
//pub mod output;
|
||||||
pub mod seat;
|
//pub mod seat;
|
||||||
pub mod shm;
|
pub mod shm;
|
||||||
pub mod shell;
|
//pub mod shell;
|
||||||
|
|
|
@ -23,12 +23,13 @@
|
||||||
//! use wayland_server::protocol::wl_shm::Format;
|
//! use wayland_server::protocol::wl_shm::Format;
|
||||||
//!
|
//!
|
||||||
//! # fn main() {
|
//! # fn main() {
|
||||||
//! # let (display, mut event_loop) = wayland_server::create_display();
|
//! # let (mut display, mut event_loop) = wayland_server::Display::new();
|
||||||
//! // Insert the ShmGlobal into your event loop
|
//! // Insert the ShmGlobal into your event loop
|
||||||
//! // Here, we specify that Yuyv and C8 format are supported
|
//! // Here, we specify that Yuyv and C8 format are supported
|
||||||
//! // additionnaly to the standart Argb8888 and Xrgb8888.
|
//! // additionnaly to the standart Argb8888 and Xrgb8888.
|
||||||
//! let shm_global = init_shm_global(
|
//! let shm_global = init_shm_global(
|
||||||
//! &mut event_loop,
|
//! &mut display,
|
||||||
|
//! event_loop.token(),
|
||||||
//! vec![Format::Yuyv, Format::C8],
|
//! vec![Format::Yuyv, Format::C8],
|
||||||
//! None // we don't provide a logger here
|
//! None // we don't provide a logger here
|
||||||
//! );
|
//! );
|
||||||
|
@ -42,7 +43,8 @@
|
||||||
//! # extern crate wayland_server;
|
//! # extern crate wayland_server;
|
||||||
//! # extern crate smithay;
|
//! # extern crate smithay;
|
||||||
//! # use wayland_server::protocol::wl_buffer::WlBuffer;
|
//! # use wayland_server::protocol::wl_buffer::WlBuffer;
|
||||||
//! # fn wrap(buffer: &WlBuffer) {
|
//! # use wayland_server::Resource;
|
||||||
|
//! # fn wrap(buffer: &Resource<WlBuffer>) {
|
||||||
//! use smithay::wayland::shm::{with_buffer_contents, BufferData};
|
//! use smithay::wayland::shm::{with_buffer_contents, BufferData};
|
||||||
//!
|
//!
|
||||||
//! with_buffer_contents(&buffer,
|
//! with_buffer_contents(&buffer,
|
||||||
|
@ -64,7 +66,8 @@
|
||||||
use self::pool::{Pool, ResizeError};
|
use self::pool::{Pool, ResizeError};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use wayland_server::{resource_is_registered, Client, EventLoopHandle, Global, Resource};
|
use wayland_server::{Display, Global, LoopToken, NewResource, Resource};
|
||||||
|
use wayland_server::commons::Implementation;
|
||||||
use wayland_server::protocol::{wl_buffer, wl_shm, wl_shm_pool};
|
use wayland_server::protocol::{wl_buffer, wl_shm, wl_shm_pool};
|
||||||
|
|
||||||
mod pool;
|
mod pool;
|
||||||
|
@ -77,6 +80,7 @@ mod pool;
|
||||||
pub struct ShmGlobalData {
|
pub struct ShmGlobalData {
|
||||||
formats: Rc<Vec<wl_shm::Format>>,
|
formats: Rc<Vec<wl_shm::Format>>,
|
||||||
log: ::slog::Logger,
|
log: ::slog::Logger,
|
||||||
|
token: LoopToken,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new SHM global advertizing given supported formats.
|
/// Create a new SHM global advertizing given supported formats.
|
||||||
|
@ -85,12 +89,15 @@ pub struct ShmGlobalData {
|
||||||
/// as they are required by the protocol. Formats given as argument
|
/// as they are required by the protocol. Formats given as argument
|
||||||
/// as additionnaly advertized.
|
/// as additionnaly advertized.
|
||||||
///
|
///
|
||||||
/// The global is directly registered into the eventloop, and this function
|
/// The global is directly created on the provided `Display`, and this function
|
||||||
/// returns the global handle, in case you whish to remove this global in
|
/// returns the global handle, in case you whish to remove this global in
|
||||||
/// the future.
|
/// the future.
|
||||||
pub fn init_shm_global<L>(
|
pub fn init_shm_global<L>(
|
||||||
evlh: &mut EventLoopHandle, mut formats: Vec<wl_shm::Format>, logger: L
|
display: &mut Display,
|
||||||
) -> Global<wl_shm::WlShm, ShmGlobalData>
|
token: LoopToken,
|
||||||
|
mut formats: Vec<wl_shm::Format>,
|
||||||
|
logger: L,
|
||||||
|
) -> Global<wl_shm::WlShm>
|
||||||
where
|
where
|
||||||
L: Into<Option<::slog::Logger>>,
|
L: Into<Option<::slog::Logger>>,
|
||||||
{
|
{
|
||||||
|
@ -102,9 +109,16 @@ where
|
||||||
let data = ShmGlobalData {
|
let data = ShmGlobalData {
|
||||||
formats: Rc::new(formats),
|
formats: Rc::new(formats),
|
||||||
log: log.new(o!("smithay_module" => "shm_handler")),
|
log: log.new(o!("smithay_module" => "shm_handler")),
|
||||||
|
token: token.clone(),
|
||||||
};
|
};
|
||||||
|
|
||||||
evlh.register_global::<wl_shm::WlShm, _>(1, shm_global_bind, data)
|
display.create_global::<wl_shm::WlShm, _>(&token, 1, move |_version, shm_new: NewResource<_>| {
|
||||||
|
let shm = shm_new.implement_nonsend(data.clone(), None::<fn(_, _)>, &data.token);
|
||||||
|
// send the formats
|
||||||
|
for f in &data.formats[..] {
|
||||||
|
shm.send(wl_shm::Event::Format { format: *f });
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Error that can occur when accessing an SHM buffer
|
/// Error that can occur when accessing an SHM buffer
|
||||||
|
@ -131,11 +145,11 @@ pub enum BufferAccessError {
|
||||||
///
|
///
|
||||||
/// If the buffer is not managed by the provided `ShmGlobal`, the closure is not called
|
/// If the buffer is not managed by the provided `ShmGlobal`, the closure is not called
|
||||||
/// and this method will return `Err(())` (this will be the case for an EGL buffer for example).
|
/// and this method will return `Err(())` (this will be the case for an EGL buffer for example).
|
||||||
pub fn with_buffer_contents<F>(buffer: &wl_buffer::WlBuffer, f: F) -> Result<(), BufferAccessError>
|
pub fn with_buffer_contents<F>(buffer: &Resource<wl_buffer::WlBuffer>, f: F) -> Result<(), BufferAccessError>
|
||||||
where
|
where
|
||||||
F: FnOnce(&[u8], BufferData),
|
F: FnOnce(&[u8], BufferData),
|
||||||
{
|
{
|
||||||
if !resource_is_registered(buffer, &buffer_implementation()) {
|
if !buffer.is_implemented_with::<ShmGlobalData>() {
|
||||||
return Err(BufferAccessError::NotManaged);
|
return Err(BufferAccessError::NotManaged);
|
||||||
}
|
}
|
||||||
let data = unsafe { &*(buffer.get_user_data() as *mut InternalBufferData) };
|
let data = unsafe { &*(buffer.get_user_data() as *mut InternalBufferData) };
|
||||||
|
@ -151,52 +165,43 @@ where
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn shm_global_bind(evlh: &mut EventLoopHandle, data: &mut ShmGlobalData, _: &Client, global: wl_shm::WlShm) {
|
impl Implementation<Resource<wl_shm::WlShm>, wl_shm::Request> for ShmGlobalData {
|
||||||
// register an handler for this shm
|
fn receive(&mut self, request: wl_shm::Request, shm: Resource<wl_shm::WlShm>) {
|
||||||
evlh.register(&global, shm_implementation(), data.clone(), None);
|
use self::wl_shm::{Error, Request};
|
||||||
// and then the custom formats
|
|
||||||
for f in &data.formats[..] {
|
|
||||||
global.format(*f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn shm_implementation() -> wl_shm::Implementation<ShmGlobalData> {
|
match request {
|
||||||
wl_shm::Implementation {
|
Request::CreatePool { id: pool, fd, size } => {
|
||||||
create_pool: |evlh, data, _, shm, pool, fd, size| {
|
if size <= 0 {
|
||||||
if size <= 0 {
|
|
||||||
shm.post_error(
|
|
||||||
wl_shm::Error::InvalidFd as u32,
|
|
||||||
"Invalid size for a new wl_shm_pool.".into(),
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let mmap_pool = match Pool::new(fd, size as usize, data.log.clone()) {
|
|
||||||
Ok(p) => p,
|
|
||||||
Err(()) => {
|
|
||||||
shm.post_error(
|
shm.post_error(
|
||||||
wl_shm::Error::InvalidFd as u32,
|
Error::InvalidFd as u32,
|
||||||
format!("Failed mmap of fd {}.", fd),
|
"Invalid size for a new wl_shm_pool.".into(),
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
let mmap_pool = match Pool::new(fd, size as usize, self.log.clone()) {
|
||||||
let arc_pool = Box::new(Arc::new(mmap_pool));
|
Ok(p) => p,
|
||||||
evlh.register(
|
Err(()) => {
|
||||||
&pool,
|
shm.post_error(
|
||||||
shm_pool_implementation(),
|
wl_shm::Error::InvalidFd as u32,
|
||||||
data.clone(),
|
format!("Failed mmap of fd {}.", fd),
|
||||||
Some(destroy_shm_pool),
|
);
|
||||||
);
|
return;
|
||||||
pool.set_user_data(Box::into_raw(arc_pool) as *mut ());
|
}
|
||||||
},
|
};
|
||||||
|
let arc_pool = Box::new(Arc::new(mmap_pool));
|
||||||
|
let pool = pool.implement_nonsend(
|
||||||
|
self.clone(),
|
||||||
|
Some(|pool: Resource<_>, _| {
|
||||||
|
drop(unsafe { Box::from_raw(pool.get_user_data() as *mut Arc<Pool>) })
|
||||||
|
}),
|
||||||
|
&self.token,
|
||||||
|
);
|
||||||
|
pool.set_user_data(Box::into_raw(arc_pool) as *mut ());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn destroy_shm_pool(pool: &wl_shm_pool::WlShmPool) {
|
|
||||||
let arc_pool = unsafe { Box::from_raw(pool.get_user_data() as *mut Arc<Pool>) };
|
|
||||||
drop(arc_pool)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Details of the contents of a buffer relative to its pool
|
/// Details of the contents of a buffer relative to its pool
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
pub struct BufferData {
|
pub struct BufferData {
|
||||||
|
@ -217,30 +222,48 @@ struct InternalBufferData {
|
||||||
data: BufferData,
|
data: BufferData,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn shm_pool_implementation() -> wl_shm_pool::Implementation<ShmGlobalData> {
|
impl Implementation<Resource<wl_shm_pool::WlShmPool>, wl_shm_pool::Request> for ShmGlobalData {
|
||||||
wl_shm_pool::Implementation {
|
fn receive(&mut self, request: wl_shm_pool::Request, pool: Resource<wl_shm_pool::WlShmPool>) {
|
||||||
create_buffer: |evlh, data, _, pool, buffer, offset, width, height, stride, format| {
|
use self::wl_shm_pool::Request;
|
||||||
if !data.formats.contains(&format) {
|
|
||||||
buffer.post_error(wl_shm::Error::InvalidFormat as u32, String::new());
|
let arc_pool = unsafe { &*(pool.get_user_data() as *mut Arc<Pool>) };
|
||||||
return;
|
|
||||||
|
match request {
|
||||||
|
Request::CreateBuffer {
|
||||||
|
id: buffer,
|
||||||
|
offset,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
stride,
|
||||||
|
format,
|
||||||
|
} => {
|
||||||
|
if !self.formats.contains(&format) {
|
||||||
|
pool.post_error(
|
||||||
|
wl_shm::Error::InvalidFormat as u32,
|
||||||
|
format!("SHM format {:?} is not supported.", format),
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let data = Box::into_raw(Box::new(InternalBufferData {
|
||||||
|
pool: arc_pool.clone(),
|
||||||
|
data: BufferData {
|
||||||
|
offset: offset,
|
||||||
|
width: width,
|
||||||
|
height: height,
|
||||||
|
stride: stride,
|
||||||
|
format: format,
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
let buffer = buffer.implement_nonsend(
|
||||||
|
self.clone(),
|
||||||
|
Some(|buffer: Resource<_>, _| {
|
||||||
|
drop(unsafe { Box::from_raw(buffer.get_user_data() as *mut InternalBufferData) })
|
||||||
|
}),
|
||||||
|
&self.token,
|
||||||
|
);
|
||||||
|
buffer.set_user_data(data as *mut ());
|
||||||
}
|
}
|
||||||
let arc_pool = unsafe { &*(pool.get_user_data() as *mut Arc<Pool>) };
|
Request::Resize { size } => match arc_pool.resize(size) {
|
||||||
let data = Box::into_raw(Box::new(InternalBufferData {
|
|
||||||
pool: arc_pool.clone(),
|
|
||||||
data: BufferData {
|
|
||||||
offset: offset,
|
|
||||||
width: width,
|
|
||||||
height: height,
|
|
||||||
stride: stride,
|
|
||||||
format: format,
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
evlh.register(&buffer, buffer_implementation(), (), Some(destroy_buffer));
|
|
||||||
buffer.set_user_data(data as *mut ());
|
|
||||||
},
|
|
||||||
resize: |_, _, _, pool, size| {
|
|
||||||
let arc_pool = unsafe { &*(pool.get_user_data() as *mut Arc<Pool>) };
|
|
||||||
match arc_pool.resize(size) {
|
|
||||||
Ok(()) => {}
|
Ok(()) => {}
|
||||||
Err(ResizeError::InvalidSize) => {
|
Err(ResizeError::InvalidSize) => {
|
||||||
pool.post_error(
|
pool.post_error(
|
||||||
|
@ -251,19 +274,15 @@ fn shm_pool_implementation() -> wl_shm_pool::Implementation<ShmGlobalData> {
|
||||||
Err(ResizeError::MremapFailed) => {
|
Err(ResizeError::MremapFailed) => {
|
||||||
pool.post_error(wl_shm::Error::InvalidFd as u32, "mremap failed.".into());
|
pool.post_error(wl_shm::Error::InvalidFd as u32, "mremap failed.".into());
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
},
|
Request::Destroy => {}
|
||||||
destroy: |_, _, _, _| {},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn destroy_buffer(buffer: &wl_buffer::WlBuffer) {
|
impl Implementation<Resource<wl_buffer::WlBuffer>, wl_buffer::Request> for ShmGlobalData {
|
||||||
let buffer_data = unsafe { Box::from_raw(buffer.get_user_data() as *mut InternalBufferData) };
|
fn receive(&mut self, request: wl_buffer::Request, _pool: Resource<wl_buffer::WlBuffer>) {
|
||||||
drop(buffer_data)
|
// this will break if new requests are added to buffer =)
|
||||||
}
|
let wl_buffer::Request::Destroy = request;
|
||||||
|
|
||||||
fn buffer_implementation() -> wl_buffer::Implementation<()> {
|
|
||||||
wl_buffer::Implementation {
|
|
||||||
destroy: |_, _, _, _| {},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue